/* ---------------------------------------------------------------------------
   gatewaycompare.com — design system

   Build spec §7: Outfit headings, IBM Plex Sans body, IBM Plex Mono for code.
   Soft shadows, ~10px radius, editorial "fintech-trust" feel.

   The palette is the logo's, sampled from the artwork rather than approximated:
   a cool ink ramp anchored on #161826, a single violet accent, per-category
   accent colours, ink header and footer with the content light between. The
   five brand primitives and the reasoning are in CLAUDE.md §13.

   No build step (build spec §1), so this is hand-authored CSS with custom
   properties rather than a compiled utility framework. It is one file, served
   immutable with a hashed query string.

   FONT FILES: the @font-face rules below expect subsetted woff2 files in
   /assets/fonts/. They are not in the repository — see CLAUDE.md § "Known data
   gaps". Until they are added the stack falls through to system fonts, which
   look fine and cost nothing. CSP sets font-src 'self', so a CDN font would be
   blocked by design.
--------------------------------------------------------------------------- */

/* --- Fonts ---------------------------------------------------------------- */

@font-face {
  font-family: 'Outfit';
  src: url('/assets/fonts/outfit-latin.woff2') format('woff2');
  font-weight: 400 900;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2122, U+2212;
}

@font-face {
  font-family: 'IBM Plex Sans';
  src: url('/assets/fonts/ibm-plex-sans-latin.woff2') format('woff2');
  font-weight: 400 600;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2122, U+2212;
}

@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/assets/fonts/ibm-plex-mono-latin.woff2') format('woff2');
  font-weight: 400 600;
  font-display: swap;
  unicode-range: U+0000-00FF, U+2000-206F;
}

/* --- Tokens --------------------------------------------------------------- */

:root {
  /* ---------------------------------------------------------------------
     Brand primitives — sampled from the supplied logo, not approximated.

       #161826  the icon and OG ground, and the darkest step of the ramp
       #9184d9  the tall bar in the mark; the brand violet
       #b2b6ca  the short bar in the mark
       #cfd3e5  "gateway" in the wordmark
       #e9e9ed  "compare" in the wordmark

     Everything below is derived from these five, so the site and the logo
     cannot drift apart.
     --------------------------------------------------------------------- */
  --brand-ink:        #161826;
  --brand-violet:     #9184d9;
  --brand-mist:       #b2b6ca;
  --brand-periwinkle: #cfd3e5;
  --brand-paper:      #e9e9ed;

  /* Cool ink ramp, hue ~232°, anchored at both ends by real brand colours:
     300 and 400 ARE the wordmark and mark greys, 950 IS the icon ground. */
  --ink-50:  #f7f7fa;
  --ink-100: #eeeef3;
  --ink-200: #e0e2ec;
  --ink-300: #cfd3e5;
  --ink-400: #b2b6ca;
  --ink-500: #8c91a8;
  --ink-600: #6b7089;
  --ink-700: #4f5468;
  --ink-800: #34384a;
  --ink-900: #212436;
  --ink-950: #161826;

  --bg:            #ffffff;
  --bg-subtle:     var(--ink-50);
  --bg-sunken:     var(--ink-100);
  --fg:            var(--ink-900);
  --fg-muted:      var(--ink-600);
  --fg-subtle:     var(--ink-500);
  --border:        var(--ink-200);
  --border-strong: var(--ink-300);

  /* Violet is the single accent: buttons, checkmarks, focus rings. One accent
     colour is what makes per-category accents legible as information rather
     than decoration.

     NOT #9184d9. The logo violet is 3.2:1 on white — fine as a shape on the
     dark header, too weak for body text or a white-on-violet button. This is
     the same hue darkened to 4.9:1, which clears AA both as text on white and
     as a background under white text. --brand-violet stays available for the
     dark surfaces, where it reads at 5.5:1. */
  --accent:        #7461cc;
  --accent-hover:  #6a56c4;
  --accent-subtle: #f2f0fc;
  --accent-border: #d5cef2;
  --accent-fg:     #ffffff;

  --success:       #059669;
  --success-bg:    #ecfdf5;
  --warning:       #b45309;
  --warning-bg:    #fffbeb;
  --danger:        #dc2626;
  --danger-bg:     #fef2f2;
  --info:          #0369a1;
  --info-bg:       #f0f9ff;

  /* Category accents (build spec §7).

     Retuned so none of them sits within reach of the violet accent — a
     category dot that reads as "this is the interactive colour" is worse than
     no dot. Gaming was #8b5cf6 and acquirers #6366f1, both of which are now
     the accent's hue; payfac was a second teal a shade off regional. */
  --cat-traditional:   #3b82f6;
  --cat-regional:      #0d9488;
  --cat-crypto:        #f59e0b;
  --cat-baas:          #ec4899;
  --cat-gaming:        #c026d3;
  --cat-high-risk:     #ef4444;
  --cat-orchestration: #06b6d4;
  --cat-payfac:        #16a34a;
  --cat-acquirer:      #64748b;
  --cat-bnpl:          #f97316;

  --font-heading: 'Outfit', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-sans:    'IBM Plex Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono:    'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  --radius:    0.625rem;
  --radius-sm: 0.375rem;
  --radius-lg: 1rem;
  --radius-full: 9999px;

  --shadow-sm: 0 1px 2px rgba(28, 25, 23, 0.05);
  --shadow:    0 1px 3px rgba(28, 25, 23, 0.08), 0 1px 2px rgba(28, 25, 23, 0.04);
  --shadow-md: 0 4px 12px rgba(28, 25, 23, 0.06), 0 2px 4px rgba(28, 25, 23, 0.04);
  --shadow-lg: 0 8px 32px rgba(28, 25, 23, 0.06);

  --container: 76rem;
  --container-narrow: 46rem;

  --header-height: 4rem;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --bg:            var(--ink-950);
    --bg-subtle:     #1b1e2f;
    --bg-sunken:     #10111d;
    --fg:            var(--brand-paper);
    --fg-muted:      var(--ink-400);
    --fg-subtle:     var(--ink-500);
    --border:        #2b2f42;
    --border-strong: var(--ink-800);

    /* On the ink ground the logo violet is 5.5:1, so dark mode gets the
       actual brand colour rather than the darkened variant. */
    --accent:        var(--brand-violet);
    --accent-hover:  #a79ce2;
    --accent-subtle: #221f3a;
    --accent-border: #3b3560;
    --accent-fg:     var(--brand-ink);

    --success-bg: #022c22;
    --warning-bg: #291a05;
    --danger-bg:  #2c0b0b;
    --info-bg:    #082f49;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow:    0 1px 3px rgba(0, 0, 0, 0.4);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
    --shadow-lg: 0 8px 32px rgba(0, 0, 0, 0.5);
  }
}

/* --- Reset ---------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

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

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--fg);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;

  /* Subtle radial dot grid — the reference site's background signature. */
  background-image: radial-gradient(circle at 1px 1px, var(--ink-200) 1px, transparent 0);
  background-size: 32px 32px;
  background-attachment: fixed;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) body {
    background-image: radial-gradient(circle at 1px 1px, var(--ink-800) 1px, transparent 0);
  }
}

h1, h2, h3, h4, h5 {
  font-family: var(--font-heading);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0 0 0.5em;
  text-wrap: balance;
}

h1 { font-size: clamp(1.875rem, 1.2rem + 2.4vw, 3rem); }
h2 { font-size: clamp(1.5rem, 1.1rem + 1.4vw, 2rem); }
h3 { font-size: 1.25rem; }
h4 { font-size: 1.0625rem; }

p { margin: 0 0 1rem; text-wrap: pretty; }

a { color: var(--accent); text-decoration-color: color-mix(in oklab, var(--accent) 35%, transparent); text-underline-offset: 2px; }
a:hover { color: var(--accent-hover); text-decoration-color: currentColor; }

code, kbd, pre, samp { font-family: var(--font-mono); font-size: 0.875em; }

img, svg { max-width: 100%; height: auto; }

hr { border: 0; border-top: 1px solid var(--border); margin: 2rem 0; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.visually-hidden {
  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: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--accent); color: var(--accent-fg);
  padding: 0.75rem 1rem; border-radius: 0 0 var(--radius) 0;
}
.skip-link:focus { left: 0; }

/* --- Layout --------------------------------------------------------------- */

.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: 1.25rem; }
.container--narrow { max-width: var(--container-narrow); }

.stack > * + * { margin-top: var(--stack-gap, 1rem); }

/* Sections carry their own vertical rhythm and their own separation. Two
   adjacent sections that happen to share a background used to butt together
   with only a hairline between them, which read as one long undifferentiated
   block — so a run of same-toned sections collapses to a single band and only
   the *first* of the run pays for the border. */
.section { padding-block: clamp(3rem, 5.5vw, 5.5rem); }
.section--sunken { background: var(--bg-subtle); }

/* One dark band, carrying the numbers. Alternating white/grey the whole way
   down is what makes a page read as a template; the brand ground appearing
   once in the middle of the page ties the header and footer together. */
.section--ink {
  background: var(--brand-ink); color: var(--brand-periwinkle);
  border-block: 1px solid color-mix(in oklab, var(--brand-violet) 22%, transparent);
}
.section--ink h2, .section--ink h3 { color: var(--brand-paper); }
.section--ink .stat__value { color: #fff; }
.section--ink .stat__label { color: var(--brand-mist); }
.section--ink a:not(.btn) { color: var(--brand-periwinkle); }
.section--ink a:not(.btn):hover { color: #fff; }

/* Numerals in the stat band are the point of the band; give them the mark's
   violet so the eye lands on them. */
.section--ink .stat + .stat .stat__value { color: #fff; }

/* The caption is a claim about the numbers above it, so it gets a rule and
   real space rather than sitting 32px under them looking unplaced. */
.stat-note {
  max-width: 56ch; margin: 2.5rem auto 0; padding-top: 2rem; text-align: center;
  font-size: 0.9375rem; line-height: 1.65;
  border-top: 1px solid color-mix(in oklab, var(--brand-mist) 22%, transparent);
  color: var(--brand-mist);
}
.stat__rule { width: 1px; align-self: stretch; background: color-mix(in oklab, var(--brand-mist) 25%, transparent); }
.section--sunken + .section--sunken { padding-top: 0; }
.section:not(.section--sunken) + .section--sunken,
.section--sunken + .section:not(.section--sunken) { border-top: 1px solid var(--border); }

/* A section that follows a run of sunken ones needs the closing rule too. */
.section--sunken:last-of-type { border-bottom: 1px solid var(--border); }

main { flex: 1 0 auto; }

/* auto-FIT, not auto-fill.
   auto-fill keeps empty tracks, so three cards in a four-track row rendered at
   the minimum width and left a third of the row blank — which is what made the
   homepage look half-finished. auto-fit collapses the empty tracks and lets the
   real items take the space. */
.grid { display: grid; gap: 1.25rem; }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr)); }

/* Cap how far a small set may stretch. Three cards across 1176px is 380px each,
   which is fine; two cards across the same row is a pair of billboards. */
.grid--capped { justify-content: start; }
.grid--capped > * { max-width: 30rem; }

.cluster { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; }
/* A button row following a block of cards needs to clear it. */
.grid + .cluster, .card + .cluster, .table-wrap + .cluster { margin-top: 2.5rem; }
.between { display: flex; flex-wrap: wrap; gap: 1rem; align-items: center; justify-content: space-between; }

/* Prose measure. Long paragraphs left to fill a 1176px container are unreadable
   and look like a wireframe; 68ch is the readable maximum. */
.measure { max-width: 68ch; }

/* --- Header --------------------------------------------------------------- */

/* The header is the brand ground, in both colour schemes.
   The supplied wordmark is light-on-transparent — it was drawn for the ink
   background the icon and OG images use — so putting it on a white bar would
   mean recolouring someone else's logo. The bar moves to meet it instead, and
   the page is book-ended by ink with the content light between. */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in oklab, var(--brand-ink) 92%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid color-mix(in oklab, var(--brand-violet) 22%, transparent);
  color: var(--brand-paper);
}

.site-header__inner { display: flex; align-items: center; gap: 1.5rem; height: var(--header-height); }

.logo {
  display: inline-flex; align-items: center; text-decoration: none;
  flex: 0 0 auto; border-radius: var(--radius-sm);
}
.logo img { display: block; height: 1.5rem; width: auto; }

/* The wordmark carries the name; the mark alone takes over when the nav needs
   the room. Both are in the DOM so neither has to load on a breakpoint change.
   Scoped with two classes so these beat `.logo img` above — with a single class
   `.logo img` won on specificity and BOTH images rendered, which is why the
   header showed a stray violet bar after the wordmark. */
.logo .logo__wordmark { display: block; }
.logo .logo__mark { display: none; height: 1.75rem; }

.nav { display: flex; gap: 0.25rem; align-items: center; margin-left: auto; }
.nav a {
  color: var(--brand-periwinkle); text-decoration: none; font-size: 0.9375rem; font-weight: 500;
  padding: 0.5rem 0.75rem; border-radius: var(--radius-sm);
}
.nav a:hover {
  color: #fff;
  background: color-mix(in oklab, var(--brand-violet) 20%, transparent);
}
.nav a[aria-current='page'] { color: #fff; font-weight: 600; }

/* Buttons sitting on the ink bar: the ghost variant inherits --fg by default,
   which is page-foreground, not header-foreground. */
.site-header .btn--ghost {
  color: var(--brand-periwinkle);
  border-color: color-mix(in oklab, var(--brand-mist) 35%, transparent);
}
.site-header .btn--ghost:hover {
  color: #fff;
  background: color-mix(in oklab, var(--brand-violet) 22%, transparent);
  border-color: var(--brand-violet);
}
.site-header .btn--primary {
  background: var(--brand-violet);
  border-color: var(--brand-violet);
  color: var(--brand-ink);
}
.site-header .btn--primary:hover { background: #a79ce2; border-color: #a79ce2; }

@media (max-width: 60rem) {
  .nav--primary { display: none; }
}

@media (max-width: 26rem) {
  .logo .logo__wordmark { display: none; }
  .logo .logo__mark { display: block; }
}

/* --- Buttons -------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  font-family: var(--font-sans); font-size: 0.9375rem; font-weight: 600;
  padding: 0.625rem 1.125rem; border-radius: var(--radius);
  border: 1px solid transparent; cursor: pointer; text-decoration: none;
  transition: background-color 120ms ease, border-color 120ms ease, transform 120ms ease;
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }

.btn--primary { background: var(--accent); color: var(--accent-fg); }
.btn--primary:hover { background: var(--accent-hover); color: var(--accent-fg); }

.btn--secondary { background: var(--bg); color: var(--fg); border-color: var(--border-strong); }
.btn--secondary:hover { background: var(--bg-sunken); color: var(--fg); }

.btn--ghost { background: transparent; color: var(--fg-muted); }
.btn--ghost:hover { background: var(--bg-sunken); color: var(--fg); }

.btn--sm { padding: 0.375rem 0.75rem; font-size: 0.875rem; }
.btn--lg { padding: 0.8125rem 1.5rem; font-size: 1rem; }
.btn--block { width: 100%; }

.btn[disabled], .btn[aria-disabled='true'] { opacity: 0.5; pointer-events: none; }

/* --- Cards ---------------------------------------------------------------- */

.card {
  background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 1.25rem; box-shadow: var(--shadow-sm);
}
.card--interactive { transition: box-shadow 150ms ease, border-color 150ms ease; }
.card--interactive:hover { box-shadow: var(--shadow-md); border-color: var(--border-strong); }

.card--sponsored {
  border-color: var(--accent-border);
  background: linear-gradient(to bottom, var(--accent-subtle), var(--bg) 40%);
}

/* --- Provider card -------------------------------------------------------- */

.provider-card { display: flex; flex-direction: column; gap: 0.875rem; height: 100%; }
.provider-card__head { display: flex; gap: 0.75rem; align-items: flex-start; }

.provider-logo {
  /* Fixed box so a slow logo cannot shift layout (build spec §9: CLS < 0.05). */
  width: 2.75rem; height: 2.75rem; flex: 0 0 2.75rem;
  border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: #fff; display: grid; place-items: center;
  overflow: hidden; font-family: var(--font-heading); font-weight: 800; font-size: 0.9rem;
  color: var(--fg-muted);
}
/* Initials-only fallback keeps the tinted ground; a real logo gets white. */
.provider-logo:not(:has(img)) { background: var(--bg-sunken); }
.provider-logo img { width: 100%; height: 100%; object-fit: contain; padding: 0.25rem; }

.provider-card__name { font-family: var(--font-heading); font-weight: 700; font-size: 1.0625rem; margin: 0; letter-spacing: -0.01em; }
.provider-card__name a { color: var(--fg); text-decoration: none; }
.provider-card__name a:hover { color: var(--accent); }
.provider-card__tagline { color: var(--fg-muted); font-size: 0.875rem; margin: 0.125rem 0 0; }

.provider-card__facts { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.625rem 1rem; margin-top: auto; }

.fact { min-width: 0; }
.fact__label {
  font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--fg-subtle); font-weight: 600; display: block; margin-bottom: 0.125rem;
}
.fact__value { font-size: 0.9375rem; font-weight: 600; color: var(--fg); font-variant-numeric: tabular-nums; }
.fact__value--muted { color: var(--fg-subtle); font-weight: 400; font-style: italic; }

/* --- Badges & pills ------------------------------------------------------- */

.badge {
  display: inline-flex; align-items: center; gap: 0.3125rem;
  font-size: 0.75rem; font-weight: 600; line-height: 1;
  padding: 0.3125rem 0.5625rem; border-radius: var(--radius-full);
  background: var(--bg-sunken); color: var(--fg-muted); border: 1px solid var(--border);
  white-space: nowrap;
}
.badge--accent  { background: var(--accent-subtle); color: var(--accent); border-color: var(--accent-border); }
.badge--success { background: var(--success-bg); color: var(--success); border-color: transparent; }
.badge--warning { background: var(--warning-bg); color: var(--warning); border-color: transparent; }
.badge--danger  { background: var(--danger-bg); color: var(--danger); border-color: transparent; }
.badge--sponsored { background: var(--bg-sunken); color: var(--fg-muted); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; font-size: 0.6875rem; }

/* Category dot uses the per-category accent as data, not decoration. */
.badge__dot { width: 0.5rem; height: 0.5rem; border-radius: var(--radius-full); background: var(--dot, var(--fg-subtle)); flex: none; }

.tag-list { display: flex; flex-wrap: wrap; gap: 0.375rem; }
.tag {
  font-size: 0.75rem; padding: 0.25rem 0.5rem; border-radius: var(--radius-sm);
  background: var(--bg-sunken); color: var(--fg-muted); text-decoration: none; border: 1px solid transparent;
}
a.tag:hover { background: var(--accent-subtle); color: var(--accent); border-color: var(--accent-border); }

/* --- Score ---------------------------------------------------------------- */

.score {
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
  width: 3.5rem; height: 3.5rem; border-radius: var(--radius); flex: none;
  font-family: var(--font-heading); font-weight: 800; font-size: 1.375rem;
  font-variant-numeric: tabular-nums; line-height: 1;
  background: var(--accent-subtle); color: var(--accent); border: 1px solid var(--accent-border);
}
.score__label { font-size: 0.5625rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; opacity: 0.75; margin-top: 0.125rem; }
.score--mid  { background: var(--warning-bg); color: var(--warning); border-color: transparent; }
.score--low  { background: var(--bg-sunken); color: var(--fg-muted); border-color: var(--border); }

/* --- Tables --------------------------------------------------------------- */

.table-wrap { overflow-x: auto; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); }

table { width: 100%; border-collapse: collapse; font-size: 0.9375rem; }
th, td { padding: 0.75rem 1rem; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
thead th {
  font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--fg-subtle); font-weight: 700; background: var(--bg-subtle);
  position: sticky; top: 0; z-index: 1;
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--bg-subtle); }
td.numeric, th.numeric { text-align: right; font-variant-numeric: tabular-nums; }

.table--compare th:first-child { width: 30%; font-weight: 600; color: var(--fg); background: var(--bg-subtle); }
.table--compare .row-differs { background: color-mix(in oklab, var(--warning-bg) 55%, transparent); }
.table--compare .winner { font-weight: 700; color: var(--success); }

/* --- Forms ---------------------------------------------------------------- */

label { display: block; font-size: 0.875rem; font-weight: 600; margin-bottom: 0.375rem; color: var(--fg); }
.field { margin-bottom: 1.25rem; }
.field__hint { font-size: 0.8125rem; color: var(--fg-muted); margin-top: 0.375rem; }
.field__error { font-size: 0.8125rem; color: var(--danger); margin-top: 0.375rem; font-weight: 600; }

input[type='text'], input[type='email'], input[type='url'], input[type='number'],
input[type='search'], input[type='password'], select, textarea {
  width: 100%; font-family: inherit; font-size: 0.9375rem; color: var(--fg);
  background: var(--bg); border: 1px solid var(--border-strong); border-radius: var(--radius);
  padding: 0.625rem 0.75rem; transition: border-color 120ms ease, box-shadow 120ms ease;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 18%, transparent);
}
input[aria-invalid='true'], select[aria-invalid='true'] { border-color: var(--danger); }
textarea { min-height: 8rem; resize: vertical; }

/* The row is the target, not the 13px native box. Sub-24px tap targets were
   the single most common finding in the layout audit. */
.checkbox {
  display: flex; gap: 0.625rem; align-items: flex-start;
  font-weight: 400; font-size: 0.9375rem; margin-bottom: 0; cursor: pointer;
  padding: 0.375rem 0.5rem; margin-inline: -0.5rem; border-radius: var(--radius-sm);
  min-height: 2rem;
}
.checkbox:hover { background: var(--bg-subtle); }
.checkbox input {
  width: 1.125rem; height: 1.125rem; flex: none; margin: 0.1875rem 0 0;
  accent-color: var(--accent); cursor: pointer;
}

/* --- Facets --------------------------------------------------------------- */

.facets { display: flex; flex-direction: column; gap: 0.5rem; }
.facet { border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg); overflow: hidden; }
.facet > summary {
  padding: 0.75rem 1rem; cursor: pointer; font-weight: 600; font-size: 0.9375rem;
  list-style: none; display: flex; justify-content: space-between; align-items: center;
}
.facet > summary::-webkit-details-marker { display: none; }
.facet > summary::after { content: '+'; color: var(--fg-subtle); font-size: 1.125rem; line-height: 1; }
.facet[open] > summary::after { content: '−'; }
.facet__body { padding: 0 1rem 1rem; max-height: 18rem; overflow-y: auto; }
.facet__option { display: flex; gap: 0.5rem; align-items: center; padding: 0.3125rem 0; font-size: 0.875rem; cursor: pointer; }
.facet__option input { accent-color: var(--accent); flex: none; }
.facet__count { margin-left: auto; font-size: 0.75rem; color: var(--fg-subtle); font-variant-numeric: tabular-nums; }
.facet__option--empty { opacity: 0.4; }

.browse-layout { display: grid; gap: 2rem; grid-template-columns: 16rem 1fr; align-items: start; }
@media (max-width: 60rem) { .browse-layout { grid-template-columns: 1fr; } }

/* --- Alerts & notes ------------------------------------------------------- */

.alert {
  padding: 0.875rem 1rem; border-radius: var(--radius); font-size: 0.9375rem;
  border: 1px solid transparent; margin-bottom: 1rem;
}
.alert--success { background: var(--success-bg); color: var(--success); }
.alert--error   { background: var(--danger-bg);  color: var(--danger); }
.alert--warning { background: var(--warning-bg); color: var(--warning); }
.alert--info    { background: var(--info-bg);    color: var(--info); }

.note {
  font-size: 0.8125rem; color: var(--fg-muted); line-height: 1.5;
  padding: 0.625rem 0.875rem; background: var(--bg-subtle);
  border-left: 3px solid var(--border-strong); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.note--legal { font-size: 0.75rem; }

/* The independence promise. Repeated across the site (build spec §11.6), so it
   gets a consistent, quiet, non-shouty treatment. */
.independence {
  border: 1px solid var(--accent-border); background: var(--accent-subtle);
  border-radius: var(--radius); padding: 1rem 1.25rem; font-size: 0.875rem; color: var(--fg);
}
.independence strong { color: var(--accent); }

.disclosure { font-size: 0.75rem; color: var(--fg-subtle); }

/* --- Citations ------------------------------------------------------------ */

.cite {
  font-size: 0.6875rem; color: var(--fg-subtle); text-decoration: none;
  vertical-align: super; margin-left: 0.1875rem; font-weight: 600;
}
.cite:hover { color: var(--accent); }
.uncited { color: var(--fg-subtle); font-style: italic; font-weight: 400; }

/* --- Hero ----------------------------------------------------------------- */

/* Centred hero.

   Everything on one axis: title, lede, search field and the single call to
   action all share a centre line, and the field is the widest element so the
   eye lands on it. The CTA row is capped at the field's width so it can never
   overhang it — that overhang was what made the old pair look misplaced. */
.hero { padding-block: clamp(3.5rem, 7vw, 6rem) clamp(2.5rem, 4vw, 3.5rem); text-align: center; }
.hero__inner { max-width: 46rem; margin-inline: auto; }

.hero__eyebrow {
  display: inline-flex; align-items: center; gap: 0.625rem;
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 1.25rem;
}
.hero__eyebrow::before,
.hero__eyebrow::after {
  content: ''; width: 1.75rem; height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, transparent, var(--brand-violet));
}
.hero__eyebrow::after { background: linear-gradient(90deg, var(--brand-violet), transparent); }

.hero__title {
  max-width: 20ch; margin-inline: auto;
  font-size: clamp(2.25rem, 1.5rem + 2.8vw, 3.5rem);
  margin-bottom: 1.125rem;
}
.hero__lede {
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.1875rem);
  color: var(--fg-muted); max-width: 56ch; margin: 0 auto 2.25rem;
}

/* The search field owns the hero. */
.search-hero { margin: 0 auto 1.5rem; max-width: 38rem; }
.search-field { position: relative; display: flex; gap: 0.5rem; }
.search-field > input { flex: 1 1 auto; min-width: 0; }
.search-hero input[type='search'] {
  flex: 1; min-width: 0;
  padding: 1rem 1.125rem; font-size: 1.0625rem;
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.search-hero .btn { padding-inline: 1.5rem; }

.hero__actions {
  position: relative; z-index: 1;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 0.75rem 1.25rem; max-width: 38rem; margin-inline: auto;
}
.hero__hint { font-size: 0.875rem; color: var(--fg-subtle); margin: 0; }

/* --- Type-ahead ----------------------------------------------------------- */

.search-hero { position: relative; z-index: 60; }
.search-field { z-index: 60; }

/* Above everything that follows it in the hero. Without lifting the FIELD as
   well, the panel sat under the "Get matched" button, which paints later in
   DOM order — the dropdown was there, just buried. */
.suggest {
  position: absolute; top: calc(100% + 0.5rem); left: 0; right: 0; z-index: 60;
  background: var(--bg); border: 1px solid var(--border-strong);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.suggest__list { list-style: none; margin: 0; padding: 0.25rem; max-height: 24rem; overflow-y: auto; }

.suggest__item a {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.5rem 0.625rem; border-radius: var(--radius-sm);
  text-decoration: none; color: inherit;
}
.suggest__item.is-active a,
.suggest__item a:hover { background: var(--accent-subtle); }

.suggest__logo {
  width: 2rem; height: 2rem; flex: 0 0 2rem; border-radius: var(--radius-sm);
  object-fit: contain; background: #fff; border: 1px solid var(--border);
}
.suggest__logo--initials {
  display: grid; place-items: center; background: var(--bg-sunken);
  font-family: var(--font-heading); font-weight: 800; font-size: 0.75rem; color: var(--fg-muted);
}

.suggest__text { min-width: 0; flex: 1; display: flex; flex-direction: column; line-height: 1.35; }
.suggest__name { font-weight: 600; font-size: 0.9375rem; }
.suggest__tagline {
  font-size: 0.8125rem; color: var(--fg-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.suggest mark { background: transparent; color: var(--accent); font-weight: 700; padding: 0; }

.suggest__fee {
  flex: 0 0 auto; font-family: var(--font-mono); font-size: 0.8125rem;
  color: var(--fg-muted); font-variant-numeric: tabular-nums;
}

.suggest__empty { padding: 0.875rem 0.75rem; color: var(--fg-muted); font-size: 0.9375rem; }
.suggest__all { border-top: 1px solid var(--border); margin-top: 0.25rem; }
.suggest__all a {
  display: block; padding: 0.625rem; border-radius: var(--radius-sm);
  font-size: 0.875rem; font-weight: 600; color: var(--accent); text-decoration: none;
}
.suggest__all a:hover { background: var(--accent-subtle); }

@media (max-width: 30rem) {
  .search-field { flex-wrap: wrap; }
  .search-hero input[type='search'] { flex: 1 1 100%; }
  .search-hero .btn { flex: 1 1 100%; }
  .suggest__fee { display: none; }
}

/* A grid, not a centred flex-wrap.
   Five flex items wrapping into 3+2 leave the second row centred under a full
   first row, which reads as misaligned at every width where it wraps. A grid
   keeps the columns aligned whatever the count, and the cells share a width so
   "Providers tracked" and "Regulators monitored" line up instead of drifting. */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr));
  gap: 2rem 1rem;
  align-items: start;
}
.stat { text-align: center; }
.stat__value {
  font-family: var(--font-heading); font-weight: 800; font-size: clamp(1.75rem, 1.2rem + 1.6vw, 2.5rem);
  line-height: 1; color: var(--fg); font-variant-numeric: tabular-nums;
}
.stat__label { font-size: 0.8125rem; color: var(--fg-muted); margin-top: 0.375rem; }

/* --- Category tiles ------------------------------------------------------- */

.category-tile {
  display: block; text-decoration: none; padding: 1.125rem;
  border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg);
  border-top: 3px solid var(--tile-accent, var(--accent));
  transition: box-shadow 150ms ease, transform 150ms ease;
}
.category-tile:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
.category-tile__name { font-family: var(--font-heading); font-weight: 700; color: var(--fg); font-size: 1rem; }
.category-tile__count { font-size: 0.8125rem; color: var(--fg-muted); margin-top: 0.125rem; }

/* --- Feed (changes, license watch) ---------------------------------------- */

.feed { list-style: none; padding: 0; margin: 0; }
.feed__item { display: flex; gap: 1rem; padding: 1rem 0; border-bottom: 1px solid var(--border); }
.feed__item:last-child { border-bottom: 0; }
.feed__date {
  font-size: 0.75rem; color: var(--fg-subtle); font-variant-numeric: tabular-nums;
  flex: 0 0 5.5rem; padding-top: 0.125rem;
}
.feed__body { min-width: 0; flex: 1; }
.feed__summary { margin: 0 0 0.25rem; }
.feed__meta { font-size: 0.8125rem; color: var(--fg-muted); }

.delta-up   { color: var(--danger); font-weight: 600; }
.delta-down { color: var(--success); font-weight: 600; }

/* --- Wizard --------------------------------------------------------------- */

.wizard { max-width: 40rem; margin-inline: auto; }
.wizard__steps { display: flex; gap: 0.5rem; margin-bottom: 2rem; }
.wizard__step { flex: 1; height: 0.25rem; border-radius: var(--radius-full); background: var(--border); }
.wizard__step--done { background: var(--accent); }
.wizard__legend { font-family: var(--font-heading); font-size: 1.375rem; font-weight: 800; margin-bottom: 0.25rem; }

fieldset { border: 0; padding: 0; margin: 0 0 1.75rem; }

.option-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(11rem, 100%), 1fr)); gap: 0.5rem; }
.option {
  display: flex; gap: 0.5rem; align-items: center; padding: 0.625rem 0.75rem;
  border: 1px solid var(--border-strong); border-radius: var(--radius);
  font-size: 0.875rem; cursor: pointer; background: var(--bg); font-weight: 400; margin: 0;
}
.option:hover { border-color: var(--accent); }
.option input { accent-color: var(--accent); flex: none; }
.option:has(input:checked) { border-color: var(--accent); background: var(--accent-subtle); }

/* --- Results -------------------------------------------------------------- */

.result { display: flex; gap: 1rem; align-items: flex-start; }
.result__body { flex: 1; min-width: 0; }
.reasons { list-style: none; padding: 0; margin: 0.5rem 0 0; display: flex; flex-direction: column; gap: 0.25rem; }
.reasons li { font-size: 0.875rem; padding-left: 1.25rem; position: relative; }
.reasons li::before { content: '✓'; position: absolute; left: 0; color: var(--success); font-weight: 700; }
.warnings li::before { content: '!'; color: var(--warning); }

.disqualified-list summary { cursor: pointer; font-weight: 600; padding: 0.75rem 0; }
.disqualified-list .feed__item { opacity: 0.7; }

/* --- Footer --------------------------------------------------------------- */

/* Ink ground, matching the header. The legal block (build spec §11) is long and
   is the last thing on every page — on the dark ground it reads as a colophon
   rather than as an apology tacked to the bottom of a white page. */
.site-footer {
  margin-top: auto;
  border-top: 1px solid color-mix(in oklab, var(--brand-violet) 22%, transparent);
  background: var(--brand-ink); color: var(--brand-periwinkle);
  padding-block: 3rem 2rem; font-size: 0.875rem;
}
.footer-grid { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr)); margin-bottom: 2.5rem; }
.footer-grid h3 { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--brand-violet); margin-bottom: 0.75rem; font-weight: 700; }
.footer-grid ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 0.4375rem; }
.footer-grid a { color: var(--brand-mist); text-decoration: none; }
.footer-grid a:hover { color: #fff; text-decoration: underline; }

.footer-brand { display: flex; align-items: center; flex-wrap: wrap; gap: 0.75rem 1.25rem; margin-bottom: 2.5rem; }
.footer-brand img { display: block; height: 1.625rem; width: auto; }
.footer-brand p { margin: 0; color: var(--brand-mist); font-size: 0.8125rem; flex: 1 1 18rem; min-width: 0; }

.legal {
  border-top: 1px solid color-mix(in oklab, var(--brand-mist) 20%, transparent);
  padding-top: 1.5rem; color: var(--brand-mist); font-size: 0.75rem; line-height: 1.65;
}
.legal p { margin-bottom: 0.5rem; }
.legal a { color: var(--brand-periwinkle); }
.legal a:hover { color: #fff; }

/* --- Breadcrumbs ---------------------------------------------------------- */

.breadcrumbs { font-size: 0.8125rem; color: var(--fg-muted); padding-block: 1rem 0; }
.breadcrumbs ol { list-style: none; display: flex; flex-wrap: wrap; gap: 0.375rem; padding: 0; margin: 0; }
.breadcrumbs li::after { content: '/'; margin-left: 0.375rem; color: var(--fg-subtle); }
.breadcrumbs li:last-child::after { content: ''; }
.breadcrumbs a { color: var(--fg-muted); text-decoration: none; }
.breadcrumbs a:hover { color: var(--accent); }

/* --- Pagination ----------------------------------------------------------- */

.pagination { display: flex; gap: 0.375rem; justify-content: center; align-items: center; margin-top: 2.5rem; flex-wrap: wrap; }
.pagination a, .pagination span {
  min-width: 2.25rem; height: 2.25rem; padding-inline: 0.5rem;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  text-decoration: none; color: var(--fg-muted); font-size: 0.875rem;
}
.pagination a:hover { border-color: var(--accent); color: var(--accent); }
.pagination [aria-current='page'] { background: var(--accent); color: var(--accent-fg); border-color: var(--accent); font-weight: 600; }

/* --- Prose ---------------------------------------------------------------- */

.prose { max-width: 68ch; }
.prose h2 { margin-top: 2.5rem; }
.prose h3 { margin-top: 1.75rem; }
.prose ul, .prose ol { padding-left: 1.25rem; margin-bottom: 1rem; }
.prose li { margin-bottom: 0.375rem; }
.prose blockquote {
  margin: 1.5rem 0; padding-left: 1rem; border-left: 3px solid var(--accent);
  color: var(--fg-muted); font-style: italic;
}
.prose pre {
  background: var(--ink-900); color: var(--ink-100); padding: 1rem;
  border-radius: var(--radius); overflow-x: auto; font-size: 0.8125rem; line-height: 1.6;
}
.prose :not(pre) > code { background: var(--bg-sunken); padding: 0.125rem 0.3125rem; border-radius: var(--radius-sm); }

/* --- Calculator (compare pages) ------------------------------------------- */

.calculator { border: 1px solid var(--accent-border); background: var(--accent-subtle); border-radius: var(--radius); padding: 1.25rem; }
.calculator__inputs { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(9rem, 100%), 1fr)); gap: 1rem; margin-bottom: 1.25rem; }
.calculator__output { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(10rem, 100%), 1fr)); gap: 1rem; }
.calculator__result { background: var(--bg); border-radius: var(--radius-sm); padding: 0.875rem; text-align: center; }
.calculator__figure { font-family: var(--font-heading); font-weight: 800; font-size: 1.5rem; font-variant-numeric: tabular-nums; }

/* --- Entrance animation (build spec §7) ----------------------------------- */

@keyframes app-rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
.rise { animation: app-rise 320ms cubic-bezier(0.22, 1, 0.36, 1) both; }
.rise:nth-child(2) { animation-delay: 60ms; }
.rise:nth-child(3) { animation-delay: 110ms; }
.rise:nth-child(4) { animation-delay: 120ms; }

/* --- Print ---------------------------------------------------------------- */

@media print {
  .site-header, .site-footer, .facets, .btn, .pagination { display: none !important; }
  body { background: #fff; color: #000; }
  .card { border: 1px solid #ccc; box-shadow: none; break-inside: avoid; }
  a[href^='http']::after { content: ' (' attr(href) ')'; font-size: 0.75em; color: #555; }
}

/* --- Fact bar ------------------------------------------------------------- *
 *
 * The five things a visitor came for, above the fold, before any table. A
 * provider page that opens with twelve rows of "Not published" tells you
 * nothing until you have read all twelve; this tells you the same truth in one
 * glance, and the unpublished cells are visibly quieter than the sourced ones.
 * ------------------------------------------------------------------------- */

.factbar {
  display: grid; gap: 1px; margin: 2rem 0 0; padding: 0;
  grid-template-columns: repeat(auto-fit, minmax(min(9.5rem, 100%), 1fr));
  background: var(--border);
  border: 1px solid var(--border); border-radius: var(--radius);
  overflow: hidden;
}
.factbar__cell { background: var(--bg); padding: 1rem 1.125rem; }
.factbar dt {
  font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--fg-subtle); font-weight: 700; margin-bottom: 0.375rem;
}
.factbar dd {
  margin: 0; font-family: var(--font-heading); font-weight: 700;
  font-size: 1.125rem; line-height: 1.25; color: var(--fg);
  font-variant-numeric: tabular-nums;
}
.factbar dd.factbar__empty {
  font-family: var(--font-sans); font-weight: 400; font-size: 0.9375rem;
  color: var(--fg-subtle); font-style: italic;
}

/* --- Head-to-head --------------------------------------------------------- *
 *
 * A compare page whose only header is an <h1> reading "A vs B" makes you read
 * the table to find out what you are comparing. The two providers get their
 * logos, names and taglines side by side, with the tables below as the detail.
 * ------------------------------------------------------------------------- */

.versus {
  display: grid; align-items: stretch; gap: 1rem;
  grid-template-columns: 1fr auto 1fr;
  margin: 2rem 0;
}
.versus__side {
  display: flex; align-items: center; gap: 0.875rem;
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 1.125rem; min-width: 0;
  text-decoration: none; color: inherit;
}
.versus__side:hover { border-color: var(--border-strong); box-shadow: var(--shadow-sm); }
.versus__side--b { flex-direction: row-reverse; text-align: right; }

.versus__logo {
  width: 3rem; height: 3rem; flex: 0 0 3rem; border-radius: var(--radius-sm);
  background: #fff; border: 1px solid var(--border);
  display: grid; place-items: center; overflow: hidden;
  font-family: var(--font-heading); font-weight: 800; color: var(--fg-muted);
}
.versus__logo img { width: 100%; height: 100%; object-fit: contain; padding: 0.25rem; }

.versus__text { min-width: 0; display: flex; flex-direction: column; }
.versus__text > span { display: block; }
.versus__name { font-family: var(--font-heading); font-weight: 700; font-size: 1.125rem; margin: 0; }
.versus__tagline {
  margin: 0.125rem 0 0; font-size: 0.875rem; color: var(--fg-muted);
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}

.versus__vs {
  display: grid; place-items: center; align-self: center;
  font-family: var(--font-heading); font-weight: 800; font-size: 0.8125rem;
  letter-spacing: 0.08em; color: var(--fg-subtle);
  width: 2.75rem; height: 2.75rem; border-radius: var(--radius-full);
  background: var(--bg-sunken); border: 1px solid var(--border);
}

@media (max-width: 40rem) {
  .versus { grid-template-columns: 1fr; }
  .versus__side--b { flex-direction: row; text-align: left; }
  .versus__vs { width: auto; height: auto; padding: 0.25rem 0.875rem; border-radius: var(--radius-full); justify-self: center; }
}

/* --- Responsive tables ---------------------------------------------------- *
 *
 * .table-wrap scrolls, but without a floor the columns crush: the audit found
 * cells 112px wide wrapping to fifteen lines on a 390px viewport. Give the
 * table a minimum and let the wrapper scroll instead.
 * ------------------------------------------------------------------------- */

.table-wrap > table { min-width: 32rem; }
.table-wrap > table.table--compare { min-width: 40rem; }

@media (max-width: 30rem) {
  th, td { padding: 0.625rem 0.75rem; }
}

/* Long buttons must wrap rather than push the page sideways. */
.btn { max-width: 100%; }
.btn--lg { white-space: normal; text-align: center; }

/* --- Compare: overlap and focus ------------------------------------------- *
 *
 * "What do these two share, and what does each have that the other doesn't" is
 * the question a comparison exists to answer, and a twenty-row table answers it
 * slowest. The bar is proportional, so the shape is readable before the numbers.
 * ------------------------------------------------------------------------- */

.overlap {
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg); margin: 0 0 1.5rem; overflow: hidden;
}
.overlap__row {
  display: grid; grid-template-columns: 9rem 8rem 1fr; align-items: center;
  gap: 1rem; padding: 0.875rem 1.125rem;
  border-bottom: 1px solid var(--border);
}
.overlap__row:last-child { border-bottom: 0; }
.overlap__label { font-weight: 600; font-size: 0.9375rem; }

.overlap__bars { display: flex; height: 0.5rem; border-radius: var(--radius-full); overflow: hidden; background: var(--bg-sunken); }
.overlap__bar { display: block; min-width: 3px; }
.overlap__bar--a { background: var(--accent); }
.overlap__bar--shared { background: var(--ink-400); }
.overlap__bar--b { background: var(--cat-orchestration); }

.overlap__counts { display: flex; flex-wrap: wrap; gap: 0.375rem; }
.overlap__chip {
  font-size: 0.75rem; font-weight: 600; padding: 0.125rem 0.5rem;
  border-radius: var(--radius-full); background: var(--bg-sunken); color: var(--fg-muted);
  white-space: nowrap;
}
.overlap__chip--shared { background: var(--bg-sunken); color: var(--fg-muted); }
.overlap__chip--a { background: var(--accent-subtle); color: var(--accent); }
.overlap__chip--b { background: #ecfeff; color: #0e7490; }

@media (max-width: 44rem) {
  .overlap__row { grid-template-columns: 1fr; gap: 0.5rem; }
  .overlap__bars { order: 3; }
}

/* Plain anchors, not a filter — every section is already in the DOM for
   crawlers, and a widget that hid the rest would be a worse page. */
.focus {
  border: 1px solid var(--accent-border); background: var(--accent-subtle);
  border-radius: var(--radius); padding: 1rem 1.125rem; margin-bottom: 2rem;
}
.focus__title { margin: 0 0 0.625rem; font-weight: 700; font-size: 0.9375rem; }
.focus__chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.focus__chip {
  display: inline-block; padding: 0.4375rem 0.875rem; border-radius: var(--radius-full);
  background: var(--bg); border: 1px solid var(--accent-border);
  font-size: 0.875rem; font-weight: 600; color: var(--accent); text-decoration: none;
}
.focus__chip:hover { background: var(--accent); color: var(--accent-fg); border-color: var(--accent); }

/* A deep-linked row should announce itself rather than leaving you hunting. */
.table--compare tr:target { box-shadow: inset 3px 0 0 var(--accent); background: var(--accent-subtle); }
:target { scroll-margin-top: calc(var(--header-height) + 1rem); }

/* --- Provider: actions and section nav ------------------------------------ */

.actions { display: flex; flex-wrap: wrap; gap: 0.625rem; margin-top: 2rem; }

/* Looks like tabs, behaves like anchors. Real tabs would hide four of the five
   panels, and on an SEO product that means hiding four fifths of the page from
   the thing that has to read it. */
.sectionnav {
  display: flex; gap: 0.25rem; overflow-x: auto; margin-top: 2rem;
  border-bottom: 1px solid var(--border);
  scrollbar-width: none;
}
.sectionnav::-webkit-scrollbar { display: none; }
.sectionnav a {
  flex: 0 0 auto; padding: 0.75rem 1rem; text-decoration: none;
  font-size: 0.9375rem; font-weight: 600; color: var(--fg-muted);
  border-bottom: 2px solid transparent; margin-bottom: -1px; white-space: nowrap;
}
.sectionnav a:hover { color: var(--fg); border-bottom-color: var(--border-strong); }
.sectionnav a:focus-visible { border-radius: var(--radius-sm) var(--radius-sm) 0 0; }

.keyfeatures {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem;
  margin-top: 1.5rem;
}
.keyfeatures__label {
  font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--fg-subtle); font-weight: 700; margin-right: 0.25rem;
}
.tag--more { background: transparent; border: 1px dashed var(--border-strong); }

/* --- Panel ---------------------------------------------------------------- *
 *
 * For a block that needs prominence inside a section without changing the
 * page's alignment. Centring one block on an otherwise left-aligned page — the
 * previous treatment — reads as an accident, especially when the section below
 * it shares the same background and is left-aligned.
 * ------------------------------------------------------------------------- */

.panel {
  background: var(--bg); border: 1px solid var(--border);
  border-radius: var(--radius); padding: clamp(1.5rem, 3vw, 2.25rem);
}
.panel--accent { border-left: 3px solid var(--accent); }
.panel > :last-child { margin-bottom: 0; }

/* A run of same-toned sections shares one band, so the sections inside it need
   their own separation or they read as one undivided wall of text. */
.section--sunken + .section--sunken > .container { padding-top: clamp(2.5rem, 4vw, 3.5rem); }

/* The closing call to action bookends the stats band, so the page opens light,
   is anchored twice in ink, and closes into the ink footer. Left-aligned like
   everything else — a centred block on a left-aligned page reads as unplanned,
   which is what the trust section and this one both used to do. */
.closing {
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: 1.5rem 2rem;
}
.closing > div:first-child { flex: 1 1 26rem; min-width: 0; }

.section--ink .btn--ghost {
  color: var(--brand-periwinkle);
  border-color: color-mix(in oklab, var(--brand-mist) 35%, transparent);
}
.section--ink .btn--ghost:hover {
  color: #fff; border-color: var(--brand-violet);
  background: color-mix(in oklab, var(--brand-violet) 22%, transparent);
}
.section--ink .btn--primary { background: var(--brand-violet); border-color: var(--brand-violet); color: var(--brand-ink); }
.section--ink .btn--primary:hover { background: #a79ce2; border-color: #a79ce2; }

/* An ink band directly above the ink footer would merge with it. */
.section--ink:last-of-type { border-bottom: 0; }

/* --- Auth ----------------------------------------------------------------- *
 *
 * Split screen. The form was previously a bare card floating in white, which
 * told a visitor nothing about what they were signing into.
 * ------------------------------------------------------------------------- */

.auth {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  min-height: calc(100vh - var(--header-height));
  align-items: stretch;
}
.auth__form {
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(2rem, 5vw, 4rem) clamp(1.25rem, 5vw, 4rem);
  max-width: 34rem; margin-inline: auto; width: 100%;
}
.auth__logo {
  display: inline-flex; align-items: center; gap: 0.625rem; margin-bottom: 2rem;
  text-decoration: none; color: var(--fg);
  font-family: var(--font-heading); font-weight: 800; letter-spacing: -0.02em;
}
.auth__logo img { height: 1.75rem; width: auto; display: block; }

.auth__form h1 { font-size: clamp(1.75rem, 1.4rem + 1.2vw, 2.25rem); margin-bottom: 0.5rem; }
.auth__lede { color: var(--fg-muted); margin-bottom: 2rem; }
.auth__fields .field { margin-bottom: 1.25rem; }
.auth__fields input[type='email'] { padding: 0.875rem 1rem; font-size: 1rem; }
.auth__foot { margin-top: 1.75rem; font-size: 0.875rem; color: var(--fg-muted); }

.auth__aside {
  background: var(--brand-ink); color: var(--brand-periwinkle);
  padding: clamp(2rem, 5vw, 4rem);
  display: flex; flex-direction: column; justify-content: center;
}
.auth__eyebrow {
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--brand-violet); margin-bottom: 1rem;
}
.auth__asideTitle {
  color: var(--brand-paper); font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2rem);
  margin-bottom: 2rem; max-width: 18ch;
}
.auth__points { list-style: none; padding: 0; margin: 0; display: grid; gap: 1.5rem; max-width: 34rem; }
.auth__points li { font-size: 0.9375rem; line-height: 1.6; color: var(--brand-mist); padding-left: 1.25rem; position: relative; }
.auth__points li::before {
  content: ''; position: absolute; left: 0; top: 0.55em;
  width: 0.5rem; height: 0.5rem; border-radius: 50%; background: var(--brand-violet);
}
.auth__points strong { display: block; color: var(--brand-paper); font-weight: 700; margin-bottom: 0.25rem; }
.auth__note {
  margin-top: 2.5rem; padding-top: 1.5rem; font-size: 0.8125rem; color: var(--brand-mist);
  border-top: 1px solid color-mix(in oklab, var(--brand-mist) 22%, transparent);
  max-width: 34rem;
}

@media (max-width: 56rem) {
  .auth { grid-template-columns: 1fr; min-height: 0; }
  .auth__aside { order: 2; }
}

/* --- Card polish ---------------------------------------------------------- *
 *
 * Cards were a flat 1px border with a barely-there shadow, which reads as a
 * wireframe. They now have a hairline top highlight, a real lift on hover, and
 * enough padding that the content is not touching the edge.
 * ------------------------------------------------------------------------- */

.card {
  padding: 1.5rem;
  position: relative;
  transition: box-shadow 180ms ease, border-color 180ms ease, transform 180ms ease;
}
.card--interactive:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }

/* Provider cards get the category accent as a top rule, so a wall of them is
   scannable by type without reading a single word. */
.provider-card { display: flex; flex-direction: column; gap: 1rem; overflow: hidden; }
.provider-card::before {
  content: ''; position: absolute; inset: 0 0 auto; height: 3px;
  background: var(--card-accent, var(--border-strong));
  opacity: 0.85;
}
.provider-card__head { display: flex; gap: 0.875rem; align-items: flex-start; }
.provider-card:hover::before { opacity: 1; }

.provider-logo {
  box-shadow: 0 1px 2px rgba(22, 24, 38, 0.06);
  transition: transform 180ms ease;
}
.card--interactive:hover .provider-logo { transform: scale(1.04); }

/* The fee block is the reason the card exists — give it a ground of its own
   instead of letting it float in the same white as everything else. */
.provider-card__facts {
  background: var(--bg-subtle); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 0.875rem 1rem;
  gap: 0.75rem 1rem;
}
.fact__value { font-variant-numeric: tabular-nums; font-weight: 700; }

/* Sponsored slots must never be mistakable for a ranked result. */
.card--sponsored { background: linear-gradient(180deg, var(--accent-subtle), var(--bg) 40%); }

/* Compare: the two sides get their provider's accent, so the eye can hold
   which column is which without re-reading the header on every row. */
.versus__side { transition: box-shadow 180ms ease, border-color 180ms ease, transform 180ms ease; }
.versus__side:hover { transform: translateY(-2px); }
.versus__side--a { border-top: 3px solid var(--accent); }
.versus__side--b { border-top: 3px solid var(--cat-orchestration); }

.table--compare tbody tr { transition: background 120ms ease; }
.table--compare .winner { position: relative; }
.table--compare .winner::after {
  content: '✓'; margin-left: 0.375rem; font-weight: 700; color: var(--success);
}

/* --- Flags ---------------------------------------------------------------- *
 *
 * Real artwork, self-hosted. A fixed box so a row of them cannot shift as they
 * load, and a hairline border because several flags are white at the edge and
 * would otherwise dissolve into the page.
 * ------------------------------------------------------------------------- */

.flag {
  display: inline-block; width: 1.25rem; height: 0.9375rem;
  object-fit: cover; vertical-align: -0.125em;
  border-radius: 2px; border: 1px solid color-mix(in oklab, var(--fg) 12%, transparent);
  background: var(--bg-sunken);
  flex: none;
}

/* The fallback when we hold no artwork for a code. */
.isocode {
  display: inline-block; font-family: var(--font-mono); font-size: 0.75rem;
  font-weight: 700; letter-spacing: 0.02em; padding: 0.0625rem 0.3125rem;
  border-radius: var(--radius-sm); background: var(--bg-sunken); color: var(--fg-muted);
  vertical-align: -0.0625em;
}

/* --- Multi-select --------------------------------------------------------- *
 *
 * 255 checkboxes on one page, all expanded, is not a form — it is a wall. This
 * collapses each group, states how many are chosen without opening it, and
 * filters. Still plain checkboxes underneath, so it submits without JS.
 * ------------------------------------------------------------------------- */

.ms {
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--bg); margin-bottom: 0.875rem; overflow: hidden;
}
.ms[open] { border-color: var(--border-strong); }
.ms.is-filled { border-left: 3px solid var(--accent); }

.ms__summary {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.875rem 1.125rem; cursor: pointer; list-style: none;
  font-weight: 600; user-select: none; min-height: 3rem;
}
.ms__summary::-webkit-details-marker { display: none; }
.ms__summary::after {
  content: '+'; color: var(--fg-subtle); font-size: 1.25rem; line-height: 1; order: 3;
}
.ms[open] .ms__summary::after { content: '−'; }
.ms__summary:hover { background: var(--bg-subtle); }

.ms__label { flex: 1; min-width: 0; }
.ms__count {
  font-size: 0.8125rem; font-weight: 600; color: var(--fg-subtle);
  padding: 0.125rem 0.5rem; border-radius: var(--radius-full); background: var(--bg-sunken);
  white-space: nowrap;
}
.ms.is-filled .ms__count { background: var(--accent-subtle); color: var(--accent); }

.ms__body { padding: 0 1.125rem 1.125rem; border-top: 1px solid var(--border); }
.ms__search { display: flex; gap: 0.5rem; align-items: center; padding-top: 1rem; margin-bottom: 0.875rem; }
.ms__search input { flex: 1; min-width: 0; }
.ms__clear {
  flex: none; background: none; border: 0; cursor: pointer; padding: 0.5rem;
  font-size: 0.8125rem; font-weight: 600; color: var(--accent); text-decoration: underline;
}

.ms__group {
  font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--fg-subtle); font-weight: 700; margin: 1rem 0 0.375rem;
}
.ms__options {
  display: grid; gap: 0.125rem;
  grid-template-columns: repeat(auto-fill, minmax(min(14rem, 100%), 1fr));
  max-height: 20rem; overflow-y: auto;
}
.ms__empty { color: var(--fg-muted); font-size: 0.9375rem; padding: 0.5rem 0; margin: 0; }

.option {
  display: flex; align-items: center; gap: 0.5rem; cursor: pointer;
  padding: 0.4375rem 0.5rem; margin-inline: -0.5rem; border-radius: var(--radius-sm);
  font-size: 0.9375rem; font-weight: 400; margin-bottom: 0; min-height: 2rem;
}
.option:hover { background: var(--bg-subtle); }
.option input { width: 1.125rem; height: 1.125rem; flex: none; accent-color: var(--accent); cursor: pointer; }
.option span { display: inline-flex; align-items: center; gap: 0.4375rem; min-width: 0; }

/* ===========================================================================
   ADMIN
   ---------------------------------------------------------------------------
   The operator's surface. Denser than the public site on purpose: this is a
   screen you work in rather than read, so the type is a step smaller and the
   tables carry more rows per screen. It still inherits every colour token, so
   dark mode and the brand palette come for free.
   =========================================================================== */

.admin-shell {
  display: grid;
  grid-template-columns: 15rem minmax(0, 1fr);
  align-items: start;
  gap: 0;
  min-height: calc(100vh - 4rem);
}

.admin-sidebar {
  position: sticky;
  top: 0;
  align-self: start;
  max-height: 100vh;
  overflow-y: auto;
  padding: 1.75rem 1rem 3rem;
  border-right: 1px solid var(--border);
  background: var(--bg-subtle);
}

.admin-sidebar__group {
  margin: 1.5rem 0 0.5rem;
  padding-inline: 0.625rem;
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--fg-subtle);
}
.admin-sidebar__group:first-child { margin-top: 0; }

.admin-sidebar__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.125rem; }

.admin-sidebar__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.5rem 0.625rem;
  border-radius: var(--radius-sm);
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--fg-muted);
  text-decoration: none;
}
.admin-sidebar__link:hover { background: var(--bg); color: var(--fg); text-decoration: none; }
.admin-sidebar__link.is-current {
  background: var(--accent-subtle);
  color: var(--accent);
  font-weight: 600;
  box-shadow: inset 2px 0 0 var(--accent);
}

.admin-sidebar__badge {
  flex: none;
  min-width: 1.375rem;
  padding: 0.0625rem 0.4375rem;
  border-radius: var(--radius-full);
  background: var(--accent);
  color: var(--accent-fg);
  font-size: 0.75rem;
  font-weight: 700;
  text-align: center;
}

.admin-main { padding: 2rem 2rem 4rem; min-width: 0; }
.admin-main > .alert { margin-bottom: 1.5rem; }

.admin-who {
  font-size: 0.8125rem;
  color: var(--brand-mist);
  max-width: 14rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Page heading with actions on the right. */
.admin-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.75rem;
}
.admin-head h1 { margin: 0; font-size: 1.5rem; }
.admin-head p { margin: 0.375rem 0 0; color: var(--fg-muted); font-size: 0.9375rem; max-width: 62ch; }

/* Stat tiles. */
.admin-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
  gap: 1rem;
  margin-bottom: 2rem;
}

.tile {
  display: block;
  padding: 1.125rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
  text-decoration: none;
  color: inherit;
}
a.tile:hover { border-color: var(--accent-border); box-shadow: var(--shadow-sm); text-decoration: none; }

.tile__label {
  margin: 0;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--fg-subtle);
}
.tile__value {
  margin: 0.375rem 0 0;
  font-family: var(--font-display, inherit);
  font-size: 1.875rem;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
}
.tile__note { margin: 0.375rem 0 0; font-size: 0.8125rem; color: var(--fg-muted); }
.tile--alert { border-color: var(--warning); background: var(--warning-bg); }
.tile--alert .tile__value { color: var(--warning); }
.tile--good .tile__value { color: var(--success); }

/* A labelled proportion, e.g. "38 of 1,376 have a sourced fee". */
.meter {
  height: 0.5rem;
  margin-top: 0.625rem;
  border-radius: var(--radius-full);
  background: var(--bg-sunken);
  overflow: hidden;
}
.meter__fill { display: block; height: 100%; border-radius: inherit; background: var(--accent); }
.meter__fill--good { background: var(--success); }
.meter__fill--warn { background: var(--warning); }

/* Two-column body: main work on the left, context on the right. */
.admin-split {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: 2rem;
  align-items: start;
}

/* Filter bar above a table. */
.admin-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.75rem;
  padding: 1rem;
  margin-bottom: 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-subtle);
}
.admin-filters .field { margin: 0; min-width: 9rem; }
.admin-filters .field label { font-size: 0.75rem; margin-bottom: 0.25rem; }
.admin-filters select,
.admin-filters input { font-size: 0.875rem; padding: 0.4375rem 0.625rem; }

/* Bulk-action bar. Hidden until something is ticked, but present in the DOM so
   it works with scripting off — the buttons simply sit there permanently. */
.bulkbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
  border: 1px solid var(--accent-border);
  border-radius: var(--radius);
  background: var(--accent-subtle);
  font-size: 0.875rem;
}
.bulkbar__count { font-weight: 600; color: var(--accent); }
.bulkbar select { font-size: 0.875rem; padding: 0.375rem 0.5rem; }

.admin-table { font-size: 0.875rem; }
.admin-table th { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.04em; }
.admin-table td { vertical-align: top; padding-block: 0.625rem; }
.admin-table tbody tr:hover { background: var(--bg-subtle); }
.admin-table .tick { width: 2.5rem; }
.admin-table .tick input { width: 1.0625rem; height: 1.0625rem; accent-color: var(--accent); }
.admin-table__sub { display: block; font-size: 0.75rem; color: var(--fg-subtle); }

/* Job runner output. */
.joblog {
  max-height: 26rem;
  overflow: auto;
  padding: 1rem 1.125rem;
  border-radius: var(--radius);
  background: var(--ink-950);
  color: var(--ink-300);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 0.8125rem;
  line-height: 1.6;
  white-space: pre-wrap;
  word-break: break-word;
}

.joblist { display: grid; gap: 0.75rem; }
.joblist__item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 1.125rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
}
.joblist__item h3 { margin: 0; font-size: 1rem; }
.joblist__item p { margin: 0.25rem 0 0; font-size: 0.875rem; color: var(--fg-muted); max-width: 58ch; }

/* The gap register on /admin/data. */
.gaplist { display: grid; gap: 0.75rem; margin: 0; padding: 0; list-style: none; }
.gaplist__item {
  display: grid;
  grid-template-columns: 5rem minmax(0, 1fr) auto;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.125rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg);
}
.gaplist__count {
  font-family: var(--font-display, inherit);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
}
.gaplist__count--zero { color: var(--success); }
.gaplist__item h3 { margin: 0; font-size: 0.9375rem; }
.gaplist__item p { margin: 0.25rem 0 0; font-size: 0.8125rem; color: var(--fg-muted); }

@media (max-width: 60rem) {
  .admin-shell { grid-template-columns: minmax(0, 1fr); }
  .admin-sidebar {
    position: static;
    max-height: none;
    border-right: 0;
    border-bottom: 1px solid var(--border);
    padding-bottom: 1.25rem;
  }
  .admin-sidebar__list {
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    overflow-x: auto;
    padding-bottom: 0.25rem;
  }
  .admin-sidebar__link.is-current { box-shadow: inset 0 -2px 0 var(--accent); }
  .admin-main { padding: 1.5rem 1.25rem 3rem; }
  .admin-split { grid-template-columns: minmax(0, 1fr); }
  .gaplist__item { grid-template-columns: 4rem minmax(0, 1fr); }
  .gaplist__item > :last-child { grid-column: 1 / -1; }
}
