:root{
    /* DDX Consulting — brand guide, July 2026 */
    --paper:#060A16; --card:#0D1220; --raised:#141B2B;
    --ink:#FFFFFF; --ink-hover:#FFFFFF;
    --dim:#CACDD0; --faint:#8D97A6;
    --line:#232C3D; --line-soft:#1A2029; --line-strong:#33405A;
    --steel:#6B8BA4; --steel-hi:#9DB4C7; --steel-dim:#46596E;
    --steel:#6B8BA4;
    /* legacy aliases kept so inline styles in the markup keep resolving */
    --cy:#6B8BA4; --green:#6B8BA4; --mint:#9DB4C7; --red:#C97A6E; /* unused: no rule references these */
    --panel-dim:#9AA1AB; --panel-faint:#6B727C; --panel-eyebrow:#6B8BA4;
  }
  *{box-sizing:border-box}
  html{scroll-behavior:smooth;background:var(--paper)}
  body{margin:0;background:var(--paper);color:var(--ink);font:15px/1.65 "Switzer","Neue Montreal",system-ui,"Segoe UI",sans-serif;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
  a{color:var(--steel);text-decoration:none;transition:color .15s ease}
  a:hover{color:var(--steel-hi)}
  h1,h2{font-family:inherit;font-weight:500;letter-spacing:-.025em;text-wrap:pretty;margin:0;color:var(--ink)}
  .wrap{max-width:1160px;margin:0 auto;padding:0 32px}
  .mono{font-family:"IBM Plex Mono",ui-monospace,monospace}
  .eyebrow{font-size:11px;font-weight:500;letter-spacing:.18em;color:var(--steel);text-transform:uppercase}
  .btn{display:inline-flex;align-items:center;justify-content:center;height:46px;padding:0 26px;background:var(--steel);color:#060A16;border-radius:2px;font-size:13px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;border:none;cursor:pointer;transition:background .15s ease}
  .btn:hover{background:var(--steel-hi);color:#060A16}
  .btn-ghost{display:inline-flex;align-items:center;justify-content:center;height:46px;padding:0 24px;background:transparent;color:var(--ink);border:1px solid var(--line-strong);border-radius:2px;font-size:13px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;cursor:pointer;transition:border-color .15s ease,color .15s ease}
  .btn-ghost:hover{border-color:var(--steel);color:var(--steel)}
  .ulink{font-size:13px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;color:var(--steel);border-bottom:1px solid rgba(107,139,164,.4);padding-bottom:3px}
  .ulink:hover{color:var(--steel-hi);border-color:var(--steel-hi)}

  /* brand mark */
  .ddx-mark{display:block;flex-shrink:0}
  .brand{display:flex;align-items:center;gap:12px;text-decoration:none}
  .brand .ddx-word{display:block;width:118px;height:auto}
  @media (max-width:640px){.brand .ddx-word{width:101px}}
  .brand .rule{width:1px;height:34px;background:linear-gradient(180deg,#1B2431,#6B8BA4,#1B2431);flex-shrink:0}

  /* nav */
  /* The bar was fully transparent until the page scrolled. That was fine over
     a dark photograph and is not over a field of marks — the links sat
     straight on the pattern with nothing dividing them from it. It carries
     its own band and rule from the first frame now, and still deepens on
     scroll. The docked colour was also still the old paper. */
  nav{position:fixed;top:0;left:0;right:0;z-index:20;
    background:linear-gradient(180deg,rgba(6,10,22,.94),rgba(6,10,22,.66));
    -webkit-backdrop-filter:blur(7px);backdrop-filter:blur(7px);
    border-bottom:1px solid rgba(107,139,164,.22);
    transition:background .25s ease,border-color .25s ease,backdrop-filter .25s ease}
  nav.docked{background:rgba(6,10,22,.95);backdrop-filter:blur(12px);
    border-bottom-color:var(--line-strong)}
  .nav-in{height:70px;display:flex;align-items:center;justify-content:space-between}
  .nav-links{display:flex;align-items:center;gap:30px;font-size:11px;font-weight:500;letter-spacing:.14em;text-transform:uppercase}
  .nav-links a{color:var(--dim)}
  .nav-links a:hover{color:var(--ink)}
  .nav-cta{display:inline-flex;align-items:center;height:36px;padding:0 20px;background:var(--steel);color:#060A16 !important;border-radius:2px;letter-spacing:.12em}
  .nav-cta:hover{background:var(--steel-hi);color:#060A16 !important}
  .nav-signin{display:inline-flex;align-items:center;height:36px;padding:0 18px;border:1px solid var(--line-strong);border-radius:2px;color:var(--dim) !important;letter-spacing:.12em}
  .nav-signin:hover{border-color:var(--steel);color:var(--steel) !important}
  @media (max-width:1000px){.nav-links a.hideS{display:none}}
  /* under 700 the bar cannot hold the lockup and two buttons without the
     sign-in wrapping onto the brand — sign-in moves to the footer links */
  @media (max-width:700px){
    .nav-links{gap:14px}
    .nav-signin{display:none}
    .brand .ddx-word{width:97px}
    .nav-cta{height:34px;padding:0 16px;font-size:10.5px}
  }

  /* Under 1000 the section links leave the bar. They have to go somewhere —
     a phone visitor could otherwise only reach Contact. */
  .nav-burger{display:none;align-items:center;justify-content:center;width:38px;height:38px;
    background:transparent;border:1px solid var(--line-strong);border-radius:2px;cursor:pointer;padding:0}
  .nav-burger:hover{border-color:var(--steel)}
  .nav-burger i{display:block;width:16px;height:1px;background:var(--ink);position:relative}
  .nav-burger i::before,.nav-burger i::after{content:"";position:absolute;left:0;width:16px;height:1px;background:var(--ink)}
  .nav-burger i::before{top:-5px}
  .nav-burger i::after{top:5px}
  @media (max-width:1000px){.nav-burger{display:inline-flex}}

  .sheet{position:fixed;inset:0;z-index:30;background:var(--paper);
    display:flex;flex-direction:column;padding:0 20px 30px;
    opacity:0;visibility:hidden;transform:translateY(-6px);
    transition:opacity .22s ease,transform .22s ease,visibility .22s ease}
  .sheet[data-open]{opacity:1;visibility:visible;transform:none}
  .sheet-top{height:70px;flex-shrink:0;display:flex;align-items:center;justify-content:space-between}
  /* the sizing rule for the wordmark is scoped to .brand, which this is not */
  .sheet-top .ddx-word{display:block;width:101px;height:auto}
  .sheet-close{width:38px;height:38px;background:transparent;border:1px solid var(--line-strong);
    border-radius:2px;color:var(--ink);font:400 20px/1 "Switzer",system-ui,sans-serif;cursor:pointer;padding:0}
  .sheet-close:hover{border-color:var(--steel);color:var(--steel)}
  .sheet-links{display:flex;flex-direction:column;margin-top:12px}
  .sheet-links a{display:block;padding:15px 0;font-size:26px;font-weight:500;letter-spacing:-.022em;
    color:var(--ink);border-bottom:1px solid var(--line-soft)}
  .sheet-links a:hover{color:var(--steel)}
  .sheet-foot{margin-top:auto;padding-top:28px;display:flex;flex-direction:column;gap:12px}
  .sheet-foot .btn,.sheet-foot .btn-ghost{width:100%}
  body.menu-open{overflow:hidden}
  @media (max-width:640px){.sheet-top{height:62px}.sheet-links a{font-size:23px;padding:13px 0}}
  @media (max-width:640px){
    .wrap{padding:0 20px}
    .nav-in{height:62px}
    .sec{padding-top:52px;padding-bottom:56px}
    /* the captions eat two thirds of a phone line and leave room for two
       logos. Drop them — a row of recognisable app marks says "it plugs
       into your stack" without being told */
    .works-in{padding:15px 0}
    .works .cap{display:none}
    .river{flex:1 1 100%;min-width:0}
    .river img{width:40px;height:40px;padding:8px}
    .sec h2{margin-bottom:28px}
    .foot{padding:28px 20px}
    .blueprint{padding:20px}
    .bp-out .chips{justify-content:flex-start}
  }


  /* ── the walk ────────────────────────────────────────────────────────
     One corridor, three places along it. The hero sits in it; sections 01
     and 02 each get a full-screen title card cut into it. Everything after
     that is an ordinary document — a buyer looking for the contact form
     should not have to walk there. */
  .plate{position:absolute;inset:0;z-index:0;overflow:hidden}
  .plate img{width:100%;height:100%;object-fit:cover;display:block;will-change:transform}
  /* Barely there. The old scrim ran to .93 across the left of the frame and
     you could see it — the picture looked filtered rather than lit. The
     atrium plate already carries its own dark left third, so all that is
     left to do is stop the type sitting directly on the gold edge. */
  .veil{position:absolute;inset:0;z-index:1;pointer-events:none;background:
    linear-gradient(90deg,rgba(11,15,20,.42) 0%,rgba(11,15,20,.14) 34%,transparent 62%)}

  .hero-zone{position:relative;overflow:hidden;min-height:100svh;display:flex;align-items:center;
    border-bottom:1px solid var(--line)}
  .hero-zone .hero{position:relative;z-index:2}

  .chapter{position:relative;height:185vh}
  .chapter-stage{position:sticky;top:0;height:100svh;overflow:hidden;display:grid;align-content:center}
  .chapter-copy{position:relative;z-index:2;width:100%;max-width:1160px;margin:0 auto;padding:0 32px;
    will-change:opacity,transform}
  .chapter-copy .k{font-size:10.5px;font-weight:500;letter-spacing:.24em;text-transform:uppercase;color:var(--steel)}
  .chapter-copy h2{font-size:clamp(30px,5.6vw,58px);line-height:1.04;letter-spacing:-.03em;
    font-weight:500;margin:22px 0 0;max-width:15ch;text-wrap:balance}
  .chapter-copy p{margin:22px 0 0;max-width:500px;font-size:16px;line-height:1.65;color:var(--dim)}
  .chapter-cue{position:absolute;z-index:2;bottom:32px;left:50%;transform:translateX(-50%);
    font-size:9.5px;font-weight:500;letter-spacing:.24em;text-transform:uppercase;color:var(--faint)}

  /* the walk is a desktop pleasure; on a phone it is a scroll tax */
  @media (max-width:820px){
    /* Same lesson as the hero: a portrait crop of this corridor is not a
       readable picture, it is a white wedge on black, and type over it needs
       a scrim that erases whatever was left. So the beat splits — the
       corridor gets a wide, short frame where its perspective survives, and
       the words sit under it on solid ground. */
    .chapter{height:auto}
    .chapter-stage{position:static;height:auto;padding:0;
      display:flex;flex-direction:column;overflow:hidden}
    .chapter .plate{position:relative;inset:auto;order:1;height:210px;
      border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
    .chapter .plate img{object-position:56% center}
    .chapter .veil{display:none}
    .chapter-copy{opacity:1 !important;transform:none !important;
      order:2;padding:26px 20px 34px}
    /* The 90deg veil was cut for a landscape frame: it darkens left-to-right
       so type can sit in the left third. A phone stacks the type instead, so
       that ramp just buries the picture. Run it top-to-bottom, and slide the
       crop toward the lit wall so the corridor still reads at this width. */
    .veil{background:linear-gradient(180deg,
      rgba(11,15,20,.28) 0%,rgba(11,15,20,.55) 30%,rgba(11,15,20,.88) 70%,rgba(11,15,20,.96) 100%)}
    /* The hero carries type all the way down, so it needs the steeper ramp:
       the light stays in the top band and everything under it goes to ground.
       60% centres the portrait crop on the ceiling slot and the lit edge —
       further right and the bright wall lands behind the headline. */
    .hero-zone .veil{background:
    /* The copy column. The reference has no text over its pattern; this hero
       does, so the field stays at full strength and the readability is bought
       here instead. White type over the lightest fill composites to 139 at
       .90, and needs about 110 to hold 4.5 — .42 clears it with margin, and
       it falls away to nothing by two thirds across so the pattern is
       untouched where nothing is written. */
    linear-gradient(90deg, rgba(6,10,22,.86) 0%, rgba(6,10,22,.72) 26%,
                           rgba(6,10,22,.42) 44%, rgba(6,10,22,.10) 62%,
                           transparent 76%),
    linear-gradient(180deg, rgba(6,10,22,.55) 0%, rgba(6,10,22,.16) 22%,
                            rgba(6,10,22,.16) 66%, rgba(6,10,22,.62) 100%)}
    /* scoped to chapters: this used to hit the hero plate as well and
       !important beat the inline transform the parallax sets */
    .chapter .plate img{transform:none !important;object-position:60% center}
    .chapter-cue{display:none}
  }
  @media (prefers-reduced-motion:reduce){
    .chapter{height:auto}
    .chapter-stage{position:static;height:auto;padding:72px 0}
    .chapter-copy{opacity:1 !important;transform:none !important}
    .chapter .plate img{transform:none !important}
    .chapter-cue{display:none}
  }

  /* hero */
  /* padding trimmed when the connects-to strip moved into the hero: at 150/96
     the block ran past a 900px-tall laptop and crowded the pillars into the cue */
  .hero{display:block;width:100%;padding-top:110px;padding-bottom:100px}
  .hero h1{font-size:clamp(38px,7.6vw,76px);line-height:1.02;margin-top:28px;letter-spacing:-.032em;max-width:14ch}

  /* ── the set-wide headline ────────────────────────────────────────────
     Light Jost in wide-tracked caps, one statement per line, the last in
     tan. It is the lockup's own typeface at display size, which is why it
     reads as the brand rather than as a font choice. Tracking is a luxury
     of width: it opens up on a desktop and closes again on a phone, where
     letters that far apart stop forming words. */
  .hero h1.setwide{font-family:"Jost",system-ui,sans-serif;font-weight:300;
    text-transform:uppercase;letter-spacing:.055em;line-height:1.13;
    font-size:clamp(29px,5.1vw,62px);max-width:none;margin-top:26px}
  .hero h1.setwide span{display:block}
  .hero h1.setwide .accent{color:var(--steel)}

  /* the offer column, opposite the words */
  /* The column lands on the lit wall, which is the brightest part of the
     plate — the dim body copy washes out there. A scrim local to this
     column keeps it readable without putting the filter back over the
     whole picture. */
  .hero-facets{display:grid;gap:26px;align-content:center;max-width:300px;
    position:relative;padding:22px 20px 24px;margin:0 -20px;
    background:linear-gradient(90deg,rgba(11,15,20,0),rgba(11,15,20,.62) 18%,rgba(11,15,20,.74));
    -webkit-backdrop-filter:blur(1.5px);backdrop-filter:blur(1.5px)}
  .facet{border-top:1px solid var(--line-strong);padding-top:14px;
    display:grid;grid-template-columns:26px 1fr;column-gap:14px;align-items:start}
  .fmark{width:20px;height:20px;grid-row:1/3;margin-top:1px;color:var(--steel)}
  .fmark.solid{color:var(--steel)}
  .facet b{font-size:11.5px;font-weight:600;letter-spacing:.12em;
    text-transform:uppercase;color:var(--ink)}
  .facet span{font-size:13.5px;line-height:1.5;color:var(--dim);margin-top:7px;grid-column:2}
  @media (min-width:1001px){
    .hero{display:grid;grid-template-columns:minmax(0,1fr) 290px;gap:70px;align-items:center}
  }
  @media (max-width:1000px){.hero-facets{display:none}}
  .hero-cue{position:absolute;z-index:3;bottom:30px;left:50%;transform:translateX(-50%);
    font-size:9.5px;font-weight:500;letter-spacing:.26em;text-transform:uppercase;color:var(--faint)}
  .hero-cue::after{content:"";display:block;width:1px;height:26px;margin:10px auto 0;
    background:linear-gradient(180deg,var(--steel),transparent)}
  .hero .sub{font-size:17px;line-height:1.65;color:var(--dim);margin:26px 0 0;max-width:520px}
  .hero-ctas{display:flex;align-items:center;gap:24px;margin-top:38px;flex-wrap:wrap}
  .hero-note{font-size:10.5px;font-weight:500;letter-spacing:.16em;color:var(--faint);margin-top:20px;text-transform:uppercase}
  /* DATA · PROCESS · AI */
  .pillars{display:flex;gap:18px;flex-wrap:wrap;margin-top:34px;padding-top:22px;border-top:1px solid var(--line)}
  .pillars span{font-size:10.5px;font-weight:500;letter-spacing:.24em;color:var(--faint);text-transform:uppercase}

  /* Phone hero. This has to sit AFTER the block above: the earlier
     max-width:640px rules are same-specificity and lose the cascade to it.
     Bottom-anchored, so the copy lands in the dark half of the vertical veil
     and the top third of the frame stays a photograph. Centred and at desktop
     leading it filled the viewport edge to edge, with no room for the cue. */
  /* the cascade is a phone device only — desktop already has a real nav */
  .hero-index{display:none}
  /* the phone eyebrow is an index rule with a short label; everywhere else
     the full sentence runs on its own. Only ever one of the two is shown. */
  .hero .eyebrow .eb-idx,.hero .eyebrow .eb-short{display:none}
  /* likewise the sub: one short sentence on a phone, the full paragraph
     everywhere else. Never both. */
  .hero .sub .sub-lead{display:none}

  /* ── Phone hero ───────────────────────────────────────────────────────
     Rebuilt against how mobile heroes actually work: the picture owns the
     top of the frame and stays legible, the words sit in a solid slab at
     the bottom, and there is ONE button near the thumb.

     The old one carried eight things — eyebrow, three-line headline, a
     five-line paragraph, two calls to action, a note, four pillars, a
     twenty-two mark logo strip and a scroll cue. Type needed about 70% of
     the frame, which left the corridor as an unreadable dark texture. The
     fix is not smaller type, it is fewer elements: the strip, pillars,
     note and eyebrow all have somewhere better to be further down. */
  @media (max-width:640px){
    /* Type first, on solid ground. The corridor is a dark, low-contrast
       photograph: used as a backdrop it forces a scrim heavy enough to
       erase itself, which is why the old phone hero read as a black
       rectangle. It goes to the foot of the cascade instead, framed, where
       it can be lit. */
    /* The reference stacks its cards on a coloured panel — that ground is
       what makes them read as a deck rather than as misaligned bars. This
       palette has no second colour to spare, but it has the corridor: the
       photograph becomes the panel, and solid dark cards step across it. */
    .hero-zone{align-items:flex-start;min-height:0;background:var(--paper);border-bottom:0}
    .hero-zone .plate,.hero-zone .veil{display:none}
    .hero{padding-top:80px;padding-bottom:30px}
    .hero .hero-note,.hero .pillars,.hero .works,.hero-cue{display:none}
    .hero .sub .sub-rest,.hero .eyebrow .eb-rest{display:none}
    .hero .sub .sub-lead{display:inline}

    /* index rule above the headline: 01 ————— PROCUREMENT & SUPPLY CHAIN */
    .hero .eyebrow{display:flex;align-items:center;gap:10px;font-size:12px;letter-spacing:.1em}
    .hero .eyebrow .eb-idx,.hero .eyebrow .eb-short{display:block}
    .hero .eyebrow .eb-idx{font-family:"IBM Plex Mono",monospace;color:var(--steel)}
    .hero .eyebrow .eb-short{position:relative;padding-left:44px;color:var(--faint)}
    .hero .eyebrow .eb-short::before{content:"";position:absolute;left:0;top:50%;
      width:34px;height:1px;background:var(--line-strong)}

    .hero h1{font-size:33px;line-height:1.08;letter-spacing:-.028em;margin-top:16px;max-width:13ch}
    /* tracking closes right down here — at .055em these caps stop reading as
       words on a 390px column */
    .hero h1.setwide{font-size:29px;letter-spacing:.012em;line-height:1.2;margin-top:14px}
    .hero .sub{font-size:15.5px;line-height:1.55;margin-top:14px;max-width:none}
    .hero-ctas{display:grid;grid-template-columns:1fr;gap:0;margin-top:22px}
    .hero-ctas .btn{width:100%;height:54px;justify-content:center;font-size:14px}
    .hero-ctas .ulink{justify-self:center;margin-top:14px;min-height:44px;
      display:inline-flex;align-items:center;border-bottom:0;font-size:13px;color:var(--dim)}

    /* ── index + one picture ─────────────────────────────────────────────
       The cascading-card pattern was tried here and abandoned: it works in
       the reference because each card is a different hue, and this palette
       is one near-black plus a tan. Offset dark-on-dark cards do not read as
       a stack, they read as a broken grid. What survives is the useful part
       — a visible table of contents instead of a hamburger and nothing —
       set flat, with the corridor as the single framed picture on the page. */
    /* Words on solid ground, then one picture that runs off the right edge.
       Nothing overlaps: the corridor is finally lit because it never has to
       sit under type. The cascading-deck pattern was tried and dropped —
       it needs a second brand colour to read, and it carries a hospitality
       register this business does not want. */
    .hero-index{display:block;margin:30px 0 0}
    .hix{display:none}
    .hix-plate{display:block;height:250px;position:relative;overflow:hidden;
      margin-right:-20px;border-top-left-radius:4px;border-bottom-left-radius:4px;
      border:1px solid var(--line);border-right:0}
    .hix-plate img{width:100%;height:100%;object-fit:cover;object-position:52% center;display:block}
    .hix-plate .cap{position:absolute;left:18px;bottom:16px;font-size:12px;letter-spacing:.08em;
      color:var(--ink);text-transform:uppercase;text-shadow:0 1px 14px rgba(11,15,20,.95)}

    /* One photographic moment per page. The chapter cards carry the headings
       for the sections beneath them, so they stay — but as headings, not as
       three more heroes in a row. The corridor appears once, in the hero
       cascade, and that is the whole of it. */
    .chapter .plate{display:none}
    .chapter-stage{border-top:1px solid var(--line)}
    .chapter-copy{padding:34px 20px 4px}
    .chapter+section,.chapter+.sec{padding-top:18px}
  }
  .pillars span::before{content:"";display:inline-block;width:4px;height:4px;background:var(--steel);margin-right:10px;vertical-align:middle;transform:rotate(45deg)}

  /* ruled card */
  .rcard{background:var(--card);border:1px solid var(--line);border-radius:2px}
  .rcard-head{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:15px 18px;border-bottom:1px solid var(--line);font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:10.5px;letter-spacing:.1em;color:var(--faint);text-transform:uppercase}
  .rrow{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:13px 18px;border-bottom:1px solid var(--line-soft);font-size:13px;color:var(--dim)}
  .rrow:last-child{border-bottom:0}
  .rrow .st{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:10px;letter-spacing:.08em;white-space:nowrap}
  .stamp{display:inline-block;border:1px solid var(--steel);color:var(--steel);border-radius:2px;padding:7px 12px;font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:10px;letter-spacing:.12em;transform:rotate(-3deg);text-transform:uppercase}

  /* works-with river */
  .works{border-top:1px solid var(--line);background:var(--card)}
  .works-in{display:flex;align-items:center;gap:22px;padding:18px 32px}
  .works .cap{font-size:10px;font-weight:500;letter-spacing:.16em;color:var(--faint);white-space:nowrap;text-transform:uppercase}
  .river{flex:1;min-width:0;overflow:hidden;-webkit-mask-image:linear-gradient(90deg,transparent,black 8%,black 92%,transparent);mask-image:linear-gradient(90deg,transparent,black 8%,black 92%,transparent)}
  .river-track{display:flex;gap:10px;width:max-content;will-change:transform}
  .river img{width:42px;height:42px;border-radius:6px;background:#FFFFFF;border:1px solid var(--line);padding:9px;flex-shrink:0}
  /* Inside the hero the strip is not a band across the page: no card, no rule,
     no page gutter, and held to the measure of the copy so it does not run out
     over the corridor. The river's own edge mask does the truncating. */
  /* Wider than the copy on purpose: the strip is a list, not a sentence, so it
     runs the full measure of the page rather than the measure of the paragraph.
     The river's own edge mask does the truncating. */
  .hero .works{background:transparent;border-top:0;margin-top:30px}
  .hero .works-in{padding:0;gap:16px}
  .hero .works .cap{font-size:9.5px}
  .hero .river img{width:38px;height:38px;padding:8px}
  @keyframes river{from{transform:translateX(0)}to{transform:translateX(-50%)}}
  @media (prefers-reduced-motion:reduce){.river-track{animation:none !important}}

  /* sections */
  section{border-top:1px solid var(--line)}
  section[id],div[id]{scroll-margin-top:84px}
  .sec{padding-top:72px;padding-bottom:80px}
  .sec h2{font-size:clamp(26px,3.4vw,38px);line-height:1.14;margin:18px 0 40px;max-width:660px;letter-spacing:-.028em}
  .sec h2.tight{margin-bottom:0}

  /* spec table */
  .spec .cols{display:grid;grid-template-columns:260px 1fr 200px;padding:13px 20px;border-bottom:1px solid var(--line);font-size:10px;font-weight:500;letter-spacing:.14em;color:var(--faint);text-transform:uppercase}
  .spec .row{display:grid;grid-template-columns:260px 1fr 200px;padding:22px 20px;border-bottom:1px solid var(--line-soft);font-size:14px;align-items:start}
  .spec .row:last-child{border-bottom:0}
  .spec .row b{font-weight:500;color:var(--ink);font-size:15px}
  .spec .row .what{color:var(--dim);line-height:1.6;padding-right:32px}
  .spec .row .tag{font-size:10px;font-weight:500;color:var(--steel);letter-spacing:.14em;text-transform:uppercase}
  @media (max-width:820px){.spec .cols{display:none}.spec .row{grid-template-columns:1fr;gap:10px}}

  /* how — three ruled columns */
  .steps3{display:grid;grid-template-columns:1fr 1fr 1fr;border-top:1px solid var(--line)}
  .steps3>div{padding:28px 32px 0 0}
  .steps3>div+div{padding-left:32px;border-left:1px solid var(--line)}
  .steps3 .stepicon{display:block;margin-bottom:16px;opacity:.9}
  .steps3 .k{font-size:10px;font-weight:500;color:var(--steel);letter-spacing:.18em;text-transform:uppercase}
  .steps3 h3{font-size:18px;font-weight:500;margin:14px 0 10px;color:var(--ink);letter-spacing:-.015em}
  .steps3 p{font-size:14px;line-height:1.65;color:var(--dim);margin:0}
  @media (max-width:820px){.steps3{grid-template-columns:1fr}.steps3>div+div{padding-left:0;border-left:0;border-top:1px solid var(--line);margin-top:26px;padding-top:26px}}

  /* blueprint */
  .blueprint{border:1px solid var(--line);border-radius:2px;background-color:var(--card);background-image:linear-gradient(rgba(107,139,164,.045) 1px,transparent 1px),linear-gradient(90deg,rgba(107,139,164,.045) 1px,transparent 1px);background-size:24px 24px;padding:32px;overflow-x:auto}
  .bp-head{display:flex;justify-content:space-between;align-items:baseline;gap:16px;margin-bottom:28px;font-family:"IBM Plex Mono",ui-monospace,monospace}
  .bp-head .fig{font-size:11px;letter-spacing:.1em;color:var(--steel);text-transform:uppercase}
  .bp-head .note{font-size:10.5px;color:var(--faint)}
  .bp-svg{overflow-x:auto}
  .bp-svg svg{display:block;min-width:940px;width:100%;height:auto}
  .bp-flow{display:none;align-items:stretch}
  .node{flex:1;border:1px solid var(--line-strong);border-radius:2px;background:var(--raised);padding:14px}
  .node.decision{border-style:dashed}
  .node.human{flex:1.1;border:1px solid var(--steel);background:rgba(107,139,164,.06)}
  .node.done{border:1px solid var(--steel);background:var(--raised)}
  .node.done .k{color:var(--steel)}
  .node .k{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:9.5px;letter-spacing:.12em;color:var(--faint);text-transform:uppercase}
  .node.human .k{color:var(--steel)}
  .node b{display:block;font-size:13px;font-weight:500;margin-top:7px;color:var(--ink)}
  .node .d{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:10.5px;color:var(--dim);margin-top:5px}
  .edge{width:28px;display:flex;align-items:center;flex-shrink:0}
  .edge i{display:block;height:1px;width:100%;background:var(--line-strong)}
  .bp-loops{margin-top:16px;display:grid;gap:8px}
  .loop{display:flex;gap:10px;align-items:baseline;border:1px dashed var(--line-strong);border-radius:2px;background:var(--raised);padding:10px 13px;font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:10.5px;color:var(--dim);flex-wrap:wrap}
  .loop .lk{color:var(--faint);letter-spacing:.1em;white-space:nowrap;text-transform:uppercase}
  .loop b{color:var(--ink);font-weight:400}
  .loop .ret{color:var(--steel);white-space:nowrap}
  .bp-out{display:flex;justify-content:space-between;align-items:center;gap:14px;margin-top:20px;flex-wrap:wrap}
  .bp-out .lead{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:10.5px;letter-spacing:.1em;color:var(--steel);white-space:nowrap;text-transform:uppercase}
  .bp-out .chips{display:flex;gap:12px;font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:10.5px;color:var(--ink);flex-wrap:wrap}
  .bp-out .chips span{border:1px solid var(--line);background:var(--raised);border-radius:2px;padding:9px 12px}
  .fig-tabs{display:flex;gap:10px;margin-bottom:26px;font-size:10.5px;font-weight:500;letter-spacing:.1em;flex-wrap:wrap}
  .fig-tab{background:transparent;border:1px solid var(--line-strong);border-radius:2px;cursor:pointer;padding:11px 16px;font:inherit;color:var(--dim);text-transform:uppercase;transition:border-color .15s ease,color .15s ease,background .15s ease}
  .fig-tab:hover{border-color:var(--steel);color:var(--steel)}
  .fig-tab.on{background:var(--steel);border-color:var(--steel);color:#060A16}
  .fig-board{display:none}
  .fig-board.on{display:block}
  @media (min-width:821px){.bp-out{display:none}}
  @media (max-width:820px){
    .fig-tabs{gap:8px}
    .fig-tab{flex:1 1 100%;text-align:left}
    .blueprint{padding:18px}
    .bp-svg{display:none}
    .bp-flow{display:flex;flex-direction:column;min-width:0}
    .node{flex:none}
    .node.human{flex:none}
    .edge{width:auto;height:22px;padding-left:26px;align-items:stretch}
    .edge i{width:1px;height:100%}
    .bp-head{flex-direction:column;align-items:flex-start;gap:4px;margin-bottom:20px}
    .bp-out{margin-top:16px;justify-content:flex-start}
    .bp-out .chips{flex-direction:column;width:100%;gap:8px}
  }

  /* case record — raised band */
  .case-band{background:var(--card)}
  .case-band .eyebrow{color:var(--steel)}
  .case-grid{display:grid;grid-template-columns:1fr 360px;gap:64px;align-items:start;margin-top:18px}
  @media (max-width:860px){.case-grid{grid-template-columns:1fr}}
  .case-grid h2{color:var(--ink);margin:0}
  .case-grid .body{font-size:15px;line-height:1.7;color:var(--dim);margin:22px 0 0;max-width:560px}
  .case-grid .src{font-size:10px;font-weight:500;color:var(--faint);margin-top:22px;letter-spacing:.14em;text-transform:uppercase}
  .dark-card{border:1px solid var(--line-strong);border-radius:2px;background:var(--raised)}
  .dark-card .r{display:flex;justify-content:space-between;padding:16px 18px;border-bottom:1px solid var(--line);font-size:14px}
  .dark-card .r:last-child{border-bottom:0}
  .dark-card .r span:first-child{color:var(--dim)}
  .dark-card .r span:last-child{font-family:"IBM Plex Mono",ui-monospace,monospace;font-weight:400;color:var(--ink)}

  /* tally band */
  .lockup{display:flex;align-items:center;gap:13px;margin-bottom:22px}
  .lockup .tile{width:44px;height:44px;background:var(--raised);border:1px solid var(--line-strong);border-radius:8px;display:flex;align-items:center;justify-content:center;flex-shrink:0}
  .lockup .wm{display:block;font-weight:500;font-size:22px;letter-spacing:-.02em;line-height:1;color:var(--ink)}
  .lockup .by{display:block;font-size:9px;letter-spacing:.24em;color:var(--steel);margin-top:6px;text-transform:uppercase}
  .tally-grid{display:grid;grid-template-columns:1fr 420px;gap:64px;align-items:start;margin-top:18px}
  @media (max-width:960px){.tally-grid{grid-template-columns:1fr}}
  .bullets{margin-top:26px;display:grid;gap:12px;font-size:14px;color:var(--dim)}
  .bullets>div{display:flex;gap:13px}
  .bullets .sq{font-size:9px;color:var(--steel);padding-top:6px;line-height:1}
  .sample .r{display:flex;justify-content:space-between;padding:15px 18px;border-bottom:1px solid var(--line-soft);font-size:14px}
  .sample .r span:first-child{color:var(--dim)}
  .sample .r span:last-child{font-family:"IBM Plex Mono",ui-monospace,monospace;color:var(--ink)}
  .sample .foot{padding:13px 18px;border-top:1px solid var(--line);font-size:10px;font-weight:500;color:var(--faint);letter-spacing:.14em;text-transform:uppercase}

  /* packs */
  .packs{display:grid;grid-template-columns:1fr 1fr 1fr;gap:16px}
  @media (max-width:900px){.packs{grid-template-columns:1fr}}
  .pack{background:var(--card);border:1px solid var(--line);border-radius:2px;padding:24px;display:flex;flex-direction:column;transition:border-color .15s ease}
  .pack:hover{border-color:var(--line-strong)}
  .pack-head{display:flex;justify-content:space-between;align-items:baseline;gap:10px}
  .pk-trigger{font-size:10px;font-weight:500;letter-spacing:.14em;color:var(--steel);text-transform:uppercase}
  .pk-price{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:12px;color:var(--dim)}
  .pk-price b{font-size:20px;color:var(--ink);font-weight:500}
  .pack h3{font-size:18px;font-weight:500;margin:14px 0 10px;color:var(--ink);letter-spacing:-.015em}
  .pack p{font-size:14px;line-height:1.65;color:var(--dim);margin:0;flex:1}
  .pk-foot{margin-top:18px;padding-top:14px;border-top:1px solid var(--line-soft);font-size:9.5px;letter-spacing:.14em;color:var(--faint);text-transform:uppercase}
  .suite{margin-top:16px;background:var(--card);border:1px solid var(--line);border-radius:2px;padding:22px 24px;display:flex;justify-content:space-between;align-items:center;gap:20px;flex-wrap:wrap}
  .suite h3{font-size:17px;font-weight:500;color:var(--ink);letter-spacing:-.015em}
  .trig-cat{margin-top:30px}
  .trig-grid{display:grid;grid-template-columns:1fr 1fr 1fr;border:1px solid var(--line);border-top:0;border-radius:0 0 2px 2px;background:var(--card)}
  @media (max-width:820px){.trig-grid{grid-template-columns:1fr}}
  .trig-grid>div{padding:15px 18px;border-bottom:1px solid var(--line-soft);border-right:1px solid var(--line-soft)}
  .trig-grid>div b{display:block;font-size:10px;letter-spacing:.14em;color:var(--steel);font-weight:500;text-transform:uppercase}
  .trig-grid>div span{display:block;margin-top:6px;font-size:13px;color:var(--dim)}

  /* faq */
  .faq-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 64px;margin-top:30px;border-top:1px solid var(--line)}
  .faq-grid>div{padding:24px 0;border-bottom:1px solid var(--line)}
  .faq-grid h3{font-size:15px;font-weight:500;margin:0 0 10px;color:var(--ink)}
  .faq-grid p{font-size:14px;line-height:1.65;color:var(--dim);margin:0}
  @media (max-width:820px){.faq-grid{grid-template-columns:1fr}}

  /* contact */
  .contact-band{background:var(--card)}
  .contact-grid{display:grid;grid-template-columns:1fr 460px;gap:64px;align-items:start}
  @media (max-width:960px){.contact-grid{grid-template-columns:1fr}}
  .form-card{border:1px solid var(--line-strong);border-radius:2px;background:var(--raised)}
  .form-body{padding:20px;display:grid;gap:15px}
  .lbl{display:block;font-size:9.5px;font-weight:500;letter-spacing:.14em;color:var(--faint);margin-bottom:8px;text-transform:uppercase}
  .fld{width:100%;height:42px;border:1px solid var(--line-strong);border-radius:2px;padding:0 13px;font:400 14px/1.5 "Switzer",system-ui,sans-serif;color:var(--ink);background:#0D1217}
  textarea.fld{height:auto;min-height:78px;padding:11px 13px;resize:vertical}
  .fld::placeholder{color:#4E545D}
  .fld:focus{outline:none;border-color:var(--steel)}
  .frow{display:grid;gap:15px;grid-template-columns:1fr 1fr}
  @media (max-width:640px){.frow{grid-template-columns:1fr}}
  .fstep{display:none}
  .fstep.on{display:grid;gap:15px}
  .chiprow{display:flex;gap:8px;flex-wrap:wrap}
  .pick{border:1px solid var(--line-strong);background:transparent;border-radius:2px;padding:10px 16px;font:500 13px "Switzer",system-ui,sans-serif;color:var(--dim);cursor:pointer;transition:all .15s ease}
  .pick:hover{border-color:var(--steel);color:var(--steel)}
  .pick.on{background:var(--steel);border-color:var(--steel);color:#060A16}
  .wizfoot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:4px;flex-wrap:wrap}
  .wizfoot .note{font-size:9.5px;font-weight:500;color:var(--faint);letter-spacing:.14em;text-transform:uppercase}
  .btn-sm{height:40px;padding:0 20px;font-size:11.5px}

  /* ── what we do ───────────────────────────────────────────────────────
     Rows, not a table. A table asks you to read across three columns; a row
     with the title set large asks you to read one thing. The tile field
     behind gives the dark ground something to do without motion. */
  .ways{position:relative;overflow:hidden}
  /* one warm bloom off the top right, the way the atrium is lit */
  .glow{position:absolute;top:-140px;right:-160px;width:520px;height:520px;
    border-radius:50%;pointer-events:none;z-index:0;
    background:radial-gradient(circle,rgba(107,139,164,.10),transparent 68%);
    filter:blur(30px)}
  .ways-in{position:relative;z-index:1}
  .ways-head{display:grid;grid-template-columns:1fr auto;gap:40px;align-items:end;
    padding-bottom:34px;border-bottom:1px solid var(--line)}
  .ways-head h2{font-size:clamp(34px,5.6vw,62px);line-height:1.04;letter-spacing:-.032em;
    font-weight:500;margin:14px 0 0}
  .ways-lede{font-size:15px;color:var(--dim);max-width:26ch;text-align:right;margin:0}

  /* ── row hover ────────────────────────────────────────────────────────
     The brand's one piece of motion is light travelling along an edge —
     it is what the atrium plate is actually a photograph of. So a row does
     not light up as a block; a line runs along its base, a warm wash bleeds
     in from the left, and the row steps forward a little. */
  .way{position:relative;display:grid;
    grid-template-columns:52px minmax(150px,1fr) minmax(0,1.5fr) 52px;
    gap:26px;align-items:center;padding:30px 0;border-bottom:1px solid var(--line);
    color:inherit;isolation:isolate;
    transition:padding-left .32s cubic-bezier(.22,.61,.36,1)}
  /* the wash */
  .way::before{content:"";position:absolute;inset:-1px 0;z-index:-1;pointer-events:none;
    background:linear-gradient(90deg,rgba(107,139,164,.09),rgba(107,139,164,.02) 46%,transparent 72%);
    opacity:0;transition:opacity .3s ease}
  /* the travelling edge */
  .way::after{content:"";position:absolute;left:0;bottom:-1px;height:1px;width:100%;
    background:linear-gradient(90deg,var(--steel),rgba(107,139,164,.35) 62%,transparent);
    transform:scaleX(0);transform-origin:left;
    transition:transform .5s cubic-bezier(.22,.61,.36,1)}
  .way:hover,.way:focus-visible{padding-left:14px}
  .way:hover::before,.way:focus-visible::before{opacity:1}
  .way:hover::after,.way:focus-visible::after{transform:scaleX(1)}

  .way .n{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:12px;color:var(--faint);
    transition:color .25s ease}
  .way:hover .n{color:var(--steel)}
  .way .ttl{font-size:clamp(26px,3.4vw,40px);line-height:1.05;letter-spacing:-.028em;
    font-weight:500;color:var(--ink)}
  .way .desc{font-size:15px;line-height:1.6;color:var(--dim);transition:color .25s ease}
  .way:hover .desc{color:var(--ink)}
  .way .arw{width:44px;height:44px;border-radius:50%;display:grid;place-items:center;
    border:1px solid var(--line-strong);background:transparent;color:var(--steel);
    font-size:17px;justify-self:end;
    transition:background .25s ease,color .25s ease,border-color .25s ease,transform .3s cubic-bezier(.22,.61,.36,1)}
  .way:hover .arw{background:var(--steel);border-color:var(--steel);color:#060A16;
    transform:translate(3px,-3px)}
  @media (prefers-reduced-motion:reduce){
    .way,.way::before,.way::after,.way .arw{transition:none}
    .way:hover{padding-left:0}
    .way:hover::after{transform:scaleX(1)}
  }
  @media (max-width:820px){
    .ways-head{grid-template-columns:1fr;gap:16px;align-items:start}
    .ways-lede{text-align:left;max-width:none}
    .way{grid-template-columns:38px 1fr 44px;gap:8px 16px;padding:24px 0}
    .way .ttl{grid-column:2}
    .way .desc{grid-column:2;margin-top:8px}
    .way .arw{grid-row:1;grid-column:3}
  }
  @media (prefers-reduced-motion:reduce){.tiles i{animation:none;opacity:.03}}

  /* ── approach ─────────────────────────────────────────────────────────
     A centred statement, then a spine. The rail and the marks are what make
     three cards read as one sequence instead of three more boxes; without
     it this section is the same shape as every other section on the page. */
  .approach .ap-head{text-align:center;max-width:760px;margin:0 auto 62px}
  .chip{display:inline-block;font-size:11px;font-weight:600;letter-spacing:.16em;
    text-transform:uppercase;color:#060A16;background:var(--steel);padding:4px 9px;border-radius:2px}
  .approach h2{font-size:clamp(32px,5vw,54px);line-height:1.06;letter-spacing:-.03em;
    font-weight:500;margin:20px 0 0}
  .approach h2 em{font-style:italic;font-weight:400;color:var(--steel);
    font-family:Georgia,"Times New Roman",serif;letter-spacing:-.01em}
  .approach .ap-head p{font-size:16px;color:var(--dim);margin:16px 0 0}

  .steps{list-style:none;margin:0 auto;padding:0;max-width:780px;counter-reset:none}
  .step{position:relative;padding-left:66px;padding-bottom:34px}
  .step:last-child{padding-bottom:0}
  /* One spine for the whole list rather than a segment per step. The unlit
     track runs the full height; a second element fills it as you scroll, so
     the line travels the section instead of three lines appearing in turn. */
  .steps{position:relative}
  .steps::before{content:"";position:absolute;left:21px;top:22px;bottom:22px;width:1px;
    background:var(--line-strong)}
  .spine{position:absolute;left:21px;top:22px;width:1px;height:0;
    background:linear-gradient(180deg,rgba(107,139,164,.35),var(--steel));
    box-shadow:0 0 10px rgba(107,139,164,.45)}
  .spine::after{content:"";position:absolute;left:-2px;bottom:-3px;width:5px;height:5px;
    border-radius:50%;background:var(--steel);box-shadow:0 0 12px 2px rgba(107,139,164,.7)}
  .step .dot{position:absolute;left:0;top:0;width:44px;height:44px;border-radius:50%;
    display:grid;place-items:center;background:var(--raised);
    border:1px solid var(--line-strong);color:var(--steel)}
  .step .dot svg{width:20px;height:20px;transition:color .35s ease}
  .step .dot{transition:border-color .35s ease,background .35s ease,box-shadow .35s ease}
  .step.lit .dot{border-color:var(--steel);background:#141B2B;
    box-shadow:0 0 0 4px rgba(107,139,164,.09)}
  .step.lit .dot svg{color:var(--steel-hi)}
  .step .card{border:1px solid var(--line);border-radius:4px;background:var(--card);padding:22px 24px}
  .step .n{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:12px;
    letter-spacing:.14em;color:var(--faint)}
  .step h3{font-size:clamp(20px,2.6vw,27px);line-height:1.15;letter-spacing:-.022em;
    font-weight:500;color:var(--ink);margin:10px 0 0}
  .step .card p{font-size:15px;line-height:1.65;color:var(--dim);margin:12px 0 0}
  @media (max-width:640px){
    .approach .ap-head{margin-bottom:40px}
    .step{padding-left:52px;padding-bottom:26px}
    .step .dot{width:38px;height:38px}
    .steps::before,.spine{left:18px}
    .step .card{padding:18px}
  }

  /* footer */
  footer{border-top:1px solid var(--line)}
  .foot{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:16px;padding:32px}
  .foot .legal,.foot .links{font-size:10px;font-weight:500;letter-spacing:.14em;color:var(--faint);text-transform:uppercase}
  .foot .links{display:flex;gap:22px}
  .foot .links a{color:var(--dim)}
  .foot .links a:hover{color:var(--steel)}
  /* tan sign-off bar, as in the brand guide */
  .signoff{background:var(--steel);color:#060A16}
  .signoff-in{display:flex;align-items:center;gap:18px;padding:16px 32px;flex-wrap:wrap}
  .signoff .name{font-size:12px;font-weight:500;letter-spacing:.22em;text-transform:uppercase}
  .signoff .bar{width:1px;height:16px;background:rgba(11,15,20,.35)}
  .signoff .tagline{font-size:11px;font-weight:400;letter-spacing:.18em;text-transform:uppercase;color:rgba(11,15,20,.72)}
  @media (max-width:640px){.signoff-in{padding:16px 20px;gap:12px}.signoff .bar{display:none}}

/* ── sub-page hero ────────────────────────────────────────────────────
   Tally and Contact open on words alone. The atrium plate belongs to the
   home page — one photograph on the site, not one per page. */
/* padding-block only — the shorthand was resetting .wrap's side
   gutters to 0 and pinning the text to the edge of the screen */
.subhero{padding-top:150px;padding-bottom:56px;border-bottom:1px solid var(--line)}
.subhero .eyebrow{margin-bottom:22px}
.subhero h1.setwide{margin-top:0}
.subhero .sub{font-size:17px;line-height:1.65;color:var(--dim);margin:24px 0 0;max-width:620px}
.subhero .hero-ctas{display:flex;align-items:center;gap:24px;margin-top:34px;flex-wrap:wrap}
@media (max-width:640px){
  .subhero{padding-top:104px;padding-bottom:40px}
  .subhero h1.setwide{font-size:29px;letter-spacing:.012em;line-height:1.2}
  .subhero .sub{font-size:15.5px;margin-top:18px}
  .subhero .hero-ctas{display:grid;grid-template-columns:1fr;gap:0}
  .subhero .hero-ctas .btn{width:100%;height:54px;justify-content:center}
  .subhero .hero-ctas .ulink{justify-self:center;margin-top:14px;min-height:44px;
    display:inline-flex;align-items:center;border-bottom:0;font-size:13px;color:var(--dim)}
}

/* ── closing band ─────────────────────────────────────────────────────
   The contact form lives on its own page now, so the home page needs an
   ending rather than simply stopping after the FAQ. */
.closer{background:var(--card);border-top:1px solid var(--line)}
.closer h2{font-size:clamp(30px,4.4vw,46px);line-height:1.08;letter-spacing:-.03em;
  font-weight:500;margin:16px 0 0}
.closer p{font-size:16px;line-height:1.65;color:var(--dim);margin:16px 0 0;max-width:56ch}
.closer .hero-ctas{display:flex;align-items:center;gap:24px;margin-top:30px;flex-wrap:wrap}
@media (max-width:640px){
  .closer .hero-ctas{display:grid;grid-template-columns:1fr;gap:0}
  .closer .hero-ctas .btn{width:100%;height:54px;justify-content:center}
  .closer .hero-ctas .ulink{justify-self:center;margin-top:14px;min-height:44px;
    display:inline-flex;align-items:center;border-bottom:0;font-size:13px;color:var(--dim)}
}

/* the number slot carries the range under it — a service and what it costs
   are one fact, so they share a column rather than becoming a price list */
.way .n{display:flex;flex-direction:column;gap:5px}
.way .n i{font-style:normal;font-size:11px;letter-spacing:.02em;color:var(--steel-dim);white-space:nowrap}
.way:hover .n i{color:var(--steel)}
@media (min-width:821px){.way{grid-template-columns:132px minmax(150px,1fr) minmax(0,1.35fr) 52px}}

/* ── hero breaks the measure ──────────────────────────────────────────
   Everything else on the site sits in the 1160px column. The hero does
   not: the plate is full-bleed, so type centred in a narrow column reads
   as a box floating on a photograph. It runs to the edges instead, and
   the facets go with it to the far side. */
.hero-zone .hero{max-width:none;
  padding-left:clamp(22px,4.4vw,88px);padding-right:clamp(22px,4.4vw,88px)}
@media (min-width:1001px){
  .hero-zone .hero{grid-template-columns:minmax(0,1fr) 300px;gap:clamp(40px,6vw,110px)}
}

/* No panel behind the facets. In the reference they sit straight on the
   picture, and the plate is dark enough there to carry them — the scrim
   was solving a problem that the wider gutters moved out of the way. */
.hero-facets{background:none;-webkit-backdrop-filter:none;backdrop-filter:none;
  padding:0;margin:0}
.facet b{font-size:11px}
.facet span{font-size:12.5px;line-height:1.45}

/* The bar sits above a full-bleed hero, so it has to share the hero's
   gutters — held inside the 1160px column it reads as a separate object
   floating over the picture rather than the top edge of the page. */
.nav-in{max-width:none;padding-left:clamp(22px,4.4vw,88px);padding-right:clamp(22px,4.4vw,88px)}

/* The facets sit over the colonnade, which is the lit part of the plate.
   A panel behind them reads as a pasted box, so the frame falls off at the
   right edge instead — it looks like the light running out, which is what
   the picture is already doing everywhere else — and the type carries a
   shadow so it never depends on whichever pixel it lands on. */
@media (min-width:1001px){
  .hero-zone .veil{background:
    linear-gradient(90deg,rgba(11,15,20,.42) 0%,rgba(11,15,20,.14) 34%,transparent 58%,
      rgba(11,15,20,.30) 74%,rgba(11,15,20,.72) 100%)}
}
.facet b,.facet span{text-shadow:0 1px 10px rgba(11,15,20,.92),0 0 26px rgba(11,15,20,.7)}
.facet{border-top-color:rgba(107,139,164,.28)}

/* The rule over the pillars used to be a border on a block inside the
   1160px column. Now that the hero runs to the edges it stretched with
   it, straight across the picture. Short mark instead, set over the words
   it belongs to — which is what the reference had. */
.hero .pillars{border-top:0;position:relative;padding-top:28px}
.hero .pillars::before{content:"";position:absolute;top:0;left:0;width:54px;height:1px;
  background:var(--steel-dim)}

/* ── hero entrance ────────────────────────────────────────────────────
   The page opens the way the picture reads: one thing at a time, from
   the ground up. Lines rise and settle in sequence, then a single pass
   of light crosses the tan line — the same gesture as the row hover and
   as the plate itself. Transform and opacity only, so nothing here costs
   a layout. Held off entirely for anyone who asked for less motion. */
@media (prefers-reduced-motion:no-preference){
  .hero .eyebrow,.hero h1.setwide span,.hero .sub,.hero-ctas,
  .hero-note,.hero .pillars,.hero-facets .facet{
    opacity:0;animation:riseIn .8s cubic-bezier(.16,.84,.44,1) forwards}
  @keyframes riseIn{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:none}}

  .hero .eyebrow            {animation-delay:.10s}
  .hero h1.setwide span:nth-child(1){animation-delay:.22s}
  .hero h1.setwide span:nth-child(2){animation-delay:.32s}
  .hero h1.setwide span:nth-child(3){animation-delay:.42s}
  .hero .sub                {animation-delay:.56s}
  .hero-ctas                {animation-delay:.66s}
  .hero-note                {animation-delay:.74s}
  .hero .pillars            {animation-delay:.82s}
  .hero-facets .facet:nth-child(1){animation-delay:.72s}
  .hero-facets .facet:nth-child(2){animation-delay:.80s}
  .hero-facets .facet:nth-child(3){animation-delay:.88s}

  /* the short mark over the pillars draws itself rather than appearing */
  .hero .pillars::before{transform-origin:left;animation:drawRule .7s cubic-bezier(.16,.84,.44,1) .92s both}
  @keyframes drawRule{from{transform:scaleX(0)}to{transform:scaleX(1)}}

  /* A shine used to run left to right across the accent word 1.05s after
     load. That is the animation Dixon kept reporting — five times, while I
     looked for it in the JavaScript. It was here, in CSS, and it is gone. */
}

/* ── problem picker ───────────────────────────────────────────────────
   A visitor who cannot name the service they want can always name the
   thing that annoys them. So the six services are stated as six
   complaints, and picking one is the route in.

   The reference floats a white card on a photograph. A white card here
   would drop a hole in the middle of a dark site, so the card is raised
   dark on a hairline instead — same gesture, this palette. */
.picker .pick-head{display:grid;grid-template-columns:1fr auto;gap:40px;align-items:end;
  margin-bottom:38px}
.picker h2{font-size:clamp(30px,4.6vw,50px);line-height:1.06;letter-spacing:-.03em;
  font-weight:500;margin:16px 0 0;max-width:20ch}
.picker h2 em{font-style:italic;font-weight:400;color:var(--steel);
  font-family:Georgia,"Times New Roman",serif;letter-spacing:-.01em}
.picker .pick-head p{font-size:16px;line-height:1.6;color:var(--dim);margin:16px 0 0;max-width:46ch}

.pick-stage{position:relative;border-radius:6px;overflow:hidden;
  padding:clamp(24px,4vw,64px);border:1px solid var(--line)}
.pick-plate{position:absolute;inset:0;z-index:0}
.pick-plate img{width:100%;height:100%;object-fit:cover;object-position:60% center;display:block}
.pick-stage::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(180deg,rgba(11,15,20,.45),rgba(11,15,20,.62))}

.pick-card{position:relative;z-index:2;max-width:820px;margin:0 auto;
  background:rgba(17,22,29,.86);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  border:1px solid var(--line-strong);border-radius:5px;padding:clamp(20px,2.6vw,30px)}
.pick-card-head{display:flex;align-items:flex-start;justify-content:space-between;gap:18px;
  padding-bottom:20px;border-bottom:1px solid var(--line)}
.pick-card .k{font-size:12px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--faint)}
.pick-card h3{font-size:clamp(19px,2.2vw,25px);line-height:1.16;letter-spacing:-.022em;
  font-weight:500;color:var(--ink);margin:8px 0 0}
.pill{flex-shrink:0;font-size:11.5px;font-weight:500;letter-spacing:.08em;color:var(--steel);
  border:1px solid rgba(107,139,164,.4);border-radius:999px;padding:6px 13px;white-space:nowrap}

.pick-grid{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:20px}
.opt{display:grid;grid-template-columns:1fr auto;align-items:center;gap:4px 14px;
  min-height:66px;padding:14px 16px;border:1px solid var(--line);border-radius:4px;
  background:rgba(11,15,20,.5);color:inherit;
  transition:border-color .22s ease,background .22s ease,transform .22s cubic-bezier(.22,.61,.36,1)}
.opt b{font-size:14.5px;font-weight:600;letter-spacing:-.005em;color:var(--ink)}
.opt span{grid-column:1;font-size:12.5px;line-height:1.45;color:var(--dim)}
.opt i{grid-row:1/3;font-style:normal;font-size:15px;color:var(--faint);transition:color .22s ease,transform .22s ease}
.opt:hover{border-color:var(--steel);background:rgba(107,139,164,.06);transform:translateX(3px)}
.opt:hover i{color:var(--steel);transform:translateX(2px)}

.pick-foot{margin-top:16px;padding:14px 16px;border:1px solid var(--line);border-radius:4px;
  font-size:13.5px;line-height:1.55;color:var(--dim);background:rgba(11,15,20,.35)}

@media (max-width:820px){
  .picker .pick-head{grid-template-columns:1fr;gap:22px;align-items:start}
  .picker .pick-head .btn{justify-self:start}
  .pick-grid{grid-template-columns:1fr}
  .pick-card-head{flex-direction:column;gap:12px}
  .pick-stage{padding:16px;border-radius:4px}
}

/* ── scroll reveal ────────────────────────────────────────────────────
   One mechanism for the whole page: an element is marked, it starts low
   and clear, and it settles when it comes into view. Groups stagger by
   position so a list arrives as a list rather than all at once.
   Everything is opt-in through .reveal, so nothing moves for a visitor
   who asked for less motion — the class is never applied. */
.reveal{opacity:0;transform:translateY(22px);
  transition:opacity .7s cubic-bezier(.16,.84,.44,1),transform .7s cubic-bezier(.16,.84,.44,1)}
.reveal.in{opacity:1;transform:none}

/* the spine is driven by scroll position, not by a per-step transition */
/* the mark pops a beat after its card */
.step .dot{transform:scale(.7);opacity:0;
  transition:transform .55s cubic-bezier(.34,1.4,.5,1) .12s,opacity .4s ease .12s}
.step.in .dot{transform:none;opacity:1}

/* the arrow was landing in the first column and shunting the label to the
   right — it belongs in the second, spanning both rows */
.opt{grid-template-columns:1fr 20px}
.opt b{grid-column:1;grid-row:1;justify-self:start;text-align:left}
.opt span{grid-column:1;grid-row:2;text-align:left}
.opt i{grid-column:2;grid-row:1/3;justify-self:end}
/* and the plate was cropped onto its own dark edge, so the rays never showed */
.pick-plate img{object-position:38% center}

/* The card was held to 820px inside a stage twice that wide, so the panel
   floated small in a large frame. It fills the stage now — the plate's job
   here is to frame it, not to sit around it. */
.pick-card{max-width:none}
.pick-grid{gap:14px}
.opt{min-height:74px;padding:16px 18px}
.opt b{font-size:15.5px}
.opt span{font-size:13px}

/* ── who we are ───────────────────────────────────────────────────────
   A consultancy sells a person, so this page puts one on the screen and
   then says four things about how the work is done. */
.who-lead{display:grid;grid-template-columns:280px 1fr;gap:clamp(28px,4vw,56px);align-items:start}
.portrait{aspect-ratio:4/5;border:1px solid var(--line-strong);border-radius:5px;
  background:linear-gradient(150deg,#171C24 20%,#2A303A 58%,#0E1218 92%);
  display:grid;place-items:center}
.portrait .ph{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:12px;
  letter-spacing:.2em;color:var(--faint)}
.who .k{font-size:12px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--steel)}
.who h2{font-size:clamp(28px,4vw,42px);line-height:1.06;letter-spacing:-.03em;font-weight:500;margin:12px 0 0}
.who .role{font-size:15px;color:var(--steel-dim);margin:10px 0 0}
.who p{font-size:16px;line-height:1.68;color:var(--dim);margin:16px 0 0;max-width:60ch}
.who-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:clamp(38px,5vw,64px)}
.wcard{border:1px solid var(--line);border-radius:4px;background:var(--card);padding:24px}
.wcard b{display:block;font-size:17px;font-weight:600;letter-spacing:-.012em;color:var(--ink)}
.wcard p{font-size:14.5px;line-height:1.6;color:var(--dim);margin:12px 0 0;max-width:none}
@media (max-width:820px){
  .who-lead{grid-template-columns:1fr;gap:24px}
  .portrait{max-width:220px}
  .who-grid{grid-template-columns:1fr;gap:12px}
  .wcard{padding:18px}
}

/* The set-wide treatment was scoped under .hero, so the sub-page heroes on
   Tally, Contact and Who we are fell back to the default h1 and ran their
   lines together. It belongs to the class, not to the home page. */
h1.setwide{font-family:"Jost",system-ui,sans-serif;font-weight:300;
  text-transform:uppercase;letter-spacing:.055em;line-height:1.13;
  font-size:clamp(29px,5.1vw,62px);max-width:none}
h1.setwide span{display:block}
h1.setwide .accent{color:var(--steel)}
@media (max-width:640px){
  h1.setwide{font-size:29px;letter-spacing:.012em;line-height:1.2}
}

/* ── phone: reach and legibility ──────────────────────────────────────
   Everything a thumb has to hit gets 44px, and nothing sets below 12px.
   These were measured, not guessed: brand 35, nav contact 34, burger and
   sheet close 38; the hero note at 10.5, section eyebrows at 11, the
   footer at 10. */
@media (max-width:820px){
  nav .brand{min-height:44px}
  .nav-cta,.nav-signin{height:44px}
  .nav-burger,.sheet-close{width:44px;height:44px}
  .foot .links a{display:inline-flex;align-items:center;min-height:44px}

  .eyebrow{font-size:12px;letter-spacing:.1em}
  .hero-note{font-size:12px;letter-spacing:.08em}
  .foot .legal,.foot .links{font-size:12px;letter-spacing:.08em}
  .picker .pick-card .k,.approach .chip,.ways .eyebrow{font-size:12px}
  .pill{font-size:12px}
  .opt span{font-size:13px}
  .way .n{font-size:12px}
}

/* the secondary link was drifting a long way under the button and
   centring itself, which read as a second, competing call */
@media (max-width:640px){
  .hero-ctas .ulink,.subhero .hero-ctas .ulink,.closer .hero-ctas .ulink{
    justify-self:start;margin-top:8px}
}

/* the footer carries a second lockup, which the nav-scoped rule missed */
@media (max-width:820px){
  .foot .brand{min-height:44px}
  .signoff .tagline,.signoff .name{font-size:12px}
}

/* ── phone: the sections that came over from the old single page ──────
   The flows and packs blocks were built for a desktop schematic and had
   never been sized for a thumb: figure tabs at 41px, the small buttons
   at 40, and mono labels running down to 9px. */
@media (max-width:820px){
  .btn-sm{height:46px;padding:0 22px;font-size:13px}
  .ulink{min-height:44px;display:inline-flex;align-items:center}
  .fig-tab{min-height:48px;font-size:12px;letter-spacing:.06em}

  .tally-card .by,.rcard .by{font-size:12px}
  .bp-head .fig,.bp-head .note{font-size:12px;letter-spacing:.06em}
  .node .k{font-size:12px;letter-spacing:.06em}
  .node b{font-size:14px}
  .node .d{font-size:12.5px}
  .loop{font-size:12px}
  .bp-out .lead,.bp-out .chips{font-size:12px}
  .spec .cols,.spec .tag{font-size:12px}
  .pack .k,.pack .fig{font-size:12px}
  .case-grid .src{font-size:12px;letter-spacing:.08em}
  .wizfoot .note,.lbl{font-size:12px;letter-spacing:.08em}
}

/* the last of them, found by walking the rendered page rather than by
   guessing at class names */
@media (max-width:820px){
  .rcard .by,.rcard-head span,.rcard.sample .foot{font-size:12px;letter-spacing:.06em}
  .pack-head .pk-trigger,.pk-trigger,.pack .pk-foot{font-size:12px;letter-spacing:.06em}
}

@media (max-width:820px){
  /* these have to match the specificity of the desktop rules they override
     — .lockup .by and .trig-grid>div b both outrank a bare class */
  .lockup .by{font-size:12px;letter-spacing:.14em}
  .trig-grid>div b{font-size:12px;letter-spacing:.08em}
  .trig-grid>div span{font-size:13px}
}

/* ── phone: the enquiry form ──────────────────────────────────────────
   Fields at 42px and a bare email link at 18px. A form is the one place
   on the site where a missed tap costs an enquiry. */
@media (max-width:820px){
  .fld{height:48px;font-size:16px}          /* 16px also stops iOS zooming on focus */
  select.fld{height:48px}
  textarea.fld{min-height:96px;font-size:16px}
  .pick{min-height:46px}
  .contact-band a[href^="mailto:"]{display:inline-flex;align-items:center;min-height:44px}
}

/* The bar floats on the plate until it docks, and this plate puts its
   brightest run of light exactly where the sign-in button sits. A short
   fall-off from the top edge carries the bar without reading as a filled
   header — it only exists while the nav is undocked. */
nav:not(.docked)::before{content:"";position:absolute;inset:0 0 auto 0;height:132px;
  z-index:-1;pointer-events:none;
  background:linear-gradient(180deg,rgba(11,15,20,.78),rgba(11,15,20,.42) 46%,transparent)}
nav{isolation:isolate}
.nav-signin{backdrop-filter:none}
nav:not(.docked) .nav-signin{border-color:rgba(107,139,164,.45);color:var(--ink) !important}

/* ── picker at the hero's width ───────────────────────────────────────
   The stage was sitting inside the 1160px column while the hero ran to
   the edges, so the one interactive block on the page read smaller than
   the picture above it. It takes the same gutters now, and the type
   inside grows with it — the options are the point of the section, not
   a footnote to it. */
@media (min-width:821px){
  .picker .sec{max-width:none;
    padding-left:clamp(22px,4.4vw,88px);padding-right:clamp(22px,4.4vw,88px)}
  .pick-stage{padding:clamp(34px,4.4vw,76px)}
  .pick-card{padding:clamp(28px,3vw,40px)}
  .pick-card h3{font-size:clamp(24px,2.9vw,34px)}
  .pick-grid{gap:16px}
  .opt{min-height:92px;padding:20px 24px}
  .opt b{font-size:17.5px}
  .opt span{font-size:14px}
  .opt i{font-size:18px}
  .pick-foot{font-size:14.5px;padding:18px 20px}
  .pick-card .k{font-size:12.5px}
}

/* The card was told to fill the stage, which left the plate as a sliver
   down one edge. Reversed: the stage keeps the hero's width, and the card
   sits back inside it so the rays read as a picture the panel is placed
   on rather than as a border around it. */
@media (min-width:821px){
  .pick-stage{padding:clamp(56px,7vw,120px) clamp(40px,7vw,130px)}
  .pick-card{max-width:900px;margin:0 auto}
  .pick-plate img{object-position:46% center}
  /* less scrim, since the plate is now something to look at */
  .pick-stage::after{background:linear-gradient(180deg,rgba(11,15,20,.30),rgba(11,15,20,.50))}
}

/* the option rows were pushed up with the card and overshot — they only
   have to hold two short lines */
@media (min-width:821px){
  .opt{min-height:0;padding:14px 18px}
  .opt b{font-size:15.5px}
  .opt span{font-size:13px}
  .opt i{font-size:16px}
  .pick-grid{gap:12px}
  .pick-foot{font-size:13.5px;padding:14px 18px;margin-top:14px}
}

/* This plate carries all of its light in the right half, so a centred crop
   leaves the strip to the left of the card as flat black and the section
   looks lit from one side only. Pushing the window right puts rays on both
   sides of the panel. */
@media (min-width:821px){
  .pick-plate img{object-position:66% center}
  .pick-stage::after{background:linear-gradient(180deg,rgba(11,15,20,.22),rgba(11,15,20,.44))}
}

/* On a phone the stage has 16px of padding, so the plate shows as a hairline
   down one edge and nothing else — 96KB of image for something nobody can
   see, on the connection least able to afford it. The card stands on the
   paper instead. */
@media (max-width:820px){
  .pick-plate{display:none}
  .pick-stage{border:0;padding:0;background:none}
  .pick-stage::after{display:none}
  .pick-card{border-radius:5px}
}

/* ── hero, closer to the mockup ───────────────────────────────────────
   The reference has no eyebrow, no note line, and a facet column set
   much quieter than the one that got built. Its restraint is the whole
   effect, so those come off. The call to action stays — a hero without
   one is a picture — but everything around it gets out of its way. */
@media (min-width:821px){
  .hero .eyebrow,.hero .hero-note{display:none}
  .hero h1.setwide{margin-top:0}
  .hero .sub{max-width:36ch;font-size:16px;line-height:1.7;margin-top:24px}
  .hero .pillars{margin-top:40px;padding-top:26px}

  /* the facets in the reference are small marks, not cards */
  .hero-facets{gap:22px;max-width:250px}
  .facet{grid-template-columns:22px 1fr;column-gap:12px;padding-top:11px}
  .fmark{width:16px;height:16px}
  .facet b{font-size:10.5px;letter-spacing:.14em}
  .facet span{font-size:12px;line-height:1.42;margin-top:5px}
}

/* the pillars are separated by small dots in the reference, not diamonds */
.pillars span::before{width:3px;height:3px;border-radius:50%;transform:none;
  background:var(--steel-dim);margin-right:11px}

/* ── phone: let the picture reach the edges ───────────────────────────
   A band with side gutters, a border and a radius reads as a card
   dropped into the page. Full bleed reads as the hero it is. */
@media (max-width:640px){
  .hero-index{margin:26px -20px 0}
  .hix-plate{height:300px;margin-right:0;border:0;border-radius:0;
    border-top:1px solid var(--line)}
  .hix-plate .cap{left:20px;bottom:18px}
}

/* narrowing the column's contents left it floating 50px short of the
   gutter every other element lines up on — narrow the track instead */
@media (min-width:1001px){
  .hero-zone .hero{grid-template-columns:minmax(0,1fr) 250px}
}

/* an earlier rule pulled the plate 20px right of the gutter and my override
   only zeroed that side, so it sat inset on the right. Bleed both. */
@media (max-width:640px){
  .hero-index{margin-left:-20px;margin-right:-20px}
  .hix-plate{margin-left:0;margin-right:0;width:auto}
}

/* Negative margins were not widening the block — its width still resolved
   from the parent's content box, so only the left edge moved. The viewport
   technique does not depend on that: pin the width to the viewport and pull
   it back by half the difference. */
@media (max-width:640px){
  .hero-index{margin-left:0;margin-right:0}
  .hix-plate{width:100vw;margin-left:calc(50% - 50vw);margin-right:calc(50% - 50vw)}
}

/* ── phone hero, tightened ────────────────────────────────────────────
   The eyebrow came off the desktop but not here, where it is the most
   cramped thing on the screen — a two-digit index, a rule and a
   forty-character line squeezed into 350px. Off here too.

   The rest was dead space: a gap under the secondary link, then a short
   picture that stopped well before the fold, so the screen read as a
   text block and a photograph rather than as one composition. The copy
   closes up and the picture runs to the bottom of the first screen. */
@media (max-width:640px){
  .hero-zone{min-height:100svh}
  .hero .eyebrow{display:none}
  .hero{padding-top:74px;padding-bottom:0}
  .hero h1.setwide{margin-top:0}
  .hero .sub{margin-top:16px}
  .hero-ctas{margin-top:24px}
  .hero-ctas .ulink{margin-top:10px}
  .hero-index{margin-top:22px}
  /* sized so the picture ends on the fold rather than leaving a band of
     empty hero under it — the copy above it is a fixed height here */
  .hix-plate{height:min(452px, 53svh)}
}

/* ── phone: the action follows you ────────────────────────────────────
   Persistent contact, the way the reference keeps a chat button pinned.
   Off until the hero has left the screen, so it never sits under a
   button that is already visible, and never on desktop where the nav
   carries one the whole way down. */
.dock{display:none}
@media (max-width:820px){
  .dock{position:fixed;left:0;right:0;bottom:0;z-index:35;display:flex;
    align-items:center;gap:14px;
    padding:12px 20px calc(12px + env(safe-area-inset-bottom));
    background:rgba(11,15,20,.94);-webkit-backdrop-filter:blur(14px);
    backdrop-filter:blur(14px);border-top:1px solid var(--line);
    transform:translateY(102%);transition:transform .32s cubic-bezier(.22,.61,.36,1)}
  .dock.up{transform:none}
  .dock-cta{flex:1;height:50px;display:flex;align-items:center;justify-content:center;
    background:var(--steel);color:#060A16;border-radius:3px;
    font-size:13.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase}
  .dock-note{font-size:12px;letter-spacing:.06em;color:var(--faint);
    text-transform:uppercase;white-space:nowrap}
  /* so the footer is never sitting under it */
  body.docked-cta{padding-bottom:78px}
  /* and the menu sheet covers it rather than fighting it */
  .sheet[data-open] ~ .dock{transform:translateY(102%)}
}
@media (prefers-reduced-motion:reduce){.dock{transition:none}}

/* ── phone hero: words on the picture ─────────────────────────────────
   Earlier attempts put type over this plate and lost — but that was the
   old corridor, and the phone crop was taken from the lit two thirds.
   The crop now comes from the left of the frame, where the top third
   measures 3.8/255 mean luminance. White type sits on that without a
   scrim at all, and the light line still arrives at the bottom of the
   frame under the button. */
@media (max-width:640px){
  .hero-zone{min-height:100svh;align-items:flex-start;background:var(--paper)}
  .hero-zone .plate{display:block;position:absolute;inset:0}
  .hero-zone .plate img{object-position:center}
  /* only enough to settle the foot of the frame, nothing over the words */
  .hero-zone .veil{display:block;background:linear-gradient(180deg,
    transparent 0%,transparent 52%,rgba(11,15,20,.34) 74%,rgba(11,15,20,.72) 100%)}

  .hero{padding-top:96px;padding-bottom:34px;position:relative;z-index:2}
  /* the separate picture band is what this replaces */
  .hero-index{display:none}
  .hero .pillars{display:flex;margin-top:30px;padding-top:20px}
}

/* ── phone hero: copy at the foot ─────────────────────────────────────
   Dixon's call, made after seeing the alternative. It costs a scrim:
   the bottom third of this plate measures 39.6 mean / 229 max, and no
   crop of it — six horizontal offsets and five vertical windows — has a
   dark foot, because the light line lands on the floor and reflects.
   So the scrim is shaped to spend as little as possible: nothing at all
   across the top 38%, where the ceiling and the upper run of the light
   stay untouched, then down hard under the words. */
@media (max-width:640px){
  .hero-zone{align-items:flex-end}
  .hero{padding-top:0;padding-bottom:38px}
  .hero-zone .veil{background:linear-gradient(180deg,
    transparent 0%,transparent 38%,rgba(11,15,20,.50) 56%,
    rgba(11,15,20,.88) 74%,rgba(11,15,20,.97) 100%)}
  /* pull the frame down so the light line and the vanishing point sit in
     the clean upper half; the scrim then only covers floor */
  .hero-zone .plate img{object-position:center 68%}
  .hero .pillars{margin-top:24px;padding-top:18px}
}

/* The copy sat at 53% of the frame, which is fine on a tall phone and
   starts losing its last line on a short one — browser chrome can take
   150px off the visible height. Lift it, and on genuinely short frames
   stop demanding a full screen at all. */
@media (max-width:640px){
  .hero{padding-bottom:64px}
}
@media (max-width:640px) and (max-height:720px){
  .hero-zone{min-height:0}
  .hero{padding-top:230px;padding-bottom:44px}
  .hero .pillars{display:none}
}

/* ── press and focus ──────────────────────────────────────────────────
   Every piece of feedback on this site was a hover state, and a phone
   has no hover: a tap did nothing at all until the page changed. These
   are the press states, kept short and physical — the thing you touched
   gives a little, then lets go.

   Focus rings go on at the same time. Only .way had one, so keyboard
   users were navigating on whatever the browser happened to draw. */
@media (hover:none){
  .way:hover{padding-left:0}
  .way:hover::before{opacity:0}
  .way:hover::after{transform:scaleX(0)}
  .way:hover .arw{background:transparent;border-color:var(--line-strong);
    color:var(--steel);transform:none}
  .way:hover .n{color:var(--faint)}
  .way:hover .desc{color:var(--dim)}
  .opt:hover{border-color:var(--line);background:rgba(11,15,20,.5);transform:none}
}

.btn:active,.dock-cta:active{transform:scale(.975);background:var(--steel-hi)}
.btn-ghost:active,.fig-tab:active,.pick:active{transform:scale(.98);border-color:var(--steel)}
.opt:active{transform:scale(.985);border-color:var(--steel);background:rgba(107,139,164,.07)}
.way:active{background:rgba(107,139,164,.05)}
.way:active .arw{background:var(--steel);border-color:var(--steel);color:#060A16}
.chips a:active,.sheet-links a:active,.ulink:active,.nav-links a:active{color:var(--steel)}
.hix:active{background:rgba(107,139,164,.06)}
.btn,.btn-ghost,.dock-cta,.opt,.pick,.fig-tab,.hix{
  transition:transform .12s ease,background .18s ease,border-color .18s ease,color .18s ease}
/* a press should feel instant even mid-transition */
.btn:active,.dock-cta:active,.opt:active,.btn-ghost:active,.pick:active,.fig-tab:active{
  transition-duration:.06s}

:focus-visible{outline:2px solid var(--steel);outline-offset:3px;border-radius:2px}
.btn:focus-visible,.dock-cta:focus-visible{outline-offset:4px}
.opt:focus-visible,.way:focus-visible{outline-offset:2px}

@media (prefers-reduced-motion:reduce){
  .btn:active,.btn-ghost:active,.dock-cta:active,.opt:active,.pick:active,.fig-tab:active{
    transform:none}
}

/* ── the foot of the page ─────────────────────────────────────────────
   From the FAQ down it was one flat near-black: the closing band sat at
   #0D1220 against #060A16, six points of luminance apart, and the footer
   had no background at all. The reference ends on a saturated gradient
   panel and a footer in its own colour; this palette has one accent, so
   it does the same job with tan at low strength and the blueprint grid
   the site already uses elsewhere.

   The closing band becomes a lit panel, the footer drops below paper so
   it reads as ground, and the sign-off stays the one bright strip. */
.closer{position:relative;overflow:hidden;
  background:
    radial-gradient(120% 100% at 88% 0%, rgba(107,139,164,.10), transparent 62%),
    linear-gradient(180deg, #12171F 0%, #0E131A 100%);
  border-top:1px solid var(--line-strong)}
/* the same 24px grid as the blueprint, barely there */
.closer::before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:
    linear-gradient(rgba(107,139,164,.035) 1px,transparent 1px),
    linear-gradient(90deg,rgba(107,139,164,.035) 1px,transparent 1px);
  background-size:24px 24px;
  -webkit-mask-image:radial-gradient(120% 90% at 80% 0%, #000 20%, transparent 72%);
  mask-image:radial-gradient(120% 90% at 80% 0%, #000 20%, transparent 72%)}
.closer .sec{position:relative;z-index:1}
.closer .eyebrow{color:var(--steel)}

/* footer sits below paper so the page has a floor rather than fading out */
footer{background:#080B0F;border-top:1px solid var(--line)}
.foot{border-bottom:1px solid var(--line-soft)}

/* and the FAQ stops being the same slab as everything above it */
#faq{background:linear-gradient(180deg, transparent, rgba(107,139,164,.022))}

/* the plate is scaled a little on phones so the parallax has somewhere to
   travel without exposing an edge */
@media (max-width:820px){
  .hero-zone .plate img{will-change:transform}
}

/* the footer links were a single flex row with a 22px gap, so on a phone
   they broke mid-label — "CLIENT SIGN IN" over three lines — and the last
   one ran off the right edge */
@media (max-width:640px){
  .foot{flex-direction:column;align-items:flex-start;gap:22px;padding:28px 20px}
  .foot .links{flex-wrap:wrap;gap:14px 20px;width:100%}
  .foot .links a{white-space:nowrap}
  .foot .legal{line-height:1.6}
}

/* ── Tally: shader backdrop ───────────────────────────────────────────
   The product page opens on a moving field rather than a photograph —
   the atrium belongs to the consultancy, and Tally should not look like
   a fifth room of it. The canvas is decorative: if WebGL2 is missing, if
   the tab is hidden, or if less motion was asked for, the script never
   runs and this static ground is what shows. */
.shader-zone{position:relative;overflow:hidden;background:
  radial-gradient(120% 90% at 76% 10%, rgba(107,139,164,.09), transparent 64%),
  linear-gradient(180deg,#0C1118,#0A0E13)}
.shader-zone #shader{position:absolute;inset:0;width:100%;height:100%;
  display:block;opacity:0;transition:opacity 1.1s ease}
.shader-zone #shader.on{opacity:.85}
/* keeps the type off the brightest drifts without flattening the field */
.shader-zone::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,rgba(11,15,20,.70),rgba(11,15,20,.34) 46%,transparent 78%),
    linear-gradient(0deg,rgba(11,15,20,.55),transparent 40%)}
.shader-zone .subhero{position:relative;z-index:1;border-bottom:0}
.shader-zone{border-bottom:1px solid var(--line)}

/* The scrim above is shaped for the desktop layout, where type sits in the
   left half. On a phone the copy runs the full width, so the streaks were
   crossing the paragraph. Even coverage there instead. */
@media (max-width:820px){
  .shader-zone::after{background:
    linear-gradient(180deg,rgba(11,15,20,.42) 0%,rgba(11,15,20,.58) 40%,rgba(11,15,20,.72) 100%)}
  .shader-zone #shader.on{opacity:.7}
}

/* ── Tally: what the client actually sees ─────────────────────────────
   The reference hero pairs a claim with a product panel underneath. The
   page already had a numbers card — a summary — but nothing that showed
   the interface. This is that panel, drawn in HTML rather than dropped
   in as a screenshot: no client named, no figure real, and it stays
   legible at any width instead of being a fixed-size image. */
.demo-zone{background:
  radial-gradient(110% 80% at 82% 0%, rgba(107,139,164,.07), transparent 60%),
  linear-gradient(180deg,#0C1118,#0A0E13);
  border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.demo-h{font-size:clamp(28px,4.2vw,46px);line-height:1.07;letter-spacing:-.03em;
  font-weight:500;margin:16px 0 0;max-width:19ch}
.demo-lede{font-size:16px;line-height:1.65;color:var(--dim);margin:16px 0 0;max-width:60ch}

.demo-frame{margin-top:clamp(28px,4vw,52px);border:1px solid var(--line-strong);
  border-radius:8px;overflow:hidden;background:var(--paper);
  box-shadow:0 30px 80px -40px rgba(0,0,0,.9)}
.demo-bar{display:flex;align-items:center;gap:12px;padding:11px 16px;
  background:var(--card);border-bottom:1px solid var(--line)}
.demo-dot{width:9px;height:9px;border-radius:50%;background:var(--steel);flex-shrink:0}
.demo-app{font-family:"Jost",system-ui,sans-serif;font-size:12px;font-weight:550;
  letter-spacing:.24em;margin-right:-.24em}
.demo-ws{font-size:12px;color:var(--faint)}
.demo-live{margin-left:auto;display:inline-flex;align-items:center;gap:7px;
  font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim)}
.demo-live i{width:6px;height:6px;border-radius:50%;background:#5FA97F;
  box-shadow:0 0 0 3px rgba(95,169,127,.16)}

.demo-body{display:grid;grid-template-columns:176px 1fr}
.demo-side{display:grid;align-content:start;gap:2px;padding:16px 10px;
  border-right:1px solid var(--line);background:#0A0E13}
.demo-side span{display:flex;align-items:center;gap:8px;padding:9px 12px;border-radius:4px;
  font-size:13px;color:var(--faint)}
.demo-side span.on{background:rgba(107,139,164,.09);color:var(--ink)}
.demo-side b{margin-left:auto;font-size:11px;font-weight:600;color:#060A16;
  background:var(--steel);border-radius:999px;padding:1px 7px}

.demo-main{padding:clamp(16px,2.2vw,26px)}
.demo-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;
  padding-bottom:18px;border-bottom:1px solid var(--line)}
.demo-k{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:11.5px;
  letter-spacing:.1em;color:var(--faint)}
.demo-main h3{font-size:clamp(17px,2vw,22px);font-weight:500;letter-spacing:-.02em;
  color:var(--ink);margin:8px 0 0}
.demo-wait{flex-shrink:0;font-size:11.5px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--steel);border:1px solid rgba(107,139,164,.42);border-radius:999px;padding:5px 11px}

.demo-steps{list-style:none;margin:0;padding:0}
.demo-steps li{display:grid;grid-template-columns:16px minmax(96px,auto) 1fr auto;
  gap:14px;align-items:baseline;padding:14px 0;border-bottom:1px solid var(--line-soft)}
.demo-steps b{font-size:14px;font-weight:600;color:var(--ink)}
.demo-steps em{font-style:normal;font-size:13.5px;color:var(--dim)}
.demo-steps .t{font-family:"IBM Plex Mono",ui-monospace,monospace;font-size:12px;color:var(--faint)}
.demo-steps .s{width:9px;height:9px;border-radius:50%;align-self:center;
  border:1px solid var(--line-strong)}
.demo-steps .done .s{background:var(--steel-dim);border-color:var(--steel-dim)}
.demo-steps .now .s{background:var(--steel);border-color:var(--steel);
  box-shadow:0 0 0 4px rgba(107,139,164,.16)}
.demo-steps .now b{color:var(--steel)}
.demo-steps .next{opacity:.5}

.demo-act{display:flex;align-items:center;justify-content:space-between;gap:16px;
  flex-wrap:wrap;margin-top:18px}
.demo-sig{font-size:13px;color:var(--faint)}
.demo-btns{display:flex;gap:10px}
.demo-btns i{font-style:normal;font-size:12.5px;font-weight:600;letter-spacing:.06em;
  text-transform:uppercase;padding:9px 16px;border-radius:3px}
.demo-btns .ghost{border:1px solid var(--line-strong);color:var(--dim)}
.demo-btns .go{background:var(--steel);color:#060A16}
.demo-note{font-size:12px;color:var(--faint);margin-top:14px;letter-spacing:.04em}

@media (max-width:820px){
  .demo-body{grid-template-columns:1fr}
  .demo-side{display:flex;gap:6px;overflow-x:auto;border-right:0;
    border-bottom:1px solid var(--line);padding:10px;scrollbar-width:none}
  .demo-side::-webkit-scrollbar{display:none}
  .demo-side span{white-space:nowrap;font-size:12.5px}
  .demo-steps li{grid-template-columns:14px 1fr auto;gap:6px 12px}
  .demo-steps em{grid-column:2/-1}
  .demo-head{flex-direction:column;gap:12px}
  .demo-act{flex-direction:column;align-items:flex-start}
  .demo-btns{width:100%}
  .demo-btns i{flex:1;text-align:center;padding:13px 16px}
}

/* The scrim over this canvas was tuned for the streak shader that used to be
   here: thin bright lines that needed holding down. A mesh gradient is soft
   and low-contrast to begin with, and the same scrim flattened it to nothing
   — the field was running the whole time and could not be seen. Much lighter,
   and only where the type actually sits. */
.shader-zone::after{background:
  linear-gradient(90deg,rgba(11,15,20,.55),rgba(11,15,20,.18) 44%,transparent 72%)}
.shader-zone #shader.on{opacity:1}
@media (max-width:820px){
  .shader-zone::after{background:
    linear-gradient(180deg,rgba(11,15,20,.20) 0%,rgba(11,15,20,.34) 44%,rgba(11,15,20,.56) 100%)}
  .shader-zone #shader.on{opacity:1}
}

/* the home hero is the atrium photograph again — the shader field it briefly
   carried belongs to Tally, where a generated surface suits a software page.
   Reversing this is one element: swap the <picture> for <canvas id="shader">
   and load assets/shader-hero.js. */

/* ── the hero pattern ────────────────────────────────────────────────
   The artwork itself, tiled — not a reconstruction. Building it from one mark
   on a grid lost both the interlock and the three flat fills, which is why it
   read as scattered triangles instead of a woven surface.

   The strip is 311px, the measured horizontal period of the artwork, repeated
   across; its seam error is 5.5 of 255. It does not repeat vertically, so the
   height is scaled to the hero rather than tiled.

   The opacities are measured. The pattern's lightest fill is #9A9AA8 and white
   type over it at full strength gives 2.78 against a 4.5 floor; .70 is where it
   clears. The resting field is .30 (12.2) and the area under the pointer
   reaches .62 (5.9), so the headline holds even with the bright area sitting
   directly behind it. */

/* ── the hero field ──────────────────────────────────────────────────
   A canvas drawn from polygons, not a picture. Every earlier version tiled a
   strip of the artwork and cut each mark out as a sprite, and every problem
   came from that: bounding boxes that read as squares, edges stripped of
   their anti-aliasing, blur wherever the tile was scaled, seams. None of it
   exists once the marks are geometry. assets/hero-field.js owns the motion.

   touch-action and the absent pointer come from Dixon's spec: a dragging
   finger should still scroll, and the field is decoration, so it takes no
   pointer of its own — the hero listens instead. */
#ddx-pattern{
  position:absolute; inset:0; z-index:0;
  width:100%; height:100%; display:block;
  touch-action:none; pointer-events:none;
}
