/* ============================================================================
   HostReview design system
   Dark dramatic hero -> bright scannable content. Data visualisation over prose.
   Motion that guides the eye. Everything is transform/opacity so it stays 60fps.
   ========================================================================== */

/* ---------------------------------------------------------------- tokens */
:root {
  --display: "Instrument Sans", "Inter", system-ui, sans-serif;
  --sans:    "Inter", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono:    ui-monospace, "SF Mono", "Cascadia Mono", Consolas, monospace;

  --ink:   #0a0e1a;
  --ink-2: #4a5468;
  --ink-3: #8892a6;

  --surface:   #ffffff;
  --surface-2: #f6f8fc;
  --surface-3: #eaeef7;
  --line:      #e3e8f2;
  --line-2:    #d1d9e8;

  /* vivid triad — used as gradients, never as flat fills */
  --a1: #4f46e5;   /* indigo  */
  --a2: #8b5cf6;   /* violet  */
  --a3: #06b6d4;   /* cyan    */
  --accent: var(--a1);
  --accent-ink: #ffffff;
  --accent-soft: #eef0ff;
  --accent-line: #c7cdfb;
  --grad:  linear-gradient(135deg, var(--a2) 0%, var(--a1) 55%, #3730c9 100%);
  --grad-bright: linear-gradient(120deg, var(--a3), var(--a2) 55%, var(--a1));

  --good: #059669; --good-soft: #e6f7f1;
  --warn: #b45309; --warn-soft: #fdf3e3;
  --bad:  #dc2626; --bad-soft: #fdedee;
  --gold: #d97706;

  --r-sm: .55rem; --r: .85rem; --r-lg: 1.25rem; --r-xl: 1.75rem;

  --sh-1: 0 1px 2px rgba(10,14,26,.05), 0 1px 3px rgba(10,14,26,.04);
  --sh-2: 0 2px 6px rgba(10,14,26,.05), 0 10px 28px -8px rgba(10,14,26,.12);
  --sh-3: 0 6px 12px rgba(10,14,26,.06), 0 24px 48px -14px rgba(10,14,26,.20);
  --sh-glow: 0 8px 28px -8px rgba(79,70,229,.5);

  --ease: cubic-bezier(.22,.61,.36,1);
  --spring: cubic-bezier(.34,1.4,.64,1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #eef1f8; --ink-2: #a1abc0; --ink-3: #6f7a91;
    --surface: #0a0d16; --surface-2: #10141f; --surface-3: #191f2e;
    --line: #1f2637; --line-2: #2b3346;
    --a1: #7c76ff; --a2: #a78bfa; --a3: #22d3ee;
    --accent-ink: #070a12; --accent-soft: #161c33; --accent-line: #2f3862;
    --good: #34d399; --good-soft: #0c2a22;
    --warn: #fbbf24; --warn-soft: #2a2011;
    --bad:  #fb7185; --bad-soft: #2c1219;
    --gold: #fbbf24;
    --sh-1: 0 1px 2px rgba(0,0,0,.55);
    --sh-2: 0 2px 8px rgba(0,0,0,.5), 0 12px 32px -10px rgba(0,0,0,.6);
    --sh-3: 0 8px 18px rgba(0,0,0,.55), 0 28px 60px -16px rgba(0,0,0,.75);
    --sh-glow: 0 8px 30px -8px rgba(124,118,255,.55);
  }
}

/* The same palette, selectable. The media query alone gave a visitor no way to
   choose; data-theme on <html> wins over it in BOTH directions, so someone on a
   dark OS can force light and vice versa. */
:root[data-theme="dark"] {
    --ink: #eef1f8; --ink-2: #a1abc0; --ink-3: #6f7a91;
    --surface: #0a0d16; --surface-2: #10141f; --surface-3: #191f2e;
    --line: #1f2637; --line-2: #2b3346;
    --a1: #7c76ff; --a2: #a78bfa; --a3: #22d3ee;
    --accent-ink: #070a12; --accent-soft: #161c33; --accent-line: #2f3862;
    --good: #34d399; --good-soft: #0c2a22;
    --warn: #fbbf24; --warn-soft: #2a2011;
    --bad:  #fb7185; --bad-soft: #2c1219;
    --gold: #fbbf24;
    --sh-1: 0 1px 2px rgba(0,0,0,.55);
    --sh-2: 0 2px 8px rgba(0,0,0,.5), 0 12px 32px -10px rgba(0,0,0,.6);
    --sh-3: 0 8px 18px rgba(0,0,0,.55), 0 28px 60px -16px rgba(0,0,0,.75);
    --sh-glow: 0 8px 30px -8px rgba(124,118,255,.55);
}
:root[data-theme="light"] { color-scheme: light; }


*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  /* clip, NOT hidden: `hidden` would make the body a scroll container and break
     every position:sticky on the site. This is the safety net for residual
     decorative overflow at very narrow widths (~360px) — the real causes at 390px
     and up are fixed properly, in .sec-head and the .doc grid. */
  overflow-x: clip;
  font: 400 16.5px/1.7 var(--sans);
  letter-spacing: -.006em;
  color: var(--ink);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ------------------------------------------------------------ typography */
h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -.032em;
  margin: 0 0 .5em;
  text-wrap: balance;
}
h1 { font-size: clamp(2.15rem, 1.45rem + 2.4vw, 3.25rem); letter-spacing: -.038em; }
h2 { font-size: clamp(1.38rem, 1.2rem + .8vw, 1.85rem); margin-top: 0; letter-spacing: -.03em; }
h3 { font-size: 1.12rem; letter-spacing: -.024em; font-weight: 600; }
p  { margin: 0 0 1.1em; }

a { color: var(--a1); text-decoration-thickness: 1px; text-underline-offset: 3px;
    transition: color .15s var(--ease); }
a:hover { color: var(--a2); }
img { max-width: 100%; height: auto; display: block; }

.wrap { max-width: 1180px; margin: 0 auto; padding: 0 1.5rem; }

/* Prose pages. This class was used by method/privacy/terms/cookies/contact but
   never defined, so all five rendered at the full 1180px — roughly 130
   characters a line, about double a readable measure. */
/* Self-sufficient, like .wrap. It previously set only max-width, which left every
   section using it flush against the left edge with no gutter at all — /about,
   /vps-hosting and /search all shipped that way, and on a phone the text touched the
   screen edge. Nothing combines this with .wrap, so the padding cannot double up. */
.wrap-narrow {
  max-width: 52rem;
  margin-inline: auto;
  padding: 0 1.5rem;
}

/* Anchor targets have to clear the sticky header, or a jump lands with the
   heading hidden underneath it. Scoped to sections and headings on purpose —
   on every `[id]` it would also over-scroll form fields when they take focus. */
:target,
section[id], .doc-sec, h2[id], h3[id] { scroll-margin-top: 5.5rem; }

/* Section header: title + rule (+ optional link). Declared AFTER .wrap on
   purpose — `.wrap { margin: 0 auto }` is a shorthand that resets margin-top,
   so on <section class="wrap sec"> whichever rule comes last wins. */
.sec { margin-top: 5rem; }
.sec-head {
  display: flex; align-items: baseline; gap: 1.25rem; margin-bottom: 1.75rem;
  /* wrap + min-width:0 below: h2 was flex:0 0 auto and .sec-link was nowrap, so a
     long heading or note could not shrink and pushed the whole page wider than a
     phone viewport. This was the single biggest cause of horizontal scroll. */
  flex-wrap: wrap;
}
.sec-head h2 { margin: 0; flex: 0 1 auto; min-width: 0; }
.sec-head::after { content: ""; flex: 1 0 2rem; height: 1px; background: var(--line); }
.sec-head .sec-link {
  font: 650 .84rem/1 var(--sans); text-decoration: none;
  min-width: 0; overflow-wrap: anywhere;
}
.sec-head .sec-link.muted { white-space: normal; }
@media (max-width: 640px) {
  /* The decorative rule earns nothing once the row wraps. */
  .sec-head::after { display: none; }
}
.sec-sub { margin: -1rem 0 2rem; font-size: .95rem; color: var(--ink-2); max-width: 66ch; }

/* Full-bleed tinted band. Alternating white / tinted / dark gives the page a
   rhythm; an unbroken run of white cards is what reads as "a simple page". */
.band {
  background: var(--surface-2); border-block: 1px solid var(--line);
  padding: 4.25rem 0; margin-top: 5rem;
}
.band .sec, .band > .wrap > .sec:first-child { margin-top: 0; }
.band-tight { padding: 2.25rem 0; }

/* ------------------------------------------------------------------ byline */
.byline {
  display: flex; align-items: center; gap: .8rem; flex-wrap: wrap;
  border: 0; border-radius: 0; box-shadow: none; background: none;
  padding: 0; margin-top: 1.6rem;
}
.avatar {
  display: grid; place-items: center; width: 2.1rem; height: 2.1rem; border-radius: 50%;
  background: var(--grad); color: #fff; font: 800 .68rem/1 var(--sans); letter-spacing: .02em;
  flex: 0 0 auto; box-shadow: none;
}
.by-text { display: grid; gap: .1rem; min-width: 0; }
.by-name { font-size: .86rem; color: var(--ink-2); }
.by-name strong { color: var(--ink); font-weight: 650; }
.by-meta { font-size: .76rem; color: var(--ink-3); }
.by-link { margin-left: auto; font: 650 .82rem/1 var(--sans); text-decoration: none; white-space: nowrap; }

/* ----------------------------------------------------------- method strip */
.method-strip { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2rem; }
@media (max-width: 820px) { .method-strip { grid-template-columns: 1fr; gap: 1.35rem } }
.ms-item { display: flex; gap: .75rem; align-items: flex-start; }
.ms-icon {
  display: grid; place-items: center; flex: 0 0 auto;
  width: auto; height: auto; border: 0; background: none; box-shadow: none;
  color: var(--a1); padding-top: .1rem;
}
.ms-title { display: block; font: 600 .92rem/1.35 var(--sans); color: var(--ink); letter-spacing: -.012em; }
.ms-body { display: block; font-size: .82rem; line-height: 1.5; color: var(--ink-2); margin-top: .15rem; }

.muted { color: var(--ink-2); }
.small { font-size: .875rem; } .tiny { font-size: .76rem; }
.mono { font-family: var(--mono); font-size: .92em; font-variant-numeric: tabular-nums; }
.center { text-align: center; } .nowrap { white-space: nowrap; }
/* The page deck. Capped at 18px: at 20.5px it competed with the h1 above it
   instead of introducing it, and pushed every intro onto three lines. */
.lead {
  font-size: clamp(1rem, .95rem + .3vw, 1.125rem);
  line-height: 1.65; color: var(--ink-2); max-width: 66ch;
}

.grad-text {
  background: var(--grad-bright); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.eyebrow {
  display: inline-flex; align-items: center; gap: .5rem;
  font: 700 .72rem/1 var(--sans); text-transform: uppercase; letter-spacing: .14em;
  color: var(--a1); margin-bottom: 1.1rem;
}

/* live pulsing dot — cheap way to make a static page feel alive */
.dot-live { width: .5rem; height: .5rem; border-radius: 50%; background: #22c55e; position: relative; flex: 0 0 auto; }
.dot-live::after {
  content: ""; position: absolute; inset: -3px; border-radius: 50%;
  border: 1.5px solid #22c55e; animation: pulse 2.2s var(--ease) infinite;
}
@keyframes pulse { 0% { transform: scale(.7); opacity: 1 } 100% { transform: scale(1.9); opacity: 0 } }

/* =========================================================== hero: aurora */
.hero {
  position: relative; isolation: isolate; overflow: hidden;
  background: #070a14; color: #f2f5fc;
  padding: 4rem 0 4.25rem;
}
/* the band below butts straight against the hero — no white sliver between */
.hero + .band { margin-top: 0; border-top: 0; }
.hero::after {           /* fine grid overlay for depth */
  content: ""; position: absolute; inset: 0; z-index: -1; opacity: .5;
  background-image: linear-gradient(rgba(255,255,255,.04) 1px, transparent 1px),
                    linear-gradient(90deg, rgba(255,255,255,.04) 1px, transparent 1px);
  background-size: 56px 56px;
  mask-image: radial-gradient(ellipse 90% 70% at 50% 30%, #000 25%, transparent 75%);
}
.aurora {
  position: absolute; inset: 0; z-index: -2; filter: blur(72px); opacity: .85;
  /* The blobs are up to 40rem wide with negative offsets; without this they push
     the document scroll width out on a phone. */
  overflow: hidden;
}
.aurora i { position: absolute; display: block; border-radius: 50%; will-change: transform; }
.aurora i:nth-child(1) { width: 40rem; height: 26rem; left: -8rem;  top: -8rem;
  background: radial-gradient(circle, #4f46e5, transparent 68%); animation: drift1 22s var(--ease) infinite alternate; }
.aurora i:nth-child(2) { width: 34rem; height: 24rem; right: -6rem; top: -4rem;
  background: radial-gradient(circle, #06b6d4, transparent 68%); animation: drift2 26s var(--ease) infinite alternate; }
.aurora i:nth-child(3) { width: 38rem; height: 22rem; left: 28%;   bottom: -12rem;
  background: radial-gradient(circle, #8b5cf6, transparent 68%); animation: drift3 30s var(--ease) infinite alternate; }
@keyframes drift1 { to { transform: translate3d(9rem, 4rem, 0) scale(1.18) } }
@keyframes drift2 { to { transform: translate3d(-7rem, 6rem, 0) scale(1.12) } }
@keyframes drift3 { to { transform: translate3d(5rem, -5rem, 0) scale(1.22) } }

.hero-grid {
  display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
  gap: 4rem; align-items: center;
}
@media (max-width: 1080px) { .hero-grid { grid-template-columns: 1fr; gap: 3rem } }

.hero .eyebrow { color: #a5b4fc; }
.hero h1 { max-width: 20ch; margin-bottom: 1rem; }
.hero .lead { color: #aab4cc; max-width: 46ch; font-size: 1.06rem; line-height: 1.62; }

/* "what are you building?" chooser — first thing a visitor can click */
.chooser { margin-top: 2rem; }
.chooser-label {
  font: 700 .72rem/1 var(--sans); text-transform: uppercase; letter-spacing: .13em;
  color: #7d8aa8; margin-bottom: .9rem; display: block;
}
.chips-row { display: flex; gap: .6rem; flex-wrap: wrap; }
.chip-link {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .6rem 1.05rem; border-radius: 999px; text-decoration: none;
  font: 650 .88rem/1 var(--sans); color: #e8ecf7;
  background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.14);
  backdrop-filter: blur(8px);
  transition: transform .2s var(--spring), background .2s var(--ease), border-color .2s var(--ease);
}
.chip-link:hover {
  color: #fff; transform: translateY(-2px) scale(1.03);
  background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.3);
}
.chip-link .ico { color: #b6c0d6; }
.chip-link:hover .ico { color: #fff; }

.trust-bar {
  display: flex; gap: 2.25rem; flex-wrap: wrap; margin-top: 2.25rem;
  padding-top: 1.6rem; border-top: 1px solid rgba(255,255,255,.11);
}
.stat b {
  display: block; font-family: var(--display); font-size: 1.75rem; font-weight: 800;
  line-height: 1; letter-spacing: -.045em; font-variant-numeric: tabular-nums; color: #fff;
}
.stat span { font-size: .68rem; color: #8794ad; text-transform: uppercase; letter-spacing: .11em; font-weight: 650; }

/* ------------------------------------------------ hero visual: live monitor */
/* The 3D tilt plus the floating cards need breathing room or they clip against
   the hero's overflow:hidden — hence the inset margins. */
.hero-visual { position: relative; margin: 1.5rem 1.75rem 3.4rem 0; }
@media (max-width: 1080px) { .hero-visual { max-width: 34rem; margin: 0 1.75rem 2.5rem 0 } }

.monitor {
  position: relative; border-radius: var(--r-lg); overflow: hidden;
  background: linear-gradient(165deg, rgba(255,255,255,.10), rgba(255,255,255,.03));
  border: 1px solid rgba(255,255,255,.14);
  box-shadow: 0 30px 70px -20px rgba(0,0,0,.75), inset 0 1px 0 rgba(255,255,255,.12);
  backdrop-filter: blur(12px);
  transform: perspective(1600px) rotateY(-4deg) rotateX(1.5deg) scale(.985);
  transform-origin: center right;
  transition: transform .6s var(--ease);
}
.monitor:hover { transform: perspective(1600px) rotateY(-1.5deg) rotateX(.5deg) scale(1); }
@media (max-width: 1080px) { .monitor, .monitor:hover { transform: none } }

.monitor-glow {
  position: absolute; inset: auto -20% -60% -20%; height: 70%;
  background: radial-gradient(ellipse at 50% 100%, rgba(6,182,212,.35), transparent 65%);
  pointer-events: none;
}
.monitor-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: .85rem 1.1rem; border-bottom: 1px solid rgba(255,255,255,.09);
  background: rgba(255,255,255,.04);
}
.monitor-title {
  display: inline-flex; align-items: center; gap: .5rem;
  font: 700 .74rem/1 var(--sans); text-transform: uppercase; letter-spacing: .1em; color: #dbe2f2;
}
.monitor-window { font: 600 .7rem/1 var(--sans); color: #7f8ca8; letter-spacing: .04em; }
.monitor-body { padding: .4rem .5rem; }

.mon-logo {
  --bc: #4f46e5;
  display: grid; place-items: center; width: 1.85rem; height: 1.85rem; border-radius: .45rem;
  background: linear-gradient(150deg, var(--bc), color-mix(in srgb, var(--bc) 72%, black));
  font: 800 .58rem/1 var(--sans); color: #fff; letter-spacing: -.03em;
  text-shadow: 0 1px 1px rgba(0,0,0,.35);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.3);
}
.mon-name { font: 650 .82rem/1 var(--sans); color: #e6ebf7; white-space: nowrap; }
.mon-val { font: 700 .76rem/1 var(--mono); color: #6ee7c8; font-variant-numeric: tabular-nums; }

.monitor-foot {
  display: flex; gap: 1.4rem; justify-content: flex-end; padding: .8rem 1.15rem;
  border-top: 1px solid rgba(255,255,255,.09); background: rgba(0,0,0,.22);
  font: 500 .72rem/1 var(--sans); color: #8494b0;
}
.monitor-foot b { color: #e6ebf7; font-weight: 700; }

/* floating accent cards */
.float-card {
  position: absolute; z-index: 2; display: grid; gap: .15rem;
  padding: .7rem .95rem; border-radius: .7rem;
  background: rgba(16,20,33,.85); border: 1px solid rgba(255,255,255,.14);
  box-shadow: 0 16px 36px -12px rgba(0,0,0,.7); backdrop-filter: blur(10px);
  animation: bob 6s var(--ease) infinite alternate;
}
.float-a { top: -1.25rem; right: -1.25rem; }
/* sits mostly *below* the panel so it never covers the footer readout */
.float-b { bottom: -3.1rem; left: -1.25rem; animation-delay: -3s; }
@keyframes bob { to { transform: translateY(-9px) } }
.fc-label { font: 600 .62rem/1 var(--sans); text-transform: uppercase; letter-spacing: .1em; color: #7f8ca8; }
.fc-value { font-family: var(--sans); font-weight: 700; font-size: .95rem; line-height: 1.2;
            letter-spacing: -.02em; color: #fff; }
.fc-warn { color: #fbbf24; }
@media (max-width: 1080px) { .float-b { left: auto; right: 1.5rem; bottom: -1.25rem } }
@media (max-width: 620px)  { .float-card { display: none } }

/* --------------------------------------------------------------- buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
  padding: .72rem 1.3rem; border-radius: var(--r-sm);
  border: 1px solid var(--line-2); background: var(--surface); color: var(--ink);
  font: 650 .91rem/1.2 var(--sans); letter-spacing: -.008em;
  text-decoration: none; cursor: pointer; white-space: nowrap; box-shadow: var(--sh-1);
  transition: transform .18s var(--spring), box-shadow .18s var(--ease),
              border-color .18s var(--ease), background .18s var(--ease), filter .18s var(--ease);
}
.btn:hover { transform: translateY(-2px); box-shadow: var(--sh-2); border-color: var(--ink-3); color: var(--ink); }
.btn:active { transform: translateY(0) scale(.985); }

.btn-primary {
  position: relative; overflow: hidden;
  border-color: transparent; color: #fff; background: var(--grad); box-shadow: var(--sh-glow);
}
.btn-primary::after {   /* sheen sweep on hover */
  content: ""; position: absolute; inset: 0; transform: translateX(-110%);
  background: linear-gradient(105deg, transparent 30%, rgba(255,255,255,.32) 50%, transparent 70%);
  transition: transform .6s var(--ease);
}
.btn-primary:hover { color: #fff; filter: brightness(1.1); box-shadow: 0 12px 34px -8px rgba(79,70,229,.6); }
.btn-primary:hover::after { transform: translateX(110%); }

.btn-ghost { background: transparent; box-shadow: none; border-color: var(--line-2); }
.btn-light { background: #fff; color: #0a0e1a; border-color: transparent; }
.btn-outline-light { background: rgba(255,255,255,.08); color: #fff; border-color: rgba(255,255,255,.45); box-shadow: none; }
.btn-outline-light:hover { color: #fff; background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.6); }
.btn-block { width: 100%; }
.btn-sm { padding: .42rem .8rem; font-size: .81rem; }
.btn-lg { padding: .92rem 1.75rem; font-size: 1rem; }
.btn-danger { color: var(--bad); border-color: var(--line); box-shadow: none; }
.btn-danger:hover { background: var(--bad-soft); border-color: var(--bad); color: var(--bad); }

:where(a, button, input, select, textarea):focus-visible { outline: 2px solid var(--a1); outline-offset: 2px; border-radius: 4px; }

/* --------------------------------------------------------- reveal on scroll */
/* Only hidden when JS confirmed it can reveal them. Without JS, or if the
   observer never fires, content stays visible — never a blank page. */
.js-anim .reveal { opacity: 0; transform: translateY(18px); }
.js-anim .reveal.in {
  opacity: 1; transform: none;
  transition: opacity .55s var(--ease), transform .55s var(--ease);
}

/* ------------------------------------------------------------ score ring */
.ring {
  position: relative; display: grid; place-items: center; flex: 0 0 auto;
  width: 4.3rem; height: 4.3rem; border-radius: 50%;
  background: conic-gradient(from -90deg, var(--a3) 0deg, var(--a2) calc(var(--v) * 1.8deg),
              var(--a1) calc(var(--v) * 3.6deg), var(--surface-3) calc(var(--v) * 3.6deg));
}
.ring::after {
  content: ""; position: absolute; inset: 5px; border-radius: 50%; background: var(--surface);
  box-shadow: inset 0 1px 4px rgba(10,14,26,.07);
}
.ring > * { position: relative; z-index: 1; }
.ring b { font-family: var(--display); font-weight: 800; font-size: 1.38rem; line-height: 1;
          letter-spacing: -.05em; font-variant-numeric: tabular-nums; }
.ring-lg { width: 7.5rem; height: 7.5rem; }
.ring-lg::after { inset: 8px; }
.ring-lg b { font-size: 2.55rem; }

/* mini rubric bars — compact data viz, reads faster than a spec list */
.minibars { display: flex; align-items: flex-end; gap: 3px; height: 1.6rem; }
.minibars i {
  width: 5px; border-radius: 2px; background: var(--grad);
  opacity: .6; transition: opacity .2s var(--ease), transform .3s var(--spring);
  transform-origin: bottom;
}
.host-row:hover .minibars i, .spotlight:hover .minibars i { opacity: 1; }

/* -------------------------------------------------------------- spec chips */
.chip {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .2rem .55rem; border-radius: 999px;
  font: 600 .72rem/1.5 var(--sans); letter-spacing: -.002em;
  background: var(--surface-2); border: 1px solid var(--line); color: var(--ink-2);
}
.chip-ok  { background: var(--good-soft); border-color: transparent; color: var(--good); }
.chip-no  { color: var(--ink-3); opacity: .75; }
.chip-hot { background: var(--warn-soft); border-color: transparent; color: var(--warn); }
.chip-row { display: flex; gap: .35rem; flex-wrap: wrap; margin-top: .55rem; }

/* ======================================================= winner spotlight */
.spotlight {
  position: relative; display: grid;
  grid-template-columns: auto 1fr auto; gap: 2rem; align-items: start;
  padding: 2rem 2.25rem; margin: 0 0 1.5rem;
  border-radius: var(--r-xl);
  background: linear-gradient(var(--surface), var(--surface)) padding-box,
              var(--grad) border-box;
  border: 1.5px solid transparent;
  box-shadow: var(--sh-3);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}
.spotlight:hover { transform: translateY(-3px); box-shadow: 0 12px 24px rgba(10,14,26,.08), 0 36px 70px -20px rgba(79,70,229,.3); }
.spotlight-tag {
  position: absolute; top: -.85rem; left: 2rem;
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .3rem .8rem; border-radius: 999px; color: #fff; background: var(--grad);
  font: 800 .68rem/1.4 var(--sans); text-transform: uppercase; letter-spacing: .1em;
  box-shadow: var(--sh-glow);
}
.spotlight h3 {
  font-family: var(--sans); font-weight: 700; letter-spacing: -.03em;
  font-size: clamp(1.4rem, 1.15rem + .9vw, 1.85rem); margin: .1rem 0 .3rem;
}
.spotlight h3 a { color: var(--ink); text-decoration: none; }
.spotlight h3 a:hover { color: var(--a1); }
.spotlight > .ring-lg { margin-top: .3rem; }   /* line the ring up with the logo row */

.spot-rubric {
  display: grid; grid-template-columns: 1fr 1fr; gap: .45rem 1.6rem;
  margin-top: 1.1rem; padding-top: 1rem; border-top: 1px solid var(--line);
}
.spot-metric { display: grid; grid-template-columns: 5.4rem 1fr 1.8rem; gap: .55rem; align-items: center; }
.sm-label { font: 600 .74rem/1 var(--sans); color: var(--ink-3); }
.sm-val { font: 700 .74rem/1 var(--mono); color: var(--ink-2); text-align: right; }
@media (max-width: 640px) { .spot-rubric { grid-template-columns: 1fr } }

.spotlight-cta { display: grid; gap: .5rem; min-width: 12rem; align-self: center; }
.spotlight-price { font-family: var(--display); font-size: 1.9rem; font-weight: 800; letter-spacing: -.045em; line-height: 1; }
@media (max-width: 900px) {
  .spotlight { grid-template-columns: auto 1fr; gap: 1.35rem 1.5rem; padding: 2.25rem 1.35rem 1.5rem; }
  .spotlight-cta { grid-column: 1 / -1; min-width: 0; }
}

/* ----------------------------------------------------------- toplist rows */
.toplist { display: grid; gap: 1rem; margin: 2rem 0 3rem; }

.host-row {
  position: relative;
  display: grid;
  grid-template-columns: 2.3rem minmax(13rem, 1.5fr) 8rem 5.4rem 10.5rem;
  gap: 1.5rem; align-items: center;
  padding: 1.4rem 1.6rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s var(--ease);
}
.host-row::before {   /* accent edge that grows on hover */
  content: ""; position: absolute; left: 0; top: 22%; bottom: 22%; width: 3px;
  border-radius: 0 3px 3px 0; background: var(--grad); opacity: 0;
  transition: opacity .22s var(--ease), top .22s var(--ease), bottom .22s var(--ease);
}
.host-row:hover { transform: translateY(-3px); box-shadow: var(--sh-3); border-color: var(--line-2); }
.host-row:hover::before { opacity: 1; top: 8%; bottom: 8%; }
.host-row.is-selected { border-color: var(--a1); box-shadow: 0 0 0 3px var(--accent-soft), var(--sh-2); }

.rank {
  display: grid; place-items: center; width: 2rem; height: 2rem; border-radius: .55rem;
  background: var(--surface-2); border: 1px solid var(--line);
  font: 700 .88rem/1 var(--sans); color: var(--ink-3); font-variant-numeric: tabular-nums;
}
.host-row.is-top .rank, .rank-1 { color: #fff; border-color: transparent; background: var(--grad); box-shadow: var(--sh-glow); }

.host-id { display: flex; align-items: center; gap: 1rem; min-width: 0; }

/* Painted in the brand's own colour — see partials/logo.php for why. */
.host-logo {
  --bc: var(--a1);
  flex: 0 0 auto; display: grid; place-items: center;
  width: 3.4rem; height: 3.4rem; border-radius: .8rem;
  background: linear-gradient(155deg,
              color-mix(in srgb, var(--bc) 92%, white),
              var(--bc) 55%,
              color-mix(in srgb, var(--bc) 72%, black));
  color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.3);
  font: 800 1rem/1 var(--sans); letter-spacing: -.04em;
  box-shadow: 0 3px 10px -3px color-mix(in srgb, var(--bc) 55%, transparent),
              inset 0 1px 0 rgba(255,255,255,.3);
  transition: transform .3s var(--spring), box-shadow .3s var(--ease);
  overflow: hidden;
}
.host-row:hover .host-logo, .spotlight:hover .host-logo {
  transform: scale(1.05) rotate(-2deg);
  box-shadow: 0 6px 18px -4px color-mix(in srgb, var(--bc) 65%, transparent),
              inset 0 1px 0 rgba(255,255,255,.35);
}
/* real logo files sit on a white plate so any mark stays legible */
.host-logo.has-img { background: #fff; border: 1px solid var(--line); padding: .4rem; }
.host-logo img { width: 100%; height: 100%; object-fit: contain; }
.host-logo-lg { width: 4.4rem; height: 4.4rem; font-size: 1.28rem; border-radius: 1rem; }
.host-logo-sm { width: 2.2rem; height: 2.2rem; font-size: .68rem; border-radius: .5rem; }

.tested-on {
  display: inline-block; margin-top: .5rem;
  font: 600 .68rem/1 var(--sans); text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3);
}

.best-for {
  display: inline-block; font: 700 .68rem/1.5 var(--sans);
  text-transform: uppercase; letter-spacing: .1em;
  background: var(--grad-bright); -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
/* Brand names are product names, not editorial headings — keep them in the sans
   so they read as labels and stay legible at small sizes. */
.host-name {
  display: block; font-family: var(--sans); font-size: 1.22rem; font-weight: 700;
  letter-spacing: -.025em; line-height: 1.2; color: var(--ink); text-decoration: none;
}
.host-name:hover { color: var(--a1); }
.host-tag {
  font-size: .83rem; line-height: 1.45; color: var(--ink-3); margin-top: .15rem;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

.price-cell b {
  display: block; font-family: var(--display); font-size: 1.75rem; font-weight: 800;
  line-height: 1; letter-spacing: -.045em; font-variant-numeric: tabular-nums;
}
.price-cell .per { font-size: .73rem; color: var(--ink-3); }
.price-cell .renew {
  display: inline-block; margin-top: .35rem; padding: .12rem .45rem; border-radius: .3rem;
  font-size: .69rem; font-weight: 700; color: var(--warn); background: var(--warn-soft);
}

.score-cell { display: grid; justify-items: center; gap: .4rem; }
.verdict-word { font: 700 .64rem/1 var(--sans); text-transform: uppercase; letter-spacing: .09em; color: var(--ink-3); }
.stars { color: var(--gold); font-size: .8rem; letter-spacing: .09em; }
.ugc { font-size: .69rem; color: var(--ink-3); }

.cta-cell { display: grid; gap: .4rem; }
.cta-cell .tcs { font-size: .66rem; color: var(--ink-3); text-align: center; }

/* compare toggle */
.cmp-toggle {
  display: inline-flex; align-items: center; justify-content: center; gap: .3rem;
  padding: .3rem .55rem; border-radius: .4rem; cursor: pointer;
  font: 600 .72rem/1.3 var(--sans); color: var(--ink-3);
  background: transparent; border: 1px dashed var(--line-2);
  transition: all .16s var(--ease);
}
.cmp-toggle:hover { color: var(--a1); border-color: var(--a1); background: var(--accent-soft); }
.cmp-toggle[aria-pressed="true"] {
  color: #fff; background: var(--grad); border-style: solid; border-color: transparent;
}

@media (max-width: 1020px) {
  .host-row {
    grid-template-columns: 2rem 1fr auto;
    grid-template-areas: "rank id score" "price price cta";
    row-gap: 1.1rem; padding: 1.4rem 1.25rem;
  }
  .rank { grid-area: rank } .host-id { grid-area: id } .score-cell { grid-area: score }
  .price-cell { grid-area: price; display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
                border-top: 1px solid var(--line); padding-top: 1rem; }
  .cta-cell { grid-area: cta; border-top: 1px solid var(--line); padding-top: 1rem; }
}
@media (max-width: 560px) {
  .host-row { grid-template-areas: "rank id id" "score price price" "cta cta cta"; }
  .price-cell { border: 0; padding-top: 0 } .cta-cell { padding-top: .5rem }
  .host-logo { width: 2.9rem; height: 2.9rem; font-size: .9rem }
}

/* ================================================== sticky compare drawer */
.cmp-drawer {
  position: fixed; left: 50%; bottom: 1.25rem; z-index: 70;
  transform: translate(-50%, 150%); opacity: 0; pointer-events: none;
  display: flex; align-items: center; gap: 1.15rem;
  padding: .8rem .85rem .8rem 1.35rem; border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 92%, transparent);
  color: #fff; box-shadow: 0 16px 44px -12px rgba(0,0,0,.55);
  backdrop-filter: blur(14px); max-width: calc(100vw - 2rem);
  transition: transform .42s var(--spring), opacity .3s var(--ease);
}
.cmp-drawer.open { transform: translate(-50%, 0); opacity: 1; pointer-events: auto; }
.cmp-drawer .cmp-names { font: 650 .88rem/1.3 var(--sans); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cmp-drawer .cmp-hint { font-size: .74rem; opacity: .6; }
.cmp-drawer .cmp-clear {
  background: none; border: 0; color: rgba(255,255,255,.6); cursor: pointer;
  font-size: 1.1rem; line-height: 1; padding: .2rem .4rem;
}
.cmp-drawer .cmp-clear:hover { color: #fff; }
@media (prefers-color-scheme: dark) {
  .cmp-drawer { background: color-mix(in srgb, var(--surface-3) 94%, transparent); border: 1px solid var(--line-2); }
}

/* ---------------------------------------------------------------- cards */
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 1.7rem; box-shadow: var(--sh-1);
}



/* exactly three across on desktop so a 6-card set never leaves an orphan */
.grid-cards { display: grid; gap: 1.4rem; grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 960px) { .grid-cards { grid-template-columns: repeat(2, minmax(0, 1fr)) } }
@media (max-width: 600px) { .grid-cards { grid-template-columns: 1fr } }

/* --------------------------------------------------------------- review */
.review-head { display: grid; grid-template-columns: 1fr 21rem; gap: 3rem; align-items: start; padding: 2.5rem 0 1rem; }
@media (max-width: 940px) { .review-head { grid-template-columns: 1fr; gap: 2rem } }
/* .crumbs now lives with the breadcrumb partial, later in this file. */

.verdict-box {
  position: relative; background: none;
  border: 0; border-left: 2px solid var(--a1);
  border-radius: 0; padding: .25rem 0 .25rem 1.5rem; overflow: hidden;
}
.verdict-box::before { display: none; }
.verdict-box h2 {
  font-family: var(--sans); font-size: .68rem; font-weight: 800; text-transform: uppercase;
  letter-spacing: .14em; color: var(--a1); margin: 0 0 .6rem;
}
.verdict-box p { margin: 0; font-size: 1.08rem; line-height: 1.65; color: var(--ink); }

/* at-a-glance grid on review pages */
.glance {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0;
  margin-top: 2rem; border-radius: 0; overflow: visible;
  background: none; border: 0; border-top: 1px solid var(--line);
}
@media (max-width: 620px) { .glance { grid-template-columns: repeat(2, minmax(0, 1fr)) } }
.glance-item { display: grid; gap: .3rem; padding: 1.1rem 1.25rem 1.1rem 0; background: none;
               border-bottom: 1px solid var(--line); }
.g-label { font: 650 .68rem/1 var(--sans); text-transform: uppercase; letter-spacing: .11em; color: var(--ink-3); }
.g-value { font: 800 1.32rem/1.15 var(--display); letter-spacing: -.035em; font-variant-numeric: tabular-nums; }
.g-warn { color: var(--warn); }
.g-none { font: 500 .82rem/1.3 var(--sans); color: var(--ink-3); letter-spacing: 0; }

.buy-box {
  position: sticky; top: 6.5rem;
  border: 1px solid var(--line-2); border-radius: var(--r-lg);
  padding: 1.75rem; background: var(--surface); box-shadow: none;
  display: grid; justify-items: center; gap: .1rem;
}
.buy-box .btn { margin-top: 1.15rem }
.buy-box > .tiny { line-height: 1.5; }
.rubric { display: grid; gap: .75rem; width: 100%; margin-top: 1.5rem; padding-top: 1.4rem; border-top: 1px solid var(--line) }
.rubric-row { display: grid; grid-template-columns: 5.9rem 1fr 1.9rem; gap: .75rem; align-items: center; font-size: .82rem }
.rubric-row span:first-child { color: var(--ink-2) }
.bar { height: .45rem; border-radius: 999px; background: var(--surface-3); overflow: hidden }
.bar span { display: block; height: 100%; border-radius: 999px; background: var(--grad-bright);
            transform-origin: left; animation: growBar .9s var(--ease) both }
@keyframes growBar { from { transform: scaleX(0) } to { transform: scaleX(1) } }

.pros-cons { display: grid; gap: 2.5rem 3.5rem; grid-template-columns: 1fr 1fr; margin: 2.5rem 0 }
@media (max-width: 700px) { .pros-cons { grid-template-columns: 1fr } }
.pros-cons > .card {
  background: none; border: 0; border-top: 2px solid var(--line);
  border-radius: 0; box-shadow: none; padding: 1.35rem 0 0;
}
.pros-cons > .pros { border-top-color: var(--good); }
.pros-cons > .cons { border-top-color: var(--bad); }
.pros-cons ul { margin: 0; padding: 0; list-style: none; display: grid; gap: .8rem }
.pros-cons li { display: flex; gap: .7rem; font-size: .95rem; line-height: 1.6; color: var(--ink-2) }
.pros-cons li::before { flex: 0 0 auto; font-weight: 800 }
.pros h3, .cons h3 { font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .13em;
                     margin-bottom: 1rem; }
.pros h3 { color: var(--good) } .cons h3 { color: var(--bad) }
.pros li::before { content: "\2713"; color: var(--good) } .cons li::before { content: "\2715"; color: var(--bad) }

/* .prose is defined in full further down — it serves the guides and the review body. */

/* --------------------------------------------------------------- tables */
.table-scroll {
  overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 1.5rem 0 2.5rem;
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--surface); box-shadow: var(--sh-1);
}
table.data { width: 100%; border-collapse: collapse; font-size: .9rem }
table.data th, table.data td { padding: .82rem 1rem; text-align: left }
table.data thead th {
  font: 800 .68rem/1.3 var(--sans); text-transform: uppercase; letter-spacing: .1em;
  color: var(--ink-3); background: var(--surface-2); border-bottom: 1px solid var(--line);
  white-space: nowrap; position: sticky; top: 0;
}
table.data tbody tr + tr th, table.data tbody tr + tr td { border-top: 1px solid var(--line) }
table.data tbody th { font-weight: 650; color: var(--ink-2); font-size: .85rem }
table.data tbody tr { transition: background .12s var(--ease) }
table.data tbody tr:hover { background: var(--surface-2) }

/* ------------------------------------------------------------------- ugc */
.ugc-meta { display: flex; gap: .65rem; align-items: center; flex-wrap: wrap; font-size: .78rem; color: var(--ink-3) }
.ugc-meta strong { color: var(--ink); font-weight: 650; font-size: .88rem }
.badge-verified { color: var(--good); font: 800 .65rem/1 var(--sans); letter-spacing: .07em;
                  background: var(--good-soft); padding: .24rem .45rem; border-radius: .3rem }

/* ---------------------------------------------------------------- forms */
label { display: block; margin-bottom: 1rem; font-size: .84rem; font-weight: 650; color: var(--ink-2) }
label.check { display: flex; gap: .55rem; align-items: center; font-weight: 500; color: var(--ink) }
input[type=text], input[type=email], input[type=password], input[type=number],
input[type=url], input[type=date], select, textarea {
  width: 100%; margin-top: .35rem; padding: .65rem .78rem;
  font: 400 .93rem/1.5 var(--sans); color: var(--ink);
  background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--r-sm);
  box-shadow: inset 0 1px 2px rgba(10,14,26,.04);
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
input:hover, select:hover, textarea:hover { border-color: var(--ink-3) }
input:focus, select:focus, textarea:focus {
  border-color: var(--a1); outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--a1) 18%, transparent);
}
textarea { min-height: 7.5rem; resize: vertical }
fieldset { border: 1px solid var(--line); border-radius: var(--r); padding: 1.4rem; margin: 0 0 1.5rem; background: var(--surface) }
legend { font: 800 .7rem/1 var(--sans); text-transform: uppercase; letter-spacing: .11em; color: var(--ink-3); padding: 0 .45rem }
.field-row { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)) }

.note { padding: .95rem 1.2rem; border-radius: var(--r-sm); font-size: .88rem; line-height: 1.6;
        margin: 1.25rem 0; border: 1px solid var(--line); border-left-width: 3px }
.note-good { background: var(--good-soft); border-color: var(--good) }
.note-warn { background: var(--warn-soft); border-color: var(--warn) }
.note-bad  { background: var(--bad-soft);  border-color: var(--bad) }

/* ============================================================================
   FILTERS
   Was one 999px pill holding six identical chips. Price is one-of-four and the
   includes are any-of-two, but both looked the same, so the control gave no clue
   which choices were exclusive. Now: a segmented control for the radio group, a
   checkbox toggle for each independent option.
   ========================================================================== */
/* Shared shell: the JS auto-submit hook, and the surface both bars sit on.
   /compare uses this as a single inline row, so the shell stays neutral and the
   stacked-group layout is a modifier. */
.filter-bar {
  display: flex; gap: .6rem; align-items: center; flex-wrap: wrap;
  padding: .9rem 1.1rem; border-radius: var(--r-lg);
  background: var(--surface-2); border: 1px solid var(--line); box-shadow: var(--sh-1);
}
.filter-bar .fb-label {
  font: 700 .655rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-3); padding: 0 .35rem;
}
/* The global `select` rule adds a .35rem top margin for stacked form fields,
   which left the selects sitting low against the label and button in this row. */
.filter-bar select { margin-top: 0; }
.filter-bar label { margin-bottom: 0; }

/* Ranking pages: labelled groups, so items align on their controls' baseline. */
.filter-bar.fb-groups { gap: 1.6rem; align-items: flex-end; padding: 1rem 1.15rem; }
.filter-form { margin: 2rem 0 1.5rem; }

/* fieldset stays `display: block` — `legend` inside a grid or flex fieldset is
   laid out inconsistently across browsers.
   The global `fieldset` rule also sets a white background and the global `label`
   rule a 1rem bottom margin, which drew a white slab behind each group and left
   dead space under the controls. Both have to be cleared here. */
.fgroup { border: 0; margin: 0; padding: 0; background: none; }
.fseg-o, .ftog { margin-bottom: 0; }
.fgroup legend {
  display: block; padding: 0; margin-bottom: .5rem;
  font: 700 .655rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-3);
}

/* ------------------------------------------------- segmented control (one of) */
.fseg {
  display: inline-flex;
  background: var(--surface); border: 1px solid var(--line-2);
  border-radius: var(--r-sm); box-shadow: var(--sh-1);
}
.fseg-o {
  position: relative; cursor: pointer;
  padding: .52rem .85rem;
  font: 650 .82rem/1 var(--sans); color: var(--ink-2); white-space: nowrap;
  transition: color .15s var(--ease), background-color .15s var(--ease);
}
.fseg-o:first-child { border-radius: var(--r-sm) 0 0 var(--r-sm); }
.fseg-o:last-child  { border-radius: 0 var(--r-sm) var(--r-sm) 0; }
.fseg-o + .fseg-o { border-left: 1px solid var(--line); }
.fseg-o input { position: absolute; opacity: 0; width: 0; height: 0; }
.fseg-o:hover { color: var(--ink); background: var(--surface-2); }

/* `.on` is server-rendered; `:has` makes the control respond to the click
   immediately, before the auto-submit round trip. */
.fseg-o.on,
.fseg-o:has(input:checked) { color: #fff; background: var(--a1); }
/* A --line divider against the filled segment would show as a pale sliver. */
.fseg-o.on + .fseg-o,
.fseg-o:has(input:checked) + .fseg-o { border-left-color: var(--a1); }
.fseg-o:has(input:focus-visible) { outline: 2px solid var(--a1); outline-offset: -2px; z-index: 1; }

/* ------------------------------------------------------ toggles (any of) */
.ftogs { display: flex; flex-wrap: wrap; gap: .4rem; }
.ftog {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .48rem .78rem .48rem .6rem; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-sm); box-shadow: var(--sh-1);
  font: 650 .82rem/1 var(--sans); color: var(--ink-2); white-space: nowrap;
  transition: color .15s var(--ease), border-color .15s var(--ease),
              background-color .15s var(--ease);
}
.ftog input { position: absolute; opacity: 0; width: 0; height: 0; }
.ftog i {                            /* a real checkbox affordance */
  flex: none; width: .95rem; height: .95rem; border-radius: .25rem;
  border: 1.5px solid var(--line-2); background: var(--surface);
  display: grid; place-items: center;
  transition: background-color .15s var(--ease), border-color .15s var(--ease);
}
.ftog i::after {
  content: "\2713"; font-size: .6rem; font-weight: 700; line-height: 1; color: #fff;
  opacity: 0; transition: opacity .12s var(--ease);
}
.ftog:hover { color: var(--ink); border-color: var(--ink-3); }

/* Toggles fill with the accent tint rather than solid accent, so they stay
   visually distinct from the exclusive segmented control above. */
.ftog.on,
.ftog:has(input:checked) {
  color: var(--a1); background: var(--accent-soft); border-color: var(--accent-line);
}
.ftog.on i,
.ftog:has(input:checked) i { background: var(--a1); border-color: var(--a1); }
.ftog.on i::after,
.ftog:has(input:checked) i::after { opacity: 1; }
.ftog:has(input:focus-visible) { outline: 2px solid var(--a1); outline-offset: 2px; }

/* ------------------------------------------------------------- result count */
.fresult {
  margin-left: auto; display: flex; align-items: center; gap: .8rem;
  padding-bottom: .15rem;
}
.fresult-n {
  font: 500 .785rem/1 var(--sans); color: var(--ink-3);
  font-variant-numeric: lining-nums tabular-nums;
}
.fresult-n b { font-weight: 800; color: var(--ink); }
.fclear {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .46rem .68rem;
  font: 650 .78rem/1 var(--sans); color: var(--ink-2); text-decoration: none;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-sm);
  transition: color .15s var(--ease), border-color .15s var(--ease);
}
.fclear span { font-size: .68rem; }
.fclear:hover { color: var(--warn); border-color: var(--warn); }

@media (max-width: 780px) {
  .filter-bar.fb-groups { gap: 1.1rem; padding: .9rem 1rem; }
  .fb-groups .fgroup, .fb-groups .fseg { width: 100%; }
  .fseg { display: flex; }
  .fseg-o { flex: 1; text-align: center; padding: .52rem .5rem; }
  .fresult {
    margin-left: 0; width: 100%;
    padding-top: .9rem; border-top: 1px solid var(--line);
  }
  .fclear { margin-left: auto; }
}

/* ---------------------------------------------------------------- cta band */
/* Vivid accent, NOT near-black: the footer below is already near-black, and two
   dark bands touching read as one muddy slab with a seam in it. */
.cta-band {
  position: relative; overflow: hidden; isolation: isolate;
  margin-top: 4.5rem; padding: 3.75rem 0;
  background: linear-gradient(135deg, #4338ca 0%, #6d5cf7 48%, #8b5cf6 100%);
  color: #fff; text-align: center;
}
.cta-band::after {          /* faint grid so the flat gradient has texture */
  content: ""; position: absolute; inset: 0; z-index: -1; opacity: .4;
  background-image: linear-gradient(rgba(255,255,255,.07) 1px, transparent 1px),
                    linear-gradient(90deg, rgba(255,255,255,.07) 1px, transparent 1px);
  background-size: 46px 46px;
  mask-image: radial-gradient(ellipse 80% 100% at 50% 50%, #000 20%, transparent 78%);
}
.cta-band h2 { margin-top: 0; color: #fff }
.cta-band p { color: #e2e0ff; max-width: 48ch; margin-inline: auto }
.cta-band .aurora { display: none }

/* ----------------------------------------------------------------- admin */
.admin-shell { display: grid; grid-template-columns: 15rem 1fr; min-height: 100vh }
@media (max-width: 860px) { .admin-shell { grid-template-columns: 1fr } }
.admin-side { background: var(--surface-2); border-right: 1px solid var(--line); padding: 1.5rem 1.15rem }
.admin-side a { display: block; padding: .52rem .72rem; border-radius: var(--r-sm); color: var(--ink-2);
                text-decoration: none; font-size: .89rem; font-weight: 600; margin-bottom: .15rem;
                transition: background .12s var(--ease), color .12s var(--ease) }
.admin-side a:hover { background: var(--surface-3); color: var(--ink) }
.admin-side a.on { color: #fff; background: var(--grad); box-shadow: var(--sh-glow) }
.admin-main { padding: 2rem 2.5rem 4rem; max-width: 1120px }
@media (max-width: 640px) { .admin-main { padding: 1.35rem } }
.admin-main > h1 { font-size: 1.8rem; margin-bottom: 1.25rem }

.kpi-row { display: grid; gap: 1.1rem; grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr)); margin-bottom: 1.75rem }
.kpi { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: 1.2rem 1.3rem; box-shadow: var(--sh-1) }
.kpi b { display: block; font-family: var(--display); font-size: 1.95rem; font-weight: 800;
         line-height: 1; letter-spacing: -.045em; font-variant-numeric: tabular-nums }
.kpi span { font-size: .68rem; text-transform: uppercase; letter-spacing: .11em; color: var(--ink-3); font-weight: 700 }

.spark { display: flex; align-items: flex-end; gap: 2px; height: 4rem; margin-top: .8rem }
.spark i { flex: 1; min-height: 2px; border-radius: 2px 2px 0 0; background: var(--grad); opacity: .85 }
.spark i:hover { opacity: 1 }

.pill { display: inline-block; padding: .2rem .58rem; border-radius: 999px;
        font: 800 .67rem/1.4 var(--sans); letter-spacing: .05em; text-transform: uppercase }
.pill-live { background: var(--good-soft); color: var(--good) }
.pill-draft { background: var(--surface-3); color: var(--ink-3) }

/* ---------------------------------------------------------------- motion */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto }
  *, *::before, *::after { transition: none !important; animation: none !important }
  .js-anim .reveal { opacity: 1; transform: none }
  .btn:hover, .host-row:hover, .cat-card:hover, .spotlight:hover { transform: none }
}

/* --------------------------------------------------- hero: the renewal gap */
/* Replaces the old fake uptime sparklines. Two bars per host: published intro
   price vs published renewal price, scaled against the largest on show. */
.gap-row {
  display: grid; grid-template-columns: 1.85rem minmax(4.5rem, auto) 1fr 2.6rem;
  gap: .7rem; align-items: center; padding: .62rem .65rem; border-radius: .6rem;
  transition: background .2s var(--ease);
}
.gap-row:hover { background: rgba(255,255,255,.05); }

.gap-bars { display: grid; gap: 3px; min-width: 0; }
.gap-bar {
  display: flex; align-items: center; justify-content: flex-end;
  height: .82rem; width: var(--w); min-width: 2.6rem; border-radius: 3px;
  padding-right: .3rem;
  transform: scaleX(0); transform-origin: left;
  animation: gapGrow .55s var(--ease) forwards;
  animation-delay: var(--d, 0ms);
}
.gap-bar b {
  font: 700 .62rem/1 var(--sans); font-variant-numeric: lining-nums tabular-nums;
  color: #fff; text-shadow: 0 1px 1px rgba(0,0,0,.4);
}
@keyframes gapGrow { to { transform: scaleX(1) } }

.gap-intro      { background: linear-gradient(90deg, #22d3ee, #06b6d4); }
.gap-renew-hot  { background: linear-gradient(90deg, #f59e0b, #ef4444); }
.gap-renew-flat { background: linear-gradient(90deg, #6d5cf7, #8b5cf6); }

.gap-mult {
  font: 800 .76rem/1 var(--sans); text-align: right;
  font-variant-numeric: lining-nums tabular-nums;
}
.gap-mult.is-hot  { color: #fbbf24; }
.gap-mult.is-flat { color: #6ee7c8; font-weight: 700; font-size: .68rem; }

.gap-key { display: inline-flex; align-items: center; gap: .35rem; }
.gap-key i { width: .6rem; height: .6rem; border-radius: 2px; display: block; }
.gap-key .k-intro { background: #06b6d4; }
.gap-key .k-renew { background: #ef4444; }
.gap-caveat { margin-left: auto; opacity: .8; }

/* ============================================================================
   REVIEW PAGE
   ========================================================================== */

/* ------------------------------------------------------------ chapter nav */
/* Long review pages need a spine. Sticks under the header, highlights the
   section you are in, and carries a CTA so the buy button never scrolls away. */
.chapter-nav {
  position: sticky; top: 4.4rem; z-index: 50;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-block: 1px solid var(--line);
  margin: 2.5rem 0 2rem;
}
.chapter-inner {
  display: flex; align-items: center; gap: .3rem;
  min-height: 3.35rem; overflow-x: auto; scrollbar-width: none;
}
.chapter-inner::-webkit-scrollbar { display: none; }
.chapter-label {
  font: 700 .72rem/1 var(--sans); text-transform: uppercase; letter-spacing: .1em;
  color: var(--ink-3); padding-right: .9rem; margin-right: .3rem;
  border-right: 1px solid var(--line); white-space: nowrap; flex: 0 0 auto;
}
.chapter-inner a:not(.chapter-cta) {
  padding: .45rem .8rem; border-radius: var(--r-sm); white-space: nowrap;
  font: 600 .87rem/1 var(--sans); color: var(--ink-2); text-decoration: none;
  transition: background .15s var(--ease), color .15s var(--ease);
}
.chapter-inner a:not(.chapter-cta):hover { background: var(--surface-3); color: var(--ink); }
.chapter-inner a.is-current { color: var(--a1); background: var(--accent-soft); }
.chapter-cta { margin-left: auto; flex: 0 0 auto; }
@media (max-width: 720px) { .chapter-label, .chapter-cta { display: none } }

.g-none { font: 500 .82rem/1.3 var(--sans); color: var(--ink-3); letter-spacing: 0; }

/* --------------------------------------------------------- cost-over-time */
.cost-module { display: grid; gap: 1.25rem; }
.cost-years {
  display: grid; grid-template-columns: 1fr 1fr minmax(0, .85fr); gap: 1.25rem;
}
@media (max-width: 900px) { .cost-years { grid-template-columns: 1fr } }

.cost-year, .cost-total {
  display: grid; gap: .5rem; align-content: start;
  padding: 1.4rem 1.5rem; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--sh-1);
}
.cost-total {
  background: linear-gradient(var(--surface), var(--surface)) padding-box,
              var(--grad) border-box;
  border: 1.5px solid transparent; box-shadow: var(--sh-2);
}
.cy-label {
  font: 700 .68rem/1 var(--sans); text-transform: uppercase; letter-spacing: .11em;
  color: var(--ink-3);
}
.cy-amount, .ct-amount {
  font-family: var(--display); font-weight: 700; font-size: 2.1rem; line-height: 1;
  letter-spacing: -.03em; font-variant-numeric: lining-nums tabular-nums;
}
.cy-amount.is-hot { color: var(--warn); }
.ct-amount { font-size: 2.4rem; }
.cy-bar { display: block; height: .5rem; border-radius: 999px; background: var(--surface-3); overflow: hidden; }
.cy-fill {
  display: block; height: 100%; width: var(--w); border-radius: 999px;
  transform-origin: left; animation: growBar .8s var(--ease) both;
}
.cy-intro { background: linear-gradient(90deg, #22d3ee, #06b6d4); }
.cy-hot   { background: linear-gradient(90deg, #f59e0b, #ef4444); }
.cy-flat  { background: var(--grad-bright); }
.cy-rate { font-size: .82rem; color: var(--ink-2); }
.cy-rate b { color: var(--warn); }
.ct-note { font-size: .82rem; color: var(--ink-2); min-height: 2.4em; }
.cost-total .btn { margin-top: .35rem; }

.cost-context {
  margin: 0; padding: 1rem 1.25rem; border-radius: var(--r);
  background: var(--surface); border: 1px solid var(--line);
  font-size: .9rem; line-height: 1.6; color: var(--ink-2);
}
.cost-context strong { color: var(--ink); }
.cost-caveat { margin: 0; font-size: .78rem; color: var(--ink-3); }

/* -------------------------------------------------------------- spec grid */
/* Replaces a two-column key/value table, which reads as raw database output. */
.spec-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: 1px;
  background: var(--line); border: 1px solid var(--line);
  border-radius: var(--r-lg); overflow: hidden;
}
.spec-item {
  display: grid; grid-template-columns: 2rem 1fr; grid-template-rows: auto auto;
  gap: .1rem .75rem; align-items: center;
  padding: 1.15rem 1.35rem; background: var(--surface);
  transition: background .15s var(--ease);
}
.spec-item:hover { background: var(--surface-2); }
.spec-icon { grid-row: 1 / 3; font-size: 1.15rem; opacity: .75; }
.spec-label {
  font: 650 .68rem/1 var(--sans); text-transform: uppercase; letter-spacing: .1em;
  color: var(--ink-3);
}
.spec-value { font: 600 .95rem/1.4 var(--sans); color: var(--ink); }

/* ------------------------------------------------------------- plan cards */
.plan-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(15.5rem, 1fr)); gap: 1.25rem; }
.plan-card {
  position: relative; display: grid; align-content: start; gap: .35rem;
  padding: 1.6rem 1.5rem; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--sh-1);
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s var(--ease);
}
.plan-card:hover { transform: translateY(-3px); box-shadow: var(--sh-3); border-color: var(--line-2); }
.plan-card.is-featured {
  background: linear-gradient(var(--surface), var(--surface)) padding-box,
              var(--grad) border-box;
  border: 1.5px solid transparent; box-shadow: var(--sh-2);
}
.plan-flag {
  position: absolute; top: -.7rem; left: 1.4rem;
  padding: .2rem .6rem; border-radius: 999px; color: #fff; background: var(--grad);
  font: 800 .62rem/1.5 var(--sans); text-transform: uppercase; letter-spacing: .1em;
  box-shadow: var(--sh-glow);
}
.plan-name { font-family: var(--sans); font-weight: 700; font-size: 1.05rem; margin: 0; letter-spacing: -.02em; }
.plan-price { display: flex; align-items: baseline; gap: .25rem; }
.pp-now {
  font-family: var(--display); font-weight: 700; font-size: 2.05rem; line-height: 1;
  letter-spacing: -.035em; font-variant-numeric: lining-nums tabular-nums;
}
.pp-per { font-size: .8rem; color: var(--ink-3); }
.plan-renew { font-size: .84rem; color: var(--ink-2); }
.plan-renew.is-hot { color: var(--warn); }
.plan-renew strong { font-weight: 700; }
.plan-term { font-size: .74rem; color: var(--ink-3); }

.plan-specs { list-style: none; margin: .9rem 0 0; padding: .9rem 0 0; border-top: 1px solid var(--line); display: grid; gap: .4rem; }
.plan-specs li { display: flex; justify-content: space-between; gap: .75rem; font-size: .84rem; }
.plan-specs span { color: var(--ink-3); }
.plan-specs b { font-weight: 650; text-align: right; }
.plan-note {
  margin: .8rem 0 0; padding: .5rem .7rem; border-radius: var(--r-sm);
  background: var(--accent-soft); color: var(--a1);
  font: 600 .78rem/1.4 var(--sans);
}
.plan-card .btn { margin-top: 1rem; }

/* ---------------------------------------------------------- reviews layout */
@media (max-width: 900px) { .reviews-layout { grid-template-columns: 1fr } }

/* Empty state: fills the column instead of leaving a hole beside a tall form. */

/* ------------------------------------------------------------- alt cards */
.alt-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); gap: 1.25rem; }
.alt-card {
  display: grid; align-content: start; gap: .55rem;
  text-decoration: none; color: inherit;
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s var(--ease);
}
.alt-card:hover { transform: translateY(-4px); box-shadow: var(--sh-3); border-color: var(--accent-line); color: inherit; }
.alt-top { display: flex; align-items: center; gap: .65rem; }
.alt-name { font: 700 1.05rem/1.2 var(--sans); letter-spacing: -.025em; flex: 1; min-width: 0; }
.alt-score {
  font: 800 .82rem/1 var(--sans); font-variant-numeric: lining-nums tabular-nums;
  color: var(--a1); background: var(--accent-soft); padding: .28rem .45rem; border-radius: .35rem;
}
.alt-tag { margin: 0; font-size: .84rem; line-height: 1.5; color: var(--ink-3); }
.alt-prices {
  display: flex; gap: 1rem; flex-wrap: wrap; padding: .7rem 0;
  border-block: 1px solid var(--line); font-size: .8rem; color: var(--ink-3);
}
.alt-prices b { font-weight: 700; color: var(--ink); font-variant-numeric: lining-nums tabular-nums; }
.alt-renew b { color: var(--warn); }
.alt-why { margin: 0; font-size: .86rem; line-height: 1.5; color: var(--ink-2); }
.alt-card .arrow { margin-top: .35rem; font: 700 .8rem/1 var(--sans); color: var(--a1);
                   display: inline-flex; gap: .35rem; align-items: center; }
.alt-card .arrow span { transition: transform .25s var(--spring); }
.alt-card:hover .arrow span { transform: translateX(4px); }

/* ============================================================================
   HEADER
   Slim dark utility bar -> sticky frosted nav with a Rankings mega-menu ->
   disclosure strip. Three tiers so the commercial disclosure stays visible
   without competing with navigation.
   ========================================================================== */

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  padding: .7rem 1.1rem; background: var(--ink); color: #fff;
  border-radius: 0 0 var(--r-sm) 0; font: 650 .88rem/1 var(--sans);
}
.skip-link:focus { left: 0; color: #fff; }

/* ------------------------------------------------------------- utility bar */
.util-bar { background: #070a14; color: #9aa6bf; font-size: .76rem; }
.util-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; min-height: 2.35rem; flex-wrap: wrap;
}
.util-left { display: inline-flex; align-items: center; gap: .5rem; letter-spacing: .01em; }
.util-right { display: inline-flex; align-items: center; gap: .8rem; }
.util-right a { color: #b6c0d6; text-decoration: none; }
.util-right a:hover { color: #fff; }
.util-sep { width: 1px; height: .85rem; background: rgba(255,255,255,.15); }
.util-badge {
  display: inline-flex; align-items: center; padding: .12rem .5rem; border-radius: 999px;
  font: 700 .66rem/1.5 var(--sans); text-transform: uppercase; letter-spacing: .08em;
  color: #6ee7c8; background: rgba(110,231,200,.12); border: 1px solid rgba(110,231,200,.25);
}
@media (max-width: 700px) { .util-right a, .util-sep { display: none } }

/* ---------------------------------------------------------------- main nav */
.site-head {
  position: sticky; top: 0; z-index: 60;
  background: color-mix(in srgb, var(--surface) 84%, transparent);
  backdrop-filter: saturate(180%) blur(18px);
  -webkit-backdrop-filter: saturate(180%) blur(18px);
  border-bottom: 1px solid var(--line);
  transition: box-shadow .25s var(--ease), background .25s var(--ease);
}
.site-head.is-stuck {
  box-shadow: 0 1px 0 var(--line), 0 10px 30px -14px rgba(10,14,26,.25);
  background: color-mix(in srgb, var(--surface) 94%, transparent);
}
.head-inner { display: flex; align-items: center; gap: 1.5rem; min-height: 4.4rem; }

.brand { display: inline-flex; align-items: center; gap: .65rem; text-decoration: none; color: var(--ink); }
.brand-mark {
  width: 2.15rem; height: 2.15rem; flex: 0 0 auto; border-radius: .62rem;
  box-shadow: var(--sh-glow); transition: transform .3s var(--spring);
}
.brand:hover .brand-mark { transform: rotate(-6deg) scale(1.06); }
/* Wordmark. Larger and set tighter than body copy so it reads as a mark rather than as a
   heading, with the two words weighted differently — "Host" lighter, "Cliff" at full weight.
   That is not decoration: the cliff is what the site is about and what the name refers to, so
   the emphasis falls where the meaning is. Rendered by .brand-name b, which the header and
   footer wrap around the second word; if it is ever a single word the whole thing simply
   renders at the lighter weight and still works. */
.brand-name {
  font-family: var(--display);
  font-weight: 500;
  font-size: 1.42rem;
  letter-spacing: -.035em;
  font-variation-settings: "SOFT" 0, "WONK" 0;
  white-space: nowrap;
}
.brand-name b {
  font-weight: 800;
  /* No negative margin here. An earlier version pulled the words together by -.06em, which
     closed up the space in "Host Cliff" and made it read as one word again — the opposite of
     the point. The space stays a space. */
}

.main-nav { display: flex; align-items: center; gap: .35rem; margin-left: auto; }
.nav-item {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .48rem .8rem; border-radius: var(--r-sm);
  font: 600 .9rem/1 var(--sans); color: var(--ink-2);
  background: none; border: 0; cursor: pointer; text-decoration: none;
  transition: background .16s var(--ease), color .16s var(--ease);
}
.nav-item:hover, .nav-item[aria-expanded="true"] { background: var(--surface-3); color: var(--ink); }
.nav-item.on { color: var(--a1); background: var(--accent-soft); }
.caret { font-size: .62rem; opacity: .6; transition: transform .2s var(--ease); }
.nav-item[aria-expanded="true"] .caret { transform: rotate(180deg); }
.nav-cta { margin-left: .6rem; }

/* ---------------------------------------------------------------- mega menu */
.has-mega { position: relative; }
.mega {
  position: absolute; top: calc(100% + .7rem); left: 50%; transform: translateX(-50%);
  width: min(58rem, calc(100vw - 3rem)); z-index: 70;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-3);
  overflow: hidden;
  animation: megaIn .18s var(--ease);
}
@keyframes megaIn { from { opacity: 0; transform: translateX(-50%) translateY(-6px) } }
.mega[hidden] { display: none; }
.mega-inner { display: grid; grid-template-columns: 1fr 15rem; }
.mega-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .25rem; padding: 1rem; }
.mega-item {
  display: flex; gap: .8rem; align-items: flex-start;
  padding: .8rem; border-radius: var(--r-sm); text-decoration: none; color: inherit;
  transition: background .15s var(--ease);
}
.mega-item:hover { background: var(--surface-2); color: inherit; }
.mega-icon {
  display: grid; place-items: center; flex: 0 0 auto;
  width: 2.1rem; height: 2.1rem; border-radius: .55rem; font-size: .95rem;
  background: var(--surface-2); border: 1px solid var(--line);
}
.mega-item:hover .mega-icon { border-color: var(--accent-line); background: var(--accent-soft); }
.mega-text { display: grid; gap: .15rem; min-width: 0; }
.mega-title { font: 650 .92rem/1.3 var(--sans); color: var(--ink); }
.mega-desc { font-size: .78rem; line-height: 1.45; color: var(--ink-3); }
.mega-pick {
  display: inline-flex; align-items: center; gap: .35rem; margin-top: .3rem;
  font: 650 .72rem/1 var(--sans); color: var(--ink-2);
}
.pick-chip {
  --bc: var(--a1);
  display: grid; place-items: center; flex: 0 0 auto;
  width: 1.25rem; height: 1.25rem; border-radius: .3rem;
  background: linear-gradient(150deg, color-mix(in srgb, var(--bc) 80%, white), var(--bc));
  color: #fff; font: 800 .5rem/1 var(--sans); letter-spacing: -.02em;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.3);
}
.mega-side {
  padding: 1.35rem 1.35rem 1.5rem;
  background: var(--surface-2); border-left: 1px solid var(--line);
}
@media (max-width: 900px) {
  .mega-inner { grid-template-columns: 1fr }
  .mega-side { border-left: 0; border-top: 1px solid var(--line) }
}

/* --------------------------------------------------------- mobile nav panel */
.nav-toggle {
  display: none; margin-left: auto; width: 2.6rem; height: 2.6rem;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); cursor: pointer; padding: 0;
  place-items: center; gap: 4px; flex-direction: column;
}
.nav-toggle span {
  display: block; width: 1.05rem; height: 1.8px; border-radius: 2px; background: var(--ink);
  transition: transform .22s var(--ease), opacity .18s var(--ease);
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(5.8px) rotate(45deg) }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0 }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5.8px) rotate(-45deg) }

@media (max-width: 860px) {
  /*
   * The header's backdrop-filter has to go at this width, and this is the whole mobile nav bug.
   *
   * backdrop-filter creates a containing block for position:fixed descendants. The nav panel
   * lives inside <header>, so its `position: fixed` resolved against the HEADER — 71px tall —
   * instead of the viewport. The result was a 49px panel with `top: 156px` measured from the
   * header's own box: the menu appeared to open, showed one row, and let the page underneath
   * show straight through it.
   *
   * Nothing in the nav CSS or JS was wrong, which is why reading them found nothing. Only asking
   * the browser which ancestors establish a containing block located it.
   *
   * The background goes fully opaque here because the blur was what made an 84%-transparent
   * header read as deliberate rather than broken.
   */
  .site-head,
  .site-head.is-stuck {
    background: var(--surface);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  .nav-toggle { display: flex; }
  .main-nav {
    position: fixed; inset: auto 0 0 0; top: var(--head-bottom, 7rem);
    flex-direction: column; align-items: stretch; gap: .2rem; margin: 0;
    padding: 1rem 1.25rem 2rem;
    background: var(--surface); border-top: 1px solid var(--line);
    box-shadow: var(--sh-3); overflow-y: auto;
    transform: translateY(-8px); opacity: 0; pointer-events: none;
    transition: opacity .2s var(--ease), transform .2s var(--ease);
  }
  .main-nav.open { transform: none; opacity: 1; pointer-events: auto; }
  .nav-item { padding: .8rem .9rem; font-size: 1rem; justify-content: space-between; }
  .nav-cta { margin: .7rem 0 0; justify-content: center; }
  .mega {
    position: static; transform: none; width: auto; animation: none;
    border: 0; box-shadow: none; border-radius: 0; background: transparent;
  }
  .mega-inner { grid-template-columns: 1fr }
  .mega-grid { grid-template-columns: 1fr; padding: .25rem 0 .5rem }
  .mega-side { display: none }
}

/* -------------------------------------------------------------- disclosure */
.disclosure {
  background: var(--surface-2); border-bottom: 1px solid var(--line);
  font-size: .78rem; line-height: 1.5; color: var(--ink-2);
}
.disclosure-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding: .6rem 0; flex-wrap: wrap;
}
.disclosure strong { color: var(--ink); font-weight: 650; }
.disclosure a { white-space: nowrap; font-weight: 600; text-decoration: none; }
.disclosure a:hover { text-decoration: underline; }

/* ============================================================================
   FOOTER - dark, four columns, real data, working newsletter.
   ========================================================================== */
.site-foot {
  position: relative; isolation: isolate; overflow: hidden;
  margin-top: 5rem; padding: 3.75rem 0 1.75rem;
  background: #070a14; color: #c2cbdf; font-size: .9rem;
}
/* The CTA band is the last child of <main>; the footer is a sibling of <main>,
   not of the band. So `.cta-band + .site-foot` never matched on any page and
   every band was followed by an 80px white sliver before the dark footer —
   which read as a rendering fault rather than a gap. Select it for real. */
/* `~`, not `+`: the fixed-position compare drawer is a DOM sibling sitting
   between <main> and the footer, so the adjacent combinator cannot reach it. */
main:has(> .cta-band:last-child) ~ .site-foot { margin-top: 0; }
.foot-glow {
  position: absolute; inset: -55% 25% auto -15%; height: 32rem; z-index: -1;
  background: radial-gradient(ellipse at 35% 45%, rgba(79,70,229,.30), transparent 62%);
  pointer-events: none;
}

/* ---------------------------------------------------------- stats strip -- */
/* Was computed in the partial and never rendered. */
.foot-stats {
  /* Columns come from the item count, which the footer sets in --cols. It was hardcoded to 4
     while the markup emits 5 whenever a price check exists, so the fifth wrapped onto its own
     row, took a left border from `li + li`, and sat next to three empty cells. */
  display: grid; grid-template-columns: repeat(var(--cols, 4), minmax(0, 1fr));
  gap: 0; margin: 0 0 2.75rem; padding: 0; list-style: none;
  border-top: 1px solid rgba(255,255,255,.09);
  border-bottom: 1px solid rgba(255,255,255,.09);
}
.foot-stats li { display: grid; gap: .2rem; padding: 1.1rem 1.25rem 1.1rem 0; }
.foot-stats li + li { padding-left: 1.25rem; border-left: 1px solid rgba(255,255,255,.09); }
.foot-stats b {
  font-family: var(--display); font-weight: 800;
  font-size: 1.3rem; line-height: 1.15; letter-spacing: -.035em; color: #fff;
  font-variant-numeric: lining-nums tabular-nums;
}
.foot-stats span { font-size: .74rem; line-height: 1.3; color: #77839c; }
@media (max-width: 780px) {
  /* Two columns, so --cols is overridden. Every ODD item is first in its row and must lose the
     left border — nth-child(3) alone was right for four items and left a stray border on the
     fifth, which is the same off-by-one the desktop layout had. Odd works for any count. */
  .foot-stats { grid-template-columns: 1fr 1fr; }
  .foot-stats li:nth-child(odd) { padding-left: 0; border-left: 0; }
  .foot-stats li:nth-child(n+3) { border-top: 1px solid rgba(255,255,255,.09); }
}

.foot-grid {
  display: grid; grid-template-columns: 1.55fr .9fr 1fr .9fr; gap: 2.75rem;
  padding-bottom: 2.5rem;
}
@media (max-width: 1000px) {
  .foot-grid { grid-template-columns: 1fr 1fr; gap: 2.25rem }
  .foot-brand { grid-column: 1 / -1 }
}
@media (max-width: 560px) { .foot-grid { grid-template-columns: 1fr } }

.foot-logo { color: #fff; margin-bottom: 1rem; }
.foot-logo .brand-name { color: #fff; }
.foot-blurb { max-width: 40ch; font-size: .86rem; line-height: 1.65; color: #98a3ba; }

/* Chips rather than a run of text ticks, which wrapped 2 + 1 and read as prose. */
.foot-proof { display: flex; gap: .4rem; flex-wrap: wrap; margin: 1.15rem 0 0; }
.fp-item {
  display: inline-flex; align-items: center; gap: .38rem;
  font: 600 .715rem/1 var(--sans); color: #a7b2c9;
  padding: .36rem .55rem .36rem .48rem;
  background: rgba(255,255,255,.045); border: 1px solid rgba(255,255,255,.10);
  border-radius: .3rem;
}
.fp-item::before { content: "\2713"; font-size: .72rem; color: #6ee7c8; font-weight: 700; }

.foot-col { display: grid; align-content: start; gap: .1rem; }
.foot-title {
  font: 700 .7rem/1 var(--sans); text-transform: uppercase; letter-spacing: .13em;
  color: #6f7c96; margin: 0 0 .95rem;
}
.foot-col a {
  display: block; padding: .3rem 0; font-size: .865rem;
  color: #b3bdd2; text-decoration: none; transition: color .15s var(--ease);
}
.foot-col a:hover { color: #fff; }

.foot-host { display: flex !important; align-items: center; gap: .55rem; }
.fh-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fh-score {
  font: 700 .74rem/1 var(--sans); color: #6ee7c8; font-variant-numeric: tabular-nums;
  background: rgba(110,231,200,.1); padding: .18rem .38rem; border-radius: .28rem;
}

/* ------------------------------------------------------------- newsletter */
/* Its own panel. It was the last thing in the tallest column — the only element
   in the footer asking for an action, in the least prominent spot. */
.sub-panel {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 26rem);
  gap: 1.5rem 2.5rem; align-items: center;
  margin: 0 0 2.5rem; padding: 1.5rem 1.65rem;
  background: rgba(255,255,255,.035); border: 1px solid rgba(255,255,255,.10);
  border-radius: var(--r-lg);
}
@media (max-width: 860px) { .sub-panel { grid-template-columns: 1fr; gap: 1.1rem; } }

.sub-label {
  display: block; margin-bottom: .3rem;
  font-family: var(--display); font-weight: 700; font-size: 1.05rem;
  letter-spacing: -.022em; color: #fff;
}
.sub-sub { margin: 0; font-size: .82rem; line-height: 1.6; color: #8f9bb4; max-width: 46ch; }
.sub-row { display: flex; gap: .45rem; }
.sub-row input {
  flex: 1; min-width: 0; margin: 0; padding: .58rem .75rem;
  font: 400 .88rem/1.4 var(--sans); color: #fff;
  background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.15);
  border-radius: var(--r-sm); box-shadow: none;
}
.sub-row input::placeholder { color: #6f7c96; }
.sub-row input:hover { border-color: rgba(255,255,255,.28); }
.sub-row input:focus {
  border-color: var(--a2); outline: none;
  box-shadow: 0 0 0 3px rgba(139,92,246,.25);
}
.sub-note { display: block; margin-top: .5rem; font-size: .74rem; color: #77839c; }
.sub-ok  { color: #6ee7c8; }
.sub-bad { color: #fb7185; }

/* ----------------------------------------------------------------- legal */
.foot-legal {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: .6rem 2.5rem; flex-wrap: wrap;
  border-top: 1px solid rgba(255,255,255,.09); padding-top: 1.4rem;
  font-size: .76rem; line-height: 1.6; color: #6f7c96;
}
/* The markup used a bare <p>, so this max-width never applied and the note ran
   the full remaining width. */
.foot-legal-note { margin: 0; max-width: 62ch; text-align: right; }
@media (max-width: 860px) { .foot-legal-note { text-align: left; } }

/* ------------------------------------------------------------- provenance */
/* A price with no date and no source is just a rumour. */
.provenance {
  margin: 2rem 0 0; padding: 1.2rem 0 0;
  background: none; border: 0; border-top: 1px solid var(--line);
  border-radius: 0;
  font-size: .85rem; line-height: 1.6; color: var(--ink-2);
}
.prov-title {
  display: block; font: 700 .68rem/1 var(--sans); text-transform: uppercase;
  letter-spacing: .12em; color: var(--ink-3); margin-bottom: .8rem;
}
.provenance p { margin: 0 0 .45rem; }
.provenance strong { color: var(--ink); font-weight: 650; }
.prov-foot { margin: .9rem 0 0 !important; padding-top: .8rem;
             border-top: 1px solid var(--line); font-size: .8rem; }

/* ------------------------------------------------------- numeral hygiene */
/* Some display faces default to old-style (descending) figures, which reads as
   a bug in data contexts — "4 of 7" dips below the baseline. Force lining,
   tabular figures everywhere a number is presented as data. */
.stat b, .ring b, .price-cell b, .spotlight-price, .kpi b, .g-value,
.fc-value, .mon-val, .sm-val, .monitor-foot b, table.data td, table.data th {
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "lnum" 1, "tnum" 1;
}

/* ------------------------------------------------------- real logo variants */
/* Fetched logos are transparent-background PNGs, so they need a light plate to
   stay legible — including inside the dark hero chart and footer. */
.mon-logo.has-img,
.pick-chip.has-img {
  background: #fff; box-shadow: inset 0 0 0 1px rgba(0,0,0,.08);
  padding: 2px; overflow: hidden;
}
.mon-logo.has-img img,
.pick-chip.has-img img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* --------------------------------------------------------- "see all" strip */
/* Sits under a truncated ranking. States the number withheld rather than just
   trailing off — a list that silently stops reads as a bug or as the whole set. */
.see-all {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; flex-wrap: wrap; margin-top: 1.25rem;
  padding: 1.35rem 1.6rem; border-radius: var(--r-lg);
  background: var(--surface-2); border: 1px solid var(--line);
}
.sa-count {
  display: block; font: 700 1.02rem/1.3 var(--display);
  letter-spacing: -.025em; color: var(--ink);
}
.sa-note { display: block; font-size: .86rem; color: var(--ink-2); margin-top: .15rem; }

/* ---------------------------------------------------- full review + aside */
.review-body { display: grid; grid-template-columns: minmax(0, 1fr) 19rem; gap: 2.5rem; align-items: start; }
@media (max-width: 920px) { .review-body { grid-template-columns: 1fr; gap: 1.75rem } }
.review-body .prose { max-width: 66ch; }
.review-aside { display: grid; gap: 1rem; position: sticky; top: 9rem; }
@media (max-width: 920px) { .review-aside { position: static } }
.review-aside .provenance { margin: 0; font-size: .8rem; }
.aside-cta { display: grid; gap: .5rem; padding: 1.2rem 0 0;
             background: none; border: 0; box-shadow: none; border-top: 1px solid var(--line); }
.ac-label {
  font: 700 .68rem/1 var(--sans); text-transform: uppercase; letter-spacing: .11em;
  color: var(--ink-3); margin-bottom: .2rem;
}

/* The old .contact-layout / .ca-* rules lived here. The page now uses .ct-*
   further down — see the CONTACT block at the end of this file. */

/* ---------------------------------------------------------- icon system */
.ico { display: block; flex: 0 0 auto; }

/* The old compare-hub picker (.cmp-picker / .cp-*) lived here. Both pages now
   render partials/vs-picker, so those rules were dead — see .vs-picker below. */

/* --------------------------------------------------------- comparison cards */
.cmp-card { display: grid; align-content: start; gap: .7rem; text-decoration: none; color: inherit;
            box-shadow: none; }
.cmp-card:hover { box-shadow: var(--sh-2); }
.cc-brands { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.cc-brand {
  display: inline-flex; align-items: center; gap: .4rem;
  font: 700 .98rem/1.2 var(--sans); letter-spacing: -.025em;
}
.cc-vs { font-size: .78rem; color: var(--ink-3); }
.cc-why { margin: 0; font-size: .875rem; line-height: 1.55; color: var(--ink-2); }
.cc-stats {
  display: grid; gap: .25rem; padding-top: .7rem; border-top: 1px solid var(--line);
  font-size: .8rem; color: var(--ink-3);
}
.cc-stats b { color: var(--ink); font-weight: 700; font-variant-numeric: lining-nums tabular-nums; }
.cc-cost b { color: var(--ink); }

/* ============================================================================
   COMPARE PAGE
   Was a single 16-row table with no brand identity. Now: the two brands as
   objects first, then three-year cost, then a grouped spec table.
   ========================================================================== */

.vs-word { color: var(--ink-3); font-weight: 500; }

/* ------------------------------------------------------------ head-to-head */
.vs-hero {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 1.5rem; align-items: stretch;
}
@media (max-width: 820px) {
  .vs-hero { grid-template-columns: 1fr; gap: .75rem }
}

.vs-card {
  position: relative; display: grid; justify-items: center; gap: .35rem;
  padding: 2rem 1.6rem 1.6rem; text-align: center;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
}
.vs-card.is-winner {
  background: linear-gradient(var(--surface), var(--surface)) padding-box,
              var(--grad) border-box;
  border: 1.5px solid transparent; box-shadow: var(--sh-2);
}
.vs-flag {
  position: absolute; top: -.7rem; left: 50%; transform: translateX(-50%);
  padding: .2rem .7rem; border-radius: 999px; white-space: nowrap;
  color: #fff; background: var(--grad);
  font: 800 .62rem/1.5 var(--sans); text-transform: uppercase; letter-spacing: .1em;
  box-shadow: var(--sh-glow);
}
.vs-card .host-logo { margin-bottom: .5rem; }
.vs-name { font-family: var(--sans); font-weight: 700; font-size: 1.3rem; letter-spacing: -.03em; margin: 0; }
.vs-tag { font-size: .84rem; line-height: 1.5; color: var(--ink-3); margin: 0 0 .9rem; max-width: 26ch; }
.vs-card .ring { margin-bottom: .1rem; }
.vs-verdict {
  font: 700 .66rem/1 var(--sans); text-transform: uppercase; letter-spacing: .11em;
  color: var(--ink-3); margin-bottom: .9rem;
}
.vs-price { margin-bottom: 1rem; }
.vp-now {
  display: block; font-family: var(--display); font-weight: 700; font-size: 1.9rem;
  line-height: 1; letter-spacing: -.04em; font-variant-numeric: lining-nums tabular-nums;
}
.vp-renew { display: block; font-size: .78rem; color: var(--warn); margin-top: .25rem; }
.vs-card .btn { max-width: 15rem; }

.vs-divider { display: grid; place-items: center; }
.vs-divider span {
  display: grid; place-items: center; width: 2.6rem; height: 2.6rem; border-radius: 50%;
  background: var(--surface); border: 1px solid var(--line-2);
  font: 800 .72rem/1 var(--sans); letter-spacing: .04em; color: var(--ink-3);
}
@media (max-width: 820px) { .vs-divider span { width: 2.2rem; height: 2.2rem; font-size: .66rem } }

.c-unit { font-size: .62em; font-weight: 500; color: var(--ink-3); letter-spacing: 0; }

/* ------------------------------------------------------- three-year cost -- */
.vs-cost { display: grid; gap: 1.1rem; }
.vc-row {
  display: grid; grid-template-columns: minmax(9rem, 12rem) 1fr auto;
  grid-template-areas: "name track total" ". detail detail";
  gap: .35rem .9rem; align-items: center;
}
@media (max-width: 640px) {
  .vc-row { grid-template-columns: 1fr auto; grid-template-areas: "name total" "track track" "detail detail" }
}
.vc-name {
  grid-area: name; display: inline-flex; align-items: center; gap: .5rem;
  font: 650 .92rem/1.3 var(--sans); min-width: 0;
}
.vc-track { grid-area: track; display: block; height: 1.5rem; background: var(--surface-3); border-radius: .4rem; overflow: hidden; }
.vc-bar {
  display: block; height: 100%; width: var(--w); border-radius: .4rem;
  background: linear-gradient(90deg, #f59e0b, #ef4444);
  transform-origin: left; animation: growBar .8s var(--ease) both;
}
.vc-bar.is-best { background: linear-gradient(90deg, #22d3ee, #06b6d4); }
.vc-total {
  grid-area: total; font-family: var(--display); font-weight: 700; font-size: 1.35rem;
  letter-spacing: -.035em; font-variant-numeric: lining-nums tabular-nums; white-space: nowrap;
}
.vc-total.is-best { color: var(--good); }
.vc-detail { grid-area: detail; font-size: .78rem; color: var(--ink-3); }
.vc-detail b { color: var(--warn); }

/* ============================================================================
   LINE BY LINE  (grouped head-to-head table)
   Was three bare columns of text on hairlines: no container, no separation
   between the two brands' columns, the winner marked only by a small green tick,
   and no sense of magnitude — "9.5 vs 8.9" looked like "5.9 vs 8.0".
   ========================================================================== */
/* NB: no `overflow: hidden` on the panel — it would kill the sticky header. */
.vs-table {
  margin-top: 1.5rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
}

/* --- three shared columns. One definition, so header and rows stay aligned. */
.vs-sticky-head,
.vs-row { display: grid; grid-template-columns: minmax(10rem, 1.15fr) 1fr 1fr; }

.vs-sticky-head {
  position: sticky; top: 4.4rem; z-index: 30;
  border-bottom: 1px solid var(--line-2);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.vs-sticky-head > * { padding: .9rem 1.1rem; }
.vsh-k {
  align-self: center;
  font: 700 .655rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-3);
}
.vsh-brand {
  display: flex; align-items: center; gap: .55rem; flex-wrap: wrap;
  font: 700 .92rem/1.2 var(--sans); letter-spacing: -.02em;
  border-left: 1px solid var(--line);
}
.vsh-wins {
  font: 700 .645rem/1 var(--sans); text-transform: uppercase; letter-spacing: .06em;
  color: var(--good); background: var(--good-soft);
  padding: .26rem .42rem; border-radius: .3rem;
}

/* ------------------------------------------------------------ group bands */
.vs-group-head {
  display: flex; align-items: baseline; gap: .7rem; flex-wrap: wrap;
  padding: .8rem 1.1rem;
  background: var(--surface-2); border-top: 1px solid var(--line);
}
.vg-n {
  font: 800 .66rem/1 var(--sans); color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.vg-title {
  font: 700 .68rem/1 var(--sans); text-transform: uppercase; letter-spacing: .13em; color: var(--a1);
}
.vg-note { font-size: .76rem; color: var(--ink-3); }

/* ------------------------------------------------------------------ rows */
.vs-row { border-top: 1px solid var(--line); transition: background .12s var(--ease); }
.vs-row > * { padding: .8rem 1.1rem; }
.vs-row:hover { background: var(--surface-2); }

.vr-label { font-size: .88rem; font-weight: 550; color: var(--ink-2); }
.vr-label em { display: block; font-style: normal; font-size: .74rem; color: var(--ink-3); margin-top: .1rem; }

/* A rule between the two brands' columns, so a value is never ambiguous. */
.vr-val {
  border-left: 1px solid var(--line);
  font-size: .92rem; color: var(--ink);
  font-variant-numeric: lining-nums tabular-nums;
}
.vr-v { display: block; }
.vr-val strong { font-family: var(--display); font-weight: 700; font-size: 1.15rem; letter-spacing: -.03em; }

/* The winning cell is filled, not just recoloured — in a two-way comparison
   "who won this row" is the whole point of the row. */
.vr-val.is-win { background: var(--good-soft); color: var(--good); font-weight: 650; }
.vr-val.is-win strong { color: var(--good); }
.vr-val.is-win .vr-v::after { content: " \2713"; font-size: .82em; }

/* Magnitude, for the bounded rows. Grey for the loser, green for the winner, so
   the bar carries both the size of the gap and the outcome. */
.vr-meter {
  display: block; height: 3px; max-width: 5.5rem; margin-top: .45rem;
  background: var(--surface-3); border-radius: 999px; overflow: hidden;
}
.vr-meter i { display: block; height: 100%; width: var(--w); background: var(--line-2); border-radius: 999px; }
.vr-val.is-win .vr-meter i { background: var(--good); }

@media (max-width: 700px) {
  /* Label on its own row: three columns in ~340px leaves nothing for the values. */
  .vs-row { grid-template-columns: 1fr 1fr; }
  .vs-row > * { padding: .7rem .85rem; }
  .vr-label {
    grid-column: 1 / -1; padding-bottom: .25rem;
    font-weight: 700; color: var(--ink);
  }
  .vr-val:nth-of-type(1) { border-left: 0; }
  .vs-sticky-head { grid-template-columns: 1fr 1fr; }
  .vs-sticky-head > * { padding: .7rem .85rem; }
  .vsh-k { display: none; }
  .vsh-brand:nth-of-type(1) { border-left: 0; }
  .vsh-brand { font-size: .84rem; }
}

/* ------------------------------------------------------------ plans blocks */
/* Plans compared — see the PLANS COMPARED block at the end of this file. */

/* ============================================================================
   REFINEMENT PASS
   The page had become card-inside-card-inside-card. Premium layouts carry
   structure with hairlines, whitespace and type hierarchy — boxes are the
   fallback, not the default. These rules override the earlier card chrome.
   ========================================================================== */

/* ------------------------------------------------------------- icon system */
.ico { display: block; flex: 0 0 auto; }

/* -------------------------------------------------------- specs: hairlines */
/* Was: a bordered grid of 8 boxed cells. Now: quiet rows with a rule between,
   which lets the values themselves carry the emphasis. */
.spec-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 0; background: none; border: 0; border-top: 1px solid var(--line);
  border-radius: 0; overflow: visible;
}
.spec-item {
  display: grid; grid-template-columns: 1.35rem 1fr; grid-template-rows: auto auto;
  gap: .15rem .8rem; align-items: baseline;
  padding: 1.15rem .5rem 1.15rem 0;
  background: none; border-bottom: 1px solid var(--line);
}
.spec-item:hover { background: none; }
.spec-icon { grid-row: 1 / 3; color: var(--ink-3); align-self: center; }
.spec-label {
  font: 600 .7rem/1 var(--sans); text-transform: uppercase; letter-spacing: .1em;
  color: var(--ink-3);
}
.spec-value { font: 500 .96rem/1.45 var(--sans); color: var(--ink); letter-spacing: -.008em; }

/* ------------------------------------------------- pros / cons: no boxes */
.pros-cons { gap: 2.5rem 3.5rem; margin: 2.5rem 0; }
.pros-cons > .card {
  background: none; border: 0; border-top: 2px solid var(--line);
  border-radius: 0; box-shadow: none; padding: 1.35rem 0 0;
}
.pros-cons > .pros { border-top-color: var(--good); }
.pros-cons > .cons { border-top-color: var(--bad); }
.pros-cons h3 { font-size: .72rem; letter-spacing: .13em; margin-bottom: 1rem; }
.pros-cons li { font-size: .95rem; line-height: 1.6; gap: .7rem; }
.pros-cons ul { gap: .8rem; }

/* ---------------------------------------------- method strip: no icon boxes */
.ms-icon {
  width: auto; height: auto; border: 0; background: none; box-shadow: none;
  color: var(--a1); padding-top: .1rem;
}
.ms-item { gap: .75rem; }
.ms-title { font-weight: 600; letter-spacing: -.012em; }

/* -------------------------------------------- feature cards: quieter chrome */

/* ------------------------------------------------------- chooser + mega icons */
.chip-link .ico { color: #b6c0d6; }
.chip-link:hover .ico { color: #fff; }
.mega-icon {
  width: auto; height: auto; background: none; border: 0; box-shadow: none;
  color: var(--ink-3); padding-top: .15rem;
}
.mega-item:hover .mega-icon { background: none; border: 0; color: var(--a1); }

/* ------------------------------------------------------- glance: hairlines */
/* A 1px-gap grid of white cells reads as a table screenshot. Rules only. */
.glance {
  gap: 0; background: none; border: 0; border-top: 1px solid var(--line);
  border-radius: 0; overflow: visible; margin-top: 2rem;
}
.glance-item {
  padding: 1.1rem 1.25rem 1.1rem 0; background: none;
  border-bottom: 1px solid var(--line); gap: .3rem;
}
.g-label { font-size: .68rem; letter-spacing: .11em; }
.g-value { font-size: 1.32rem; letter-spacing: -.035em; }

/* ------------------------------------------------------ section rhythm */
.sec { margin-top: 5rem; }
.band { padding: 4.25rem 0; margin-top: 5rem; }
.sec-head { margin-bottom: 1.75rem; gap: 1.25rem; }
.sec-sub { margin: -1rem 0 2rem; }

/* ------------------------------------------------------ verdict: quieter */
.verdict-box {
  background: none; border: 0; border-left: 2px solid var(--a1);
  border-radius: 0; padding: .25rem 0 .25rem 1.5rem;
}
.verdict-box::before { display: none; }
.verdict-box h2 { font-size: .68rem; letter-spacing: .14em; margin-bottom: .6rem; }
.verdict-box p { font-size: 1.08rem; line-height: 1.65; color: var(--ink); }

/* --------------------------------------------------------- byline: quieter */
.byline {
  border: 0; border-radius: 0; box-shadow: none; background: none;
  padding: 0; margin-top: 1.6rem; gap: .8rem;
}
.avatar { width: 2.1rem; height: 2.1rem; box-shadow: none; }

/* ---------------------------------------------------- provenance: quieter */
.provenance {
  background: none; border: 0; border-top: 1px solid var(--line);
  border-radius: 0; padding: 1.2rem 0 0;
}
.review-aside .provenance { border-top-color: var(--line-2); }
.aside-cta { background: none; border: 0; box-shadow: none; padding: 1.2rem 0 0;
             border-top: 1px solid var(--line); }

/* ------------------------------------------------------------ plan cards */
/* Keep the boxes here — these are purchase choices and boxes help comparison —
   but lighten them so they do not shout over the cost module. */
.plan-card { box-shadow: none; }
.plan-card:hover { box-shadow: var(--sh-2); }
.plan-note { background: none; padding: 0; color: var(--ink-2); font-weight: 500; }
.plan-note::before { content: "— "; color: var(--a1); }

/* --------------------------------------------------- cost module: emphasis */
.cost-year, .cost-total { box-shadow: none; }
.cy-amount, .ct-amount { letter-spacing: -.04em; }
.ct-amount { font-size: 2.55rem; }
.cost-context { background: none; border: 0; border-left: 2px solid var(--accent-line);
                border-radius: 0; padding: .2rem 0 .2rem 1.25rem; }

/* ------------------------------------------------------------- empty state */

/* ------------------------------------------------------------- alt cards */
.alt-card { box-shadow: none; }
.alt-card:hover { box-shadow: var(--sh-2); }

/* ============================================================================
   FLAT-PRICE FRAMING
   A provider whose price never rises used to render as two identical grey
   numbers and a small grey caption. These rules give that case its own visual
   weight, so the best fact about the host is the most prominent one.
   ========================================================================== */

/* glance strip: sub-labels and a positive state */
.g-ok { color: var(--good); }
.g-sub { display: block; margin-top: .25rem; font: 500 .72rem/1.3 var(--sans);
         letter-spacing: 0; color: var(--ink-3); }
.g-sub-warn { color: var(--warn); }

/* cost module, flat variant */
.cost-flat { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
             gap: 0; align-items: start; }
@media (max-width: 900px) { .cost-flat { grid-template-columns: 1fr; } }

.cf-lead { padding: 1.75rem 2rem 1.75rem 0; }
.cf-compare { padding: 1.75rem 0 1.75rem 2rem; border-left: 1px solid var(--line); }
@media (max-width: 900px) {
  .cf-lead { padding: 0 0 1.5rem; }
  .cf-compare { padding: 1.5rem 0 0; border-left: 0; border-top: 1px solid var(--line); }
}

.cf-price {
  display: block; margin: .5rem 0 .75rem;
  font-family: var(--display); font-weight: 800;
  font-size: clamp(3rem, 2.2rem + 3vw, 4.5rem); line-height: 1;
  letter-spacing: -.05em; font-variant-numeric: lining-nums tabular-nums;
}
.cf-per { font-family: var(--sans); font-size: .3em; font-weight: 600; color: var(--ink-3);
          letter-spacing: -.01em; }
.cf-badge {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .3rem .7rem; border-radius: 999px;
  background: var(--good-soft); color: var(--good);
  font: 700 .74rem/1.4 var(--sans); letter-spacing: .01em;
}
.cf-copy { margin: 1.1rem 0 0; font-size: .95rem; line-height: 1.65; color: var(--ink-2);
           max-width: 40ch; }

.cf-bar-row { display: grid; grid-template-columns: minmax(7rem, 10rem) 1fr auto;
              gap: .9rem; align-items: center; margin-top: .9rem; }
@media (max-width: 560px) { .cf-bar-row { grid-template-columns: 1fr auto; }
  .cf-track { grid-column: 1 / -1; } }
.cf-bar-k { font: 600 .84rem/1.35 var(--sans); color: var(--ink-2); }
.cf-bar-k em { display: block; font-style: normal; font-size: .72rem; color: var(--ink-3);
               font-weight: 500; margin-top: .1rem; }
.cf-track { height: 1.5rem; background: var(--surface-3); border-radius: .3rem; overflow: hidden; }
.cf-fill { display: block; height: 100%; width: var(--w); border-radius: .3rem;
           transform-origin: left; }
.js-anim .cf-fill { animation: growBar .8s var(--ease) both; }
.cf-flat { background: linear-gradient(90deg, #22d3ee, #06b6d4); }
.cf-hot  { background: linear-gradient(90deg, #f59e0b, #ef4444); }
.cf-bar-v { font: 800 1.05rem/1 var(--sans); font-variant-numeric: lining-nums tabular-nums;
            white-space: nowrap; }
.cf-bar-v.is-hot { color: var(--warn); }

.cf-verdict { margin: 1.35rem 0 1.25rem; padding-left: 1.1rem;
              border-left: 2px solid var(--accent-line);
              font-size: .92rem; line-height: 1.65; color: var(--ink-2); }
.cf-verdict strong { color: var(--ink); }

/* plans: a held price is a feature, not an absence */
.plan-renew.is-flat { color: var(--good); font-weight: 650; }

/* ============================================================================
   READER REVIEWS
   Was two plain boxes and a default form with a <select> for the rating.
   Now: a summary panel anchors the section, reviews are cards, and the rating
   input is an accessible star picker built from real radio inputs.
   ========================================================================== */

/* --------------------------------------------------------- summary panel */
.rating-summary {
  display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr) minmax(0, 1fr);
  gap: 0; margin: 0 0 2.5rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); overflow: hidden;
}
@media (max-width: 900px) { .rating-summary { grid-template-columns: 1fr 1fr; } }
@media (max-width: 620px) { .rating-summary { grid-template-columns: 1fr; } }

.rs-score, .rs-dist, .rs-trust { padding: 1.75rem; }
.rs-dist  { border-left: 1px solid var(--line); }
.rs-trust { border-left: 1px solid var(--line); background: var(--surface-2); }
@media (max-width: 900px) {
  .rs-trust { grid-column: 1 / -1; border-left: 0; border-top: 1px solid var(--line); }
}
@media (max-width: 620px) {
  .rs-dist { border-left: 0; border-top: 1px solid var(--line); }
}

.rs-score { display: grid; align-content: start; justify-items: start; gap: .15rem; }
.rs-big {
  font-family: var(--display); font-weight: 800;
  font-size: clamp(3rem, 2.4rem + 2vw, 4rem); line-height: 1;
  letter-spacing: -.05em; font-variant-numeric: lining-nums tabular-nums;
}
.rs-big.rs-empty { color: var(--ink-3); }
.rs-outof { font: 500 .78rem/1 var(--sans); color: var(--ink-3); }
.rs-stars { margin-top: .55rem; color: var(--gold); font-size: 1.05rem; letter-spacing: .1em; }
.rs-stars.is-empty { color: var(--line-2); }
.rs-count { margin-top: .5rem; font: 600 .8rem/1.4 var(--sans); color: var(--ink-2); }

/* distribution bars */
.rs-dist { display: grid; align-content: center; gap: .45rem; }
.rs-row { display: grid; grid-template-columns: 2.6rem 1fr 1.75rem; gap: .7rem; align-items: center; }
.rs-star-k { font: 600 .78rem/1 var(--sans); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.rs-star-k span { color: var(--gold); }
.rs-track { height: .5rem; background: var(--surface-3); border-radius: 999px; overflow: hidden; }
.rs-fill { display: block; height: 100%; width: var(--w); border-radius: 999px;
           background: var(--grad-bright); transform-origin: left; }
.js-anim .rs-fill { animation: growBar .7s var(--ease) both; }
.rs-n { font: 600 .78rem/1 var(--sans); color: var(--ink-3); text-align: right;
        font-variant-numeric: tabular-nums; }

/* moderation policy — the trust half of a review section */
.rs-trust { display: grid; align-content: start; gap: .6rem; }
.rs-trust-k, .rv-empty-k, .rv-form-k {
  font: 700 .68rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-3);
}
.rs-trust ul { margin: 0; padding: 0; list-style: none; display: grid; gap: .45rem; }
.rs-trust li { display: grid; grid-template-columns: .9rem 1fr; gap: .5rem;
               font-size: .82rem; line-height: 1.5; color: var(--ink-2); }
.rs-trust li::before { content: "\2713"; color: var(--good); font-size: .78rem; }
.rs-trust-link { font: 650 .78rem/1 var(--sans); text-decoration: none; margin-top: .25rem; }

/* --------------------------------------------------------------- layout */
.reviews-grid { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
                gap: 2.5rem; align-items: start; }
@media (max-width: 900px) { .reviews-grid { grid-template-columns: 1fr; gap: 2rem; } }

/* ---------------------------------------------------------- review cards */
.rv-list { display: grid; gap: 1rem; }
.rv-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 1.5rem 1.6rem;
  transition: border-color .2s var(--ease);
}
.rv-card:hover { border-color: var(--line-2); }
.rv-head { display: grid; grid-template-columns: 2.5rem 1fr auto; gap: .85rem;
           align-items: start; margin-bottom: 1rem; }
.rv-avatar {
  display: grid; place-items: center; width: 2.5rem; height: 2.5rem; border-radius: 50%;
  background: var(--grad); color: #fff; font: 800 .74rem/1 var(--sans); letter-spacing: -.01em;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.25);
}
.rv-who { display: grid; gap: .2rem; min-width: 0; }
.rv-author { font: 700 .95rem/1.3 var(--sans); letter-spacing: -.012em; display: flex;
             align-items: center; gap: .5rem; flex-wrap: wrap; }
.rv-verified {
  font: 700 .64rem/1 var(--sans); letter-spacing: .05em; text-transform: uppercase;
  color: var(--good); background: var(--good-soft); padding: .22rem .42rem; border-radius: .3rem;
}
.rv-meta { font-size: .78rem; color: var(--ink-3); }
.rv-rating { display: grid; justify-items: end; gap: .15rem; }
.rv-rating-stars { color: var(--gold); font-size: .82rem; letter-spacing: .08em; }
.rv-rating-n { font: 800 .82rem/1 var(--sans); color: var(--ink-2);
               font-variant-numeric: tabular-nums; }
.rv-title { font-size: 1.02rem; margin: 0 0 .4rem; letter-spacing: -.018em; }
.rv-body { margin: 0; font-size: .93rem; line-height: 1.7; color: var(--ink-2); }

/* ------------------------------------------------------------ empty state */
.rv-empty {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 1.75rem 1.85rem;
}
.rv-empty h3 { margin: .6rem 0 .5rem; font-size: 1.15rem; }
.rv-empty > p { margin: 0 0 1.4rem; font-size: .92rem; line-height: 1.65; color: var(--ink-2);
                max-width: 46ch; }
.rv-guide { margin: 0; display: grid; gap: 0; border-top: 1px solid var(--line); }
.rv-guide > div { display: grid; gap: .15rem; padding: .85rem 0; border-bottom: 1px solid var(--line); }
.rv-guide dt { font: 650 .88rem/1.4 var(--sans); color: var(--ink); }
.rv-guide dd { margin: 0; font-size: .8rem; line-height: 1.5; color: var(--ink-3); }

/* ------------------------------------------------------------- the form */
.rv-form-wrap { position: sticky; top: 6.5rem; }
@media (max-width: 900px) { .rv-form-wrap { position: static; } }
.rv-form {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 1.75rem;
}
.rv-form-note { margin: .5rem 0 1.5rem; font-size: .85rem; line-height: 1.6; color: var(--ink-2); }
.rv-form label { font-size: .8rem; }
.rv-legal { margin: 1rem 0 0; font-size: .74rem; line-height: 1.6; color: var(--ink-3); }

/* star picker — real radios, CSS only, keyboard operable */
.rv-stars { border: 0; padding: 0; margin: 0 0 1.5rem; }
.rv-stars legend {
  padding: 0; margin-bottom: .5rem;
  font: 700 .68rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-3);
}
/* DOM order is 5→1; reversing the row puts 1 on the left, which lets
   `input:checked ~ label` fill every star below the chosen one. */
.rv-stars-row { display: flex; flex-direction: row-reverse; justify-content: flex-end; gap: .2rem; }
.rv-stars-row input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.rv-stars-row label { margin: 0; cursor: pointer; line-height: 1; padding: .1rem; }
.rv-star { font-size: 1.85rem; color: var(--line-2); transition: color .12s var(--ease); }
.rv-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0);
         white-space: nowrap; }
/* hover fills the hovered star and everything visually left of it */
.rv-stars-row label:hover .rv-star,
.rv-stars-row label:hover ~ label .rv-star { color: var(--gold); }
/* checked state persists that fill */
.rv-stars-row input:checked ~ label .rv-star { color: var(--gold); }
/* keyboard focus must be visible even though the input is off-screen */
.rv-stars-row input:focus-visible + label .rv-star { outline: 2px solid var(--a1);
  outline-offset: 2px; border-radius: 3px; }
.rv-stars-hint { display: block; margin-top: .4rem; font-size: .74rem; color: var(--ink-3); }

/* live character counter (progressive enhancement) */
.rv-counter { display: block; margin-top: .4rem; font: 500 .72rem/1 var(--sans); color: var(--ink-3);
              font-variant-numeric: tabular-nums; }
.rv-counter.is-short { color: var(--warn); }
.rv-counter.is-ok { color: var(--good); }

/* ============================================================================
   FULL SPECIFICATION TABLE
   Replaces the plain bordered `table.data` on ranking pages. The old version
   put the score in tiny monospace, printed intro and renewal as two unrelated
   numbers, and gave three wide wrapping text columns most of the width.

   Structure here: a sticky provider column so sideways scrolling never loses
   the row identity, the renewal multiplier attached to the renewal figure,
   the winning value marked in every comparable column, and sortable headings.
   ========================================================================== */

.num { font-variant-numeric: lining-nums tabular-nums; }

.spec-wrap { margin-top: 1.75rem; }

.spec-scroll {
  overflow-x: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-1);
  /* Momentum scrolling on touch, and a keyboard-reachable scroll region. */
  -webkit-overflow-scrolling: touch;
}
.spec-scroll:focus-visible { outline: 2px solid var(--a1); outline-offset: 3px; }

.spec {
  width: 100%;
  border-collapse: separate;      /* separate, so sticky cells keep their borders */
  border-spacing: 0;
  font-family: var(--sans);
}

/* ------------------------------------------------------------- headings */
.spec thead th {
  padding: 0;
  text-align: left;
  vertical-align: bottom;
  white-space: nowrap;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line-2);
}
.spec thead button {
  all: unset;
  box-sizing: border-box;
  display: flex; align-items: center; gap: .35rem;
  width: 100%;
  padding: .95rem .95rem;
  cursor: pointer;
  font: 700 .67rem/1 var(--sans);
  text-transform: uppercase; letter-spacing: .11em;
  color: var(--ink-3);
  transition: color .15s var(--ease);
}
.spec thead button:hover { color: var(--ink); }
.spec thead button:focus-visible { outline: 2px solid var(--a1); outline-offset: -2px; }
.spec th.sp-nosort {
  padding: .95rem .95rem;
  font: 700 .67rem/1 var(--sans);
  text-transform: uppercase; letter-spacing: .11em;
  color: var(--ink-3);
}

/* Sort direction caret. Dim on hover, solid on the active column. */
.sp-arrow {
  width: 0; height: 0; flex: none;
  border-left: .22rem solid transparent;
  border-right: .22rem solid transparent;
  border-top: .3rem solid currentColor;
  opacity: 0;
  transition: opacity .15s var(--ease), transform .18s var(--ease);
}
.spec thead button:hover .sp-arrow { opacity: .3; }
.spec thead th[aria-sort] button { color: var(--ink); }
.spec thead th[aria-sort] .sp-arrow { opacity: 1; color: var(--a1); }
.spec thead th[aria-sort="ascending"] .sp-arrow { transform: rotate(180deg); }

/* ----------------------------------------------------------------- body */
.spec tbody th,
.spec tbody td {
  padding: .85rem .95rem;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: middle;
  font-weight: 500;
  color: var(--ink);
}
.spec tbody tr:last-child th,
.spec tbody tr:last-child td { border-bottom: 0; }

.spec tbody tr:hover td,
.spec tbody tr:hover th.sp-sticky { background: var(--surface-2); }

/* -------------------------------------------------- sticky first column */
/* z-index order: header corner (4) > body sticky (3) > header row (2). */
.spec .sp-sticky {
  position: sticky; left: 0; z-index: 3;
  background: var(--surface);
  min-width: 14rem;
  box-shadow: 1px 0 0 var(--line);
}
.spec thead .sp-sticky { z-index: 4; background: var(--surface-2); box-shadow: 1px 0 0 var(--line-2); }

.sp-host {
  display: flex; align-items: center; gap: .75rem;
  text-decoration: none; color: inherit;
}
.sp-host-t { display: grid; gap: .12rem; min-width: 0; }
.sp-name {
  font: 700 .93rem/1.25 var(--sans); letter-spacing: -.015em;
  transition: color .15s var(--ease);
}
.sp-host:hover .sp-name { color: var(--a1); }
.sp-for {
  font-size: .705rem; line-height: 1.3; color: var(--ink-3);
  max-width: 10.5rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ------------------------------------------------------- score + meter */
.sp-score { display: grid; gap: .32rem; width: 2.9rem; }
.sp-score b { font: 800 .95rem/1 var(--sans); letter-spacing: -.02em; }
.sp-meter {
  display: block; height: 3px; border-radius: 999px;
  background: var(--surface-3); overflow: hidden;
}
.sp-meter i {
  display: block; height: 100%; width: var(--w);
  border-radius: 999px; background: var(--grad-bright);
}
.sp-score.is-best b { color: var(--a1); }

/* ------------------------------------------------------------- figures */
.sp-money,
.sp-renew { font: 700 .9rem/1 var(--sans); white-space: nowrap; letter-spacing: -.01em; }
.sp-sub   { font: 700 .9rem/1 var(--sans); letter-spacing: -.01em; }
.sp-unit  { font-size: .74em; font-weight: 600; color: var(--ink-3); margin-left: .04rem; }
.sp-none  { font-size: .78rem; color: var(--ink-3); }
.sp-text  {
  /* "WP Engine User Portal" would otherwise set this column's width on its own. */
  display: block; max-width: 8.5rem;
  font-size: .82rem; color: var(--ink-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Renewal keeps the figure in ink; the badge carries the meaning, so the
   column stays scannable as numbers with a signal attached. */
.sp-renew { display: inline-flex; align-items: baseline; gap: .38rem; }
.sp-renew em {
  font: 700 .655rem/1 var(--sans); font-style: normal; letter-spacing: .02em;
  padding: .24rem .36rem; border-radius: .3rem;
}
.sp-renew.is-up em   { color: var(--warn); background: var(--warn-soft); }
.sp-renew.is-flat em { color: var(--good); background: var(--good-soft); }

/* Best in column: one accent treatment, used identically everywhere. */
.sp-money.is-best,
.sp-sub.is-best {
  display: inline-block;
  color: var(--a1); background: var(--accent-soft);
  padding: .24rem .46rem; margin: -.24rem -.46rem;
  border-radius: .35rem;
}
.sp-renew.is-best {
  padding: .24rem .46rem; margin: -.24rem -.46rem;
  border-radius: .35rem;
  background: var(--accent-soft); color: var(--a1);
}

/* ------------------------------------------------- included / excluded */
.sp-inc { white-space: nowrap; }
.sp-tick {
  display: inline-flex; align-items: center; gap: .28rem;
  font: 650 .675rem/1 var(--sans); letter-spacing: .01em;
  padding: .28rem .42rem .28rem .34rem;
  border: 1px solid var(--line); border-radius: .35rem;
  margin-right: .26rem;
}
.sp-tick:last-child { margin-right: 0; }
.sp-tick i { font-style: normal; font-size: .72rem; line-height: 1; }
.sp-tick.yes {
  color: var(--good); background: var(--good-soft);
  border-color: color-mix(in srgb, var(--good) 26%, transparent);
}
.sp-tick.no { color: var(--ink-3); }

/* -------------------------------------------------------------- legend */
.spec-legend {
  display: flex; flex-wrap: wrap; align-items: center; gap: .4rem 1.3rem;
  margin-top: 1rem;
  font-size: .745rem; color: var(--ink-3);
}
.spec-legend > span { display: inline-flex; align-items: center; gap: .42rem; }
.spec-legend i { display: block; width: .6rem; height: .6rem; border-radius: 2px; flex: none; }
.lg-best { background: var(--a1); }
.lg-up   { background: var(--warn); }
.lg-flat { background: var(--good); }
.spec-hint { margin-left: auto; }

/* ------------------------------------------------- method note (footnote) */
.rank-note {
  margin-top: 2.75rem; padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  max-width: 72ch;
}
.rank-note-k {
  display: block; margin-bottom: .55rem;
  font: 700 .68rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-3);
}
.rank-note p {
  margin: 0;
  font-size: .875rem; line-height: 1.7; color: var(--ink-2);
}

@media (max-width: 860px) {
  .spec-hint { margin-left: 0; flex-basis: 100%; }
}
@media (max-width: 700px) {
  .spec .sp-sticky { min-width: 11rem; }
  .sp-for { display: none; }              /* the name has to win the space */
  .spec-legend { gap: .35rem .85rem; font-size: .715rem; }
  .spec thead button,
  .spec th.sp-nosort,
  .spec tbody th,
  .spec tbody td { padding-left: .8rem; padding-right: .8rem; }
}

/* ============================================================================
   DOCUMENT PAGES  (/method)
   Was one long prose column at full 1180px width with eight unindexed sections
   and the rubric weights set as monospace text in a table cell.
   ========================================================================== */

/* 13.5rem index + 4rem gap + 42rem body — so the facts strip below the lead
   ends exactly where the content column does. */
.doc-head { padding-top: 3rem; max-width: 59.5rem; }
.doc-head .lead { margin-bottom: 2rem; }

/* Hard facts, stated as figures. A trust page should open with something
   checkable rather than another paragraph. */
.doc-facts {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0; margin: 0; padding: 0; list-style: none;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.doc-facts li { padding: 1.15rem 1.25rem 1.15rem 0; display: grid; gap: .18rem; }
.doc-facts li + li { padding-left: 1.25rem; border-left: 1px solid var(--line); }
.doc-facts b {
  font-family: var(--display); font-weight: 800;
  font-size: 1.5rem; line-height: 1; letter-spacing: -.035em;
  font-variant-numeric: lining-nums tabular-nums;
}
.doc-facts span { font-size: .755rem; line-height: 1.35; color: var(--ink-3); }
@media (max-width: 720px) {
  .doc-facts { grid-template-columns: 1fr 1fr; }
  .doc-facts li:nth-child(3) { padding-left: 0; border-left: 0; }
  .doc-facts li:nth-child(n+3) { border-top: 1px solid var(--line); }
}

/* ------------------------------------------------------- index + column */
.doc {
  display: grid; grid-template-columns: 13.5rem minmax(0, 1fr);
  gap: 4rem; align-items: start;
  margin-top: 3.5rem; padding-bottom: 2rem;
}
@media (max-width: 1000px) {
  /* minmax(0, 1fr), not 1fr: a bare `1fr` is `minmax(auto, 1fr)`, so a wide
     min-content child — the data tables on /privacy and /cookies — expands the
     track past the viewport instead of scrolling inside its own container. */
  .doc { grid-template-columns: minmax(0, 1fr); gap: 2.5rem; }
}

.doc-toc { position: sticky; top: 6rem; }
@media (max-width: 1000px) {
  .doc-toc {
    position: static;
    border: 1px solid var(--line); border-radius: var(--r-lg);
    padding: 1.25rem 1.4rem; background: var(--surface-2);
  }
}
.doc-toc-k {
  display: block; margin-bottom: .8rem;
  font: 700 .66rem/1 var(--sans); text-transform: uppercase; letter-spacing: .13em;
  color: var(--ink-3);
}
.doc-toc ol {
  list-style: none; margin: 0; padding: 0;
  counter-reset: toc;
  display: grid; gap: .1rem;
}
.doc-toc li { counter-increment: toc; }
.doc-toc a {
  display: grid; grid-template-columns: 1.6rem 1fr; align-items: baseline;
  padding: .4rem 0;
  font: 500 .83rem/1.4 var(--sans); color: var(--ink-2); text-decoration: none;
  transition: color .15s var(--ease);
}
.doc-toc a::before {
  content: "0" counter(toc);
  font: 700 .68rem/1.6 var(--sans); color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.doc-toc a:hover { color: var(--ink); }
.doc-toc a.is-current { color: var(--a1); font-weight: 650; }
.doc-toc a.is-current::before { color: var(--a1); }

/* ------------------------------------------------------------- sections */
.doc-body { max-width: 44rem; }        /* ~71 characters, a readable measure */

/* When the panel leads the document rather than sitting inside section 01, it
   needs its own gap — `.doc-sec + .doc-sec` cannot supply it. */
.doc-body > .admit { margin-bottom: 2.75rem; }

/* Data tables inside a prose measure: the four-column privacy table wrapped
   almost every cell at the body font size. */
.doc-sec .data { font-size: .84rem; }
.doc-sec .data th, .doc-sec .data td { padding: .7rem .75rem; }

.doc-sec + .doc-sec { margin-top: 2.75rem; padding-top: 2.75rem; border-top: 1px solid var(--line); }

/* A list that ends a section would otherwise put its own bottom rule a few
   centimetres above the section separator — two parallel lines reading as a
   mistake. The separator is the structural one, so the list gives way. */
.doc-sec > :last-child .src-list > div:last-child,
.src-list > div:last-child,
.rub-list li:last-child,
.deny li:last-child { border-bottom: 0; }
.doc-num {
  display: block; margin-bottom: .5rem;
  font: 700 .68rem/1 var(--sans); letter-spacing: .13em; color: var(--a1);
  font-variant-numeric: tabular-nums;
}
.doc-sec h2 { font-size: clamp(1.5rem, 1.35rem + .7vw, 1.85rem); margin: 0 0 1rem; }
.doc-sec h3 { font-size: 1rem; margin: 0 0 .35rem; letter-spacing: -.015em; }
.doc-sec p { font-size: .95rem; line-height: 1.75; color: var(--ink-2); margin: 0 0 1rem; }
.doc-sec p:last-child { margin-bottom: 0; }
.doc-sec code {
  font-family: var(--mono); font-size: .84em;
  background: var(--surface-3); padding: .1rem .3rem; border-radius: .25rem;
}

/* A pull-quote for the one line that matters most in a section. */
.doc-pull {
  margin: 1.75rem 0 0 !important;
  padding-left: 1.15rem; border-left: 2px solid var(--a1);
  font-size: 1.02rem !important; line-height: 1.6 !important;
  color: var(--ink) !important; letter-spacing: -.012em;
}

/* ------------------------------------------------- the admission (01) */
/* The strongest thing on a trust page is the thing it declines to claim, so it
   is set as a statement rather than a generic warning box. */
.admit {
  border: 1px solid var(--line); border-left: 3px solid var(--warn);
  border-radius: var(--r-sm); background: var(--warn-soft);
  padding: 1.4rem 1.5rem;
}
.admit-lead {
  font-family: var(--display); font-weight: 700;
  font-size: 1.12rem !important; line-height: 1.45 !important;
  letter-spacing: -.02em; color: var(--ink) !important;
  margin-bottom: .7rem !important;
}
.admit p:last-child { margin-bottom: 0; font-size: .9rem !important; }

/* ------------------------------------------------------- sources (02) */
.src-list { margin: 0; display: grid; gap: 0; }
.src-list > div {
  display: grid; grid-template-columns: 11rem minmax(0, 1fr); gap: 1.5rem;
  padding: 1.1rem 0; border-bottom: 1px solid var(--line);
}
.src-list > div:first-child { border-top: 1px solid var(--line); }
.src-list dt { font: 700 .855rem/1.45 var(--sans); letter-spacing: -.01em; }
.src-list dd { margin: 0; font-size: .89rem; line-height: 1.7; color: var(--ink-2); }
@media (max-width: 620px) {
  .src-list > div { grid-template-columns: 1fr; gap: .3rem; }
}

/* -------------------------------------------------------- rubric (03) */
.rub { margin: 1.5rem 0 0; }

/* The five weights sum to 100%, so one divided bar is the honest shape. */
.rub-bar {
  display: flex; height: 2.6rem; margin-bottom: 1.5rem;
  border-radius: var(--r-sm); overflow: hidden;
  box-shadow: var(--sh-1);
}
.rub-bar > span {
  display: grid; place-items: center;
  width: var(--w); flex: none;
  /* One accent, five tints — the weight controls the depth, nothing else. */
  background: color-mix(in srgb, var(--a1) var(--t), var(--surface));
  font: 700 .72rem/1 var(--sans);
  color: #fff;
  font-variant-numeric: tabular-nums;
}
/* The two lightest segments need dark text to stay legible. */
.rub-bar > span:nth-child(4),
.rub-bar > span:nth-child(5) { color: var(--a1); }

.rub-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.rub-list li {
  display: grid;
  grid-template-columns: .7rem 7.5rem 2.6rem auto;
  grid-template-areas: "sw name pct ev" ".  desc desc desc";
  gap: .3rem .7rem; align-items: center;
  padding: .95rem 0; border-bottom: 1px solid var(--line);
}
.rub-list li:first-child { border-top: 1px solid var(--line); }
.rub-swatch {
  grid-area: sw; width: .7rem; height: .7rem; border-radius: 2px;
  background: color-mix(in srgb, var(--a1) var(--t), var(--surface));
}
.rub-name { grid-area: name; font: 700 .875rem/1 var(--sans); letter-spacing: -.01em; }
.rub-pct  { grid-area: pct; font: 800 .875rem/1 var(--sans); color: var(--a1); }
.rub-ev   {
  grid-area: ev; justify-self: start;
  font: 700 .645rem/1 var(--sans); text-transform: uppercase; letter-spacing: .06em;
  padding: .26rem .44rem; border-radius: .3rem;
}
.ev-strong { color: var(--good); background: var(--good-soft); }
.ev-mid    { color: var(--ink-2); background: var(--surface-3); }
.ev-weak   { color: var(--warn); background: var(--warn-soft); }
.rub-desc  { grid-area: desc; font-size: .845rem; line-height: 1.65; color: var(--ink-2); }
@media (max-width: 560px) {
  .rub-list li {
    grid-template-columns: .7rem 1fr auto;
    grid-template-areas: "sw name pct" ".  ev  ev" ".  desc desc";
  }
  .rub-bar > span { font-size: 0; }        /* labels stop fitting; the list has them */
}

/* -------------------------------------- what commission cannot do (05) */
.deny { list-style: none; margin: 1.25rem 0 0; padding: 0; display: grid; gap: 0; }
/* Marker is absolute, not a grid column: each item holds a bold lead plus a
   sentence, and a two-column grid pushed that second child into the 1.1rem
   marker column — one word per line. */
.deny li {
  position: relative;
  padding: .85rem 0 .85rem 1.75rem; border-bottom: 1px solid var(--line);
  font-size: .9rem; line-height: 1.7; color: var(--ink-2);
}
.deny li:first-child { border-top: 1px solid var(--line); }
.deny li::before {
  content: "\2715";                       /* a denial, so a cross, not a tick */
  position: absolute; left: 0; top: .85rem;
  font-size: .74rem; line-height: 1.7; color: var(--warn); font-weight: 700;
}
.deny b { color: var(--ink); font-weight: 700; }

/* --------------------------------------------------- limitations (06) */
.limits { list-style: none; margin: 0; padding: 0; counter-reset: lim; display: grid; gap: .75rem; }
/* Same as .deny: h3 + p are two children, so an absolute counter rather than a
   grid column, otherwise the paragraph lands in the 2rem number track. */
.limits li {
  counter-increment: lim; position: relative;
  padding: 1.2rem 1.35rem 1.2rem 3.5rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
}
.limits li::before {
  content: counter(lim, decimal-leading-zero);
  position: absolute; left: 1.35rem; top: 1.2rem;
  font: 800 .8rem/1.5 var(--sans); color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.limits p { margin: 0 !important; font-size: .88rem !important; }

/* ---------------------------------------------------- corrections (08) */
.fix {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1.75rem;
  align-items: center;
  padding: 1.6rem 1.75rem;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-lg);
}
.fix h3 { margin-bottom: .4rem; }
.fix p { margin: 0 !important; font-size: .88rem !important; }
.fix .btn { white-space: nowrap; }
@media (max-width: 620px) {
  .fix { grid-template-columns: 1fr; gap: 1.1rem; }
  .fix .btn { justify-self: start; }
}

/* ============================================================================
   PLANS COMPARED
   Was two bare lists on hairlines. `highlight` and `bandwidth` are populated for
   every plan in the database and neither was rendered; "1 site(s)" was a
   placeholder plural; and a flat price printed "then $35" beside $35 — the same
   number twice, framed as though it changed.
   ========================================================================== */
.vp-lead { margin-bottom: 1.75rem; }

.vs-plans {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem;
  /* `start`, not `stretch`: forcing equal height on a 1-plan and a 2-plan panel
     left ~200px of empty box. Unequal heights, with the count in each header,
     say "this one has fewer plans" without the void. */
  align-items: start;
}
@media (max-width: 780px) { .vs-plans { grid-template-columns: 1fr; } }

.vp-panel {
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
}

.vp-head {
  display: flex; align-items: center; gap: .55rem;
  padding: .95rem 1.15rem; border-bottom: 1px solid var(--line);
  background: var(--surface-2);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
}
.vp-name { font: 700 .98rem/1.2 var(--sans); letter-spacing: -.022em; }
.vp-count {
  margin-left: auto;
  font: 700 .645rem/1 var(--sans); text-transform: uppercase; letter-spacing: .08em;
  color: var(--ink-3); background: var(--surface-3);
  padding: .28rem .46rem; border-radius: .3rem;
}
.vp-empty { margin: 0; padding: 1.5rem 1.15rem; font-size: .88rem; color: var(--ink-3); }

/* ------------------------------------------------------------- a plan row */
.vplan {
  display: grid; gap: .55rem; justify-items: start;
  padding: 1.15rem 1.15rem 1.25rem;
}
.vplan + .vplan { border-top: 1px solid var(--line); }

.vpl-top {
  display: flex; align-items: baseline; gap: 1rem; width: 100%;
}
.vpl-name {
  display: flex; align-items: center; gap: .5rem; flex-wrap: wrap;
  font: 700 1rem/1.3 var(--sans); letter-spacing: -.022em;
}
.vpl-badge {
  font: 700 .625rem/1 var(--sans); text-transform: uppercase; letter-spacing: .06em;
  color: var(--good); background: var(--good-soft);
  padding: .26rem .42rem; border-radius: .3rem; white-space: nowrap;
}
.vpl-price {
  margin-left: auto;
  font-family: var(--display); font-weight: 800; font-size: 1.55rem;
  letter-spacing: -.04em; line-height: 1; white-space: nowrap;
  font-variant-numeric: lining-nums tabular-nums;
}

/* The provider's own one-line pitch for the tier. Real data, previously unused. */
.vpl-hi { margin: 0; font-size: .855rem; line-height: 1.55; color: var(--ink-2); }

.vpl-renew {
  display: inline-flex; align-items: baseline; gap: .4rem;
  font: 500 .8rem/1 var(--sans); color: var(--ink-2);
}
.vpl-renew b { font-weight: 800; color: var(--ink); }
.vpl-renew.is-hot { color: var(--warn); }
.vpl-renew.is-hot b { color: var(--warn); }
.vpl-renew em {
  font: 700 .655rem/1 var(--sans); font-style: normal; letter-spacing: .02em;
  color: var(--warn); background: var(--warn-soft);
  padding: .24rem .36rem; border-radius: .3rem;
}
.vpl-hold {
  display: inline-flex; align-items: center; gap: .35rem;
  font: 700 .7rem/1 var(--sans); letter-spacing: .01em;
  color: var(--good); background: var(--good-soft);
  padding: .32rem .5rem; border-radius: .3rem;
}
.vpl-hold::before { content: "\2713"; font-size: .72rem; }

/* Limits as data, not prose. */
.vpl-chips { display: flex; flex-wrap: wrap; gap: .35rem; }
.vpl-chip {
  font: 600 .715rem/1 var(--sans); color: var(--ink-2);
  background: var(--surface-2); border: 1px solid var(--line);
  padding: .32rem .5rem; border-radius: .3rem; white-space: nowrap;
}

.vplan .btn { margin-top: .35rem; }

.vp-note {
  margin: 1.5rem 0 0; max-width: 70ch;
  font-size: .805rem; line-height: 1.7; color: var(--ink-3);
}

@media (max-width: 520px) {
  .vpl-top { flex-wrap: wrap; gap: .35rem; }
  .vpl-price { margin-left: 0; font-size: 1.4rem; }
}



/* ============================================================================
   ADMIN — PRICE HEALTH
   Prices are confirmed by hand, so the job is making "which ones went stale"
   impossible to miss rather than something to remember.
   ========================================================================== */
.ph-lead {
  max-width: 78ch; margin: 0 0 1.35rem;
  font-size: .89rem; line-height: 1.7; color: var(--ink-2);
}

.ph-summary { display: flex; flex-wrap: wrap; gap: .6rem; margin-bottom: 1.5rem; }
.ph-stat {
  display: grid; gap: .15rem; min-width: 7.5rem;
  padding: .8rem 1rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-sm);
}
.ph-stat b {
  font-family: var(--display); font-weight: 800; font-size: 1.35rem; line-height: 1;
  letter-spacing: -.035em; font-variant-numeric: lining-nums tabular-nums;
}
.ph-stat span { font-size: .74rem; color: var(--ink-3); }
.ph-stat.is-warn { border-color: color-mix(in srgb, var(--warn) 40%, transparent); background: var(--warn-soft); }
.ph-stat.is-warn b { color: var(--warn); }
.ph-stat.is-ok b { color: var(--good); }

/* A flagged row is tinted, so the list can be scanned without reading the ages. */
.ph-table tbody tr.is-stale { background: var(--warn-soft); }
.ph-table td { vertical-align: middle; }

.ph-flag, .ph-ok {
  font: 700 .7rem/1 var(--sans);
  padding: .26rem .42rem; border-radius: .3rem;
  font-variant-numeric: tabular-nums;
}
.ph-flag { color: var(--warn); background: color-mix(in srgb, var(--warn) 14%, transparent); }
.ph-ok   { color: var(--good); background: var(--good-soft); }
.ph-never { font-size: .78rem; color: var(--ink-3); font-style: italic; }
.ph-draft {
  font: 700 .62rem/1 var(--sans); text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-3); background: var(--surface-3);
  padding: .22rem .38rem; border-radius: .28rem; margin-left: .35rem;
}
.ph-src {
  display: inline-block; max-width: 18rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--ink-2); vertical-align: bottom;
}

/* ------------------------------------------------- price watch (findings) */
/* Prefixed pw- rather than extending ph-: these are decision cards, not table
   furniture, and three earlier class collisions in this file were all caused by
   reusing a prefix that already meant something else. */
.pw-flash {
  margin: 0 0 1.2rem; padding: .7rem .9rem; border-radius: .5rem;
  font-size: .88rem; border: 1px solid transparent;
}
.pw-flash.is-ok  { color: var(--good); background: var(--good-soft); border-color: color-mix(in srgb, var(--good) 30%, transparent); }
.pw-flash.is-bad { color: var(--warn); background: var(--warn-soft); border-color: color-mix(in srgb, var(--warn) 35%, transparent); }

.pw-h {
  display: flex; align-items: center; gap: .5rem;
  font-size: 1.05rem; margin: 2.2rem 0 .9rem;
}
.pw-h span {
  font: 700 .72rem/1 var(--sans); color: var(--warn);
  background: var(--warn-soft); padding: .24rem .44rem; border-radius: .3rem;
}
.pw-empty {
  padding: 1.1rem; border: 1px dashed var(--line); border-radius: .6rem;
  color: var(--ink-2); font-size: .9rem; margin: 1.4rem 0 0;
}

.pw-card {
  border: 1px solid var(--line); border-left-width: 3px;
  border-radius: .6rem; padding: 1rem 1.1rem; margin-bottom: 1rem;
  background: var(--surface-2);
}
.pw-card.is-warn { border-left-color: var(--warn); }
.pw-card.is-bad  { border-left-color: var(--bad, var(--warn)); }
.pw-card.is-ok   { border-left-color: var(--good); }

.pw-card-head { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; }
.pw-card-head h3 { margin: 0; font-size: 1rem; flex: 0 1 auto; min-width: 0; }
.pw-when { font-size: .76rem; color: var(--ink-3); margin-left: auto; }

.pw-badge {
  font: 700 .66rem/1 var(--sans); text-transform: uppercase; letter-spacing: .05em;
  padding: .26rem .44rem; border-radius: .3rem; white-space: nowrap;
}
.pw-badge.is-warn { color: var(--warn); background: var(--warn-soft); }
.pw-badge.is-bad  { color: var(--warn); background: color-mix(in srgb, var(--warn) 18%, transparent); }
.pw-badge.is-ok   { color: var(--good); background: var(--good-soft); }

.pw-note { margin: .7rem 0 .9rem; font-size: .89rem; color: var(--ink-2); }

.pw-compare { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin-bottom: .9rem; }
.pw-col { display: grid; gap: .1rem; }
.pw-k { font: 700 .66rem/1 var(--sans); text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3); }
.pw-col b { font-size: 1.15rem; font-variant-numeric: tabular-nums; }
.pw-col em { font-size: .78rem; color: var(--ink-2); font-style: normal; }
.pw-arrow { color: var(--ink-3); font-size: 1.1rem; }

.pw-ev { margin-bottom: .9rem; }
.pw-ev summary { cursor: pointer; font-size: .82rem; color: var(--ink-2); }
.pw-ev-list { list-style: none; margin: .6rem 0 0; padding: 0; display: grid; gap: .5rem; }
.pw-ev-list li {
  display: flex; align-items: baseline; gap: .45rem; flex-wrap: wrap;
  font-size: .8rem; padding-bottom: .5rem; border-bottom: 1px solid var(--line);
}
.pw-amt { font-weight: 800; font-variant-numeric: tabular-nums; }
.pw-tag {
  font: 700 .62rem/1 var(--sans); color: var(--ink-3);
  background: var(--surface-3); padding: .2rem .34rem; border-radius: .26rem;
}
.pw-tag.is-renew { color: var(--warn); background: var(--warn-soft); }
/* The quoted context is the evidence, so it wraps rather than truncating. */
.pw-ev-list q { color: var(--ink-2); flex: 1 1 100%; overflow-wrap: anywhere; }

.pw-fields { display: flex; gap: .7rem; flex-wrap: wrap; align-items: flex-end; }
.pw-fields label { display: grid; gap: .22rem; }
.pw-fields span { font: 700 .66rem/1 var(--sans); text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3); }
.pw-fields input {
  font: 500 .9rem var(--sans); padding: .42rem .55rem;
  border: 1px solid var(--line); border-radius: .38rem;
  background: var(--surface); color: var(--ink); width: 9rem;
}
.pw-src-f { flex: 1 1 16rem; min-width: 0; }
.pw-src-f input { width: 100%; }

.pw-acts { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin-top: .8rem; }
.pw-visit { font-size: .8rem; }

.pw-url {
  display: flex; gap: .6rem; align-items: flex-end; flex-wrap: wrap;
  margin-top: .9rem; padding-top: .9rem; border-top: 1px solid var(--line);
}
.pw-url label { display: grid; gap: .22rem; flex: 1 1 22rem; min-width: 0; }
.pw-url span { font: 700 .66rem/1 var(--sans); text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3); }
.pw-url input {
  font: 500 .86rem var(--sans); padding: .42rem .55rem; width: 100%;
  border: 1px solid var(--line); border-radius: .38rem;
  background: var(--surface); color: var(--ink);
}

.ph-act { display: flex; gap: .35rem; align-items: center; }
.ph-act form { margin: 0; }

.ph-foot {
  margin: 1.5rem 0 0; max-width: 78ch;
  font-size: .84rem; line-height: 1.7; color: var(--ink-2);
  padding-top: 1.1rem; border-top: 1px solid var(--line);
}
.ph-foot strong { color: var(--ink); }



/* ============================================================================
   VS PICKER  (/compare, and the foot of each comparison)

   Three attempts to improve this by tweaking failed because the problem was
   structural: two identical grey-bordered boxes inside a grey panel, the figures
   set as a small grey caption, and a thin outlined VS. Nothing said "versus" and
   nothing used the brand colours the data already carries.

   Rebuilt as a matchup: white elevated panel, each card tinted with its own
   brand colour, figures as a real stat row, and a filled VS on a rule that runs
   between the two sides.
   ========================================================================== */
.vs-picker {
  display: grid; gap: 1.4rem;
  padding: 1.6rem 1.7rem 1.7rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-2);
}

.vsp-matchup {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  gap: 1.15rem; align-items: end;
}
@media (max-width: 660px) {
  .vsp-matchup { grid-template-columns: 1fr; gap: .85rem; }
  .vs-picker { padding: 1.2rem 1.2rem 1.3rem; }
}

.vsp-side { min-width: 0; }
.vsp-lab {
  display: block; margin-bottom: .5rem;
  font: 700 .655rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-3);
}

/* --------------------------------------------------------------- the card */
.vsp-card {
  --bc: var(--a1);
  position: relative; overflow: hidden;
  display: grid; gap: .9rem;
  padding: 1.05rem 1.1rem 1rem;
  border: 1px solid var(--line-2); border-radius: var(--r);
  /* A whisper of the brand colour, so the two sides are visibly different
     things rather than two copies of the same control. */
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--bc) 7%, var(--surface)) 0%,
      var(--surface) 62%);
  box-shadow: var(--sh-1);
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease),
              transform .15s var(--ease);
}
.vsp-card:hover { border-color: color-mix(in srgb, var(--bc) 45%, var(--line-2)); }
.vsp-card:focus-within {
  border-color: var(--bc);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--bc) 20%, transparent), var(--sh-1);
}

/* Brand colour as a top edge — the cheapest way to make a card feel owned. */
.vsp-edge {
  position: absolute; inset: 0 0 auto; height: 3px;
  background: linear-gradient(90deg, var(--bc), color-mix(in srgb, var(--bc) 45%, white));
}

.vsp-id {
  display: grid; grid-template-columns: auto minmax(0, 1fr) .8rem;
  gap: .75rem; align-items: center;
}
/* The shared chip is 1.25rem for menus; here it heads a card, so it scales and
   sits on a plate of its own colour. */
.vsp-id > .pick-chip {
  width: 2.6rem; height: 2.6rem; border-radius: .55rem; font-size: .85rem;
}

.vsp-sel {
  appearance: none; -webkit-appearance: none;
  width: 100%; margin: 0; padding: 0;
  font-family: var(--display); font-weight: 800; font-size: 1.22rem; line-height: 1.15;
  letter-spacing: -.035em; color: var(--ink);
  background: none; border: 0; border-radius: 0; box-shadow: none;
  cursor: pointer; text-overflow: ellipsis;
}
.vsp-sel:focus, .vsp-sel:hover { outline: none; box-shadow: none; border: 0; }

.vsp-chev {
  justify-self: end; pointer-events: none;
  width: 0; height: 0;
  border-left: .3rem solid transparent; border-right: .3rem solid transparent;
  border-top: .36rem solid var(--ink-3);
}

/* ------------------------------------------------------------ stat row */
.vsp-stats {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0; margin: 0;
  border-top: 1px solid var(--line);
  padding-top: .8rem;
}
.vsp-stats > div { display: grid; gap: .1rem; padding-right: .5rem; }
.vsp-stats > div + div {
  padding-left: .75rem; border-left: 1px solid var(--line);
}
.vsp-stats dt {
  font: 700 .62rem/1 var(--sans); text-transform: uppercase; letter-spacing: .1em;
  color: var(--ink-3);
}
.vsp-stats dd {
  margin: 0;
  font-family: var(--display); font-weight: 800; font-size: 1.08rem; line-height: 1.1;
  letter-spacing: -.035em; color: var(--ink);
  font-variant-numeric: lining-nums tabular-nums;
}
.vsp-stats dd.vsp-score { color: var(--a1); }

/* ------------------------------------------------------------ the divider */
/* A rule that runs between the cards, with the badge sitting on it. */
.vsp-vs {
  position: relative; z-index: 1;
  align-self: center; justify-self: center;
  display: grid; place-items: center;
  width: 3rem; height: 3rem; border-radius: 50%;
  font: 800 .78rem/1 var(--sans); letter-spacing: .06em;
  color: #fff; background: var(--grad);
  box-shadow: var(--sh-glow), inset 0 1px 0 rgba(255,255,255,.25);
  margin-top: 1.35rem;         /* centres on the cards, not on label + card */
}
.vsp-vs::before {
  content: ""; position: absolute; z-index: -1;
  left: -1.4rem; right: -1.4rem; top: 50%; height: 1px;
  background: var(--line-2);
}
@media (max-width: 660px) {
  .vsp-vs { margin-top: 0; justify-self: start; width: 2.5rem; height: 2.5rem; }
  .vsp-vs::before { display: none; }
}

/* ------------------------------------------------------------- the action */
.vsp-act { display: grid; justify-items: center; gap: .45rem; }
.vsp-go { width: 100%; max-width: 20rem; justify-content: center; }
.vsp-err { margin: 0; font: 600 .76rem/1.35 var(--sans); color: var(--warn); }
.vsp-err:empty { display: none; }

.vs-picker-note {
  margin: .8rem 0 0;
  font-size: .785rem; line-height: 1.6; color: var(--ink-3);
}

/* ============================================================================
   DOCUMENT PAGES — shared additions for /privacy and /terms
   These reuse the /method components; only the variants are new.
   ========================================================================== */

/* Green variant of the admission panel. /method leads with what it declines to
   claim (warn); /privacy leads with what it declines to collect, which is good
   news, so the same component in the positive colour. */
.admit.is-good {
  border-left-color: var(--good);
  background: var(--good-soft);
}

/* The .deny list without the cross. The cross is right for "commission cannot
   do X"; it would be wrong on a list of rights you *do* have. */
.deny.is-plain li::before {
  content: "";
  width: .32rem; height: .32rem; margin-top: .62rem; margin-left: .05rem;
  border-radius: 50%;
  background: var(--ink-3);
}
.deny.is-plain li { padding-left: 1.15rem; }

/* Trailing "related pages" line on a legal document. */
.doc-related {
  margin-top: 2rem !important;
  padding-top: 1.1rem; border-top: 1px solid var(--line);
  font-size: .82rem !important; color: var(--ink-3) !important;
}


/* ============================================================================
   TRUE-COST CALCULATOR (/cost)
   Prices every host over the term the reader actually plans to stay. The column
   that matters is not the rate — it is how long that rate is locked for.
   ========================================================================== */

/* The one line that explains the whole page. */
.tc-twist {
  margin: 1.5rem 0 0; padding: 1.1rem 1.25rem;
  border: 1px solid var(--line); border-left: 3px solid var(--warn);
  border-radius: var(--r-sm); background: var(--warn-soft);
  font-size: .92rem; line-height: 1.65; color: var(--ink-2);
  max-width: 80ch;
}
.tc-twist b { color: var(--ink); }
.tc-twist[hidden] { display: none; }

.tc-wrap { margin-top: 1.75rem; }

/* ------------------------------------------------------------ the columns */
/* One definition shared by the head and the rows so they cannot drift. */
.tc-head,
.tc-row {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) 7.5rem 8.5rem 9.5rem auto;
  gap: 1rem; align-items: center;
}

.tc-head {
  padding: 0 1.15rem .7rem;
  font: 700 .655rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-3);
}
.tc-head .tc-h-total { color: var(--ink-2); }

.tc-row {
  position: relative;
  padding: 1rem 1.15rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--sh-1);
  margin-bottom: .5rem;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.tc-row:hover { border-color: var(--line-2); box-shadow: var(--sh-2); }

/* The cheapest option over the chosen horizon. */
.tc-row.is-best {
  border-color: color-mix(in srgb, var(--good) 40%, transparent);
  background: color-mix(in srgb, var(--good) 4%, var(--surface));
}

.tc-id { display: flex; align-items: center; gap: .7rem; min-width: 0; }
.tc-id-t { display: grid; gap: .1rem; min-width: 0; }
.tc-id-t a {
  font: 700 .95rem/1.25 var(--sans); letter-spacing: -.02em;
  color: inherit; text-decoration: none;
}
.tc-id-t a:hover { color: var(--a1); }
.tc-id-t em {
  font-style: normal; font-size: .73rem; color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.tc-cell { display: grid; gap: .18rem; }
.tc-cell b {
  font: 800 .98rem/1 var(--sans); letter-spacing: -.02em;
  font-variant-numeric: lining-nums tabular-nums;
}
.tc-cell em { font-style: normal; font-size: .715rem; color: var(--ink-3); }

/* How long the intro rate holds — the number this page is really about. */
.tc-lock {
  justify-self: start;
  font-weight: 700 !important; letter-spacing: .01em;
  color: var(--ink-2) !important;
  background: var(--surface-3); padding: .2rem .38rem; border-radius: .28rem;
}
.tc-up   { color: var(--warn) !important; font-weight: 700 !important; }
.tc-flat { color: var(--good); }

.tc-total b { font-family: var(--display); font-size: 1.35rem; letter-spacing: -.04em; }
.tc-row.is-best .tc-total b { color: var(--good); }

.tc-cta { display: flex; align-items: center; gap: .5rem; justify-self: end; }
.tc-badge {
  font: 700 .625rem/1 var(--sans); text-transform: uppercase; letter-spacing: .06em;
  color: var(--good); background: var(--good-soft);
  padding: .3rem .44rem; border-radius: .3rem; white-space: nowrap;
}

/* The plain-English version of the sum, spanning the full row width. */
.tc-note {
  grid-column: 1 / -1;
  margin: .25rem 0 0; padding-top: .7rem;
  border-top: 1px dashed var(--line);
  font-size: .785rem; line-height: 1.55; color: var(--ink-3);
}
.tc-warn { color: var(--warn); font-weight: 600; }
.tc-good { color: var(--good); font-weight: 600; }

/* ------------------------------------------------------------------ small */
@media (max-width: 1000px) {
  .tc-head { display: none; }          /* labels move inline on the rows */
  .tc-row {
    grid-template-columns: 1fr 1fr;
    gap: .75rem 1rem;
  }
  .tc-id { grid-column: 1 / -1; }
  .tc-cta { grid-column: 1 / -1; justify-self: start; }
  /* Without the header row, each figure has to say what it is. */
  .tc-cell::before {
    content: attr(data-label);
    font: 700 .62rem/1 var(--sans); text-transform: uppercase; letter-spacing: .1em;
    color: var(--ink-3);
  }
  .tc-cell { gap: .3rem; }
}
@media (max-width: 520px) {
  .tc-row { grid-template-columns: 1fr; }
  .tc-total b { font-size: 1.25rem; }
}

/* ============================================================================
   BREADCRUMBS
   Visible path plus the anchor for BreadcrumbList structured data.
   ========================================================================== */
.crumbs { margin: 0 0 1.5rem; }
.crumbs ol {
  display: flex; flex-wrap: wrap; align-items: center; gap: .1rem .5rem;
  list-style: none; margin: 0; padding: 0;
  font: 500 .78rem/1.4 var(--sans); color: var(--ink-3);
}
.crumbs li { display: inline-flex; align-items: center; gap: .5rem; }
.crumbs li + li::before {
  content: "/"; color: var(--line-2); font-weight: 600;
}
.crumbs a { color: var(--ink-3); text-decoration: none; }
.crumbs a:hover { color: var(--a1); }
.crumbs [aria-current] { color: var(--ink-2); font-weight: 600; }

/* ============================================================================
   404
   Was a heading and two buttons. A visitor here wanted something specific.
   ========================================================================== */
.nf { padding: 3.5rem 1.5rem 1rem; max-width: 62rem; }
.nf-code {
  display: block;
  font-family: var(--display); font-weight: 800; font-size: clamp(3rem, 2rem + 5vw, 5rem);
  line-height: .9; letter-spacing: -.05em;
  color: var(--surface-3);
  margin-bottom: .35rem;
}
.nf h1 { margin: 0 0 .8rem; }
.nf .lead { margin-bottom: 2.5rem; }

.nf-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem;
}
@media (max-width: 860px) { .nf-grid { grid-template-columns: 1fr; } }

.nf-block {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 1.25rem 1.35rem; box-shadow: var(--sh-1);
}
.nf-k {
  display: block; margin: 0 0 .5rem;
  font: 700 .655rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-3);
}
.nf-link {
  display: flex; align-items: center; gap: .55rem;
  padding: .55rem 0; border-bottom: 1px solid var(--line);
  font: 600 .875rem/1.35 var(--sans); color: var(--ink-2); text-decoration: none;
  transition: color .15s var(--ease);
}
.nf-link:last-child { border-bottom: 0; }
/* Explicit class, not :first-of-type — the logo chip is also a span and was
   being stretched to fill the row. */
.nf-t { flex: 1; min-width: 0; }
.nf-link em { font-style: normal; color: var(--ink-3); }
.nf-link:hover { color: var(--a1); }
.nf-link:hover em { color: var(--a1); }
.nf-score {
  font: 800 .74rem/1 var(--sans); color: var(--a1);
  font-variant-numeric: tabular-nums;
}
.nf-foot { margin: 1.75rem 0 0; font-size: .84rem; color: var(--ink-3); }

/* ============================================================================
   GUIDES INDEX
   ========================================================================== */
.bl-list { display: grid; gap: .75rem; }

.bl-card {
  display: grid; grid-template-columns: 2.75rem minmax(0, 1fr); gap: 1.25rem;
  padding: 1.5rem 1.6rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.bl-card:hover { border-color: var(--line-2); box-shadow: var(--sh-2); }
@media (max-width: 620px) {
  .bl-card { grid-template-columns: 1fr; gap: .5rem; padding: 1.25rem 1.25rem 1.35rem; }
}

.bl-n {
  font-family: var(--display); font-weight: 800; font-size: 1.15rem; line-height: 1.3;
  letter-spacing: -.03em; color: var(--line-2);
  font-variant-numeric: tabular-nums;
}
.bl-title { margin: 0 0 .5rem; font-size: clamp(1.15rem, 1.05rem + .5vw, 1.4rem); }
.bl-title a { color: inherit; text-decoration: none; }
.bl-title a:hover { color: var(--a1); }
.bl-ex { margin: 0 0 1rem; font-size: .92rem; line-height: 1.65; color: var(--ink-2); max-width: 68ch; }

.bl-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: .4rem 1rem;
  font-size: .765rem; color: var(--ink-3);
}
.bl-go {
  margin-left: auto; font: 650 .8rem/1 var(--sans); color: var(--a1);
}
@media (max-width: 620px) { .bl-go { margin-left: 0; } }

/* ============================================================================
   GUIDE BODY  (prose)
   Long-form article text inside the document layout.
   ========================================================================== */
.prose > *:first-child { margin-top: 0; }
.prose p { font-size: .97rem; line-height: 1.8; color: var(--ink-2); margin: 0 0 1.15rem; }
.prose h2 {
  margin: 2.5rem 0 .9rem;
  font-size: clamp(1.4rem, 1.3rem + .6vw, 1.7rem); letter-spacing: -.028em;
  padding-top: 1.5rem; border-top: 1px solid var(--line);
}
.prose h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.prose h3 { margin: 1.9rem 0 .6rem; font-size: 1.08rem; letter-spacing: -.02em; }
.prose strong { color: var(--ink); font-weight: 700; }
.prose a { font-weight: 550; }
.prose code {
  font-family: var(--mono); font-size: .86em;
  background: var(--surface-3); padding: .12rem .32rem; border-radius: .25rem;
}

.prose ul, .prose ol { margin: 0 0 1.3rem; padding-left: 1.3rem; }
.prose li {
  font-size: .95rem; line-height: 1.75; color: var(--ink-2);
  margin-bottom: .5rem; padding-left: .2rem;
}
.prose li::marker { color: var(--ink-3); }
.prose ol li::marker { font-weight: 700; }

/* In-article call to action. */
.post-cta {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 1.5rem 2rem; align-items: center;
  margin: 3rem 0 0; padding: 1.6rem 1.75rem;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
.post-cta h2 { margin: 0 0 .35rem; font-size: 1.12rem; letter-spacing: -.022em; }
.post-cta p { margin: 0; font-size: .875rem; line-height: 1.65; color: var(--ink-2); }
.post-cta .btn { white-space: nowrap; }
@media (max-width: 700px) {
  .post-cta { grid-template-columns: 1fr; }
  .post-cta .btn { justify-self: start; }
}

/* Read next. */
.post-next { margin-top: 2.75rem; padding-top: 1.75rem; border-top: 1px solid var(--line); }
.post-next-k {
  margin: 0 0 1rem;
  font: 700 .655rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-3);
}
.post-next-list { display: grid; gap: .6rem; }
.post-next-item {
  display: grid; gap: .25rem;
  padding: 1rem 1.15rem; text-decoration: none;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); transition: border-color .15s var(--ease);
}
.post-next-item:hover { border-color: var(--a1); }
.pn-title { font: 700 .95rem/1.35 var(--sans); letter-spacing: -.02em; color: var(--ink); }
.pn-ex { font-size: .82rem; line-height: 1.6; color: var(--ink-3); }
.pn-meta { font: 600 .72rem/1 var(--sans); color: var(--a1); margin-top: .2rem; }

/* ============================================================================
   HOME — RANKINGS BY USE CASE
   Was six identical cards holding a title and a truncated intro. Each now names
   the current #1 pick with its score and entry price, so the card answers the
   question instead of only asking it.
   ========================================================================== */
.uc-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 1rem; margin-top: 1.5rem;
}

.uc-card {
  /* flex, not grid: the intro flexes so the pick block and the link sit on the
     same line across a row whatever length the intro happens to be. */
  display: flex; flex-direction: column; gap: .8rem;
  padding: 1.35rem 1.4rem 1.25rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
  text-decoration: none; color: inherit;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease),
              transform .18s var(--ease);
}
.uc-card:hover {
  border-color: var(--line-2); box-shadow: var(--sh-3); transform: translateY(-3px);
}

.uc-top { display: flex; align-items: baseline; gap: .75rem; }
.uc-top h3 {
  margin: 0; flex: 1; min-width: 0;
  font-size: 1.06rem; letter-spacing: -.025em;
}
.uc-count {
  font: 700 .625rem/1 var(--sans); text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-3); background: var(--surface-3);
  padding: .28rem .42rem; border-radius: .3rem; white-space: nowrap;
}
.uc-intro { flex: 1; margin: 0; font-size: .855rem; line-height: 1.6; color: var(--ink-3); }

/* The answer: who currently tops this list. */
.uc-pick {
  --bc: var(--a1);
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  gap: .6rem; align-items: center;
  padding: .7rem .8rem;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--bc) 5%, var(--surface-2));
}
.uc-pick-t { display: grid; gap: .05rem; min-width: 0; }
.uc-pick-t em {
  font-style: normal; font-size: .655rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.uc-pick-t b { font: 700 .93rem/1.2 var(--sans); letter-spacing: -.022em; }
.uc-pick-n { display: grid; justify-items: end; gap: .05rem; }
.uc-pick-n b {
  font: 800 .95rem/1 var(--sans); color: var(--a1);
  font-variant-numeric: tabular-nums;
}
.uc-pick-n em { font-style: normal; font-size: .68rem; color: var(--ink-3); white-space: nowrap; }

.uc-go { font: 650 .8rem/1 var(--sans); color: var(--a1); }
.uc-card:hover .uc-go span { margin-left: .15rem; }

/* The calculator card, which has figures rather than a pick. */
.uc-card-alt { background: var(--surface-2); }
.uc-tool { display: grid; gap: .4rem; }
.uc-tool span { font-size: .8rem; color: var(--ink-2); }
.uc-tool b {
  font-family: var(--display); font-weight: 800; font-size: 1.05rem;
  letter-spacing: -.03em; color: var(--warn); margin-right: .25rem;
}
.uc-tool span:last-child b { color: var(--good); }

/* ============================================================================
   HOME — WHY TRUST THESE RANKINGS
   Was three cards asserting trustworthiness. Each claim now shows its figure.
   ========================================================================== */
.tr-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 1rem; margin-top: 1.5rem;
}
.tr-card {
  display: grid; align-content: start; gap: .8rem;
  padding: 1.5rem 1.55rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
}
.tr-head { display: flex; align-items: center; gap: .65rem; }
.tr-head h3 { margin: 0; font-size: 1.02rem; letter-spacing: -.022em; }
.tr-ico {
  display: grid; place-items: center; flex: none;
  width: 2.1rem; height: 2.1rem; border-radius: .55rem;
  color: var(--a1); background: var(--accent-soft);
  border: 1px solid var(--accent-line);
}
.tr-card > p { margin: 0; font-size: .875rem; line-height: 1.7; color: var(--ink-2); }
.tr-sub { font-size: .795rem !important; color: var(--ink-3) !important; }
.tr-sub b { color: var(--ink-2); }

/* The five weights, drawn from config so they cannot drift from the scoring. */
.tr-weights { list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; }
.tr-weights li {
  display: grid; grid-template-columns: 5.5rem minmax(0, 1fr) 2.4rem;
  gap: .7rem; align-items: center;
}
.trw-bar {
  /* All three pinned to row 1: the bar precedes the label in the DOM, so grid
     auto-placement was wrapping it onto its own row. */
  grid-column: 2; grid-row: 1; height: .45rem; border-radius: 999px;
  background: var(--surface-3); overflow: hidden;
}
.trw-bar i {
  display: block; height: 100%; width: var(--w);
  /* Relative to 100%, so 30% draws 30% — the honest reading of a weight. */
  background: var(--a1); border-radius: 999px;
}
.trw-k { grid-column: 1; grid-row: 1; font: 600 .8rem/1 var(--sans); color: var(--ink-2); }
.trw-v {
  grid-column: 3; grid-row: 1; justify-self: end;
  font: 800 .82rem/1 var(--sans); color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.tr-big { display: flex; align-items: baseline; gap: .5rem; }
.tr-big b {
  font-family: var(--display); font-weight: 800;
  font-size: clamp(2rem, 1.7rem + 1.2vw, 2.6rem); line-height: 1;
  letter-spacing: -.045em; color: var(--warn);
}
.tr-big span { font-size: .84rem; color: var(--ink-3); }

.tr-deny { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.tr-deny li {
  position: relative; padding: .55rem 0 .55rem 1.4rem;
  border-bottom: 1px solid var(--line);
  font-size: .84rem; line-height: 1.6; color: var(--ink-2);
}
.tr-deny li:last-child { border-bottom: 0; }
.tr-deny li::before {
  content: "\2715"; position: absolute; left: 0; top: .62rem;
  font-size: .7rem; font-weight: 700; color: var(--warn);
}
.tr-deny b { color: var(--ink); font-weight: 800; }


/* ============================================================================
   HOME — GUIDES
   Was three identical cards with the excerpt truncated to 120 characters, which
   cut every one mid-sentence. It was also a fourth card grid on a page that
   already had three, so the section had no reason to look different.

   Now a featured lead beside a compact numbered list: editorial shape, distinct
   from the product grids above it, and the lead's excerpt runs in full.
   ========================================================================== */
.hg {
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 1rem; margin-top: 1.5rem; align-items: start;
}
@media (max-width: 900px) { .hg { grid-template-columns: 1fr; } }

/* ------------------------------------------------------------------ lead */
.hg-lead {
  display: grid; align-content: start; gap: .7rem;
  padding: 1.6rem 1.7rem 1.5rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
  text-decoration: none; color: inherit;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.hg-lead:hover { border-color: var(--line-2); box-shadow: var(--sh-3); }

.hg-kicker {
  justify-self: start;
  font: 700 .625rem/1 var(--sans); text-transform: uppercase; letter-spacing: .1em;
  color: var(--a1); background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  padding: .3rem .48rem; border-radius: .3rem;
}
.hg-lead h3 {
  margin: 0;
  font-size: clamp(1.28rem, 1.15rem + .7vw, 1.6rem); letter-spacing: -.03em;
  line-height: 1.2;
}
.hg-lead p {
  margin: 0; max-width: 52ch;
  font-size: .93rem; line-height: 1.7; color: var(--ink-2);
}
.hg-foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: .35rem .9rem;
  margin-top: .3rem; padding-top: .9rem; border-top: 1px solid var(--line);
  font-size: .765rem; color: var(--ink-3);
}
.hg-foot em {
  margin-left: auto; font-style: normal;
  font: 650 .8rem/1 var(--sans); color: var(--a1);
}
@media (max-width: 520px) { .hg-foot em { margin-left: 0; } }

/* ------------------------------------------------------------ the others */
.hg-rest {
  display: grid; align-content: start;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-1); overflow: hidden;
}
.hg-row {
  display: grid; grid-template-columns: 1.9rem minmax(0, 1fr) 1rem;
  gap: .85rem; align-items: center;
  padding: 1.1rem 1.3rem;
  text-decoration: none; color: inherit;
  transition: background-color .15s var(--ease);
}
.hg-row + .hg-row { border-top: 1px solid var(--line); }
.hg-row:hover { background: var(--surface-2); }

.hg-n {
  font-family: var(--display); font-weight: 800; font-size: .95rem;
  letter-spacing: -.03em; color: var(--line-2);
  font-variant-numeric: tabular-nums;
}
.hg-row:hover .hg-n { color: var(--a1); }

.hg-row-t { display: grid; gap: .15rem; min-width: 0; }
.hg-row-t b { font: 700 .95rem/1.35 var(--sans); letter-spacing: -.02em; }
.hg-row-t em { font-style: normal; font-size: .735rem; color: var(--ink-3); }

.hg-arrow {
  justify-self: end; color: var(--line-2); font-size: .9rem;
  transition: color .15s var(--ease), transform .15s var(--ease);
}
.hg-row:hover .hg-arrow { color: var(--a1); transform: translateX(2px); }

/* ============================================================================
   GUIDE PAGES — additions
   The article was structurally fine but visually a wall of grey text with no
   anchor to scan and no payoff up front.
   ========================================================================== */

/* Reading progress. Fixed under the sticky header. */
.rp {
  position: fixed; top: 0; left: 0; right: 0; z-index: 60;
  height: 3px; background: transparent; pointer-events: none;
}
.rp i {
  display: block; height: 100%; width: 0;
  background: var(--grad-bright);
  transition: width .08s linear;
}
@media (prefers-reduced-motion: reduce) { .rp i { transition: none; } }

/* The short version — the payoff before the 900 words. */
.tk {
  margin: 0 0 2.5rem; padding: 1.4rem 1.55rem;
  background: var(--accent-soft);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-lg);
}
.tk-k {
  display: block; margin-bottom: .8rem;
  font: 700 .655rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em;
  color: var(--a1);
}
.tk ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .7rem; }
.tk li {
  position: relative; padding-left: 1.5rem;
  font-size: .91rem; line-height: 1.65; color: var(--ink);
}
.tk li::before {
  content: ""; position: absolute; left: 0; top: .55rem;
  width: .45rem; height: .45rem; border-radius: 50%;
  background: var(--a1);
}

/* Next in the series — the guides are a sequence, so it names the next one. */
.post-next-up {
  display: grid; gap: .4rem;
  margin: 3rem 0 0; padding: 1.5rem 1.65rem;
  background: var(--surface); border: 1px solid var(--line-2);
  border-left: 3px solid var(--a1);
  border-radius: var(--r-sm); text-decoration: none; color: inherit;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.post-next-up:hover { box-shadow: var(--sh-2); border-color: var(--a1); }
.pnu-k {
  font: 700 .645rem/1 var(--sans); text-transform: uppercase; letter-spacing: .1em;
  color: var(--a1);
}
.pnu-title {
  font-family: var(--display); font-weight: 800;
  font-size: 1.18rem; line-height: 1.25; letter-spacing: -.03em;
}
.pnu-ex { font-size: .875rem; line-height: 1.65; color: var(--ink-2); max-width: 56ch; }
.pnu-go {
  margin-top: .3rem;
  font: 650 .78rem/1 var(--sans); color: var(--ink-3);
}
.pnu-go em { font-style: normal; color: var(--a1); }

/* ============================================================================
   GUIDES INDEX — additions
   ========================================================================== */
.bl-order { margin: 1.5rem 0 1.25rem; }

/* The list is an <ol> now; the visible numbers come from .bl-n, so suppress
   the marker rather than showing two sets of numbers. */
.bl-list { list-style: none; padding: 0; }

/* Two takeaways per card: the reason to click, rather than another arrow. */
.bl-tk {
  list-style: none; margin: 0 0 1.1rem; padding: .9rem 0 0;
  border-top: 1px solid var(--line);
  display: grid; gap: .5rem;
}
.bl-tk li {
  position: relative; padding-left: 1.25rem;
  font-size: .855rem; line-height: 1.6; color: var(--ink-2);
}
.bl-tk li::before {
  content: ""; position: absolute; left: 0; top: .52rem;
  width: .35rem; height: .35rem; border-radius: 50%;
  background: var(--a1);
}

/* ============================================================================
   CONTACT
   The topic was a <select> with its five explanations listed separately in a
   sidebar, so you chose "Correction" in one place and read what that meant in
   another. The options now carry their own explanation, which also empties out
   most of what the sidebar was for.
   ========================================================================== */
.ct-sec { margin-top: 2rem; }
.ct-errs { margin: .4rem 0 0; padding-left: 1.2rem; }

.ct-grid {
  display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 2.5rem; align-items: start; margin-top: 1.5rem;
}
@media (max-width: 900px) { .ct-grid { grid-template-columns: 1fr; gap: 2rem; } }

/* ------------------------------------------------------------- the form */
.ct-form { display: grid; gap: 1.1rem; }
.ct-form label { margin-bottom: 0; }
.ct-form textarea { min-height: 9.5rem; }
.ct-form .btn { justify-self: start; }

.ct-legal {
  margin: 0; font-size: .78rem; line-height: 1.65; color: var(--ink-3);
}
.ct-hp { position: absolute; left: -9999px; }

/* ------------------------------------------------------ topic as cards */
.ct-topics { border: 0; margin: 0; padding: 0; background: none; }
.ct-topics legend {
  display: block; padding: 0; margin-bottom: .6rem;
  font: 700 .655rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-3);
}
.ct-topic-grid { display: grid; gap: .5rem; }

.ct-topic {
  position: relative; display: grid;
  grid-template-columns: 2.1rem minmax(0, 1fr) 1.1rem;
  gap: .75rem; align-items: start;
  margin-bottom: 0; padding: .85rem .95rem;
  cursor: pointer;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-sm); box-shadow: var(--sh-1);
  transition: border-color .15s var(--ease), background-color .15s var(--ease);
}
.ct-topic input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.ct-topic:hover { border-color: var(--ink-3); }
.ct-topic.on,
.ct-topic:has(input:checked) {
  border-color: var(--a1); background: var(--accent-soft);
}
.ct-topic:has(input:focus-visible) { outline: 2px solid var(--a1); outline-offset: 2px; }

.ct-topic-i {
  display: grid; place-items: center;
  width: 2.1rem; height: 2.1rem; border-radius: .5rem;
  color: var(--ink-3); background: var(--surface-2);
  border: 1px solid var(--line);
  transition: color .15s var(--ease), background-color .15s var(--ease);
}
.ct-topic.on .ct-topic-i,
.ct-topic:has(input:checked) .ct-topic-i {
  color: #fff; background: var(--a1); border-color: var(--a1);
}

.ct-topic-t { display: grid; gap: .15rem; min-width: 0; }
.ct-topic-t b { font: 700 .9rem/1.3 var(--sans); letter-spacing: -.018em; color: var(--ink); }
.ct-topic-t em {
  /* The global `label` rule sets font-weight 650, which the hint inherits and
     which made it read as bold as the option it describes. */
  font-style: normal; font-weight: 400;
  font-size: .795rem; line-height: 1.55; color: var(--ink-2);
}

/* Radio affordance, drawn rather than native so it matches the card. */
.ct-topic-tick {
  align-self: center; justify-self: end;
  width: 1.05rem; height: 1.05rem; border-radius: 50%;
  border: 1.5px solid var(--line-2); background: var(--surface);
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.ct-topic.on .ct-topic-tick,
.ct-topic:has(input:checked) .ct-topic-tick {
  border-color: var(--a1);
  box-shadow: inset 0 0 0 3.5px var(--surface), inset 0 0 0 1rem var(--a1);
}

/* ---------------------------------------------------------- the sidebar */
.ct-aside { display: grid; gap: .75rem; }
.ct-block {
  padding: 1.2rem 1.3rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
}
.ct-block-strong { background: var(--surface-2); }
.ct-k {
  display: block; margin-bottom: .6rem;
  font: 700 .645rem/1 var(--sans); text-transform: uppercase; letter-spacing: .11em;
  color: var(--ink-3);
}
.ct-block p {
  margin: 0; font-size: .825rem; line-height: 1.65; color: var(--ink-2);
}
.ct-mail {
  display: block; margin-bottom: .5rem;
  font: 700 .95rem/1.3 var(--sans); letter-spacing: -.018em;
  word-break: break-all;
}

/* What we will and will not do — stated as a list, because a paragraph buries it. */
.ct-will { list-style: none; margin: 0 0 .8rem; padding: 0; display: grid; gap: 0; }
.ct-will li {
  position: relative; padding: .55rem 0 .55rem 1.5rem;
  border-bottom: 1px solid var(--line);
  font-size: .825rem; line-height: 1.55; color: var(--ink-2);
}
.ct-will li:last-child { border-bottom: 0; }
.ct-will li::before {
  position: absolute; left: 0; top: .6rem;
  font-size: .72rem; font-weight: 700;
}
.ct-will li.yes::before { content: "\2713"; color: var(--good); }
.ct-will li.no::before  { content: "\2715"; color: var(--warn); }

/* ============================================================================
   GUIDED FINDER (/finder)
   One question per screen, answers in the query string. Options are submit
   buttons, so the whole flow works without JavaScript and a result is a URL
   someone can send to a colleague.
   ========================================================================== */
.fd-sec { margin-top: 2rem; }

/* ------------------------------------------------------------ the question */
.fd-card {
  max-width: 40rem; margin: 0 auto;
  padding: 1.9rem 2rem 1.7rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-2);
}
@media (max-width: 560px) { .fd-card { padding: 1.4rem 1.35rem 1.3rem; } }

.fd-progress {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  margin-bottom: 1.4rem;
}
.fd-step {
  font: 700 .655rem/1 var(--sans); text-transform: uppercase; letter-spacing: .12em;
  color: var(--ink-3);
}
.fd-dots { display: flex; gap: .3rem; }
.fd-dots i {
  width: 1.4rem; height: .28rem; border-radius: 999px;
  background: var(--surface-3);
}
.fd-dots i.done { background: var(--accent-line); }
.fd-dots i.now  { background: var(--a1); }

.fd-q {
  margin: 0 0 .4rem;
  font-size: clamp(1.35rem, 1.2rem + .8vw, 1.7rem); letter-spacing: -.03em;
}
.fd-hint { margin: 0 0 1.4rem; font-size: .875rem; line-height: 1.6; color: var(--ink-3); }

/* Options are <button type=submit>, one per answer — no JS, no radio + submit. */
.fd-opts { display: grid; gap: .5rem; }
.fd-opt {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  width: 100%; padding: .95rem 1.1rem; cursor: pointer; text-align: left;
  font: 650 .95rem/1.35 var(--sans); color: var(--ink);
  background: var(--surface); border: 1px solid var(--line-2);
  border-radius: var(--r-sm); box-shadow: var(--sh-1);
  transition: border-color .15s var(--ease), background-color .15s var(--ease),
              transform .12s var(--ease);
}
.fd-opt em { font-style: normal; color: var(--line-2); transition: color .15s var(--ease); }
.fd-opt:hover {
  border-color: var(--a1); background: var(--accent-soft); transform: translateX(2px);
}
.fd-opt:hover em { color: var(--a1); }
.fd-opt:focus-visible { outline: 2px solid var(--a1); outline-offset: 2px; }

.fd-restart {
  margin: 1.2rem 0 0; padding-top: 1rem; border-top: 1px solid var(--line);
  font-size: .8rem; color: var(--ink-3);
}

/* --------------------------------------------------------------- the recap */
/* What was asked, so a result can be audited rather than taken on faith. */
.fd-recap {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem .8rem;
  padding: .9rem 1.1rem; margin-bottom: 1.25rem;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.fd-recap-k {
  font: 700 .645rem/1 var(--sans); text-transform: uppercase; letter-spacing: .11em;
  color: var(--ink-3);
}
.fd-recap ul { display: flex; flex-wrap: wrap; gap: .4rem; list-style: none; margin: 0; padding: 0; }
.fd-recap li {
  font: 600 .765rem/1 var(--sans); color: var(--ink-2);
  background: var(--surface); border: 1px solid var(--line);
  padding: .32rem .5rem; border-radius: .3rem;
}
.fd-redo { margin-left: auto; font: 650 .78rem/1 var(--sans); }
@media (max-width: 620px) { .fd-redo { margin-left: 0; } }

/* -------------------------------------------------------------- the result */
.fd-results { display: grid; gap: .75rem; }

.fd-res {
  padding: 1.25rem 1.35rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
}
.fd-res.is-top {
  border-color: color-mix(in srgb, var(--a1) 40%, transparent);
  box-shadow: 0 0 0 3px var(--accent-soft), var(--sh-1);
}

.fd-res-head {
  display: grid; grid-template-columns: 1.9rem auto minmax(0, 1fr) auto auto;
  gap: .75rem; align-items: center;
  padding-bottom: 1rem; margin-bottom: .9rem;
  border-bottom: 1px solid var(--line);
}
@media (max-width: 640px) {
  .fd-res-head { grid-template-columns: 1.9rem auto minmax(0, 1fr); }
  .fd-res-n { grid-column: 2 / -1; justify-items: start !important; }
}

.fd-rank {
  display: grid; place-items: center;
  width: 1.9rem; height: 1.9rem; border-radius: 50%;
  font: 800 .82rem/1 var(--sans);
  color: var(--ink-2); background: var(--surface-2); border: 1px solid var(--line);
}
.fd-res.is-top .fd-rank {
  color: #fff; background: var(--grad); border-color: transparent;
  box-shadow: var(--sh-glow);
}

.fd-res-id { display: grid; gap: .1rem; min-width: 0; }
.fd-res-id a {
  font: 700 1rem/1.25 var(--sans); letter-spacing: -.022em;
  color: inherit; text-decoration: none;
}
.fd-res-id a:hover { color: var(--a1); }
.fd-res-id em { font-style: normal; font-size: .73rem; color: var(--ink-3); }

.fd-res-n { display: grid; justify-items: end; gap: .1rem; }
.fd-res-n b {
  font-family: var(--display); font-weight: 800; font-size: 1.1rem; line-height: 1;
  letter-spacing: -.035em; font-variant-numeric: lining-nums tabular-nums;
}
.fd-res-n em { font-style: normal; font-size: .68rem; color: var(--ink-3); }

/* Why it ranked there. Generated from the scoring, so it cannot contradict it. */
.fd-why { list-style: none; margin: 0 0 1.1rem; padding: 0; display: grid; gap: .45rem; }
.fd-why li {
  position: relative; padding-left: 1.5rem;
  font-size: .865rem; line-height: 1.55; color: var(--ink-2);
}
.fd-why li::before {
  position: absolute; left: 0; top: .5rem;
  font-size: .72rem; font-weight: 700; line-height: 1;
}
.fd-why li.is-good::before { content: "\2713"; color: var(--good); }
.fd-why li.is-bad::before  { content: "\2715"; color: var(--warn); }
.fd-why li.is-flat::before { content: "\2022"; color: var(--ink-3); }
.fd-why li.is-bad { color: var(--ink-2); }

.fd-res-cta { display: flex; flex-wrap: wrap; gap: .45rem; }

/* ============================================================================
   FAQ
   Native <details>/<summary>: expands with no JavaScript and is keyboard
   accessible for free. Both competitor sites have FAQs and this had none —
   they answer real long-tail queries and are eligible for rich results.
   ========================================================================== */
.faq { display: grid; gap: .5rem; max-width: 52rem; }

.faq-item {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--sh-1);
  transition: border-color .15s var(--ease);
}
.faq-item[open] { border-color: var(--line-2); }
.faq-item:hover { border-color: var(--line-2); }

.faq-item summary {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 1.05rem 1.2rem; cursor: pointer;
  font: 700 .96rem/1.4 var(--sans); letter-spacing: -.018em; color: var(--ink);
  list-style: none;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary:focus-visible { outline: 2px solid var(--a1); outline-offset: -2px; border-radius: var(--r); }

/* Drawn marker: the native triangle differs on every platform. */
.faq-item summary i {
  position: relative; flex: none; width: .8rem; height: .8rem;
}
.faq-item summary i::before,
.faq-item summary i::after {
  content: ""; position: absolute; background: var(--ink-3);
  transition: transform .18s var(--ease), background-color .15s var(--ease);
}
.faq-item summary i::before { inset: 45% 0 45% 0; }                    /* horizontal */
.faq-item summary i::after  { inset: 0 45% 0 45%; }                    /* vertical */
.faq-item[open] summary i::after { transform: scaleY(0); }
.faq-item[open] summary i::before { background: var(--a1); }

.faq-a { padding: 0 1.2rem 1.15rem; }
.faq-a p {
  margin: 0; max-width: 68ch;
  font-size: .91rem; line-height: 1.75; color: var(--ink-2);
}

/* ============================================================================
   HOST DIRECTORY (/hosts)
   There was no browse path: a review was only reachable through a ranking, so
   nothing linked the reviews as a set and a provider-name search had no landing
   page. A-Z on purpose — the rankings already do the ordering.
   ========================================================================== */
.hd-sec { margin-top: 2rem; }
.hd-list { display: grid; gap: .5rem; }

.hd-row {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) 6rem 6.5rem 8rem 9rem auto;
  gap: 1rem; align-items: center;
  padding: .9rem 1.1rem;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: var(--sh-1);
  transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}
.hd-row:hover { border-color: var(--line-2); box-shadow: var(--sh-2); }

.hd-id {
  display: flex; align-items: center; gap: .7rem; min-width: 0;
  text-decoration: none; color: inherit;
}
.hd-id-t { display: grid; gap: .1rem; min-width: 0; }
.hd-id-t b { font: 700 .95rem/1.25 var(--sans); letter-spacing: -.02em; }
.hd-id:hover b { color: var(--a1); }
.hd-id-t em {
  font-style: normal; font-size: .73rem; color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.hd-cell { display: grid; gap: .12rem; min-width: 0; }
.hd-cell b { font: 800 .93rem/1 var(--sans); letter-spacing: -.02em; }
.hd-cell em { font-style: normal; font-size: .7rem; color: var(--ink-3); }
.hd-flat { color: var(--good); }
.hd-up   { color: var(--warn) !important; font-weight: 700; }
.hd-date { font-size: .8rem !important; font-weight: 600 !important; color: var(--ink-2); }
.hd-cta { justify-self: end; }

@media (max-width: 1040px) {
  .hd-row { grid-template-columns: minmax(0, 1fr) 1fr 1fr; gap: .8rem 1rem; }
  .hd-id  { grid-column: 1 / -1; }
  .hd-cta { grid-column: 1 / -1; justify-self: start; }
  /* Without a header row each figure has to name itself. */
  .hd-cell::before {
    content: attr(data-label);
    font: 700 .615rem/1 var(--sans); text-transform: uppercase; letter-spacing: .1em;
    color: var(--ink-3);
  }
  .hd-cell { gap: .28rem; }
}
@media (max-width: 560px) { .hd-row { grid-template-columns: 1fr 1fr; } }

/* ============================================================================
   THEME TOGGLE
   The palette already had a full prefers-color-scheme dark set with no way to
   choose it. data-theme on <html> overrides the media query in both directions.
   ========================================================================== */
.theme-btn {
  display: inline-grid; place-items: center;
  width: 1.75rem; height: 1.75rem; padding: 0;
  background: none; border: 1px solid transparent; border-radius: .4rem;
  color: inherit; cursor: pointer; opacity: .75;
  transition: opacity .15s var(--ease), border-color .15s var(--ease);
}
.theme-btn:hover { opacity: 1; border-color: rgba(255,255,255,.22); }
.theme-btn:focus-visible { outline: 2px solid var(--a1); outline-offset: 1px; }
.theme-btn svg { display: block; }
/* Only the icon for the mode you would switch TO is shown. */
.theme-btn .t-sun  { display: none; }
:root[data-theme="dark"] .theme-btn .t-sun  { display: block; }
:root[data-theme="dark"] .theme-btn .t-moon { display: none; }

/* ============================================================================
   TOOLS HUB (/tools)
   Three tools existed with no page grouping them, and the nav had reached seven
   top-level items. Each card leads with the question the tool answers rather than
   its name, and carries a live figure — a card that only names a thing is a link
   pretending to be a card.
   ========================================================================== */
/* The body flexes so the stat and the link align across a row. */
/* ============================================================================
   ADMIN ADDITIONS
   ========================================================================== */
/* Inline FAQ editor cards sit closer together than a standalone form would. */
.faq-admin { margin-bottom: .75rem; }
.faq-admin label { margin-bottom: .7rem; }

/* Affiliate link table: the URL needs room to be readable, the rest do not. */
.lk-help { margin: 0 0 1.25rem; }
.lk-table td { vertical-align: top; }
.lk-url { min-width: 22rem; font-family: var(--mono); font-size: .8rem; }
.lk-sm  { min-width: 6rem; }

/* ============================================================================
   FINDER RESULTS — rebuilt
   The results were a list of grey ticks: #1 looked identical to #2, a figure like
   $420 was flagged as a drawback with nothing to compare it against, and the
   drawback sat in the same list as the positives so it was the easiest thing to
   skim past. A shortlist should read as a decision.
   ========================================================================== */

/* The trade-off between the three, stated once, up front. */
.fd-verdict {
  margin-bottom: 1.25rem; padding: 1.15rem 1.35rem;
  background: var(--accent-soft); border: 1px solid var(--accent-line);
  border-radius: var(--r);
}
.fd-v-lead {
  margin: 0; font-size: 1.02rem; line-height: 1.55; color: var(--ink);
  letter-spacing: -.015em;
}
.fd-v-lead b { font-weight: 800; }
.fd-v-trade {
  margin: .7rem 0 0; padding-top: .7rem;
  border-top: 1px solid var(--accent-line);
  font-size: .875rem; line-height: 1.65; color: var(--ink-2);
}
.fd-v-k {
  display: inline-block; margin-right: .4rem;
  font: 700 .625rem/1 var(--sans); text-transform: uppercase; letter-spacing: .09em;
  color: var(--warn);
}

/* The winner has to look like one. */
.fd-res.is-top { padding-top: 1.6rem; }
.fd-badge {
  position: absolute; top: -.7rem; left: 1.35rem;
  font: 700 .625rem/1 var(--sans); text-transform: uppercase; letter-spacing: .08em;
  color: #fff; background: var(--grad);
  padding: .38rem .6rem; border-radius: .3rem;
  box-shadow: var(--sh-glow);
}
.fd-res { position: relative; }

.fd-figs { display: flex; gap: 1.5rem; }
.fd-fig { display: grid; justify-items: end; gap: .1rem; }
.fd-fig b {
  font-family: var(--display); font-weight: 800; font-size: 1.22rem; line-height: 1;
  letter-spacing: -.04em; font-variant-numeric: lining-nums tabular-nums;
}
.fd-fig em { font-style: normal; font-size: .68rem; color: var(--ink-3); white-space: nowrap; }
.fd-res.is-top .fd-fig b { font-size: 1.45rem; }
@media (max-width: 640px) {
  .fd-figs { grid-column: 1 / -1; justify-content: start; }
  .fd-fig { justify-items: start; }
}

/* Match and cost, drawn against the rest of the shortlist. */
.fd-bars { display: grid; gap: .45rem; margin-bottom: 1.1rem; }
.fd-bar {
  display: grid; grid-template-columns: 3.2rem minmax(0, 1fr) auto;
  gap: .7rem; align-items: center;
}
.fd-bar-k {
  font: 700 .62rem/1 var(--sans); text-transform: uppercase; letter-spacing: .09em;
  color: var(--ink-3);
}
.fd-track {
  height: .45rem; border-radius: 999px; background: var(--surface-3); overflow: hidden;
}
.fd-track i { display: block; height: 100%; width: var(--w); border-radius: 999px; }
.fd-track i.is-match { background: var(--grad-bright); }
.fd-track i.is-cheap { background: var(--good); }
.fd-track i.is-cost  { background: var(--warn); }
.fd-bar-v {
  font: 700 .74rem/1 var(--sans); color: var(--ink-2);
  font-variant-numeric: lining-nums tabular-nums; white-space: nowrap;
}

/* Reasons and cost, separated — so the drawback cannot be skimmed past. */
.fd-reasons {
  display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: 1rem 1.5rem; margin-bottom: 1.1rem;
}
@media (max-width: 720px) { .fd-reasons { grid-template-columns: 1fr; gap: .9rem; } }
.fd-col-k {
  display: block; margin-bottom: .5rem;
  font: 700 .62rem/1 var(--sans); text-transform: uppercase; letter-spacing: .09em;
  color: var(--ink-3);
}
.fd-col-bad {
  padding-left: 1rem; border-left: 2px solid color-mix(in srgb, var(--warn) 45%, transparent);
}
@media (max-width: 720px) {
  .fd-col-bad { padding-left: 0; border-left: 0; padding-top: .8rem; border-top: 1px solid var(--line); }
}
.fd-col-bad .fd-col-k { color: var(--warn); }

/* ==========================================================================
   Tracked-but-not-reviewed host page (views/brand-listed.php)
   Deliberately quieter than a review: no score ring, no verdict box, no CTA
   gradient. The restraint is the point — this page must not look like a
   recommendation, because it is not one.
   ========================================================================== */
.lb-head { padding: 2.5rem 0 0; }
.lb-id { align-items: center; margin: 1.25rem 0 1.5rem; }
.lb-h1 { margin: 0; font-size: clamp(1.8rem, 1.35rem + 1.6vw, 2.6rem); letter-spacing: -.03em; }
.lb-sub { margin: .35rem 0 0; }

.lb-notice {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .35rem 1rem;
  align-items: start; padding: 1.1rem 1.25rem;
  background: var(--surface-2); border: 1px solid var(--line);
  border-left: 3px solid var(--ink-3); border-radius: var(--r);
}
.lb-notice-k {
  font: 700 .68rem/1 var(--sans); letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-2); padding: .32rem .6rem; background: var(--surface-3);
  border-radius: 999px; white-space: nowrap;
}
.lb-notice p { margin: 0; font-size: .95rem; color: var(--ink-2); }
.lb-notice a { color: var(--accent); font-weight: 600; }

.lb-body { padding: 2.5rem 0 4rem; }
.lb-grid { display: grid; grid-template-columns: minmax(0, 1fr) 20rem; gap: 3rem; align-items: start; }
.lb-h2 { font-size: 1.35rem; letter-spacing: -.02em; margin: 2.5rem 0 1rem; }
.lb-main > .lb-h2:first-child { margin-top: 0; }

.lb-cost { display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.lb-fig { padding: 1.1rem 1.2rem; background: var(--surface); }
.lb-fig-k { display: block; font: 600 .7rem/1 var(--sans); letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-3); margin-bottom: .5rem; }
.lb-fig b { display: block; font: 700 1.7rem/1 var(--display); letter-spacing: -.03em; }
.lb-fig em { display: block; margin-top: .25rem; font-size: .82rem; font-style: normal; color: var(--ink-3); }
.lb-fig.is-up b { color: var(--warn); }
.lb-fig.is-up em { color: var(--warn); font-weight: 600; }

.lb-gap { margin: 1rem 0 0; padding: .9rem 1.1rem; font-size: .93rem; color: var(--ink-2);
  background: var(--warn-soft); border-radius: var(--r-sm); }

.lb-table { width: 100%; border-collapse: collapse; font-size: .93rem; }
.lb-table th, .lb-table td { padding: .75rem .9rem; text-align: left; border-bottom: 1px solid var(--line); }
.lb-table thead th { font: 600 .72rem/1 var(--sans); letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-3); white-space: nowrap; }
.lb-table tbody th { font-weight: 650; }

.lb-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 1px;
  margin: 0; background: var(--line); border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; }
.lb-facts > div { padding: .9rem 1.1rem; background: var(--surface); }
.lb-facts dt { font: 600 .7rem/1 var(--sans); letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-3); margin-bottom: .35rem; }
.lb-facts dd { margin: 0; font-weight: 600; }

.lb-src { margin: 2rem 0 0; font-size: .85rem; color: var(--ink-3); }

.lb-aside { position: sticky; top: 6.5rem; }
.lb-card { padding: 1.35rem; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface-2); }
.lb-card-k { display: block; font: 700 .72rem/1 var(--sans); letter-spacing: .08em;
  text-transform: uppercase; color: var(--ink-2); }
.lb-card .muted { margin: .5rem 0 1rem; }
.lb-alts { list-style: none; margin: 0 0 1.1rem; padding: 0; display: grid; gap: .5rem; }
.lb-alts a { display: flex; align-items: center; gap: .7rem; padding: .6rem .7rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-sm); }
.lb-alts a:hover { border-color: var(--accent-line); }
.lb-alts b { display: block; font-size: .93rem; }
.lb-alts em { font-style: normal; font-size: .8rem; color: var(--ink-3); }

@media (max-width: 1000px) {
  .lb-grid { grid-template-columns: minmax(0, 1fr); gap: 2.5rem; }
  .lb-aside { position: static; }
}
@media (max-width: 560px) {
  .lb-notice { grid-template-columns: minmax(0, 1fr); }
}

/* --------------------------------- directory: the tracked-but-unreviewed block */
.hd-listed { margin-top: 3.5rem; }
.hd-listed-note { max-width: 46rem; margin: -.35rem 0 1.5rem; font-size: .95rem; color: var(--ink-2); }
.hd-row.is-listed { background: var(--surface-2); }
.hd-row.is-listed .hd-id b { font-weight: 650; }
.hd-tag {
  display: inline-block; font: 700 .66rem/1 var(--sans) !important; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-2); padding: .3rem .55rem;
  background: var(--surface-3); border-radius: 999px; white-space: nowrap;
}

/* --------------------------------------------------------------- about page */
/* ab- prefix: nothing else in this file uses it. Three class collisions earlier in
   the project all came from reusing a prefix that already meant something. */
.ab-hero { padding: 3.5rem 0 1.5rem; }
.ab-hero h1 { margin: .4rem 0 .8rem; }

.ab-body { padding-bottom: 4rem; }
.ab-block { padding: 2rem 0; border-top: 1px solid var(--line); }
.ab-block:first-child { border-top: 0; padding-top: .5rem; }
.ab-block h2 { font-size: 1.35rem; margin: 0 0 .9rem; scroll-margin-top: 6rem; }
.ab-block p { margin: 0 0 .9rem; }
.ab-block p:last-child { margin-bottom: 0; }

/* Tier definitions. The count sits in the term, so the difference between what is
   reviewed and what is merely tracked is legible at a glance. */
.ab-tiers { margin: 1.2rem 0; display: grid; gap: 1rem; }
.ab-tiers dt {
  display: flex; align-items: center; gap: .5rem;
  font: 800 1rem/1.2 var(--sans); letter-spacing: -.01em;
}
.ab-count {
  font: 700 .72rem/1 var(--sans);
  color: var(--accent); background: var(--accent-soft);
  padding: .26rem .46rem; border-radius: .3rem;
  font-variant-numeric: tabular-nums;
}
.ab-tiers dd {
  margin: .3rem 0 0; padding-left: .9rem;
  border-left: 2px solid var(--line);
  color: var(--ink-2); font-size: .95rem;
}

.ab-nots { margin: 0; padding-left: 1.1rem; display: grid; gap: .6rem; }
.ab-nots li { color: var(--ink-2); }
.ab-nots strong { color: var(--ink); }

.ab-person { display: flex; gap: 1.1rem; align-items: flex-start; flex-wrap: wrap; }
.ab-photo { border-radius: 50%; object-fit: cover; flex: 0 0 auto; }
.ab-person-text { flex: 1 1 18rem; min-width: 0; }
.ab-name { display: block; font: 800 1.05rem/1.3 var(--sans); }
.ab-role { display: block; font-size: .84rem; color: var(--ink-3); margin-bottom: .6rem; }
.ab-profiles { display: flex; gap: .8rem; flex-wrap: wrap; font-size: .84rem; }

.ab-foot {
  margin: 2rem 0 0; padding: 1rem 1.1rem;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: .6rem;
  font-size: .9rem; color: var(--ink-2);
}

@media (max-width: 640px) {
  .ab-hero { padding-top: 2.2rem; }
  .ab-block { padding: 1.5rem 0; }
}

/* ------------------------------------------------------ callout (prose notes) */
/* Added with the Hosting.com ownership note. It was written with these classes
   before they existed — the same mistake as .wrap-narrow earlier in this project,
   where five pages rendered at full width because the class was never defined.
   Lives inside .prose, so it has to survive the prose typography around it. */
.prose .callout,
.callout {
  margin: 1.6rem 0;
  padding: 1rem 1.15rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--ink-3);
  border-radius: .5rem;
  background: var(--surface-2);
  font-size: .95rem;
}
.callout > :first-child { margin-top: 0; }
.callout > :last-child  { margin-bottom: 0; }
.callout p { margin: 0 0 .7rem; }
.callout strong { color: var(--ink); }

/* A change of ownership is a caveat about the review, not decoration. */
.callout-warn {
  border-left-color: var(--warn);
  background: var(--warn-soft);
}

/* ------------------------------------------------------------------ sr-only */
/* Was referenced by a table caption before it existed, which would have rendered
   the caption as visible body text. Clip rather than display:none, so screen
   readers still announce it. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ------------------------------------------------- VPS compared (/vps-hosting) */
/* vps- prefix, not vp-: .vp-head and .vp-note already belong to the comparison
   brand cards. Reusing that prefix is what caused three separate collisions
   earlier in this project. */
.vps-head { padding: 3.5rem 0 1.5rem; }
.vps-head h1 { margin: .4rem 0 .8rem; }
.vps-head .callout { margin-top: 1.6rem; }

.vps-table-wrap { padding-bottom: 1rem; }
.vps-table { width: 100%; }
.vps-table th { white-space: nowrap; }
.vps-table td { vertical-align: middle; }

.vps-host { display: flex; align-items: center; gap: .55rem; white-space: nowrap; }
.vps-host a { font-weight: 700; }

.vps-term { display: block; font-size: .74rem; color: var(--ink-3); font-style: normal; }

/* The renewal jump is the point of the whole site, so it is not subtle. */
.vps-jump {
  font: 700 .72rem/1 var(--sans); font-style: normal;
  color: var(--warn); background: var(--warn-soft);
  padding: .2rem .34rem; border-radius: .26rem; margin-left: .3rem;
  white-space: nowrap;
}

/* A missing figure reads as missing, not as zero or as cheap. */
.vps-unknown { font-size: .82rem; color: var(--ink-3); font-style: italic; }

.vps-note {
  max-width: 52rem; margin: 1.2rem 0 0;
  font-size: .86rem; color: var(--ink-2);
}

.vps-sources { padding: 2.5rem 0 4rem; }
.vps-sources h2 { font-size: 1.15rem; margin: 0 0 1rem; }
.vps-src-list { list-style: none; margin: 0 0 1.5rem; padding: 0; display: grid; gap: .7rem; }
.vps-src-list li {
  display: grid; gap: .15rem;
  padding-bottom: .7rem; border-bottom: 1px solid var(--line);
  font-size: .88rem;
}
.vps-src-list strong { font-size: .92rem; }
.vps-src-list span { color: var(--ink-2); overflow-wrap: anywhere; }
.vps-foot { font-size: .9rem; color: var(--ink-2); }

@media (max-width: 640px) {
  .vps-head { padding-top: 2.2rem; }
}

/* ------------------------------------------------------------ admin analytics */
.an-lead { max-width: 60rem; color: var(--ink-2); font-size: .92rem; margin: 0 0 1.2rem; }

.an-ranges { display: flex; gap: .4rem; flex-wrap: wrap; margin-bottom: 1.6rem; }
.an-range {
  font: 600 .8rem/1 var(--sans); padding: .45rem .7rem;
  border: 1px solid var(--line); border-radius: .4rem;
  color: var(--ink-2); background: var(--surface);
}
.an-range.on { color: #fff; background: var(--accent); border-color: var(--accent); }

/* The state this page is in today, so it reads as "nothing to show yet" rather
   than as a broken dashboard full of zeros and blank percentages. */
.an-empty {
  padding: 1.6rem; border: 1px dashed var(--line); border-radius: .7rem;
  background: var(--surface-2); max-width: 44rem;
}
.an-empty h2 { margin: 0 0 .8rem; font-size: 1.1rem; }
.an-empty p { margin: 0 0 .9rem; color: var(--ink-2); font-size: .93rem; }
.an-empty-note { font-size: .86rem !important; }

.an-tiles {
  display: grid; gap: .8rem; margin-bottom: 2rem;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
}
.an-tile {
  padding: .9rem 1rem; border: 1px solid var(--line);
  border-radius: .6rem; background: var(--surface-2);
}
.an-tile b { display: block; font-size: 1.5rem; font-variant-numeric: tabular-nums; line-height: 1.1; }
.an-tile span { display: block; font-size: .78rem; color: var(--ink-3); margin-top: .15rem; }
.an-tile em { display: block; font-size: .74rem; color: var(--ink-3); font-style: normal; margin-top: .35rem; }
.an-tile.is-money b { color: var(--good); }

.an-h { font-size: 1.05rem; margin: 2rem 0 .8rem; }

/* One bar per day, no charting library — this is a single number per day and a
   library would be the fourth-largest asset on the site. */
.an-spark {
  display: flex; align-items: flex-end; gap: 2px;
  height: 5rem; padding: .5rem; margin-bottom: .5rem;
  border: 1px solid var(--line); border-radius: .5rem; background: var(--surface-2);
}
.an-spark i {
  flex: 1 1 0; min-width: 2px;
  height: var(--h, 0%); min-height: 2px;
  background: var(--accent); border-radius: 1px 1px 0 0;
}

.an-table td, .an-table th { vertical-align: middle; }
/* A long URL must not stretch the table past the viewport. */
.an-page { max-width: 22rem; }
.an-page a { overflow-wrap: anywhere; }

.an-devices { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; max-width: 30rem; }
.an-devices li { display: grid; grid-template-columns: 7rem 1fr auto; gap: .6rem; align-items: center; font-size: .84rem; }
.an-dev-k { color: var(--ink-2); text-transform: capitalize; }
.an-dev-bar { height: .5rem; background: var(--surface-3); border-radius: .25rem; overflow: hidden; }
.an-dev-bar i { display: block; height: 100%; width: var(--w, 0%); background: var(--accent); }
.an-dev-v { font-variant-numeric: tabular-nums; color: var(--ink-2); }

.an-foot {
  margin-top: 2.5rem; padding: .9rem 1rem;
  border-left: 3px solid var(--line); background: var(--surface-2);
  font-size: .86rem; color: var(--ink-2);
}

/* ------------------------------------------------- review page: at a glance */
/* Replaces .glance, which was a flat 3-column text grid. ag- prefix because g-*
   is still used by the compare page; renaming those is a separate job. */
.ataglance {
  display: grid; gap: 1rem; margin-top: 2rem;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
}

/* The money panel. Tinted from the brand colour rather than a fixed accent, so a
   review page carries some of the host's identity without being coloured by it. */
.ag-money {
  position: relative; overflow: hidden;
  padding: 1.25rem 1.35rem;
  border: 1px solid var(--line); border-radius: .8rem;
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--bc) 6%, transparent),
      transparent 60%),
    var(--surface-2);
}
/* A hairline of the brand colour down the left edge — enough to tie the panel to the
   logo above it, not enough to compete with the price. */
.ag-money::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 3px;
  background: var(--bc);
}
.ag-money.is-holds::before { background: var(--good); }
.ag-money.is-steep::before { background: var(--warn); }

.ag-k {
  display: block;
  font: 650 .68rem/1 var(--sans); text-transform: uppercase; letter-spacing: .11em;
  color: var(--ink-3); margin-bottom: .85rem;
}

/* now -> later, as one movement rather than two unrelated figures. */
.ag-flow { display: flex; align-items: baseline; gap: .9rem; flex-wrap: wrap; }
.ag-step { display: grid; }
.ag-step b {
  font: 800 2.1rem/1 var(--display); letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
}
.ag-step em {
  font: 500 .72rem/1.3 var(--sans); font-style: normal;
  color: var(--ink-3); margin-top: .3rem;
}
/* CSS arrow rather than a glyph: an em dash and an arrow character sit on different
   baselines in the display face and the row looked misaligned. */
.ag-arrow {
  position: relative; width: 1.6rem; height: 2px;
  background: var(--line); align-self: center; flex: 0 0 auto;
}
.ag-arrow::after {
  content: ""; position: absolute; right: -1px; top: -3px;
  border-left: 6px solid var(--line);
  border-top: 4px solid transparent; border-bottom: 4px solid transparent;
}
.ag-money.is-holds .ag-then b { color: var(--good); }
.ag-money.is-steep .ag-then b { color: var(--warn); }

.ag-verdict {
  display: inline-block; margin-top: 1rem;
  font: 700 .74rem/1 var(--sans);
  padding: .4rem .6rem; border-radius: .35rem;
}
.ag-verdict.is-ok      { color: var(--good); background: var(--good-soft); }
.ag-verdict.is-warn    { color: var(--warn); background: var(--warn-soft); }
.ag-verdict.is-unknown { color: var(--ink-3); background: var(--surface-3); }

.ag-total {
  margin: 1rem 0 0; padding-top: .9rem;
  border-top: 1px solid var(--line);
  font-size: .88rem; color: var(--ink-2);
}
.ag-total b { font-size: 1.05rem; color: var(--ink); font-variant-numeric: tabular-nums; }
.ag-total em { display: block; font-style: normal; font-size: .76rem; color: var(--ink-3); margin-top: .2rem; }

/* The three facts that decide a purchase. Everything else lives in Specifications —
   repeating it here is what forced the old filler cell. */
.ag-facts {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: .55rem; align-content: start;
}
.ag-facts li {
  display: grid; grid-template-columns: 1.15rem 1fr auto; gap: .6rem;
  align-items: center;
  padding: .7rem .9rem;
  border: 1px solid var(--line); border-radius: .55rem;
  background: var(--surface-2);
  font-size: .86rem;
}
.ag-facts svg { color: var(--ink-3); }
.ag-fk { color: var(--ink-2); }
.ag-fv { font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.ag-fv em { display: block; font: 500 .7rem/1.2 var(--sans); font-style: normal; color: var(--ink-3); }
/* An absent figure reads as absent, not as a value. */
.ag-fv.is-none { font-weight: 500; font-size: .8rem; color: var(--ink-3); font-style: italic; }

@media (max-width: 900px) {
  .ataglance { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 480px) {
  .ag-step b { font-size: 1.75rem; }
  .ag-facts li { grid-template-columns: 1.15rem 1fr; }
  .ag-fv { text-align: left; grid-column: 2; }
}

/* ------------------------------------------------------------------- search */
/* Header field. Sized to sit in the nav row without pushing the CTA off, and it
   becomes full-width inside the mobile panel where there is room. */
.nav-search { display: flex; align-items: center; gap: .3rem; }
.nav-search input {
  font: 500 .84rem var(--sans);
  width: 8.5rem; padding: .42rem .6rem;
  border: 1px solid var(--line); border-radius: .4rem;
  background: var(--surface-2); color: var(--ink);
  transition: width .18s ease, background .18s ease;
}
.nav-search input::placeholder { color: var(--ink-3); }
.nav-search input:focus { width: 11rem; background: var(--surface); outline: 2px solid var(--accent); outline-offset: 1px; }
/* Clear the browser's own X in WebKit — it collides with our submit button. */
.nav-search input::-webkit-search-cancel-button { display: none; }
.nav-search button {
  display: grid; place-items: center;
  width: 2rem; height: 2rem; padding: 0;
  border: 1px solid var(--line); border-radius: .4rem;
  background: var(--surface-2); color: var(--ink-2); cursor: pointer;
}
.nav-search button:hover { color: var(--ink); background: var(--surface-3); }

.se-head { padding: 3rem 0 0; }
.se-head h1 { margin: .3rem 0 1.2rem; font-size: 1.9rem; }

.se-form { display: flex; gap: .5rem; margin-bottom: .9rem; }
.se-form input {
  flex: 1 1 auto; min-width: 0;
  font: 500 1rem var(--sans); padding: .7rem .9rem;
  border: 1px solid var(--line); border-radius: .5rem;
  background: var(--surface); color: var(--ink);
}
.se-count { font-size: .86rem; color: var(--ink-3); margin: 0; }

.se-body { padding: 1.5rem 0 4rem; }

.se-empty {
  padding: 1.4rem; border: 1px dashed var(--line); border-radius: .7rem;
  background: var(--surface-2); color: var(--ink-2); font-size: .93rem;
}
.se-empty p { margin: 0 0 .8rem; }
.se-empty p:last-child { margin-bottom: 0; }
.se-jump { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .5rem .9rem; }

.se-h {
  display: flex; align-items: center; gap: .5rem;
  font-size: 1.05rem; margin: 2rem 0 .7rem;
}
.se-h span {
  font: 700 .7rem/1 var(--sans); color: var(--ink-3);
  background: var(--surface-3); padding: .22rem .4rem; border-radius: .28rem;
}

.se-list { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.se-item {
  display: flex; align-items: center; gap: .75rem;
  padding: .8rem .95rem;
  border: 1px solid var(--line); border-radius: .6rem;
  background: var(--surface-2); color: inherit; text-decoration: none;
}
.se-item:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); background: var(--surface); }
.se-txt { display: grid; gap: .15rem; flex: 1 1 auto; min-width: 0; }
.se-txt strong { font-size: .96rem; }
.se-sub { font-size: .82rem; color: var(--ink-3); }
.se-tag {
  font: 600 .65rem/1 var(--sans); font-style: normal;
  color: var(--ink-3); background: var(--surface-3);
  padding: .2rem .34rem; border-radius: .25rem; margin-left: .35rem;
  vertical-align: middle;
}
.se-price { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.se-price em { display: block; font: 500 .68rem/1.2 var(--sans); font-style: normal; color: var(--ink-3); }

@media (max-width: 900px) {
  /* In the mobile panel the field has the whole width, so let it use it. */
  .nav-search { width: 100%; }
  .nav-search input { flex: 1 1 auto; width: auto; }
  .nav-search input:focus { width: auto; }
}

/* ------------------------------------------------------- currency switcher */
.cur-form { display: inline-flex; align-items: center; gap: .3rem; }
.cur-form select {
  font: 600 .72rem var(--sans);
  padding: .18rem 1.1rem .18rem .35rem;
  border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
  border-radius: .3rem;
  background: transparent; color: inherit; cursor: pointer;
  /* The utility bar is dark; a native select would render its own light chrome. */
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right .42rem center, right .28rem center;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
}
.cur-form select option { color: #111; background: #fff; }
.cur-form button { font: 600 .7rem var(--sans); padding: .15rem .4rem; cursor: pointer; }

/* Stated once at the top rather than beside every figure: a converted price a reader
   cannot check against a rate is exactly the kind of unsourced number this site exists
   to complain about. */
.cur-note {
  background: var(--accent-soft);
  border-bottom: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  font-size: .8rem; color: var(--ink-2);
  padding: .5rem 0;
}
.cur-note strong { color: var(--ink); font-variant-numeric: tabular-nums; }

@media (max-width: 700px) {
  .cur-note { font-size: .74rem; }
}

/* ----------------------------------------------------------------- glossary */
.gl-head { padding: 3.5rem 0 1.5rem; }
.gl-head h1 { margin: .4rem 0 .8rem; }

.gl-jump { display: flex; flex-wrap: wrap; gap: .45rem; margin-top: 1.6rem; }
.gl-jump a {
  display: inline-flex; align-items: center; gap: .35rem;
  font: 600 .78rem/1 var(--sans); text-decoration: none;
  padding: .45rem .65rem;
  border: 1px solid var(--line); border-radius: .4rem;
  color: var(--ink-2); background: var(--surface-2);
}
.gl-jump a:hover { color: var(--ink); border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }
.gl-jump em { font-style: normal; color: var(--ink-3); font-size: .7rem; }

.gl-body { padding-bottom: 4rem; }
.gl-h {
  font-size: 1.2rem; margin: 2.5rem 0 1rem;
  padding-bottom: .5rem; border-bottom: 1px solid var(--line);
  scroll-margin-top: 6rem;
}
.gl-list { margin: 0; }
.gl-item { padding: 1.1rem 0; border-bottom: 1px solid var(--line); scroll-margin-top: 6rem; }
.gl-item:last-child { border-bottom: 0; }
.gl-item dt {
  font: 800 1.02rem/1.3 var(--display); letter-spacing: -.015em;
  margin-bottom: .35rem;
}
.gl-item dd { margin: 0; }
/* The plain meaning reads as the answer; the caveat reads as the interesting part. */
.gl-short { margin: 0 0 .5rem; font-size: .95rem; }
.gl-more {
  margin: 0; font-size: .89rem; color: var(--ink-2);
  padding-left: .85rem; border-left: 2px solid var(--line);
}
.gl-foot {
  margin: 2.5rem 0 0; padding: .9rem 1.1rem;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: .6rem;
  font-size: .89rem; color: var(--ink-2);
}

/* ------------------------------------------------- host directory (/hosts) */
/* Sort bar. Sticky under the header, because at 27 rows heading for 100 the controls
   have to stay reachable once you are inside the list. */
.hd-bar {
  position: sticky; top: 4.4rem; z-index: 20;
  display: flex; align-items: center; gap: .8rem; flex-wrap: wrap;
  padding: .7rem .9rem; margin-bottom: 1rem;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: blur(8px);
  border: 1px solid var(--line); border-radius: .6rem;
  scroll-margin-top: 5rem;
}
.hd-bar-k {
  font: 650 .66rem/1 var(--sans); text-transform: uppercase; letter-spacing: .1em;
  color: var(--ink-3);
}
.hd-sorts { display: flex; gap: .35rem; flex-wrap: wrap; flex: 1 1 auto; }
.hd-sort {
  font: 600 .78rem/1 var(--sans); text-decoration: none;
  padding: .4rem .6rem; border-radius: .35rem;
  color: var(--ink-2); border: 1px solid transparent;
}
.hd-sort:hover { color: var(--ink); background: var(--surface-2); }
.hd-sort.on { color: #fff; background: var(--accent); }
.hd-bar-n { font-size: .74rem; color: var(--ink-3); white-space: nowrap; }

/* Letter dividers, alphabetical order only. */
.hd-letter {
  font: 800 .8rem/1 var(--display); letter-spacing: .04em;
  color: var(--ink-3);
  padding: 1rem .2rem .3rem;
  scroll-margin-top: 7rem;
}
.hd-letter:first-child { padding-top: .2rem; }

/* The renewal multiple, drawn rather than described. */
.hd-renew .hd-jump { display: flex; align-items: center; gap: .4rem; margin-top: .25rem; }
.hd-jump-bar {
  flex: 1 1 auto; min-width: 2rem; max-width: 4.5rem;
  height: .3rem; border-radius: .15rem;
  background: var(--surface-3); overflow: hidden;
}
.hd-jump-bar i {
  display: block; height: 100%; width: var(--w, 0%);
  /* Amber into red: the steeper the cliff, the hotter the bar. */
  background: linear-gradient(90deg, #f59e0b, #dc2626);
}
.hd-flat-t { color: var(--good) !important; font-weight: 600; }

@media (max-width: 760px) {
  .hd-bar { position: static; }
  .hd-jump-bar { max-width: none; }
}

/* A-Z jump strip. Missing letters stay in place, disabled, so the row does not
   reflow as hosts are added and an absence is visible rather than invisible. */
.hd-az {
  display: flex; flex-wrap: wrap; gap: .15rem;
  margin: -.3rem 0 1.1rem;
  padding: .5rem .6rem;
  border: 1px solid var(--line); border-radius: .5rem;
  background: var(--surface-2);
}
.hd-az a, .hd-az span {
  display: grid; place-items: center;
  min-width: 1.5rem; padding: .2rem 0;
  font: 700 .74rem/1 var(--sans); text-decoration: none; border-radius: .25rem;
}
.hd-az a { color: var(--ink); }
.hd-az a:hover { background: var(--accent); color: #fff; }
.hd-az span { color: var(--ink-3); opacity: .38; }

.hd-none {
  padding: 1.2rem; border: 1px dashed var(--line); border-radius: .6rem;
  background: var(--surface-2); color: var(--ink-2); font-size: .92rem;
}

/* Postal address blocks on /privacy and /contact. <address> is italic by default in
   every browser, which reads as an aside rather than as the legally required identity
   of the data controller. */
.doc-address, .ct-address {
  font-style: normal;
  margin: .8rem 0 0;
  padding: .8rem 1rem;
  border-left: 3px solid var(--line);
  background: var(--surface-2);
  font-size: .9rem;
  line-height: 1.65;
}
.ct-address { margin: 0 0 .6rem; }

/* =================================================== alternatives page ====
   Namespaced altp-* on purpose: .alt-card and .alt-why already exist for the
   brand page's clickable cards, where .alt-why is a <p> with margin:0 and
   .alt-card:hover applies a transform. Reusing them here — an <article> with a
   <ul> inside — stripped the list markers and made a non-clickable card jump. */
.altp-baseline {
  margin: 1.5rem 0 0; padding: 1.1rem 1.25rem;
  border: 1px solid var(--line); border-radius: 12px; background: var(--surface-2);
}
.altp-bl-k {
  display: block; margin-bottom: .7rem;
  font: 700 .715rem/1 var(--sans); letter-spacing: .07em; text-transform: uppercase;
  color: var(--ink-3);
}
.altp-baseline ul {
  list-style: none; margin: 0 0 .8rem; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(115px, 1fr)); gap: .9rem;
}
.altp-baseline li { display: grid; gap: .15rem; }
.altp-baseline b { font: 700 1.15rem/1.2 var(--sans); color: var(--ink); }
.altp-baseline span { font-size: .755rem; color: var(--ink-3); }
.altp-baseline p { margin: 0; }

.altp-list { display: grid; gap: .8rem; margin-top: 1.1rem; }
.altp-card {
  display: grid; grid-template-columns: auto 1fr; gap: 1rem;
  padding: 1.1rem 1.25rem; border: 1px solid var(--line);
  border-radius: 12px; background: var(--surface);
}
.altp-rank {
  width: 30px; height: 30px; display: grid; place-items: center;
  border-radius: 50%; background: var(--surface-2); border: 1px solid var(--line);
  font: 700 .85rem/1 var(--sans); color: var(--ink-2);
}
.altp-body h3 { margin: 0 0 .5rem; font-size: 1.02rem; }
.altp-body h3 a { display: inline-flex; align-items: center; gap: .45rem; }
.altp-why { margin: 0 0 .7rem; padding-left: 1.1rem; display: grid; gap: .22rem; }
.altp-why li { font-size: .87rem; line-height: 1.5; color: var(--ink-2); }
.altp-figs {
  display: flex; flex-wrap: wrap; gap: .2rem 1.1rem; margin: 0;
  font-size: .8rem; color: var(--ink-3);
}
.altp-figs dt { font-weight: 650; }
.altp-figs dt::after { content: ':'; }
.altp-figs dd { margin: 0 .5rem 0 0; color: var(--ink-2); }

@media (max-width: 560px) {
  .altp-card { grid-template-columns: 1fr; gap: .6rem; }
}

/* ============================================================ deals page ====
   Ranked-by-real-cost page. Two devices carry the argument visually:
     .dl-slope    a slope chart: two rankings of the same hosts, joined by crossing lines
     .dl-cost     one row per host, its bar split into intro-rate and renewal-rate spend
   The cliff bar (.hd-jump-bar) is reused from /hosts rather than restyled, so a
   4.8x reads identically wherever a visitor meets it. */

.dl-hero {
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(80rem 26rem at 12% -18%, color-mix(in srgb, var(--a1) 12%, transparent), transparent 70%),
    var(--surface-2);
}
.dl-hero-in { padding: 1.4rem 0 2.5rem; }
.dl-h1 {
  margin: .5rem 0 .7rem;
  font-size: clamp(1.9rem, 4.6vw, 3.1rem); line-height: 1.06; letter-spacing: -.02em;
}
.dl-lead { max-width: 62ch; margin: 0 0 1.6rem; font-size: 1.03rem; line-height: 1.65; color: var(--ink-2); }

.dl-stats {
  list-style: none; margin: 0 0 1.4rem; padding: 0;
  /* Fixed 2 then 4 columns rather than auto-fit. With four items, auto-fit settled on three
     at tablet widths and left the fourth cell empty — and because the 1px "gap" is really the
     container's border colour showing through, that empty cell rendered as a grey block.
     Four items divide cleanly into 2x2 or 1x4, so neither layout can leave a hole. */
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
}
@media (min-width: 780px) {
  .dl-stats { grid-template-columns: repeat(4, 1fr); }
}
.dl-stats li { padding: 1rem 1.1rem; background: var(--surface); display: grid; gap: .25rem; }
.dl-stats b { font: 800 1.5rem/1.05 var(--sans); letter-spacing: -.02em; color: var(--ink); }
.dl-stats span { font-size: .765rem; line-height: 1.4; color: var(--ink-3); }
.dl-note { max-width: 68ch; margin: 0; font-size: .845rem; line-height: 1.6; color: var(--ink-3); }

.dl-sec { margin-top: 3rem; }
.dl-sec h2 { margin-bottom: .5rem; }
.dl-sub { max-width: 66ch; margin: 0 0 1.2rem; color: var(--ink-2); line-height: 1.65; }

/* ---------------------------------------------------------------- podium */
.dl-podium { display: grid; grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); gap: .9rem; }
.dl-pod {
  position: relative; padding: 1.3rem 1.25rem 1.15rem;
  border: 1px solid var(--line); border-radius: 14px; background: var(--surface);
}
.dl-pod.is-first {
  border-color: color-mix(in srgb, var(--a1) 45%, var(--line));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--a1) 22%, transparent), var(--sh-2);
}
.dl-pod-rank {
  position: absolute; top: -.7rem; left: 1.15rem;
  width: 1.65rem; height: 1.65rem; display: grid; place-items: center;
  border-radius: 50%; background: var(--ink); color: var(--surface);
  font: 800 .8rem/1 var(--sans);
}
.dl-pod.is-first .dl-pod-rank { background: var(--a1); color: #fff; }
.dl-pod h3 { margin: .45rem 0 .7rem; font-size: 1.02rem; }
.dl-pod h3 a { display: inline-flex; align-items: center; gap: .45rem; }
.dl-pod-total { margin: 0; font: 800 1.85rem/1 var(--sans); letter-spacing: -.025em; color: var(--ink); }
.dl-pod-sub { margin: .2rem 0 .9rem; font-size: .755rem; color: var(--ink-3); }
.dl-pod-figs {
  display: grid; grid-template-columns: auto 1fr; gap: .22rem .6rem; margin: 0 0 .8rem;
  font-size: .815rem;
}
.dl-pod-figs dt { color: var(--ink-3); }
.dl-pod-figs dd { margin: 0; color: var(--ink-2); font-weight: 600; }
.dl-pod-flag {
  margin: 0; padding-top: .7rem; border-top: 1px solid var(--line);
  font: 600 .775rem/1.4 var(--sans); color: var(--ink-3);
}
.dl-pod-flag.is-holds { color: var(--good); }

/* ------------------------------------------------- the rank flip (centrepiece) */
/* ---------------------------------------------------------------- table */
.dl-host { display: inline-flex; align-items: center; gap: .45rem; font-weight: 650; }
.dl-flat-t { color: var(--good); font-weight: 650; font-size: .82rem; }
/* ---------------------------------------------------------------- flat cards */
.dl-flat { display: grid; grid-template-columns: repeat(auto-fit, minmax(185px, 1fr)); gap: .8rem; }
.dl-flat-card {
  display: grid; gap: .35rem; padding: 1.1rem 1.15rem;
  border: 1px solid color-mix(in srgb, var(--good) 30%, var(--line));
  border-radius: 12px; background: color-mix(in srgb, var(--good) 5%, var(--surface));
  color: inherit;
}
.dl-flat-card:hover { border-color: var(--good); color: inherit; }
.dl-flat-top { display: flex; align-items: center; gap: .45rem; }
.dl-flat-price { font: 800 1.5rem/1 var(--sans); letter-spacing: -.02em; color: var(--ink); }
.dl-flat-price em { font: 600 .8rem/1 var(--sans); font-style: normal; color: var(--ink-3); }
.dl-flat-msg { font-size: .78rem; color: var(--good); font-weight: 600; }

/* ---------------------------------------------------------------- timeline */
.dl-timeline { list-style: none; margin: 0; padding: 0; border-left: 2px solid var(--line); }
.dl-tl-row {
  position: relative; padding: .7rem 0 .7rem 1.2rem;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem 1rem;
}
.dl-tl-row::before {
  content: ""; position: absolute; left: -5px; top: 1.05rem;
  width: 8px; height: 8px; border-radius: 50%; background: var(--ink-3);
}
.dl-tl-row.is-up::before   { background: var(--warn); }
.dl-tl-row.is-down::before { background: var(--good); }
.dl-tl-date { font: 600 .755rem/1 var(--sans); color: var(--ink-3); min-width: 6rem; }
.dl-tl-host a { font-weight: 650; }
.dl-tl-move { display: flex; align-items: baseline; gap: .45rem; font-size: .875rem; }
.dl-tl-move s { color: var(--ink-3); }
.dl-tl-move b { color: var(--ink); }
.dl-tl-move em { font-size: .72rem; font-style: normal; color: var(--ink-3); }
.dl-tl-row.is-up   .dl-tl-move em { color: var(--warn); }
.dl-tl-row.is-down .dl-tl-move em { color: var(--good); }

/* ------------------------------------------------- slope chart (the argument)
   Two rankings joined by lines that cross. Alignment between the SVG and the two
   HTML lists is the only real risk, so both derive from one row height: 10 SVG
   units per row, --dl-row per row in CSS, and preserveAspectRatio="none" lets the
   SVG stretch to whatever the rows actually measure. Nothing is measured in JS. */
.dl-slope {
  --dl-row: 2.5rem;
  border: 1px solid var(--line); border-radius: 14px;
  background: var(--surface); overflow: hidden;
}
.dl-slope-heads {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: .75rem 1.1rem; border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}
.dl-slope-h {
  font: 700 .705rem/1 var(--sans); letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-3);
}
.dl-slope-h-r { text-align: right; }

.dl-slope-body {
  position: relative;
  display: grid; grid-template-columns: minmax(0, 1fr) clamp(2.5rem, 12vw, 8rem) minmax(0, 1fr);
  padding: .5rem 0;
}
.dl-slope-col { list-style: none; margin: 0; padding: 0; }
.dl-slope-col li {
  height: var(--dl-row);
  display: flex; align-items: center; gap: .4rem;
  padding: 0 1.1rem; min-width: 0;
}
.dl-slope-col li a {
  font-weight: 650; font-size: .875rem; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.dl-slope-col li em {
  font: 600 .74rem/1 var(--sans); font-style: normal; color: var(--ink-3); white-space: nowrap;
}
.dl-slope-n {
  flex: 0 0 auto; width: 1.35rem; text-align: center;
  font: 800 .75rem/1 var(--sans); color: var(--ink-3);
}
/* Right column reads inward, so the two lists mirror each other around the lines. */
.dl-slope-right li { flex-direction: row-reverse; }

.dl-slope-col li.is-worse  .dl-slope-n { color: var(--warn); }
.dl-slope-col li.is-better .dl-slope-n { color: var(--good); }

.dl-slope-svg {
  /* Sits in the middle grid cell and spans the full row stack. */
  width: 100%; height: 100%; display: block; overflow: visible;
}
.dl-slope-svg line { stroke-width: 1.5; stroke-linecap: round; opacity: .55; }
.dl-slope-svg line.is-worse  { stroke: var(--warn); opacity: .85; stroke-width: 2; }
.dl-slope-svg line.is-better { stroke: var(--good); opacity: .8; }
.dl-slope-svg line.is-same   { stroke: var(--ink-3); opacity: .3; }

.dl-slope-take {
  margin: 1rem 0 0; padding: .95rem 1.1rem;
  border-left: 3px solid var(--warn); border-radius: 0 10px 10px 0;
  background: color-mix(in srgb, var(--warn) 7%, var(--surface));
  font-size: .9rem; line-height: 1.6; color: var(--ink-2);
}
.dl-slope-take b { color: var(--warn); }

/* --------------------------------------------------------- cost breakdown rows
   Replaces a nine-column table. The bar is the data: segment widths are the real
   cash split between intro-rate months and renewal-rate months, and total width
   is this host against the dearest, so a long bar is genuinely expensive. */
.dl-cost { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.dl-cost-row {
  display: grid; align-items: center; gap: .35rem 1rem;
  grid-template-columns: 1.9rem minmax(9rem, 15rem) minmax(0, 1fr) 6.5rem;
  grid-template-areas: "rank id viz total" ".  meta meta meta";
  padding: .85rem 1.1rem;
  border: 1px solid var(--line); border-radius: 12px; background: var(--surface);
}
.dl-cost-row.is-best {
  border-color: color-mix(in srgb, var(--a1) 40%, var(--line));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--a1) 16%, transparent);
}
.dl-cost-row.is-flat { border-color: color-mix(in srgb, var(--good) 32%, var(--line)); }
.dl-cost-row.is-unknown { background: var(--surface-2); }

.dl-cost-rank { grid-area: rank; font: 800 .9rem/1 var(--sans); color: var(--ink-3); text-align: center; }
.dl-cost-id   { grid-area: id; display: grid; gap: .18rem; min-width: 0; }
.dl-cost-id a { display: inline-flex; align-items: center; gap: .4rem; }
.dl-cost-id strong { font-size: .93rem; }
.dl-cost-terms { font-size: .765rem; line-height: 1.45; color: var(--ink-3); }
.dl-cost-terms abbr { text-decoration: none; border-bottom: 1px dotted var(--ink-3); }
.dl-cost-mult { font-style: normal; font-weight: 700; color: var(--warn); }

.dl-cost-viz { grid-area: viz; display: grid; gap: .3rem; min-width: 0; }
.dl-cost-bar {
  display: flex; width: var(--bar, 100%); min-width: 3px;
  height: .7rem; border-radius: .35rem; overflow: hidden;
  background: var(--surface-3);
}
.dl-cost-seg { display: block; width: var(--seg, 0%); height: 100%; }
.dl-cost-seg.is-intro { background: linear-gradient(90deg, color-mix(in srgb, var(--a1) 55%, transparent), var(--a1)); }
.dl-cost-seg.is-renew { background: linear-gradient(90deg, #f59e0b, #dc2626); }
.dl-cost-split { display: flex; flex-wrap: wrap; gap: .1rem .9rem; font-size: .72rem; }
.dl-cost-split em { font-style: normal; color: var(--ink-3); }
.dl-cost-split em.is-intro { color: var(--a1); font-weight: 600; }
.dl-cost-split em.is-renew { color: var(--warn); font-weight: 600; }
.dl-cost-unknown { font-size: .78rem; line-height: 1.5; color: var(--ink-3); }

.dl-cost-total { grid-area: total; text-align: right; display: grid; gap: .1rem; }
.dl-cost-total b { font: 800 1.15rem/1 var(--sans); letter-spacing: -.02em; color: var(--ink); }
.dl-cost-total span { font-size: .69rem; color: var(--ink-3); }

.dl-cost-meta { grid-area: meta; font-size: .715rem; color: var(--ink-3); }

.dl-cost-key {
  display: flex; flex-wrap: wrap; align-items: center; gap: .35rem 1rem;
  margin-top: 1rem; font-size: .765rem; color: var(--ink-3);
}
.dl-key-swatch { width: .85rem; height: .55rem; border-radius: .275rem; display: inline-block; }
.dl-key-swatch.is-intro { background: var(--a1); }
.dl-key-swatch.is-renew { background: linear-gradient(90deg, #f59e0b, #dc2626); }
.dl-key-note { flex: 1 1 18rem; }

@media (max-width: 860px) {
  .dl-cost-row {
    grid-template-columns: 1.9rem minmax(0, 1fr) auto;
    grid-template-areas: "rank id total" ". viz viz" ". meta meta";
  }
  .dl-cost-total { text-align: right; }
}

@media (max-width: 600px) {
  /* The slope chart's value is the crossing lines; below this width the two lists
     cannot both be legible, so it degrades to the left ranking with the movement
     stated in words rather than shrinking into an unreadable tangle. */
  .dl-slope-body { grid-template-columns: 1fr; }
  .dl-slope-svg, .dl-slope-right { display: none; }
  .dl-slope-h-r { display: none; }
  .dl-slope-col li { height: auto; padding: .55rem 1.1rem; }
  .dl-slope-col li::after {
    content: attr(data-move); margin-left: auto;
    font: 600 .72rem/1 var(--sans); color: var(--ink-3); white-space: nowrap;
  }
  .dl-slope-col li.is-worse::after  { color: var(--warn); }
  .dl-slope-col li.is-better::after { color: var(--good); }
}

/* Flat-price hosts get one green segment, not a two-tone cliff they do not have. */
.dl-cost-seg.is-level { background: linear-gradient(90deg, color-mix(in srgb, var(--good) 55%, transparent), var(--good)); }
.dl-cost-split em.is-level { color: var(--good); font-weight: 600; }

/* ============================================================= tools hub ====
   Hero + intent router + cards + provenance chain. The router is the part that
   earns its space: four cards of equal weight make choosing a reading exercise,
   whereas one line per intent resolves it in a glance. */

.tl-hero {
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(70rem 24rem at 85% -20%, color-mix(in srgb, var(--a1) 11%, transparent), transparent 70%),
    var(--surface-2);
}
.tl-hero-in { padding: 1.4rem 0 2.4rem; }
.tl-h1 {
  margin: .5rem 0 .7rem;
  font-size: clamp(1.8rem, 4.2vw, 2.9rem); line-height: 1.07; letter-spacing: -.02em;
}
.tl-lead { max-width: 60ch; margin: 0 0 1.5rem; font-size: 1.02rem; line-height: 1.65; color: var(--ink-2); }

/* Column count is fixed rather than auto-fit: with four items, auto-fit settled on three at
   tablet widths and left a grey hole where the fourth should have been — the same bug as the
   footer stats strip. Four divides cleanly into 2x2 and 1x4. */
.tl-stats {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-radius: 12px; overflow: hidden;
}
@media (min-width: 820px) { .tl-stats { grid-template-columns: repeat(4, 1fr); } }
.tl-stats li { padding: .95rem 1.05rem; background: var(--surface); display: grid; gap: .22rem; }
.tl-stats b { font: 800 1.4rem/1.05 var(--sans); letter-spacing: -.02em; color: var(--ink); }
.tl-stats span { font-size: .745rem; line-height: 1.4; color: var(--ink-3); }

.tl-sec { margin-top: 2.6rem; }
.tl-router-h { margin-bottom: .9rem; }

/* ---------------------------------------------------------------- router */
.tl-router {
  list-style: none; margin: 0; padding: 0;
  border: 1px solid var(--line); border-radius: 14px; overflow: hidden;
}
.tl-router li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem 1rem;
  padding: .85rem 1.15rem; background: var(--surface);
}
.tl-router li + li { border-top: 1px solid var(--line); }
.tl-router li:hover { background: var(--surface-2); }
.tl-router-if { flex: 1 1 22rem; font-size: .89rem; line-height: 1.55; color: var(--ink-2); }
.tl-router a { font: 650 .89rem/1.4 var(--sans); white-space: nowrap; }

/* ---------------------------------------------------------------- cards */
.tl-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: .9rem;
}
.tl-card {
  display: flex; flex-direction: column; gap: .5rem;
  padding: 1.35rem 1.35rem 1.2rem;
  border: 1px solid var(--line); border-radius: 14px; background: var(--surface);
  color: inherit; transition: transform .25s var(--spring), border-color .25s, box-shadow .25s;
  /* The whole card is one <a>, so the global underline applied to every line of text inside it —
     heading, body copy and the stat label all struck through with a rule. The card reads as a
     link from its shape and its arrow; the underline belongs on the CTA only. */
  text-decoration: none;
}
.tl-card:hover {
  transform: translateY(-3px); border-color: var(--accent-line);
  box-shadow: var(--sh-2); color: inherit;
}
.tl-ico {
  width: 2.2rem; height: 2.2rem; display: grid; place-items: center;
  border-radius: 10px; background: color-mix(in srgb, var(--a1) 12%, transparent);
  color: var(--a1);
}
.tl-q { margin: .35rem 0 0; font-size: 1.02rem; line-height: 1.3; }
.tl-name {
  font: 700 .69rem/1 var(--sans); letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-3);
}
.tl-body { flex: 1; margin: .2rem 0 0; font-size: .865rem; line-height: 1.65; color: var(--ink-2); }
.tl-stat {
  display: flex; align-items: baseline; gap: .45rem;
  margin-top: .3rem; padding-top: .8rem; border-top: 1px solid var(--line);
}
.tl-stat b {
  font: 800 1.15rem/1 var(--sans); letter-spacing: -.02em; color: var(--a1);
  font-variant-numeric: lining-nums tabular-nums;
}
.tl-stat em { font-style: normal; font-size: .755rem; line-height: 1.35; color: var(--ink-3); }
.tl-go { font: 650 .82rem/1 var(--sans); color: var(--a1); }

/* ------------------------------------------------------- provenance chain */
.tl-chain {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: .9rem;
  counter-reset: none;
}
.tl-chain li {
  display: grid; grid-template-columns: auto 1fr; gap: .75rem; align-items: start;
  padding: 1.1rem 1.15rem; border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface-2);
}
.tl-chain-n {
  width: 1.6rem; height: 1.6rem; display: grid; place-items: center;
  border-radius: 50%; background: var(--a1); color: #fff;
  font: 800 .78rem/1 var(--sans);
}
.tl-chain-t { display: grid; gap: .3rem; font-size: .825rem; line-height: 1.6; color: var(--ink-2); }
.tl-chain-t strong { font-size: .885rem; color: var(--ink); }
/* The CTA keeps its underline on hover, so the card still signals where the click goes. */
.tl-card:hover .tl-go { text-decoration: underline; text-underline-offset: 3px; }

/* ==================================================== mobile touch targets ====
   Measured from inside a 390px viewport, not guessed: the currency select rendered
   22px tall, the A-Z jump letters 18px, and the theme, compare and clear buttons
   24-28px. All are fine with a mouse and awkward with a thumb.

   Only standalone CONTROLS are enlarged. Inline links inside prose and table cells
   are deliberately left at text height — a link in the middle of a sentence is
   supposed to match the sentence, and padding them would wreck the line rhythm. */
@media (max-width: 860px) {
  .cur-form select {
    min-height: 2rem; padding: .35rem 1.2rem .35rem .5rem; font-size: .8rem;
  }
  .theme-btn { width: 2.1rem; height: 2.1rem; }

  /* The jump strip is 26 letters across; each needs a real target, and wrapping to
     a third row costs nothing on a page this long. */
  .hd-az { gap: .25rem; padding: .6rem; }
  .hd-az a, .hd-az span { min-width: 1.9rem; padding: .45rem 0; font-size: .8rem; }

  .cmp-toggle { padding: .5rem .7rem; font-size: .76rem; }
  .cmp-clear { min-height: 2rem; padding: .4rem .8rem; }

  /* The two smallest label sizes in the stylesheet, which land near 9px. Everything
     else sits at 10.5-11px uppercase with tracking, which is a deliberate
     typographic choice and reads fine; these two were simply too far down. */
  /* A-Z letters: 18px before this block, 27px after the first pass, now clear of 30. */
  .hd-az a, .hd-az span { padding: .55rem 0; min-width: 2rem; }

  /* Only the two smallest things a reader actually READS are raised. The rest of the
     sub-11px text is micro-labelling — spec ticks, unit suffixes, the two-letter brand
     chip at 8px which is an icon rather than text — and enlarging those would break the
     shapes containing them for no reading benefit. No body copy is affected: Lighthouse
     measures legibility against paragraph text, and every <p> here is 13.8px or more. */
  .hd-tag { font-size: .72rem; }
  .verdict-word { font-size: .72rem; }
}
