/* BetweenBooks — the welcome page at /welcome. Standalone: the app's own chrome (rail,
   shelf, book page) is not wanted here, so this does not load styles.css.

   The token block below is therefore a COPY of the one in styles.css, which is the source
   of truth — change a colour there and change it here too. The alternative was lifting the
   tokens into a third file both stylesheets import, which would have meant editing the
   running app's stylesheet; that is a bigger change than this page is worth on its own, but
   it is the right fix the moment a second page needs them.

   Two themes, same mechanism as the app: `data-theme` on <html>, resolved before first
   paint by the inline script in welcome.html, sharing the app's localStorage key so a
   visitor who has already chosen a side keeps it. */

/* --------------------------------------------------------------------- tokens */

:root {
  color-scheme: light;

  --bg: #f2eff8;
  --surface: #fbf9fe;
  --surface-2: #f6f3fc;
  --sidebar: #ece7f6;
  --border: #e0d9ef;
  --border-strong: #c9c0e0;
  --text: #2b2440;
  --muted: #6b6288;
  --accent: #6a4fb8;
  --accent-hover: color-mix(in srgb, var(--accent) 86%, #000);
  --accent-soft: color-mix(in srgb, var(--accent) 11%, var(--surface));
  --accent-line: color-mix(in srgb, var(--accent) 34%, var(--surface));
  --on-accent: #ffffff;
  --star: #c08a1e;
  --star-empty: #ded5ee;
  --ring: var(--accent);

  --shadow: 0 1px 2px rgba(42, 30, 70, .05), 0 2px 8px rgba(42, 30, 70, .06);
  --shadow-lift: 0 2px 6px rgba(42, 30, 70, .08), 0 12px 28px rgba(42, 30, 70, .12);

  --reading-bg: #fbe7d6; --reading-fg: #8a5426;
  --read-bg: #dcefe4;    --read-fg: #2c6349;
  --want-bg: #e3e4f3;    --want-fg: #565a7d;
  --dnf-bg: #f8dfe8;     --dnf-fg: #8a3556;

  --aurora-1: #6a4fb8; --aurora-2: #c58fb8; --aurora-3: #7f9fd6; --aurora-op: .42;

  --r-sm: 4px;
  --r: 6px;
  --r-full: 999px;

  /* Mirrors the type block in styles.css, which stays the source of truth — the landing
     page and the app are one typographic system, so this is a copy and never a variant.
     Two faces: Plex Sans for anything read as language, Plex Mono for anything read as a
     mark. See styles.css for why the display serif is gone. */
  --font-ui: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
             "Helvetica Neue", Arial, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               monospace;
  /* Mirrors --font-display in styles.css. Marketing headlines only — see .display below. */
  --font-display: "EB Garamond", Georgia, "Times New Roman", serif;

  --fs-3xs: .68rem;
  --fs-2xs: .74rem;
  --fs-xs:  .82rem;
  --fs-sm:  .88rem;
  --fs-md:  .95rem;
  --fs-lg:  1.06rem;
  --fs-xl:  1.3rem;
  --fs-2xl: 1.75rem;
  --fs-3xl: 2.3rem;
  --fs-hero: 3.2rem;
  --fs-pill: .6rem;

  --w-normal: 400;
  --w-medium: 500;
  --w-semi: 600;

  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
  --ease-out: cubic-bezier(.22, .61, .36, 1);
  --t-fast: 120ms;
  --t: 190ms;
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --bg: #14101f;
  --surface: #1d1730;
  --surface-2: #262040;
  --sidebar: #100d19;
  --border: #2f2749;
  --border-strong: #423868;
  --text: #ebe5f8;
  --muted: #a99cc6;
  --accent: #b49bf2;
  --accent-hover: color-mix(in srgb, var(--accent) 82%, #fff);
  --accent-soft: color-mix(in srgb, var(--accent) 16%, var(--surface));
  --accent-line: color-mix(in srgb, var(--accent) 38%, var(--surface));
  --on-accent: #17102b;
  --star: #e8b84f;
  --star-empty: #372f52;

  --shadow: 0 1px 2px rgba(0, 0, 0, .55), 0 2px 10px rgba(0, 0, 0, .45);
  --shadow-lift: 0 4px 12px rgba(0, 0, 0, .55), 0 18px 40px rgba(0, 0, 0, .55);

  --reading-bg: #3a2a18; --reading-fg: #edbe83;
  --read-bg: #1d3327;    --read-fg: #92d5ae;
  --want-bg: #232042;    --want-fg: #b0abd0;
  --dnf-bg: #35202c;     --dnf-fg: #eba3bf;

  --aurora-1: #b49bf2; --aurora-2: #5b3fa8; --aurora-3: #4f5fa8; --aurora-op: .38;
}

/* ----------------------------------------------------------------------- base */

* { box-sizing: border-box; }
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: var(--fs-md)/1.58 var(--font-ui);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { color: var(--accent-hover); text-decoration: underline; }

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

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

/* The theme flip, same as the app's: the palette is one attribute on <html>, so there is
   nothing to interpolate and a view transition animates the two snapshots instead. The new
   frame fades in over a static old one rather than cross-fading, which keeps the page
   opaque the whole way across. `*` cannot match these pseudo-elements, hence the second
   reduced-motion block. */
::view-transition-old(root),
::view-transition-new(root) { mix-blend-mode: normal; }
::view-transition-old(root) { animation: none; z-index: 0; }
::view-transition-new(root) { animation: theme-fade 360ms var(--ease-out); z-index: 1; }
@keyframes theme-fade { from { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) { animation: none !important; }
}

/* Marketing headlines, and the ONE place a second face is spent. The rule inside the app
   still holds — a book title in a grid cell is data, not literature, and gets the sans —
   but a hero headline is not a field of a form, it is the sentence that has to carry the
   product in 50 milliseconds. EB Garamond is a real book face, so the vintage half of the
   identity arrives in the type rather than in decoration.

   Tracking is far softer than the sans needed: an oldstyle serif at 51px is already fitted
   for display, and the -.032em that kept Plex from falling apart would close Garamond up.
   Georgia is the fallback because it is the nearest-metric serif a machine is likely to
   have — the page must still be right when the webfonts never arrive. */
.display {
  font-family: var(--font-display);
  font-weight: var(--w-medium);
  letter-spacing: -.012em;
  line-height: 1.06;
  margin: 0 0 1.1rem;
}
/* The accent inside a headline: italic and the accent colour, on the one word the sentence
   turns on. Garamond has a true cursive italic, which is the reason this reads as emphasis
   rather than as a slanted roman. */
.display em { font-style: italic; color: var(--accent); }

.wrap { max-width: 1180px; margin: 0 auto; padding: 0 2rem; }
.sect { padding: 5.5rem 0; }
.band { border-top: 1px solid var(--border); }
.band.tinted { background: var(--surface-2); }
.band.rail { background: var(--sidebar); }

.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-3xs); font-weight: var(--w-medium); letter-spacing: .14em;
  text-transform: uppercase; color: var(--accent); margin: 0 0 .8rem;
}
.lede { color: var(--muted); font-size: var(--fs-lg); line-height: 1.6; max-width: 54ch; margin: 0 0 1.2rem; }
.lede:last-child { margin-bottom: 0; }
.centered { text-align: center; }
.centered .lede { margin-left: auto; margin-right: auto; }

.two-col {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 4rem;
  align-items: center;
}

/* ------------------------------------------------------------------- controls */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  font: inherit; font-weight: var(--w-medium); padding: .68rem 1.15rem;
  border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  background: var(--surface); color: var(--text); cursor: pointer;
  transition: background var(--t-fast) var(--ease-out),
              border-color var(--t-fast) var(--ease-out),
              color var(--t-fast) var(--ease-out),
              transform var(--t-fast) var(--ease-spring);
}
.btn:hover { border-color: var(--accent); color: var(--accent); text-decoration: none; }
.btn:active { transform: translateY(1px) scale(.98); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent);
               box-shadow: var(--shadow); }
.btn.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover);
                     color: var(--on-accent); }
.btn.ghost { background: transparent; border-color: transparent; color: var(--muted); }
.btn.ghost:hover { background: var(--surface-2); border-color: var(--border); color: var(--accent); }
.btn.block { width: 100%; }

.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r);
}

.pill {
  font-size: var(--fs-3xs); font-weight: var(--w-semi); letter-spacing: .02em;
  padding: .1rem .4rem; border-radius: var(--r-full); white-space: nowrap;
}
.pill.want { background: var(--want-bg); color: var(--want-fg); }
.pill.reading { background: var(--reading-bg); color: var(--reading-fg); }
.pill.read { background: var(--read-bg); color: var(--read-fg); }
.pill.dnf { background: var(--dnf-bg); color: var(--dnf-fg); }

/* A segmented switch, the same shape the app uses for its status filter. */
.seg-group {
  display: inline-flex; gap: .2rem; padding: .25rem;
  border-radius: var(--r-full); background: var(--surface-2); border: 1px solid var(--border);
}
.seg {
  font: inherit; font-size: var(--fs-sm); font-weight: var(--w-medium); border: 0; cursor: pointer;
  border-radius: var(--r-full); padding: .42rem 1rem;
  background: transparent; color: var(--muted);
  transition: background var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out);
}
.seg[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }

/* ------------------------------------------------------------------------ nav */

.topbar { border-bottom: 1px solid var(--border); background: var(--sidebar); }
.topbar .wrap { display: flex; align-items: center; gap: 2rem; padding-top: .9rem; padding-bottom: .9rem; }
.brand { display: flex; align-items: center; gap: .6rem; color: var(--text); }
.brand:hover { text-decoration: none; }
.brand svg { width: 30px; height: 30px; }
.brand-name {
  font-family: var(--font-display);
  font-weight: var(--w-semi);
  letter-spacing: .005em;
  font-size: var(--fs-xl);
}
.nav-links { display: flex; align-items: center; gap: 1.6rem; margin-left: auto; }
.nav-links a { color: var(--muted); font-weight: var(--w-medium); font-size: var(--fs-md); }
.nav-links a.btn { color: var(--on-accent); }

/* ---------------------------------------------------------------------- hero */

.hero { position: relative; overflow: hidden; }
.hero .wrap { position: relative; padding-top: 5.5rem; padding-bottom: 5rem; }

/* The sign-in screen's aurora, held still. A landing page has enough going on without
   ambient drift, and stillness is also the answer for reduced motion. */
.aurora { position: absolute; inset: 0; pointer-events: none; opacity: var(--aurora-op); }
/* The marbling runs across the very top of the hero, under the header's bottom rule, so it
   reads as the edge of a sheet rather than as a decorative divider dropped into the page. */
.marble {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 120px;
  opacity: .5;
  pointer-events: none;
}
.aurora span { position: absolute; border-radius: 50%; filter: blur(80px); }
.aurora .b1 { top: -22rem; left: -14rem; width: 46rem; height: 46rem; background: var(--aurora-1); }
.aurora .b2 { top: -12rem; right: -16rem; width: 40rem; height: 40rem; background: var(--aurora-2); }
.aurora .b3 { bottom: -26rem; left: 34%; width: 38rem; height: 38rem; background: var(--aurora-3); }

.hero h1 { font-size: var(--fs-hero); margin-bottom: 1.4rem; }

/* Section headings, sized here rather than inline on each <h2>. Both sit on the same step
   now: they were 2.35 and 2.6rem, a difference no reader can see between two headings that
   never share a screen, and the kind of near-miss the ramp exists to stop. */
.display.h-sect,
.display.h-close { font-size: var(--fs-3xl); }
.hero .lede { margin-bottom: 2rem; }
.cta-row { display: flex; flex-wrap: wrap; gap: .7rem; align-items: center; }
.credit { color: var(--muted); font-size: var(--fs-sm); margin: 1.1rem 0 0; }
.credit strong { color: var(--text); font-weight: var(--w-semi); }

/* --------------------------------------------------------------- shelf mockup */

.mock { padding: 1.1rem; box-shadow: var(--shadow-lift); }
.mock-body { display: grid; grid-template-columns: 150px minmax(0, 1fr); gap: 1.1rem; align-items: start; }

.rail-label {
  margin: 0 0 .45rem .3rem; font-size: var(--fs-3xs); font-weight: var(--w-semi);
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
/* The container holds the two shelves an account cannot lose; the ones you made list
   below it, unboxed — the same split the app's own rail makes. */
.rail-box {
  display: flex; flex-direction: column; gap: .15rem; padding: .3rem;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r); box-shadow: var(--shadow);
}
.rail-list { display: flex; flex-direction: column; gap: .15rem; margin-top: .35rem; }
.shelf-btn {
  display: flex; align-items: center; gap: .6rem; width: 100%;
  font: inherit; font-size: var(--fs-md); font-weight: var(--w-medium); text-align: left;
  border: 0; border-radius: var(--r-sm); padding: .5rem .6rem; cursor: pointer;
  background: transparent; color: var(--muted);
  transition: background var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out);
}
.shelf-btn:hover { background: var(--accent-soft); color: var(--text); }
.shelf-btn[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }
.shelf-btn svg { flex: none; width: 17px; height: 17px; fill: none; stroke: currentColor;
                 stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; opacity: .85; }
.shelf-btn .nm { flex: 1; min-width: 0; }
.shelf-btn .ct {
  flex: none; font-size: var(--fs-2xs); font-weight: var(--w-semi); padding: .05rem .4rem;
  border-radius: var(--r-full); background: var(--accent-soft); color: var(--muted);
}
.shelf-btn[aria-pressed="true"] .ct { background: rgba(255, 255, 255, .22); color: inherit; }

.shelf-name { margin: 0 0 .1rem; font-size: var(--fs-lg); font-weight: var(--w-semi); letter-spacing: -.02em; }
.shelf-sub { margin: 0 0 .8rem; color: var(--muted); font-size: var(--fs-xs); }
.grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .6rem; }

.tile {
  background: transparent; border: 0; display: flex; flex-direction: column;
  transition: transform var(--t) var(--ease-out);
}
.tile:hover { transform: translateY(-2px); }
/* The app's own no-cover treatment, which is what most of a real shelf looks like. */
.tile .cover {
  aspect-ratio: 2 / 3; display: grid; place-items: center; padding: .5rem;
  text-align: center; font-size: var(--fs-3xs); line-height: 1.3; color: var(--muted);
  background: linear-gradient(150deg, var(--accent-soft), var(--surface-2));
  border-radius: var(--r-sm); box-shadow: var(--shadow);
  transition: box-shadow var(--t) var(--ease-out);
}
.tile:hover .cover { box-shadow: var(--shadow-lift); }
.tile .body { padding: .45rem 0 0; display: flex; flex-direction: column; gap: .2rem; flex: 1; }
/* Height-locked for the same reason the app's tile caption is: an unclamped caption wraps
   to a different line count per title and again on the font swap, which reflows the mock
   shelf. See the note on .book .title in styles.css. The reserved height is derived from
   the token rather than restating it, so the two cannot drift apart. */
.tile .t {
  font-weight: var(--w-semi); font-size: var(--fs-xs);
  line-height: 1.22; letter-spacing: -.01em;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden;
  min-height: calc(var(--fs-xs) * 1.22 * 2);
}
.tile .a { color: var(--muted); font-size: var(--fs-3xs); }
.tile .meta { display: flex; justify-content: space-between; align-items: center;
              gap: .25rem; margin-top: auto; padding-top: .3rem; }
.bar { height: 4px; background: var(--accent-soft); border-radius: var(--r-full);
       overflow: hidden; margin-top: .15rem; }
.bar i { display: block; height: 100%; background: var(--accent); border-radius: inherit; }
.bar.big { height: 10px; margin: 0 0 1.2rem; }

/* -------------------------------------------------------------- rating widget */

.panel-title {
  margin: 0 0 1.2rem; font-size: var(--fs-xs); font-weight: var(--w-semi);
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}
.aspects { display: flex; flex-direction: column; gap: 1.05rem; }
.aspect { display: flex; align-items: center; gap: 1rem; }
.aspect .label { flex: none; width: 6.5rem; font-size: var(--fs-sm); font-weight: var(--w-medium); color: var(--muted); }
.aspect .val { margin-left: auto; font-size: var(--fs-sm); font-weight: var(--w-semi); color: var(--text); }

.stars { display: flex; gap: .25rem; }
/* Each slot is an empty star with a clipped filled star over it, so a half needs no SVG
   gradient — and therefore no ids to collide when the row is repeated four times. */
.star { position: relative; width: 28px; height: 28px; }
.star svg { position: absolute; inset: 0; width: 28px; height: 28px; }
.star .fill { position: absolute; inset: 0; overflow: hidden; width: 0; }
.star .fill svg { position: static; display: block; }
.star .hit { position: absolute; inset: 0; display: flex; }
.star .hit button {
  flex: 1; border: 0; background: none; padding: 0; margin: 0; cursor: pointer; height: 100%;
}

.avg-row {
  margin-top: 1.4rem; padding-top: 1.1rem; border-top: 1px solid var(--border);
  display: flex; align-items: baseline; gap: .6rem;
}
.avg-row .n { margin-left: auto; font-size: var(--fs-2xl); font-weight: var(--w-semi);
              letter-spacing: -.03em; line-height: 1; }

/* ------------------------------------------------------------------- progress */

.progress-read { display: flex; align-items: baseline; gap: .6rem; margin-bottom: .55rem; }
.progress-read strong { font-size: var(--fs-3xl); font-weight: var(--w-semi); letter-spacing: -.03em; line-height: 1; }
.stepper { display: flex; align-items: center; gap: .5rem; }
.stepper .box {
  display: grid; place-items: center; width: 2.1rem; height: 2.1rem;
  border: 1px solid var(--border-strong); border-radius: var(--r-sm); color: var(--muted);
}
.stepper .page {
  flex: 1; border: 1px solid var(--border-strong); border-radius: var(--r-sm);
  padding: .48rem .65rem; font-weight: var(--w-medium);
}
.pill-row { display: flex; gap: .4rem; margin-top: 1.2rem; flex-wrap: wrap; }
.pill-row .pill { font-size: var(--fs-2xs); padding: .22rem .6rem; }

/* ---------------------------------------------------------------------- stats */

.stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .9rem; margin-top: 2.6rem; }
.stat { padding: .9rem 1rem; text-align: left; }
.stat .n { font-size: var(--fs-2xl); font-weight: var(--w-semi); letter-spacing: -.03em; line-height: 1.1; }
.stat .l { color: var(--muted); font-size: var(--fs-xs); font-weight: var(--w-medium); }

/* -------------------------------------------------------------------- pricing */

.tiers { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.2rem;
         max-width: 780px; margin: 0 auto; }
.tier { padding: 1.8rem; position: relative; }
.tier.featured { border-color: var(--accent-line); box-shadow: var(--shadow-lift); }
.tier h3 { margin: 0 0 .3rem; font-weight: var(--w-semi); font-size: var(--fs-lg); }
.tier .who { margin: 0 0 1.2rem; color: var(--muted); font-size: var(--fs-sm); }
.price { display: flex; align-items: baseline; gap: .35rem; margin-bottom: 1.4rem; }
.price .amt { font-size: var(--fs-3xl); font-weight: var(--w-semi); letter-spacing: -.03em; line-height: 1; }
.price .per { color: var(--muted); font-size: var(--fs-md); }
.tier .badge {
  position: absolute; top: -.7rem; left: 1.8rem;
  background: var(--accent); color: var(--on-accent); font-size: var(--fs-3xs); padding: .25rem .6rem;
}
.rule { height: 1px; background: var(--border); margin: 1.4rem 0; }
.ticks { display: flex; flex-direction: column; gap: .7rem; }
.ticks li { display: flex; gap: .6rem; align-items: flex-start; font-size: var(--fs-md); color: var(--muted); }
.ticks svg { flex: none; width: 17px; height: 17px; margin-top: .15rem; fill: none;
             stroke: var(--accent); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.ticks { list-style: none; margin: 0; padding: 0; }
.fineprint { text-align: center; color: var(--muted); font-size: var(--fs-xs); margin: 1.6rem 0 0; }

/* ------------------------------------------------------------------------ faq */

.faq { max-width: 760px; margin: 0 auto; }
.faq-item { border-bottom: 1px solid var(--border); }
.faq-q {
  font: inherit; font-size: var(--fs-lg); font-weight: var(--w-semi); letter-spacing: -.01em;
  width: 100%; text-align: left; border: 0; background: none; cursor: pointer;
  color: var(--text); padding: 1.15rem 0;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.faq-q svg {
  flex: none; width: 20px; height: 20px; fill: none; stroke: var(--muted);
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
  transition: transform var(--t) var(--ease-out);
}
.faq-q[aria-expanded="true"] svg { transform: rotate(180deg); }
.faq-a { margin: -.3rem 0 1.3rem; color: var(--muted); line-height: 1.65; max-width: 62ch; }

/* --------------------------------------------------------------------- footer */

.foot .wrap { display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap;
              padding-top: 2.6rem; padding-bottom: 1rem; }
.foot-links { display: flex; gap: 1.4rem; margin-left: auto; flex-wrap: wrap; }
.foot-links a { color: var(--muted); font-size: var(--fs-sm); }
.foot .small { color: var(--muted); font-size: var(--fs-xs); padding-bottom: 2.6rem; margin: 0; }
.foot .brand svg { width: 24px; height: 24px; }

/* ---------------------------------------------------------------- narrow */

@media (max-width: 900px) {
  .wrap { padding: 0 1.25rem; }
  .sect { padding: 3rem 0; }
  .two-col { grid-template-columns: 1fr; gap: 2rem; }
  .hero .wrap { padding-top: 2.6rem; padding-bottom: 3rem; }
  .hero h1 { font-size: var(--fs-3xl); }
  .display { font-size: var(--fs-2xl); }
  .nav-links { gap: 1rem; }
  /* The links go to the footer at this width; the one action stays. */
  .nav-links a:not(.btn) { display: none; }
  .mock-body { grid-template-columns: 1fr; }
  .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tiers { grid-template-columns: 1fr; }
  .cta-row { flex-direction: column; align-items: stretch; }
  .cta-row .btn { width: 100%; }
  /* Every tappable thing clears 44px on a touch layout. */
  .btn { min-height: 46px; }
  .shelf-btn { min-height: 44px; }
  .faq-q { min-height: 52px; }
  .aspect .label { width: auto; flex: 1; }
  .star, .star svg { width: 24px; height: 24px; }
}
