/* LicensePath marketing site
   Palette: deep navy + warm brass on an ivory paper ground — a credentialing,
   "official seal" feel distinct from the app's own in-product teal/amber system. */

:root {
  --paper: #faf6ec;
  --surface: #ffffff;
  --surface-2: #f2e9d8;
  --ink: #14182b;
  --ink-muted: #4f5573;
  --ink-faint: #8b8fa8;
  --navy: #1c2b57;
  --navy-soft: #e7ebf5;
  --navy-ink: #101c3d;
  --brass: #ad7c2c;
  --brass-soft: #f7ead0;
  --brass-ink: #7c5a1e;
  --emerald: #1f6b52;
  --emerald-soft: #e2f0ea;
  --red: #a63a3a;
  --red-soft: #f7e6e6;
  --border: #e2d9c4;
  --border-soft: #ece4d3;
  --shadow: 0 1px 2px rgba(20, 24, 43, 0.05), 0 6px 20px rgba(20, 24, 43, 0.06);
  --shadow-lg: 0 8px 24px rgba(20, 24, 43, 0.10), 0 24px 60px rgba(20, 24, 43, 0.12);
  /* Fixed-dark accent band — intentionally does NOT flip with theme (--navy/--navy-ink
     do, since they double as light-mode accent-on-paper colors elsewhere). Used for the
     stat band and email-capture band, which are meant to read as a dark contrast strip
     in both themes, not as a surface that follows the page's own light/dark state.
     Also reused anywhere else a solid navy fill needs light text/icons on top regardless
     of theme (status banner, primary button, logo mark, feature-icon hover) — those broke
     in dark mode when they filled with var(--navy)/var(--navy-ink), which flip to light
     accent colors in dark mode and are only safe to use as foreground ink, not as a solid
     background meant to stay dark. --band-brass is the amber that pairs with --band-bg;
     it's fixed for the same reason --band-ink is. */
  --band-bg: #14203f;
  --band-ink: #eef1fb;
  --band-brass: #f2d29a;
  /* Tells the browser which native-control chrome (checkbox/select-popup/
     scrollbar) to draw. Without this, a checkbox in the dark-mode agency/
     launch-updates forms rendered as an unstyled solid white square instead
     of a dark-appropriate control - Chromium's per-control dark inference
     doesn't reliably catch every element. Set on :root so it always matches
     the same prefers-color-scheme logic the custom tokens above follow; the
     [data-theme] overrides below keep it in sync if a manual toggle is ever
     wired up on any page sharing this stylesheet. */
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #0d1120; --surface: #151a2e; --surface-2: #1b2238;
    --ink: #efeade; --ink-muted: #aab0cc; --ink-faint: #6f7592;
    --navy: #8ea1e0; --navy-soft: rgba(142, 161, 224, 0.14); --navy-ink: #c3d0f5;
    --brass: #e6bd6f; --brass-soft: rgba(230, 189, 111, 0.14); --brass-ink: #f2d29a;
    --emerald: #57c39c; --emerald-soft: rgba(87, 195, 156, 0.14);
    --red: #e08484; --red-soft: rgba(224, 132, 132, 0.14);
    --border: #2a3151; --border-soft: #202641;
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 10px 30px rgba(0, 0, 0, 0.3);
    --shadow-lg: 0 12px 30px rgba(0, 0, 0, 0.35), 0 30px 70px rgba(0, 0, 0, 0.4);
    color-scheme: dark;
  }
}
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] {
  --paper: #0d1120; --surface: #151a2e; --surface-2: #1b2238;
  --ink: #efeade; --ink-muted: #aab0cc; --ink-faint: #6f7592;
  --navy: #8ea1e0; --navy-soft: rgba(142, 161, 224, 0.14); --navy-ink: #c3d0f5;
  --brass: #e6bd6f; --brass-soft: rgba(230, 189, 111, 0.14); --brass-ink: #f2d29a;
  --emerald: #57c39c; --emerald-soft: rgba(87, 195, 156, 0.14);
  --red: #e08484; --red-soft: rgba(224, 132, 132, 0.14);
  --border: #2a3151; --border-soft: #202641;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 10px 30px rgba(0, 0, 0, 0.3);
  --shadow-lg: 0 12px 30px rgba(0, 0, 0, 0.35), 0 30px 70px rgba(0, 0, 0, 0.4);
  color-scheme: dark;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; }

/* Branded keyboard-focus ring. Only fires for keyboard/programmatic focus
   (:focus-visible), never on mouse click, so it adds polish without adding
   noise. Form fields keep their own dedicated focus treatment below (more
   specific selector, so it wins there); this covers every other interactive
   element that previously fell back to the bare UA outline. */
a:focus-visible,
button:focus-visible,
.btn:focus-visible,
.faq-q:focus-visible,
.state-chip:focus-visible {
  outline: 2px solid var(--brass-ink);
  outline-offset: 3px;
  border-radius: 4px;
}
.wrap { max-width: 1180px; margin: 0 auto; padding: 0 24px; }
.wrap-narrow { max-width: 860px; margin: 0 auto; padding: 0 24px; }

h1, h2, h3, h4 {
  font-family: "Newsreader", Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 500;
  letter-spacing: -0.008em;
  line-height: 1.2;
  margin: 0 0 12px;
  color: var(--ink);
  text-wrap: balance;
}
/* Base type scale — a real fallback size per level, not just "whatever the UA
   default is." Anything more specific (.hero h1, .section-head h2, .feature-card
   h3, .how-subhead) overrides this by selector specificity; this exists so a
   bare heading with no wrapper class (e.g. the "who this is for" h2) still lands
   on-scale instead of falling back to the browser's default serif size. */
h1 { font-size: clamp(32px, 4.2vw, 44px); line-height: 1.14; }
h2 { font-size: clamp(27px, 3.2vw, 34px); line-height: 1.18; }
h3 { font-size: 19px; line-height: 1.3; }
h4 { font-size: 16px; line-height: 1.35; }
p { line-height: 1.65; color: var(--ink-muted); margin: 0 0 14px; }
.eyebrow {
  font-size: 12px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--brass-ink); margin: 0 0 12px; display: block;
}

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: "Inter", sans-serif; font-weight: 600; font-size: 14.5px;
  padding: 12px 22px; border-radius: 8px; border: 1px solid transparent;
  cursor: pointer; text-decoration: none;
  transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.12s ease, border-color 0.12s ease;
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
/* Both on-page forms ship with their submit button intentionally disabled
   until a real backend is wired up (see the maintainer comments in
   index.html). Without this, a disabled <button> inherited every active
   look - solid fill, hover lift, hover shimmer - so it read as clickable
   right up until a click did nothing. This mutes it and turns off every
   hover-triggered effect below, so "not yet available" is visible, not just
   implied by the tooltip. */
.btn:disabled, .btn[disabled] {
  opacity: 0.5; cursor: not-allowed; box-shadow: none;
}
.btn:disabled:hover, .btn[disabled]:hover {
  transform: none; box-shadow: none;
}
.btn:disabled::after, .btn[disabled]::after { display: none; }
.btn-primary, .btn-brass { position: relative; overflow: hidden; }
.btn-primary::after, .btn-brass::after {
  content: ""; position: absolute; top: 0; left: -60%; width: 40%; height: 100%;
  background: linear-gradient(120deg, transparent, rgba(255, 255, 255, 0.35), transparent);
  transform: skewX(-20deg); transition: left 0.55s ease;
}
.btn-primary:hover::after, .btn-brass:hover::after { left: 130%; }
.btn-primary { background: var(--band-bg); color: var(--band-ink); box-shadow: var(--shadow); }
.btn-primary:hover { background: color-mix(in srgb, var(--band-bg) 82%, black); box-shadow: var(--shadow-lg); transform: translateY(-1px); }
.btn-primary:focus-visible { box-shadow: var(--shadow-lg); }
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--border); }
.btn-ghost:hover {
  background: var(--surface-2); border-color: color-mix(in srgb, var(--navy) 30%, var(--border));
  transform: translateY(-1px); box-shadow: var(--shadow);
}
.btn-brass { background: var(--brass); color: #201404; }
/* Was: background var(--brass-ink), color #fff. --brass-ink flips direction with
   theme (dark brown in light mode, light amber in dark mode) — pairing it with
   fixed white text meant dark mode's hover state dropped to ~1.45:1 contrast.
   Brightening instead of swapping to brass-ink keeps the dark ink legible in
   both themes, since lightening a background can only raise contrast against
   near-black text, never lower it. */
.btn-brass:hover { background: color-mix(in srgb, var(--brass) 85%, white); color: #201404; box-shadow: var(--shadow); transform: translateY(-1px); }
.btn-block { width: 100%; }
.btn-sm { padding: 9px 16px; font-size: 13.5px; }

/* ---------- Header ---------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  /* Solid fallback first: if color-mix() is unsupported, this declaration is
     the only one the browser accepts, so the sticky header still has an
     opaque background instead of falling through to transparent (which
     would let page content scroll up directly underneath the nav links). */
  background: var(--paper);
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
  transition: box-shadow 0.25s ease;
}
.site-header.scrolled { box-shadow: var(--shadow); }
.site-header .wrap {
  display: flex; align-items: center; justify-content: space-between;
  height: 68px; gap: 20px;
}
.logo {
  display: flex; align-items: center; gap: 9px;
  font-family: "Newsreader", Georgia, serif; font-weight: 600; font-size: 19px;
  color: var(--ink); text-decoration: none; flex-shrink: 0;
}
.logo-mark {
  width: 30px; height: 30px; border-radius: 8px;
  overflow: hidden; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow);
}
/* The real app icon (design/app-icon/export/icon-512.png, same file wired into
   app.json's "icon" key) carries its own fixed teal/gold artwork and background -
   it's a fixed brand asset, not a themed UI surface, so it renders identically
   regardless of the site's light/dark state or navy/brass palette. */
.logo-mark img { width: 100%; height: 100%; object-fit: cover; display: block; }

.main-nav { display: flex; align-items: center; gap: 28px; flex: 1; justify-content: center; }
/* :not(.btn) throughout - .nav-cta-mobile below lives inside .main-nav for
   layout purposes (it only renders in the mobile dropdown) but needs to keep
   its own .btn/.btn-primary look. Without the exclusion, this selector's
   element-selector specificity (class+element) would beat a plain .btn-*
   class selector and silently override the button's color/size/weight back
   to a plain nav-link style. */
.main-nav a:not(.btn) {
  font-size: 14px; font-weight: 500; color: var(--ink-muted); text-decoration: none;
  transition: color 0.12s ease;
}
.main-nav a:not(.btn):hover { color: var(--ink); }
.nav-toggle {
  display: none; background: none; border: 1px solid var(--border); border-radius: 8px;
  width: 40px; height: 40px; align-items: center; justify-content: center; cursor: pointer;
  color: var(--ink); transition: background 0.15s ease, border-color 0.15s ease;
}
.nav-toggle:hover { background: var(--surface-2); border-color: color-mix(in srgb, var(--navy) 24%, var(--border)); }
/* Hamburger -> X morph. Each bar is its own <line> in the SVG (see index.html)
   so it can rotate/fade independently; .is-open is toggled by script.js
   alongside aria-expanded, so the icon itself confirms the open/closed state
   instead of relying on the dropdown's own appearance alone. Unguarded by
   prefers-reduced-motion to match this file's existing convention for
   discrete, user-triggered state changes (e.g. the .faq-q chevron below). */
.nt-line { transition: transform 0.22s ease, opacity 0.15s ease; transform-origin: 9px 9px; }
.nav-toggle.is-open .nt-line-1 { transform: translateY(4.5px) rotate(45deg); }
.nav-toggle.is-open .nt-line-2 { opacity: 0; }
.nav-toggle.is-open .nt-line-3 { transform: translateY(-4.5px) rotate(-45deg); }
.header-cta { flex-shrink: 0; }
.nav-cta-mobile { display: none; }

/* ---------- Status banner ---------- */
/* Uses the fixed --band-bg/--band-ink/--band-brass tokens (same family as the
   stat band and email-capture band below), not var(--navy-ink)/var(--paper).
   Those flip with theme — in dark mode --navy-ink becomes a LIGHT accent color
   (#c3d0f5), which turned this into near-white text on a near-white bar
   (~1.1:1 contrast, effectively invisible). The fixed band tokens keep this a
   dark navy strip with light text in both themes, matching the visual design
   intent (a persistent status strip, not a surface that should adapt). */
.status-banner {
  background: var(--band-bg); color: var(--band-ink);
}
.status-banner .wrap {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 6px 14px; padding: 10px 24px; text-align: center; font-size: 12.5px;
}
.status-banner strong {
  font-family: "IBM Plex Mono", monospace; font-weight: 600; letter-spacing: 0.04em;
  color: var(--band-brass); font-size: 11.5px;
}
.status-banner span.sep { color: color-mix(in srgb, var(--band-ink) 45%, transparent); }
.status-banner .msg { color: color-mix(in srgb, var(--band-ink) 85%, transparent); }

/* ---------- Hero ---------- */
.hero { padding: 76px 0 88px; position: relative; overflow: hidden; }
.hero::before {
  content: ""; position: absolute; top: -220px; right: -160px; width: 560px; height: 560px;
  border-radius: 50%; background: radial-gradient(circle, var(--brass-soft) 0%, transparent 70%);
  pointer-events: none; z-index: 0;
}
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: radial-gradient(circle, color-mix(in srgb, var(--navy) 16%, transparent) 1px, transparent 1.6px);
  background-size: 26px 26px;
  -webkit-mask-image: linear-gradient(180deg, black, transparent 82%);
  mask-image: linear-gradient(180deg, black, transparent 82%);
  opacity: 0.55;
}
@media (prefers-reduced-motion: no-preference) {
  .hero::before { animation: heroDrift 16s ease-in-out infinite alternate; }
}
@keyframes heroDrift {
  0% { transform: translate(0, 0) scale(1); }
  100% { transform: translate(-36px, 26px) scale(1.1); }
}
.hero .wrap {
  display: grid; grid-template-columns: 1.05fr 0.95fr; gap: 56px; align-items: center;
  position: relative; z-index: 1;
}
.hero h1 { font-size: clamp(34px, 4.6vw, 55px); line-height: 1.08; margin-bottom: 18px; }
.hero h1 em { font-style: italic; color: var(--brass-ink); }
.hero .dek { font-size: 17px; line-height: 1.65; color: var(--ink-muted); max-width: 52ch; margin-bottom: 26px; }
.hero-ctas { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 28px; }
.hero-proof {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 0; font-size: 13px; color: var(--ink-muted);
}
.hero-proof strong { font-family: "IBM Plex Mono", monospace; color: var(--navy-ink); font-weight: 600; }
/* The separator dot lives on ::before, glued to the stat text that follows
   it, rather than as its own flex item (previously a standalone .proof-sep
   span between each pair). A flex-wrap line break can only ever land between
   flex items, so a free-floating separator span could end up stranded alone
   at the end of a wrapped line on narrow viewports. Binding it to its
   following stat as one atomic inline unit means the break now always lands
   before a whole "dot + stat" group, never after an orphaned dot. */
.hero-proof .stat { display: inline-flex; align-items: center; }
.hero-proof .stat:not(:first-child)::before {
  content: ""; width: 3px; height: 3px; border-radius: 50%;
  background: var(--ink-faint); flex-shrink: 0; margin: 0 12px;
}

.snapshot-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 18px;
  padding: 26px; box-shadow: var(--shadow-lg);
}
.snapshot-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; }
.snapshot-title { font-size: 13px; font-weight: 600; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.06em; }
.snapshot-badge {
  font-family: "IBM Plex Mono", monospace; font-size: 11px; font-weight: 600;
  background: var(--brass-soft); color: var(--brass-ink); padding: 3px 9px; border-radius: 999px;
}
.snapshot-body { display: flex; align-items: center; gap: 24px; }
.donut { flex-shrink: 0; }
.donut circle { transition: stroke-dashoffset 1.15s cubic-bezier(0.16, 1, 0.3, 1) 0.2s; }
.donut.donut-pending circle:not(:first-child) { stroke-dashoffset: 289; }
.donut-figure { font-family: "IBM Plex Mono", monospace; font-size: 15px; font-weight: 600; fill: var(--ink); }
.snapshot-legend { list-style: none; margin: 0; padding: 0; flex: 1; }
.snapshot-legend li { display: flex; align-items: center; gap: 9px; font-size: 13px; color: var(--ink-muted); padding: 5px 0; }
.snapshot-legend .dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0; }
.dot-good { background: var(--navy); }
.dot-warn { background: var(--brass); }
.snapshot-caption {
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border-soft);
  font-size: 11.5px; color: var(--ink-faint); font-style: italic; margin-bottom: 0;
}

/* ---------- Section scaffolding ---------- */
section { padding: 88px 0; }
section.tight { padding: 64px 0; }
.section-head { max-width: 640px; margin-bottom: 44px; }
.section-head.center { margin-left: auto; margin-right: auto; text-align: center; }
.section-head h2 { font-size: clamp(26px, 3.4vw, 36px); }
.on-surface { background: var(--surface); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.on-surface-2 { background: var(--surface-2); }
/* Small print under a section's main content (currently the pricing
   disclaimer). Pulled out of an inline style on the <p> so it's a reusable,
   themeable rule instead of one-off hardcoded values. */
.section-note { text-align: center; font-size: 13px; color: var(--ink-faint); max-width: 640px; margin: 20px auto 0; }

/* ---------- Who this is for ---------- */
.who-body { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: start; }
.who-body p { font-size: 16px; color: var(--ink-muted); }
.who-body .lede { font-size: 19px; color: var(--ink); line-height: 1.5; }

/* ---------- How it works ---------- */
.how-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: start; }
.how-subhead { font-size: 15px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--ink-faint); margin-bottom: 16px; font-family: "Inter", sans-serif; font-weight: 600; }
.how-subnote { font-size: 13.5px; color: var(--ink-muted); margin: -4px 0 16px; }
.category-list { list-style: none; margin: 0; padding: 0; counter-reset: cat; }
.category-list li {
  counter-increment: cat; display: flex; align-items: baseline; gap: 14px;
  padding: 11px 0; border-bottom: 1px solid var(--border-soft); font-size: 14.5px; color: var(--ink);
}
.category-list li::before {
  content: counter(cat, decimal-leading-zero);
  font-family: "IBM Plex Mono", monospace; font-size: 12px; color: var(--brass-ink);
  font-weight: 600; flex-shrink: 0; width: 22px;
}
.process-list { list-style: none; margin: 0; padding: 0; }
.process-step { display: flex; gap: 16px; padding: 18px 0; border-bottom: 1px solid var(--border-soft); }
.process-step:last-child { border-bottom: none; }
.process-num {
  font-family: "IBM Plex Mono", monospace; font-weight: 600; font-size: 13px;
  color: var(--navy-ink); background: var(--navy-soft); border-radius: 8px;
  width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.process-title { font-weight: 600; font-size: 15px; color: var(--ink); margin-bottom: 3px; }
.process-detail { font-size: 13.5px; color: var(--ink-muted); margin: 0; line-height: 1.55; }

/* ---------- Stat band ---------- */
.stat-band { padding: 0; background: var(--band-bg); }
.stat-band-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  padding: 40px 24px;
}
.stat-band-item {
  text-align: center; padding: 0 16px; border-left: 1px solid rgba(255, 255, 255, 0.14);
  display: flex; flex-direction: column; gap: 6px;
}
.stat-band-item:first-child { border-left: none; }
.stat-band-figure {
  font-family: "IBM Plex Mono", monospace; font-weight: 600; font-size: clamp(24px, 3vw, 32px);
  color: var(--band-brass); letter-spacing: -0.01em;
}
.stat-band-label { font-size: 12.5px; color: rgba(255, 255, 255, 0.78); line-height: 1.4; }

/* ---------- Feature grid ---------- */
.feature-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.feature-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 14px;
  padding: 26px 24px; box-shadow: var(--shadow);
  transition: transform 0.22s ease, box-shadow 0.22s ease, border-color 0.22s ease;
}
.feature-card:hover {
  transform: translateY(-5px); box-shadow: var(--shadow-lg);
  border-color: color-mix(in srgb, var(--navy) 24%, var(--border));
}
.feature-icon {
  width: 40px; height: 40px; border-radius: 10px; background: var(--navy-soft);
  display: flex; align-items: center; justify-content: center; margin-bottom: 16px;
  color: var(--navy-ink); transition: background 0.22s ease, color 0.22s ease, transform 0.22s ease;
}
.feature-card:hover .feature-icon { background: var(--band-bg); color: var(--band-ink); transform: scale(1.08); }
.feature-card h3 { font-size: 16.5px; margin-bottom: 6px; }
.feature-card p { font-size: 13.5px; margin: 0; }

/* ---------- State coverage ---------- */
.states-lede { max-width: 660px; margin: -20px auto 36px; text-align: center; font-size: 15px; }
.state-grid { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.state-chip {
  display: flex; align-items: baseline; gap: 6px;
  font-family: "IBM Plex Mono", monospace; font-weight: 600; font-size: 14px; color: var(--navy-ink);
  background: var(--navy-soft); border: 1px solid color-mix(in srgb, var(--navy) 22%, var(--border));
  padding: 9px 14px; border-radius: 999px; text-decoration: none; transition: background 0.12s ease, transform 0.12s ease;
}
a.state-chip:hover { background: color-mix(in srgb, var(--navy) 14%, var(--navy-soft)); transform: translateY(-2px); box-shadow: var(--shadow); }
.state-chip em {
  font-style: normal; font-family: "Inter", sans-serif; font-weight: 500; font-size: 12.5px; color: var(--ink-muted);
}
.state-chip-more {
  color: var(--brass-ink); background: var(--brass-soft);
  border-color: color-mix(in srgb, var(--brass) 30%, var(--border));
  font-family: "Inter", sans-serif; font-weight: 600; font-size: 13px;
}

/* ---------- Content review ---------- */
.review-grid { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 56px; align-items: center; }
.stat-card-group { display: grid; grid-template-columns: 1fr; gap: 1px; background: var(--border); border: 1px solid var(--border); border-radius: 16px; overflow: hidden; box-shadow: var(--shadow); }
.stat-card { background: var(--surface); padding: 22px 24px; display: flex; align-items: baseline; justify-content: space-between; gap: 16px; transition: background 0.2s ease; }
.stat-card:hover { background: var(--surface-2); }
.stat-card .n { font-family: "IBM Plex Mono", monospace; font-size: 26px; font-weight: 600; color: var(--ink); white-space: nowrap; }
.stat-card .l { font-size: 13px; color: var(--ink-muted); text-align: right; }
.stat-card.pending .n { color: var(--brass-ink); }
.source-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.source-tag {
  font-size: 12px; font-weight: 500; color: var(--ink-muted); background: var(--surface-2);
  border: 1px solid var(--border); padding: 5px 12px; border-radius: 999px;
}

/* ---------- Pricing ---------- */
.pricing-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; max-width: 780px; margin: 0 auto; }
/* minmax(0, 1fr), not a bare 1fr: a bare 1fr track's implicit minimum is
   "auto", which is its content's min-content size. Every card holds a
   full-width .btn (white-space: nowrap, per the base .btn rule) whose own
   unbreakable label is wider than a fair quarter-share of the grid in the
   ~981-1050px tablet band, just above the 980px breakpoint that collapses
   this to two columns - so the four tracks refused to shrink that far and
   pushed the grid past the viewport, causing real horizontal page scroll
   at those widths. minmax(0, 1fr) lets a track shrink past its content's
   natural minimum (wrapping the button label onto two lines there instead)
   rather than blowing out the layout. */
.pricing-grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); max-width: 1100px; gap: 20px; align-items: stretch; }
.pricing-grid-4 .price-card { display: flex; flex-direction: column; }
.pricing-grid-4 .price-features { flex: 1; }
.price-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 16px;
  padding: 30px 28px; box-shadow: var(--shadow); position: relative;
  transition: transform 0.22s ease, box-shadow 0.22s ease;
}
.price-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.price-card.featured { border-color: var(--navy); box-shadow: var(--shadow-lg); }
@media (prefers-reduced-motion: no-preference) {
  .price-card.featured { animation: featuredGlow 4.5s ease-in-out infinite; }
}
@keyframes featuredGlow {
  0%, 100% { box-shadow: var(--shadow-lg); }
  50% { box-shadow: 0 10px 30px color-mix(in srgb, var(--brass) 25%, transparent), var(--shadow-lg); }
}
.price-badge {
  position: absolute; top: -13px; right: 24px; background: var(--brass); color: #201404;
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em; padding: 5px 12px; border-radius: 999px;
}
.price-tier { font-size: 13px; font-weight: 600; color: var(--ink-faint); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 10px; }
.price-amount { font-family: "Newsreader", Georgia, serif; font-size: 40px; font-weight: 500; color: var(--ink); margin-bottom: 4px; }
.price-amount small { font-family: "Inter", sans-serif; font-size: 14px; font-weight: 500; color: var(--ink-faint); white-space: nowrap; }
.price-note { font-size: 12.5px; color: var(--ink-faint); margin-bottom: 22px; }
.price-features { list-style: none; margin: 0 0 24px; padding: 0; }
.price-features li { display: flex; gap: 10px; align-items: flex-start; padding: 8px 0; font-size: 14px; color: var(--ink); }
.price-features li svg { flex-shrink: 0; margin-top: 3px; color: var(--navy); }

/* ---------- FAQ ---------- */
.faq-list { max-width: 760px; margin: 0 auto; }
.faq-item { border-bottom: 1px solid var(--border); }
.faq-item:first-child { border-top: 1px solid var(--border); }
.faq-q {
  width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 20px 4px; font-family: "Newsreader", Georgia, serif; font-size: 16.5px; font-weight: 500;
  color: var(--ink); transition: color 0.15s ease;
}
/* Was previously unstyled on hover - the pointer cursor was the only hint
   these rows were interactive. A subtle color shift (skipped once a row is
   already open, since its answer is the more relevant "active" signal at
   that point) brings it in line with every other clickable element on the
   page having a considered hover state. */
.faq-item:not([open]) .faq-q:hover { color: var(--brass-ink); }
.faq-item:not([open]) .faq-q:hover .chev { color: var(--brass-ink); }
.faq-q .chev { flex-shrink: 0; transition: transform 0.18s ease, color 0.15s ease; color: var(--ink-faint); }
.faq-item[open] .faq-q .chev { transform: rotate(180deg); }
.faq-a { padding: 0 4px 20px; margin: 0; font-size: 14.5px; max-width: 68ch; }
.inline-link {
  color: var(--navy-ink); text-decoration: underline;
  text-underline-offset: 3px; text-decoration-thickness: 1px;
  text-decoration-color: color-mix(in srgb, var(--navy-ink) 40%, transparent);
  transition: text-decoration-color 0.15s ease;
}
.inline-link:hover { text-decoration-color: currentColor; }

/* ---------- Agencies form ---------- */
.split-panel { display: grid; grid-template-columns: 0.85fr 1.15fr; gap: 56px; align-items: start; }
.form-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: 16px;
  padding: 30px; box-shadow: var(--shadow);
}
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 14px; }
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; }
.field label { font-size: 12.5px; font-weight: 600; color: var(--ink-muted); }
.field input, .field select, .field textarea {
  font-family: inherit; font-size: 14px; padding: 11px 13px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--paper); color: var(--ink); width: 100%;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: 2px solid var(--navy); outline-offset: 1px; border-color: var(--navy);
}
.field textarea { resize: vertical; min-height: 92px; font-family: inherit; }
.checkbox-row { display: flex; align-items: flex-start; gap: 9px; margin-bottom: 18px; }
.checkbox-row input { margin-top: 3px; }
.checkbox-row label { font-size: 13px; color: var(--ink-muted); }
.form-note { font-size: 11.5px; color: var(--ink-faint); margin-top: 12px; margin-bottom: 0; }

/* ---------- Email capture ---------- */
.capture-section { background: var(--band-bg); color: var(--band-ink); }
.capture-section .section-head h2 { color: var(--band-ink); }
.capture-section .section-head p { color: rgba(238, 241, 251, 0.72); }
.capture-section .section-head .eyebrow { color: var(--band-brass); }
.capture-card {
  background: var(--surface); color: var(--ink); border-radius: 18px; padding: 36px;
  max-width: 560px; margin: 0 auto; box-shadow: var(--shadow-lg);
}
.capture-card .field input, .capture-card .field select { background: var(--paper); }

/* ---------- Footer ---------- */
.site-footer { padding: 56px 0 40px; border-top: 1px solid var(--border); }
.footer-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 40px; flex-wrap: wrap; margin-bottom: 32px; }
.footer-nav { display: flex; gap: 24px; flex-wrap: wrap; }
.footer-nav a { font-size: 13.5px; color: var(--ink-muted); text-decoration: none; }
.footer-nav a:hover { color: var(--ink); }
.footer-legal { font-size: 12px; line-height: 1.7; color: var(--ink-faint); max-width: 820px; }
.footer-bottom { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-top: 24px; font-size: 12px; color: var(--ink-faint); }

/* ---------- Scroll reveal ----------
   Progressive enhancement only: the hidden (opacity:0) state is scoped under
   .js-reveal, a class script.js adds to <html> itself right before it starts
   observing elements. Without JS (or with prefers-reduced-motion: reduce),
   .js-reveal is never added, so .reveal/.reveal-stagger/.section-head content
   is never hidden in the first place - nothing to "fall back" to. */
@media (prefers-reduced-motion: no-preference) {
  .reveal, .reveal-stagger > *, .section-head {
    transition: opacity 0.7s cubic-bezier(0.16, 1, 0.3, 1), transform 0.7s cubic-bezier(0.16, 1, 0.3, 1);
  }
  .js-reveal .reveal:not(.is-visible),
  .js-reveal .section-head:not(.is-visible) {
    opacity: 0; transform: translateY(22px);
  }
  .js-reveal .reveal-stagger:not(.is-visible) > * {
    opacity: 0; transform: translateY(18px);
  }
  .reveal-d1.is-visible { transition-delay: 0.12s; }
  .reveal-stagger.is-visible > *:nth-child(1) { transition-delay: 0.02s; }
  .reveal-stagger.is-visible > *:nth-child(2) { transition-delay: 0.08s; }
  .reveal-stagger.is-visible > *:nth-child(3) { transition-delay: 0.14s; }
  .reveal-stagger.is-visible > *:nth-child(4) { transition-delay: 0.20s; }
  .reveal-stagger.is-visible > *:nth-child(5) { transition-delay: 0.26s; }
  .reveal-stagger.is-visible > *:nth-child(6) { transition-delay: 0.32s; }
  .reveal-stagger.is-visible > *:nth-child(7) { transition-delay: 0.38s; }
  .reveal-stagger.is-visible > *:nth-child(8) { transition-delay: 0.44s; }
  .reveal-stagger.is-visible > *:nth-child(9) { transition-delay: 0.50s; }
  .reveal-stagger.is-visible > *:nth-child(10) { transition-delay: 0.56s; }
  .reveal-stagger.is-visible > *:nth-child(n+11) { transition-delay: 0.6s; }
}

/* ---------- Responsive ---------- */
/* Mobile nav dropdown polish. .nav-open is toggled by script.js (see the
   click handler's inline nav.style.* block) — this only styles the links
   inside it once open, it doesn't change how/when the dropdown appears.
   :not(.btn) excludes .nav-cta-mobile, which keeps its own pill-button
   sizing/padding instead of being stretched into a full-width divided row
   like the plain text links above it. */
.main-nav.nav-open a:not(.btn) {
  width: 100%; padding: 11px 2px; border-bottom: 1px solid var(--border-soft);
}

@media (max-width: 980px) {
  .hero .wrap { grid-template-columns: 1fr; }
  .who-body, .how-grid, .review-grid, .split-panel { grid-template-columns: 1fr; }
  .feature-grid { grid-template-columns: repeat(2, 1fr); }
  .pricing-grid-4 { grid-template-columns: repeat(2, 1fr); }
  .main-nav { display: none; }
  .nav-cta-mobile { display: inline-flex; margin-top: 4px; align-self: flex-start; }
  .stat-band-grid { grid-template-columns: repeat(2, 1fr); row-gap: 28px; }
  .stat-band-item:nth-child(3) { border-left: none; }
}
@media (max-width: 560px) {
  .header-cta { display: none; }
}
@media (max-width: 640px) {
  section { padding: 56px 0; }
  .hero { padding: 44px 0 56px; }
  .feature-grid { grid-template-columns: 1fr; }
  .pricing-grid, .pricing-grid-4 { grid-template-columns: 1fr; }
  .form-row { grid-template-columns: 1fr; }
  .nav-toggle { display: flex; }
  .snapshot-body { flex-direction: column; }
  .footer-bottom { flex-direction: column; }
  .stat-band-grid { grid-template-columns: 1fr; }
  .stat-band-item { border-left: none; border-top: 1px solid rgba(255,255,255,0.14); padding-top: 20px; }
  .stat-band-item:first-child { border-top: none; }
}

/* ---------- Per-state exam-snapshot donut colors ----------
   The homepage's .donut/.snapshot-* pattern is reused verbatim on each state
   landing page's Exam snapshot section, with a 3-segment ring (Life/Health/
   State law) instead of the homepage's 2-segment on-track/needs-work ring -
   these three color modifiers are the only new additions, giving the
   per-state Life/Health/State-law ring its own colors without touching the
   homepage's .dot-good/.dot-warn (performance-toned) or any shared layout rule. */
.dot-life { background: var(--navy); }
.dot-health { background: var(--brass); }
.dot-law { background: var(--emerald); }

/* ==========================================================================
   Ambient / dynamic layer — additive only.
   Everything below is new: no existing selector above this line is edited.
   Where a rule targets a pre-existing class (e.g. .feature-card, .hero,
   .stat-band), it only ever adds properties that class didn't already
   declare (a new ::before, a new keyframe, a position/overflow needed to
   contain a new decorative layer) — never a value that overrides something
   set above. All theme colors route through the existing custom properties
   so light/dark both stay correct automatically. Every continuous/looping
   animation is scoped under prefers-reduced-motion: no-preference, matching
   the convention already used for heroDrift/featuredGlow above; discrete,
   hover-triggered transitions (e.g. the new .feature-card shimmer) follow
   the same unguarded pattern already used by .btn-primary::after above,
   since they're user-initiated and non-looping, not ambient motion.
   ========================================================================== */

/* ---------- Hero: layered ambient backdrop ----------
   .hero-bg is new markup added only in index.html, sitting as the first
   child of .hero, before .wrap. It shares .hero's existing stacking context
   at z-index 0 — the same level as the pre-existing .hero::before/::after —
   so .hero .wrap (z-index 1, untouched) still paints on top of all of it.
   Pages that don't add this markup (state landing pages) simply keep their
   current .hero::before/::after exactly as before; nothing here changes
   how those render. */
.hero-bg {
  position: absolute; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
}
.hero-parallax {
  position: absolute; inset: 0;
  transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
.hero-blob {
  position: absolute; border-radius: 50%; filter: blur(2px);
}
.hero-blob-a {
  top: -190px; left: -150px; width: 420px; height: 420px;
  background: radial-gradient(circle, color-mix(in srgb, var(--navy) 20%, transparent) 0%, transparent 70%);
}
.hero-blob-b {
  bottom: -230px; right: -130px; width: 480px; height: 480px;
  background: radial-gradient(circle, color-mix(in srgb, var(--brass) 24%, transparent) 0%, transparent 72%);
}
.hero-blob-c {
  top: 38%; left: 54%; width: 320px; height: 320px;
  background: radial-gradient(circle, color-mix(in srgb, var(--emerald) 15%, transparent) 0%, transparent 70%);
}
/* Engraved-seal compass/ring motif — echoes the "official credentialing"
   feel called for instead of a generic decorative blob. Pure SVG strokes,
   currentColor so it follows --navy through both themes. */
.hero-motif {
  position: absolute; top: 50%; right: 4%; width: 340px; height: 340px;
  max-width: 46vw; transform: translateY(-50%);
  color: var(--navy); opacity: 0.14;
}
/* Fine engraved-paper grain, drawn from an inline SVG turbulence filter
   (no network request, no external asset) rather than a fetched texture. */
.hero-grain {
  position: absolute; inset: -10%; opacity: 0.05; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='90' height='90'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
@media (prefers-reduced-motion: no-preference) {
  .hero-blob-a { animation: heroBlobDriftA 22s ease-in-out infinite alternate; }
  .hero-blob-b { animation: heroBlobDriftB 27s ease-in-out infinite alternate; }
  .hero-blob-c { animation: heroBlobDriftC 19s ease-in-out infinite alternate; }
  .hero-motif { animation: heroMotifSpin 90s linear infinite; }
  .hero-grain { animation: heroGrainShift 1s steps(4) infinite; }
}
@keyframes heroBlobDriftA {
  0% { transform: translate(0, 0) scale(1); }
  100% { transform: translate(30px, 24px) scale(1.08); }
}
@keyframes heroBlobDriftB {
  0% { transform: translate(0, 0) scale(1); }
  100% { transform: translate(-26px, -30px) scale(1.06); }
}
@keyframes heroBlobDriftC {
  0% { transform: translate(0, 0) scale(1); }
  100% { transform: translate(-18px, 16px) scale(0.95); }
}
@keyframes heroMotifSpin {
  from { transform: translateY(-50%) rotate(0deg); }
  to { transform: translateY(-50%) rotate(360deg); }
}
@keyframes heroGrainShift {
  0% { background-position: 0 0; }
  25% { background-position: 20px 0; }
  50% { background-position: 20px 20px; }
  75% { background-position: 0 20px; }
  100% { background-position: 0 0; }
}
@media (max-width: 640px) {
  /* Keep the backdrop but thin it out on small screens: fewer overlapping
     blurred layers to paint, and less visual competition with the copy
     once the hero grid stacks to one column. */
  .hero-motif { opacity: 0.08; width: 220px; height: 220px; }
  .hero-blob-c { display: none; }
}

/* Idle micro-float on the hero snapshot card, so it reads as a live,
   present piece of UI rather than a flat screenshot. */
@media (prefers-reduced-motion: no-preference) {
  .snapshot-card { animation: snapshotFloat 6s ease-in-out infinite; }
}
@keyframes snapshotFloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-6px); }
}

/* ---------- Stat band / capture section: ambient backdrop ----------
   Both are the fixed-dark --band-bg strips. New pseudo-elements only — no
   existing declaration on .stat-band/.capture-section is touched, just a
   position/overflow pair they didn't previously declare, needed to contain
   the new decorative layer. Applies to every page that uses these classes,
   turning the flat navy fill into a soft, slowly drifting engraved-line +
   glow surface instead. */
.stat-band, .capture-section { position: relative; overflow: hidden; }
.stat-band::before, .capture-section::before {
  content: ""; position: absolute; inset: -20%; z-index: 0; pointer-events: none;
  background-image:
    repeating-linear-gradient(115deg, rgba(255, 255, 255, 0.05) 0px, rgba(255, 255, 255, 0.05) 1px, transparent 1px, transparent 64px),
    radial-gradient(ellipse 60% 80% at 15% 30%, rgba(242, 210, 154, 0.12) 0%, transparent 60%),
    radial-gradient(ellipse 55% 70% at 85% 75%, rgba(142, 161, 224, 0.14) 0%, transparent 60%);
}
.stat-band > *, .capture-section > * { position: relative; z-index: 1; }
@media (prefers-reduced-motion: no-preference) {
  .stat-band::before, .capture-section::before { animation: bandDrift 26s ease-in-out infinite alternate; }
}
@keyframes bandDrift {
  0% { transform: translate(0, 0); }
  100% { transform: translate(-3%, 2%); }
}

/* ---------- Feature card: hover shimmer ----------
   Same skewed-sheen technique already used on .btn-primary/.btn-brass above,
   applied to the feature cards. position/overflow are new declarations on
   .feature-card (it previously declared neither), needed to clip the sheen;
   the card's own padding already keeps every existing child well clear of
   the edge, so clipping introduces no visual change on its own. */
.feature-card { position: relative; overflow: hidden; }
.feature-card::before {
  content: ""; position: absolute; top: 0; left: -60%; width: 40%; height: 100%;
  background: linear-gradient(120deg, transparent, color-mix(in srgb, var(--brass) 18%, transparent), transparent);
  transform: skewX(-20deg); transition: left 0.65s ease; pointer-events: none;
}
.feature-card:hover::before { left: 130%; }

/* ---------- State-coverage flow diagram: lines draw in on scroll ----------
   New .state-flow-svg/.flow-line/.flow-arrow classes added to the existing
   <svg>/<line>/<polygon> elements in index.html's #states diagram — none of
   their existing attributes (coordinates, stroke, fill) are touched. Keyed
   off the same .reveal/.is-visible toggle script.js already applies to the
   diagram's wrapper, so the four connectors draw downward in sequence and
   each arrowhead settles in just behind its line, instead of the whole
   diagram simply fading up as one flat image. */
@media (prefers-reduced-motion: no-preference) {
  .state-flow-svg .flow-line {
    stroke-dasharray: 30; stroke-dashoffset: 30;
    transition: stroke-dashoffset 0.5s ease;
  }
  .state-flow-svg .flow-arrow {
    opacity: 0; transform-origin: center;
    transition: opacity 0.25s ease;
  }
  .reveal.is-visible .state-flow-svg .flow-line { stroke-dashoffset: 0; }
  .reveal.is-visible .state-flow-svg .flow-arrow { opacity: 1; }
  .state-flow-svg .flow-line-1 { transition-delay: 0.3s; }
  .state-flow-svg .flow-arrow-1 { transition-delay: 0.7s; }
  .state-flow-svg .flow-line-2 { transition-delay: 0.75s; }
  .state-flow-svg .flow-arrow-2 { transition-delay: 1.15s; }
  .state-flow-svg .flow-line-3 { transition-delay: 1.2s; }
  .state-flow-svg .flow-arrow-3 { transition-delay: 1.6s; }
  .state-flow-svg .flow-line-4 { transition-delay: 1.65s; }
  .state-flow-svg .flow-arrow-4 { transition-delay: 2.05s; }
}
