/* rikAI grammar pages — /grammar/〜.
   Loads on top of style.css: nav, footer, sentence lab, waitlist and every
   colour token come from there. This file only adds what a grammar page
   needs that the home page doesn't: the point's masthead, the structure
   card, and the stack of worked example sentences.

   All rules are scoped under .gpage so nothing here can reach the home
   page or the tech page. */

/* .railhost, not .gpage: the shell and the pinned app rail are shared by the
   grammar/vocabulary pages and the feature pages, so they hang off a class
   both carry. Everything still scoped under .gpage below is grammar-only. */
.railhost {
  --gmaxw: 820px;    /* prose measure — narrower than the site's 1080 */
  --grail: 340px;    /* the rail: the app card, pinned */
  --gtop: 88px;      /* sticky offset: the nav is ~70px, plus breathing room */

  --phone-h: clamp(280px, calc(100vh - 316px), 700px);
      /* the rail's phone: as tall as the window allows once the nav offset,
         the words under it and the button are paid for (~316px), so the
         whole card is on screen; 700px is as wide as the rail allows */
  --phone-r: calc(var(--phone-h) * 0.075); /* its corner, in proportion */
}

/* the seal is the bare star, like every other tab's mark */
.gpage .seal { border-radius: 0; }

/* ── shell ────────────────────────────────────────────────────────── */

.railhost .gwrap {
  max-width: var(--gmaxw);
  margin: 0 auto;
  padding: 0 24px;
}

.railhost .gwrap-wide { max-width: var(--gwide); }

.gpage .gsec { padding: 54px 0 0; }

/* ── the layout: the page, and the app beside it ──────────────────
   One column of content — hero, sentences, forms, meaning, the rest — and
   a rail holding the app the whole way down. The sentences get the width;
   the rail is the only navy thing on a charcoal page. */
.railhost .glayout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--grail);
  gap: 0 64px;
  align-items: stretch;   /* the rail cell must span the whole page, or the
                             sticky child has no height to travel through */
}

.railhost .gmain,
.railhost .grail { min-width: 0; }   /* long sentences can't widen the grid */

.railhost .grail { padding-top: 26px; }   /* level with the breadcrumb */

/* Pinned, with no scrollbar of its own — a scroll container takes the wheel
   before the page does, which reads as a stuck page. Instead the anchor
   moves: while the card fits, --gtop pins it under the nav; when it is
   taller than the viewport the second value goes negative and pins it by
   its bottom edge. --stick-h is measured by site.js; without it the card
   simply pins to the top. */
.railhost .gstick {
  position: sticky;
  top: min(var(--gtop), calc(100vh - var(--stick-h, 0px) - 28px));
  top: min(var(--gtop), calc(100svh - var(--stick-h, 0px) - 28px));   /* iOS: the screen with its bars showing */
}

/* ── the app card ─────────────────────────────────────────────────── */

/* No plate: the phone is the object. It is a whole device — the frame's
   inner box has the exact aspect of the captures (700×1517), so every screen
   is shown entire, status bar to home bar, and nothing is cropped or faded.
   Five screens sit stacked inside it and site.js fades between them; the
   first is the one a page with no JS shows. */
.railhost .app-card { text-align: center; }

.railhost .phone {
  position: relative;
  width: calc((var(--phone-h) - 14px) * 0.4614 + 14px);
  height: var(--phone-h);
  margin: 0 auto 22px;
  padding: 7px;
  box-sizing: border-box;
  border-radius: var(--phone-r);
  background: #2A2E38;
  box-shadow: inset 0 0 0 1px #3B404C, 0 18px 40px -18px rgba(0, 0, 0, 0.7);
  overflow: hidden;
  cursor: pointer;
}

.railhost .phone:focus-visible {
  outline: 2px solid var(--ai-light);
  outline-offset: 4px;
}

/* the screen behind the screens: black, so a screen sliding in has a screen
   colour beside it and not the bezel's grey */
.railhost .phone::before {
  content: "";
  position: absolute;
  inset: 7px;
  border-radius: calc(var(--phone-r) - 6px);
  background: #000;
}

.railhost .phone img {
  position: absolute;
  inset: 7px;
  width: calc(100% - 14px);
  height: calc(100% - 14px);
  object-fit: cover;   /* same aspect as the box; cover only absorbs the rounding */
  object-position: 50% 0;
  border-radius: calc(var(--phone-r) - 6px);
  /* Screens SLIDE, the way they move in the app: the next one waits off the
     right edge, the ones already seen sit off the left. A cross-fade showed
     two screens through each other for half a second, which read as the
     phone morphing. */
  transform: translateX(102%);
  transition: transform 0.38s cubic-bezier(0.2, 0.7, 0.2, 1);
}

.railhost .phone img.is-on { transform: none; }
.railhost .phone img.is-past { transform: translateX(-102%); }

@media (prefers-reduced-motion: reduce) {
  .railhost .phone img { transition: none; }
}

.railhost .app-dots {
  display: flex;
  justify-content: center;
  gap: 9px;
  margin-top: 14px;
}

.railhost .app-dots button {
  width: 7px;
  height: 7px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: color-mix(in srgb, var(--paper-dim) 45%, transparent);
  cursor: pointer;
  transition: background 0.2s ease, transform 0.2s ease;
}

.railhost .app-dots button[aria-selected="true"] {
  background: var(--blue-bright);
  transform: scale(1.35);
}

.railhost .app-dots button:focus-visible {
  outline: 2px solid var(--ai-light);
  outline-offset: 3px;
}

.railhost .app-eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ai-light);
}

.railhost .app-h {
  font-family: var(--display);
  font-size: 22px;
  font-weight: 600;
  line-height: 1.3;
  margin-top: 8px;
  color: var(--paper);
}

.railhost .app-btn {
  display: flex;
  margin-top: 18px;
  font-size: 15px;
  padding: 12px 22px;
}

.railhost .app-more {
  display: block;
  text-align: center;
  margin-top: 12px;
  font-size: 13.5px;
  color: var(--ai-light);
}

.railhost .app-more:hover { color: var(--gold); }

/* ── LEGACY: the split ──────────────────────────────────────────────
   Only the hand-written grammar pages in STATIC_SLUGS still carry the
   .gsplit markup. Delete this block once those pages are converted. */
.gpage .gsplit {
  display: grid;
  grid-template-columns: 0.88fr 1.12fr;
  gap: 0 56px;
  padding-top: 54px;
  align-items: stretch;
}

.gpage .gsplit-left,
.gpage .gsplit-right { min-width: 0; }

.gpage .gsplit .gsec { padding-top: 0; }
.gpage .gsplit .gsec + .gsec { padding-top: 30px; }
.gpage .gsplit-left .gsec + .gsec { padding-top: 22px; }
.gpage .gsplit-left .gsec-head { margin-bottom: 12px; }
.gpage .gsplit-left .gsec-head h2 { font-size: clamp(19px, 1.6vw, 21px); }
.gpage .gsplit-left .stab { padding: 10px 15px; font-size: 11.5px; }
.gpage .gsplit-left .sline { padding: 14px 20px; }
.gpage .gsplit-left .sform { font-size: clamp(17px, 1.7vw, 20px); line-height: 1.5; }
.gpage .gsplit-left .snote { font-size: 13px; margin-top: 10px; }
.gpage .gsplit-left .gprose p { font-size: 14.5px; line-height: 1.62; }
.gpage .gsplit-left .gprose p + p { margin-top: 9px; }

/* A narrower rail before the page gives it up: the phone stays on screen
   down to a small laptop window. */
@media (max-width: 1180px) {
  .railhost {
    --grail: 250px;
    --phone-h: clamp(240px, calc(100vh - 316px), 520px);
  }
  .railhost .glayout { gap: 0 44px; }
  .railhost .app-h { font-size: 19px; }
  .railhost .app-btn { font-size: 14px; padding: 11px 16px; }
}

/* One column below this. The rail does not vanish: site.js moves the
   app card into the page right after the sentences, where it lies as a band
   — the phone on the left, the words beside it — so it lands just after the
   reader has seen what the app does. With no JS the card sits at the end of
   the page instead. */
@media (max-width: 960px) {
  .railhost .gwrap-wide { max-width: var(--gmaxw); }

  .railhost .glayout {
    grid-template-columns: 1fr;
    gap: 0;
  }

  /* The run. The rail is tall and the card inside it is still sticky, so
     when the reader reaches the phone it pins under the nav and stays while
     they scroll on through it — site.js turns the five screens over the
     length of the run — and only then does the page carry on to Forms. */
  .railhost .grail {
    padding-top: 0;
    margin-top: 30px;
    height: 320vh;
  }

  .railhost .app-card {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 0 26px;
    align-items: center;
    text-align: left;
    padding: 20px 24px;
    background: var(--plate);
    border: 1px solid var(--plate-line);
    border-radius: 20px;
  }

  .railhost .phone {
    --phone-h: clamp(260px, 42vh, 380px);
    grid-row: 1 / span 5;
    margin: 0;
  }

  .railhost .app-dots { justify-content: flex-start; margin-top: 12px; }
  .railhost .app-h { font-size: 21px; margin-top: 6px; }
  .railhost .app-btn { display: inline-flex; justify-self: start; margin-top: 16px; font-size: 14.5px; padding: 11px 18px; }
  .railhost .app-more { text-align: left; margin-top: 10px; }

  /* legacy split, one column */
  .gpage .gsplit {
    grid-template-columns: 1fr;
    gap: 0;
    padding-top: 0;
  }

  .gpage .gsplit .gsec,
  .gpage .gsplit .gsec + .gsec { padding-top: 54px; }
}

.gpage .gsec-head { margin-bottom: 24px; }

.gpage .gsec-head h2,
.gpage .gsec-head h1 {
  font-size: clamp(21px, 2.4vw, 25px);
  margin-top: 6px;
}

/* The hub pages open on their heading — no hero plate, no lede — so the
   title wears the section-head look and the grid under it drops the padding
   that would otherwise put a second gap between two stacked heads. */
.gpage .ghub-title { margin-top: 26px; }
.gpage .ghub-title + .gsec { padding-top: 0; }

/* ── breadcrumb ───────────────────────────────────────────────────── */

.gpage .gcrumb {
  padding: 26px 0 0;
  font-size: 12.5px;
  color: var(--paper-dim);
  letter-spacing: 0.04em;
}

.gpage .gcrumb a { color: var(--ai-light); }
.gpage .gcrumb a:hover { color: var(--gold); }
.gpage .gcrumb .sep { margin: 0 8px; opacity: 0.5; }
.gpage .gcrumb [aria-current] { color: var(--paper-dim); }

/* ── the point itself ─────────────────────────────────────────────── */

.gpage .gp-hero { padding: 30px 0 8px; }

.gpage .gp-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
}

.gpage .gp-level {
  border: 1px solid var(--gold);
  border-radius: 6px;
  background: color-mix(in srgb, var(--gold) 10%, transparent);
  color: var(--gold);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.1em;
  padding: 3px 9px;
}

.gpage .gp-kind {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ai-light);
}

.gpage .gp-form {
  font-family: var(--display);
  font-size: clamp(38px, 7vw, 62px);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: 0.02em;
}

/* Romaji inside the headline rather than only under it. The <h1> used to hold
   nothing but kana, so a page about you ni naru had no headline matching the
   words anyone searches for. Keyboard spelling here — "you ni naru", not
   "yō ni naru" — since that is what gets typed; the macron transcription keeps
   its place in .gp-romaji below. */
.gpage .gp-h1-romaji {
  display: block;
  font-size: clamp(19px, 2.8vw, 27px);
  font-weight: 500;
  letter-spacing: 0.05em;
  color: var(--gold);
  margin-top: 12px;
}

/* The reading, inline in the headline: 遠慮（えんりょ）. Smaller and quieter
   than the headword so the kanji still reads as the title, but real text in
   the <h1> rather than a caption underneath — that is the line search results
   quote, and someone who typed the kana needs to see it in it. */
.gpage .gp-h1-kana {
  font-size: 0.5em;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--gold);
  white-space: nowrap;
}

.gpage .gp-romaji {
  color: var(--gold);
  font-size: 14px;
  letter-spacing: 0.14em;
  margin-top: 4px;
}

/* The keyboard spelling, because that is the one people type into a search
   box. The macron above is the better transcription and stays first. */
.gpage .gp-alt {
  color: var(--paper-dim);
  letter-spacing: 0.1em;
}

.gpage .gp-en {
  font-family: var(--display);
  font-size: clamp(19px, 2.3vw, 23px);
  color: var(--paper);
  margin-top: 20px;
  line-height: 1.5;
}

.gpage .gp-en .sep { color: var(--gold); margin: 0 5px; opacity: 0.7; }

.gpage .gp-answer { max-width: 68ch; margin: 22px 0 18px; color: var(--paper-dim); font-size: 18px; line-height: 1.7; text-wrap: pretty; }
.gpage .gp-answer strong { color: var(--paper); font-weight: 700; }

.gpage .gp-lede {
  color: var(--paper-dim);
  font-size: 16px;
  margin-top: 16px;
  max-width: 60ch;
}

/* ── structure card ───────────────────────────────────────────────── */

.gpage .struct {
  background: var(--ink-soft);
  border: 1px solid var(--ink-line);
  border-radius: var(--radius);
  overflow: hidden;
}

.gpage .struct-tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--ink-line);
}

.gpage .stab {
  appearance: none;
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  margin: 0;
  padding: 13px 20px;
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--paper-dim);
  cursor: pointer;
  transition: color 0.18s ease, border-color 0.18s ease;
}

.gpage .stab:hover { color: var(--paper); }

.gpage .stab[aria-selected="true"] {
  color: var(--gold);
  border-bottom-color: var(--gold);
}

.gpage .sline { display: none; padding: 26px 24px; }
.gpage .sline.is-on { display: block; }

.gpage .sform {
  font-family: var(--display);
  font-size: clamp(19px, 2.6vw, 25px);
  line-height: 1.6;
}

/* the slot the learner fills in vs. the fixed parts they type verbatim */
.gpage .sform .slot {
  color: var(--ai-light);
  border-bottom: 1px dashed color-mix(in srgb, var(--ai-light) 55%, transparent);
}

.gpage .sform .fixed { color: var(--gold); }
.gpage .sform .plus { color: var(--paper-dim); margin: 0 8px; font-size: 0.8em; }

.gpage .snote {
  color: var(--paper-dim);
  font-size: 14px;
  margin-top: 14px;
  max-width: 56ch;
}

/* ── prose ────────────────────────────────────────────────────────── */

.gpage .gprose p {
  color: var(--paper-dim);
  font-size: 15.5px;
  max-width: 62ch;
}

.gpage .gprose p + p { margin-top: 16px; }

.gpage .gprose b { color: var(--paper); font-weight: 500; }
.gpage .gprose .ja { font-family: var(--display); color: var(--gold); }

/* ── worked examples ──────────────────────────────────────────────── */

.gpage .ex {
  border-top: 1px solid color-mix(in srgb, var(--ink-line) 70%, transparent);
  padding: 34px 0 4px;
}

.gpage .ex:first-of-type { border-top: 0; padding-top: 8px; }

.gpage .ex-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
}

/* the label says what this sentence demonstrates — these are cases, not
   steps, so they are named rather than numbered */
.gpage .ex-pattern {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ai-light);
}

.gpage .ex-reg {
  font-size: 11.5px;
  letter-spacing: 0.1em;
  color: var(--ai-light);
  border: 1px solid color-mix(in srgb, var(--ai-light) 45%, transparent);
  background: color-mix(in srgb, var(--ai-light) 8%, transparent);
  border-radius: 999px;
  padding: 2px 10px;
  flex: none;
}

/* the home page lab is a two-column feature; here it is the whole width */
.gpage .sentence-lab.solo {
  display: block;
  padding: 0;
}

/* Tall enough for the longest word panel on the page, so moving from word to
   word never resizes the card and shifts the sentence you're reading. */
.gpage .solo .sl-card { min-height: 218px; }

.gpage .ex-en {
  color: var(--paper-dim);
  font-size: 15px;
  margin-top: 12px;
  max-width: 60ch;
}

.gpage .ex-en::before {
  content: "→";
  color: var(--gold);
  margin-right: 8px;
  opacity: 0.75;
}

/* the word the page is about, underlined solid in every sentence, in the
   headword's blue — the tapped word beside it is the lighter one */
.gpage .tok.gp {
  border-bottom-color: var(--blue-bright);
  color: var(--blue-bright);
}

/* ── the Anki button ──────────────────────────────────────────────
   On the page it is a demo, so the click answers with where the real
   thing lives. The label is a sentence rather than a word, so the pill
   stops being a pill and wraps inside the column it sits in. */
.gpage .anki-add.added {
  border-radius: 14px;
  max-width: 100%;
  padding: 9px 14px;
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.45;
  text-align: left;
  white-space: normal;
  cursor: default;
}

/* ── contrast + related ───────────────────────────────────────────── */

.gpage .ccards { display: grid; gap: 16px; }

.gpage .ccard {
  background: var(--ink-soft);
  border: 1px solid var(--ink-line);
  border-left: 2px solid var(--shu);
  border-radius: var(--radius);
  padding: 20px 22px;
}

.gpage .ccard h3 {
  font-size: 17px;
  margin-bottom: 8px;
}

.gpage .ccard h3 .ja { color: var(--gold); }
.gpage .ccard p { color: var(--paper-dim); font-size: 14.5px; }

.gpage .rel {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 14px;
}

.gpage .rcard {
  display: block;
  background: var(--ink-soft);
  border: 1px solid var(--ink-line);
  border-radius: var(--radius);
  padding: 16px 18px;
  transition: border-color 0.18s ease, transform 0.18s ease;
}

.gpage .rcard:hover {
  border-color: color-mix(in srgb, var(--gold) 55%, transparent);
  transform: translateY(-2px);
}

.gpage .rcard-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.gpage .rcard-ja {
  font-family: var(--display);
  font-size: 19px;
  color: var(--gold);
}

.gpage .rcard-lv {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--paper-dim);
  flex: none;
}

.gpage .rcard p {
  color: var(--paper-dim);
  font-size: 13px;
  margin-top: 6px;
}

/* ── also asked ───────────────────────────────────────────────────── */
/* The same questions people are already typing into a search box, answered
   short. Deliberately quieter than .ccard — this is the tail of the page,
   not the argument of it. */

.gpage .qa {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 2px;
  background: var(--ink-line);
  border: 1px solid var(--ink-line);
  border-radius: var(--radius);
  overflow: hidden;
}

.gpage .qitem {
  background: var(--ink-soft);
  padding: 20px 22px;
}

.gpage .qitem h3 {
  font-size: 15.5px;
  line-height: 1.45;
  margin-bottom: 8px;
}

.gpage .qitem h3 .ja { color: var(--gold); }

.gpage .qitem p {
  color: var(--paper-dim);
  font-size: 14px;
  line-height: 1.65;
}

.gpage .qitem p .ja { color: var(--ai-light); }

/* An answer that hands off to another point links out of the paragraph. */
.gpage .qitem p a {
  color: var(--ai-light);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--ai-light) 40%, transparent);
}

.gpage .qitem p a:hover {
  color: var(--gold);
  text-decoration-color: var(--gold);
}

/* ── funnel back to the app ───────────────────────────────────────── */

.gpage .gcta {
  margin: 62px 0 0;
  background: var(--ink-soft);
  border: 1px solid var(--ink-line);
  border-radius: var(--radius);
  padding: 34px 30px;
  text-align: center;
}

.gpage .gcta h2 { font-size: clamp(21px, 2.6vw, 26px); }

.gpage .gcta p {
  color: var(--paper-dim);
  font-size: 15px;
  margin: 12px auto 0;
  max-width: 52ch;
}

.gpage .gcta .wait { margin-top: 22px; }

.gpage .gcta-links {
  margin-top: 18px;
  font-size: 13.5px;
  color: var(--paper-dim);
}

.gpage .gcta-links a { color: var(--ai-light); }
.gpage .gcta-links a:hover { color: var(--gold); }

.gpage .gtail { padding-bottom: 90px; }


/* ── the scale ────────────────────────────────────────────────────
   The page is read, not scanned: everything runs a step bigger than the
   home page, and the space around it is the point, not a gap to fill.
   Kept together, and after every rule it overrides, so a size is set in
   one place. */
.gpage .gsec { padding-top: 64px; }
.gpage .gexamples { padding-top: 60px; }
.gpage .gsec-head { margin-bottom: 28px; }
.gpage .gsec-head h2,
.gpage .gsec-head h1 { font-size: clamp(24px, 2.6vw, 30px); }

/* The word, boxed: a plate one step up from the page, the headword large
   and blue at the top, the romaji and the glosses under it. The lede sits
   below the box on the bare page. */
.gpage .gp-hero {
  margin-top: 22px;
  padding: 26px 32px 30px;
  background: var(--plate);
  border: 1px solid var(--plate-line);
  border-radius: 20px;
  text-align: center;
}
.gpage .gp-meta { margin-bottom: 20px; justify-content: center; }
.gpage .gp-form { color: var(--blue-bright); font-weight: 700; }
.gpage .gp-h1-romaji { color: var(--paper); font-size: clamp(24px, 2.8vw, 32px); }
.gpage .gp-h1-tail { color: var(--paper-dim); font-size: 0.7em; font-weight: 400; margin-left: 6px; }
.gpage .gp-en { color: var(--paper-bright); font-weight: 600; font-size: clamp(22px, 2.5vw, 27px); }
.gpage .gp-lede {
  font-size: 18px;
  line-height: 1.7;
  margin-top: 26px;
  max-width: 60ch;
}

.gpage .sl-sentence { font-size: clamp(30px, 3vw, 40px); line-height: 1.65; }
.gpage .sl-hint { font-size: 12.5px; }
.gpage .solo .sl-card { padding: 28px 30px; min-height: 236px; background: var(--card); border-color: var(--card-line); }
.gpage .wp-surface { font-size: 34px; }
.gpage .wp-reading { font-size: 15.5px; }
.gpage .wp-gloss { font-size: 18px; }
.gpage .wp-fn { font-size: 14.5px; }

.gpage .ex {
  background: var(--plate);
  border: 1px solid var(--plate-line);
  border-radius: 20px;
  padding: 26px 30px 22px;
}
.gpage .ex:first-of-type { border-top: 1px solid var(--plate-line); padding-top: 26px; }
.gpage .ex + .ex { margin-top: 18px; }
.gpage .ex-pattern,
.gpage .ex-reg { font-size: 12px; }
.gpage .ex-en { font-size: 16.5px; margin-top: 14px; max-width: 64ch; }

.gpage .gprose p { font-size: 17px; line-height: 1.72; max-width: 68ch; }
.gpage .gprose p + p { margin-top: 18px; }

.gpage .stab { font-size: 13px; padding: 14px 22px; }
.gpage .sline { padding: 28px 26px; }
.gpage .sform { font-size: clamp(21px, 2.6vw, 27px); }
.gpage .snote { font-size: 15px; margin-top: 16px; max-width: 60ch; }

.gpage .ccard { padding: 22px 24px; }
.gpage .ccard h3 { font-size: 18px; }
.gpage .ccard p { font-size: 15px; }
.gpage .qitem h3 { font-size: 16.5px; }
.gpage .qitem p { font-size: 14.5px; }

/* ── mobile ───────────────────────────────────────────────────────── */

@media (max-width: 680px) {
  .railhost .gwrap { padding: 0 20px; }
  .gpage .gsec { padding-top: 44px; }
  .gpage .gp-hero { padding-top: 22px; }

  .gpage .ex-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .gpage .sline { padding: 22px 20px; }
  .gpage .ex { padding: 20px 18px 18px; border-radius: 16px; }

  /* On a phone the word card answers the tap directly under the words, with
     the contour and the hint after it — on a desktop it sits below both,
     which on a phone put it under the fold, so a tap looked like nothing. */
  .gpage .sentence-lab.solo { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; }
  .gpage .sentence-lab.solo > * { min-width: 0; }   /* the wide contours scroll inside their box instead of widening the page */
  .gpage .solo .sl-card { order: 1; margin-top: 16px; }
  .gpage .solo .sl-contour { order: 2; margin-top: 18px; }
  .gpage .solo .sl-hint { order: 3; }
  /* On a phone the device IS the card: no plate, no words, no dots — just
     the phone and one button under it — and it takes every pixel under the
     nav that the button leaves, so the pinned run fills the screen. 80vw is
     the ceiling, so it never spans edge to edge. */
  .railhost { --gtop: 76px; }    /* the nav is one row, ~62px, here */
  .railhost .app-card { display: block; text-align: center; padding: 0; background: none; border: 0; }
  .railhost .phone {
    --phone-h: max(300px, min(calc(100vh - var(--gtop) - 78px), calc((80vw - 14px) / 0.4614 + 14px)));
    /* iOS Safari's 100vh is the screen with its bars hidden; svh is the
       screen with them showing, so the pinned card fits either way */
    --phone-h: max(300px, min(calc(100svh - var(--gtop) - 78px), calc((80vw - 14px) / 0.4614 + 14px)));
    margin: 0 auto;
  }
  .railhost .app-eyebrow,
  .railhost .app-h,
  .railhost .app-more,
  .railhost .app-dots { display: none; }
  .railhost .app-btn { display: inline-flex; margin-top: 10px; font-size: 14px; padding: 10px 20px; }
  .gpage .qitem { padding: 18px 20px; }
  .gpage .gcta { padding: 28px 20px; }
  .gpage .gtail { padding-bottom: 70px; }
}
