/* The display face draws its ampersand so tightly that "Q&A" reads as "Q3A".
   This borrows one grotesque glyph — U+0026 and nothing else — from whatever
   plain sans the device already has, and leaves every other letter alone. If
   none of them resolve the rule simply drops and the original glyph is used. */
@font-face {
  font-family: "AmpSwap";
  src: local("Helvetica Neue"), local("HelveticaNeue"), local("Helvetica"),
       local("Arial"), local("Arimo"), local("Roboto"), local("Noto Sans"),
       local("Liberation Sans"), local("DejaVu Sans");
  unicode-range: U+0026;
  font-display: swap;
}

/* Android Chrome and iOS Safari inflate text on their own unless told not to —
   that is what made the layout "cramped" on phones other than the one it was
   built on: every fixed size silently grew and the capsule nav overflowed. */
html, body { -webkit-text-size-adjust: 100%; -moz-text-size-adjust: 100%; text-size-adjust: 100%; }

  /* ===== Tokens ======================================================== */
  :root {
    --teal-deep: #23414A;
    --teal-mid: #4E838D;
    --blue: #3B82E0;
    --violet: #8B5CF6;
    --orange-blaze: #F0721A;
    --orange-coral: #E8794A;
    --cream: #E8E4D6;
    --cream-light: #F1EEE0;
    --black: #1C1C1C;

    --font-display: "AmpSwap", "Archivo", "Roboto Condensed", "Helvetica Neue", Arial, sans-serif;
    --font-mono: "AmpSwap", "Space Mono", ui-monospace, Menlo, monospace;
    --font-body: "Inter", system-ui, sans-serif;

    --pad-x: clamp(1.5rem, 4vw, 4rem);
    --pad-y: clamp(1.5rem, 3.5vw, 3rem);
    --max-w: 1440px;
    --spine-w: 4px;
    --spine-gap: clamp(18px, 2.5vw, 32px);

    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

    /* ===== Northstar paper — one ground, no themes ====================
       Warm paper for the page, ink navy for type, deep navy for the hero,
       the footer and any framed product shot. Orange is for primary
       actions and nothing else. */
    --paper-hi:  #FDFBF4;
    --paper:     #F8F4EB;
    --ground:    #F4EFE6;
    --ground-paper: #F4EFE6;
    --ink:       #16131F;
    --ink-muted: #4C4658;   /* 7.9:1 on the paper ground */
    --rule:      rgba(22,19,31,.14);
    --panel:     rgba(248,244,235,.76);
    --accent:    #833504;   /* link orange, dark enough to read as body text */

    --navy:      #0E1220;
    --navy-hi:   #171C2E;
    --on-navy:   #F1EEE0;
    --on-navy-muted: #B6B3C4;
    --gn-1:      #F1EEE0;

    --glass-bg: rgba(253,251,244,.72);
    --glass-border: rgba(22,19,31,.10);
    --glass-shadow: 0 24px 60px rgba(28,22,60,.14), inset 0 1px 0 rgba(253,251,244,.9);
    --gradient:    linear-gradient(180deg, #3B82E0, #8B5CF6 50%, #F0721A);
    --gradient-ok: linear-gradient(180deg in oklch, #3B82E0, #8B5CF6 50%, #F0721A);

    --header-offset: 86px;
  }

  /* ===== Base ========================================================== */
  *, *::before, *::after { box-sizing: border-box; }

  html { scroll-behavior: smooth; }
  /* Nothing may widen the page sideways. `clip` rather than `hidden`, so the
     document scroller and every position: sticky inside it keep working. */
  html, body { overflow-x: clip; }

  body {
    margin: 0;
    background: var(--ground);
    background-attachment: fixed;
    color: var(--ink);
    font-family: "AmpSwap", var(--font-body);
    -webkit-font-smoothing: antialiased;
  }

  h1, h2, h3, p, ol, ul { margin: 0; }
  ol, ul { list-style: none; padding: 0; }
  a { color: inherit; }

  :focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

  .label {
    font-family: "AmpSwap", var(--font-mono);
    font-size: 12px;
    letter-spacing: .14em;
    line-height: 1.9;
    text-transform: uppercase;
    font-weight: 400;
    color: var(--ink-muted);
  }
  .label--strong { font-weight: 700; color: var(--ink); }
  .label--accent { color: var(--accent); }
  .label--diff { color: var(--paper-muted, #8A88A0); opacity: .55; }
  .section .content h2#capabilities.label--strong,
  .section .content h2#work.label--strong { color: rgba(86, 84, 100, .4); }
  /* sits lower so the ghost never rides into the approach copy above */
  .section .content h2#work.label--strong { transform: translateY(-82%); }

  /* ── BUILD 119: panel titles are filled ghosts behind the content ─────
     lab-titles option 20 at 85%. The heading keeps its id and its place in
     the document — it is restyled, not replaced, so anchors, aria-labelledby
     and the outline are untouched. It sits at z-index 0 inside .content and
     is pulled up 85% of its own height, so that much shows above the first
     block and the remainder is covered BY that block. Which means the block
     has to be opaque and above it — see .workbento / .svc below — and the
     section needs headroom or its own overflow crops the letter tops. ---- */
  .section .content { position: relative; }
  /* NOTE the selector weight: `h2.label--strong` alone loses to the tick rule
     that follows this block, which sets position: relative. Same trap as the
     hero/work seam — beat it on specificity, not on order. */
  .section .content h2.label--strong {
    position: absolute; left: -90px; top: 0; z-index: 0;
    margin: 0; padding-left: 0;
    transform: translateY(-80%);
    font-family: "AmpSwap", var(--font-display); font-weight: 800;
    font-variation-settings: "wdth" 62;
    text-transform: uppercase; white-space: nowrap;
    line-height: .78; letter-spacing: -.04em;
    font-size: clamp(2.6rem, 8vw, 7rem);
    color: var(--ghost-ink, rgba(241,238,224,.075));
    pointer-events: none; user-select: none;
  }
  .section .content h2.label--strong::before { display: none; }
  /* On cream the ghost needs more weight than it does on near-black — .075 of
     ink over #F5F3EC is barely a smudge. */
  /* the first block in each panel is what covers the ghost */
  .section .content > *:not(h2) { position: relative; z-index: 2; }
  /* the covering block must butt up against the ghost — any top margin here
     opens a gap and the word is simply floating above the content, not
     layered behind it */
  .section .content > h2.label--strong + * { margin-top: 0; }
  /* headroom for the raised letters */
  .sheetcard > .section { padding-top: clamp(4.5rem, 11vh, 7rem); }

  /* Section headings carry their section's colour as a tick. */
  h2.label--strong { position: relative; padding-left: 14px; }
  h2.label--strong::before {
    content: ""; position: absolute; left: 0; top: -2px; bottom: -2px;
    width: 4px; background: var(--sec-accent, var(--gradient));
  }

  /* ===== Each section owns one colour and one device ==================== */


  /* ── BUILD 119: the approach is a rail, not panels beside an orb ──────
     The old block gave four glass panels 58% of the width and left the rest
     to a WebGL orb that barely read — on the new flat panels that empty half
     was the loudest thing in the section. It is now one full-width rail: the
     brand gradient as the process line, a node per stage in that stage's
     colour, and four columns divided by hairlines. Same four stages, same
     words. The orb canvas is gone; its script already guards on a missing
     element, so nothing else had to change. ---------------------------- */
  .approach { margin-top: clamp(1.6rem, 3.6vh, 2.6rem); }
  .approach-line {
    display: block; height: 2px; border-radius: 2px;
    background: linear-gradient(90deg,
      var(--blue) 0%, var(--violet) 42%, var(--orange-coral) 74%, var(--orange-blaze) 100%);
    opacity: .8;
  }
  .stages {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  }
  .stage {
    position: relative; min-width: 0;
    padding: clamp(1.3rem, 2.8vh, 1.9rem) clamp(1rem, 2.2vw, 1.9rem) 0 0;
  }
  .stage + .stage {
    padding-left: clamp(1rem, 2.2vw, 1.9rem);
    box-shadow: inset 1px 0 0 var(--rule);
  }
  /* the node sits ON the process line, punched out of the panel ground */
  .stage::before {
    content: ""; position: absolute; left: 0; top: -5.5px;
    width: 9px; height: 9px; border-radius: 100vw;
    background: var(--ac);
    box-shadow: 0 0 0 4px var(--ground), 0 0 14px var(--ac);
  }
  .stage + .stage::before { left: clamp(1rem, 2.2vw, 1.9rem); }
  .stage-n {
    display: block; font-family: "AmpSwap", var(--font-mono);
    font-size: .6rem; letter-spacing: .2em; color: var(--ac); margin-bottom: .55rem;
  }
  .stage h3 {
    font-family: "AmpSwap", var(--font-display); font-weight: 700; font-variation-settings: "wdth" 78;
    text-transform: uppercase; letter-spacing: -.01em;
    font-size: clamp(.95rem, 1.5vw, 1.2rem); line-height: 1.05; margin: 0 0 .45rem;
  }
  .stage p {
    margin: 0; color: var(--ink-muted); font-weight: 300;
    font-size: .85rem; line-height: 1.55;
  }
  @media (max-width: 860px) {
    .stages { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .stage::before { display: none; }
    .stage { border-top: 1px solid var(--rule); }
    .stage + .stage { box-shadow: none; }
    .stage:nth-child(3), .stage:nth-child(4) { margin-top: clamp(.9rem, 2vh, 1.3rem); }
  }
  @media (max-width: 520px) { .stages { grid-template-columns: 1fr; } }


  /* ── BUILD 119: The difference, rebuilt as a threshold ────────────────
     It was a two-column table, which read as a spec sheet. It is now six
     crossings: the old way on the left in muted body type, a connector that
     picks up that row's colour, and our way on the right in condensed caps
     behind a coloured edge. Each row's colour is a sample of the brand
     gradient in order, so the six edges stacked ARE the spine — the same
     device the panels just gave up, put back where it means something. ---- */
  .shift-head, .shift-row {
    display: grid;
    grid-template-columns: 2.4rem minmax(0, 1fr) minmax(48px, .9fr) minmax(0, 1.15fr);
    align-items: center;
    column-gap: clamp(.6rem, 1.6vw, 1.4rem);
  }
  .shift-head {
    margin-top: clamp(1.6rem, 4vh, 2.6rem);
    padding-bottom: .8rem;
    font-family: "AmpSwap", var(--font-mono); font-size: .58rem;
    letter-spacing: .2em; text-transform: uppercase; color: var(--ink-muted);
  }
  .shift-head .shift-them { text-align: right; }
  .shift-head .shift-us {
    color: var(--ink);
    border-left: 2px solid var(--rule);
    padding-left: clamp(.9rem, 2vw, 1.6rem);
  }
  .shift { list-style: none; margin: 0; padding: 0; }
  .shift-row { padding: clamp(.75rem, 1.8vh, 1.1rem) 0; }
  .shift-row + .shift-row { border-top: 1px solid rgba(255,255,255,.06); }
  .shift-n {
    font-family: "AmpSwap", var(--font-mono); font-size: .92rem; letter-spacing: .18em;
    font-weight: 600;
    color: var(--ac);
  }
  .shift-them {
    text-align: right; color: var(--ink-muted);
    font-weight: 300; font-size: clamp(.85rem, 1.2vw, .98rem); opacity: .72;
  }
  /* the crossing itself */
  .shift-line {
    position: relative; height: 1px; align-self: center;
    background: linear-gradient(90deg, rgba(255,255,255,.06), var(--ac));
  }
  .shift-line::after {
    content: ""; position: absolute; right: 0; top: 50%;
    width: 6px; height: 6px;
    border-top: 1.5px solid var(--ac); border-right: 1.5px solid var(--ac);
    transform: translateY(-50%) rotate(45deg);
  }
  /* our side sits behind a coloured edge — the threshold the row crosses */
  .shift-us {
    font-family: "AmpSwap", var(--font-display); font-weight: 700;
    font-variation-settings: "wdth" 78;
    text-transform: uppercase; letter-spacing: -.01em;
    font-size: clamp(.95rem, 1.6vw, 1.3rem); line-height: 1.1;
    color: var(--ink);
    border-left: 2px solid var(--ac);
    padding-left: clamp(.9rem, 2vw, 1.6rem);
  }
  @media (max-width: 760px) {
    .shift-head { display: none; }
    .shift-row {
      grid-template-columns: 2.2rem minmax(0, 1fr);
      row-gap: .35rem; padding: clamp(.8rem, 2vh, 1.1rem) 0;
    }
    .shift-n { grid-row: 1; }
    .shift-them { grid-column: 2; text-align: left; }
    .shift-line { grid-column: 2; height: 1px; width: 42px; margin: .2rem 0; }
    .shift-line::after { display: none; }
    .shift-us { grid-column: 2; border-left: 0; padding-left: 0;
      box-shadow: inset 0 2px 0 0 transparent; }
  }


  /* ── Daylight, balanced (BUILD 119) ───────────────────────────────────
     Daylight was cream from top to bottom, which left the card numerals
     invisible on their pale rails and gave the page no rhythm. Two of the
     four panels now keep the night ground in Daylight, so the page reads
     half light and half dark either way round. The whole token set is
     restored inside them, which is what makes everything that lives in a
     panel — numerals, rails, chips, the ghost title — correct automatically
     rather than needing its own light-mode exception. ------------------- */
  /* Cjay, 27 Aug: the hero and the section under it are cream in Daylight.
     The difference keeps the night ground, so the page still turns over once
     rather than running cream from top to bottom. */
  /* anything that hard-codes a light-theme ink inside those panels */

  /* ---- Approach: four glass panels on the right, glowing borders ---- */
  /* label pushed down toward the panels per the red markup */
  .label--sunk { margin-top: clamp(2.4rem, 5.5vh, 3.6rem); }
  .apcol { grid-column: 1; min-width: 0; }
  .approach-grid {
    margin-top: clamp(1rem, 2.2vh, 1.5rem);
    display: grid;
    grid-template-columns: minmax(0, 58%) minmax(0, 1fr);
    column-gap: clamp(1rem, 3vw, 3rem);
    align-items: center;
  }
  .apanels {
    grid-column: 1; grid-row: 1;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: clamp(.7rem, 1.4vw, 1rem);
  }
  .orb-wrap {
    grid-column: 2; grid-row: 1;
    position: relative;
    aspect-ratio: 1 / 1;
    width: 100%;
    max-width: 380px;
    justify-self: center;
  }
  .orb-wrap canvas { display: block; width: 100%; height: 100%; }
  /* inside .apcol, so it hugs the panel grid instead of clearing the orb row */
  .approach-lede {
    color: var(--ink-muted); font-size: .95rem; line-height: 1.62; font-weight: 300;
    max-width: 56ch;
    margin: clamp(.8rem, 1.8vh, 1.2rem) 0 0;
  }
  @media (max-width: 1100px) {
    .approach-grid { grid-template-columns: 1fr; }
    .apcol { grid-column: 1; }
    .orb-wrap { display: none; }   /* panels take the full width here */
  }
  @media (max-width: 700px) { .apanels { grid-template-columns: 1fr; } }
  /* the swept fraction of the border, 0 -> 100% on hover */
  @property --sweep {
    syntax: "<percentage>";
    inherits: false;
    initial-value: 0%;
  }

  .apanel {
    position: relative;
    display: flex; flex-direction: column; gap: .3rem;
    justify-content: center;
    padding: clamp(.85rem, 1.5vw, 1.15rem) clamp(1.05rem, 2vw, 1.5rem);
    border-radius: 13px;
    background:
      /* specular streak across the upper third — the gloss */
      linear-gradient(158deg,
        rgba(255,255,255,.26) 0%,
        rgba(255,255,255,.10) 14%,
        rgba(255,255,255,.02) 30%,
        rgba(255,255,255,0) 46%),
      /* soft counter-light rising from the lower edge */
      linear-gradient(0deg, rgba(255,255,255,.06) 0%, rgba(255,255,255,0) 30%),
      rgba(18, 20, 44, .14);
    border: 1px solid transparent;
    -webkit-backdrop-filter: blur(24px) saturate(2);
    backdrop-filter: blur(24px) saturate(2);
    box-shadow:
      0 24px 60px rgba(2,4,14,.45),
      inset 0 1px 0 rgba(255,255,255,.22),
      inset 0 -1px 0 rgba(255,255,255,.06);
    min-height: clamp(92px, 13vh, 120px);
    isolation: isolate;
    --sweep: 0%;
  }
  /* glass gloss: a bright arc hugging the top edge, fading out by mid-panel */
  .apanel > .gloss {
    content: "";
    position: absolute; inset: 0;
    border-radius: inherit;
    pointer-events: none;
    z-index: 0;
    background:
      radial-gradient(120% 62% at 50% -18%,
        rgba(255,255,255,.30) 0%,
        rgba(255,255,255,.10) 34%,
        rgba(255,255,255,0) 62%);
    mix-blend-mode: screen;
    opacity: .85;
  }
  .apanel > .anum, .apanel > h3, .apanel > p { position: relative; z-index: 1; }

  /* The line: a conic gradient carrying all three brand colours, starting at
     the top-right corner (from 58deg) and running clockwise. It is masked to
     a 1px ring, and revealed progressively as --sweep animates to 100%. */
  .apanel::before {
    content: "";
    position: absolute; inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: conic-gradient(from 58deg,
      var(--blue) 0%,
      var(--violet) 30%,
      var(--orange-blaze) 62%,
      var(--orange-coral) 80%,
      var(--blue) 100%);
    -webkit-mask-image:
      conic-gradient(from 58deg, #000 0 var(--sweep), transparent var(--sweep) 100%),
      linear-gradient(#000 0 0),
      linear-gradient(#000 0 0);
    mask-image:
      conic-gradient(from 58deg, #000 0 var(--sweep), transparent var(--sweep) 100%),
      linear-gradient(#000 0 0),
      linear-gradient(#000 0 0);
    -webkit-mask-clip: border-box, content-box, border-box;
    mask-clip: border-box, content-box, border-box;
    -webkit-mask-composite: source-in, xor;
    mask-composite: intersect, exclude;
    pointer-events: none;
    z-index: 1;
  }
  .apanel:hover::before,
  .apanel:focus-within::before { --sweep: 100%; transition: --sweep 1.05s linear; }

  /* halo in the same three colours, fading up as the line completes */
  .apanel::after {
    content: "";
    position: absolute; inset: -1px;
    border-radius: inherit;
    background: conic-gradient(from 58deg,
      var(--blue) 0%, var(--violet) 30%, var(--orange-blaze) 62%,
      var(--orange-coral) 80%, var(--blue) 100%);
    filter: blur(17px) brightness(1.4) saturate(1.06);
    opacity: 0;
    transition: opacity .5s var(--ease-out);
    pointer-events: none;
    z-index: -1;
  }
  .apanel:hover::after,
  .apanel:focus-within::after { opacity: .16; transition: opacity .7s var(--ease-out) .45s; }

  .apanel .anum { transition: color .4s var(--ease-out); }
  .apanel:hover .anum { color: var(--orange-blaze); }

  /* If mask-composite is unsupported, fall back to a plain fading ring. */
  @supports not ((mask-composite: intersect) or (-webkit-mask-composite: source-in)) {
    .apanel::before { -webkit-mask-image: none; mask-image: none; background: none;
      border: 1px solid var(--violet); opacity: 0; transition: opacity .4s var(--ease-out); }
    .apanel:hover::before { opacity: 1; }
  }
  @media (prefers-reduced-motion: reduce) {
    .apanel:hover::before, .apanel:focus-within::before { transition: none; --sweep: 100%; }
    .apanel::after { transition: none; }
  }
  .apanel .anum {
    font-family: "AmpSwap", var(--font-mono); font-size: .64rem; letter-spacing: .2em;
    color: var(--ink-muted);
  }
  .apanel h3 {
    font-family: "AmpSwap", var(--font-display); font-weight: 700; text-transform: uppercase;
    font-size: clamp(.94rem, 1.45vw, 1.16rem); letter-spacing: -.005em; line-height: 1.08;
    margin: 0;
  }
  .apanel p {
    margin: 0; color: var(--ink-muted);
    font-size: .84rem; line-height: 1.45; font-weight: 300;
    max-width: 36ch;
  }

  /* Approach — BLUE constellation: nodes on a falling line. */
  section[aria-labelledby="approach"] { --sec-accent: var(--blue); }
  section[aria-labelledby="approach"] .pindex { color: var(--blue); }
  section[aria-labelledby="approach"] .plist { position: relative; }
  section[aria-labelledby="approach"] .plist::before {
    content: ""; position: absolute; left: 5px; top: 12px; bottom: 12px;
    width: 1px; background: linear-gradient(180deg, rgba(59,130,224,.7), rgba(59,130,224,.08));
  }
  section[aria-labelledby="approach"] .prow { position: relative; padding-left: 30px; }
  section[aria-labelledby="approach"] .prow::before {
    content: ""; position: absolute; left: 0; top: 8px;
    width: 11px; height: 11px; border-radius: 50%;
    background: radial-gradient(circle at 35% 30%, #CFE4FF, var(--blue) 60%, #10305E);
    box-shadow: 0 0 12px rgba(59,130,224,.55);
  }

  /* Capabilities — PURPLE: gradient ghost numerals, nebula glow on hover. */
  section[aria-labelledby="capabilities"] { --sec-accent: var(--violet); }
  section[aria-labelledby="capabilities"] .cap > .label--accent {
    display: block;
    color: transparent;
    background: linear-gradient(180deg, #C9AEFF, #8B5CF6 55%, rgba(139,92,246,.15));
    -webkit-background-clip: text; background-clip: text;
    font-size: clamp(2.2rem, 4.5vw, 3.6rem); font-weight: 700;
    font-family: "AmpSwap", var(--font-display); letter-spacing: -.02em; line-height: 1;
    margin-bottom: .4rem;
  }
  section[aria-labelledby="capabilities"] .cap { position: relative; overflow: hidden; }
  section[aria-labelledby="capabilities"] .cap::after {
    content: ""; position: absolute; right: -10%; top: -30%;
    width: 50%; height: 160%; pointer-events: none;
    background: radial-gradient(50% 50% at 50% 50%, rgba(139,92,246,.16) 0%, rgba(139,92,246,0) 70%);
    opacity: 0; transition: opacity .4s var(--ease-out);
  }
  section[aria-labelledby="capabilities"] .cap:hover::after { opacity: 1; }

  /* Selected work — ORANGE: glass cards stacking on scroll (ScrollStack port). */
  .stack { position: relative; margin-top: clamp(2rem, 5vh, 3.25rem); }
  .stack-card {
    position: relative;
    display: flex; flex-direction: column; justify-content: space-between;
    gap: 2.4rem;
    width: 100%;                      /* buttons shrink-to-fit; force uniform width */
    height: min(52vh, 330px);         /* identical height for every card */
    padding: clamp(1.5rem, 4vw, 3rem);
    margin-bottom: 90px;
    /* Glass: a translucent pane with a lit top edge and a sheen across it. */
    background:
      linear-gradient(150deg, rgba(255,255,255,.11) 0%, rgba(255,255,255,.022) 38%, rgba(255,255,255,0) 60%),
      rgba(18, 20, 44, .18);
    border: 1px solid transparent;
    border-radius: 13px;
    -webkit-backdrop-filter: blur(24px) saturate(2);
    backdrop-filter: blur(24px) saturate(2);
    box-shadow:
      0 24px 60px rgba(2,4,14,.45),
      inset 0 1px 0 rgba(255,255,255,.22),
      inset 0 -1px 0 rgba(255,255,255,.06);
    cursor: pointer;
    text-align: left;
    color: inherit; font: inherit;
    transform-origin: top center;
    will-change: transform;
    backface-visibility: hidden;
  }
  /* ===== BorderGlow (vanilla port of React Bits BorderGlow) =============
     Cursor-direction mesh border + edge light on the stack cards.
     Driven by two vars set from pointermove: --edge-proximity (0-100)
     and --cursor-angle. Config: sensitivity 0, cone 38, radius 63px,
     intensity 2.2, mesh in brand violet/orange/blue, warm gold edge. */
  .stack-card ,
  .stack-card::before,
  .stack-card::after,
  .stack-card > .edge-light ,
  .stack-card:not(:hover)::before,
  .stack-card:not(:hover)::after,
  .stack-card:not(:hover) > .edge-light ,
  /* mesh-gradient border ring, cone-masked toward the cursor */
  .stack-card::before ,
  /* soft mesh fill drifting in from the edges */
  .stack-card::after ,
  /* the outer edge-light ring, gold, intensity 2.2 baked into the alphas */
  .stack-card > .edge-light ,
  .stack-card > .edge-light::before ,

  .stack-card:last-of-type { margin-bottom: 0; }
  @media (max-width: 640px) {
    .stack-card { height: auto; min-height: 380px; }
  }
  .stack-card .spread { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; }
  .stack-card .spread .label:not(.label--accent) { margin-top: .35rem; font-size: .86rem; letter-spacing: .16em; }
  /* Index: a small orange dot leads the numeral, like a marker on a list. */
  .stack-card .spread .label--accent {
    font-size: 1.15em;
    letter-spacing: .1em;
    /* line up with the name below rather than colliding with the spine */
    margin-left: 46px;
  }
  .stack-card h3 {
    font-family: "AmpSwap", var(--font-display);
    font-weight: 700;
    font-size: clamp(2rem, 5.6vw, 5rem);
    letter-spacing: .07em;
    line-height: 1;
    margin: .5rem 0 0;
    display: inline-block;
    transform: translate(46px, -35px);
    transform-origin: left center;
  }
  /* the tagline follows the name's horizontal nudge so their left edges line up,
     and closes the gap the name's upward shift opened */
  .stack-card .tagline { transform: translate(46px, -22px); }
  .stack-card .tagline {
    font-size: .85rem;
    font-weight: 300; max-width: 26ch;
    margin: .75rem 0 0; line-height: 1.5;
  }
  .stack-card .stack-foot {
    display: flex; justify-content: flex-end; align-items: baseline; gap: 1rem;
    padding-bottom: .15rem;
  }
  .stack-card .stack-foot .label--accent { font-size: .86rem; letter-spacing: .16em; }
  /* The concept/client label runs up the left edge on a hairline, like a spine. */
  .stack-card .stack-foot .label:not(.label--accent) {
    position: absolute;
    left: calc(clamp(1.5rem, 4vw, 3rem) + .85rem);
    bottom: clamp(1.5rem, 4vw, 3rem);
    transform-origin: left bottom;
    transform: rotate(-90deg);
    white-space: nowrap;
    display: flex; align-items: center; gap: .7rem;
    font-size: .78rem;
    letter-spacing: .16em;
    /* never longer than the card is tall, minus its padding */
    max-width: calc(min(52vh, 330px) - (clamp(1.5rem, 4vw, 3rem) * 2));
    overflow: hidden;
  }
  .stack-card .stack-foot .label:not(.label--accent)::before {
    content: "";
    width: clamp(28px, 5vw, 56px); height: 1px;
    background: currentColor; opacity: .5;
    flex: none;
  }
  /* Hover: a full Nebula gradient rides the card border. */
  .stack-card:hover {
    transform: translateY(-5px);
    border-color: rgba(255,255,255,.14);
    transition: transform 1s var(--ease-out), border-color 1s var(--ease-out), box-shadow 1s var(--ease-out);
  }
  .stack-card:hover::before {
    background:
      linear-gradient(rgba(18,20,44,.34) 0 100%) padding-box,
      linear-gradient(120deg, rgba(59,130,224,.55) 0%, rgba(139,92,246,.55) 42%, rgba(240,114,26,.55) 100%) border-box !important;
    opacity: .1 !important;
    -webkit-mask-image: none !important;
    mask-image: none !important;
    transition: opacity 1s var(--ease-out), background 1s var(--ease-out);
  }

  /* Pinned: while a card is held in the stack it carries a Blaze Orange edge. */
  .stack-card.pinned {
    box-shadow:
      0 0 0 1px rgba(240,114,26,.85),
      0 0 20px rgba(240,114,26,.44),
      0 24px 60px rgba(2,4,14,.5),
      inset 0 1px 0 rgba(255,255,255,.26);
  }
  .stack-card.pinned:hover {
    box-shadow:
      0 0 0 1px rgba(240,114,26,1),
      0 0 28px rgba(240,114,26,.4),
      0 24px 60px rgba(2,4,14,.5);
  }

  /* category pills on the card face */

  /* ---- Work bento (BUILD 107): Muflon-style grid replaces the scroll
     stack. JurisAI wide across the top, CRM + INSTICK
     in the left column, JurisAi Word tall on the right; below, the mirror:
     Aurelia tall on the left, Senora + Noir Auto stacked on the right. Same peek
     mechanics: the live deck pans slowly behind the chips. ---- */

  /* ---- Peek cards (BUILD 106): the deck itself is the card face.
     A pointer-transparent iframe pans slowly behind the chips; it mounts
     only when the card approaches the viewport and animates only while
     on screen. On file:// (no /decks) the pane stays as quiet glass. ---- */
  /* the grid assembles as it arrives — cards fade and rise, never a plain scroll */

  /* they arrive at their own pace — and never travel far enough to sit on a
     neighbour (Cjay, 26 Aug): the difference is time, not distance. */

  /* BUILD 119: a real stagger on top of the slower durations, so the grid
     unfolds card by card as you come down the page rather than all together. */
  /* Frames mount and unmount as you scroll; without this, Chrome's scroll
     anchoring "corrects" for the change and nudges the page a few hundred px. */
  /* BUILD 113: the gloss — one scrim + a faint brand tint over every deck face, decks slightly desaturated,
     so seven very different decks read as one family; the card wakes up (full colour, thinner scrim) on hover. */
  @keyframes peekDrift {
    from { transform: translateY(0) scale(1.02); }
    to   { transform: translateY(-26%) scale(1.02); }
  }
  .chip { position: absolute; z-index: 3; }

  /* ── Card chrome ───────────────────────────────────────────────────────
     The faces are busy, so the chrome keeps to two corners it can own: the
     name plate top-right (over a soft scrim so it reads on any face) and a
     ghost numeral bottom-left, sized differently per piece. Nothing solid,
     nothing that lands on the product's own header. */
  /* the tags share the rail rather than floating over the artwork */
  /* the name plate: one idea, seven shapes — always top-right, always cream */
  /* tags: cream, so they read on a cream frame and on a film alike */
  /* BUILD 119: the poster face — a bespoke, constantly looping miniature per
     project (peeks/*.html). It fills the card exactly, never drifts, and is
     shown at full colour, so the deck gloss/scrim is off wherever one is used. */




  /* ══ Project-card chrome, reworked (BUILD 119) ════════════════════════
     From the reference Cjay sent: white pills over the artwork, the name in
     black with its discipline in violet beneath, lifted off the card by a
     stacked shadow so it reads as sitting above the picture rather than
     printed on it. Top and bottom of every face fade into blur so the pills
     always have somewhere quiet to sit, whatever the face is showing.
     The ghost numerals and their rail are gone with this. ------------- */

  /* the face fills the card again — there is no rail to leave room for */

  /* top and bottom blur, the way the reference does it: a real backdrop
     blur behind a mask, not a dark gradient painted over the picture */

  /* ── the name pill ── */
  /* the title grows when you reach for the card */

  /* ── the bottom pills: the same object, smaller ── */
  /* the one that goes somewhere */
  /* Drawn, not typed: U+2197 is in the emoji set, and iOS and Android will
     happily render it as a blue emoji arrow. A mask keeps it in currentColor. */
  @media (max-width: 620px) {
    /* the pills are sized for a 660px card; on a 390px phone they were eating
       the face */
  }

  /* The stamp/pill mix is retired: from the reference Cjay sent, every card
     now carries the same white pill. name-stamp / name-pill / name-drop are
     left on the elements but no longer style anything. */


  /* Embedded case-study previews inside the popup */
  .cs-embed-wrap { padding: 0 !important; overflow: hidden; }
  .cs-embed {
    display: block;
    width: 100%;
    height: min(72vh, 760px);
    border: 0;
    border-radius: 12px;
    background: #07060F;
  }
  .cs-embed--deck {
    height: auto;
    aspect-ratio: 16 / 10;
    min-height: 560px;
    max-height: 82vh;
  }

  /* Selected work — ORANGE: (accent) */
  section[aria-labelledby="work"] { --sec-accent: var(--orange-blaze); }

  /* NO zoom here. Zoom also scales --pad-x and --max-w, so the .inner grid
     and its spine shifted inward and stopped lining up with the sections
     above — that was the misalignment down the whole page. The size
     reduction is applied to the CONTENT instead, leaving the frame alone. */

  /* Clients — CREAM: editorial, an oversized ghost quote mark, no glass. */
  section[aria-labelledby="clients"] { --sec-accent: var(--cream-light); }
  section[aria-labelledby="clients"] .quote { position: relative; }
  section[aria-labelledby="clients"] .quote blockquote { position: relative; }
  section[aria-labelledby="clients"] .quote blockquote::before {
    content: "\201C";
    position: absolute; left: -0.52em; top: -0.30em;
    font-family: "AmpSwap", var(--font-display); font-weight: 700;
    font-size: 2.6em; line-height: 1;
    color: var(--cream-light); opacity: .16;
  }

  /* Contact — the full NEBULA: the one section with the whole gradient. */
  section[aria-labelledby="contact"] .contact-mail {
    background: var(--gradient);
    -webkit-background-clip: text; background-clip: text;
    color: transparent;
    transition: opacity .3s;
  }
  section[aria-labelledby="contact"] .contact-mail:hover { opacity: .75; }
  section[aria-labelledby="contact"] { padding-bottom: clamp(2rem, 4.5vh, 3rem); }
  section[aria-labelledby="contact"] h2.label--strong::before { background: var(--gradient); }

  /* Light theme: devices designed on dark get proper daylight counterparts. */
  /* BUILD 120: with the hero cream, the capsule can no longer be dark glass
     with cream ink — it becomes light glass with ink type. */
  /* Daylight capsule: the same glass the night one is, not a solid slab —
     low-alpha paper, a highlight along the top edge and the blur doing the
     work (Cjay, 27 Aug). */
  /* The monogram is drawn on its own dark ground, so on light glass it read as
     a murky square with a halo. Sat on a round dark plate it is the mark again,
     and rendering it above its natural size stops the edges breaking up. */
  /* the drop keeps its dark panel — it is a surface over the page, not part of it */
  /* the outline button was cream-on-cream and had all but vanished */

  /* In Daylight the lockup keeps a piece of the night: the mark was drawn for a
     dark ground and the wordmark reads better held against one. */

  /* ---- Daylight, deck era (BUILD 99): cards, glass, sky, scrims ---- */
  /* covered cards recede into soft shadow, not into night */

  .section { padding: clamp(4rem, 12vh, 9rem) var(--pad-x); }

  /* ---- Hero pins; the rest of the page slides up over it ----
     The fixed positioning lives on the MAIN .hero block below — an earlier
     duplicate rule was being overridden by it, which is why the pin never
     took effect in builds 86–87. One rule, one owner. */
  .oversheet { margin-top: var(--hero-h); }
  /* pure spacer — the WORK card is the first visible edge over the hero */
  .oversheet {
    position: relative;
    z-index: 1;
    background: transparent;
  }
  /* Each sheet-card carries its own ground, so the starfield shows between
     them. .sheetstars is the field that sits behind the capabilities card. */


  /* The ampersand is the one glyph Archivo cannot carry at a narrow width
     axis — at wdth 62 it reads as a 3. Every & inside display type is
     wrapped at runtime and set back to a normal width, at a slightly
     smaller size so it still sits with the caps around it. */
  .amp {
    font-style: normal;
    font-variation-settings: "wdth" 100;
    font-weight: 600;
    font-size: .92em;
    padding: 0 .04em;
  }

  /* ── Specks (BUILD 119) ──────────────────────────────────────────────
     The starfield only ever showed on the body, which the opaque panels
     cover — so past the hero the page had no texture at all. Every panel
     now carries the same field of small brand-coloured specks, in BOTH
     themes: brighter on the night grounds, quieter on the papers, so it
     reads as texture rather than dirt. It sits at z-index 0 under the
     content and takes no pointer events. ------------------------------ */
  .sheetcard::after,
  .sheetcard.sheetcard--stack::after {
    content: "";
    position: absolute; inset: 0; z-index: 0;
    pointer-events: none;
    background-color: transparent;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='320'%3E%3Ccircle cx='24' cy='40' r='1.4' fill='%233B82E0' opacity='.55'/%3E%3Ccircle cx='140' cy='18' r='1' fill='%238B5CF6' opacity='.5'/%3E%3Ccircle cx='250' cy='92' r='1.5' fill='%23F0721A' opacity='.42'/%3E%3Ccircle cx='70' cy='150' r='.9' fill='%23F1EEE0' opacity='.42'/%3E%3Ccircle cx='196' cy='205' r='1.3' fill='%233B82E0' opacity='.42'/%3E%3Ccircle cx='30' cy='252' r='1' fill='%238B5CF6' opacity='.45'/%3E%3Ccircle cx='296' cy='176' r='.9' fill='%23E8794A' opacity='.45'/%3E%3Ccircle cx='110' cy='96' r='.8' fill='%23F1EEE0' opacity='.3'/%3E%3Ccircle cx='172' cy='288' r='1.1' fill='%23F0721A' opacity='.38'/%3E%3Ccircle cx='264' cy='300' r='.8' fill='%233B82E0' opacity='.38'/%3E%3Ccircle cx='88' cy='214' r='1.2' fill='%23E8794A' opacity='.3'/%3E%3Ccircle cx='214' cy='128' r='.8' fill='%238B5CF6' opacity='.35'/%3E%3C/svg%3E");
    background-repeat: repeat;
    opacity: .55;
  }
  /* On cream the specks need MORE presence, not less: the brand hues are mid
     tones, so against #F2EFE5 they wash out where they would glow on near
     black. Cjay: the cream panels should carry the same field as the night
     ones. */
  /* the panels that stay dark in Daylight keep the night strength */
  @media (prefers-reduced-motion: reduce) { .sheetcard::after { opacity: .3; } }

  .sheetcard {
    position: relative;
    background: var(--ground);
    border-radius: clamp(18px, 2.4vw, 30px);
    box-shadow:
      0 -1px 0 rgba(255,255,255,.10),
      0 -34px 70px rgba(2,4,14,.62);
    border-top: 1px solid rgba(255,255,255,.07);
  }
  /* ---- Approach →︎ Capabilities handoff (transition lab option 03) ----
     Approach pins; Capabilities climbs over it; the card underneath
     scales back and dims as it is covered, so the depth is visible. */
  /* top/bottom is chosen per card by the deck driver: short cards pin at
     the top, cards taller than the viewport pin at the bottom so none of
     their content is scrolled past unreachably. */
  .stackpin {
    position: sticky;
    top: 0;
    z-index: 1;
  }
  .sheetcard--approach {
    position: relative;
    z-index: 2;
    border-radius: clamp(18px, 2.4vw, 30px) clamp(18px, 2.4vw, 30px) 0 0;
    box-shadow:
      0 -1px 0 rgba(255,255,255,.10),
      0 -34px 70px rgba(2,4,14,.66);
    border-top: 1px solid rgba(255,255,255,.08);
    transform-origin: 50% 0;
    will-change: transform;
  }
  /* The receding card is DARKENED by a scrim, never faded: lowering its own
     opacity would make it translucent and show the fixed hero through it. */
  .sheetcard--approach::after {
    content: "";
    position: absolute; inset: 0;
    border-radius: inherit;
    background: #04030A;
    opacity: var(--recede, 0);
    pointer-events: none;
    z-index: 4;
  }
  /* The card is sized to its contents — label + panels — not to the
     section's usual generous rhythm. */
  .sheetcard--approach > .section {
    padding-top: clamp(1.1rem, 2.4vh, 1.7rem);
    padding-bottom: clamp(1.5rem, 3.2vh, 2.4rem);
  }
  .approach-lede-wrap { margin-top: clamp(.9rem, 2vh, 1.4rem); }
  /* The capabilities card sits ON the star field rather than on the ground,
     so the sky reads continuously behind its rows. */
  .capsky {
    position: relative;
    background: rgba(7, 6, 15, .55);
    overflow: hidden;
  }
  /* The first sheet fades IN over the hero instead of covering it along a
     hard edge: its top is mask-transparent, so the starfield shows through
     and the daylight builds gradually. */
  .sheetcard--caps {
    -webkit-mask-image: linear-gradient(180deg, transparent 0, rgba(0,0,0,.55) 90px, #000 clamp(155px, 20vh, 215px));
    mask-image: linear-gradient(180deg, transparent 0, rgba(0,0,0,.55) 90px, #000 clamp(155px, 20vh, 215px));
  }

  /* Work is now the FIRST card over the hero — trimmed top padding so the
     label sits close to the leading edge. Caps' bottom trim kept from the
     old caps/work join; it now meets Clients and reads fine. */
  .sheetcard--caps > .capsky > .section { padding-bottom: clamp(2rem, 5vh, 3.5rem); }
  .sheetcard--work > .section { padding-top: clamp(3.2rem, 7.5vh, 5.2rem); }
  .sheetcard--work > .section { padding-bottom: clamp(2.2rem, 5vh, 3.5rem); }
  .sheetcard--diff > .section { padding-top: clamp(2.5rem, 6vh, 4rem); }
  /* BUILD 119: the first card meets the hero, not another card — so it carries
     no seam at all: no top border, no gradient hairline, no lip shadow, no
     rounded lip. Written as a two-class selector on purpose — .sheetcard--stack
     defines those same properties further down the file, and at equal
     specificity it would simply win. */
  /* Cjay, 26 Aug: EVERY panel, not just the first two. With the deck retired
     these were the lip of a card riding over another card — there is no such
     thing on the page any more. Two-class selector because .sheetcard--stack
     sets the same properties further down at equal specificity. */
  .sheetcard.sheetcard--stack {
    border-top: 0;
    box-shadow: none;
    border-radius: 0;
  }
  .sheetcard.sheetcard--stack::before { display: none; }
  .capsky > .sheetstars {
    position: absolute; inset: 0;
    mix-blend-mode: screen;
    pointer-events: none;
    z-index: 0;
  }
  .capsky > .sheetstars canvas { width: 100%; height: 100%; display: block; }
  .capsky > .section { position: relative; z-index: 1; }
  /* Every section is its own card and rides over the one before it, so the
     whole page reads as a deck. Each carries the same leading edge, which
     is also the border between one section and the next. */
  .sheetcard--stack {
    position: relative;
    border-radius: clamp(18px, 2.4vw, 30px) clamp(18px, 2.4vw, 30px) 0 0;
    box-shadow:
      0 -1px 0 rgba(255,255,255,.10),
      0 -34px 70px rgba(2,4,14,.66);
    border-top: 1px solid rgba(255,255,255,.08);
    transform-origin: 50% 0;
    will-change: transform;
  }
  /* ascending, so each card covers the one above it */
  .sheetcard--work    { z-index: 1; }
  .sheetcard--caps    { z-index: 2; }
  .sheetcard--diff    { z-index: 3; }
  .sheetcard--clients { z-index: 4; }
  .sheetcard--faq     { z-index: 5; }
  .sheetcard--contact { z-index: 6; }

  /* the receding scrim — darkens, never fades (a faded card would go
     translucent and show the fixed hero straight through it) */
  .sheetcard--stack::after {
    content: "";
    position: absolute; inset: 0;
    border-radius: inherit;
    background: #04030A;
    opacity: var(--recede, 0);
    pointer-events: none;
    z-index: 4;
  }
  .sheetcard--stack::before {
    content: "";
    position: absolute; left: 0; right: 0; top: -1px;
    height: 1px;
    background: linear-gradient(90deg,
      transparent 0%, var(--blue) 18%, var(--violet) 50%, var(--orange-blaze) 82%, transparent 100%);
    opacity: .45;
    pointer-events: none;
    z-index: 5;
  }
  .sheetcard--approach::before {
    content: "";
    position: absolute; left: 0; right: 0; top: -1px;
    height: 1px;
    background: linear-gradient(90deg,
      transparent 0%, var(--blue) 18%, var(--violet) 50%, var(--orange-blaze) 82%, transparent 100%);
    opacity: .5;
    pointer-events: none;
  }

  /* a hairline of brand colour along the leading edge */
  .oversheet--legacy::before {
    content: "";
    position: absolute; left: 0; right: 0; top: -1px;
    height: 1px;
    border-radius: inherit;
    background: linear-gradient(90deg,
      transparent 0%, var(--blue) 18%, var(--violet) 50%, var(--orange-blaze) 82%, transparent 100%);
    opacity: .5;
    pointer-events: none;
  }

  .inner {
    width: 100%;
    max-width: var(--max-w);
    margin: 0 auto;
    display: flex;
    gap: var(--spine-gap);
    align-items: stretch;
  }

  /* BUILD 119: the gradient bar down the left of every panel is gone at
     Cjay's request. The element stays in the markup (it is decorative and
     aria-hidden) so the panels keep their measure; only the paint is off. */
  .spine {
    flex: none;
    width: 0;
    background: none;
  }

  .content { flex: 1; min-width: 0; }

  /* ===== Hero ========================================================== */

  /* ===== Hero nav: plain anchors, no effects ===== */
  .build-stamp {
    position: absolute; left: 14px; bottom: 12px; z-index: 6;
    font-family: "AmpSwap", var(--font-mono); font-size: .58rem;
    letter-spacing: .18em; color: var(--cream-light); opacity: .35;
  }
  /* Fixed bar, links in page order, 20% transparent so the page reads
     through it. Lives OUTSIDE .hero — the hero's stacking context would
     otherwise trap it beneath the oversheet. */
  /* BUILD 119: the nav is a pinned capsule, not a full-width bar. It floats
     clear of the page, carries the monogram, sits above everything at z-index
     90, and tightens once you leave the top of the page. */
  /* the CTA rides inside the capsule now, filled rather than outlined */
  /* pinned state */

  /* ── The nav drop (BUILD 120) ─────────────────────────────────────────
     Hovering "What we build" in the capsule drops the eight disciplines
     underneath it, each going straight to its own page, plus one link to the
     section itself. Opens on hover AND on keyboard focus; the wrapper's
     padding-top is the bridge that stops it closing as the pointer travels
     from the link down into the menu. ---------------------------------- */
  /* the caret is the only signal that this one opens — it turns over when it does */
  /* `.open` is here too: on a pointer device a CLICK on the item sets that
     class, and without this the menu stayed invisible — so clicking the item
     did nothing at all, since it no longer navigates either. */

  /* ── The drop's preview panel (BUILD 120) ─────────────────────────────
     lab-navdrop option 05. The panel on the left previews whichever service
     the pointer is on — and it shows THAT TILE'S OWN MINIATURE, cloned live
     out of the What we build bento, so the two can never drift apart. The
     clone needs `.tile.demo` for the miniatures' constant-motion state and
     the `--ill-*` variables `.svc` normally provides; every other thing a
     .tile carries is stripped back off below. --------------------------- */


  @media (max-width: 760px) {
    /* on a phone the capsule is already edge to edge — a drop panel under it
       would cover the page, so the link just goes to the section */
  }



  /* the theme toggle is an icon: sun while it is dark, moon while it is light */

  .galaxy-bg {
    position: absolute; inset: 0; z-index: 0;
    opacity: 0; animation: orbIn 1.6s var(--ease-out) .2s forwards;
    /* The blend lives HERE, not on the canvas: z-index + the opacity animation
       isolate this element, so a blend on the child canvas would see nothing
       behind it and render raw black. Blending the isolated group itself
       composites against the hero's nebula — black vanishes, stars add. */
    mix-blend-mode: screen;
  }
  .galaxy-bg canvas { width: 100%; height: 100%; display: block; }


  /* ── BUILD 119: bottom-aligned hero (lab-hero-layout option 11) ──────
     The lockup and the message sit on the bottom edge of the hero and the
     disciplines run as a band along the very top, under the capsule. The
     nebula gets the middle of the block instead of being crowded out. ---- */
  :root { --hero-h: 60svh; }
  /* the block spans 70% of the panel and is centred in it. The copy was pulled
     150px left of that block, which left the whole right half of the hero empty
     — it now starts at the block's own left edge (Cjay, 26 Aug). */
  .hero .inner {
    align-self: stretch; width: 100%; max-width: var(--max-w); margin: 0 auto;
    display: flex;
  }
  /* the three pieces are spread across the full height of that block rather
     than bunched at its foot, so the hero fills its measure top to bottom */
  .hero .content {
    flex: 1; min-width: 0;
    display: flex; flex-direction: column; justify-content: space-between;
    gap: clamp(.8rem, 2vh, 1.4rem);
  }
  @media (max-width: 1100px) {
    .hero .inner { width: auto; max-width: none; }
  }
  .hero-lockup { display: flex; align-items: center; gap: .9rem;
    animation: rise .9s var(--ease-out) .2s both; }
  .hero-mono { width: 38px; height: auto; display: block; }
  .hero-word {
    font-family: "AmpSwap", var(--font-display);
    font-variation-settings: "wdth" 112, "wght" 300;
    text-transform: uppercase; white-space: nowrap;
    font-size: clamp(1rem, 1.6vw, 1.35rem);
    letter-spacing: .26em; line-height: 1; margin: 0;
  }
  .hero .hero-headline {
    text-align: left;
    font-size: clamp(1.5rem, 4.1vw, 3.55rem);
    font-variation-settings: "wdth" 78;
    line-height: 1.02;
    margin: 0;
  }
  /* Brand entrance: NOVASTRUM types itself, then the star arrives like an
     asteroid — big, blurred and off-course, settling into place — and blinks
     ONCE to put the mark in focus. Plays once per landing, never loops. */
  .hero-brand { display: flex; align-items: center; gap: clamp(.28rem, .8vw, .55rem); min-height: 1.15em; letter-spacing: .05em; }
  .hb-word { display: inline-flex; align-items: center; white-space: nowrap; }
  /* Star and caret hide themselves ONLY when the entrance is going to play
     (html.hb-anim, set inline beside the hero). Without that class the hero is
     simply the finished picture — which is what a phone that never got to run
     the animation must still see. */
  .hb-caret { display: inline-block; width: .06em; height: .9em; margin-left: .09em; background: currentColor; opacity: 0; }
  .hb-anim .hb-caret { opacity: 1; animation: hbCaret .8s steps(1) infinite; }
  @keyframes hbCaret { 50% { opacity: 0; } }
  .hb-caret.done { animation: none; opacity: 0; transition: opacity .25s .25s; }
  .hb-tagline { min-height: 1.3em; }
  .hb-caret--tag { visibility: hidden; height: 1em; }
  .hb-caret--tag.on { visibility: visible; }
  .hb-star { height: 1.06em; width: auto; display: block; will-change: transform, filter, opacity; }
  .hb-anim .hb-star { opacity: 0; }
  .hb-star.in { animation: hbAsteroid 1.45s cubic-bezier(.16, 1, .3, 1) forwards; }
  /* From the BACK: a point of light far out in space, growing as it
     approaches, tumbling slightly, a touch of overshoot on arrival. */
  @keyframes hbAsteroid {
    0%   { opacity: 0; transform: scale(.04); filter: blur(2px); }
    40%  { opacity: 1; }
    78%  { transform: scale(1.12); filter: blur(0); }
    100% { opacity: 1; transform: none; filter: none; }
  }
  .hb-starwrap { position: relative; display: inline-block; line-height: 0; }
  /* The blink is a single point-flash at the star's core — not a glow on the
     whole mark. */
  .hb-flash { position: absolute; inset: 0; margin: auto; width: 34%; height: 34%;
    border-radius: 50%; pointer-events: none; opacity: 0;
    background: radial-gradient(circle, rgba(255, 249, 232, .95) 0%, rgba(255, 216, 150, .5) 42%, transparent 70%); }
  .hb-flash.go { animation: hbFlash .5s ease-out 1 both; }
  @keyframes hbFlash {
    0%   { opacity: 0; transform: scale(.35); }
    35%  { opacity: 1; transform: scale(1.7); }
    100% { opacity: 0; transform: scale(2.4); }
  }
  @media (prefers-reduced-motion: reduce) {
    .hb-star { opacity: 1 !important; animation: none !important; }
    .hb-caret { display: none; }
  }
  .hero .hero-cta { justify-content: flex-start; margin-top: 0; }
  .hero .hero-lockup { flex: none; }
  /* The ends move toward the headline. MARGINS, not transforms: every one of
     these elements runs the shared `rise` entrance with fill-mode `both`, and
     that keyframe ends on `transform: translateY(0)` — so a declared transform
     here is overwritten the moment the animation settles. And margins get eaten
     by space-between, which redistributes the free space they consume — so the
     offsets are relative `top`, which is exact and immune to both. */
  .hero .hero-lockup { position: relative; top: 40px; }
  .hero .hero-cta    { position: relative; top: -40px; }
  @media (max-width: 1100px) {
    .hero .hero-lockup, .hero .hero-cta { top: 0; }
  }
  .hero-rail {
    display: flex; gap: 2.4rem; overflow: hidden;
    font-family: "AmpSwap", var(--font-mono); font-size: .6rem; letter-spacing: .18em;
    text-transform: uppercase; color: var(--ink-muted); white-space: nowrap;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  }
  .hero-rail--top { position: absolute; top: 0; z-index: 2;
    left: calc((100% - min(var(--max-w), 100% - 2 * var(--pad-x))) / 2 + var(--spine-gap));
    right: calc((100% - min(var(--max-w), 100% - 2 * var(--pad-x))) / 2);
    padding: .8rem clamp(1.5rem, 4vw, 4rem);
    border-bottom: 1px solid var(--rule);
    animation: rise 1s var(--ease-out) .5s both; }
  .hero-rail div { display: flex; gap: 2.4rem; animation: railslide 34s linear infinite; }
  @keyframes railslide { to { transform: translateX(-100%); } }
  @media (prefers-reduced-motion: reduce) { .hero-rail div { animation: none; } }
  @media (max-width: 700px) {
    .hero .hero-headline { font-size: clamp(1.3rem, 5.6vw, 1.8rem); }
  }

  .hero {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 0;
    overflow: hidden;
    height: var(--hero-h);
    min-height: var(--hero-h);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: clamp(5rem, 11vh, 7rem) clamp(1.25rem, 3vw, 3rem) clamp(2rem, 5vh, 3.5rem);
    /* Blue-to-orange ambient ground, teal-dominant, orange rising lower right,
       one faint violet breath top-right so the blend has depth. */
    /* Deep space: a violet nebula band running the diagonal, magenta and
       orange blooms inside it, everything sitting on near-black indigo. */
    /* Flat Deep Space — no colour washes. The streaks carry the hero. */
    background: #07060F;
  }

  /* ── BUILD 119: the stacking deck is retired ─────────────────────────
     The hero no longer sits fixed with the page riding over it, and the
     section cards no longer pin and recede under one another. Everything is
     in normal flow. These were the small-screen overrides; they are now the
     only behaviour, so the layout is the same at every width.
     The two drivers (hero recede, section deck) return early. -------- */
  .hero { position: relative !important; top: auto; }
  .oversheet { margin-top: 0; }
  .stackpin { position: relative !important; top: auto !important; bottom: auto !important; }
  .sheetcard--approach, .sheetcard--stack { transform: none !important; --recede: 0 !important; }
  @media (max-width: 700px) {
    .hero { height: auto; min-height: auto; padding-bottom: 2.5rem; }
  }

  /* BUILD 120: in Daylight the hero is cream, not a window onto space. It
     inherits the light tokens like any other panel; only the starfield needs
     handling, and that is done on .galaxy-bg below. */
  /* The Lightspeed canvas draws bright streaks on black and composites with
     `screen`, which on cream does nothing at all. Inverting the canvas turns
     those into dark streaks on white, and `multiply` then keeps the streaks
     and drops the white — the same starfield, drawn in ink. */
  /* The canvas clears to transparent, so in Daylight it just draws normally —
     no blend, no invert. Inverting turned the brand hues into their opposites;
     the colours come from TINTS_DAY in the script instead. */

  /* Hero spine: the gradient rule with the descriptor set vertically above it. */
  .spine-col {
    flex: none;
    width: 16px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 18px;
    animation: rise .9s var(--ease-out) .1s both;
  }

  .spine-label {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    font-family: "AmpSwap", var(--font-mono);
    font-size: 12px;
    /* tracking is what gives the label its length down the column */
    letter-spacing: .58em;
    text-transform: uppercase;
    color: var(--ink);
    white-space: nowrap;
    flex: none;
  }

  .spine-line {
    width: var(--spine-w);
    flex: 1;
    min-height: 60px;
    background: var(--gradient);
    background: var(--gradient-ok);
    transform-origin: top;
    animation: draw 1s var(--ease-out) .35s both;
  }

  /* Iridescent spheres — hero only, held above the footer rule. */
  .orbs {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    overflow: hidden;
    opacity: 0; animation: orbIn 1.6s var(--ease-out) .5s forwards;
  }
  .orbs svg { width: 100%; height: 100%; display: block; }

  /* Light glass needs a darker field behind it or everything washes out. */

  .monogram { width: clamp(58px, 6.4vw, 98px); height: auto; display: block; }

  .orb {
    animation: drift var(--dur) var(--delay) ease-in-out infinite alternate;
    will-change: transform;
  }

  /* Entrance: each shape rises and settles once on load, staggered,
     then the outer group's drift carries on underneath. */
  .pop {
    transform-box: fill-box;
    transform-origin: center;
    animation: pop 1.1s var(--ease-out) var(--delay) both;
  }

  .tw { animation: twinkle var(--twp) var(--twd) ease-in-out infinite alternate; }
  @keyframes twinkle { from { opacity: .15; } to { opacity: 1; } }

  /* Shooting stars: each fires for ~1.4s of its cycle, then the sky is
     still until its next pass. Head leads, tail trails via the gradient. */
  .shoot-run {
    animation: shootRun var(--sp) var(--sd) linear infinite;
    opacity: 0;
  }
  @keyframes shootRun {
    0%    { transform: translate(0, 0);       opacity: 0; }
    1%    { opacity: 1; }
    10%   { transform: translate(460px, 0);   opacity: 1; }
    12%   { transform: translate(520px, 0);   opacity: 0; }
    100%  { transform: translate(520px, 0);   opacity: 0; }
  }

  /* The left star arrives slowly, then breathes. */
  .star-in {
    transform-box: fill-box; transform-origin: center;
    animation: starIn 1.6s var(--ease-out) .9s both;
  }
  @keyframes starIn { from { opacity: 0; transform: scale(.45); } to { opacity: 1; transform: scale(1); } }
  .star-pulse { animation: starBreathe 5s 2.5s ease-in-out infinite alternate; }
  @keyframes starBreathe { from { opacity: .78; } to { opacity: 1; } }

  .star-breathe {
    transform-box: fill-box; transform-origin: center;
    animation: starBreathe 6s ease-in-out infinite alternate;
  }
  .nova-lens { animation: novaPulse 6s ease-in-out infinite alternate; }

  .nova { animation: novaPulse 6s ease-in-out infinite alternate; transform-box: fill-box; transform-origin: center; }
  @keyframes novaPulse { from { opacity: .8; } to { opacity: 1; } }

  @keyframes pop {
    from { opacity: 0; transform: translateY(34px) scale(.82); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
  }

  @keyframes orbIn { to { opacity: 1; } }
  @keyframes drift { to { transform: translate(var(--dx), var(--dy)); } }

  /* BUILD 119: the ticker hero sits directly on the nebula — the glass panel
     that used to box the wordmark lockup is gone with it. Keeping the panel
     around a short hero just draws a large empty rectangle. */
  .hero .inner {
    position: relative; z-index: 1;
    max-width: var(--max-w);
    padding: 0;
    background: none; border: 0; border-radius: 0;
    -webkit-backdrop-filter: none; backdrop-filter: none;
    box-shadow: none;
  }

  .hero-header {
    display: flex;
    justify-content: flex-end;
    align-items: baseline;
    gap: 1rem;
    margin-bottom: clamp(.5rem, 2vh, 1.25rem);
    animation: rise .9s var(--ease-out) .15s both;
  }

  .toggle {
    background: none; border: none; padding: 0; cursor: pointer;
    color: var(--ink-muted);
    font-family: "AmpSwap", var(--font-mono); font-size: 12px;
    letter-spacing: .14em; text-transform: uppercase;
    transition: color .2s;
  }
  .toggle:hover { color: var(--accent); }

  .mark {
    font-family: "AmpSwap", var(--font-display);
    font-variation-settings: "wdth" 112, "wght" 300;
    text-transform: uppercase;
    color: var(--ink);
    white-space: nowrap;
    display: block;
    font-size: clamp(1.7rem, 6.4vw, 5.4rem);
    letter-spacing: .22em;
    line-height: 1.1;
    /* letters stretched to twice their height — the width stays as set, so the
       lockup gets tall and narrow rather than simply bigger */
    transform: scaleY(2.7);
    transform-origin: left center;
    animation: rise 1s var(--ease-out) .3s both;
  }
  .mark .w1, .mark .w2 { display: inline; }
  /* narrow screens: the line becomes a stack rather than shrinking away */
  @media (max-width: 720px) {
    .statement p br { display: none; }
    .statement p { max-width: 44ch; }
    .mark { white-space: normal; font-size: clamp(1.7rem, 8.5vw, 2.6rem); letter-spacing: .14em; line-height: 1.02; transform: scaleY(2.2); }
    .mark .w1, .mark .w2 { display: block; }
  }
  .mark span { display: block; }

  .sr-only {
    position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }

  .statement {
    display: flex; justify-content: flex-end;
    margin-top: clamp(1.75rem, 5vh, 3.25rem);
    /* pull past the panel's own padding so the text sits 10px off its border */
    margin-right: 0;
    animation: rise 1s var(--ease-out) .45s both;
  }
  .statement p {
    /* wide enough to fall in exactly two lines, flush right */
    max-width: 62ch;
    font-size: clamp(.95rem, 1.25vw, 1.15rem);
    line-height: 1.6; font-weight: 300;
    text-wrap: balance;
    text-align: right;
    margin: 0;
  }

  .hero-footer {
    display: flex; justify-content: flex-end; align-items: baseline;
    gap: 22px;
    margin-top: clamp(2rem, 6vh, 3.5rem);
    padding-top: 1rem;
    border-top: 1px solid var(--rule);
    animation: rise 1s var(--ease-out) .6s both;
  }

  /* ---- Outcome-first hero: headline, CTAs, credibility strip ---- */
  .hero-headline {
    font-family: "AmpSwap", var(--font-display);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: -.02em;
    line-height: 1.08;
    font-size: clamp(1.35rem, 2.9vw, 2.4rem);
    text-align: right;
    text-wrap: balance;
    margin: clamp(1.75rem, 5vh, 3.25rem) 0 0;
    animation: rise 1s var(--ease-out) .4s both;
  }
  .hero-headline + .statement { margin-top: clamp(.7rem, 1.8vh, 1.1rem); }
  .hero-cta {
    display: flex; justify-content: flex-end; align-items: center;
    flex-wrap: wrap;
    gap: .8rem;
    margin-top: clamp(1.2rem, 3vh, 1.9rem);
    animation: rise 1s var(--ease-out) .55s both;
  }
  .btn {
    display: inline-block;
    font-family: "AmpSwap", var(--font-mono);
    font-size: .72rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    text-decoration: none;
    padding: .85em 1.5em;
    border-radius: 100vw;
    transition: color .25s var(--ease-out), background-color .25s var(--ease-out), border-color .25s var(--ease-out);
  }
  /* blaze orange lives ONLY on the primary action in the hero */
  .btn--primary { color: var(--orange-blaze); border: 1px solid var(--orange-blaze); }
  .btn--primary:hover { background: var(--orange-blaze); color: #07060F; }
  .btn--ghost { color: var(--cream-light); border: 1px solid var(--glass-border); }
  .btn--ghost:hover { border-color: var(--cream-light); }
  .hero-strip {
    text-align: right;
    margin-top: clamp(1.1rem, 2.6vh, 1.6rem);
    animation: rise 1s var(--ease-out) .65s both;
  }
  /* short viewports: trim the new block's air so the panel never clips */
  @media (max-height: 760px) {
    .hero-headline { font-size: clamp(1.15rem, 2.2vw, 1.7rem); margin-top: 1.1rem; }
    .hero-cta { margin-top: .9rem; }
    .hero-strip { margin-top: .8rem; }
    .hero-footer { margin-top: 1.2rem; }
  }
  @media (max-width: 560px) {
    .hero-cta { flex-direction: column; align-items: stretch; }
    .btn { text-align: center; }
  }

  /* ===== Approach ====================================================== */
  .plist { margin-top: clamp(2rem, 5vh, 3.5rem); }

  .prow {
    display: grid;
    grid-template-columns: 4rem minmax(9rem, 1fr) 2.2fr;
    gap: clamp(1rem, 3vw, 2.5rem);
    align-items: baseline;
    padding: clamp(1.5rem, 4vh, 2.5rem) 0;
    border-top: 1px solid var(--rule);
  }
  .prow:last-child { border-bottom: 1px solid var(--rule); }
  .pindex { align-self: start; }

  .ptitle {
    font-family: "AmpSwap", var(--font-display);
    font-weight: 700;
    font-size: clamp(1.5rem, 3.2vw, 2.5rem);
    letter-spacing: -.02em;
    line-height: 1;
    text-transform: uppercase;
  }

  .pdef {
    font-size: clamp(1rem, 1.2vw, 1.15rem);
    line-height: 1.5; font-weight: 300; text-wrap: pretty;
  }

  /* ===== Capabilities: rows replaced by the bento in BUILD 97 ========== */

  /* Aligned to the rows' text column (past the numeral) and set at the same
     size as the row copy, per the red box on the screenshot. */
  .caps-foot {
    margin: clamp(1.6rem, 3vw, 2.4rem) 0 0;
    margin-left: calc(clamp(4.5rem, 7vw, 6.5rem) + clamp(1rem, 3vw, 3rem));
    max-width: 92ch;
    font-size: 1.06rem;
    line-height: 1.6;
    color: var(--ink-muted);
    padding-top: 1.1rem;
  }
  @media (max-width: 620px) { .caps-foot { margin-left: 0; } }

  /* ---- What we build: gradient hairline + discipline bento ---- */
  .wwb-rule {
    border: 0; height: 1px;
    margin: clamp(2rem, 4.5vh, 3rem) 0 clamp(1.7rem, 3.6vh, 2.4rem);
    background: linear-gradient(90deg,
      transparent 0%, var(--blue) 18%, var(--violet) 50%, var(--orange-blaze) 82%, transparent 100%);
    opacity: .35;
  }
  /* ---- What we build: the alive bento (BUILD 111, from lab v10) ----
     Tokens the tiles need, scoped here so the theme blocks stay untouched. */
  .svc { --ill-line: rgba(241,238,224,.55); --ill-fill: rgba(241,238,224,.07); --tint-a: .16;
    --paper: #ECE6D4; --paper-ink: #16131F; --paper-muted: #5E5B70; --paper-rule: rgba(22,19,31,.18); --paper-line: rgba(22,19,31,.64); --paper-fill: rgba(22,19,31,.055);
    --slate: #22213A; --slate-ink: var(--cream-light); }
  /* ---- type on the tiles only (the stage panels above keep the site's .apanel type) ---- */
  .tile h3 { font-family: "AmpSwap", var(--t-font); font-weight: 700; text-transform: var(--t-case); font-variation-settings: "wdth" var(--t-wdth), "wght" var(--t-wght); font-size: clamp(.92rem, 1.2vw, 1.05rem); letter-spacing: var(--t-ls); line-height: 1.08; margin: 0; }
  /* ===== the bold grid: three tiers, rows of different heights ===== */
  .svc { margin-top: clamp(1.6rem, 3.5vh, 2.6rem); --r1: clamp(90px, 11.2vh, 106px); --rFlow: clamp(108px, 13.5vh, 130px); --r5: clamp(110px, 14vh, 134px); --r6: clamp(98px, 12.2vh, 114px); --r7: clamp(110px, 14vh, 134px);
    display:grid; grid-template-columns: repeat(12, minmax(0,1fr)); gap: clamp(.38rem, .65vw, .5rem);
    grid-template-rows: minmax(var(--r1), auto) minmax(var(--r1), auto) 32px minmax(var(--rFlow), auto) minmax(var(--r5), auto) minmax(var(--r5), auto);
    grid-template-areas:
      "ai   ai   ai   ai   ai   ai   ai   ai   crm  crm  crm  crm"
      "ai   ai   ai   ai   ai   ai   ai   ai   crm  crm  crm  crm"
      "tape tape tape tape tape tape tape tape tape tape tape tape"
      "flow flow flow flow flow flow flow flow flow flow flow flow"
      "com  com  com  com  web  web  web  web  docs docs docs docs"
      "com  com  com  com  ux   ux   ux   ux   brand brand brand brand"; }
  .tile { justify-content: flex-start; align-items: stretch; gap: .26rem; padding: clamp(.55rem, .85vw, .75rem) clamp(.65rem, 1vw, .9rem); }
  .tile > * { position: relative; z-index: 1; } .tile > .gloss { z-index: 0; }
  .tile > .tint { position:absolute; inset:0; border-radius: inherit; pointer-events:none; z-index:0; background: radial-gradient(55% 45% at 100% 0%, color-mix(in srgb, var(--ac) calc(var(--tint-a) * 100%), transparent) 0%, transparent 70%); }
  .tile--blue { --ac: var(--blue); } .tile--violet { --ac: var(--violet); } .tile--blaze { --ac: var(--orange-blaze); }
  .tile:is(:hover,.demo) .anum { color: var(--ac); }
  .tile .head { display:flex; align-items:center; justify-content: space-between; }
  .tile .head .dot { width: 5px; height: 5px; border-radius: 50%; background: var(--ac); opacity: .8; box-shadow: 0 0 9px var(--ac); }
  .tile p { max-width: 38ch; text-wrap: pretty; }
  .ill { color: var(--ill-line); height: clamp(52px, 5vw, 66px); display:flex; align-items:center; justify-content:center; margin: .15rem 0 .3rem; }
  .ill svg { width: 100%; height: 100%; overflow: visible; } .ill .ac { color: var(--ac); } .ill .ff { fill: var(--ill-fill); }
  .ill text { font-family: "AmpSwap", var(--font-mono); letter-spacing: .08em; text-transform: uppercase; }
  .ill .btn { cursor: pointer; } .ill .btn:hover rect { filter: brightness(1.12); }
  .kw { display:flex; flex-wrap: wrap; gap: .22rem; margin-top: auto; padding-top: .3rem; }
  .kw li { font-family: "AmpSwap", var(--font-mono); font-size: .54rem; letter-spacing: .11em; text-transform: uppercase; line-height: 1; padding: .4em .55em .36em; border: 1px solid var(--rule); border-radius: 999px; color: var(--ink-muted); white-space: nowrap; transition: border-color .3s var(--ease-out), color .3s var(--ease-out); }
  .tile:is(:hover,.demo) .kw li { border-color: color-mix(in srgb, var(--ac) 55%, transparent); color: var(--ink); }
  /* side layout: copy left, drawing right */
  .tile--side { display:grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-template-rows: auto auto auto 1fr; column-gap: clamp(.6rem, 1.1vw, 1rem); grid-template-areas: "head ill" "h ill" "p ill" "kw ill"; align-items: start; }
  .tile--side > .head { grid-area: head; } .tile--side > h3 { grid-area: h; } .tile--side > p { grid-area: p; } .tile--side > .kw { grid-area: kw; align-self: end; }
  .tile--side > .ill { grid-area: ill; align-self: center; height: 100%; max-height: 100%; margin: 0; }
  /* --- tier XL: condensed poster type, generous padding, giant ghost --- */
  .tile--xl { padding: clamp(.8rem, 1.35vw, 1.15rem) clamp(.9rem, 1.55vw, 1.35rem); }
  .svc .tile--xl h3 { font-variation-settings: "wdth" var(--xl-wdth), "wght" var(--xl-wght); font-size: var(--xl-size); line-height: .88; letter-spacing: var(--xl-ls); }
  .tile--xl p { font-size: clamp(.74rem, .85vw, .82rem); max-width: 34ch; line-height: 1.45; }
  .tile--ai { grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); }
  .tile--ai > .ill { max-height: clamp(172px, 16.8vw, 214px); } .tile--flow > .ill { max-height: clamp(94px, 9vw, 112px); } .tile--web > .ill { max-height: 94px; } .tile--brand > .ill { max-height: clamp(118px, 11.3vw, 140px); }
  /* --- the statement strip: extended type on paper --- */
  .tile--flow { grid-template-columns: minmax(0, .9fr) minmax(0, 1.05fr) minmax(0, 1.05fr); grid-template-areas: "head head ill" "h kw ill"; grid-template-rows: auto 1fr; padding: clamp(.8rem, 1.4vw, 1.2rem) clamp(1rem, 1.7vw, 1.5rem); }
  .tile--flow > .kw { grid-area: kw; align-self: center; margin: 0 0 0 clamp(1rem, 2.4vw, 2.2rem); padding: 0; gap: .35rem; flex-wrap: wrap; }
  .tile--flow > .kw li { font-size: .62rem; padding: .5em .8em .45em; } .tile--flow > .kw li.kw-more { flex-basis: 100%; }
  .tile--flow > h3 { align-self: center; }
  .svc .tile--flow h3 { font-variation-settings: "wdth" var(--flow-wdth), "wght" var(--flow-wght); font-size: var(--flow-size); line-height: .95; letter-spacing: var(--flow-ls); }
  .tile--flow p { font-size: clamp(.74rem, .85vw, .82rem); max-width: 46ch; }
  /* --- tier tall --- */
  .tile--saas .ill { height: clamp(140px, 13vw, 168px); flex: none; } .tile--saas { gap: .3rem; }
  .tile--saas h3 { font-size: clamp(1rem, 1.4vw, 1.2rem); }
  .tile--com .ill { height: clamp(140px, 13vw, 164px); } .tile--com h3 { font-size: clamp(1.7rem, 2.7vw, 2.3rem); margin-top: auto; } .tile--com > .kw { margin-top: .5rem; }
  .tile--web h3 { font-size: clamp(1.55rem, 2.5vw, 2.15rem); }
  .tile--web > .kw { align-self: start; margin-top: .5rem; gap: .32rem; } .tile--web > .kw li { font-size: .6rem; padding: .48em .75em .42em; } .tile--web { grid-template-columns: minmax(0, 1fr) minmax(0, .85fr); }
  /* --- tier compact: mono title, drawing is the hero, no paragraph --- */
  .tile--s { display:grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); grid-template-rows: auto auto 1fr; grid-template-areas: "head ill" "h ill" "kw ill"; column-gap: .6rem; padding: .55rem .7rem .5rem; align-items: start; }
  .tile--s > .head { grid-area: head; } .svc .tile--s > h3 { grid-area: h; font-family: "AmpSwap", var(--s-font); font-size: var(--s-size); letter-spacing: var(--s-ls); line-height: 1.3; max-width: 14ch; } .tile--s > .kw { grid-area: kw; align-self: end; }
  .tile--s > .ill { grid-area: ill; align-self: stretch; height: 100%; margin: 0; }
  .tile--brand .ill { height: clamp(96px, 9.4vw, 116px); }
  .tile--crm .ill { height: clamp(150px, 14.5vw, 184px); } .tile--ux .ill { height: clamp(80px, 7.8vw, 94px); }
  .tile--brand h3 { font-size: clamp(1rem, 1.4vw, 1.2rem); }
  /* --- surfaces --- */
  .tile--paper { background: var(--paper); color: var(--paper-ink); --ink: var(--paper-ink); --ink-muted: var(--paper-muted); --rule: var(--paper-rule); --ill-line: var(--paper-line); --ill-fill: var(--paper-fill); --tint-a: .22; -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: 0 24px 60px rgba(2,4,14,.35); }
  .tile--paper > .gloss { opacity: .18; mix-blend-mode: normal; } .tile--paper .anum { color: var(--paper-muted); }
  .tile--slate { background: var(--slate); color: var(--slate-ink); --ink: var(--slate-ink); -webkit-backdrop-filter: none; backdrop-filter: none; } .tile--slate > .gloss { opacity: .45; }
  /* --- ghost numerals, spotlight --- */
  .tile > .ghost { position:absolute; right: .55rem; bottom: .25rem; z-index: 0; pointer-events: none; font-family: "AmpSwap", var(--font-display); font-weight: 700; font-variation-settings: "wdth" 112; font-size: clamp(3.3rem, 5.3vw, 4.9rem); letter-spacing: -.05em; line-height: .8; color: var(--ink); opacity: .028; transition: color .5s var(--ease-out), opacity .5s var(--ease-out), transform .6s var(--ease-out); }
  .tile--xl > .ghost, .tile--flow > .ghost { font-size: clamp(5.5rem, 8.6vw, 8rem); opacity: .032; right: .5rem; bottom: .3rem; }
  .tile:is(:hover,.demo) > .ghost { color: var(--ac); opacity: .06; transform: translateY(-4px); }
  .tile--paper > .ghost { opacity: .045; }
  .tile--gup > .ghost { opacity: .065; } .tile--gup.tile--paper > .ghost { opacity: .09; } .tile--gup:is(:hover,.demo) > .ghost { opacity: .12; }
  .tile > .spot { position:absolute; inset:0; border-radius: inherit; pointer-events:none; z-index:0; opacity:0; transition: opacity .4s var(--ease-out); background: radial-gradient(170px 170px at var(--mx, 50%) var(--my, 50%), rgba(255,255,255,.11), transparent 60%); }
  .tile:hover > .spot { opacity: 1; }
  .tile--paper > .spot { background: radial-gradient(170px 170px at var(--mx, 50%) var(--my, 50%), rgba(22,19,31,.07), transparent 60%); }
  /* --- the tape --- */
  .tape { overflow: hidden; display:flex; align-items:center; height: 32px; border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule); position: relative; }
  .tape::before, .tape::after { content: ""; position: absolute; top: 0; bottom: 0; width: 9%; pointer-events: none; z-index: 1; } .tape::before { left: 0; background: linear-gradient(90deg, var(--paper), transparent); } .tape::after { right: 0; background: linear-gradient(270deg, var(--paper), transparent); }
  .tape-track { display:flex; align-items:center; gap: 1.1rem; white-space: nowrap; font-family: "AmpSwap", var(--font-mono); font-size: .6rem; letter-spacing: .22em; text-transform: uppercase; color: var(--ink-muted); animation: tape 70s linear infinite; }
  .tape-track i { font-style: normal; font-weight: 700; } .tape-track i:nth-of-type(3n+1) { color: var(--blue); } .tape-track i:nth-of-type(3n+2) { color: var(--violet); } .tape-track i:nth-of-type(3n) { color: var(--orange-blaze); }
  @keyframes tape { to { transform: translateX(-50%); } }
  .tape { background: var(--paper); border-color: transparent; border-radius: 6px; } .tape-track { color: var(--paper-muted); } .tape-track span:hover { color: var(--paper-ink); }
  /* --- stamp --- */
  .stamp { position:absolute; right: 1rem; bottom: 3.4rem; width: 62px; height: 62px; z-index: 1; pointer-events: none; color: var(--ink); opacity: .55; animation: spin 26s linear infinite; }
  .stamp text { font-family: "AmpSwap", var(--font-mono); font-size: 9.6px; letter-spacing: .2em; text-transform: uppercase; fill: currentColor; } .tile:is(:hover,.demo) .stamp { opacity: .9; }
  /* --- reveal --- */
  /* entrance: a plain fade — no transforms on the grid children (they live inside a card the deck driver scales) */
  /* BUILD 119: slowed right down - at .7s with a 55ms stagger and no movement
     at all, the whole grid was in before you could see it happen. Now 1.6s per
     tile on a 140ms stagger, with a short rise and a blur coming off, so the
     grid assembles rather than appearing. The rise is only 8px: these tiles sit
     in grid cells with small gutters, and anything larger has them briefly
     sitting on their neighbours. */
  .svc:not(.in) > * { opacity: 0; } .svc.in > * { animation: rise 1.9s var(--ease-out) backwards; animation-delay: calc(var(--i, 0) * 185ms); }
  @keyframes rise {
    from { opacity: 0; transform: translateY(8px); filter: blur(7px); }
    60%  { opacity: 1; }
    to   { opacity: 1; transform: none; filter: blur(0); }
  }
  @media (prefers-reduced-motion: reduce) {
    .svc.in > * { animation: rise .4s linear backwards; animation-delay: 0ms; }
    @keyframes rise { from { opacity: 0; } to { opacity: 1; } }
  }

  /* ===== motion vocabulary ===== */
  .ill .mv { transform-box: fill-box; transform-origin: center; transition: transform .7s var(--ease-out), opacity .5s var(--ease-out), fill-opacity .5s var(--ease-out); }
  .ill .draw { stroke-dasharray: 400; stroke-dashoffset: 0; } .tile:is(:hover,.demo) .ill .draw { animation: drawIn 1.1s var(--ease-out) both; }
  @keyframes drawIn { from { stroke-dashoffset: 400; } to { stroke-dashoffset: 0; } }
  @keyframes sweepX { from { transform: scaleX(0); } to { transform: scaleX(1); } }
  @keyframes pop { from { transform: scale(0); } 70% { transform: scale(1.18); } to { transform: scale(1); } }
  @keyframes spin { to { transform: rotate(360deg); } } @keyframes flow { to { stroke-dashoffset: -14; } }
  @keyframes pulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.08); } } @keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
  @keyframes blink { 0%,100% { opacity: .25; } 50% { opacity: 1; } }
  /* 01 AI */
  .a-spark { transform-box: fill-box; transform-origin: center; } .tile:is(:hover,.demo,.asked) .a-spark { animation: spin 2.4s linear infinite; }
  .a-hl { transform-box: fill-box; transform-origin: left center; } .tile.asked .a-hl { animation: sweepX .8s var(--ease-out) both; } .tile.asked .a-hl2 { animation-delay: .15s; }
  .tile.asked .a-cite { animation: pop .5s var(--ease-out) .5s both; } .tile.asked .a-cite2 { animation-delay: .65s; }
  .a-src { transition: transform .8s var(--ease-out); transform-box: fill-box; transform-origin: bottom center; } .tile:is(:hover,.demo,.asked) .a-src1 { transform: rotate(10deg) translate(6px, -2px); } .tile:is(:hover,.demo,.asked) .a-src2 { transform: rotate(-6deg) translate(-3px, -3px); }
  .a-caret { animation: blink 1s steps(1) infinite; } .tile.asked .a-caret { opacity: 0; animation: none; } .a-bar { cursor: pointer; }
  .a-ans { opacity: .35; transition: opacity .4s; } .tile.asked .a-ans { opacity: 1; }
  /* 02 SaaS: build →︎ test →︎ deploy */
  .s-tick { opacity: 0; transition: opacity .3s; } .tile.run .s-tick { opacity: 1; } .s-node rect { transition: stroke .4s; }
  .tile.run .s-t1 { animation: pop .4s var(--ease-out) .35s both; } .tile.run .s-t2 { animation: pop .4s var(--ease-out) 1s both; } .tile.run .s-t3 { animation: pop .4s var(--ease-out) 1.65s both; }
  .s-prog { transform-box: fill-box; transform-origin: left center; transform: scaleX(0); } .tile.run .s-prog { animation: sweepX 1.7s linear .2s both; }
  .s-toast { opacity: 0; transform: translateY(8px); transition: opacity .35s, transform .35s; } .tile.run .s-toast { opacity: 1; transform: translateY(0); transition-delay: 1.95s; }
  .s-line { transition: opacity .6s; } .s-line2 { opacity: 0; } .tile.run.alt .s-line1 { opacity: 0; } .tile.run.alt .s-line2 { opacity: 1; } .tile.alt:not(.run) .s-line1 { opacity: 0; } .tile.alt:not(.run) .s-line2 { opacity: 1; }
  .tile.run .s-card { animation: bob .6s var(--ease-out) 2.1s 1; }
  /* 03 Websites */
  .w-needle { transform-box: view-box; transform-origin: 58px 96px; transform: rotate(-70deg); transition: transform 1s cubic-bezier(.2,.9,.3,1.15); } .tile:is(:hover,.demo) .w-needle { transform: rotate(0deg); }
  .w-el, .tile.el .w-en { opacity: 0; transition: opacity .5s var(--ease-out); } .w-en, .tile.el .w-el { opacity: 1; transition: opacity .5s var(--ease-out); } .w-pill { cursor: pointer; }
  /* 04 Commerce */
  .c-p { opacity: 0; transform: translateX(14px); transition: opacity .45s var(--ease-out), transform .55s var(--ease-out); } .c-p.on { opacity: 1; transform: translateX(0); } .c-p.off { transform: translateX(-14px); }
  .c-dot { opacity: .3; transition: opacity .3s, fill .3s; } .c-dot.on { opacity: 1; fill: var(--ac); }
  .c-flyer > g { transform-box: view-box; opacity: 0; } .tile.flying .c-flyer > g { animation: hop .8s cubic-bezier(.35,.05,.45,1) both; }
  @keyframes hop { 0% { opacity: 1; transform: translate(0,0) rotate(0) scale(1); } 45% { opacity: 1; transform: translate(52px,-46px) rotate(18deg) scale(.9); } 100% { opacity: 0; transform: translate(98px,22px) rotate(38deg) scale(.3); } }
  .c-bag { transform-box: fill-box; transform-origin: 50% 0; animation: sway 4.5s ease-in-out infinite; } .calm .c-bag { animation: none; }
  @keyframes sway { 0%,100% { transform: rotate(-2.5deg); } 50% { transform: rotate(2.5deg); } }
  .tile.flying .c-bag { animation: catch .5s var(--ease-out) .62s 1; } @keyframes catch { 0% { transform: scale(1,1); } 40% { transform: scale(1.12,.86); } 70% { transform: scale(.96,1.06); } 100% { transform: scale(1,1); } }
  .c-face { transition: opacity .4s var(--ease-out) .9s; } .tile.hasbag .c-face { opacity: .8; }
  .c-badge { opacity: 0; } .tile.hasbag .c-badge { opacity: 1; } .tile.bought .c-badge { animation: pulse .5s var(--ease-out) .7s; }
  .c-added { transition: opacity .3s var(--ease-out); } .tile.bought .c-added { opacity: 1; transition-delay: .8s; }
  .tile:is(:hover,.demo) .c-btn { animation: pulse 1.4s ease-in-out infinite; }
  .c-step { transition: fill .4s var(--ease-out), opacity .4s var(--ease-out); } .tile.bought .c-step { fill: var(--ac); opacity: 1; transition-delay: .9s; } .tile.bought .c-s2 { transition-delay: 1.3s; } .tile.bought .c-s3 { transition-delay: 1.7s; }
  .c-rail { transform-box: fill-box; transform-origin: left center; transform: scaleX(0); } .tile.bought .c-rail { animation: sweepX .9s var(--ease-out) .9s both; }
  .c-van { transform-box: view-box; } .tile.bought .c-van { animation: drive 1.9s cubic-bezier(.45,0,.6,1) 1.8s both; } .tile.bought .c-wheel { animation: spin .5s linear 1.8s 4; }
  .tile.showvan .c-van { opacity: 1 !important; animation: none !important; transform: translateX(30px); }
  @keyframes drive { 0% { opacity: 0; transform: translateX(-6px); } 12% { opacity: 1; transform: translateX(0); } 82% { opacity: 1; } 100% { opacity: 0; transform: translateX(64px); } }
  /* 05 Automation */
  .tile:is(:hover,.demo) .f-link { animation: flow .7s linear infinite; } .tile:is(:hover,.demo) .f-bolt { animation: blink .8s ease-in-out infinite; }
  .f-done { transition: fill-opacity .4s; } .tile:is(:hover,.demo) .f-done, .tile.hit .f-done { fill-opacity: .22; }
  .f-node { cursor: pointer; } .f-node:hover rect { stroke: var(--ac); }
  .tile.hit .f-tick { animation: drawIn .5s var(--ease-out) both; }
  .calm .pk { display: none; }
  /* 06 CRM board */
  .k-card { cursor: pointer; transform-box: view-box; transition: transform .65s var(--ease-out), opacity .4s var(--ease-out); } .k-card rect { transition: stroke .4s, fill-opacity .4s; }
  .k-card:hover rect { stroke: var(--ac); } .k-card.won rect { stroke: var(--ac); fill: var(--ac); fill-opacity: .16; }
  .k-card .k-tick { opacity: 0; transition: opacity .3s .3s; } .k-card.won .k-tick { opacity: 1; } .k-card.reset { opacity: 0; transition: opacity .35s var(--ease-out); } .k-card.lift { animation: bob .6s var(--ease-out) 1; }
  /* 07 Documents: clauses get inserted */
  .d-ins { transform-box: fill-box; transform-origin: left center; transform: scaleX(0); } .d-ins.on { animation: sweepX .7s var(--ease-out) both; }
  .d-mark { opacity: 0; transition: opacity .3s .5s; } .d-mark.on { opacity: 1; }
  .tile.inserting .d-btn { transform: translateY(1px) scale(.96); } .d-page.reset .d-ins, .d-page.reset .d-mark { transition: opacity .3s; opacity: 0; }
  /* 08 Data: datasets by practice area */
  .b-bar { transform-box: fill-box; transform-origin: center bottom; transition: transform .7s var(--ease-out); }
  .dc { cursor: pointer; } .dc rect { fill: var(--ac); fill-opacity: 0; transition: fill-opacity .3s, stroke .3s; } .dc.on rect { fill-opacity: .22; stroke: var(--ac); } .dc.on text { fill: var(--ac); }
  .tl { transition: opacity .6s; opacity: 0; } .tl.on { opacity: 1; }
  /* 09 Product design: blocks get drawn */
  .u-blk { transform-box: fill-box; transform-origin: top left; animation: drawBlk .55s var(--ease-out) both; } @keyframes drawBlk { from { transform: scale(0,.15); } to { transform: scale(1,1); } }
  .u-cur { transition: transform .8s var(--ease-out); } .u-canvas { cursor: crosshair; }
  .u-mini { animation: pop .4s var(--ease-out) both; }
  /* 10 Brand — a style sheet that works */
  .br-ring { transform-box: fill-box; transform-origin: center; animation: spin 24s linear infinite; }
  .br-star { transform-box: fill-box; transform-origin: center; animation: pulse 5s ease-in-out infinite; }
  .br-t { cursor: pointer; font-variation-settings: "wdth" var(--w), "wght" 500; animation: wave 7s ease-in-out infinite; }
  .br-t:nth-child(2) { animation-delay: .5s; } .br-t:nth-child(3) { animation-delay: 1s; } .br-t:hover { animation-play-state: paused; }
  @keyframes wave { 0%, 100% { font-variation-settings: "wdth" var(--w), "wght" 300; } 50% { font-variation-settings: "wdth" var(--w), "wght" 700; } }
  .br-caret { animation: blink 1.1s steps(1) infinite; }
  .br-tg, .br-knob { transition: transform .35s var(--ease-out), fill .35s var(--ease-out), opacity .35s var(--ease-out); }
  .tile.tg-on .br-tg { fill: var(--ac); opacity: 1; } .tile.tg-on .br-knob { transform: translateX(16px); }
  .tile.tg-on .br-tglabel { opacity: 1; }
  .br-btn2, .ac[fill="currentColor"] { transition: fill .4s var(--ease-out); }
  .br-word { transition: font-variation-settings .8s var(--ease-out); }
  .sw { cursor: pointer; transition: transform .3s var(--ease-out); } .sw:hover { transform: translateY(-2px); filter: brightness(1.15); }
  .calm .a-caret { display: none; }

  /* ===== type systems (all Archivo variable + Space Mono — the brand's own faces) ===== */
  .svc { --t-font: var(--font-display); --t-case: uppercase; --t-wdth: 100; --t-wght: 700; --t-ls: -.005em;
    --xl-wdth: 62; --xl-wght: 700; --xl-ls: 0; --xl-size: clamp(1.7rem, 3.1vw, 2.6rem);
    --flow-wdth: 125; --flow-wght: 700; --flow-ls: .005em; --flow-size: clamp(1.3rem, 2.4vw, 2.1rem);
    --s-font: var(--font-mono); --s-size: .7rem; --s-ls: .14em; }
  /* the mix: poster on the two loud tiles (AI, Brand), wordmark on the strip + standard tiles, mono on the compact pair */
  .svc { --t-wdth: 112; --t-wght: 400; --t-ls: .14em; --xl-wdth: 62; --xl-wght: 700; --xl-ls: 0; --xl-size: clamp(2.4rem, 4.1vw, 3.5rem); --flow-wdth: 112; --flow-wght: 300; --flow-ls: .16em; --flow-size: clamp(1.2rem, 2.1vw, 1.8rem); --s-font: var(--font-mono); --s-size: .96rem; --s-ls: .12em; }
  .svc .tile--brand h3 { font-variation-settings: "wdth" 62, "wght" 700; letter-spacing: 0; font-size: clamp(1.5rem, 2.6vw, 2.2rem); line-height: .92; }
  .tile--brand .kw li:nth-child(n+4) { display: none; }
  

  @media (max-width: 1100px) {
    .svc { grid-template-columns: repeat(6, minmax(0,1fr)); grid-template-rows: none; grid-auto-rows: auto; grid-template-areas:
      "ai ai ai ai ai ai" "crm crm crm com com com" "tape tape tape tape tape tape" "flow flow flow flow flow flow" "web web web docs docs docs" "ux ux ux brand brand brand"; }
    .tile { min-height: clamp(120px, 14vh, 150px); } .tile--saas .ill { height: 150px; }
  }
  @media (max-width: 620px) {
    .svc { grid-template-columns: 1fr; grid-template-areas: "ai" "crm" "tape" "flow" "com" "web" "docs" "ux" "brand"; }
    .tile--side, .tile--s { display:flex; align-items: stretch; } .tile--side > .head, .tile--s > .head { order:-2; } .tile--side > .ill, .tile--s > .ill { order:-1; } .tile--side > .kw, .tile--s > .kw { align-self: stretch; }
    .tile--side > .ill, .tile--s > .ill { height: clamp(96px, 30vw, 150px); margin: .15rem 0 .3rem; }
    .svc { --xl-size: 1.8rem; --flow-size: 1.4rem; }
  }
  @media (prefers-reduced-motion: reduce) {
    .ill *, .ill, .tape-track, .stamp, .br-aa { animation: none !important; transition: none !important; }
    .w-needle { transform: rotate(0); } .pk { display: none; } .svc > * { animation: none !important; opacity: 1 !important; }
    .apanel:hover::before, .apanel:focus-within::before { transition:none; --sweep: 100%; } .apanel::after { transition:none; }
  }
  .tile .anum { font-size: .6rem; }
  /* the link pill: last keyword, shown on hover (feeds the popup's Discipline tab) */
  .kw li.kw-more { padding: 0; border: 0; } .kw li.kw-more .bento-link { display: inline-block; margin: 0; font-size: .54rem; letter-spacing: .11em; padding: .4em .55em .36em; border: 1px solid var(--ac); border-radius: 999px; color: var(--ac); opacity: 0; transition: opacity .3s var(--ease-out); }
  .tile:hover .kw li.kw-more .bento-link, .tile:focus-within .kw li.kw-more .bento-link { opacity: 1; }
  .tile[data-href] { cursor: pointer; } .tile[data-href] .kw li.kw-more .bento-link--page { opacity: 1; border-color: var(--ac); color: var(--ac); }
  /* off-screen: every loop sleeps */
  .svc:not(.alive) .ill *, .svc:not(.alive) .stamp, .svc:not(.alive) .tape-track, .svc:not(.alive) .ghost { animation-play-state: paused !important; }
  .apanel > .bento-link { position: relative; z-index: 1; }
  .bento-link {
    margin-top: auto;
    font-family: "AmpSwap", var(--font-mono);
    font-size: .64rem; letter-spacing: .14em; text-transform: uppercase;
    text-decoration: none;
    color: var(--ink-muted);
    opacity: 0;
    transition: opacity .3s var(--ease-out), color .3s var(--ease-out);
  }
  .apanel:hover .bento-link, .apanel:focus-within .bento-link { opacity: 1; }
  .bento-link:hover { color: var(--orange-blaze); }
  @media (hover: none) { .bento-link { opacity: 1; } }

  /* ---- The difference: quiet two-column comparison ---- */
  .diff-head {
    font-family: "AmpSwap", var(--font-display);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: -.02em;
    line-height: 1.05;
    font-size: clamp(1.6rem, 3.4vw, 2.7rem);
    margin: clamp(1.1rem, 2.4vh, 1.6rem) 0 0;
    text-wrap: balance;
  }
  .diffgrid {
    margin-top: clamp(1.8rem, 4vh, 2.6rem);
    max-width: 84ch;
    border-top: 1px solid var(--rule);
  }
  .diffrow {
    display: grid;
    grid-template-columns: 1fr 1fr;
    border-bottom: 1px solid var(--rule);
  }
  .diffcell {
    margin: 0;
    padding: clamp(.8rem, 1.7vh, 1.1rem) clamp(.6rem, 1.5vw, 1.4rem);
    font-size: 1.02rem;
    line-height: 1.5;
  }
  .diffcell--them { color: var(--ink-muted); font-weight: 300; }
  .diffcell--us   { color: var(--ink); font-weight: 400; border-left: 1px solid var(--rule); }
  .diffrow--head .diffcell { padding-top: 1rem; padding-bottom: .7rem; }
  .diffrow--head .diffcell--them { color: var(--ink-muted); }
  .diff-close {
    margin: clamp(1.6rem, 3.5vh, 2.2rem) 0 0;
    font-size: 1.02rem; line-height: 1.6; font-weight: 300;
    color: var(--ink-muted);
    max-width: 60ch;
  }
  @media (max-width: 620px) {
    .diffcell { font-size: .92rem; padding-left: clamp(.4rem, 2vw, .8rem); padding-right: clamp(.4rem, 2vw, .8rem); }
  }

  /* ---- FAQ: one answer card, chips as the remote control ---- */
  /* All panels share one grid cell, so the card sizes itself to the tallest
     answer and never jumps when the active panel changes. */
  .faq-answer {
    display: grid;
    margin-top: clamp(1.6rem, 3.5vh, 2.4rem);
    max-width: 84ch;
    background: var(--glass-bg);
    border: 1px solid var(--glass-border);
    border-radius: 13px;
    padding: clamp(1.2rem, 2.4vw, 1.7rem);
    -webkit-backdrop-filter: blur(14px) saturate(1.4);
    backdrop-filter: blur(14px) saturate(1.4);
  }
  .faq-panel {
    grid-area: 1 / 1;
    opacity: 0;
    visibility: hidden;
    transition: opacity .35s var(--ease-out), visibility 0s linear .35s;
  }
  .faq-panel.on { opacity: 1; visibility: visible; transition-delay: 0s; }
  .faq-panel p { margin: 0; font-size: 1.02rem; line-height: 1.62; font-weight: 300; text-wrap: pretty; }
  .faq-panel strong { font-weight: 400; color: var(--ink); }
  .faq-chips {
    display: flex; flex-wrap: wrap; gap: .45rem;
    margin-top: clamp(1rem, 2.2vh, 1.4rem);
    max-width: 84ch;
  }
  .faq-chip {
    font-family: "AmpSwap", var(--font-mono);
    font-size: .68rem; letter-spacing: .12em; text-transform: uppercase;
    color: var(--ink-muted); background: none;
    border: 1px solid var(--rule); border-radius: 99px;
    padding: .55em 1.05em; cursor: pointer;
    transition: color .3s var(--ease-out), border-color .3s var(--ease-out), background-color .3s var(--ease-out);
  }
  .faq-chip:hover { color: var(--ink); }
  .faq-chip.on {
    color: #07060F;
    background: var(--orange-blaze);
    border-color: var(--orange-blaze);
  }
  .faq-more {
    margin: clamp(1.2rem, 2.6vh, 1.7rem) 0 0;
    font-size: .95rem; font-weight: 300; color: var(--ink-muted);
  }
  .faq-more a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--accent); }
  .faq-more a:hover { color: var(--accent); }
  @media (prefers-reduced-motion: reduce) { .faq-panel { transition: none; } }
  .caps {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: clamp(2rem, 4vw, 3.5rem);
    margin-top: clamp(2rem, 5vh, 3.5rem);
  }

  .cap { border-top: 1px solid var(--rule); padding-top: 1.5rem; }

  .cap h3 {
    font-family: "AmpSwap", var(--font-display);
    font-weight: 700;
    font-size: clamp(1.15rem, 1.7vw, 1.4rem);
    letter-spacing: -.01em;
    line-height: 1.15;
    text-transform: uppercase;
    margin: .5rem 0 .85rem;
  }

  .cap p {
    font-size: .975rem; line-height: 1.6; font-weight: 300;
    color: var(--ink); text-wrap: pretty;
  }

  /* ===== Work (cards) ================================================== */
  .workgrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: clamp(1rem, 2vw, 1.5rem);
    margin-top: clamp(2rem, 5vh, 3.5rem);
  }

  .card {
    display: flex; flex-direction: column;
    text-align: left;
    background: var(--glass-bg);
    border: 1px solid var(--glass-border);
    border-radius: 16px;
    overflow: hidden;
    padding: 0;
    cursor: pointer;
    color: inherit;
    font: inherit;
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    transition: border-color .25s var(--ease-out), transform .25s var(--ease-out), box-shadow .25s var(--ease-out);
  }
  .card:hover { border-color: var(--accent); transform: translateY(-3px); box-shadow: 0 18px 40px rgba(2,4,14,.4); }

  .card-shot {
    aspect-ratio: 16 / 10;
    background: var(--panel);
    border-bottom: 1px solid var(--rule);
    display: flex; align-items: center; justify-content: center;
    overflow: hidden;
  }
  .card-shot img, .card-shot svg { width: 100%; height: 100%; object-fit: cover; display: block; }

  .card-body { padding: 1.25rem 1.25rem 1.5rem; flex: 1; display: flex; flex-direction: column; }

  .card h3 {
    font-family: "AmpSwap", var(--font-display);
    font-weight: 700;
    font-size: clamp(1.15rem, 1.9vw, 1.5rem);
    letter-spacing: -.02em;
    line-height: 1.05;
    text-transform: uppercase;
    margin: .4rem 0 .6rem;
  }

  .card p {
    font-size: .95rem; line-height: 1.5; font-weight: 300;
    text-wrap: pretty; flex: 1;
  }

  .card-foot {
    display: flex; justify-content: space-between; align-items: baseline;
    gap: 1rem; margin-top: 1.25rem;
  }

  /* ===== Case study overlay =========================================== */
  .overlay {
    position: fixed; inset: 0; z-index: 100;
    background:
      radial-gradient(50% 34% at 85% 8%, rgba(139,92,246,.12) 0%, rgba(139,92,246,0) 70%),
      radial-gradient(46% 30% at 10% 90%, rgba(59,130,224,.10) 0%, rgba(59,130,224,0) 70%),
      var(--ground);
    overflow-y: auto;
    padding: var(--pad-y) var(--pad-x) clamp(4rem, 10vh, 7rem);
    opacity: 0; visibility: hidden;
    transition: opacity .3s var(--ease-out), visibility 0s linear .3s;
  }
  .overlay.open { opacity: 1; visibility: visible; transition-delay: 0s; }

  .overlay-bar {
    display: flex; justify-content: space-between; align-items: baseline;
    gap: 1rem; margin-bottom: clamp(2rem, 6vh, 4rem);
  }

  .close {
    background: none; border: none; padding: 0; cursor: pointer;
    color: var(--ink);
    font-family: "AmpSwap", var(--font-mono); font-size: 12px;
    letter-spacing: .14em; text-transform: uppercase;
    transition: color .2s;
  }
  .close:hover { color: var(--accent); }

  .cs-title {
    font-family: "AmpSwap", var(--font-display);
    font-weight: 700;
    font-size: clamp(2.5rem, 8vw, 6rem);
    letter-spacing: -.035em;
    line-height: .9;
    text-transform: uppercase;
  }

  .cs-lede {
    max-width: 52ch;
    font-size: clamp(1.05rem, 1.5vw, 1.3rem);
    line-height: 1.5; font-weight: 300;
    margin-top: clamp(1.25rem, 3vh, 2rem);
    text-wrap: pretty;
  }

  .cs-meta { display: flex; flex-wrap: wrap; gap: .4rem 1.1rem; margin-top: 1.5rem; }

  /* Case study head (lab option 03, revised per screenshot): the overview
     stays put on the left while the tabs and their content live on the
     right, so nothing reflows and the deck stays high on the page. */
  .cs-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: clamp(1.5rem, 3.5vw, 3rem);
    align-items: start;
    margin-top: clamp(1.2rem, 3vh, 2rem);
  }
  .cs-overview p { font-size: 1rem; line-height: 1.62; font-weight: 300; max-width: 54ch; text-wrap: pretty; }
  .cs-tabs { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: 1rem; }
  .cs-tab {
    font-family: "AmpSwap", var(--font-mono);
    font-size: .68rem; letter-spacing: .14em; text-transform: uppercase;
    color: var(--ink-muted); background: none;
    border: 1px solid var(--rule); border-radius: 99px;
    padding: .5em 1em; cursor: pointer;
    transition: color .3s var(--ease-out), border-color .3s var(--ease-out);
  }
  .cs-tab:hover { color: var(--ink); }
  .cs-tab[aria-selected="true"] { color: var(--ink); border-color: var(--accent); }
  .cs-panel { display: none; }
  .cs-panel.on { display: block; }
  .cs-panel p { font-size: .98rem; line-height: 1.6; font-weight: 300; max-width: 60ch; text-wrap: pretty; }
  .cs-panel .cs-list { max-width: 60ch; }
  @media (max-width: 860px) {
    .cs-head { grid-template-columns: 1fr; }
  }
  @media (prefers-reduced-motion: reduce) { .cs-tab { transition: none; } }

  .cs-sections { margin-top: clamp(2.5rem, 7vh, 4.5rem); }

  .cs-row {
    display: grid;
    grid-template-columns: minmax(8rem, 1fr) 3fr;
    gap: clamp(1rem, 3vw, 2.5rem);
    padding: clamp(1.5rem, 4vh, 2.25rem) 0;
    border-top: 1px solid var(--rule);
  }
  .cs-row:last-child { border-bottom: 1px solid var(--rule); }
  .cs-row p { font-size: 1rem; line-height: 1.6; font-weight: 300; max-width: 62ch; text-wrap: pretty; }
  .cs-list { margin: 0; padding: 0; list-style: none; max-width: 62ch; display: grid; gap: .6rem; }
  .cs-list li { font-size: 1rem; line-height: 1.55; font-weight: 300; padding-left: 1.4rem;
    position: relative; text-wrap: pretty; }
  .cs-list li::before { content: ""; position: absolute; left: 0; top: .62em;
    width: 8px; height: 1px; background: var(--accent); }

  .cs-visuals { margin-top: clamp(2.5rem, 6vh, 4rem); display: grid; gap: clamp(1rem, 2vw, 1.5rem); }

  .cs-shot {
    background: var(--panel);
    border: 1px solid var(--rule);
    min-height: 220px;
    display: flex; align-items: center; justify-content: center;
    padding: 1rem;
  }
  .cs-shot svg, .cs-shot img { width: 100%; height: auto; display: block; }

  .cs-links { display: flex; flex-wrap: wrap; gap: 1.5rem; margin-top: clamp(2rem, 5vh, 3rem); }
  .cs-links a { text-decoration: none; border-bottom: 1px solid var(--accent); padding-bottom: 2px; }
  .cs-links a:hover { color: var(--accent); }
  .cs-links a.primary {
    border: 1px solid var(--accent); border-radius: 2px;
    padding: .7rem 1.4rem; color: var(--accent); transition: .2s;
  }
  .cs-links a.primary:hover { background: var(--accent); color: var(--ground); }

  /* The page is held still by pinning the body at its current offset, not by
     `overflow: hidden` — that drops the scroll position on iOS, and closing a
     case study threw you somewhere else on the page. */
  body.locked { position: fixed; left: 0; right: 0; width: 100%; overflow: hidden; }

  /* ===== Testimonials ================================================== */
  /* Filmstrip (clients lab option 09), at the 15px-narrower slide width:
     horizontal scroll-snap slides with an oversized ghost index. */
  .quotes {
    display: flex;
    gap: clamp(1rem, 2vw, 1.4rem);
    margin-top: clamp(2rem, 5vh, 3.5rem);
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    padding-bottom: 1.2rem;
    scrollbar-width: thin;
    scrollbar-color: rgba(139,92,246,.45) transparent;
    overscroll-behavior-x: contain;
  }
  .quotes::-webkit-scrollbar { height: 7px; }
  .quotes::-webkit-scrollbar-thumb { background: rgba(139,92,246,.4); border-radius: 4px; }
  .quote {
    flex: 0 0 min(80%, 505px);
    scroll-snap-align: start;
    position: relative;
    overflow: hidden;
    display: block;
    background:
      linear-gradient(150deg, rgba(255,255,255,.07) 0%, rgba(255,255,255,.02) 42%, transparent 62%),
      rgba(18, 20, 44, .20);
    border: 1px solid var(--rule);
    border-radius: 13px;
    padding: clamp(1.2rem, 2.4vw, 1.7rem);
    -webkit-backdrop-filter: blur(18px) saturate(1.6);
    backdrop-filter: blur(18px) saturate(1.6);
  }
  .quote .qnum {
    position: absolute; right: .5rem; top: -1.5rem;
    font-family: "AmpSwap", var(--font-display); font-weight: 700; font-size: 5.4rem;
    color: rgba(139,92,246,.13); line-height: 1; pointer-events: none;
  }
  .quote blockquote {
    position: relative;
    margin: .7rem 0 0;
    font-size: clamp(1rem, 1.35vw, 1.14rem);
    line-height: 1.58; font-weight: 300; text-wrap: pretty;
  }
  .quote cite { font-style: normal; position: relative; }
  @media (max-width: 760px) { .quote { flex-basis: min(88%, 400px); } }

  /* ===== Contact ======================================================= */
  .contact-mail {
    display: inline-block;
    font-family: "AmpSwap", var(--font-display);
    font-weight: 700;
    /* sized to the contact column, which is narrower now that the Q&A sits
       beside it — at 3.5rem the address broke mid-word */
    font-size: clamp(1.05rem, 3.4vw, 2.6rem);
    white-space: nowrap; max-width: 100%;
    letter-spacing: -.03em;
    line-height: 1.05;
    text-decoration: none;
    margin: clamp(1.5rem, 4vh, 2.5rem) 0;
    word-break: break-word;
    transition: color .2s;
  }
  .contact-mail:hover { color: var(--accent); }

  .foot {
    display: flex; justify-content: space-between; flex-wrap: wrap;
    gap: 1rem 2rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--rule);
  }


  /* ── Q&A beside the contact (BUILD 120) ───────────────────────────────
     From Cjay's layout: the contact copy holds the left of the panel and the
     Q&A card stack sits on the right, under its own small label. Card deck is
     lab-qa option 03 — one answer on the face at a time, the rest waiting
     behind it, and a click sends the top card away. -------------------- */
  .contact-grid {
    display: grid;
    /* 65 / 35, not an even split — the contact copy carries the address and
       has to hold the panel (Cjay, 27 Aug) */
    grid-template-columns: minmax(0, 65fr) minmax(0, 35fr);
    gap: clamp(2rem, 5vw, 4rem);
    align-items: start;
    margin-top: 0;
  }
  .qa { position: relative; }
  /* the same ghost the panel titles use, at the scale this column allows */
  /* lifted out of the flow and raised the same 80% as the panel ghosts, so
     Q&A sits on exactly the line CONTACT does */
  .qa-label {
    position: absolute; left: 0; top: 0; transform: translateY(-80%);
    font-family: "AmpSwap", var(--font-display); font-weight: 800;
    font-variation-settings: "wdth" 62;
    text-transform: uppercase; letter-spacing: -.04em; line-height: .78;
    /* the SAME size as the panel ghosts — at a different size the -80% lift
       resolves differently and the two stop sharing a line */
    font-size: clamp(2.6rem, 8vw, 7rem);
    color: var(--ghost-ink, rgba(241,238,224,.075));
    margin: 0; padding: 0; pointer-events: none; user-select: none;
  }
  .qa-deck { position: relative; z-index: 1; height: clamp(230px, 30vh, 290px); }
  .qa-card {
    position: absolute; inset: 0; cursor: pointer;
    border-radius: 18px; padding: clamp(1.2rem, 2.4vw, 1.8rem);
    /* fully opaque: at .96 the card behind showed its heading through the
       face and the top card read as double-printed */
    background: linear-gradient(155deg, #1E1C40, #0D0C1D);
    border: 1px solid rgba(255,255,255,.13);
    box-shadow: 0 28px 64px rgba(2,4,14,.55);
    display: flex; flex-direction: column; justify-content: center; gap: .75rem;
    transition: transform .55s var(--ease-out), opacity .45s var(--ease-out);
  }
  .qa-q {
    font-family: "AmpSwap", var(--font-display); font-weight: 700; font-variation-settings: "wdth" 82;
    text-transform: uppercase; letter-spacing: -.01em; line-height: 1.08;
    font-size: clamp(1rem, 1.7vw, 1.3rem); margin: 0;
  }
  .qa-a { margin: 0; color: var(--ink-muted); font-weight: 300; font-size: .92rem; line-height: 1.6; }
  .qa-n {
    position: absolute; right: 1.2rem; bottom: 1rem;
    font-family: "AmpSwap", var(--font-mono); font-size: .55rem; letter-spacing: .18em; color: var(--ink-muted);
  }
  .qa-hint {
    font-family: "AmpSwap", var(--font-mono); font-size: .55rem; letter-spacing: .16em;
    text-transform: uppercase; color: var(--ink-muted); margin: 1.5rem 0 0; text-align: center;
  }
  @media (max-width: 900px) {
    .contact-grid { grid-template-columns: 1fr; gap: clamp(2rem, 6vh, 3rem); }
    .qa-deck { height: clamp(250px, 40vh, 320px); }
  }


  /* ── The footer (BUILD 120) ───────────────────────────────────────────
     Grouped columns so the whole site is reachable from the foot of the page —
     all eight service pages, all seven projects — closed by the wordmark
     running as an outline marquee, each repetition in a different brand
     colour. lab-footer option 06. --------------------------------------- */
  .foot-cols {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: clamp(1rem, 2.2vw, 2rem);
    margin: clamp(.9rem, 2.2vh, 1.5rem) 0 clamp(1rem, 2.5vh, 1.7rem);
  }
  .foot-col h4 {
    margin: 0 0 .9rem; font-family: "AmpSwap", var(--font-mono); font-size: .55rem;
    letter-spacing: .22em; text-transform: uppercase; color: var(--ink-muted); font-weight: 400;
  }
  .foot-col a {
    display: block; text-decoration: none; color: var(--ink); padding: .3rem 0;
    font-family: "AmpSwap", var(--font-display); font-weight: 600; font-variation-settings: "wdth" 92;
    font-size: .92rem; transition: color .25s, transform .3s var(--ease-out);
  }
  .foot-col a:hover { color: var(--accent); transform: translateX(4px); }
  .foot-col small {
    display: block; margin-top: .9rem; color: var(--ink-muted);
    font-family: "AmpSwap", var(--font-mono); font-size: .58rem; letter-spacing: .1em; line-height: 1.8;
  }

  .foot-marquee {
    margin-top: clamp(1.4rem, 3.5vh, 2.2rem);
    overflow: hidden;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
  }
  .foot-marquee > div { display: flex; align-items: center; gap: clamp(.8rem, 2vw, 1.6rem);
    width: max-content; animation: footslide 44s linear infinite; }
  @keyframes footslide { to { transform: translateX(-50%); } }
  @media (prefers-reduced-motion: reduce) { .foot-marquee > div { animation: none; } }
  .foot-word {
    font-family: "AmpSwap", var(--font-display); font-weight: 800; font-variation-settings: "wdth" 62;
    text-transform: uppercase; letter-spacing: -.04em; line-height: .78;
    font-size: clamp(2.2rem, 7vw, 5.6rem); white-space: nowrap;
    color: transparent; -webkit-text-stroke: 1.5px var(--ac);
  }
  .foot-dot { width: 9px; height: 9px; border-radius: 100vw; background: var(--ac); flex: none;
    box-shadow: 0 0 14px var(--ac); }
  @media (max-width: 620px) {
    .foot-col a { font-size: .85rem; }
    .foot-word { -webkit-text-stroke-width: 1.2px; }
  }

  /* ---- Countable truths + final CTA + site footer ---- */
  .truths {
    display: flex; flex-wrap: wrap;
    margin-top: clamp(1.4rem, 3vh, 2rem);
    border-top: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
    max-width: 84ch;
  }
  .truth {
    flex: 1 1 10rem;
    display: flex; flex-direction: column; gap: .35rem;
    padding: clamp(1rem, 2.2vh, 1.4rem) clamp(.9rem, 2vw, 1.4rem);
    border-left: 1px solid var(--rule);
  }
  .truth:first-child { border-left: 0; }
  .truth-n {
    font-family: "AmpSwap", var(--font-display);
    font-weight: 700;
    font-size: clamp(2rem, 4vw, 3.1rem);
    line-height: 1;
    letter-spacing: -.02em;
  }
  .contact-head {
    font-family: "AmpSwap", var(--font-display);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: -.02em;
    line-height: 1.05;
    font-size: clamp(1.6rem, 3.4vw, 2.7rem);
    margin: clamp(1.8rem, 4vh, 2.6rem) 0 0;
    text-wrap: balance;
  }
  .contact-sub {
    margin: .7rem 0 0;
    font-size: 1.02rem; line-height: 1.6; font-weight: 300;
    color: var(--ink-muted);
    max-width: 54ch;
  }
  .site-foot { margin-top: clamp(.8rem, 2vh, 1.4rem);
    padding-left: calc((100% - min(var(--max-w), 100% - 2 * var(--pad-x))) / 2 + var(--spine-gap));
    padding-right: calc((100% - min(var(--max-w), 100% - 2 * var(--pad-x))) / 2); }
  .foot-rule {
    border: 0; height: 1px; margin: 0 0 clamp(1.2rem, 2.6vh, 1.8rem);
    background: linear-gradient(90deg,
      transparent 0%, var(--blue) 18%, var(--violet) 50%, var(--orange-blaze) 82%, transparent 100%);
    opacity: .35;
  }
  .site-foot-row {
    display: flex; justify-content: space-between; align-items: center;
    flex-wrap: wrap; gap: .8rem 2rem;
  }
  .site-foot-row--legal { margin-top: .9rem; }
  .site-foot-brand { display: inline-flex; align-items: center; gap: .55rem; }
  .site-foot-brand img { display: block; }
  .site-foot-links { display: flex; flex-wrap: wrap; gap: .2rem 1.3rem; }
  .site-foot-links a {
    font-family: "AmpSwap", var(--font-mono);
    font-size: .66rem; letter-spacing: .13em; text-transform: uppercase;
    color: var(--ink-muted); text-decoration: none;
    transition: color .25s;
  }
  .site-foot-links a:hover { color: var(--ink); }
  @media (max-width: 620px) { .truth { flex-basis: 45%; } .truth:nth-child(3) { border-left: 0; } }

  /* ===== Motion ======================================================== */
  @keyframes draw { from { transform: scaleY(0); } to { transform: scaleY(1); } }
  @keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }

  /* ===== Responsive ==================================================== */
  @media (max-width: 760px) {
    .cs-row { grid-template-columns: 1fr; row-gap: .5rem; }
  }

  @media (max-width: 760px) {
    .prow { grid-template-columns: 3rem 1fr; row-gap: .75rem; }
    .pdef { grid-column: 2; }
    .statement, .hero-footer { justify-content: flex-start; }
    .hero-cta { justify-content: flex-start; }
    .hero-headline, .hero-strip { text-align: left; }
    .statement p { max-width: none; }
  }

  @media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
      animation-duration: .01ms !important;
      transition-duration: .01ms !important;
    }
  }


  /* ══ PHONE PASS (BUILD 119) ═══════════════════════════════════════════
     Narrowed, not flattened. Everything below keeps a device the desktop
     layout is built on rather than letting it collapse into a stack of
     identical blocks: the nav stays a capsule (never a dropdown), the
     bento stays a bento, the difference keeps its coloured threshold, and
     the approach keeps its process line — turned on its side.
     This block is last in the stylesheet on purpose: this file has a long
     history of earlier rules winning the cascade. ---------------------- */

  @media (max-width: 620px) {
    /* — the nav is a capsule at every width. No hamburger, no dropdown. — */

    /* — hero: one ranged-left column, the rail kept —
         The rail is fixed under the capsule and takes 56–89px, so the content
         has to start below that or the lockup lands straight on it, which is
         exactly what was happening. */
    .hero { padding-top: 106px; height: auto; min-height: 0; }
    .hero .inner { width: auto; max-width: none; }
    .hero .hero-lockup { top: 0; justify-content: flex-start; }
    .hero .hero-cta { top: 0; }
    /* buttons sized to their words, not stretched edge to edge */
    /* the row wraps to a column on a narrow screen, and a stretched cross-axis
       is what was making both buttons full width — align them to the start */
    .hero .hero-cta { gap: .5rem; flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; }
    .hero .hero-cta .btn { flex: 0 0 auto; padding: .8em 1.25em; font-size: .62rem; }
    .hero .hero-headline { font-size: clamp(1.45rem, 7.4vw, 2.1rem); }
    /* the nav capsule sits at the very top on a phone, so the disciplines
       rail drops below it rather than hiding behind it */
    .hero-rail--top { top: 56px; padding: .55rem .9rem; font-size: .54rem;
      border-top: 1px solid var(--rule); }

    /* — the ghost panel titles scale with the panel, not the desktop — */
    .section .content h2.label--strong {
      left: 4px; font-size: clamp(2rem, 13vw, 3.2rem); transform: translateY(-78%);
    }
    .sheetcard > .section { padding-top: clamp(3rem, 9vh, 4.2rem); }

    /* — the numeral rail keeps its proportions on a narrow card — */
    .chip--index { left: 12px; font-size: 2.1rem; }
  }

  /* — bigger phones keep a paired bento; only the smallest go single file — */
  @media (min-width: 481px) and (max-width: 620px) {
    .svc {
      grid-template-columns: repeat(2, minmax(0, 1fr));
      grid-template-areas: "ai ai" "crm crm" "tape tape" "flow flow"
                           "com web" "docs ux" "brand brand";
    }
  }

  @media (max-width: 760px) {
    /* — the difference keeps its threshold: the coloured edge our side sits
         behind, and an arrow that still points across it — */
    .shift-us {
      border-left: 2px solid var(--ac);
      padding-left: .8rem;
      margin-top: .1rem;
    }
    .shift-them { padding-left: .1rem; }
    .shift-line { width: 30px; margin-left: .1rem; }
    .shift-line::after { display: block; }
  }

  @media (max-width: 860px) {
    /* — the approach keeps its process line: stood up on its side, with the
         same node per stage, instead of losing it entirely — */
    .approach { display: grid; grid-template-columns: 14px minmax(0, 1fr); column-gap: 1rem; }
    .approach-line {
      grid-column: 1; grid-row: 1;
      width: 2px; height: 100%; justify-self: center;
      background: linear-gradient(180deg,
        var(--blue) 0%, var(--violet) 42%, var(--orange-coral) 74%, var(--orange-blaze) 100%);
    }
    .stages { grid-column: 2; grid-row: 1; grid-template-columns: 1fr; }
    .stage, .stage + .stage {
      border-top: 0; box-shadow: none;
      padding: 0 0 clamp(1rem, 2.6vh, 1.5rem) 0;
    }
    .stage::before, .stage + .stage::before {
      display: block; left: -1.72rem; top: .45rem;
    }
    .stage:last-child { padding-bottom: 0; }
    .approach-lede { grid-column: 2; grid-row: 2; }
  }


  /* ── The work grid on a phone (BUILD 121) ─────────────────────────────
     PLACED AFTER THE PHONE PASS ON PURPOSE: that block sets the same chip
     properties at the same specificity and was winning on order alone.
     One card per row read as a column of slabs, not as the site. It keeps the
     bento instead: the JurisAI poster holds the full width, the other six pair
     up two to a row, and everything shrinks to suit — which is what makes it
     look like the page rather than a stack. ---------------------------- */
  @media (max-width: 620px) {
    /* the same 16/10 the desktop cards use — a square crops faces that were
       composed landscape, which is what made them read as a different design */

    /* At half a phone's width the chrome has to come down with the card — and
       these have to be written ID-first, because the per-card name-plate rules
       further up are ID selectors and outrank any class selector no matter how
       many classes it chains. */
    /* the live-site pill is the longest of them and pushed the row onto a
       second line; it stays on the poster card, which has the width for it */
    /* the hero card keeps a readable plate — it has the room */
  }
  @media (max-width: 380px) {
    /* below this a paired card is too small to read at all */
  }



  /* ── The What we build bento on a phone (BUILD 121) ───────────────────
     The same treatment the work grid just had: keep the bento rather than
     dropping to one tall column, and scale the tile chrome to suit. Placed
     after the phone pass, which sets `.svc` to a single column at equal
     specificity and would otherwise win on order. ----------------------- */
  @media (max-width: 620px) {
    .svc {
      grid-template-columns: repeat(2, minmax(0, 1fr));
      grid-template-areas:
        "ai   ai"
        "crm  com"
        "tape tape"
        "flow flow"
        "web  docs"
        "ux   brand";
      gap: .4rem;
      --xl-size: 1.55rem; --flow-size: 1.15rem;
    }
    .tile { min-height: 0; padding: .5rem .6rem .55rem; }
    .svc .tile h3 { font-size: .74rem; line-height: 1.12; }
    .tile--side > .ill, .tile--s > .ill { height: clamp(58px, 17vw, 82px); }
    .tile > .ill { height: clamp(46px, 13vw, 62px); }
    .tile p { font-size: .66rem; line-height: 1.45; }
    .tile .anum { font-size: .48rem; }
    .kw { gap: .18rem; padding-top: .25rem; }
    .kw li { font-size: .44rem; padding: .32em .45em .28em; letter-spacing: .06em; }
    /* the poster and the wide flow tile keep their scale — they have the width */
    .svc .tile--xl h3 { line-height: .92; }
    .tile--xl > .ill { height: clamp(78px, 22vw, 110px); }
  }
  @media (max-width: 380px) {
    .svc { grid-template-columns: 1fr;
      grid-template-areas: "ai" "crm" "tape" "flow" "com" "web" "docs" "ux" "brand"; }
  }


  /* ── The four stages as a 2×2 on narrow screens (BUILD 121) ───────────
     The single vertical rail made four short stages into a long column. As a
     2×2 each stage carries its own piece of the process line — a rule in its
     own colour with its node sitting on it — so the device survives being
     split up. After the earlier 860px block, which sets these same properties.
     -------------------------------------------------------------------- */
  @media (max-width: 860px) {
    .approach { display: block; }
    .approach-line { display: none; }
    .stages {
      grid-template-columns: repeat(2, minmax(0, 1fr));
      column-gap: clamp(.9rem, 3vw, 1.6rem);
      row-gap: clamp(1.4rem, 4vh, 2.2rem);
      margin-top: .4rem;
    }
    .stage, .stage + .stage {
      border-top: 2px solid var(--ac);
      box-shadow: none;
      padding: clamp(.9rem, 2.4vh, 1.3rem) 0 0;
    }
    .stage:last-child { padding-bottom: 0; }
    .stage::before, .stage + .stage::before {
      display: block; left: 0; top: -5.5px;
    }
    .approach-lede { margin-top: clamp(1.4rem, 4vh, 2.2rem); }
  }
  @media (max-width: 420px) {
    .stage h3 { font-size: .82rem; }
    .stage p { font-size: .74rem; }
  }


  /* The address is the one thing on the Contact panel that has to be reached
     for; at the shared clamp's floor it was 16.8px on a phone. It gets its own
     scale there — 6.4vw, which is 25px at 390 and still fits on one line. */
  @media (max-width: 620px) {
    .contact-mail { font-size: clamp(1.35rem, 6.4vw, 2.1rem); }
  }
  @media (max-width: 360px) {
    .contact-mail { font-size: 1.28rem; }
  }


  /* ── The footer on a phone (BUILD 121) ────────────────────────────────
     `auto-fit, minmax(180px, 1fr)` collapses to ONE column at 390px, which
     turned twenty links into a single tall list. Two columns halves it; the
     address spans both because it is the longest line in the footer. ---- */
  @media (max-width: 620px) {
    .foot-cols {
      grid-template-columns: repeat(2, minmax(0, 1fr));
      gap: 1.3rem 1rem;
      margin: 1.2rem 0 1.4rem;
    }
    .foot-col h4 { margin-bottom: .5rem; font-size: .5rem; letter-spacing: .18em; }
    .foot-col a { font-size: .78rem; padding: .2rem 0; }
    .foot-col small { font-size: .52rem; line-height: 1.7; margin-top: .6rem; }
    /* all four share the two columns — spanning the last one left Studio
       sitting alone in a row with a hole beside it */
    .foot-col:last-child a { font-size: .66rem; letter-spacing: -.01em; word-break: break-all; }

    .site-foot-row--legal {
      flex-direction: row; flex-wrap: wrap; align-items: center;
      gap: .45rem .9rem; padding-top: .9rem;
    }
    .site-foot-row--legal .label { font-size: .5rem; letter-spacing: .12em; }
    .site-foot-brand { flex: 0 0 100%; }

    .foot-marquee { margin-top: 1.2rem; }
    .foot-marquee > div { gap: .7rem; }
    .foot-word { font-size: clamp(1.5rem, 7.4vw, 2.3rem); -webkit-text-stroke-width: 1.1px; }
    .foot-dot { width: 6px; height: 6px; }
    .site-foot { padding-bottom: .6rem; }
  }


  /* ── The case study on a phone (BUILD 121) ────────────────────────────
     Two changes, both mobile only:
     • the deck comes first and the written detail follows it, because on a
       phone the tabs pushed the thing you opened the card to see off screen;
     • the deck is RENDERED WIDE AND SCALED DOWN rather than squeezed into
       390px. Every deck is composed for a laptop; letting it reflow at phone
       width breaks its layouts, so it is laid out at 1000px and scaled to
       fit, which keeps the composition and just makes it smaller. -------- */
  /* The order flips wherever the popup is a single column — that is 860px,
     the width at which .cs-head stops being two columns. Below 620 the deck is
     scaled as well; the ordering alone applies over the wider band. */
  @media (max-width: 860px) {
    .overlay .content { display: flex; flex-direction: column; }
    .overlay .overlay-bar { order: 1; }
    .overlay .cs-title   { order: 2; }
    .overlay .cs-meta    { order: 3; }
    .overlay .cs-visuals { order: 4; margin-top: clamp(1rem, 3vh, 1.6rem); }
    .overlay .cs-head    { order: 5; }
    .overlay .cs-sections{ order: 6; }
    .overlay .cs-links   { order: 7; }
  }

  @media (max-width: 620px) {
    /* The scale itself is set in JS — `calc(length / number)` is a length, and
       scale() needs a bare number, so doing this in CSS silently produced
       `transform: none`. The rule below only prepares the box. */
    /* display:block matters — the wrapper is a flex container, and as a flex
       ITEM the iframe was being shrunk straight back to the container width,
       so every width set on it computed to 322px however it was set. */
    .cs-embed-wrap { overflow: hidden; border-radius: 12px; display: block; }
    .cs-embed--deck { min-height: 0; max-height: none; aspect-ratio: auto;
      border-radius: 0; transform-origin: top left; }
    /* the non-deck embeds (films, live pages) just get shorter */
    .cs-embed { height: min(52vh, 420px); }
  }


  /* ── The rest of the phone batch (BUILD 121) ─────────────────────────── */
  @media (max-width: 620px) {
    /* the header sits 30px lower, and everything pinned under it follows */
    /* the nav is taller now, so the rail and the hero drop with it rather than
       stacking three things on top of each other at the top of the page */
    .hero-rail--top { top: 106px; border-bottom: 1px solid var(--rule); }
    .hero { padding-top: 182px; }

    /* The reveals were janky here: a blurred, animating layer the width of the
       screen is expensive on a phone, and several were in flight at once.
       Opacity and a short rise only — no filter — and the stagger is tightened
       so the grid is not still arriving when you have scrolled past it. */
    .svc.in > * { animation-duration: 1.1s; animation-delay: calc(var(--i, 0) * 70ms); }
    @keyframes rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
  }

  /* the sun and moon are centred in their button on every screen */

  /* the mark keeps its dark disc wherever it appears in Daylight, not only in
     the nav — it is drawn on a dark ground and needs one under it */


  /* ── Nav vs the brand lockup, and the drop on a phone (BUILD 121) ───── */

  /* The capsule is fixed, so the hero's own mark and wordmark scroll straight
     under it. Rather than move either, the lockup fades out as it approaches —
     the nav already carries the mark, so nothing is lost. Driven by --lockfade
     from the scroll handler. */
  .hero-lockup { opacity: var(--lockfade, 1); transition: opacity .18s linear; }

  @media (max-width: 760px) {
    /* the drop works on a phone too — first tap opens it, second follows the
       link. It was hidden here, which is why tapping just jumped to the section */
    /* `:not(.open)` belongs on the DROP, not the menu — the menu never carries
       that class, so as written this matched whenever the item was hovered and
       forced the panel to stay invisible. On a phone a tap leaves :hover stuck,
       which is why the menu took seconds to appear. */               /* no room for the preview here */
  }


  /* ── Legibility and sizing (BUILD 121) ────────────────────────────────
     Everything here is a size increase for readability, plus the two grids
     brought to the same measure. Last in the stylesheet so it wins. -------- */

  /* the nav reads at arm's length */

  /* the ghost titles at 40% */
  :root { --ghost-ink: rgba(241,238,224,.40); }

  @media (max-width: 620px) {

    /* the project cards take the same measure as the What we build tiles —
       they were 159x99 against the tiles' 159x195 */   /* = the tiles' 159x224 */

    /* card chrome up a step with them */

    /* and the service tiles' own type */
    .svc .tile h3 { font-size: .86rem; }
    .tile p { font-size: .74rem; }
    .kw li { font-size: .52rem; padding: .34em .5em .3em; }
    .stage h3 { font-size: .92rem; }
    .stage p { font-size: .82rem; }
    .shift-them { font-size: .92rem; }
    .shift-us { font-size: 1rem; }
    .foot-col a { font-size: .86rem; }
  }


  /* A card whose face has been unmounted for memory should not read as broken:
     the peek keeps a quiet ground of its own beneath the iframe. */


  /* ── Phone project grid: 1 / 2 / 1 / 2 / 1, and bigger (BUILD 121) ───── */
  @media (max-width: 620px) {
    /* the full-width three */
    /* the paired four, taller than before so they read at a glance */
    /* the full-width cards have room for the larger plate */
  }

  /* ── The nav, 20% up again ───────────────────────────────────────────── */

  /* ── No numbers on the What we build tiles ───────────────────────────── */
  .svc .tile .anum, .svc .tile > .ghost { display: none; }


  /* ── The drop panel: opaque, themed, and instant (BUILD 121) ──────────
     It was taking seconds to appear on a phone. The cause was
     `backdrop-filter: blur(22px) saturate(1.4)` on the panel — compositing a
     blur that size over a busy page is slow enough on a phone to look broken.
     It is a solid 90% surface now, which also means it can follow the theme
     instead of always being dark. ---------------------------------------- */

  @media (max-width: 760px) {
    /* directly under the capsule — `top` here is measured from the capsule
       itself, because its backdrop-filter makes it the containing block for
       fixed children */
    /* no transition on a phone either: the reveal should be immediate */
  }


  /* How it gets built: two by two at every width, not four across. */
  .stages { grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: clamp(1rem, 3vw, 2.4rem); row-gap: clamp(1.4rem, 3.5vh, 2.2rem); }
  .stage + .stage { box-shadow: none; }
  .stage, .stage + .stage { border-top: 2px solid var(--ac); padding: clamp(.9rem, 2.4vh, 1.3rem) 0 0; }
  .stage::before, .stage + .stage::before { display: block; left: 0; top: -5.5px; }
  .approach { display: block; }
  .approach-line { display: none; }


  /* the panel's own content stays above the wash */



  /* ── The brand wash (BUILD 121) ───────────────────────────────────────
     A slow drift of the brand colours behind What we build, Selected work and
     the footer, in BOTH themes — stronger on paper, quieter on the night
     grounds where the specks and nebula already carry colour.
     It goes on an inner wrapper, never on the sheetcard: those wrappers are
     positioned children with their own backgrounds, so anything painted on the
     card behind them never shows. The top of the first one is masked away so
     it fades out of the hero instead of starting on a hard line. ---------- */
  .capsky, .sheetcard--work > .section, .site-foot { position: relative; }
  .capsky > *, .sheetcard--work > .section > *, .site-foot > * { position: relative; z-index: 1; }

  .capsky::before,
  .sheetcard--work > .section::before,
  .site-foot::before {
    /* ONE colour field for the whole document, not one per panel. Each panel
       paints the same gradient, sized to the full page height and offset by its
       own distance from the top (--washY, set in script), so the blobs line up
       across panel boundaries and the wash reads as continuous rather than
       stopping and restarting at every edge. */
    content: ""; display: block; position: absolute; inset: 0;
    z-index: 0; pointer-events: none;
    background-repeat: no-repeat;
    background-size: 100% var(--washH, 100%);
    background-position: 0 var(--washY, 0px);
    background-image:
      radial-gradient(58vw 40vh at 12% 5%, rgba(59,130,224,0.30), transparent 72%),
      radial-gradient(58vw 40vh at 86% 10%, rgba(139,92,246,0.29), transparent 72%),
      radial-gradient(58vw 40vh at 30% 17%, rgba(240,114,26,0.22), transparent 72%),
      radial-gradient(58vw 40vh at 92% 22%, rgba(59,130,224,0.26), transparent 72%),
      radial-gradient(58vw 40vh at 8% 28%, rgba(232,121,74,0.23), transparent 72%),
      radial-gradient(58vw 40vh at 64% 33%, rgba(139,92,246,0.28), transparent 72%),
      radial-gradient(58vw 40vh at 20% 41%, rgba(59,130,224,0.28), transparent 72%),
      radial-gradient(58vw 40vh at 88% 46%, rgba(240,114,26,0.21), transparent 72%),
      radial-gradient(58vw 40vh at 44% 53%, rgba(139,92,246,0.26), transparent 72%),
      radial-gradient(58vw 40vh at 6% 60%, rgba(59,130,224,0.25), transparent 72%),
      radial-gradient(58vw 40vh at 78% 66%, rgba(232,121,74,0.22), transparent 72%),
      radial-gradient(58vw 40vh at 28% 73%, rgba(139,92,246,0.26), transparent 72%),
      radial-gradient(58vw 40vh at 92% 80%, rgba(59,130,224,0.26), transparent 72%),
      radial-gradient(58vw 40vh at 52% 87%, rgba(240,114,26,0.20), transparent 72%),
      radial-gradient(58vw 40vh at 14% 93%, rgba(139,92,246,0.25), transparent 72%),
      radial-gradient(58vw 40vh at 82% 97%, rgba(59,130,224,0.24), transparent 72%);
    filter: blur(34px);
    /* A pure pixel drift, never a scale: every panel shifts by the same amount,
       so the field stays aligned across the joins while it moves. */
    /* static: the drifting wash read as backgrounds shrinking/expanding (Cjay) */
    will-change: transform;
  }
  /* on paper it can be stronger; on near-black it only needs a hint */
  /* Fades are only needed where a washed panel meets one that carries no wash:
     the hero above, the dark difference panel below, and the page's end. Between
     What we build and Selected work there is no fade at all — the field simply
     carries on, which is the whole point. */
  .capsky::before {
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 24%, #000 100%);
    mask-image: linear-gradient(180deg, transparent 0%, #000 24%, #000 100%);
  }
  .sheetcard--work > .section::before {
    -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 76%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 0%, #000 76%, transparent 100%);
  }
  .site-foot::before {
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 30%, #000 84%, transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0%, #000 30%, #000 84%, transparent 100%);
  }
  /* In Daylight the difference panel is the one dark ground on a page of paper,
     so its edges were the two hardest lines on the site. Fade its own ground in
     and out over ~90px and the change of panel stops reading as a rule. */

  /* The hero paints its own ground, so the wash below it was hidden right up to
     the hero's last pixel and then appeared all at once — the "solid line where
     it stops". This bridge carries the same colours up over the hero's bottom
     edge, fading in, so the two grounds meet without a seam. It sits above the
     galaxy layer (z 0) and below the hero copy (z 1). */
  .hero::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0;
    height: min(52vh, 420px); z-index: 0; pointer-events: none;
    background:
      radial-gradient(46% 120% at 20% 118%, rgba(59,130,224,.30), transparent 68%),
      radial-gradient(44% 116% at 78% 112%, rgba(139,92,246,.28), transparent 68%),
      radial-gradient(52% 130% at 58% 132%, rgba(240,114,26,.20), transparent 68%);
    filter: blur(26px);
    /* stops at .45, not 1 — the wash on the other side of the boundary is itself
       only part-way in there, and matching it is the whole point */
    /* Rises to a soft peak and falls away again before the edge, so colour
       appears on both sides of the boundary and neither side starts on a line. */
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, rgba(0,0,0,.34) 62%, transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0%, rgba(0,0,0,.34) 62%, transparent 100%);
    /* static: the drifting wash read as backgrounds shrinking/expanding (Cjay) */
    will-change: transform;
  }
  @media (prefers-reduced-motion: reduce) { .hero::after { animation: none; } }

  @keyframes capsflow {
    0%   { transform: translate3d(0, 0, 0); }
    50%  { transform: translate3d(26px, -20px, 0); }
    100% { transform: translate3d(-22px, 18px, 0); }
  }
  @media (prefers-reduced-motion: reduce) {
    .capsky::before, .sheetcard--work > .section::before, .site-foot::before { animation: none; }
  }


  /* the Work drop carries no preview panel — just the seven, two up */

  /* The nav stays reachable wherever you are, including over an open case
     study — the overlay is z-index 100, so the capsule sits above it. */
  .overlay .overlay-bar { padding-top: clamp(2.6rem, 7vh, 4.2rem); }

  /* the footer mark and wordmark, 40% up */
  .site-foot-brand img { width: 31px; height: 31px; }
  .site-foot-brand .label--strong { font-size: .92rem; letter-spacing: .2em; }
  @media (max-width: 620px) {
    .site-foot-brand img { width: 28px; height: 28px; }
    .site-foot-brand .label--strong { font-size: .82rem; }
  }



/* ==== was the Daylight fork; now the only ground ==================== */
.shift-row + .shift-row { border-top-color: rgba(22,19,31,.08); }
.shift-line { background: linear-gradient(90deg, rgba(22,19,31,.08), var(--ac)); }
.sheetcard--diff {
    /* EXACTLY the hero's ground, not a near-miss: #0B0A16 against the hero's
       #07060F drew a visible step across the page and washed the translucent
       cards out against it. */
    background: #07060F;
    color: #F1EEE0;
    --ground: #07060F;
    --ink: #F1EEE0;
    --ink-muted: #8A88A0;
    --accent: #E8794A;
    --rule: rgba(255,255,255,.10);
    --panel: rgba(18,18,40,.5);
    --glass-bg: rgba(10,12,26,.42);
    --glass-border: rgba(255,255,255,.16);
    --ghost-ink: rgba(241,238,224,.075);
  }
.sheetcard--diff .shift-us { color: #F1EEE0; }
section[aria-labelledby="clients"] { --sec-accent: #16131F; }
section[aria-labelledby="clients"] .quote blockquote::before {
    color: #16131F; opacity: .12;
  }
.stack-card {
    --card-bg: #FFFFFF;
    /* box-shadow lives on the deck-era light rule below — single owner */
  }
.stack-card > .edge-light, .stack-card > .edge-light::before, .stack-card::after { mix-blend-mode: multiply; opacity: calc(0.22 * (var(--edge-proximity) - var(--color-sensitivity)) / (100 - var(--color-sensitivity))); }
.hero-lockup {
    background: #0B0A16;
    color: var(--cream-light);
    padding: .55rem 1.15rem .6rem .7rem;
    border-radius: 100vw;
    box-shadow: 0 14px 34px rgba(28,22,60,.28);
    align-self: flex-start;
  }
.hero-word { color: var(--cream-light); }
.hero .btn--ghost {
    color: var(--ink); border-color: rgba(22,19,31,.28);
  }
.hero .btn--ghost:hover { background: #16131F; color: var(--cream-light); border-color: #16131F; }
.sheetcard {
    box-shadow:
      0 -1px 0 rgba(255,255,255,.7),
      0 -34px 70px rgba(28,22,60,.16);
    border-top: 1px solid rgba(22,19,31,.08);
  }
.sheetcard--stack, .sheetcard--approach {
    box-shadow:
      0 -1px 0 rgba(255,255,255,.75),
      0 -34px 70px rgba(28,22,60,.18);
    border-top: 1px solid rgba(22,19,31,.10);
  }
.sheetcard--stack::after, .sheetcard--approach::after { background: #55506A; }
.capsky { background: rgba(22,19,31,.035); }
.capsky .sheetstars { display: none; }
.apanel {
    background:
      linear-gradient(158deg,
        rgba(255,255,255,.92) 0%,
        rgba(255,255,255,.6) 30%,
        rgba(255,255,255,.38) 60%),
      rgba(255,255,255,.5);
    border: 1px solid rgba(22,19,31,.08);
    box-shadow:
      0 18px 44px rgba(28,22,60,.12),
      inset 0 1px 0 rgba(255,255,255,.95),
      inset 0 -1px 0 rgba(22,19,31,.04);
  }
.apanel > .gloss { opacity: .3; }
.orb-wrap canvas { filter: saturate(1.25) contrast(1.18) brightness(.82); }
.quote {
    background:
      linear-gradient(150deg, rgba(255,255,255,.92) 0%, rgba(255,255,255,.62) 42%, rgba(255,255,255,.4) 62%),
      rgba(255,255,255,.35);
    border: 1px solid rgba(22,19,31,.08);
  }
.quote .qnum { color: rgba(139,92,246,.16); }
.card:hover { box-shadow: 0 18px 40px rgba(28,22,60,.16); }
.stack-card {
    background:
      linear-gradient(150deg, rgba(255,255,255,.95) 0%, rgba(255,255,255,.7) 38%, rgba(255,255,255,.55) 60%),
      rgba(255,255,255,.5);
    box-shadow:
      0 18px 44px rgba(28,22,60,.12),
      inset 0 1px 0 rgba(255,255,255,.95),
      inset 0 -1px 0 rgba(22,19,31,.04);
  }
.stack-card:hover { border-color: rgba(22,19,31,.12); }
.stack-card:hover::before {
    background:
      linear-gradient(rgba(255,255,255,.82) 0 100%) padding-box,
      linear-gradient(120deg, rgba(59,130,224,.55) 0%, rgba(139,92,246,.55) 42%, rgba(240,114,26,.55) 100%) border-box !important;
  }
.sheetcard::after, .sheetcard.sheetcard--stack::after { opacity: .85; }
.sheetcard.sheetcard--diff::after { opacity: .55; }
body { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='320'%3E%3Ccircle cx='24' cy='40' r='1.4' fill='%233B82E0' opacity='.55'/%3E%3Ccircle cx='140' cy='18' r='1' fill='%238B5CF6' opacity='.5'/%3E%3Ccircle cx='250' cy='92' r='1.5' fill='%23F0721A' opacity='.42'/%3E%3Ccircle cx='70' cy='150' r='.9' fill='%23F1EEE0' opacity='.42'/%3E%3Ccircle cx='196' cy='205' r='1.3' fill='%233B82E0' opacity='.42'/%3E%3Ccircle cx='30' cy='252' r='1' fill='%238B5CF6' opacity='.45'/%3E%3Ccircle cx='296' cy='176' r='.9' fill='%23E8794A' opacity='.45'/%3E%3Ccircle cx='110' cy='96' r='.8' fill='%23F1EEE0' opacity='.3'/%3E%3Ccircle cx='172' cy='288' r='1.1' fill='%23F0721A' opacity='.38'/%3E%3Ccircle cx='264' cy='300' r='.8' fill='%233B82E0' opacity='.38'/%3E%3Ccircle cx='88' cy='214' r='1.2' fill='%23E8794A' opacity='.3'/%3E%3Ccircle cx='214' cy='128' r='.8' fill='%238B5CF6' opacity='.35'/%3E%3C/svg%3E"); }
.sheetcard::after { mix-blend-mode: multiply; }
body {
    background-image:
      radial-gradient(60% 40% at 8% 30%, rgba(59,130,224,.06) 0%, rgba(59,130,224,0) 70%),
      radial-gradient(60% 40% at 92% 55%, rgba(139,92,246,.06) 0%, rgba(139,92,246,0) 70%),
      radial-gradient(50% 36% at 50% 96%, rgba(240,114,26,.05) 0%, rgba(240,114,26,0) 70%);
  }
.hero {
    background: var(--ground);
    color: var(--ink);
  }
.galaxy-bg {
    mix-blend-mode: normal;
    filter: none;
    opacity: 1;
  }
.orbs svg { filter: brightness(.72) saturate(1.08); }
.svc { --ill-line: rgba(22,19,31,.55); --ill-fill: rgba(22,19,31,.05); --tint-a: .12;
    --paper: #0B0A18; --paper-ink: #F1EEE0; --paper-muted: #8A88A0; --paper-rule: rgba(255,255,255,.14); --paper-line: rgba(241,238,224,.55); --paper-fill: rgba(241,238,224,.07);
    --slate: #E3DFD3; --slate-ink: #16131F; }
.tile--paper { background: var(--paper); border-color: transparent; box-shadow: 0 18px 44px rgba(28,22,60,.20); }
.tile--slate { background: var(--slate); border-color: transparent; }
.tile > .spot { background: radial-gradient(170px 170px at var(--mx, 50%) var(--my, 50%), rgba(59,130,224,.10), transparent 60%); }
.tile--paper > .spot { background: radial-gradient(170px 170px at var(--mx, 50%) var(--my, 50%), rgba(253,251,244,.14), transparent 60%); }
.tile > .ghost { opacity: .05; }
.tile--paper > .ghost { opacity: .07; }
.tile--gup > .ghost { opacity: .09; }
.tile--gup.tile--paper > .ghost { opacity: .12; }
.tile { background: linear-gradient(158deg, rgba(253,251,244,.82) 0%, rgba(247,244,234,.58) 30%, rgba(240,236,224,.4) 60%), rgba(247,244,234,.44); border: 1px solid rgba(22,19,31,.08); box-shadow: 0 18px 44px rgba(28,22,60,.12), inset 0 1px 0 rgba(253,251,244,.75), inset 0 -1px 0 rgba(22,19,31,.04); }
.tile > .gloss { opacity: .12; }
.tile::before { padding: 1.6px; }
.wwb-rule { opacity: .8; height: 2px; }
.svc .tile--paper { background: var(--paper); border-color: transparent; box-shadow: 0 18px 44px rgba(28,22,60,.22); }
.svc .tile--slate { background: var(--slate); border-color: transparent; }
.qa-card {
    background: linear-gradient(155deg, var(--paper-hi), var(--paper));
    border-color: rgba(22,19,31,.10);
    box-shadow: 0 24px 56px rgba(28,22,60,.16);
  }
.site-foot-brand img, .hero-mono {
    background: #0B0A16; border-radius: 100vw; padding: 4px;
    box-shadow: 0 2px 8px rgba(28,22,60,.28);
  }
.sheetcard--diff { --ghost-ink: rgba(241,238,224,.40); }
.capsky { background: none; }
.capsky::before, .sheetcard--work > .section::before, .site-foot::before {
    background-image:
      radial-gradient(58vw 40vh at 12% 5%, rgba(59,130,224,0.52), transparent 72%),
      radial-gradient(58vw 40vh at 86% 10%, rgba(139,92,246,0.50), transparent 72%),
      radial-gradient(58vw 40vh at 30% 17%, rgba(240,114,26,0.37), transparent 72%),
      radial-gradient(58vw 40vh at 92% 22%, rgba(59,130,224,0.46), transparent 72%),
      radial-gradient(58vw 40vh at 8% 28%, rgba(232,121,74,0.41), transparent 72%),
      radial-gradient(58vw 40vh at 64% 33%, rgba(139,92,246,0.48), transparent 72%),
      radial-gradient(58vw 40vh at 20% 41%, rgba(59,130,224,0.48), transparent 72%),
      radial-gradient(58vw 40vh at 88% 46%, rgba(240,114,26,0.36), transparent 72%),
      radial-gradient(58vw 40vh at 44% 53%, rgba(139,92,246,0.46), transparent 72%),
      radial-gradient(58vw 40vh at 6% 60%, rgba(59,130,224,0.44), transparent 72%),
      radial-gradient(58vw 40vh at 78% 66%, rgba(232,121,74,0.38), transparent 72%),
      radial-gradient(58vw 40vh at 28% 73%, rgba(139,92,246,0.45), transparent 72%),
      radial-gradient(58vw 40vh at 92% 80%, rgba(59,130,224,0.45), transparent 72%),
      radial-gradient(58vw 40vh at 52% 87%, rgba(240,114,26,0.35), transparent 72%),
      radial-gradient(58vw 40vh at 14% 93%, rgba(139,92,246,0.44), transparent 72%),
      radial-gradient(58vw 40vh at 82% 97%, rgba(59,130,224,0.42), transparent 72%);
  }
.sheetcard--diff {
    background-image:
      linear-gradient(180deg, var(--ground-paper, #F2EFE5) 0, rgba(242,239,229,0) 96px),
      linear-gradient(0deg,   var(--ground-paper, #F2EFE5) 0, rgba(242,239,229,0) 80px);
  }
.hero::after {
    background:
      radial-gradient(46% 120% at 20% 118%, rgba(59,130,224,.52), transparent 68%),
      radial-gradient(44% 116% at 78% 112%, rgba(139,92,246,.50), transparent 68%),
      radial-gradient(52% 130% at 58% 132%, rgba(240,114,26,.36), transparent 68%);
  }
/* ======================================================================
   NORTHSTAR — header, hero, services, work, contact, footer
   Everything below is the new system. A sticky header rather than a fixed
   one, so nothing is ever hidden underneath it; no backdrop-filter, which
   was creating a containing block for the fixed overlay and janking on
   phones; and no hover-only menus.
   ====================================================================== */
  html { scroll-padding-top: calc(var(--header-offset) + 12px); }
  #work, #capabilities, #difference, #contact, [id^="work-"] {
    scroll-margin-top: calc(var(--header-offset) + 12px);
  }

  .site-head {
    position: sticky; top: 0; z-index: 120;
    display: flex; align-items: center; gap: clamp(.5rem, 2vw, 1.4rem);
    /* Content sits on the same span as the work tiles: centred
       min(max-w, 100% − 2·pad-x), plus the spine-gap on the left. */
    padding: .85rem calc((100% - min(var(--max-w), 100% - 2 * var(--pad-x))) / 2)
             .85rem calc((100% - min(var(--max-w), 100% - 2 * var(--pad-x))) / 2 + var(--spine-gap));
    background: var(--navy); color: var(--on-navy);
    border-bottom: 0;
    transition: background-color .25s var(--ease-out), padding .25s var(--ease-out),
                box-shadow .25s var(--ease-out), border-color .25s var(--ease-out);
  }
  .site-head.is-scrolled {
    padding-top: .5rem; padding-bottom: .5rem;
    /* Stays navy on scroll — the white flip read as a different site (Cjay). */
    background: var(--navy);
    box-shadow: 0 6px 22px rgba(4,3,12,.45);
  }
  .hd-brand { display: inline-flex; align-items: center; gap: .6rem; min-height: 44px;
    text-decoration: none; color: inherit; padding: .2rem; border-radius: 12px; }
  .hd-brand img { width: 30px; height: 30px; display: block; border-radius: 50%; background: #0B0A18; }
  .hd-word { font-family: var(--font-display); font-weight: 600; letter-spacing: .12em;
    text-transform: uppercase; font-size: .82rem; white-space: nowrap; }

  .hd-nav { display: flex; align-items: center; gap: .2rem; margin-left: auto; }
  .hd-link { display: inline-flex; align-items: center; gap: .4em; min-height: 44px;
    padding: .55em .85em; border: 0; background: none; font-family: var(--font-mono);
    font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: inherit;
    text-decoration: none; border-radius: 100vw; cursor: pointer; }
  .hd-link svg { width: 11px; height: 8px; opacity: .7; transition: transform .2s var(--ease-out); }
  .hd-link:hover { background: rgba(255,255,255,.10); }
  .site-head.is-scrolled .hd-link:hover { background: rgba(255,255,255,.10); }
  .hd-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }
  .hd-cta { min-height: 44px; display: inline-flex; align-items: center; padding: .6em 1.15em;
    border-radius: 100vw; background: var(--orange-blaze); color: #16131F;
    font-family: var(--font-mono); font-size: .72rem; letter-spacing: .1em;
    text-transform: uppercase; text-decoration: none; font-weight: 700; white-space: nowrap; }
  .hd-cta:hover { background: #FF862F; }

  .hd-menu-wrap { position: relative; }
  .hd-menu { position: absolute; top: calc(100% + .55rem); right: 0;
    width: min(460px, 86vw); padding: .5rem; background: var(--paper-hi); color: var(--ink);
    border: 1px solid var(--rule); border-radius: 18px;
    box-shadow: 0 26px 60px rgba(28,22,60,.20); display: grid; gap: .1rem;
    opacity: 0; pointer-events: none; transform: translateY(-6px);
    transition: opacity .18s var(--ease-out), transform .18s var(--ease-out); }
  .hd-menu-wrap.open .hd-menu { opacity: 1; pointer-events: auto; transform: none; }
  .hm-item { display: block; min-height: 44px; padding: .6rem .7rem; border-radius: 12px;
    text-decoration: none; color: inherit; }
  .hm-item:hover, .hm-item:focus-visible { background: rgba(22,19,31,.06); }
  .hm-item span { display: block; font-family: var(--font-display); font-weight: 700; font-size: .95rem; }
  .hm-item small { display: block; margin-top: .1rem; color: var(--ink-muted);
    font-size: .78rem; line-height: 1.45; }
  .hm-all { display: flex; align-items: center; min-height: 44px; margin-top: .3rem;
    padding: .6rem .7rem; border-radius: 12px; font-family: var(--font-mono);
    font-size: .68rem; letter-spacing: .1em; text-transform: uppercase;
    text-decoration: none; color: var(--accent); }
  .hm-all:hover { background: rgba(240,114,26,.10); }

  .hd-burger { display: none; width: 44px; height: 44px; border: 0; background: none;
    cursor: pointer; padding: 10px; color: inherit; }
  .hd-burger span { display: block; height: 2px; border-radius: 2px; background: currentColor;
    margin: 4px 0; transition: transform .2s var(--ease-out), opacity .2s var(--ease-out); }
  .hd-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
  .hd-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
  .hd-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

  .hd-sheet { position: fixed; inset: 0; z-index: 200; background: var(--navy);
    color: var(--on-navy); overflow-y: auto; }
  .hd-sheet[hidden] { display: none; }
  .hd-sheet-in { min-height: 100%; padding: 1.2rem clamp(1.2rem, 6vw, 2rem) 3rem;
    display: flex; flex-direction: column; gap: .2rem; }
  .hd-sheet-close { align-self: flex-end; min-height: 44px; padding: .6em 1em;
    border: 1px solid rgba(255,255,255,.22); background: none; color: inherit;
    border-radius: 100vw; font-family: var(--font-mono); font-size: .7rem;
    letter-spacing: .12em; text-transform: uppercase; cursor: pointer; }
  .hd-sheet-lead { font-family: var(--font-display); font-weight: 700;
    font-size: clamp(1.6rem, 8vw, 2.2rem); color: inherit; text-decoration: none;
    padding: .55rem 0; min-height: 48px; }
  .hd-sheet-kicker { margin: 1.1rem 0 .2rem; font-family: var(--font-mono); font-size: .68rem;
    letter-spacing: .16em; text-transform: uppercase; color: var(--on-navy-muted); }
  .hd-sheet-list { display: grid; }
  .hd-sheet-list a { min-height: 52px; display: flex; align-items: center; color: inherit;
    text-decoration: none; font-size: 1.02rem; border-bottom: 1px solid rgba(255,255,255,.10); }
  .hd-sheet-cta { margin-top: 1.6rem; min-height: 52px; display: inline-flex; align-items: center;
    justify-content: center; border-radius: 100vw; background: var(--orange-blaze); color: #16131F;
    text-decoration: none; font-family: var(--font-mono); font-size: .78rem;
    letter-spacing: .12em; text-transform: uppercase; font-weight: 700; }
  .hd-sheet-lang { display: inline-flex; align-items: center; min-height: 44px; margin-top: .9rem;
    color: inherit; text-decoration: none; font-family: var(--font-mono); font-size: .78rem;
    letter-spacing: .12em; text-transform: uppercase; opacity: .75; }
  .hd-sheet-lang:hover { opacity: 1; text-decoration: underline; }

  @media (max-width: 760px) {
    .hd-nav { display: none; }
    .hd-burger { display: block; margin-left: auto; }
    .hd-cta { font-size: .56rem; padding: .45em .75em; min-height: 34px; }
    .hd-word { font-size: .72rem; letter-spacing: .1em; }
    .site-head { padding: .6rem .8rem; gap: .5rem; }
    .hero-rail, .foot-marquee { display: none !important; }
  }
  a:focus-visible, button:focus-visible, summary:focus-visible, [tabindex]:focus-visible {
    outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 8px;
  }

/* ===== Hero — normal flow, navy ground, sparse slow stars ============== */
  .hero { position: relative; display: flex; align-items: flex-end;
    /* the old hero was pinned to --hero-h (60svh); it is content-led now, with
       a floor, which is what took 100px off it */
    height: auto; min-height: min(49vh, 440px);
    background: var(--navy); color: var(--on-navy);
    padding: clamp(1.8rem, 4.6vh, 3.4rem) 0 clamp(1.6rem, 3.6vh, 2.8rem); overflow: hidden; }
  /* Same box as every section's .inner: sections centre min(max-w, vw − 2·pad-x)
     via section padding + auto margins; computing the min() here makes the hero
     land on identical edges at every width, and the spine-gap pad matches the
     tiles' first-column offset. Content only — the galaxy stays full-bleed. */
  .hero .inner { position: relative; z-index: 1; width: 100%; align-self: center; height: auto;
    max-width: min(var(--max-w), calc(100vw - 2 * var(--pad-x))); margin: 0 auto; padding: 0; }
  @media (min-width: 1101px) {
    .hero .content { padding-left: var(--spine-gap); }
  }
  .hero .content { display: block; height: auto; min-height: 0; }
  .hero .galaxy-bg { position: absolute; inset: 0; z-index: 0; }
  /* the hero opens on the header's exact navy and the galaxy fades in below,
     so bar and hero read as one surface (Cjay) */
  .hero::after { content: ""; position: absolute; top: 0; left: 0; right: 0;
    height: clamp(90px, 14vh, 150px); pointer-events: none; z-index: 0;
    background: linear-gradient(180deg, var(--navy) 0%, rgba(14,18,32,.55) 55%, transparent 100%); }
  /* Galaxy ground: brand-tinted nebulae and a faint milky band under the
     streak canvas — the flat navy read as empty, not as space (Cjay). */
  .hero .galaxy-bg::before { content: ""; position: absolute; inset: 0;
    background:
      radial-gradient(52% 38% at 74% 24%, rgba(139,92,246,.16), transparent 68%),
      radial-gradient(44% 34% at 18% 66%, rgba(59,130,224,.14), transparent 70%),
      radial-gradient(30% 24% at 60% 78%, rgba(240,114,26,.08), transparent 72%),
      linear-gradient(118deg, transparent 34%, rgba(241,238,224,.045) 47%, rgba(139,92,246,.05) 53%, transparent 66%);
  }
  .hero-eyebrow { font-family: var(--font-mono); font-size: .68rem; letter-spacing: .18em;
    text-transform: uppercase; color: var(--on-navy-muted); margin-bottom: 1rem; }
  .hero-headline { font-family: var(--font-display); font-weight: 800;
    font-size: clamp(2.1rem, 6.4vw, 4.4rem); line-height: 1.02; letter-spacing: -.02em;
    color: var(--on-navy); margin: 0; }
  .hero-sub { margin: 1.1rem 0 0; max-width: 46ch; font-size: clamp(1rem, 1.4vw, 1.16rem);
    line-height: 1.6; color: var(--on-navy-muted); }
  /* the old hero pulled its buttons up 40px under a lockup that is gone */
  .hero .hero-cta { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: 1.9rem;
    position: static; top: auto; justify-content: flex-start; }
  .hero .btn { min-height: 48px; display: inline-flex; align-items: center; }
  .hero .btn--primary { background: var(--orange-blaze); color: #16131F; border-color: transparent; }
  .hero .btn--primary:hover { background: #FF862F; color: #16131F; }
  .hero .btn--ghost { color: var(--on-navy); border-color: rgba(255,255,255,.34); background: none; }
  .hero .btn--ghost:hover { background: rgba(255,255,255,.10); color: var(--on-navy); }
  .hero-rail { color: var(--on-navy-muted); }
  @media (max-width: 760px) {
    .hero { min-height: auto; padding-top: clamp(2rem, 6vh, 3rem); }
    .hero-sub { font-size: 1rem; }
    .hero .hero-cta .btn { flex: 1 1 auto; justify-content: center; padding: .9em 1rem; }
  }
  @media (prefers-reduced-motion: reduce) { .hero .galaxy-bg { display: none; } }

/* ===== Section watermarks — never cropped ============================== */
  .section .content h2.label--strong { left: 0; }
  @media (max-width: 900px) { .section .content h2.label--strong { font-size: clamp(2rem, 9vw, 3.4rem); } }
  @media (max-width: 760px) {
    /* the spine column's flex gap pushed all content ~18px right of centre
       on phones; the spine is invisible there anyway (Cjay) */
    .inner { gap: 0; }
    .site-head { padding-left: calc((100% - min(var(--max-w), 100% - 2 * var(--pad-x))) / 2); }
    .site-foot { padding-left: calc((100% - min(var(--max-w), 100% - 2 * var(--pad-x))) / 2) !important; }
    .hero-rail--top { left: calc((100% - min(var(--max-w), 100% - 2 * var(--pad-x))) / 2); }
    .hero .content { padding-left: 0; }
    .section .content h2.label--strong { display: none; }
    /* the section ghosts read as real titles on phones (Cjay) */
    .section .content h2#capabilities.label--strong,
    .section .content h2#work.label--strong,
    .section .content h2#difference.label--strong { display: block; font-size: clamp(2.7rem, 11.5vw, 3.4rem); }
    /* lift the title clear of the cards and give it more presence — at -78%
       too much of it was buried, and .4 read too faint on a phone (Cjay) */
    .section .content h2#capabilities.label--strong { transform: translateY(-90%); color: rgba(86, 84, 100, .55); }

  }

/* ===== What we build — eight equal cards, commerce first =============== */
  /* The cards keep the bento's hook classes so the miniature animations still
     find them; the bento's own grid placement is overridden here. */
  .svc.svc-grid { display: grid !important; gap: clamp(.9rem, 1.6vw, 1.3rem);
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    grid-template-areas: none !important; grid-auto-rows: auto !important;
    /* the bento's EXPLICIT row tracks survived the override and reserved
       ~480px of empty space below the tiles */
    grid-template-rows: none !important; }
  @media (min-width: 1100px) {
    .svc.svc-grid { grid-template-columns: repeat(4, minmax(0, 1fr)) !important; }
  }
  .svc-grid > .svc-card { grid-area: auto !important; align-items: stretch !important; }
  /* `--paper` flips per tile: the cards the bento marked `tile--paper` are the
     dark ones in the run, exactly as they were. Everything the drawings use —
     line, fill, rule, muted — comes off these two sets. */
  .svc-grid .svc-card {
    --paper-line: rgba(22,19,31,.64); --paper-fill: rgba(22,19,31,.055);
    --ill-line: rgba(22,19,31,.64);   --ill-fill: rgba(22,19,31,.055);
  }
  /* Which cards are dark depends on how many sit in a row, so it is decided by
     position, not by a class in the markup. Two across: dark, light / light,
     dark — a chequer. Four across: dark, light, dark, light, straight across. */
  .svc-grid .svc-card:nth-child(4n+1), .svc-grid .svc-card:nth-child(4n+4) {
    background: var(--navy) !important; color: var(--on-navy) !important;
    border-color: rgba(255,255,255,.10) !important;
    --ink: var(--on-navy); --ink-muted: var(--on-navy-muted);
    --paper-ink: var(--on-navy); --paper-muted: var(--on-navy-muted);
    --paper-rule: rgba(255,255,255,.14); --rule: rgba(255,255,255,.14);
    --paper-line: rgba(241,238,224,.55); --paper-fill: rgba(241,238,224,.07);
    --ill-line: rgba(241,238,224,.55);   --ill-fill: rgba(241,238,224,.07);
  }
  .svc-grid .svc-card:nth-child(4n+1), .svc-grid .svc-card:nth-child(4n+4) h3 { color: var(--ink); }
  .svc-grid .svc-card:nth-child(4n+1), .svc-grid .svc-card:nth-child(4n+4) p  { color: var(--ink-muted); }
  .svc-grid .svc-card:nth-child(4n+2), .svc-grid .svc-card:nth-child(4n+3) {
    background: var(--paper-hi) !important; color: #16131F !important;
    border-color: rgba(22,19,31,.14) !important;
    --ink: #16131F; --ink-muted: #4C4658;
    --paper-ink: #16131F; --paper-muted: #4C4658;
    --paper-rule: rgba(22,19,31,.18); --rule: rgba(22,19,31,.14);
    --paper-line: rgba(22,19,31,.64); --paper-fill: rgba(22,19,31,.055);
    --ill-line: rgba(22,19,31,.64);   --ill-fill: rgba(22,19,31,.055);
  }
  .svc-grid .svc-card:nth-child(4n+2), .svc-grid .svc-card:nth-child(4n+3) h3 { color: var(--ink); }
  .svc-grid .svc-card:nth-child(4n+2), .svc-grid .svc-card:nth-child(4n+3) p  { color: var(--ink-muted); }
  @media (min-width: 1100px) {
    .svc-grid .svc-card:nth-child(odd) {
      background: var(--navy) !important; color: var(--on-navy) !important;
      border-color: rgba(255,255,255,.10) !important;
      --ink: var(--on-navy); --ink-muted: var(--on-navy-muted);
      --paper-ink: var(--on-navy); --paper-muted: var(--on-navy-muted);
      --paper-rule: rgba(255,255,255,.14); --rule: rgba(255,255,255,.14);
      --paper-line: rgba(241,238,224,.55); --paper-fill: rgba(241,238,224,.07);
      --ill-line: rgba(241,238,224,.55);   --ill-fill: rgba(241,238,224,.07);
    }
    .svc-grid .svc-card:nth-child(odd) h3 { color: var(--ink); }
    .svc-grid .svc-card:nth-child(odd) p  { color: var(--ink-muted); }
    .svc-grid .svc-card:nth-child(even) {
      background: var(--paper-hi) !important; color: #16131F !important;
      border-color: rgba(22,19,31,.14) !important;
      --ink: #16131F; --ink-muted: #4C4658;
      --paper-ink: #16131F; --paper-muted: #4C4658;
      --paper-rule: rgba(22,19,31,.18); --rule: rgba(22,19,31,.14);
      --paper-line: rgba(22,19,31,.64); --paper-fill: rgba(22,19,31,.055);
      --ill-line: rgba(22,19,31,.64);   --ill-fill: rgba(22,19,31,.055);
    }
    .svc-grid .svc-card:nth-child(even) h3 { color: var(--ink); }
    .svc-grid .svc-card:nth-child(even) p  { color: var(--ink-muted); }
  }
  /* the bento sized and placed some of these per tile; here every card is the
     same shape, so the copy runs the full width of it */
  .svc-grid .svc-card > h3,
  .svc-grid .svc-card > p,
  .svc-grid .svc-card > .svc-num,
  .svc-grid .svc-card > .svc-open {
    width: auto !important; max-width: none !important; flex: none !important;
    margin-left: 0 !important; margin-right: 0 !important; align-self: stretch !important;
    text-align: left !important; }
  .svc-grid .svc-card { position: relative; display: flex; flex-direction: column; gap: .5rem;
    padding: clamp(1.1rem, 2vw, 1.5rem); background: var(--paper-hi); color: var(--ink);
    text-decoration: none; border: 1px solid var(--rule); border-radius: 20px;
    box-shadow: 0 10px 26px rgba(28,22,60,.06); --ac: var(--orange-blaze);
    transition: transform .25s var(--ease-out), box-shadow .25s var(--ease-out),
                border-color .25s var(--ease-out); }
  .svc--violet { --ac: var(--violet); } .svc--blue { --ac: var(--blue); }
  .svc--coral { --ac: var(--orange-coral); }
  .svc-card:hover { transform: translateY(-3px); box-shadow: 0 20px 44px rgba(28,22,60,.13);
    border-color: rgba(22,19,31,.2); }
  .svc-num { font-family: var(--font-mono); font-size: .62rem; letter-spacing: .16em; color: var(--ac); }
  /* The drawing is a direct child of the card: the bento sizes each one with
     `.tile--ai > .ill`, a direct-child selector, and a wrapper broke it — which
     is why they came out as cropped slivers. */
  .svc-grid .svc-card > .ill { margin: .3rem 0 .6rem; width: 100%; }
  .svc-grid .svc-card > .ill svg { width: 100%; height: 100%; display: block; }
  /* four of them carried only a max-height in the bento, and the base .ill
     height is 64px, so their real height has to be named here */
  .svc-grid .svc-card.tile--ai   > .ill { height: clamp(172px, 16.8vw, 214px); }
  .svc-grid .svc-card.tile--flow > .ill { height: clamp(94px, 9vw, 112px); }
  .svc-grid .svc-card.tile--web  > .ill { height: clamp(94px, 9vw, 112px); }
  .svc-grid .svc-card.tile--s    > .ill { height: clamp(132px, 12.5vw, 158px); }
  .svc-grid .svc-card h3 { margin: .35rem 0 0; font-family: var(--font-display); font-weight: 800;
    font-size: clamp(1.12rem, 1.7vw, 1.35rem); line-height: 1.12; letter-spacing: -.01em; }
  .svc-grid .svc-card p { margin: 0; color: var(--ink-muted); font-size: .93rem; line-height: 1.55; }
  .svc-open { margin-top: auto; padding-top: .7rem; font-family: var(--font-mono);
    font-size: .66rem; letter-spacing: .12em; text-transform: uppercase; color: var(--ac); }
  @media (max-width: 760px) {
    /* two across on a phone, still alternating dark and light as you read */
    .svc.svc-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
      gap: .7rem; }
    .svc-grid .svc-card { padding: .85rem; }
    .svc-grid .svc-card h3 { font-size: 1rem; }
    .svc-grid .svc-card p { font-size: .82rem; }
    .svc-grid .svc-card > .ill { margin: .2rem 0 .45rem; }
    .svc-grid .svc-card.tile--ai   > .ill { height: 116px; }
    .svc-grid .svc-card.tile--crm  > .ill { height: 108px; }
    .svc-grid .svc-card.tile--com  > .ill { height: 104px; }
    .svc-grid .svc-card.tile--s    > .ill { height: 100px; }
    .svc-grid .svc-card.tile--brand > .ill { height: 78px; }
  }

/* ===== Selected work — five posters, commerce first ====================
   Static screenshots, not live product UI in an iframe: seven embedded apps
   was the heaviest thing on the page and the reason phones ran out of memory. */
  .wgrid { display: grid; gap: clamp(1rem, 2vw, 1.6rem);
    grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr)); }
  .wcard { display: flex; flex-direction: column; text-align: left; padding: 0;
    border: 1px solid var(--rule); border-radius: 22px; background: var(--paper-hi);
    color: var(--ink); overflow: hidden; cursor: pointer; font: inherit;
    box-shadow: 0 12px 30px rgba(28,22,60,.07);
    transition: transform .25s var(--ease-out), box-shadow .25s var(--ease-out); }
  .wcard:hover { transform: translateY(-3px); box-shadow: 0 22px 48px rgba(28,22,60,.14); }
  /* The live face sits over its own poster. The poster is never removed, so a
     card that is torn down (or whose frame is still loading) shows the picture
     instead of going blank — which is what the old grid did. */
  .wshot { position: relative; display: block; background: var(--navy);
    aspect-ratio: 660 / 412; overflow: hidden; }
  .wshot img { position: absolute; inset: 0; width: 100%; height: 100%;
    object-fit: cover; display: block; }
  .wshot iframe { position: absolute; left: 50%; top: 50%; border: 0;
    transform-origin: center; opacity: 0; transition: opacity .45s var(--ease-out);
    pointer-events: none; }
  .wshot iframe.on { opacity: 1; }
  @media (prefers-reduced-motion: reduce) { .wshot iframe { display: none; } }
  /* The poster itself drifts, slowly, so a card whose live face cannot run —
     Low Power Mode, data saver, a struggling phone — still moves. It is a
     compositor-only transform animation, which keeps running when scripts
     and timers are throttled. Both ends of the drift keep the image
     over-scaled, so no edge is ever exposed. Paused once a live face is
     actually showing; off entirely under reduced motion. */
  @media (prefers-reduced-motion: no-preference) {
    .wshot img { animation: posterDrift 22s ease-in-out infinite alternate; }
    .wcard:nth-child(even) .wshot img { animation-duration: 27s; animation-direction: alternate-reverse; }
    .wshot:has(iframe.on) img { animation-play-state: paused; }
  }
  @keyframes posterDrift {
    from { transform: scale(1.07) translate(-1.3%, -.7%); }
    to   { transform: scale(1.13) translate(1.3%, .7%); }
  }
  .wbody { display: flex; flex-direction: column; gap: .5rem; padding: clamp(.95rem, 1.6vw, 1.3rem); }
  .wtop { display: flex; align-items: baseline; flex-wrap: wrap; gap: .5rem; }
  .wtitle { font-family: var(--font-display); font-weight: 800;
    font-size: clamp(1.1rem, 1.6vw, 1.3rem); line-height: 1.1; }
  .wcat { font-family: var(--font-mono); font-size: .62rem; letter-spacing: .14em;
    text-transform: uppercase; color: var(--ink-muted); }
  .wline { color: var(--ink-muted); font-size: .93rem; line-height: 1.5; }
  /* tags wrap on their own row, so they can never crowd the title */
  .wtags { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .15rem; }
  .wtags i { font-style: normal; font-family: var(--font-mono); font-size: .6rem;
    letter-spacing: .1em; text-transform: uppercase; padding: .42em .7em; border-radius: 100vw;
    background: rgba(22,19,31,.06); color: var(--ink-muted); }
  @media (min-width: 1100px) {
    .wgrid { grid-template-columns: repeat(6, 1fr); }
    .wcard { grid-column: span 2; }
    .wcard:nth-child(1), .wcard:nth-child(2) { grid-column: span 3; }
  }
  @media (max-width: 760px) { .wgrid { grid-template-columns: 1fr; } }

/* ===== Contact — a form that does something ============================ */
  .contact-grid { display: grid; gap: clamp(1.6rem, 3vw, 3rem);
    grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); align-items: start; }
  @media (max-width: 900px) { .contact-grid { grid-template-columns: 1fr; } }
  .contact-head { font-family: var(--font-display); font-weight: 800;
    font-size: clamp(1.5rem, 3vw, 2.2rem); line-height: 1.1; margin: 0 0 .5rem; }
  .contact-sub { margin: 0 0 1.4rem; color: var(--ink-muted); font-size: 1rem; line-height: 1.6; }
  .cform { display: grid; gap: .8rem; }
  .cf-row { display: grid; gap: .8rem; grid-template-columns: 1fr 1fr; }
  @media (max-width: 560px) { .cf-row { grid-template-columns: 1fr; } }
  .cf-field { display: grid; gap: .3rem; }
  .cf-field[hidden] { display: none; }
  .cf-seg { display: flex; gap: .5rem; }
  .cf-seg-opt { flex: 1; cursor: pointer; }
  .cf-seg-opt input { position: absolute; opacity: 0; pointer-events: none; }
  .cf-seg-opt span { display: block; text-align: center; padding: .6rem .9rem;
    border: 1px solid rgba(22,19,31,.22); border-radius: .55rem;
    font-size: .86rem; transition: background .15s, color .15s, border-color .15s; }
  .cf-seg-opt input:checked + span { background: #16131F; color: #F4F1E8; border-color: #16131F; }
  .cf-seg-opt input:focus-visible + span { outline: 2px solid currentColor; outline-offset: 2px; }
  .cf-field > span { font-family: var(--font-mono); font-size: .64rem; letter-spacing: .14em;
    text-transform: uppercase; color: var(--ink-muted); }
  .cf-field input, .cf-field select, .cf-field textarea {
    min-height: 48px; width: 100%; padding: .7rem .85rem; font: inherit; font-size: 1rem;
    color: var(--ink); background: var(--paper-hi); border: 1px solid var(--rule); border-radius: 12px; }
  .cf-field textarea { min-height: 120px; resize: vertical; }
  .cf-field input:focus-visible, .cf-field select:focus-visible, .cf-field textarea:focus-visible {
    outline: 3px solid var(--accent); outline-offset: 1px; border-color: transparent; }
  .cf-field.bad input, .cf-field.bad textarea { border-color: #B4261C; background: #FDF3F2; }
  .cf-actions { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin-top: .3rem; }
  .cf-send { min-height: 50px; min-width: 140px; justify-content: center; display: inline-flex;
    align-items: center; padding: .8em 1.8em; border: 0; border-radius: 100vw; cursor: pointer;
    background: var(--orange-blaze); color: #16131F; font-family: var(--font-mono);
    font-size: .74rem; letter-spacing: .12em; text-transform: uppercase; font-weight: 700; }
  .cf-send:hover { background: #FF862F; }
  .cf-note { margin: 0; font-size: .88rem; line-height: 1.5; color: var(--ink-muted); }
  .cf-note.ok { color: #14532D; } .cf-note.bad { color: #9F1D14; }
  .contact-or { margin: 1.3rem 0 0; color: var(--ink-muted); font-size: .92rem; }
  /* the old page set this as a display-sized gradient headline; here it is a
     secondary line under the form, so it reads at body size */
  .contact-copy .contact-mail, a.contact-mail {
    display: inline-flex; align-items: center; min-height: 44px;
    font-family: var(--font-body); font-size: 1rem; font-weight: 600;
    letter-spacing: 0; background: none; -webkit-background-clip: border-box;
    background-clip: border-box; -webkit-text-fill-color: currentColor;
    color: var(--accent); text-decoration: none; }
  .contact-mail:hover { text-decoration: underline; }

/* ===== Q&A — a plain accordion, with a little colour ==================== */
  .qa { position: relative; }
  .qa::before {
    content: ""; position: absolute; inset: -1.4rem -1.2rem -1.4rem -1.2rem;
    z-index: 0; pointer-events: none; border-radius: 22px;
    background:
      radial-gradient(70% 55% at 12% 8%,  rgba(59,130,224,.16), transparent 70%),
      radial-gradient(64% 52% at 92% 26%, rgba(139,92,246,.15), transparent 70%),
      radial-gradient(72% 58% at 70% 96%, rgba(240,114,26,.12), transparent 72%);
    filter: blur(18px);
  }
  .qa > * { position: relative; z-index: 1; }
  .qa-label::after {
    content: ""; display: inline-block; width: 7px; height: 7px; margin-left: .5em;
    border-radius: 50%; background: var(--orange-blaze); vertical-align: .05em;
  }
  /* each answer takes a brand colour in turn, so the column is not all ink */
  .qa-item { --qa: var(--blue); }
  .qa-item:nth-child(4n+2) { --qa: var(--violet); }
  .qa-item:nth-child(4n+3) { --qa: var(--orange-blaze); }
  .qa-item:nth-child(4n+4) { --qa: var(--orange-coral); }
  .qa-item > summary { position: relative; padding-left: .95rem; }
  .qa-item > summary::before {
    content: ""; position: absolute; left: 0; top: 50%; width: 3px; height: 0;
    transform: translateY(-50%); border-radius: 3px; background: var(--qa);
    transition: height .22s var(--ease-out);
  }
  .qa-item[open] > summary::before,
  .qa-item > summary:hover::before { height: 0; }
  .qa-item > summary::before { display: none; }
  .qa-item[open] > summary { color: var(--qa); }
  .qa-item[open] > summary::after { border-color: var(--qa); }
  .qa-body { padding-left: .95rem; }

  .qa-label { font-family: var(--font-mono); font-size: .66rem; letter-spacing: .18em;
    text-transform: uppercase; color: var(--ink-muted); margin: 0 0 .7rem; }
  .qa-acc { border-top: 1px solid var(--rule); }
  .qa-item { border-bottom: 1px solid var(--rule); }
  .qa-item > summary { list-style: none; cursor: pointer; min-height: 52px; display: flex;
    align-items: center; justify-content: space-between; gap: 1rem; padding: .9rem 0;
    font-family: var(--font-display); font-weight: 700; font-size: 1rem; line-height: 1.3; }
  .qa-item > summary::-webkit-details-marker { display: none; }
  .qa-item > summary::after { content: ""; flex: none; width: 12px; height: 12px;
    border-right: 2px solid var(--ink-muted); border-bottom: 2px solid var(--ink-muted);
    transform: rotate(45deg) translate(-2px, -2px); transition: transform .2s var(--ease-out); }
  .qa-item[open] > summary::after { transform: rotate(-135deg) translate(-3px, -3px); }
  .qa-body { padding: 0 0 1rem; color: var(--ink-muted); font-size: .95rem; line-height: 1.6; }
  .qa-body p { margin: 0; }

/* ===== The difference panel — no edge, either side =====================
   A straight cream-to-navy ramp still reads as a band, because alpha moves
   linearly while the eye does not. These are eased over twice the distance,
   so the panel arrives and leaves without a boundary. */
  .sheetcard--diff {
    background-color: var(--navy);
    background-image:
      linear-gradient(180deg,
        rgb(244,239,230) 0%,
        rgba(244,239,230,.94) 10%,
        rgba(244,239,230,.80) 24%,
        rgba(244,239,230,.58) 40%,
        rgba(244,239,230,.34) 57%,
        rgba(244,239,230,.15) 74%,
        rgba(244,239,230,.04) 89%,
        rgba(244,239,230,0)  100%),
      linear-gradient(0deg,
        rgb(244,239,230) 0%,
        rgba(244,239,230,.94) 10%,
        rgba(244,239,230,.80) 24%,
        rgba(244,239,230,.58) 40%,
        rgba(244,239,230,.34) 57%,
        rgba(244,239,230,.15) 74%,
        rgba(244,239,230,.04) 89%,
        rgba(244,239,230,0)  100%);
    background-size: 100% clamp(180px, 26vh, 260px), 100% clamp(160px, 23vh, 230px);
    /* the ramp is a background, so the copy has to start after it — cream type
       part-way down a cream-to-navy fade is unreadable */
    padding-top: clamp(190px, 27vh, 275px);
    padding-bottom: clamp(170px, 24vh, 245px);
    background-position: top center, bottom center;
    background-repeat: no-repeat;
  }

/* ===== Hero meeting the paper ==========================================
   The hero's foot was the last straight line on the page. The ramp lives in
   the top of the panel below it rather than in the hero, so the hero keeps
   its height and the buttons keep their dark ground. */
  .sheetcard--caps {
    background-color: var(--ground);
    background-image: linear-gradient(180deg,
      rgb(14,18,32) 0%,
      rgba(14,18,32,.92) 12%,
      rgba(14,18,32,.74) 28%,
      rgba(14,18,32,.48) 46%,
      rgba(14,18,32,.24) 66%,
      rgba(14,18,32,.07) 85%,
      rgba(14,18,32,0) 100%);
    background-size: 100% clamp(110px, 15vh, 160px);
    background-position: top center;
    background-repeat: no-repeat;
  }
  /* the watermark starts below the ramp, not inside it */
  /* a notch closer to the hero than the original 20vh — same dissolve, less air */
  .sheetcard--caps > .capsky > .section { padding-top: clamp(5.4rem, 12vh, 7.5rem); }

/* ===== Selected work ==================================================== */
  /* 30px off the tail, below the last card */
  .sheetcard--work > .section { padding-bottom: clamp(2.9rem, 6.1vh, 4.9rem); }

/* ===== Footer — the second navy ground ================================= */
  /* Full-bleed: it used to sit inset inside the contact panel's content
     column, which drew a paper margin down both sides of the navy and cut
     the wash off with it. */
  .site-foot {
    border-radius: 0 !important;
    /* Same span as the work tiles — content never runs outside it (Cjay). */
    padding-left: calc((100% - min(var(--max-w), 100% - 2 * var(--pad-x))) / 2 + var(--spine-gap)) !important;
    padding-right: calc((100% - min(var(--max-w), 100% - 2 * var(--pad-x))) / 2) !important;
  }
  @media (max-width: 760px) {
    .site-foot { padding-left: calc((100% - min(var(--max-w), 100% - 2 * var(--pad-x))) / 2) !important; }
    padding-top: clamp(9rem, 19vh, 12rem) !important;
    background-color: var(--navy);
    background-image: linear-gradient(180deg,
      rgb(244,239,230) 0%,
      rgba(244,239,230,.92) 12%,
      rgba(244,239,230,.74) 28%,
      rgba(244,239,230,.48) 46%,
      rgba(244,239,230,.24) 66%,
      rgba(244,239,230,.07) 85%,
      rgba(244,239,230,0) 100%);
    background-size: 100% clamp(120px, 17vh, 180px);
    background-position: top center;
    background-repeat: no-repeat;
  }

  .sheetcard--contact .site-foot,
  .site-foot {
    /* background-COLOR, not the shorthand: the shorthand was wiping the ramp
       set above it and putting the hard paper-to-navy edge back. */
    background-color: var(--navy); color: var(--on-navy);
    margin-top: clamp(2.5rem, 6vh, 4.5rem);
    padding: clamp(2rem, 5vh, 3.4rem) clamp(1.2rem, 4vw, 3rem) clamp(1.4rem, 3vh, 2.4rem);
    border-radius: 24px 24px 0 0;
  }
  .site-foot .foot-rule { display: none; }
  .site-foot h4 { color: var(--on-navy-muted); }
  /* one link per line again: the tap-target rule above made them inline */
  .site-foot .foot-col { display: flex; flex-direction: column; }
  .site-foot .foot-col a, .site-foot .foot-col > a {
    display: flex; align-items: center; min-height: 34px;
    color: var(--on-navy); text-decoration: none; }
  .site-foot .foot-col a:hover { color: #fff; text-decoration: underline; }
  .site-foot small { color: var(--on-navy-muted); }
  .site-foot-row--legal { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap;
    margin-top: 1.6rem; padding-top: 1.2rem; border-top: 1px solid rgba(255,255,255,.12);
    color: var(--on-navy-muted); }
  .site-foot-row--legal .label { color: var(--on-navy-muted); }
  .foot-marquee { opacity: .16; }
