/* cnpt site: shared styles for every public page (/, /about, /network, /work).
   Type is Manrope, self-hosted as one variable file with a 200–800 weight axis (SIL Open Font
   License 1.1, fonts/Manrope-OFL.txt). One family does everything: the small uppercase labels are the
   same face set small and tracked out, which is how the references set them. */
@font-face{font-family:'Manrope';src:url(/fonts/manrope.woff2) format('woff2');font-weight:200 800;font-style:normal;font-display:swap}
:root{
  color-scheme:light;
  /* one accent, spent on the action that starts a project and nothing else */
  --signal:#E60045;
  --ink:#0E0E0D; --paper:#FFFFFF;
  /* the bar's own height, and how far down the window it floats: anything that has to clear the
     bar needs both, because the bar's bottom edge is the two added together */
  --nav-h:68px; --nav-top:8px; --sec-pad:clamp(54px,5.6vw,92px);
  --max:1400px; --pad:clamp(16px,2.6vw,34px); --hair:1px;
  /* one geometry, and it is generous: the references round a card hard enough that the corner is
     part of the look rather than an apology for a rectangle */
  --r-card:20px; --r-sm:8px; --r-cap:999px;
  /* the inset from a card's edge to the type on it, shared by every card that carries type */
  --card-pad:clamp(22px,3vw,40px);
  /* the bar across the top is a bar: enough of a corner to sit on the paper, not a pill */
  --r-nav:14px;
  --font:'Manrope',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  /* the small uppercase labels are the same face, set small and tracked out, as the references set them */
  --mono:var(--font);
  /* Light and large. Tracking tightens as the size grows, which is how a grotesque is set. */
  --t-display:clamp(56px,11vw,168px); --t-h2:clamp(30px,4.4vw,58px); --t-h3:clamp(19px,1.7vw,25px);
  --t-lede:clamp(18px,1.7vw,26px); --t-body:15px; --t-meta:10.5px;
  --w-display:350; --w-title:400; --w-body:400;

  /* the paper, and the white that sits on it */
  --bg:#F2F2F0;          /* the page */
  --bg-2:#FFFFFF;        /* a card on it */
  --bg-3:#EAEAE7;        /* a card inside a card, or a placeholder where a picture goes */
  --fg:#0E0E0D;          /* anything that has to carry */
  --fg-2:#4F4F4A;        /* the quieter half of a sentence, a value */
  --fg-3:#6E6E68;        /* a label, a caption: the lightest a word may be */
  --line:#E2E2DE;        /* between rows */
  --ink-border:#D4D4CF;  /* around a control */
  --fill:#0E0E0D;        /* a control that is switched on, and the type on it */
  --on-fill:#FFFFFF;
  /* a dark block on a light page: the hero, and any card that carries a picture */
  --slab:#1A1A18; --on-slab:#FFFFFF; --on-slab-2:#B4B4AE;
}
:root[data-theme="dark"]{
  color-scheme:dark;
  --bg:#0E0E0D;
  --bg-2:#171716;
  --bg-3:#1F1F1D;
  --fg:#FFFFFF;
  --fg-2:#B7B7B1;
  --fg-3:#92928C;
  --line:#242422;
  --ink-border:#33332F;
  --fill:#FFFFFF;
  --on-fill:#0E0E0D;
  --slab:#000000; --on-slab:#FFFFFF; --on-slab-2:#AFAFA9;
}
::selection{background:var(--signal);color:#fff}
*{box-sizing:border-box;margin:0;padding:0}
/* a link to a section lands below the bar, not behind it: the bar's height, the gap it floats in,
   and that gap again underneath so the first line is not touching it */
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;
  scroll-padding-top:calc(var(--nav-h) + var(--nav-top) * 2)}
body{background:var(--bg);color:var(--fg);font-family:var(--font);font-size:var(--t-body);
  line-height:1.6;font-weight:var(--w-body);letter-spacing:-0.014em;-webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility}
a{color:inherit;text-decoration:none}
.wrap{max-width:var(--max);margin:0 auto;padding:0 var(--pad)}
/* words written straight onto the paper start where the words on a card start */
.sec > .wrap > *,footer > .wrap > *{padding-inline:var(--card-pad)}
/* except a row of cards, which is a card and keeps the card line */
.sec > .wrap > .packs{padding-inline:0}
.dark{background:var(--bg);color:var(--fg)}

/* nav */
/* the gutter comes off the width as well as off the cap, the same way the contact band takes it,
   so the bar keeps its margin on a window narrower than the page */
nav{position:sticky;top:var(--nav-top);z-index:20;margin:var(--nav-top) auto 0;
  width:calc(100% - var(--pad) * 2);max-width:calc(var(--max) - var(--pad) * 2);
  background:var(--bg-2);border-radius:var(--r-nav);box-shadow:0 1px 2px rgba(0,0,0,.04)}
/* a card's own padding, so the wordmark starts where the type on every card below it starts */
nav .wrap{height:var(--nav-h);padding:0 var(--card-pad)}
/* three columns: the wordmark, the section links centred on the page, then Sign in and the button */
nav .wrap{height:var(--nav-h);display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:24px}
/* The lockup: the stacked mark with the name beside it. --lk is the mark's height and the
   reference's own proportions hang off it -- the name set at .515 of it, the gap at .415 -- so the
   foot wears the same lockup simply by naming a larger --lk. */
.nav-home,.foot-home{display:flex;align-items:center;gap:calc(var(--lk) * .415);color:var(--fg)}
.wm-mk{display:block;flex:none;height:var(--lk);width:auto}
.wm-line{font-size:calc(var(--lk) * .515);line-height:1.2;letter-spacing:-0.014em;white-space:nowrap}
.nav-home{grid-column:1;justify-self:start;--lk:27px}
/* the extended mark carries "Concept Canada 2027" beside the wordmark, so it is wider and set a touch
   smaller than the plain wordmark would be */
.navlinks{display:flex;align-items:center;gap:30px;font-size:14px;font-weight:400;color:var(--fg-3)}
.nav-actions{display:flex;align-items:center;gap:14px;font-size:14px;font-weight:400;color:var(--fg-3)}
.navlinks{grid-column:2}
.nav-actions{grid-column:3;justify-self:end}
/* the dark/light switch: the sun when a tap would turn the page light, the eclipse when it would
   turn it dark again */
.theme-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;
  flex:none;padding:0;border:0;background:none;color:var(--fg-3);cursor:pointer;transition:color .25s ease}
/* the two marks sit on top of each other and turn into one another */
.theme-btn svg{position:absolute;display:block;width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;
  transition:opacity .3s var(--ease-theme),transform .45s var(--ease-theme)}
.theme-btn .th-eclipse{opacity:0;transform:rotate(-80deg) scale(.5)}
:root[data-theme="light"] .theme-btn .th-sun{opacity:0;transform:rotate(80deg) scale(.5)}
:root[data-theme="light"] .theme-btn .th-eclipse{opacity:1;transform:none}
.theme-btn:focus-visible{outline:2px solid var(--fg);outline-offset:2px;border-radius:var(--r-cap)}
@media(hover:hover){.theme-btn:hover{color:var(--fg)}}
.navlinks a:not(.btn):hover{color:var(--fg)}
/* One action component,three roles,the same three everywhere including the signed-in side:
   .btn-signal is the brand pink and is reserved for Start a project,so a
   ghost and a filled button measure exactly the same. */
.btn{display:inline-flex;align-items:center;justify-content:center;height:var(--btn-h,44px);
  padding:0 var(--btn-x,22px);border-radius:var(--r-cap);
  font-size:var(--btn-t,14px);font-weight:var(--w-title);letter-spacing:-0.014em;flex:none}
.btn-signal{background:var(--fill);color:var(--on-fill);--btn-fill:var(--signal)}.btn-lg{--btn-h:56px;--btn-x:28px;--btn-t:15px}
/* a way through is a line of type: the filled box is kept for an action, not for a link */
.link-out{display:inline-flex;align-items:center;gap:10px;font-size:15px;font-weight:var(--w-title);letter-spacing:-0.014em;color:var(--fg)}
.link-out > span{position:relative;text-decoration:none}
/* drawn under the words rather than decorated onto them: a text decoration hangs off the baseline,
   and the boxes the letters roll in move that baseline */
.link-out > span::after{content:"";position:absolute;left:0;right:0;bottom:-.42em;height:var(--hair);
  background:var(--fg-3);transition:background-color .25s ease}
.link-out svg{display:block;width:11px;height:11px;transition:transform .25s var(--ease-out)}

/* A paragraph that begins in ink and finishes in grey: the claim, then the explanation. */
.split{font-size:var(--t-lede);font-weight:var(--w-body);line-height:1.34;letter-spacing:-0.02em;color:var(--fg-3)}
.split strong{font-weight:inherit;color:var(--fg)}
/* the three things we do run past as a band: one set, then the same set again, so translating the
   track by half its width returns it exactly where it started. Each line carries its own spacing,
   so half the track is exactly the first set. */
.ticker{overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 4%,#000 96%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 4%,#000 96%,transparent)}
.ticker-track{display:flex;width:max-content}
.motion .ticker-track{animation:ticker 46s linear infinite}
@keyframes ticker{to{transform:translate3d(-50%,0,0)}}
@media(hover:hover){.ticker:hover .ticker-track{animation-play-state:paused}}
/* section shell */
.sec{padding:var(--sec-pad) 0}
.sec-join{padding-top:0}
/* A section says its name: small, spaced, set in the mono so it reads as a label rather than as
   something to read. */
.eyebrow{display:block;font-family:var(--mono);font-size:var(--t-meta);font-weight:var(--w-title);
  letter-spacing:.06em;text-transform:uppercase;color:var(--fg-3);font-variant-numeric:tabular-nums}
/* on a dark block it takes the block's own quiet ink, not the page's */
.slab-dark .eyebrow,.cta .eyebrow{color:var(--on-slab-2)}
.pack-len,.member-spec dt,.fbottom,.tags,.count,.member-role{
  font-family:var(--mono);font-variant-numeric:tabular-nums;letter-spacing:.04em}
.pack-len,.member-spec dt{
  font-size:var(--t-meta);text-transform:uppercase;letter-spacing:.06em}
/* A running head: the rule says a section starts, then the label and the line that says what the
   section covers, together on one line. It was a two-column grid, which left that line stranded in
   the middle of the page above a heading that began again at the left margin. */
.sec-head{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 22px;margin-bottom:clamp(20px,2.2vw,30px)}
/* the standfirst carries the measure now, so the heading can run wider */
.sec h2 + .split,.sec h1 + .split{margin-top:clamp(14px,1.5vw,20px);max-width:46ch}
/* the claim and the sentence that explains it, side by side: the left column is set at display
   size and the right at reading size, which is how both references open a section. */
.sec-top{display:grid;gap:clamp(12px,1.4vw,18px)}
@media(min-width:900px){
  .sec-top{grid-template-columns:minmax(0,1.04fr) minmax(0,1fr);gap:clamp(36px,5vw,92px);align-items:start}
  /* in its own column the heading no longer needs a measure, and the sentence beside it has one */
  .sec-top > :is(h1,h2){max-width:none}
  .sec-top > :is(.split,.lede){margin-top:7px;max-width:52ch}
}
.sec-head p{font-size:var(--t-body);color:var(--fg-3);max-width:58ch;font-weight:var(--w-body)}
/* A section heading. On an inner page the first one is the page's own h1, which is a matter of
   what the page means rather than how big it is, so both are set the same. */
h2,:is(.sec,.cta) h1{font-size:var(--t-h2);font-weight:var(--w-display);letter-spacing:-0.035em;line-height:1.02;max-width:20ch}
.lede{font-size:var(--t-lede);line-height:1.55;color:var(--fg-2);max-width:58ch;margin-top:22px}
.eyebrow + :is(h1,h2){margin-top:18px}

/* what we do — three value rows: icon, title, description + tags */
.values{margin-top:clamp(26px,2.6vw,34px)}
/* 24 | 240 | the rest, 44 apart, which at 1440 leaves the body the 900px the reference gives it */
.value{--vt:clamp(21px,1.9vw,24.5px);position:relative;display:grid;
  grid-template-columns:24px clamp(140px,18.5vw,240px) minmax(0,1fr);
  gap:clamp(20px,3.1vw,44px);padding:26px 0;
  border-bottom:var(--hair) solid var(--line)}
/* centre the 24px mark on the title's first line (line-height 1.1) at every title size */
.value-ic{display:block;margin-top:calc(var(--vt) * .55 - 12px);color:var(--fg-2)}
.value-ic svg{display:block;width:24px;height:24px}
.value-core .value-ic{color:var(--fg)}
.value h3{font-size:var(--vt);font-weight:var(--w-title);letter-spacing:-0.026em;line-height:1.1}
:where(.value-body) p{font-size:15px;line-height:1.6;letter-spacing:-0.014em;color:var(--fg-3)}
/* the run of tags under a row is plain text here, not the mono label it is elsewhere */
.value-body .tags{margin-top:14px;font-size:12.5px;line-height:1.45;letter-spacing:-0.014em;
  font-weight:var(--w-body)}
.tags{display:flex;flex-wrap:wrap;gap:4px 18px;margin-top:20px;font-size:13px;font-weight:var(--w-title);color:var(--fg-3)}
.tags span{position:relative}
.tags span:not(:last-child)::after{content:"·";position:absolute;right:-11px}

.acc-row{
  width:100%;background:none;border:0;cursor:pointer;text-align:left;
  font-family:inherit;color:inherit;padding:34px 0;
  display:grid;grid-template-columns:minmax(0,1fr) auto;gap:44px;align-items:center;
  transition:opacity .5s var(--ease-out);-webkit-tap-highlight-color:transparent;
}.acc-row:focus-visible{outline:2px solid var(--signal);outline-offset:6px;border-radius:4px}

/* A letterform arrives as a point of ink and grows into itself. What opens is a circle cut out of
   the shape, so what you see is always the letter's own edge: a round dot at first, because a small
   enough piece of anything is round, and then its true outline as the circle passes the contours.
   The shape is never stretched or squashed to get there — it is uncovered, not deformed. Each
   letterform follows the one before it, in reading order. */
@keyframes mk-morph{
  0%{opacity:0;transform:scale(.52);clip-path:circle(7% at 50% 54%)}
  18%{opacity:1}
  100%{opacity:1;transform:scale(1);clip-path:circle(80% at 50% 54%)}
}
/* A circle wide enough to hold a box is about 71% of it, so the reveal is finished a little before
   the end, not most of the way through: the curve starts slowly on purpose, to let the dot be a dot
   before it becomes a letter. */
:root{--ease-morph:cubic-bezier(.5,0,.25,1)}
.motion :is(.acc,.sum-list li).in .acc-mk.is-live :is(path,circle,rect,ellipse,polygon){
  animation:mk-morph 1.05s var(--ease-morph) calc(var(--d,0ms) + 220ms + var(--i,0) * 190ms) backwards}

.prac-note{font-size:14px;color:var(--fg-3);margin-top:28px;max-width:64ch}

/* packages — three columns of work a client can commission by name. Each one is a ruled column:
   icon and number, the name, what it is, then the spec sheet of what is in it and how long it runs. */
/* The packages are the cards on this page, so the row sits on the card line and each one is a
   white box with a hairline and a 20px corner, 28 of padding, 22 between its parts. */
.packs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;margin-top:clamp(26px,2.6vw,34px)}
.pack{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:22px;
  background:var(--bg-2);border-radius:var(--r-card);padding:28px;
  box-shadow:inset 0 0 0 var(--hair) var(--line);
  transition:box-shadow .32s var(--ease-out),transform .32s var(--ease-out)}
.pack-ic{display:block;color:var(--fg-2);transition:color .5s var(--ease-out)}
.pack-ic svg{display:block;width:24px;height:24px}
.pack h3{font-size:clamp(21px,1.9vw,24.5px);font-weight:var(--w-title);letter-spacing:-0.026em;line-height:1.1}
.pack > p{font-size:14px;line-height:1.6;letter-spacing:-0.014em;color:var(--fg-3)}
/* what is in the package: one ruled line each, so it reads as a spec sheet rather than a run of chips.
   The slack sits above the list, so the spec sheets line up across the row however long the copy runs. */
.pack-in{list-style:none;width:100%;margin-top:auto}
.pack-in li{padding:11px 0;font-size:14px;line-height:1.6;letter-spacing:-0.014em;color:var(--fg-2);
  border-top:var(--hair) solid var(--line)}
/* lengths sit at the foot of each column, so they share one line across the row */
.pack-len{font-size:var(--t-meta);font-weight:var(--w-title);letter-spacing:.11em;
  text-transform:uppercase;color:var(--fg-3)}
.pack-len strong{margin-right:9px;font-weight:inherit;color:inherit}
/* the three marks breathe out of step with each other, the way the reference's marks do */
.motion .pack-ic svg{animation:pack-breath 6s ease-in-out infinite}
.motion .pack:nth-child(2) .pack-ic svg{animation-delay:-2s}
.motion .pack:nth-child(3) .pack-ic svg{animation-delay:-4s}
@keyframes pack-breath{0%,100%{transform:scale(1)}50%{transform:scale(1.055)}}
/* three across while there is room, then two, then one */
@media(max-width:900px){.packs{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:620px){.packs{grid-template-columns:minmax(0,1fr)}}

/* focus */
:is(h1,h2) em{font-style:normal;color:inherit}
/* a heading that only has half the page to itself takes the step below the full-width one */
.cta-grid :is(h1,h2){font-size:clamp(28px,3.6vw,52px);letter-spacing:-0.036em}

/* team — one ruled column per person: portrait on top, then the name, what they do, and a small spec sheet.
   Stacking the card is what lets three sit across the page instead of two. */
.team{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0 32px;margin-top:56px}
.member{position:relative;display:grid;grid-template-columns:minmax(0,1fr);align-content:start;padding:32px 0 40px}
.member-id{margin-top:20px}
.member-spec{align-self:start;margin-top:20px}
/* the frame matches the portraits' own 1350×1764 crop, so nothing is cut off */
.member-photo{position:relative;display:flex;align-items:center;justify-content:center;aspect-ratio:1350/1764;
  overflow:hidden;background:var(--bg-2)}
/* initials sit behind the photo and only show if the image file is missing */
.member-init{font-size:clamp(40px,5vw,64px);font-weight:var(--w-title);letter-spacing:-0.035em;color:var(--fg-3)}  /* it only shows when the portrait does not load, so it has to be readable on its own */
.member-photo img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 20%;
  transition:transform .8s var(--ease-out)}
.member h3{font-size:clamp(18px,1.45vw,21px);font-weight:var(--w-title);letter-spacing:-0.026em;line-height:1.15}
.member-role{font-size:13px;color:var(--fg-3);margin-top:8px}
/* a line or two on what each person does, under their role */
.member-bio{margin-top:12px;font-size:13px;line-height:1.55;color:var(--fg-3)}
/* a role keeps to one line while there is room for it; one too long for the line beside it drops
   whole to the next, and only one too long for the card at all breaks inside */
.member-role span{display:inline-block;max-width:100%;white-space:normal}
/* spec sheet: label | value rows */
.member-spec > div{display:grid;grid-template-columns:64px minmax(0,1fr);gap:10px;align-items:baseline;
  padding:7px 0}
.member-spec > div:last-child{padding-bottom:0}
.member-spec dt{font-size:11.5px;font-weight:var(--w-title);color:var(--fg-3)}
.member-spec dd{font-size:13px;line-height:1.5;color:var(--fg-2)}
.member-spec dd span{color:var(--fg-3)}
.member-spec a{display:inline-flex;align-items:center;gap:6px;transition:color .25s ease}
.member-spec svg{display:block;width:10px;height:10px;flex:none}
.member-spec a:focus-visible{outline:2px solid var(--signal);outline-offset:3px;border-radius:4px}
/* three across while there is room for them, then two, then one */
@media(max-width:900px){.team{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:620px){.team{grid-template-columns:minmax(0,1fr)}}

/* hover opens one frame: the person under the pointer takes more of the row and the other two give
   way, the way the 2026 portfolio's media rows do. The portrait is the part that grows — it keeps its
   height and simply shows more of its own crop. The words underneath scale with their own column
   rather than rewrapping, which is also what keeps them inside it: this pair of factors is the
   reference's, and it holds the row's weight of type even — what the open column gains, the two
   beside it give up. The column width is worked out from the page measure the way the reference
   works out its cards, scrollbar included.
   Only where there is a real pointer, and only while all three are across. */
.team{--member-w:calc((min(100vw - var(--sbw,0px),var(--max)) - var(--pad) * 2 - 64px) / 3);
  --open:1.35;
  --type-up:calc(2 * var(--open) / (var(--open) + 1));
  --type-down:calc(2 / (var(--open) + 1))}
/* the words are one block only where they scale together; everywhere else they stay their own grid
   items, so the phone layout is untouched */
.member-info{display:contents}
@media(hover:hover) and (pointer:fine) and (min-width:1181px){
  .team{display:flex;gap:0 32px}
  .member{flex:1 1 0;min-width:0;transition:flex-grow .45s var(--ease-ref)}
  .team:has(.member:hover) .member:hover{flex-grow:var(--open)}
  /* the frame keeps the height it had, so the row never jumps */
  .member-photo{aspect-ratio:auto;height:calc(var(--member-w) * 1764 / 1350)}
  .member-info{display:block;width:var(--member-w);transform-origin:0 0;
    transition:transform .45s var(--ease-ref)}
  .team:has(.member:hover) .member:hover .member-info{transform:scale(var(--type-up))}
  .team:has(.member:hover) .member:not(:hover) .member-info{transform:scale(var(--type-down))}
}

/* cta band */
/* A dark card on a light page. The background is on the block itself rather than on a pseudo-
   element behind it: a pseudo-element is invisible to anything that reads computed styles, so every
   word on it reported as white-on-paper. */
.cta{position:relative;isolation:isolate;color:var(--on-slab);background:var(--slab);
  /* the gutter has to come off the width as well as off the cap, or on a window narrower than the
     page the band keeps its cap, fills the window and loses the margin every other card keeps */
  width:calc(100% - var(--pad) * 2);max-width:calc(var(--max) - var(--pad) * 2);margin:0 auto;
  border-radius:var(--r-card);
  padding:clamp(40px,4.4vw,68px) 0}
/* the band is a card, so the type on it is inset by a card's padding like any other */
.cta .wrap{padding:0 var(--card-pad)}
.cta :is(h1,h2){max-width:18ch}
:where(.cta) p{font-size:17px;color:var(--on-slab-2);max-width:52ch;margin-top:22px;line-height:1.6}
.cta .split strong{color:var(--on-slab)}
.cta .btn-signal{background:var(--on-slab);color:var(--slab);--btn-fill:var(--signal)}
@media(hover:hover){.cta .btn-signal:hover{color:#fff}}
.cta .link-out{color:var(--on-slab)}
.cta .link-out > span::after{background:var(--on-slab-2)}
.cta-row{display:flex;flex-wrap:wrap;align-items:center;gap:16px 30px;margin-top:40px}
/* the short way in, under the long one: no account, an address and a line */
.cta-note{grid-column:1 / -1;padding-top:8px}
.cta-note-head{font-size:15px;font-weight:var(--w-title);letter-spacing:-0.014em;color:var(--on-slab);margin:0 0 14px}
.cta-note-head span{font-weight:var(--w-body);color:var(--on-slab-2)}
.cta-note .form-status{margin-top:10px}
/* copy on the left, the enquiry form on the right */
.cta-grid{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,6fr);gap:64px;align-items:start}

/* contact form — stage chips above a prompt-style message box */
button.btn{border:0;font-family:inherit;cursor:pointer}

.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.cta-form{position:relative;display:grid;gap:22px}
.stage{border:0;min-width:0}
.stage legend{font-size:13px;font-weight:var(--w-title);color:var(--on-slab-2);margin-bottom:12px}
.stage-opts{display:flex;flex-wrap:wrap;gap:8px}
.stage-opt{position:relative;display:block}
/* the radio stays focusable and readable by screen readers; the chip is what people see */
.stage-opt input{position:absolute;inset:0;margin:0;opacity:0;cursor:pointer}
.stage-opt span{display:inline-flex;align-items:center;height:40px;padding:0 18px;border-radius:var(--r-sm);
  font-size:14px;font-weight:var(--w-title);letter-spacing:-0.012em;color:var(--on-slab);box-shadow:inset 0 0 0 var(--hair) rgba(255,255,255,.26);
  transition:background-color .25s ease,color .25s ease,box-shadow .25s ease}
.stage-opt input:checked + span{background:var(--on-slab);color:var(--slab);box-shadow:none}
.stage-opt input:focus-visible + span{outline:2px solid var(--on-slab);outline-offset:3px}
/* the composer is drawn like the chips and outline buttons: no fill, a hairline, the page's own ink */
.composer{border-radius:var(--r-sm);box-shadow:inset 0 0 0 var(--hair) rgba(255,255,255,.26);transition:box-shadow .25s ease}
.composer:hover{box-shadow:inset 0 0 0 var(--hair) rgba(255,255,255,.45)}
.composer:focus-within{box-shadow:inset 0 0 0 var(--hair) var(--on-slab)}
.composer textarea,.composer input{font-family:inherit;font-size:16px;font-weight:var(--w-body);letter-spacing:-0.004em;color:var(--fg);
  background:none;border:0;outline:none;caret-color:var(--on-slab)}
.composer textarea{display:block;width:100%;min-height:130px;padding:8px 22px 14px;line-height:1.55;resize:none}
.composer ::placeholder{color:var(--on-slab-2);opacity:1}
/* keep browser autofill from painting a light box inside the transparent field */
.composer input:-webkit-autofill{-webkit-text-fill-color:var(--on-slab);box-shadow:0 0 0 1000px var(--slab) inset}
.composer-head{display:flex;align-items:baseline;justify-content:space-between;gap:16px;padding:16px 22px 0}
.composer-head label,.composer-foot label{font-size:12.5px;font-weight:var(--w-title);color:var(--on-slab-2);white-space:nowrap;cursor:text}
.req{color:var(--on-slab)}
.composer-foot{display:flex;align-items:center;gap:14px;padding:10px 10px 10px 22px;border-top:var(--hair) solid rgba(255,255,255,.2)}
.composer input{flex:1;min-width:0;height:40px}
.count{font-size:12.5px;font-weight:var(--w-title);color:var(--on-slab-2);font-variant-numeric:tabular-nums;white-space:nowrap}
.count.is-near{color:var(--on-slab)}
/* Send is this form's action, drawn as the filled neutral control */
.btn-send{gap:8px;background:var(--on-slab);color:var(--slab)}
.btn-send svg{display:block;width:10px;height:10px}
/* Send stays disabled until every required field is filled in */
.btn-send:disabled{background:transparent;color:var(--on-slab-2);box-shadow:inset 0 0 0 var(--hair) rgba(255,255,255,.22);
  cursor:not-allowed;transform:none}
.cta-form.is-sending .btn-send{opacity:.7;cursor:progress}
.form-foot{display:grid;gap:6px;margin-top:-8px}
.form-note{font-size:13px;font-weight:var(--w-title);color:var(--on-slab-2)}
.form-status{min-height:1.6em;font-size:14.5px;font-weight:var(--w-title);color:var(--on-slab)}

/* footer */
footer{padding:72px 0 56px}
.fgrid{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:44px;align-items:start}
.foot-home{--lk:34px;width:max-content;max-width:100%}
footer .tag{font-size:14px;color:var(--fg-3);margin-top:22px;max-width:34ch;line-height:1.6}
.fcol h4{font-size:13px;font-weight:var(--w-title);color:var(--fg);margin-bottom:16px}
.fcol a,.fcol div{display:block;font-size:14px;color:var(--fg-3);margin-bottom:9px}
.fcol a:hover{color:var(--fg)}
/* the rule sits inside the padding, so it starts and ends on the type line with the words
   above and below it rather than running out to the card line */
.fbottom::before{content:"";position:absolute;top:0;left:var(--card-pad);right:var(--card-pad);
  height:var(--hair);background:var(--line)}
.fbottom{position:relative;margin-top:64px;padding-top:26px;display:flex;
  justify-content:space-between;gap:20px;flex-wrap:wrap;font-size:13px;color:var(--fg-3);font-weight:var(--w-title)}

/* motion — entrance reveals
   Only active while <html> has .motion (set in <head> when JS runs and reduced-motion is off).
   The script tags targets with data-rv="up|fade|clip|split|line|rule|cta" and adds .in as they
   scroll into view; the attribute is dropped once the reveal ends so hover transitions take over. */
:root{--ease-out:cubic-bezier(.16,1,.3,1);--ease-io:cubic-bezier(.7,0,.2,1);--ease-pop:cubic-bezier(.34,1.56,.64,1);
  --ease-theme:cubic-bezier(.4,0,.2,1);
  /* the curves the 2026 portfolio moves on: one for everything that travels, one for the
     overshoot a control gives back under the pointer */
  --ease-ref:cubic-bezier(.2,.7,.2,1);--ease-spring:cubic-bezier(.34,1.4,.55,1)}

/* changing the theme: every colour on the page eases to its new value. The class is only on the page
   while the change is running, so nothing else has to carry a transition it does not want. */
.theming,.theming *,.theming *::before,.theming *::after{
  transition:background-color .5s var(--ease-theme),
    border-color .5s var(--ease-theme) 40ms,
    box-shadow .5s var(--ease-theme) 40ms,
    outline-color .5s var(--ease-theme) 40ms,
    color .5s var(--ease-theme) 90ms,
    fill .5s var(--ease-theme) 90ms,
    stroke .5s var(--ease-theme) 90ms,
    text-decoration-color .5s var(--ease-theme) 90ms!important}
.motion:not(.motion-ready) body{visibility:hidden}
.motion:not(.motion-ready) *,.motion:not(.motion-ready) *::before{transition:none!important}
.sec{overflow-x:clip}

.motion .nav-home,.motion .navlinks > *,.motion .nav-actions > *{animation:nav-in .9s var(--ease-out) backwards}
.motion .navlinks > :nth-child(1){animation-delay:.08s}
.motion .navlinks > :nth-child(2){animation-delay:.14s}
.motion .navlinks > :nth-child(3){animation-delay:.2s}
.motion .navlinks > :nth-child(4){animation-delay:.26s}
.motion .nav-actions > :nth-child(1){animation-delay:.32s}
.motion .nav-actions > :nth-child(2){animation-delay:.38s}
@keyframes nav-in{from{opacity:0;transform:translateY(-12px)}}

.motion [data-rv]{transition:opacity .8s ease var(--d,0ms),transform .8s var(--ease-ref) var(--d,0ms)}
.motion [data-rv="up"]:not(.in){opacity:0;transform:translateY(16px)}
.motion [data-rv="fade"]:not(.in){opacity:0}
.motion [data-rv="clip"]{transition:clip-path .8s var(--ease-io) var(--d,0ms)}
.motion [data-rv="clip"]:not(.in){clip-path:inset(0 100% 0 0)}
.motion [data-rv="clip"].in{clip-path:inset(0 0 0 0)}
.motion [data-rv="line"]:not(.in)::before{transform:scaleX(0)}

/* headings: each word rises out of its own mask */
.wd{display:inline-block;vertical-align:top;overflow:hidden;padding:0 .06em .14em;margin:0 -.06em -.14em}
.wd > span{display:inline-block}
.motion [data-rv="split"] .wd > span{transition:transform 1.1s var(--ease-out) calc(var(--d,0ms) + var(--i,0) * 45ms)}
.motion [data-rv="split"]:not(.in) .wd > span{transform:translateY(115%)}

/* contact: the red layer opens out over the black section */
.motion .cta[data-rv]{transition:clip-path 1.2s var(--ease-out) var(--d,0ms)}
.motion .cta[data-rv]:not(.in){clip-path:inset(3% 2% round var(--r-card))}
.motion .cta[data-rv].in{clip-path:inset(0% 0% round var(--r-card))}

/* ruled rows (value rows, process steps, deliverables, focus items): the rule draws first, then the contents rise in */
.motion [data-rv="rule"]:not(.in)::before{transform:scaleX(0)}
.motion [data-rv="rule"] > *{transition:opacity .8s ease,transform .8s var(--ease-ref);
  transition-delay:calc(var(--d,0ms) + 200ms + var(--i,0) * 80ms)}
.motion [data-rv="rule"]:not(.in) > *{opacity:0;transform:translateY(16px)}
.motion [data-rv="rule"] > :nth-child(2){--i:1}
.motion [data-rv="rule"] > :nth-child(3){--i:2}
.motion [data-rv="rule"] > :nth-child(4){--i:3}

/* motion — interaction */
.btn{position:relative;overflow:hidden;isolation:isolate;
  transition:color .4s var(--ease-out),border-color .4s var(--ease-out),transform .3s var(--ease-out)}
.btn::before{content:"";position:absolute;inset:-2px;z-index:-1;background:var(--btn-fill,var(--fg));
  transform:translateY(105%);transition:transform .55s var(--ease-out)}
.btn:active{transform:scale(.97)}
.btn:focus-visible{outline:2px solid var(--fg);outline-offset:3px}
.navlinks a,.nav-actions a:not(.btn),.fcol a{transition:color .25s ease}

/* :where() keeps these below the reveal transitions until a step has finished revealing */
:where(.step > *, .step .dot, .step .dot svg, .value > *, .member > *, .focus-item > *, .pack > *){transition:opacity .5s var(--ease-out),color .5s var(--ease-out)}

/* the step is a transition on the row itself, so it also eases back out when the pointer leaves */
.sum-list li,.value,.pack-in li{transition:padding-left .3s var(--ease-ref)}
.value{transition:padding-left .3s var(--ease-ref),border-color .5s var(--ease-out)}
@media(hover:hover){
  .btn:not(:disabled):hover::before{transform:none}
  .link-out:hover > span::after{background:var(--fg)}
  .link-out:hover svg{transform:translate(2px,-2px)}  /* whatever the button looked like at rest, the red that rises under it carries white */
  .btn-signal:hover{color:#fff}
  .stage-opt:hover input:not(:checked) + span{box-shadow:inset 0 0 0 var(--hair) #fff}
  .btn-send:not(:disabled):hover{color:#fff}
  .acc-list:has(.acc-row:hover) .acc-row:not(:hover){opacity:.45}
  /* the row leans in: the mark grows into its larger size while the letterforms redraw themselves
     one after the other, so pointing at a practice writes its name again rather than just magnifying
     it. The wordmark beside them keeps its size. */
  .acc-row:hover .acc-mk{transform:scale(1.32)}
  .motion :is(.acc-row,.sum-list li):hover .acc-mk.is-live :is(path,circle,rect,ellipse,polygon){
    animation:mk-morph .86s var(--ease-morph) calc(var(--i,0) * 170ms) backwards}
  .acc-row:hover .acc-name{transform:translateX(8px)}
  .acc-row:hover .acc-ic::before,.acc-row:hover .acc-ic::after{background:var(--fill)}
  .acc-row:hover .acc-seg{color:var(--fg-2)}

  /* dim the icon, not its black backing, so a lit rule never shows through a dimmed icon */
  .track:has(.step:hover) .step:not(:hover) > :not(.dot),
  .track:has(.step:hover) .step:not(:hover) .dot svg{opacity:.45}

  /* same as the process: rules light together down to the hovered row; text and icons respond per row */
  :is(.value:hover, .value:has(~ .value:hover)){border-bottom-color:var(--ink-border)}
  .values:has(.value:hover) .value:not(:hover) > *{opacity:.45}
  .value:hover .value-ic{color:var(--fg)}
  .value-core:hover .value-ic{color:var(--fg)}

  /* packages answer hover like the focus items */
  .pack:hover{box-shadow:inset 0 0 0 var(--hair) var(--ink-border);transform:translateY(-3px)}
  .pack:hover .pack-ic{color:var(--fg)}
  /* every section mark answers the pointer with the reference's overshoot: it lifts and comes back */
  .value-ic,.pack-ic{transition:transform .4s var(--ease-spring),color .5s var(--ease-out)}
  .value:hover .value-ic,.pack:hover .pack-ic{transform:translateY(-5px) scale(1.06)}

  .focus:has(.focus-item:hover) .focus-item:not(:hover) > *{opacity:.45}

  /* a ruled row steps into its own rule when you point at it, the way the reference's contact rows
     do. The row keeps its width and only its contents inset, so nothing beside it moves. */
  :is(.sum-list li,.value,.dl,.pack-in li):hover{padding-left:10px}
  /* team rows answer hover like the value rows: the rule lights, the other person dims, the portrait leans in */
  .member:hover::before{background:var(--fg-2)}
  .team:has(.member:hover) .member:not(:hover) > *{opacity:.45}
  .member:hover img{transform:scale(1.03)}
  .member-spec a:hover{color:var(--fg)}
}
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .ticker-track{animation:none!important}
  *,*::before,*::after{animation-duration:.01ms!important;animation-delay:0s!important;
    transition-duration:.01ms!important;transition-delay:0s!important}
}

/* team cards stack once two no longer fit side by side without the school line wrapping */
@media(max-width:1180px){
  .team{gap:0 24px}
}

/* tablet */
@media(max-width:1000px){
  :root{--sec-pad:80px}
  .sec-head{margin-bottom:36px}

  .navlinks,.nav-actions{gap:20px}
  .acc-row{grid-template-columns:minmax(0,1fr) auto;gap:18px 16px;padding:26px 0}

  .motion .step[data-rv]:not(.in)::before{transform:scaleY(0)}

  .packs{gap:0 32px;margin-top:40px}
  .value{grid-template-columns:24px minmax(0,1fr);gap:12px 20px;padding:22px 0}
  .value-body{grid-column:2}

  .team{margin-top:44px}
  .member{padding:32px 0 40px}
  footer{padding:56px 0 40px}
  .cta-grid{grid-template-columns:1fr;gap:44px}
  .fgrid{grid-template-columns:1fr 1fr;gap:40px 32px}
  .fgrid > :first-child{grid-column:1 / -1}
  .fbottom{margin-top:48px}
}
@media(max-width:760px){

  .lede{font-size:17px}
}
/* phone */
@media(max-width:620px){
  :root{--nav-h:62px;--sec-pad:64px}
  .nav-home{--lk:23px}
  nav .wrap{gap:12px}
  .nav-actions{gap:8px}
  .nav-actions .btn{height:36px;padding:0 15px;font-size:13px}
  .theme-btn{width:32px;height:32px}
  .theme-btn svg{width:18px;height:18px}
  .sec-head{gap:12px 16px;margin-bottom:28px}
  .eyebrow + :is(h1,h2){margin-top:20px}

  .acc-row{padding:22px 0}

  .prac-note{margin-top:24px}

  .packs{margin-top:32px}
  .pack{padding:24px 0 4px}
  .pack h3{margin-top:18px}
  .value{grid-template-columns:1fr;gap:12px;padding:20px 0}
  .value-body{grid-column:auto}
  .value-ic{margin-top:0}

  /* phone: small portrait beside the name, spec sheet full width underneath */
  .team{margin-top:36px}
  .member{grid-template-columns:112px minmax(0,1fr);grid-template-rows:auto;gap:0 18px;padding:28px 0 32px;align-items:center}
  .member-photo{grid-row:auto}
  .member h3{font-size:22px}
  .member-role{font-size:14px;margin-top:8px}
  /* the portrait sits beside the name, and everything wordy runs the full width underneath */
  .member-bio{grid-column:1 / -1;margin-top:18px}
  .member-spec{grid-column:1 / -1;margin-top:20px}
  .member-spec > div{grid-template-columns:84px minmax(0,1fr)}
  .lede{font-size:16px;margin-top:18px}
  .cta{padding:64px 0}
  :where(.cta) p{font-size:16px}
  .cta-row{margin-top:32px}
  .fbottom{margin-top:40px}
}
/* the section links move into the menu before the centred row runs into Sign in / My Project and the button */
@media(max-width:900px){
  .navlinks{display:none}
  nav .wrap{display:flex;justify-content:space-between}
}
@media(max-width:480px){
  .hero-cta .btn,.cta-row .btn{flex:1 1 100%;justify-content:center}
  /* the email keeps its own line; Send runs full width underneath */
  .composer-head{padding:14px 18px 0}
  .composer textarea{padding:8px 18px 12px}
  .composer-foot{flex-wrap:wrap;gap:6px 12px;padding:6px 10px 10px 18px}
  .btn-send{flex:1 1 100%;justify-content:center}
}
@media(max-width:400px){
  .fgrid{grid-template-columns:1fr}
}

/* ---------- pages ---------- */
/* the current page in the nav */
.navlinks a[aria-current="page"]{color:var(--fg)}
/* inner pages start with a section right under the nav */
.page-first{padding-top:calc(var(--sec-pad) * .8)}

/* a page built from several sections keeps that section's title at the top while you are inside it,
   so the page stays divided as it scrolls */
.page-sections .sec-head{position:sticky;top:calc(var(--nav-h) + var(--nav-top));z-index:6;gap:8px 20px;
  margin-bottom:40px;padding:14px var(--card-pad) 15px;border-top:0;background:var(--bg)}

/* phone menu: the section links move into a sheet under the nav */
.nav-menu{display:none;position:relative;width:40px;height:40px;border:0;border-radius:var(--r-sm);background:none;cursor:pointer;
  box-shadow:inset 0 0 0 var(--hair) var(--ink-border);color:var(--fg);flex:none}
.nav-menu span{position:absolute;left:12px;right:12px;height:var(--hair);background:currentColor;transition:transform .3s var(--ease-out),top .3s var(--ease-out)}
.nav-menu span:first-child{top:15.5px}
.nav-menu span:last-child{top:22.5px}
.nav-menu[aria-expanded="true"] span:first-child{top:19px;transform:rotate(45deg)}
.nav-menu[aria-expanded="true"] span:last-child{top:19px;transform:rotate(-45deg)}
.nav-sheet{position:absolute;left:0;right:0;top:100%;background:var(--bg);padding:12px 0 28px}
nav .nav-sheet .wrap{display:block;height:auto}
.nav-sheet a{display:flex;align-items:center;gap:14px;padding:12px 0;font-size:26px;font-weight:400;letter-spacing:-0.028em;color:var(--fg-3)}
.nav-sheet a[aria-current="page"],.nav-sheet a:hover{color:var(--fg)}

/* nav icons: a section link shows its icon on hover or keyboard focus, and the page you are on keeps its icon lit
   (playing its motion once as the page opens). The phone sheet always shows them.
   The link keeps a slot for the icon, so nothing in the nav moves when it appears. */
.nav-ic{display:block;flex:none;width:24px;height:24px}
.nav-ic svg{display:block;width:100%;height:100%;overflow:visible;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.nav-ic svg *{transform-box:fill-box;transform-origin:center}
.nav-ic [pathLength]{stroke-dasharray:1 2}
.nav-sheet .ic-go{color:var(--fg-3)}
.navlinks .nav-link{position:relative;padding-left:22px;margin-left:-18px}
.navlinks .nav-link:first-child{margin-left:-22px} /* the row centres on the words; the first icon sits just outside it */
.navlinks .nav-ic{position:absolute;left:0;top:50%;width:16px;height:16px;margin-top:-8px;opacity:0;
  transition:opacity .2s ease,transform .45s var(--ease-out)}
.motion .navlinks .nav-ic{transform:scale(.6)}
.navlinks .nav-link[aria-current="page"]{--sd:450ms} /* after the nav has slid in */
.navlinks .nav-link:is([aria-current="page"],:focus-visible) .nav-ic{opacity:1;transform:none}
@media(hover:hover){
  .navlinks .nav-link:hover .nav-ic{opacity:1;transform:none}
}
@media(max-width:1000px){
  .navlinks .nav-link{margin-left:-8px}
}
/* each icon has its own entrance: the shapes pop in turn, the dashes light up around the circle,
   the globe is drawn and then ticked, the team gathers around the person in front. In the sheet they run one link after another. */
.nav-ic svg > :nth-child(2){--i:1} .nav-ic svg > :nth-child(3){--i:2} .nav-ic svg > :nth-child(4){--i:3}
.nav-ic svg > :nth-child(5){--i:4} .nav-ic svg > :nth-child(6){--i:5} .nav-ic svg > :nth-child(7){--i:6} .nav-ic svg > :nth-child(8){--i:7}
.nav-sheet a:nth-child(2){--sd:70ms} .nav-sheet a:nth-child(3){--sd:140ms} .nav-sheet a:nth-child(4){--sd:210ms} .nav-sheet a:nth-child(5){--sd:280ms}
.motion :is(.navlinks .nav-link:hover,.navlinks .nav-link:focus-visible,.navlinks .nav-link[aria-current="page"],.nav-sheet a) .ic-practices svg > *{
  animation:nic-pop .6s cubic-bezier(.34,1.56,.64,1) calc(var(--sd,0ms) + var(--i,0) * 80ms) backwards}
.motion :is(.navlinks .nav-link:hover,.navlinks .nav-link:focus-visible,.navlinks .nav-link[aria-current="page"],.nav-sheet a) .ic-works path:first-child{animation:nic-draw .7s var(--ease-out) var(--sd,0ms) backwards}
.motion :is(.navlinks .nav-link:hover,.navlinks .nav-link:focus-visible,.navlinks .nav-link[aria-current="page"],.nav-sheet a) .ic-works path:last-child{
  animation:nic-draw .35s var(--ease-out) calc(var(--sd,0ms) + 450ms) backwards}
.motion :is(.navlinks .nav-link:hover,.navlinks .nav-link:focus-visible,.navlinks .nav-link[aria-current="page"],.nav-sheet a) .ic-talent circle{
  animation:nic-pop .5s cubic-bezier(.34,1.56,.64,1) calc(var(--sd,0ms) + var(--i,0) * 70ms) backwards}
.motion :is(.navlinks .nav-link:hover,.navlinks .nav-link:focus-visible,.navlinks .nav-link[aria-current="page"],.nav-sheet a) .ic-talent path{
  animation:nic-draw .4s var(--ease-out) calc(var(--sd,0ms) + var(--i,0) * 70ms) backwards}
.motion :is(.navlinks .nav-link:hover,.navlinks .nav-link:focus-visible,.navlinks .nav-link[aria-current="page"],.nav-sheet a) .ic-updates path{
  animation:nic-draw .45s var(--ease-out) calc(var(--sd,0ms) + var(--i,0) * 90ms) backwards}
@keyframes nic-pop{from{transform:scale(0) rotate(-40deg)}}
@keyframes nic-draw{from{stroke-dashoffset:1.01}}

/* home: each page gets a section of its own, with the numbered list of what is on it */
.sum-list{list-style:none;margin-top:clamp(24px,2.6vw,32px)}
.sum-list li{padding:18px 0}
/* A row with exactly two things in it -- a title and one line about it -- reads across the width.
   A row with more in it than that reads down, or its parts end up scattered between two columns. */
.sum-list li > div{display:grid;grid-template-columns:minmax(0,1fr);gap:10px 44px;align-items:baseline}
@media(min-width:761px){
  .sum-list li > div:has(> :nth-child(2)):not(:has(> :nth-child(3))){
    grid-template-columns:minmax(0,7fr) minmax(0,5fr)}
}
.sum-list li > div > p{margin-top:0}
.sum-list h3{font-size:clamp(22px,2.2vw,28px);font-weight:var(--w-title);letter-spacing:-0.032em;line-height:1.05}@media(hover:hover){
  .sum-list li:hover .acc-mk{transform:scale(1.32)}
}
.sum-list p{margin-top:8px;font-size:15px;line-height:1.6;color:var(--fg-3);max-width:62ch}
/* the short list of the same people: the name on the left, what they do set against it on the
   right, and a hairline under each of them, the way the reference draws the row */
#s-network .sum-list li{border-bottom:var(--hair) solid var(--line)}
#s-network .sum-list p{max-width:none}
@media(min-width:761px){#s-network .sum-list li > div > p{text-align:right}}

/* The four stages are not cards: a mark, the name, the copy and the length, as type on the page. */
.steps{list-style:none;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(24px,2.5vw,36px);margin-top:clamp(26px,2.6vw,34px)}
.step-card{display:flex;flex-direction:column;align-items:flex-start;gap:14px}
.step-ic{display:block;color:var(--fg-2);transition:color .5s var(--ease-out)}
.step-ic svg{display:block;width:24px;height:24px}
.step-card h3{font-size:clamp(21px,1.9vw,24.5px);font-weight:var(--w-title);letter-spacing:-0.026em;line-height:1.1}
.step-card p{font-size:14px;line-height:1.6;letter-spacing:-0.014em;color:var(--fg-3)}
.step-len{font-size:var(--t-meta);font-weight:var(--w-title);letter-spacing:.11em;
  text-transform:uppercase;color:var(--fg-3)}
@media(hover:hover){.step-card:hover .step-ic{color:var(--fg)}}

@media(max-width:900px){.steps{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:520px){
  .steps{grid-template-columns:minmax(0,1fr)}
}

.sum-note{margin-top:22px;font-size:15px;line-height:1.6;color:var(--fg-3);max-width:52ch}
.sum-more{margin-top:30px}
.sum-more .btn svg{width:11px;height:11px;margin-left:10px}
@media(hover:hover){.sum-more .btn:hover{background:var(--fill);border-color:var(--fg);color:var(--on-fill)}}
@media(max-width:760px){
  .sum-list li{padding:20px 0}
  .sum-list li > div{gap:6px}

}

/* the way out to a client's own site, sitting under the row it belongs to. Qualified, because
   `.sum-list p` is a class plus a type and would otherwise keep its own 8px. */
.sum-list .work-link{margin-top:18px}

/* the marks of the clients so far. It is the hero band again, so it rides on .ticker and adds only
   what differs. Each mark carries its own trailing space instead of the row using `gap`: with `gap`
   there is one space fewer than there are marks, and half the track would stop being exactly the
   first set — which is what the -50% turn relies on. */
.logos{margin-top:56px;
  --fade:min(150px,14%);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 var(--fade),#000 calc(100% - var(--fade)),transparent);
  mask-image:linear-gradient(90deg,transparent,#000 var(--fade),#000 calc(100% - var(--fade)),transparent)}
.logos-track{align-items:center}
.motion .logos-track{animation-duration:58s}
.logos svg{display:block;flex:none;width:auto;margin-right:clamp(64px,9vw,130px);
  color:var(--fg-2);transition:color .45s var(--ease-out)}
.logo-mkpk{height:18px}
.logo-vayence{height:26px}
/* a square mark reads far smaller than a wordmark set to the same height — the wordmark is six
   times as wide — so the slab is given a third more height to sit level with it */
.logo-kh{height:32px}
@media(hover:hover){.logos:hover svg{color:var(--fg-2)}}
@media(max-width:620px){
  .logos{margin-top:38px}
  .logo-mkpk{height:15px}
  .logo-vayence{height:21px}
  .logo-kh{height:25px}
}

/* client works */
/* the note under the engagement list: the way through for work that is not listed yet */
/* One engagement to a row: the client, the state of it set against the client on the right, the
   brief under them both, and what the work covers as chips. Each row closes on a hairline. */
.works{list-style:none;margin-top:clamp(24px,2.6vw,32px)}
.work{padding:26px 0;border-bottom:var(--hair) solid var(--line)}
.work-head{display:flex;align-items:baseline;justify-content:space-between;gap:24px}
.work h3{font-size:clamp(21px,1.9vw,24.5px);font-weight:var(--w-title);letter-spacing:-0.026em;line-height:1.1}
.work-state{flex:none;font-size:var(--t-meta);font-weight:var(--w-title);letter-spacing:.11em;
  text-transform:uppercase;color:var(--fg-3);white-space:nowrap}
/* the film belongs to the entry it sits in: the row's own width, its own 2:1, and the card frame
   the portraits use. It holds its height from the start, so nothing below it jumps when it loads.
   The frame holds the 2:1 and the film fills it, rather than the film sizing the frame: a scaled
   video whose box works out to a fraction of a pixel otherwise leaves a seam along its foot, and a
   seam shows whatever is behind it. Both are set to the film's own paper, so there is nothing
   darker than the film anywhere under it, in either theme. */
.work-film{--film-paper:#f6f6f6;position:relative;aspect-ratio:2/1;margin-top:20px;
  border-radius:var(--r-card);overflow:hidden;background:var(--film-paper);
  box-shadow:inset 0 0 0 var(--hair) var(--line)}
.work-film video{position:absolute;left:-2px;top:-2px;display:block;
  width:calc(100% + 4px);height:calc(100% + 4px);object-fit:cover;background:var(--film-paper)}
.work > p{margin-top:12px;font-size:14px;line-height:1.6;letter-spacing:-0.014em;color:var(--fg-3);max-width:72ch}
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px}
.chips span{display:inline-flex;align-items:center;height:28px;padding:0 13px;border-radius:var(--r-cap);
  box-shadow:inset 0 0 0 var(--hair) var(--ink-border);font-size:11.5px;font-weight:var(--w-title);
  letter-spacing:-0.008em;color:var(--fg-3);white-space:nowrap}
@media(max-width:620px){.work-head{display:block}.work-state{display:block;margin-top:6px}}
.works-note{margin-top:48px;font-size:14px;color:var(--fg-3);max-width:60ch}
.works-note a{color:var(--fg);text-decoration:underline;text-underline-offset:3px}

/* short contact band at the foot of each page */
.cta-short .cta-grid{align-items:end}
.cta-short .cta-row{margin-top:0;justify-content:flex-end}

/* talent: the pool is still being built, so the page says so */
.status-line{display:inline-flex;align-items:center;gap:8px;margin-top:22px;font-size:13.5px;font-weight:var(--w-title);color:var(--on-slab-2)}
.status-dot{width:8px;height:8px;border-radius:50%;background:var(--fg);opacity:.9}
.motion .status-dot{animation:status-pulse 2.4s ease-in-out infinite}
@keyframes status-pulse{50%{opacity:.3}}
.status-line + h2{margin-top:14px}

/* a label that follows the mouse over something clickable: what clicking does */
.cursor-tip{position:fixed;left:0;top:0;z-index:100;pointer-events:none;will-change:transform}
.cursor-tip span{display:inline-flex;align-items:center;height:30px;padding:0 14px;border-radius:var(--r-cap);background:var(--fill);color:var(--on-fill);
  font-size:12.5px;font-weight:var(--w-title);letter-spacing:-0.004em;white-space:nowrap;box-shadow:0 6px 24px rgba(0,0,0,.28);
  opacity:0;transform:scale(.6);transform-origin:0 0;transition:opacity .18s ease,transform .25s var(--ease-out)}
.cursor-tip.on span{opacity:1;transform:none}

@media(max-width:1000px){
  .works{grid-template-columns:1fr}
  .cta-short .cta-row{justify-content:flex-start}
}
@media(max-width:900px){
  .nav-menu{display:inline-flex}
}
/* a small phone: the mark, the button and the menu have to share 320px, so the space comes out of the
   gaps and the button. The mark keeps its size: below about 130px its second line stops drawing. */
@media(max-width:380px){
  nav .wrap{gap:10px}
  .nav-actions{gap:6px}
  .nav-actions .btn{padding:0 12px;font-size:12.5px}
  .nav-home .wm-line{display:none}
}
@media(max-width:620px){
  .nav-menu{width:36px;height:36px}
  .nav-menu span{left:11px;right:11px}
  .nav-menu span:first-child{top:14px}
  .nav-menu span:last-child{top:20.5px}
  .nav-menu[aria-expanded="true"] span:first-child,.nav-menu[aria-expanded="true"] span:last-child{top:17.25px} /* a wide band is too thin on a phone */
}

/* admin mode (site-admin.js)
   Only ever on screen for an editor Google and ADMIN_EMAILS have both agreed on: the script puts
   .admin-editing on <html> and builds the bar. The bar is a tool rather than part of the page, so
   it is the dark slab in both themes, and the words on its pink stay #fff like every other. */
footer .fbottom span[role="button"]{cursor:pointer}
.admin-note{margin-top:14px;font-size:13px;line-height:1.5;color:var(--fg-3);max-width:34ch}

/* every line the editor may change, marked without moving anything: an outline takes no space */
.admin-editing [data-ed]{outline:var(--hair) dashed var(--ink-border);outline-offset:3px;border-radius:2px}
.admin-editing [data-ed]:focus{outline:2px solid var(--signal)}
.admin-editing [data-ed].is-changed{outline-style:solid;outline-color:var(--signal)}
.admin-editing [data-ed]:empty::before{content:"empty";font-style:italic;color:var(--fg-3)}
/* the bar is as tall as its own rows: on a phone they wrap, so site-admin.js measures it and the
   page keeps exactly that much room under the footer */
.admin-open body{padding-bottom:calc(var(--admin-h,96px) + 28px)}

.admin-bar{position:fixed;left:0;right:0;bottom:0;z-index:90;display:flex;align-items:center;
  flex-wrap:wrap;gap:10px 14px;padding:14px var(--pad);background:var(--slab);color:var(--on-slab);
  font-size:13px;letter-spacing:-0.014em;box-shadow:0 -1px 0 rgba(255,255,255,.14)}
.admin-mode{font-weight:var(--w-title);flex:none}
.admin-who{flex:none;min-width:0;max-width:40%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--on-slab-2)}
.admin-status{flex:1 1 200px;min-width:0;color:var(--on-slab-2)}
.admin-tools{flex:none;display:flex;align-items:center;flex-wrap:wrap;gap:10px}
.admin-status.is-trouble{color:#fff}
.admin-status.is-trouble::before{content:"";display:inline-block;width:7px;height:7px;margin-right:8px;
  border-radius:var(--r-cap);background:var(--signal);vertical-align:1px}
.admin-btn{flex:none;height:34px;padding:0 15px;border-radius:var(--r-cap);border:var(--hair) solid rgba(255,255,255,.3);
  background:none;color:var(--on-slab);font:inherit;font-weight:var(--w-title);letter-spacing:-0.014em;cursor:pointer;
  transition:border-color .25s var(--ease-out),opacity .25s ease}
.admin-btn:disabled{opacity:.42;cursor:default}
.admin-btn:focus-visible{outline:2px solid #fff;outline-offset:2px}
.admin-btn-go{background:var(--signal);border-color:var(--signal);color:#fff}
@media(hover:hover){.admin-btn:not(:disabled):hover{border-color:#fff}}
