/* ============================================================
   Verbunk — Night theme for the public site.
   Written against the EXISTING class names so every page keeps
   its copy and markup; only the stylesheet link changes.
   Direction A hero, B type system, C proof. See docs/16-the-flywheel.md
   ============================================================ */
:root{
  --night:#07090c; --night-2:#0d1218; --night-3:#141b23;
  --paper:#f7f6f3; --paper-2:#efede8; --card:#fff;
  --ink:#14161a; --ink-2:#4c525c; --ink-3:#646a72;
  --gi:#f2f6fb; --gi-2:#94a2b4; --gi-3:#7e8996;
  --acc:#3ddba4; --acc-ink:#04150f;
  /* THE GROUND IS PART OF THE NAME. Every contrast defect found on 18 August
     was one ink used on the ground it was not chosen for: --acc is 11:1 on the
     console and 1.77:1 on a white card; --brick is the link colour and it is a
     LIGHT-surface colour, 3.52:1 on a card. The palette recorded the colour and
     not the ground, so choosing wrongly looked like choosing. These names make
     it a naming error instead, and scripts/lib/site-audit.mjs §3 enforces the
     pairing on every run. */
  --acc-on-light:#0b6a49;      /* 6.62 on white, 6.16 on the accent tint */
  --brick-on-dark:#e0674a;     /* 5.60 on the card ground; --brick is 3.52 */
  --brick-on-dark-hover:#f08a6b;
  --gi-4:#8d99a8;              /* captions on the DARKEST card, 6.55 */
  --warn:#ffbe3d; --brick:#b8442e; --ok:#1f7a55;
  --line:#dfdbd2; --line-dk:rgba(255,255,255,.09);
  /* NO WEBFONT. Hanken Grotesk came from a render-blocking Google Fonts sheet;
     with the host unreachable, first paint was 77.2s. The name is removed as well
     as the link: leaving a family nothing supplies would say the site uses a
     typeface it no longer loads, and render differently for the few who happen to
     have it installed. */
  --sans:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --max:1180px; --r:14px;
}
*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}*{animation:none!important;transition:none!important}}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--sans);
  font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased}
img,svg{max-width:100%;display:block}
h1,h2,h3,h4{margin:0 0 .5em;font-weight:800;letter-spacing:-.035em;line-height:1.05;text-wrap:balance}
h1{font-size:clamp(2.3rem,5.6vw,4rem)}
h2{font-size:clamp(1.8rem,4vw,2.7rem);text-transform:uppercase}
h3{font-size:1.12rem;text-transform:uppercase;letter-spacing:-.02em}
h4{font-size:.95rem}
p{margin:0 0 1em}
a{color:var(--brick);text-decoration:none}
a:hover{text-decoration:underline}
/* A FOCUS RING NOBODY CAN SEE IS NOT A FOCUS RING. --acc measures 1.64:1 on the
   paper ground and 1.51 on a band; WCAG 1.4.11 asks 3:1. So on every light page
   a keyboard user had no indication whatever of where they were — and the ring
   looked deliberate because on the night ground, where it was designed, it is
   11.27. The ground is part of the name here exactly as it is for ink.
   --acc-on-light is 6.13 on paper and only 2.84 on a dark card, so this is a
   base plus an override, not a swap. */
:focus-visible{outline:2px solid var(--acc-on-light);outline-offset:3px;border-radius:4px}
.site-header :focus-visible,.hero :focus-visible,.band-dark :focus-visible,
.site-footer :focus-visible,.form-card :focus-visible,.auth-page :focus-visible,
.dash :focus-visible{outline-color:var(--acc)}
.wrap{max-width:var(--max);margin:0 auto;padding:0 22px}
.center{text-align:center}
.small{font-size:.85rem;color:var(--ink-3)}
.mt-2{margin-top:1rem}.mt-3{margin-top:1.6rem}
.lead{font-size:clamp(1.02rem,1.9vw,1.2rem);color:var(--ink-2);max-width:52ch}
.kicker{display:inline-block;font-family:var(--mono);font-size:.68rem;font-weight:600;
  letter-spacing:.18em;text-transform:uppercase;color:var(--brick);margin-bottom:12px}
.section-intro{max-width:58ch}
/* CLIPPED, NOT SHOVED OFF-SCREEN. left:-9999px leaves a full-size element in
   the layout with real ink on a real ground — the gallery measured this link at
   3.71:1 on the auth pages the moment it existed, which is a true reading of
   something no one can ever see. A 1px clipped box is the same visual result,
   cannot push the page sideways, does not break in RTL, and is small enough
   that a renderer measuring what a visitor sees correctly ignores it. */
.skip-link{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.skip-link:focus{width:auto;height:auto;clip-path:none;left:12px;top:12px;z-index:99;background:var(--acc);color:var(--acc-ink);
  padding:10px 16px;border-radius:6px;font-weight:700}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font:inherit;
  font-size:.92rem;font-weight:700;padding:12px 22px;border-radius:99px;border:1px solid transparent;
  cursor:pointer;text-decoration:none;min-height:48px}
.btn:hover{text-decoration:none}
.btn-primary{background:var(--acc);color:var(--acc-ink)}
.btn-primary:hover{background:#5ae7b6}
.btn-secondary{background:transparent;color:var(--ink);border-color:var(--line)}
.btn-secondary:hover{border-color:var(--ink)}
/* on dark grounds the secondary button must invert or it is invisible */
.hero .btn-secondary,.band-dark .btn-secondary,.site-header .btn-secondary,
.auth-page .btn-secondary{color:var(--gi);border-color:rgba(255,255,255,.22);background:transparent}
.hero .btn-secondary:hover,.band-dark .btn-secondary:hover,
.site-header .btn-secondary:hover{border-color:rgba(255,255,255,.5);color:#fff}
.hero .btn-ghost,.band-dark .btn-ghost,.site-header .btn-ghost{color:var(--gi-2)}
.hero .btn-ghost:hover,.band-dark .btn-ghost:hover,.site-header .btn-ghost:hover{color:var(--gi)}
.btn-ghost{background:transparent;color:var(--ink-2);padding:12px 14px}
.btn-ghost:hover{color:var(--ink)}
.btn-sm{padding:9px 16px;min-height:40px;font-size:.85rem}
.btn-block{width:100%}
.cta-row{display:flex;flex-wrap:wrap;gap:12px;align-items:center}
.microcopy{font-size:.84rem;color:var(--ink-3);margin-top:12px}

/* ---------- header ---------- */
.site-header{background:var(--night);color:var(--gi);position:sticky;top:0;z-index:40;
  border-bottom:1px solid var(--line-dk)}
.header-inner{display:flex;align-items:center;justify-content:space-between;gap:18px;
  max-width:var(--max);margin:0 auto;padding:16px 22px}
.site-header .wrap>.header-inner{padding-left:0;padding-right:0}
.logo{font-weight:800;letter-spacing:.24em;font-size:.78rem;color:var(--gi);text-decoration:none;
  text-transform:uppercase}
.logo:hover{text-decoration:none}
.logo .dot{color:var(--acc)}
/* :not(.btn) IS LOAD-BEARING. .mobile-nav is a <nav> inside .site-header, so
   this rule and the one on .mobile-nav a both outspecify .btn-primary (0,2,x
   against 0,1,0) and repainted the drawer's own buttons. The primary CTA kept
   its mint background and took --gi-2 for ink: 1.47:1, the least readable
   thing on the site, on the most important control a phone visitor has. It
   also took the drawer's 10px/2px padding. Invisible to a static read, and
   .mobile-nav.open had never been rendered by any check until 19 August. */
.site-header nav a:not(.btn),.header-ctas a.btn-ghost{color:var(--gi-2);font-size:.9rem}
.site-header nav a:hover{color:var(--gi);text-decoration:none}
.site-header .main-nav{display:none;gap:24px}
@media(min-width:900px){.site-header .main-nav{display:flex}}
.header-ctas{display:flex;align-items:center;gap:12px}
.header-ctas .btn-secondary{border-color:rgba(255,255,255,.2);color:var(--gi)}
.header-ctas .btn-secondary:hover{border-color:rgba(255,255,255,.45)}
.nav-toggle{display:inline-flex;flex-direction:column;justify-content:center;gap:4px;
  background:transparent;border:1px solid var(--line-dk);color:var(--gi);
  border-radius:8px;padding:10px 9px;font:inherit;cursor:pointer}
/* the toggle is three bare spans in the markup — they are the bars */
.nav-toggle span{display:block;width:16px;height:1.5px;background:currentColor;border-radius:2px}
@media(min-width:900px){.nav-toggle{display:none}}
.mobile-nav{display:none;flex-direction:column;gap:2px;padding:8px 0 16px;border-top:1px solid var(--line-dk)}
.mobile-nav.open{display:flex}
/* The drawer is a <nav> inside .site-header, so any descendant rule can
   outrank its display:none. At desktop it must be hidden whatever JS did. */
@media(min-width:900px){.nav-toggle,.mobile-nav,.mobile-nav.open{display:none}}
.mobile-nav a:not(.btn){color:var(--gi-2);padding:10px 2px;font-size:.95rem}

/* ---------- hero ---------- */
.hero{background:var(--night);color:var(--gi);position:relative;isolation:isolate;overflow:hidden;
  padding:70px 0 60px}
.hero::before{content:"";position:absolute;inset:0;z-index:-1;
  background:
    radial-gradient(115% 85% at 76% 16%, rgba(61,219,164,.15), transparent 58%),
    radial-gradient(95% 75% at 10% 92%, rgba(77,163,255,.13), transparent 62%),
    linear-gradient(#0c1219, var(--night) 72%)}
.hero h1,.hero h2{color:var(--gi)}
.hero .lead,.hero p{color:var(--gi-2)}
.hero .kicker{color:var(--acc)}
.hero a:not(.btn){color:var(--acc)}

/* ---------- bands & sections ---------- */
section{padding:70px 0}
.band{background:var(--paper-2)}
.band-dark{background:var(--night);color:var(--gi)}
.band-dark h2,.band-dark h3{color:var(--gi)}
.band-dark p,.band-dark .lead{color:var(--gi-2)}
.band-dark .kicker{color:var(--acc)}

/* ---------- cards & grids ---------- */
.grid{display:grid;gap:16px}
.grid-2{grid-template-columns:1fr}
.grid-3{grid-template-columns:1fr}
@media(min-width:760px){.grid-2{grid-template-columns:repeat(2,1fr)}
  .grid-3{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1000px){.grid-3{grid-template-columns:repeat(3,1fr)}}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:26px 24px}
.card h3{margin-bottom:8px}
.card p{color:var(--ink-2);font-size:.94rem;margin-bottom:0}
.band-dark .card{background:var(--night-2);border-color:var(--line-dk)}
.band-dark .card p{color:var(--gi-2)}
.card-icon{width:42px;height:42px;border-radius:11px;margin-bottom:16px;display:grid;place-items:center;
  background:rgba(61,219,164,.12);border:1px solid rgba(61,219,164,.28);color:var(--acc);
  font-weight:800;font-size:1.05rem}
.split{display:grid;gap:30px;grid-template-columns:1fr;align-items:center}
@media(min-width:900px){.split{grid-template-columns:1fr 1fr}}
.full{grid-column:1/-1}

/* ---------- lists, stats, tags ---------- */
.check-list{list-style:none;margin:0 0 1.2em;padding:0;display:grid;gap:10px}
.check-list li{padding-left:22px;position:relative;color:var(--ink-2)}
.check-list li::before{content:"→";position:absolute;left:0;color:var(--brick);font-family:var(--mono)}
.band-dark .check-list li{color:var(--gi-2)}
.band-dark .check-list li::before{color:var(--acc)}
.stat{display:flex;flex-direction:column;gap:3px}
.stat strong,.stat b{font-family:var(--mono);font-size:1.9rem;font-weight:700;letter-spacing:-.035em;
  font-variant-numeric:tabular-nums;line-height:1.1}
.stat span{font-size:.84rem;color:var(--ink-2)}
.band-dark .stat span{color:var(--gi-2)}
.tag{display:inline-flex;align-items:center;gap:5px;font-size:.7rem;font-weight:700;
  padding:3px 9px;border-radius:99px;font-family:var(--mono);letter-spacing:.05em}
.tag::before{content:"";width:5px;height:5px;border-radius:50%;background:currentColor}
.tag-ok,.tag-live{color:var(--ok);background:rgba(31,122,85,.12)}
.tag-warn{color:#8a6a12;background:rgba(255,190,61,.16)}
.tag-muted{color:var(--ink-3);background:rgba(109,115,123,.12)}
.band-dark .tag-ok,.band-dark .tag-live{color:var(--acc);background:rgba(61,219,164,.14)}
.flow-step{display:flex;gap:16px;align-items:flex-start;padding:18px 0;border-bottom:1px solid var(--line)}
.flow-step:last-child{border-bottom:0}
.flow-step h3{margin-bottom:6px}
.photo-slot{border:1px dashed var(--line);border-radius:var(--r);min-height:220px;display:grid;
  place-items:center;font-family:var(--mono);font-size:.66rem;letter-spacing:.18em;
  text-transform:uppercase;color:var(--ink-3);background:var(--paper-2);text-align:center;padding:20px}
.band-dark .photo-slot{border-color:var(--line-dk);background:var(--night-2);color:var(--gi-3)}

/* ---------- forms ---------- */
.field{display:flex;flex-direction:column;gap:6px;margin-bottom:18px}
.field label{font-weight:650;font-size:.9rem}
.field input,.field select,.field textarea{font:inherit;font-size:.95rem;padding:12px 14px;
  border:1px solid var(--line);border-radius:10px;background:var(--card);color:var(--ink);width:100%;
  box-sizing:border-box;max-width:100%}
/* A textarea is user-resizable by default, in BOTH axes. Dragging the handle
   sideways pushed it straight out of the card behind it, because the card is
   sized to its content and the drag is not content. Vertical only: a person
   wanting more room for a note gets it, and the layout cannot be broken from
   the corner of a text box. */
.field textarea{resize:vertical;min-height:96px}
.field input:focus,.field select:focus,.field textarea:focus{outline:2px solid var(--acc-on-light);outline-offset:1px}
.field .hint,.field small{font-size:.82rem;color:var(--ink-3)}
.consent{display:flex;gap:10px;align-items:flex-start;font-size:.88rem;color:var(--ink-2);margin-bottom:18px}
.consent input{margin-top:3px;flex:none}
.form-error{color:var(--brick);font-size:.86rem;font-weight:600}
.form-success{color:var(--ok);font-size:.9rem;font-weight:600}
/* THE GROUND IS PART OF THE NAME, and these two had no ground. --brick and
   --ok are LIGHT-surface inks: on the footer they measure 3.71 and 3.77, on a
   dark card 3.50 and 3.56. Every newsletter form on this site lives in the
   footer and every sign-up form lives on a dark card, so the ONLY sentence a
   visitor sees when something goes wrong, and the ONLY confirmation when it
   goes right, were both below AA on every page. Neither had ever been
   rendered: at rest .form-success is hidden and .form-error is empty, so the
   whole class was invisible to a gallery that only ever loaded pages. */
.site-footer .form-error,.band-dark .form-error,
.form-card .form-error,.auth-page .form-error{color:var(--brick-on-dark)}
.site-footer .form-success,.band-dark .form-success,
.form-card .form-success,.auth-page .form-success{color:var(--acc)}
.band-dark .field label{color:var(--gi)}
.band-dark .field input,.band-dark .field select,.band-dark .field textarea{
  background:var(--night-2);border-color:var(--line-dk);color:var(--gi)}
.band-dark .consent{color:var(--gi-2)}
.newsletter-row{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-start}
.newsletter-row .field{flex:1;min-width:220px;margin-bottom:0}

/* auth pages: single centred card on night */
.auth-page{background:var(--night);min-height:100vh;display:grid;place-items:center;padding:40px 20px}
.auth-page .card{max-width:440px;width:100%}

/* ---------- tables ---------- */
table{width:100%;border-collapse:collapse;font-size:.92rem}
th,td{text-align:left;padding:11px 12px;border-bottom:1px solid var(--line)}
th{font-family:var(--mono);font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink-3);font-weight:600}
td b{font-family:var(--mono);font-variant-numeric:tabular-nums}

/* ---------- footer ---------- */
.site-footer{background:var(--night);color:var(--gi-2);padding:54px 0 36px;font-size:.9rem}
.site-footer a{color:var(--gi-2)}
.site-footer a:hover{color:var(--gi);text-decoration:none}
.site-footer h4{font-family:var(--mono);font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--gi-3);font-weight:600;margin-bottom:12px}
.footer-grid{display:grid;gap:28px;grid-template-columns:1fr}
@media(min-width:760px){.footer-grid{grid-template-columns:1.4fr 1fr 1fr 1fr}}
.site-footer ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
.footer-bottom{margin-top:34px;padding-top:20px;border-top:1px solid var(--line-dk);
  display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;font-size:.82rem;color:var(--gi-3)}

/* ============================================================
   Legacy homepage components, restyled for the night theme.
   These class names come from the original site and carry its
   copy, so they are covered here rather than rewritten.
   ============================================================ */
.main-nav{display:none;gap:24px}
@media(min-width:900px){.main-nav{display:flex}}
.header-sep{width:1px;height:20px;background:var(--line-dk)}
/* GRID, NOT FLEX. Three pill buttons in a row are 66px of text each at 375px,
   so "Find Staff" wrapped to two lines inside its own pill — 73px tall against
   a 48px min-height. The drawer only ever exists below 900px, where a stacked
   full-width button is the pattern anyway and cannot wrap. */
.drawer-ctas{display:grid;gap:10px;padding:12px 2px 0}
.hero-grid{display:grid;gap:34px;grid-template-columns:1fr;align-items:center}
@media(min-width:960px){.hero-grid{grid-template-columns:1.05fr .95fr}}
.live-pill{display:inline-flex;align-items:center;gap:7px;font-family:var(--mono);font-size:.66rem;
  font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--acc);
  border:1px solid rgba(61,219,164,.3);border-radius:99px;padding:5px 12px}
.live-dot{width:6px;height:6px;border-radius:50%;background:var(--acc);flex:none}

/* the product-as-hero dashboard */
.dash{border:1px solid var(--line-dk);border-radius:16px;background:rgba(12,17,23,.74);
  backdrop-filter:blur(16px);overflow:hidden}
.dash-head{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:15px 18px;border-bottom:1px solid var(--line-dk);flex-wrap:wrap}
.dash-title{font-weight:700;font-size:.96rem;color:var(--gi)}
.dash-sub{font-size:.78rem;color:var(--gi-2)}
.dash-body{padding:18px;display:flex;flex-direction:column;gap:16px}
.readiness-row{display:flex;align-items:center;gap:16px}
.readiness-score{font-family:var(--mono);font-size:3rem;font-weight:700;letter-spacing:-.04em;
  line-height:1;color:var(--acc);font-variant-numeric:tabular-nums}
.readiness-meta strong{display:block;color:var(--gi);font-size:.9rem}
.readiness-meta span{font-size:.8rem;color:var(--gi-2)}
.stat-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px;
  padding-top:14px;border-top:1px solid var(--line-dk)}
@media(min-width:520px){.stat-grid{grid-template-columns:repeat(4,1fr)}}
.stat-grid .stat strong,.stat-grid .stat b{font-size:1.35rem;color:var(--gi)}
.stat-grid .stat span{color:var(--gi-2);font-size:.76rem}
.accent{color:var(--acc)}
.warn{color:var(--warn)}
.bar-row{display:flex;align-items:center;gap:10px;font-size:.78rem;color:var(--gi-2)}
.zone{min-width:104px;color:var(--gi)}
.bar{flex:1;height:6px;border-radius:99px;background:rgba(255,255,255,.1);overflow:hidden}
.bar>span,.bar>i{display:block;height:100%;background:var(--acc);border-radius:99px}
.bar-row .warn~.bar>span,.bar.warn>span{background:var(--warn)}
.pct{font-family:var(--mono);font-variant-numeric:tabular-nums;min-width:38px;text-align:right;color:var(--gi)}
.dash-alert{display:flex;gap:10px;align-items:flex-start;padding:11px 13px;border-radius:10px;
  background:rgba(255,190,61,.1);border:1px solid rgba(255,190,61,.28);font-size:.8rem;color:var(--gi)}
.dash-label{font-family:var(--mono);font-size:.62rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--gi-3)}
/* The caption that says a card is illustrative ran edge to edge and clipped its
   own first and last letters, at the tightest tracking on the page. It is a
   disclaimer: it has to be readable or it is not a disclaimer. Padding, room to
   wrap, and lighter ink than gi-3 because it sits on the DARKEST surface here. */
.dash .dash-label,.dash-foot,.dash > .dash-label{display:block;padding:10px 18px 14px;
  line-height:1.5;white-space:normal;overflow-wrap:anywhere;color:var(--gi-4)}
.dash-table{width:100%;font-size:.8rem}
.dash-table th,.dash-table td{border-bottom-color:var(--line-dk);color:var(--gi-2);padding:8px 10px}
.dash-table td b,.dash-table td strong{color:var(--gi)}
.flow{display:flex;flex-direction:column}
.rev{direction:rtl}.rev>*{direction:ltr}
@media(max-width:899px){.rev{direction:ltr}}
.mt-4{margin-top:2.2rem}
.testimonial{background:var(--card);border:1px solid var(--line);border-radius:var(--r);padding:28px 26px}
.band-dark .testimonial{background:var(--night-2);border-color:var(--line-dk)}
.attrib{display:flex;align-items:center;gap:12px;margin-top:16px;font-size:.86rem;color:var(--ink-2)}
.band-dark .attrib{color:var(--gi-2)}
.avatar{width:38px;height:38px;border-radius:50%;background:var(--paper-2);flex:none;
  display:grid;place-items:center;font-weight:700;color:var(--ink-3);font-size:.8rem}
.band-dark .avatar{background:var(--night-3);color:var(--gi-3)}
.placeholder-note{font-family:var(--mono);font-size:.66rem;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-3);border:1px dashed var(--line);border-radius:8px;padding:10px 12px;display:inline-block}
.band-dark .placeholder-note{color:var(--gi-3);border-color:var(--line-dk)}
.tri-cta{display:grid;gap:16px;grid-template-columns:1fr}
@media(min-width:820px){.tri-cta{grid-template-columns:repeat(3,1fr)}}
.footer-brand{max-width:34ch}
.footer-brand p{color:var(--gi-2)}

/* ---------- auth pages: the five classes login.html asks for ----------
   login.html and the signup pages paint themselves on --night via
   .auth-page, but every one of .auth-wrap, .form-card, .form-grid,
   .auth-switch and .route-choice styled NOTHING, and .field/.kicker/.lead
   are written for LIGHT surfaces. The result was near-black ink on a
   near-black ground: the page rendered, and could not be read. */
.auth-wrap{width:100%;max-width:460px;display:flex;flex-direction:column;gap:22px}
.auth-wrap .kicker{color:var(--acc)}
.auth-wrap h1,.auth-wrap h2,.auth-wrap h3{color:var(--gi)}
.auth-wrap .lead,.auth-wrap p{color:var(--gi-2)}
.auth-wrap .small{color:var(--gi-3)}

.form-card{background:var(--night-2);border:1px solid var(--line-dk);border-radius:var(--r);
  padding:26px 24px}
.form-grid{display:grid;gap:0}
.form-card .field:last-of-type{margin-bottom:0}
.form-card label{color:var(--gi)}
.form-card input,.form-card select,.form-card textarea{
  background:var(--night-3);border-color:var(--line-dk);color:var(--gi)}
.form-card input::placeholder{color:var(--gi-3)}
.form-card input:focus,.form-card select:focus,.form-card textarea:focus{
  outline:2px solid var(--acc);outline-offset:1px}
.form-card .form-error:empty{display:none}
.form-card .form-error{margin-top:10px}

.auth-switch{text-align:center;color:var(--gi-2);font-size:.9rem;margin:0}
.route-choice{display:grid;gap:12px;grid-template-columns:1fr}
@media(min-width:560px){.route-choice{grid-template-columns:1fr 1fr}}
.route-choice .card{background:var(--night-2);border:1px solid var(--line-dk);height:100%;
  transition:border-color .18s ease,transform .18s ease}
.route-choice .card h3{color:var(--gi)}
.route-choice .card p{color:var(--gi-2)}
.route-choice a.card:hover,.route-choice a.card:focus-visible{
  border-color:var(--acc);transform:translateY(-2px)}
.auth-page{grid-template-rows:auto 1fr;align-content:stretch;padding:0 20px 40px}
.auth-page .site-header{align-self:start;width:100%}
.auth-page .auth-wrap{align-self:center;justify-self:center;padding:40px 0}

/* ---------- motion ----------
   Two moments only, both tied to meaning: a readiness bar draws itself to
   the width it is claiming, and the live marker breathes so a projected
   console reads as live rather than frozen. Everything else stays still. */
@keyframes bar-draw{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes live-breathe{
  0%,100%{opacity:1;box-shadow:0 0 0 0 rgba(61,219,164,.55)}
  50%{opacity:.55;box-shadow:0 0 0 5px rgba(61,219,164,0)}
}
.bar>span,.bar>i{transform-origin:left center;animation:bar-draw .9s cubic-bezier(.22,.61,.36,1) both}
.bar-row:nth-child(2) .bar>i{animation-delay:.08s}
.bar-row:nth-child(3) .bar>i{animation-delay:.16s}
.bar-row:nth-child(4) .bar>i{animation-delay:.24s}
.live-dot{animation:live-breathe 2.4s ease-in-out infinite}
.readiness-score{animation:bar-draw .6s ease-out both}

@media (prefers-reduced-motion: reduce){
  .bar>span,.bar>i,.live-dot,.readiness-score{animation:none}
  .route-choice a.card:hover,.route-choice a.card:focus-visible{transform:none}
}

/* The auth header at 360px: two full-size CTAs and a wordmark do not fit, so
   the button wrapped into a circle. On a sign-in page the second CTA is the
   one thing already offered twice below, in the route cards — so it steps
   aside rather than being squeezed. */
@media (max-width:560px){
  .auth-page .site-header .btn{white-space:nowrap;padding-inline:14px;font-size:.78rem}
  /* WAS KEYED ON THE HREF — a[href="signup-worker.html"] — and rewriting the
     site's links to the extensionless form silently stopped it matching. Every
     class in that selector still resolved, so the static battery stayed green;
     the rendered gallery caught the overflow.
     Naming the URL was the real mistake, not the spelling of it. The rule wants
     "the secondary offer steps aside", and the secondary offer is a DIFFERENT
     url on each of the three auth pages — which is why signup-worker, whose
     header CTA is /signup-business, was never covered by it at all and
     overflowed 375px on its own. Keyed on the button's role it covers all
     three, and it cannot rot when a URL changes. */
  .auth-page .header-ctas .btn-secondary{display:none}
}

/* ---------- consent rows ----------
   `.consent` was display:flex over a <label> whose content is an <input>, bare
   TEXT NODES and two <a> elements. Flex makes every one of those a separate
   item, so "I accept the / privacy policy / and / terms / ." rendered as five
   columns of stacked words. It was not a wrapping bug; the sentence had been
   taken apart. Ten pages carried it.

   Block flow puts the sentence back together and the checkbox is pinned into
   the indent, so the hanging shape survives without splitting the text. */
.consent{display:block;position:relative;padding-left:30px;padding-right:0}
.consent input{position:absolute;left:0;top:.25em;margin:0;flex:none}
.consent a{white-space:nowrap}

/* ---------- .dash is a dark surface on a light page ----------
   The console mock paints itself dark, but only .dash-title and .dash-sub were
   given dark-surface ink. Everything else inside it — a .stat caption, a
   .check-list item, an ordinary paragraph — kept the LIGHT page's near-black,
   so the venue line and all three checklist items were invisible on the very
   card that exists to be read. Same shape as the login page: a dark container
   whose contents were never told. */
.dash .stat span,.dash .stat small{color:var(--gi-2)}
.dash .stat b,.dash .stat strong{color:var(--gi)}
.dash .check-list li{color:var(--gi-2)}
.dash p,.dash li,.dash td,.dash th{color:var(--gi-2)}
.dash h1,.dash h2,.dash h3,.dash h4,.dash b,.dash strong{color:var(--gi)}
.dash .small,.dash .microcopy{color:var(--gi-3)}

/* A grid or flex item's default minimum size is its CONTENT, not zero — so a
   wide child stretches the track it sits in rather than being clamped by it,
   and `max-width:100%` then resolves against the stretched track and clamps
   nothing. `resize:vertical` already stops the drag that caused this, but the
   floor is what makes the card structurally unable to be pushed open. */
.form-grid,.form-card,.field{min-width:0}
.field>input,.field>select,.field>textarea{min-width:0}

/* ---------- the accent was chosen for the console and reused on paper ----------
   Every value below was MEASURED on the live pages, not guessed, and each one
   is the same mistake in a different place: an ink picked against the dark
   Control Room, then used on a light card or a dark card that never got the
   dark-surface treatment.

   .card-icon — the step numbers 01 / 02 / 03 — was --acc on WHITE: 1.77:1.
   A number nobody can read is not a step marker. 6.62 now.                     */
.card-icon{color:var(--acc-on-light)}
.band-dark .card-icon{color:var(--acc)}

/* Status tags inside a console mock kept the light-page inks — "Confirmed",
   "Live" and "Action needed" at 3.59 and 3.75 on the dark card they sit on.
   The same tags elsewhere on the card already use the console inks; these had
   simply never been told which surface they were on.                          */
.dash .tag-ok,.dash .tag-live{color:var(--acc)}
.dash .tag-warn{color:var(--warn)}

/* A form card is a dark surface, and three things inside it were still using
   light-page ink. The worst was .form-note at 1.04:1 — the sentence under the
   submit button telling somebody what happens after they press it, invisible
   on six pages.                                                               */
.form-card .hint,.form-card small,.form-card .field small{color:var(--gi-3)}
.form-card .form-note,.form-card .microcopy,.form-card p{color:var(--gi-2)}

/* --brick is the link colour and it is a LIGHT-surface colour: 3.52:1 on the
   card ground. Every "privacy policy" and "terms" link in a consent row was
   below AA. Lighter brick on dark surfaces only — the light pages keep theirs,
   where it measures 4.98.                                                     */
.form-card a,.consent a,.auth-wrap a,.dash a,.band-dark a{color:var(--brick-on-dark)}
.form-card a:hover,.consent a:hover,.auth-wrap a:hover,.band-dark a:hover{color:var(--brick-on-dark-hover)}


/* ---------- rules recovered from css/styles.css, 18 August ----------
   That stylesheet was linked by NO page, so every class in it styled nothing —
   .notice, .prose, .page-hero, .badge, .tabs, .accordion and the two dashboard
   shells, 41 uses across fourteen pages. Deleting the orphan file is what made
   them visible: the audit had been counting its definitions as if pages loaded
   it, which is the very defect the audit exists to catch, living inside the
   check.

   The rules below are the ones those classes needed, translated out of the old
   sheet's token vocabulary into the one the live sheets define. A rule that
   references a token nobody declares resolves to nothing, which would have left
   the classes exactly as unstyled as before. */
.page-hero{padding: 58px 0 50px;
  background:
    radial-gradient(900px 420px at 90% -20%, rgba(143, 91, 59, 0.08), transparent 60%),
    var(--paper-2);
  border-bottom: 1px solid var(--line);}
.tabs{border-bottom: 1px solid var(--line); display: flex; gap: 4px; overflow-x: auto;}
.tabs button{background: none; border: none; border-bottom: 2px solid transparent;
  color: var(--ink-3); font: inherit; font-weight: 600; font-size: 0.95rem;
  padding: 12px 16px; cursor: pointer; white-space: nowrap;}
/* THE SELECTED TAB WAS --acc ON PAPER: 1.64:1, the same pair and the same
   number as the focus ring fixed on 19 August, in the one control on this page
   that switches the content. Nothing saw it because the gallery's contrast walk
   listed p, li, span, td, a ... and not BUTTON, so every button on the site was
   outside the measurement. --acc-on-light is 6.62 here.
   The RING is offset INWARD because .tabs is an overflow-x:auto scroll strip:
   an outline drawn 3px outside a tab flush against that container is cropped on
   three sides and a keyboard user sees nothing. Contrast was never the problem
   there; the clip was. */
.tabs button[aria-selected="true"]{color: var(--acc-on-light); border-bottom-color: var(--acc-on-light);}
.tabs button:focus-visible{outline-offset: -3px;}
.tab-panel{padding-top: 34px;}
.tab-panel[hidden]{display: none;}
.accordion{border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--card);}
.accordion details{border-bottom: 1px solid var(--line); background: var(--card);}
.accordion details:last-child{border-bottom: none;}
.accordion summary{cursor: pointer; list-style: none; padding: 18px 20px; font-weight: 600;
  display: flex; justify-content: space-between; align-items: center; gap: 14px;}
.accordion summary::-webkit-details-marker{display: none;}
.accordion summary::after{content: "+"; color: var(--acc); font-size: 1.3rem; font-weight: 400; flex: none;}
.accordion details[open] summary::after{content: "–";}
.accordion .a-body{padding: 0 20px 18px; color: var(--ink-2); font-size: 0.94rem;}
.badge-row{display: flex; flex-wrap: wrap; gap: 10px; margin-top: 20px;}
.badge{font-size: 0.78rem; font-weight: 600; color: var(--ink-2);
  border: 1px solid var(--line); border-radius: 999px; padding: 6px 14px;
  background: var(--card);}
.notice{background: var(--amber-tint); border: 1px solid rgba(187, 122, 40, 0.28); border-left: 3px solid var(--amber);
  border-radius: var(--radius-sm); padding: 14px 18px; font-size: 0.9rem; color: var(--ink-2);}
.mb-0{margin-bottom: 0;}
.dash-page{padding: 40px 0 80px;}
.dash-page .dash{font-size: 0.9rem;}
.dash-topbar{display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 26px;}
.prose{max-width: 760px;}
.prose h2{font-size: 1.35rem; margin-top: 2em;}
.prose p, .prose li{color: var(--ink-2);}

/* ---------- two the gallery found that no static read could ----------

   1. A REGRESSION I INTRODUCED TODAY. The dark-surface link colour was applied
      to `a` inside .band-dark, and a BUTTON is an anchor: "See the agency
      platform" became brick-on-dark ink sitting on the green accent fill,
      1.91:1. A button carries its own ink and must be excluded from any rule
      about link colour. */
.form-card a.btn,.consent a.btn,.auth-wrap a.btn,.dash a.btn,.band-dark a.btn{color:var(--acc-ink)}
.band-dark a.btn-secondary,.dash a.btn-secondary{color:var(--gi)}

/* 2. .dash WAS SEMI-TRANSPARENT — rgba(12,17,23,.74) — so on a LIGHT band it
      composites to a mid grey rather than the near-black its inks were chosen
      against, and --gi-2 landed at 3.29:1 on the very card that shows a worker
      their next shift. The card is a console: it is opaque now, and its inks
      mean what they say wherever it sits. */
.dash{background:var(--night-2)}

/* ---------- the hamburger was outside the window ----------
   At 375 the header showed BOTH the desktop CTAs and the mobile toggle, so the
   toggle was pushed to x=365..401 in a 375px viewport and seven pages scrolled
   sideways. Found by the gallery at the mobile breakpoint; the desktop pass was
   clean, which is the whole reason the gallery measures both.

   Scoped with :has(.nav-toggle) so it only applies to headers that HAVE a
   mobile menu to fall back to — the auth pages have no toggle and keep their
   single CTA, which is the only way in on a sign-in page. */
@media (max-width:899px){
  .site-header:has(.nav-toggle) .header-ctas{display:none}
}
