/* FrameMatic, final identity: "Screening Room".
   The room is dark and the type holds still; the light moves. Footage, photographs and the builds are the only light.
   Signature: wide Archivo title cards, light engraved numerals, and the frame (the letterbox that opens, from the
   M-in-a-frame of the mark). Four solid colours, one family, square edges, no borders, no gradients, no tints,
   no translucent layers. Motion: scroll-driven CSS on the root timeline (compositor) behind @supports, one-shot
   cues started by observers, reel.js for video. Nothing runs at rest. Full rules: IDENTITY-SPEC.md. */

@font-face {
  font-family: "Archivo FM"; src: url(fonts/archivo-fm.woff2) format("woff2");
  font-weight: 300 800; font-stretch: 100% 125%; font-display: swap;
}
@font-face { font-family: "Archivo Fallback"; src: local("Arial"), local("ArialMT"); size-adjust: 104%; ascent-override: 86%; descent-override: 21%; line-gap-override: 0%; }

:root {
  /* the palette: the whole of it */
  --night: #0b0c0e;      /* the room: ground, masthead, footer, letterbox bars */
  --screen: #f4f2ee;     /* the light: type on Night, buttons, the house-lights ground, menus */
  --ash: #a2a3a7;        /* secondary type on Night (7.8:1) */
  --graphite: #55565b;   /* secondary type on Screen (6.6:1) */

  --f: "Archivo FM", "Archivo Fallback", system-ui, sans-serif;
  --wide: 122%;          /* title cards */
  --wide-2: 116%;        /* credits, the end card on phones */
  --gut: clamp(20px, 4.4vw, 72px);
  --gap: clamp(16px, 2.2vw, 36px);
  --max: 1760px;
  --hh: 72px;
  --s1: clamp(.75rem, 1.2vw, 1.25rem);
  --s2: clamp(1.25rem, 2.6vw, 2.5rem);
  --s3: clamp(2.5rem, 5.5vw, 5.5rem);
  --s4: clamp(4.5rem, 8.4vw, 8.5rem);

  --t-display: min(clamp(2.3rem, .9rem + 4.9vw, 6.4rem), 10.6vw);
  --t-h2: min(clamp(1.9rem, .95rem + 3.05vw, 4.4rem), 9.5vw);
  --t-h3: clamp(1.45rem, 1.05rem + 1.45vw, 2.45rem);
  --t-fig: clamp(2.15rem, 1rem + 4.1vw, 5.6rem);
  --t-lead: clamp(1.125rem, 1rem + .42vw, 1.4rem);
  --t-body: clamp(1.0625rem, 1rem + .18vw, 1.1875rem);
  --t-small: .9375rem;

  /* motion (ALIVE-SPEC 6b, the founder's 20 rules): every duration and curve on the site comes from here */
  --ease-out: cubic-bezier(.16, 1, .3, 1);       /* entrances, settles, reveals, presses (no overshoot) */
  --ease-in-out: cubic-bezier(.65, 0, .35, 1);   /* on-screen moves from one place to another, crossfades */
  --ease-rise: cubic-bezier(.35, .2, .25, 1);     /* the rise of an object travelling on an arc (its y; x is in-out) */
  --dur-in: 250ms;        /* entrances */
  --dur-out: 200ms;       /* exits: 20% shorter */
  --dur-menu: 200ms;      /* menus open */
  --dur-menu-out: 160ms;  /* menus close: 20% shorter */
  --dur-press: 100ms;     /* press feedback */
  --dur-cut: 320ms;       /* crossfades between shots, screens and panels */
  --dur-move: 300ms;      /* a thing moving across a screen (tab marker, shared element) */
  --dur-travel: 640ms;    /* an object travelling between two screens, on an arc */
  --dur-reveal: 850ms;    /* a frame's mask opening */
  --dur-pulse: 420ms;     /* the one success pulse */
  --stagger: 30ms;        /* between list rows; a headline, its line and its button settle two steps apart */
  --press: .97;           /* buttons and tappable cards on press */
  --pop: .95;             /* menus start here, at their trigger */
  color-scheme: dark;
}
@media (prefers-reduced-motion: reduce) {
  :root { --dur-in: 0ms; --dur-out: 0ms; --dur-menu: 0ms; --dur-menu-out: 0ms; --dur-press: 0ms; --dur-cut: 0ms; --dur-move: 0ms; --dur-travel: 0ms; --dur-reveal: 0ms; --dur-pulse: 0ms; --stagger: 0ms; --press: 1; --pop: 1; }
}
@media (max-width: 47.99em) { :root { --hh: 60px; } }
/* the narrowest phones: title cards a little less wide, so a long word never pushes the page sideways */
@media (max-width: 22.49em) { :root { --wide: 110%; --wide-2: 106%; } }

*, *::before, *::after { box-sizing: border-box; }
html { background: var(--night); color: var(--screen); -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scroll-padding-top: calc(var(--hh) + 16px); }
body { margin: 0; font-family: var(--f); font-size: var(--t-body); line-height: 1.6; font-stretch: 100%; overflow-x: clip; -webkit-font-smoothing: antialiased; }
img, picture, video, svg { display: block; max-width: 100%; }
img { height: auto; }
h1, h2, h3, h4, p, ul, ol, dl, dd, figure, blockquote { margin: 0; }
/* a word longer than its column (large type, a reader's 200% text, a phone at 320) breaks rather than push the page
   sideways; at ordinary sizes every word fits, so nothing breaks */
h1, h2, h3, h4, summary, legend, .statement__t, p, li, dd, dt { overflow-wrap: anywhere; }
ul, ol { padding: 0; list-style: none; }
a { color: inherit; }
button { font: inherit; color: inherit; }
strong { font-weight: 650; }
:focus-visible { outline: 2px solid var(--screen); outline-offset: 3px; }
.house :focus-visible, .drop :focus-visible { outline-color: var(--night); }
::selection { background: var(--screen); color: var(--night); }

.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gut); }
.g12 { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); }

/* ---------- type ---------- */
.tc { font-stretch: var(--wide); font-weight: 760; letter-spacing: 0; line-height: 1; text-wrap: balance; overflow-wrap: anywhere; }
/* on the narrowest phones a long word ("engagements") still fits its line whole: the title cards narrow one step */
@media (max-width: 22.49em) { .tc { font-stretch: 114%; } }
.h2 { font-size: var(--t-h2); line-height: 1.02; }
.h3 { font-size: var(--t-h3); font-weight: 640; line-height: 1.08; text-wrap: balance; overflow-wrap: anywhere; }
.lead { font-size: var(--t-lead); line-height: 1.45; color: var(--ash); text-wrap: pretty; }
.house .lead, .drop .lead { color: var(--graphite); }
/* numbers speak one voice: light, a little wide, tabular */
.fig, .clock { font-weight: 300; font-stretch: 110%; font-variant-numeric: tabular-nums lining-nums; letter-spacing: 0; line-height: .95; }
/* a figure never outgrows its column: "~20 hrs/month" is 7.04em wide at this setting, so 14cqi fits any column */
.fig { font-size: min(var(--t-fig), 14cqi); white-space: nowrap; }
.result, .case__text { container-type: inline-size; }

.skip { position: absolute; left: 12px; top: -80px; z-index: 100; background: var(--screen); color: var(--night); padding: 10px 16px; font-weight: 600; }
.skip:focus { top: 12px; }

/* ---------- buttons and links ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 14px; flex: none; align-self: flex-start;
  background: var(--screen); color: var(--night); text-decoration: none; border: 0; cursor: pointer;
  font-weight: 650; font-size: 1.0625rem; line-height: 1; padding: 19px 24px 19px 26px; border-radius: 2px;
}
.btn--l { padding: 23px 30px 23px 32px; font-size: 1.1875rem; }
.house .btn, .drop .btn { background: var(--night); color: var(--screen); }
.arr { width: 1.05em; height: 1.05em; flex: none; transition: transform var(--dur-in) var(--ease-out); }
.btn:hover .arr, .link:hover .arr, .mast__cta:hover .arr, .rel__a:hover .arr, .slide a:hover .arr { transform: translateX(4px); }
.link { display: inline; font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .32em; }
.link .arr { display: inline-block; vertical-align: -.16em; margin-left: .45em; }
/* the arrow held to a link's last word (lib.mjs withArrow): the span stands in for the space before it */
.nw { white-space: nowrap; padding-left: .25em; }
.link:hover { text-decoration-thickness: 2px; }
@media (max-width: 47.99em) { .link { padding-block: 12px; margin-block: -12px; } }
.sq { width: 52px; height: 52px; display: grid; place-items: center; background: var(--screen); color: var(--night); border: 0; border-radius: 2px; cursor: pointer; }
.sq svg { width: 20px; height: 20px; }
.sq:disabled { background: var(--night); color: var(--ash); cursor: default; }
.textbtn { background: none; border: 0; padding: 8px 0; font-weight: 600; text-decoration: underline; text-underline-offset: .32em; text-decoration-thickness: 1px; cursor: pointer; }
.textbtn:hover { text-decoration-thickness: 2px; }

/* ---------- motion primitives ---------- */
/* rule 4: buttons and tappable cards give under the finger */
.btn, .mast__cta, .sq, .textbtn, .slide a, .cut a, .rel__a, .dir__item a, .jobs a, .mast__menu { transition: transform var(--dur-press) var(--ease-out); }
.btn:active, .mast__cta:active, .sq:active:not(:disabled), .textbtn:active, .slide a:active, .cut a:active, .rel__a:active, .dir__item a:active, .jobs a:active, .mast__menu:active { transform: scale(var(--press)); }
/* rules 3 and 6: rows settle 30 ms apart; a headline, its line and its button settle in that order. fm.js gives each
   one its --i; only content below the first screen ever waits, and only until it arrives */
.js [data-rise] .rise { transition: opacity var(--dur-in) var(--ease-out), transform var(--dur-in) var(--ease-out); transition-delay: calc(min(var(--i, 0), 10) * var(--stagger)); }
.js [data-rise]:not(.is-in) .rise { opacity: 0; transform: translateY(14px); }
@media (prefers-reduced-motion: reduce) { .js [data-rise]:not(.is-in) .rise { opacity: 1; transform: none; } }
/* the title card settles on load by transform alone: it is never hidden, not for a frame */
@media (prefers-reduced-motion: no-preference) {
  .title__h, .title__side > * { animation: settle var(--dur-in) var(--ease-out) both; }
  .title__side > :nth-child(1) { animation-delay: calc(2 * var(--stagger)); }
  .title__side > :nth-child(2) { animation-delay: calc(4 * var(--stagger)); }
  .title__side > :nth-child(3) { animation-delay: calc(6 * var(--stagger)); }
}
@keyframes settle { from { transform: translateY(12px); } }
/* rule 8: one pulse confirms success, once */
.is-pulse { animation: pulse var(--dur-pulse) var(--ease-out) 1; }
@keyframes pulse { 40% { transform: scale(1.04); } }
/* rule 18: icon and label swaps crossfade with a small blur and scale (small elements only) */
.swap { display: inline-grid; }
.swap > * { grid-area: 1 / 1; transition: opacity var(--dur-in) var(--ease-out), filter var(--dur-in) var(--ease-out), transform var(--dur-in) var(--ease-out); }
.swap > :last-child, [aria-expanded="true"] > .swap > :first-child, .is-swapped > .swap > :first-child { opacity: 0; filter: blur(3px); transform: scale(.85); }
[aria-expanded="true"] > .swap > :last-child, .is-swapped > .swap > :last-child { opacity: 1; filter: none; transform: none; }

/* ---------- masthead: the top bar of the frame ----------
   Logo on the grid, the menus, and one lit block flush into the right edge: the only light in the bar is the call
   to action, on every screen size. */
.mast { position: sticky; top: 0; z-index: 60; background: var(--night); }
.mast__bar { min-height: var(--hh); display: flex; align-items: center; padding-left: max(var(--gut), calc((100vw - var(--max)) / 2 + var(--gut))); }
.mast__logo { flex: none; align-self: stretch; display: flex; align-items: center; }
.mast__logo img { height: 25px; width: auto; }
.mast__nav { margin-left: auto; margin-right: clamp(28px, 3.2vw, 56px); }
.mast__nav > ul { display: flex; align-items: center; gap: clamp(22px, 2.5vw, 42px); }
.mast__nav > ul > li > a, .mast__btn { display: inline-flex; align-items: center; gap: 8px; padding: 10px 0; background: none; border: 0; font-weight: 500; font-size: 1rem; line-height: 1; text-decoration: none; cursor: pointer; white-space: nowrap; }
.mast__nav > ul > li > a:hover, .mast__nav > ul > li > a[aria-current], .mast__btn:hover, .mast__btn[data-current], .mast__btn[aria-expanded="true"] { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .45em; }
.chev { width: 11px; height: 8px; flex: none; transition: transform var(--dur-menu-out) var(--ease-out); }
.mast__btn[aria-expanded="true"] .chev, .pmenu__sec[open] > summary .chev { transform: rotate(180deg); transition-duration: var(--dur-menu); }
.mast__menu { display: none; align-self: stretch; margin-left: auto; padding: 0 clamp(14px, 3vw, 22px); background: none; border: 0; font-weight: 600; font-size: 1rem; cursor: pointer; }
.mast__cta {
  align-self: stretch; flex: none; display: flex; align-items: center; gap: 12px; margin-block: 6px;
  padding-inline: clamp(22px, 2.4vw, 38px) max(clamp(22px, 2.4vw, 38px), calc((100vw - var(--max)) / 2 + var(--gut)));
  background: var(--screen); color: var(--night); text-decoration: none; font-weight: 650; font-size: 1.0625rem; white-space: nowrap;
}
.mast__cta:focus-visible { outline-color: var(--night); outline-offset: -5px; }
.mast__menu:focus-visible { outline-offset: -5px; }
@media (max-width: 63.99em) {
  .mast__nav { display: none; }
  .js .mast__menu { display: block; }
}
@media (max-width: 47.99em) {
  .mast__logo img { height: 20px; }
  .mast__cta { font-size: .9375rem; gap: 8px; padding-inline: 16px var(--gut); }
  .mast__cta .arr { display: none; }
}
/* a reader's large text on a narrow phone: the lit block may take two lines, and nothing pushes the page sideways */
@media (max-width: 47.99em) {
  .mast__cta { flex: 0 1 auto; min-width: 0; white-space: nowrap; line-height: 1.05; font-size: min(.9375rem, 4.2vw); margin-block: 5px; }
  .mast__menu { flex: none; font-size: min(1rem, 4.4vw); }
  .foot a[href^="mailto:"], .pmenu__mail a { overflow-wrap: anywhere; }
}
@media (max-width: 22.49em) {
  .mast__logo img { height: 17px; }
  .mast__menu { padding-inline: 12px; font-size: min(.9375rem, 4.4vw); }
  .mast__cta { padding-inline: 13px 14px; font-size: min(.875rem, 4.2vw); }
}

/* the menus: house lights for navigation (Screen panels under the bar) */
.drop { position: absolute; left: 0; right: 0; top: 100%; background: var(--screen); color: var(--night); padding-block: var(--s2) var(--s3); max-height: calc(100svh - var(--hh)); overflow-y: auto; }
.drop[hidden], .pmenu[hidden] { display: none; }
/* rules 2, 10, 11, 12, 15: menus grow from their trigger (scale .95, opacity 0) in 200 ms and go back to it in 160 */
.drop, .pmenu {
  transform-origin: var(--ox, 50%) 0; opacity: 0; transform: scale(var(--pop));
  transition: opacity var(--dur-menu-out) var(--ease-out), transform var(--dur-menu-out) var(--ease-out);
}
.drop.is-open, .pmenu.is-open { opacity: 1; transform: none; transition-duration: var(--dur-menu); }
.drop .rise, .pmenu .rise { transition: opacity var(--dur-in) var(--ease-out), transform var(--dur-in) var(--ease-out); transition-delay: calc(min(var(--i, 0), 10) * var(--stagger)); }
.drop:not(.is-open) .rise, .pmenu:not(.is-open) .rise { opacity: 0; transform: translateY(8px); transition-delay: 0ms; transition-duration: var(--dur-menu-out); }
.drop__grid { display: grid; column-gap: var(--gap); row-gap: var(--s2); }
.drop__grid--svc { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.drop__head { display: block; font-stretch: var(--wide); font-weight: 720; font-size: 1.1875rem; line-height: 1.15; text-decoration: none; margin-bottom: 16px; }
.drop__col li + li { margin-top: 6px; }
.drop__col li a, .drop__builds a { text-decoration: none; color: var(--graphite); }
.drop a:hover { color: var(--night); text-decoration: underline; text-underline-offset: .3em; text-decoration-thickness: 1px; }
.drop__grid--demos { grid-template-columns: repeat(12, minmax(0, 1fr)); align-items: start; }
.drop__builds { grid-column: 1 / span 8; columns: 3; column-gap: var(--gap); }
.drop__builds li { break-inside: avoid; padding-bottom: 12px; }
.drop__builds a { display: block; color: var(--night); font-weight: 600; line-height: 1.3; }
.drop__ind { display: block; font-weight: 400; color: var(--graphite); font-size: .9375rem; }
.drop__preview { grid-column: 9 / -1; }
.drop__preview .xf { aspect-ratio: 1080 / 620; background: var(--night); }
.drop__preview .xf img { object-position: 50% 0; }
/* rule 16: an image swap overlaps: the new picture fades in over the old, then the old one goes */
.xf { position: relative; overflow: hidden; }
.xf img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.xf img.is-in { animation: xf-in var(--dur-cut) var(--ease-in-out) both; }
@keyframes xf-in { from { opacity: 0; } }
.drop__preview figcaption { margin-top: 14px; color: var(--graphite); font-size: .9375rem; line-height: 1.5; }
.drop__foot { display: flex; gap: 40px; margin-top: var(--s2); }
@media (max-width: 79.99em) { .drop__grid--svc { grid-template-columns: repeat(3, minmax(0, 1fr)); } .drop__builds { columns: 2; } }

/* the phone menu */
.pmenu { position: fixed; inset: var(--hh) 0 0 0; background: var(--night); overflow-y: auto; z-index: 59; }
.pmenu__in { padding-block: 24px 48px; display: flex; flex-direction: column; }
.pmenu__sec > summary, .pmenu__a { display: flex; align-items: center; justify-content: space-between; list-style: none; cursor: pointer; text-decoration: none; font-stretch: var(--wide); font-weight: 720; font-size: 2rem; line-height: 1.15; padding-block: 10px; }
.pmenu__sec > summary::-webkit-details-marker { display: none; }
.pmenu__sec > summary .chev { width: 18px; height: 12px; }
.pmenu__sec ul { padding: 4px 0 18px; }
.pmenu__sec li a { display: block; padding: 7px 0; color: var(--ash); text-decoration: none; font-size: 1.125rem; }
.pmenu__mail { margin-top: 36px; color: var(--ash); }

/* ---------- the title card and the opening ---------- */
.title__card { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); align-items: end; padding-top: clamp(28px, 6.5vh, 80px); }
.title__h { grid-column: 1 / span 9; font-size: var(--t-display); line-height: .98; }
.title__side { grid-column: 10 / -1; display: flex; flex-direction: column; gap: 26px; padding-bottom: .3em; }
.title__side .lead { color: var(--ash); }
.title--inner .title__h { grid-column: 1 / span 8; }
.title--inner .title__side { grid-column: 9 / -1; }
.open { position: relative; overflow: hidden; margin-top: clamp(28px, 5.5vh, 64px); aspect-ratio: 4 / 5; background: var(--night); }
.frame__reel, .open > .reel, .open > picture { position: absolute; inset: 0; }
.open > picture img { width: 100%; height: 100%; object-fit: cover; object-position: var(--pos, 50% 50%); }
.reel__poster img, .reel__clip { position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover; }
.reel__poster img { object-position: var(--focus, 50% 50%); }
/* every library photo carries its crop: --pd (desktop) and, where the phone frame needs another, --pm */
img { --pos: var(--pd, 50% 50%); }
@media (max-width: 47.99em) {
  img { --pos: var(--pm, var(--pd, 50% 50%)); }
  .reel__poster img { object-position: var(--focus-m, var(--focus, 50% 50%)); }
}
.reel__clip { z-index: 1; opacity: 0; pointer-events: none; }
.reel__clip.is-on { opacity: 1; }
.reel__clip.is-in { z-index: 2; transition: opacity var(--reel-fade, 1.2s) var(--ease-in-out); } /* rule 16: the outgoing clip stays lit underneath */
.reel__toggle { position: absolute; z-index: 6; top: 14px; right: 14px; width: 44px; height: 44px; display: grid; place-items: center; transition: transform var(--dur-press) var(--ease-out); background: var(--night); color: var(--screen); border: 0; border-radius: 2px; cursor: pointer; }
.reel__toggle[hidden] { display: none; }
.reel__toggle:active { transform: scale(var(--press)); }
.reel__icon { width: 15px; height: 15px; grid-area: 1 / 1; transition: opacity var(--dur-in) var(--ease-out), filter var(--dur-in) var(--ease-out), transform var(--dur-in) var(--ease-out); }
.reel__icon--play, .is-reel-paused > .reel__toggle .reel__icon--pause { opacity: 0; filter: blur(3px); transform: scale(.85); }
.is-reel-paused > .reel__toggle .reel__icon--play { opacity: 1; filter: none; transform: none; }
.open__post, .open__bar { display: none; }
@media (min-width: 48em) { .open { aspect-ratio: 16 / 9; } }
@media (min-width: 64em) {
  .open { aspect-ratio: auto; height: calc(100svh - var(--hh)); min-height: 540px; }
  .open > .reel__toggle { right: calc(max(0px, (100% - var(--max)) / 2) + var(--gut) + 14px); }
}
/* Phones and tablets: the picture comes straight after the title, the lead and the button after the picture, so
   the first screen is a title card and moving film. */
@media (max-width: 63.99em) {
  .title { display: flex; flex-direction: column; }
  .title__card { display: contents; }
  .title__h, .title__side { padding-inline: var(--gut); }
  .title__h { padding-top: clamp(22px, 4vh, 44px); }
  .title__side { order: 3; padding-top: 26px; padding-bottom: 0; gap: 22px; }
  .open { order: 2; margin-top: 24px; }
}
/* The opening move: the posts part and the bar drops as you scroll; the picture pulls back from 112%. Root scroll
   timeline (composited). fm.js writes --open-end (where the frame meets the masthead) and attaches the move only
   while the frame is on screen, so it costs nothing further down and replays when you come back up. */
@supports (animation-timeline: scroll()) and (animation-range: 0px 100px) {
  @media (min-width: 64em) and (prefers-reduced-motion: no-preference) {
    .js .open__post, .js .open__bar { display: block; position: absolute; z-index: 4; background: var(--night); }
    .open__post { top: 0; bottom: 0; width: calc(max(0px, (100% - var(--max)) / 2) + var(--gut) + 1px); }
    .open__post--l { left: 0; } .open__post--r { right: 0; }
    .open__bar { left: 0; right: 0; bottom: 0; height: max(0px, calc(100% - (min(100vw, var(--max)) - 2 * var(--gut)) / 2.39)); }
    .open__post, .open__bar, .open > .reel, .open > picture { animation-timing-function: linear; animation-fill-mode: both; animation-timeline: scroll(root); animation-range: 0px var(--open-end, 60vh); }
    .open.sl-on .open__post--l { animation-name: post-l; } .open.sl-on .open__post--r { animation-name: post-r; } .open.sl-on .open__bar { animation-name: bar-b; }
    .open.sl-on > .reel, .open.sl-on > picture { animation-name: pull-back; }
    .js .open.is-past .open__post, .js .open.is-past .open__bar { display: none; }
  }
}
@keyframes post-l { to { transform: translateX(-100%); } }
@keyframes post-r { to { transform: translateX(100%); } }
@keyframes bar-b { to { transform: translateY(100%); } }
@keyframes pull-back { from { transform: scale(1.12); } to { transform: none; } }

/* ---------- a frame that opens as it arrives ----------
   Two bars in the ground colour hold the picture to a letterbox slit; fm.js parts them once, when the frame is a
   little way into the screen, and the picture settles from 106%. Solid bars, never a translucent layer; the move
   always finishes, so nothing rests half open. Screens (the builds' software) open the same way, like a monitor
   coming on, without the settle. */
.gate { position: relative; overflow: hidden; }
@media (prefers-reduced-motion: no-preference) {
  .js .gate > * { clip-path: inset(43% 0 43% 0); transition: clip-path var(--dur-reveal) var(--ease-out); }
  .js .gate.is-open > * { clip-path: inset(0); }
  .js .gate > picture img, .js .gate > .reel { transform: scale(1.06); transition: transform calc(var(--dur-reveal) * 1.6) var(--ease-out); }
  .js .gate.is-open > picture img, .js .gate.is-open > .reel { transform: none; }
  /* a long page wipes down from its top; a screen opens like a monitor coming on (no settle: UI stays sharp) */
  .js .gate--down > * { clip-path: inset(0 0 100% 0); }
  .js .gate.is-opened > * { clip-path: none; }
}
.gate--screen { overflow: visible; }
/* a capture of a brand site is a screen too: it opens without the settle, so its type stays sharp */
.js .gate--screen > picture img, .js .gate--screen > img { transform: none; transition: none; }

/* ---------- section heads: four compositions, so no two neighbours open the same way ----------
   stair: a wide title, the lead stepped down and to the right
   column: the title at the head of a list column, level with the picture beside it (the cut)
   feature: the title in the space a double feature leaves (results)
   hold: the title holds (sticky) while the reading passes beside it (house lights) */
.stair { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); margin-bottom: var(--s3); }
.stair > .h2 { grid-column: 1 / span 10; }
.stair > .lead { grid-column: 7 / -1; margin-top: var(--s1); max-width: 40ch; }
/* the stair never leaves a band of black under it: the lead steps down one small step, and where scenes follow
   ("What happens underneath") the first scene's own top space is the only gap */
.under .stair { margin-bottom: 0; }
/* "What happens underneath": the one-line lead sits level with the title's last line, so no half of it waits empty */
@media (min-width: 64em) {
  .under .stair > .h2 { grid-column: 1 / span 7; }
  .under .stair > .lead { grid-column: 8 / -1; grid-row: 1; align-self: end; margin-top: 0; }
}
@media (max-width: 63.99em) { .stair > .h2, .stair > .lead { grid-column: 1 / -1; } .stair > .lead { margin-top: 18px; } }

/* ---------- the cut ---------- */
.cuts { padding-block: var(--s4) var(--s3); }
.cuts__grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); }
.cuts__head { grid-column: 1 / span 6; grid-row: 1; padding-bottom: var(--s2); }
.cuts__head .lead { margin-top: 20px; max-width: 34ch; }
.cuts__list { grid-column: 1 / span 6; grid-row: 2; }
.cut a { display: block; text-decoration: none; padding-block: clamp(16px, 3.2vh, 34px); }
.cut__t { font-size: var(--t-h3); font-weight: 640; line-height: 1.06; }
.cut__t .arr { display: inline-block; vertical-align: -.02em; margin-left: .18em; width: .6em; height: .6em; opacity: 0; transform: translateX(-6px); will-change: transform, opacity; transition: opacity var(--dur-out) var(--ease-out), transform var(--dur-out) var(--ease-out); }
.cut a:focus-visible .cut__t .arr, .cut.is-on .cut__t .arr { opacity: 1; transform: none; transition-duration: var(--dur-in); }
.cut p { margin-top: .45em; color: var(--ash); max-width: 38ch; }
.js .cut:not(.is-on) .cut__t { color: var(--ash); }
.cuts__monitor { grid-column: 8 / -1; grid-row: 1 / span 2; position: sticky; top: calc(var(--hh) + 5vh); align-self: start; height: min(76vh, 800px); overflow: hidden; background: var(--night); }
/* rule 16: the new shot dissolves in over the old one, which stays lit underneath until it is covered */
.cuts__shot { position: absolute; inset: 0; opacity: 0; z-index: 1; transition: opacity 0s linear var(--dur-cut); }
.cuts__shot.is-on { opacity: 1; z-index: 2; transition: opacity var(--dur-cut) var(--ease-in-out); }
.cuts.is-scrubbing .cuts__shot, .cuts.is-scrubbing .cuts__shot.is-on { transition: none; }
.cuts__shot img { width: 100%; height: 100%; object-fit: cover; object-position: var(--pos, 50% 50%); }
.no-js .cuts__monitor { display: none; }
@media (max-width: 63.99em) {
  .cuts__head, .cuts__list, .cuts__monitor { grid-column: 1 / -1; }
  .cuts__head { grid-row: 1; }
  .cuts__monitor { grid-row: 2; top: var(--hh); z-index: 3; height: auto; aspect-ratio: 16 / 9; margin-inline: calc(-1 * var(--gut)); }
  /* the pinned monitor never covers the row it is showing: the list starts clear of it, and fm.js puts the reading
     line just under the monitor, so the active row is the one right below the picture */
  .cuts__list { grid-row: 3; padding-top: 18px; margin-bottom: calc(-1 * var(--cut-tail, 0px)); }
  .cuts { padding-bottom: calc(var(--s3) + var(--cut-tail, 0px)); }
  .cut a { padding-block: 20px; scroll-margin-top: calc(var(--hh) + 56.25vw + 18px); }
}

/* ---------- the businesses we build for: the list held beside the footage ----------
   The industries reel plays at full brightness with nothing on it (no words on footage, no grade, no scrim); the
   list sits beside it in row type. Desktop: the film bleeds off the left edge on seven columns, the words hold the
   right five. Phones: the film first, the words under it. */
.biz { padding-block: var(--s4) 0; }
.biz__grid { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); column-gap: var(--gap); align-items: stretch; }
.biz__film { position: relative; overflow: hidden; background: var(--night); min-height: min(calc(100svh - var(--hh)), 960px); }
.biz__film > .reel__toggle { top: auto; bottom: 16px; right: 16px; }
.biz__text { padding-block: var(--s2); padding-right: max(var(--gut), calc((100vw - var(--max)) / 2 + var(--gut))); align-self: center; }
.biz__list { margin-top: var(--s2); font-size: var(--t-h3); font-weight: 640; line-height: 1.12; }
.biz__list li + li { margin-top: .22em; }
.biz__text .lead { margin-block: var(--s2) 22px; max-width: 36ch; }
@media (max-width: 63.99em) {
  .biz__grid { grid-template-columns: minmax(0, 1fr); }
  .biz__film { min-height: 0; aspect-ratio: 4 / 3; }
  .biz__text { padding: var(--s3) var(--gut) 0; }
}

/* ---------- the builds (home): one working, then all 19 as their own sites ---------- */
.builds { padding-block: var(--s4) 0; }
.builds > .stair { margin-bottom: var(--s3); }
/* one build working on the page: the clock and its words on the left, the phone beside the desk on the right */
.live { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); row-gap: var(--s2); align-items: center; margin-bottom: var(--s4); }
.live__text { grid-column: 1 / span 4; container-type: inline-size; }
.live__h { font-size: var(--t-h3); font-weight: 640; line-height: 1.08; text-wrap: balance; }
.live__copy { display: flex; flex-direction: column; align-items: flex-start; }
.live__copy > p { margin-top: 16px; color: var(--ash); max-width: 38ch; }
.live__copy .live__verdict { color: var(--screen); }
.live__copy .textbtn { margin-top: 14px; }
.live__copy .link { margin-top: 10px; }
.live__screens { grid-column: 5 / -1; display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 8fr); gap: var(--gap); align-items: center; }
@media (max-width: 79.99em) {
  .live__text { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); align-items: end; }
  .live__text .clock, .live__h { grid-column: 1 / span 6; }
  .live__copy { grid-column: 8 / -1; grid-row: 1 / span 2; }
  .live__copy > p:first-child { margin-top: 0; }
  .live__screens { grid-column: 1 / -1; }
}
@media (max-width: 63.99em) {
  .live__text { display: block; }
  .live__copy > p:first-child { margin-top: 16px; }
  .live__screens { grid-template-columns: minmax(0, 1fr); max-width: 560px; }
  .live__phone { max-width: 400px; }
}

/* ---------- the screening strip ----------
   Starts on the grid and runs off the right edge (no empty half beside the first screen); each screen is a rebuilt
   brand site's own first screen, and on phones its phone screen. */
.strip { overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x mandatory; scroll-padding-inline: var(--edge); scrollbar-width: none; outline-offset: -2px; --edge: max(var(--gut), calc((100vw - var(--max)) / 2 + var(--gut))); --slide-w: min(40vw, 760px); }
.strip::-webkit-scrollbar { display: none; }
.strip__track { display: flex; gap: var(--gap); width: max-content; padding-inline: var(--edge); }
.slide { flex: 0 0 var(--slide-w); scroll-snap-align: start; }
.slide a { display: block; text-decoration: none; }
.slide__pic { display: block; aspect-ratio: 1080 / 620; overflow: hidden; background: var(--night); }
.slide__pic img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 0; }
@media (max-width: 47.99em) { .strip { --slide-w: 64vw; } .slide__pic { aspect-ratio: 346 / 600; } }
.slide__cap { display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: baseline; margin-top: 18px; }
.slide__name { font-size: clamp(1.15rem, 1rem + .5vw, 1.5rem); font-weight: 650; }
.slide__kind { color: var(--ash); }
.slide__line { display: block; margin-top: 8px; color: var(--ash); max-width: 52ch; }
.slide a:hover .slide__name { text-decoration: underline; text-underline-offset: .3em; text-decoration-thickness: 1px; }
.slide__you { display: flex; flex-direction: column; justify-content: flex-end; gap: 18px; padding: clamp(22px, 4vw, 56px); background: var(--screen); color: var(--night); }
.slide__you-t { display: flex; align-items: center; gap: 16px; font-stretch: var(--wide); font-weight: 760; font-size: var(--t-h2); line-height: 1; }
.slide__you-t .arr { width: .7em; height: .7em; }
.slide__you-b { color: var(--graphite); max-width: 30ch; font-size: var(--t-lead); line-height: 1.4; }
.strip__ctl { display: flex; align-items: center; justify-content: space-between; gap: 24px; margin-bottom: var(--s2); }
.strip__btns { display: flex; gap: 10px; }
.no-js .strip__btns { display: none; }
@media (max-width: 47.99em) { .sq { width: 48px; height: 48px; } }

/* ---------- results: a double feature, full bleed ----------
   Two verified figures as two photographs side by side, edge to edge, under one head; each figure in light
   numerals under its picture. Gauntlet round 2: the head is a title card (title left, line bottom right); the pictures are one height (3:2), so both figures sit on one
   baseline, and the telecom desk shows whole (at 4:5 it ran 933 px tall, two thirds of it a blank sheet).
   "All case studies" closes the second column. */
.results { padding-block: var(--s4) 0; }
.results__head { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); margin-bottom: var(--s3); }
.results__head > .h2 { grid-column: 1 / span 7; }
.results__head > .lead { grid-column: 9 / -1; align-self: end; max-width: 36ch; }
@media (max-width: 63.99em) { .results__head > .h2, .results__head > .lead { grid-column: 1 / -1; } .results__head > .lead { margin-top: 18px; } }
.results__pair { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--gap); align-items: start; }
.results__pair { --edge-l: max(var(--gut), calc((100vw - var(--max)) / 2 + var(--gut))); --edge-r: var(--edge-l); }
.result--a { grid-column: 1; grid-row: 1; }
.result--b { grid-column: 2; grid-row: 1; }
.results__all { grid-column: 2; grid-row: 2; padding: 0 var(--edge-r) 0 0; }
.result { container-type: inline-size; }
.result__shot img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; object-position: var(--pos, 50% 50%); }
.result__body { padding-top: var(--s2); }
.result--a .result__body { padding-left: var(--edge-l); }
.result--b .result__body { padding-right: var(--edge-r); }
.result .fig { font-size: min(var(--t-fig), 13cqi); }
.result__what { color: var(--ash); margin-block: 16px 22px; max-width: 30ch; font-size: var(--t-lead); line-height: 1.4; }
@media (max-width: 47.99em) {
  .results__pair { grid-template-columns: minmax(0, 1fr); }
  .result--a { grid-column: 1; grid-row: 1; }
  .result--b { grid-column: 1; grid-row: 2; margin-top: var(--s3); }
  .results__all { grid-column: 1; grid-row: 3; padding-inline: var(--gut); }
  .result__shot img { aspect-ratio: 5 / 4; }
  .result--a .result__body, .result--b .result__body { padding-inline: var(--gut); }
}

/* ---------- house lights: the reading room ---------- */
.house { background: var(--screen); color: var(--night); }
.sec + .house { margin-top: var(--s4); }
.house .link { color: var(--night); }
.hl { padding-block: var(--s4); }
.hl__grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); row-gap: var(--s3); }
.hl__head { grid-column: 1 / span 5; align-self: start; position: sticky; top: calc(var(--hh) + var(--s2)); display: flex; flex-direction: column; align-items: flex-start; gap: 22px; }
.hl__head .lead { max-width: 30ch; }
.hl__body { grid-column: 7 / -1; }
@media (max-width: 63.99em) { .hl__head, .hl__body { grid-column: 1 / -1; position: static; } }
.steps li + li { margin-top: var(--s3); }
.steps__t { font-size: var(--t-h3); font-weight: 640; line-height: 1.1; text-wrap: balance; max-width: 22ch; }
.steps p { margin-top: 14px; color: var(--ash); max-width: 40ch; font-size: var(--t-lead); line-height: 1.5; }
.house .steps p { color: var(--graphite); }
.qa__item + .qa__item { margin-top: var(--s2); }
.qa__item > summary { list-style: none; cursor: default; }
.qa__item > summary::-webkit-details-marker { display: none; }
.qa__q { font-size: clamp(1.3rem, 1.05rem + 1vw, 2rem); font-weight: 640; line-height: 1.15; text-wrap: balance; }
.qa__a { margin-top: 12px; color: var(--graphite); max-width: 56ch; font-size: var(--t-lead); line-height: 1.5; }
.qa__a p + p { margin-top: .8em; }
.qa__a a { color: var(--night); text-underline-offset: .25em; }
.qa--fold .qa__item > summary { cursor: pointer; display: flex; justify-content: space-between; gap: 20px; align-items: baseline; }
.qa--fold .qa__item > summary::after { content: ""; flex: none; width: 12px; height: 12px; border: solid currentColor; border-width: 0 2px 2px 0; transform: translateY(-4px) rotate(45deg); transition: transform var(--dur-menu-out) var(--ease-out); }
.qa--fold .qa__item[open] > summary::after { transform: translateY(2px) rotate(225deg); transition-duration: var(--dur-menu); }

/* ---------- the end card ----------
   A title card in reverse: the closing title on the left, the reply promise and the button bottom-aligned on the
   right (no column waits empty), then the page's closing shot full bleed, then (only when the page has them) the
   place line and the onward links. Home folds "How a project runs" in as one compact row of beats. */
.endcard { padding-block: var(--s4) 0; }
.endcard--plain { padding-bottom: var(--s3); }
.endcard__top { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); row-gap: var(--s2); align-items: end; }
.endcard__h { grid-column: 1 / span 8; font-size: var(--t-display); line-height: .98; max-width: 15ch; }
.endcard__act { grid-column: 9 / -1; display: flex; flex-direction: column; align-items: flex-start; gap: 24px; padding-bottom: .3em; }
.endcard__act .lead { color: var(--screen); max-width: 30ch; }
.endcard__shot { margin-top: var(--s3); aspect-ratio: 4 / 3; }
.endcard__shot > picture img { width: 100%; height: 100%; object-fit: cover; object-position: var(--pos, 50% 50%); }
@media (min-width: 48em) { .endcard__shot { aspect-ratio: 2.39 / 1; } }
.endcard__foot { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); row-gap: var(--s2); padding-block: var(--s2) 0; align-items: start; }
.endcard__place { grid-column: 1 / span 6; font-size: var(--t-lead); line-height: 1.45; color: var(--ash); max-width: 40ch; }
.endcard__place strong { color: var(--screen); font-weight: 600; }
.endcard__more { grid-column: 8 / -1; display: flex; flex-wrap: wrap; gap: 16px 40px; padding-top: .3em; }
.endcard__foot > .endcard__more:only-child { grid-column: 1 / -1; }
/* the beats: how a project runs, four short steps in one row, no numbers */
.endcard__steps { margin-top: var(--s3); }
.beats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: var(--gap); row-gap: var(--s2); }
.beats__t { font-size: clamp(1.2rem, 1rem + .7vw, 1.6rem); font-weight: 640; line-height: 1.15; text-wrap: balance; }
.beats p { margin-top: 10px; color: var(--ash); max-width: 30ch; }
@media (max-width: 63.99em) {
  .endcard__h, .endcard__act, .endcard__place, .endcard__more { grid-column: 1 / -1; }
  .endcard__act { padding-bottom: 0; }
  .beats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 47.99em) { .beats { grid-template-columns: minmax(0, 1fr); } }

/* ---------- footer ---------- */
.foot { padding-block: var(--s3) 28px; color: var(--ash); font-size: var(--t-small); }
.foot__grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); row-gap: 40px; }
.foot__brand { grid-column: 1 / span 4; }
.foot__logo img { height: 26px; width: auto; margin-bottom: 22px; }
.foot__brand a { color: var(--screen); }
.foot__col { grid-column: span 2; }
.foot__col:nth-of-type(1) { grid-column: 6 / span 2; }
.foot__h { font-size: var(--t-small); font-weight: 400; color: var(--ash); margin-bottom: 14px; }
.foot__col li + li { margin-top: 8px; }
.foot__col a, .foot__base a { color: var(--screen); text-decoration: none; }
.foot__col a:hover, .foot__base a:hover { text-decoration: underline; text-underline-offset: .3em; }
.foot__base { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px 24px; margin-top: var(--s3); }
.foot__base p:last-child { display: flex; flex-wrap: wrap; gap: 8px 24px; }
@media (max-width: 63.99em) { .foot__brand { grid-column: 1 / -1; } .foot__col, .foot__col:nth-of-type(1) { grid-column: span 4; } }
@media (max-width: 47.99em) {
  .foot__col, .foot__col:nth-of-type(1) { grid-column: span 6; } .foot__col:nth-of-type(3) { grid-column: 1 / -1; }
  .foot__col li + li { margin-top: 0; }
  .foot__col a, .foot__brand p a { display: inline-block; padding-block: 12px; }
  .foot__base a { display: inline-block; padding-block: 12px; }
}

/* ---------- content pages ---------- */
.band { margin-top: clamp(28px, 5.5vh, 64px); overflow: hidden; aspect-ratio: 4 / 3; }
.band > picture img { width: 100%; height: 100%; object-fit: cover; object-position: var(--pos, 50% 50%); }
@media (min-width: 48em) { .band { aspect-ratio: 2.39 / 1; } }
.sec { padding-block: var(--s4) 0; }
.sec--last { padding-bottom: var(--s4); }
/* prose: the title stacked over the reading, the first paragraph in Screen */
.prose { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); }
.prose > .h2 { grid-column: 1 / span 9; }
.prose__body { grid-column: 1 / span 7; margin-top: var(--s2); font-size: var(--t-lead); line-height: 1.5; color: var(--ash); }
.prose--right .prose__body { grid-column: 6 / span 7; }
.prose__body p + p, .prose__body ul + p, .prose__body p + ul { margin-top: 1em; }
.prose__body p:first-child { color: var(--screen); }
.house .prose__body { color: var(--graphite); }
.house .prose__body p:first-child { color: var(--night); }
.prose__body a { text-underline-offset: .25em; }
.prose__body ul li { padding-left: 1.1em; position: relative; }
.prose__body ul li + li { margin-top: .4em; }
.prose__body ul li::before { content: ""; position: absolute; left: 0; top: .72em; width: .45em; height: 2px; background: currentColor; }
@media (max-width: 63.99em) { .prose > .h2, .prose__body, .prose--right .prose__body { grid-column: 1 / -1; } }
/* rows without links: a quiet grid of titled paragraphs */
.jobs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s3) var(--gap); }
.jobs--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.jobs h3 { font-size: var(--t-h3); font-weight: 640; line-height: 1.08; text-wrap: balance; }
.jobs p { margin-top: 14px; color: var(--ash); max-width: 40ch; }
.house .jobs p { color: var(--graphite); }
.jobs a { text-decoration: none; }
.jobs a:hover h3 { text-decoration: underline; text-underline-offset: .2em; text-decoration-thickness: 2px; }
@media (max-width: 63.99em) { .jobs--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 47.99em) { .jobs, .jobs--3 { grid-template-columns: minmax(0, 1fr); gap: 36px; } }
/* one screen of proof: the picture first, full bleed, the title as its caption */
.proof { padding-top: var(--s4); }
.proof__pic { display: block; }
.proof__pic img { width: 100%; height: auto; }
.proof > .caphead { margin-top: var(--s2); }
/* prose beside a phone: a rebuilt brand site's own phone screen stands in the columns the reading leaves */
.prose__phone { display: block; grid-column: 9 / -1; grid-row: 1 / span 2; align-self: start; justify-self: end; width: 100%; max-width: 360px; }
.prose--phone > .h2 { grid-column: 1 / span 8; }
/* the phone is taller than the title and the reading: the spare height goes under the reading, never between them */
.prose--phone { grid-template-rows: auto 1fr; }
.prose--phone > .prose__body { align-self: start; }
.prose__phone a { display: block; }
.prose__phone img { width: 100%; height: auto; }
.prose__phone figcaption { margin-top: 12px; font-size: var(--t-small); color: var(--ash); }
@media (max-width: 63.99em) { .prose__phone { grid-column: 1 / -1; grid-row: auto; margin-top: var(--s3); max-width: 300px; } }
/* gauntlet round 2: the phone is as tall as the words beside it, never taller (it hung 400 px below the reading and
   left the left two thirds of the screen empty). It takes the height of the title and the reading (height 0, at least
   the grid area) and shows its top: the brand's bar, headline and request field */
@media (min-width: 64em) {
  .prose--phone .prose__phone { align-self: stretch; height: 0; min-height: max(100%, 380px); display: flex; flex-direction: column; }
  .prose--phone .prose__phone > a { flex: 1 1 auto; min-height: 0; overflow: hidden; }
  .prose--phone .prose__phone img { height: 100%; object-fit: cover; object-position: top; }
}
.jobs--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 79.99em) { .jobs--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 47.99em) { .jobs--4 { grid-template-columns: minmax(0, 1fr); } }
.caphead { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); margin-top: var(--s2); align-items: start; }
.caphead > .h2 { grid-column: 1 / span 6; font-size: clamp(1.7rem, .95rem + 2.4vw, 3.4rem); }
.caphead > div { grid-column: 8 / -1; display: flex; flex-direction: column; align-items: flex-start; gap: 22px; }
@media (max-width: 63.99em) { .caphead > .h2, .caphead > div { grid-column: 1 / -1; } }
@media (max-width: 47.99em) { .proof__pic { margin-inline: var(--gut); max-width: 400px; } .proof__pic img { aspect-ratio: 346 / 600; object-fit: cover; object-position: top; } }
/* the statement: a wide shot, the line below it in one tone */
.statement__frame { aspect-ratio: 4 / 3; }
.statement__frame > picture img { width: 100%; height: 100%; object-fit: cover; object-position: var(--pos, 50% 50%); }
@media (min-width: 48em) { .statement__frame { aspect-ratio: 2.39 / 1; } }
/* one tone: the whole line is the claim (two tones as a device is slop #7; Ash for a whole line is kept for the
   demos' before and now). The picture's own gate opens over it, the line follows a step below */
.statement__t { font-stretch: var(--wide-2); font-size: var(--t-h2); font-weight: 720; line-height: 1.06; color: var(--screen); max-width: 24ch; margin-top: var(--s3); text-wrap: balance; }
.statement__t strong { color: inherit; font-weight: inherit; }
.statement--plain .statement__t { margin-top: 0; }
/* related: two large links */
.rel { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s2) var(--gap); }
.rel__a { text-decoration: none; display: block; }
.rel__t { display: block; font-size: var(--t-h3); font-weight: 640; line-height: 1.1; overflow-wrap: anywhere; }
/* the arrow rides on the last word, so a long title wraps instead of pushing the arrow off the screen */
.rel__t .arr { display: inline-block; width: .6em; height: .6em; margin-left: .35em; vertical-align: .02em; }
.rel__b { display: block; margin-top: 12px; color: var(--ash); max-width: 40ch; }
@media (max-width: 47.99em) { .rel { grid-template-columns: minmax(0, 1fr); } }
/* split and two columns */
.split { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); row-gap: var(--s2); align-items: center; }
.split__pic { grid-column: 1 / span 6; }
.split__pic img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; object-position: var(--pos, 50% 50%); }
.split__text { grid-column: 8 / -1; }
.split--flip .split__pic { grid-column: 7 / -1; grid-row: 1; }
.split--flip .split__text { grid-column: 1 / span 5; grid-row: 1; }
.split__text .h3 { margin-bottom: 18px; }
.split__text p { color: var(--ash); }
.split__text p + p { margin-top: 1em; }
@media (max-width: 63.99em) { .split__pic, .split__text, .split--flip .split__pic, .split--flip .split__text { grid-column: 1 / -1; grid-row: auto; } }
.cols2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s2) var(--gap); }
.cols2 h3 { font-size: var(--t-h3); font-weight: 640; line-height: 1.1; }
.cols2 p, .cols2 li { color: var(--ash); }
.house .cols2 p, .house .cols2 li { color: var(--graphite); }
.cols2 p { margin-top: 14px; }
.cols2 ul { margin-top: 14px; }
.cols2 li + li { margin-top: 8px; }
@media (max-width: 47.99em) { .cols2 { grid-template-columns: minmax(0, 1fr); } }
/* a case study: the figure in light numerals, the story in prose */
.case { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); row-gap: var(--s2); }
.case__pic { grid-column: 1 / span 5; }
.case__pic img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; object-position: var(--pos, 50% 50%); }
.case__text { grid-column: 7 / -1; }
.case__text .h3 { margin-bottom: 18px; max-width: 24ch; }
.case__what { color: var(--ash); margin-block: 14px var(--s2); font-size: var(--t-lead); max-width: 34ch; }
.case__text p { color: var(--ash); max-width: 52ch; }
.case__text p + p { margin-top: 1em; }
.case__text strong { color: var(--screen); }
@media (max-width: 63.99em) { .case__pic, .case__text { grid-column: 1 / -1; } .case__pic img { aspect-ratio: 5 / 4; } }
/* the builds directory (demos index): names on the left, one frame that cuts to the build in focus */
.dir { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); }
.dir__list { grid-column: 1 / span 5; grid-row: 2; }
.dir__lead { grid-column: 1 / span 5; grid-row: 1; margin-bottom: var(--s3); max-width: 34ch; }
.dir__item { scroll-margin-top: calc(var(--hh) + 24px); }
.dir__item + .dir__item { margin-top: var(--s2); }
.dir__item a { text-decoration: none; display: block; }
.dir__name { font-size: var(--t-h3); font-weight: 640; line-height: 1.08; }
.dir__name .arr { display: inline-block; width: .55em; height: .55em; margin-left: .2em; vertical-align: 0; }
.dir__kind { color: var(--ash); margin-top: 4px; }
.dir__line { color: var(--ash); margin-top: 8px; max-width: 46ch; }
.dir__name, .dir__kind, .dir__line { display: block; }
.dir__pic { display: none; }
.dir__frame { grid-column: 6 / -1; grid-row: 1 / span 2; position: sticky; top: calc(var(--hh) + 6vh); align-self: start; aspect-ratio: 1080 / 620; overflow: hidden; }
.dir__frame img { object-position: 50% 0; }
.dir__frame { background: var(--night); }
.js .dir__item:not(.is-on) .dir__name { color: var(--ash); }
.dir__item:target .dir__name { color: var(--screen); }
@media (max-width: 63.99em) {
  .dir__list, .dir__lead { grid-column: 1 / -1; }
  .dir__frame { display: none; }
  .dir__pic { display: block; margin-bottom: 14px; }
  .dir__pic img { width: min(100%, 320px); aspect-ratio: 346 / 440; object-fit: cover; object-position: 50% 0; }
  .js .dir__item:not(.is-on) .dir__name { color: var(--screen); }
}
/* reading pages: type alone on the title card, then the whole page under house lights */
.title--read { padding-bottom: var(--s3); }
.read { padding-bottom: var(--s4); }
.read .prose__body, .read .jobs p, .read .cols2 p, .read .cols2 li { max-width: 64ch; }
.read .statement__t { color: var(--night); }
.read .case__text p, .read .case__what, .read .case__built li { color: var(--graphite); }
.read .case__text strong { color: var(--night); }
.statement__after { margin-top: var(--s2); max-width: 44ch; }
.case__built { margin: 1em 0; }
.case__built li { color: var(--ash); padding-left: 1.1em; position: relative; }
.case__built li + li { margin-top: .4em; }
.case__built li::before { content: ""; position: absolute; left: 0; top: .78em; width: .45em; height: 2px; background: currentColor; }
.case .fig { margin-top: .2em; }
/* a case study (gauntlet round 2): the outcome in title-card type above the engagement, the picture and the reading
   swapping sides from one engagement to the next, the rest of what we built folded into a native disclosure */
.case__head { margin-bottom: var(--s2); }
.case__head > .h2 { max-width: 22ch; }
.case-sec + .case-sec { margin-top: var(--s4); }
@media (min-width: 64em) {
  .case--flip > .case__pic { grid-column: 8 / -1; grid-row: 1; }
  .case--flip > .case__text { grid-column: 1 / span 6; grid-row: 1; }
}
.case__more { margin: 0 0 1em; }
.case__more > summary { cursor: pointer; display: inline-flex; align-items: baseline; gap: 12px; font-weight: 640; list-style: none; }
.case__more > summary::-webkit-details-marker { display: none; }
.case__more > summary::after { content: ""; flex: none; width: 9px; height: 9px; border: solid currentColor; border-width: 0 2px 2px 0; transform: translateY(-3px) rotate(45deg); transition: transform var(--dur-menu-out) var(--ease-out); }
.case__more[open] > summary::after { transform: translateY(2px) rotate(225deg); transition-duration: var(--dur-menu); }
.case__more > .case__built { margin-top: .6em; }

/* the groups (gauntlet round 2): a run of cut lists becomes one grid, each group its own picture, title and pages */
.groups { padding-block: var(--s4) 0; }
.groups__grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s3) var(--gap); }
.group__pic { aspect-ratio: 16 / 10; }
.group__pic > picture img { width: 100%; height: 100%; object-fit: cover; object-position: var(--pd, 50% 50%); }
.group__h { margin-top: var(--s2); font-size: var(--t-h3); font-weight: 640; line-height: 1.08; text-wrap: balance; }
.group__intro { margin-top: 12px; color: var(--ash); max-width: 44ch; }
.group__list { margin-top: var(--s1); display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--gap); }
.group__list a { display: block; padding-block: 12px; text-decoration: none; transition: transform var(--dur-press) var(--ease-out); }
.group__list a:active { transform: scale(var(--press)); }
.group__t { display: block; font-size: clamp(1.15rem, .9rem + .75vw, 1.6rem); font-weight: 640; line-height: 1.15; text-wrap: balance; }
.group__t .arr { display: inline-block; width: .7em; height: .7em; vertical-align: -.02em; }
.group__b { display: block; margin-top: 4px; color: var(--ash); font-size: var(--t-small); line-height: 1.45; }
.group__list a:hover .group__t, .group__list a:focus-visible .group__t { text-decoration: underline; text-underline-offset: .2em; text-decoration-thickness: 2px; }
@media (max-width: 63.99em) { .groups__grid { grid-template-columns: minmax(0, 1fr); } .group__pic { aspect-ratio: 4 / 3; } }
@media (max-width: 29.99em) { .group__list { grid-template-columns: minmax(0, 1fr); } }

/* /about: the work, not a services list (the 19 builds as their own sites, then the services as a quiet list) */
.builds--about .builds__more { margin-top: var(--s3); }
/* the project form, under house lights */
.form { display: grid; gap: 22px; max-width: 46rem; }
.form label { display: block; font-weight: 600; margin-bottom: 8px; }
.form .hint { display: block; font-weight: 400; color: var(--graphite); font-size: var(--t-small); margin-top: 2px; }
.form input, .form textarea, .form select { width: 100%; font: inherit; color: var(--night); background: transparent; border: 0; border-bottom: 2px solid var(--night); border-radius: 0; padding: 14px 14px 12px; }
.form textarea { min-height: 9em; resize: vertical; }
.form input:focus-visible, .form textarea:focus-visible, .form select:focus-visible { outline: 2px solid var(--night); outline-offset: 2px; }
.form__note { color: var(--graphite); font-size: var(--t-small); }
.form__group { border: 0; padding: 0; margin: 0 0 var(--s2); display: grid; gap: 22px; min-width: 0; }
.form__group legend { padding: 0; margin-bottom: 6px; }
.form .btn { justify-self: start; }
.form__sent { outline: none; transform-origin: 0 50%; }
.form__sent .lead { margin-top: 14px; }
.form fieldset { border: 0; margin: 0; padding: 0; min-width: 0; display: grid; gap: 22px; }
.form fieldset + fieldset { margin-top: var(--s2); }
.form legend { padding: 0; margin-bottom: 6px; }
.form__sent { outline: none; }
.form__sent .lead { margin-top: 14px; }
/* the live form's wiring: the honeypot is out of sight and out of the tab order; an answer that needs fixing says so
   under its field (weight and a heavier underline, no colour: the room has none) and in one solid Night summary */
.form { position: relative; }
.form__trap { position: absolute; left: 0; top: 0; margin: 0; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.field__error:not(:empty) { display: block; margin-top: 8px; font-weight: 650; color: var(--night); }
.field--invalid input, .field--invalid textarea, .field--invalid select { border-bottom-width: 4px; padding-bottom: 10px; }
.form__alert { background: var(--night); color: var(--screen); padding: var(--s2); outline: none; }
.form__alert ul { margin: 12px 0 0; padding-left: 1.1em; }
.form__alert a { color: var(--screen); text-underline-offset: .25em; }
.form__alert li + li { margin-top: 6px; }
.form .btn.is-busy { cursor: progress; }
.form__act .form__note:not(:empty) { margin-top: 12px; }
.title__links { display: flex; flex-wrap: wrap; gap: 8px 24px; margin-top: 18px; }

/* ---------- the content-page template (build/inner.mjs) ---------- */
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.title--plain { padding-bottom: var(--s3); }
.statement__after { margin-top: var(--s2); max-width: 46ch; }
/* long reads: the title card on Night, then the house lights come up for the whole reading (legal, glossary) */
.read { padding-bottom: var(--s4); }
.read .prose__body { grid-column: 1 / span 8; }
.house .statement__t { color: var(--night); }
.house .rel__b, .house .dir__kind, .house .dir__line, .house .case__text p, .house .split__text p { color: var(--graphite); }

/* ---------- concept builds (demo pages) ---------- */
.record { padding-block: var(--s4) 0; }
.record__row { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); align-items: end; }
.record__row + .record__row { margin-top: var(--s3); }
.record__fig { grid-column: 1 / span 8; font-size: var(--t-h2); font-stretch: var(--wide-2); font-weight: 720; line-height: 1.02; text-wrap: balance; }
.record__what { grid-column: 9 / -1; color: var(--ash); max-width: 34ch; padding-bottom: .35em; }
.record__row--past .record__fig { color: var(--ash); }
@media (max-width: 63.99em) { .record__fig, .record__what { grid-column: 1 / -1; } .record__what { margin-top: 16px; padding: 0; } }
/* the brand's own site, its five layers noted beside it */
.site { padding-block: var(--s4) 0; }
.site__head { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); margin-bottom: var(--s3); }
.site__head > .h2 { grid-column: 1 / span 9; }
.site__head > .lead { grid-column: 1 / span 6; margin-top: var(--s1); max-width: 44ch; }
.site__grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); }
.site__notes { grid-column: 1 / span 3; position: relative; }
.site__screen { grid-column: 4 / -1; }
.note { transition: opacity var(--dur-in) var(--ease-out); }
.note h3 { font-size: clamp(1.2rem, 1rem + .7vw, 1.6rem); font-weight: 640; line-height: 1.15; text-wrap: balance; }
.note p { margin-top: 10px; color: var(--ash); font-size: var(--t-small); line-height: 1.55; max-width: 30ch; }
.js .site__notes.is-placed .note { position: absolute; left: 0; right: 0; top: var(--y, 0); }
.site__notes:not(.is-placed) .note + .note { margin-top: 28px; }
.site__done { margin-top: var(--s2); color: var(--ash); font-size: var(--t-lead); }
@media (max-width: 63.99em) {
  .site__head > .h2, .site__head > .lead { grid-column: 1 / -1; }
  .site__screen { grid-column: 1 / -1; margin-inline: calc(-1 * var(--gut)); }
  .site__notes { grid-column: 1 / -1; grid-row: 2; margin-top: var(--s2); display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px var(--gap); }
  .js .site__notes.is-placed .note { position: static; }
  .site__notes:not(.is-placed) .note + .note { margin-top: 0; }
  .note p { display: none; }
  .note h3 { font-size: 1.0625rem; }
}
/* what happens underneath: the scenes, a clock each, one or two of the brand's screens. Three compositions, chosen
   from the content by build/fm/demo.mjs so no two neighbours sit the same way: pair (the words beside a phone and a
   desk, either way round), left or right (one screen to one side of the words) and wide (the words above one wide
   screen of five or more rows). */
.under { padding-block: var(--s4) 0; }
.scene { padding-block: var(--s4) 0; }
.scene__grid { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); row-gap: var(--s2); align-items: start; }
.scene__text { grid-column: 1 / span 4; position: sticky; top: calc(var(--hh) + var(--s2)); container-type: inline-size; }
/* the clock fills its column at most, so "11:40 am" holds one line beside a screen */
.clock { display: block; font-size: min(clamp(3.2rem, 1.3rem + 5.6vw, 7.6rem), 19cqi); margin-bottom: 24px; }
.scene__h { font-size: var(--t-h3); font-weight: 640; line-height: 1.08; text-wrap: balance; }
.scene__copy { display: flex; flex-direction: column; align-items: flex-start; }
.scene__copy > p { margin-top: 16px; color: var(--ash); max-width: 38ch; }
.scene__copy .scene__verdict { color: var(--screen); }
.scene__copy .textbtn { margin-top: 14px; }
.scene__copy .textbtn + .textbtn { margin-top: 2px; }
.scene__screens { grid-column: 6 / -1; display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--gap); align-items: start; }
.scene--left .scene__screens, .scene--right .scene__screens, .scene--wide .scene__screens { display: block; }
.scene--wide .scene__text { grid-column: 1 / -1; position: static; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); align-items: end; }
.scene--wide .clock, .scene--wide .scene__h { grid-column: 1 / span 6; }
.scene--wide .scene__copy { grid-column: 8 / -1; grid-row: 1 / span 2; align-self: end; }
.scene--wide .scene__copy > p:first-child { margin-top: 0; }
.scene--wide .scene__screens { grid-column: 1 / -1; }
/* one screen left of the words: the screen takes the first seven columns, the words hold on the right; a phone alone
   sits nearer the words */
@media (min-width: 64em) {
  .scene--left .scene__text { grid-column: 9 / -1; grid-row: 1; }
  .scene--left .scene__screens { grid-column: 1 / span 7; grid-row: 1; }
  .scene--left.scene--phone .scene__text { grid-column: 8 / -1; }
  .scene--left.scene--phone .scene__screens { grid-column: 2 / span 5; }
  .scene--left.scene--phone .bs-phone { margin-left: auto; }
  .scene--right.scene--phone .scene__screens { grid-column: 7 / span 5; }
}
/* a pair can open the other way round: the phone and the desk on the left, the words holding on the right */
@media (min-width: 80em) {
  .scene--flip .scene__text { grid-column: 9 / -1; grid-row: 1; }
  .scene--flip .scene__screens { grid-column: 1 / span 7; grid-row: 1; }
}
/* below 1280 px a phone and a desk need the full width: the words go above them; a single screen keeps its side */
@media (max-width: 79.99em) {
  .scene--pair .scene__text { grid-column: 1 / span 8; position: static; }
  .scene--pair .scene__screens { grid-column: 1 / -1; }
  .scene--right .scene__text { grid-column: 1 / span 5; }
  .scene--right .scene__screens { grid-column: 6 / -1; }
  .scene--left .scene__text { grid-column: 8 / -1; }
}
@media (max-width: 63.99em) {
  .scene__text, .scene--pair .scene__text, .scene--left .scene__text, .scene--right .scene__text, .scene__screens, .scene--left .scene__screens, .scene--right .scene__screens { grid-column: 1 / -1; position: static; }
  .scene--wide .scene__text { display: block; }
  .scene--wide .scene__copy > p:first-child { margin-top: 16px; }
  .scene__screens { grid-template-columns: minmax(0, 1fr); max-width: 560px; }
  .scene--wide .scene__screens { max-width: none; }
}

@media (forced-colors: active) {
  .btn, .sq, .reel__toggle, .mast__cta { border: 1px solid ButtonText; }
  .open__post, .open__bar, .gate::before, .gate::after { display: none !important; }
}
@media print { .mast, .open, .reel__toggle, .credits__bg, .strip__btns { display: none; } }

/* ---------- pictures held beside the reading (build/fm/inner.mjs) ----------
   Beside: a type-only section that follows another holds one of the page's pictures (sticky) on four columns while
   its words read on seven, so no screen at 1440 is a wall of type. The side alternates from page to page. Walk: a
   walkthrough is a Hold: the title, its line and a picture hold on the left, the steps read on the right. Questions
   and the form hold a picture under their heading. Under house lights the pictures are still (no gate). */
.beside { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); row-gap: var(--s2); align-items: start; }
.beside__words { grid-column: 1 / span 7; grid-row: 1; }
.beside__pic { grid-column: 9 / -1; grid-row: 1; position: sticky; top: calc(var(--hh) + var(--s2)); }
.beside--flip .beside__words { grid-column: 6 / -1; }
.beside--flip .beside__pic { grid-column: 1 / span 4; }
.beside__pic img, .walk__pic img, .hl__pic img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; object-position: var(--pos, 50% 50%); max-height: calc(100svh - var(--hh) - 2 * var(--s2)); }
.beside__words > .lead { margin-top: var(--s1); max-width: 40ch; }
.beside__words > .jobs, .beside__words > .cols2, .beside__words > .prose__body { margin-top: var(--s3); }
.beside .jobs--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* a phone screen held beside the words (the Websites hub's four jobs) */
.beside--phone .beside__pic { max-width: 360px; justify-self: center; width: 100%; }
.beside--phone .beside__pic a { display: block; }
.beside--phone .beside__pic img { aspect-ratio: auto; height: auto; max-height: none; }
.beside--phone figcaption { margin-top: 12px; font-size: var(--t-small); color: var(--ash); }
.walk { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); column-gap: var(--gap); row-gap: var(--s3); align-items: start; }
.walk__head { grid-column: 1 / span 5; position: sticky; top: calc(var(--hh) + var(--s2)); display: flex; flex-direction: column; align-items: flex-start; gap: 20px; }
.walk__head .lead { max-width: 34ch; }
.walk__pic, .hl__pic { width: 100%; margin-top: 8px; }
.walk__pic img, .hl__pic img { aspect-ratio: 4 / 3; max-height: 46svh; }
.walk > .steps { grid-column: 7 / -1; }
.hl__grid--form .hl__head { gap: 0; }
.hl__grid--form .hl__pic { margin-top: 0; }
.hl__grid--form .hl__pic img { aspect-ratio: 4 / 5; max-height: calc(100svh - var(--hh) - 2 * var(--s2)); }
.form__promise { margin-top: 14px; }
.endcard__links { display: flex; flex-wrap: wrap; gap: 14px 32px; }
@media (max-width: 63.99em) {
  .beside__words, .beside__pic, .beside--flip .beside__words, .beside--flip .beside__pic, .walk__head, .walk > .steps { grid-column: 1 / -1; grid-row: auto; position: static; }
  .beside__pic img, .walk__pic img, .hl__pic img, .hl__grid--form .hl__pic img { aspect-ratio: 16 / 9; max-height: none; }
  .hl__grid--form .hl__head:empty { display: none; }
}
@media (max-width: 47.99em) { .beside__pic img, .walk__pic img, .hl__pic img, .hl__grid--form .hl__pic img { aspect-ratio: 4 / 3; } }
/* the homepage opens on film: on wide screens its title is set a step smaller, so it holds three lines on its nine
   columns and the letterbox takes well over half of the first screen at rest */
@media (min-width: 64em) {
  .pg-home .title__h { font-size: min(var(--t-display), 4.7vw); }
  .pg-home .open { margin-top: clamp(24px, 4vh, 44px); }
}
