/* Landing page — built to docs/DESIGN.md. Read that first.
   Tokens, type roles and the motion budget all come from there. */

@import url('fonts.css');

.lp {
  /* §3 Colour — one chromatic accent, everything else paper/ink/hairline */
  --paper: #FBFAF8;
  --wash: #F4F3F0;
  --speaker: #F2EFEA;
  --ink: #14161A;
  --ink-soft: #5A6068;
  /* 5.14:1 on --paper. DESIGN.md §3 specified #8B9098, which measures 3.08:1 —
     below the 4.5:1 of WCAG 1.4.3, and this token carries real text: the section
     markers, the rail numbers, the row numbers, the transcript speaker labels
     and the disclosure glyph. assets/app.css reached the same conclusion about
     its own --faint and moved first; this is the same correction on the page
     more people see. Kept distinct from --ink-soft so the tier still reads as
     quieter. */
  --ink-faint: #666B73;
  --rule: #E2E0DB;
  --rule-strong: #C9C6BF;
  --signal: #7A1F2B;

  --measure: 66ch;
  --gutter: 24px;
  --max: 1200px;

  background: var(--paper);
  color: var(--ink);
  font-family: 'Geist', sans-serif;
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* ── Type roles (§4). Serif = a person speaking. Grotesque = the system.
      Mono = a fact. Never use the serif decoratively. ─────────────────── */
.lp .mono { font-family: 'Geist Mono', ui-monospace, monospace; font-weight: 500; font-size: .82em; }
.lp .eyebrow {
  font-weight: 500; font-size: 13px; text-transform: uppercase;
  letter-spacing: .12em; color: var(--ink-soft); margin: 0 0 24px;
  /* Uncontained — never a pill. The reference gallery uses this 15/60 vs 6/60. */
}
.lp .micro { font-size: 13px; color: var(--ink-soft); }
.lp .lede { font-size: 20px; line-height: 1.55; max-width: 46ch; }

.lp-thesis {
  font-family: 'Geist', sans-serif; font-weight: 600;
  /* Sized for the column it sits in, not the page. It was clamped to 58px when
     it spanned the full width; in half that measure the serif line ran past the
     column and the forced breaks stopped meaning anything. */
  font-size: clamp(30px, 3.5vw, 44px); line-height: 1.08;
  letter-spacing: -.022em; margin: 0 0 28px;
}
/* Instrument Serif for the two nouns the product is. DESIGN.md reserves the
   serif for a person speaking, and this is the one place the page speaks in
   its own voice rather than describing itself — the optical size and the
   -0.01em pull keep it sitting on the same baseline as the grotesque. */
.lp-thesis em {
  font-family: 'Instrument Serif', Georgia, serif;
  font-style: normal; font-weight: 400;
  /* Optically matched, not numerically: Instrument Serif's lowercase runs
     smaller than Geist's at the same size, so it needs the extra 10% and a
     touch of negative tracking to sit as one line of the same voice. */
  font-size: 1.1em; letter-spacing: -.012em;
  /* The claret, on the one phrase that names the product. DESIGN.md §3 keeps
     the accent for interactive and current state; this is the deliberate
     exception, recorded there — it is the brand colour on the brand promise,
     and it measures 9.8:1 on paper. */
  color: var(--signal);
}
.lp-thesis-tail { color: var(--ink-soft); font-size: .74em; letter-spacing: -.015em; }
.lp-thesis-sm { font-weight: 600; font-size: clamp(26px, 3.6vw, 40px); letter-spacing: -.02em; margin: 0 0 24px; }

.lp h2 { font-weight: 600; font-size: clamp(22px, 2.6vw, 34px); letter-spacing: -.02em; margin: 0 0 20px; line-height: 1.15; }
.lp h3.sub { font-weight: 600; font-size: 17px; letter-spacing: 0; margin: 40px 0 12px; }
.lp p { max-width: var(--measure); }

/* The one place the serif is allowed: words somebody actually said. */
.lp .spoken {
  font-family: 'Instrument Serif', Georgia, serif;
  font-weight: 400; font-style: normal;
  font-size: clamp(22px, 2.8vw, 30px); line-height: 1.3; letter-spacing: -.01em;
  margin: 0 0 24px; padding: 20px 24px;
  background: var(--speaker); border-left: 2px solid var(--rule-strong);
  max-width: 40ch;
}

/* ── Links + the single accent (§3) ──────────────────────────────────── */
.lp a { color: var(--signal); text-underline-offset: 3px; text-decoration-thickness: 1px; }
.lp a:hover { text-decoration-thickness: 2px; }
.lp :is(a, button, [tabindex]):focus-visible {
  outline: 2px solid var(--signal); outline-offset: 3px; border-radius: 2px;
}

.lp .btn-primary {
  display: inline-block; margin: 8px 0 12px;
  padding: 13px 22px; border: 1px solid var(--ink); border-radius: 4px;
  background: var(--ink); color: var(--paper);
  font-weight: 500; font-size: 15px; letter-spacing: .01em; text-decoration: none;
  /* Neutral, not accent-filled: 82% of the reference set uses neutral CTAs. */
  transition: background .18s ease, border-color .18s ease;
}
.lp .btn-primary:hover { background: #000; border-color: #000; }

/* Google's button, in the LIGHT variant they publish.

   Their guidance is unchanged — the full-colour mark, unmodified, with clear
   space around it and the wordmark beside it. What changed is the face. Filled
   ink was the only solid black on the page and read as heavy against the paper;
   Google offer a light button for exactly this ground, so this is softer and
   still THEIR button rather than our recolouring of one. It also now matches
   the Google button on the sign-in page, which was already an outline.

   #747775 is Google's specified stroke, and it is here rather than
   --rule-strong for a measurable reason: WCAG 2.2 (1.4.11) wants 3:1 for the
   boundary of a control, and --rule-strong measures 1.63:1 on paper against
   #747775's 4.34:1. A hairline is right for dividing content and too faint to
   carry the edge of a button. */
.lp .btn-primary.btn-google {
  display: inline-flex; align-items: center; gap: 12px;
  background: transparent;
  border-color: #747775;
  color: var(--ink);
}
/* One class more than `.lp .btn-primary:hover`, so this wins outright instead
   of on declaration order — the tie that once left two hero transcripts
   stacked on this same page. */
.lp .btn-primary.btn-google:hover {
  background: transparent;
  border-color: var(--ink);
}
.lp .btn-google .g-mark {
  width: 18px; height: 18px; flex: none;
  /* The white tile went with the ink face. Google's mark is drawn for a light
     ground and is now sitting on one. The 2px stays — it is the clear space
     their guidance asks for, and keeping it stops the wordmark shifting. */
  padding: 2px; box-sizing: content-box;
}

/* ── Hero ─────────────────────────────────────────────────────────────── */
.lp-hero { max-width: var(--max); margin: 0 auto; padding: 72px var(--gutter) 0; }
/* Equal columns, both starting at the same top edge. The right column was
   1.05fr when the headline sat above the grid and only the lede shared the
   row; now the whole argument is on the left, so the two carry the same
   weight. */
.lp-hero-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 48px; align-items: stretch; }
/* The copy column fills the row so its sign-in block can sit on the film's
   bottom edge. `stretch` above rather than `start`: with `start` the column was
   only as tall as its text and left a wedge of empty page beneath it. */
.lp-hero-copy { display: flex; flex-direction: column; }
.lp-hero-cta { margin-top: auto; padding-top: 8px; }
.returning-note { font-size: 15px; color: var(--ink-soft); margin: 0 0 4px; }

/* Sits with the sign-in button rather than drifting a full paragraph below it.
   Kept as inline text: making it a flex row turns each "·" separator into its
   own anonymous flex item, which is a lot of machinery for three links. */
.lp-jump { margin: 6px 0 0; line-height: 1.9; }

.lp-video { margin: 0; }
.lp-video video {
  width: 100%; height: auto; display: block;
  border: 1px solid var(--rule); border-radius: 6px; background: var(--wash);
  /* Explicit ratio so the poster reserves space — measured CLS 0. Must match
     the encoded frame: this said 846/686 after the films were re-cut to
     920×840, and the mismatch letterboxed both of them, which read as a large
     empty margin around the hero. Both clips are encoded onto this one canvas
     precisely so the mode switch cannot move the page. */
  aspect-ratio: 920 / 840;
}
/* The mode switch. Two tabs sharing one frame — a segmented control, because
   the choice is between two views of one thing, not two destinations. */
.lp-modes {
  display: inline-flex; margin: 0 0 12px;
  border: 1px solid var(--rule-strong); border-radius: 5px; overflow: hidden;
}
.lp-modes button {
  font: inherit; font-size: 13px; font-weight: 500; letter-spacing: .01em;
  padding: 7px 15px; border: 0; background: transparent; color: var(--ink-soft);
  cursor: pointer; transition: background .15s ease, color .15s ease;
  /* app.css styles every bare <button> as a filled control with a 10px radius.
     This reset only cleared `border`, so the radius leaked through and each tab
     drew its own rounded corners INSIDE a 5px container — two pills in a box
     rather than one segmented control. The research page's identical-looking
     switch escapes it only by being built from <a> elements, which carry no
     such default. Squared off here so the container's own radius and its
     overflow:hidden do the shaping, exactly as .rs-modes does. */
  border-radius: 0;
  /* Same source: the global rule adds a transform/shadow transition and a
     flex gap meant for icon buttons. Neither belongs on a text tab. */
  gap: 0;
}
.lp-modes button + button { border-left: 1px solid var(--rule-strong); }
.lp-modes button:hover { color: var(--ink); }
/* Claret, not ink: DESIGN.md reserves the accent for interactive and current
   state, and this IS current state. Filled ink also left the selected tab as
   the heaviest thing in the hero, outweighing the sign-in button beside it.
   Paper on claret measures 9.78:1. */
.lp-modes button[aria-selected="true"] { background: var(--signal); color: var(--paper); }
.lp-modes button:focus-visible {
  outline: 2px solid var(--signal); outline-offset: -3px;
}
/* The ring is drawn INSIDE the button, so on a claret pill a claret ring is
   claret on claret — 1.00:1, and a keyboard user loses the focus indicator on
   the one tab they are standing on. Paper against the fill instead. */
.lp-modes button[aria-selected="true"]:focus-visible { outline-color: var(--paper); }

.lp-video-toggle {
  margin-top: 10px; padding: 6px 12px; font: inherit; font-size: 13px; font-weight: 500;
  background: transparent; color: var(--ink); border: 1px solid var(--rule-strong);
  border-radius: 4px; cursor: pointer;
}
.lp-video-toggle:hover { border-color: var(--ink); }
.lp-video figcaption { margin-top: 10px; max-width: 46ch; }


/* ── Body: rail + rows ────────────────────────────────────────────────── */
.lp-body { max-width: var(--max); margin: 0 auto; padding: 0 var(--gutter); display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 56px; }

.lp-rail { position: sticky; top: 88px; align-self: start; padding-top: 96px; }
.lp-rail ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.lp-rail a { display: block; color: var(--ink-soft); text-decoration: none; font-size: 14px; padding-left: 12px; border-left: 2px solid var(--rule); }
.lp-rail a:hover { color: var(--ink); }
.lp-rail a[aria-current="true"] { color: var(--signal); border-left-color: var(--signal); }
.lp-rail .mono { color: var(--ink-faint); margin-right: 6px; }

.lp-main { min-width: 0; }
.lp-main .row {
  display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 20px;
  padding: 96px 0; border-top: 1px solid var(--rule);
  /* §7 — biggest single performance win in the document (FCP 1156ms → 152ms). */
  content-visibility: auto;
  contain-intrinsic-size: auto 640px;
}
.lp-main .row:first-child { border-top: 0; }
.row-n { color: var(--ink-faint); margin: 6px 0 0; }

/* ── Facts (§5) — hairlines, never cards ──────────────────────────────── */
.facts { display: grid; grid-template-columns: 180px minmax(0, 1fr); gap: 0; margin: 8px 0 0; }
.facts dt { font-weight: 500; padding: 14px 12px 14px 0; border-top: 1px solid var(--rule); }
.facts dd { margin: 0; padding: 14px 0; border-top: 1px solid var(--rule); color: var(--ink-soft); }

.lp-close { padding: 96px 0; border-top: 1px solid var(--rule); }

/* ── Footer as an information surface ─────────────────────────────────── */
.lp-foot { max-width: var(--max); margin: 0 auto; padding: 40px var(--gutter) 72px; border-top: 1px solid var(--rule); color: var(--ink-soft); }
.lp-foot p { margin: 0 0 6px; }

/* ── Motion (§7). ONE moving thing per viewport; in the hero that is the
      video, so nothing else here animates above the fold.
      Rule 1: the hidden state lives in the KEYFRAME, never the base rule —
      putting it in the base rule rendered a hero as an empty white box in
      Firefox 141. Content is visible with no CSS animation support, with JS
      disabled, and under reduced motion. ─────────────────────────────── */
@media (prefers-reduced-motion: no-preference) {
  .lp-main .row > * { animation: lp-rise .6s cubic-bezier(.22,.8,.28,1) both; }
  .lp-main .row > *:nth-child(2) { animation-delay: 60ms; }
  /* Rule 2: a scroll-driven timeline can REST part-way through, unlike a
     time-based one that always finishes. An element sitting at the fold on
     load stops mid-keyframe and stays there — on the FAQ at 360px that left
     body text at 79% opacity, i.e. 3.81:1, under the 4.5:1 AA minimum. So the
     scroll-linked variant moves the element and never touches its opacity;
     the fade belongs to the time-based rule, which is guaranteed to complete.
     (Firefox never showed this: it has no animation-timeline and falls back.) */
  @supports (animation-timeline: view()) {
    .lp-main .row > * {
      animation-name: lp-slide;
      animation-timeline: view();
      animation-range: entry 0% entry 42%;
    }
  }
}
@keyframes lp-rise { from { opacity: 0; translate: 0 12px } to { opacity: 1; translate: 0 0 } }
@keyframes lp-slide { from { translate: 0 12px } to { translate: 0 0 } }

/* ── Responsive ───────────────────────────────────────────────────────── */
@media (max-width: 900px) {
  .lp-hero { padding-top: 48px; }
  .lp-hero-grid { grid-template-columns: 1fr; gap: 32px; }
  .lp-body { grid-template-columns: 1fr; gap: 0; }
  .lp-rail { display: none; }          /* the markers already give navigation */
  .lp-main .row { grid-template-columns: 1fr; gap: 8px; padding: 64px 0; }
  .row-n { margin: 0; }
  .facts { grid-template-columns: 1fr; }
  .facts dd { border-top: 0; padding-top: 0; }
}
@media (max-width: 460px) {
  .lp { font-size: 16px; }
  .lp .spoken { padding: 16px; }
}

/* ── Video transcript (§8) ────────────────────────────────────────────────
   The clip is muted and its on-screen type is small, so a caption track alone
   is not a sufficient alternative. A readable transcript is also simply good
   information for this audience. <details> keeps it collapsed without hiding
   it from assistive technology or from find-in-page in modern browsers. */
.lp-transcript { margin-top: 14px; border-top: 1px solid var(--rule); padding-top: 12px; }
.lp-transcript summary {
  cursor: pointer; font-size: 14px; font-weight: 500; color: var(--ink-soft);
  list-style: none;
}
.lp-transcript summary::-webkit-details-marker { display: none; }
.lp-transcript summary::before { content: '＋ '; color: var(--ink-faint); }
.lp-transcript[open] summary::before { content: '－ '; }
.lp-transcript summary:hover { color: var(--ink); }
/* `hidden` has to win. The UA rule is [hidden]{display:none} at specificity
   (0,1,0), and so is `.lp-lines{display:grid}` — later wins, so the attribute
   did nothing and BOTH hero transcripts rendered, stacked, whichever mode was
   showing. Any class that sets `display` can silently disable `hidden`; this
   scopes the guard to the landing page rather than trusting each one. */
.lp [hidden] { display: none !important; }
.lp-lines { margin: 14px 0 0; padding: 0 0 0 0; list-style: none; display: grid; gap: 10px; font-size: 15px; }
.lp-lines li { display: grid; grid-template-columns: 66px minmax(0, 1fr); gap: 12px; color: var(--ink-soft); }
.lp-lines .who {
  font-family: 'Geist Mono', ui-monospace, monospace; font-size: 12px; font-weight: 500;
  color: var(--ink-faint); padding-top: 3px;
}

/* Wordmark in the footer. The landing page is paper-only (dark mode was
   removed), so it needs just the one mark variant. */
.lp-wordmark {
  display: flex; align-items: center; gap: 9px;
  font-family: 'Fraunces Wordmark', Georgia, serif;
  font-weight: 700; font-size: 21px; letter-spacing: -.02em;
  color: var(--ink); margin: 0 0 10px;
}
.lp-wordmark a {
  display: inline-flex; align-items: center; gap: 8px;
  color: inherit; text-decoration: none;
}
.lp-wordmark a:hover, .lp-wordmark a:focus-visible { text-decoration: underline; text-underline-offset: 4px; }
.lp-wordmark em { font-style: normal; color: var(--signal); }
.lp-wordmark-mark {
  width: 1.15em; height: 1.15em; flex: none;
  background: url('brand/mark.png') center / contain no-repeat;
}

/* ── Account pages (sign in / sign up / forgot / reset) ──────────────────
   Deliberately the landing page's tokens rather than a second visual
   language: these four screens are the first product surface most people
   see. One column, hairline rules, no card shadow — the form IS the page,
   so it does not need a box drawn around it to be found. */
.lp-account { padding: 0 0 96px; }
.lp-account .acct {
  max-width: 27rem; margin: 0 auto; padding: 64px var(--gutter) 0;
}
.lp-account .eyebrow { margin-bottom: 18px; }
.lp-account .eyebrow .mono { color: var(--signal); }
.acct-standfirst { color: var(--ink-soft); font-size: 16px; margin: 0 0 30px; }

.acct-form { display: grid; gap: 18px; }
.acct-field { display: grid; gap: 6px; }
.acct-field > span:first-child {
  font-size: 13px; font-weight: 500; letter-spacing: .02em; color: var(--ink);
}
.acct-field input {
  font: inherit; font-size: 16px; color: var(--ink);
  padding: 11px 12px; background: #FFFDFB;
  border: 1px solid var(--rule-strong); border-radius: 4px;
  /* Border-based depth only — see the guardrails in CLAUDE.md. */
  transition: border-color .15s ease, box-shadow .15s ease;
}
/* The enquiry form's textarea wears the input's clothes. Same border, same
   focus ring — a message box that looks like a different species from the
   fields above it reads as an afterthought. */
.acct-field textarea {
  font: inherit; font-size: 16px; line-height: 1.5; color: var(--ink);
  padding: 11px 12px; background: #FFFDFB;
  border: 1px solid var(--rule-strong); border-radius: 4px;
  transition: border-color .15s ease, box-shadow .15s ease;
  resize: vertical; min-height: 140px;
}
.acct-field :is(input, textarea):hover { border-color: var(--ink-faint); }
.acct-field textarea:focus-visible {
  outline: none; border-color: var(--ink);
  box-shadow: 0 0 0 3px rgba(122, 31, 43, .22);
}
.acct-field :is(input, textarea)[aria-invalid="true"] { border-color: var(--signal); }
.acct-opt { color: var(--ink-faint); font-weight: 400; }

/* A field's error sits under the field it belongs to, named in words. Colour
   is not carrying the meaning — the sentence is (WCAG 1.4.1). */
.acct-err { font-size: 14px; color: var(--signal); }

/* Outcome panels. Hairline, no fill: depth is a rule, never a shadow. */
.acct-sent, .acct-problem {
  border: 1px solid var(--rule-strong); border-left: 2px solid var(--signal);
  border-radius: 4px; padding: 16px 18px; margin: 0 0 28px;
}
.acct-sent p, .acct-problem p { margin: 0 0 8px; }
.acct-sent p:last-child, .acct-problem p:last-child { margin-bottom: 0; }

/* The honeypot. Off the canvas rather than display:none, which some bots skip;
   never reachable by keyboard or screen reader. */
.acct-hp {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden;
}

.acct-field input:hover { border-color: var(--ink-faint); }
.acct-field input:focus-visible {
  outline: none; border-color: var(--ink);
  /* A ring rather than a shadow: it is the focus indicator, not decoration.
     3:1 against the paper, which is the WCAG 1.4.11 floor. */
  box-shadow: 0 0 0 3px rgba(122, 31, 43, .22);
}
.acct-hint { color: var(--ink-faint); }

.lp-account .btn-primary { margin: 4px 0 0; text-align: center; cursor: pointer; }
/* Links keep the landing page's claret (.lp a) — they are the same kind of
   link on the same paper, and a second link colour here would be a second
   accent by the back door. */
.acct-links { margin: 0; }

/* The alternate door. Quieter than the primary action but not hidden — an
   institution's staff arrive this way. */
.acct-alt { margin-top: 34px; padding-top: 22px; border-top: 1px solid var(--rule); }
.acct-alt p { margin: 0 0 12px; }

/* On the signup page this block comes FIRST, not after the form, and the two
   ran together: the button sat directly on top of "Or use an email address",
   which sat directly on top of the first field. `.acct-links { margin: 0 }` is
   right where it ends a form and wrong where it introduces one. Space it as the
   separator it is here. */
.acct-alt + .acct-links {
  margin: 22px 0 18px;
  color: var(--ink-soft);
}
/* .lp-qualified: `.lp a` sets the claret link colour and would otherwise
   outrank a bare class here, leaving this reading as a link rather than the
   secondary button it is. */
/* The same Google button as the hero's, so the two match. #747775 rather than
   --rule-strong for the same contrast reason given up at .btn-google. */
.lp .acct-alt-btn {
  display: inline-block; padding: 11px 18px;
  border: 1px solid #747775; border-radius: 4px;
  background: transparent; color: var(--ink); text-decoration: none;
  font-size: 15px; font-weight: 500;
}
.lp .acct-alt-btn:hover { border-color: var(--ink); text-decoration: none; }

.acct-note { margin-top: 30px; padding-top: 20px; border-top: 1px solid var(--rule); }
.acct-note p { margin: 0 0 10px; max-width: none; }
.acct-note p:last-child { margin-bottom: 0; }
.acct-who { font-size: 15px; color: var(--ink-soft); margin: 0; }

@media (max-width: 520px) {
  .lp-account .acct { padding-top: 40px; }
}

/* ── Practice-hour packs (?page=plans) ───────────────────────────────────
   A list, not a pricing grid: the packs differ in one number, so that
   number leads each row and everything else follows it. No cards, no
   badges, no "most popular" — three boxes with icons is the shape every
   AI-generated pricing page takes, and this is not one. */
.acct.acct-wide { max-width: 44rem; }
.plan-balance {
  margin: 0 0 6px; font-size: 18px; color: var(--ink);
  padding-bottom: 18px; border-bottom: 1px solid var(--rule);
}
.plan-balance strong { font-weight: 600; }
.plan-note { margin: 10px 0 40px; }

.lp-account .plan-h { font-size: 22px; font-weight: 600; letter-spacing: -.01em; margin: 0 0 6px; }
.plan-lede { color: var(--ink-soft); font-size: 15px; margin: 0 0 18px; max-width: 52ch; }

.plan-list { list-style: none; margin: 0 0 14px; padding: 0; border-top: 1px solid var(--rule); }
.plan-row {
  display: grid; grid-template-columns: 7rem minmax(0, 1fr) auto;
  gap: 20px; align-items: baseline;
  padding: 20px 0; border-bottom: 1px solid var(--rule);
}
.plan-figure {
  margin: 0; font-size: 28px; font-weight: 500; letter-spacing: -.02em; color: var(--ink);
  line-height: 1;
}
.plan-figure span {
  display: block; font-size: 11px; font-weight: 500; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-faint); margin-top: 6px;
}
.plan-body h3 { margin: 0 0 4px; font-size: 16px; font-weight: 600; }
.plan-body p { margin: 0; font-size: 15px; color: var(--ink-soft); max-width: 40ch; }
.plan-cta { margin: 0; font-size: 15px; white-space: nowrap; text-align: right; }
.plan-price { display: block; font-weight: 600; color: var(--ink); margin-bottom: 4px; }
/* The billing period sits with the figure, not above it: the number is what is
   being compared and the qualifier must not compete with it for weight. */
.plan-per { font-weight: 400; font-size: 13px; color: var(--ink-faint); }
.plan-more { margin: 0 0 44px; }

/* The per-hour figure. It sits with the blurb rather than the price because it
   is how the packs are compared to EACH OTHER — the number beside the button is
   what this one costs, and two numbers in one column would read as a discount. */
.plan-hourly { margin: 6px 0 0; max-width: 44ch; white-space: normal; }

/* A form, but visually just the button inside it. */
.plan-buy { margin: 0; }
.lp-account .plan-buy .btn-primary { margin: 0; display: inline-block; }
.lp .btn-primary.btn-sm { padding: 8px 16px; font-size: 14px; }

/* ── Usage tables (?page=usage) ───────────────────────────────────────────
 *
 * A data table is new on an account page, so it gets its own rule rather than
 * borrowing one. Hairlines under rows, no card, no zebra: the design contract
 * is depth-by-rule, and a striped table reads as a spreadsheet rather than as
 * a statement.
 *
 * The figures are the point of the page, so they get tabular numerals — without
 * them the minute columns fail to line up digit-for-digit and the eye cannot
 * compare two rows without reading both. */
.usage-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
  /* Below this the columns crush rather than wrap; .table-scroll takes over. */
  min-width: 520px;
}
.usage-table th,
.usage-table td {
  text-align: left;
  padding: 12px 16px 12px 0;
  border-bottom: 1px solid var(--rule);
  vertical-align: top;
}
.usage-table th {
  font-size: 11px; font-weight: 500; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-faint);
  padding-bottom: 8px;
}
.usage-table tbody tr:last-child td { border-bottom: 0; }
.usage-table td:last-child,
.usage-table th:last-child { padding-right: 0; }

/* Figures right-aligned and monospaced-by-figure, so columns compare. */
.usage-table .u-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* A qualifier under a cell's main value — "live voice", "your own test run".
   On its own line, quieter, and never competing with the value above it. */
.u-tag {
  display: block;
  margin-top: 3px;
  font-size: 12px;
  color: var(--ink-faint);
}

/* The scroll container is defined in app.css, which every account page also
   loads; this only sets the floor width for THIS table, since the shared rule
   assumes the wider dashboard tables. */
.table-scroll > .usage-table { min-width: 520px; }
.lp-account .table-scroll { margin: 0 0 8px; }

/* ── The usage page's own furniture ───────────────────────────────────────── */

/* The page carries its navigation now the balance banner does not sit above it.
   Sits above the eyebrow, quiet, and wraps rather than scrolling on a phone. */
/* The control on its own line, the explanation under it. Run together they
   read as one sentence that happens to start with a button — and the eye has
   to find where the clickable part ends. */
.plan-manage { display: grid; gap: 4px; justify-items: start; }

/* A form that is only a control. Without this the block-level form pushes the
   button onto its own line and breaks the nav row it belongs to. */
.nav-post { display: inline; margin: 0; }
.nav-post .page-action { vertical-align: baseline; }

.acct-nav {
  display: flex; flex-wrap: wrap; gap: 8px 22px;
  margin: 0 0 26px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--rule);
}

/* Donut beside the sentence that states the same numbers exactly.
   The ring is the glance; the words are the answer. */
.usage-summary {
  display: flex; align-items: center; gap: 26px;
  margin: 0 0 8px;
}
.usage-summary-text { min-width: 0; flex: 1 1 auto; }
.usage-summary .plan-balance { border-bottom: 0; padding-bottom: 0; margin-bottom: 4px; }
.usage-summary .plan-note { margin: 0; }
.chart-donut { display: block; flex: none; }

@media (max-width: 560px) {
  /* Stacked, and smaller: at this width the ring beside the text squeezes the
     sentence into three or four words a line. */
  .usage-summary { flex-direction: column; align-items: flex-start; gap: 14px; }
  .usage-summary .chart-donut { width: 64px; height: 64px; }
}

/* ── Bars, inside the by-chatbot table ────────────────────────────────────── */

/* Ink, never claret: docs/DESIGN.md reserves the accent for interactive and
   current state and forbids it as a background, which a filled bar is. A
   monochrome mark on paper also reads as measurement rather than as branding. */
.chart-bar {
  display: block;
  height: 8px;
  border-radius: 2px;
  background: var(--rule);
  overflow: hidden;
}
.chart-bar-fill {
  display: block;
  height: 100%;
  background: var(--ink-soft);
  border-radius: 2px;
}
.u-bar-cell { width: 40%; vertical-align: middle; padding-right: 16px; }
.u-bar-head { width: 40%; }

@media (max-width: 640px) {
  /* The stacked layout gives every cell a label and its own line. A bar has no
     label worth printing and no number of its own — it is the row's own figure
     drawn — so it spans the row under the name instead of taking a line. */
  .usage-table-bars .u-bar-cell {
    width: auto;
    display: block;
    padding: 6px 0 2px;
  }
  .usage-table-bars .u-bar-cell::before { content: none; }
}

/* On a phone the table stacks instead of scrolling.
 *
 * Scrolling was the first answer and it was the wrong one HERE: the figures
 * are the whole point of this page, and they were the part pushed off the
 * right edge — so the reader saw four dates and had to swipe to learn anything.
 * Each row becomes a small block with its column name beside each value.
 * The names come from data-label, so the <th> row can stay for screen readers
 * and for the wider layout, and there is no second copy of the headings to
 * fall out of step with the first. */
@media (max-width: 640px) {
  .lp-account .table-scroll { overflow-x: visible; }
  .usage-table,
  .table-scroll > .usage-table { min-width: 0; display: block; }
  .usage-table thead {
    /* Hidden from sight, kept for assistive technology. */
    position: absolute; width: 1px; height: 1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  }
  .usage-table tbody,
  .usage-table tr { display: block; }
  .usage-table tr {
    padding: 14px 0;
    border-bottom: 1px solid var(--rule);
  }
  .usage-table tbody tr:last-child { border-bottom: 0; }
  /* Grid, not flex: a cell can hold a value AND a qualifier ("live voice"),
     and as flex siblings those two sat side by side and forced each other to
     wrap. Two columns — label, then value — with the qualifier dropping to a
     second row under the value where it belongs. The value itself is an
     anonymous grid item (a bare text node), which auto-places into the free
     cell beside the label. */
  .usage-table td {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    gap: 2px 16px;
    padding: 3px 0;
    border-bottom: 0;
    text-align: right;
  }
  .usage-table td[data-label]::before {
    content: attr(data-label);
    grid-column: 1; grid-row: 1;
    text-align: left;
    font-size: 11px; font-weight: 500; letter-spacing: .1em; text-transform: uppercase;
    color: var(--ink-faint);
    padding-top: 3px;
  }
  .usage-table td .u-tag { grid-column: 2; margin-top: 0; text-align: right; }
}

@media (max-width: 640px) {
  .plan-row { grid-template-columns: 5.5rem minmax(0, 1fr); }
  .plan-figure { font-size: 24px; }
  .plan-cta { grid-column: 2; text-align: left; }
}

/* The pack list already closes with a hairline; the note that follows must not
   draw a second one two pixels below it. */
.plan-list + .acct-note { border-top: 0; margin-top: 26px; padding-top: 0; }

/* Supporting-research page: the reference list. Hanging indents like a printed
   bibliography; DOIs may wrap anywhere or they overflow a phone viewport. */
.rs-refs { list-style: none; margin: 8px 0 0; padding: 0; }
.rs-refs li {
  font-size: 14px; line-height: 1.55; color: var(--ink-soft);
  padding: 10px 0 10px 1.6em; text-indent: -1.6em;
  border-top: 1px solid var(--rule);
}
.rs-refs li:first-child { border-top: 0; padding-top: 0; }
.rs-refs a { overflow-wrap: anywhere; }

/* In-text citations on the research page. The parenthetical author–year is a
   link into .rs-refs; keep it quieter than a prose link so a paragraph with
   four citations doesn't read as a wall of accent. */
/* Citations are links and dress like the site's other links — claret with an
   underline. The grey special-case failed WCAG's link-distinction check in the
   two paragraphs where it sat against bold ink. */
.lp .cite { color: var(--signal); }

/* Landing on a reference from a citation: mark the entry, glyph-and-tone only
   is not enough here because nothing names it — a short-lived wash does. */
.rs-refs li:target {
  background: var(--wash);
  box-shadow: inset 2px 0 0 var(--signal);
  padding-left: calc(1.6em + 12px); text-indent: -1.6em;
  scroll-margin-top: 24px;
}

/* FAQ: open editorial Q&A, no accordions. Questions are the grotesque — the
   serif stays reserved for words somebody actually said. */
.qa { margin: 8px 0 0; }
.qa h3 {
  font-weight: 600; font-size: 18px; letter-spacing: -.01em; line-height: 1.3;
  margin: 0 0 10px; padding-top: 24px; border-top: 1px solid var(--rule);
  max-width: var(--measure); scroll-margin-top: 24px;
}
.qa h3:first-child { border-top: 0; padding-top: 0; }
.qa p { color: var(--ink-soft); margin: 0 0 24px; }
.qa p strong { color: var(--ink); font-weight: 600; }
.qa .qa-more { display: block; margin-top: 6px; font-size: 13px; width: fit-content; }


/* The header is a sticky band now, so a followed anchor must stop clear of it
   or the section heading lands underneath the band. */
.lp section[id],
.lp [id="scenarios"], .lp [id="governance"], .lp [id="pricing"],
.lp [id="scenario"], .lp [id="rehearse"] {
  scroll-margin-top: 76px;
}


/* ── The research mode switch ──────────────────────────────────────────────
   Same segmented control as the hero's video switch, so the two read as one
   idiom. Links rather than buttons: each mode is a document somebody may want
   to open in a new tab or send to a committee. */
.rs-modes {
  display: inline-flex; margin: 0 0 24px;
  border: 1px solid var(--rule-strong); border-radius: 5px; overflow: hidden;
}
.rs-modes a {
  font-size: 13px; font-weight: 500; letter-spacing: .01em;
  padding: 7px 16px; color: var(--ink-soft); text-decoration: none;
  transition: background .15s ease, color .15s ease;
}
.rs-modes a + a { border-left: 1px solid var(--rule-strong); }
.rs-modes a:hover { color: var(--ink); }
.rs-modes a[aria-current="page"] { background: var(--signal); color: var(--paper); }
.rs-modes a:focus-visible { outline: 2px solid var(--signal); outline-offset: -3px; }
/* Same inset-ring problem as .lp-modes above. */
.rs-modes a[aria-current="page"]:focus-visible { outline-color: var(--paper); }


/* The limitations list. Numbered because a reader cites them back at you by
   number, and spaced because each one is a separate concession. */
.rs-limits { margin: 18px 0 0; padding: 0 0 0 22px; display: grid; gap: 16px; }
.rs-limits li { padding-left: 6px; }
.rs-limits strong { color: var(--ink); }
