/* ============================================================================
   VALIDTHRU — MARKETING SITE STYLESHEET
   site/assets/site.css · v2.0.0 · A4 editorial system

   Loaded by every marketing page. Archivo is self-hosted below — there are NO
   external requests from this stylesheet. Page-specific layout goes in a
   small <style> block on the page, referencing tokens only.

   Layer 1 — TOKENS: from Design kit.html, verbatim. Light is Signal,
             Signal light is the site's only palette; the Blueprint dark
             palette lives in the portal and the console.
   Layer 2 — KIT COMPONENTS: vt-body, vt-btn, vt-pill, vt-ring, vt-card,
             vt-item, vt-field/vt-input — from Design kit.html.
   Layer 3 — EDITORIAL: display type, kickers, folios, desk card stack,
             ledger strip, stat numerals, pull quotes, steps, mono
             captions, prose — from design-explorations/a4-editorial.html.
   Layer 4 — SHELL: header, footer, theme toggle, skip link, base + a11y.
   ========================================================================== */

/* Archivo — self-hosted variable font (wght 100-900), latin + latin-ext subsets.
   Downloaded from Google Fonts v25 on 1 September 2026; SIL-adjacent OFL license.
   No third-party font hosts — font-src stays 'self'. */
@font-face{
  font-family:'Archivo'; font-style:normal; font-weight:100 900; font-display:swap;
  src:url('fonts/archivo-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Archivo'; font-style:normal; font-weight:100 900; font-display:swap;
  src:url('fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1EFF,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* ============================================================
   ValidThru — design tokens + components
   The marketing site is Signal light and nothing else. The Blueprint
   dark palette lives in the client portal (an owner sets it for every
   customer at once) and in the admin console (an operator sets their own).
   ============================================================ */

:root{
  --vt-font:'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --vt-mono:ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  /* type scale */
  --vt-t-xs:12.5px; --vt-t-s:13.5px; --vt-t-base:15px; --vt-t-md:17px;
  --vt-t-lg:21px; --vt-t-xl:26px; --vt-t-2xl:33px; --vt-t-3xl:41px;
  --vt-lh:1.55;

  /* spacing, 4px base */
  --vt-s1:4px; --vt-s2:8px; --vt-s3:12px; --vt-s4:16px;
  --vt-s5:24px; --vt-s6:32px; --vt-s7:48px; --vt-s8:64px;

  /* radii */
  --vt-r-s:8px; --vt-r-m:11px; --vt-r-l:14px;

  /* ---- light · Signal ---- */
  color-scheme: light;
  --vt-bg:#F5F6F8; --vt-surface:#FFFFFF; --vt-ink:#232A33; --vt-soft:#646D78; --vt-line:#E2E5E9;
  --vt-primary:#232A33; --vt-on-primary:#FFFFFF; --vt-primary-hover:#39424E;
  --vt-valid:#0FA46F; --vt-valid-text:#09724D;
  --vt-soon:#E3A424; --vt-soon-text:#7D5A0C;
  --vt-expired:#C64438; --vt-expired-text:#A93A2B;
  --vt-pill-mix:22%; --vt-pill-mix-soon:32%;

  /* ---- brand · Iris ----
     One accent across the marketing site, the client portal and the admin
     console. Verified: white on --vt-brand is 6.10:1, and
     --vt-brand-subtle-text on --vt-brand-subtle is 9.32:1 — both clear AA at
     every size, which is why the accent is this violet and not the lighter
     one it is drawn from. Status colours (valid, soon, expired) are NOT brand
     and never move: they carry meaning, and meaning does not follow fashion. */
  --vt-brand:#6D3BE8; --vt-brand-hover:#5A2ED0; --vt-brand-on:#FFFFFF;
  --vt-brand-subtle:#EFEAFE; --vt-brand-subtle-text:#4C1D95;
  --vt-brand-line:color-mix(in srgb, var(--vt-brand) 38%, transparent);
}

/* ---- one appearance ----
   The marketing site is Signal light, and only that. The Blueprint dark
   palette still exists — in the client portal, where an owner turns it on for
   every customer at once (settings.portal_theme, migration 0019), and in the
   admin console, where it is an operator's own preference. A marketing page
   has no reader with a preference yet, so it has one appearance: the pills,
   the ring and the contrast ratios below are all verified against this one
   palette in Design kit.html. */


/* ==========================================================================
   2. KIT COMPONENTS — from Design kit.html
   ========================================================================== */

.vt-body{background:var(--vt-bg); color:var(--vt-ink);
  font-family:var(--vt-font); font-size:var(--vt-t-base); line-height:var(--vt-lh);
  -webkit-font-smoothing:antialiased}
.vt-link{color:var(--vt-ink); font-weight:600; text-decoration:underline; text-underline-offset:3px}
.vt-link:focus-visible{outline:2px solid var(--vt-ink); outline-offset:2px; border-radius:2px}

/* buttons — works on <button> and <a> */
.vt-btn{display:inline-flex; align-items:center; gap:8px; cursor:pointer;
  font:600 var(--vt-t-base)/1 var(--vt-font); padding:12px 18px;
  border-radius:var(--vt-r-m); border:1.5px solid transparent;
  background:var(--vt-brand); color:var(--vt-brand-on);
  text-decoration:none; white-space:nowrap;
  transition:background .15s ease}
.vt-btn:hover{background:var(--vt-brand-hover)}
.vt-btn--ghost{background:transparent; border-color:var(--vt-line); color:var(--vt-ink)}
.vt-btn--ghost:hover{background:color-mix(in srgb, var(--vt-ink) 6%, transparent)}
.vt-btn--quiet{background:transparent; color:var(--vt-ink); padding:12px 10px}
.vt-btn--quiet:hover{background:color-mix(in srgb, var(--vt-ink) 6%, transparent)}
.vt-btn:disabled{opacity:.45; cursor:not-allowed}
.vt-btn:focus-visible{outline:2px solid var(--vt-ink); outline-offset:2px}
@media (pointer: coarse){ .vt-btn{min-height:44px} }

/* forms */
.vt-field{display:flex; flex-direction:column; gap:6px; max-width:340px}
.vt-field > label{font:600 var(--vt-t-s)/1 var(--vt-font); color:var(--vt-ink)}
.vt-input{font:500 var(--vt-t-base)/1.3 var(--vt-font); color:var(--vt-ink);
  background:var(--vt-surface); border:1.5px solid var(--vt-line);
  border-radius:var(--vt-r-m); padding:11px 12px; width:100%}
.vt-input::placeholder{color:var(--vt-soft)}
.vt-input:focus-visible{outline:2px solid var(--vt-ink); outline-offset:1px; border-color:var(--vt-ink)}
.vt-hint{font:500 var(--vt-t-xs)/1.4 var(--vt-font); color:var(--vt-soft)}
.vt-field--error .vt-input{border-color:var(--vt-expired-text)}
.vt-field--error .vt-hint{color:var(--vt-expired-text)}

/* status pills */
.vt-pill{display:inline-flex; align-items:center;
  font:700 11px/1 var(--vt-font); letter-spacing:.02em;
  padding:4px 9px; border-radius:999px}
.vt-pill--valid{background:color-mix(in srgb, var(--vt-valid) var(--vt-pill-mix), transparent); color:var(--vt-valid-text)}
.vt-pill--soon{background:color-mix(in srgb, var(--vt-soon) var(--vt-pill-mix-soon), transparent); color:var(--vt-soon-text)}
.vt-pill--expired{background:color-mix(in srgb, var(--vt-expired) var(--vt-pill-mix), transparent); color:var(--vt-expired-text)}

/* ring — --pct is lifetime elapsed (0–100). Expired = full ring. */
.vt-ring{--pct:100; --size:36px; width:var(--size); height:var(--size);
  transform:rotate(-90deg); flex:none; display:block}
.vt-ring circle{fill:none; stroke-width:4.5}
.vt-ring__track{stroke:var(--vt-line)}
.vt-ring__arc{stroke-linecap:round; stroke-dasharray:var(--pct) 100}
.vt-ring__arc--valid{stroke:var(--vt-valid)}
.vt-ring__arc--soon{stroke:var(--vt-soon)}
.vt-ring__arc--expired{stroke:var(--vt-expired)}
.vt-ring__check{fill:none; stroke:var(--vt-ink); stroke-width:3.9; stroke-linecap:round; stroke-linejoin:round}

/* cards & item rows */
.vt-card{background:var(--vt-surface); border:1px solid var(--vt-line);
  border-radius:var(--vt-r-l); padding:var(--vt-s5)}
.vt-item{display:flex; align-items:center; gap:12px;
  background:var(--vt-surface); border:1px solid var(--vt-line);
  border-radius:var(--vt-r-m); padding:12px 14px}
.vt-item__body{flex:1; min-width:0}
.vt-item__name{font:700 14px/1.2 var(--vt-font); color:var(--vt-ink)}
.vt-item__meta{font:500 var(--vt-t-xs)/1.3 var(--vt-font); color:var(--vt-soft); margin-top:2px}


/* ==========================================================================
   3. BASE + A11Y
   ========================================================================== */

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
html,body{overflow-x:clip}
body{margin:0}
img,svg{max-width:100%}
p,h1,h2,h3,h4,ul,ol,figure,blockquote{margin:0}

.sr-only{position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0}

.skip-link{position:fixed; top:-100px; left:16px; z-index:100;
  background:var(--vt-brand); color:var(--vt-brand-on);
  padding:10px 16px; border-radius:var(--vt-r-m);
  font:600 var(--vt-t-s)/1 var(--vt-font); text-decoration:none}
.skip-link:focus,.skip-link:focus-visible{top:16px}

/* one focus treatment everywhere; never remove without replacing */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline:2px solid var(--vt-ink); outline-offset:2px}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:0.01ms !important; animation-iteration-count:1 !important;
    transition-duration:0.01ms !important; scroll-behavior:auto !important}
}

/* anchors clear the 68px sticky header */
[id]{scroll-margin-top:88px}

/* page measure — every band of content sits in one of these */
.measure{max-width:1200px; margin:0 auto; padding:0 clamp(20px, 4vw, 48px)}


/* ==========================================================================
   4. EDITORIAL TYPE — display scale, kickers, folios, mono captions
   ========================================================================== */

/* poster headline (hero) */
.display{font:800 clamp(42px, 6.6vw, 92px)/0.99 var(--vt-font);
  letter-spacing:-0.035em; color:var(--vt-ink); text-wrap:balance}
/* closing-CTA scale headline */
.display--sub{font:800 clamp(30px, 4.4vw, 56px)/1.05 var(--vt-font);
  letter-spacing:-0.03em}

/* kicker — small caps label above a headline */
.kicker{font:700 var(--vt-t-xs)/1 var(--vt-font); letter-spacing:.14em;
  text-transform:uppercase; color:var(--vt-soft); margin-bottom:22px}

/* deck — the standfirst under a display headline */
.deck{margin-top:26px; max-width:44ch; color:var(--vt-soft);
  font:500 var(--vt-t-md)/1.6 var(--vt-font)}

/* fine print under a CTA row */
.fine{margin-top:16px; font:500 var(--vt-t-xs)/1.4 var(--vt-font); color:var(--vt-soft)}

/* mono caption — dates, folios, machine-issued text */
.mono-caption{font:600 12px/1 var(--vt-mono); color:var(--vt-soft); letter-spacing:.06em}

/* horizontal print rule */
.rule{border:0; border-top:1px solid var(--vt-line)}

/* section frame: title left, folio right */
.sect{padding:clamp(48px, 8vh, 88px) 0}
.sect__head{display:flex; align-items:baseline; justify-content:space-between;
  gap:16px; flex-wrap:wrap; margin-bottom:30px}
.sect__title{font:800 clamp(24px, 3vw, var(--vt-t-2xl))/1.15 var(--vt-font);
  letter-spacing:-0.02em; color:var(--vt-ink)}
.sect__folio{font:600 12px/1 var(--vt-mono); color:var(--vt-soft); letter-spacing:.08em}


/* ==========================================================================
   5. HERO SPLIT + DESK — scattered card stack
   ========================================================================== */

.hero{display:grid; grid-template-columns:minmax(0,7fr) minmax(0,5fr);
  gap:clamp(32px, 5vw, 72px); align-items:center;
  padding:clamp(40px, 7vh, 84px) 0 clamp(48px, 8vh, 96px)}
.hero__cta{margin-top:34px; display:flex; gap:12px; flex-wrap:wrap; align-items:center}

/* the desk — a loose stack of item cards, like paperwork */
.desk{position:relative; min-height:520px}
.desk__card{position:absolute; width:min(320px, 92%);
  background:var(--vt-surface); border:1px solid var(--vt-line);
  border-radius:var(--vt-r-l); padding:18px 18px 16px;
  box-shadow:0 18px 40px -18px color-mix(in srgb, var(--vt-ink) 28%, transparent),
             0 2px 6px color-mix(in srgb, var(--vt-ink) 7%, transparent);
  transition:transform .25s ease}
.desk__card:hover{transform:rotate(0deg) translateY(-4px)}
.desk__head{display:flex; align-items:flex-start; justify-content:space-between; gap:12px}
.desk__label{font:700 var(--vt-t-md)/1.2 var(--vt-font); color:var(--vt-ink)}
.desk__meta{font:500 var(--vt-t-xs)/1.4 var(--vt-font); color:var(--vt-soft); margin-top:4px}
.desk__foot{display:flex; align-items:center; gap:10px; margin-top:14px;
  padding-top:12px; border-top:1px dashed var(--vt-line)}
.desk__date{font:600 12px/1 var(--vt-mono); color:var(--vt-soft); letter-spacing:.04em}
.desk__card--1{top:0; right:8%; transform:rotate(-3.2deg); z-index:5}
.desk__card--2{top:120px; left:0; transform:rotate(2.1deg); z-index:4}
.desk__card--3{top:248px; right:0; transform:rotate(-1.4deg); z-index:3}
.desk__card--4{top:372px; left:6%; transform:rotate(1.8deg); z-index:2}
.desk__caption{position:absolute; bottom:-34px; right:0;
  font:600 var(--vt-t-xs)/1 var(--vt-font); color:var(--vt-soft)}


/* ==========================================================================
   6. LEDGER STRIP + STAT NUMERALS
   ========================================================================== */

.ledger{background:var(--vt-surface); border:1px solid var(--vt-line);
  border-radius:var(--vt-r-l); overflow:hidden}
.ledger__masthead{display:flex; align-items:baseline; justify-content:space-between;
  gap:16px; flex-wrap:wrap; padding:26px 28px 0}
.ledger__title{font:800 var(--vt-t-lg)/1.2 var(--vt-font); letter-spacing:-0.01em}
.ledger__date{font:600 12px/1 var(--vt-mono); color:var(--vt-soft); letter-spacing:.06em}
.ledger__stats{display:grid; grid-template-columns:repeat(4, minmax(0,1fr));
  gap:0; padding:22px 28px 26px; border-bottom:1px solid var(--vt-line)}
.stat{padding-right:18px}
.stat + .stat{padding-left:18px; border-left:1px solid var(--vt-line)}
.stat__n{font:800 clamp(30px, 4vw, 52px)/1 var(--vt-font);
  letter-spacing:-0.03em; color:var(--vt-ink); font-variant-numeric:tabular-nums}
.stat__l{font:600 var(--vt-t-xs)/1.3 var(--vt-font); color:var(--vt-soft); margin-top:6px}
.stat--soon .stat__n{color:var(--vt-soon-text)}
.stat--expired .stat__n{color:var(--vt-expired-text)}
.ledger__rows{list-style:none; padding:0}
.ledger__row{display:flex; align-items:center; gap:14px;
  padding:15px 28px; border-bottom:1px solid var(--vt-line)}
.ledger__row:last-of-type{border-bottom:0}
.ledger__body{flex:1; min-width:0}
.ledger__name{font:700 14.5px/1.25 var(--vt-font); color:var(--vt-ink)}
.ledger__meta{font:500 var(--vt-t-xs)/1.35 var(--vt-font); color:var(--vt-soft); margin-top:2px}
.ledger__when{font:600 12px/1 var(--vt-mono); color:var(--vt-soft); letter-spacing:.03em;
  text-align:right; flex:none; font-variant-numeric:tabular-nums}
.ledger__more{padding:16px 28px; background:color-mix(in srgb, var(--vt-ink) 3%, transparent);
  font:500 var(--vt-t-s)/1.4 var(--vt-font); color:var(--vt-soft);
  display:flex; justify-content:space-between; align-items:center; gap:12px; flex-wrap:wrap}


/* responsive: the split flattens, the desk becomes a near-straight list */
@media (max-width: 920px){
  .hero{grid-template-columns:1fr; gap:44px; align-items:start}
  .desk{min-height:0; display:flex; flex-direction:column; gap:14px; padding-bottom:34px}
  .desk__card{position:static; width:100%;
    box-shadow:0 2px 8px color-mix(in srgb, var(--vt-ink) 8%, transparent)}
  .desk__card--1{transform:rotate(-0.6deg)}
  .desk__card--2{transform:rotate(0.5deg)}
  .desk__card--3{transform:rotate(-0.4deg)}
  .desk__card--4{transform:rotate(0.5deg)}
  .desk__caption{bottom:6px}
}
@media (max-width: 700px){
  .ledger__stats{grid-template-columns:repeat(2, minmax(0,1fr)); gap:18px 0;
    padding-left:18px; padding-right:18px}
  .stat:nth-child(3){padding-left:0; border-left:0}
  .ledger__row,.ledger__masthead,.ledger__more{padding-left:18px; padding-right:18px}
  .ledger__when{display:none}
}


/* ==========================================================================
   7. LONG-FORM — article, pull quotes, steps, prose
   ========================================================================== */

/* essay-style article column (marketing narrative sections) */
.article{max-width:66ch; margin:0 auto}
.article > p{font:500 var(--vt-t-md)/1.75 var(--vt-font); color:var(--vt-ink); margin-bottom:26px}
.article > p:first-of-type::first-letter{font:800 3.4em/0.8 var(--vt-font);
  float:left; padding:8px 12px 0 0; color:var(--vt-ink)}
.article .soft{color:var(--vt-soft)}

/* pull quote — ruled left border, display weight */
.pull{margin:44px 0; padding:6px 0 6px 26px; border-left:3px solid var(--vt-ink)}
.pull p{font:700 clamp(20px, 2.6vw, 27px)/1.35 var(--vt-font);
  letter-spacing:-0.015em; color:var(--vt-ink); text-wrap:balance}

/* numbered steps set like essay sections */
.steps{counter-reset:step; margin:38px 0 6px; display:grid; gap:0}
.step{display:grid; grid-template-columns:72px minmax(0,1fr); gap:18px;
  padding:24px 0; border-top:1px solid var(--vt-line)}
.step::before{counter-increment:step; content:"0" counter(step);
  font:800 var(--vt-t-2xl)/1 var(--vt-font); letter-spacing:-0.02em;
  color:color-mix(in srgb, var(--vt-ink) 26%, transparent)}
.step h3{font:700 var(--vt-t-md)/1.3 var(--vt-font); color:var(--vt-ink)}
.step p{margin-top:6px; font:500 var(--vt-t-base)/1.65 var(--vt-font); color:var(--vt-soft); max-width:52ch}
@media (max-width: 700px){
  .step{grid-template-columns:52px minmax(0,1fr)}
  .step::before{font-size:var(--vt-t-xl)}
}

/* prose — long-form legal/security/about pages. Wrap the body in .prose. */
.prose{max-width:66ch}
.prose > * + *{margin-top:16px}
.prose h1{font:800 clamp(30px, 4vw, var(--vt-t-3xl))/1.1 var(--vt-font);
  letter-spacing:-0.025em; color:var(--vt-ink); margin-bottom:10px}
.prose h2{font:800 var(--vt-t-xl)/1.2 var(--vt-font); letter-spacing:-0.015em;
  color:var(--vt-ink); margin-top:44px; padding-top:28px; border-top:1px solid var(--vt-line)}
.prose h2:first-child{margin-top:0; padding-top:0; border-top:0}
.prose h3{font:700 var(--vt-t-lg)/1.25 var(--vt-font); color:var(--vt-ink); margin-top:32px}
.prose p,.prose li{font:500 var(--vt-t-base)/1.7 var(--vt-font); color:var(--vt-ink)}
.prose .soft{color:var(--vt-soft)}
.prose ul,.prose ol{padding-left:24px}
.prose li{margin-bottom:8px}
.prose li::marker{color:var(--vt-soft)}
.prose a{color:var(--vt-ink); font-weight:600; text-decoration:underline; text-underline-offset:3px}
.prose strong{font-weight:700; color:var(--vt-ink)}
.prose code{font:500 0.9em/1.4 var(--vt-mono); color:var(--vt-ink);
  background:color-mix(in srgb, var(--vt-ink) 6%, transparent);
  border-radius:4px; padding:1px 5px}
.prose blockquote{margin:28px 0; padding:6px 0 6px 26px; border-left:3px solid var(--vt-ink)}
.prose blockquote p{font:700 var(--vt-t-md)/1.5 var(--vt-font); letter-spacing:-0.01em}
.prose hr{border:0; border-top:1px solid var(--vt-line); margin:40px 0}
.prose table{width:100%; border-collapse:collapse; font:500 var(--vt-t-s)/1.5 var(--vt-font)}
.prose th{text-align:left; font:700 var(--vt-t-xs)/1.3 var(--vt-font);
  letter-spacing:.08em; text-transform:uppercase; color:var(--vt-soft);
  padding:8px 16px 8px 0; border-bottom:1px solid var(--vt-line)}
.prose td{padding:9px 16px 9px 0; border-bottom:1px solid var(--vt-line); vertical-align:top}
.prose-meta{font:600 12px/1.5 var(--vt-mono); color:var(--vt-soft);
  letter-spacing:.06em; margin-bottom:36px; font-variant-numeric:tabular-nums}


/* ==========================================================================
   8. CLOSING CTA
   ========================================================================== */

.close{padding:clamp(48px, 9vh, 96px) 0; text-align:center}
.close h2{font:800 clamp(30px, 4.4vw, 56px)/1.05 var(--vt-font);
  letter-spacing:-0.03em; color:var(--vt-ink); text-wrap:balance; max-width:22ch; margin:0 auto}
.close p{margin:18px auto 0; max-width:46ch; color:var(--vt-soft); font:500 var(--vt-t-base)/1.6 var(--vt-font)}
.close .vt-btn{margin-top:28px}


/* ==========================================================================
   9. SHELL — sticky header, collapsing logo, dropdown nav, column footer
   ========================================================================== */

/* The header sticks and stays transparent at rest, so the page scrolls under
   it. Past ~40px the shell script adds .is-scrolled: a hairline and a tinted
   background appear, and the full lockup cross-fades to the ring mark alone.
   Both marks live stacked inside .brand__slot, whose size is FIXED — the
   collapse can never reflow the nav. */
.site-header{position:sticky; top:0; z-index:60;
  background:transparent; border-bottom:1px solid transparent;
  transition:background .2s ease, border-color .2s ease}
/* Opaque, not frosted: the bar passes over dark cards and photographs on
   these pages, and nav text has to keep its contrast over all of them. */
.site-header.is-scrolled,
.site-header.is-menu-open{
  background:var(--vt-bg); border-bottom-color:var(--vt-line)}
/* nothing can add .is-scrolled without JS — keep the bar opaque there so
   page text never runs under a transparent header */
html:not([data-js]) .site-header{background:var(--vt-bg); border-bottom-color:var(--vt-line)}

.site-header__inner{display:flex; align-items:center; gap:10px; height:68px}

/* brand — fixed 136x28 slot, two SVGs stacked and cross-faded */
.brand{display:flex; align-items:center; flex:none; margin-right:auto;
  color:var(--vt-ink); text-decoration:none}
.brand:focus-visible{outline:2px solid var(--vt-ink); outline-offset:4px; border-radius:4px}
.brand__slot{position:relative; display:block; width:136px; height:28px; flex:none}
.brand__slot svg{position:absolute; top:0; left:0; height:28px; display:block;
  transition:opacity .22s ease}
.brand__lockup{width:136px}
.brand__mark{width:28px; opacity:0}
.site-header.is-scrolled .brand__lockup{opacity:0}
.site-header.is-scrolled .brand__mark{opacity:1}
@media (prefers-reduced-motion: reduce){ .brand__slot svg{transition:none} }
/* mark geometry — the kit ring at 75% lifetime, valid. The arc is the company
   mark and stays GREEN: the Iris accent is the product's colour, the logo is
   the company's, and they are not the same thing. Never recolour it here. */
.brand__slot circle{fill:none; stroke-width:4.5}
.brand__ring-track{stroke:var(--vt-line)}
.brand__ring-arc{stroke:var(--vt-valid); stroke-linecap:round; stroke-dasharray:75 100}
.brand__ring-check{fill:none; stroke:var(--vt-ink); stroke-width:3.9;
  stroke-linecap:round; stroke-linejoin:round}
.brand__word{fill:var(--vt-ink); font-family:var(--vt-font);
  font-size:19px; font-weight:800; letter-spacing:-0.38px}
/* footer variant */
.brand--sm .brand__slot,.brand--sm .brand__lockup{width:118px}
.brand--sm .brand__slot,.brand--sm .brand__slot svg{height:24px}

/* nav — sits right of centre, actions hard right */
.site-nav{display:flex; align-items:center; gap:2px;
  margin-right:clamp(8px, 4.5vw, 60px)}
.nav-group{position:relative; display:flex; align-items:center; height:68px}

.nav-trigger{display:inline-flex; align-items:center; gap:6px; min-height:36px;
  padding:8px 12px; border-radius:var(--vt-r-s); border:0; background:transparent;
  font:600 var(--vt-t-s)/1 var(--vt-font); color:var(--vt-soft);
  cursor:pointer; white-space:nowrap;
  transition:background .15s ease, color .15s ease}
.nav-trigger:hover,.nav-group.is-open .nav-trigger{color:var(--vt-ink);
  background:color-mix(in srgb, var(--vt-ink) 6%, transparent)}
.nav-group[data-current] .nav-trigger{color:var(--vt-ink)}
.nav-chev{width:10px; height:6px; flex:none; transition:transform .18s ease}
.nav-group.is-open .nav-chev{transform:rotate(180deg)}

.nav-menu{position:absolute; top:calc(100% - 8px); left:0; z-index:70;
  list-style:none; min-width:198px; margin:0; padding:6px;
  background:var(--vt-surface); border:1px solid var(--vt-line);
  border-radius:var(--vt-r-s);
  box-shadow:0 20px 44px -22px color-mix(in srgb, var(--vt-ink) 50%, transparent),
             0 2px 8px color-mix(in srgb, var(--vt-ink) 8%, transparent);
  opacity:0; visibility:hidden; transform:translateY(-4px);
  /* visibility flips the instant the panel opens, so the first link is
     focusable straight away, and waits for the fade on the way out */
  transition:opacity .16s ease, transform .16s ease, visibility 0s linear .16s}
.nav-group.is-open > .nav-menu{opacity:1; visibility:visible; transform:none;
  transition:opacity .16s ease, transform .16s ease, visibility 0s}
.nav-menu a{display:block; padding:8px 10px; border-radius:6px; text-align:left;
  font:600 var(--vt-t-s)/1.35 var(--vt-font); color:var(--vt-ink);
  text-decoration:none; white-space:nowrap}
.nav-menu a:hover{background:color-mix(in srgb, var(--vt-ink) 7%, transparent)}
.nav-menu a[aria-current="page"]{text-decoration:underline;
  text-decoration-thickness:2px; text-underline-offset:4px}
.nav-menu__label,.nav-extra{display:none}

.site-header__actions{display:flex; align-items:center; gap:8px; flex:none}
.site-header__actions .vt-btn{border-radius:999px; padding:10px 17px;
  font-size:var(--vt-t-s)}
.site-header__actions .vt-btn--quiet{padding:10px 12px}

/* menu button — narrow layouts only */
.nav-toggle{display:none; align-items:center; gap:8px; min-height:36px;
  padding:8px 12px; border-radius:999px; cursor:pointer;
  background:transparent; border:1.5px solid var(--vt-line);
  font:600 var(--vt-t-s)/1 var(--vt-font); color:var(--vt-ink)}
.nav-toggle:hover{background:color-mix(in srgb, var(--vt-ink) 6%, transparent)}
.nav-toggle__bars{width:14px; height:10px; flex:none}
html:not([data-js]) .nav-toggle{display:none !important}

/* --- narrow layout: the nav becomes a panel under the bar ---------------- */
@media (max-width: 899px){
  .site-nav{display:none; position:absolute; top:100%; left:0; right:0;
    flex-direction:column; align-items:stretch; gap:2px; margin:0;
    padding:12px clamp(20px, 4vw, 48px) 20px;
    background:var(--vt-surface); border-bottom:1px solid var(--vt-line);
    box-shadow:0 26px 44px -30px color-mix(in srgb, var(--vt-ink) 55%, transparent);
    max-height:calc(100dvh - 68px); overflow-y:auto}
  .site-header.is-menu-open .site-nav{display:flex}
  .nav-group{display:block; height:auto; position:static; padding:10px 0}
  .nav-group + .nav-group{border-top:1px solid var(--vt-line)}
  .nav-trigger{display:none}
  .nav-menu__label{display:block; margin:0 0 6px;
    font:700 11px/1 var(--vt-font); letter-spacing:.14em;
    text-transform:uppercase; color:var(--vt-soft)}
  .nav-menu{position:static; min-width:0; padding:0; opacity:1; visibility:visible;
    transform:none; background:none; border:0; border-radius:0; box-shadow:none}
  .nav-menu a{padding:9px 0; font-size:var(--vt-t-base); white-space:normal}
  .nav-menu a:hover{background:none; text-decoration:underline; text-underline-offset:3px}
  .nav-extra{display:flex; align-items:center; gap:12px; flex-wrap:wrap;
    padding-top:14px; margin-top:10px; border-top:1px solid var(--vt-line)}
  .nav-toggle{display:inline-flex}
  .site-header__actions .theme-toggle,
  .site-header__actions .vt-btn--quiet{display:none}
}
@media (max-width: 899px){
  /* no JS: no menu button, so flatten every group into one wrapped row */
  html:not([data-js]) .site-nav{display:flex; position:static; flex-direction:row;
    flex-wrap:wrap; padding:0 0 14px; background:none; border:0; box-shadow:none}
  html:not([data-js]) .site-header__inner{flex-wrap:wrap; height:auto; padding-top:14px}
  html:not([data-js]) .brand{margin-right:auto}
  html:not([data-js]) .nav-group{padding:0; border:0}
  html:not([data-js]) .nav-group + .nav-group{border:0}
  html:not([data-js]) .nav-menu{display:flex; flex-wrap:wrap; gap:0 4px}
  html:not([data-js]) .nav-menu__label{display:none}
  html:not([data-js]) .nav-menu a{padding:8px 8px; font-size:var(--vt-t-s)}
  html:not([data-js]) .nav-extra{display:none}
}
/* --- footer: small columns, then a bottom row ---------------------------- */
.site-footer{border-top:1px solid var(--vt-line); margin-top:24px}
.site-footer__inner{padding:clamp(40px, 6vw, 64px) 0 34px}
.site-footer__cols{display:grid; gap:32px 24px;
  grid-template-columns:repeat(5, minmax(0, 1fr))}
.footer-col h2{font:700 11px/1 var(--vt-font); letter-spacing:.14em;
  text-transform:uppercase; color:var(--vt-soft); margin-bottom:14px}
.footer-col ul{list-style:none; margin:0; padding:0;
  display:flex; flex-direction:column; gap:9px}
.footer-col a{font:500 var(--vt-t-s)/1.4 var(--vt-font); color:var(--vt-ink);
  text-decoration:none}
.footer-col a:hover{text-decoration:underline; text-underline-offset:3px}
.footer-col a[aria-current="page"]{text-decoration:underline;
  text-decoration-thickness:2px; text-underline-offset:3px}

.site-footer__bottom{display:flex; align-items:center; justify-content:space-between;
  gap:12px 28px; flex-wrap:wrap;
  margin-top:clamp(36px, 5vw, 56px); padding-top:22px;
  border-top:1px solid var(--vt-line)}
.site-footer__colophon{display:flex; align-items:center; gap:14px; flex-wrap:wrap;
  font:500 var(--vt-t-xs)/1.5 var(--vt-font); color:var(--vt-soft)}
.site-footer__colophon .brand{margin-right:0}
.site-footer__legal{display:flex; align-items:center; flex-wrap:wrap; gap:4px 22px}
.site-footer__legal a{font:500 var(--vt-t-xs)/1.4 var(--vt-font);
  color:var(--vt-soft); text-decoration:none}
.site-footer__legal a:hover{color:var(--vt-ink); text-decoration:underline;
  text-underline-offset:3px}

@media (max-width: 860px){
  .site-footer__cols{grid-template-columns:repeat(3, minmax(0, 1fr))}
}
@media (max-width: 520px){
  .site-footer__cols{grid-template-columns:repeat(2, minmax(0, 1fr)); gap:28px 16px}
}

/* ============================================================
   Notice pages (/verify, /unsubscribe) — src/pages/notice.ts
   The Worker's CSP is style-src 'self' with no 'unsafe-inline', so these
   pages carry no <style> block and no style attributes: every rule they
   need is here, and the mark is drawn with classes rather than the
   custom properties .vt-ring uses.
   ============================================================ */
.nt-body{display:flex; align-items:center; justify-content:center;
  min-height:100vh; min-height:100svh; padding:24px}
.nt-wrap{width:100%; max-width:440px}
.nt-brand{display:flex; align-items:center; justify-content:center; gap:9px;
  margin-bottom:18px}
.nt-brand__word{font:800 17px/1 var(--vt-font); letter-spacing:-0.02em; color:var(--vt-ink)}
.nt-mark{width:26px; height:26px; flex:none; display:block; transform:rotate(-90deg)}
.nt-mark circle{fill:none; stroke-width:4.5}
.nt-mark__track{stroke:var(--vt-line)}
.nt-mark__arc{stroke:var(--vt-valid); stroke-linecap:round; stroke-dasharray:75 100}
.nt-mark__check{fill:none; stroke:var(--vt-ink); stroke-width:3.9;
  stroke-linecap:round; stroke-linejoin:round}
.nt-card{background:var(--vt-surface); border:1px solid var(--vt-line);
  border-radius:var(--vt-r-l); padding:26px 24px}
.nt-h{font:800 var(--vt-t-xl)/1.2 var(--vt-font); letter-spacing:-0.02em; color:var(--vt-ink)}
.nt-p{margin-top:10px; color:var(--vt-soft); font-size:var(--vt-t-s); line-height:1.55}
.nt-form{margin-top:20px}
.nt-form .vt-btn{width:100%; justify-content:center; min-height:48px}
