/* ==========================================================================
   Agency Software Report - design system
   Direction "Signal": modern product-led publication.
   Warm off-white ground, indigo-to-violet accent, self-hosted type,
   soft-shadowed cards that lift, real vendor screenshots as imagery.

   Kept deliberately cheap for the Lighthouse budget: no framework, no
   animation library, transforms and opacity only, and off-screen article
   sections skip layout entirely.
   ========================================================================== */

/* --- Type -----------------------------------------------------------------
   Both faces are subset to the 186 characters the site renders. Inter carries
   the reading text, Bricolage Grotesque the display type. See
   tools/subset-content-fonts.py.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/fonts/inter-latin.771d413a.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/fonts/bricolage-latin.41f0d369.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* --- Tokens --------------------------------------------------------------- */
:root {
  --ground: #f7f7f5;
  --surface: #ffffff;
  --surface-2: #fcfcfb;
  --ink: #0a0f1c;
  --ink-2: #4a5266;
  /* Muted text is deliberately dark enough to clear 4.5:1 on both the ground and
     white surfaces at the smallest size the design uses. */
  --ink-3: #656c7a;
  --line: #e7e7e3;
  --line-2: #d9d9d4;
  --brand: #4f46e5;
  --brand-2: #7c3aed;
  --brand-tint: #f0effe;
  --mint: #0b7a5a;
  --mint-tint: #e8f5f0;
  --amber: #b45309;
  --amber-tint: #fdf3e6;

  --font-sans: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-display: 'Bricolage Grotesque', 'Inter', system-ui, sans-serif;

  --step--1: 0.8125rem;
  --step-0: 1rem;
  --step-1: 1.0625rem;
  --step-2: 1.25rem;
  --step-3: 1.5rem;
  --step-4: 1.9rem;
  --step-5: 2.4rem;

  --radius: 20px;
  --radius-sm: 12px;
  --radius-pill: 999px;
  --shadow: 0 1px 2px rgba(10, 15, 28, 0.04), 0 12px 32px -14px rgba(10, 15, 28, 0.16);
  --shadow-hi: 0 2px 4px rgba(10, 15, 28, 0.05), 0 26px 52px -18px rgba(79, 70, 229, 0.28);
  --wrap: 1180px;
  /* The reading measure. The article and trust-page body column is set to exactly
     this width, so the measure and the grid track stay in step and the body never
     leaves dead space beside the rail. */
  --measure: 38rem;
  /* Article pages run a wider track than the trust pages. A seven column comparison table
     needs about 900px to sit without a scrollbar, and a 608px track forced one on every
     table wide enough to be useful. */
  --measure-article: 44rem;
}

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

* { margin: 0; }

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

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img,
svg { display: block; max-width: 100%; }

img { height: auto; }

a { color: var(--brand); }

button { font: inherit; }

:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
  border-radius: 4px;
}

.wrap {
  width: min(var(--wrap), 92vw);
  margin-inline: auto;
}

.skip-link {
  position: absolute;
  left: 0.75rem;
  top: -100px;
  z-index: 40;
  background: var(--ink);
  color: #fff;
  padding: 0.7rem 1.1rem;
  border-radius: var(--radius-sm);
  font-weight: 600;
  text-decoration: none;
  transition: top 0.15s ease;
}

.skip-link:focus { top: 0.75rem; }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- Headings ------------------------------------------------------------- */
h1, h2, h3, h4, .display {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.028em;
  line-height: 1.08;
  text-wrap: balance;
  color: var(--ink);
}

h1 { font-size: clamp(2.1rem, 5vw, var(--step-5)); }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-2); }

p { text-wrap: pretty; }

/* --- Header --------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: rgba(247, 247, 245, 0.82);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--line);
}

.header-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1.6rem;
  min-height: 66px;
  padding-block: 0.5rem;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.1rem;
  letter-spacing: -0.035em;
}

.mark { color: var(--brand); flex: none; }

.wordmark-accent { color: var(--brand); }

.site-nav { margin-left: auto; }

.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 0 1.4rem;
  list-style: none;
  padding: 0;
}

.site-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 2.5rem;
  color: var(--ink-2);
  text-decoration: none;
  font-size: 0.875rem;
  font-weight: 600;
  transition: color 0.15s ease;
}

.site-nav a:hover,
.site-nav a[aria-current='page'] { color: var(--brand); }

.header-cta {
  display: inline-flex;
  align-items: center;
  min-height: 2.5rem;
  padding: 0 1.1rem;
  border-radius: var(--radius-pill);
  background: var(--ink);
  color: #fff;
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
}

.header-cta:hover { background: var(--brand); }

/* --- Buttons -------------------------------------------------------------- */
.button {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.75rem;
  padding: 0 1.5rem;
  border-radius: var(--radius-pill);
  background: var(--ink);
  color: #fff;
  font-weight: 600;
  font-size: 0.95rem;
  text-decoration: none;
  transition: background 0.15s ease, transform 0.15s ease;
}

.button:hover { background: var(--brand); transform: translateY(-1px); }

.button-secondary {
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
}

.button-secondary:hover { background: var(--surface); color: var(--brand); border-color: var(--brand); }

/* --- Hero ----------------------------------------------------------------- */
.hero {
  position: relative;
  padding: 4rem 0 3rem;
  overflow: hidden;
}

.hero-mesh {
  position: absolute;
  inset: -40% -10% auto -10%;
  height: 620px;
  pointer-events: none;
  background:
    radial-gradient(520px 320px at 16% 24%, rgba(124, 58, 237, 0.20), transparent 70%),
    radial-gradient(620px 380px at 80% 6%, rgba(79, 70, 229, 0.18), transparent 72%),
    radial-gradient(420px 300px at 54% 62%, rgba(15, 157, 118, 0.12), transparent 70%);
}

.hero-grid {
  position: relative;
  display: grid;
  grid-template-columns: 1.02fr 0.98fr;
  gap: 3.2rem;
  align-items: center;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.34rem 0.85rem;
  border-radius: var(--radius-pill);
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  color: var(--brand);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.hero h1 { margin-top: 1.1rem; }

.hero h1 em {
  font-style: normal;
  background: linear-gradient(100deg, var(--brand), var(--brand-2) 58%, var(--mint));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.hero-lede {
  margin-top: 1.1rem;
  font-size: 1.08rem;
  color: var(--ink-2);
  max-width: 34rem;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  margin-top: 1.7rem;
}

.hero-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 2.2rem;
  margin-top: 2.2rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}

.hero-stats b {
  display: block;
  font-family: var(--font-display);
  font-size: 1.45rem;
  font-weight: 800;
  letter-spacing: -0.03em;
}

.hero-stats span { font-size: 0.78rem; color: var(--ink-3); font-weight: 500; }

/* --- Browser frame -------------------------------------------------------- */
.frame {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 18px;
  box-shadow: var(--shadow-hi);
  overflow: hidden;
}

.frame-bar {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}

.frame-bar i {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--line-2);
  flex: none;
}

.frame-bar span {
  margin-left: 0.6rem;
  padding: 0.2rem 0.6rem;
  border-radius: 6px;
  background: var(--ground);
  color: var(--ink-3);
  font-size: 0.7rem;
}

.frame img { width: 100%; }

/*
 * The verified-price caption is a row under the screenshot, not a card floating over it.
 * It used to be absolutely positioned at `left: -18px; bottom: 26px`, which put it on top of
 * whatever the vendor's page had in that corner: on the Fireflies capture it covered three
 * lines of the feature list, and the point of showing a real screenshot is that the reader
 * can read it.
 */
.frame-chip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin: 0;
  padding: 0.7rem 0.95rem;
  border-top: 1px solid var(--line);
  background: var(--surface-2);
}

.frame-chip b {
  font-family: var(--font-display);
  font-size: 1.15rem;
  letter-spacing: -0.02em;
}

.frame-chip small { display: block; font-size: 0.68rem; color: var(--ink-3); }

.chip-ok { color: var(--mint); font-size: 0.78rem; font-weight: 700; }

/* --- Sections ------------------------------------------------------------- */
.section { padding: 3.2rem 0; }

.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem;
  margin-bottom: 1.5rem;
}

.section-head p { color: var(--ink-3); font-size: 0.88rem; margin-top: 0.35rem; }

.rail-arrows { display: flex; gap: 0.5rem; flex: none; }

.rail-arrows button {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow);
  color: var(--ink-2);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.rail-arrows button:hover { color: var(--brand); border-color: var(--brand); }

/* --- Card rail ------------------------------------------------------------ */
.rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(290px, 1fr);
  gap: 1.2rem;
  overflow-x: auto;
  padding: 0.3rem 0.3rem 1.4rem;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  list-style: none;
  margin: 0;
}

.rail::-webkit-scrollbar { display: none; }

/* --- Cards ---------------------------------------------------------------- */
.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  scroll-snap-align: start;
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.3, 1), box-shadow 0.3s ease;
}

.card:hover { transform: translateY(-5px); box-shadow: var(--shadow-hi); }

.card-thumb {
  position: relative;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: #efefec;
  border-bottom: 1px solid var(--line);
}

.card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  transition: transform 0.5s ease;
}

.card:hover .card-thumb img { transform: scale(1.04); }

.card-badge {
  position: absolute;
  top: 0.75rem;
  left: 0.75rem;
  padding: 0.3rem 0.7rem;
  border-radius: var(--radius-pill);
  background: rgba(10, 15, 28, 0.86);
  color: #fff;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.card-badge.is-value { background: rgba(11, 122, 90, 0.94); }

.card-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: 1.1rem 1.15rem 1.3rem;
}

.card-cat {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--brand);
}

.card-body h3 { font-size: 1.06rem; line-height: 1.28; margin-top: 0.4rem; }

.card-body h3 a { color: inherit; text-decoration: none; }

.card:hover .card-body h3 a { color: var(--brand); }

.card-body p { font-size: 0.87rem; color: var(--ink-2); margin-top: 0.5rem; flex: 1; }

.card-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  margin-top: 0.95rem;
  font-size: 0.76rem;
  color: var(--ink-3);
  font-weight: 500;
}

.card-meta b { color: var(--brand); font-weight: 700; }

/* --- Bento tiles ---------------------------------------------------------- */
.bento {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.2rem;
  list-style: none;
  padding: 0;
}

.tile {
  display: flex;
  flex-direction: column;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.tile:hover { transform: translateY(-4px); box-shadow: var(--shadow-hi); }

.tile.is-wide {
  grid-column: span 2;
  background: linear-gradient(140deg, #0a0f1c, #1b2240);
  border-color: transparent;
  color: #fff;
}

.tile-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brand);
}

.tile.is-wide .tile-label { color: #9c9bf5; }

.tile h3 { font-size: 1.14rem; margin-top: 0.5rem; }

.tile h3 a { color: inherit; text-decoration: none; }

.tile p { font-size: 0.88rem; color: var(--ink-2); margin-top: 0.5rem; }

.tile.is-wide p { color: #b9bfd4; }

.tile-more {
  margin-top: auto;
  padding-top: 0.9rem;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--brand);
}

.tile.is-wide .tile-more { color: #9c9bf5; }

/* --- Price strip ---------------------------------------------------------- */
.price-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.price-cell { padding: 1.2rem 1.15rem; border-right: 1px solid var(--line); }

.price-cell:last-child { border-right: 0; }

.price-cell h3 { font-size: 0.82rem; text-transform: uppercase; letter-spacing: 0.06em; }

.price-cell b {
  display: block;
  margin-top: 0.45rem;
  font-family: var(--font-display);
  font-size: 1.45rem;
  font-weight: 800;
  letter-spacing: -0.03em;
}

.price-cell span { display: block; font-size: 0.74rem; color: var(--ink-3); }

.price-tag {
  display: inline-block;
  margin-top: 0.7rem;
  padding: 0.15rem 0.5rem;
  border-radius: 6px;
  background: var(--mint-tint);
  color: var(--mint);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* --- Page head ------------------------------------------------------------ */
.page-head { padding: 2.6rem 0 0.5rem; }

/*
 * No character cap on a page headline. The cap was 22ch, which is 543 px at the size this
 * heading renders at, and the longest title on the site needs 982 px. The result was a
 * headline breaking after four words with a wide empty column beside it. Headlines are
 * meant to run to the width of the column they sit in; the reading measure below them is
 * what keeps body text comfortable.
 */
.page-head h1 { margin-top: 0.9rem; }

.deck {
  margin-top: 1rem;
  font-size: var(--step-1);
  color: var(--ink-2);
  max-width: var(--measure);
}

.breadcrumbs { font-size: 0.82rem; color: var(--ink-3); }

.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  list-style: none;
  padding: 0;
}

.breadcrumbs li + li::before { content: '/'; margin-right: 0.4rem; color: var(--line-2); }

.breadcrumbs a { color: var(--ink-3); text-decoration: none; }

.breadcrumbs a:hover { color: var(--brand); }

.section-label {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brand);
}

/* --- Article head furniture ---------------------------------------------- */
.updated-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  margin-top: 1.1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
  font-size: 0.82rem;
  color: var(--ink-3);
}

.updated-key { font-weight: 700; color: var(--ink-2); }

.stamp { font-size: 0.82rem; color: var(--ink-3); }

.stamp-label {
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 0.7rem;
  color: var(--mint);
}

.expert {
  margin-top: 1.5rem;
  padding: 1.2rem 1.3rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.expert-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brand);
}

.expert-body { display: flex; gap: 0.9rem; margin-top: 0.7rem; align-items: flex-start; }

.expert-avatar {
  flex: none;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--brand), var(--brand-2));
  color: #fff;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.05rem;
}

.expert-name { font-weight: 700; }

.expert-role { font-size: 0.85rem; color: var(--ink-2); }

.expert-beat { font-size: 0.85rem; color: var(--ink-3); margin-top: 0.35rem; }

.stat-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1px;
  margin-top: 1.5rem;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.stat { padding: 1rem 1.1rem; background: var(--surface); }

.stat dt {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.stat dd {
  margin: 0.3rem 0 0;
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 800;
  letter-spacing: -0.03em;
}

.stat-key dd { color: var(--brand); }

.toc-box {
  margin-top: 1.5rem;
  padding: 1.2rem 1.3rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.toc-title {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.toc {
  margin-top: 0.7rem;
  padding-left: 1.1rem;
  display: grid;
  gap: 0.15rem;
  font-size: 0.92rem;
}

.toc a { text-decoration: none; }

.toc a:hover { text-decoration: underline; }

.disclosure {
  margin-top: 1.5rem;
  padding: 1rem 1.15rem;
  border-radius: var(--radius-sm);
  background: var(--amber-tint);
  border: 1px solid #f2ddbe;
  font-size: 0.85rem;
  color: #6b4a12;
}

.disclosure a { color: #6b4a12; }

/* --- Verdict -------------------------------------------------------------- */
.verdict {
  margin-top: 1.5rem;
  padding: 1.5rem 1.6rem;
  border-radius: var(--radius);
  background: linear-gradient(140deg, #0a0f1c, #1b2240);
  color: #fff;
  box-shadow: var(--shadow-hi);
}

.verdict-heading {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #9c9bf5;
}

.verdict-answer { margin-top: 0.6rem; font-size: var(--step-1); }

.verdict-answer a { color: #b8b6ff; }

.verdict table { margin-top: 1.1rem; font-size: 0.88rem; color: var(--ink); }

/* --- Tables --------------------------------------------------------------- */
/*
 * A table shows its content or it is not a table. Two rules stopped that happening:
 * `white-space: nowrap` on the header row, and `min-width: 34rem` on the table. Together
 * they made a seven column comparison need 1062px inside a 608px column, so every wide
 * table grew a horizontal scrollbar and the columns a reader came for sat off screen.
 *
 * Headers wrap now, no minimum width is imposed, and the wrapper clips the rounded corners
 * rather than scrolling.
 */
.table-scroll {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

caption {
  caption-side: top;
  text-align: left;
  padding: 0.8rem 0.9rem 0.5rem;
  font-size: 0.8rem;
  color: var(--ink-3);
  font-weight: 600;
}

th,
td {
  padding: 0.72rem 0.75rem;
  text-align: left;
  vertical-align: top;
}

thead th {
  background: var(--ink);
  color: var(--surface);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.76rem;
  letter-spacing: 0.03em;
  line-height: 1.3;
}

tbody th,
tbody td { border-top: 1px solid var(--line); }

tbody th { font-weight: 700; }

.is-highlighted { background: var(--brand-tint); }

/*
 * Below the desktop breakpoint a wide table becomes a labelled list. Seven columns cannot
 * be read on a phone at any font size, and the scrollbar this replaces hid the columns
 * rather than showing them. The row heading stays as the heading and each value carries
 * its column name, which `md.js` writes into `data-label`.
 */
@media (max-width: 61.25rem) {
  .table-scroll thead { display: none; }

  .table-scroll table,
  .table-scroll tbody,
  .table-scroll tr,
  .table-scroll th,
  .table-scroll td { display: block; width: auto; }

  .table-scroll tbody tr {
    padding: 0.85rem 0.95rem;
    border-top: 1px solid var(--line);
  }

  .table-scroll tbody tr:first-child { border-top: 0; }

  .table-scroll tbody th {
    padding: 0 0 0.45rem;
    border-top: 0;
    font-size: 0.92rem;
  }

  .table-scroll tbody td {
    display: grid;
    grid-template-columns: minmax(6.5rem, 38%) 1fr;
    gap: 0.75rem;
    padding: 0.22rem 0;
    border-top: 0;
  }

  .table-scroll tbody td::before {
    content: attr(data-label);
    padding-top: 0.12rem;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--ink-3);
  }
}

/* --- Callouts ------------------------------------------------------------- */
.callout {
  margin: 1.6rem 0;
  padding: 1.05rem 1.2rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--surface);
}

.callout-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: -0.01em;
}

.callout-note { background: var(--brand-tint); border-color: #ddd9fb; }

.callout-note .callout-title { color: var(--brand); }

.callout-caution { background: var(--amber-tint); border-color: #f2ddbe; }

.callout-caution .callout-title { color: var(--amber); }

/* --- Prose ---------------------------------------------------------------- */
.prose { max-width: var(--measure); }

.prose h2 {
  font-size: var(--step-3);
  margin: 2.4rem 0 0.8rem;
}

.prose h3 { font-size: var(--step-2); margin: 1.7rem 0 0.6rem; }

.prose p { margin: 0.9rem 0; }

.prose ul,
.prose ol { margin: 1rem 0; padding-left: 1.3rem; display: grid; gap: 0.4rem; }

.prose li::marker { color: var(--brand); }

.prose a { color: var(--brand); text-underline-offset: 2px; }

.prose strong { font-weight: 700; }

.prose blockquote {
  margin: 1.6rem 0;
  padding: 0.85rem 1.15rem;
  border-left: 4px solid var(--brand);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--brand-tint);
  font-size: var(--step-1);
  font-weight: 500;
  letter-spacing: -0.01em;
}

.prose table { margin: 1.3rem 0; }

/* Grouping the body into sections lets the browser skip the ones below the fold.
   `contain-intrinsic-size: auto` remembers real heights once rendered, so the
   scrollbar and anchor positions stay correct and nothing shifts. */
.prose-section {
  content-visibility: auto;
  contain-intrinsic-size: auto 640px;
}

/* --- Pick line ------------------------------------------------------------ */
.best-pick {
  margin: 1.5rem 0 0.75rem;
  padding: 0.85rem 1.1rem;
  border-radius: var(--radius-sm);
  background: var(--mint-tint);
  border: 1px solid #c8e4da;
  font-size: 0.97rem;
}

.best-pick-label {
  display: inline-block;
  margin-right: 0.5rem;
  padding: 0.15rem 0.5rem;
  border-radius: 6px;
  background: var(--mint);
  color: #fff;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.best-pick-note { color: var(--ink-2); font-size: 0.88rem; }

/* --- Screenshots ---------------------------------------------------------- */
.shot { margin: 1.6rem 0; }

.shot img {
  width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
  background: var(--surface);
}

.shot figcaption {
  margin-top: 0.6rem;
  font-size: 0.8rem;
  color: var(--ink-3);
}

/* --- FAQ ------------------------------------------------------------------ */
.faq { margin-top: 1.2rem; display: grid; gap: 0.7rem; }

.faq-item {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 0.35rem 1.1rem;
  box-shadow: var(--shadow);
}

.faq-item summary {
  cursor: pointer;
  padding: 0.75rem 0;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.faq-item summary::-webkit-details-marker { display: none; }

.faq-item summary::after {
  content: '+';
  margin-left: auto;
  font-size: 1.3rem;
  font-weight: 400;
  color: var(--brand);
  line-height: 1;
}

.faq-item[open] summary::after { content: '\2013'; }

.faq-item summary h3 { font-size: 1rem; margin: 0; }

.faq-answer { padding-bottom: 0.85rem; font-size: 0.93rem; color: var(--ink-2); }

/* --- Author --------------------------------------------------------------- */
/* Author details, closing the article. The reader who has finished the guide is the one
   who wants the byline, so this sits last rather than competing with the answer. */
.author {
  margin-top: 2.6rem;
  padding: 1.4rem 1.5rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.author-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.author-body {
  display: flex;
  gap: 0.9rem;
  align-items: flex-start;
  margin-top: 0.85rem;
}
.author-avatar {
  flex: none;
  width: 2.7rem;
  height: 2.7rem;
  margin: 0;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--brand);
  color: #fff;
  font-weight: 700;
  font-size: 0.95rem;
}
.author-name { font-weight: 700; font-size: 1.02rem; color: var(--ink); }
.author-role { margin-top: 0.15rem; font-size: 0.85rem; color: var(--ink-3); }
.author-bio { margin-top: 0.55rem; font-size: 0.92rem; color: var(--ink-2); }
.author-credentials { margin-top: 0.4rem; font-size: 0.82rem; color: var(--ink-3); }
.author-standards {
  margin-top: 1.1rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--line);
  font-size: 0.82rem;
  color: var(--ink-3);
}

/* --- CTA ------------------------------------------------------------------ */
.cta {
  margin: 2rem 0;
  padding: 1.6rem;
  border-radius: var(--radius);
  background: linear-gradient(140deg, var(--brand), var(--brand-2));
  color: #fff;
}

.cta-title { color: #fff; font-size: var(--step-2); }

.cta p { margin-top: 0.6rem; color: #e9e7ff; }

.cta .button { margin-top: 1rem; background: #fff; color: var(--ink); }

.cta .button:hover { background: #fff; color: var(--brand); }

/* --- Hub and article listings -------------------------------------------- */
.hub-grid,
.article-list {
  display: grid;
  gap: 1.2rem;
  list-style: none;
  padding: 0;
}

.hub-grid { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

.article-list { grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); }

.hub-card,
.article-card {
  display: flex;
  flex-direction: column;
  padding: 1.4rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.hub-card:hover,
.article-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-hi); }

.hub-card-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brand);
}

.hub-card h3,
.article-card h3 { font-size: 1.14rem; margin-top: 0.45rem; }

.hub-card h3 a,
.article-card h3 a { color: inherit; text-decoration: none; }

.hub-card h3 a:hover,
.article-card h3 a:hover { color: var(--brand); }

.hub-card p,
.article-card p { font-size: 0.89rem; color: var(--ink-2); margin-top: 0.5rem; }

.hub-card-more,
.article-meta {
  margin-top: auto;
  padding-top: 0.9rem;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--brand);
}

.article-meta { font-weight: 500; color: var(--ink-3); }

/* --- Footer --------------------------------------------------------------- */
.site-footer {
  margin-top: 3rem;
  padding-top: 2.6rem;
  background: var(--surface);
  border-top: 1px solid var(--line);
}

.footer-inner {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr;
  gap: 2.4rem;
  padding-bottom: 2rem;
}

.footer-brand .brand { font-size: 1.05rem; }

.footer-tagline { margin-top: 0.8rem; font-size: 0.9rem; color: var(--ink-2); }

.footer-note,
.footer-legal { margin-top: 0.5rem; font-size: 0.8rem; color: var(--ink-3); }

.footer-legal a { color: var(--ink-3); }

.footer-heading {
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.footer-nav ul {
  margin-top: 0.7rem;
  list-style: none;
  padding: 0;
  display: grid;
  gap: 0.1rem;
}

.footer-nav a {
  display: inline-flex;
  align-items: center;
  min-height: 2.1rem;
  color: var(--ink-2);
  text-decoration: none;
  font-size: 0.88rem;
}

.footer-nav a:hover { color: var(--brand); }

.footer-base {
  padding: 1rem 0 1.6rem;
  border-top: 1px solid var(--line);
  font-size: 0.8rem;
  color: var(--ink-3);
}

/* --- Responsive ----------------------------------------------------------- */
/* --- Trust-page layout ----------------------------------------------------
   A reading column with a supporting rail of short context cards. The rail is not
   sticky: a sticky element here costs layout work on every scroll for no gain the
   reader asked for, and it competes with the Lighthouse budget.
   -------------------------------------------------------------------------- */
.ledger {
  display: grid;
  /* The body column is the reading measure, not a share of the wrap. A `1fr` column
     here stretched the track to 834px while `.prose` capped the text at 544px, which
     left roughly 290px of empty space between the body and the rail on every page.
     Sizing the track to the measure and centring the pair removes that gap. */
  grid-template-columns: minmax(0, var(--measure)) 19rem;
  justify-content: center;
  gap: 2.6rem;
  align-items: start;
  padding-top: 1.5rem;
}

/* The columns are stated rather than left to source order. The rail is a supporting aside,
   so it belongs on the right even on the pages that happen to place it first in the markup. */
.ledger-rail { display: grid; gap: 1rem; align-content: start; grid-column: 2; }

.ledger-main { min-width: 0; grid-column: 1; }

.rail-card {
  padding: 1.2rem 1.3rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.rail-heading { font-size: 1rem; }

.rail-card p { margin-top: 0.45rem; }

.small { font-size: 0.875rem; }

.muted { color: var(--ink-3); }

.lede {
  margin-top: 1rem;
  font-size: var(--step-1);
  color: var(--ink-2);
  max-width: var(--measure);
}

/* --- Article layout -------------------------------------------------------- */
/*
 * Articles run as a pair: a sticky contents rail on the left and the reading column on the
 * right. The rail comes first in the document so it reads as navigation before the body
 * for a screen reader or a text browser, and the short answer still opens the body column
 * immediately under the title.
 */
.ledger-article {
  grid-template-columns: 15rem minmax(0, var(--measure-article));
}

.ledger-article .ledger-rail {
  grid-column: 1;
  position: sticky;
  top: 5.4rem;
  align-self: start;
}

.ledger-article .ledger-main { grid-column: 2; }

/* Contents rail: a quiet card that does not compete with the body. */
.toc-box {
  margin-top: 0;
  padding: 1rem 1.1rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: none;
}

.toc-title {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.toc {
  margin-top: 0.65rem;
  padding-left: 1.15rem;
  display: grid;
  gap: 0.1rem;
  font-size: 0.82rem;
  line-height: 1.35;
}

/* Block links with real padding. A bare 16px text link fails the target-size audit, and
   the extra height also makes the rail easier to hit with a mouse. */
.toc a {
  display: block;
  padding: 0.4rem 0.45rem;
  border-radius: 8px;
  color: var(--ink-2);
  text-decoration: none;
}

.toc a:hover { background: var(--brand-tint); color: var(--brand); }

/*
 * Article titles carry more weight than a hub or policy title.
 *
 * The size is set so the longest title on the site stays on one line at every desktop width.
 * Measured: the widest title needs 21.3 px of width per pixel of font size, and the column
 * offers 1180 px at 1440. A 24ch cap used to sit here, which held the heading to 778 px and
 * broke every article title across two lines. tools/check-titles.cjs reports any headline
 * that wraps, so this can be re-checked rather than re-guessed.
 */
.article .page-title {
  font-size: clamp(1.9rem, 3.7vw, 3rem);
}

/* The deck sits under a full-width headline, so it may run wider than the body measure
   without becoming hard to read. */
.article .deck { max-width: 48rem; }

/* The article body runs on the wider track, which is what gives a seven column
   comparison table room to sit without a scrollbar. */
.article .prose { max-width: var(--measure-article); }

/* --- Responsive ----------------------------------------------------------- */
@media (max-width: 61.25rem) {
  .hero-grid { grid-template-columns: 1fr; gap: 2.4rem; }
  .bento { grid-template-columns: repeat(2, 1fr); }
  .tile.is-wide { grid-column: span 2; }
  .footer-inner { grid-template-columns: 1fr 1fr; }
  .ledger { grid-template-columns: 1fr; gap: 2rem; }
  .ledger-rail { order: 2; grid-column: 1; }
  .ledger-main { grid-column: 1; }
  /* The article rail is hidden rather than stacked. On a phone the short answer has to
     stay directly under the title, and a contents list above it would push it down; the
     section headings themselves carry the structure. */
  .ledger-article .ledger-rail { display: none; }
}

/* Small screens: full-height touch targets in a single scrollable nav row, and a
   header that does not stick. A sticky header on a phone spends a large share of a
   short viewport on navigation the reader has not reached yet, and it also keeps a
   sticky element out of the layout path. */
@media (max-width: 47.5rem) {
  .site-header { position: static; }

  .site-nav {
    width: 100%;
    margin-left: 0;
    order: 3;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }

  .site-nav::-webkit-scrollbar { display: none; }

  .site-nav ul { flex-wrap: nowrap; gap: 0 1.4rem; }

  .site-nav a { min-height: 2.75rem; white-space: nowrap; }

  .header-cta { margin-left: auto; }

  .hero { padding-top: 2.6rem; }

  .frame-chip { left: 0; }

  .bento { grid-template-columns: 1fr; }

  .tile.is-wide { grid-column: span 1; }

  .footer-inner { grid-template-columns: 1fr; gap: 1.8rem; }

  .rail { grid-auto-columns: minmax(260px, 84%); }

  .stat-strip { grid-template-columns: 1fr 1fr; }

  .expert-body { flex-direction: column; gap: 0.7rem; }
}

@media (max-width: 30rem) {
  .rail { grid-auto-columns: minmax(240px, 92%); }
  .hero-stats { gap: 1.4rem; }
}

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

  .card:hover,
  .tile:hover,
  .hub-card:hover,
  .article-card:hover,
  .button:hover { transform: none; }
}

@media print {
  .site-header,
  .site-footer,
  .rail-arrows,
  .skip-link { display: none; }

  body { background: #fff; }

  .card,
  .tile,
  .verdict { box-shadow: none; border: 1px solid #ccc; }
}
/* Hub pages list every guide in the hub, so a large hub renders eight or more cards with
   images in one pass. Skipping layout for the cards that are off-screen keeps the first
   paint cheap. The `auto` keyword in contain-intrinsic-size means the browser remembers
   each card's real size after the first render, so nothing shifts on scroll. */
.card {
  content-visibility: auto;
  contain-intrinsic-size: auto 460px;
}

/* The same treatment for the rail on the home page, where only the first two or three
   cards are ever visible at once. */
.rail-track > .card {
  contain-intrinsic-size: auto 420px;
}
/* Data plate.
   Guides whose vendors have no captured pricing page would otherwise leave a hole in the
   card grid next to cards that do have one. The plate fills the same frame with the
   guide's key figure instead of a photograph, so the grid stays even and nothing on the
   page pretends to be a screenshot it is not. */
.card-thumb.is-plate {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.15rem;
  padding: 1rem 1.15rem;
  background:
    radial-gradient(120% 90% at 12% 8%, rgba(124, 58, 237, 0.34) 0%, rgba(124, 58, 237, 0) 62%),
    linear-gradient(150deg, #171d33 0%, #0a0f1c 100%);
}

.card-thumb.is-plate::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
  background-size: 26px 26px;
  pointer-events: none;
}

.plate-label {
  position: relative;
  z-index: 1;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: #9c9bf5;
}

.plate-value {
  position: relative;
  z-index: 1;
  font-family: var(--font-display), system-ui, sans-serif;
  font-size: 1.95rem;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: #ffffff;
}

.plate-note {
  position: relative;
  z-index: 1;
  font-size: 0.78rem;
  line-height: 1.35;
  color: #b9bfd4;
}
/* Site index.
   The full list of pages runs to forty entries, which is a long single column. Two columns
   on a wide screen halve the scrolling; a single column is kept where that would be
   cramped. `break-inside` stops an entry being split across the column boundary. */
/* Scoped to .prose because the shared `.prose ul` rule sets `display: grid`, and a grid
   container ignores `columns` entirely. */
.prose .index-list {
  display: block;
  columns: 2;
  column-gap: 2.25rem;
  margin: 0 0 1.75rem;
  padding: 0;
  list-style: none;
}

.prose .index-list li {
  margin: 0 0 0.5rem;
  break-inside: avoid;
}

.prose .index-list a {
  font-weight: 600;
}

@media (max-width: 640px) {
  .prose .index-list {
    columns: 1;
  }
}

/* --- Vendor pricing strip -------------------------------------------------
   Sits directly under the verdict, so the reader who already knows what they
   want can act before reading the argument. Selectors are scoped under .prose
   because .prose ul / .prose a would otherwise outrank a bare class. */
.prose .pricing-strip {
  margin-top: 1.25rem;
  padding: 1.2rem 1.3rem;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}

.prose .pricing-strip-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--step-1);
  font-weight: 600;
  color: var(--ink);
}

.prose .pricing-links {
  list-style: none;
  margin: 0.85rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.prose .pricing-links li {
  margin: 0;
}

.prose .pricing-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0.5rem 1rem;
  border: 1px solid var(--line-2);
  border-radius: var(--radius-pill);
  background: var(--surface);
  color: var(--brand);
  font-size: var(--step--1);
  font-weight: 600;
  text-decoration: none;
}

.prose .pricing-links a:hover,
.prose .pricing-links a:focus-visible {
  border-color: var(--brand);
  background: var(--brand-tint);
}

.prose .pricing-strip-note {
  margin: 0.9rem 0 0;
  font-size: var(--step--1);
  color: var(--ink-3);
}

/*
 * The verdict table is not a labelled data table, it is two columns of prose: the
 * question and the pick. The label-and-value grid that comparison tables use on
 * phones does not fit it. Because the verdict cells are produced by the renderer
 * rather than by the Markdown converter, they carry no data-label, so the empty
 * label column pushed the question across the row while the pick sat underneath
 * it. Each row simply stacks instead: question first, pick below.
 */
@media (max-width: 61.25rem) {
  .table-scroll .verdict-table tbody td {
    display: block;
    padding: 0;
  }

  .table-scroll .verdict-table tbody td::before { content: none; }

  .table-scroll .verdict-table tbody th {
    padding: 0.25rem 0 0.65rem;
  }
}
