/* ==========================================================================
   Rankfile — default theme
   --------------------------------------------------------------------------
   Hand-authored, token-driven CSS. No build step and no framework runtime, so
   the whole stylesheet ships in one request.

   Every colour, radius, width and font here is a custom property whose value
   the admin panel writes into an inline <style> block in <head>. Editing the
   theme settings restyles the site without touching this file.

   Structure:
     1. Tokens
     2. Reset and base
     3. Layout primitives
     4. Typography
     5. Buttons, badges, pills
     6. Header and navigation
     7. Rank list  <- the signature element
     8. Comparison cards and their optional blocks
     9. Matrix / table layout
    10. Page sections
    11. Footer, cookie bar, sticky CTA
    12. Responsive
    13. Dark mode, motion, print
   ========================================================================== */

/* 1. Tokens ---------------------------------------------------------------- */

:root {
  /* Overridden per-site from theme settings. */
  --c-primary: #1b4dff;
  --c-secondary: #121826;
  --c-accent: #ffb020;
  --c-positive: #0f9d77;
  --c-negative: #dc3b49;

  --ink: #121826;
  --ink-2: #414b60;
  --ink-3: #6b7488;
  --paper: #f6f7f9;
  --surface: #ffffff;
  --line: #e3e6ec;
  --line-strong: #cbd1dc;

  --radius: 14px;
  --radius-sm: 8px;
  --radius-pill: 999px;
  --container: 1180px;
  --scale: 1;

  --shadow-1: 0 1px 2px rgb(18 24 38 / 6%), 0 1px 3px rgb(18 24 38 / 4%);
  --shadow-2: 0 4px 12px rgb(18 24 38 / 8%), 0 2px 4px rgb(18 24 38 / 4%);
  --shadow-3: 0 12px 32px rgb(18 24 38 / 12%);

  --font-body: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  --font-display: var(--font-body);
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;

  /* Spacing scale, multiplied by the theme's spacing setting. */
  --s1: calc(0.25rem * var(--scale));
  --s2: calc(0.5rem * var(--scale));
  --s3: calc(0.75rem * var(--scale));
  --s4: calc(1rem * var(--scale));
  --s5: calc(1.5rem * var(--scale));
  --s6: calc(2rem * var(--scale));
  --s7: calc(3rem * var(--scale));
  --s8: calc(4.5rem * var(--scale));

  --header-h: 64px;
}

/* 2. Reset and base -------------------------------------------------------- */

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

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

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, svg, video { max-width: 100%; height: auto; display: block; }
img { border-style: none; }

a { color: var(--c-primary); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { text-decoration-thickness: 2px; }

button, input, select, textarea { font: inherit; color: inherit; }

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

/* Visible, consistent keyboard focus everywhere. */
:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--c-primary) 55%, transparent);
  outline-offset: 2px;
  border-radius: 4px;
}

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

.skip-link {
  position: absolute; left: var(--s4); top: -100px; z-index: 100;
  background: var(--surface); color: var(--ink); padding: var(--s3) var(--s4);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-2);
  transition: top .15s ease;
}
.skip-link:focus { top: var(--s4); }

/* Safety net: a block that somehow renders with no content takes no space. */
.rf-auto:empty { display: none; }

/* 3. Layout primitives ----------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--s4);
}
.wrap--narrow { max-width: 760px; }
.wrap--wide { max-width: calc(var(--container) + 200px); }

.stack > * + * { margin-top: var(--s4); }
.stack-lg > * + * { margin-top: var(--s6); }

.row { display: flex; flex-wrap: wrap; gap: var(--s3); align-items: center; }
.row--between { justify-content: space-between; }
.row--end { justify-content: flex-end; }

.section { padding-block: var(--s7); }
.section:first-child { padding-top: var(--s6); }
.section--tight { padding-block: var(--s5); }
.section--flush { padding-block: 0; }

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s5);
  box-shadow: var(--shadow-1);
}

/* 4. Typography ------------------------------------------------------------ */

h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: 1.15;
  letter-spacing: -0.022em;
  margin: 0 0 var(--s3);
  font-weight: 700;
  color: var(--ink);
  text-wrap: balance;
  /* text-wrap: balance decides where to break; it cannot break a word that
     has nowhere to break. A long product name or a pasted URL would otherwise
     run straight out of the column. */
  overflow-wrap: anywhere;
}

h1 { font-size: clamp(2rem, 1.35rem + 2.4vw, 3rem); letter-spacing: -0.032em; }
h2 { font-size: clamp(1.5rem, 1.2rem + 1.2vw, 2.05rem); }
h3 { font-size: clamp(1.2rem, 1.08rem + 0.5vw, 1.4rem); }
h4 { font-size: 1.05rem; }

p { margin: 0 0 var(--s4); }
p:last-child { margin-bottom: 0; }

.lede { font-size: 1.135rem; color: var(--ink-2); line-height: 1.6; text-wrap: pretty; }
.muted { color: var(--ink-3); }
.small { font-size: 0.875rem; }
.tiny { font-size: 0.8125rem; }

.eyebrow {
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: var(--s2);
}

.prose { overflow-wrap: break-word; }
.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }
.prose h2, .prose h3 { margin-top: var(--s6); }
.prose ul, .prose ol { padding-left: 1.25em; margin: 0 0 var(--s4); }
.prose li + li { margin-top: var(--s2); }
.prose img { border-radius: var(--radius-sm); margin-block: var(--s5); }
.prose blockquote {
  margin: var(--s5) 0; padding: var(--s2) 0 var(--s2) var(--s4);
  border-left: 3px solid var(--c-accent); color: var(--ink-2); font-style: italic;
}
.prose table { width: 100%; border-collapse: collapse; margin-block: var(--s5); }
.prose th, .prose td { padding: var(--s3); border-bottom: 1px solid var(--line); text-align: left; }

/* Numerals in ranks, scores and prices must never jitter between values. */
.tnum { font-variant-numeric: tabular-nums lining-nums; }

/* 5. Buttons, badges, pills ------------------------------------------------ */

.btn {
  --btn-bg: var(--c-primary);
  --btn-fg: #fff;
  overflow-wrap: anywhere;
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s2);
  padding: 0.72em 1.25em;
  min-height: 44px;               /* comfortable touch target */
  font-weight: 650; font-size: 0.95rem; line-height: 1.2;
  text-decoration: none; text-align: center;
  border: 1px solid transparent; border-radius: var(--radius-sm);
  background: var(--btn-bg); color: var(--btn-fg);
  cursor: pointer;
  transition: transform .12s ease, box-shadow .12s ease, background-color .12s ease;
}
.btn:hover { text-decoration: none; box-shadow: var(--shadow-2); transform: translateY(-1px); }
.btn:active { transform: translateY(0); }

.btn--block { display: flex; width: 100%; }
.btn--lg { font-size: 1.02rem; padding: 0.85em 1.5em; min-height: 50px; }
.btn--sm { font-size: 0.85rem; padding: 0.5em 0.9em; min-height: 36px; }

.btn--accent { --btn-bg: var(--c-accent); --btn-fg: #2a1c00; }
.btn--dark { --btn-bg: var(--c-secondary); --btn-fg: #fff; }
.btn--ghost {
  --btn-bg: transparent; --btn-fg: var(--c-primary);
  border-color: var(--line-strong);
}
.btn--ghost:hover { background: var(--paper); }
.btn--quiet { --btn-bg: transparent; --btn-fg: var(--ink-2); padding-inline: 0; min-height: 0; }
.btn--quiet:hover { box-shadow: none; transform: none; color: var(--c-primary); }

/* Button style variants set from theme settings. */
[data-btn="pill"] .btn { border-radius: var(--radius-pill); }
[data-btn="square"] .btn { border-radius: 2px; }
[data-btn="outline"] .btn {
  background: transparent; color: var(--c-primary); border-color: currentColor;
}
[data-btn="outline"] .btn:hover { background: var(--c-primary); color: #fff; }

.badge {
  display: inline-flex; align-items: center; gap: 0.35em;
  padding: 0.28em 0.7em;
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.03em;
  text-transform: uppercase;
  border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--c-primary) 10%, transparent);
  color: var(--c-primary);
  white-space: nowrap;
}
.badge--award { background: color-mix(in srgb, var(--c-accent) 22%, transparent); color: #7a4d00; }
.badge--positive { background: color-mix(in srgb, var(--c-positive) 14%, transparent); color: var(--c-positive); }
.badge--neutral { background: var(--paper); color: var(--ink-3); }

.pill {
  display: inline-flex; align-items: center;
  padding: 0.3em 0.75em;
  font-size: 0.82rem; border-radius: var(--radius-pill);
  background: var(--paper); color: var(--ink-2); border: 1px solid var(--line);
  /* Short labels sit on one line naturally because the pill sizes to its
     content; a long one wraps instead of escaping the card. */
  max-width: 100%;
  overflow-wrap: anywhere;
}

.pill-list { display: flex; flex-wrap: wrap; gap: var(--s2); margin: 0; padding: 0; list-style: none; }

.ribbon {
  position: absolute; top: 0; right: 0;
  padding: 0.3em 0.85em;
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: #2a1c00; background: var(--c-accent);
  border-radius: 0 var(--radius) 0 var(--radius-sm);
}

/* 6. Header and navigation ------------------------------------------------- */

.site-header {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  position: relative; z-index: 40;
}
.site-header[data-sticky="1"] { position: sticky; top: 0; }

.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--s2) var(--s4);
  min-height: var(--header-h);
  padding-block: var(--s2);
}

.brand { display: inline-flex; align-items: center; gap: var(--s3); text-decoration: none; color: var(--ink); }
.brand__logo { max-height: 38px; width: auto; }
.brand__name { font-family: var(--font-display); font-weight: 800; font-size: 1.16rem; letter-spacing: -0.02em; }
.brand__tagline { font-size: 0.8rem; color: var(--ink-3); }

.nav { display: flex; align-items: center; gap: var(--s1); min-width: 0; }
/* Scoped to the direct child: a descendant selector here outranks .nav__sub
   and would force every dropdown open. Shared resets stay separate, and
   deliberately set no `display`. */
/* Wrapping matters: without it a long menu pushes the header wider than the
   viewport and takes the burger button off-screen with it. */
.nav > ul { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s1); }
.nav ul { list-style: none; margin: 0; padding: 0; }
.nav li { position: relative; }

.nav a {
  display: inline-flex; align-items: center; gap: var(--s2);
  padding: 0.55em 0.75em;
  font-size: 0.94rem; font-weight: 550; color: var(--ink-2);
  text-decoration: none; border-radius: var(--radius-sm);
  /* Labels stay on one line; the list wraps instead. Breaking a menu label
     mid-word looks like a fault rather than a design. */
  white-space: nowrap;
}
.nav a:hover, .nav a[aria-current="page"] { color: var(--ink); background: var(--paper); }

.nav__sub {
  position: absolute; top: 100%; left: 0; min-width: 208px;
  display: none; flex-direction: column; gap: 0;
  padding: var(--s2);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-3);
}
.nav li:hover > .nav__sub,
.nav li:focus-within > .nav__sub { display: flex; }
.nav__sub a { width: 100%; }
/* The last item sits at the right edge, so its panel opens leftwards instead
   of pushing past the viewport. */
.nav > ul > li:last-child > .nav__sub { left: auto; right: 0; }
/* Never wider than the viewport, however long the child labels are. */
.nav__external { font-size: 0.75em; opacity: 0.6; }
.nav__sub { max-width: min(320px, calc(100vw - 2rem)); }
.nav__sub a { white-space: normal; }

.nav-toggle {
  display: none; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  background: none; border: 1px solid var(--line); border-radius: var(--radius-sm);
  cursor: pointer;
}

.mode-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: none; cursor: pointer; color: var(--ink-2);
}
.mode-toggle:hover { background: var(--paper); }

/* 7. Rank list — the signature element ------------------------------------- */
/*
   The ranking is the page, so the numbering is the structure rather than an
   ornament: a hairline spine runs down the list with the position set in large
   tabular numerals, and the award winner gets the only filled marker.
*/

.rank-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s4); }

/*
   The numeral sits inside the card rather than in a column beside it.
   A separate rail column cost 76px of layout width, which pushed every card
   that far right of the page heading, the repeated top pick and every section
   below it — one page with two left edges. The number is just as prominent
   here, the cards line up with everything else, and the numerals still form
   their own vertical line because every card shares that same edge.
*/

.rank-item { position: relative; }

.rank-rail {
  position: absolute;
  top: var(--s4);
  left: var(--s5);
  z-index: 2;
}

.rank-num {
  display: flex; align-items: center; justify-content: center;
  min-width: 38px; height: 30px;
  padding-inline: 0.55em;
  font-family: var(--font-display);
  font-size: 1.02rem; font-weight: 800; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--ink-2);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-pill);
}

/* The card reserves a row for it, so the numeral never lands on the logo. */
.rank-item > .card { padding-top: calc(var(--s5) + 34px); }

.rank-item[data-award]:not([data-award=""]) .rank-num {
  color: #2a1c00;
  background: var(--c-accent);
  border-color: color-mix(in srgb, var(--c-accent) 70%, #000);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--c-accent) 20%, transparent);
}

/* 8. Comparison cards ------------------------------------------------------ */

.card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  padding: var(--s5);
  transition: box-shadow .16s ease, border-color .16s ease;
}
.card:hover { box-shadow: var(--shadow-2); border-color: var(--line-strong); }
.card[data-award]:not([data-award=""]) {
  border-color: color-mix(in srgb, var(--c-accent) 55%, var(--line));
  box-shadow: var(--shadow-2);
}

/*
   Three zones: brand, body, action. `align-items: start` plus `gap` means a
   zone that renders nothing simply collapses — there is no empty column and
   no leftover margin, because spacing lives entirely in the gap.
*/
.card__grid {
  display: grid;
  grid-template-columns: minmax(140px, 200px) minmax(0, 1fr) minmax(170px, 215px);
  gap: var(--s5);
  align-items: start;
}

.card__brand {
  display: flex; flex-direction: column; gap: var(--s3); align-items: flex-start;
  /* A grid child defaults to min-width:auto, which lets a long business name
     widen the whole column past its maximum. */
  min-width: 0;
}

.card__logo {
  width: 100%; max-width: 190px; height: 58px;
  object-fit: contain; object-position: left center;
}

.card__name {
  font-size: 1.22rem; font-weight: 750; letter-spacing: -0.02em; margin: 0;
  overflow-wrap: anywhere;
}
.card__tagline { font-size: 0.87rem; color: var(--ink-3); margin: 0; overflow-wrap: anywhere; }

.card__body { display: flex; flex-direction: column; gap: var(--s4); min-width: 0; }
.card__desc { margin: 0; color: var(--ink-2); }

.card__action {
  display: flex; flex-direction: column; gap: var(--s3);
  align-items: stretch;
  min-width: 0;
}
.card__cta-note { text-align: center; font-size: 0.8rem; color: var(--ink-3); }

/* Where the button sits in its column.
   Scoped to the three-zone grid on purpose: in the stacked, minimal and
   feature layouts the action is laid out differently, and alignment here would
   fight those rules rather than help. */

/* The brand column takes the same three positions as the action column. */

.card__grid > .card__brand[data-brand="middle"] { align-self: center; }

.card__grid > .card__brand[data-brand="floating"] {
  align-self: start;
  position: sticky;
  top: calc(var(--header-h) + var(--s4));
}

.card__grid > .card__action[data-cta="middle"] { align-self: center; }

/* Sticky needs somewhere to travel, so the zone stays top-aligned and the
   offset clears the sticky header. On a short card there is no travel and it
   simply behaves like "top". */
.card__grid > .card__action[data-cta="floating"] {
  align-self: start;
  position: sticky;
  top: calc(var(--header-h) + var(--s4));
}

@media (max-width: 900px) {
  /* The grid has collapsed and the zones have rearranged, so both alignments
     stop meaning anything. */
  .card__grid > .card__action[data-cta="middle"],
  .card__grid > .card__action[data-cta="floating"],
  .card__grid > .card__brand[data-brand="middle"],
  .card__grid > .card__brand[data-brand="floating"] {
    align-self: start;
    position: static;
  }
}

@media print {
  .card__grid > .card__action[data-cta="floating"],
  .card__grid > .card__brand[data-brand="floating"] { position: static; }
}

/* Page header --------------------------------------------------------------- */
/*
   Three treatments for a comparison heading: plain, a full-bleed cover image,
   or a picture beside the text.

   On a cover the text must stay legible over a photograph nobody has vetted,
   so contrast is not left to the image. A gradient scrim sits between the two,
   weighted towards whichever side the text is on, and there is a floor beneath
   even the lightest setting — a "no overlay" option would just be a promise
   the theme cannot keep.
*/

.page-head { padding-block: var(--s6) var(--s5); }
.page-head__text { overflow-wrap: anywhere; min-width: 0; }
.page-head__text > :last-child { margin-bottom: 0; }
.page-head__meta { margin: var(--s3) 0 0; font-size: 0.875rem; color: var(--ink-3); }
.page-head__disclosure { margin-top: var(--s4); }

/* -- Cover ------------------------------------------------------------------ */

.page-head--cover {
  position: relative;
  display: flex;
  align-items: center;
  padding-block: var(--s7);
  overflow: hidden;
  background: var(--c-secondary);
  --scrim-near: 0.62;
  --scrim-far: 0.28;
}

.page-head--cover[data-height="compact"] { min-height: 220px; }
.page-head--cover[data-height="standard"] { min-height: 330px; }
.page-head--cover[data-height="tall"] { min-height: 460px; padding-block: var(--s8); }

.page-head--cover[data-overlay="subtle"] { --scrim-near: 0.42; --scrim-far: 0.16; }
.page-head--cover[data-overlay="light"] { --scrim-near: 0.54; --scrim-far: 0.22; }
.page-head--cover[data-overlay="medium"] { --scrim-near: 0.68; --scrim-far: 0.34; }
.page-head--cover[data-overlay="strong"] { --scrim-near: 0.84; --scrim-far: 0.58; }

.page-head__image {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}

/* The scrim: heavier behind the text, lighter where the photograph can show. */
.page-head--cover::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(
      100deg,
      rgb(10 14 21 / var(--scrim-near)) 0%,
      rgb(10 14 21 / var(--scrim-near)) 34%,
      rgb(10 14 21 / var(--scrim-far)) 78%,
      rgb(10 14 21 / var(--scrim-far)) 100%
    ),
    linear-gradient(to top, rgb(10 14 21 / 30%) 0%, rgb(10 14 21 / 0%) 55%);
}

.page-head--cover[data-align="center"]::after {
  background:
    linear-gradient(
      to bottom,
      rgb(10 14 21 / var(--scrim-far)) 0%,
      rgb(10 14 21 / var(--scrim-near)) 55%,
      rgb(10 14 21 / var(--scrim-near)) 100%
    );
}

.page-head--cover .page-head__inner {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: var(--s5);
}

.page-head--cover .page-head__text {
  flex: 1 1 auto;
  max-width: 46rem;
  color: #fff;
  /* Second line of defence on a busy photograph: costs nothing and rescues
     the awkward cases the scrim alone does not. */
  text-shadow: 0 1px 2px rgb(0 0 0 / 45%);
}
.page-head--cover h1 { color: #fff; }
.page-head--cover .lede { color: rgb(255 255 255 / 88%); }
.page-head--cover .page-head__meta { color: rgb(255 255 255 / 72%); }

.page-head--cover[data-align="center"] .page-head__inner { justify-content: center; }
.page-head--cover[data-align="center"] .page-head__text { text-align: center; margin-inline: auto; }

/* The disclosure is a card, so it keeps its own surface and drops the shadow
   the surrounding text is carrying. */
.page-head--cover .page-head__disclosure .disclosure {
  background: rgb(255 255 255 / 94%);
  border-color: transparent;
  text-shadow: none;
}

.page-head--cover .page-head__badge {
  flex: none;
  width: 120px; height: 120px;
  object-fit: contain;
  filter: drop-shadow(0 4px 12px rgb(0 0 0 / 35%));
}

/* -- Animated waves ---------------------------------------------------------- */
/*
   A header that draws itself. Worth knowing what it costs and what it does
   not: with no image there is nothing to download and no largest-contentful
   paint to wait for, so a wave header is the quickest of the four. The motion
   animates transform only, which the compositor handles without touching
   layout — a background that reflowed the page sixty times a second would cost
   far more than it is worth.

   Colours come from the theme tokens, so it always looks like part of the site
   rather than a widget dropped onto it.
*/

.page-head--wave {
  position: relative;
  display: flex;
  align-items: center;
  padding-block: var(--s7) calc(var(--s7) + 40px);
  overflow: hidden;
  background:
    linear-gradient(
      152deg,
      var(--c-secondary) 0%,
      color-mix(in srgb, var(--c-primary) 42%, var(--c-secondary)) 58%,
      color-mix(in srgb, var(--c-primary) 68%, var(--c-secondary)) 100%
    );
}

.page-head--wave[data-height="compact"] { min-height: 240px; }
.page-head--wave[data-height="standard"] { min-height: 340px; }
.page-head--wave[data-height="tall"] { min-height: 470px; }

.page-head--wave .page-head__inner {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: var(--s5);
}

.page-head--wave .page-head__text {
  flex: 1 1 auto;
  max-width: 46rem;
  color: #fff;
  text-shadow: 0 1px 2px rgb(0 0 0 / 35%);
}
.page-head--wave h1 { color: #fff; }
.page-head--wave .lede { color: rgb(255 255 255 / 88%); }
.page-head--wave .page-head__meta { color: rgb(255 255 255 / 72%); }
.page-head--wave .page-head__disclosure .disclosure {
  background: rgb(255 255 255 / 94%);
  border-color: transparent;
  text-shadow: none;
}

.page-head--wave[data-align="center"] .page-head__inner { justify-content: center; }
.page-head--wave[data-align="center"] .page-head__text { text-align: center; margin-inline: auto; }

.page-head--wave .page-head__badge {
  flex: none;
  width: 120px; height: 120px;
  object-fit: contain;
  filter: drop-shadow(0 4px 12px rgb(0 0 0 / 32%));
}

/* An image is optional here; when present the waves ride over it, and the
   scrim keeps the heading readable exactly as it does on a cover. */
.page-head--wave .page-head__image { opacity: 0.55; }
.page-head--wave[data-overlay="subtle"] .page-head__image { opacity: 0.75; }
.page-head--wave[data-overlay="light"] .page-head__image { opacity: 0.65; }
.page-head--wave[data-overlay="strong"] .page-head__image { opacity: 0.35; }

.waves {
  position: absolute;
  inset-inline: 0;
  bottom: -1px;              /* hides the hairline some browsers leave */
  height: clamp(60px, 9vw, 120px);
  z-index: 0;
  pointer-events: none;
}
.waves svg { display: block; width: 100%; height: 100%; }

/*
   One period of the path is 176 user units and the path runs 704, so a
   176-unit translate lands on an identical position with no edge ever
   entering the viewBox. Anything less than a whole period visibly jumps.
*/
.waves__set use {
  animation: rf-wave-drift 18s cubic-bezier(0.55, 0.5, 0.45, 0.5) infinite;
  will-change: transform;
}

.waves__set use:nth-child(1) {
  fill: color-mix(in srgb, var(--c-primary) 34%, transparent);
  animation-duration: 13s; animation-delay: -2s;
}
.waves__set use:nth-child(2) {
  fill: color-mix(in srgb, var(--c-primary) 22%, transparent);
  animation-duration: 17s; animation-delay: -3s;
}
.waves__set use:nth-child(3) {
  fill: color-mix(in srgb, var(--c-accent) 16%, transparent);
  animation-duration: 22s; animation-delay: -4s;
}
.waves__set use:nth-child(4) {
  /* The last one is the page's own background, so the header dissolves into
     the content below rather than stopping at a hard edge. */
  fill: var(--paper);
  animation-duration: 28s; animation-delay: -5s;
}

@keyframes rf-wave-drift {
  from { transform: translateX(-176px); }
  to { transform: translateX(0); }
}

/* Motion is opt-out twice over: the editor can still the waves for everyone,
   and a visitor who has asked their system for less motion gets a static
   header regardless of that choice. Continuous background movement is a real
   problem for vestibular disorders, not a preference. */
.page-head--wave[data-motion="still"] .waves__set use { animation: none; }

@media (prefers-reduced-motion: reduce) {
  .waves__set use { animation: none; will-change: auto; }
}

@media (max-width: 760px) {
  .page-head--wave { padding-block: var(--s6) calc(var(--s6) + 30px); }
  .page-head--wave[data-height="standard"] { min-height: 270px; }
  .page-head--wave[data-height="tall"] { min-height: 350px; }
  .page-head--wave .page-head__inner { flex-direction: column; align-items: flex-start; gap: var(--s4); }
  .page-head--wave[data-align="center"] .page-head__inner { align-items: center; }
  .page-head--wave .page-head__badge { width: 84px; height: 84px; }
}

@media print {
  .waves { display: none; }
  .page-head--wave { min-height: 0; background: none; padding-block: var(--s4); }
  .page-head--wave .page-head__text { color: var(--ink); text-shadow: none; }
  .page-head--wave h1, .page-head--wave .lede { color: var(--ink); }
}

/* -- Thumbnail beside the text ---------------------------------------------- */

.page-head--thumb { padding-block: var(--s6) var(--s5); }

.page-head--thumb .page-head__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(240px, 0.9fr);
  gap: var(--s6);
  align-items: center;
}

.page-head--thumb[data-align="left"] .page-head__text { order: 2; }
.page-head--thumb[data-align="left"] .page-head__aside { order: 1; }

.page-head__aside { position: relative; }

.page-head__thumb {
  width: 100%;
  aspect-ratio: 13 / 9;
  object-fit: cover;
  border-radius: var(--radius);
  box-shadow: var(--shadow-2);
}

.page-head--thumb .page-head__badge {
  position: absolute;
  right: calc(-1 * var(--s3));
  bottom: calc(-1 * var(--s3));
  width: 110px; height: 110px;
  object-fit: contain;
  filter: drop-shadow(0 4px 12px rgb(18 24 38 / 22%));
}

@media (max-width: 900px) {
  .page-head--thumb .page-head__inner { grid-template-columns: minmax(0, 1fr); gap: var(--s5); }
  /* Text first on a narrow screen whichever side the picture sits on: the
     heading is what the reader came for. */
  .page-head--thumb[data-align="left"] .page-head__text,
  .page-head--thumb .page-head__text { order: 1; }
  .page-head--thumb[data-align="left"] .page-head__aside,
  .page-head--thumb .page-head__aside { order: 2; }
  .page-head__thumb { aspect-ratio: 16 / 9; }
  .page-head--thumb .page-head__badge { width: 84px; height: 84px; }
}

@media (max-width: 760px) {
  .page-head--cover { padding-block: var(--s6); }
  .page-head--cover[data-height="tall"] { min-height: 340px; padding-block: var(--s7); }
  .page-head--cover[data-height="standard"] { min-height: 260px; }
  .page-head--cover .page-head__inner { flex-direction: column; align-items: flex-start; gap: var(--s4); }
  .page-head--cover[data-align="center"] .page-head__inner { align-items: center; }
  .page-head--cover .page-head__badge { width: 84px; height: 84px; }
}

@media print {
  .page-head__image, .page-head--cover::after { display: none; }
  .page-head--cover { min-height: 0; background: none; padding-block: var(--s4); }
  .page-head--cover .page-head__text { color: var(--ink); text-shadow: none; }
  .page-head--cover h1, .page-head--cover .lede { color: var(--ink); }
}

/* Repeated top pick --------------------------------------------------------- */
/*
   The same entry as rank 1, shown again under the list. Tinted and labelled so
   it reads as a deliberate recap rather than a stray duplicate row.
*/

.top-pick {
  display: block;
  margin-top: var(--s5);
  padding: var(--s5);
  background: color-mix(in srgb, var(--c-accent) 7%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--c-accent) 50%, var(--line));
  border-radius: var(--radius);
  box-shadow: var(--shadow-2);
}

.top-pick__label {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3);
  margin-bottom: var(--s4);
}
.top-pick__rank {
  font-size: 0.78rem; font-weight: 650; color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

/* Slightly quieter than the card above it: this is a reminder, not a second
   first place. */
.top-pick .card__name { font-size: 1.15rem; }

@media (max-width: 760px) {
  .top-pick { padding: var(--s4); }
}

@media print {
  .top-pick { break-inside: avoid; }
}

/* Whole-card affiliate links ------------------------------------------------ */
/*
   Opt-in per comparison page. The attribute is written by the template; the
   -ready flag is added by the script, so the pointer cursor only appears when
   the behaviour is genuinely wired up.
*/

[data-card-link][data-card-ready] { cursor: pointer; }

[data-card-link][data-card-ready]:hover {
  border-color: color-mix(in srgb, var(--c-primary) 45%, var(--line));
  box-shadow: var(--shadow-2);
}

/* Text stays selectable, so give it the cursor that says so — the click
   handler ignores a click that follows a selection. */
[data-card-link][data-card-ready] p,
[data-card-link][data-card-ready] li,
[data-card-link][data-card-ready] dd,
[data-card-link][data-card-ready] .card__desc,
[data-card-link][data-card-ready] .details__body { cursor: text; }

/* Controls inside keep their own cursor and their own click. */
[data-card-link][data-card-ready] a,
[data-card-link][data-card-ready] button,
[data-card-link][data-card-ready] summary { cursor: pointer; }

/* Table rows and dense rows get the same affordance. */
tr[data-card-link][data-card-ready]:hover td { background: color-mix(in srgb, var(--c-primary) 6%, transparent); }
.minimal-row[data-card-link][data-card-ready]:hover { box-shadow: var(--shadow-2); }

/* Keyboard users reach the button inside, not the card, so make that
   obvious by lifting the whole card when anything in it is focused. */
[data-card-link][data-card-ready]:focus-within { box-shadow: var(--shadow-2); }

/* Rating -------------------------------------------------------------------- */

.rating { display: flex; align-items: center; gap: var(--s2); }

.rating__score {
  display: flex; align-items: baseline; gap: 0.1em;
  font-family: var(--font-display); font-weight: 800;
  font-size: 1.75rem; letter-spacing: -0.04em; line-height: 1;
  font-variant-numeric: tabular-nums lining-nums;
  color: var(--ink);
}
.rating__max { font-size: 0.85rem; font-weight: 600; color: var(--ink-3); }
.rating__meta { font-size: 0.78rem; color: var(--ink-3); }

/* Stars are one outline row with a filled row clipped over it, so a 4.3 shows
   as exactly 86% and there is no half-star sprite to maintain. */
.stars { position: relative; display: inline-block; line-height: 0; }
.stars__row { display: flex; gap: 1px; }
.stars__row svg { width: 15px; height: 15px; }
.stars__row--base { color: var(--line-strong); }
.stars__row--fill {
  position: absolute; inset-block: 0; inset-inline-start: 0;
  overflow: hidden; width: var(--fill, 0%); color: var(--c-accent);
}

/* Pros and cons ------------------------------------------------------------- */

.proscons { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s4); }
.proscons--single { grid-template-columns: minmax(0, 1fr); }

.ticklist { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); font-size: 0.9rem; }
.ticklist li { display: grid; grid-template-columns: 18px minmax(0, 1fr); gap: var(--s2); align-items: start; }
.ticklist svg { width: 15px; height: 15px; margin-top: 4px; }
.ticklist--pro svg { color: var(--c-positive); }
.ticklist--con svg { color: var(--c-negative); }

.list-title {
  font-size: 0.74rem; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: var(--s2);
}

/* Facts strip — renders only the entries that exist, so no empty slots ------ */

.facts { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4); margin: 0; padding: 0; }
.facts > div { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.facts dt { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-3); }
.facts dd { margin: 0; font-size: 0.9rem; font-weight: 600; overflow-wrap: anywhere; }

/* Scores -------------------------------------------------------------------- */

.scores { display: grid; gap: var(--s2); margin: 0; }
.score { display: grid; grid-template-columns: minmax(84px, 110px) minmax(0, 1fr) 34px; gap: var(--s3); align-items: center; }
.score__label { font-size: 0.8rem; color: var(--ink-2); }
.score__track { height: 6px; background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-pill); overflow: hidden; }
.score__fill { display: block; height: 100%; background: var(--c-primary); border-radius: inherit; }
.score__value { font-size: 0.82rem; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }

/* Expandable long description ---------------------------------------------- */

.details { border-top: 1px solid var(--line); padding-top: var(--s3); margin-top: var(--s1); }
.details > summary {
  cursor: pointer; font-size: 0.88rem; font-weight: 650; color: var(--c-primary);
  list-style: none; display: inline-flex; align-items: center; gap: var(--s2);
}
.details > summary::-webkit-details-marker { display: none; }
.details > summary::after { content: "▾"; font-size: 0.75em; transition: transform .15s ease; }
.details[open] > summary::after { transform: rotate(180deg); }
.details__body { padding-top: var(--s3); font-size: 0.93rem; color: var(--ink-2); }

/* Layout variants ----------------------------------------------------------- */
/* Each variant reuses the same card partials; only the container changes. */

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
  gap: var(--s4);
  align-items: stretch;
}
.card--stacked { display: flex; flex-direction: column; gap: var(--s4); }
/* Pushes the action zone to the bottom so buttons align across a row
   regardless of how much copy each entry carries. */
.card--stacked .card__action { margin-top: auto; }
.card--stacked .card__brand { align-items: center; text-align: center; }
.card--stacked .card__logo { object-position: center; margin-inline: auto; }

.rank-chip {
  position: absolute; top: var(--s3); left: var(--s3);
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 30px; height: 26px; padding-inline: 0.4em;
  font-size: 0.8rem; font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--ink-2); background: var(--paper);
  border: 1px solid var(--line); border-radius: var(--radius-pill);
}
.card[data-award]:not([data-award=""]) .rank-chip {
  color: #2a1c00; background: var(--c-accent); border-color: transparent;
}

.minimal-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); }
.minimal-row {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto minmax(150px, 180px);
  gap: var(--s4);
  align-items: center;
  padding: var(--s3) var(--s4);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.minimal-row[data-award]:not([data-award=""]) {
  border-color: color-mix(in srgb, var(--c-accent) 55%, var(--line));
}
.minimal-row__rank { font-size: 1.1rem; font-weight: 800; color: var(--ink-3); text-align: center; font-variant-numeric: tabular-nums; }
.minimal-row__brand { display: flex; align-items: center; gap: var(--s3); min-width: 0; overflow-wrap: anywhere; }
.minimal-row__brand img { width: 104px; height: 40px; object-fit: contain; object-position: left center; flex: none; }
.minimal-row__meta { display: flex; align-items: center; gap: var(--s3); }
.minimal-row .card__action { flex-direction: row; }
.minimal-row .rating__score { font-size: 1.15rem; }

.feature {
  display: grid;
  grid-template-columns: minmax(230px, 300px) minmax(0, 1fr);
  gap: var(--s6);
  padding: var(--s6);
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--c-accent) 45%, var(--line));
  border-radius: var(--radius);
  box-shadow: var(--shadow-2);
}
.feature__aside { display: flex; flex-direction: column; gap: var(--s4); align-items: flex-start; }
.feature__logo { max-width: 200px; max-height: 80px; object-fit: contain; object-position: left center; }
.feature__aside .card__action { width: 100%; }
.feature__main { display: flex; flex-direction: column; gap: var(--s4); min-width: 0; }
.feature__main h2 { margin: 0; }

.landing-hero {
  display: flex; flex-direction: column; align-items: center; gap: var(--s4);
  text-align: center;
  padding: var(--s7) var(--s5);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-2);
}
.landing-hero h2 { margin: 0; font-size: clamp(1.8rem, 1.3rem + 2vw, 2.6rem); }
.landing-hero__logo { max-height: 88px; width: auto; object-fit: contain; }
.landing-hero__action { width: min(340px, 100%); }
.landing-hero .facts { justify-content: center; }
.landing-hero .proscons { text-align: left; width: min(720px, 100%); }

@media (max-width: 900px) {
  .feature { grid-template-columns: minmax(0, 1fr); gap: var(--s5); padding: var(--s5); }
  .minimal-row { grid-template-columns: 34px minmax(0, 1fr) minmax(140px, 170px); grid-template-areas: "rank brand action" "meta meta meta"; }
  .minimal-row__rank { grid-area: rank; }
  .minimal-row__brand { grid-area: brand; }
  .minimal-row__meta { grid-area: meta; }
  .minimal-row .card__action { grid-area: action; }
}

@media (max-width: 760px) {
  .minimal-row { grid-template-columns: 34px minmax(0, 1fr); grid-template-areas: "rank brand" "meta meta" "action action"; }
  .card--stacked .card__brand { align-items: flex-start; text-align: left; }
  .card--stacked .card__logo { margin-inline: 0; object-position: left center; }
}

/* 9. Matrix / table layout -------------------------------------------------- */

.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
}

.matrix { width: 100%; border-collapse: separate; border-spacing: 0; min-width: 680px; }
.matrix th, .matrix td {
  padding: var(--s3) var(--s4);
  text-align: left; vertical-align: middle;
  border-bottom: 1px solid var(--line);
  overflow-wrap: anywhere;
}
.matrix thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--paper);
  font-size: 0.74rem; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
  color: var(--ink-3);
  border-bottom: 1px solid var(--line-strong);
  white-space: nowrap;
}
.matrix tbody tr:last-child td { border-bottom: 0; }
.matrix tbody tr:hover td { background: color-mix(in srgb, var(--c-primary) 3%, transparent); }
.matrix td.is-rank { width: 56px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ink-3); }
.matrix .cell-brand { display: flex; align-items: center; gap: var(--s3); min-width: 0; }
.matrix .cell-brand img { width: 96px; height: 36px; object-fit: contain; object-position: left center; flex: none; }
.matrix .cell-brand strong { font-weight: 700; }

/* Sticky first column keeps the business visible while scanning wide tables. */
.matrix--sticky td:nth-child(2), .matrix--sticky th:nth-child(2) {
  position: sticky; left: 0; z-index: 1; background: var(--surface);
}
.matrix--sticky thead th:nth-child(2) { z-index: 3; background: var(--paper); }

/* 10. Page sections --------------------------------------------------------- */

.hero { padding-block: var(--s7) var(--s6); }
.hero__inner { display: grid; gap: var(--s5); align-items: center; }
.hero--split .hero__inner { grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr); }
.hero--center { text-align: center; }
.hero--center .hero__inner { justify-items: center; max-width: 760px; margin-inline: auto; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s3); }
.hero__image { border-radius: var(--radius); box-shadow: var(--shadow-2); }

.faq { display: grid; gap: var(--s2); }
.faq__item { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.faq__q {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  padding: var(--s4); cursor: pointer; font-weight: 650; list-style: none;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after { content: "+"; font-size: 1.3em; font-weight: 400; color: var(--ink-3); flex: none; }
.faq__item[open] .faq__q::after { content: "–"; }
.faq__a { padding: 0 var(--s4) var(--s4); color: var(--ink-2); }

.cta-panel {
  background: var(--c-secondary); color: #fff;
  border-radius: var(--radius); padding: var(--s6);
  display: grid; gap: var(--s4); align-items: center;
}
.cta-panel h2, .cta-panel h3 { color: #fff; }
.cta-panel p { color: rgb(255 255 255 / 78%); }
.cta-panel--split { grid-template-columns: minmax(0, 1fr) auto; }

.testimonials { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: var(--s4); }
.testimonial { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: var(--s5); }
.testimonial__quote { font-size: 1.02rem; color: var(--ink-2); }
.testimonial__who { display: flex; align-items: center; gap: var(--s3); margin-top: var(--s4); }
.testimonial__who img { width: 38px; height: 38px; border-radius: 50%; object-fit: cover; }

.author-card { display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: var(--s4); align-items: start; }
.author-card img { width: 72px; height: 72px; border-radius: 50%; object-fit: cover; }

.video-frame {
  position: relative; aspect-ratio: 16 / 9;
  border-radius: var(--radius); overflow: hidden; background: var(--c-secondary);
}
.video-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.related { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: var(--s4); }
.related a {
  display: block; padding: var(--s4);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  text-decoration: none; color: var(--ink);
  transition: border-color .14s ease, box-shadow .14s ease;
}
.related a:hover { border-color: var(--c-primary); box-shadow: var(--shadow-2); }

.divider-dots { display: flex; justify-content: center; gap: var(--s2); color: var(--line-strong); }

/* Breadcrumbs and disclosure ------------------------------------------------ */

.crumbs { font-size: 0.84rem; color: var(--ink-3); padding-block: var(--s4) 0; }
.crumbs ol { display: flex; flex-wrap: wrap; gap: var(--s2); list-style: none; margin: 0; padding: 0; }
.crumbs li + li::before { content: "/"; margin-right: var(--s2); color: var(--line-strong); }
.crumbs a { color: inherit; text-decoration: none; }
.crumbs a:hover { color: var(--c-primary); text-decoration: underline; }

.disclosure {
  font-size: 0.82rem; line-height: 1.55; color: var(--ink-3);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: var(--s3) var(--s4);
}
.disclosure strong { color: var(--ink-2); }
.disclosure--floating {
  position: fixed; right: var(--s4); bottom: var(--s4); z-index: 30;
  max-width: 320px; box-shadow: var(--shadow-3);
}

/* 11. Footer, cookie bar, sticky CTA ---------------------------------------- */

.site-footer {
  background: var(--c-secondary); color: rgb(255 255 255 / 72%);
  padding-block: var(--s7) var(--s5); margin-top: var(--s8);
}
.site-footer a { color: rgb(255 255 255 / 88%); text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.site-footer h3 { color: #fff; font-size: 0.78rem; letter-spacing: 0.09em; text-transform: uppercase; }

.footer-grid { display: grid; grid-template-columns: minmax(220px, 1.4fr) repeat(auto-fit, minmax(150px, 1fr)); gap: var(--s6); }
.footer-nav { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); font-size: 0.92rem; }
.footer-bottom {
  display: flex; flex-wrap: wrap; gap: var(--s3); justify-content: space-between;
  margin-top: var(--s6); padding-top: var(--s4);
  border-top: 1px solid rgb(255 255 255 / 12%);
  font-size: 0.84rem;
}
.social { display: flex; gap: var(--s3); }
.social a { display: inline-flex; width: 34px; height: 34px; align-items: center; justify-content: center; border: 1px solid rgb(255 255 255 / 18%); border-radius: var(--radius-sm); }

.cookie-bar {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 60;
  background: var(--surface); border-top: 1px solid var(--line);
  box-shadow: 0 -6px 24px rgb(18 24 38 / 10%);
  padding: var(--s4);
}
.cookie-bar__inner { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s4); justify-content: space-between; }
.cookie-bar__text { font-size: 0.875rem; color: var(--ink-2); max-width: 62ch; }
.cookie-bar--box {
  inset-inline: auto 0; max-width: 380px; margin: var(--s4);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.cookie-bar--box .cookie-bar__inner { flex-direction: column; align-items: stretch; }

/*
   Three things can be pinned to the bottom edge: the cookie notice, the promo
   bar and the sticky call to action. They stack rather than overlap — the
   notice sits at the floor because it is the one that must be answered, and
   --dock-h is the height a script measures for it (0 when it is absent, which
   is every visit after the first).
*/
.promo-bar {
  position: fixed; inset-inline: 0; bottom: var(--dock-h, 0px); z-index: 55;
  background: var(--c-secondary); color: #fff;
  border-top: 1px solid rgb(255 255 255 / 12%);
  box-shadow: 0 -6px 24px rgb(18 24 38 / 22%);
  padding: var(--s3) 0;
  padding-bottom: max(var(--s3), env(safe-area-inset-bottom));
}

.promo-bar__inner {
  display: flex; align-items: center; gap: var(--s4);
  flex-wrap: wrap;
}

.promo-bar__image { width: 76px; height: 30px; object-fit: contain; flex: none; }

.promo-bar__highlight {
  flex: none;
  padding: 0.3em 0.7em;
  font-size: 0.76rem; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase;
  color: #2a1c00; background: var(--c-accent);
  border-radius: var(--radius-sm);
  white-space: nowrap;
}

.promo-bar__body { flex: 1 1 320px; min-width: 0; }
.promo-bar__text { margin: 0; font-size: 0.95rem; font-weight: 600; line-height: 1.35; overflow-wrap: anywhere; }
.promo-bar__note { margin: 2px 0 0; font-size: 0.8rem; color: rgb(255 255 255 / 66%); }

.promo-bar__cta { flex: none; }

.promo-bar__close {
  flex: none;
  width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 1.2rem; line-height: 1;
  color: rgb(255 255 255 / 70%);
  background: none; border: 1px solid rgb(255 255 255 / 22%);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.promo-bar__close:hover { color: #fff; border-color: rgb(255 255 255 / 45%); }

/* Reserves the bar's height at the end of the flow. JavaScript replaces these
   with the measured height; the values are the fallback when it does not run. */
.promo-bar__spacer { height: 74px; }

@media (max-width: 760px) {
  .promo-bar { padding-block: var(--s3); }
  .promo-bar__inner { gap: var(--s3); row-gap: var(--s2); }
  .promo-bar__body { flex-basis: 100%; order: 2; }
  .promo-bar__cta { order: 3; flex: 1 1 auto; }
  .promo-bar__close { order: 4; }
  .promo-bar__image, .promo-bar__highlight { order: 1; }
  .promo-bar__spacer { height: 132px; }
}

@media print {
  .promo-bar, .promo-bar__spacer { display: none !important; }
}

.sticky-cta {
  position: fixed; inset-inline: 0; bottom: var(--dock-h, 0px); z-index: 50;
  display: none;
  background: var(--surface); border-top: 1px solid var(--line);
  box-shadow: 0 -4px 18px rgb(18 24 38 / 10%);
  padding: var(--s3) var(--s4);
  padding-bottom: max(var(--s3), env(safe-area-inset-bottom));
}
.sticky-cta__inner { display: flex; align-items: center; gap: var(--s3); justify-content: space-between; }
.sticky-cta__brand { display: flex; align-items: center; gap: var(--s3); min-width: 0; }
.sticky-cta__brand img { width: 76px; height: 30px; object-fit: contain; object-position: left center; flex: none; }
.sticky-cta__name { font-weight: 700; font-size: 0.92rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 12. Responsive ------------------------------------------------------------ */

@media (max-width: 1080px) {
  .card__grid { grid-template-columns: minmax(130px, 170px) minmax(0, 1fr) minmax(160px, 190px); gap: var(--s4); }
}

@media (max-width: 900px) {
  .card__grid {
    grid-template-columns: minmax(0, 1fr) minmax(150px, 200px);
    grid-template-areas: "brand action" "body body";
  }
  .card__brand { grid-area: brand; }
  .card__body { grid-area: body; }
  .card__action { grid-area: action; }
  .hero--split .hero__inner { grid-template-columns: minmax(0, 1fr); }
  .cta-panel--split { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 760px) {
  :root { --header-h: 58px; }

  .nav-toggle { display: inline-flex; }

  .nav {
    display: none;
    position: absolute; top: 100%; inset-inline: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    padding: var(--s3);
    background: var(--surface); border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow-3);
    max-height: calc(100dvh - var(--header-h)); overflow-y: auto;
  }
  .nav[data-open="1"] { display: flex; }
  .nav ul { flex-direction: column; align-items: stretch; gap: 0; }
  .nav a { padding: 0.8em 0.6em; }
  .nav__sub { position: static; display: flex; box-shadow: none; border: 0; padding: 0 0 0 var(--s4); }

  .rank-rail { top: var(--s3); left: var(--s4); }
  .rank-num { min-width: 34px; height: 27px; font-size: 0.94rem; }

  .card { padding: var(--s4); }
  .rank-item > .card { padding-top: calc(var(--s4) + 30px); }
  .card__grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "brand" "body" "action"; gap: var(--s4); }
  .card__logo { max-width: 160px; height: 50px; }
  .proscons { grid-template-columns: minmax(0, 1fr); }
  .score { grid-template-columns: minmax(74px, 96px) minmax(0, 1fr) 30px; }

  .sticky-cta { display: block; }
  body[data-sticky-cta="1"] { padding-bottom: 76px; }

  .footer-grid { grid-template-columns: minmax(0, 1fr); gap: var(--s5); }
  .disclosure--floating { position: static; max-width: none; box-shadow: none; }
}

@media (max-width: 420px) {
  .wrap { padding-inline: var(--s3); }
  .minimal-row__brand img { width: 84px; height: 32px; }
  .facts { gap: var(--s2) var(--s3); }
  .btn { font-size: 0.9rem; }
}

/* Landscape phones: keep the sticky bars from eating the viewport. */
@media (max-height: 460px) and (orientation: landscape) {
  .site-header[data-sticky="1"] { position: relative; }
  .sticky-cta { display: none; }
  body[data-sticky-cta="1"] { padding-bottom: 0; }
}

/* 13. Dark mode, motion, print ---------------------------------------------- */

[data-mode="dark"] {
  --ink: #eef1f6;
  --ink-2: #b9c1d0;
  --ink-3: #8b93a5;
  --paper: #0d1119;
  --surface: #151b26;
  --line: #262f3f;
  --line-strong: #364155;
  --c-secondary: #0a0e15;
  --shadow-1: 0 1px 2px rgb(0 0 0 / 40%);
  --shadow-2: 0 4px 14px rgb(0 0 0 / 45%);
  --shadow-3: 0 12px 32px rgb(0 0 0 / 55%);
  color-scheme: dark;
}
/* Before the script resolves "auto", let form controls and scrollbars follow
   the device on their own. */
[data-mode="auto"] { color-scheme: light dark; }

[data-mode="dark"] .btn--accent { --btn-fg: #1a1200; }
[data-mode="dark"] .badge--award { color: #ffd489; }
[data-mode="dark"] .site-footer { border-top: 1px solid var(--line); }

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

@media print {
  .site-header, .site-footer, .cookie-bar, .sticky-cta, .card__action, .nav { display: none !important; }
  .card, .panel { border: 1px solid #ccc; box-shadow: none; break-inside: avoid; }
  body { background: #fff; }
}
