/* =============================================================
   UNLOCK AI VALUE — Infosys kiosk
   V4 look and feel, from INF_FSM_GLO_359.2 in Figma.
   ============================================================= */

@import url('fonts.css');

:root {
  --display: 'Geist', 'Inter', 'Helvetica Neue', sans-serif;
  --body: 'Geist', 'Inter', 'Helvetica Neue', Helvetica, sans-serif;
  --label: 'Geist', 'Inter', 'Helvetica Neue', Helvetica, sans-serif;

  /* PAGE. The renders are flattened onto white, so the page has to be the same
     white or the seams show at the edge of a plate. */
  --page: #FFFFFF;

  /* TEXT. */
  --ink: #061838;         /* 16.6:1 on white */
  --deep: #01183B;        /* 16.3:1  lockup */
  /* The design's interactive blue. It measures 4.6:1 on pure white and 4.28:1
     over the washed renders, so it fails AA for text at body size. */
  --brand: #007CC3;       /*  4.6:1 on white - fills and accents only */
  --mid: #004C77;         /*  9.4:1  body copy, scale labels */
  --btn-ink: #00446D;     /* 10.4:1  controls */

  /* Legacy aliases; all resolve to light-ground values. */
  --fg: var(--ink);
  --fg-2: var(--mid);
  --fg-3: var(--btn-ink);
  --fg-4: #2E5C80;        /*  7.2:1  was 5.6, which read as hazed on the washes */
  --blue: var(--brand);
  --blue-lift: #0069A8;   /*  6.0:1  the blue that carries text on white */
  --blue-deep: #00568C;
  --ink-lift: #E8F2FB;    /* pale wash, was the dark ground's lift */
  --hair: rgba(0, 76, 119, 0.16);

  /* SURFACES, verbatim from the file. */
  --card: linear-gradient(76.16deg, rgba(156, 209, 255, 0.30) 3.09%, rgba(91, 165, 230, 0.09) 85.6%);
  --card-line: #FFFFFF;
  --card-shadow: 2px 4px 20px 5px rgba(0, 124, 195, 0.05);
  --pill-line: rgba(255, 255, 255, 0.9);
  --pill-shadow: 2px 4px 20px 0 rgba(0, 65, 108, 0.15);
  --pill-fill: linear-gradient(101.84deg, rgba(123, 194, 255, 0.25) 1.96%, rgba(0, 136, 255, 0.25) 100%);
  --pill-solid: #C9E3FF;   /* the pill fill flattened onto white: the hover for white pills */
  --radius: 20px;
  --radius-pill: 30px;

  /* The two white washes the design lays over every render, so type never sits
     on the busiest part of the glass. */
  --wash-top: linear-gradient(180deg, rgba(255,255,255,0.80) 25.19%, rgba(255,255,255,0) 86.02%);
  --wash-side: linear-gradient(270deg, rgba(255,255,255,0.80) 7.48%, rgba(255,255,255,0) 86.02%);

  /* Glass tokens, still read by a few panels. */
  --glass: rgba(255, 255, 255, 0.72);
  --glass-2: rgba(255, 255, 255, 0.60);
  --glass-line: rgba(255, 255, 255, 0.9);
  --glass-lip: rgba(255, 255, 255, 0.8);

  /* spacing scales with the stage, which is always 16:9 and width-driven */
  --s1: clamp(4px, 0.32cqw, 7px);
  --s2: clamp(8px, 0.62cqw, 13px);
  --s3: clamp(12px, 1.05cqw, 22px);
  --s4: clamp(18px, 1.70cqw, 34px);
  --s5: clamp(26px, 2.50cqw, 50px);
  --s6: clamp(34px, 3.60cqw, 74px);
  --s7: clamp(44px, 5.20cqw, 106px);

  /* The left gutter is the logo's own left edge (67 at 1920), so every column
     of copy starts on the same line as the lockup. */
  --pad-x: clamp(22px, 3.49cqw, 67px);
  --pad-t: clamp(46px, 6.40cqw, 116px);
  --pad-b: clamp(26px, 4.20cqw, 76px);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  /* Expo-out: leaves fast, lands slowly. Entrances only. */
  --ease-in-out-soft: cubic-bezier(0.16, 1, 0.30, 1);
  --ease-mech: cubic-bezier(0.65, 0, 0.35, 1);
}

/* ---------- copy panel -----------------------------------------
   Copy sits on a light surface; the surface repoints the text tokens inside it. */

* { box-sizing: border-box; margin: 0; padding: 0; }

/* 22 Sep: every font-size in this file is 1.07x the design's value ("slightly
   larger on all three kiosk widths"). The frame is 1920 wide and scaled by --k,
   so the bump carries to 1440 and 1280 with it. */
html, body {
  height: 100%;
  background: var(--page);
  color: var(--ink);
  font-family: var(--body);
  font-weight: 400;
  font-size: 17.1px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}

button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
input, textarea { font: inherit; }
:focus-visible { outline: 1px solid var(--blue-lift); outline-offset: 4px; }

/* ---------- stage ------------------------------------------- */

#shell { position: fixed; inset: 0; display: grid; place-items: center; background: var(--page); }
/* The stage fills the window; only the composition inside it is locked to 16:9. */
#stage {
  position: relative;
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  /* The room. Both stops are driven from JS per value pool, so entering a pool
     changes the whole space rather than just tinting the object. */
  /* White room: the renders are flattened onto white, so any other ground shows a seam at each plate edge. */
  --room-a: #FFFFFF;
  --room-b: #F4F9FE;
  background: radial-gradient(130% 95% at 30% 20%, var(--room-a) 0%, var(--room-b) 62%, #EDF5FC 100%);
  transition: background 900ms var(--ease);
  isolation: isolate;
}
/* Plates are finished artwork: normal blend, full strength. */
/* #bg is now a probe, never painted. */
#bg {
  position: absolute; inset: 0;
  background: center / cover no-repeat;   /* never painted: a probe for CSS */
  opacity: 0;
  pointer-events: none;
}
#bgA, #bgB {
  position: absolute; inset: 0;
  /* Full-bleed. The plates cover the whole window and the content stays on the
     16:9 #frame centred inside it. */
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: 0;
  pointer-events: none;
}
/* Two fixed roles rather than a ping-pong. #bgA is the plate on screen and is
   never animated; #bgB is the one arriving, and it fades in over the top. */
#bgA { transition: transform 700ms var(--ease); }
#bgB { transition: opacity 800ms cubic-bezier(0.37, 0, 0.63, 1), transform 700ms var(--ease); }
#bgA.on, #bgB.on { opacity: 1; }

/* ---------- the question film at 70%, in a blurred frame ----------
   22 Sep: the diagnostic picture (plate and film alike) is reduced by ~30% so it
   no longer fills the screen. What shows around it is #filmFrame: the same
   plate, full-bleed and blurred, so the frame is always the picture's own
   colour (app.js syncPlate keeps its image in step with #bgA/#bgB). The frame
   sits under the plates in the DOM; the plates and films scale over it. */
#filmFrame {
  position: absolute; inset: -4%;
  /* 22 Sep (Rob): plain white, no blurred copy of the plate — the blue haze it
     left at the bottom left is gone. The plate still arrives as --plate from
     app.js, so `var(--plate) center / cover` can go back here if wanted. */
  background: #FFFFFF;
  opacity: 0;
  pointer-events: none;
  transition: opacity 700ms var(--ease);
}
#stage[data-view='diag'] #filmFrame { opacity: 1; }
#stage[data-view='diag'] #bgA,
#stage[data-view='diag'] #bgB,
.bg-video[data-view='diag'] {
  /* 22 Sep (Rob): full-bleed again, 100% width and height, no reduction. The
     wash on #sideScrim keeps the copy legible. Set --film-scale below 1 (and
     a transform-origin) to shrink the picture into a frame again. */
  transform: scale(var(--film-scale, 1));
  transform-origin: 0% 100%;
}

/* The design lays two white washes over every render: a band down from the top
   at 25% height, and one in from the right edge across 46% of the width. */
/* z-index 1, not 2. These wash the RENDER so type can sit on it; they must never
   come between the plate and the content. */
#topScrim {
  position: absolute; inset: 0 0 auto 0; height: 25%;
  z-index: 1; pointer-events: none;
  opacity: 1;
  background: var(--wash-top);
}
/* The side wash follows the copy column, so it flips with the layout: the
   diagnostic reads on the right, the pool screens read on the left. */
#sideScrim {
  position: absolute; inset: 0 0 0 auto; width: 46%;
  z-index: 1; pointer-events: none;
  opacity: 0; transition: opacity 700ms var(--ease);
  background: var(--wash-side);
}
/* Only where the copy reads on the right and the view has no wash of its own. */
#stage[data-view='diag'] #sideScrim,
#stage[data-view='identify'] #sideScrim { opacity: 1; }
/* 22 Sep: on the question screen the wash is wider and runs to solid white at
   the right, so the question column always reads whatever the film is doing
   under it. It sits above the film and its blurred frame (z-index 1). */
#stage[data-view='diag'] #sideScrim {
  /* Starts at the right edge and reaches in over the picture's right side, so
     the film is veiled where it meets the copy rather than stopping short of it. */
  /* 22 Sep (Rob): the whole width. Solid white under the question column on
     the right, easing to a light veil that still sits over the film at the far
     left, so the picture reads softer everywhere and never fights the copy. */
  width: 100%;
  background: linear-gradient(270deg,
    #FFFFFF 0%, #FFFFFF 22%,
    rgba(255,255,255,0.94) 36%,
    rgba(255,255,255,0.72) 50%,
    rgba(255,255,255,0.46) 66%,
    rgba(255,255,255,0.28) 84%,
    rgba(255,255,255,0.18) 100%);
}

/* Every plate is now a baked 3D glass render from the design file, flattened
   onto white and shipped at the frame's own 1920 wide. */
/* The film is video/bg-start-1.mp4. */
#stage[data-view='attract']  #bg { background-image: url('../images/backgrounds/bg-start-1.jpg'); }
#stage[data-view='intro']    #bg { background-image: url('../images/backgrounds/bg-six-pools-1.jpg'); }
#stage[data-view='explore']  #bg { background-image: url('../images/backgrounds/bg-six-pools-2.jpg'); }
#stage[data-view='diag']     #bg { background-image: url('../images/backgrounds/bg-diagnostic-1.jpg'); }
#stage[data-view='identify'] #bg { background-image: url('../images/backgrounds/bg-results-access-1.jpg'); }

/* Opening a pool swaps to that pool's own render. */
#stage[data-view='explore'][data-pool='strategy'] #bg { background-image: url('../images/backgrounds/bg-six-pools-3.jpg'); }
#stage[data-view='explore'][data-pool='data']     #bg { background-image: url('../images/backgrounds/bg-six-pools-4.jpg'); }
#stage[data-view='explore'][data-pool='process']  #bg { background-image: url('../images/backgrounds/bg-six-pools-5.jpg'); }
#stage[data-view='explore'][data-pool='legacy']   #bg { background-image: url('../images/backgrounds/bg-six-pools-6.jpg'); }
#stage[data-view='explore'][data-pool='physical'] #bg { background-image: url('../images/backgrounds/bg-six-pools-7.jpg'); }
#stage[data-view='explore'][data-pool='trust']    #bg { background-image: url('../images/backgrounds/bg-six-pools-8.jpg'); }

/* The question plate follows the pool being asked about (app.js sets data-pool). */
#stage[data-view='cases'] #bg { background-image: url('../images/backgrounds/bg-results-2.jpg'); }
/* 22 Sep: the same calm plate as the results screens (see --plate-results). */
#stage[data-view='prio']  #bg { background-image: var(--plate-results); }
#stage[data-view='diag'][data-pool='strategy'] #bg { background-image: url('../images/backgrounds/bg-diagnostic-1.jpg'); }
#stage[data-view='diag'][data-pool='data']     #bg { background-image: url('../images/backgrounds/bg-diagnostic-2.jpg'); }
#stage[data-view='diag'][data-pool='process']  #bg { background-image: url('../images/backgrounds/bg-diagnostic-3.jpg'); }
#stage[data-view='diag'][data-pool='legacy']   #bg { background-image: url('../images/backgrounds/bg-diagnostic-4.jpg'); }
#stage[data-view='diag'][data-pool='physical'] #bg { background-image: url('../images/backgrounds/bg-diagnostic-5.jpg'); }
#stage[data-view='diag'][data-pool='trust']    #bg { background-image: url('../images/backgrounds/bg-diagnostic-6.jpg'); }
/* Part two rotates through the same set, one plate on from its pool. */
#stage[data-view='diag'][data-pool='strategy'][data-sub='1'] #bg { background-image: url('../images/backgrounds/bg-diagnostic-2.jpg'); }
#stage[data-view='diag'][data-pool='data'][data-sub='1']     #bg { background-image: url('../images/backgrounds/bg-diagnostic-3.jpg'); }
#stage[data-view='diag'][data-pool='process'][data-sub='1']  #bg { background-image: url('../images/backgrounds/bg-diagnostic-4.jpg'); }
#stage[data-view='diag'][data-pool='legacy'][data-sub='1']   #bg { background-image: url('../images/backgrounds/bg-diagnostic-5.jpg'); }
#stage[data-view='diag'][data-pool='physical'][data-sub='1'] #bg { background-image: url('../images/backgrounds/bg-diagnostic-6.jpg'); }
#stage[data-view='diag'][data-pool='trust'][data-sub='1']    #bg { background-image: url('../images/backgrounds/bg-diagnostic-1.jpg'); }

/* Nitin's note: soft, near-plain, blue on blue. */
/* Results and the closing screen use the calmest renders. */
/* Figma 550:1129 ships the results and closing screens on a plain blue-on-blue
   gradient with one soft diagonal sweep — no hexagon render. bg-results-1.jpg is
   byte-identical to bg-six-pools-2 and bg-thank-you-1, i.e. the generic plate,
   so the four screens are drawn here instead of pointing at it.
   Swap --plate-results for url(...) if the file's own export is dropped in. */
:root {
  --plate-results:
    linear-gradient(118deg, rgba(255,255,255,0.00) 26%, rgba(255,255,255,0.55) 44%, rgba(255,255,255,0.00) 58%),
    linear-gradient(118deg, rgba(255,255,255,0.00) 62%, rgba(255,255,255,0.30) 71%, rgba(255,255,255,0.00) 80%),
    radial-gradient(120% 90% at 18% 6%, #FAFCFE 0%, rgba(250,252,254,0) 62%),
    linear-gradient(168deg, #F4F9FD 0%, #EAF2FB 46%, #DEEBF8 100%);
}
#stage[data-view='wrap'][data-beat='1'] #bg { background-image: var(--plate-results); }
#stage[data-view='wrap'][data-beat='2'] #bg { background-image: var(--plate-results); }
/* Beat 3 has its own plate from the design (Figma 326:181) — the hexagon bubbles
   clear the centre band where the three cards sit. */
/* Figma 525:194 and 550:1129 sit on one and the same plate ("image 24"), so the
   ring screens do too: no blue wash on the last beat that the file does not have. */
#stage[data-view='wrap'][data-beat='3'] #bg { background-image: var(--plate-results); }
#stage[data-view='done'] #bg { background-image: var(--plate-results); }

/* Background films (.bg-video) and the scrim over them. They sit above the plates
   and below the canvas, so the 3D and all copy still render on top. The plate
   underneath stays put, so a film only ever fades in over its own still. */
.bg-video {
  /* Full-bleed, cropped by object-fit so the film never letterboxes. */
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity 800ms cubic-bezier(0.37, 0, 0.63, 1);   /* matches the plate fade */
}
/* .on is added by app.js once the film is actually playing, never before, so a
   film still buffering can never flash its poster or a black frame. */
.bg-video.on { opacity: 1; }
/* The diagnostic films are one-second moves that begin on their plate, so they
   cut in fast rather than spend the move fading. */
.bg-video[data-once] { transition-duration: 250ms; }
/* Q1 -> Q2 within a pool is a straight cut, not a fade: app.js adds this to the
   incoming film so it arrives at full opacity on the frame the outgoing one is
   already holding. */
.bg-video.film-cut { transition: none; opacity: 1; }
#bgVideoScrim {
  position: absolute; inset: 0;
  background: none;
  opacity: 0;
  pointer-events: none;
  transition: opacity 700ms var(--ease);
}
/* ---------- attract headline ---------------------------------- */
/* Blue sentence, ink accent; white clears the film's contrast. */
#v-attract .d-xl { color: var(--brand); }
#v-attract .d-xl em { color: var(--ink); }

#stage[data-view='attract'] #bgVideoScrim { opacity: 0; }

#gl { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* The particle layer. z-index stays auto so it keeps its DOM position: above the
   plates and the film, below the two white washes (z-index 1) and below #frame
   (z-index 2). */
#px {
  position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  pointer-events: none;
  opacity: 0; transition: opacity 900ms var(--ease);
}
#stage[data-view] #px { opacity: 1; }
/* Attract runs a film, which already has motion of its own. */
#stage[data-view='attract'] #px { opacity: 0.55; }
/* Off by default, on for exactly one screen. */
#gl { opacity: 0; transition: opacity 500ms var(--ease); }
#stage[data-view='explore']:not([data-pool]) #gl { opacity: 1; }
/* The canvas draws nothing visible but still catches taps, so it is switched off. */
#gl[hidden] { display: none; }

/* The design surface. */
#frame {
  position: absolute;
  z-index: 2;
  top: 0; left: 0;
  width: 1920px;
  height: 1080px;
  transform-origin: top left;
  /* Scaled to fit and centred, both set from JS. */
  transform: translate(var(--fx, 0px), var(--fy, 0px)) scale(var(--k, 1));
  container-type: size;
  container-name: stage;
  /* Transparent to input so the board under it can be touched. */
  pointer-events: none;
}

/* Below the frame so it never sits over the type. */
#grain {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  opacity: 0.035; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}
/* Gone. */
#vignette {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: none;
}

/* ---------- chrome: brand lockup only ----------------------- */

#chrome { position: absolute; z-index: 6; inset: 0; pointer-events: none; }
.bar.top {
  display: block;
  padding: 0;
}
/* The brand is also the way out: tapping it starts over. #chrome is
   pointer-events: none, so it has to opt back in. */
/* Figma 552:43: the logo alone at frame (67, 68), 95x35. Absolutely placed so
   the bar's padding cannot move it, the way .ai-mark is.
   22 Sep: grown to 44 high (was 35) to sit level with the AI Value mark, whose
   centre is at y 83.5; the top moves up so the two marks share a centre line. */
.brand {
  position: absolute; left: 57px; top: 53px;
  display: flex; align-items: center;
  pointer-events: auto; cursor: pointer;
  padding: 8px 10px; margin: 0;
  border-radius: 10px;
  transition: background 0.2s var(--ease);
}
.brand:active { background: rgba(0, 76, 119, 0.10); }
.brand:focus-visible { outline: 1px solid var(--blue-lift); outline-offset: 3px; }
/* The file's own #007CC3, the same blue as the AI Value mark on the right: no
   filter, so the two marks in the header are one colour. */
.brand img {
  /* Frame px, so it scales with the stage: the same share of the screen at 1920,
     1440 and 1280. */
  height: 44px; width: auto;
  /* On smaller screens the stage scale (--k) shrinks it; hold it at a readable
     36 real px (up to 1.6x its frame size) so it does not get lost. */
  height: max(44px, min(70px, calc(36px / var(--k, 1))));
  filter: none;
}
/* The Unlock AI Value mark at the far right of the header (Figma 552:58): 111x87
   at frame (1732, 40). Absolute so the bar's padding does not move it. */
/* Also a way home: whichever mark someone reaches for, it starts over. */
.ai-mark {
  position: absolute; left: 1732px; top: 40px; width: 111px; height: 87px;
  padding: 0; border: 0; background: none; border-radius: 12px;
  pointer-events: auto; cursor: pointer;
  transition: background 0.2s var(--ease);
}
.ai-mark img { display: block; width: 100%; height: 100%; object-fit: contain; }
.ai-mark:active { background: rgba(0, 76, 119, 0.10); }
.ai-mark:focus-visible { outline: 1px solid var(--blue-lift); outline-offset: 3px; }
/* 22 Sep: the first page carries the mark top right too, so the header is the
   same on every screen; the centred mark above the headline is retired. */
.attract-mark { display: none; }


/* One colour: --deep on every screen. */

/* ---------- views ------------------------------------------- */

#views { position: absolute; inset: 0; z-index: 5; pointer-events: none; }
.view {
  position: absolute; inset: 0;
  padding: var(--pad-t) var(--pad-x) var(--pad-b);
  display: none; pointer-events: auto;
}
.view.on { display: block; }
@keyframes rise   { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes riseIn { from { opacity: 0; transform: translateY(14px) scale(0.985); } to { opacity: 1; transform: none; } }
/* Cards travel a little further and settle, so six of them arriving in sequence
   reads as dealing rather than blinking. */
@keyframes cardIn { from { opacity: 0; transform: translateY(26px) scale(0.965); } to { opacity: 1; transform: none; } }

.view.on > * { animation: rise 0.7s var(--ease) both; }

/* Overall progress, at the top of the panel where the eye already is. The
   per-pool clusters stay in the corner as detail; this is the headline. */
/* Thinner, and above the meta row rather than under it. */
/* Six questions are six discrete steps, and a continuous bar was measuring a
   thing that only ever moves in sixths. */
/* The stepper carries the count beside it: the hexagon shows how far along you
   are at a glance, the words say it exactly. */
.qstep-row {
  display: flex; align-items: center; gap: 22px;
  /* 22 Sep: the pool name sits in this row beside the question number, so the
     row runs straight into the question (was 34 to a separate eyebrow line). */
  margin: 0 0 14px;
}
.qstep-row .qmeta { min-height: 0; }
/* The question nav reuses .pool-nav's drawing but sits in the action row on the
   right, in flow, and is always live. */
.pool-nav.q-steps { position: static; opacity: 1; pointer-events: auto; }
.qactions .qnav[hidden] { display: none; }
.pool-nav.q-steps .pn-arrow { pointer-events: auto; }
.pool-nav.q-steps .pn-arrow[disabled] { opacity: 0.34; pointer-events: none; }
.qcount {
  font-family: var(--label); font-weight: 400;
  font-size: clamp(13.9px, 0.891cqw, 17.1px);
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--fg-4);
  white-space: nowrap;
}
/* The file draws this at 102 x 114.2. Held at ~70% of that: it is a place
   marker beside the question, not a second diagram competing with the ring on
   the plate. The viewBox is authored 1:1, so this is its own pixel size. */
.hexstep { display: block; width: auto; height: 82px; overflow: visible; }
/* The file's own unfilled capsule. Sampled off the design: a flat pale blue,
   not a tint of the brand. */
.hs-seg {
  stroke: #D3EDFF;
  transition: stroke 0.4s var(--ease), opacity 0.4s var(--ease);
}
.hs-seg.on { stroke: var(--brand); }

/* Own sky blue so a half-done question reads differently from a finished one.
   The dash window is set in hexstep.js; only the colour lives here. */
.hs-part {
  stroke: var(--hs-half, #4F9DFF);
  stroke-dasharray: var(--f, 0) 1;   /* pathLength is 1, so --f is the share filled */
  pointer-events: none;
  transition: stroke-dasharray 0.45s var(--ease);
}
.hs-part:not(.live) { opacity: 0; }
.hexstep.enter .hs-part.live {
  animation: hsPartIn 0.55s var(--ease) both, hsPartPulse 0.9s var(--ease) 1;
  animation-delay: calc(0.1s + var(--i, 0) * 0.14s), calc(0.55s + var(--i, 0) * 0.14s);
}
@keyframes hsPartIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes hsPartPulse { 0% { filter: drop-shadow(0 0 0 rgba(79, 157, 255, 0)); } 40% { filter: drop-shadow(0 0 6px rgba(79, 157, 255, 0.6)); } 100% { filter: drop-shadow(0 0 0 rgba(79, 157, 255, 0)); } }
/* Figma 550:450 is 30px; held to the mark's own scale. */
.hs-num {
  fill: var(--brand);
  font-family: var(--label); font-weight: 500; font-size: 22.5px;
  letter-spacing: -0.3px;
  transform-box: fill-box; transform-origin: center;
}
.hexstep.enter .hs-seg.on {
  animation: hsFill 0.5s var(--ease) both;
  animation-delay: calc(0.1s + var(--i, 0) * 0.14s);
}
.hexstep.enter .hs-seg.now { animation: hsFill 0.5s var(--ease) both, hsPulse 0.9s var(--ease) 1; animation-delay: calc(0.1s + var(--i, 0) * 0.14s), calc(0.5s + var(--i, 0) * 0.14s); }
.hexstep.enter .hs-num { animation: hsNum 0.5s var(--ease) 0.25s both; }
@keyframes hsFill { from { stroke: #D3EDFF; } to { stroke: var(--brand); } }
@keyframes hsPulse { 0% { filter: drop-shadow(0 0 0 rgba(0, 124, 195, 0)); } 40% { filter: drop-shadow(0 0 6px rgba(0, 124, 195, 0.55)); } 100% { filter: drop-shadow(0 0 0 rgba(0, 124, 195, 0)); } }
@keyframes hsNum { from { opacity: 0; transform: translateY(6px) scale(0.8); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .hexstep.enter * { animation: none !important; } }

.qprog {
  position: relative; height: 3px; border-radius: 2px;
  background: rgba(0, 76, 119, 0.16);
  margin: 0 0 var(--s4);
  overflow: hidden;
}
/* --blue, not --blue-lift. The lift is reserved for the slider and Next, so
   there are two bright blues on the screen instead of six. */
.qprog i {
  position: absolute; top: 0; bottom: 0; left: 0;
  display: block; width: 0;
  background: var(--blue); border-radius: 2px;
  transition: width 0.45s var(--ease);
}

/* ---------- staggered entrance --------------------------------
   A whole screen arriving as one slab reads rigid. */
.stagger > * { animation: riseIn 0.72s var(--ease-in-out-soft) both; }
.stagger > *:nth-child(1) { animation-delay: 0.04s; }
.stagger > *:nth-child(2) { animation-delay: 0.13s; }
.stagger > *:nth-child(3) { animation-delay: 0.22s; }
.stagger > *:nth-child(4) { animation-delay: 0.31s; }
.stagger > *:nth-child(5) { animation-delay: 0.40s; }
.stagger > *:nth-child(6) { animation-delay: 0.49s; }
.stagger > *:nth-child(7) { animation-delay: 0.58s; }
.stagger > *:nth-child(8) { animation-delay: 0.67s; }
.stagger > *:nth-child(9) { animation-delay: 0.76s; }
.stagger > *:nth-child(10) { animation-delay: 0.85s; }

/* The six pool cards deal out one at a time. 110ms apart is slow enough to read
   as a sequence and short enough that the last one is not a wait. */

@media (prefers-reduced-motion: reduce) {
  .stagger > * { animation: none; }
}
/* Explore drives its own modes with opacity transitions; a fill-mode animation would override them. */
#v-explore.on > * { animation: none; }

/* Keeps the copy column legible whatever the plate does on its left. */
#v-explore .copy-scrim {
  position: absolute; inset: 0; z-index: 0;
  /* Two gradients: the left band carries the copy column, the bottom band carries the footer chrome. */
  /* Light: the copy sits on a panel, so this only settles the footer chrome. */
  background:
    linear-gradient(90deg,
      rgba(255, 255, 255, 0.72) 0%, rgba(255, 255, 255, 0.42) 38%, rgba(255, 255, 255, 0) 62%),
    linear-gradient(0deg,
      rgba(255, 255, 255, 0.84) 0%, rgba(255, 255, 255, 0.38) 10%, rgba(255, 255, 255, 0) 18%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 520ms var(--ease);
}
#v-explore.focus .copy-scrim { opacity: 1; }
/* The overview needs a stronger gradient than the focus scrim. */
/* The overview carries no copy of its own. */
#v-explore:not(.focus) .copy-scrim { opacity: 0; }

/* ---------- framework screen ----------------------------------
   Its own step between attract and the hexagon. */
#v-intro { display: none; }
/* Stacked: eyebrow, headline and lede centred at the top, the actions beneath. */
#v-intro.on {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: var(--s5);
  padding: var(--pad-t) var(--pad-x) var(--pad-b);
}
.fw-lead {
  position: relative; text-align: center;
  animation: rise 0.6s var(--ease) both;
}
.fw-title {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(36.4px, 3.317cqw, 66.3px);
  line-height: 1.06; letter-spacing: -0.02em;
  color: var(--brand);
  margin: var(--s3) 0 var(--s4);
}
/* Blue sentence, ink accent, the same inversion the attract headline uses. */
.fw-title em { font-style: normal; color: var(--ink); }
/* Figma 412:199: 22px Geist, 1.6 line height, black, 973px column, centred,
   three paragraphs with a blank line between them. */
.fw-lede {
  font-size: 23.5px; line-height: 1.6; color: #000;
  width: 973px; max-width: 100%; margin: 0 auto;
}
.fw-lede p + p { margin-top: 1.6em; }
.fw-lead .label { color: var(--blue-lift); }

/* Two ways on: read the pools first, or go straight to the diagnostic. */
.fw-actions {
  display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 44px;
}
.fw-go { min-width: 301px; }
/* "Explore the six pools" is an underlined text link in the design (Figma
   412:252), the diagnostic is the pill beside it. */
.fw-skip {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 4px;
  font-family: var(--label); font-weight: 500; font-size: 17.1px; line-height: 1.4;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--brand);
  cursor: pointer;
}
.fw-skip u { text-decoration: underline; text-underline-offset: 0.2em; }
.fw-skip .arrow { font-family: var(--body); font-size: 1.15em; }
.fw-skip:active { color: var(--blue-deep); }


/* ---------- type primitives --------------------------------- */

.label {
  font-family: var(--label); font-weight: 600;
  font-size: clamp(14px, 0.916cqw, 17.8px);
  letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--blue-lift);
}
/* --brand measures 4.00:1 at worst over the renders. */
.label.cool { color: var(--blue-lift); }

.d-xl, .d-l, .d-m {
  font-family: var(--display); font-weight: 300;
  line-height: 1.02; letter-spacing: -0.022em; color: var(--fg);
  text-wrap: balance;
}
.d-xl { font-size: clamp(42.8px, 4.922cqw, 94.2px); }
.d-l  { font-size: clamp(34.2px, 3.638cqw, 68.5px); }
.d-m  { font-size: clamp(25.7px, 2.568cqw, 47.1px); }
.d-xl em, .d-l em, .d-m em { font-style: normal; color: var(--brand); }

p.lede {
  color: var(--fg-2); font-weight: 300;
  font-size: clamp(15.8px, 1.157cqw, 22.7px); line-height: 1.6;
}
p.body { color: var(--fg-2); font-size: clamp(15.2px, 1.049cqw, 19.5px); line-height: 1.62; }

/* centred statement block — the default composition */
.statement { width: min(1120px, 64cqw); margin: 0 auto; text-align: center; }
.statement .label { display: block; margin-bottom: var(--s3); }
.statement .lede { max-width: 48ch; margin: var(--s3) auto 0; }

/* ---------- buttons: no boxes, a rule and a colour ---------- */

/* A pill, from the design: 0.5px white hairline, radius 30, the shared blue
   shadow, transparent fill. */
.btn {
  font-family: var(--label); font-weight: 500;
  font-size: clamp(13.9px, 0.917cqw, 17.5px);
  letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--btn-ink);
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s2);
  padding: 0 clamp(20px, 2.0cqw, 40px);
  min-height: clamp(48px, 3.70cqw, 71px);   /* the file's pill height, not 82 */
  border: 0.5px solid var(--pill-line);
  border-radius: var(--radius-pill);
  box-shadow: var(--pill-shadow);
  position: relative;
}
.btn:active { background: rgba(255, 255, 255, 0.55); }

.btn.primary { background: var(--pill-fill); color: var(--btn-ink); }
.btn.primary:active { background: rgba(0, 136, 255, 0.32); }

/* No fill, so it reads as the secondary of a pair. */
.btn.quiet { background: transparent; color: var(--btn-ink); }
.btn.quiet:active { background: rgba(255, 255, 255, 0.55); }
.btn:disabled { opacity: 0.4; pointer-events: none; }
.btn .arrow { font-family: var(--body); font-size: 1.15em; }

/* ---------- attract ----------------------------------------- */

/* Centred. */
#v-attract { display: none; place-items: center; }

#v-attract.on { display: grid; }
#v-attract .statement { max-width: none; }
#v-attract .d-xl { max-width: 21ch; margin: var(--s3) auto 0; }
/* Figma 552:188 had the mark 162x127 centred above the headline; it now lives
   in the header (.ai-mark), see above. */

.touch-cue {
  margin-top: var(--s5); white-space: nowrap;
  /* inline-flex so the parent's text-align keeps it centred */
  display: inline-flex; align-items: center; gap: var(--s3);
  font-family: var(--label); font-weight: 500;
  font-size: clamp(14px, 0.916cqw, 17.8px);
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--fg-3);
}
/* Only the wording breathes. The beacon keeps its own ping, which is the part
   that says "touch"; fading the two together would mute exactly that. */
.touch-cue .tc-text { animation: breathe 3.4s var(--ease) infinite; }
@keyframes breathe { 0%, 100% { opacity: 0.4 } 50% { opacity: 1 } }

/* ---------- explore: framework hexagon left, reading right --- */

#v-explore { pointer-events: none; }

/* 889 is measured: the board's ink spans y 194–845 centred on x 960. */
.hex-hint {
  /* Figma 287:748/749: a 387x71 pill at y 897, the design's pill fill and
     hairline, "TAP A VALUE POOL TO EXPLORE" in brand blue. */
  position: absolute; left: 0; right: 0; top: 897px; bottom: auto;
  margin: 0 auto; width: 387px; height: 71px;
  display: flex; align-items: center; justify-content: center;
  border-radius: var(--radius-pill);
  border: 0.5px solid #FFFFFF;
  background: var(--pill-fill);
  box-shadow: var(--pill-shadow);
  font-family: var(--label); font-weight: 500;
  font-size: 17.1px; line-height: 1.4;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--brand);
  text-align: center;
  pointer-events: none;
}
.touch-dot { position: relative; width: 26px; height: 26px; flex: none; }
.touch-dot i {
  position: absolute; inset: 9px; border-radius: 50%;
  background: var(--blue-lift); display: block;
}
.touch-dot::before, .touch-dot::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  border: 1.5px solid var(--blue-lift);
  animation: touchPing 2.4s var(--ease) infinite;
}
.touch-dot::after { animation-delay: 1.2s; }
@keyframes touchPing {
  0% { transform: scale(0.35); opacity: 0.9; }
  70%, 100% { transform: scale(1.15); opacity: 0; }
}

/* three quick facts, tick per pool colour */
.pr-facts { list-style: none; margin-top: var(--s4); }
.pr-facts li {
  --seg: var(--blue);
  position: relative; padding: var(--s2) 0 var(--s2) calc(var(--s3) + 8px);
  border-bottom: 1px solid var(--hair);
  font-size: clamp(15.2px, 1.098cqw, 19.5px); color: var(--fg-2);
}
/* The list is rebuilt for every pool, so the run replays on each change. */
.pr-facts li { animation: rise 0.6s var(--ease) both; animation-delay: calc(0.25s + var(--i, 0) * 0.18s); }
.pr-facts li:nth-child(1) { --i: 0; }
.pr-facts li:nth-child(2) { --i: 1; }
.pr-facts li:nth-child(3) { --i: 2; }
.pr-facts li:nth-child(4) { --i: 3; }
.pr-facts li:first-child { border-top: 1px solid var(--hair); }
/* The footer below carries its own top rule, so a bottom border on the last fact
   drew a second line a few pixels above it. Rules go between the facts only. */
.pr-facts li:last-child { border-bottom: none; }
/* Pointy-top hexagon marker, the same silhouette as the framework board. */
.pr-facts li::before,
.pr-facts li::after {
  content: ''; position: absolute; left: 0; top: 50%;
  width: 12px; height: 13px; margin-top: -6.5px;
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
  background: var(--seg);
}
.pr-facts li::before {
  animation: hexPop 0.52s var(--ease) both;
  animation-delay: calc(0.35s + var(--i, 0) * 0.18s);   /* just behind its row */
}
.pr-facts li::after {
  opacity: 0;
  animation: hexPing 3.4s var(--ease) infinite;
  animation-delay: calc(0.35s + var(--i, 0) * 0.18s);
}

@keyframes hexPop {
  from { opacity: 0; transform: scale(0.3) rotate(-30deg); }
  to   { opacity: 1; transform: none; }
}
@keyframes hexPing {
  0%   { opacity: 0.55; transform: scale(1); }
  55%  { opacity: 0;    transform: scale(2.1); }
  100% { opacity: 0;    transform: scale(2.1); }
}

@media (prefers-reduced-motion: reduce) {
  .pr-facts li::before { animation: none; }
  .pr-facts li::after { display: none; }
}

/* ---------- explore: framework overview vs one open pool ----------
   The board is one object doing two jobs. */

#v-explore .col {
  pointer-events: auto; z-index: 1;
  position: absolute; top: var(--pad-t); left: var(--pad-x); bottom: var(--pad-b);
  /* Keep in step with the 0.46 the scene solves the free width from. */
  width: 42%; max-width: 620px;
  display: flex; flex-direction: column; justify-content: center;
  opacity: 0; pointer-events: none;
  transition: opacity 0.5s var(--ease);
}
#v-explore.focus .col { opacity: 1; pointer-events: auto; }

/* ---------- the framework hexagon (SVG) ---------------------
   Replaces the WebGL board. */
#hexWrap {
  position: absolute; inset: 0;
  pointer-events: none;
  opacity: 0; transition: opacity 520ms var(--ease);
}
#stage[data-view='explore']:not([data-pool]) #hexWrap { opacity: 1; }
#stage[data-view='explore']:not([data-pool]) #hexWrap .hex-hit { pointer-events: auto; }
#hexSvg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* Wedges and labels animate about the hexagon's own centre (frame 960, 520): the
   SVG groups through transform-box: view-box so the origin is in viewBox units,
   the HTML. */
.hex-seg {
  transform-box: view-box; transform-origin: 960px 520px;
  transition: opacity 320ms var(--ease), transform 550ms cubic-bezier(0.22, 1, 0.36, 1);
}
.hex-labels .hex-lbl { transition: opacity 320ms var(--ease), transform 550ms cubic-bezier(0.22, 1, 0.36, 1); }
/* Hover: the wedge drifts 4.5% out from the centre and back (js/hexagon.js moves
   its labels with it). Only while the board is the thing on screen. */
#stage[data-view='explore']:not([data-pool]) .hex-seg.hover,
#stage[data-view='prio'] .prio-hex .hex-seg.hover { transform: scale(1.045); }
.hex-seg.hover .hex-hit { cursor: pointer; }
.hex-hit { fill: transparent; cursor: pointer; }

/* Entrance: each wedge scales in from the centre and fades, one after the other
   round the ring, the labels riding with their wedge and the centre mark last. */
#hexWrap.enter .hex-seg {
  animation: hexIn 1400ms var(--ease-in-out-soft) both;
  animation-delay: calc(var(--i, 0) * 420ms);
}
#hexWrap.enter .hex-labels .hex-lbl {
  animation: hexIn 1400ms var(--ease-in-out-soft) both;
  animation-delay: calc(220ms + var(--i, 0) * 420ms);
  /* The base transform is inline (centre + rotate), so the keyframe scales with
     it rather than replacing it. */
  transform-origin: center;
}
@keyframes hexIn {
  from { opacity: 0; scale: 0.72; }
  to   { opacity: 1; scale: 1; }
}

/* Exit: the tapped wedge lifts and holds while the other five draw back into the
   centre and fade, in the 520ms before #hexWrap fades out. */
#hexWrap.picked .hex-seg { opacity: 0; transform: scale(0.82); }
#hexWrap.picked .hex-seg.on { opacity: 1; transform: scale(1.06); }
#hexWrap.picked .hex-labels .hex-lbl { opacity: 0; }
#hexWrap.picked .hex-labels .hex-lbl.on { opacity: 1; }

/* The design's actual lettering. */
.hex-labels { position: absolute; inset: 0; pointer-events: none; }
.hex-labels .hex-lbl {
  position: absolute; display: block;
  transform-origin: center;
  user-select: none; -webkit-user-drag: none;
}
/* The file's own lettering (Tungsten outlines). On the artwork ring the verb
   sits on the navy trapezoid, so its navy outline is turned white (the files
   are single-colour outlines, so an invert is exact); the name outline is
   already white. */
.hex-labels .hex-lbl { pointer-events: none; }
.hex-artwork .hex-labels .hex-verb { filter: brightness(0) invert(1); }

/* overview only */
#v-explore.focus .hex-hint { opacity: 0; pointer-events: none; }
#v-explore .hex-hint { transition: opacity 0.4s var(--ease); }

/* focus only — the pool screen's chrome, from Figma 287:1051. */

/* "Back to the framework": top right, 361x71 at (1517, 30), 18px brand blue with
   the design's 8px dot in front of it. */
#v-explore .focus-foot {
  position: absolute; top: 937px; right: 42px;   
  opacity: 0; pointer-events: none;
  transition: opacity 0.5s var(--ease);
}
#v-explore.focus .focus-foot { opacity: 1; pointer-events: auto; }
.ff-back {
  display: inline-flex; align-items: center; justify-content: center; gap: 20px;
  width: 361px; height: 71px; padding: 0 26px;
  border-radius: var(--radius-pill);
  border: 0.5px solid #FFFFFF;
  box-shadow: var(--pill-shadow);
  background: transparent;
  font-family: var(--label); font-weight: 400; font-size: 19.3px; line-height: 1.4;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--brand);
  white-space: nowrap; cursor: pointer;
  transition: background 0.2s var(--ease);
}
.ff-back { background: #FFFFFF; }
.ff-back:active { background: #DCEBFA; }
.ff-back:focus-visible { outline: 1px solid var(--blue-lift); outline-offset: 3px; }
.ff-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--brand); flex: none; }

/* Previous / Next: bottom left, 70x71 at (82, 937) and 143x71 at (168, 937). */
.pool-nav {
  position: absolute; left: 82px; top: 937px; z-index: 2;   /* bottom left, as the design has them (Figma 287:1083) */
  display: flex; align-items: center; gap: 16px;
  opacity: 0; transition: opacity 0.5s var(--ease); pointer-events: none;
}
#v-explore.focus .pool-nav { opacity: 1; }
#v-explore.focus .pn-arrow { pointer-events: auto; }
/* Figma 550:812: the arrows 70x71 either side of six bars — 35px pale ones and a
   60px dark one for the pool on screen — 30px apart, 31px from the arrows. */
.pool-nav { gap: 31px; }
.pool-dots { display: flex; align-items: center; gap: 30px; }
.pool-dots i {
  display: block; width: 35px; height: 5px; border-radius: 1px;
  background: rgba(115, 133, 154, 0.22);
  transition: width 0.35s var(--ease), background 0.35s var(--ease);
}
.pool-dots i.on { width: 60px; background: #0A3D62; }
.pn-fwd .arrow, .pn-fwd span { font-size: 17.1px; }
.pn-arrow {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  height: 71px;
  border-radius: var(--radius-pill);
  border: 0.5px solid #FFFFFF;
  box-shadow: var(--pill-shadow);
  background: transparent;
  font-family: var(--label); font-weight: 500; font-size: 17.1px; line-height: 1.4;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--btn-ink);
  cursor: pointer;
}
.pn-arrow[hidden] { display: none; }   /* the pill's display beat the hidden attribute */
.pn-prev { width: 70px; }
.pn-prev, .pn-round, .pn-fwd { width: 70px; height: 70px; border-radius: 50%; padding: 0; }
.pn-next { width: 143px; }
.pn-arrow .arrow { font-size: 19.3px; }
.pn-arrow:active { background: rgba(255, 255, 255, 0.45); }
.pn-arrow:focus-visible { outline: 1px solid var(--blue-lift); outline-offset: 3px; }

.pool-read.swap { animation: swapIn 0.46s var(--ease) both; }
@keyframes swapIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

.pr-rule { height: 2px; width: 44px; margin-bottom: var(--s3); background: var(--blue); }
.pr-verb {
  font-family: var(--label); font-weight: 500; font-size: clamp(14px, 0.916cqw, 17.8px);
  letter-spacing: 0.13em; text-transform: uppercase;
}
.pr-name {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(27.8px, 2.782cqw, 51.4px); line-height: 1.04; letter-spacing: -0.022em;
  margin-top: var(--s2); text-wrap: balance;
}
.pr-blurb { margin-top: var(--s3); font-size: clamp(15.3px, 1.089cqw, 21.5px); line-height: 1.55; color: var(--fg-2); max-width: 46ch; }
.pr-tiles-head { margin-top: var(--s5); }
.pr-tiles { margin-top: var(--s3); display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; }
.tile {
  --tile-accent: var(--blue);
  text-align: left; display: flex; flex-direction: column; gap: var(--s1);
  padding: var(--s3) var(--s3) var(--s4);
  border-top: 2px solid var(--tile-accent);
  background: rgba(0, 76, 119, 0.028);
  transition: background 0.22s var(--ease), transform 0.22s var(--ease);
}
.tile:active { background: rgba(0, 76, 119, 0.075); }
.tile.pending { border-top-color: var(--fg-4); background: rgba(0, 76, 119, 0.014); }
.tile .t-n {
  font-family: var(--label); font-weight: 500; font-size: clamp(13.9px, 0.812cqw, 15.5px);
  letter-spacing: 0.13em; color: var(--fg-4);
}
.tile .t-client {
  font-family: var(--display); font-weight: 500;
  font-size: clamp(15.8px, 1.225cqw, 22.7px); line-height: 1.15; letter-spacing: -0.014em; color: var(--fg);
}
.tile.pending .t-client { color: var(--fg-3); }
.tile .t-title { font-size: clamp(14px, 0.951cqw, 17.1px); color: var(--fg-2); line-height: 1.35; }
.tile .t-metric {
  margin-top: auto; padding-top: var(--s2);
  font-family: var(--label); font-weight: 500; font-size: clamp(13.9px, 0.886cqw, 17px);
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--tile-accent);
}
.tile.pending .t-metric { color: var(--fg-4); }

/* ---------- the case study reader ---------------------------
   Full screen, floating over whatever plate is showing. */
#tileSheet {
  position: absolute; z-index: 8; inset: 0;
  opacity: 0; pointer-events: none;
  transition: opacity 0.32s var(--ease);
}
#tileSheet.on { opacity: 1; pointer-events: auto; }
/* The render stays visible underneath: this only takes it back far enough that
   the sheet reads as the front layer. */
.ts-scrim { position: absolute; inset: 0; background: rgba(236, 245, 253, 0.82); }

.ts-card {
  /* Near full frame: 60 in from each side, 50 top and bottom. */
  position: absolute; left: 60px; top: 50%; transform: translateY(-50%);
  width: 1800px; height: 980px;
  padding: 70px 84px 62px;
  /* A case with no article is a lead and nothing else. */
  border-radius: var(--radius);
  border: 1px solid var(--card-line);
  /* White first so type has something to sit on, then the design's card gradient
     over it. */
  /* Solid: nothing behind the sheet shows through the copy any more. The photo
     (.ts-photo) and its wash sit on this. */
  background: #EEF6FD;
  box-shadow: 2px 12px 48px 2px rgba(0, 124, 195, 0.18);
  /* The -50% is the vertical centring; the rest is the entrance, which settles
     to the centred position when the sheet is on. */
  transform: translateY(calc(-50% + 14px)) scale(0.988);
  transition: transform 0.36s var(--ease-mech);
  display: flex; flex-direction: column;
  overflow: hidden;
}
#tileSheet.on .ts-card { transform: translateY(-50%); }
.ts-card.short { height: auto; }
/* The case photo fills the card; the wash holds the left for the copy and lets
   the people on the right come through. */
.ts-photo, .ts-wash { position: absolute; inset: 0; pointer-events: none; }
.ts-photo { width: 100%; height: 100%; object-fit: cover; object-position: right center; }
/* Figma 626:717: the copy column sits on a near-solid wash (0.95 to 53%), which
   thins to 0.3 at 71% and is gone at the right edge, so the photo shows where
   there is no text and never competes with it. */
.ts-wash {
  background: linear-gradient(90deg,
    rgba(233, 246, 255, 0.98) 0%, rgba(233, 246, 255, 0.98) 60%,
    rgba(233, 246, 255, 0.72) 72%, rgba(233, 246, 255, 0.28) 84%,
    rgba(233, 246, 255, 0) 100%);
  /* The stops sit 5% right of the file's: this card is 1800 wide to the file's
     1600 and its copy column reaches 70% across, so the solid wash follows it. */
}
.ts-card > :not(.ts-photo):not(.ts-wash) { position: relative; z-index: 1; }
/* Copy keeps to the washed left; the close/continue control stays top right. */
.ts-card .case-stack { max-width: 1120px; }   /* the file's 942-wide column at 1600, scaled; three outcome columns fit */
/* .ts-card > * makes this relative (specificity beats the static here), so the
   page reader's left: 67 / top: 120 were still shifting the copy 67 right and
   120 down from the eyebrow. Zeroed: the copy starts under the eyebrow, at its
   left edge. */
.ts-card .case-stack { position: relative; left: 0; top: 0; width: 100%; margin-top: 30px; overflow: auto; min-height: 0; flex: 1 1 auto; padding-bottom: 0; }
/* 22 Sep: the 96px foot that "cleared" the pinned Back/Continue was the reason
   every case overflowed — that button sits bottom right, outside the 1120px copy
   column, so the copy never met it. Scrolling stays as a fallback for a longer
   case, with the scrollbar hidden. */
.ts-card .case-stack { scrollbar-width: none; -ms-overflow-style: none; }
.ts-card .case-stack::-webkit-scrollbar { display: none; width: 0; height: 0; }
.ts-card .case-hero { width: 100%; }
.ts-card .case-title { font-size: 68.5px; }
/* The file's case headlines are sentences (Figma 626:683: 50px in 942 at 1600),
   so they take the file's size rather than the reader's 64. */
.ts-card.long-title .case-title { font-size: 52px; line-height: 1.04; letter-spacing: -0.026em; max-width: 1060px; }
/* A touch smaller in the sheet so every featured case sits without scrolling. */
.ts-card .case-sub { font-size: 24px; line-height: 1.32; }
.ts-card .case-sect p { font-size: 18.4px; line-height: 1.5; }
.ts-card .case-col { width: 760px; }
.ts-card .case-rule { width: 100%; margin-left: 0; }
.ts-card .case-outcome { width: 100%; }
.ts-card.no-outcome .case-rule { display: none; }

.ts-top { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s4); }
.ts-eyebrow, #tileClose {
  font-family: var(--label); font-weight: 500;
  font-size: clamp(13.9px, 0.891cqw, 17.1px);
  letter-spacing: 0.13em; text-transform: uppercase;
}
.ts-eyebrow { color: var(--blue-lift); }
/* The sheet's Back / Continue is the same pill as NEXT on the question screen
   (.pn-arrow): 71 tall, hairline, the shared shadow, 16px label. It used to be
   a 44px text link on a white wash, so it read as a different control. */
#tileClose {
  color: var(--btn-ink); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  height: 71px; padding: 0 34px;
  border-radius: var(--radius-pill);
  border: 0.5px solid #FFFFFF;
  box-shadow: var(--pill-shadow);
  /* Solid white: it sits over the case photo, where the glass fill vanished. */
  background: #FFFFFF;
  font-size: 17.1px; line-height: 1.4;
  /* Bottom right of the card, in the same corner the results nav uses, rather
     than up beside the eyebrow. */
  position: absolute; right: 84px; bottom: 62px; z-index: 2;
}
#tileClose:active { background: rgba(255, 255, 255, 0.45); }
#tileClose:focus-visible { outline: 1px solid var(--blue-lift); outline-offset: 3px; }

.ts-hero { margin-top: 40px; }
.ts-metric {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(40.7px, 4.347cqw, 83.5px); line-height: 1.02; letter-spacing: -0.026em;
  color: var(--ink);
}
.ts-title {
  margin-top: 10px;
  font-size: clamp(17.1px, 1.393cqw, 26.8px); line-height: 1.3; color: var(--fg-4);
}
.ts-rule { margin-top: 68px; height: 1px; background: var(--hair); }

.ts-body { display: flex; gap: 92px; margin-top: 50px; min-height: 0; }
.ts-article { width: 800px; flex: 0 0 800px; }
.ts-stats   { width: 460px; flex: 0 0 460px; }

.ts-lead {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(17.1px, 1.393cqw, 26.8px); line-height: 1.5; letter-spacing: -0.005em;
  color: var(--ink);
}
.ts-sections { margin-top: 26px; display: flex; flex-direction: column; gap: 26px; }
.ts-sect h4 {
  font-family: var(--label); font-weight: 600;
  font-size: clamp(13.9px, 0.836cqw, 16.1px);
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--fg-4);
  margin-bottom: 10px;
}
.ts-sect p {
  font-size: clamp(15px, 1.059cqw, 20.3px); line-height: 1.6; letter-spacing: -0.002em;
  color: var(--mid);
}
.ts-stat + .ts-stat { margin-top: 24px; }
.ts-stat b {
  display: block;
  font-family: var(--display); font-weight: 300;
  font-size: clamp(25.7px, 2.341cqw, 44.9px); line-height: 1.05; letter-spacing: -0.02em;
  color: var(--brand);          /* large text: 3.6:1 against a 3.0 floor */
}
.ts-stat span {
  display: block; margin-top: 2px;
  font-size: clamp(13.9px, 0.947cqw, 18.2px); line-height: 1.35; color: var(--mid);
}
/* Nothing to say in the right column when a case has no figures yet. */
.ts-stats:empty { display: none; }
.ts-stats:empty + * { flex: 1 1 auto; }
#tsFlag { margin-top: auto; }

.pr-sect { margin-top: var(--s4); }
.pr-sect h4 {
  font-family: var(--label); font-weight: 600; font-size: clamp(13.9px, 0.856cqw, 16.3px);
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--fg-3);
  margin-bottom: var(--s2);
}
.pr-sect p { font-size: clamp(14.7px, 1cqw, 18.9px); line-height: 1.62; color: var(--fg-2); max-width: 58ch; }
.pr-sect ul { list-style: none; display: flex; flex-direction: column; gap: var(--s2); }
.pr-sect li { font-size: clamp(14.7px, 1cqw, 18.9px); color: var(--fg-2); }

#v-explore .foot {
  flex: none; margin-top: var(--s4);
  padding-top: var(--s4); border-top: 1px solid var(--hair);
  display: flex; align-items: center; gap: var(--s5);
}
#v-explore .foot .hint {
  font-family: var(--label); font-weight: 500; font-size: clamp(13.9px, 0.886cqw, 17px);
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--fg-3);
}
/* White, not --blue-lift: the numeral needs the widest contrast margin on the screen. */
#seenCount { color: var(--ink); font-weight: 600; }

/* ---------- diagnostic -------------------------------------- */

#v-diag { pointer-events: none; }
/* The design's own footprint, in the frame's own pixels: the content box sits at
   x 1096, y 156 and is 727 wide. */
#v-diag .qcol {
  pointer-events: auto; z-index: 1;
  position: absolute; top: 156px; left: 1096px; right: auto; bottom: 75px;
  width: 727px; max-width: none;
  display: flex; flex-direction: column;
}

/* ---------- fine print --------------------------------------
   The benchmark credit. */
.fine-print {
  margin-top: var(--s4);
  font-size: clamp(13.9px, 0.877cqw, 16.7px); line-height: 1.5;
  color: var(--fg-3);
}
#v-done .fine-print { margin-top: var(--s5); max-width: 62ch; margin-left: auto; margin-right: auto; }

/* ---------- case study, inside the question panel --------------
   A strip rather than a card, sitting between the answer and Next: someone has just decided and is about to move on. */
.qcase {
  margin-top: var(--s5);
  display: flex; align-items: center; gap: clamp(14px, 1.2cqw, 24px);
  text-align: left; width: 100%;
  padding: clamp(14px, 1.3cqw, 26px) clamp(18px, 1.7cqw, 34px);
  background: var(--card);
  border: 1px solid var(--card-line);
  border-radius: var(--radius);
  box-shadow: var(--card-shadow);
  transition: box-shadow 0.22s var(--ease);
}
.qcase[hidden] { display: none; }
.qcase:active { box-shadow: 2px 4px 14px 2px rgba(0, 124, 195, 0.12); }
/* The pool's colour, as an edge rather than a fill: at this size a coloured
   panel competes with the slider for attention. */
.qc-bar { flex: none; width: 2px; align-self: stretch; min-height: 30px; background: var(--blue); border-radius: 2px; }
.qc-read { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
/* White, not blue. Blue-lift is the instrument and the primary action; a
   coloured number here read as a second headline competing with the question. */
.qc-metric {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(19.3px, 1.445cqw, 27.8px); line-height: 1.16; letter-spacing: -0.01em;
  color: var(--ink);
}
.qc-sub {
  display: flex; flex-wrap: wrap; gap: 0 8px;
  font-size: clamp(14.3px, 0.963cqw, 18.5px); line-height: 1.35; color: var(--fg-3);
}
.qc-sub b { font-weight: 500; color: var(--ink); }
.qc-sub b::after { content: ' ·'; color: var(--fg-4); font-weight: 400; }
.qc-more {
  margin-left: auto; flex: none;
  font-family: var(--display); font-weight: 300;
  font-size: clamp(14.3px, 1.006cqw, 19.3px); color: var(--blue-lift);
  display: inline-flex; align-items: center; gap: 10px; min-height: 44px;
}
.qcase:active .qc-more { color: var(--blue-lift); }

/* One height for all six questions, with the action row pinned to the bottom. */
/* The panel fills the column's footprint. */
#v-diag .qpanel {
  display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0;
}
/* Nothing in the panel shrinks: a three-line question pushes the slider down instead of under it. */
#v-diag .qpanel > * { flex-shrink: 0; }
#v-diag .mslider { margin-bottom: auto; }
/* One row: which pool, what it is about, where you are. */
/* One line, one height, on every question. */
/* Long pool names ellipsised in one row. */
.qmeta {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  /* Figma 550:453: the eyebrow is one 25px line. */
  min-height: 25px; line-height: 1.4;
}
.qmeta > * { white-space: normal; }
.qkind { min-width: 0; }
.qmeta .pool-tag {
  /* Figma 550:453: 18px Geist Regular, 0.13em, the brand blue. */
  font-family: var(--label); font-weight: 400; font-size: 19.3px;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--brand);
}
/* Sentence case on purpose. Seven uppercase letterspaced labels on one screen is
   what "everything is shouting" looks like; this is now one of three. */
/* Matched to the pool tag's size rather than sitting a point above it. */
.qkind {
  font-size: 26.8px; line-height: 1.3; color: var(--mid);
}
/* Off-screen but readable. Used by the identify fields' labels. */
.sr-only {
  position: absolute !important; width: 1px; height: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}
.qtext {
  font-family: var(--display); font-weight: 300;
  /* Grown with the column. At 26ch the question was leaving a third of the panel
     empty to its right. */
  /* The design's 54px does not fit. */
  font-size: 57.8px; line-height: 1.06; letter-spacing: -0.014em; color: #000;   /* Figma 550:454 */
  /* Figma 550:452 sets 10 between the eyebrow and the question; the old --s6
     step pushed the whole column 60px down and cost the actions their room. */
  margin: 10px 0 0; max-width: none; text-wrap: balance;
  /* Exactly two lines, which is now what every question takes. Reserving it
     keeps Next in the same place between questions. */
  min-height: 2.12em;
}
/* Questions over ~64 characters step down so three lines still fit the column. */
.qtext.long { font-size: 49.2px; }

/* options: rows separated by one hairline, no boxes */
/* ---------- maturity slider -----------------------------------
   Replaces the five tapoptions. */
/* Full width of the panel, so it lines up with the progress bar above it and the
   case study below. */
.mslider { margin-top: 40px; outline: none; }   /* Figma 550:451 gap */
.mslider:focus-visible .ms-track::before { box-shadow: 0 0 0 2px var(--blue-lift); }

/* Scale anchors, not headings. */
/* Geist Medium, uppercase, tracked, in --mid. */
.ms-ends {
  display: flex; justify-content: space-between; gap: var(--s4);
  font-family: var(--label); font-weight: 500;
  font-size: 17.1px; line-height: 1.4;
  letter-spacing: 0.13em; text-transform: uppercase;
  color: #004C77;   /* Figma 550:456 */
}
.ms-ends span:last-child { text-align: right; }

/* 56px tall so the whole strip is the touch target; the rail it draws is 6px. */
.ms-track {
  position: relative; height: 56px; margin: var(--s1) 0 var(--s2);
  cursor: pointer; touch-action: none;
}
.ms-track::before {
  content: ''; position: absolute; left: 0; right: 0; top: 50%;
  height: 6px; margin-top: -3px; border-radius: 3px;
  background: rgba(0, 76, 119, 0.20);
}
.ms-fill {
  position: absolute; left: 0; top: 50%; width: 0;
  height: 6px; margin-top: -3px; border-radius: 3px;
  background: var(--brand);
  transition: width 0.18s var(--ease);
}
.ms-ticks {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: space-between;
  pointer-events: none;
}
.ms-ticks i {
  display: block; width: 12px; height: 12px; border-radius: 50%;
  background: rgba(0, 76, 119, 0.34);
  transition: background 0.18s var(--ease), transform 0.18s var(--ease);
}
.ms-ticks i.on { background: var(--brand); }
.ms-thumb {
  position: absolute; top: 50%; left: 0;
  width: 34px; height: 34px; border-radius: 50%;
  transform: translate(-50%, -50%) scale(0.2);
  background: #FFFFFF;
  box-shadow: 0 2px 10px rgba(0, 65, 108, 0.28), 0 0 0 6px rgba(0, 124, 195, 0.14);
  opacity: 0; pointer-events: none;
  transition: left 0.18s var(--ease), transform 0.2s var(--ease), opacity 0.2s var(--ease);
}
.ms-thumb.set { opacity: 1; transform: translate(-50%, -50%) scale(1); }
/* Unanswered: the thumb waits at the start of the line and pulses, so it reads
   as the thing to touch. The ring breathes out and fades; it stops on the
   first answer (.set). */
.ms-thumb:not(.set) {
  left: 0; opacity: 1; transform: translate(-50%, -50%) scale(1);
  animation: msThumbIn 0.5s var(--ease) 0.75s both,
             msPulse 1.8s ease-out 1.3s infinite;
}
/* On the first question of a run only (app.js adds .coach): once it has
   arrived it nudges along the line and back, twice, so it reads as something
   that slides rather than a dot to tap. Every later question just pulses. */
.mslider.coach .ms-thumb:not(.set) {
  animation: msThumbIn 0.5s var(--ease) 0.75s both,
             msNudge 1.5s cubic-bezier(0.45, 0, 0.25, 1) 1.35s 2,
             msPulse 1.8s ease-out 1.3s infinite;
}
@keyframes msNudge {
  0%, 100% { left: 0; }
  42%      { left: 15%; }
  58%      { left: 15%; }
}
.ms-thumb::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  box-shadow: 0 0 0 0 rgba(0, 124, 195, 0.55);
  opacity: 0; pointer-events: none;
}
.ms-thumb:not(.set)::after { animation: msRing 1.8s ease-out 1.3s infinite; }
@keyframes msThumbIn { from { opacity: 0; transform: translate(-50%, -50%) scale(0.2); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
@keyframes msPulse {
  0%, 100% { box-shadow: 0 2px 10px rgba(0, 65, 108, 0.28), 0 0 0 6px rgba(0, 124, 195, 0.14), 0 0 0 0 rgba(0, 124, 195, 0); }
  45%      { box-shadow: 0 2px 14px rgba(0, 65, 108, 0.30), 0 0 0 9px rgba(0, 124, 195, 0.24), 0 0 28px 6px rgba(0, 124, 195, 0.35); }
}
@keyframes msRing {
  0%   { opacity: 1; box-shadow: 0 0 0 0 rgba(0, 124, 195, 0.50); }
  100% { opacity: 0; box-shadow: 0 0 0 26px rgba(0, 124, 195, 0); }
}

/* Reserves the tallest reading in the set (5.58em) so Next never moves. */
.ms-read { min-height: 5.7em; }
.ms-hint {
  font-size: clamp(15px, 1.027cqw, 18.2px);
  color: var(--mid);
}
.ms-hint.gone { display: none; }
.ms-label {
  /* Figma 550:466: the stop's name semibold, its description regular, both 22px
     on 1.6 in #004C77. */
  font-weight: 600; font-size: 23.5px; line-height: 1.6; color: #004C77;
}
.ms-detail { font-size: 23.5px; line-height: 1.6; color: #004C77; margin-top: 0; }

/* ---- slider motion ----
   Entrance, replayed by buildSlider on every question: the track draws from the left, the stops land in turn, the end labels rise. */
.mslider.enter .ms-track { animation: msTrackIn 0.9s var(--ease-in-out-soft) both; }
.mslider.enter .ms-ticks i { animation: msTickIn 0.5s var(--ease-in-out-soft) both; }
.mslider.enter .ms-ticks i:nth-child(1) { animation-delay: 0.20s; }
.mslider.enter .ms-ticks i:nth-child(2) { animation-delay: 0.32s; }
.mslider.enter .ms-ticks i:nth-child(3) { animation-delay: 0.44s; }
.mslider.enter .ms-ticks i:nth-child(4) { animation-delay: 0.56s; }
.mslider.enter .ms-ticks i:nth-child(5) { animation-delay: 0.68s; }
.mslider.enter .ms-ends span { animation: rise 0.7s var(--ease) both; }
.mslider.enter .ms-ends span:last-child { animation-delay: 0.12s; }
.mslider.enter .ms-hint { animation: rise 0.7s var(--ease) 0.5s both; }
@keyframes msTrackIn { from { transform: scaleX(0); opacity: 0; } to { transform: scaleX(1); opacity: 1; } }
.ms-track { transform-origin: left center; }
@keyframes msTickIn { from { transform: scale(0.2); opacity: 0; } to { transform: scale(1); opacity: 1; } }
/* The reading, each time the stop changes. */
.ms-read.swap .ms-label,
.ms-read.swap .ms-detail { animation: riseIn 0.42s var(--ease) both; }
.ms-read.swap .ms-detail { animation-delay: 0.06s; }

@media (prefers-reduced-motion: reduce) {
  .ms-fill, .ms-thumb, .ms-ticks i { transition: none; }
  .ms-thumb:not(.set), .ms-thumb:not(.set)::after { animation: none; }
  .mslider.enter *, .ms-read.swap * { animation: none !important; }
}

.qactions {
  margin-top: var(--s5); padding-top: var(--s4);
  border-top: 1px solid var(--hair);
  display: flex; align-items: center; gap: var(--s4);
}
/* Back and Next: the pool screens' pills, side by side on the right, so the
   two things that move you through the run sit under the thumb together and
   nothing else shares their row (Figma has them left; this is the change). */
/* 747 wide, so the row ends at 1843 — the right edge of the AI Value mark. */
.qactions { gap: 16px; justify-content: flex-end; border-top: 0; padding-top: 0; margin-top: 74px; width: 747px; }
.qnav { display: flex; align-items: center; gap: 16px; }
/* One case and every case in one place: the way into the gallery rides on the
   card as a mark in the corner, where the 270px pill used to eat a third of the
   row. The card runs the full width to 1843, level with the mark in the header,
   rather than stopping at the file's 696. */
/* Figma 655:682 / 656:825: two cards in a row, 16 apart, 36 under the readout. */
.qcase-row { position: relative; width: 747px; margin-top: 36px; display: flex; gap: 16px; align-items: flex-start; }
/* The case card (655:719): 499x175, the headline at (43, 31) in 348, the line
   at x 25 from y 31 for 69, "Read the case" at (44, 120). */
.qcase-row .qcase-card {
  /* One fixed height whatever the headline's length: the title clamps to three
     lines and "Read the case" pins to the foot, so both cards always match. */
  width: 499px; height: 180px; min-height: 0; margin-top: 0;
  padding: 28px 40px 22px 43px;
}
.qcase-row .qcase-card .qcc-line { left: 25px; top: 28px; width: 1px; height: 66px; background: #007CC3; }
.qcase-row .qcase-card .qcc-title {
  margin: 0; max-width: 348px;
  font-weight: 300; font-size: 21.4px; line-height: 1.02; letter-spacing: -0.026em; color: var(--ink);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.qcase-row .qcase-card .qcc-read { margin-top: auto; padding-top: 18px; font-weight: 300; font-size: 19.3px; line-height: 1.58; }
/* The way to the pool's other cases (656:823): 210x174, the file's icon, the
   link along the foot. */
.qcase-row .qcase-all {
  width: 210px; height: 180px; min-height: 0; padding: 27px 8px 22px; align-items: center;
}
.qcase-row .qcase-all[hidden] { display: none; }
.qcase-row .qcase-all .qca-icon { display: block; width: 93px; height: 93px; }
.qcase-row .qcase-all .qcc-read {
  margin-top: auto; padding-top: 6px;
  /* Wraps inside the 210px card and centres, instead of running past its edge. */
  display: block; white-space: normal; text-align: center;
  font-size: 16.5px; line-height: 1.3; max-width: 100%; padding-left: 2px; padding-right: 2px;
}
.qcase-row .qcase-all .qcc-arrow { margin-left: 2px; white-space: nowrap; }
/* 22 Sep: with the single-case card retired (app.js SHOW_CASE_CARD), "View all
   case studies" is the row's only card and runs its full width as a low strip:
   the icon at the left, the link beside it. */
.qcase-row.all-only .qcase-all {
  width: 747px; min-height: 0;
  flex-direction: row; align-items: center; gap: 26px;
  padding: 22px 40px 22px 30px;
}
.qcase-row.all-only .qcase-all .qca-icon { width: 62px; height: 62px; }
.qcase-row.all-only .qcase-all .qcc-read { margin-top: 0; padding-top: 0; font-size: 21.4px; }
/* 23 Sep: a pool with no case of its own keeps "View all" at its usual size,
   in its usual place on the right, so it doesn't move between questions. */
.qcase-row.no-case { justify-content: flex-end; }
/* The case card (Figma 550:467): 696x142, card gradient, 1px white border, radius 20, brand-blue line down the left. */
.qcase-card {
  position: relative; display: flex; flex-direction: column; align-items: flex-start;
  width: 696px; min-height: 142px; margin-top: var(--s5);
  padding: 20px 40px 18px 57px; text-align: left;
  border-radius: var(--radius); border: 1px solid #FFFFFF;
  background: var(--card); box-shadow: var(--card-shadow);
  cursor: pointer;
}
.qcase-card[hidden] { display: none; }
.qcase-row[hidden] { display: none; }
.qcase-card .qcc-line { position: absolute; left: 32px; top: 27px; width: 3px; height: 89px; border-radius: 2px; background: #5EB2F5; }
.qcase-card .qcc-metric { font-size: 27.8px; line-height: 1.4; color: #000; }
.qcase-card .qcc-title { margin-top: 2px; font-size: 23.5px; line-height: 1.6; color: #000; }
.qcase-card .qcc-read { margin-top: 3px; font-weight: 300; font-size: 19.3px; line-height: 1.58; color: var(--brand); display: inline-flex; flex-wrap: nowrap; align-items: center; gap: 6px; white-space: nowrap; }
.qcase-card .qcc-arrow { flex: none; font-family: var(--body); }
.qcase-card:active { background: rgba(255, 255, 255, 0.85); }
.qactions .pn-arrow { pointer-events: auto; }
.qactions .pn-arrow[disabled] { opacity: 0.34; pointer-events: none; }
.qactions .pn-arrow[hidden] { display: none; }
.btn .arrow.back { font-size: 1.15em; }

/* Six-step position indicator. */

/* ---------- results ----------------------------------------- */

#v-wrap { display: none; }
#v-wrap.on { display: block; }
.beat {
  position: absolute; inset: var(--pad-t) var(--pad-x) var(--pad-b);
  display: none; padding-bottom: clamp(34px, 3.4cqw, 62px);
}
/* content sits centred in the leftover height; the nav keeps its own band */
.beat.on {
  display: flex; flex-direction: column; justify-content: center; gap: var(--s6);
  animation: rise 0.72s var(--ease) both;
}

/* The V4 plates are calm enough for the copy to sit straight on them. */

.beat-nav {
  position: absolute; left: 0; right: 0; bottom: 0;
  display: flex; align-items: center; justify-content: space-between;
}
/* The results screens use the question screen's nav: round back + NEXT pill,
   bottom right. The step pips are gone, so there is nothing on the left. */
.beat-nav { justify-content: flex-end; }
.beat-nav .qnav { display: flex; align-items: center; gap: var(--s3); pointer-events: auto; }
/* Beats 1 and 2 keep the question screen's exact 143px NEXT pill; only the last
   beat, whose label is longer, is allowed to grow. */
#beat3 .beat-nav .pn-next { width: auto; padding: 0 34px; }

/* ---- beat 1: your position ----
   Heading from Figma 454:92 (icon slot, name, tagline); body and featured benchmark panel below. */
.arch-wrap { width: min(1320px, 88cqw); margin: 0 auto; display: flex; flex-direction: column; gap: var(--s6); }
#beat1 .b1 { text-align: left; }
.pos-label { display: block; font-size: 15px; letter-spacing: 0.13em; color: var(--brand); margin-bottom: 45px; }
.pos-row { display: flex; align-items: center; gap: 57px; }
/* The design's 247x219 image slot. */
.pos-glyph { flex: none; width: 247px; height: 219px; display: flex; align-items: center; justify-content: center; }
.pos-icon { display: block; max-width: 247px; max-height: 219px; width: auto; height: auto; }
.pos-icon[hidden] { display: none; }
.pos-glyph .arch-glyph { width: 200px; }
.pos-glyph .arch-glyph[hidden] { display: none; }
.arch-hex { display: block; width: 100%; height: auto; overflow: visible; }
.ag-seg { stroke: rgba(0, 105, 168, 0.26); }
.ag-seg.on { stroke: var(--brand); }
.pos-text { min-width: 0; display: flex; flex-direction: column; gap: 22px; }
.pos-name {
  font-family: var(--display); font-weight: 300;
  font-size: 57.8px; line-height: 1.06; letter-spacing: -0.014em; color: var(--ink); text-wrap: balance;
}
.pos-tag { font-weight: 500; font-size: 21.4px; line-height: 1.6; color: var(--blue-lift); }

/* Copy on the left, the strongest benchmark result on the right. */
#beat1 .arch-cols {
  display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: var(--s5);
  align-items: start;
}
#beat1 .arch-cols:has(.arch-stat[hidden]) { grid-template-columns: minmax(0, 1fr); }
#beat1 .arch-text { display: flex; flex-direction: column; gap: var(--s4); max-width: 74ch; }
#beat1 .arch-body { font-size: clamp(15.2px, 1.025cqw, 19.5px); }
#beat1 .arch-risk {
  padding-left: var(--s3); border-left: 2px solid var(--blue);
  font-size: clamp(15.2px, 1.049cqw, 19.5px); line-height: 1.6; color: var(--fg-2);
}

/* The featured benchmark number. On the card surface so it reads as a lifted
   panel rather than as a third paragraph. */
.arch-stat {
  background: var(--card); border: 1px solid var(--card-line);
  border-radius: var(--radius); box-shadow: var(--card-shadow);
  padding: clamp(18px, 1.72cqw, 33px) clamp(16px, 1.354cqw, 26px);
}
.arch-stat[hidden] { display: none; }
.as-num {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(40.7px, 3.852cqw, 73.8px); line-height: 1.0; letter-spacing: -0.03em;
  color: var(--blue-lift);
}
.as-unit {
  margin-top: var(--s2);
  font-family: var(--label); font-weight: 600; font-size: clamp(12.8px, 0.802cqw, 15.4px);
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--fg-3);
}
.as-pool { margin-top: var(--s3); font-size: clamp(16.1px, 1.124cqw, 21.4px); color: var(--fg); }
.as-band { margin-top: 2px; font-size: clamp(13.9px, 0.877cqw, 16.5px); color: var(--fg-4); }

/* beat 2 — benchmark */
.bench-head { text-align: left; }
.bench-head .d-m { margin-top: var(--s2); }
.bench-praise { margin-top: var(--s3); font-size: clamp(14.8px, 1.066cqw, 20.4px); max-width: none; white-space: nowrap; }   /* always one line */
.bench-praise b { color: var(--blue-lift); font-weight: 500; }
.bench-list { display: flex; flex-direction: column; }
.bench-row {
  display: grid; grid-template-columns: 13.5em 1fr 6.2em; align-items: center; gap: var(--s4);
  padding: clamp(8px, 0.7cqw, 15px) 0; border-bottom: 1px solid var(--hair);
}
.bench-row:first-child { border-top: 1px solid var(--hair); }
.bench-row .nm { font-size: clamp(14.6px, 0.984cqw, 18.4px); line-height: 1.25; color: var(--fg); }
/* Sentence case. */
/* Measured against the PLATE, not against white. */
.bench-row .bd {
  font-size: clamp(13.9px, 0.877cqw, 16.5px); margin-top: 1px;
  font-weight: 500; color: var(--fg-4);
}
.bench-row .bd-0 { color: #C0271D; }   /* Unstarted     4.70:1 on plate */
.bench-row .bd-1 { color: #A34D00; }   /* Piloting      4.61:1 */
.bench-row .bd-2 { color: #7A6200; }   /* Scaling       4.67:1 */
.bench-row .bd-3 { color: #0E7264; }   /* Orchestrating 4.62:1 */
.bench-row .bd-4 { color: #1A743A; }   /* Compounding   4.63:1 */
/* A pool the visitor chose not to assess: named, unscored, no bar. */
.bench-row.na .nm { color: var(--fg-4); }
.bench-row .bd-na { color: var(--fg-4); font-weight: 400; }
.bench-row.na .track { background: transparent; border-top: 1px dashed rgba(0, 76, 119, 0.22); height: 0; }
.bench-row.na .val .raw { color: var(--fg-4); }
.track { position: relative; height: 6px; background: rgba(0, 76, 119, 0.07); }
.track .fill { position: absolute; inset: 0 auto 0 0; width: 0; transition: width 1.1s var(--ease-mech); }
/* The industry range (BENCHMARK_BAND), a shaded region on every track. The
   edges are set once on .bench-list from the data, so rows cannot drift. */
.track .bandzone {
  position: absolute; top: -9px; bottom: -9px;
  left: var(--band-from, 38%); right: calc(100% - var(--band-to, 62%));
  background: rgba(0, 124, 195, 0.11);
  border-left: 1px solid rgba(0, 76, 119, 0.32);
  border-right: 1px solid rgba(0, 76, 119, 0.32);
}
.track .bandzone.labelled::after {
  content: 'WHERE MOST MANUFACTURERS SIT'; position: absolute; top: -23px; left: 50%; transform: translateX(-50%);
  font-family: var(--label); font-weight: 500; font-size: 13.4px;
  letter-spacing: 0.11em; color: var(--fg-3); white-space: nowrap;
}
.bench-row.na .track .bandzone { display: none; }
/* 22 Sep (Rob): the score alone, large — no Above / In range / Below word. The
   range on the track already says where the score sits. */
.bench-row .val { text-align: right; }
/* 23 Sep: an assessed pool's stage sits under its score, right-aligned. */
.bench-row .val .bd { margin-top: 6px; }
.bench-row .val b.score {
  display: block; font-family: var(--display); font-weight: 300;
  font-size: 40px; line-height: 1; letter-spacing: -0.02em; color: var(--ink);
}
.bench-row .val b.score .of { font-size: 0.5em; font-weight: 400; color: var(--fg-3); letter-spacing: 0; margin-left: 2px; }
.bench-row .val .raw {
  font-family: var(--label); font-weight: 400; font-size: clamp(13.9px, 0.856cqw, 15.6px);
  letter-spacing: 0.1em; color: var(--fg-3);
}
.v-above { color: var(--blue-lift); }
.v-in, .v-below { color: var(--ink); }
/* The range is wider than a tick, so the value column takes a little more room for "In range". */
.bench-row { grid-template-columns: 13.5em 1fr 7.4em; }

/* The standing industry stat between the subhead and the chart. */
.bench-stat {
  margin: 18px 0 0; padding: 12px 16px; max-width: 62ch;
  border-left: 3px solid var(--brand); background: rgba(255, 255, 255, 0.55);
}
.bench-stat .n {
  font-family: var(--display); font-weight: 300; font-size: clamp(23.5px, 1.498cqw, 27.8px);
  line-height: 1; letter-spacing: -0.02em; color: var(--blue-lift);
}
.bench-stat .t { margin-top: 5px; font-size: clamp(14.4px, 0.813cqw, 15.5px); line-height: 1.4; color: var(--fg-2); }
/* The beat-1 stat carries words where it used to carry "+N". */
.arch-stat .as-num-text { font-size: clamp(25.7px, 2.033cqw, 38.5px); line-height: 1.12; letter-spacing: -0.015em; }

/* beat 3 — forecast, columns divided by rules not boxes */
/* Head and content share one left edge. Scoped by class because beats get reordered. */
.bench-wrap {
  width: min(1320px, 88cqw); margin: 0 auto;
  display: flex; flex-direction: column; gap: var(--s6);
}
/* This beat carries six rows and a source credit under them, which is more than
   the shared wrap was spaced for. */
.bench-wrap { gap: var(--s5); }
.bench-wrap .fine-print { margin-top: 0; max-width: 1290px; }   /* clear of the nav at the right */
/* 22 Sep: the beat starts at the top; with the stat gone and the credit in the
   nav row, six rows fit the height with no scrolling. */
/* 23 Sep: heading and result rows together, centred between the header
   (logos) and the footer (credit + nav band). */
#beat2.on { justify-content: center; }
/* The box runs from the foot of the header logos (y 127) to the top of the nav
   band (y 933), so centred here reads as centred between header and footer. */
#beat2 { padding-top: 12px; padding-bottom: 72px; }
#beat2 .bench-wrap { flex: 0 0 auto; min-height: 0; }
.bench-row { padding: 12px 0; }
/* The credit sits in the nav band, left, level with the buttons. */
.beat-nav.bench-nav { justify-content: space-between; align-items: center; }
.bench-credit { margin: 0; max-width: 1180px; font-size: 14.5px; line-height: 1.45; color: var(--fg-3); }
/* ---------- beat 3: your result ------------------------------
   Figma 496:194. */
#beat3.on { display: block; }
.res-left {
  position: absolute;
  /* 22 Sep: brought in from the design's x 67 to sit closer to the ring. */
  left: calc(200px - var(--pad-x)); top: calc(274px - var(--pad-t));
  width: 760px;
  display: flex; flex-direction: column; gap: 44px;
}
/* Scoped to .stagger so app.js can deal the column again every time beat 3
   opens, rather than only on the first paint of the session. */
.res-left.stagger > * { animation: riseIn 0.72s var(--ease-in-out-soft) both; }
.res-left.stagger > :nth-child(1) { animation-delay: 0.10s; }
.res-left.stagger > :nth-child(2) { animation-delay: 0.22s; }
.res-left.stagger > :nth-child(3) { animation-delay: 0.34s; }
/* Figma 550:1187: the eyebrow sits 10 above the headline, not a whole gap. */
.res-head-group { display: flex; flex-direction: column; gap: 10px; }
.res-eyebrow { font-size: 19.3px; font-weight: 400; letter-spacing: 0.13em; color: var(--brand); }
.res-head {
  font-family: var(--display); font-weight: 300;
  font-size: 57.8px; line-height: 1.08; letter-spacing: -0.014em; color: var(--ink);
  margin: 0; text-wrap: balance;
}
.res-body { max-width: 680px; font-weight: 300; font-size: 21.4px; line-height: 1.6; color: var(--ink); margin: 0; }
/* Figma 550:1191 stacked three 52-high rows 22 apart; 22 Sep: the three tiers
   sit in one row, evenly sharing the column, with tighter spacing. */
.res-legend { display: flex; flex-direction: row; align-items: flex-start; gap: 24px; }
.res-row { display: flex; align-items: flex-start; gap: 14px; flex: 1 1 0; min-width: 0; }
.res-row .res-swatch { margin-top: 1px; }
.res-left.stagger .res-row {
  animation: riseIn 0.6s var(--ease-in-out-soft) both;
  animation-delay: calc(0.62s + var(--i, 0) * 0.14s);
}
/* The tier name over its pools, not beside them (Figma 550:1194). */
.res-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
/* The swatch is the wedge's own strength, so the key reads against the ring:
   the same 0.90 / 0.38 / 0.14 the file gives the hexagon. */
.res-swatch {
  flex: none; width: 30px; height: 30px; border-radius: 5px;
  border: 1px solid #fff; background: rgba(0, 124, 195, 0.90);
  box-shadow: 0 2px 10px rgba(0, 124, 195, 0.18);
}
.t-maintain .res-swatch { background: rgba(0, 124, 195, 0.38); }
.t-resolve  .res-swatch { background: rgba(0, 124, 195, 0.14); }
.t-skipped  .res-swatch { background: transparent; border: 1px dashed rgba(0, 124, 195, 0.45); box-shadow: none; }
.t-skipped  .res-pools  { color: var(--fg-4); }
.res-tier {
  font-family: var(--label); font-weight: 600; font-size: 15px;
  letter-spacing: 0.13em; text-transform: uppercase; color: #00568C;
}
.res-pools { font-weight: 300; font-size: 20.3px; line-height: 1.3; color: var(--ink); white-space: normal; }
.res-pools b { font-weight: 300; margin: 0 0.45em; }

/* The ring. A full 1920x1080 layer like #hexWrap, anchored to the frame (the
   beat's own inset is undone) and slid to the design's position. */
.res-hex {
  position: absolute; width: 1920px; height: 1080px;
  left: calc(-1 * var(--pad-x)); top: calc(-1 * var(--pad-t));
  transform: translate(517px, 21px);
  pointer-events: none;
}
.res-hex .hex-hit { pointer-events: none; cursor: default; }
/* Verbatim from Figma 550:1140: the two leading wedges sit at 0.90, the two
   middle ones at 0.38, the two trailing ones at 0.14. Nothing in between. */
.res-hex .hex-seg .hex-tex                         { opacity: 0.90; }
.res-hex .hex-seg[data-tier='maintain'] .hex-tex { opacity: 0.38; }
.res-hex .hex-seg[data-tier='resolve']  image { opacity: 0.14; }
.res-hex .hex-seg[data-tier='skipped']  image { opacity: 0.05; }
.res-hex .hex-labels .hex-lbl[data-tier='skipped'] { opacity: 0.35; }
.res-hex .hex-seg .hex-tex { transition: opacity 0.5s var(--ease); }
/* Builds in the same way the overview does, a touch quicker. */
.res-hex.enter .hex-seg {
  animation: hexIn 1000ms var(--ease-in-out-soft) both;
  animation-delay: calc(0.2s + var(--i, 0) * 240ms);
}
.res-hex.enter .hex-labels .hex-lbl {
  animation: hexIn 1000ms var(--ease-in-out-soft) both;
  animation-delay: calc(0.36s + var(--i, 0) * 240ms);
  transform-origin: center;
}
@media (prefers-reduced-motion: reduce) {
  .res-left.stagger > *, .res-left.stagger .res-row, .res-hex.enter .hex-seg, .res-hex.enter .hex-labels .hex-lbl { animation: none; }
}

/* three retrieval routes on the closing screen */
.retrieve { list-style: none; margin: var(--s4) auto 0; max-width: 42ch; text-align: left; }
/* Flex, not grid: Safari sized the grid column at min-content and broke every line. */
.retrieve li {
  display: flex; gap: var(--s2); align-items: baseline;
  padding: var(--s2) 0; border-bottom: 1px solid var(--hair);
  font-size: clamp(14.8px, 1.021cqw, 19.3px); color: var(--fg-2);
}
.retrieve li[hidden] { display: none; }   /* the flex display beat the hidden attribute */
.retrieve li > span:last-child { flex: 1 1 auto; min-width: 0; }
.retrieve li:first-child { border-top: 1px solid var(--hair); }
.retrieve .r-n {
  flex: 0 0 2.4em;
  font-family: var(--label); font-weight: 600; font-size: clamp(13.9px, 0.856cqw, 16.3px);
  letter-spacing: 0.12em; color: var(--blue-lift);
}
.retrieve b { color: var(--fg); font-weight: 500; }

/* beat 5 — proof */
.pending-note {
  margin-top: var(--s4); padding-left: var(--s3); border-left: 2px solid var(--blue-deep);
  font-family: var(--label); font-weight: 400; font-size: clamp(13.9px, 0.886cqw, 16.3px);
  letter-spacing: 0.08em; line-height: 1.9; color: var(--fg-3);
}
.pending-note b { color: var(--blue-lift); letter-spacing: 0.13em; }

/* ---------- delivery ---------------------------------------- */

#v-identify { display: none; }
#v-identify.on { display: grid; place-items: center; }
/* Dark-ground pseudo-element; kept off on the white build. */
/* Wider than the other statement screens: the reader needs room to be the
   subject rather than a detail under the copy. */
.deliver-wrap { text-align: center; width: min(860px, 58cqw); }

/* ---------- identify, from Figma 326:280 ---------------------
   Geometry in frame pixels, like the diagnostic column and the case reader: #frame is a fixed 1920x1080 surface scaled by. */
/* No view padding here: everything on this screen is placed at the file's own
   frame coordinates, so the padding would only offset them. */
#v-identify { padding: 0; }
/* Full-bleed, but must not sit over the form and swallow its taps. */
#v-identify .deliver-wrap {
  position: absolute; inset: 0; width: auto;
  display: grid; place-items: center;
  pointer-events: none;
}
#v-identify .id-done { pointer-events: auto; }
#v-identify .id-ask {
  position: absolute; left: 0; right: 0; top: 198px;
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
}
#v-identify .id-ask[hidden] { display: none; }
.id-art-wrap { position: relative; display: block; width: 396px; height: 264px; }
.id-art { display: block; width: 396px; height: 264px; object-fit: contain; }   /* Figma 552:931 */
/* The arrows are baked into the render, so they cannot be made to travel. What
   can travel is the light on them: a highlight swept around the ring's own
   silhouette, which reads as the orbit turning while the document holds still. */
/* The mask is inlined, not linked: this runs from file:// on the stand, and
   Chrome will not load a CSS mask-image off a file:// URL — it resolves to an
   empty mask and the whole layer disappears. A data URI has no origin to
   refuse. It is the orbit's own silhouette, lifted out of the render. */
.id-orbit {
  position: absolute; inset: 0; overflow: hidden; pointer-events: none;
  --orbit-mask: url('data:image/png;base64,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');
  -webkit-mask-image: var(--orbit-mask);   mask-image: var(--orbit-mask);
  -webkit-mask-size: 100% 100%;   mask-size: 100% 100%;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  mix-blend-mode: screen;
}
.id-orbit i {
  position: absolute; left: 51%; top: 58%;
  width: 300%; height: 300%;
  transform: translate(-50%, -50%);
  background: conic-gradient(from 0deg,
    rgba(255, 255, 255, 0)    0deg,
    rgba(255, 255, 255, 0)   28deg,
    rgba(150, 210, 255, 0.62) 58deg,
    rgba(255, 255, 255, 1)    78deg,
    rgba(150, 210, 255, 0.62) 98deg,
    rgba(255, 255, 255, 0)  130deg,
    rgba(255, 255, 255, 0)  360deg);
  animation: orbitRun 3.8s linear infinite;
}
/* Counter-clockwise, the way the arrowheads point (up on the right, down on the left). */
@keyframes orbitRun { to { transform: translate(-50%, -50%) rotate(-1turn); } }
@media (prefers-reduced-motion: reduce) { .id-orbit { display: none; } }
.id-eyebrow {
  margin-top: 29px;
  font-family: var(--label); font-weight: 400; font-size: 19.3px; line-height: 1.4;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--blue-lift);
}
#v-identify .id-title {
  margin-top: 10px;
  font-family: var(--display); font-weight: 300;
  font-size: 57.8px; line-height: 1.06; letter-spacing: -0.014em; color: var(--ink);
}

.id-form { margin-top: 24px; display: flex; flex-direction: column; align-items: center; }
.id-field {
  position: relative; display: block;
  width: 384px; height: 69px;
  border: 2px solid var(--card-line); border-radius: 5px;
  box-shadow: 2px 4px 20px 0 rgba(0, 65, 108, 0.05);
}
.id-field + .id-field { margin-top: 18px; }
.id-field input {
  display: block; width: 100%; height: 100%;
  background: transparent; border: none; border-radius: inherit;
  text-align: center; color: var(--ink);
  font-family: var(--body); font-weight: 300; font-size: 25.7px;
  padding: 0 var(--s3);
}
.id-field input:focus { outline: none; }
.id-field:focus-within { border-color: var(--blue-lift); }
/* The real placeholder is hidden: the visible one is the row below, so the icon
   and the words travel together and stay centred as a pair. */
.id-field input::placeholder { color: transparent; }
.id-ph {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  pointer-events: none; opacity: 0;
  transition: opacity 0.18s var(--ease);
  font-family: var(--label); font-weight: 500; font-size: 17.1px;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--fg-4);
}
.id-field input:placeholder-shown ~ .id-ph { opacity: 1; }
.id-ph-ico { width: 19px; height: 19px; display: block; }
.id-ph-at { font-weight: 500; font-size: 19.3px; }

/* 71px, per the file; the shared .btn padding would make it 81. */
.id-form .id-go {
  margin-top: 47px;
  width: 287px; height: 71px; min-height: 71px;
  padding-top: 0; padding-bottom: 0;
}
.id-form .mf-error { margin-top: var(--s3); }
/* Name and email are not compulsory: the same underlined link as the
   framework screen sits under the pill as the way past. */
.id-form .id-skip { margin-top: 24px; color: var(--btn-ink); }
.id-form .id-skip u { text-decoration-color: var(--pill-line); }
.deliver-wrap .lede { margin: var(--s3) auto 0; max-width: 46ch; }
.id-title { margin-top: var(--s2); }

/* ---------- on-screen keyboard (js/osk.js) ------------------
   22 Sep: the stand is a touch screen that may have no keyboard attached. A
   keyboard icon sits in each field; on a touch device the keys also rise when a
   field is tapped. While open the art hides and the form lifts, so the keys
   sit under the button rather than over it. */
.id-kbd {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; border-radius: 8px;
  display: grid; place-items: center;
  color: var(--blue-lift); opacity: 0.8;
  pointer-events: auto; cursor: pointer;
  transition: opacity 0.18s var(--ease), background 0.18s var(--ease);
}
.id-kbd svg { width: 24px; height: 16px; display: block; }
.id-kbd:active, .id-field:focus-within .id-kbd { opacity: 1; background: rgba(0, 124, 195, 0.08); }
.id-field { padding-right: 0; }
.id-field input { padding-right: 58px; padding-left: 58px; }   /* centred text clears the icon */

.osk {
  /* Centred with auto margins, not a transform: the rise animation owns transform. */
  position: absolute; left: 0; right: 0; bottom: 26px; margin: 0 auto;
  width: 1000px; padding: 16px; overflow: hidden;
  display: flex; flex-direction: column; gap: 10px;
  border-radius: 22px;
  background: rgba(255, 255, 255, 0.62);
  border: 1px solid var(--glass-line);
  box-shadow: 2px 8px 40px 0 rgba(0, 65, 108, 0.16);
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  pointer-events: auto; z-index: 8;
  animation: rise 0.32s var(--ease) both;
  user-select: none; touch-action: manipulation;
}
.osk[hidden] { display: none; }
.osk-row { display: flex; justify-content: center; gap: 10px; }
.osk-key {
  flex: 0 0 84px; height: 64px;
  display: grid; place-items: center;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.85);
  border: 1px solid #FFFFFF;
  box-shadow: 0 2px 8px rgba(0, 65, 108, 0.08);
  font-family: var(--body); font-weight: 400; font-size: 27px; line-height: 1;
  color: var(--ink);
  transition: background 0.08s var(--ease), transform 0.08s var(--ease);
}
.osk-key:active { background: rgba(0, 124, 195, 0.16); transform: translateY(1px); }
.osk-key.osk-fn {
  background: rgba(0, 124, 195, 0.10);
  font-family: var(--label); font-weight: 500; font-size: 20px; color: var(--blue-deep);
}
.osk-key.w15 { flex-basis: 131px; }
.osk-key.w2  { flex-basis: 131px; }
.osk-key.w5  { flex-basis: 178px; }   /* every row adds up to the 930px of the letter rows */
.osk-key.w1  { flex-basis: 84px; }
.osk-key[data-key="{shift}"] span, .osk-key[data-key="{bksp}"] span, .osk-key[data-key="{hide}"] span { font-size: 28px; }
.osk.shift .osk-key[data-key="{shift}"] { background: var(--brand); color: #fff; }
.osk-key[data-key="{next}"] { background: var(--brand); color: #fff; border-color: var(--brand); }
.osk-key[data-key="{next}"]:active { background: var(--blue-lift); }
.osk-key[data-key=".com"] { font-family: var(--body); font-weight: 400; font-size: 23px; color: var(--ink); background: rgba(255, 255, 255, 0.85); }

/* The lifted form: art and orbit away, everything else up to make room. */
#v-identify.osk-open .id-art-wrap { display: none; }
#v-identify.osk-open .id-ask { top: 92px; }
#v-identify.osk-open .id-eyebrow { margin-top: 0; }
#v-identify.osk-open .id-form .id-go { margin-top: 30px; }
#v-identify.osk-open .id-form .id-skip { margin-top: 14px; }

/* ---------- email capture ----------------------------------
   One field, centred, sized like the rest of the build rather than like a form control. */
/* Centred, like the rest of the screen. */
.email-form { margin: var(--s6) auto 0; max-width: 520px; text-align: center; }
.ef-field { display: block; }
.ef-label {
  display: block; font-family: var(--label); font-weight: 500;
  font-size: clamp(13.9px, 0.856cqw, 16.3px); letter-spacing: 0.13em;
  text-transform: uppercase; color: var(--fg-3);
}
.email-form input {
  display: block; width: 100%; margin-top: var(--s2); text-align: center;
  background: transparent; border: none; border-bottom: 1px solid var(--hair);
  color: var(--fg); font-family: var(--body); font-weight: 300;
  font-size: clamp(18.2px, 1.445cqw, 27.8px); letter-spacing: normal;
  /* 56px of field, so it is a real target for a finger on a touchscreen. */
  padding: var(--s3) 0; min-height: 56px;
  transition: border-color 0.24s var(--ease);
}
.email-form input::placeholder { color: var(--fg-4); }
.email-form input:focus { outline: none; border-bottom-color: var(--blue-lift); }
.email-form .btn.primary { margin-top: var(--s5); }
.mf-error {
  font-family: var(--label); font-weight: 400; font-size: clamp(13.9px, 0.856cqw, 16.3px);
  letter-spacing: 0.12em; color: #E0736B; margin-top: var(--s3); min-height: 15px;
}

/* ---------- the acknowledgement ------------------------------
   Shown in place of the field. */
.id-done { display: flex; flex-direction: column; align-items: center; }
.id-done[hidden] { display: none; }
.id-done .lede { margin-top: var(--s3); }
.id-done #idDoneEmail { color: var(--blue-lift); }
.id-done .btn.primary { margin-top: var(--s5); }
.id-tick {
  width: clamp(56px, 4.6cqw, 88px); height: clamp(56px, 4.6cqw, 88px);
  margin-bottom: var(--s4);
  display: grid; place-items: center;
  border: 1px solid var(--glass-line); border-radius: 50%;
  background: rgba(0, 76, 119, 0.05);
}
.id-tick svg { width: 58%; height: 58%; overflow: visible; }
.id-tick path {
  fill: none; stroke: var(--blue-lift); stroke-width: 3.2;
  stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 44; stroke-dashoffset: 44;
  animation: tickIn 0.5s var(--ease-in-out-soft) 0.12s both;
}
@keyframes tickIn { to { stroke-dashoffset: 0; } }
@media (prefers-reduced-motion: reduce) {
  .id-tick path { animation: none; stroke-dashoffset: 0; }
}

/* ---------- the badge reader ----------
   Sized to be the first thing seen, and centred so it lands on the middle of the identify plate, whose hexagon rings. */

/* ---------- done -------------------------------------------- */

/* ---------- done — Figma 487:195 -------------------------------- */
#v-done { display: none; padding: 0; }
#v-done.on { display: block; }
.done-left {
  position: absolute; left: 67px; top: 274px; width: 820px;
  display: flex; flex-direction: column; gap: 40px;
}
.done-head { display: flex; flex-direction: column; gap: 10px; }
.done-eyebrow {
  font-family: var(--label); font-weight: 400; font-size: 19.3px; line-height: 1.4;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--brand);
}
.done-title {
  font-family: var(--display); font-weight: 300; font-size: 57.8px; line-height: 1.06;
  letter-spacing: -0.014em; color: #000;
}
.done-body { width: 700px; font-weight: 300; font-size: 21.4px; line-height: 1.62; color: #000; }
.done-email { color: var(--blue-lift); }
/* The design's card surface, shared by both cards. */
.done-card {
  border-radius: var(--radius); border: 1px solid var(--card-line);
  background: linear-gradient(90deg, rgba(156, 209, 255, 0.30) 3.1%, rgba(91, 165, 230, 0.09) 85.6%);
  box-shadow: var(--card-shadow);
}
.done-specialist { display: flex; flex-direction: column; gap: 14px; padding: 36px 40px 74px; }
.done-label {
  font-family: var(--label); font-weight: 600; font-size: 15px; line-height: 1.4;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--blue-deep);
}
.done-card-title { font-weight: 300; font-size: 32.1px; line-height: 1.4; color: #000; }
.done-card-body { font-weight: 300; font-size: 21.4px; line-height: 1.62; color: #000; }
.done-report {
  position: absolute; left: 1039px; top: 274px; width: 640px;
  display: flex; flex-direction: column; align-items: center; gap: 24px;
  padding: 36px 40px 44px;
}
.done-report .done-label { width: 100%; }
#v-done .qr {
  width: 240px; height: 240px; display: grid; place-items: center;
  border: 1px solid var(--brand); border-radius: 6px;
  background: rgba(255, 255, 255, 0.10);
  font-family: var(--label); font-weight: 500; font-size: 16.1px; line-height: 1.4;
  letter-spacing: 0.13em; text-transform: uppercase; text-align: center; color: var(--brand);
  padding: 0 40px;
}
#v-done .qr.live { padding: 14px; background: #FFFFFF; }
#v-done .qr svg { width: 100%; height: 100%; display: block; }
.done-url { margin-top: -10px; font-family: var(--label); font-size: 13.9px; letter-spacing: 0.06em; color: var(--blue-lift); word-break: break-all; text-align: center; }
.done-url[hidden] { display: none; }
#v-done .retrieve { width: 100%; max-width: none; margin: 0; }
#v-done .retrieve li { padding: 20px 0; border-bottom: 1px solid #9CD1FF; font-size: 21.4px; font-weight: 300; color: #000; }
#v-done .retrieve li:first-child { border-top: none; }
#v-done .retrieve li:last-child { border-bottom: 1px solid #9CD1FF; }
#v-done .retrieve .r-n { flex: 0 0 26px; font-weight: 500; font-size: 16.1px; color: var(--brand); }
.done-foot { position: absolute; left: 67px; top: 937px; }
#v-done .restart-btn {
  width: auto; padding: 0 34px;
  background: #FFFFFF;   
  pointer-events: auto;
}
#v-done .restart-btn:active { background: #EEF6FD; }

/* ---------- narrow preview windows -------------------------- */

@container stage (max-width: 1100px) {
  #v-diag .qcol, #v-explore .col { width: 56%; }
  .pr-tiles { grid-template-columns: 1fr; }
  .bench-row { grid-template-columns: 11em 1fr 6.4em; gap: var(--s3); }   /* room for "In range" */
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ---------- full-bleed washes ----------------------------------
   Plates and film cover the whole window; the 16:9 #frame sits centred inside. */
#v-explore .copy-scrim,
.ts-scrim {
  inset: calc(var(--fy, 0px) / var(--k, 1) * -1) calc(var(--fx, 0px) / var(--k, 1) * -1);
}

/* The case study blocks (Figma 411:1675) now live only in the sheet (#tileSheet). */
/* ---------- before we start: which pools matter (Figma 525:194) ----- */
#v-prio { display: none; padding: 0; }
#v-prio.on { display: block; }
/* Figma 578:2390 centres the column on the frame rather than hanging it from a
   fixed top, so it holds its balance whether one pool is listed or six. Centred
   with justify-content, not a transform: the view's entrance animation owns
   transform and would reset it. */
.prio-copy {
  /* 22 Sep: in from the file's x 67 to sit closer to the ring, as on the results. */
  position: absolute; left: 200px; top: 0; bottom: 0; width: 786px;
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center;
}
.prio-eyebrow { font-weight: 400; font-size: 19.3px; letter-spacing: 0.13em; color: var(--blue-lift); }
.prio-title { margin-top: 10px; font-family: var(--display); font-weight: 300; font-size: 57.8px; line-height: 1.06; letter-spacing: -0.014em; color: var(--ink); }
.prio-lede { margin-top: 26px; width: 786px; font-weight: 300; font-size: 21.4px; line-height: 1.62; color: var(--mid); }
/* Hidden: the ring already shows which pools are in, in the place the visitor
   is looking and tapping. Repeating it as a numbered list on the left said the
   same thing twice and was the only thing making this column tall. Still built
   by app.js, so it stays available to screen readers and to any future layout. */
.prio-list {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  list-style: none;
}
.prio-list li {
  display: flex; align-items: center; gap: 14px; height: 67px;
  border-bottom: 1px solid #9CD1FF;
  animation: rise 0.45s var(--ease) both;
}
.prio-list li b { flex: none; width: 34px; font-family: 'Inter', var(--label); font-weight: 600; font-size: 16.1px; letter-spacing: 0.13em; color: var(--blue-lift); }
.prio-list li span { font-weight: 300; font-size: 23.5px; line-height: 1.4; color: var(--ink); }
/* Six rows plus a hint plus the button did not fit the column, and the hint was
   saying what the ring already says. Gone; the list runs straight into Start. */
.prio-go { margin-top: 48px; min-width: 287px; }
/* Hidden until a pool is chosen; fades in with the first tap. */
/* The stagger's riseIn would otherwise pin the button's opacity, so it is taken off the button. */
/* Out of flow while it is hidden, not just invisible: otherwise an empty screen
   still reserves 99px for it and the copy sits above the centre line. */
.prio-copy.stagger > .prio-go {
  position: absolute; top: 100%; left: 0;
  animation: none; opacity: 0; transform: translateY(8px); pointer-events: none;
  transition: opacity 0.4s var(--ease), transform 0.4s var(--ease);
}
#v-prio.has-choice .prio-copy.stagger > .prio-go { position: static; opacity: 1; transform: none; pointer-events: auto; }
/* The ring: a full 1920x1080 hexagon layer (js/hexagon.js) slid so the ring sits
   in the design's box (1194,163 → the layer's ring at 660,180). */
.prio-hex { position: absolute; left: 529px; top: 30px; width: 1920px; height: 1080px; pointer-events: none; animation: none; }
.prio-hex svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.prio-hex .hex-hit { pointer-events: auto; cursor: pointer; }
.prio-hex .hex-seg .hex-tex { opacity: 0.90; }
.prio-hex .hex-seg[data-tier='resolve'] .hex-tex { opacity: 0.14; }
/* Figma 572:2342 is named "Hexagon — faint (16%)" and means it: an unchosen
   pool is the glass at 0.16, with its label at full strength so the ring stays
   readable. Grayscale put a colour on screen that is nowhere in the file. */
.prio-hex .hex-seg[data-tier='idle'] .hex-tex { filter: none; opacity: 0.16; }
.prio-hex .hex-labels .hex-lbl[data-tier='idle'] { opacity: 1; }
.prio-hex .hex-seg .hex-tex { transition: opacity 0.4s var(--ease), filter 0.4s var(--ease); }
/* Same entrance as the explore hexagon (#hexWrap.enter). */
.prio-hex.enter .hex-seg { animation: hexIn 1400ms var(--ease-in-out-soft) both; animation-delay: calc(var(--i, 0) * 420ms); }
.prio-hex.enter .hex-labels .hex-lbl { animation: hexIn 1400ms var(--ease-in-out-soft) both; animation-delay: calc(220ms + var(--i, 0) * 420ms); transform-origin: center; }
/* Still centred on the file's 1317+327/2 = 1480, but in a box wide enough for
   the line: at 327 it broke after "REMOVE". A transform cannot do the centring
   here — the view's entrance animation owns transform and resets it. */
.prio-tap { position: absolute; left: 1270px; top: 910px; width: 420px; white-space: nowrap; text-align: center; font-family: var(--label); font-weight: 500; font-size: 17.1px; letter-spacing: 0.13em; text-transform: uppercase; color: var(--brand); }

/* ---------- the case study gallery --------------
   Every case opened so far, three columns by two rows, on the case study plate. */
#v-cases { display: none; padding-top: 196px; }
#v-cases.on { display: flex; flex-direction: column; gap: 44px; }
.cg-head { display: flex; flex-direction: column; gap: var(--s2); }
.cg-lede { max-width: 70ch; }
/* Fixed columns and rows: with two cases open the tiles used to stretch to half
   the screen each, which read as panels rather than cards. */
.cg-grid {
  flex: 0 0 auto; min-height: 0;
  display: grid; grid-template-columns: repeat(4, 420px); grid-auto-rows: 250px;   /* a four-line headline and a two-line metric */
  justify-content: start; align-content: start;
  gap: 24px;
}
.cg-grid .tile {
  min-height: 0; padding: 22px 24px;
  background: rgba(255, 255, 255, 0.72); border-radius: var(--radius);
  border: 1px solid #FFFFFF; border-top: 3px solid var(--tile-accent);
  box-shadow: var(--card-shadow); cursor: pointer;
  animation: rise 0.6s var(--ease) both; animation-delay: calc(var(--i, 0) * 0.08s);
}
.cg-grid .tile .t-pool {
  font-family: var(--label); font-weight: 600; font-size: 13.9px;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--tile-accent);
}
/* Five lines did not fit 172 and the metric was being cut by the bottom edge.
   The running number goes: in the gallery the pool name above it already says
   which case this is, and the number said nothing twice. The title holds two
   lines, the metric one, and the tile clips rather than spills. */
.cg-grid .tile { overflow: hidden; }
.cg-grid .tile .t-n { display: none; }
.cg-grid .tile .t-client {
  margin-top: 4px; font-size: 20.3px; line-height: 1.18;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
  overflow: hidden;
}
.cg-grid .tile .t-metric {
  padding-top: 10px; line-height: 1.3;
  /* Two lines rather than an ellipsis: the four featured metrics all fit in two. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; white-space: normal;
}
.cg-empty {
  grid-column: 1 / -1; align-self: start; padding: 26px 30px;
  background: rgba(255, 255, 255, 0.6); border-radius: var(--radius); border: 1px solid #FFFFFF;
  font-size: 19.3px; color: var(--fg-2); max-width: 640px;
}
.cg-foot { display: flex; justify-content: flex-end; margin-top: auto; }
.cg-back { width: auto; padding: 0 28px; pointer-events: auto; }
.cg-back .arrow.back { font-size: 19.3px; }


.case-stack {
  position: absolute; left: 67px; top: 120px; width: 942px;
  display: flex; flex-direction: column; align-items: flex-start;
}
.case-eyebrow {
  margin-bottom: 26px;
  font-family: var(--label); font-weight: 500; font-size: 17.1px; line-height: 1.45;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--blue-lift);
  white-space: nowrap;
}
.case-hero { width: 942px; display: flex; flex-direction: column; gap: 10px; }
.case-title {
  font-family: var(--display); font-weight: 300; font-size: 77px; line-height: 1.02;
  letter-spacing: -0.026em; color: var(--ink); text-wrap: balance;
}
.case-sub { font-size: 26.8px; line-height: 1.3; color: var(--fg-4); }
.case-col {
  margin-top: 34px; width: 580px;
  display: flex; flex-direction: column; gap: 22px;
}
.case-lead { font-weight: 300; font-size: 25.7px; line-height: 1.45; letter-spacing: -0.005em; color: var(--ink); }
.case-sections { display: flex; flex-direction: column; gap: 22px; }
.case-sect { display: flex; flex-direction: column; gap: 8px; }
.case-sect h4 {
  font-family: var(--label); font-weight: 600; font-size: 16.1px; line-height: 1.3;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--fg-4);
}
.case-sect p { font-size: 19.3px; line-height: 1.55; color: var(--mid); }
.case-rule { margin: 28px 0 0 -6px; width: 750px; height: 1px; background: rgba(0, 76, 119, 0.22); }
.case-outcome { margin-top: 22px; width: 826px; }
.case-outcome[hidden] { display: none; }
.case-outcome-label {
  font-family: var(--label); font-weight: 700; font-size: 19.3px; line-height: 1.5;
  letter-spacing: -0.005em; text-transform: uppercase; color: var(--brand);
}
.case-stats { display: flex; align-items: flex-start; }
.case-stat {
  /* Figma 626:683: three 292-wide columns on a 325 pitch, at 1600. Scaled to
     the 1800 card: 328 wide, 366 pitch. Room for a figure that is a phrase
     ("Faster Strategic Decisions") rather than one word ("Halved"). */
  display: flex; flex-direction: column; width: 328px; margin-right: 38px; flex: none; gap: 14px;
  /* Rebuilt per case, so it replays on each page. */
  animation: rise 0.6s var(--ease) both;
  animation-delay: calc(0.6s + var(--i, 0) * 0.18s);
}
.case-stat:nth-child(1) { --i: 0; }
.case-stat:nth-child(2) { --i: 1; }
.case-stat:nth-child(3) { --i: 2; }
.case-stat:nth-child(4) { --i: 3; }
.case-stat:last-child { margin-right: 0; }
.case-stat b { font-weight: 400; font-size: 36.4px; line-height: 1.08; letter-spacing: -0.005em; color: var(--brand); text-wrap: balance; }
.case-stat span { font-weight: 300; font-size: 18.2px; line-height: 1.25; letter-spacing: -0.005em; color: var(--ink); max-width: 300px; }
.case-lead[hidden] { display: none; }
.case-flag { display: none; }   

/* ---------- hover (mouse only) ---------------------------------- */
/* Every button keeps its own rest colour. Hover: plain pills fill pale blue,
   the primary pill fills brand blue; all lift 2px. Fine pointer only, so a
   touch never leaves a stuck hover. */
.btn, .pn-arrow, .ff-back, .fw-skip, .qcase-card, #tileClose, .brand, .tile {
  transition: background 0.2s var(--ease), color 0.2s var(--ease),
              box-shadow 0.2s var(--ease), transform 0.2s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .btn:hover:not([disabled]), .pn-arrow:hover:not([disabled]), .ff-back:hover, #v-done .restart-btn:hover,
  .fw-skip:hover, .qcase-card:hover, #tileClose:hover, .brand:hover, .tile:hover {
    background: var(--pill-fill); transform: translateY(-2px);
  }
  .btn:hover:not([disabled]), .pn-arrow:hover:not([disabled]), .ff-back:hover, #v-done .restart-btn:hover {
    box-shadow: 2px 6px 24px 0 rgba(0, 124, 195, 0.22);
  }
  /* 22 Sep (Rob): the white pills take the solid light blue on hover, not the
     translucent gradient, so the change reads on a white ground. */
  .pn-arrow:hover:not([disabled]), .ff-back:hover, #v-done .restart-btn:hover, #tileClose:hover { background: var(--pill-solid); }
  .btn.primary:hover:not([disabled]) { background: var(--brand); color: #FFFFFF; box-shadow: 2px 6px 24px 0 rgba(0, 124, 195, 0.30); }
  .ff-back:hover, #v-done .restart-btn:hover { color: var(--blue-deep); }
  .ff-back:hover .ff-dot { background: var(--blue-deep); }
  .fw-skip:hover { color: var(--blue-deep); border-radius: 999px; padding-left: 14px; padding-right: 14px; }
  /* White, against the card's pale blue rest state. White alone was invisible
     the first time round, so the lift, the lit rim and the deeper shadow below
     stay: they are what makes the change read from across a stand. */
  .qcase-card:hover, .tile:hover {
    background: #FFFFFF;
    box-shadow:
      0 18px 38px -10px rgba(0, 88, 150, 0.30),
      inset 0 0 0 1px rgba(255, 255, 255, 0.95),
      inset 0 1px 0 rgba(255, 255, 255, 1),
      inset 0 -22px 30px -22px rgba(255, 255, 255, 0.85);
    transform: translateY(-3px);
  }
  .qcase-card:hover .qcc-line { background: var(--brand); width: 4px; }
  .qcase-card:hover .qcc-read { color: var(--blue-deep); }
  .brand:hover { background: rgba(0, 76, 119, 0.08); }
}

/* Wrappers around the hexagon layers; only css/mobile.css gives them a box. */
.hex-box, .res-hex-box { display: contents; }


/* ---------- header at 1440 / 1280 ---------------------------
   .brand and .ai-mark are placed in frame px, so they ride the stage scale
   (--k) down. The logo does not: .brand img holds itself at ~30 real px by
   growing 1/--k, so as the screen shrinks the mark gets taller while its top
   stays at 60px and the lockup drifts away from the top edge. These pull the
   two marks back up by the amount the logo grew. */
@media (max-width: 1600px) {
  .brand   { top: 44px; }
  .ai-mark { top: 28px; }
}
@media (max-width: 1360px) {
  .brand   { top: 36px; }
  .ai-mark { top: 20px; }
}
