/* =========================================================================
   ORIGINAL LIMITED — v5 SHARED COMPONENTS
   Hero coded canvas · Bento grid · Client tiles · Animated timeline
   Live calculator · Marquee ribbon · Marquee footer · Not10robots band
   Appended after the base system. Same tokens, same rules.
   ========================================================================= */

/* =========================================================================
   1. NO-BROWNS DOCTRINE
   Carbon #101820 is a BLUE black. Blended onto gold it skews olive-brown
   (78% alpha measures #453B1D). Every ink on a gold field is therefore
   SOLID carbon — hierarchy comes from size and weight, never opacity.
   Never use rgba() for text on --gold.
   ========================================================================= */
.on-gold, .marquee, .marquee-group li, .ctable-us th, .ctable-us td{
  --ink-on-gold: #101820;
}

/* =========================================================================
   2. HERO — coded canvas texture (replaces the gradient)
   A real canvas: a drifting glyph field that repels from the pointer.
   ========================================================================= */
.hero {
  background: var(--carbon) !important;
  isolation: isolate;
}
/* Kill the old gradient wash entirely */
.hero::before { display: none !important; }

/* inset:0 — bleeding past the edge caused a horizontal scrollbar. The texture
   is drawn edge-to-edge and faded with a mask instead of being clipped. */
/* =========================================================================
   HERO GL — WebGL2 volumetric raymarcher
   The canvas bleeds 30% past the section on every side so the section's
   overflow:hidden clip always lands on empty canvas. The shader's own
   vignette (1 - dot(uv,uv)*0.62) fades the field to black well before the
   bleed boundary, so the clip can never catch a lit pixel. No mask is used --
   masks on a clipped box are what produced the hard horizontal edge before.
   ========================================================================= */
.hero-radar {
  position: absolute;
  /* A canvas is a REPLACED element: inset does not size it, so with no
     intrinsic size it collapses to 300x150. The bleed is therefore stated as
     explicit width/height percentages of the section, which a replaced element
     does honour. The radar shader fades itself radially well inside this box,
     so the bleed is now just a safety margin rather than a vignette. */
  top: -12%; right: -12%; bottom: -12%; left: -12%;
  width: 124%; height: 124%;
  z-index: 0; pointer-events: none;
  opacity: 0; transition: opacity 900ms ease 120ms;
}
/* Only reveal once the renderer reports it has compiled AND drawn, so a WebGL
   failure shows the flat carbon hero rather than an empty black box.
   The renderer sets radar-ready / radar-fallback on the HERO SECTION itself
   (host = canvas.parentElement), not on <html> -- so these are same-element
   selectors, not descendant ones. On failure it also removes the canvas, which
   is what actually prevents the black box; this rule is the belt to that
   braces. */
.hero.radar-ready .hero-radar { opacity: 1; }
.hero.radar-fallback .hero-radar { opacity: 0; }

/* Copy scrim. Required, not decorative: with no scrim the lede sits directly on
   the densest part of the linework and stops being readable. Opaque under the
   copy on the left, falling to zero by ~70% so the relief still reads on the
   right. A flat wash would kill the relief; a shader-side fix cannot protect
   the noscript/JS-off case. */
/* A real element, not ::after: the ::after slot is already taken by a retired
   binary-strip rule in styles.css and retired-veil rules in components.css,
   all of which set `content: none`. Using our own element sidesteps that
   cascade entirely and survives those rules being reinstated. */
.hero-scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(97deg,
    rgba(5,8,12,.95) 2%,
    rgba(5,8,12,.90) 24%,
    rgba(5,8,12,.58) 44%,
    rgba(5,8,12,.10) 60%,
    rgba(5,8,12,0) 70%);
}
@media (prefers-reduced-motion: reduce) {
  .hero.radar-ready .hero-radar { opacity: .42; }
}
@media (max-width: 900px) {
  .hero-scrim {
}

    background: linear-gradient(180deg,
      rgba(5,8,12,.92) 0%,
      rgba(5,8,12,.80) 46%,
      rgba(5,8,12,.52) 72%,
      rgba(5,8,12,.30) 100%);
  }

/* No WebGL, no JS, or JS disabled: a composed CSS field, never an empty box. */
.hero-fallback {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(58% 46% at 62% 42%, rgba(255,182,18,.20), transparent 70%),
    radial-gradient(38% 30% at 70% 50%, rgba(255,198,58,.14), transparent 72%),
    radial-gradient(70% 60% at 50% 50%, rgba(16,24,32,.30), transparent 78%);
}
.hero-veil {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(16,24,32,0.72) 0%, rgba(16,24,32,0.18) 34%, rgba(16,24,32,0.55) 74%, rgba(16,24,32,0.95) 100%),
    radial-gradient(70% 52% at var(--px, 50%) var(--py, 40%), rgba(255,182,18,0.13), transparent 70%);
  transition: background 220ms var(--ease);
}
.hero-inner, .hero-proof, .hero-art { position: relative; z-index: 2; }

/* The headline reacts differently to the pointer than the canvas does:
   a gold sheen tracks the cursor across the type. */
.hero-title { position: relative; }
.hero-title .line { position: relative; display: inline-block; }
.hero-title::after {
  content: "";
  position: absolute; inset: -6% -4%;
  background: radial-gradient(280px circle at var(--px, 50%) var(--py, 50%),
              rgba(255,182,18,0.18), transparent 68%);
  opacity: 0; transition: opacity 320ms var(--ease);
  pointer-events: none; z-index: -1;
}
.hero-title:hover::after { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .hero-title::after { display: none; }
}

/* =========================================================================
   3. BENTO GRID — replaces the six-row capability list
   ========================================================================= */
.bento {
  max-width: var(--maxw); margin: var(--s-7) auto 0;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  /* Was gap: 1px over a --rule-light background and a 1px border -- a
     hairline-grid trick that draws the dividers using the container as a
     backdrop. It looked deliberate but it is not: the cells read as touching
     boxes, with 1px between them and no breathing room, which is what "0px to
     2px apart" describes. Real space, real dividers, one rule. */
  gap: var(--gap-cell);
  background: none;
  border: 0;
}
.bento-card {
  background: var(--white);
  /* Use the card token instead of a hardcoded 27px. 27px is on neither the
     --s-1..--s-9 scale nor the accepted baseline, so it was the single
     remaining spacing-guard failure. --pad-card is the project's own fluid
     card padding (clamp(20px, 2.4vw, 34px)) and already covers 27px across
     the responsive range. */
  padding: var(--pad-card);
  display: flex; flex-direction: column;
  position: relative;
  transition: background var(--med) var(--ease), box-shadow var(--med) var(--ease);
}
.bento-card { border: 1px solid var(--rule-light); }
.bento-card:hover { background: var(--paper); border-color: var(--gold); }
.bento-full:hover { background: var(--carbon-lift); }
.bento-wide   { grid-column: span 7; }
.bento-narrow { grid-column: span 5; }
.bento-third  { grid-column: span 4; }
.bento-half   { grid-column: span 6; }
.bento-full   { grid-column: span 12; }

.bento-verb {
  font-family: var(--display);
  font-variation-settings: "wdth" 70, "wght" 870;
  font-size: clamp(2.1rem, 4.4vw, 3.6rem);
  line-height: 0.9; text-transform: uppercase; letter-spacing: -0.035em;
  color: var(--gold-ink); margin-bottom: 14px;
}
.bento-card h3 {
  font-family: var(--display);
  font-variation-settings: "wdth" 84, "wght" 800;
  font-size: clamp(1.25rem, 2.1vw, 1.7rem);
  line-height: 1.06; text-transform: uppercase; letter-spacing: -0.024em;
  color: var(--ink); margin-bottom: 14px;
}
.bento-card p { color: #333d48; font-size: 1rem; line-height: 1.6; margin-bottom: 20px; }
.bento-card p:last-child { margin-bottom: 0; }
.bento-list { display: flex; flex-wrap: wrap; gap: 8px; margin-top: auto; }
.bento-list li {
  font-family: var(--mono); font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase;
  padding: 8px 13px; border: 1px solid var(--rule-light); border-radius: var(--pill);
  color: #3d4753;
}
.bento-stat {
  font-family: var(--display);
  font-variation-settings: "wdth" 68, "wght" 870;
  font-size: clamp(2.6rem, 5.4vw, 4rem);
  line-height: 0.88; letter-spacing: -0.04em;
  color: var(--gold-ink); margin-bottom: 12px;
}
.bento-full {
  background: var(--carbon); border-color: var(--carbon);
}
.bento-full h3 { color: var(--white); }
.bento-full p { color: var(--on-dark-dim); }
.bento-full .bento-list li { border-color: var(--rule-gold); color: var(--white); }
.bento-full .bento-verb { color: var(--gold); }

/* =========================================================================
   4. CLIENT TILES — image or elegant placeholder
   Placeholders are designed, not empty: gold rule + monogram + name.
   ======================================================================= */
.tile-grid {
  max-width: var(--maxw); margin: clamp(30px, 4vw, 52px) auto 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
  gap: 1px;
  background: var(--rule-dark);
  border: 1px solid var(--rule-dark);
}
.tile {
  position: relative;
  background: var(--carbon);
  aspect-ratio: 4 / 3;
  overflow: hidden;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: clamp(14px, 1.6vw, 22px);
  text-decoration: none;
  transition: background var(--med) var(--ease);
}
.tile:hover { background: var(--carbon-lift); }
.tile:focus-visible { background: var(--carbon-lift); outline: 3px solid var(--gold); outline-offset: -3px; }
.tile.has-img::after {
  content: ""; position: absolute; inset: 0;
  /* deep enough to hold white type over a bright product shot */
  background: linear-gradient(180deg, rgba(16,24,32,0.34) 0%, rgba(16,24,32,0.88) 72%);
}
.tile-img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  /* cover fills the tile; it crops but never distorts. contain was letterboxing
     white-background product shots into bright boxes against the dark design. */
  object-fit: cover;
  filter: grayscale(1) contrast(1.06);
  transition: filter var(--slow) var(--ease), transform 700ms var(--ease);
}
/* Colour lifts on hover, but the scrim deepens — contrast is protected. */
.tile:hover .tile-img { filter: grayscale(0) contrast(1); transform: scale(1.04); }
.tile.has-img { background: var(--carbon-deep); }

/* Logo tiles: a transparent brand mark dies under a dark scrim, so these render
   on a light card with dark type instead. Photo tiles keep the scrim. */
.tile.has-logo { background: #f4f1ea; }
.tile.has-logo::before {
  background: repeating-linear-gradient(135deg, rgba(16,24,32,0.035) 0 1px, transparent 1px 13px);
}
.tile.has-logo::after { display: none; }
.tile.has-logo .tile-img {
  object-fit: contain;
  padding: clamp(16px, 2.4vw, 30px);
  background: #f4f1ea;
  filter: none;
}
.tile.has-logo:hover .tile-img { filter: none; transform: scale(1.03); }
.tile.has-logo:hover { background: #fff; }
.tile.has-logo .tile-name { color: #101820; }
.tile.has-logo .tile-meta { color: #3d4753; }
.tile.has-logo .tile-mono { color: rgba(16, 24, 32, 0.34); }
.tile.has-logo .tile-badge { color: var(--gold); background: #101820; }
.tile.has-img:hover::after {
  background: linear-gradient(180deg, rgba(16,24,32,0.44) 0%, rgba(16,24,32,0.95) 78%);
}
/* Placeholder texture — a faint diagonal rule field, never an empty box */
.tile::before {
  content: ""; position: absolute; inset: 0;
  background:
    repeating-linear-gradient(135deg,
      rgba(255,255,255,0.035) 0 1px, transparent 1px 11px);
  pointer-events: none;
}
.tile-mono {
  position: absolute;
  top: clamp(12px, 1.4vw, 18px); left: clamp(14px, 1.6vw, 22px);
  font-family: var(--display);
  font-variation-settings: "wdth" 72, "wght" 850;
  font-size: clamp(1.5rem, 2.6vw, 2.1rem);
  line-height: 1; letter-spacing: -0.03em;
  color: rgba(255, 182, 18, 0.5);
}
.tile-name {
  position: relative; z-index: 2;
  font-family: var(--display);
  font-variation-settings: "wdth" 88, "wght" 760;
  font-size: clamp(0.95rem, 1.15vw, 1.08rem);
  line-height: 1.16; letter-spacing: -0.014em;
  color: var(--white);
  margin-bottom: 7px; text-wrap: balance;
}
.tile-meta {
  position: relative; z-index: 2;
  font-family: var(--mono); font-size: 0.68rem; line-height: 1.5;
  letter-spacing: 0.05em; color: var(--on-dark-dim);
}
.tile-badge {
  position: absolute; top: 0; right: 0; z-index: 3;
  font-family: var(--mono); font-size: 0.6rem; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  background: var(--gold); color: #101820;
  padding: 6px 10px;
}

/* =========================================================================
   5. ANIMATED TIMELINE
   ======================================================================= */
.tl {
  max-width: var(--maxw); margin: 0 auto;
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  /* the ol markers rendered on top of the hand-written 01/02 numerals, which is
     what produced the "1  1  11" double-numbering */
  list-style: none; padding: 0;
  gap: 1px;
  background: var(--rule-dark);
  border: 1px solid var(--rule-dark);
}
.tl-step {
  background: var(--carbon);
  padding: var(--pad-card);
  position: relative; overflow: hidden;
  min-height: clamp(200px, 24vw, 320px);
  display: flex; flex-direction: column;
}
.tl-step::before {
  content: ""; position: absolute; inset: auto 0 0 0; height: 3px;
  background: var(--gold);
  transform: scaleX(0); transform-origin: left;
  transition: transform 620ms var(--ease);
}
.tl-step.in::before { transform: scaleX(1); }
.tl-year {
  font-family: var(--display);
  font-variation-settings: "wdth" 66, "wght" 870;
  font-size: clamp(1.9rem, 3.4vw, 2.9rem);
  line-height: 0.9; letter-spacing: -0.035em;
  color: var(--gold); margin-bottom: 12px;
}
.tl-step h3 {
  font-family: var(--display);
  font-variation-settings: "wdth" 84, "wght" 780;
  font-size: clamp(1rem, 1.4vw, 1.2rem);
  text-transform: uppercase; letter-spacing: -0.02em;
  color: var(--white); margin-bottom: 10px;
}
.tl-step p { color: var(--on-dark-dim); font-size: 0.9rem; line-height: 1.55; margin: 0; }
.tl-rail {
  max-width: var(--maxw); margin: 0 auto clamp(34px, 4vw, 52px);
  display: flex; align-items: center; gap: 0;
}
.tl-rail i {
  flex: 1 1 auto; height: 3px; background: var(--rule-dark);
  position: relative;
}
.tl-rail i::after {
  content: ""; position: absolute; inset: 0;
  background: var(--gold); transform: scaleX(0); transform-origin: left;
  transition: transform 900ms var(--ease);
}
.tl-rail i.in::after { transform: scaleX(1); }
.tl-rail b {
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--gold); flex: 0 0 auto;
  box-shadow: 0 0 0 4px var(--carbon);
}

/* =========================================================================
   6. LIVE CALCULATOR — updates on input, no submit
   ======================================================================= */
.calc-form.is-live .calc-hint::after {
  content: " — updates live";
  color: var(--gold-ink); font-weight: 700;
}
.calc-live-flag {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--mono); font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--gold-ink); margin-bottom: 18px;
}
.calc-live-flag i {
  width: 8px; height: 8px; border-radius: 50%; background: #2f9e44;
  animation: pulse 1.8s ease-in-out infinite;
}

/* =========================================================================
   7. NOT10ROBOTS BAND
   ======================================================================= */
.robots {
  background: var(--gold); color: #101820;
  padding: var(--section-air) var(--gutter);
}
.robots-inner {
  max-width: var(--maxw); margin: 0 auto;
  display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  gap: clamp(24px, 3.6vw, 68px); align-items: center;
}
.robots-mark {
  font-family: var(--display);
  font-variation-settings: "wdth" 76, "wght" 870;
  font-size: clamp(2.4rem, 6.4vw, 5.2rem);
  line-height: 0.9; text-transform: uppercase; letter-spacing: -0.038em;
  margin: 0 0 18px;
}
.robots-tag {
  font-family: var(--mono); font-size: 0.76rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: #101820; margin-bottom: 20px;
}
.robots p {
  font-size: clamp(1.04rem, 1.24vw, 1.18rem); line-height: 1.58;
  color: #101820; max-width: 54ch; margin-bottom: 1em;
}
.robots-btn {
  /* Was a second, drifting copy of .button: 56px tall, 1.6em of side padding,
     0.92rem, wght 780, tracking 0.02. It now carries ONLY what actually makes
     this button different -- its colours and its top margin. Geometry comes
     from .button via the markup (class="button robots-btn"). */
  background: #101820; color: var(--gold);
  border-color: #101820;
  margin-top: var(--s-2);
  transition: transform var(--fast) var(--ease), background var(--fast) var(--ease);
}
.robots-btn:hover { background: #000; transform: translateY(-2px); }
.robots-btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; }
.robots-side {
  border: 2px solid #101820; padding: var(--pad-card);
}
.robots-side h3 {
  font-variation-settings: "wdth" 78, "wght" 850;
  font-size: clamp(1.1rem, 1.8vw, 1.4rem);
  text-transform: uppercase; letter-spacing: -0.024em;
  margin-bottom: 16px;
}
.robots-side li {
  padding: 11px 0 11px 24px; border-bottom: 1px solid rgba(16,24,32,0.22);
  position: relative; font-size: 0.95rem; line-height: 1.45; color: #101820;
}
.robots-side li:last-child { border-bottom: 0; }
.robots-side li::before {
  content: ""; position: absolute; left: 0; top: 19px;
  width: 9px; height: 9px; background: #101820;
}

/* =========================================================================
   8. MARQUEE RIBBON (shared, reusable)
   ======================================================================= */
/* --- Rebuild: the ribbon read as a hairline strip -------------------------
   Three fixes, then a proper editorial rail.

   1. TYPE SIZE. .ribbon-group li had been swept into the --micro list at
      11.04px, overriding the clamp() below, so the sector names rendered as
      smallprint instead of display type. Removed from that list.
   2. THE AMPERSAND. At "wdth" 74 the & was crushed into a shape that read as
      a currency sign (HEALTHCARE ¤ REGULATED). Opened to wdth 88 so the
      ampersand is legible, and moved the real heaviness into weight.
   3. SEPARATOR. A 1px border-right on every item drew a fence of vertical
      hairlines, and the last item in a group drew a line at the loop seam.
      Replaced with a rotated square glyph that is part of the type, so it
      scales with the text and cannot disagree with the rhythm.
   Plus: edge fades so items dissolve at the ribbon's ends rather than being
   sliced by the overflow edge, and real vertical padding so the rail has
   air instead of sitting flush against its rules. */
.ribbon {
  background: var(--gold); color: #101820;
  padding: clamp(18px, 2.1vh, 26px) 0; overflow: hidden;
  border-block: 1px solid rgba(16,24,32,0.28);
  position: relative;
  /* Fade both ends. --ribbon-fade is transparent in the middle so the centre
     of the rail stays fully saturated. */
  -webkit-mask-image: linear-gradient(90deg,
    transparent 0, #000 clamp(28px, 5vw, 76px),
    #000 calc(100% - clamp(28px, 5vw, 76px)), transparent 100%);
  mask-image: linear-gradient(90deg,
    transparent 0, #000 clamp(28px, 5vw, 76px),
    #000 calc(100% - clamp(28px, 5vw, 76px)), transparent 100%);
}
.ribbon-track { display: flex; width: max-content; animation: ribbon-run 52s linear infinite; }
.ribbon:hover .ribbon-track { animation-play-state: paused; }
.ribbon-group { display: flex; align-items: center; }

/* Matched to the footer marquee. The two rails sat a few inches apart on the
   home page and read as different systems: this one was Archivo at wdth 88 on a
   solid gold ground, that one Reeler at 800 outlined in gold. Same job, same
   page, so they are now one treatment -- Reeler, outlined, gold ground. */
.ribbon-group li {
  font-family: var(--heading);
  font-weight: 800;
  font-size: clamp(1.85rem, 4.4vw, 3.6rem);
  line-height: 1.04; text-transform: uppercase;
  letter-spacing: .004em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(16,24,32,.62);
  white-space: nowrap;
  display: flex; align-items: center; gap: clamp(18px, 2.4vw, 40px);
  padding: 0 clamp(18px, 2.4vw, 40px);
}
/* Separator as a typographic glyph, not a border. A rotated square gives a
   diamond that optically matches the uppercase cap height. */
.ribbon-group li::after {
  content: "";
  width: 0.3em; height: 0.3em;
  /* The li is now transparent-with-an-outline, so `currentColor` resolves to
     transparent and the diamond would vanish. It is drawn in ink directly. */
  background: rgba(16,24,32,.62);
  transform: rotate(45deg);
  flex: none;
}
/* =========================================================================
   KEYFRAMES — RESTORED 2026-10-03
   -------------------------------------------------------------------------
   Ten animations were referenced by class rules but their @keyframes blocks
   did not exist. They were lost when the orphaned-rule repair swept the
   cascade, because the keyframes sat inside the same top-level runs as the
   mobile rules that were being re-wrapped. Every affected rule kept its
   `animation:` shorthand, so nothing looked wrong in the CSS or in a parse
   check — the browser just silently ignored each one.

   What that actually cost:
     - entrance animations snapped into place with no motion
     - the scrolling tracks (marquee, rail, fm) stood still
     - three "live" dots and the console caret stopped pulsing
     - the footer wordmark stopped breathing
   Which is the whole of "nothing is moving on the website".

   Declared: ribbon-run, slotPulse. Everything below is restored. The
   dead-reference audit in check-css-parse should now report zero.
   ========================================================================= */

/* --- entrances ---------------------------------------------------------- */
@keyframes ruleDraw {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
@keyframes diag-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
@keyframes log-in {
  from { opacity: 0; transform: translateX(-8px); }
  to   { opacity: 1; transform: none; }
}

/* --- scrolling tracks ---------------------------------------------------
   All three use width:max-content + duplicated groups, so translating by
   -50% lands exactly on the start of the copy: no seam, no blank strip. */
@keyframes marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@keyframes rail {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@keyframes fm {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* --- ambient ------------------------------------------------------------ */
@keyframes blink {
  0%, 50%   { opacity: 1; }
  50.01%, 100% { opacity: 0; }
}
@keyframes pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: .45; transform: scale(.82); }
}
@keyframes pulseDot {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: .55; transform: scale(.86); }
}
/* Was filter: drop-shadow(...) breathing -- both the shadow and the motion.
   Drop-shadows are out per the standing preference, so this now breathes
   opacity and colour only. Same intent, no shadow. */
@keyframes mark-breathe {
  0%, 100% { opacity: .74; color: var(--gold); }
  50%      { opacity: 1;   color: var(--gold-bright, var(--gold)); }
}

/* Motion opt-outs. These were sitting at top level as bare `animation: none`
   declarations, so the header rail and the footer marquee were static at EVERY
   viewport for every visitor -- including people who never asked for reduced
   motion. They belong inside the media query, and only there. */
@media (prefers-reduced-motion: reduce) {
  .marquee-track,
  .rail-track,
  .fm-track { animation: none; }
}

@keyframes ribbon-run {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .ribbon-track { animation: none; }
  .ribbon { -webkit-mask-image: none; mask-image: none; }
}

/* =========================================================================
   8b. FAQ — every answer visible, nothing to open
   ========================================================================= */
.faq-list { border-top: 1px solid var(--rule-dark); }
.faq-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(14px, 2.4vw, 44px);
  padding: clamp(22px, 2.8vw, 34px) 0;
  border-bottom: 1px solid var(--rule-dark);
  transition: background var(--med) var(--ease);
}
.faq-item:hover { background: rgba(255, 182, 18, 0.045); }
.faq-num {
  font-family: var(--mono); font-size: 0.84rem; font-weight: 700;
  letter-spacing: 0.1em; color: var(--gold);
  padding-top: 0.34em; min-width: 2.6ch;
}
.faq-q {
  font-family: var(--display);
  font-variation-settings: "wdth" 84, "wght" 800;
  font-size: clamp(1.16rem, 1.9vw, 1.52rem);
  line-height: 1.14; text-transform: uppercase; letter-spacing: -0.024em;
  color: var(--white); margin-bottom: 12px;
}
.faq-a { color: var(--on-dark-dim); font-size: 1.02rem; line-height: 1.62; max-width: 78ch; margin: 0; }
.faq-a strong { color: var(--white); }

/* =========================================================================
   8c. EVIDENCE BLOCK — always visible, never behind a toggle
   ========================================================================= */
/* Was a 3px gold border-left on a tinted slab -- a side stripe, which the
   craft floor bans above 1px. Replaced with the same top rule the rest of this
   section uses, so the block is separated the way its neighbours are. */
.evidence-block {
  margin-top: clamp(26px, 3.4vw, 44px);
  border-top: 1px solid var(--rule-light);
  padding-top: clamp(20px, 2.6vw, 30px);
}
.evidence-inner { max-width: 76ch; }
.evidence-inner p { color: #38424e; margin-bottom: 0.9em; }
.evidence-inner p:last-child { margin-bottom: 0; }
.evidence-inner strong { color: var(--ink); }
.evidence-inner ul { margin-top: 16px; border-top: 1px solid var(--rule-light); }
.evidence-inner li {
  padding: 11px 0 11px 24px; position: relative;
  border-bottom: 1px solid var(--rule-light);
  font-family: var(--mono); font-size: 0.8rem; letter-spacing: 0.04em;
  color: #38424e;
}
.evidence-inner li::before {
  content: ""; position: absolute; left: 0; top: 19px;
  width: 9px; height: 9px; background: var(--gold-ink);
}
.evidence-inner a { color: var(--gold-ink); border-bottom: 2px solid rgba(122, 82, 0, 0.4); padding-bottom: 2px; }
.evidence-inner a:hover { border-bottom-color: var(--gold-ink); }
.on-dark .evidence-block, .band-dark .evidence-block { background: rgba(255, 182, 18, 0.06); }
.on-dark .evidence-inner p, .on-dark .evidence-inner li { color: var(--on-dark-dim); }
.on-dark .evidence-inner strong { color: var(--white); }
.on-dark .evidence-inner ul, .on-dark .evidence-inner li { border-bottom-color: var(--rule-dark); }
.on-dark .evidence-inner li::before { background: var(--gold); }
.on-dark .evidence-inner a { color: var(--gold); border-bottom-color: rgba(255, 182, 18, 0.4); }

/* =========================================================================
   9. FOOTER — the reason to scroll to the bottom
   ========================================================================= */
.site-footer {
  background: #05080b;
  padding: clamp(48px, 6vw, 90px) var(--gutter) 30px;
  border-top: 3px solid var(--gold);
}
.footer-live {
  max-width: var(--maxw); margin: 0 auto clamp(34px, 4vw, 56px);
  border: 1px solid var(--rule-dark);
  border-top: 2px solid var(--gold);
  background: var(--carbon-deep);
  padding: clamp(16px, 2vw, 24px) clamp(18px, 2.2vw, 28px);
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  gap: clamp(14px, 2vw, 26px); align-items: center;
}
.footer-live-label {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--mono); font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--gold);
  white-space: nowrap;
}
.footer-live-label i {
  width: 8px; height: 8px; border-radius: 50%; background: var(--gold);
  animation: pulse 1.8s ease-in-out infinite;
}
.footer-live-out {
  font-family: var(--mono); font-size: 0.88rem; line-height: 1.6;
  color: var(--white); margin: 0; min-height: 2.6em;
}
.footer-live-out b { color: var(--gold); }
/* =========================================================================
   THE START A BRIEF BUTTON TRAVELS
   -------------------------------------------------------------------------
   There is no decorative pill. The real CTA is the element that moves: it
   lifts out of the flex row, springs to whichever nav item the pointer is
   over, takes on that item's label and href, and springs back to its own
   home on leave. script.js positions it absolutely and pads the nav by its
   width so nothing reflows when it leaves.

   Scoped to a real pointer. Applied unconditionally this overrode the
   existing `.primary-nav a` padding at every width, which pushed the nav
   79px past a 320px viewport. The script refuses to run without
   (hover: hover) and (pointer: fine), so the styling is scoped the same way.
   ========================================================================= */
/* Containing block for the travelling CTA, which is absolutely positioned.

   Scoped to .liquid-live -- the class the script adds at the moment it mounts
   the spring, and removes when it does not. Two earlier attempts keyed this to
   a media query and both were wrong: (hover:hover)/(pointer:fine) is true in
   headless Chromium even under mobile emulation, and a hand-picked min-width
   missed the real breakpoint. Letting the script declare the same condition it
   already tests is the only version that cannot disagree with itself.

   It matters because the mobile drawer translates the nav off-canvas; a
   positioned nav stops inheriting the fixed header's clipping and the overflow
   guard correctly reports live overflow. */
.primary-nav.liquid-live { position: relative; }

@media (hover: hover) and (pointer: fine) {

  .primary-nav > a {
    position: relative;
    /* ABOVE the button -- see the note on `.primary-nav > .liquid-pill`. Words
       and button were both z-index 1 with the button declared later, so the button
       painted over the word it had arrived on and hid it. The word must paint on
       top of the gold for the black label to read. */
    z-index: 2;
    padding: 9px 13px;
    border-radius: 999px;
    /* The nav words are WHITE. Not dim grey. A dimmed word under a gold pill
       reads as disabled rather than as the thing the pill has arrived on, and
       it made the whole row look washed out next to the gold. */
    color: var(--white);
    transition: color 160ms ease;
    /* The travelling button IS the hover affordance. An underline underneath
       doubled the signal and fought the shape in flight. */
    text-decoration: none;
  }

  /* The word the button has flown onto turns BLACK, exactly like the START A
     BRIEF text sitting on the gold at rest. The button covers it, but the word
     is black underneath for the whole approach, so the handoff reads as one
     object arriving on a marked slot rather than a pill sliding over grey
     text. Words with no button on them stay white. */
  .primary-nav > a.is-liquid-target { color: var(--carbon); }
  /* ...but never in OUTLINE mode. The outline button has a transparent fill, so
     the black word showed plainly INSIDE the ring instead of being covered
     (AJ: "the button outline still renders the words but in black and I dont
     want the words in black to render inside the outline button"). The ring is
     drawn over the nav row, so the word underneath stays white. */
  .site-header.is-ghosted .primary-nav > a.is-liquid-target { color: var(--white); }

  /* "Start a brief" is a WORD now, not the button. It stays parked in the row
     for the whole time the effect runs and never travels. The gold button is
     .liquid-pill below. The two were one element until now, which is why the
     label had to be dragged across the header with the button. */
  .primary-nav > a.nav-cta {
    position: relative;
    /* ABOVE the button. This and the pill were both z-index 1, and the pill is
       LATER in the DOM (`a.nav-cta` is child 7, `.liquid-pill` is child 8), so the
       gold button painted ON TOP of this anchor -- it hid the very word it parks
       on, while the other seven anchors (z-index: 2) correctly showed through.
       MEASURED: parked button interior gold=4098px, DARK=60px, ink in only 10 of
       123 columns, so "START A BRIEF" was not legible at all.
       AJ: "the button is still parked in front of the start a brief words". */
    z-index: 2;
    color: var(--white);
  }

  /* The gold button. Absolutely positioned so it can fly without the row
     reflowing, centred on the row's line, and it covers the word underneath
     -- which is why that word goes black. */
  .primary-nav > .liquid-pill {
    position: absolute;
    top: 50%;
    left: 0;
    /* BEHIND the words. Was z-index 2 against the words' z-index 1, so the button
       covered whichever word it landed on (AJ: "in regular mode want the button
       BEHIND the header words"). Now the word sits on top of the gold and reads
       black against it. */
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 40px;
    padding: 9px 13px;
    border-radius: 999px;
    background: var(--gold);
    /* NEVER paint the button's own label.
       The travelling button IS this span -- script.js does
       `const cta = nav.querySelector('.liquid-pill')` and then, on every hover,
       writes the target word's text into it:
           const label = el.textContent.trim(); if (label) cta.textContent = label;
       That text exists so naturalWidth() can measure the target and size the pill
       to match; the parked anchor keeps the real link and its own label.

       MEASURED: the pill has childNodes = 1 and that node is TEXT "Start a brief",
       computed color rgb(16, 24, 32) = carbon. So the button drew its own copy of
       the word in black on top of the real nav word now visible through it from
       behind -- the word appeared TWICE inside the button, once black and once
       white (AJ: "the button still has black words inside it in regular mode and in
       outline mode").

       `transparent` rather than emptying it: the glyphs must keep occupying their
       box or naturalWidth() collapses to zero and the button has nothing to size
       against. Only the paint is removed. What you see inside the button is the nav
       word painting on top of it -- which is the intended effect. */
    color: transparent;
    font-size: 0.78rem;
    font-weight: 700;
    font-variation-settings: "wdth" 92, "wght" 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
    pointer-events: none;
    will-change: transform, width;
  }
  .primary-nav > a:hover,
  .primary-nav > a:focus-visible { text-decoration: none; }

  /* The button covers the item it is standing on, so that label steps aside
     rather than showing through the gold.

     Deliberately NOT pointer-events:none. Taking the item under the cursor
     out of hit-testing makes the browser retarget to whatever is beneath it,
     which fires a mouseleave on the nav and springs the button straight back
     home -- the whole travel lasted about one frame. The button sits on a
     higher z-index and covers the label anyway, so nothing needs to be
     disabled. */
  /* Was `color: transparent`, which cancelled the `var(--carbon)` rule above (same
     specificity, later in the cascade, so it won). Measured: the word under the
     button went INVISIBLE instead of black, so the black-on-gold label AJ asked
     for never appeared. The target word must read BLACK.
     This rule is scoped to SOLID mode: in outline mode the button is a hollow
     gold ring with a transparent fill, and a black word inside it looked wrong --
     there the word stays white (see the .is-ghosted override above). */
  .site-header:not(.is-ghosted) .primary-nav > a.is-liquid-target {
    color: var(--carbon);
  }

  /* The CTA is the traveller. script.js only ever writes `transform`; this is
     what it looks like at rest and in flight. */
  /* superseded: .nav-cta is a parked word now; the flying button is
   .liquid-pill above. */

  /* Outlined when parked, filled in flight: the item the pointer is on reads
     as the current target, and the resting CTA still reads as a call. */
  .primary-nav > .nav-cta:not(.pill-on-cta),
  .primary-nav > .nav-cta:hover,
  .primary-nav > .nav-cta:focus-visible {
    color: var(--carbon);
    background: var(--gold);
  }
}

@media (prefers-reduced-motion: reduce) {
  .primary-nav > .nav-cta { transition: none; }
}

.footer-top {
  /* Was a THREE-column grid. The 2026-10-03 footer redesign makes four
     columns (brand, Explore, Studio, Policies), so the fourth child wrapped
     onto a second row and left a large void beside it. styles.css also
     carries a flex-wrap definition for this selector; components.css loads
     second, so this grid wins. Keeping both is the real hazard here. */
  max-width: var(--maxw); margin: 0 auto; display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1fr;
  column-gap: clamp(24px, 3.4vw, 56px); row-gap: 34px;
  align-items: start;
  padding-bottom: 34px; border-bottom: 1px solid var(--rule-dark);
}
.footer-col h3 {
  font-family: var(--mono); font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 16px;
}
.footer-col a {
  display: block; padding: 7px 0;
  font-size: 0.98rem; color: var(--on-dark-dim);
  transition: color var(--fast) var(--ease), transform var(--fast) var(--ease);
}
.footer-col a:hover { color: var(--gold); transform: translateX(4px); }
.footer-col p { font-size: 0.92rem; color: var(--on-dark-dim); margin: 0 0 10px; }
.footer-wordmark-glow {
  display: inline-block;
  filter: drop-shadow(0 0 18px rgba(255, 182, 18, 0.28));
  animation: mark-breathe 7s ease-in-out infinite;
}
  0%, 100% { filter: drop-shadow(0 0 14px rgba(255,182,18,0.22)); }
@media (max-width: 900px) {
  50% { filter: drop-shadow(0 0 30px rgba(255,182,18,0.46)); }
}

.footer-bottom {
  /* Was minmax(0,1fr) minmax(0,1.3fr) auto -- THREE tracks for a row that
     now has TWO children, after the three-paragraph legal block was
     compressed into one line of fine print. The extra track is why "Back to
     top" was floating in the middle of the footer instead of sitting at the
     right edge. */
  max-width: var(--maxw); margin: 26px auto 0; display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end; column-gap: 28px; row-gap: 18px;
}
.footer-bottom p { font-size: 0.88rem; color: var(--on-dark-dim); margin: 0; max-width: 44ch; }
.footer-bottom p.footer-fine {
  /* .footer-bottom p carries max-width: 44ch, sized for the old short legal
     lines. At 0.72rem mono that measured 310px inside a 1164px grid track, so
     the fine print wrapped to six lines and left a void before "Back to top".
     Widened to a comfortable measure for the single combined paragraph.
     Selector is .footer-bottom p.footer-fine, NOT .footer-fine: the rule it
     has to beat is `.footer-bottom p` at (0,1,1), and a bare .footer-fine is
     only (0,1,0), so the original wins no matter which comes later. */
  max-width: 84ch;
  font-family: var(--mono); font-size: 0.72rem !important;
  line-height: 1.72; letter-spacing: 0.03em; color: var(--on-dark-dim) !important;
}
.back-top {
  font-family: var(--mono); font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold); white-space: nowrap;
}
.footer-cta {
  max-width: var(--maxw); margin: 0 auto clamp(34px, 4vw, 54px);
  display: flex; flex-wrap: wrap; align-items: center; gap: 18px 28px;
  padding-bottom: 30px;
}
.footer-cta h2 {
  font-family: var(--display);
  font-variation-settings: "wdth" 74, "wght" 870;
  font-size: clamp(1.9rem, 4.6vw, 3.4rem);
  line-height: 0.94; text-transform: uppercase; letter-spacing: -0.034em;
  color: var(--white); margin: 0; flex: 1 1 320px;
}

/* =========================================================================
   11. PAGE HEAD — shared interior-page masthead
   ========================================================================= */
.page-head {
  padding: clamp(132px, 16vh, 190px) var(--gutter) clamp(36px, 5vw, 66px);
  background: var(--carbon);
  position: relative; overflow: hidden;
}
.page-head-inner { max-width: var(--maxw); margin: 0 auto; position: relative; z-index: 2; }
.page-eyebrow {
  font-family: var(--mono); font-size: 0.76rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 18px;
  display: flex; align-items: center; gap: 12px;
}
.page-eyebrow::before {
  content: ""; width: 34px; height: 2px; background: var(--gold); flex: 0 0 auto;
}
.page-title {
  font-family: var(--display);
  font-variation-settings: "wdth" 72, "wght" 870;
  font-size: clamp(2.4rem, 7.4vw, 6rem);
  line-height: 0.88; text-transform: uppercase; letter-spacing: -0.038em;
  margin-bottom: 26px; max-width: 18ch; text-wrap: balance;
}
.page-title em { color: var(--gold); }
.page-lede {
  font-size: clamp(1.08rem, 1.4vw, 1.28rem); line-height: 1.55;
  color: var(--on-dark); max-width: 62ch; margin: 0;
}
.page-lede a { color: var(--gold); border-bottom: 2px solid rgba(255,182,18,0.4); }
/* RETIRED 2026-10-03. This rule painted a stray binary debug token
   ("01001111 01110010 01100101 ...", decoding to "OreiinilMMisrOK") as
   visible text across the bottom of EVERY .page-head -- so on all 18
   interior pages. It was injected from here, not from any HTML file, which
   is why a source search for it came back empty and it survived every build.

   It rendered in gold at 14% opacity behind a gradient mask, which is
   precisely why it read as intentional decoration in a thumbnail and was
   only caught by looking at a full-size screenshot and decoding the glyphs.

   Removed rather than restyled: there is no content here worth keeping. */
.primary-nav a[aria-current="page"] { color: var(--gold); }
.primary-nav a[aria-current="page"]::after { transform: scaleX(1); background: var(--gold); }

.band { padding: var(--section) var(--gutter); }
.band-dark { background: var(--carbon); }
.band-deep { background: var(--carbon-deep); }
.band-light { background: var(--paper); color: var(--ink); }
.band-white { background: var(--white); color: var(--ink); }
.band-inner { max-width: var(--maxw); margin: 0 auto; }
.band-head { margin-bottom: clamp(30px, 4vw, 52px); }
.band-head h2 {
  font-family: var(--display);
  font-variation-settings: "wdth" 76, "wght" 860;
  font-size: clamp(1.9rem, 4.6vw, 3.4rem);
  line-height: 0.94; text-transform: uppercase; letter-spacing: -0.032em;
  margin-bottom: 16px; max-width: 22ch; text-wrap: balance;
}
.band-head h2 em { color: var(--gold); }
.band-light .band-head h2 em, .band-white .band-head h2 em { color: var(--gold-ink); }
.band-head p { color: var(--on-dark-dim); max-width: 62ch; font-size: 1.04rem; }
.band-light .band-head p, .band-white .band-head p { color: #38424e; }

/* =========================================================================
   13. HERO SPLIT — statement left, proof rail right
   ========================================================================= */
.hero-lower {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
  gap: clamp(28px, 4vw, 72px);
  align-items: start;
  margin-top: clamp(34px, 5vw, 62px);
  padding-bottom: clamp(60px, 8vw, 120px);
}
.hero-facts {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1px;
  background: var(--rule-dark); border: 1px solid var(--rule-dark);
}
.hero-facts li { background: var(--carbon); padding: clamp(16px, 2vw, 24px); display: flex; flex-direction: column; gap: 8px; }
.hero-facts b {
  font-family: var(--display);
  font-variation-settings: "wdth" 68, "wght" 870;
  font-size: clamp(1.9rem, 3.6vw, 3rem);
  line-height: 0.9; letter-spacing: -0.035em;
  color: var(--gold); font-variant-numeric: tabular-nums;
}
.hero-facts span {
  font-family: var(--mono); font-size: 0.74rem; line-height: 1.55;
  letter-spacing: 0.05em; color: var(--on-dark-dim);
}

/* case media — never stretch */
.case-media { position: relative; min-height: clamp(240px, 30vw, 420px); background: var(--carbon-lift); }
.case-media .tile-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.case-pair .case-media { min-height: clamp(200px, 24vw, 320px); }
.case-media-compact { min-height: clamp(160px, 20vw, 280px); }
.case { border-top: 1px solid var(--rule-dark); padding: clamp(28px, 4vw, 56px) 0; }
.case-pair { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(22px, 3.4vw, 68px); }
.case-pair .case { display: grid; grid-template-columns: 1fr; gap: 20px; }

/* =========================================================================
   14. NARRATIVE CASE STUDIES (work page)
   ========================================================================= */
.narr {
  border-top: 1px solid var(--rule-dark);
  padding: clamp(30px, 4.4vw, 68px) 0;
  /* With the media gone, a two-column grid left half the page empty. The text
     now runs the full measure and the three blocks sit side by side, which is
     what the column was for in the first place. */
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 2.8vw, 48px);
  align-items: start;
}
.narr-head { grid-column: 1 / -1; }
.narr-media { display: none; }
.narr-body {
  grid-column: 1 / -1;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 2.8vw, 48px);
  align-items: start;
}
@media (max-width: 900px) {
  .narr-body { grid-template-columns: minmax(0, 1fr); gap: 22px; }
}

.narr-num {
  font-family: var(--mono); font-size: 0.78rem; font-weight: 700;
  letter-spacing: 0.22em; color: var(--gold); margin-bottom: 16px;
}
.narr-title {
  font-family: var(--display);
  font-variation-settings: "wdth" 76, "wght" 860;
  font-size: clamp(1.9rem, 3.8vw, 3.1rem);
  line-height: 0.94; text-transform: uppercase; letter-spacing: -0.032em;
  color: var(--white); margin-bottom: 16px;
}
.narr-stage {
  margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px;
}
.narr-verdict { margin: 0; }
.narr-media {
  grid-column: 2; grid-row: 1 / span 2;
  position: relative; align-self: start;
  aspect-ratio: 4 / 3; overflow: hidden; background: var(--carbon-deep);
  border: 1px solid var(--rule-dark);
}
.narr-media img {
  width: 100%; height: 100%; object-fit: contain;
  padding: clamp(10px, 1.6vw, 22px);
  background: var(--carbon-deep);
  filter: grayscale(1) contrast(1.06);
  transition: filter var(--slow) var(--ease), transform 800ms var(--ease);
}
.narr:hover .narr-media img { filter: grayscale(0) contrast(1); transform: scale(1.03); }
.narr-media-empty {
  display: flex; align-items: center; justify-content: center;
  background:
    repeating-linear-gradient(135deg, rgba(255,255,255,0.04) 0 1px, transparent 1px 12px),
    var(--carbon);
}
.narr-mono {
  font-family: var(--display);
  font-variation-settings: "wdth" 70, "wght" 850;
  font-size: clamp(3rem, 7vw, 5.4rem); letter-spacing: -0.04em;
  color: rgba(255, 182, 18, 0.42);
}
/* This re-declared display:flex and undid the three-column grid set above --
   same duplicate-class trap as the footer link columns. */
.narr-body { grid-column: 1 / -1; display: grid; gap: clamp(20px, 2.8vw, 48px); }
.narr-block h3 {
  font-family: var(--mono); font-size: 0.76rem; font-weight: 700;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 10px;
}
.narr-block p { color: var(--on-dark-dim); font-size: 1rem; line-height: 1.62; margin: 0; }
.narr-block p strong { color: var(--white); }
.narr-block-scope ul { border-top: 1px solid var(--rule-dark); }
.narr-block-scope li {
  padding: 11px 0 11px 24px; border-bottom: 1px solid var(--rule-dark);
  position: relative; font-size: 0.96rem; color: var(--on-dark);
}
.narr-block-scope li::before {
  content: ""; position: absolute; left: 0; top: 19px;
  width: 9px; height: 9px; background: var(--gold);
}
.narr-note {
  grid-column: 1 / -1;
  font-family: var(--mono); font-size: 0.78rem; line-height: 1.7;
  letter-spacing: 0.04em; color: var(--on-dark-dim);
  border-top: 1px solid var(--rule-dark); padding-top: 18px;
}
.narr-note strong { color: var(--gold); }

/* =========================================================================
   15. FOUNDER + AGENT ROSTER
   ========================================================================= */
.founder {
  display: grid; grid-template-columns: minmax(0, 0.34fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 72px); align-items: start;
}
.portrait-slot {
  position: relative; aspect-ratio: 3 / 4; max-width: 300px;
  border: 1px solid var(--rule-dark);
  background:
    repeating-linear-gradient(135deg, rgba(255,255,255,0.035) 0 1px, transparent 1px 12px),
    var(--carbon-lift);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
}
.portrait-initials {
  font-family: var(--display);
  font-variation-settings: "wdth" 70, "wght" 870;
  font-size: clamp(2.6rem, 5vw, 3.8rem); letter-spacing: -0.04em;
  color: rgba(255, 182, 18, 0.6);
}
.portrait-note {
  font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--on-dark-dim); margin: 0;
}
.founder-name {
  font-family: var(--display);
  font-variation-settings: "wdth" 74, "wght" 870;
  font-size: clamp(2rem, 4.4vw, 3.4rem); line-height: 0.92;
  text-transform: uppercase; letter-spacing: -0.034em;
  color: var(--white); margin-bottom: 8px;
}
.founder-body p { color: var(--on-dark-dim); max-width: 64ch; }
.founder-facts {
  display: flex; flex-wrap: wrap; gap: clamp(20px, 3vw, 48px); margin-top: 30px;
  border-top: 1px solid var(--rule-dark); padding-top: 26px;
}
.founder-facts li { display: flex; flex-direction: column; gap: 6px; }
.founder-facts b {
  font-family: var(--display);
  font-variation-settings: "wdth" 70, "wght" 870;
  font-size: clamp(1.7rem, 3vw, 2.4rem); line-height: 1; letter-spacing: -0.03em;
  color: var(--gold);
}
.founder-facts span {
  font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--on-dark-dim);
}
.agent-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: 0; background: none;
  border-top: 1px solid var(--rule-dark);
  border-left: 1px solid var(--rule-dark);
}
.agent {
  position: relative; background: var(--carbon);
  border-right: 1px solid var(--rule-dark);
  border-bottom: 1px solid var(--rule-dark);
  padding: var(--pad-card);
  transition: background var(--med) var(--ease), box-shadow var(--med) var(--ease);
}
.agent:hover { background: var(--carbon-lift); box-shadow: inset 0 -4px 0 var(--gold); }
.agent-idx {
  position: absolute; top: clamp(14px, 1.8vw, 22px); right: clamp(16px, 2vw, 24px);
  font-family: var(--mono); font-size: 0.68rem; font-weight: 700;
  letter-spacing: 0.16em; color: rgba(255, 182, 18, 0.42);
}
.agent-face {
  aspect-ratio: 1; width: 100%; max-width: 132px; margin-bottom: 18px;
  border: 1px solid var(--rule-gold);
  background: var(--carbon-deep);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.agent-body h3 {
  font-family: var(--display);
  font-variation-settings: "wdth" 84, "wght" 840;
  font-size: 1.28rem; text-transform: uppercase; letter-spacing: -0.024em;
  color: var(--white); margin-bottom: 4px;
}
.agent-role {
  font-family: var(--mono); font-size: 0.72rem; font-weight: 700;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--gold);
  margin-bottom: 12px;
}
.agent-desc { font-size: 0.94rem; line-height: 1.55; color: var(--on-dark-dim); margin: 0; }
/* A.J. leads the roster — same card, no special-casing */
.agent-founder { background: var(--carbon-lift); box-shadow: inset 4px 0 0 var(--gold); }
.agent-founder .agent-face { border-color: var(--gold); }
.agent-founder .agent-desc { color: var(--on-dark); }

/* =========================================================================
   16. CONSOLE FOLLOW-UP — a link, not a button
   ========================================================================= */
.console-follow {
  margin-top: clamp(22px, 3vw, 36px);
  font-family: var(--mono); font-size: 0.84rem; letter-spacing: 0.04em;
  color: var(--on-dark-dim);
}
.console-follow a {
  color: var(--gold); border-bottom: 2px solid rgba(255, 182, 18, 0.4);
  padding-bottom: 2px; transition: border-color var(--fast) var(--ease);
}
.console-follow a:hover { border-bottom-color: var(--gold); }
.roster-footnote {
  margin-top: clamp(24px, 3vw, 38px);
  font-family: var(--mono); font-size: 0.78rem; line-height: 1.7;
  color: var(--on-dark-faint); max-width: 72ch;
}
.ledger { margin-top: clamp(40px, 5vw, 80px); }
.ledger-head { margin-bottom: clamp(22px, 3vw, 38px); }
.ledger-head h3 {
  font-family: var(--display);
  font-variation-settings: "wdth" 80, "wght" 850;
  font-size: clamp(1.5rem, 3vw, 2.3rem);
  text-transform: uppercase; letter-spacing: -0.028em;
  color: var(--white); margin-bottom: 12px;
}
.ledger-head p { color: var(--on-dark-dim); max-width: 64ch; }
/* These are long-form agreement summaries, not headlines. 320px columns made
   them an unreadable block of text; two wider columns suit the copy. */
.ledger-rows {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px; background: var(--rule-dark);
  border-top: 1px solid var(--rule-dark);
}
.ledger-rows article { padding: var(--pad-card); }
.ledger-rows article h4 { margin-bottom: 10px; }
.ledger-rows article p { font-size: .95rem; line-height: 1.62; }
.ledger-rows article .ledger-tag { margin-top: 14px; } .ledger-rows { grid-template-columns: minmax(0, 1fr); }
.ledger-rows article {
  background: var(--carbon);
  padding: var(--pad-card);
}
.ledger-badge {
  display: inline-block;
  font-family: var(--mono); font-size: 0.66rem; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase;
  background: var(--gold); color: #101820; padding: 5px 10px; margin-bottom: 14px;
}
.ledger-rows h4 {
  font-family: var(--display);
  font-variation-settings: "wdth" 84, "wght" 820;
  font-size: 1.2rem; text-transform: uppercase; letter-spacing: -0.022em;
  color: var(--white); margin-bottom: 10px;
}
.ledger-rows p { font-size: 0.93rem; line-height: 1.55; color: var(--on-dark-dim); margin: 0 0 10px; }
.ledger-tag {
  font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.08em;
  color: var(--gold); margin: 0;
}


/* =========================================================================
   17. FLOW — connective tissue between sections
   A hard colour cut reads as a new page, not a new section. These seams,
   the running section index, and the dead-space trims keep the scroll moving.
   ========================================================================= */

/* Running section index — the eye always knows where it is */
.sec-index {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--mono); font-size: 0.76rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 18px;
}
.sec-index::after {
  content: ""; flex: 1 1 auto; height: 1px;
  background: linear-gradient(90deg, rgba(255,182,18,0.5), transparent);
  max-width: 220px;
}
.robots-tag span[aria-hidden] { color: #101820; opacity: 0.55; }

/* Seams: a hairline + a short gold tick instead of a bare colour change */
main > section + section { position: relative; }
.band-light::before, .band-white::before,
.robots::before {
  content: ""; position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 72px; height: 4px; background: #101820;
}

/* Section rhythm: every seam is now a real change of surface, so the scroll
   never runs two identical backgrounds together. */
.proof { background: var(--carbon-deep); }
.band-light.on-prod { background: var(--carbon); }
        /* band-head defaults to white — on paper that is invisible */

/* Trim the dead gap the method section was leaving behind */
.method { padding-bottom: var(--section-deep); }
.proof { padding-top: var(--section-deep); }

/* =========================================================================
   18. PRODUCTION — real archive artifacts
   ========================================================================= */
.prod-grid {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 1px;
  background: var(--rule-dark);
  border: 1px solid var(--rule-dark);
}
.prod-shot {
  grid-column: span 2;
  background: var(--white);
  margin: 0;
  display: flex; flex-direction: column;
  transition: background var(--med) var(--ease), box-shadow var(--med) var(--ease);
}
.prod-shot-wide { grid-column: span 4; }
.prod-shot:hover { background: #fff; box-shadow: inset 0 -4px 0 var(--gold); }
.prod-shot img {
  width: 100%; height: 100%; display: block;
  aspect-ratio: 1;                              /* most of this art is square */
  object-fit: contain;                          /* never crop, never stretch */
  /* A distinct surface: three of the four artifacts are white artwork, and on a
     near-white backdrop they vanished. This is darker than the artwork. */
  background: #d9d4ca;
  padding: clamp(14px, 2vw, 26px);
}
.prod-shot-wide img { aspect-ratio: 4 / 3; }
/* white artwork still needs an edge to read against the surface */
.prod-shot img { box-shadow: inset 0 0 0 1px rgba(16,24,32,0.10); }
.prod-shot figcaption {
  padding: clamp(14px, 1.8vw, 22px);
  display: flex; flex-direction: column; gap: 6px;
  border-top: 1px solid var(--rule-light);
}
.prod-shot figcaption b {
  font-family: var(--display);
  font-variation-settings: "wdth" 84, "wght" 820;
  font-size: 1.06rem; text-transform: uppercase; letter-spacing: -0.022em;
  color: var(--ink);
}
.prod-shot figcaption span {
  font-family: var(--mono); font-size: 0.76rem; line-height: 1.5;
  letter-spacing: 0.05em; color: #3d4753;
}
.prod-note {
  margin-top: clamp(22px, 2.6vw, 34px);
  font-family: var(--mono); font-size: 0.8rem; line-height: 1.7;
  color: #3d4753; max-width: 78ch;
}

/* 3-up proof grid fills its row instead of leaving a dead cell */
.tile-grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

/* ribbon sits on light now — it needs its own dark neighbours on both sides */
@media (max-width: 900px) {
  .prod-shot, .prod-shot-wide { grid-column: span 3; }
  .tile-grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .prod-grid { grid-template-columns: 1fr; }
  .prod-shot, .prod-shot-wide { grid-column: span 1; }
  .tile-grid-3 { grid-template-columns: 1fr; }
}



/* =========================================================================
   19. ONE CARD ANATOMY — site-wide
   Image on top, text in a band beneath. Text is NEVER overlaid on imagery.
   This is the single pattern the homepage, clients page and case studies share.
   ========================================================================= */
.showcase {
  display: grid; gap: 0; background: none;
  border-top: 1px solid var(--rule-dark);
  border-left: 1px solid var(--rule-dark);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
}
.showcase-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.card {
  position: relative; background: var(--carbon);
  border-right: 1px solid var(--rule-dark);
  border-bottom: 1px solid var(--rule-dark);
  display: flex; flex-direction: column;
  transition: background var(--med) var(--ease), box-shadow var(--med) var(--ease);
}
.card:hover { background: var(--carbon-lift); box-shadow: inset 0 -4px 0 var(--gold); }
.card-media {
  position: relative; overflow: hidden;
  background: #0b0f14;                    /* sits behind the artwork */
  aspect-ratio: 4 / 3;
}
.card-media img {
  width: 100%; height: 100%;
  object-fit: contain;                     /* never crop a client's work */
  padding: clamp(12px, 1.6vw, 24px);
  filter: grayscale(1) contrast(1.04);
  transition: filter var(--slow) var(--ease), transform 700ms var(--ease);
}
.card:hover .card-media img { filter: grayscale(0) contrast(1); transform: scale(1.03); }
.card-body {
  padding: clamp(16px, 2vw, 24px);
  border-top: 1px solid var(--rule-dark);
  display: flex; flex-direction: column; gap: 7px; flex: 1;
}
.card-kicker {
  font-family: var(--mono); font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--gold); margin: 0;
}
.card-title {
  font-family: var(--display);
  font-variation-settings: "wdth" 86, "wght" 800;
  font-size: clamp(1.02rem, 1.25vw, 1.2rem);
  line-height: 1.14; text-transform: uppercase; letter-spacing: -0.024em;
  color: var(--white); margin: 0;
}
.card-meta {
  font-size: 0.88rem; line-height: 1.5; color: var(--on-dark-dim); margin: 0;
}
.card-badge {
  position: absolute; top: 0; right: 0; z-index: 3;
  font-family: var(--mono); font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  background: var(--gold); color: #101820; padding: 6px 11px;
}

/* =========================================================================
   20. ROSTER — a clean typed list beats a grid of fake tiles
   ========================================================================= */
.roster-block { margin-top: clamp(44px, 5.4vw, 76px); }
.roster-block .roster-head { margin-bottom: clamp(18px, 2.4vw, 30px); }
.roster-head h3 {
  font-family: var(--display);
  font-variation-settings: "wdth" 80, "wght" 850;
  font-size: clamp(1.4rem, 2.6vw, 2.1rem);
  text-transform: uppercase; letter-spacing: -0.028em;
  color: var(--white); margin-bottom: 10px;
}
.roster-head p { color: var(--on-dark-dim); max-width: 66ch; font-size: 0.98rem; }
.roster { display: block; border-top: 1px solid var(--rule-dark); }
.roster-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr) auto;
  gap: clamp(12px, 2vw, 28px); align-items: baseline;
  padding: 14px 0; border-bottom: 1px solid var(--rule-dark);
  transition: background var(--fast) var(--ease);
}
.roster-row:hover { background: rgba(255, 182, 18, 0.04); }
.roster-name {
  font-family: var(--display);
  font-variation-settings: "wdth" 90, "wght" 760;
  font-size: clamp(0.98rem, 1.15vw, 1.1rem);
  letter-spacing: -0.012em; color: var(--white);
}
.roster-sector { font-size: 0.88rem; line-height: 1.45; color: var(--on-dark-dim); }
.roster-tag {
  font-family: var(--mono); font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.13em; text-transform: uppercase;
  border: 1px solid var(--rule-gold); color: var(--gold);
  padding: 5px 9px; white-space: nowrap;
}
.roster-row:has(.roster-tag) .roster-name { color: var(--gold); }
@media (max-width: 900px) {
  .showcase-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .roster-row { grid-template-columns: minmax(0, 1fr) auto; }
  .roster-sector { grid-column: 1 / -1; order: 3; }
  .showcase-3, .showcase { grid-template-columns: 1fr; }
  .bento-wide, .bento-narrow { grid-column: span 6; }
  .bento-third { grid-column: span 6; }
  .tl { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .robots-inner { grid-template-columns: 1fr; }
  .footer-top { grid-template-columns: 1fr 1fr; } .hero-lower { grid-template-columns: 1fr; }
  .footer-live { grid-template-columns: 1fr; gap: 12px; }
  .footer-bottom { grid-template-columns: 1fr; }
  .back-top { justify-self: start; }
  .narr { grid-template-columns: 1fr; }
  .narr-media { grid-column: 1; grid-row: auto; }
  .narr-head, .narr-body, .narr-note { grid-column: 1; }
  .founder { grid-template-columns: 1fr; }
  .bento-wide, .bento-narrow, .bento-third, .bento-half { grid-column: span 12; }
  .tl { grid-template-columns: 1fr; }
  .footer-top { grid-template-columns: 1fr; }
  .tile-grid { grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr)); }
  .case-pair { grid-template-columns: 1fr; }
  .page-title { font-size: clamp(2.2rem, 12vw, 3rem); }
  .tl-step { min-height: 0; }
  .footer-live-out { font-size: 0.8rem; }
    .hero-facts { grid-template-columns: 1fr; }
  .faq-item { grid-template-columns: 1fr; gap: 8px; }
}

@media (prefers-reduced-motion: reduce) {
  .footer-live-label i, .calc-live-flag i, .console-live i { animation: none; }
  .footer-wordmark-glow { animation: none; }
  .ribbon-track { animation: none; }
  .tl-step::before { transform: scaleX(1); }
  .tl-rail i::after { transform: scaleX(1); }
}



/* =========================================================================
   BUILDER — a la carte scope
   ========================================================================= */
.builder { background: var(--carbon); padding: var(--section) var(--gutter); }
.builder-inner { max-width: var(--maxw); margin: 0 auto; }
.builder-head { max-width: 68ch; margin-bottom: clamp(34px, 4.4vw, 60px); }
.builder-head h2 {
  font-family: var(--display);
  font-variation-settings: "wdth" 80, "wght" 850;
  font-size: clamp(2rem, 4.4vw, 3.6rem); line-height: 0.98;
  text-transform: uppercase; letter-spacing: -0.032em; color: var(--white); margin-bottom: 16px;
}
.builder-head h2 em { font-style: normal; color: var(--gold); }
.builder-head > p { color: var(--on-dark-dim); font-size: 1.02rem; line-height: 1.66; }

.builder-body {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 380px);
  gap: clamp(24px, 3.4vw, 52px); align-items: start;
}
.cat + .cat { margin-top: clamp(30px, 3.6vw, 48px); }
.cat-head { margin-bottom: 16px; padding-bottom: 12px; border-bottom: 1px solid var(--rule-dark); }
.cat-name {
  font-family: var(--display);
  font-variation-settings: "wdth" 84, "wght" 840;
  font-size: clamp(1.18rem, 1.7vw, 1.55rem); text-transform: uppercase;
  letter-spacing: -0.026em; color: var(--white); margin-bottom: 5px;
}
.cat-blurb { font-family: var(--mono); font-size: 0.78rem; line-height: 1.55;
             letter-spacing: 0.03em; color: var(--on-dark-dim); margin: 0; }
.cat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); gap: 10px; }

.svc {
  position: relative; text-align: left; cursor: pointer;
  background: var(--carbon-lift); color: inherit;
  border: 1px solid var(--rule-dark);
  padding: 16px 18px 16px 46px;
  display: flex; gap: 0;
  font: inherit; color: inherit;
  transition: border-color var(--fast) var(--ease), background var(--fast) var(--ease);
}
.svc:hover { border-color: var(--gold); background: #16212c; }
.svc:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.svc-check {
  position: absolute; left: 17px; top: 18px;
  width: 15px; height: 15px; border: 1px solid var(--rule-gold); background: transparent;
  transition: background var(--fast) var(--ease), border-color var(--fast) var(--ease);
}
.svc[aria-pressed="true"] { border-color: var(--gold); background: rgba(255,182,18,0.07); }
.svc[aria-pressed="true"] .svc-check { background: var(--gold); border-color: var(--gold); }
.svc[aria-pressed="true"] .svc-check::after {
  content: ""; position: absolute; left: 4px; top: 1px;
  width: 4px; height: 8px; border: solid #101820;
  border-width: 0 2px 2px 0; transform: rotate(45deg);
}
.svc-body { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.svc-name {
  font-family: var(--display);
  font-variation-settings: "wdth" 88, "wght" 790;
  font-size: 1.01rem; line-height: 1.16; text-transform: uppercase;
  letter-spacing: -0.02em; color: var(--white);
}
.svc-desc { font-size: 0.855rem; line-height: 1.5; color: var(--on-dark-dim); }
.svc-meta { font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.06em; color: #7c8896; }
.svc-meta b { color: var(--gold); font-weight: 700; }

/* The scope rail follows the reader down the whole builder.
   `align-self: start` is REQUIRED: as a grid item the cart defaults to
   align-self:auto, which stretches it to the full 2843px row height. A sticky
   box taller than the viewport cannot stick -- it just scrolls away (measured:
   cartTop fell to -1893px, off-screen by 25% of the way down). Pinning the item
   to its own content height is what makes sticky work. `top` clears the fixed
   header. max-height + overflow keeps a long scope scrollable inside the box
   instead of running off the bottom of the screen. */
.builder-cart {
  position: sticky;
  top: 104px;
  align-self: start;
  max-height: calc(100vh - 128px);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: rgba(255,182,18,0.42) transparent;
}
.builder-cart::-webkit-scrollbar { width: 8px; }
.builder-cart::-webkit-scrollbar-track { background: transparent; }
.builder-cart::-webkit-scrollbar-thumb { background: rgba(255,182,18,0.42); }
.cart-inner {
  background: var(--carbon-deep); border: 1px solid var(--rule-dark);
  padding: var(--pad-card);
}
.cart-inner h3 {
  font-family: var(--display);
  font-variation-settings: "wdth" 82, "wght" 850;
  font-size: 1.1rem; text-transform: uppercase; letter-spacing: -0.024em;
  color: var(--white); margin-bottom: 14px;
}
.cart-empty { font-size: 0.85rem; color: #7c8896; line-height: 1.5; margin-bottom: 14px; }
.cart-list { list-style: none; margin: 0 0 16px; padding: 0;
             max-height: 230px; overflow-y: auto; }
.cart-list:empty { display: none; }
.cart-item {
  display: flex; align-items: baseline; gap: 8px;
  padding: 7px 0; border-bottom: 1px solid var(--rule-dark);
  font-size: 0.855rem; color: var(--on-dark-dim); line-height: 1.35;
}
.cart-item span { flex: 1; min-width: 0; }
.cart-item b { font-family: var(--mono); font-size: 0.78rem; color: var(--white); white-space: nowrap; }
.cart-item button {
  background: none; border: 0; color: #7c8896; cursor: pointer;
  font-size: 1.05rem; line-height: 1; padding: 0 2px; flex-shrink: 0;
}
.cart-item button:hover { color: var(--gold); }
.cart-totals { border-top: 1px solid var(--gold); padding-top: 12px; }
.cart-row { display: flex; justify-content: space-between; align-items: baseline;
            padding: 3px 0; font-family: var(--mono); font-size: 0.78rem; color: #7c8896; }
.cart-row b { color: var(--white); }
.cart-row-total { margin-top: 6px; padding-top: 9px; border-top: 1px solid var(--rule-dark); }
.cart-row-total span, .cart-row-total b { color: var(--gold); font-size: 0.86rem; font-weight: 700; }
.cart-note { font-size: 0.74rem; line-height: 1.55; color: #6b7784; margin: 12px 0 0; }
.cart-match { margin-top: 14px; padding: 12px; background: rgba(255,182,18,0.08);
              border-left: 1px solid var(--gold); }
.cart-match-label { font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.14em;
                    text-transform: uppercase; color: var(--gold); margin: 0 0 5px; }
.cart-match-name { font-family: var(--display);
  font-variation-settings: "wdth" 86, "wght" 840; font-size: 1.02rem;
  text-transform: uppercase; letter-spacing: -0.02em; color: var(--white); margin: 0 0 5px; }
.cart-match-why { font-size: 0.78rem; line-height: 1.5; color: var(--on-dark-dim); margin: 0; }
.cart-cta { display: block; width: 100%; margin-top: 16px; text-align: center; }
.cart-clear { display: block; width: 100%; margin-top: 9px; background: none; border: 0;
              color: #6b7784; font-family: var(--mono); font-size: 0.72rem;
              letter-spacing: 0.1em; text-transform: uppercase; cursor: pointer; padding: 5px; }
.cart-clear:hover { color: var(--gold); }
@media (max-width: 900px) {
  .builder-body { grid-template-columns: 1fr; }
  .builder-cart { position: static; }
}


.agent-face { background: var(--carbon-deep); border: 1px solid var(--rule-dark); overflow: hidden; }
.agent-face img { width: 100%; height: 100%; object-fit: cover; display: block; aspect-ratio: 1; }
.portrait-slot img, .portrait-slot .agent-face img { width: 100%; height: 100%; object-fit: cover; }

.roster-row { grid-template-columns: minmax(0,1.5fr) minmax(0,1.2fr) minmax(0,1fr) 5.4rem 6.6rem; }
.roster-cat  { font-size: .84rem; line-height: 1.45; color: var(--on-dark-dim); }
.roster-loc  { font-family: var(--mono); font-size: .7rem; line-height: 1.4; letter-spacing: .03em; color: #7c8896; }
.roster-year { font-family: var(--mono); font-size: .72rem; letter-spacing: .06em; color: var(--gold); white-space: nowrap; }
.roster-cols { display: grid; grid-template-columns: minmax(0,1.5fr) minmax(0,1.2fr) minmax(0,1fr) 5.4rem 6.6rem;
  gap: 14px 22px; margin-bottom: 6px; padding-bottom: 8px; border-bottom: 1px solid var(--gold); }
.roster-collabel { font-family: var(--mono); font-size: .64rem; letter-spacing: .14em;
  text-transform: uppercase; color: #6b7784; }
@media (max-width: 900px) {
  .roster-row { grid-template-columns: minmax(0,1fr) auto auto; }
  .roster-cat { grid-column: 1 / -1; order: 3; }
  .roster-loc { order: 2; }
  .roster-cols { display: none; }
}


/* =========================================================================
   HEADER + FOOTER — the frame around every page
   ========================================================================= */
.header-rail {
  /* Was a solid gold bar. With the track switched to the footer marquee's
     transparent-fill + gold text-stroke treatment, gold text on a gold bar
     left the category labels completely invisible -- only the separator
     diamonds showed. Carbon behind the stroked gold is what makes them read,
     and it is what the footer marquee already sits on. */
  position: fixed; top: 0; left: 0; right: 0; z-index: 60;
  height: 28px;
  background: var(--carbon-deep);
  border-bottom: 1px solid rgba(255, 182, 18, .26);
  overflow: hidden;
  display: flex; align-items: center;
}
.rail-track {
  /* Was mono 11px on a solid gold bar. AJ asked for this strip to match the
     footer marquee -- the "messy" one -- in style and colour, so it now uses
     the same language: Reeler, uppercase, transparent fill with a gold
     text-stroke over carbon. The bar keeps its own scale, because a 28px
     strip cannot carry the footer's 5.2rem type, but everything else is
     shared. */
  width: max-content;
  display: flex; align-items: center; gap: 0; white-space: nowrap;
  font-family: var(--heading);
  font-weight: 800;
  font-size: 13px;
  text-transform: uppercase; letter-spacing: .12em;
  color: transparent;
  -webkit-text-stroke: 1px rgba(255, 182, 18, .62);
  animation: rail 38s linear infinite;
}
.rail-track > * { flex-shrink: 0; }
.rail-track i { -webkit-text-stroke: 0; color: var(--gold); font-size: .42em; }
.rail-track > * { flex-shrink: 0; }
.rail-group { display: flex; align-items: center; gap: 22px; padding-right: 22px; }
.rail-track i { width: 4px; height: 4px; background: #101820; border-radius: 50%; flex: none; }

.site-header { top: 28px !important; }
.site-header.scrolled { box-shadow: 0 1px 0 var(--rule-dark), 0 18px 40px -28px rgba(0,0,0,.9); }

/* .brand was a column stack to sit the "AI · Marketing · Commerce" strapline
   under the wordmark. That strapline is gone from every page, so this is now
   a single inline child -- the column/gap was dead weight and added 5px of
   phantom height to the header. */
.brand { display: flex; align-items: center; }

.primary-nav a {
  position: relative; padding: 6px 2px;
  transition: color var(--fast) var(--ease);
}
.primary-nav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px;
  height: 1px; background: var(--gold);
  transform: scaleX(0); transform-origin: left; transition: transform var(--med) var(--ease);
}
.primary-nav a:hover::after, .primary-nav a:focus-visible::after,
.primary-nav a[aria-current]::after { transform: scaleX(1); }
.primary-nav a[aria-current] { color: var(--white); }
.primary-nav a:hover { color: var(--white); }

.nav-cta { transition: transform var(--fast) var(--ease), box-shadow var(--fast) var(--ease); }
.nav-cta:hover { transform: translateY(-1px); box-shadow: 0 8px 22px -8px rgba(255,182,18,.7); }

.footer-marquee {
  /* Full-bleed. .site-footer carries horizontal padding, so the marquee used
     to be inset by the gutter on both sides -- it stopped short of the screen
     edges while the text inside it was sized off the viewport. Pull it back
     out with negative margins equal to the footer gutter. */
  margin-left: calc(var(--gutter) * -1);
  margin-right: calc(var(--gutter) * -1);
  border-top: 1px solid var(--rule-dark); border-bottom: 1px solid var(--rule-dark);
  /* overflow-x:hidden alone still let the animated track add ~21px to the
     document scroll box on some pages. contain:paint makes the clip a hard
     boundary so the marquee can never widen the page. */
  overflow: hidden; contain: paint;
  padding: clamp(10px, 1.4vw, 18px) 0; margin-bottom: clamp(34px, 5vw, 70px);
}
.fm-track {
  /* width:max-content + non-shrinking children stops flex from SQUEEZING the
     four repeats to fit the content column. They measured 1296px inside a
     1440px viewport, i.e. narrower than the screen, so the -50% loop exposed a
     blank strip on every cycle. */
  width: max-content;
  display: flex; align-items: center; gap: 30px; white-space: nowrap;
  /* Reeler, per request. Reeler is NOT a variable font, so the old
     font-variation-settings axes ("wdth" 72, "wght" 880) are inert here and
     are replaced by font-weight. letter-spacing goes positive because Reeler
     is narrower and set tight it closes up at display size. */
  font-family: var(--heading);
  font-weight: 800;
  font-size: clamp(2.1rem, 6.4vw, 5.2rem); line-height: 1;
  text-transform: uppercase; letter-spacing: .004em; color: transparent;
  -webkit-text-stroke: 1px rgba(255,182,18,.45);
  animation: fm 44s linear infinite;
}
.fm-track > * { flex-shrink: 0; }
.fm-group { display: flex; align-items: center; gap: 30px; }
.fm-track i { -webkit-text-stroke: 0; color: var(--gold); font-size: .34em; }
@media (max-width: 900px) {
  .brand-tag { display: none; }
  .site-header { padding-left: 16px; padding-right: 16px; }
  .brand .ol-wordmark { max-width: 132px; }
  .site-header { padding-left: 12px; padding-right: 12px; gap: 10px; }
  .brand .ol-wordmark { max-width: 116px; }
  .menu-toggle { padding: 9px 12px; font-size: .72rem; letter-spacing: .12em; }
}



/* The range inputs were 8px tall because the visible rail carried the height
   and the input itself was collapsed. Give the input a real 28px hit area and
   let the rail render inside it. */
.calc-range, .roi-range, input[type="range"], .slider-field input[type="range"] {
  -webkit-appearance: none; appearance: none;
  background: transparent;
  height: 30px; padding: 0; margin: 0;
  cursor: pointer;
}
.slider-field input[type="range"]::-webkit-slider-runnable-track { height: 4px; background: var(--rule-dark); }
.slider-field input[type="range"]::-moz-range-track { height: 4px; background: var(--rule-dark); }
input[type="range"]::-webkit-slider-runnable-track { height: 4px; background: var(--rule-dark); }
input[type="range"]::-moz-range-track { height: 4px; background: var(--rule-dark); }
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 20px; height: 20px; margin-top: -8px;
  background: var(--gold); border: 0; border-radius: 0;
}
input[type="range"]::-moz-range-thumb {
  width: 20px; height: 20px; background: var(--gold); border: 0; border-radius: 0;
}
input[type="range"]:focus-visible { outline: 2px solid var(--gold); outline-offset: 4px; }

.back-top { min-height: 44px; display: inline-flex; align-items: center; }
/* keep every footer link a comfortable target.
   This must NOT set display:inline-block -- it has the same specificity as
   .footer-col a and came later in the file, so it overrode display:block and
   collapsed the link columns into "ServicesMethodWorkResults". */
.site-footer a { padding: 5px 0; }
.footer-col a { display: block; }

/* section heading for the five-phase timeline */
.tl-h {
  font-family: var(--mono); font-size: .72rem; font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase; color: var(--gold);
  margin: clamp(28px, 4vw, 48px) 0 18px;
}

.faq-h {
  font-family: var(--mono); font-size: .72rem; font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase; color: var(--gold);
  margin: clamp(26px, 3.6vw, 44px) 0 20px;
}

.scope-receipt {
  background: var(--carbon-deep); border: 1px solid var(--gold);
  border-left-width: 3px; padding: 20px 22px; margin-bottom: 22px;
}
.scope-receipt-label {
  font-family: var(--mono); font-size: .68rem; font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase; color: var(--gold); margin: 0 0 12px;
}
.scope-receipt ul { list-style: none; margin: 0 0 12px; padding: 0; }
.scope-receipt li {
  font-size: .92rem; line-height: 1.5; color: var(--white);
  padding: 5px 0; border-bottom: 1px solid var(--rule-dark);
}
.scope-receipt li:last-child { border-bottom: 0; }
.scope-receipt-total {
  font-family: var(--mono); font-size: .82rem; letter-spacing: .04em;
  color: var(--gold); margin: 0; font-weight: 700;
}

/* phase 05 takes the full width, then the two proof stats get their own band --
   packing 1 + 2 + 2 into a four-column grid left three dead cells. */
.tl-last { grid-template-columns: minmax(0, 1fr); }
.tl-proof {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px; background: var(--rule-dark);
  border-top: 1px solid var(--gold); margin-top: 1px;
}
.tl-proof-item {
  background: var(--carbon); padding: clamp(20px, 2.6vw, 32px);
  display: flex; flex-direction: column; gap: 8px;
}
.tl-proof-item .tl-year { font-size: clamp(2.4rem, 5vw, 4rem); margin: 0; }
.tl-proof-item h3 {
  font-family: var(--display);
  font-variation-settings: "wdth" 86, "wght" 820;
  font-size: clamp(1.05rem, 1.5vw, 1.3rem); text-transform: uppercase;
  letter-spacing: -.022em; color: var(--white); margin: 0;
}
.tl-proof-item p:last-child { font-size: .93rem; line-height: 1.6; color: var(--on-dark-dim); margin: 0; } .tl-proof { grid-template-columns: minmax(0, 1fr); }

/* A missing image used to render a lone monogram, which read as a broken image.
   Where there is no photograph, show the proof itself. */
.narr-media-empty {
  background: var(--carbon-deep); border: 1px solid var(--gold);
  display: flex; flex-direction: column; justify-content: center; gap: 16px;
  padding: clamp(26px, 3.6vw, 48px); text-align: left; aspect-ratio: auto; min-height: 0;
}
.narr-mono-label {
  font-family: var(--mono); font-size: .66rem; font-weight: 700; letter-spacing: .2em;
  text-transform: uppercase; color: var(--gold); margin: 0;
}
.narr-quote {
  font-family: var(--display);
  font-variation-settings: "wdth" 80, "wght" 800;
  font-size: clamp(1.3rem, 2.4vw, 2rem); line-height: 1.16; letter-spacing: -.024em;
  color: var(--white); margin: 0; border: 0; padding: 0;
}
.narr-quote strong { color: var(--gold); font-weight: inherit; }
.narr-mono-note {
  font-family: var(--mono); font-size: .7rem; letter-spacing: .08em;
  color: #7c8896; margin: 0;
}

/* =========================================================================
   INDUSTRIES
   ========================================================================= */
.ind-stack { display: flex; flex-direction: column; gap: 1px; background: var(--rule-light); border: 1px solid var(--rule-light); }
.ind { background: #fff; padding: clamp(24px, 3.2vw, 44px); }
.ind-head { max-width: 62ch; margin-bottom: clamp(18px, 2.4vw, 30px); }
.ind-head h2 {
  font-family: var(--display);
  font-variation-settings: "wdth" 82, "wght" 850;
  font-size: clamp(1.5rem, 3vw, 2.2rem); text-transform: uppercase;
  letter-spacing: -.03em; color: var(--carbon); margin-bottom: 10px;
}
.ind-lede { font-size: 1rem; line-height: 1.6; color: var(--on-light-dim); margin: 0; }
.ind-grid { display: grid; grid-template-columns: minmax(0,.9fr) minmax(0,1.3fr) minmax(0,.9fr); gap: clamp(20px, 3vw, 44px); }
.ind-col-wide { border-left: 1px solid var(--rule-light); border-right: 1px solid var(--rule-light); padding: 0 clamp(20px, 2.6vw, 36px); }
.ind-label {
  font-family: var(--mono); font-size: var(--micro, .69rem); font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--gold); margin: 0 0 12px;
  /* the three columns of a sector are read as a set; a one-line vs two-line
     label offset the whole column against its neighbours */
  min-height: 1.2em;
}
.ind-col { display: flex; flex-direction: column; }
.ind-col .ind-body, .ind-col ul { flex: 1; }
.ind-proof, .ind-scope { list-style: none; margin: 0; padding: 0; }
.ind-proof li, .ind-scope li {
  font-size: .9rem; line-height: 1.5; padding: 7px 0;
  border-bottom: 1px solid var(--rule-light); color: var(--on-light-dim);
}
.ind-scope li { color: var(--carbon); }
.ind-body { font-size: .96rem; line-height: 1.68; color: var(--on-light-dim); margin: 0; }
.ind-cta {
  margin-top: clamp(40px, 5vw, 76px); padding: clamp(26px, 3.4vw, 46px);
  background: var(--carbon); text-align: center;
}
.ind-cta h2 {
  font-family: var(--display); font-variation-settings: "wdth" 80, "wght" 850;
  font-size: clamp(1.6rem, 3.2vw, 2.4rem); text-transform: uppercase;
  letter-spacing: -.03em; color: var(--white); margin-bottom: 12px;
}
.ind-cta p { max-width: 58ch; margin: 0 auto 22px; color: var(--on-dark-dim); line-height: 1.62; }
.ind-cta .button { display: inline-flex; }
@media (max-width: 900px) {
  .ind-grid { grid-template-columns: minmax(0,1fr); gap: 24px; }
  .ind-col-wide { border-left: 0; border-right: 0; border-top: 1px solid var(--rule-light);
}

                  border-bottom: 1px solid var(--rule-light); padding: 24px 0; }

/* =========================================================================
   NOT FOR YOU
   ========================================================================= */
.nfy { background: var(--carbon); padding: var(--section-tight) var(--gutter); }
.nfy-inner { max-width: var(--maxw); margin: 0 auto; }
.nfy-head { max-width: 62ch; margin-bottom: clamp(28px, 3.6vw, 46px); }
.nfy-head h2 {
  font-family: var(--display); font-variation-settings: "wdth" 80, "wght" 860;
  font-size: clamp(1.9rem, 4.4vw, 3.4rem); line-height: .98; text-transform: uppercase;
  letter-spacing: -.034em; color: var(--white); margin-bottom: 14px;
}
.nfy-head p { color: var(--on-dark-dim); font-size: 1.02rem; line-height: 1.64; }


.nfy-card h3 {
  font-family: var(--display); font-variation-settings: "wdth" 86, "wght" 820;
  font-size: 1.1rem; text-transform: uppercase; letter-spacing: -.024em;
  color: var(--gold); margin-bottom: 10px;
}
.nfy-card p { font-size: .93rem; line-height: 1.62; color: var(--on-dark-dim); margin: 0; }
.nfy-foot { margin-top: clamp(26px, 3.4vw, 40px); padding-top: 22px; border-top: 1px solid var(--rule-dark); }
.nfy-foot p { max-width: 70ch; color: var(--on-dark-dim); font-size: .98rem; line-height: 1.64; }
.nfy-foot strong { color: var(--white); }

.prose { max-width: 74ch; }
.prose h2 {
  font-family: var(--display); font-variation-settings: "wdth" 84, "wght" 840;
  font-size: clamp(1.2rem, 2.2vw, 1.6rem); text-transform: uppercase; letter-spacing: -.028em;
  color: var(--carbon); margin: clamp(30px, 4vw, 46px) 0 12px;
}
.prose h2:first-child { margin-top: 0; }
.prose p { font-size: 1.02rem; line-height: 1.72; color: var(--on-light-dim); margin: 0 0 16px; }
.prose ul { margin: 0 0 16px; padding-left: 20px; }
.prose li { font-size: 1rem; line-height: 1.66; color: var(--on-light-dim); margin-bottom: 8px; }
.prose a { color: var(--carbon); border-bottom: 1px solid var(--gold); text-decoration: none; }
.prose a:hover { border-bottom-width: 2px; }
.prose-note {
  margin-top: clamp(26px, 3.4vw, 40px) !important; padding-top: 18px;
  border-top: 1px solid var(--rule-light);
  font-family: var(--mono); font-size: .78rem !important; line-height: 1.6 !important;
  letter-spacing: .04em; color: #6f6a60 !important;
}

/* =========================================================================
   RESULTS -- provenance is the design, not a footnote
   ========================================================================= */
.prov-legend { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%,320px),1fr)); gap: 20px; margin-bottom: clamp(28px,4vw,44px); }
.prov-key { padding: 20px 22px; border-left: 1px solid var(--gold); background: #fff; }
.prov-key p { font-size: .9rem; line-height: 1.6; color: var(--on-light-dim); margin: 10px 0 0; }
.prov-tag {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--mono); font-size: var(--micro, .69rem); font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; padding: 0; white-space: nowrap;
}
/* Same rule as the ribbon tags: the provenance is a qualifier on the figure, not
   the figure. A solid gold plate out-shouted the $13.4M it was attached to and
   made one card look more important than its neighbours. Both are now the same
   weight, and the marker carries the distinction. */
.prov-tag::before {
  content: ""; width: 7px; height: 7px; flex: none; border-radius: 50%;
}
.prov-practice { color: #6f6a60; }
.prov-practice::before { background: none; box-shadow: inset 0 0 0 1.5px #6f6a60; }
.prov-client   { color: var(--gold-ink); }
.prov-client::before { background: var(--gold); }
.res-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%,280px),1fr)); gap: 1px; background: var(--rule-light); border: 1px solid var(--rule-light); }
.res-card { background: #fff; padding: clamp(22px,2.6vw,32px); display: flex; flex-direction: column; }
.res-value {
  font-family: var(--display); font-variation-settings: "wdth" 76, "wght" 850;
  font-size: clamp(2.2rem, 5.2vw, 3.4rem); line-height: .9; letter-spacing: -.04em;
  color: var(--carbon); margin-bottom: 10px;
}
.res-label {
  font-family: var(--display); font-variation-settings: "wdth" 88, "wght" 780;
  font-size: .96rem; text-transform: uppercase; letter-spacing: -.014em;
  color: var(--gold-ink); margin-bottom: 9px;
  /* Labels ran to two lines on some cards and one on others, so the gap between
     the figure and its description shifted card to card. The line box is 1.2em at
     this size, so 2.4em holds two lines even where the text needs only one. */
  line-height: 1.2;
  min-height: 2.4em;
}
.res-ctx { font-size: .88rem; line-height: 1.58; color: var(--on-light-dim); margin: 0 0 16px; flex: 1;
  min-height: 4.75em; }
.res-src { font-size: .74rem; color: #6f6a60; margin: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.res-caveat { margin-top: clamp(34px,4.4vw,56px); padding: clamp(24px,3vw,38px); background: var(--carbon); }
.res-caveat h2 {
  font-family: var(--display); font-variation-settings: "wdth" 82, "wght" 850;
  font-size: clamp(1.2rem,2.4vw,1.6rem); text-transform: uppercase; letter-spacing: -.028em;
  color: var(--gold); margin-bottom: 12px;
}
.res-caveat p { color: var(--on-dark-dim); line-height: 1.68; margin: 0; max-width: 78ch; }
.sec-title-sm {
  font-family: var(--display); font-variation-settings: "wdth" 82, "wght" 850;
  font-size: clamp(1.5rem,3vw,2.1rem); text-transform: uppercase; letter-spacing: -.032em;
  color: var(--carbon); margin: clamp(38px,4.6vw,62px) 0 22px;
}
.res-named { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%,320px),1fr)); gap: clamp(18px,2.4vw,28px); }
.res-case { padding: clamp(22px,2.6vw,32px); border: 1px solid var(--rule-light); background: #fff; }
.res-case h3 {
  font-family: var(--display); font-variation-settings: "wdth" 84, "wght" 840;
  font-size: 1.35rem; text-transform: uppercase; letter-spacing: -.028em;
  color: var(--carbon); margin-bottom: 6px;
}
.res-case-type { font-family: var(--mono); font-size: .7rem; letter-spacing: .12em; text-transform: uppercase; color: var(--gold); margin-bottom: 14px; }
.res-case-body { font-size: .94rem; line-height: 1.66; color: var(--on-light-dim); margin: 0 0 14px; }
.res-case-note { font-size: .78rem; line-height: 1.56; color: #6f6a60; margin: 0; padding-top: 12px; border-top: 1px solid var(--rule-light); }
.res-more { margin-top: 22px; font-size: .9rem; color: var(--on-light-dim); }
.res-more a { color: var(--carbon); border-bottom: 1px solid var(--gold); text-decoration: none; }

.hp-nums { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%,190px),1fr)); gap: 1px; background: var(--rule-light); border: 1px solid var(--rule-light); margin-bottom: clamp(26px,3.4vw,40px); }
.hp-num { background: #fff; padding: clamp(18px,2.2vw,26px); display: flex; flex-direction: column; gap: 4px; }
.hp-num-v { font-family: var(--display); font-variation-settings: "wdth" 76,"wght" 850; font-size: clamp(1.7rem,3.4vw,2.3rem); line-height: 1; letter-spacing: -.038em; color: var(--carbon); }
.hp-num-l { font-size: .84rem; line-height: 1.45; color: var(--on-light-dim); }
.hp-num-s { font-family: var(--mono); font-size: .69rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--gold-ink); margin-top: 5px; }
.sec-head a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--gold); }

.form-privacy {
  margin-top: 22px; padding: 20px 22px;
  background: var(--paper, #F5F3EE); border: 1px solid var(--rule-light);
}
.form-privacy p { font-size: .84rem; line-height: 1.62; color: var(--on-light-dim); margin: 0 0 10px; }
.form-privacy-h {
  font-family: var(--mono) !important; font-size: .62rem !important; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--carbon) !important; margin: 0 0 10px !important;
}
.form-privacy-links { margin: 14px 0 0 !important; padding-top: 12px; border-top: 1px solid var(--rule-light); }
.form-privacy a { color: var(--carbon); border-bottom: 1px solid var(--gold); text-decoration: none; }
.form-privacy a:hover { border-bottom-width: 2px; }

.cart-cta.is-disabled, .button.is-disabled {
  opacity: .45; pointer-events: none; cursor: not-allowed;
  filter: saturate(.35);
}

/* An odd item count in a 2-col grid leaves an empty cell that renders as a
   grey block against the grid background. Let the last odd item span. */
.ledger-rows > article:last-child:nth-child(odd) { grid-column: 1 / -1; }
@media (max-width: 900px) {
  .ledger-rows > article:last-child:nth-child(odd) { grid-column: auto; }
}


/* ---- empty-cell class fix ----------------------------------------------
   These grids faked hairline borders with `gap:1px` over a coloured
   background. That technique makes any unfilled cell render as a solid block
   of the background colour -- which is exactly what happened to .res-grid
   (14 items / 4 columns = 2 empty cells) and .ledger-rows (5 items / 2
   columns = 1 empty cell). Real borders on the items themselves cannot fail
   regardless of how many items there are.
   ------------------------------------------------------------------------ */
.res-grid { gap: 0; background: none; border: 1px solid var(--rule-light); }
.res-card {
  border-right: 1px solid var(--rule-light);
  border-bottom: 1px solid var(--rule-light);
  margin: 0 -1px -1px 0;
}
/* trailing items still get a right border so the outer edge stays square */
.res-card:nth-child(4n) { border-right: 0; }

.cat-grid { gap: clamp(12px, 1.4vw, 20px); background: none; border: 0; }
/* an odd trailing card spans the row instead of leaving a ragged hole */
.cat-grid > *:last-child:nth-child(odd) { grid-column: 1 / -1; } .cat-grid > *:last-child:nth-child(odd) { grid-column: auto; }

/* =========================================================================
   TRIAGE STRIP
   Adds a scannable summary layer rather than hiding anything. Every visitor
   can get all four verdicts in one pass and choose where to read in depth.
   ========================================================================= */
.triage { background: var(--carbon); padding: var(--section-tight) var(--gutter); }
.triage-inner { max-width: var(--maxw); margin: 0 auto; display: grid; grid-template-columns: minmax(0,.8fr) minmax(0,2fr); gap: clamp(24px, 4vw, 64px); align-items: start; }
.triage-label {
  font-family: var(--mono); font-size: .64rem; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--gold); margin: 0 0 12px;
}
.triage-head h2 {
  font-family: var(--display); font-variation-settings: "wdth" 80, "wght" 860;
  font-size: clamp(1.6rem, 3.4vw, 2.6rem); line-height: .98; text-transform: uppercase;
  letter-spacing: -.034em; color: var(--white); margin: 0;
}
.triage-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1px; background: var(--rule-dark); border: 1px solid var(--rule-dark); }
.triage-list a {
  display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1.5fr) auto;
  gap: 16px; align-items: baseline; padding: clamp(14px,1.8vw,20px) clamp(16px,2vw,24px);
  background: var(--carbon-deep); text-decoration: none;
  transition: background .18s ease;
}
.triage-list a:hover { background: var(--carbon-lift); }
.triage-list a:hover .triage-v { color: var(--gold); }
.triage-c {
  font-family: var(--display); font-variation-settings: "wdth" 88, "wght" 820;
  font-size: .95rem; text-transform: uppercase; letter-spacing: -.02em; color: var(--white);
}
.triage-v { font-size: .93rem; line-height: 1.45; color: var(--on-dark-dim); transition: color .18s ease; }
.triage-t {
  font-family: var(--mono); font-size: .62rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--gold); white-space: nowrap; text-align: right;
}
@media (max-width: 900px) {
  .triage-list a { grid-template-columns: minmax(0,1fr) minmax(0,1.4fr) minmax(0,auto); gap: 12px; }
  .triage-inner { grid-template-columns: minmax(0,1fr); }
  .triage-list a { grid-template-columns: minmax(0,1fr); gap: 5px; }
  .triage-t { text-align: left; }
  .triage-t { white-space: normal; }
}


/* =========================================================================
   HERO -- rebuilt
   The old hero showed archive file counts while $13.4M sat unused on the
   results page, and its headline described a problem rather than a service.
   These rules add provenance labels to the proof block and pull the section
   up so it fills the viewport instead of leaving dead space beneath it.
   ========================================================================= */
.hero-inner { padding-bottom: clamp(48px, 6vw, 92px); }

.hero-proof {
  border: 1px solid var(--rule-dark);
  background: var(--carbon-deep);
  padding: var(--pad-card);
}
.hero-proof-h {
  font-family: var(--mono); font-size: .62rem; font-weight: 700; letter-spacing: .15em;
  text-transform: uppercase; color: var(--on-dark-faint); margin: 0 0 14px;
}
.hero-proof .hero-facts { border: 0; background: none; gap: 1px; }
.hero-proof .hero-facts li { background: var(--carbon); }

.tag {
  font-family: var(--mono); font-size: .69rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; font-style: normal; align-self: flex-start;
  padding: 3px 8px; white-space: nowrap;
}
.tag-practice { background: #2A333F; color: var(--gold); }
.tag-client   { background: var(--gold); color: var(--carbon); }

.hero-proof-link {
  display: inline-block; margin-top: 16px;
  font-family: var(--mono); font-size: .68rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--gold); text-decoration: none;
  border-bottom: 1px solid transparent; padding-bottom: 2px;
}
.hero-proof-link:hover { border-bottom-color: var(--gold); }
@media (max-width: 900px) {
  .hero-proof .hero-facts { grid-template-columns: 1fr 1fr; }
  .hero-proof .hero-facts { grid-template-columns: 1fr; }
  .hero { min-height: calc(100vh - var(--hero-chrome, 150px)); display: flex; flex-direction: column; justify-content: center; }
  .hero-inner { padding-top: clamp(96px, 12vh, 150px); padding-bottom: clamp(36px, 5vh, 68px); }
  .hero-title--reveal .line {
}

    display: block;
    transform: translateY(0.72em) rotate(1.1deg);
    opacity: 0;
    transition:
      transform 820ms cubic-bezier(.16,.84,.28,1),
      opacity 620ms cubic-bezier(.16,.84,.28,1);
  }
@media (max-width: 900px) {
  .hero-title--reveal .line.line-in { transform: translateY(0) rotate(0); opacity: 1; }
}


/* =========================================================================
   PROOF BAND
   Namespaced `band-*` on purpose: `.ribbon` is already the shared gold
   marquee ticker in the header (background: gold, display:flex, marquee
   animation). Reusing those class names made this block inherit the
   ticker's styles and collapse onto one line.
   ========================================================================= */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.proofband {
  position: relative; z-index: 3;
  --band-pad: max(var(--gutter), calc((100% - var(--maxw)) / 2));
  background: var(--carbon-deep);
  border-top: 1px solid var(--rule-dark);
  border-bottom: 1px solid var(--rule-dark);
  /* no vertical padding of its own: the cells supply their own. The band-link row
     used to live here and left ~34px of empty carbon behind when it was removed. */
  padding: 0;
}
.band-track {
  list-style: none;
  margin: 0 auto; padding: 0;
  max-width: none;
  width: 100%;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px; background: var(--rule-dark);
  border: 1px solid var(--rule-dark);
}
.band-cell {
  background: var(--carbon-deep);
  border-inline: 1px solid transparent;
  padding: clamp(16px, 2vw, 24px) clamp(14px, 1.8vw, 22px);
  display: flex; flex-direction: column; gap: 7px;
  position: relative; overflow: hidden;
  transition: background 240ms var(--ease);
}
.band-cell::after {
  content: ""; position: absolute; left: 0; top: 0; height: 2px; width: 0;
  background: var(--gold); transition: width 420ms var(--ease);
}
.band-cell:hover { background: var(--carbon); }
.band-cell:hover::after { width: 100%; }
.band-cell b {
  font-family: var(--display);
  font-variation-settings: "wdth" 66, "wght" 870;
  font-size: clamp(2.1rem, 4.2vw, 3.5rem);
  line-height: .86; letter-spacing: -.042em;
  color: var(--gold); font-variant-numeric: tabular-nums;
}
.band-cell > span {
  font-size: .82rem; line-height: 1.45; color: var(--on-dark-dim);
  max-width: 22ch;
}
/* Provenance must stay honest and readable, but it is a qualifier on the figure,
   not the headline. Both tags used to share the name "tag" and rendered with two
   different treatments -- a dim outline and a solid gold plate -- so the gold one
   shouted louder than the $13.4M it was qualifying. Same weight, same shape, and
   the distinction is carried by the marker: filled for delivery we can own,
   hollow for results led elsewhere. */
.band-cell .tag {
  align-self: flex-start;
  display: inline-flex; align-items: center; gap: 8px;
  margin: 0; padding: 0;
  background: none !important; border: 0 !important;
  font-family: var(--mono); font-size: var(--micro, .69rem); font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase;
  color: var(--on-dark-faint); white-space: nowrap;
}
.band-cell .tag::before {
  content: ""; width: 7px; height: 7px; flex: none;
  border-radius: 50%;
}
.band-cell .tag-practice::before { background: none; box-shadow: inset 0 0 0 1.5px var(--on-dark-faint); }
.band-cell .tag-client::before   { background: var(--gold); }
.band-cell .tag-client   { color: var(--gold); }

/* Bottom-align the tag and reserve two caption lines, so all four tags sit on one
   baseline instead of stepping down wherever a caption happens to wrap. */
.band-cell > span { min-height: 2.9em; }
.band-cell .tag { margin-top: auto; padding-top: 2px; }

/* hero-lower is single-column now that the proof moved to the band below */
.hero-lower { grid-template-columns: minmax(0, 1fr); gap: 0; }
.hero-lower-copy { max-width: 62ch; } .band-track { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 900px) {
  .band-track { grid-template-columns: minmax(0, 1fr); }
  .band-cell b { font-size: 2.4rem; }
}


/* =========================================================================
   HERO — rebuilt from scratch (typographic-first)
   -------------------------------------------------------------------------
   Why this is a rewrite and not a patch:
   The old hero stacked a full-bleed <canvas> (masked to a radial gradient)
   under a .hero-veil (a 180deg linear gradient). Two independent sources of
   the straight horizontal seam:
     1. mask-image fading toward the edge of an overflow:hidden box leaves
        unpainted pixels at the boundary, and the box clips them to a
        perfectly straight line;
     2. the veil's 180deg stops banded visibly against the flat carbon.
   The fix is structural: no canvas, no mask, no directional gradient. The
   only background is one very soft radial glow, which has no stop to band
   against and therefore no edge to show.
   ========================================================================= */

.hero {
  position: relative;
  background: var(--carbon);
  overflow: hidden;
  padding: 0;
  min-height: 100vh;
  min-height: 100svh;
  display: flex;
  align-items: center;
  isolation: isolate;
}
/* The veil stays retired: a 180deg gradient banded against the flat carbon and
   is exactly what produced the hard horizontal seam. The canvas is back, but
   it is not masked or veiled -- the shader's own vignette fades the field to
   black before the section's overflow clip, so there is nothing to band. */
.hero-veil { display: none !important; }

/* One soft field of light. Extremely wide and soft on purpose: a tight
   radial reads as a visible disc, a broad one reads as light in a room. */
.hero-field {
  position: absolute; inset: -10%;
  z-index: 0; pointer-events: none;
  background:
    radial-gradient(58% 46% at var(--px, 50%) var(--py, 38%),
      rgba(255, 182, 18, 0.10), rgba(255, 182, 18, 0) 100%),
    radial-gradient(80% 62% at 50% 0%,
      rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0) 100%);
  transition: background 320ms var(--ease);
}

.hero-inner {
  position: relative; z-index: 2;
  width: 100%; max-width: var(--maxw); margin: 0 auto;
  padding: clamp(96px, 10.5vh, 142px) var(--gutter) clamp(44px, 5.5vh, 80px);
}

.hero-eyebrow { margin-bottom: clamp(18px, 2.4vh, 30px); }

.hero-title {
  font-family: var(--display);
  font-variation-settings: "wdth" 74, "wght" 862;
  /* Duplicate of the later .hero-title rule. Kept in sync so the two cannot
     diverge if cascade order ever changes. The later one wins today. */
  font-size: clamp(2.9rem, min(9.6vw, 15.2vh), 8.8rem);
  line-height: 0.88;
  text-transform: uppercase;
  letter-spacing: -0.04em;
  /* 15ch orphaned "YOUR" onto a line of its own. The longest intended line
     is "YOUR PROCESS DID." at 17 characters, so the measure has to clear it
     or the manual <span> breaks stop meaning anything. */
  max-width: 19ch;
  margin: 0;
}
.hero-title .gold { color: var(--gold); }

/* animated hairline -- the one flourish, bounded and cheap */
.hero-rule { margin: clamp(26px, 3.4vh, 44px) 0 clamp(24px, 3vh, 40px); height: 1px; position: relative; max-width: 640px; }
.hero-rule i {
  position: absolute; inset: 0 auto 0 0; display: block; height: 1px; width: 100%;
  background: linear-gradient(90deg, var(--gold), rgba(255, 182, 18, 0.05) 62%, transparent);
  transform-origin: left center; transform: scaleX(0);
  animation: ruleDraw 1500ms cubic-bezier(.16,.84,.28,1) 320ms forwards;
}

.hero-lower {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 0.75fr);
  gap: clamp(28px, 4vw, 76px);
  align-items: start;
}
.hero-lede {
  font-size: clamp(1.02rem, 1.2vw, 1.18rem);
  line-height: 1.66; color: var(--on-dark-dim); margin: 0 0 26px; max-width: 56ch;
}
.hero-lede strong { color: var(--white); font-weight: 600; }

/* the contained panel that carries the motion */
.hero-live {
  border: 1px solid var(--rule-dark);
  background: rgba(8, 12, 17, 0.55);
  backdrop-filter: blur(2px);
  padding: clamp(16px, 1.8vw, 22px);
}
.hero-live-h {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--mono); font-size: .6rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--on-dark-faint);
  margin: 0 0 11px;
}
.hero-live-h i {
  width: 6px; height: 6px; border-radius: 50%; background: var(--gold);
  animation: pulseDot 2200ms ease-in-out infinite;
} 0%,100% { opacity: 1; } 50% { opacity: .25; }
.hero-live-list { list-style: none; margin: 0; padding: 0; }
.hero-live-list li {
  font-size: .8rem; line-height: 1.36; color: var(--on-dark-faint);
  padding: 7px 0; border-top: 1px solid rgba(255, 255, 255, .07);
  display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap;
}
.hero-live-list b {
  font-family: var(--display);
  font-variation-settings: "wdth" 72, "wght" 840;
  font-size: 1rem; letter-spacing: -.02em; color: var(--gold);
  font-variant-numeric: tabular-nums;
}
.hero-live-foot {
  margin: 11px 0 0; padding-top: 10px; border-top: 1px solid rgba(255,255,255,.07);
  font-family: var(--mono); font-size: .58rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--on-dark-faint);
}
.hero-live-foot span { color: var(--gold); }
@media (max-width: 900px) {
  .hero-rule i { animation: none; transform: scaleX(1); }
  .hero-live-h i { animation: none; }
  .hero-lower { grid-template-columns: minmax(0, 1fr); }
  .hero-live { max-width: 460px; }
  .hero { min-height: auto; }
  .hero-title { font-size: clamp(2.5rem, 13vw, 4rem); max-width: none; }
  .hero-inner { padding-top: 108px; }
  .hero-lower { grid-template-columns: minmax(0, 1fr); }
  .hero-live { display: none; }
  .hero-lede { max-width: 68ch; }
  .hero-rule { margin: clamp(18px, 2.4vh, 30px) 0 clamp(16px, 2.2vh, 28px); }
}


/* =========================================================================
   HERO — bleed layer, short section
   .hero-field bleeds 30% past the section on all sides and draws only inside
   a central ellipse. The section still clips, but the clip lands on empty
   canvas, so no straight edge can appear. There is deliberately no mask:
   a fading mask inside an overflow:hidden box is what produced the seam.
   ========================================================================= */
.hero {
  position: relative;
  background: var(--carbon);
  overflow: hidden;
  isolation: isolate;
  min-height: min(86svh, 780px);
  display: flex; align-items: center;
  padding: 0;
}
.hero::after  { content: none; }
.hero-veil    { display: none !important; }

.hero-field {
  /* inset:-30% needs explicit width/height: <canvas> is a replaced element,
     so width:auto resolves to its intrinsic 300x150 and the bleed silently
     does not happen. 160% = the -30% inset on each side. */
  position: absolute; inset: -30%;
  width: 160%; height: 160%;
  z-index: 0; pointer-events: none;
  /* no -webkit-mask / mask-image anywhere: that is the artifact source */
}

.hero-inner {
  position: relative; z-index: 2;
  width: 100%; max-width: var(--maxw); margin: 0 auto;
  padding: clamp(120px, 13vh, 168px) var(--gutter) clamp(36px, 5vh, 64px);
}

.hero-eyebrow {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--mono); font-size: .7rem; font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 clamp(14px, 2vh, 24px);
}

.hero-title {
  font-family: var(--display);
  font-variation-settings: "wdth" 74, "wght" 862;
  /* Ceiling raised 8.2rem -> 8.8rem. Measured with a Range over the real text
     (not the block box): at 1440-2100 the longest line was 1160px inside a
     1308-1340px content box, so 8.2rem was leaving 148-180px of width unused
     and pinning the headline at a flat 131.2px across that whole range.
     8.8rem = 140.8px, which still leaves >=60px of slack at every width. */
  font-size: clamp(2.6rem, min(9.4vw, 13.4vh), 8.8rem);
  line-height: 0.87;
  text-transform: uppercase;
  letter-spacing: -0.04em;
  max-width: 19ch;          /* "YOUR PROCESS DID." is 17 characters */
  margin: 0;
  text-shadow: 0 2px 34px rgba(8, 12, 17, 0.75);
}
.hero-title .line { display: block; }
.hero-title .gold {
  color: var(--gold);
  text-shadow: 0 0 44px rgba(255, 182, 18, 0.30), 0 2px 34px rgba(8, 12, 17, 0.8);
}

.hero-rule {
  margin: clamp(18px, 2.6vh, 30px) 0 clamp(16px, 2.2vh, 26px);
  height: 1px; position: relative; max-width: 620px;
}
.hero-rule i {
  position: absolute; inset: 0 auto 0 0; display: block; height: 1px; width: 100%;
  background: linear-gradient(90deg, var(--gold), rgba(255,182,18,.04) 66%, transparent);
  transform-origin: left center; transform: scaleX(0);
  animation: ruleDraw 1400ms cubic-bezier(.16,.84,.28,1) 260ms forwards;
}

.hero-lede {
  font-size: clamp(1rem, 1.15vw, 1.14rem);
  line-height: 1.6; color: var(--on-dark-dim);
  margin: 0 0 clamp(20px, 2.6vh, 28px);
  max-width: 58ch;
  text-shadow: 0 1px 22px rgba(8, 12, 17, 0.8);
}
.hero-lede strong { color: var(--white); font-weight: 600; }

.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; }

/* Retired: the studio-status box moved out of the hero. The figures live in
   the proof band immediately below it. */
.hero-live, .hero-lower, .hero-lower-copy { display: none !important; }
@media (max-width: 780px) {
  .hero-rule i { animation: none; transform: scaleX(1); }
  .hero { min-height: auto; }
  .hero-inner { padding-top: clamp(88px, 13vh, 116px); }
  .hero-title { font-size: clamp(2.35rem, 12.4vw, 4.1rem); max-width: none; }
  .hero-lede { max-width: none; }
  .hero-eyebrow { font-size: .6rem; letter-spacing: .14em; }
}
@media (max-width: 560px) {
  /* A fixed 2.1rem belongs to the small-phone tier only. It sat at 780px,
     which made a 768px tablet render the same 34px headline as a 320px
     phone, leaving half the viewport empty. */
  .hero-title { font-size: 2.1rem; }
  .hero-actions .button { width: 100%; justify-content: center; }
}


/* =========================================================================
   HEADER / HERO BLEND
   The header was an opaque carbon bar sitting on top of the hero, so the
   field started at y=148 and the two read as separate stacked surfaces.
   On a page that has a hero, the header goes transparent until the user
   scrolls, letting the hero canvas run full-bleed to the top of the window.
   :has() keeps this scoped to the homepage -- on every other page the header
   must stay solid or nav text would sit on light content.
   ========================================================================= */
body:has(.hero) .site-header:not(.scrolled) {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-bottom-color: transparent;
  box-shadow: none;
}
/* The brand-tag under the logo and the hero eyebrow are the same words and
   now collide, because the header floats over the hero. The hero eyebrow is
   the fuller line, so the tag stands down wherever there is a hero. */
body:has(.hero) .brand-tag { display: none; }

/* The gold marquee rail is brand furniture, not chrome -- let it float too. */
body:has(.hero) .header-rail:not(.scrolled-rail) { position: relative; }

/* Once scrolled, behaviour is unchanged: solid, blurred, with the hairline. */
body:has(.hero) .site-header.scrolled {
  background: rgba(8, 12, 17, 0.9);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border-bottom-color: var(--rule-dark);
}
/* Nav legibility over a moving field: a tight text shadow, no plate. */
body:has(.hero) .site-header:not(.scrolled) .primary-nav a,
body:has(.hero) .site-header:not(.scrolled) .brand,
body:has(.hero) .site-header:not(.scrolled) .menu-toggle {
  text-shadow: 0 1px 16px rgba(8, 12, 17, 0.9), 0 0 3px rgba(8, 12, 17, 0.75);
}

/* =========================================================================
   LEGIBILITY FLOOR
   Impeccable flagged 284 undersized-text instances: functional labels in the
   9.3px-10.2px range, which fail on high-DPI and small viewports. Rather than
   patch forty rules individually, raise the floor for the mono micro-label
   families and let the layouts absorb it. 11px is the bar; only non-interactive
   legal smallprint keeps a 10px floor.
   ========================================================================= */
:root {
  --micro: .69rem;      /* 11.04px at 16px root -- the new floor */
  --micro-sm: .63rem;   /* 10.08px -- smallprint/legal only */
}
.brand-tag, .console-live, .calc-live-flag, .footer-live-label,
.rail-track, .roster-head, .roster td, .band-cell .tag, .res-prov, .res-source,
.triage-t, .ribbon-link, .band-link, .hero-eyebrow, .eyebrow,
.hp-num-s, .industry-note, .case-stage, .narr-meta, .narr-evidence,
.ledger-item b, .proof-meta, .stat-note,
.calc-label, .calc-unit, .calc-foot, .pkg-note, .pkg-tag, .pkg-cost,
.faq-item dt, .price-note, .service-unit, .service-timeline,
.label, .meta, .micro,
/* second pass -- classes found by measuring the rendered pages, not by guessing */
.calc-hint, .return-severity, .rh-label, .return-row dt, .tier-note, .tier-flag,
.return-table th, .roster-collabel, .team-role, .ind-tag { font-size: var(--micro) !important; }

/* The footer marquee's separator dot was 3.8px. It is decorative, but a mark
   that small renders as a smudge on high-DPI, so it gets a real size. */
.fm-track i { font-size: .6rem; line-height: 1; }
.roster-badge, .roster-prov, .calc-basis, .calc-disclaimer,
.hint, .option-tag, .roster-cell { font-size: var(--micro) !important; }

/* 2x header logo. The wordmark is 476x206 (2.31:1) and was rendered at 74px
   tall; intrinsic ratio is preserved and never stretched. */
/* Header wordmark.
   Now an INLINE svg, not an <img>: inlining is what lets the page's CSS
   reach the fill. An SVG loaded through <img src> is an isolated document --
   external stylesheets cannot touch it, so fill="currentColor" inside the
   file would resolve against the SVG document, not the page, and the hover
   colour could not be driven from here at all.

   Source artwork is AJ's, supplied 2026-10-03 as Original Limited Logo.svg.
   The Illustrator export carried ~440KB of <metadata> private data, stripped
   on import: 443,275 bytes -> 9,298. The logo is a single <path> with
   fill="currentColor", so colour is entirely a CSS decision.

   Intrinsic ratio is 273 x 115.4 = 2.366:1. Never stretched -- height is
   set, width follows from preserveAspectRatio="xMinYMid meet". */
.brand .ol-wordmark {
  height: 62px;
  width: auto;
  display: block;
  color: var(--on-dark);
  transition: color 240ms ease;
}
@media (min-width: 1181px) { .brand .ol-wordmark { height: 74px; } }
@media (min-width: 1600px) { .brand .ol-wordmark { height: 86px; } }
@media (min-width: 2200px) { .brand .ol-wordmark { height: 96px; } }
@media (max-width: 1180px) { .brand .ol-wordmark { height: 56px; } }
@media (max-width: 900px) {
  .brand .ol-wordmark { height: 46px; }
  .menu-toggle { padding: 9px 10px; font-size: .68rem; letter-spacing: .1em; }
}


/* =========================================================================
   NEWSLETTER
   Layout only. The form does not transmit: submit is intercepted in script.js
   and reports a placeholder message rather than silently swallowing the
   address. Wire a provider endpoint before launch.
   ========================================================================= */
.newsletter {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(24px, 4vw, 64px);
  align-items: center;
  padding: clamp(26px, 3.4vw, 44px) 0;
  border-top: 1px solid var(--rule-dark);
}
.newsletter-h {
  font-family: var(--display);
  font-variation-settings: "wdth" 78, "wght" 840;
  font-size: clamp(1.3rem, 2.3vw, 1.9rem);
  line-height: 1.02; letter-spacing: -.03em; text-transform: uppercase;
  color: var(--white); margin: 0 0 10px;
}
.newsletter-sub {
  font-size: .92rem; line-height: 1.6; color: var(--on-dark-dim);
  margin: 0; max-width: 52ch;
}
.newsletter-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
  position: relative;
}
.newsletter-form input {
  font-family: var(--mono); font-size: var(--micro, .69rem);
  color: var(--white); background: var(--carbon-deep);
  border: 1px solid var(--rule-dark);
  padding: 15px 16px; min-width: 0;
  transition: border-color var(--fast, .18s) var(--ease);
}
.newsletter-form input::placeholder { color: var(--on-dark-faint); }
.newsletter-form input:focus {
  outline: none; border-color: var(--gold);
}
.newsletter-form .button { white-space: nowrap; }
.newsletter-note {
  grid-column: 1 / -1;
  font-family: var(--mono); font-size: var(--micro, .69rem);
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--on-dark-faint);
  margin: 2px 0 0; min-height: 1.2em;
}
.newsletter-note.is-ok { color: var(--gold); }
.newsletter-note.is-bad { color: var(--warn, #ff8f6b); }
@media (max-width: 900px) {
  .newsletter { grid-template-columns: minmax(0, 1fr); }
  .newsletter-form { grid-template-columns: minmax(0, 1fr); }
  .newsletter-form .button { width: 100%; justify-content: center; }
}


/* =========================================================================
   FIVE-PHASE SPINE
   Was a 4-column grid with a single orphan step wrapped into a second row,
   then a separate "what each phase produces" section repeating the same five
   items as cards. Now: one five-across spine where each phase carries its own
   output, so the reader never has to hold five numbers in their head and then
   look them up again 400px down.
   ========================================================================= */
.tl-spine { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.tl-when {
  font-family: var(--mono); font-size: var(--micro, .69rem); font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase; color: var(--on-dark-faint);
  margin: 0 0 12px;
}
.tl-out {
  margin: auto 0 0 !important; padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, .08);
  font-size: .84rem !important; line-height: 1.55 !important; color: var(--on-dark-faint) !important;
}
.tl-out span {
  display: block; font-family: var(--mono); font-size: var(--micro, .69rem);
  font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 7px;
} .tl-spine { grid-template-columns: repeat(3, minmax(0, 1fr)); } .tl-spine { grid-template-columns: repeat(2, minmax(0, 1fr)); } .tl-spine { grid-template-columns: minmax(0, 1fr); } .tl-step { min-height: 0; }

/* =========================================================================
   CLIENTS TALLY
   Counts up once when it first scrolls into view. The final value is written
   into the markup, so with JS off the reader still sees the real number --
   the counter only animates from 0, it never supplies the value.
   ========================================================================= */
.tally { background: var(--carbon-deep); border-block: 1px solid var(--rule-dark);
  /* the 161px desktop header plus rail would otherwise overlap the first
     tally row when this block is scrolled to, clipping the number tops */
  scroll-margin-top: 200px; }
.tally-inner {
  max-width: var(--maxw); margin: 0 auto;
  padding: clamp(28px, 4vw, 52px) var(--gutter);
  display: grid; grid-template-columns: repeat(3, minmax(0, auto)) minmax(0, 1fr);
  gap: clamp(20px, 3.4vw, 56px); align-items: start;
}
.tally-num {
  font-family: var(--display);
  font-variation-settings: "wdth" 72, "wght" 860;
  font-size: clamp(2.4rem, 5.4vw, 4.4rem);
  line-height: .88; letter-spacing: -.04em; color: var(--gold);
  margin: 0 0 10px;
}
.tally-num b { font-weight: inherit; font-variant-numeric: tabular-nums; }
.tally-label {
  font-family: var(--mono); font-size: var(--micro, .69rem); font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase; color: var(--on-dark-faint);
  margin: 0; max-width: 22ch;
}
.tally-note {
  font-size: .84rem; line-height: 1.6; color: var(--on-dark-dim);
  margin: 0; padding-left: clamp(16px, 2vw, 30px);
  border-left: 1px solid var(--rule-dark); align-self: center;
}
@media (max-width: 900px) {
  .tally-inner { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .tally-note { grid-column: 1 / -1; border-left: 0; border-top: 1px solid var(--rule-dark);
}

                padding: 16px 0 0; }
@media (max-width: 900px) {
  .tally-inner { grid-template-columns: minmax(0, 1fr); gap: 22px; }
  .tally-label { max-width: none; }
}

.rm-head {
  font-family: var(--mono); font-size: var(--micro, .69rem); font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--gold);
  margin: 0 0 16px;
}
.rm-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  /* --rule is defined nowhere in this project. Bare var() on an undefined
     custom property invalidates the whole declaration at computed-value
     time, so both of these silently rendered as unset. --rule-dark is the
     token that actually exists. */
  gap: 1px; background: var(--rule-dark); border: 1px solid var(--rule-dark);
}
.rm-grid > div { background: var(--paper, #fff); padding: clamp(14px, 1.8vw, 20px); }
.rm-label {
  font-family: var(--mono); font-size: var(--micro, .69rem); font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--on-light-faint, #6d6a62);
  margin: 0 0 9px; min-height: 2.4em;
}
.rm-val {
  font-family: var(--display); font-variation-settings: "wdth" 76, "wght" 840;
  font-size: clamp(1.3rem, 2.2vw, 1.9rem); line-height: 1;
  letter-spacing: -.03em; color: var(--carbon); margin: 0;
  font-variant-numeric: tabular-nums;
}
.rm-val span {
  display: block; font-family: var(--mono); font-size: var(--micro-sm, .63rem);
  font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--on-light-faint, #6d6a62); margin-top: 7px;
}
.rm-val-us { color: var(--gold-ink); }
.rm-foot {
  font-size: .8rem; line-height: 1.6; color: var(--on-light-faint, #6d6a62);
  margin: 14px 0 0; max-width: 74ch;
} .rm-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } .rm-grid { grid-template-columns: minmax(0, 1fr); }
@media (max-width: 900px) {
  .rm-label { min-height: 0; }
}


/* =========================================================================
   TYPE-ONLY CASE CARDS
   The showcase used three photographs drawn from three of the four engagements.
   A curated subset with imagery reads as stronger than the full set without it,
   so the imagery came off and the fourth card came on. Same rule as the work
   page and the clients page: no stock, no propping, no gaps.
   ========================================================================= */

.card-type .card-body { display: flex; flex-direction: column; gap: 9px; padding: clamp(20px, 2.4vw, 28px); }
.card-type .card-title { font-size: clamp(1.15rem, 1.7vw, 1.4rem); }
.card-type .card-meta { color: var(--on-dark-dim); margin: 0; }
.card-verdict {
  font-family: var(--mono); font-size: var(--micro, .69rem); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--gold);
  margin: auto 0 0 !important; padding-top: 14px;
  border-top: 1px solid rgba(255,255,255,.08);
} .showcase-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } .showcase-4 { grid-template-columns: minmax(0, 1fr); }

/* the case-study verdict line, paired with the stage badge */
.narr-verdict {
  font-family: var(--mono); font-size: var(--micro, .69rem); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase; color: var(--gold);
  margin: 0 0 0 12px;
} .narr-verdict { display: block; margin: 8px 0 0; }

/* =========================================================================
   GENERATED AGENT MARKS
   Replaces 20 JPEGs that were each a single capital letter on a dark tile. The
   marks are inline SVG, so there is no image request, no broken-placeholder
   state, and nothing to reflow. .agent-face keeps its box and clips the mark to
   the same shape the photo used to fill.
   ========================================================================= */
.agent-face, .portrait-slot {
  position: relative; overflow: hidden;
  background: var(--carbon-deep);
  border: 1px solid var(--rule-dark);
}
.agent-face { aspect-ratio: 1 / 1; width: 100%; }
/* the mark was inset inside a larger tile; let it fill the box it is given */
.agent-face .agent-mark { width: 100%; height: 100%; }
.portrait-slot { aspect-ratio: 1 / 1; display: block; }
.agent-mark { display: block; width: 100%; height: 100%; }
.portrait-slot .agent-mark { object-fit: cover; }

/* A quiet frame so the mark reads as a deliberate tile, not a missing photo. */
.agent-face::after, .portrait-slot::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  box-shadow: inset 0 0 0 1px rgba(255, 182, 18, .12);
}
.agent:hover .agent-face { border-color: var(--gold); }

/* =========================================================================
   CALCULATOR HEAD -- shared by services.html and pricing.html
   ========================================================================= */
.calc-head { max-width: 62ch; margin-bottom: clamp(22px, 3vw, 38px); }
.calc-head h2 {
  font-family: var(--display);
  font-variation-settings: "wdth" 84, "wght" 840;
  font-size: clamp(1.6rem, 3vw, 2.4rem); line-height: 1.04;
  text-transform: uppercase; letter-spacing: -0.03em;
  color: var(--white); margin-bottom: 12px;
}
.calc-head h2 em { font-style: normal; color: var(--gold); }
.calc-head p { font-size: clamp(0.95rem, 1.15vw, 1.05rem); line-height: 1.62; color: var(--ink); }
.band-calc { padding-top: clamp(46px, 6vw, 82px); }

/* A package name the visitor has NOT selected must not look like their own
   price. Dimmed and dashed so the distinction survives at a glance. */
.return-tier-guess { opacity: .62; font-style: italic; border-style: dashed; }

/* An anchored section must clear the sticky masthead, or the heading lands
   underneath it. Same value the masthead is offset by. */
#worth-it, #builder, .calc-head { scroll-margin-top: 120px; }

/* =========================================================================
   TEAM ROSTER — LANES
   Replaces a flat 4-column grid of twenty identical tiles. A grid of equals
   says nothing about the team; grouping by function makes the structure the
   content, and the mark sits beside the text instead of floating above it so
   the column stops carrying dead space.
   ========================================================================= */
.agent-grid { display: none; }        /* retired flat grid */

.lane { margin-bottom: clamp(34px, 4.4vw, 58px); }
.lane:last-child { margin-bottom: 0; }

.lane-head {
  display: grid; grid-template-columns: auto minmax(0,1fr);
  gap: 0 16px; align-items: baseline;
  padding-bottom: 14px; margin-bottom: clamp(16px, 2vw, 24px);
  border-bottom: 1px solid var(--rule-dark);
}
.lane-num {
  grid-row: 1 / span 2;
  font-family: var(--mono); font-size: 0.74rem; letter-spacing: 0.14em;
  color: var(--gold); opacity: .8;
}
.lane-name {
  font-family: var(--display);
  font-variation-settings: "wdth" 84, "wght" 840;
  font-size: clamp(1.2rem, 1.9vw, 1.6rem); text-transform: uppercase;
  letter-spacing: -0.026em; color: var(--white);
}
.lane-blurb { font-family: var(--mono); font-size: 0.78rem; line-height: 1.5; color: #8b97a5; }

/* Tiles flow to fill each row at any count, so a 2-member lane does not leave
   two lonely columns and a 4-member lane does not stretch. */
.lane-grid { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.lane-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.lane-grid[data-count="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.lane-grid[data-count="4"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.lane-grid[data-count="5"] { grid-template-columns: repeat(5, minmax(0, 1fr)); }
@media (max-width: 900px) {
  .lane-grid[data-count="4"], .lane-grid[data-count="5"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .lane-grid, .lane-grid[data-count] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .lane-grid, .lane-grid[data-count] { grid-template-columns: minmax(0, 1fr); }
}


.lane-tile {
  position: relative; display: grid;
  grid-template-columns: 56px minmax(0, 1fr); gap: 14px; align-items: start;
  padding: 16px 16px 18px;
  background: #0c1219; border: 1px solid var(--rule-dark);
  transition: border-color 220ms var(--ease), transform 220ms var(--ease), background 220ms var(--ease);
}
.lane-tile:hover {
  border-color: rgba(255,182,18,.42); background: #0f1720;
  transform: translateY(-2px);
}
.agent-mark-box { width: 56px; height: 56px; }
.agent-mark-box svg { width: 100%; height: 100%; height: 100%; display: block; }
.lane-tile .agent-idx {
  position: absolute; top: 12px; right: 14px;
  font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.1em; color: var(--gold); opacity: .5;
}
.lane-tile .agent-body { min-width: 0; }
.lane-tile h3 {
  font-family: var(--display); font-variation-settings: "wdth" 82, "wght" 850;
  font-size: 1.02rem; text-transform: uppercase; letter-spacing: -0.02em;
  color: var(--white); margin-bottom: 4px;
}
.lane-tile .agent-role {
  font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--gold); margin-bottom: 8px;
}
.lane-tile .agent-desc { font-size: 0.84rem; line-height: 1.55; color: #aab4c0; margin: 0; }
@media (max-width: 900px) {
  .lane-head { grid-template-columns: auto minmax(0,1fr); }
  .lane-tile { grid-template-columns: 44px minmax(0,1fr); gap: 12px; padding: 14px; }
  .agent-mark-box { width: 44px; height: 44px; }
}


/* =========================================================================
   INDUSTRY ICONS + SECTOR RIBBON
   Inline SVG so the set inherits the gold on hover, costs one request, and
   scales cleanly to every breakpoint. Squared caps and a 1.6 stroke keep the
   six drawing at one weight.
   ========================================================================= */
.ind-title { display: flex; align-items: center; gap: 14px; margin-bottom: 10px; }
.ind-title h2 { margin: 0; }
.ind-mark {
  flex: 0 0 auto; display: grid; place-items: center;
  width: 54px; height: 54px;
  border: 1px solid var(--rule-dark); background: #0c1219;
  color: var(--gold);
  transition: border-color 240ms var(--ease), background 240ms var(--ease);
}
.ind-icon { width: 32px; height: 32px; display: block; }
/* Hover on the whole sector block, not just the icon, so the affordance matches
   the target the visitor is actually pointing at. */
.ind:hover .ind-mark { border-color: rgba(255,182,18,.55); background: rgba(255,182,18,.08); }
@media (prefers-reduced-motion: reduce) {
  .ind-mark { transition: none; }
}


/* An undated engagement is a fact, not a layout hole. Italic and quiet so it
   reads as deliberate rather than as a value that failed to load. */
.roster-undated { font-style: italic; opacity: .55; letter-spacing: 0.01em; }

/* The two infinite marquee tracks (header rail, footer CTA) animate with
   translateX. Even clipped, their animated transform can leave a ~21px
   phantom scroll box at some widths, which shows as a stray horizontal
   scrollbar. overflow-x:clip removes it without creating a scroll container,
   so position:sticky (the scope rail, the header) keeps working. */
html { overflow-x: clip; }


/* =========================================================================
   GLOBAL OVERRIDES -- Reeler headings, and no drop shadows anywhere
   -------------------------------------------------------------------------
   1. Reeler on every heading. Covers the semantic h1-h6 elements plus the
      display classes that are headings by role (page/section/card titles,
      founder and lane names, stat numbers).
      !important is deliberate: ~100 existing rules set font-family and
      font-weight on their own selectors, which outrank a bare element
      selector. One blunt global rule beats 100 surgical edits, and this is a
      single global type decision.
      font-variation-settings is reset because Reeler is NOT variable. Leaving
      "wght 860" set makes the browser synthesize a faux-bold on top of a face
      that is already ultra-bold, which smears the counters.

   2. No drop shadows. Only OFFSET/blurred shadows are removed. Inset shadows
      are this design's actual accent language -- gold underline rules, 1px
      borders, the left gold bar -- so they stay, and the focus-visible ring
      stays because removing it would break keyboard navigation. A blurred
      offset shadow reads as dated skeuomorphism against a flat carbon/gold
      system.
   ========================================================================= */

h1, h2, h3, h4, h5, h6,
.page-title, .section-title, .sec-title-sm, .hero-title, .robots-mark,
.card-title, .founder-name, .lane-name, .narr-title, .res-label,
.stat-value, .stat-num, .proof-num, .step-num, .work-num, .faq-num,
.hp-num, .hp-num-v, .price-amount, .tile-title, .marquee-word {
  font-family: var(--heading) !important;
  font-weight: 400 !important;
  font-variation-settings: normal !important;
  font-style: normal !important;
}

/* Strip the offset/blurred shadows. Scoped per-selector rather than a blanket
   `* { box-shadow: none }` so inset accents and focus rings survive. */
.site-header.scrolled { box-shadow: 0 1px 0 var(--rule-dark); }
.nav-cta:hover         { transform: none; box-shadow: none; }
.hero-eyebrow, .hero-title, .proof-band, .band-cell, .proof-strip,
.stat-value, .hp-num-v, .marquee-word, .wordmark-glow { text-shadow: none; }

/* The gold glow that pulsed behind the hero CTA. */
.hero-cta-glow, .cta-glow, .btn-glow { filter: none !important; }
/* Card / tile lift shadows. */
.tile:hover, .card:hover, .bench-card:hover, .bento-card:hover,
.agent:hover, .prod-shot:hover, .proof-card:hover { box-shadow: none; }
/* The gold halo on the standalone CTA mark. */
.brand-cta, .nav-cta, .button-gold { box-shadow: none; }

/* --- Drop shadows: none anywhere -----------------------------------------
   A blanket text-shadow reset is safe and necessary here: the header set one
   text-shadow on a wrapper, which INHERITED down to every child (measured: 21
   elements carrying it that had no shadow of their own). Text-shadow is never
   an accent in this design -- it exists only for legibility over the hero.
   box-shadow is handled per-selector so the INSET gold rules, 1px borders and
   the focus-visible ring all survive; only offset/blurred lifts are removed. */
* { text-shadow: none !important; }

.site-header.scrolled { box-shadow: 0 1px 0 var(--rule-dark); }
.nav-cta:hover,
.button-gold:hover,
.bench-card:hover,
.bench-card:not(.bench-card-key):hover,
.bench-card-key:hover,
.tile:hover, .card:hover, .bento-card:hover,
.agent:hover, .prod-shot:hover, .prod-shot img { box-shadow: none; }

/* The gold halo that pulsed behind the hero CTA mark. */
.hero-cta-glow, .cta-glow, .btn-glow,
.wordmark-glow, .brand-cta { filter: none !important; box-shadow: none; }

/* --- Hero heading back to Archivo, not Reeler ----------------------------
   Reverted at the client's request. Reeler read too heavy at 127px display size
   and lost the brand's condensed Archivo character in the lockup, so the hero
   h1 is pinned back to --display (Archivo) while every other heading on the
   site stays Reeler.

   Scope is the hero ONLY. --heading is set on a broad selector, so this has to
   out-specify it. The proof-section figures below the hero (.hp-num-v /
   .hp-num-l, e.g. "$13.4M") are OUTSIDE .hero and deliberately keep Reeler --
   they are number-bearing display type, which is exactly what Reeler is for.
   Spacing, tracking and the increased header clearance are all untouched. */
.hero .hero-title,
.hero .hero-title .line,
.hero .hero-title .line.gold {
  font-family: var(--display);
  /* Restore the condensed axis. The blanket heading rule above sets
     font-variation-settings: normal on .hero-title, which silently killed the
     wdth 74 the hero had always used -- restoring the family alone left the
     headline rendering at full width. Values match the pre-Reeler backup
     (components.css:1990 in the .bak-20261001-230844 snapshot). */
  font-variation-settings: "wdth" 74, "wght" 862;
}

/* Heading-style elements that were still pinned to Archivo. Switched to Reeler
   so numbers and headings are one face. Detected by a runtime audit that
   flagged every heading-tag / -title / -head / -num / -label element whose
   computed font was Archivo. */
.return-headline,
.rh-num,
.brief-title {
  font-family: var(--heading);
}

/* --- Reeler numerals: no fallback needed ---------------------------------
   REMOVED: a block that pushed every digit-bearing heading (.hp-num-v,
   .faq-num, .robots-mark, .res-label, .faq-q) back to Archivo.

   It existed because the Personal Use build of Reeler maps all ten digits and
   "%" onto ONE shared glyph -- the `dollar` outline, 982 points of licence
   watermark reading "Personal USE ONLY WWW.ARLING". 1 distinct outline across
   0-9 versus 26 across A-Z.

   The face now installed is the full file: 364 glyphs, 360 codepoints, CFF
   outlines, 10 distinct outlines across 0-9. Real numerals, so Reeler can set
   the numbers and this workaround is no longer required anywhere. */

/* Display elements -> Reeler. Selectors here deliberately mirror the
   specificity of the Archivo rules they override (.return-hero .rh-num is 0,2,0,
   so a bare .rh-num at 0,1,0 would lose). components.css loads after styles.css,
   so an equal-specificity rule here wins.
   Nav links, buttons, .skip-link and inline <b>/<strong> are intentionally NOT
   in this list: they are interface, not headings. */
.return-hero .rh-num,
.rh-num,
.rm-val,
.slider-field output,
.return-tier,
.newsletter-h,
.accent-line {
  font-family: var(--heading);
}

/* Round two of the heading sweep: display figures and display names still on
   Archivo. Body copy (.accent-line, .page-lede) is deliberately left on Archivo
   -- those are sentences, not headings. */
.tier-name,
.tier-price,
.tl-year,
.res-value,
.start-domain,
.bento-verb {
  font-family: var(--heading);
}

/* =========================================================================
   HEADER -> HERO CLEARANCE
   Measured at 1600x950 before this change:
     header (.site-header) bottom   = 189px
     .hero-title top                = 169px
     gap                            = -20px   <-- they OVERLAP
   So there was effectively no white space between the logo and "YOUR AI
   PILOT". The headline was sitting inside the header's box.

   This sets the clearance explicitly on .hero-inner, which is where the live
   layout puts it: .hero is a flex box with align-items:center, so top padding
   on .hero itself is ignored. Padding on the inner block is what moves the
   centred content down. Target: >= 64px of clear space, logo bottom to title
   top, at every width.
   ========================================================================= */
.hero-inner { padding-top: clamp(216px, 24vh, 304px); } .hero-inner { padding-top: clamp(168px, 20vh, 220px); } .hero-inner { padding-top: clamp(148px, 19vh, 190px); }

/* =========================================================================
   CONTRAST FIXES -- light bands
   The "Is it worth it?" and "Five phases." headings sat at 1.11:1 (white on
   #f5f3ee) and 1.58:1 (gold on the same), i.e. effectively invisible.

   Cause: the light-band darkening rules only matched `.band-head`. Both of
   these sections use `.calc-head`, which was never in the selector, so they
   inherited the dark-band white heading.
   ========================================================================= */
.band-light .calc-head h2,
.band-white .calc-head h2 { color: var(--ink); }
.band-light .calc-head h2 em,
.band-white .calc-head h2 em { color: var(--gold-ink); }
.band-light .calc-head p,
.band-white .calc-head p { color: #38424e; }

/* Marginal misses, resolved against each element's REAL backdrop rather than
   its section class. My first attempt darkened .roster-collabel and .cart-note
   and made both worse: they sit on the dark roster band (#080c11) and the dark
   cart panel (#17202b), not on paper, so they needed to go lighter.
     #6b7784 on #080c11 = 4.29:1  (short of 4.5)
     #5a6675 on #080c11 = 3.35:1  (worse -- this was my error)
     #7f8b99 on #080c11 = 5.65:1  OK
     #7f8b99 on #17202b = 5.28:1  OK */
.cart-note,
.cart-clear,
.roster-collabel { color: #7f8b99; }

/* .rm-foot is a source note. It sits on DIV.return = carbon, NOT on paper.
   Darkening it to #4f4b45 dropped it to 2.07:1 -- I had assumed a light band.
   Verified against the measured backdrop: carbon + this grey = 9.6:1. */
.rm-foot,
.ledger-note { color: #8b97a6; }

/* .ind-label is 11px gold on a WHITE card (#fff inside .ind): 1.76:1. On white
   the display gold cannot be used for small text -- switched to the existing
   gold-family ink token, 6.92:1. */
.ind-label { color: var(--gold-ink); }

/* Derived price for the suggested package, shown under the match name so the
   claim and the number are always on screen together. */
.cart-match-price {
  margin: 10px 0 0;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold);
}
.cart-match-price[hidden] { display: none; }

/* =========================================================================
   CONTRAST PASS 2 -- resolved against SAMPLED PIXELS, not computed styles.

   The computed-style ancestor walk produced wrong answers in both directions:
   it called a dark-on-gold .ledger-badge "white on gold", and it called
   .rm-foot a paper note when it sits on carbon. So each case below was
   re-measured by screenshotting the page and taking the modal (most common)
   colour inside the element's own box as the real backdrop.

     .hp-num-l       white on a near-white card   1.06:1  -> ink   18.8:1
     .ctable-us th/td white on the gold highlight row 2.10:1 -> ink 10.7:1
     .ledger-badge   WAS listed here and that fix was WRONG -- see below.
     .res-case-type  gold on a white card         1.65:1  -> gold-ink 6.9:1
   ========================================================================= */
.hp-num-l { color: var(--ink); }

.ctable-us th,
.ctable-us td { color: var(--ink); }

/* The plain .ctable-us selector above is (0,2,0) and LOSES to
   `.compare-table tbody th` at (0,2,1), which sets colour: var(--white) --
   white text on the gold highlight row. Matching the descendant chain bumps
   specificity to (0,3,1) and wins. */
.compare-table tbody .ctable-us th,
.compare-table tbody .ctable-us td { color: var(--ink); }

/* CORRECTION. This badge already carries background:var(--gold) at
   components.css:984. An earlier contrast pass recoloured the TEXT to gold,
   producing gold-on-gold at 1:1 -- completely invisible, 9 instances on
   work.html. The pass misread the badge as sitting on a near-black backdrop
   when it sits on its own gold fill. Ink on gold measures 10.0:1. */
.ledger-badge { color: var(--ink); }

.res-case-type { color: var(--gold-ink); }

/* =========================================================================
   FONT AWESOME ICONS
   The site used hand-written inline <svg> icons. They are now Font Awesome 6
   Free classes. Font Awesome renders via ::before on an <i>, so it needs
   explicit sizing and alignment -- without these the glyphs sit on the text
   baseline and the button arrows drop below centre.

   The industry marks kept their .ind-icon class so the existing block rules
   that size and colour them keep working.
   ========================================================================= */
i.fa-solid, i.fa-regular, i.fa-brands {
  display: inline-block;
  font-style: normal;
  font-variant: normal;
  line-height: 1;
  text-rendering: auto;
}

/* Button / link arrows: sized to the button's cap height and optically centred. */
/* Keyed on "an icon inside a control", not on fa-solid specifically. The
   old selector listed fa-solid only, so the contact submit button -- which
   uses fa-regular fa-copy -- matched nothing and inherited the button's
   full font-size. It rendered at 16.2px beside 13.28px icons in every other
   button. Listing families meant adding a new family silently reintroduced
   the mismatch. */
.button i[class*="fa-"],
a i[class*="fa-"],
button i[class*="fa-"] {
  font-size: 0.82em;
  vertical-align: -0.06em;
  transition: transform var(--med) var(--ease);
}
.button:hover i.fa-arrow-right { transform: translateX(3px); }

/* The standalone copy control in the calculator output. */
.return-copy i.fa-regular,
[data-copy-return] i.fa-regular { font-size: 0.9em; vertical-align: -0.04em; }

/* Industry marks. The pre-existing rule at components.css:2736 already sets
   .ind-icon to 32x32 display:block, which is exactly the box the old <svg>
   occupied. Inherit that box so swapping <svg> for <i> does not shift the
   layout -- only centre the FA glyph inside it. */
i.ind-icon {
  width: 32px; height: 32px;
  font-size: 24px;
  line-height: 32px;
  text-align: center;
}

/* The line under the tier cards that tells the reader the tiers are built from
   the same service list as the builder. Without it the claim is invisible. */
.tier-source {
  margin: clamp(20px, 2.4vw, 30px) auto 0;
  max-width: 62ch;
  text-align: center;
  color: var(--on-dark-dim);
  font-size: 0.92rem;
  line-height: 1.6;
}
  .calc-range,
  .roi-range,
  .slider-field input[type="range"],
  input[type="range"] {
    height: 44px;
  }
  .slider-field input[type="range"]::-webkit-slider-runnable-track,
  input[type="range"]::-webkit-slider-runnable-track { height: 6px; }
  .slider-field input[type="range"]::-moz-range-track,
  input[type="range"]::-moz-range-track { height: 6px; }
  .slider-field input[type="range"]::-webkit-slider-thumb,
  input[type="range"]::-webkit-slider-thumb {
    width: 26px; height: 26px; margin-top: -10px;
  }
  .slider-field input[type="range"]::-moz-range-thumb,
  input[type="range"]::-moz-range-thumb { width: 26px; height: 26px; }
@media (max-width: 900px) {
  .cart-clear {
}

    min-height: 44px;
    display: flex; align-items: center; justify-content: center;
    padding: 10px 4px;
  }
  /* Fixed 248px, NOT a vh calc. The header's height tracks viewport WIDTH
     (it jumps when the desktop nav appears) and not height, so any vh term
     mispredicts it: at 1280x800 a 26vh term gives 208px against a 212px
     header. 248px clears the tallest measured header (230px at 6016) at every
     width and height from 821px up.
     This also fixes an in-page-anchor fault the first version had: at 1024px
     the old media query did not apply, so scroll-padding-top stayed at the
     base 172px against a 184px header and #engagements / #comparison landed
     12px BEHIND the header. */
@media (max-width: 900px) {
  .page-head { padding-top: 248px; }
}

  html { scroll-padding-top: 248px; }


/* =========================================================================
   LEDGER BADGE (the <p> variant) -- must stay LAST.
   components.css:992 sets `.ledger-rows p { color: var(--on-dark-dim) }` at
   specificity (0,1,1), which beats `.ledger-badge` at (0,1,0). The badge still
   carries background:var(--gold) from the base rule, so those five <p>
   badges rendered 58% white on gold at 1.37:1. Raise the specificity so the
   gold fill always gets ink text: 10.0:1.
   ========================================================================= */
.ledger-rows p.ledger-badge,
.ledger-rows article p.ledger-badge {
  color: var(--ink);
}

/* =========================================================================
   404 page. Added because the site had no 404.html, so a mistyped or retired
   URL returned the bare host default instead of anything on-brand. Lists every
   real page, because the failure mode for a client site is "I followed a link
   you sent and hit nothing".
   ========================================================================= */
.err-map {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
  gap: 1px;
  background: var(--rule-dark);
  border: 1px solid var(--rule-dark);
  margin: 0 0 clamp(40px, 5vw, 72px);
}
.err-link {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: clamp(16px, 1.6vw, 22px) clamp(16px, 1.8vw, 24px);
  background: var(--carbon);
  color: var(--on-dark);
  text-decoration: none;
  border: 0;
}
.err-link:hover,
.err-link:focus-visible { background: var(--carbon-2, #16202a); }
.err-link-name {
  font-family: var(--display);
  font-variation-settings: "wght" 700, "wdth" 96;
  font-size: 1.02rem;
  color: var(--gold);
}
.err-link-note {
  font-size: .86rem;
  line-height: 1.5;
  color: var(--on-dark-dim);
}


/* =========================================================================
   LIGHT-SURFACE <strong> OVERRIDE.
   styles.css:127 declares `strong { color: var(--white) }` globally, so every
   <b>/<strong> is forced white regardless of its backdrop. That is correct on
   the dark carbon sections, but it silently breaks on any light band: the gold
   .robots section was rendering its <strong> at 1.8:1 on gold -- effectively
   invisible. The earlier contrast sweep missed it because its element list
   omitted `strong`. Any light-surface block must now opt back in.
   ========================================================================= */
.robots strong,
.robots b { color: inherit; }

/* =========================================================================
   HOME PAGE REBUILD — 2026-10
   Four sections redone against the Impeccable craft floor. Each note says
   what was wrong and why the replacement is different.

   1. EVIDENCE LEDGER (replaces the hero-metric grid)
      The old strip was four cards of big-number / small-label / attribution
      tag — the hero-metric template, which is the most recognisable
      AI-generated layout there is, and it repeated three figures that appear
      again further down. Now one continuous sentence: figures set inline at
      display weight, labels in body case, attribution as a small tag. It
      reads as a claim being made, not a scoreboard being displayed.
   ========================================================================= */
.band-ledger {
  max-width: var(--maxw); margin: 0 auto;
  padding: clamp(18px, 2vw, 26px) var(--gutter);
  /* Flex, not a bordered row. The first pass put border-right on every item,
     which broke the moment the line wrapped: a separator dangled at the end of
     row one and "90 days to first system live" sat alone on row two. The
     attribution tags already separate the items, so the rule was doing nothing
     except breaking. Gap carries the rhythm instead. */
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: clamp(10px, 1.2vw, 20px) clamp(16px, 2.4vw, 44px);
  font-size: clamp(.88rem, 1.02vw, 1.02rem); line-height: 1.5;
  color: var(--on-dark-dim);
}
.band-ledger .led { display: inline-flex; align-items: baseline; gap: .5em; }
.band-ledger b {
  font-family: var(--heading); font-weight: 700;
  font-size: 1.5em; line-height: 1; color: var(--white);
  letter-spacing: -0.02em; white-space: nowrap;
}
.band-ledger .tag { font-size: .62em; white-space: nowrap; }
@media (max-width: 900px) {
  .band-ledger { flex-direction: column; gap: 12px; }
  .band-ledger .led { flex-wrap: wrap; }
}


/* =========================================================================
   2. THE THREE TRAITS
      The heading forced a line break that stacked one clause on top of
      itself, and the three traits it promised were buried inside a run-on
      paragraph. The list is now the structure. Numbering is earned here: the
      sequence IS three specific things, so a count carries information rather
      than decorating.
   ========================================================================= */
/* Was a 1px-gap card grid with a rule-coloured background. When the three
   traits became tabs, those declarations survived and the tablist landed in
   the first grid cell with the panel in the second -- so the control floated
   to the left of its own content, the panel was clipped at the cell edge, and
   the 1px gap rules read as a grey slab behind both. It is a block now. */
.traits {
  margin: clamp(26px, 3.2vw, 48px) 0 0;
  display: block;
}






/* The payoff line. "That is the whole business" was an orphan paragraph in
   the middle of a run-on; it is now the closing sentence of the argument and
   the emphasis sits on the second half, not the first. */
.accent-line {
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(1.42rem, 3.1vw, 2.5rem); line-height: 1.12;
  letter-spacing: -0.026em; color: var(--ink);
  /* 24ch wrapped as "That / is the whole business." -- splitting the emphasis
     across lines is the one thing this line must not do. 38ch holds the whole
     closing sentence on one line at every width this section is read at. */
  max-width: 38ch; margin: clamp(30px, 3.8vw, 58px) 0 0;
  text-wrap: balance;
}
.accent-tail { color: var(--gold-ink, #8a5c00); }

/* =========================================================================
   3. EVIDENCE BLOCK
      Two dense paragraphs with the single largest divider buried mid-sentence.
      Reordered so 74% vs 25% leads as a paired figure, the rest follows as
      prose, and the citations become a compact source row rather than a
      bulleted list floating under the argument.
   ========================================================================= */
.evidence-block { margin-top: clamp(38px, 4.6vw, 72px); }
.evidence-inner {
  border-top: 1px solid var(--rule-light);
  padding-top: clamp(22px, 2.6vw, 34px);
}
.ev-lead {
  display: flex; flex-wrap: wrap; gap: clamp(18px, 3vw, 56px);
  align-items: flex-end; margin-bottom: clamp(18px, 2.2vw, 28px);
}
.ev-figure { margin: 0; display: flex; flex-direction: column; gap: .18em; max-width: 20ch; }
.ev-figure b {
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(2.6rem, 5.4vw, 4.4rem); line-height: .88;
  letter-spacing: -0.03em; color: var(--ink);
}
.ev-figure span { font-size: .94rem; line-height: 1.45; color: var(--on-light-dim); }
.ev-figure-alt b { color: var(--on-light-dim); }
.evidence-inner p { font-size: 1.02rem; line-height: 1.68; color: var(--on-light-dim); max-width: 62ch; }
.ev-src {
  list-style: none; margin: clamp(18px, 2vw, 26px) 0 0; padding: 0;
  border-top: 1px solid var(--rule-light); padding-top: 14px;
  display: grid; gap: 4px;
  font-family: var(--mono); font-size: .72rem; line-height: 1.5;
  letter-spacing: .02em; color: var(--ink-muted);
}
.ev-src em { font-style: italic; }

/* =========================================================================
   4. PHASE RAIL
      The console cycles one phase at a time, so a visitor who did not watch
      it loop saw a quarter of the method. The rail states all five at a
      glance, each with what it produces, and the console becomes the live run
      of a method you can already read in full.
   ========================================================================= */
.method-split {
  display: grid; gap: clamp(24px, 3vw, 44px);
  grid-template-columns: minmax(0, 1.25fr) minmax(0, .75fr);
  align-items: start;
  margin-top: clamp(26px, 3.2vw, 46px);
} .method-split { grid-template-columns: 1fr; }

.phase-rail {
  list-style: none; margin: 0; padding: 0;
  border-top: 1px solid var(--rule-dark);
}
.phase-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "n name" ". out";
  gap: 0 clamp(12px, 1.4vw, 18px);
  padding: clamp(13px, 1.5vw, 18px) 0;
  border-bottom: 1px solid var(--rule-dark);
}
.phase-item b {
  grid-area: n;
  font-family: var(--mono); font-size: .72rem; font-weight: 700;
  color: var(--gold); padding-top: .34em; letter-spacing: .06em;
}
.phase-name {
  grid-area: name;
  font-family: var(--heading); font-weight: 700;
  font-size: 1.04rem; line-height: 1.2; color: var(--white);
}
.phase-out {
  grid-area: out;
  font-size: .86rem; line-height: 1.45; color: var(--on-dark-dim);
}


/* Method heading balance. .method-head is a two-column grid; the h2 column
   came out 676px, which set "The method, named and in public" as three ragged
   lines ("THE METHOD, / NAMED AND / IN PUBLIC") while the subhead sat far to
   the right. Widen the heading column, balance the wrap, and stop the subhead
   from drifting to the baseline of a three-line block. */
.method-head { grid-template-columns: minmax(0, 1.45fr) minmax(0, .55fr); align-items: end; }
.method-head h2 { text-wrap: balance; }
@media (max-width: 900px) {
  .method-head { grid-template-columns: 1fr; align-items: start; }
}



/* =========================================================================
   CLIENTS PAGE REBUILD
   Follows the same pattern as the home-page evidence block: a row of figures,
   then prose underneath in its own band. The old version put the note in a
   fourth grid column, which collapsed to roughly one word per line and clipped
   at 1440px.

   The roster was a grid of <li> pretending to be a table, with its column
   labels marked aria-hidden -- assistive tech got an unlabelled list of 51
   rows. It is tabular data, so it is a table, and the browser-default figures
   are themed from the palette rather than left to chance.
   ========================================================================= */
.tally-inner { display: block; }
.tally-row {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 3vw, 48px);
  align-items: end;
}
.tally-stat { min-width: 0; }
.tally-num { margin-bottom: 8px; }
.tally-label { max-width: 20ch; }
.tally-notes {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(18px, 3vw, 56px);
  margin-top: clamp(24px, 3vw, 44px);
  padding-top: clamp(18px, 2.2vw, 26px);
  border-top: 1px solid var(--rule-dark);
}
.tally-note { font-size: .88rem; line-height: 1.62; color: var(--on-dark-dim); margin: 0; max-width: 52ch; }
.tally-note i { font-style: italic; color: var(--on-dark); }
@media (max-width: 900px) {
  .tally-row { grid-template-columns: 1fr; gap: 22px; }
  .tally-notes { grid-template-columns: 1fr; }
  .tally-label { max-width: none; }
}


/* ---- the roster table -------------------------------------------------- */
.roster-wrap {
  margin-top: clamp(22px, 2.8vw, 40px);
  overflow-x: auto;                      /* 5 columns cannot shrink below legibility */
  -webkit-overflow-scrolling: touch;
}
.roster {
  width: 100%; min-width: 680px;
  border-collapse: collapse;
  text-align: left;
}
.roster thead th {
  font-family: var(--mono); font-size: var(--micro, .69rem); font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase;
  color: var(--on-dark-faint);
  padding: 0 clamp(12px, 1.4vw, 20px) 12px;
  border-bottom: 1px solid var(--rule-dark);
  white-space: nowrap;
}
.roster thead th:first-child { padding-left: 0; }
.roster tbody th, .roster tbody td {
  padding: clamp(11px, 1.3vw, 15px) clamp(12px, 1.4vw, 20px);
  border-bottom: 1px solid rgba(255,255,255,.09);
  vertical-align: baseline;
}
.roster tbody th { font-weight: 500; }
.roster tbody tr:first-child th, .roster tbody tr:first-child td { padding-top: 18px; }
.roster tbody tr:last-child th, .roster tbody tr:last-child td { border-bottom: 0; }
.roster tbody th {
  font-family: var(--heading); font-weight: 700; font-size: 1.02rem;
  line-height: 1.25; color: var(--white);
}
.roster td { font-size: .92rem; color: var(--on-dark-dim); }
.roster .roster-year {
  font-variant-numeric: tabular-nums;   /* years are compared down the column */
  white-space: nowrap;
}
.roster-undated { font-style: italic; color: var(--on-dark-faint); }
.roster-tag {
  display: inline-block;
  font-family: var(--mono); font-size: .62rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink); background: var(--gold);
  padding: .25em .6em; border-radius: 2px;
  white-space: nowrap;
}
.roster tbody tr:hover th, .roster tbody tr:hover td { background: rgba(255,182,18,.045); }
@media (max-width: 900px) {
  .roster { min-width: 560px; }
  .roster tbody th { font-size: .96rem; }
}



/* =========================================================================
   PROOF STRIP — fourth pass
   Two earlier versions still built the banned hero-metric template (a large
   figure, a small label, an accent tag). This is now four parallel clauses of
   running prose. The attribution that used to be a badge is grammar instead:
   "built from zero in-house", "deleted". Nothing is displayed for its own sake,
   so the strip cannot drift back into a row of scoreboard numbers.
   ========================================================================= */
/* Runs as one flowing sentence across the container measure. The first pass set
   four clauses as stacked rows in a 44ch column, which left roughly 500px of
   dead space to the right at 1440 and read as an unresolved box rather than a
   deliberate one. Only the figures are marked, so the eye takes the numbers and
   the sentence carries everything else. */
.band-claim {
  max-width: 74ch;                       /* body measure floor is 65-75ch */
  margin: 0 auto;
  padding: clamp(22px, 2.4vw, 34px) var(--gutter);
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(1.06rem, 1.34vw, 1.34rem);
  line-height: 1.42; letter-spacing: -0.012em;
  color: var(--on-dark-dim);
  text-wrap: pretty;
}
.band-claim span {
  color: var(--white);
  /* The figure takes the gold so it can be found without reading the sentence.
     Weight, not colour alone, carries the emphasis -- the surrounding text is
     already the same face and size, so the colour is redundant reinforcement
     rather than the only signal. */
  color: var(--gold);
  white-space: nowrap;
} .band-claim { max-width: none; }

/* =========================================================================
   EVIDENCE — 74% and 25% are now a comparison in a sentence rather than two
   displayed figures with captions under them, which was the same banned shape
   for the second time in this one section.
   ========================================================================= */
.evidence-body {
  margin-top: clamp(20px, 2.4vw, 32px);
  display: grid; gap: clamp(12px, 1.5vw, 20px);
  max-width: 68ch;
}
.evidence-body p { font-size: 1.04rem; line-height: 1.7; color: var(--on-light-dim); margin: 0; }
.ev-src {
  list-style: none; margin: clamp(22px, 2.6vw, 34px) 0 0; padding: 14px 0 0;
  border-top: 1px solid var(--rule-light);
  font-family: var(--mono); font-size: .7rem; line-height: 1.6;
  letter-spacing: .015em; color: var(--ink-muted);
  max-width: 78ch;
}
.ev-src em { font-style: italic; }
.ev-cta { margin: clamp(16px, 2vw, 26px) 0 0; }
.ev-cta a {
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(1rem, 1.2vw, 1.14rem);
  color: var(--ink); text-decoration: none;
  border-bottom: 2px solid var(--gold-ink, #8a5c00);
  padding-bottom: 2px;
  transition: border-color .18s ease;
}
.ev-cta a:hover { border-bottom-color: var(--ink); }


/* =========================================================================
   1. HERO EVIDENCE RAIL
   Was a standalone strip between the hero and the manifesto. It is now the
   base of the hero, where "prove it" is the question the visitor actually has
   before scrolling. The label is set as a rail caption, not a kicker: the
   craft floor bans an eyebrow above a heading, and this is a caption on a data
   rail rather than a label announcing the headline below it.
   ========================================================================= */
.hero-evidence {
  position: relative; z-index: 2;
  margin-top: clamp(30px, 4vw, 58px);
  padding-top: clamp(16px, 1.8vw, 24px);
  border-top: 1px solid rgba(255,255,255,.16);
  max-width: 76ch;
}
.hero-evidence-label {
  font-family: var(--mono); font-size: .66rem; font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 .7em;
}
.hero-evidence .band-claim { padding: 0; margin: 0; max-width: none; font-size: clamp(.98rem, 1.16vw, 1.16rem); }

/* =========================================================================
   2. TRAIT + EVIDENCE TABS
   The three traits were prose columns and the evidence was a wall of figures
   underneath that appeared to support all three and therefore supported none.
   One component: the trait is the control, and selecting it reveals only the
   figure that bears on it. Full ARIA tabs with roving tabindex.
   ========================================================================= */
.traits { margin-top: clamp(26px, 3.2vw, 48px); }














.evidence-body { font-size: 1.04rem; line-height: 1.7; color: var(--on-light-dim); margin: clamp(18px, 2.2vw, 28px) 0 0; max-width: 68ch; }

/* =========================================================================
   3. THE CONSOLE, WITH THE METHOD INSIDE IT
   Heading, subhead, five phases and the follow link were a separate block
   beside the console, so the section read as "some text" and "a demo". The
   method is the console now -- the phases are its job list and the heading is
   its title.
   ========================================================================= */
.console-h {
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(1.5rem, 2.9vw, 2.5rem); line-height: 1.06;
  letter-spacing: -0.026em; color: var(--white);
  margin: 0 0 .5em; text-wrap: balance;
}
.console-head {
  padding: clamp(18px, 2.2vw, 30px) clamp(18px, 2.2vw, 30px) clamp(16px, 2vw, 24px);
  border-bottom: 1px solid rgba(255,255,255,.09);
}
.console-sub {
  font-size: clamp(.94rem, 1.1vw, 1.04rem); line-height: 1.55;
  color: var(--on-dark-dim); margin: 0; max-width: 58ch;
}
.console-phases {
  list-style: none; margin: 0; padding: 0 clamp(18px, 2.2vw, 30px);
  border-top: 1px solid rgba(255,255,255,.09);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr));
}
.cphase {
  display: grid; grid-template-areas: "n name" ". out";
  gap: .1em clamp(10px, 1.2vw, 14px);
  padding: clamp(12px, 1.4vw, 17px) 0;
  border-bottom: 1px solid rgba(255,255,255,.07);
}
.cphase b {
  grid-area: n; font-family: var(--mono); font-size: .68rem; font-weight: 700;
  color: var(--gold); padding-top: .3em; letter-spacing: .06em;
}
.cphase-name {
  grid-area: name; font-family: var(--heading); font-weight: 700;
  font-size: .98rem; line-height: 1.2; color: var(--white);
}
.cphase-out { grid-area: out; font-size: .82rem; line-height: 1.42; color: var(--on-dark-dim); }
.console-follow { margin-top: clamp(20px, 2.4vw, 30px); }


/* =========================================================================
   WORDMARK
   The supplied assets/ol-wordmark-white.png rendered as "Driginal /
   pat!ur!" -- wrong letters, slanted, with bars struck through it, while the
   site text around it was upright. The alt attribute said "Original Limited",
   so assistive tech and crawlers got the right name and every sighted visitor
   got the garbled one. There was no vector source in the project; that PNG was
   the only wordmark.
   It is set live in Reeler now, which is the display face already self-hosted
   and already carrying every heading on the site. It cannot corrupt, it is
   sharp at any DPR, it inherits the font, and it drops 13KB. The two-line
   layout matches the PNG's own proportions (476x206). aria-hidden on the spans
   because the link already carries the full accessible name.
   ========================================================================= */


/* =========================================================================
   COUNT-UP DIVIDING BAND
   Its own section again, because that is what it is. The figures now climb from
   zero when the band first crosses into view -- the values they arrive at were
   always the point, and arriving instantly gave the eye nothing to do. The
   label under each figure stays a prose clause rather than a short caption, so
   this is still not a row of stat cards.
   ========================================================================= */
.band-nums {
  list-style: none; margin: 0;
  max-width: var(--maxw); margin-inline: auto;
  padding: clamp(30px, 4vw, 58px) var(--gutter);
  display: grid; gap: var(--gap-cell);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
}
.bnum { min-width: 0; position: relative; }
.bnum + .bnum::before {
  content: ""; position: absolute; left: calc(clamp(24px, 3vw, 48px) / -2);
  top: .15em; bottom: .2em; width: 1px; background: var(--rule-dark);
}
.bnum-n {
  /* Reduced from clamp(2.2rem, 4.6vw, 3.9rem). Once the icon moved inline it
     took a slice of a four-column grid, and at the old size the figures
     overran: 110,000+ collided with the neighbouring icon and "90 days"
     wrapped onto a second line, knocking that row off the others' baseline.
     Sized against the widest figure in the set, not the shortest. */
  display: inline;
  white-space: nowrap;
  font-family: var(--heading);
  font-weight: 700;
  font-size: clamp(1.55rem, 2.85vw, 2.7rem);
  line-height: .95;
  letter-spacing: -0.034em;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
  margin: 0;
}
.bnum-l {
  display: block;
  font-size: clamp(.88rem, 1.02vw, 1rem); line-height: 1.5;
  color: var(--on-dark-dim); max-width: 26ch;
}
/* icon and figure share one row; the label sits above the pair, not below it */
.bnum-fig { display: flex; align-items: baseline; gap: clamp(10px, 1vw, 16px); margin-top: .18em; }
/* The label above each figure runs to one line on three of the four and two on
   the fourth, which left the numbers sitting at two different heights in the
   same row. Column layout with the figure pushed to the bottom pins every
   figure to a shared baseline regardless of how its label wraps. */
.bnum { display: flex; flex-direction: column; }
.bnum-fig { margin-top: auto; }

.bnum-l { margin-bottom: .34em; }

@media (max-width: 900px) {
  .band-nums { grid-template-columns: 1fr; gap: 22px; }
  .bnum + .bnum::before { left: 0; top: calc(-22px / 2); bottom: auto; right: 0; width: auto; height: 1px; }
}


/* =========================================================================
   BENTO, ORIGAMI FACETS
   Opposing corner cuts so the cells read as folded planes rather than a grid of
   rectangles. Adjacent cells cut complementary corners so a fold line runs
   between them instead of ending in mid-air.
   ========================================================================= */
.bento-method {
  /* This is the "SIX CONNECTED MOVES" grid on the homepage -- the one AJ
     described as boxes "0px to 2px apart". It carried its own gap: 1px over
     a --rule-light backdrop, a second hairline grid that overrode the .bento
     rule further up the file. Real space between the facets, and the fold
     lines now belong to the cells rather than to the container. */
  display: grid; gap: var(--gap-cell);
  background: none;
  border: 0;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-top: clamp(26px, 3.2vw, 46px);
}
.bc {
  background: var(--paper, #f5f3ee);
  padding: 19px;
  min-width: 0;
  /* The fold. Two opposing corners, one long one short. clip-path removes the
     corner triangles, so a border would be clipped away with them -- the edge
     is carried by the folded silhouette itself. */
  clip-path: polygon(0 0, calc(100% - 22px) 0, 100% 22px, 100% 100%, 22px 100%, 0 calc(100% - 22px));
  transition: transform var(--med) var(--ease), background var(--med) var(--ease);
}
.bc:hover { transform: translateY(-3px); background: var(--white); }
/* The claim occupies the first column for two rows. Accountable spans the two
   remaining columns of row two -- at span 1 it left an empty cell, and because
   the 1px gaps are painted by the container's rule-coloured background, that
   empty cell rendered as a grey block roughly the size of a whole facet. The
   grid now fills completely. */
.bc-claim {
  grid-column: 1; grid-row: 1 / span 2;
  display: flex; flex-direction: column;
  background: var(--ink, #101820);
  clip-path: polygon(0 0, calc(100% - 34px) 0, 100% 34px, 100% 100%, 0 100%);
}
.bc-trait-wide { grid-column: 2 / span 2; }
.bc-evidence { grid-column: 1 / -1; }
.bc-label {
  font-family: var(--mono); font-size: .66rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 .9em;
}
.bc-claim p.bc-claim {
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(1.4rem, 2.6vw, 2.24rem); line-height: 1.1;
  letter-spacing: -0.028em; color: var(--white);
  margin: clamp(26px, 3vw, 48px) 0 .7em; text-wrap: pretty;
}
.bc-tail {
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(1.06rem, 1.7vw, 1.42rem); line-height: 1.16;
  letter-spacing: -0.02em; color: var(--gold);
  margin: auto 0 0;                 /* anchored to the foot of the facet */
  padding-top: 1.2em;
}
.bc-trait-name {
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(1.14rem, 1.9vw, 1.5rem); line-height: 1.08;
  letter-spacing: -0.022em; color: var(--ink);
  margin: 0 0 .45em;
}
.bc-trait-body { font-size: .93rem; line-height: 1.55; color: var(--on-light-dim); margin: 0 0 1em; }
.bc-fig {
  display: flex; align-items: baseline; gap: .5em; flex-wrap: wrap;
  margin: 0 0 .9em; font-size: .86rem; line-height: 1.5;
  color: var(--on-light-dim);
}
.bc-fig b {
  font-family: var(--heading); font-weight: 700;
  font-size: 2.05em; line-height: 1; letter-spacing: -0.03em;
  color: var(--gold-ink, #8a5c00); font-variant-numeric: tabular-nums;
}
.bc-fig b + b { font-size: 1.15em; }
.bc-src {
  font-family: var(--mono); font-size: .67rem; line-height: 1.55;
  letter-spacing: .015em; color: var(--ink-muted);
  margin: 0; padding-top: 11px; border-top: 1px solid var(--rule-light);
}
.bc-src em { font-style: italic; }
.bc-src-wide { max-width: 88ch; }
.bc-ev-text { font-size: 1.02rem; line-height: 1.68; color: var(--on-light-dim); margin: 0 0 1em; max-width: 74ch; }
.bc-cta { margin: 1em 0 0; }
.bc-cta a {
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(1rem, 1.2vw, 1.12rem);
  color: var(--ink); text-decoration: none;
  border-bottom: 2px solid var(--gold-ink, #8a5c00); padding-bottom: 2px;
  transition: border-color .18s ease;
}
.bc-cta a:hover { border-bottom-color: var(--ink); }
@media (max-width: 900px) {
  .bento-method { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .bc-evidence { grid-column: 1 / -1; }
  .bento-method { grid-template-columns: 1fr; }
  .bc-claim { grid-row: auto; }
  .bc-trait-wide { grid-column: auto; }
  .bc { transition: background-color .22s ease; }
  .bc:hover { background: #fbfaf7; }
  .bc-claim:hover { background: var(--ink, #101820); }
}



/* =========================================================================
   FOOTER WORDMARK
   Top-level and outside every media query on purpose. An earlier version of
   this rule was spliced into the middle of a @media block and inherited a
   stray "img" token from the rule it replaced, so the selector parsed as
   "img" token glued to the front of the selector, so it parsed as an unknown
   element followed by a class, matched nothing, and the whole declaration was
   dropped -- the footer mark silently fell back to Archivo at body size in dim
   grey. It is live Reeler, two lines, matching the header.
   ========================================================================= */




/* =========================================================================
   BRAND MARK — NOT REPRODUCED HERE ON PURPOSE

   assets/ol-wordmark-white.png is the approved logotype, exactly as supplied:
   not upside down, not mirrored, not distorted. The two copies of it are sized
   by rules that already existed before any review pass touched them:

     header  .brand .ol-wordmark     ->  height 132px, and the responsive ladder below it
     footer  img.footer-mark -> height 88px

   An earlier attempt added a `.brand .ol-wordmark` height rule here. It never applied:
   `.brand .ol-wordmark` is specificity (0,1,1) and outranks a bare `.brand .ol-wordmark` at
   (0,1,0), so the header stayed at its original 132px regardless. Nothing was
   resized, and no override is needed now that the <img> is back.

   Do not regenerate the asset and do not replace these <img> elements with
   live text. See the comments beside each <img> in partials/header.html and
   partials/footer.html.
   ========================================================================= */



/* =========================================================================
   IMAGE SLOT — PLACEHOLDER COMPONENT
   -------------------------------------------------------------------------
   A reserved space for artwork that does not exist yet. Drop an <img> inside
   a .img-slot and it replaces the hatch automatically.

   Designed to be obviously temporary: diagonal hatch in the site's own gold on
   carbon, a dashed rule, and a mono label naming what belongs there. It must
   never be mistakable for finished artwork, because shipping a hatch pattern
   as if it were a photograph is worse than shipping an empty box.

   Deliberately NOT styled like the surrounding content: it sits on its own
   plate so it reads as "unfilled", not as a design element.
   ========================================================================= */
.img-slot {
  position: relative;
  display: block;
  aspect-ratio: var(--slot-ratio, 16 / 10);
  margin: clamp(16px, 2vw, 24px) 0 0;
  border: 1px dashed var(--rule-gold);
  background-color: rgba(255, 182, 18, 0.035);
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(255, 182, 18, 0.10) 0 1px,
    transparent 1px 9px
  );
  overflow: hidden;
}
.img-slot::after {
  /* corner ticks, so the slot reads as a registered frame not a broken box */
  content: "";
  position: absolute; inset: 7px;
  border: 1px solid rgba(255, 182, 18, 0.16);
  pointer-events: none;
}
.img-slot-label {
  position: absolute; inset: auto 0 0 0;
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px;
  background: rgba(8, 12, 17, 0.82);
  border-top: 1px solid var(--rule-gold);
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--gold);
}
.img-slot-label::before {
  content: ""; width: 5px; height: 5px; flex: 0 0 5px;
  background: var(--gold); border-radius: 50%;
}
.img-slot-ratio {
  position: absolute; top: 9px; left: 10px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.12em;
  color: rgba(255, 182, 18, 0.5);
}

/* On-light variant. The default hatch was authored against the carbon claim
   cell and almost disappears on the cream trait cards -- the slot read as an
   empty box rather than a marked placeholder. Same construction, values
   swapped so the hatch is legible on whatever surface it sits on. */
.img-slot--on-light {
  border-color: rgba(16, 24, 32, 0.34);
  background-color: rgba(16, 24, 32, 0.022);
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(16, 24, 32, 0.13) 0 1px,
    transparent 1px 9px
  );
}
.img-slot--on-light::after { border-color: rgba(16, 24, 32, 0.10); }
.img-slot--on-light .img-slot-ratio { color: rgba(16, 24, 32, 0.44); }
.img-slot--on-light .img-slot-label {
  background: rgba(16, 24, 32, 0.06);
  border-top-color: rgba(16, 24, 32, 0.22);
  color: var(--gold-ink);
}
.img-slot--on-light .img-slot-label::before { background: var(--gold-deep); }

/* when real artwork arrives: <figure class="img-slot is-filled"><img …></figure> */
.img-slot.is-filled { border-style: solid; background-image: none; background-color: var(--carbon-deep); }
.img-slot.is-filled .img-slot-label,
.img-slot.is-filled .img-slot-ratio { display: none; }
.img-slot.is-filled::after { display: none; }
.img-slot.is-filled > img { display: block; width: 100%; height: 100%; object-fit: cover; }

@media (prefers-reduced-motion: no-preference) {
  .img-slot-label::before { animation: slotPulse 2.6s ease-in-out infinite; }
  @keyframes slotPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.3; } }
}
@media (prefers-reduced-motion: reduce) {
  .img-slot-label::before { animation: none; }
}

/* =========================================================================
   1. PROOF BAND — ICONS
   Font Awesome, self-hosted, so the glyphs are one drawn system at one weight
   rather than characters borrowed from the font's own symbol block.
   ========================================================================= */
.bnum-i {
  /* was a 1.16rem block on its own line above the figure. Now it sits inline
     with the number at a size that reads as a peer of it, not a caption.
     Optically nudged down to sit on the numeral baseline rather than the em box. */
  flex: 0 0 auto;
  font-size: clamp(1.15rem, 1.7vw, 1.6rem);
  line-height: 1;
  color: var(--gold);
  opacity: .9;
  transform: translateY(.06em);
}

/* =========================================================================
   2. ARCHIVE LEDGER — replaced four identical showcase cards
   A card grid was the page structure: four equal boxes of kicker, heading and
   text, which is the lazy container and carries no hierarchy. The engagements
   are a ledger instead — an ordered list ruled by hairlines, where the
   discipline reads as a tag in the margin and the title and verdict share a
   measure. The order is the argument, so it is an <ol>, and it is announced.
   ========================================================================= */
.archive {
  list-style: none; margin: clamp(26px, 3vw, 44px) 0 0; padding: 0;
  border-top: 1px solid var(--rule-dark);
}
.arch-row {
  display: grid; gap: clamp(6px, 1vw, 18px) clamp(20px, 3vw, 48px);
  grid-template-columns: minmax(0, 13ch) minmax(0, 1.15fr) minmax(0, 1fr);
  align-items: start;
  padding: clamp(18px, 2.1vw, 27px) 0;
  border-bottom: 1px solid var(--rule-dark);
}
.arch-tag {
  font-family: var(--mono); font-size: .69rem; font-weight: 700;
  letter-spacing: .13em; text-transform: uppercase;
  color: var(--gold); margin: 0; padding-top: .42em;
  line-height: 1.4;
}
.arch-title {
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(1.06rem, 1.5vw, 1.3rem); line-height: 1.16;
  letter-spacing: -0.021em; color: var(--white); margin: 0; text-wrap: pretty;
}
.arch-body { font-size: .95rem; line-height: 1.62; color: var(--on-dark-dim); margin: 0; max-width: 52ch; }
@media (max-width: 900px) {
  .arch-row { grid-template-columns: 1fr; }
  .arch-tag { padding-top: 0; }
  .arch-row { transition: background-color .2s ease; }
}


/* =========================================================================
   3. NOT-FOR LEDGER — replaced four identical cards
   These are exclusions, so they read as a plain two-column definition list:
   who it is for, and why it does not work. Dignified rather than struck
   through -- this section exists to save the reader a wasted month, not to
   shame them for asking.
   ========================================================================= */
.nfy-list { margin: clamp(26px, 3vw, 46px) 0 0; border-top: 1px solid var(--rule-dark); }
.nfy-row {
  display: grid; gap: clamp(8px, 1vw, 16px) clamp(24px, 4vw, 60px);
  grid-template-columns: minmax(0, 28ch) minmax(0, 1fr);
  align-items: baseline;
  padding: clamp(20px, 2.3vw, 30px) 0;
  border-bottom: 1px solid var(--rule-dark);
}
.nfy-name {
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(1.12rem, 1.8vw, 1.52rem); line-height: 1.1;
  letter-spacing: -0.024em; color: var(--white); margin: 0; text-wrap: pretty;
}
.nfy-why { font-size: .97rem; line-height: 1.66; color: var(--on-dark-dim); margin: 0; max-width: 66ch; } .nfy-row { grid-template-columns: 1fr; }


/* =========================================================================
   ARCHIVE — FEATURED + SUPPORTING
   Four equal ledger rows read as a table of contents: everything weighed the
   same, so nothing pulled. The portfolio engagement is the largest claim on
   the page, so it leads and carries the figures; the other three support it as
   ruled rows. The figures here are the same three the proof band counts up,
   which is the point -- the band is the hook, this is the receipt.
   ========================================================================= */
.archive { display: grid; gap: 0 clamp(28px, 3.4vw, 56px); grid-template-columns: minmax(0, 1.06fr) minmax(0, 1fr); align-items: start;
           margin: clamp(28px, 3.2vw, 48px) 0 0; }
.arch-lead { border-top: 1px solid var(--rule-dark); padding-top: clamp(20px, 2.2vw, 30px); }
.arch-lead-title {
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(1.5rem, 2.5vw, 2.12rem); line-height: 1.06;
  letter-spacing: -0.028em; color: var(--white);
  margin: 0 0 .7em; text-wrap: balance;
}
.arch-lead-body {
  font-size: 1rem; line-height: 1.64; color: var(--on-dark-dim);
  margin: 0 0 clamp(20px, 2.4vw, 32px); max-width: 50ch;
}
.arch-figures {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: clamp(14px, 1.8vw, 22px);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--rule-dark); padding-top: clamp(16px, 1.8vw, 24px);
}
.arch-figures li { min-width: 0; }
.arch-figures b {
  display: block;
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(1.42rem, 2.3vw, 2rem); line-height: .96;
  letter-spacing: -0.03em; color: var(--gold);
  font-variant-numeric: tabular-nums; margin: 0 0 .3em;
}
.arch-figures span {
  display: block; font-size: .8rem; line-height: 1.42; color: var(--on-dark-dim);
}
.arch-rest { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--rule-dark); }
@media (max-width: 900px) {
  .archive { grid-template-columns: 1fr; gap: clamp(28px, 5vw, 40px); }
  .arch-figures { grid-template-columns: 1fr; gap: 16px; }
}



/* The section intro sat in a narrow column with dead space beside the heading,
   while the three supporting rows underneath used the full measure. Same
   problem at two scales: the head gets a two-column rhythm so the paragraph
   sits opposite the title instead of trailing it in a thin measure. */
.proof-head {
  display: grid; gap: clamp(14px, 2vw, 48px);
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  align-items: end;
}
.proof-head p { max-width: 54ch; margin: 0; } .proof-head { grid-template-columns: 1fr; }


/* =========================================================================
   NEXT STEP — the shared exit
   Lives in the footer on every page. One gold action, the page's own wording,
   and the label says what happens rather than "click here". Sits above the
   newsletter so it reads as part of the page rather than an afterthought in
   the fine print.
   ========================================================================= */
.footer-next {
  /* Was a 2px gold border-top on a 10px-radius box. A thick accent on one
     edge of a rounded element fights the corner radius, and this one carried
     it for no information: the panel already has a gold CTA inside it. */
  max-width: var(--maxw); margin: 0 auto clamp(30px, 3.6vw, 48px);
  padding: var(--pad-card);
  border: 1px solid var(--rule-dark);
  border-radius: 10px;
}
.footer-next-label {
  font-family: var(--mono); font-size: .69rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--gold); margin: 0 0 .5em;
}
.footer-next-out {
  font-size: 1rem; line-height: 1.55; color: var(--on-dark-dim);
  margin: 0; max-width: 56ch;
}
.footer-next-btn { flex: 0 0 auto; }
@media (max-width: 900px) {
  .footer-next { grid-template-columns: 1fr; }
  .footer-next-btn { width: 100%; }
}



/* =========================================================================
   RESULTS LEDGER — 14 equal cards become two groups
   Sixteen <h2>s in one grid meant nothing read as more important than anything
   else, and the page's own caveat said the two Original Limited engagements are
   the ones getting the big figures. So they now lead, and the twelve in-house
   seniority figures sit behind them as what they are. Order carries the
   argument instead of fourteen peers.
   ========================================================================= */
.res-ledger { display: grid; gap: clamp(30px, 3.6vw, 52px); }
.res-group-head { margin: 0 0 clamp(16px, 2vw, 24px); max-width: 62ch; }
/* The results page is a LIGHT band (--paper), so this head takes the
   light-surface tokens. It first took the dark ones and rendered white on
   cream. Read the surface before picking the text token. */
.res-group-head h3 {
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(1.18rem, 1.9vw, 1.56rem); line-height: 1.12;
  letter-spacing: -0.024em; color: var(--ink); margin: 0 0 .38em;
}
.res-group-head p { font-size: .95rem; line-height: 1.6; color: var(--on-light-dim); margin: 0; }
.res-cards {
  display: grid; gap: var(--rule-1, 1px);
  background: var(--rule-dark);
  border: var(--rule-1, 1px) solid var(--rule-dark);
  border-radius: var(--r-md, 10px);
  overflow: hidden;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 232px), 1fr));
}
/* The two contracted engagements get more room and a gold figure. They sit on
   a dark surface inside a light band, so EVERY token inside them flips to the
   dark set. Setting only the background left --ink body copy sitting on
   --carbon-lift, which is what made the first attempt invisible. */
.res-group:first-child .res-cards { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.res-group:first-child .res-card {
  background: var(--c-carbon-lift, #17202b);
  color: var(--on-dark);
  --ink: var(--on-dark);
  --on-light-dim: var(--on-dark-dim);
  --gold-ink: var(--gold);
  --rule-light: var(--rule-dark);
}
.res-group:first-child .res-value { color: var(--gold); font-size: clamp(1.7rem, 3vw, 2.5rem); }
.res-group:first-child .res-label { color: var(--on-dark); }
.res-group:first-child .res-ctx { color: var(--on-dark-dim); }
.res-group:first-child .res-src { color: var(--on-dark-dim); }
.res-group:first-child .prov-tag { color: var(--gold); } .res-cards { grid-template-columns: 1fr; }


/* =========================================================================
   PROOF BAND — SOURCE LINE
   The homepage states $13.4M, 110,000+ and -41.6%; results.html carries the
   same figures with their sources and stage labels. Restating a number without
   saying where it is proved reads as a claim. One line names the source, so
   the headline does the work and results holds the proof.
   ========================================================================= */
.band-source {
  font-family: var(--mono); font-size: .74rem; line-height: 1.7;
  letter-spacing: var(--track-wide, .08em);
  color: #1b2530; margin: clamp(20px, 2.4vw, 30px) 0 0;
  max-width: 62ch;
  /* .proofband has no inner container. .band-nums supplies its own gutter via
     max-width + margin-inline:auto + padding, which is why the figures line up
     with every other band on the site. .band-source had none, so it rendered
     flush against the viewport edge at x=0 while the numbers above it sat at
     the gutter. Same gutter, same max-width, so the two align. */
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.band-source a {
  color: var(--gold); text-decoration: underline;
  text-underline-offset: 3px; text-decoration-thickness: 1px;
}
.band-source a:hover { color: var(--gold-bright, var(--gold)); }


/* =========================================================================
   JUMP RAILS — roster periods and case studies
   51 roster rows and six case studies at 7,774px is a lot of scrolling to
   discover. The rail is a flat ruled strip, not a pill row: it matches the
   ledger treatment used everywhere else rather than introducing a new shape.
   ========================================================================= */
.roster-jump { margin: 0 0 clamp(20px, 2.4vw, 30px); }
.roster-jump-label {
  font-family: var(--mono); font-size: .69rem; font-weight: 700;
  letter-spacing: var(--track-wide, .14em); text-transform: uppercase;
  color: var(--gold); margin: 0 0 .7em;
}
.roster-jump ul {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap;
  border-top: 1px solid var(--rule-dark); border-bottom: 1px solid var(--rule-dark);
}
.roster-jump li { border-right: 1px solid var(--rule-dark); }
.roster-jump li:last-child { border-right: 0; }
.roster-jump a {
  display: block; padding: 11px clamp(12px, 1.6vw, 20px);
  font-family: var(--mono); font-size: .8rem; font-weight: 700;
  letter-spacing: .08em; color: var(--on-dark-dim); text-decoration: none;
  transition: color .16s var(--ease, ease), background-color .16s var(--ease, ease);
}
.roster-jump a:hover, .roster-jump a:focus-visible {
  color: var(--carbon-deep); background: var(--gold);
}
/* the anchored row should read as the destination */
.roster tr:target > th, .narr:target .narr-num { color: var(--gold); } .roster-jump a { padding: 9px 13px; font-size: .74rem; }


/* =========================================================================
   FAQ GROUPS
   Ten questions rendering as a flat list reads as a filed document. Four named
   clusters make it a structured dataset a reader can navigate. The group head
   reuses the ledger rule rather than introducing a card shape.
   ========================================================================= */
.faq-group { margin: 0 0 clamp(28px, 3.2vw, 44px); }
.faq-group:last-child { margin-bottom: 0; }
.faq-group-h {
  font-family: var(--heading); font-weight: 700;
  font-size: clamp(1.06rem, 1.6vw, 1.32rem); line-height: var(--lead-snug, 1.12);
  letter-spacing: var(--track-snug, -0.02em); color: var(--gold);
  margin: 0 0 .3em;
}
.faq-group-b {
  font-family: var(--mono); font-size: .78rem; line-height: 1.65;
  letter-spacing: var(--track-wide, .06em); color: var(--on-dark-dim);
  margin: 0 0 4px;
  border-bottom: 1px solid var(--rule-dark); padding-bottom: 14px;
}


/* =========================================================================
   ROSTER — reclaim the dead right third
   The Note column carries a value on 15 of 51 rows (36 are empty), so the
   column stretched to ~35% of the viewport and left the table floating in
   dead space. The column stays -- the notes that exist are worth showing --
   but the table now occupies only what it uses, and the rail above it shares
   the same measure so the two read as one unit.
   ========================================================================= */
.roster { width: 100%; max-width: 1000px; }
.roster th:last-child, .roster td:last-child { width: 1%; white-space: nowrap; }
@media (max-width: 900px) {
  .roster { max-width: 100%; }
}

/* JS-off fallback for the brief form. Without this the visitor sees a dead
   form; with it they get the only route that still works, plainly stated.
   Deliberately NOT gold-on-dark at reduced size: this is an error state. */
.brief-noscript {
  border: 1px solid var(--gold);
  padding: clamp(20px, 3vw, 34px);
  margin-bottom: clamp(20px, 3vw, 32px);
  background: var(--carbon-lift);
  color: var(--on-dark);
  max-width: var(--measure, 68ch);
}
.brief-noscript h2 {
  font-family: var(--display);
  font-variation-settings: "wdth" 74, "wght" 840;
  font-size: clamp(1.1rem, 1.6vw, 1.35rem);
  color: var(--gold);
  margin: 0 0 10px;
}
.brief-noscript p { margin: 0 0 10px; line-height: 1.6; }
.brief-noscript-line { color: var(--on-dark-dim); font-family: var(--mono); font-size: .82rem; }

/* Legal block: entity, year, and client-mark attribution. Added 2026-10-04 --
   the footer named the city but never the entity or the year, which is the one
   thing a commercial LLC site is expected to state. */
.footer-legal {
  border-top: 1px solid var(--rule, rgba(255, 255, 255, .14));
  margin-top: clamp(28px, 4vw, 48px);
  padding-top: clamp(20px, 3vw, 30px);
  max-width: var(--measure, 68ch);
}
.footer-legal p {
  margin: 0 0 8px;
  font-family: var(--mono);
  font-size: .76rem;
  line-height: 1.7;
  color: var(--on-dark-dim);
}
.footer-copy { color: var(--gold); }


/* Hover: the mark takes the site's gold, as requested. Applied to the link
   so the whole mark responds, not just its painted path. */
.brand:hover .ol-wordmark,
.brand:focus-visible .ol-wordmark { color: var(--gold); }
.brand .ol-wordmark path { fill: currentColor; }

/* Footer mark shares the treatment at its own size. */
.footer-mark { height: 46px; width: auto; color: var(--on-dark); transition: color 240ms ease; }
.site-footer a:hover .ol-wordmark,
.site-footer a:focus-visible .ol-wordmark { color: var(--gold); }

/* ---------------------------------------------------------------------------
   No underline on the header nav. The travelling button is the hover
   affordance: it flies onto the word and covers it, so an underline drawn
   underneath is never seen and only ever doubled the signal.

   This lives at the end of the file deliberately. Two earlier attempts were
   declared mid-file at the same specificity as the rule that builds the
   ::after, so the later one won and the underline kept rendering. Source order
   is the whole fix here.
   --------------------------------------------------------------------------- */
.primary-nav a::after { content: none; }

/* ---------------------------------------------------------------------------
   The parked word must look like a WORD.

   Forcing `background: none` on `.primary-nav > a.nav-cta` is load-bearing.
   Two rules elsewhere still paint it as a gold button -- `styles.css`
   `.primary-nav .nav-cta` and this file's own `:not(.pill-on-cta)` /
   `:hover` / `:focus-visible` blocks. Because the button became a separate
   `.liquid-pill`, the anchor has to be plain text or the header shows TWO gold
   pills at once: one flying, one parked. That is exactly what the frame-by-
   -frame audit of the recorded run showed from frame 3 onward.

   It has to out-SPECIFY them, not out-order them. `styles.css` is linked
   after `components.css`, so putting this at the end of this file was not
   enough -- same specificity (0,2,1), later file wins. Prefixing `body`
   raises it to (0,2,2) and makes load order irrelevant.
   --------------------------------------------------------------------------- */
  body .primary-nav > a.nav-cta,
  body .primary-nav > a.nav-cta:hover,
  body .primary-nav > a.nav-cta:focus-visible,
  body .primary-nav > a.nav-cta:not(.pill-on-cta) {
    background: none;
    background-color: transparent;
    border: 0;
    box-shadow: none;
    transform: none;
    color: var(--white);
    text-decoration: none;
  }

/* ---------------------------------------------------------------------------
   Liquid goo layer on the travelling button.

   A ::before pseudo-element carries the goo so the button's real text, box
   metrics and width measurement are untouched -- wrapping the label in an SVG
   would break naturalWidth(), the centring, and white-space: nowrap all at
   once. The pseudo is absolutely positioned to cover the button, so it costs
   the layout nothing.

   Gold (#ffb612) is the primary body; white is the secondary highlight.
   The goo filter lives on the pseudo, NOT on the button -- filtering the
   button itself would rasterise its text every frame.
   --------------------------------------------------------------------------- */

/* ---------------------------------------------------------------------------
   Liquid silhouette.

   The goo lives in an SVG element BEHIND the pill, not as a filter on an
   HTML node. Two reasons, both load-bearing:

   1. Performance. CSS `filter: url(#...)` on an HTML element promotes it to
      its own rasterisation surface every frame whether or not the effect is
      visible. Running the goo on SVG content avoids that.
   2. Legibility. A filter on the pill would drag the label through
      feGaussianBlur + feColorMatrix and destroy the 12.48px uppercase tracked
      type. Here the text is real DOM, crisp, on top of the melt.

   The silhouette is sized and positioned from script.js every frame while
   travelling. It is hidden and its rAF loop cancelled at rest.
   --------------------------------------------------------------------------- */
  .ol-silhouette {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 2;
    /* overflow:hidden CONTAINS the goo. The filter region is
       x=-60% y=-90% width=220% height=280%, so its output always extends past
       the path; with overflow:visible that expanded output painted as faint
       diagonal lines across the header background.
       script.js sizes this box to the pill PLUS PAD on every side, and PAD(30)
       exceeds the goo bleed (stdDeviation 10 needs ~20px), so clipping here cuts
       nothing that should be visible -- it only stops the bleed. */
    overflow: hidden;
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    will-change: transform;
    overflow: visible;
  }
  .ol-silhouette.is-live { opacity: 1; visibility: visible; }

  /* The label is carbon, so it needs gold behind it at all times. Letting the
     pill's fill go transparent during travel painted dark text on a dark nav
     and the label vanished mid-flight. The silhouette sits BEHIND the pill,
     so the pill keeps a plain gold fill for the text and the melt reads as the
     fringe around it. */
  .primary-nav > .liquid-pill.is-travel,
  .primary-nav > .liquid-pill.is-burst { background: var(--gold); }

  /* ...but NEVER in outline mode. The travelling/burst gold fill was beating the
     outline treatment and painting a SOLID gold button in outline mode.
     MEASURED ON PIXELS: gold bbox 106px wide with 51 of 90 interior pixels gold
     -- FILLED, though computed style reported `rgba(0,0,0,0)`. So a computed-style
     check passed while the button was visibly solid (AJ: "in outline mode the
     button is empty and just a gold outline still"). The pill carries `is-travel`
     whenever it moves, including the idle hover it does while parked, so this
     state is reached constantly -- not only during a shot.
     `!important` because the competing rules share specificity and the cascade
     order had been resolving in the wrong direction. */
  .site-header.is-ghosted .primary-nav > .liquid-pill.is-travel,
  .site-header.is-ghosted .primary-nav > .liquid-pill.is-burst {
    background: transparent !important;
  }

/* ---- WebGL liquid surface ------------------------------------------------ */
.ol-glcanvas {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0;
  /* fades out when the pill parks */
  transition: opacity .22s ease-out;
  will-change: transform, opacity;
}
.ol-glcanvas.is-live { opacity: 1; }

/* ---- pull-back easter egg -------------------------------------------------
   A deliberately rare, discoverable-by-accident interaction. It must never
   look broken while idle, so nothing here changes until the button has
   actually been wound back against the logo. */


/* winding state: the button tightens up as it is pulled */

/* ---- yank-the-logo easter egg --------------------------------------------
   AJ's spec: the HEADER STAYS BLACK. Only the SVG wordmark goes gold, the
   button fuses with it, they rocket off the right edge, and a permanent
   wireframe ghost is left where they were.

   The ghost strokes the existing glyph geometry rather than swapping fill for
   stroke colour: a colour-only swap produces no true outline, and any OPEN
   path would disappear entirely under fill:none. The wordmark glyphs are
   closed letterforms, so stroking them yields a real wireframe.
   non-scaling-stroke keeps the hairline 1px regardless of the viewBox scale. */
.site-header .brand .ol-wordmark path,
.site-header .brand .ol-wordmark polygon,
.site-header .brand .ol-wordmark polyline {
  transition: fill .25s ease;
  fill: currentColor;
}

/* The wordmark goes gold as the button slides over it.
   Needs !important on BOTH the colour and the path fill: the wordmark carries
   fill="currentColor" and other header rules set .brand's colour, so setting
   color alone left the glyphs rendering white during the lock. */
/* locked: one fused gold mass */
html body .site-header .brand.is-logo-locked { color: var(--gold) !important; }
html body .site-header .brand.is-logo-locked .ol-wordmark path,
html body .site-header .brand.is-logo-locked .ol-wordmark polygon,
html body .site-header .brand.is-logo-locked .ol-wordmark polyline {
  fill: var(--gold) !important;
}


/* Charging state (placed AFTER is-logo-locked on purpose: at full wind BOTH classes are
   applied, and is-logo-locked's gold fill was winning the cascade, so the mark
   stayed gold and fused with the gold button -- the very bug this fixes): the mark rings up in gold, it does NOT fill gold.
   Filling it gold made the logo the exact same colour as the button -- and at
   full wind the button sits on top of the mark (logo x=72..247, button 8..137),
   so gold-on-gold fused into one unreadable blob and "Original Limited" vanished.
   A gold outline on a white fill keeps the charge legible underneath the button. */
html body .site-header .brand.is-logo-gold { color: #ffffff !important; }
/* Locking charges the button, NOT the mark.
   AJ: "as it locks and the mouse is over the logo the white svg logo gets a
   gold outline and it should not have an outline at this point."

   This rule previously stroked the wordmark gold at 1.6px, so hovering the mark
   drew a gold keyline around solid white letters. The charge reads from the
   button and the liquid surface instead; the mark stays clean white. */
html body .site-header .brand.is-logo-gold .ol-wordmark path,
html body .site-header .brand.is-logo-gold .ol-wordmark polygon,
html body .site-header .brand.is-logo-gold .ol-wordmark polyline {
  fill: #ffffff !important;
  stroke: none !important;
  stroke-width: 0;
}

.site-header .brand.is-logo-locked .ol-wordmark path {
  filter: drop-shadow(0 0 14px rgba(255, 182, 18, .55));
}
.primary-nav.is-locked .liquid-pill {
  background: var(--gold) !important;
  box-shadow: 0 0 22px rgba(255, 182, 18, .45);
  /* Outline mode must be pure line work: no fill, no bloom. Measured during an
     outline pull this rule painted a 22px gold glow around a hollow ring, which
     read as a lit solid button rather than an outline. */
  .site-header.is-ghosted .primary-nav.is-locked .liquid-pill { box-shadow: none; }
}

/* ---- the persistent outline state ----------------------------------------
   After the gag the header shows an OUTLINE logo and an OUTLINE button at
   their own resting spots, and STAYS that way. Nothing clears it except
   running the gag again.

   The button outline is gold; its label is WHITE -- including "Start a brief".
   It does not change colour on hover, unlike the logo which goes gold. */
.ol-ghost { position: fixed; inset: 0; z-index: 90; pointer-events: none; }

/* outline logo: white, gold on hover */
/* Outline logo -- fill is TRANSPARENT. Nothing is filled; the outline is the
   whole mark, so a faint body fill is wrong here.
   non-scaling-stroke resolves in DEVICE pixels, so weight does not shrink with
   the logo. 0.5px is the floor: the wordmark is ONE path with 26 closed
   subpaths, so every letter with a counter contributes an inner AND an outer
   contour, and anything heavier tangles. Lower stroke opacity keeps the tangle
   reading as a delicate trace instead of a blob. */
.ol-ghost-mark { position: fixed; pointer-events: auto; }
.ol-ghost-mark svg { width: 100%; height: 100%; display: block; }
.ol-ghost-mark path,
.ol-ghost-mark polygon,
.ol-ghost-mark polyline {
  fill: transparent;
  /* WHITE outline, not gold. AJ: "the outline mode logo needs to be a white
     outline not a gold outline like it is now."

     This was flipped to gold once because white at .82 opacity composited to a
     neutral grey (measured rgb(97,98,100)) and read as an artefact. That
     reasoning was wrong -- the grey came from the OPACITY, not from white
     itself. Opacity is now 1, so the stroke stays true white and pairs with the
     gold outline button as the brief describes. */
  stroke: #ffffff;
  stroke-width: 1.1;
  /* 1, not .9: the earlier low opacity was what desaturated the stroke to a
     neutral grey, and a thin line at that opacity is hard to read on the dark
     band. */
  stroke-opacity: 1;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  transition: stroke .25s ease, stroke-opacity .25s ease;
}
.ol-ghost-mark:hover path,
.ol-ghost-mark:hover polygon,
.ol-ghost-mark:hover polyline {
  fill: transparent;
  stroke: var(--gold);
  stroke-opacity: 1;
}

/* Outline button.
   This styles the LIVE .liquid-pill rather than a detached clone, so the
   outline button keeps the exact spring and rubber-band physics of the solid
   one and travels between the header words the same way. A clone would have
   been frozen at its parking spot. */
.site-header.is-ghosted .liquid-pill {
  opacity: 1;
  background: transparent;
  border: 1.5px solid var(--gold);
  box-shadow: none;
  /* NO LABEL. The outline frames the header word it sits on, and that word
     already prints its own text -- so a visible label here drew the same words
     twice, on top of each other. The pill keeps its measured width (which comes
     from its text) so the outline still sizes to the word correctly; only the
     ink is withheld. */
  color: transparent;
  -webkit-text-stroke: 0;
}
.site-header.is-ghosted .liquid-pill span,
/* ---- is-gone: the empty window between flight and outline ----------------
   For GONE_PAUSE_MS after the pair shoots off, the header is deliberately
   EMPTY -- no mark, no button, no liquid surface. Without this the header began
   restoring itself the instant the flight landed, which made it look like
   nothing had left at all. */
.site-header.is-gone .brand,
.site-header.is-gone .liquid-pill,
.site-header.is-gone .ol-glcanvas {
  opacity: 0 !important;
  visibility: hidden;
}
/* The empty window is the PAUSE only, not the fade. `is-gone` used to stay on
   for the whole 2s outline fade as well, which kept the outline button at
   opacity 0 the entire time -- the outline logo faded in but the outline button
   never appeared at all.
   The button must be free to fade UP once this class lifts. The solid mark does
   not need it, because `is-ghosted .brand` keeps the mark hidden throughout. */
.site-header.is-ghosted .ol-ghost,
.site-header.is-ghosted .ol-ghost-mark { opacity: 1; }
/* While the outline is fading in, the solid versions must STAY hidden.
   Previously `is-gone` was removed in the same tick that `is-ghosted` was added,
   so the solid wordmark and gold button snapped back to opacity 1 while the
   outline was still at 0 -- a visible flash of regular mode (AJ: "the logo and
   the button briefly flash back regular before going away").
   `transition: none` matters here: without it the opacity change is animated
   from whatever it was, which reintroduced the flash one frame later.

   NOTE: this hides the MARK ONLY. The outline button is not a separate element
   -- `.liquid-pill` IS the outline button in outline mode (same box, transparent
   fill, gold border), so hiding it here hid the outline button as well and it
   never faded in at all. It is excluded deliberately. The solid button is kept
   out of the way by `is-gone`, which covers the whole empty window instead. */
.site-header.is-ghosted .brand {
  opacity: 0 !important;
}

/* ---- solid -> outline crossfade (2s, both directions) --------------------
   `is-outgoing` fades the solid logo and button out over the same 2s that
   `is-ghosted` fades the outline versions in, so the header never snaps from
   one treatment to the other. The outline layers are already transparent at
   rest, so crossfading them in costs nothing until the class lands. */
.site-header .brand,
.site-header .liquid-pill {
  transition: opacity var(--ghost-fade, 2s) var(--ease);
}
.site-header.is-outgoing .brand,
.site-header.is-outgoing .liquid-pill { opacity: 0; }
/* `is-outgoing` alone must not leave the solid mark visible. It only drove
   opacity to 0 over 2s, which meant a fully opaque solid white logo sat in the
   header fading away -- the "brief flash back regular" AJ saw right after the
   shoot-off. Hide the element outright; the empty window is intentional, so
   there is nothing to crossfade FROM. */
.site-header.is-outgoing .brand,
.site-header.is-outgoing .liquid-pill { visibility: hidden; }

/* The nav words travel WITH the chain in outline mode, so they leave with it and
   return with it. Measured before this: word opacity sat at 1 through the entire
   empty window and the whole 2s fade, while the mark and button ramped 0 -> 1 --
   so the words were already fully present for the whole transition and the
   header reassembled out of order (AJ: "the words need to fade back in the time
   as the logo and button do to match").

   Only OUTLINE mode, because only there do the words fly off. In solid mode the
   words never leave, so they must stay put. `transition` matches the ghost mark's
   so both ramp on the same curve and finish together. */
/* Unscoped on purpose. Scoping the transition to `is-ghosted` broke the
   return-to-solid leg: that handler removes `is-ghosted` at the START of the fade
   (it has to, to bring the solid mark back), which stripped the transition in the
   same tick opacity changed, so the words snapped to full opacity instead of
   ramping. Measured: 10 frames of empty header, then an instant pop.
   Carrying the transition unconditionally means the ramp is available on BOTH
   legs, and the words only ever change opacity during the transition, so this has
   no effect on normal navigation. */
.site-header .primary-nav > a {
  /* `visibility` must step with NO delay. It is a discrete property, so it does
     not animate -- any duration/delay just defers the switch. Measured with
     `visibility 0s linear 2s`: the words ramped opacity 0 -> 1 across the whole
     fade while still visibility:hidden, then flipped visible at 1.00. Nothing
     was painted during the ramp, so the fade was invisible -- the words just
     appeared (AJ: "its fading but not correctly or in the right spot").
     `0s` with no delay switches visibility on the same frame opacity starts
     moving, so the ramp is actually seen. */
  transition: opacity var(--ghost-fade, 2s) var(--ease),
              visibility 0s;
}
/* NOT gated on `is-ghosted`. On the outline -> solid leg that class is removed at
   the START of the fade, because it has to be for the solid mark to come back --
   so a ghosted-scoped rule stopped applying and the words jumped straight from 0
   to 1 while the mark was still ramping (measured 12 mismatched frames).
   The words are hidden whenever the header is empty or outgoing, whichever mode
   the loop is in. `!important` so nothing later in the cascade can win. */
.site-header.is-gone .primary-nav > a,
.site-header.is-outgoing .primary-nav > a {
  opacity: 0 !important;
  visibility: hidden !important;
  /* Kill the transition while the header is empty. The words were re-seated at
     their resting positions on landing, so they must vanish in a single frame --
     not spend GHOST_FADE_MS fading OUT. Measured with the transition still live:
     the empty pause ran 849ms against a 500ms target, because the words were
     still on screen, dimming, for most of it.
     The rule is scoped to the empty/outgoing state only, so it lifts the moment
     is-gone clears -- which is precisely when the fade-IN starts, leaving the
     inbound ramp untouched. */
  transition: none !important;
}


.site-header.is-outgoing .ol-glcanvas { opacity: 0 !important; }

.site-header .ol-ghost,
.site-header .ol-ghost-mark {
  transition: opacity var(--ghost-fade, 2s) var(--ease);
}
/* The real mark must be fully hidden while the ghost one carries the outline,
   otherwise both draw at once for the length of the fade. */
.site-header.is-ghosted .brand { visibility: hidden; }
.site-header.is-ghosted .liquid-pill * { color: transparent !important; }
.site-header.is-ghosted .liquid-pill,
.site-header.is-ghosted .primary-nav.is-locked .liquid-pill { box-shadow: none !important; }
.site-header.is-ghosted .liquid-pill span { opacity: 1; }
/* The solid WebGL surface must not paint under the outline. It was still
   rendering behind the now-transparent pill, which is what made the outline
   button SPAZ rather than animate normally -- the molten blob and the spring
   were both driving visible pixels at once. */
.site-header.is-ghosted .ol-glcanvas { opacity: 0 !important; }
/* No transition on the travelling pill's MOTION: with the goo gone it must settle
   like the solid button does on first load, with no crossfade fighting it.
   `transition: none` here also killed the outline button's 2s fade-in -- the pill
   has to animate opacity from 0 to 1 as the outline arrives. So the motion
   properties are suppressed individually and opacity is left transitionable. */
.site-header.is-ghosted .liquid-pill {
  transition: transform .18s var(--ease), width .18s var(--ease) !important;
}
/* NOTE: an earlier version of this block forced `transform: translateY(-50%)`
   onto the parked outline button with !important, on the theory that the nav's
   centring needed help. It was the sole cause of the outline-mode drag clip:
   detachPill writes `transform:none` when the button starts moving, but this
   !important rule won, so the pill kept the -20px nav offset while position:fixed
   took it out of flow -- the ring travelled 20px high and eased back over .18s
   (measured T=59 -> 39 -> 59). Solid mode has no equivalent rule, which is
   precisely why only outline mode clipped. The parked button needs no help: it
   is never detached, so the nav's centring applies normally. */

/* The outline BUTTON must fade in over the same 2s as the outline logo. It was
   snapping to full opacity on the frame `is-gone` lifted, so the button was
   simply present while the logo was still ramping up. */
/* OPACITY ONLY -- never `transform`.
   An earlier version added `transform .18s` here so the outline button would
   fade in with the logo. It did fade, but transitioning `transform` also meant
   that when easter-egg.js wrote `transform:none` on the detach frame, the nav's
   translateY(-50%) eased to none over 180ms instead of applying instantly: the
   button rose 20px and sank back before behaving (measured T=59 -> 39 -> 59).
   Solid mode's transition list is `opacity 2s` only, which is why it never
   clipped. `transform` must stay untransitioned so the hand-off is a cut. */
.site-header.is-ghosted:not(.is-gone) .liquid-pill {
  transition: opacity var(--ghost-fade, 2s) var(--ease) !important;
}
   /* Must be !important. `.primary-nav.is-locked .liquid-pill` sets a solid gold
      background WITH !important, and an important declaration beats a normal one
      no matter which is later -- so locking in outline mode snapped the outline
      button back to solid gold. In outline mode the control stays an outline
      through the wind, the lock and the launch. */
.site-header.is-ghosted .liquid-pill {
  background: transparent !important;
  border: 1.5px solid var(--gold) !important;
  color: transparent !important;
}

/* The brand stands down (visibility only -- it must stay IN FLOW or the header
   reflows and the whole thing jumps). The .liquid-pill is NOT hidden: it IS the
   outline button now, styled above, and it must keep travelling. An older
   `opacity: 0` rule lived here and won over the outline styling, which left the
   nav showing bare words with no button at all in the outline state. */
.site-header.is-ghosted .brand { visibility: hidden; }
.site-header.is-ghosted .brand { color: inherit; }

/* ---- collapsed nav: the liquid pill has no job ---------------------------
   Below the breakpoint the header collapses to the hamburger menu ("Open
   navigation menu") and the nav row is pushed off-canvas. The pill was still
   being rendered there: measured at 1024px as a 26x40 gold blob at 0,70 and at
   390px as 26x40 at 390,422 -- both off the CTA and visibly wrong.

   With no visible nav row there is nothing to hover and nothing to frame, so
   the pill, its WebGL surface and the easter egg all stand down. The static
   CTA keeps working. */
@media (max-width: 1180px) {
  .primary-nav > .liquid-pill { display: none; }
  .site-header .ol-glcanvas { display: none; }
  .site-header.is-ghosted .brand { visibility: visible; }
  .site-header.is-ghosted .ol-ghost { display: none; }
}

/* The logo outline arrives 2s AFTER the button's, so the two read as separate
   events. It fades up rather than popping into place. */
.ol-ghost-mark--late {
  opacity: 0;
  animation: olGhostLate 1.1s ease forwards;
}
@keyframes olGhostLate {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.css-parse-sentinel { --css-parse-sentinel: 1; }
