/* ============================================================
   CARBONSIG COMPONENTS v2.0 — built ONLY from tokens.css
   Enqueue AFTER tokens.css. Page templates use these classes;
   they never restyle with inline values.
   ============================================================ */

/* ---------- Reset & base ---------- */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{font-family:var(--font-sans);color:var(--c-body);background:var(--s-page);
  line-height:var(--lh-body);-webkit-font-smoothing:antialiased;font-size:var(--t-body)}
img,svg,video{display:block;max-width:100%;height:auto}
a{color:var(--c-link);text-decoration:none;transition:color var(--dur-2) var(--ease)}
a:hover{color:var(--c-action-hover);text-decoration:underline}
:focus-visible{outline:3px solid var(--c-focus);outline-offset:2px;border-radius:4px}
/* Focus ring on dark surfaces — ratified, DESIGN_LANGUAGE §8.6. --c-focus is 1.96:1 on
   --s-navy, a WCAG 1.4.11 failure everywhere a navy band carries a control, including
   the primary closing CTAs. Listed by surface rather than handled per-component so a
   new navy section inherits a compliant ring without anyone remembering to patch it.
   (0,2,0) beats the (0,1,0) base rule; recolours only, so offset/width stay uniform. */
.on-dark :focus-visible,         /* any dark container — section, card or panel */
.section--navy :focus-visible,   /* navy bands + the site footer */
.cta-panel :focus-visible,       /* closing-CTA panel (navy card on a light band) */
.card--navy :focus-visible,
.hx-hero :focus-visible,         /* homepage dark gradient showcase */
.jn-panel :focus-visible{outline-color:var(--c-focus-on-dark)} /* dark product panels (--s-panel) */
/* light islands nested in a dark surface take the light ring back */
.on-light :focus-visible,.vh-panel :focus-visible,
.hx-panel :focus-visible,.product-preview :focus-visible{outline-color:var(--c-focus)}
/* .vh-panel is deliberately NOT listed: it is a LIGHT panel (background:var(--s-page),
   DL §1 — the marketing panel stays light even on a navy band), so its controls need the
   light-surface --c-focus. Listing it here gave them a pale cyan ring on white. */
h1,h2,h3,h4{color:var(--c-heading);letter-spacing:-.02em;line-height:var(--lh-heading)}

/* ---------- Layout ---------- */
.container{max-width:var(--container);margin-inline:auto;padding-inline:var(--gutter)}
.section{padding-block:var(--section-y)}
.section--alt{background:var(--s-alt)}
.section--sunken{background:var(--s-sunken)}
/* ---------- SURFACE INK ROLES ----------
   CLAUDE.md promises "text colour is decided by its surface... this makes invisible
   text impossible". Keying the roles to .section--navy did not deliver that, in BOTH
   directions:
     - a dark card on a LIGHT band (.cta-panel) never matched, so five page
       stylesheets each privately re-coloured its links — all picking the same token;
     - worse, a LIGHT island inside a navy band (.vh-panel) still matched
       ".section--navy p", so its body text rendered white-on-white. Measured 1.00:1
       on /verifiers/ and /platform/ — genuinely invisible, not merely low contrast.

   Fixed by making the ink an INHERITED VARIABLE that the surface sets. The selectors
   below are unchanged in shape, but they now resolve --ink from the nearest surface,
   so a light island simply re-declares the variables and everything inside it flips
   back. Nesting works at any depth, in either direction, with no :not() exclusions.

   Any dark container takes .on-dark — section, card or panel. The three legacy
   classes are listed alongside it so existing markup keeps working. */
.on-dark,.section--navy,.cta-panel,.card--navy{
  --ink:var(--c-on-dark-muted);
  --ink-strong:var(--c-on-dark);
  --ink-link:var(--c-eyebrow-dark);
}
/* A LIGHT island inside a dark surface resets the roles. .vh-panel/.hx-panel/
   .product-preview are the app-faithful marketing panels, which stay light on a navy
   band by DL §1 — that is exactly the case that was rendering invisible. */
.on-light,.vh-panel,.hx-panel,.product-preview{
  --ink:var(--c-body);
  --ink-strong:var(--c-heading);
  --ink-link:var(--c-link);
}
.section--navy{background:var(--s-navy)}
.on-dark,.on-dark p,.on-dark li,.on-dark .body,
.section--navy,.section--navy p,.section--navy li,.section--navy .body,
.cta-panel,.cta-panel p,.cta-panel li,.cta-panel .body,
.card--navy,.card--navy p,.card--navy li,.card--navy .body{color:var(--ink)}
.on-dark h1,.on-dark h2,.on-dark h3,.on-dark h4,
.section--navy h1,.section--navy h2,.section--navy h3,.section--navy h4,
.cta-panel h1,.cta-panel h2,.cta-panel h3,.cta-panel h4,
.card--navy h1,.card--navy h2,.card--navy h3,.card--navy h4{color:var(--ink-strong)}
.on-dark .eyebrow,.section--navy .eyebrow,.cta-panel .eyebrow,.card--navy .eyebrow{color:var(--ink-link)}
/* :not(.btn): button variants keep their own AA colours (P3 fix — .section--navy a was
   overriding .btn--dark to 7DD3FC-on-white, 1.6:1). The .cta-panel arm is what the five
   page stylesheets were each patching privately; it lives here now. */
.on-dark a:not(.btn),.section--navy a:not(.btn),
.cta-panel a:not(.btn),.card--navy a:not(.btn){color:var(--ink-link)}
.on-dark .btn--ghost,.section--navy .btn--ghost,
.cta-panel .btn--ghost,.card--navy .btn--ghost{color:var(--ink-link)} /* 6.48:1 on navy, AA */
.on-dark .hl,.section--navy .hl,.cta-panel .hl,.card--navy .hl{color:var(--ink-link)} /* --c-link is ~2:1 on navy; the on-dark accent is 6.48:1 */

/* ---------- Grid ---------- */
.grid{display:grid;gap:var(--sp-6)}
ol.grid,ul.grid,ol.card-fill,ul.card-fill{list-style:none}
.cols-2{grid-template-columns:repeat(2,1fr)}
.cols-3{grid-template-columns:repeat(3,1fr)}
.cols-4{grid-template-columns:repeat(4,1fr)}
@media (max-width:768px){ .cols-2,.cols-3,.cols-4{grid-template-columns:1fr} }

/* ---------- Typography helpers ---------- */
.h-display{font-size:var(--t-display);font-weight:800;line-height:var(--lh-tight);letter-spacing:-.03em}
.h1{font-size:var(--t-h1);font-weight:800}
.h2{font-size:var(--t-h2);font-weight:800}
.h3{font-size:var(--t-h3);font-weight:700}
.h4{font-size:var(--t-h4);font-weight:700}
.body-lg{font-size:var(--t-body-lg);color:var(--c-body);line-height:var(--lh-body)}
.body{font-size:var(--t-body);color:var(--c-body)}
.small{font-size:var(--t-small);color:var(--c-muted)}
.measure{max-width:var(--measure)}
.eyebrow{display:inline-block;font-size:var(--t-caption);font-weight:700;
  text-transform:uppercase;letter-spacing:.08em;color:var(--c-link);margin-bottom:var(--sp-2)}
.muted{color:var(--c-muted)}

/* ---------- Buttons ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-2);
  font-family:inherit;font-weight:600;font-size:var(--t-body);line-height:1;
  min-height:var(--tap-min);padding:12px 26px;border:none;border-radius:var(--r-full);
  cursor:pointer;text-decoration:none;transition:background var(--dur-2) var(--ease),transform var(--dur-1) var(--ease)}
.btn:active{transform:scale(.98)}
.btn:hover{text-decoration:none}
.btn--primary{background:var(--c-action);color:var(--c-on-dark)}
.btn--primary:hover{background:var(--c-action-hover);color:var(--c-on-dark)}
.btn--secondary{background:transparent;color:var(--c-action);border:1.5px solid var(--c-action);padding:11px 24px}
.btn--secondary:hover{background:var(--s-bluelt)}
.btn--ghost{background:transparent;color:var(--c-action);padding:12px 14px}
.btn--ghost:hover{text-decoration:underline}
.btn--dark{background:var(--c-on-dark);color:var(--brand-navy)}
.btn--dark:hover{background:var(--s-on-dark-hover);color:var(--brand-navy)}
.btn[disabled],.btn.is-disabled{opacity:.45;cursor:not-allowed;pointer-events:none}
.btn--lg{font-size:var(--t-body-lg);padding:16px 34px}
.btn--block{width:100%}

/* ---------- Forms ---------- */
.field{display:flex;flex-direction:column;gap:6px}
.label{font-size:var(--t-small);font-weight:600;color:var(--c-body)}
.input,.select,.textarea{width:100%;min-height:var(--input-h);border:1.5px solid var(--c-border-strong);
  border-radius:var(--r-md);padding:0 14px;font-family:inherit;font-size:var(--t-body);
  color:var(--c-heading);background:var(--s-page);transition:border-color var(--dur-2),box-shadow var(--dur-2)}
.textarea{min-height:120px;padding:12px 14px;resize:vertical}
.input:focus,.select:focus,.textarea:focus{outline:none;border-color:var(--c-action);box-shadow:0 0 0 3px rgba(10,110,168,.15)}
.input.is-error{border-color:var(--c-error)}
.error-text{font-size:var(--t-small);color:var(--c-error)}
.checkbox-row{display:flex;align-items:flex-start;gap:var(--sp-3);cursor:pointer;min-height:var(--tap-min)}
.checkbox{width:22px;height:22px;flex-shrink:0;border:1.5px solid var(--c-border-strong);
  border-radius:6px;accent-color:var(--c-action);cursor:pointer}

/* ---------- Cards ---------- */
.card{background:var(--s-page);border:1px solid var(--c-border);border-radius:var(--r-lg);
  padding:var(--sp-6);box-shadow:var(--sh-sm);transition:box-shadow var(--dur-2),transform var(--dur-2)}
.card:hover{box-shadow:var(--sh-md)}
.card--accent{background:var(--s-bluelt);border-color:var(--c-border-accent)}
.card--navy{background:var(--s-navy);border:none}
.card--navy h3,.card--navy h4{color:var(--c-on-dark)}
.card--navy p{color:var(--c-on-dark-muted)}

/* ---------- Pills / badges ---------- */
.pill{display:inline-flex;align-items:center;gap:6px;font-size:11px;font-weight:700;
  letter-spacing:.03em;text-transform:uppercase;padding:5px 12px;border-radius:var(--r-full)}
.pill--light{background:var(--s-bluelt);color:var(--c-link)}
.pill--dark{background:rgba(255,255,255,.14);color:var(--c-eyebrow-dark)}
.pill--success{background:var(--c-success-tint);color:var(--c-success)}

/* ---------- Header / nav ---------- */
/* backdrop-filter lives on ::before so the header is NOT a containing block for the
   position:fixed mobile nav sheet (otherwise the sheet collapses to header height). */
.site-header{position:sticky;top:0;z-index:50;background:rgba(255,255,255,.85);border-bottom:1px solid var(--c-border)}
.site-header::before{content:'';position:absolute;inset:0;z-index:-1;backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px)}
.site-header .container{display:flex;align-items:center;justify-content:space-between;min-height:64px}
.nav-links{display:flex;gap:var(--sp-6);list-style:none}
.nav-links a{font-size:var(--t-small);font-weight:500;color:var(--c-body);
  min-height:var(--tap-min);display:inline-flex;align-items:center}
.nav-links a:hover{color:var(--c-heading)}
.nav-toggle{display:none;width:var(--tap-min);height:var(--tap-min);border:none;background:none;cursor:pointer}
.header-login{white-space:nowrap}
.nav-login-item{display:none} /* desktop: the header Log In button is shown instead */
/* ⚠ DS AMENDMENT — AWAITING RATIFICATION (MIGRATION_BLUEPRINT §3.2).
   Nav breakpoint 900 → 1024. Five groups with descriptor lines do not fit a
   900px desktop bar; below 1024 the sheet is the correct affordance. This is the
   only design-system value the IA skeleton changes — the multi-level nav's own
   styles are all additive and live in ia.css. */
@media (max-width:1023px){
  .nav-links{position:fixed;inset:64px 0 0 0;flex-direction:column;gap:0;background:var(--s-page);
    padding:var(--sp-4);transform:translateX(100%);transition:transform var(--dur-3) var(--ease);
    border-top:1px solid var(--c-border);overflow-y:auto}
  .nav-links.is-open{transform:translateX(0)}
  .nav-links a{min-height:48px;font-size:var(--t-body-lg);border-bottom:1px solid var(--c-border);width:100%}
  .nav-toggle{display:inline-flex;align-items:center;justify-content:center}
  .header-login{display:none} /* moves into the nav sheet below */
  .nav-login-item{display:block;margin-top:var(--sp-4)}
  .nav-login-item a{width:100%;border-bottom:none;color:var(--c-action)} /* beats .nav-links a (same specificity, later) */
}

/* ---------- Compare table → stacks on mobile ---------- */
.compare{width:100%;border-collapse:separate;border-spacing:0;border:1px solid var(--c-border);
  border-radius:var(--r-lg);overflow:hidden}
.compare th,.compare td{padding:12px 16px;text-align:left;border-top:1px solid var(--c-border);font-size:var(--t-small)}
.compare thead th{background:var(--s-navy);color:var(--c-on-dark);font-weight:600;
  text-transform:uppercase;letter-spacing:.04em;font-size:var(--t-caption)}
.compare .col-win{background:var(--c-action)}  /* AA: white on #0A6EA8 = 4.6:1 (brand blue failed at small size) */
.compare .col-win,.compare .col-win *{color:var(--c-on-dark)}
@media (max-width:768px){
  .compare,.compare thead,.compare tbody,.compare tr,.compare th,.compare td{display:block}
  .compare thead{display:none}
  /* Rows are divided BANDS inside the table's own border, not one bordered card each.
     They used to be cards, which on an 11-row table put 11 boxes back to back — the
     over-boxing DL §8.5 exists to prevent. The table keeps its own border and radius, so
     the group still reads as ONE object. Promoted from the pricing window's .pr-compare,
     which scoped it locally and flagged that the primitive wanted the same. */
  .compare tr{border:none;border-radius:0;margin-bottom:0;overflow:visible;
    border-top:1px solid var(--c-border);padding-block:var(--sp-2)}
  .compare tbody tr:first-child{border-top:none}
  /* the row header was the first line inside its own box; now it labels the band below it */
  .compare tbody th[scope="row"]{color:var(--c-heading);font-weight:700}
  .compare td{border-top:none;display:flex;justify-content:space-between;gap:var(--sp-4)}
  .compare td::before{content:attr(data-label);font-weight:700;color:var(--c-heading)}
  .compare td.col-win::before{color:var(--c-on-dark)} /* P3d fix: ::before is not covered by .col-win * — label was navy-on-action-blue 1.9:1 */
}

/* ---------- Utilities ---------- */
.stack>*+*{margin-top:var(--sp-4)}
.stack-lg>*+*{margin-top:var(--sp-8)}
.center{text-align:center}
/* gap is --sp-6 (24px), not --sp-4 (16px): the DoD requires interactive targets to sit
   ≥24px apart, and 16px failed that everywhere a hero pairs two CTAs. Fixed here rather
   than per page — the pricing window had it scoped to .pr-hero, which left every other
   dual-CTA row on the site still at 16px. */
.cta-row{display:flex;gap:var(--sp-6);flex-wrap:wrap}
@media (max-width:480px){ .cta-row .btn{width:100%} }
.visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---------- Motion preference ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
}
.reveal{opacity:0;transform:translateY(16px)}
@media (prefers-reduced-motion:no-preference){
  .reveal{transition:opacity var(--dur-3) var(--ease),transform var(--dur-3) var(--ease)}
  .reveal.is-visible{opacity:1;transform:none}
}
@media (prefers-reduced-motion:reduce){ .reveal{opacity:1;transform:none} }
/* ⚠ DS AMENDMENT (F1, no-JS end-state — DESIGN_LANGUAGE §4). Without this, .reveal's
   opacity:0 is only ever undone by JS adding .is-visible, so with scripting off and a
   default motion preference the content never appears. .no-js is set on <html> and
   removed by an inline script in parts/header.php before first paint, so this rule
   affects ONLY readers and crawlers without JS. Last word by document order, and
   (0,2,0) beats the (0,1,0) base rule. */
.no-js .reveal{opacity:1;transform:none}

/* ---------- Composed blocks (Phase 2) — tokens only ---------- */
/* Verification lifecycle rail — shared grammar, promoted from verifier-hub.css.
   Rendered by /verifiers/, /platform/, /solutions/45v/, /solutions/epd/ and the
   front-page hub block, so it lives with the components rather than behind a
   15 KB widget stylesheet that rail-only pages had to load for three rules.
   Widget-specific .vh-panel.is-armed/.is-playing overrides remain in
   verifier-hub.css and still win: that file is enqueued after this one. */
/* 6. Lifecycle rail (footer) — LIGHT pills */
.vh-lifecycle{display:flex;align-items:center;justify-content:center;gap:var(--sp-2);flex-wrap:wrap;
  padding:var(--sp-4) var(--sp-6);border-top:1px solid var(--c-border);background:var(--s-alt)}
.vh-life{font-size:var(--t-caption);font-weight:700;letter-spacing:.02em;padding:var(--sp-2) var(--sp-3);
  border-radius:var(--r-full);border:1px solid var(--c-border);
  transition:color var(--dur-4) var(--ease),background var(--dur-4) var(--ease),border-color var(--dur-4) var(--ease)}
.vh-life.is-done{background:var(--s-sunken);color:var(--c-muted)}
/* is-current stays font-weight:800 at every phase so the wrapping row never
   reflows (zero layout shift); only colour/background/border animate. */
.vh-life.is-current{background:var(--s-bluelt);color:var(--c-link);border-color:var(--c-border-accent);font-weight:800}
.vh-life.is-upcoming{background:transparent;color:var(--c-muted)}
.vh-life-arrow{color:var(--c-muted);flex:none}
/* An arrow and the step it points INTO wrap as one unit. The rail is flex-wrap:wrap, so
   at 375-1023px a line could previously end on a dangling arrow pointing at nothing, with
   its step orphaned onto the next line. Grouping them makes that impossible at any width. */
.vh-step{display:inline-flex;align-items:center;gap:var(--sp-2);min-width:0} /* --c-border-strong was 1.41:1 on
  the rail's --s-alt band; these arrows carry the sequence, so they take a text role. */

/* Stats band */
.stat-num{font-size:var(--t-h1);font-weight:800;line-height:var(--lh-tight);
  color:var(--c-heading);letter-spacing:-.03em}
.stat-label{font-size:var(--t-small);color:var(--c-muted);margin-top:var(--sp-2)}
.on-dark .stat-num,.section--navy .stat-num,.cta-panel .stat-num,.card--navy .stat-num{color:var(--ink-strong)}
.on-dark .stat-label,.section--navy .stat-label,.cta-panel .stat-label,.card--navy .stat-label{color:var(--ink)}

/* Logo row */
.logo-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-8) var(--sp-12)}
.logo-row img{height:var(--sp-8);width:auto}
@media (max-width:480px){
  .logo-row{gap:var(--sp-6) var(--sp-8)}
  .logo-row img{height:var(--sp-6)}
}

/* Testimonial */
.testimonial{border-left:var(--sp-1) solid var(--c-action);padding-left:var(--sp-6)}
.testimonial blockquote{font-size:var(--t-h3);font-weight:500;color:var(--c-heading);
  line-height:var(--lh-heading)}
.testimonial figcaption{margin-top:var(--sp-4);font-size:var(--t-small);color:var(--c-muted)}
.on-dark .testimonial blockquote,.section--navy .testimonial blockquote{color:var(--ink-strong)}
.on-dark .testimonial figcaption,.section--navy .testimonial figcaption{color:var(--ink)}

/* ---------- Testimonial card (§8 customer stories) — balanced 2-col, no dead half ---------- */
.tc-card{display:grid;grid-template-columns:auto minmax(0,var(--measure));gap:var(--sp-8);
  align-items:center;width:fit-content;max-width:100%;margin-inline:auto;
  background:var(--s-page);border:1px solid var(--c-border);border-radius:var(--r-xl);
  box-shadow:var(--sh-md);padding:var(--sp-8)}
.tc-visual{display:flex;align-items:center;justify-content:center;
  border-inline-end:1px solid var(--c-border);padding-inline-end:var(--sp-8)}
.tc-visual img{height:var(--sp-16);width:auto}
.tc-quote{font-size:var(--t-h3);font-weight:500;color:var(--c-heading);line-height:var(--lh-heading)}
.tc-cite{margin-top:var(--sp-4);font-size:var(--t-small);color:var(--c-muted)}
.tc-cite strong{color:var(--c-heading)}
@media (max-width:768px){
  .tc-card{grid-template-columns:1fr;gap:var(--sp-6);text-align:center;justify-items:center;padding:var(--sp-6)}
  .tc-visual{border-inline-end:none;padding-inline-end:0;border-block-end:1px solid var(--c-border);padding-block-end:var(--sp-6)}
}

/* ---------- Slim section + top-hairline utilities (footnote-grade strips) ---------- */
.section--slim{padding-block:var(--sp-8)}
.section--hairline{border-top:1px solid var(--c-border)}

/* ---------- Company-credential strip (§13) — lighter than §8's card, footnote-grade ---------- */
.cred-strip{display:flex;align-items:center;justify-content:center;gap:var(--sp-4);
  max-width:var(--measure);margin-inline:auto;font-size:var(--t-small);
  line-height:var(--lh-body);color:var(--c-muted);text-align:left}
.cred-strip img{height:var(--sp-12);width:auto;flex-shrink:0}
.cred-strip strong{color:var(--c-heading)}
@media (max-width:768px){ .cred-strip{flex-direction:column;text-align:center;gap:var(--sp-3)} }

/* CTA row centered variant (cta-band) */
.cta-row--center{justify-content:center}

/* Verification marks — dark/coloured brand SVGs on a DARK surface sit on small
   white rounded chips (never recolour a brand mark). Tokens per tech-lead spec.

   The white fill is now an ON-DARK ARM rather than the component's default. It was
   the default, which meant the chip painted #FFFFFF regardless of what it sat on:
   on a light band that is a white box on near-white, which DESIGN_LANGUAGE §9 names
   ("white-boxed logos") and which at 3x zoom reads as a broken-image placeholder.
   /partners/ had already patched it page-side (partners.css .pt-marks) and
   /verifiers/ §7 still carries it on a white band, so the same defect was being
   solved once per page.

   Split so the backing follows the surface, using the same selector list as the
   surface ink roles above — one place decides what "dark" means. Verified against
   every .mark-chip on the site (10 instances: 8 on .section--navy, 2 on
   /partners/ sunken): no dark-surface chip loses its backing. */
.mark-row{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:var(--sp-4)}
.mark-chip{display:inline-flex;align-items:center;border-radius:var(--r-md);flex-shrink:0}
.on-dark .mark-chip,.section--navy .mark-chip,.cta-panel .mark-chip,.card--navy .mark-chip{
  background:var(--s-page);padding:var(--sp-2)}
/* flex-shrink:0 — as a flex item in .cred-strip / .vh-partners the chip could shrink below
   its content, and the global img{max-width:100%} then clamped the mark inside it. The mark
   silently letterboxes rather than overflowing, so it reads as "the logo is small" instead of
   as a layout bug. .cred-strip img already carried flex-shrink:0; the CHIP did not. */
.mark-chip img{height:var(--sp-8);width:auto}

/* Team (Phase 3e) — tokens only. Headshots: equal circles, B&W treatment. */
.team-card{text-align:center}
.team-photo{width:var(--sp-24);height:var(--sp-24);border-radius:var(--r-full);
  object-fit:cover;filter:grayscale(1);margin-inline:auto;border:1px solid var(--c-border)}
.team-name{font-size:var(--t-h4);font-weight:700;color:var(--c-heading)}
.team-role{font-size:var(--t-small);font-weight:600;color:var(--c-muted);
  text-transform:uppercase;letter-spacing:.05em}

/* Linked cards (Phase 3f) — a whole .card as an anchor: keep the card's own
   text colours/hover (shadow lift), suppress link underline bleeding through. */
a.card{text-decoration:none;color:inherit}
a.card:hover{text-decoration:none}

/* Certification badge chip (Phase 3-trust) — seals need more size than
   wordmark logos to stay legible; --sp-16 = 64px, tokens only. */
.mark-chip--lg img{height:var(--sp-16)}

/* Active nav item (Phase 4a) — aria-current is the styling hook. */
.nav-links a[aria-current="page"]{color:var(--c-heading);font-weight:700}

/* ═══════════════════════════════════════════════════════════════════
   TIER 0 — STRUCTURAL RICHNESS (Phase C item 1). Tokens only.
═══════════════════════════════════════════════════════════════════ */

/* Wide container for heroes / marquee / stats — full on large screens */
.container--wide{max-width:var(--container-wide);margin-inline:auto;padding-inline:var(--gutter)}

/* ---- Split hero: text + product-preview card ---- */
.hero-grid{display:grid;grid-template-columns:1.05fr .95fr;gap:var(--sp-16);align-items:center}
@media (max-width:900px){ .hero-grid{grid-template-columns:1fr;gap:var(--sp-12)} }

/* ---- Product-preview card (idealized Builder mini-canvas, static;
   upgradeable to the W1 animation via .is-* state classes) ---- */
.product-preview{background:var(--s-page);border:1px solid var(--c-border);border-radius:var(--r-lg);
  box-shadow:var(--sh-lg);padding:var(--sp-6);max-width:520px;margin-inline:auto;
  width:100%;container-type:inline-size}
/* width:100% is REQUIRED alongside container-type:inline-size, not decorative. Inline-size
   containment makes the box's inline size independent of its contents, so a shrink-to-fit
   panel collapses to its padding (measured: 48px at every viewport). Filling the parent
   gives the container a width to be queried against. */
.pv-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);
  padding-bottom:var(--sp-4);border-bottom:1px solid var(--c-border);margin-bottom:var(--sp-6)}
.pv-tab{font-size:var(--t-small);font-weight:700;color:var(--c-heading)}
.pv-status{display:inline-flex;align-items:center;gap:6px;font-size:var(--t-caption);font-weight:700;
  text-transform:uppercase;letter-spacing:.04em;padding:4px 10px;border-radius:var(--r-full);
  background:var(--c-success-tint);color:var(--c-success)}
.pv-status::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--c-success)}
/* node canvas: process row + a direct-emission node hanging below */
.pv-canvas{display:grid;grid-template-columns:1fr auto 1fr auto 1fr;align-items:center;gap:var(--sp-2)}
.pv-node{border:1px solid var(--c-border);border-left:4px solid var(--node-reviewed);
  border-radius:var(--r-sm);padding:var(--sp-3);background:var(--s-page);min-width:0}
.pv-node.is-incomplete{border-left-color:var(--node-incomplete)}
.pv-node.is-draft{border-left-color:var(--node-draft)}
.pv-node.is-reviewed{border-left-color:var(--node-reviewed)}
.pv-scope{display:inline-block;font-size:var(--t-caption);font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  color:var(--c-muted);background:var(--s-sunken);border-radius:var(--r-full);padding:2px 8px;margin-bottom:6px}
.pv-name{font-size:var(--t-small);font-weight:600;color:var(--c-heading);line-height:1.2;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pv-val{font-size:var(--t-caption);color:var(--c-muted);margin-top:2px}
.pv-node--out .pv-val{color:var(--c-heading);font-weight:700}
.pv-link{height:2px;background:var(--c-border-strong);width:100%;min-width:16px;align-self:center}
.pv-emit{margin-top:var(--sp-3);display:flex;justify-content:center}
.pv-emit .pv-node{max-width:230px}
.pv-legend{display:flex;flex-wrap:wrap;gap:var(--sp-3) var(--sp-4);margin-top:var(--sp-6);
  padding-top:var(--sp-4);border-top:1px solid var(--c-border)}
.pv-key{display:inline-flex;align-items:center;gap:6px;font-size:var(--t-caption);color:var(--c-muted)}
.pv-key::before{content:"";width:10px;height:10px;border-radius:3px}
.pv-key--incomplete::before{background:var(--node-incomplete)}
.pv-key--draft::before{background:var(--node-draft)}
.pv-key--reviewed::before{background:var(--node-reviewed)}
/* Canvas collapse is CONTAINER-based, matching .jn-canvas. It was a viewport media query,
   which is the wrong axis: between roughly 880 and 990px the hero is still two columns, so
   the panel is squeezed to ~408-439px while the viewport is wide — the query never fired and
   .pv-name (nowrap + ellipsis) clipped "Steelmaking". Measured, not guessed.
   min-width:0 is load-bearing: the base .pv-link carries min-width:16px, which fought
   width:2px and painted a 16x16 grey square instead of a 2px connector at phone widths. */
@container (max-width:400px){
  .pv-canvas{grid-template-columns:1fr;gap:var(--sp-2)}
  .pv-link{width:2px;height:16px;min-width:0;margin-inline:auto}
}
@supports not (container-type:inline-size){
  @media (max-width:520px){
    .pv-canvas{grid-template-columns:1fr;gap:var(--sp-2)}
    .pv-link{width:2px;height:16px;min-width:0;margin-inline:auto}
  }
}

/* ---- Logo strip: labelled band, larger de-emphasised-but-legible marks ---- */
.logo-strip{border-top:1px solid var(--c-border);border-bottom:1px solid var(--c-border);
  padding-block:var(--sp-8)}
.logo-strip .logo-strip-label{display:block;text-align:center;font-size:var(--t-small);
  color:var(--c-muted);margin-bottom:var(--sp-6)}
.logo-strip .logo-row{justify-content:center;gap:var(--sp-12) var(--sp-16)}
/* Mark HEIGHT is owned by the lockup section further down, which keys it to --logo-h /
   --logo-h-sm. This block used to declare it too, via --sp-12/--sp-8 — the same computed
   values, so nothing looked wrong, but there were two definitions of one thing in two token
   vocabularies and only the later one won. Editing --logo-h here would have appeared to do
   nothing. Found by qa/tools/css-lint.py. */
@media (max-width:640px){ .logo-strip .logo-row{gap:var(--sp-6) var(--sp-8)} }

/* ---- Case-study marquee moment ---- */
.marquee{display:grid;grid-template-columns:auto 1fr;gap:var(--sp-16);align-items:center}
.marquee-visual{display:flex;align-items:center;justify-content:center;background:var(--s-page);
  border-radius:var(--r-lg);padding:var(--sp-12) var(--sp-16);box-shadow:var(--sh-md);min-width:0}
.marquee-visual img{width:100%;max-width:320px;height:auto}
@media (max-width:768px){ .marquee{grid-template-columns:1fr;gap:var(--sp-8)} .marquee-visual{padding:var(--sp-8)} }

/* ---- Even card grid (kills the orphan "hole" for 5-up on 3-col) ---- */
.card-fill{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--sp-6)}
.card-fill>*{flex:1 1 300px;max-width:380px}
@media (max-width:680px){ .card-fill>*{flex-basis:100%;max-width:none} }

/* ---- Count-up numerals: reduced-motion shows the final value as-authored ---- */
@media (prefers-reduced-motion:reduce){ .stat-num[data-count]{visibility:visible} }

/* Accent surface (light-blue emphasis) — for band rhythm without going navy */
.section--accent{background:var(--s-bluelt)}
.section--accent .eyebrow{color:var(--c-link)}


/* ============================================================
   TIER 1 — DEPTH PRIMITIVES  (icons · data-meaning colour · depth · comparison)
   ============================================================ */

/* ---- Feature-card icons: one hand-drawn 24-grid stroke family in a tinted,
   softly-raised chip. Icons use stroke:currentColor and inherit the chip colour,
   so they re-tint on any surface. Decorative (aria-hidden). ---- */
.icon-chip{display:inline-flex;align-items:center;justify-content:center;
  width:var(--sp-12);height:var(--sp-12);border-radius:var(--r-md);flex:none;
  background:var(--s-bluelt);color:var(--c-link);box-shadow:var(--sh-sm)}
.cs-icon{width:24px;height:24px;display:block}
.cs-icon-accent{fill:currentColor;stroke:none}          /* solid emphasis element inside an icon */
.on-dark .icon-chip,.section--navy .icon-chip{background:var(--c-overlay-light);color:var(--ink-link);box-shadow:none}
.card--accent .icon-chip{background:var(--s-page)}

/* subtle depth: lift the card on hover (motion-safe) so the grid isn't flat */
.card{transition:box-shadow var(--dur-2) var(--ease),transform var(--dur-2) var(--ease)}
.card:hover{transform:translateY(-2px)}
a.card:focus-visible{transform:translateY(-2px)}
@media (prefers-reduced-motion:reduce){ .card:hover,a.card:focus-visible{transform:none} }

/* ---- Data-meaning status (green=reviewed/good · amber=draft/caution ·
   red=incomplete/risk). SEMANTIC use only; reuses the node-state aliases. ---- */
.status{display:inline-flex;align-items:center;gap:var(--sp-2);font-size:var(--t-small);
  font-weight:600;line-height:1.2}
.status::before{content:"";width:10px;height:10px;border-radius:50%;background:currentColor;flex:none}
.status--reviewed{color:var(--node-reviewed)}
.status--draft{color:var(--node-draft)}
.status--incomplete{color:var(--node-incomplete)}
.status-pill{display:inline-flex;align-items:center;gap:6px;font-size:var(--t-caption);
  font-weight:700;letter-spacing:.02em;padding:4px 10px;border-radius:var(--r-full)}
.status-pill--reviewed{background:var(--c-success-tint);color:var(--c-success)}
.status-pill--draft{background:var(--c-warning-tint);color:var(--c-warning)}
.status-pill--incomplete{background:var(--c-error-tint);color:var(--c-error)}

/* ---- Closing-CTA panel: a contained navy card on a light band, so the final
   CTA reads as its own object and never merges into the navy footer. ---- */
.cta-band--panel{background:var(--s-alt)}
.cta-panel{background:var(--s-navy);border-radius:var(--r-xl);box-shadow:var(--sh-lg);
  padding:var(--sp-16) var(--sp-8)}
.cta-panel .eyebrow{color:var(--c-eyebrow-dark)}
.cta-panel h2{color:var(--c-on-dark)}
.cta-panel .body-lg,.cta-panel p{color:var(--c-on-dark-muted)}
@media (max-width:768px){ .cta-panel{padding:var(--sp-12) var(--sp-6)} }

/* ---- "Old way vs CarbonSig" comparison visual (pure CSS, qualitative) ---- */
.vs{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-6);align-items:stretch}
@media (max-width:768px){ .vs{grid-template-columns:1fr} }
.vs-col{border:1px solid var(--c-border);border-radius:var(--r-lg);
  padding:var(--sp-8);background:var(--s-page);box-shadow:var(--sh-sm)}
.vs-col--new{background:var(--s-bluelt);border-color:var(--c-border-accent)}
.vs-head{margin-bottom:var(--sp-4)}
.vs-head .h4{margin:0}
.vs-list{list-style:none;margin:0;padding:0;display:grid;gap:var(--sp-4)}
.vs-item{display:grid;grid-template-columns:auto 1fr;gap:var(--sp-3);align-items:start}
.vs-mark{width:var(--sp-6);height:var(--sp-6);flex:none;border-radius:var(--r-full);
  display:inline-flex;align-items:center;justify-content:center}
.vs-mark .cs-icon{width:16px;height:16px;stroke-width:2.25}
.vs-item--bad .vs-mark{background:var(--c-error-tint);color:var(--c-error)}
.vs-item--good .vs-mark{background:var(--c-success-tint);color:var(--c-success)}
.vs-item p{margin:0}


/* ============================================================
   PHASE 1 — W1 HERO JOURNEY + IMPRESSION LAYER (tokens only)
   ============================================================ */

/* ---- Two-tone headline: ONE payoff phrase per headline, solid accent
   (--c-link: 5.51:1 on white, 4.93:1 on --s-bluelt — AA large). ---- */
.hl{color:var(--c-link)}

/* ---- cs-flow: connector marching-ants (RATIFIED). The one ambient-motion
   exception, used only on live connectors inside an active narrative beat. ---- */
@keyframes cs-flow{to{stroke-dashoffset:-26}}

/* ---- Product panel shell (promoted from verifier-hub.css) --------------
   The LIGHT app-faithful browser panel, shared by the front page, /verifiers/,
   /platform/ and /ai/. DL §1: the marketing panel stays light even on a navy band —
   which is why .vh-panel is NOT in the dark-surface focus rule at the top of this file.
   .vh-panel carries container-type:inline-size, and its width:100% is load-bearing for
   that: inline-size containment makes the box's width independent of its contents, so
   without it the panel would collapse to its padding. */
/* ---- Light browser panel ---- */
.vh-panel{width:100%;background:var(--s-page);border:1px solid var(--c-border);
  border-radius:var(--r-xl);box-shadow:var(--sh-xl);overflow:hidden;container-type:inline-size}

/* 1. Browser frame — real URL, neutral monochrome window dots */
.vh-browser{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);
  background:var(--s-sunken);border-bottom:1px solid var(--c-border)}
.vh-dots{display:inline-flex;gap:var(--sp-2);flex:none}
.vh-dot{width:var(--sp-2);height:var(--sp-2);border-radius:var(--r-full);background:var(--c-border-strong)}
.vh-url{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:var(--t-caption);
  color:var(--c-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.vh-url b{color:var(--c-heading);font-weight:700}

/* 2. App bar — engagement label · System/Product selectors · view tabs · chips */
.vh-appbar{display:flex;align-items:center;gap:var(--sp-3) var(--sp-4);flex-wrap:wrap;
  padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--c-border)}
.vh-sys{font-size:var(--t-small);font-weight:700;color:var(--c-heading);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* ---- W1 journey panel ------------------------------------------------ */
.journey{max-width:640px;margin-inline:auto;width:100%}
.jn-panel{background:var(--s-panel);border:1px solid var(--c-border-panel);
  border-radius:var(--r-xl);box-shadow:var(--sh-xl);overflow:hidden;container-type:inline-size}
/* browser frame — truthful: real URL, neutral mono dots (never macOS R/A/G) */
.jn-browser{display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-3) var(--sp-4);
  background:var(--s-panel-deep);border-bottom:1px solid var(--c-border-panel)}
.jn-dot{width:10px;height:10px;border-radius:50%;background:var(--c-border-on-dark);flex:none}
.jn-url{margin-left:var(--sp-2);font-size:var(--t-caption);color:var(--c-on-dark-muted);
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.jn-url b{color:var(--c-on-dark);font-weight:600}
/* app bar — real product grammar: model name · real tab row · status pill */
.jn-appbar{display:flex;align-items:center;gap:var(--sp-4);padding:var(--sp-3) var(--sp-4);
  border-bottom:1px solid var(--c-border-panel);flex-wrap:wrap}
.jn-model{font-size:var(--t-small);font-weight:600;color:var(--c-on-dark);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.jn-tabs{display:flex;gap:var(--sp-4);margin-left:auto}
.jn-tabs span{font-size:var(--t-caption);font-weight:600;color:var(--c-on-dark-muted);
  padding-bottom:2px;border-bottom:2px solid transparent}
.jn-tabs .is-active{color:var(--c-on-dark);border-bottom-color:var(--brand-blue)}
/* outlined status pill (the app's chip style — tinted text, never solid) */
.jn-pill{display:inline-flex;align-items:center;gap:6px;font-size:var(--t-caption);font-weight:700;
  letter-spacing:.02em;padding:3px 10px;border-radius:var(--r-full);border:1.5px solid;flex:none;
  transition:color var(--dur-4) var(--ease),border-color var(--dur-4) var(--ease)}
.jn-pill--progress{color:var(--node-draft-ondark);border-color:var(--node-draft-ondark)}
.jn-pill--ready,.jn-pill--verified{color:var(--node-reviewed-ondark);border-color:var(--node-reviewed-ondark)}
/* stage */
.jn-stage{position:relative;padding:var(--sp-4) var(--sp-4) var(--sp-3)}
.jn-cap{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-3);
  margin-bottom:var(--sp-4);flex-wrap:wrap;min-height:44px}
.jn-cap b{color:var(--c-on-dark);font-size:var(--t-body);font-weight:700}
.jn-cap span{color:var(--c-on-dark-muted);font-size:var(--t-small)}
/* canvas: process row + hanging direct-emission node (real Builder shape) */
.jn-canvas{position:relative;display:grid;grid-template-columns:1fr auto 1fr auto 1fr;
  align-items:center;gap:var(--sp-2);min-height:220px;align-content:center;
  padding-bottom:var(--sp-16)} /* reserved overlay row: AI chip + metric never collide with nodes */
.jn-emit{grid-column:1 / -1;display:flex;justify-content:center;margin-top:var(--sp-2)}
.jn-emit .jn-node{max-width:230px}
/* node card — the app's grammar: raised card, state-coloured LEFT EDGE */
.jn-node{background:var(--s-panel-raised);border:1px solid var(--c-border-on-dark);
  border-left:4px solid var(--c-border-on-dark);border-radius:var(--r-sm);padding:var(--sp-3);
  min-width:0;opacity:0;transform:translateY(8px);
  transition:opacity var(--dur-4) var(--ease),transform var(--dur-4) var(--ease),
    border-color var(--dur-4) var(--ease),background var(--dur-4) var(--ease),box-shadow var(--dur-4) var(--ease)}
.jn-node.is-on{opacity:1;transform:none}
.jn-node.is-incomplete{border-left-color:var(--node-incomplete-ondark);box-shadow:var(--glow-incomplete)}
.jn-node.is-draft{border-left-color:var(--node-draft-ondark);background:var(--node-draft-fill-ondark);box-shadow:var(--glow-draft)}
.jn-node.is-reviewed{border-left-color:var(--node-reviewed-ondark);background:var(--node-reviewed-fill-ondark);box-shadow:var(--glow-reviewed)}
.jn-scope{display:inline-block;font-size:var(--t-caption);font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;color:var(--c-on-dark-muted);margin-bottom:4px}
.jn-node.is-incomplete .jn-scope{color:var(--node-incomplete-ondark)}
.jn-node.is-draft .jn-scope{color:var(--node-draft-ondark)}
.jn-node.is-reviewed .jn-scope{color:var(--node-reviewed-ondark)}
.jn-name{font-size:var(--t-small);font-weight:600;color:var(--c-on-dark);line-height:1.25}
.jn-val{font-size:var(--t-caption);color:var(--c-on-dark-muted);margin-top:2px}
/* wires: inline SVG lines; dashed = missing data; .is-live = flowing */
.jn-wire{width:100%;min-width:16px;height:12px;align-self:center}
.jn-wire line{stroke:var(--c-border-on-dark);stroke-width:2.5;stroke-dasharray:var(--wire-dash)}
.jn-wire.is-live line{stroke:var(--brand-blue);animation:cs-flow var(--dur-flow) linear infinite}
.jn-wire.is-solid line{stroke-dasharray:none}
/* AI EF chip — sparkle marks AI (purple token pending; sparkle carries it) */
.jn-ai{position:absolute;left:0;bottom:0;max-width:60%;display:inline-flex;align-items:center;gap:6px;
  background:var(--c-overlay-light);border:1px solid var(--c-border-on-dark);border-radius:var(--r-full);
  padding:6px 12px;font-size:var(--t-caption);font-weight:600;color:var(--c-on-dark);
  opacity:0;transform:translateY(8px);transition:opacity var(--dur-4) var(--ease),transform var(--dur-4) var(--ease)}
.jn-ai.is-on{opacity:1;transform:none}
.jn-ai b{color:var(--c-eyebrow-dark);font-weight:700}
/* metric chip */
.jn-metric{position:absolute;right:0;bottom:0;background:var(--c-overlay-light);
  border:1px solid var(--c-border-on-dark);border-radius:var(--r-md);padding:var(--sp-2) var(--sp-3);
  text-align:right;opacity:0;transform:translateY(8px);
  transition:opacity var(--dur-4) var(--ease),transform var(--dur-4) var(--ease)}
.jn-metric.is-on{opacity:1;transform:none}
.jn-metric .jn-mv{color:var(--c-on-dark);font-size:var(--t-h4);font-weight:800;letter-spacing:-.02em}
.jn-metric .jn-mv b{color:var(--node-reviewed-ondark)}
.jn-metric .jn-ml{color:var(--c-on-dark-muted);font-size:var(--t-caption);font-weight:600}
/* verify stamp — role label only, never a named firm on demo data */
.jn-stamp{position:absolute;left:50%;top:44%;transform:translate(-50%,-50%) rotate(-8deg) scale(.6);
  border:2.5px solid var(--node-reviewed-ondark);color:var(--node-reviewed-ondark);border-radius:var(--r-md);
  padding:var(--sp-3) var(--sp-4);text-align:center;background:var(--node-reviewed-fill-ondark);
  opacity:0;transition:opacity var(--dur-5) var(--ease),transform var(--dur-5) var(--ease);pointer-events:none}
.jn-stamp.is-on{opacity:1;transform:translate(-50%,-50%) rotate(-8deg) scale(1)}
.jn-stamp .jn-sb{font-size:var(--t-small);font-weight:800;letter-spacing:.02em;text-transform:uppercase}
.jn-stamp .jn-ss{font-size:var(--t-caption);color:var(--c-on-dark-muted);margin-top:2px}
/* receipt (Carbon Receipt) */
.jn-receipt{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) translateY(10px);
  width:min(300px,86%);background:var(--s-page);border-radius:var(--r-md);box-shadow:var(--sh-lg);
  padding:var(--sp-4);opacity:0;transition:opacity var(--dur-5) var(--ease),transform var(--dur-5) var(--ease);pointer-events:none}
.jn-receipt.is-on{opacity:1;transform:translate(-50%,-50%)}
.jn-receipt .jn-rh{display:flex;align-items:center;justify-content:space-between;
  border-bottom:1px dashed var(--c-border-strong);padding-bottom:var(--sp-2);margin-bottom:var(--sp-2)}
.jn-receipt .jn-rh b{color:var(--c-heading);font-size:var(--t-small)}
.jn-receipt .jn-row{display:flex;justify-content:space-between;font-size:var(--t-caption);
  color:var(--c-body);margin:4px 0}
.jn-receipt .jn-row span:last-child{font-weight:700;color:var(--c-heading)}
.jn-receipt .jn-tot{display:flex;justify-content:space-between;border-top:1px solid var(--c-border);
  margin-top:var(--sp-2);padding-top:var(--sp-2)}
.jn-receipt .jn-tot b{color:var(--c-heading);font-size:var(--t-small)}
.jn-receipt .jn-tot .jn-n{color:var(--c-success)}
/* outcomes overlay — framed as what the verified number UNLOCKS */
.jn-wins{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;
  gap:var(--sp-3);opacity:0;transition:opacity var(--dur-4) var(--ease);pointer-events:none}
.jn-wins.is-on{opacity:1}
.jn-wins .jn-wt{color:var(--c-on-dark);font-size:var(--t-body);font-weight:700;text-align:center}
.jn-wins .jn-ws{color:var(--c-on-dark-muted);font-size:var(--t-caption);text-align:center;margin-top:-6px}
.jn-wingrid{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-3)}
.jn-win{display:flex;align-items:center;gap:var(--sp-3);background:var(--c-overlay-light);
  border:1px solid var(--c-border-on-dark);border-radius:var(--r-md);padding:var(--sp-3);
  color:var(--c-on-dark);font-size:var(--t-small);font-weight:600;
  opacity:0;transform:translateY(8px);transition:opacity var(--dur-4) var(--ease),transform var(--dur-4) var(--ease)}
.jn-wins.is-on .jn-win{opacity:1;transform:none}
.jn-wins.is-on .jn-win:nth-child(2){transition-delay:var(--stagger)}
.jn-wins.is-on .jn-win:nth-child(3){transition-delay:calc(var(--stagger)*2)}
.jn-wins.is-on .jn-win:nth-child(4){transition-delay:calc(var(--stagger)*3)}
.jn-win .icon-chip{width:var(--sp-8);height:var(--sp-8);background:var(--c-overlay-light);
  color:var(--c-eyebrow-dark);box-shadow:none}
/* legend (real Builder legend vocabulary) */
.jn-legend{display:flex;flex-wrap:wrap;gap:var(--sp-3) var(--sp-4);margin-top:var(--sp-4);
  padding-top:var(--sp-3);border-top:1px solid var(--c-border-panel)}
.jn-key{display:inline-flex;align-items:center;gap:6px;font-size:var(--t-caption);color:var(--c-on-dark-muted)}
.jn-key::before{content:"";width:10px;height:10px;border-radius:3px}
.jn-key--incomplete::before{background:var(--node-incomplete-ondark)}
.jn-key--draft::before{background:var(--node-draft-ondark)}
.jn-key--reviewed::before{background:var(--node-reviewed-ondark)}
/* step tabs (labeled progress — click to jump; fill = time in step) */
.jn-steps{display:flex;gap:var(--sp-2);margin-top:var(--sp-4)}
.jn-step{position:relative;flex:1;min-height:var(--tap-min);border:1px solid var(--c-border-strong);
  background:var(--s-page);border-radius:var(--r-sm);cursor:pointer;font-family:inherit;
  font-size:var(--t-caption);font-weight:700;color:var(--c-muted);padding:var(--sp-2) var(--sp-1) var(--sp-3);
  overflow:hidden;transition:color var(--dur-2) var(--ease),border-color var(--dur-2) var(--ease)}
.jn-step .jn-num{display:block;font-weight:800;color:var(--c-border-strong);font-size:var(--t-caption)}
.jn-step[aria-selected="true"]{color:var(--c-heading);border-color:var(--c-action)}
.jn-step[aria-selected="true"] .jn-num{color:var(--c-action)}
.jn-step.is-done{color:var(--c-body)}
.jn-step.is-done .jn-num{color:var(--c-success)}
.jn-fill{position:absolute;left:0;right:0;bottom:0;height:4px;background:var(--s-sunken)}
.jn-fill i{position:absolute;inset:0;background:var(--c-action);transform:scaleX(0);transform-origin:left}
.jn-step.is-done .jn-fill i{transform:scaleX(1);background:var(--c-success)}
.jn-step[aria-selected="true"] .jn-fill i.is-running{transform:scaleX(1);
  transition:transform var(--dur-step) linear}
/* controls (WCAG 2.2.2: visible pause; hidden until JS boots) */
.jn-controls{display:flex;align-items:center;gap:var(--sp-3);margin-top:var(--sp-3);
  font-size:var(--t-small);color:var(--c-muted);flex-wrap:wrap}
.jn-controls .jn-note{font-size:var(--t-caption)}
.btn--chip{min-height:var(--tap-min);padding:8px 16px;font-size:var(--t-small);
  background:var(--s-page);color:var(--c-action);border:1px solid var(--c-border-strong);border-radius:var(--r-full)}
.btn--chip:hover{border-color:var(--c-action)}
/* stacked canvas at narrow container widths (matches .pv-canvas behaviour) */
.jn-step{min-width:0} /* flex items must be allowed to shrink (375px overflow fix) */
@container (max-width:520px){
  .jn-canvas{grid-template-columns:1fr;min-height:0}
  .jn-wire{width:12px;height:16px;margin-inline:auto}
  .jn-tabs{display:none}
}
@supports not (container-type:inline-size){
  @media (max-width:560px){
    .jn-canvas{grid-template-columns:1fr;min-height:0}
    .jn-wire{width:12px;height:16px;margin-inline:auto}
    .jn-tabs{display:none}
  }
}
/* step tabs wrap into two rows on narrow viewports instead of overflowing */
@media (max-width:560px){
  .jn-steps{flex-wrap:wrap}
  .jn-step{flex:1 1 30%}
}
/* reduced motion: end-state, no auto-play, tabs still jump between states */
@media (prefers-reduced-motion:reduce){
  .jn-node,.jn-ai,.jn-metric,.jn-stamp,.jn-receipt,.jn-wins,.jn-win{transition:none}
  .jn-wire.is-live line{animation:none;stroke-dasharray:none}
  .jn-step[aria-selected="true"] .jn-fill i.is-running{transition:none;transform:scaleX(1)}
}

/* ---- Race comparison (the old site's best idiom, on-token) ---- */
.race{display:grid;gap:var(--sp-6)}
.race-row{display:grid;gap:var(--sp-2)}
.race-head{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-4);flex-wrap:wrap}
.race-head .h4{margin:0}
.race-meta{display:flex;gap:var(--sp-2) var(--sp-4);flex-wrap:wrap;font-size:var(--t-small);color:var(--c-muted)}
.race-track{height:var(--sp-4);border-radius:var(--r-full);background:var(--s-sunken);
  border:1px solid var(--c-border);overflow:hidden;position:relative}
.race-bar{position:absolute;inset:0;border-radius:var(--r-full);transform:scaleX(0);transform-origin:left}
.race--run .race-bar{transition:transform var(--dur-count) var(--ease)}
.race-bar--old{background:var(--c-error)}
.race-bar--new{background:var(--c-success)}
.race--run .race-bar--old{transform:scaleX(1);transition-delay:var(--dur-1)}
.race--run .race-bar--new{transform:scaleX(.4);transition-delay:calc(var(--dur-1)*3)}
@media (prefers-reduced-motion:reduce){
  .race-bar--old{transform:scaleX(1)}
  .race-bar--new{transform:scaleX(.4)}
  .race--run .race-bar{transition:none}
}

/* ---- Logo strip: lockup heights + mono-at-rest treatment ---- */
.logo-strip .logo-row img{height:var(--logo-h);width:auto;opacity:.9;
  filter:grayscale(1);transition:filter var(--dur-2) var(--ease),opacity var(--dur-2) var(--ease)}
.logo-strip .logo-row a:hover img,.logo-strip .logo-row a:focus-visible img,
.logo-strip .logo-row img:hover{filter:none;opacity:1}
@media (max-width:640px){ .logo-strip .logo-row img{height:var(--logo-h-sm)} }
@media (prefers-reduced-motion:reduce){ .logo-strip .logo-row img{transition:none} }

/* Animated client logo marquee — reproduces the old site's carousel, improved.
   Seamless infinite loop: the track holds TWO identical logo groups and scrolls
   -50% (exactly one group). Grayscale→colour on hover; edge fade; pauses on hover
   and keyboard focus; prefers-reduced-motion = static, centred, no scroll. */
.logo-marquee-label{display:block;text-align:center;text-transform:uppercase;letter-spacing:.08em;
  font-size:var(--t-small);font-weight:700;color:var(--c-muted);margin-bottom:var(--sp-8)}
.logo-marquee{position:relative;overflow:hidden;  /* full-bleed: sits outside .container */
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%)}
.logo-track{display:flex;align-items:center;width:max-content;gap:var(--sp-16);
  animation:cs-logo-scroll 42s linear infinite;will-change:transform}
.logo-marquee:hover .logo-track,.logo-marquee:focus-within .logo-track,
.logo-marquee.is-paused .logo-track{animation-play-state:paused}
/* The visible pause toggle. Sits inside the full-bleed marquee, aligned to the container
   edge so it never floats over a mark. Hidden with no JS (it could not work) and under
   reduced motion (there is no animation left to pause). */
.lr-pause{position:absolute;right:var(--gutter);top:50%;transform:translateY(-50%);z-index:1}
.no-js .lr-pause{display:none}
@media (prefers-reduced-motion:reduce){ .lr-pause{display:none} }
@media (max-width:640px){ .lr-pause{position:static;transform:none;display:block;margin:var(--sp-4) auto 0} }
.logo-track img{height:var(--logo-h);width:auto;opacity:.72;filter:grayscale(1);
  transition:opacity var(--dur-2) var(--ease),filter var(--dur-2) var(--ease)}
.logo-track img:hover{opacity:1;filter:none}
@keyframes cs-logo-scroll{from{transform:translateX(0)}to{transform:translateX(-50%)}}
@media (max-width:640px){ .logo-track{gap:var(--sp-8)} .logo-track img{height:var(--logo-h-sm)} }
@media (prefers-reduced-motion:reduce){
  .logo-marquee{-webkit-mask-image:none;mask-image:none}
  .logo-track{animation:none;flex-wrap:wrap;justify-content:center;width:auto;gap:var(--sp-8) var(--sp-12)}
  .logo-track img[aria-hidden="true"]{display:none}
}

/* ---- Status-lifecycle strip (real Registered-flow vocabulary, on navy) ---- */
.lifecycle{display:flex;align-items:center;gap:var(--sp-2);flex-wrap:wrap}
.lifecycle .jn-pill{cursor:default}
.lifecycle-arrow{color:var(--c-on-dark-muted);flex:none}
.lifecycle .jn-pill--pending{color:var(--c-on-dark-muted);border-color:var(--c-border-on-dark)}

/* ---- Quote pair ---- */
.quote-pair{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-8)}
@media (max-width:768px){ .quote-pair{grid-template-columns:1fr} }

/* ---- Standalone credential trust row (two-stories: company credential only) ---- */
.credential-row{display:flex;align-items:center;justify-content:center;gap:var(--sp-6);
  flex-wrap:wrap;text-align:left}
.credential-row img{height:var(--sp-16);width:auto}
.credential-row p{max-width:44ch;margin:0}

/* ---- Hero ambient background + trust ticks ---- */
.hero--ambient{background:var(--bg-ambient)}
.hero-ticks{list-style:none;display:flex;gap:var(--sp-3) var(--sp-6);flex-wrap:wrap;margin:0;padding:0}
.hero-ticks li{display:inline-flex;align-items:center;gap:var(--sp-2);
  font-size:var(--t-small);font-weight:500;color:var(--c-muted)}
.hero-ticks .cs-icon{width:16px;height:16px;color:var(--c-success);flex:none}

/* ---- Centering utilities (no inline styles, ever) ---- */
.mx-auto{margin-inline:auto}
.lifecycle--center{justify-content:center}

/* ---- AA fix: ghost button inside the navy cta-panel (the .section--navy
   override doesn't reach it — --c-action on navy was ~2.3:1). ---- */
.cta-panel .btn--ghost{color:var(--c-eyebrow-dark)}

/* ---- Credential seal legibility on light bands: white chip + border,
   seal at --sp-24 (thin engraving strokes need the size). ---- */
.credential-row .credential-badge{display:inline-flex;align-items:center;justify-content:center;
  background:var(--s-page);border:1px solid var(--c-border);border-radius:var(--r-lg);
  padding:var(--sp-4);box-shadow:var(--sh-sm);flex:none}
.credential-row .credential-badge img{height:var(--sp-24);width:auto}
