/* Shared styling for /legal/* pages (also imported by /hardware and
   /showroom). Reading-page polish 2026-05-15: body bumps to 18px and
   dims to --mid, paragraph spacing opens up to 22px, h2 gets a hairline
   rule, the first paragraph after h1+last-updated gets italic lede
   treatment, inline links soften, external-link arrow uses screen-
   reader-safe alt text, and a .callout class boxes the trust-bearing
   clauses (refund window, discontinuation terms, liability cap,
   right-to-erasure SLA, account recovery procedure). */

:root {
  --bg:#07090c; --s1:#0d1018; --s2:#131820;
  --b1:#1e2535; --b2:#2a3347;
  --amber:#e8a020;
  --amber-soft:rgba(232, 160, 32, 0.85);
  --adim:rgba(232,160,32,0.10);
  /* Secondary brand accent. Kept in sync with index.html. See
     docs/design/design-tokens.md. Tier 1 ships the token, redesign
     pass turns it on. */
  --accent:#a32420;
  --text:#eaf0fc; --mid:#96a8c4; --dim:#8898b8;
  /* Status tokens added 2026-05-21 for the design-handoff bundle's
     .neglist red X markers + future status surfaces. Matches the
     :root in index.html. */
  --red:#d63031;
  --disp:'Barlow Condensed', system-ui, sans-serif;
  --serif:Georgia, 'Charter', 'Iowan Old Style', serif;
  --mono:'JetBrains Mono', monospace;
  /* Motion duration token used by the design-handoff bundle's
     .lh-nav, .lcross, .lfoot hover transitions. The full motion
     scale lives in index.html; legal.css only needs the snappy
     value. */
  --dur-snappy: 0.15s;
  /* linear() spring with ~5% overshoot. Mirrors the same token in
     index.html :root so the hamburger panel + any other meth-header-
     family bounce surface has a shared bounce easing across the site.
     Browsers without linear() degrade gracefully via the fallback at
     each usage site. See index.html for the generator note. */
  --ease-bounce-soft: linear(
    0, 0.063 1.9%, 0.512 7.8%, 0.793 12.5%, 0.892, 0.964,
    1.015 19.5%, 1.034, 1.046 24.3%, 1.05 27%, 1.046,
    1.029 37.7%, 1.001 53.3%, 0.995 61%, 1
  );
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* Cross-document View Transitions (item #4 from the 2026-06-05 polish-
   brief sequence). Opts every page that loads legal.css into a default
   browser crossfade when navigating between same-origin pages. The
   landing/analyze surface (index.html) carries the same opt-in inline
   since it doesn't load legal.css.

   Browser support: Chrome/Edge 126+, Safari 18.2+, Firefox 144+ partial
   (~85% global). Unsupported browsers do a normal hard-cut navigation;
   nothing breaks. No JS, no markup changes, no per-element view-
   transition-name (those would come in a follow-up if we wanted
   shared-element morphs on e.g. the header wordmark).

   prefers-reduced-motion is honored by the user agent automatically per
   spec. No CSS override needed on our side. */
@view-transition { navigation: auto; }

/* Browser-native text-wrap improvements (item #2 from the 2026-06-05
   polish-brief sequence). `balance` rebalances headings to remove
   orphans/widows; capped to ~6 lines so longer-than-six accordion
   sub-headings degrade to normal wrapping (no harm). `pretty` optimizes
   the last few lines of paragraphs to avoid one-word last lines.
   - balance: Baseline 2024 (Chrome 114+, Firefox 121+, Safari 17.5+)
   - pretty: Chrome/Edge 117+ and recent Safari; not yet in Firefox.
   Both degrade silently to normal wrapping. Sweep covers every page
   that loads legal.css; landing/analyze monolith carries the same
   rules inline in index.html. */
h1, h2, h3 { text-wrap: balance; }
p { text-wrap: pretty; }

body {
  background: var(--bg);
  /* Body text dims to --mid (was --text). High-contrast cool white on
     near-black is harsh for long reading; ~85% reduces eye strain
     across legal-length copy. Bold + italic + headers stay --text so
     emphasis pops by being brighter, not heavier. */
  color: var(--mid);
  font-family: var(--serif);
  font-size: 18px;
  line-height: 1.75;
  min-height: 100vh;
}

/* Brand bar — sticky on legal pages (audit F23 alignment). Adds a
   "← Home" back link on the right so readers who arrived from a
   footer link aren't trapped at browser-back. */
.legal-header {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 28px;
  border-bottom: 1px solid var(--b1);
  background: rgba(7, 9, 12, 0.96);
  backdrop-filter: blur(8px);
  position: sticky;
  top: 0;
  z-index: 50;
}
.legal-header a { color: inherit; text-decoration: none; display: flex; gap: 12px; align-items: center; }
.legal-header .dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--amber); box-shadow: 0 0 10px var(--amber);
  flex-shrink: 0;
}
.legal-header .name {
  font-family: var(--disp);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  transition: color var(--dur-base, 0.18s) ease;
}
.legal-header .name span { color: var(--amber); }
/* Logo hover: whole wordmark goes amber (matches the .h-logo
   behavior in index.html, the .meth-header .mk logo below).
   "Miata" is already amber; on hover the "Dyno" part joins it
   so the logo lights up as a single brand confirmation. */
.legal-header a:hover .name,
.legal-header a:focus-visible .name { color: var(--amber); }
.legal-header .spacer { flex: 1; }
.legal-header .back-home {
  font-family: var(--disp);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--mid);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  padding: 0 4px;
  transition: color 0.15s ease;
}
.legal-header .back-home:hover { color: var(--amber); }
.legal-header .back-home:focus-visible { outline: 2px solid var(--amber); outline-offset: 3px; color: var(--amber); }

/* main: text column constrained to 65ch (~640-680px in 18px Georgia)
   for comfortable reading measure. Page background remains full-width
   because main is the inner container. Below 1024px, main centers in
   the viewport; at >=1024px, the page becomes a 2-column grid with
   main on the left and the TOC aside on the right (see .doc-shell). */
main {
  max-width: 65ch;
  margin: 0 auto;
  padding: 72px 28px 80px;
}

/* doc-shell: 2-column grid on long pages (methodology, privacy, terms).
   At >=1024px the main text column stays at 65ch on the left of the
   centered shell and the TOC aside sits to its right. Pages without a
   .page-toc aside simply lay out as before (main centered). */
.doc-shell {
  max-width: 1100px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 65ch);
  justify-content: center;
}
.doc-shell main {
  max-width: 65ch;
  margin: 0;  /* shell handles centering */
}
@media (min-width: 1024px) {
  .doc-shell {
    grid-template-columns: minmax(0, 65ch) 220px;
    column-gap: 56px;
    justify-content: center;
  }
}

/* H1 on documentation pages. Uses system-ui sans (not condensed
   display) at sentence case so the doc voice reads calm, not
   marketing. Brand anchor lives in the small amber .tag eyebrow
   above the h1, not in the h1 itself.

   Size bumped from a fixed 30px to clamp(28px, 2.8vw, 36px) so the
   Termly h1 (terms, privacy) sits closer to the bundle's .lhero h1
   range (28-40px). At desktop, Termly = 36px vs bundle = 40px, much
   closer than the prior 30 vs 56. Mobile floors at 28px (overridden
   to 24px in the <=560px media query for narrow phones). */
h1 {
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-size: clamp(28px, 2.8vw, 36px);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.2;
  color: var(--text);
  margin-bottom: 8px;
}

.tag {
  font-family: var(--disp);
  font-size: 11px;
  color: var(--amber);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  margin-bottom: 28px;
}

/* h2: section break. Short amber rule sits ABOVE the heading (width
   20px, height 4px, left-aligned) as a section marker, replacing the
   previous border-bottom hairline. Echoes the landing's amber-eyebrow
   underline pattern (.h-tag::before) at thicker scale. */
h2 {
  font-family: var(--disp);
  font-size: 24px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text);
  margin-top: 56px;
  margin-bottom: 16px;
  position: relative;
  /* TOC + hash-link jumps land the heading below the sticky header
     instead of behind it. Mobile header wraps to ~100px; desktop is
     single-row ~60px (see the 1024px override). */
  scroll-margin-top: 112px;
}
@media (min-width: 1024px) {
  h2 { scroll-margin-top: 88px; }
}
h2::before {
  content: '';
  display: block;
  width: 20px;
  height: 4px;
  background: var(--amber);
  margin-bottom: 14px;
}

/* h3: subsection. Amber 4x16px bar sits in the left gutter via
   absolute positioning; h3 text indents 14px to make room for it.
   The bar reads as marginalia rather than coloring the heading text
   (which would over-deploy amber across Termly-dense pages). */
h3 {
  font-family: var(--disp);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text);
  margin-top: 32px;
  margin-bottom: 12px;
  position: relative;
  padding-left: 14px;
}
h3::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 4px;
  height: 16px;
  background: var(--amber);
}

p { margin-bottom: 22px; }

/* Lede paragraph: first <p> child of <main>. Per reviewer note, this
   selector survives Termly regenerations because it depends on
   structural position, not a wrapper class. NB the .last-updated stamp
   uses <div> (not <p>) so it doesn't get matched here. */
main > p:first-of-type {
  font-style: italic;
  color: var(--mid);
  font-size: 19px;
  line-height: 1.7;
  margin-bottom: 32px;
}

/* Emphasis: bold + italic pop because they're --text (brighter) on the
   --mid body. No font-weight bump on strong (would over-emphasize). */
strong { color: var(--text); font-weight: 600; }
em { color: var(--text); font-style: italic; }

/* Lists: 22px indent for the bullet/number gutter; outside list-style-
   position gives hanging-indent so multi-line bullet content wraps
   under the first line's text (not under the bullet). 12px between
   items for breathing room against the 22px paragraph rhythm. */
ul, ol {
  margin-left: 22px;
  margin-bottom: 22px;
  list-style-position: outside;
}
li {
  margin-bottom: 12px;
  line-height: 1.7;
  padding-left: 4px;
}

/* Inline links: softer amber (~85% saturation) + cleaner underline
   rendering via offset + thickness control. Reduces the strobe effect
   in Termly-dense pages. */
a {
  color: var(--amber-soft);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: color 0.15s ease;
}
a:hover { color: var(--amber); }
a:focus-visible { outline: 2px solid var(--amber); outline-offset: 2px; }

/* External-link arrow: visible ↗ but speak-suppressed. The slash in
   `content: "..."/"…"` is the CSS speak alt: empty string after the
   slash makes screen readers skip the pseudo-content. Supported in
   Chrome 77+, Firefox 87+, Safari 16+. Older clients see the arrow
   and announce "up-right arrow"; acceptable fallback. */
a[target="_blank"]::after {
  content: " ↗" / "";
  font-family: var(--mono);
  font-size: 0.85em;
  opacity: 0.7;
}

/* Inline code spans (Termly-style inline references): JetBrains Mono
   on a slightly tinted background. Padding tightened from the prior
   button-like rendering. */
code, kbd, samp {
  font-family: var(--mono);
  font-size: 0.9em;
  background: var(--s2);
  color: var(--text);
  padding: 1px 6px;
  border-radius: 2px;
}

/* .last-updated: small stamp at the top of the page. Rendered as
   <div class="last-updated"> (NOT <p>) so the lede selector
   `main > p:first-of-type` skips this and targets the first real
   paragraph below it. */
.last-updated {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--dim);
  font-style: italic;
  margin-bottom: 32px;
  letter-spacing: 0.04em;
}

/* Full attribution at the bottom of the page. Reviewer note: two clean
   signals — small stamp at top, full attribution at bottom. */
.attribution {
  margin-top: 56px;
  padding-top: 22px;
  border-top: 1px solid var(--b1);
  font-family: var(--mono);
  font-size: 12px;
  color: var(--dim);
  line-height: 1.7;
  letter-spacing: 0.04em;
}
.attribution a { color: var(--mid); text-decoration: none; }
.attribution a:hover { color: var(--amber); }

/* .callout: highlight the trust-bearing clauses (refund window,
   discontinuation terms, liability cap, right-to-erasure SLA,
   account recovery procedure). Title is rendered as <h3> for semantic
   correctness (callouts ARE subsections). The standard h3 left bar
   is suppressed inside a callout since the callout already has its
   own left border. */
.callout {
  border-left: 3px solid var(--amber);
  background: var(--adim);
  padding: 18px 22px;
  margin: 28px 0;
  border-radius: 0;
}
.callout > *:last-child { margin-bottom: 0; }
.callout h3 {
  /* Override the standard h3 gutter pattern inside callouts. The
     callout's own left border is the visual anchor; the gutter bar
     would compete. Use amber text instead since we already have an
     amber visual frame around it. */
  font-family: var(--disp);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--amber);
  margin-top: 0;
  margin-bottom: 10px;
  padding-left: 0;
}
.callout h3::before { display: none; }

/* .placeholder-note: retained from prior CSS for any page still using
   it (currently none, but harmless to keep). */
.placeholder-note {
  background: var(--adim);
  border-left: 3px solid var(--amber);
  padding: 14px 18px;
  margin: 24px 0;
  font-size: 14px;
  color: var(--mid);
}

footer.legal-foot {
  border-top: 1px solid var(--b1);
  padding: 24px 28px;
  font-size: 12px;
  color: var(--dim);
  text-align: center;
}
footer.legal-foot a {
  color: var(--mid);
  margin: 0 10px;
  display: inline-block;
  min-height: 44px;
  padding: 12px 4px;
  line-height: 20px;
  text-decoration: none;
}
footer.legal-foot a:hover { color: var(--amber); }

/* TOC for long pages (privacy, terms). Populated by /legal/legal-toc.js
   from h2[id] elements in main on page load. Subtle visual treatment
   (small caps, low contrast, amber for current section + Top link).

   Phone (<1024px): a collapsible "Contents ▾" panel. order:-1 pulls it
   above the article in the single-column doc-shell grid (the aside is a
   grid sibling of main, kept there so the desktop right-rail layout
   works; it can't move into main without breaking the 2-col grid). The
   list is hidden until the heading button sets data-open="true".
   Desktop (>=1024px): the original sticky right rail; the button reverts
   to a static-looking heading and the list is always shown. */
.page-toc {
  display: block;
  order: -1;
  margin: 24px 28px 8px;  /* top: clears the sticky header (panel is first
                             in the grid on phone); sides match main's 28px
                             padding so the border aligns with the prose */
  border: 1px solid var(--b1);
  background: var(--s1);
}
.page-toc[data-open="true"] {
  border-color: var(--b2);
}
@media (min-width: 1024px) {
  .page-toc {
    position: sticky;
    top: 100px;  /* below the 60px sticky legal-header + breathing room */
    align-self: start;
    padding-top: 72px;  /* matches main's padding-top for visual baseline */
    order: 0;
    margin: 0;
    border: none;
    background: transparent;
    /* Long TOCs (terms has 23 sections + Top) exceed the viewport. The
       sticky rail must scroll internally or its bottom entries — and the
       Top link — are pinned off-screen and unreachable. Measured: 858px
       TOC vs 668px available on a 1366x768 laptop. Mirrors the kit spec
       (max-height: calc(100vh - 92px); overflow-y: auto). */
    max-height: calc(100vh - 100px);
    overflow-y: auto;
  }
}
/* Phone: the heading is a 44px disclosure button (label + chevron). */
.page-toc-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  min-height: 44px;
  padding: 12px 16px;
  margin: 0;
  border: none;
  background: transparent;
  font-family: var(--disp);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--mid);
  cursor: pointer;
}
.page-toc-heading:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: -2px;
}
.page-toc[data-open="true"] .page-toc-heading {
  color: var(--text);
  border-bottom: 1px solid var(--b1);
}
.page-toc-chevron {
  font-size: 10px;
  line-height: 1;
  transition: transform 0.18s ease;
}
.page-toc[data-open="true"] .page-toc-chevron {
  transform: rotate(180deg);
}
.page-toc-list {
  list-style: none;
  margin: 0;
  padding: 0 16px 12px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  display: none;  /* phone: shown only when the panel is open */
}
.page-toc[data-open="true"] .page-toc-list {
  display: block;
}
/* Desktop: button reverts to a static-looking heading; list always on. */
@media (min-width: 1024px) {
  .page-toc-heading {
    display: block;
    width: auto;
    min-height: 0;
    padding: 0 0 10px;
    margin-bottom: 14px;
    border-bottom: 1px solid var(--b1);
    color: var(--dim);
    font-size: 10px;
    cursor: default;
  }
  .page-toc[data-open="true"] .page-toc-heading {
    color: var(--dim);
  }
  .page-toc-chevron {
    display: none;
  }
  .page-toc-list {
    display: block;
    padding: 0;
  }
}
.page-toc-list li {
  margin-bottom: 0;
  padding-left: 0;
}
.page-toc-link {
  display: block;
  padding: 6px 0 6px 10px;
  border-left: 2px solid transparent;
  color: var(--mid);
  text-decoration: none;
  font-variant: small-caps;
  letter-spacing: 0.08em;
  line-height: 1.4;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.page-toc-link:hover {
  color: var(--text);
}
.page-toc-link.is-current {
  color: var(--amber);
  border-left-color: var(--amber);
}
.page-toc-link:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 2px;
}
.page-toc-top {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--b1);
}
.page-toc-top .page-toc-link {
  font-variant: normal;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  font-size: 10px;
}
.page-toc-top .page-toc-link:hover {
  color: var(--amber);
}
/* Reduced-motion: drop the color/border transitions on TOC links so
   the active-section change happens instantly. */
@media (prefers-reduced-motion: reduce) {
  .page-toc-link,
  .page-toc-chevron {
    transition: none;
  }
}

/* Mobile-narrow refinements. Body bumps from desktop 18px to 17px
   (was 15px before this pass — direction was backwards for reading).
   Header padding tightens. */
@media (max-width: 560px) {
  .legal-header { padding: 14px 18px; gap: 10px; }
  .legal-header .name { font-size: 16px; }
  .legal-header .back-home { font-size: 10px; letter-spacing: 0.14em; }
  main { padding: 44px 18px 64px; }
  .page-toc { margin: 16px 18px 8px; }  /* match the tighter main padding */
  h1 { font-size: 24px; line-height: 1.2; }
  h2 { font-size: 20px; margin-top: 44px; }
  h3 { font-size: 13px; margin-top: 28px; }
  body { font-size: 17px; line-height: 1.7; }
  main > p:first-of-type { font-size: 17px; }
  p { margin-bottom: 20px; }
  .callout { padding: 14px 16px; margin: 22px 0; }
  footer.legal-foot { padding: 16px 14px; }
  footer.legal-foot a { margin: 0 4px; padding: 12px 8px; }
}

/* ============================================================
   Trust-pages chrome (Phase 2 brand reset 2026-05-16).
   Used by /methodology (T-16) and /privacy (T-17).
   ============================================================ */

.meth-page-body{
  background:var(--bg);
  color:var(--text);
  font-family:var(--mono);
  font-size:13px;
  line-height:1.65;
  min-height:100vh;
  overflow-x:hidden;
}

/* Laptop layout override. The global `main { max-width: 65ch }` rule
   above is correct for /legal/* (long-form prose where reading measure
   matters), but it caps /methodology, /showroom, /hardware at ~640px
   wide — which leaves the change-log table, sample-card grid, and
   numbered procedure crammed into a third of the laptop viewport.

   Override main width on .meth-page-body to 1100px so the layout-heavy
   children (.log table, .show-grid, .priv-*) get the room they were
   designed for. Prose elements get an explicit 720px cap so reading
   measure stays comfortable — a 1000px paragraph is unreadable. Mobile
   reflow at ≤1100px uses the same 28px gutter pattern as /legal/. */
body.meth-page-body main{
  max-width:1100px;
  margin:0 auto;
  padding:56px 40px 80px;
}
/* Prose-dominant content pages (hardware, methodology) size their column to
   the reading content, not the 1100px layout width. The 1100px exists for the
   showroom + privacy grids and tables; on a prose page it left the 720px text
   stranded against an empty right half on a laptop. The wide elements here
   either scroll (the equation pre) or reflow (the change-log), so a narrower
   centered column costs them nothing. */
body.meth-reading main{ max-width:840px; }
body.meth-page-body .model-prose,
body.meth-page-body .hw-list,
body.meth-page-body .hw-steps,
body.meth-page-body .hw-note,
body.meth-page-body .hw-app,
body.meth-page-body .hw-disclosure{
  max-width:720px;
}
@media (max-width:1100px){
  /* 18px side padding matches the general content pages. Methodology was an
     anomalous 28px, which on a phone (where this padding is the width
     constraint, not the 720/980px max-widths) squeezed the text column. At
     tablet widths the max-widths cap the content so this is visually identical
     there; it only widens the phone column. */
  body.meth-page-body main{ padding:48px 18px 80px; }
}

.meth-header{
  display:flex; align-items:center; gap:16px;
  padding:16px 32px;
  border-bottom:1px solid var(--b1);
  background:rgba(7,9,12,0.96);
  position:sticky; top:0; z-index:50;
  transition:padding .25s ease, background-color .25s ease;
}
.meth-header .mk{ display:flex; align-items:center; gap:10px; text-decoration:none; color:inherit; }
.meth-header .mk .dot{ width:10px; height:10px; border-radius:50%; background:var(--amber); box-shadow:0 0 12px rgba(232,160,32,0.5); }
/* DYNO color pinned to var(--mid) explicitly. Was previously implicit
   via body inheritance, which left landing's white DYNO drifting from
   cookies/support's grey DYNO. Pinning here locks the grey on every
   meth-header page regardless of body color. MIATA stays amber via the
   em rule below; hover rule overrides to amber on the whole wordmark.

   FONT (2026-05-29 founder ask after PR #328 landed): chrome typography
   uses the OS-native system font stack instead of var(--disp) (Barlow
   Condensed). The "font I want" the founder kept pointing at on
   cookies/support was actually system-ui — those pages weren't loading
   Barlow Condensed before PR #328, so the rendered face was Segoe UI /
   SF / Roboto depending on visitor's OS. PR #328 made every page render
   Barlow Condensed (the declared brand font), and the founder explicitly
   reversed: keep Barlow Condensed for content (page H1/H2/H3, hero
   eyebrows, etc.) but switch CHROME (wordmark + nav + hamburger panel)
   to system-ui. Trade-off accepted: chrome looks OS-native on every
   visitor's device (varies by OS), brand font preserved in content. */
.meth-header .mk .nm{ font-family:system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; font-weight:700; font-size:15px; letter-spacing:3px; text-transform:uppercase; color:var(--mid); transition:color var(--dur-base, 0.18s) ease; }
.meth-header .mk .nm em{ font-style:normal; color:var(--amber); }
/* Logo hover: whole wordmark goes amber. Matches the .h-logo and
   .legal-header logo hover patterns. */
.meth-header .mk:hover .nm,
.meth-header .mk:focus-visible .nm{ color:var(--amber); }
/* font-family:system-ui chrome stack — see .meth-header .mk .nm comment
   above. Nav links inherit this through the cascade; SIGN OUT button on
   /account/dashboard also inherits via .meth-header .nav button{font-family:inherit}. */
.meth-header .nav{ display:flex; gap:18px; margin-left:24px; font-family:system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; font-size:11px; font-weight:700; letter-spacing:0.14em; }
.meth-header .nav a{ color:var(--mid); text-decoration:none; transition:color 0.15s ease; }
.meth-header .nav a:hover{ color:var(--text); }
.meth-header .nav a.cur{ color:var(--text); border-bottom:1px solid var(--amber); padding-bottom:2px; }

/* Theme-toggle button in inner-page chrome (port of landing's .h-util-btn
   from index.html:429). Scoped to the three chrome families that load
   legal.css: .meth-header .nav, .lh-nav (legal cluster + estimate +
   showroom/nc2-stock), and .h-nav (legal/terms + pro/index). Lives at
   the end of each nav with a faint left-border separator so it reads
   as utility rather than site-nav. 44px hit target per Apple HIG.
   Icon swap (sun in dark / moon in light) is handled by the body.light
   rule in the LIGHT THEME block at the top of this file. */
.meth-header .h-util-btn,
.lh-nav .h-util-btn,
.h-nav .h-util-btn{
  display:inline-flex; align-items:center; justify-content:center;
  min-width:44px; min-height:36px;
  padding:0 10px; margin-left:6px;
  background:none; border:none; cursor:pointer;
  color:var(--mid);
  border-left:1px solid var(--b1);
  transition:color var(--dur-base, 0.18s) ease;
}
.meth-header .h-util-btn:hover,
.lh-nav .h-util-btn:hover,
.h-nav .h-util-btn:hover{ color:var(--text); }
.meth-header .h-util-btn:focus-visible,
.lh-nav .h-util-btn:focus-visible,
.h-nav .h-util-btn:focus-visible{ outline:2px solid var(--amber); outline-offset:3px; color:var(--text); }
/* Icon-size rule deliberately UNSCOPED (no .meth-header / .lh-nav /
   .h-nav prefix) to match the .h-util-btn .ti-moon{display:none} rule
   below at the same (0,2,0) specificity. The prefixed version that
   shipped originally was (0,3,0) and silently beat the (0,2,0) moon-
   hide on meth-header pages, making BOTH sun + moon icons render at
   once. Fixed 2026-05-28 (post-merge audit). The .h-util-btn class
   is only used by theme-toggle buttons, so chrome-scope adds no value. */
.h-util-btn .ti-icon{ width:16px; height:16px; display:block; }
/* PRO badge on the PRO nav link, matching landing (amber when not the
   current page). Inner pages never have /pro/ as .cur (it uses a
   different header), so PRO always renders amber here for free users. */
.meth-header .nav a[href="/pro/"]:not(.cur){ color:var(--amber); }
.meth-header .nav a[href="/pro/"]:not(.cur):hover{ color:#f4b840; }

/* Pro-gated nav entries. Mirrors the landing rules at index.html
   lines 382-387 so a signed-in Pro user sees the SAME nav items on
   content-surface pages as on landing: PRO + SIGN IN for free users,
   DASHBOARD + ACCOUNT for Pro users. body[data-pro="1"] is set by
   assets/js/pro-nav.js after GET /me confirms pro_tier===1. Applies to
   both the inline nav and the phone hamburger panel. */
.meth-header .nav .h-nav-pro-only{ display:none; }
body[data-pro="1"] .meth-header .nav .h-nav-pro-only{ display:inline-block; }
body[data-pro="1"] .meth-header .nav .h-nav-free-only{ display:none; }
.h-menu-panel .h-menu-pro-only{ display:none; }
body[data-pro="1"] .h-menu-panel .h-menu-pro-only{ display:block; }
body[data-pro="1"] .h-menu-panel .h-menu-free-only{ display:none; }
.meth-header .spacer{ flex:1; }
/* "← Home" / back-to-app link. Bumped from a quiet text link to a
   bordered button-style affordance (2026-05-19) so non-tech-savvy
   visitors can spot the way back to the main app at a glance. The
   3px amber left rule matches the .ltb-pricing-band and .real-sample
   card pattern, so the back link reads as a deliberate site element,
   not a hidden footnote. */
.meth-header .back-home{
  font-family:system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; font-size:12px; font-weight:700;
  letter-spacing:0.12em; text-transform:uppercase;
  color:var(--text); text-decoration:none; min-height:44px;
  display:inline-flex; align-items:center; gap:8px;
  padding:8px 16px;
  background:var(--s1);
  border:1px solid var(--b1);
  border-left:2px solid var(--amber);
  transition:color var(--dur-base, 0.18s) ease, background var(--dur-base, 0.18s) ease, border-color var(--dur-base, 0.18s) ease;
}
.meth-header .back-home:hover{
  color:var(--amber);
  background:var(--s2);
  border-color:var(--b2);
  border-left-color:var(--amber);
}
.meth-header .back-home:focus-visible{ outline:2px solid var(--amber); outline-offset:3px; }

/* Laptop scale-up: match landing exactly (2026-05-27 third pass).
   Inner-page header on laptop. Phone (<=720px) and tablet (721-880px)
   layouts deliberately untouched.

   History:
     PR #285 first pass: one notch tighter than landing (22/13/18).
       Founder said "still looks off."
     PR #286 second pass: one notch bigger than landing (26/14/22).
       Founder said "header switches back and forth between pages."
     This pass: match landing 1:1 so navigating between landing and
       inner pages produces ZERO visible chrome resize on laptop.

   Each value matches the landing reference at index.html line 545-549:

   | Element        | Landing >=881 | Inner (this pass) |
   | wordmark .nm   | 23px          | 23px              |
   | dot            | 10x10         | 10x10             |
   | logo gap       | 16px          | 16px              |
   | nav font       | 13px          | 13px              |
   | nav gap        | 28px          | 28px              |
   | padding-Y      | 22px          | 22px              |

   back-home button is HIDDEN on laptop (2026-05-27 founder pick). The
   inline nav above already has a HOME link, so the bordered button on
   the right is redundant and was the visual-mass asymmetry that
   wordmark/nav matching alone could not fix (landing has no equivalent
   bordered button on its right). Phone (<=720px) still shows back-home
   because the nav is hidden behind the hamburger; the 2026-05-19
   user-research rationale ("non-tech-savvy visitors spot the way back")
   still applies there. Tablet (721-880px) keeps it (founder ask was
   laptop-specific).

   Scroll-shrink behavior was landing-only before 2026-05-30; now lives
   in /assets/js/header-shrink.js loaded by every meth-header page, and
   the body.shrunk CSS rules at the bottom of this @media block (laptop)
   + outside the @media (default) apply universally. Dashboard + account
   inline their chrome so they duplicate the same body.shrunk rules
   inline. Inner pages now match landing's chrome animation.

   Breakpoint min-width 881 unchanged. Single source of truth with
   index.html line 545. */
@media (min-width: 881px){
  .meth-header{ padding:22px 32px; gap:18px; }
  .meth-header .mk{ gap:16px; }
  .meth-header .mk .dot{ width:10px; height:10px; }
  .meth-header .mk .nm{ font-size:23px; }
  /* margin-left:auto pushes the nav to the right edge, matching the
     landing header (index.html:402, header nav.h-nav{margin-left:auto}).
     Replaces the prior margin-left:32px which sat the nav next to the
     wordmark on the left. That left-vs-right difference was the
     "nav jumps sides when I click into a page" complaint (2026-05-27).
     With the spacer + back-home both hidden below, the nav is the only
     right-side content, so the layout reads logo-left / nav-right
     exactly like landing. */
  .meth-header .nav{ gap:28px; margin-left:auto; font-size:13px; }
  /* Spacer no longer needed on laptop: it existed to push the back-home
     button to the far right while the nav sat on the left. The nav is
     now right-aligned and back-home is hidden, so the spacer would only
     add a zero-width flex child. Hide it for clarity. */
  .meth-header .spacer{ display:none; }
  .meth-header .back-home{ display:none; }
  /* Shrunk state on laptop (added 2026-05-30). Padding halves (22 -> 11);
     wordmark drops 23 -> 16px (intentionally 3px LARGER than nav 13px
     to compensate for a cap-height rendering quirk: at the same px
     size the wordmark renders visibly shorter than the nav, probably
     from the <em>MIATA</em> tag shifting glyph metrics) and
     letter-spacing tightens from 3px (= 0.13em at 23px) to 0.14em so
     the wordmark visually matches the nav at the shrunk size, not just
     numerically. Without the letter-spacing match the wordmark looks
     small/airy at 13px while the nav looks dense — same px, different
     visual size. See assets/js/header-shrink.js for the JS that toggles
     the .shrunk class. */
  body.shrunk .meth-header{ padding-top:11px; padding-bottom:11px; }
  body.shrunk .meth-header .mk .nm{ font-size:16px; letter-spacing:0.14em; }
}

/* Shrunk state default (default / tablet, < 881px). Padding ~7px drop;
   wordmark drops 15 -> 11px (matches nav font-size:11px) with the same
   letter-spacing match. */
/* Wrapped in @media (max-width: 880px) 2026-05-30 because previously
   these default rules had no media query, so they applied at ALL
   viewport sizes — same selector + same specificity + later source
   order = they silently overrode the laptop @media body.shrunk rules
   above. Net effect: every 'fix' to the laptop wordmark size in PRs
   #353/#354/#356 went nowhere because this 11px rule won at laptop
   too. Mutually-exclusive media queries kill the override. */
@media (max-width: 880px){
  body.shrunk .meth-header{ padding-top:9px; padding-bottom:9px; }
  body.shrunk .meth-header .mk .nm{ font-size:11px; letter-spacing:0.14em; }
}

/* Shrunk background blur tightens slightly post-scroll for both themes. */
body.shrunk .meth-header{ background:rgba(7,9,12,.98); }
body.light.shrunk .meth-header{ background:rgba(251,252,255,.98); }

/* Add letter-spacing to the wordmark's existing transition so the
   tightening animates instead of snapping at the shrink threshold. */
.meth-header .mk .nm{ transition:font-size .25s ease, letter-spacing .25s ease, color .25s ease; }

@media (prefers-reduced-motion: reduce){
  .meth-header, .meth-header .mk, .meth-header .mk .nm, .meth-header .nav a{ transition:none; }
}

.meth-hero{ padding:56px 40px 28px; position:relative; overflow:hidden; }
.meth-hero.with-watermark::before{
  content:'F = ma'; position:absolute; right:-10px; top:-16px;
  font-family:var(--disp); font-style:italic; font-size:220px; font-weight:800;
  color:rgba(255,255,255,0.012); letter-spacing:-0.04em;
  pointer-events:none; line-height:1;
}
.meth-hero .eyebrow{
  font-family:var(--disp); font-size:11px; font-weight:700;
  letter-spacing:0.22em; color:var(--amber);
  text-transform:uppercase; margin-bottom:14px;
  display:flex; align-items:center; gap:10px;
}
.meth-hero .eyebrow::before{ content:''; display:block; width:28px; height:1px; background:var(--amber); }
.meth-hero h1{
  font-family:var(--disp); font-weight:800;
  font-size:clamp(36px, 4.5vw, 56px);
  letter-spacing:-0.01em; line-height:0.98;
  text-transform:uppercase; margin:0 0 16px; max-width:880px;
}
.meth-hero h1 em{ font-style:italic; color:var(--amber); }
.meth-hero .sub{
  font-family:var(--serif); font-size:16px; line-height:1.7;
  color:var(--text); max-width:720px; margin:0;
}
.meth-hero .sub b{ color:var(--text); font-weight:700; }
.meth-hero .sub em{ color:var(--mid); font-style:italic; }

.meth-section{ padding:40px 40px 12px; border-top:1px solid var(--b1); }
.meth-h2{
  font-family:var(--disp); font-weight:800; font-size:22px;
  letter-spacing:0.06em; text-transform:uppercase; color:var(--text);
  margin:0 0 18px; display:flex; align-items:baseline; gap:14px;
}
.meth-h2 .num{
  font-family:var(--mono); font-size:10px; letter-spacing:0.18em;
  color:var(--amber); text-transform:uppercase;
}

.meth-foot{
  padding:28px 40px; border-top:1px solid var(--b1);
  font-family:var(--mono); font-size: 12px; color:var(--dim);
  letter-spacing:0.10em; text-transform:uppercase;
}

/* Methodology page-specific (.model-*, .log, .limits) */
.model-eq{
  font-family:var(--mono); font-size:13px; line-height:1.8;
  background:var(--s2); border:1px solid var(--b1);
  padding:16px 18px; margin:12px 0 18px;
  color:var(--text); max-width:740px;
  overflow-x:auto; white-space:pre;
}
.model-eq .var{ color:var(--amber); }
.model-eq .op{ color:var(--mid); }
.model-eq .com{ color:var(--dim); }
.model-prose{
  font-family:var(--mono); font-size:13px; line-height:1.7;
  color:var(--mid); max-width:720px; margin:0 0 14px;
}
.model-prose strong{ color:var(--text); font-weight:500; }
.model-prose em{ color:var(--mid); font-style:italic; }
.model-prose code{
  font-family:var(--mono); font-size:12px;
  background:var(--s2); border:1px solid var(--b1);
  padding:1px 6px; color:var(--text);
}
.model-prose a{ color:var(--amber); text-decoration:none; border-bottom:1px solid rgba(232,160,32,0.5); }
.model-prose a:hover{ color:#f4b840; }

.log{ border:1px solid var(--b1); margin:8px 0 8px; max-width:980px; }
.log-row{
  display:grid; grid-template-columns:130px 110px 1fr;
  gap:18px; padding:14px 18px;
  border-bottom:1px solid var(--b1);
  align-items:baseline;
}
.log-row:last-child{ border-bottom:none; }
.log-row .date{
  font-family:var(--mono); font-size:12px; color:var(--amber);
  letter-spacing:0.04em;
}
.log-row .ver{
  font-family:var(--disp); font-weight:700; font-size:13px;
  letter-spacing:0.12em; text-transform:uppercase; color:var(--text);
}
.log-row .what{
  font-family:var(--mono); font-size:13px; line-height:1.65; color:var(--mid);
}
.log-row .what b{ color:var(--text); font-weight:500; }
.log-row .what .diff{
  display:inline-block; font-family:var(--mono); font-size: 12px;
  background:var(--s2); border:1px solid var(--b1);
  padding:1px 6px; color:var(--text); margin-left:6px;
}
.log-row .what .reest{
  display:inline-block; font-family:var(--disp); font-weight:700;
  font-size:10px; letter-spacing:0.18em; text-transform:uppercase;
  color:var(--green); border:1px solid var(--green); padding:1px 6px;
  margin-left:6px;
}
.log-row.first .date{ color:var(--green); }
.log-row.first .ver::before{ content:'\25CF '; color:var(--green); margin-right:4px; }

.limits{
  display:grid; grid-template-columns:repeat(2, 1fr); gap:1px;
  background:var(--b1); border:1px solid var(--b1); max-width:880px;
}
.limits .cell{ background:var(--s1); padding:14px 16px; }
.limits .cell .l{
  font-family:var(--disp); font-weight:700; font-size:12px;
  letter-spacing:0.14em; text-transform:uppercase; color:var(--amber);
  margin-bottom:6px;
}
.limits .cell .v{
  font-family:var(--mono); font-size:12px; line-height:1.65;
  color:var(--mid); margin:0;
}
.limits .cell .v b{ color:var(--text); font-weight:500; }

/* Privacy page-specific (.priv-*) */
.priv-tldr{
  border:1px solid var(--b1); border-left:2px solid var(--amber);
  background:var(--adim);
  padding:22px 26px; max-width:760px;
  margin:4px 0 18px;
}
.priv-tldr h4{
  font-family:var(--disp); font-weight:800; font-size:12px;
  letter-spacing:0.20em; text-transform:uppercase; color:var(--amber);
  margin:0 0 14px;
}
.priv-tldr ol{
  margin:0; padding-left:24px;
  font-family:var(--serif); font-size:16px; line-height:1.6; color:var(--text);
  list-style:none; counter-reset:tldr;
}
.priv-tldr ol li{
  counter-increment:tldr;
  position:relative; margin-bottom:12px;
  padding-left:0;
}
.priv-tldr ol li::before{
  content:counter(tldr, decimal-leading-zero);
  position:absolute; left:-32px; top:2px;
  font-family:var(--mono); font-size: 12px; color:var(--amber);
  letter-spacing:0.10em;
}
.priv-tldr ol li b{ color:var(--text); font-weight:700; }
.priv-tldr ol li:last-child{ margin-bottom:0; }

.priv-fields{ border:1px solid var(--b1); max-width:880px; }
.priv-fields .row{
  display:grid; grid-template-columns:200px 1fr 100px;
  gap:18px; padding:12px 18px;
  border-bottom:1px solid var(--b1);
  align-items:baseline;
}
.priv-fields .row:last-child{ border-bottom:none; }
.priv-fields .row .k{
  font-family:var(--disp); font-weight:700; font-size:12px;
  letter-spacing:0.12em; text-transform:uppercase; color:var(--text);
}
.priv-fields .row .v{
  font-family:var(--mono); font-size:12px; line-height:1.65; color:var(--mid);
}
.priv-fields .row .v b{ color:var(--text); font-weight:500; }
.priv-fields .row .when{
  font-family:var(--mono); font-size: 12px; color:var(--amber);
  letter-spacing:0.10em; text-transform:uppercase; text-align:right;
}
.priv-fields .row .when.dim{ color:var(--dim); }

.priv-never{
  display:grid; grid-template-columns:repeat(2, 1fr); gap:1px;
  background:var(--b1); border:1px solid var(--b1); max-width:880px;
}
.priv-never .cell{
  background:var(--s1); padding:12px 16px;
  display:flex; gap:12px; align-items:baseline;
}
.priv-never .cell .x{
  font-family:var(--mono); font-size:13px; color:var(--red);
  flex-shrink:0; font-weight:700;
}
.priv-never .cell .v{
  font-family:var(--mono); font-size:12px; line-height:1.55; color:var(--text);
}
.priv-never .cell .v b{ color:var(--text); font-weight:500; }
.priv-never .cell .v span.dim{ color:var(--mid); }

.priv-svc{ border:1px solid var(--b1); max-width:880px; }
.priv-svc .row{
  display:grid; grid-template-columns:130px 1fr 1fr;
  gap:18px; padding:14px 18px;
  border-bottom:1px solid var(--b1);
}
.priv-svc .row:last-child{ border-bottom:none; }
.priv-svc .row.h{
  background:var(--s2);
  font-family:var(--disp); font-weight:700; font-size:11px;
  letter-spacing:0.18em; text-transform:uppercase; color:var(--dim);
}
.priv-svc .row .svc{
  font-family:var(--disp); font-weight:700; font-size:13px;
  letter-spacing:0.10em; text-transform:uppercase; color:var(--text);
}
.priv-svc .row .role{
  font-family:var(--mono); font-size:12px; line-height:1.6; color:var(--mid);
}
.priv-svc .row .data{
  font-family:var(--mono); font-size:12px; line-height:1.6; color:var(--text);
}
.priv-svc .row .data b{ color:var(--text); font-weight:500; }

.priv-rights{
  display:grid; grid-template-columns:repeat(3, 1fr); gap:1px;
  background:var(--b1); border:1px solid var(--b1); max-width:880px;
}
.priv-rights .cell{ background:var(--s1); padding:14px 16px; }
.priv-rights .cell .l{
  font-family:var(--disp); font-weight:700; font-size:12px;
  letter-spacing:0.14em; text-transform:uppercase; color:var(--amber);
  margin-bottom:8px;
}
.priv-rights .cell .v{
  font-family:var(--mono); font-size:12px; line-height:1.6; color:var(--mid);
  margin:0;
}
.priv-rights .cell .v a{
  color:var(--text); text-decoration:none;
  border-bottom:1px solid var(--b2); padding-bottom:1px;
}
.priv-rights .cell .v a:hover{ color:var(--amber); border-bottom-color:var(--amber); }

.priv-prose{
  font-family:var(--serif); font-size:16px; line-height:1.7;
  color:var(--text); max-width:720px; margin:0 0 14px;
}
.priv-prose b{ color:var(--text); font-weight:700; }
.priv-prose em{ color:var(--mid); font-style:italic; }
.priv-prose a{
  color:var(--amber); text-decoration:none;
  border-bottom:1px solid rgba(232,160,32,0.5);
}
.priv-prose a:hover{ color:#f4b840; }
.priv-prose code{
  font-family:var(--mono); font-size:12px;
  background:var(--s2); border:1px solid var(--b1);
  padding:1px 5px; color:var(--text);
}

.priv-meta{
  font-family:var(--mono); font-size: 12px; color:var(--dim);
  letter-spacing:0.10em; text-transform:uppercase;
  margin-top:4px;
}
.priv-meta b{ color:var(--mid); font-weight:500; }

/* Phone hamburger menu for meth-header pages (2026-05-26 founder feedback
   after PR #266 shipped landing-only). Mirrors the landing hamburger
   pattern at index.html but scoped to .meth-header. Shared JS at
   /assets/js/header-menu.js handles open/close + a11y + dismissal.
   Class names match the landing's (.h-menu-btn, .h-menu-panel,
   .h-menu-line, .h-menu-divider) so the script finds elements by ID
   regardless of which page loaded it. */
.meth-header .h-menu-btn{
  display:none; /* laptop default; phone media query flips to inline-flex */
  align-items:center;justify-content:center;
  flex-direction:column;gap:4px;
  width:44px;height:44px;
  margin-left:8px;
  background:none;border:none;cursor:pointer;
  color:var(--mid);
  transition:color var(--dur-snappy, 0.15s) ease;
}
.meth-header .h-menu-btn:hover{ color:var(--text); }
.meth-header .h-menu-btn:focus-visible{ outline:2px solid var(--amber); outline-offset:3px; color:var(--text); }
.meth-header .h-menu-line{
  display:block;width:20px;height:2px;background:currentColor;
  transition:transform var(--dur-snappy, 0.15s) ease, opacity var(--dur-snappy, 0.15s) ease;
}
.meth-header .h-menu-btn[aria-expanded="true"]{ color:var(--text); }
.meth-header .h-menu-btn[aria-expanded="true"] .h-menu-line:nth-child(1){
  transform:translateY(6px) rotate(45deg);
}
.meth-header .h-menu-btn[aria-expanded="true"] .h-menu-line:nth-child(2){ opacity:0; }
.meth-header .h-menu-btn[aria-expanded="true"] .h-menu-line:nth-child(3){
  transform:translateY(-6px) rotate(-45deg);
}

/* Slide-down panel. Sits outside <header> in markup, fixed at top.
   z-index 49 is one below the .meth-header sticky (z-index:50), so
   the header chrome stays visible during the slide-down animation.
   Identical .h-menu-panel rule lives in index.html inline CSS for
   the landing page; each page only sees one definition because
   index.html doesn't load legal.css. Drift risk noted in PR brief —
   future cleanup PR can extract a shared hamburger.css. */
.h-menu-panel{
  display:none;
  position:fixed;left:0;right:0;top:0;
  z-index:49;
  flex-direction:column;
  background:rgba(7,9,12,0.98);
  border-bottom:1px solid var(--b1);
  padding:80px 16px 20px; /* top padding clears the meth-header height */
  transform:translateY(-100%);
  opacity:0;
  pointer-events:none;
  transition:transform 0.22s var(--ease-bounce-soft, ease), opacity 0.18s ease;
}
.h-menu-panel.open{
  transform:translateY(0);
  opacity:1;
  pointer-events:auto;
}
.h-menu-panel a{
  display:block;
  padding:14px 8px;
  font-family:system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;font-weight:700;
  font-size:14px;letter-spacing:0.14em;text-transform:uppercase;
  color:var(--mid);text-decoration:none;
  border-bottom:1px solid var(--b1);
  transition:color var(--dur-snappy, 0.15s) ease;
}
.h-menu-panel a:hover{ color:var(--text); }
.h-menu-panel a:focus-visible{ outline:2px solid var(--amber); outline-offset:-2px; color:var(--text); }
.h-menu-panel a.cur{ color:var(--text); }

/* Theme toggle inside the panel (phone hamburger). Port of landing's
   .h-menu-theme from index.html:520. Borrows .h-util-btn styling but
   full-width with a text label so it reads as a menu row rather than
   a nav-corner glyph. */
.h-menu-divider{ height:8px; }
.h-menu-panel .h-util-btn.h-menu-theme{
  width:100%; min-height:48px;
  padding:14px 8px; margin-left:0;
  border-left:0;
  justify-content:flex-start; gap:14px;
  font-family:var(--disp); font-weight:700;
  font-size:13px; letter-spacing:0.14em; text-transform:uppercase;
  color:var(--mid);
}
.h-menu-panel .h-util-btn.h-menu-theme:focus-visible{
  outline:2px solid var(--amber); outline-offset:-2px;
}
.h-menu-theme-label{ display:inline-block; }
.h-menu-panel a.cur::before{
  content:'';display:inline-block;width:6px;height:6px;border-radius:50%;
  background:var(--amber);box-shadow:0 0 6px var(--amber);
  margin-right:10px;vertical-align:middle;
}
.h-menu-panel a[href="/pro/"]:not(.cur){ color:var(--amber); }
.h-menu-panel a[href="/pro/"]:not(.cur):hover{ color:#f4b840; }

/* Lock body scroll while menu is open. Defined identically in
   index.html inline CSS for landing; CSS cascade picks whichever
   loads last. Functionally identical. */
body.hm-open{ overflow:hidden; }

/* ============================================================
   LIGHT THEME (extension 2026-05-28). Activates the body.light toggle
   on every page that loads legal.css (meth-header pages: methodology,
   privacy, hardware, estimate, plus the four legal/* trust pages and
   /legal/index.html). Pro/showroom/welcome/404 have their own inline
   token overrides because they don't load this CSS file.

   Token strategy mirrors landing's :root override at index.html:177:
     - bg/s1-s3: cool blue-grey palette (DESIGN.md "deliberately not
       white"), s1 whiter than bg so cards float against canvas
     - b1/b2: lighter borders for the content surfaces
     - amber: shifted from #e8a020 (dark-mode amber) to #a85a00
       (richer + WCAG AA on light bg)
     - text/mid/dim: dark-on-light, cool tone matches bg hue
   ============================================================ */
body.light{
  --bg:#e9edf3; --s1:#fbfcff; --s2:#dfe5ed; --s3:#cbd4e0;
  --b1:#cbd2dd; --b2:#a8b1c0;
  --amber:#a85a00; --adim:rgba(168,90,0,0.12);
  --red:#931c1f; --red2:#b32426; --rdim:rgba(179,36,38,0.08);
  --green:#055f4c;
  --text:#1a1f2e; --mid:#364158; --dim:#4a5468;
}

/* meth-header chrome overrides for light theme. The header background
   is hardcoded rgba(7,9,12,.96) in the dark-default rule and can't
   reference a token because rgba() can't take a CSS variable. Mirror
   landing's light-mode chrome treatment so the meth-header reads as
   the same chrome family in either theme. */
body.light .meth-header{ background:rgba(251,252,255,0.94); }
body.light .meth-header .dot{ box-shadow:0 0 8px rgba(168,90,0,0.55); }
body.light .h-menu-panel{ background:rgba(251,252,255,0.98); }
/* Same shape for the .lh chrome (estimate + legal/* pages) and
   .legal-header chrome (showroom/nc2-stock). These were missing from
   PR #313's first pass; without them the headers stay dark in light
   mode. Caught in post-merge audit 2026-05-28. */
body.light .lh{ background:rgba(251,252,255,0.92); }
body.light .legal-header{ background:rgba(251,252,255,0.96); }
body.light .legal-header .dot{ box-shadow:0 0 8px rgba(168,90,0,0.55); }
/* Scrolled variants (header-fade pages re-apply solid bg once user
   scrolls past 60px via scroll-fade.js). Without these, headers go
   transparent on scroll then re-darken in light mode. */
body.light.header-fade.is-scrolled .meth-header{ background-color:rgba(251,252,255,0.96); }
body.light.header-fade.is-scrolled .legal-header{ background-color:rgba(251,252,255,0.96); }
body.light.header-fade.is-scrolled .lh{ background-color:rgba(251,252,255,0.92); }

/* Theme-toggle button icon swap (same pattern as landing's
   .h-util-btn .ti-sun / .ti-moon at index.html:441-443). Sun visible
   in dark mode (tap to switch to light), moon in light mode (tap to
   switch back). */
.h-util-btn .ti-moon{ display:none; }
body.light .h-util-btn .ti-sun{ display:none; }
body.light .h-util-btn .ti-moon{ display:block; }

/* Crossfade animation for theme flips after first paint. The pre-paint
   theme-init script (inline at start of each <body>) sets initialized
   only AFTER the first apply, so the initial render is snap-applied
   without a crossfade. Manual toggle + OS-preference live change DO
   fire the crossfade. */
body.theme-transitioning,
body.theme-transitioning *{
  transition: background-color 220ms ease, color 220ms ease, border-color 220ms ease, box-shadow 220ms ease !important;
}
@media (prefers-reduced-motion: reduce){
  body.theme-transitioning,
  body.theme-transitioning *{ transition:none !important; }
}

@media (prefers-reduced-motion: reduce){
  .meth-header .h-menu-line{ transition:none; }
  .h-menu-panel{ transition:none; }
}

/* Mobile reflows for trust pages */
@media (max-width: 720px){
  /* flex-wrap removed 2026-05-26: hamburger replaces the inline nav so
     the header collapses to one row (logo + spacer + back-home + ☰).
     The prior wrap-to-multiple-rows behavior fired when the inline nav
     didn't fit; now the nav is hidden on phone and rendered inside the
     hamburger panel below. */
  .meth-header{ padding:14px 18px; gap:10px; flex-wrap:nowrap; }
  /* Inline nav hidden on phone — replaced by the hamburger panel.
     Prior phone-specific .meth-header .nav rule (2026-05-16 tap-target
     bump to 13px font) is preserved in git history but inert here
     since the nav is display:none. */
  .meth-header .nav{ display:none; }
  /* Back-home stays inline in row 1 (no longer full-width). The prior
     full-width-on-phone treatment was tied to the wrap-to-row-3
     layout; with single-row layout it sits flat next to the spacer.
     flex-shrink:0 prevents it from squeezing if the spacer needs to
     give up space at iPhone SE widths. Fades out on scroll past 60px
     via body.is-scrolled rule (see below). */
  .meth-header .back-home{
    width:auto;
    justify-content:center;
    margin-top:0;
    flex-shrink:0;
  }
  /* Hamburger reveals on phone. */
  .meth-header .h-menu-btn{ display:inline-flex; }
  /* Panel becomes flex on phone (still gated by .open for the reveal). */
  .h-menu-panel{ display:flex; }
  .meth-hero{ padding:40px 22px 22px; }
  .meth-hero h1{ font-size:30px; }
  .meth-section{ padding:32px 22px 8px; }
  /* Outro + footer tightening 2026-05-26: founder feedback that the
     bottom box "seems big" on phone. The outro section ("Spot something
     wrong in the math?") is one short paragraph but inherited the
     full 32px top padding of regular meth-sections, and the meth-foot
     immediately below stacked another 22px top + 22px bottom for one
     short uppercase line. Combined ~84px of pure padding for ~2 lines
     of text. Compresses the outro to 18px/4px and the meth-foot to
     14px/16px on phone. Laptop padding unchanged. */
  .meth-outro{ padding:18px 22px 4px; }
  .meth-foot{ padding:14px 22px 16px; }
  /* Phone changelog: tighter card padding + line-height so the entry reads as
     a denser block instead of a sparse, narrow text box (founder feedback). */
  .log-row{ grid-template-columns:1fr; gap:4px; padding:12px 14px; }
  .log-row .what{ line-height:1.55; }
  .limits{ grid-template-columns:1fr; }
  .priv-fields .row{ grid-template-columns:1fr; gap:4px; }
  .priv-fields .row .when{ text-align:left; }
  .priv-never{ grid-template-columns:1fr; }
  .priv-svc .row{ grid-template-columns:1fr; gap:4px; }
  .priv-svc .row.h{ display:none; }
  .priv-rights{ grid-template-columns:1fr; }
}

/* ============================================================
   DESIGN-HANDOFF BUNDLE 2026-05-21 — appended block.

   Selectors below (.lh, .lhero, .lsection, .lh2, .lprose, .lmono,
   .tldr, .kvtab, .neglist, .posgrid, .emblock, .lupdate, .lcross,
   .lfoot, .lcallout, .mailto) are the new visual template for the
   /legal/refunds, /legal/support, and /legal/ hub pages.

   The bundle's source used .callout for its callout pattern. The
   existing /legal/* surfaces (Termly-generated terms + privacy +
   cookies) already use .callout with different markup + styling.
   Renamed to .lcallout in this appended block to avoid the
   selector clash.

   Bundle's @import of colors_and_type.css is intentionally omitted
   because every token referenced by the appended selectors is
   already in the :root block at the top of this file. New tokens
   (--red, --dur-snappy) were added to :root in the same commit.
   ============================================================ */

/* Sticky header (bundle .lh) */
.lh {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; gap: 24px;
  padding: 14px 32px;
  background: rgba(7, 9, 12, 0.92);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--b1);
}
.lh-logo {
  display: inline-flex; align-items: center; gap: 10px;
  text-decoration: none; color: var(--text);
  font-family: var(--disp); font-weight: 700; font-size: 16px;
  letter-spacing: 0.04em; text-transform: uppercase;
}
.lh-dot {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--amber);
  box-shadow: 0 0 12px rgba(232, 160, 32, 0.55);
}
.lh-name em { font-style: normal; color: var(--amber); }
.lh-nav {
  /* margin-left: auto pushes nav to the right edge so layout reads
     logo-left | nav-right (matches dashboard/account header pattern).
     Founder feedback 2026-05-29: nav-next-to-logo "looks squeezed"
     on lh pages; nav-on-right reads cleaner. The .lh-spacer element
     that previously absorbed the gap is now redundant but left in
     markup as a harmless dead div (removing it requires editing 7
     pages; CSS-only fix is the surgical move). */
  display: flex; gap: 18px; margin-left: auto;
  font-family: var(--disp); font-size: 11px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--mid);
}
.lh-nav a { color: var(--mid); text-decoration: none; transition: color var(--dur-snappy); }
.lh-nav a:hover { color: var(--text); }
.lh-nav a.cur {
  color: var(--text); border-bottom: 1px solid var(--amber); padding-bottom: 2px;
}
/* PRO is the upgrade path; highlight it amber when the user is NOT
   already on /pro/. When on /pro/ the link gets .cur (white + amber
   underline) and the page itself is the amber moment. Mirrors the
   landing rule in index.html. Reviewer-endorsed 2026-05-23. */
.lh-nav a[href="/pro/"]:not(.cur) { color: var(--amber); }
.lh-nav a[href="/pro/"]:not(.cur):hover { color: #f4b840; }
/* Account slot gating (2026-05-27): mirrors the .meth-header .nav rules
   and index.html lines 382-387 so the lh-header legal/estimate cluster
   carries the same single account slot as every other page. SIGN IN +
   PRO (free-only) show for logged-out visitors; ACCOUNT (pro-only)
   shows once pro-nav.js sets body[data-pro="1"]. */
.lh-nav .h-nav-pro-only { display: none; }
body[data-pro="1"] .lh-nav .h-nav-pro-only { display: inline-block; }
body[data-pro="1"] .lh-nav .h-nav-free-only { display: none; }
.lh-spacer { margin-left: auto; }
/* .lh-meta hidden 2026-05-29: founder feedback was that the
   "LEGAL · TERMS" / "LEGAL · REFUNDS" / etc. wayfinding strip on
   the far right was taking layout real estate that nav should
   occupy. With .lh-nav now pushed to the right, the meta would sit
   next to nav and clutter the chrome. The page-identity wayfinding
   role is taken over by the h1 hero on each page ("Terms of
   Service", "Refund policy", etc.) plus the URL bar. Estimate''s
   "ESTIMATOR" meta is collateral (also hidden); founder accepted
   the trade-off when filing this fix. To restore on estimate
   specifically, add an inline style override on estimate/index.html. */
.lh-meta {
  display: none;
  font-family: var(--mono); font-size: 10px;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--dim);
}
/* Laptop bump on inner-page chrome 2026-05-23. The phone default of 16px
   brand reads cramped on 1280px+ monitors. Bumping to 20px on laptop only
   keeps the content-surface intent (smaller than landing's 23px) while
   giving the brand enough presence for the larger viewport. Nav text
   stays at 11px — inner pages are reading surfaces, nav chrome stays
   compact. See docs/design/design-tokens.md "Brand-surface vs content-
   surface" for the system. */
@media (min-width: 881px) {
  .lh-logo { font-size: 20px; gap: 12px; }
  .lh-dot { width: 11px; height: 11px; }
}
@media (max-width: 720px) {
  .lh { padding: 12px 18px; flex-wrap: wrap; gap: 14px; }
  .lh-nav { width: 100%; margin-left: 0; overflow-x: auto; padding-bottom: 2px; gap: 12px; }
  .lh-meta { display: none; }
}
/* Phone audit 2026-05-23 P1 BLOCKER: at iPhone widths 375/390 the
   cumulative width of the 5 nav labels (HOME/SHOWROOM/METHODOLOGY/PRO/
   HARDWARE) exceeded the viewport by ~32px, clipping HARDWARE off the
   right edge with no visible scroll cue. Shrinking the gap and the
   letter-spacing brings the total under both 375 and 390 budgets
   without touching font-size or padding. Laptop (>=881px) and tablet
   (481-720px) layouts unchanged. See
   docs/reviews/phone-only-audit-2026-05-23.md §4 for the budget math. */
@media (max-width: 480px) {
  .lh-nav { gap: 8px; }
  .lh-nav a { letter-spacing: 0.10em; }
}

/* Hero (bundle .lhero) */
.lhero {
  padding: 56px 40px 28px;
  position: relative; overflow: hidden;
  border-bottom: 1px solid var(--b1);
  max-width: 1100px;
  margin: 0 auto;
}
.lhero::before {
  content: attr(data-watermark);
  position: absolute; right: -16px; top: -28px;
  font-family: var(--disp); font-style: italic; font-weight: 800;
  font-size: clamp(140px, 18vw, 240px); letter-spacing: -0.04em;
  color: rgba(255, 255, 255, 0.012);
  pointer-events: none; line-height: 1;
}
.lhero .eyebrow {
  font-family: var(--disp); font-size: 11px; font-weight: 700;
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--amber);
  margin-bottom: 14px;
  display: flex; align-items: center; gap: 10px;
}
.lhero .eyebrow::before {
  content: ''; display: block; width: 28px; height: 1px; background: var(--amber);
}
.lhero h1 {
  font-family: var(--disp); font-weight: 800;
  font-size: clamp(28px, 3.2vw, 40px);
  letter-spacing: 0; line-height: 1.05;
  text-transform: uppercase; margin: 0 0 16px;
  max-width: 880px;
  text-wrap: balance;
}
.lhero h1 em { font-style: italic; color: var(--amber); }
.lhero .sub {
  font-family: var(--serif); font-size: 16px; line-height: 1.7;
  color: var(--text); max-width: 720px; margin: 0;
}
.lhero .sub b { color: var(--text); font-weight: 700; }
.lhero .sub em { color: var(--mid); font-style: italic; }
.lhero .sub a { color: var(--amber); text-decoration: none; border-bottom: 1px solid rgba(232, 160, 32, 0.5); }
@media (max-width: 720px) { .lhero { padding: 36px 18px 20px; } }

/* Section (bundle .lsection) */
.lsection {
  padding: 40px 40px 18px;
  border-top: 1px solid var(--b1);
  max-width: 1100px;
  margin: 0 auto;
}
@media (max-width: 720px) { .lsection { padding: 28px 18px 14px; } }

.lh2 {
  font-family: var(--disp); font-weight: 800; font-size: 22px;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--text);
  margin: 0 0 18px; display: flex; align-items: baseline; gap: 14px;
}
.lh2 .num {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.18em;
  color: var(--amber); text-transform: uppercase;
}

/* Prose (bundle .lprose, .lmono) */
.lprose {
  font-family: var(--serif); font-size: 16px; line-height: 1.7;
  color: var(--text); max-width: 720px; margin: 0 0 14px;
}
.lprose b { color: var(--text); font-weight: 700; }
.lprose em { color: var(--mid); font-style: italic; }
.lprose a { color: var(--amber); text-decoration: none; border-bottom: 1px solid rgba(232, 160, 32, 0.5); padding-bottom: 1px; }
.lprose a:hover { border-bottom-color: var(--amber); }
.lprose code {
  font-family: var(--mono); font-size: 13px;
  background: var(--s2); border: 1px solid var(--b1);
  padding: 1px 6px; color: var(--text);
}
.lmono {
  font-family: var(--mono); font-size: 13px; line-height: 1.7;
  color: var(--mid); max-width: 720px; margin: 0 0 14px;
}
.lmono strong { color: var(--text); font-weight: 500; }

/* Sub-heading + list styling for the long legal pages (terms). The short
   siblings (refunds/cookies/support) use .kvtab/.neglist instead and
   carry no .lh3/.llist, so these selectors only affect terms. Harmonized
   with .lprose (serif body, amber accents). */
.lh3 {
  font-family: var(--disp); font-weight: 700; font-size: 15px;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--text);
  margin: 24px 0 10px;
}
.llist {
  font-family: var(--serif); font-size: 16px; line-height: 1.7;
  color: var(--text); max-width: 720px; margin: 0 0 14px; padding-left: 22px;
}
.llist li { margin-bottom: 8px; }
.llist li::marker { color: var(--amber); }

/* Terms uses the new .lh2/.lprose/.lcallout vocabulary INSIDE the
   doc-shell + page-toc layout (it's long enough to keep the contents
   sidebar). The full-width .lsection wrapper would fight the 2-column
   grid, so section separation is a ruled .lh2 instead. Scoped to
   .doc-shell so the single-column siblings are untouched. */
.doc-shell .lh2 {
  margin-top: 40px; padding-top: 32px; border-top: 1px solid var(--b1);
}
.doc-shell main > .lh2:first-child {
  margin-top: 0; padding-top: 0; border-top: none;
}

/* TL;DR card (bundle .tldr) */
.tldr {
  border: 1px solid var(--b1); border-left: 2px solid var(--amber);
  background: var(--adim);
  padding: 22px 26px; max-width: 760px;
  margin: 4px 0 22px;
}
.tldr h4 {
  font-family: var(--disp); font-weight: 800; font-size: 12px;
  letter-spacing: 0.20em; text-transform: uppercase; color: var(--amber);
  margin: 0 0 14px;
}
.tldr ol {
  margin: 0; padding-left: 24px;
  font-family: var(--serif); font-size: 16px; line-height: 1.6; color: var(--text);
  list-style: none; counter-reset: tldr;
}
.tldr ol li {
  counter-increment: tldr;
  position: relative; margin-bottom: 12px;
  padding-left: 0;
}
.tldr ol li::before {
  content: counter(tldr, decimal-leading-zero);
  position: absolute; left: -34px; top: 2px;
  font-family: var(--mono); font-size: 12px; color: var(--amber);
  letter-spacing: 0.10em;
}
.tldr ol li b { color: var(--text); font-weight: 700; }
.tldr ol li:last-child { margin-bottom: 0; }
/* Closing note under a TL;DR list: marks the box as a non-binding
   summary (used on /legal/terms). Muted mono so it reads as a footnote,
   not another list item. */
.tldr-note {
  margin: 16px 0 0;
  font-family: var(--mono); font-size: 12px; line-height: 1.6;
  letter-spacing: 0.04em; color: var(--dim);
}

/* Key/value table (bundle .kvtab) */
.kvtab {
  border: 1px solid var(--b1); max-width: 880px;
  margin: 8px 0 18px;
}
.kvtab .row {
  display: grid; grid-template-columns: 200px 1fr 120px;
  gap: 18px; padding: 12px 18px;
  border-bottom: 1px solid var(--b1);
  align-items: baseline;
}
.kvtab .row:last-child { border-bottom: none; }
.kvtab .row .k {
  font-family: var(--disp); font-weight: 700; font-size: 12px;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--text);
}
.kvtab .row .v {
  font-family: var(--mono); font-size: 13px; line-height: 1.65; color: var(--mid);
}
.kvtab .row .v b { color: var(--text); font-weight: 500; }
.kvtab .row .when {
  font-family: var(--mono); font-size: 12px; color: var(--amber);
  letter-spacing: 0.10em; text-transform: uppercase; text-align: right;
}
.kvtab .row .when.dim { color: var(--dim); }
@media (max-width: 720px) {
  .kvtab .row { grid-template-columns: 1fr; gap: 4px; }
  .kvtab .row .when { text-align: left; }
}

/* Negative-list grid (bundle .neglist) */
.neglist {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px;
  background: var(--b1); border: 1px solid var(--b1); max-width: 880px;
  margin: 8px 0 18px;
}
.neglist .cell {
  background: var(--s1); padding: 14px 18px;
  display: flex; gap: 12px; align-items: baseline;
}
.neglist .cell .x {
  font-family: var(--mono); font-size: 12px; color: var(--red);
  flex-shrink: 0; font-weight: 700;
}
.neglist .cell .v {
  font-family: var(--mono); font-size: 12px; line-height: 1.55; color: var(--text);
}
.neglist .cell .v b { color: var(--text); font-weight: 500; }
.neglist .cell .v span.dim { color: var(--mid); display: block; font-size: 11px; margin-top: 2px; }
@media (max-width: 600px) { .neglist { grid-template-columns: 1fr; } }

/* Positive grid (bundle .posgrid, used by support response-times) */
.posgrid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px;
  background: var(--b1); border: 1px solid var(--b1); max-width: 880px;
  margin: 8px 0 18px;
}
.posgrid .cell {
  background: var(--s1); padding: 16px 18px;
}
.posgrid .cell .l {
  font-family: var(--disp); font-weight: 700; font-size: 12px;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--amber);
  margin-bottom: 8px;
}
.posgrid .cell .num {
  font-family: var(--disp); font-weight: 800; font-size: 28px;
  letter-spacing: -0.01em; color: var(--text); line-height: 1;
  font-variant-numeric: tabular-nums;
  margin-bottom: 6px;
}
.posgrid .cell .v {
  font-family: var(--mono); font-size: 12px; line-height: 1.6; color: var(--mid);
  margin: 0;
}
.posgrid .cell .v a {
  color: var(--text); text-decoration: none;
  border-bottom: 1px solid var(--b2); padding-bottom: 1px;
}
.posgrid .cell .v a:hover { color: var(--amber); border-bottom-color: var(--amber); }
@media (max-width: 720px) { .posgrid { grid-template-columns: 1fr; } }

/* Email block (bundle .emblock) */
.emblock {
  display: grid; grid-template-columns: auto 1fr; gap: 18px; align-items: center;
  border: 1px solid var(--b1); border-left: 2px solid var(--amber);
  padding: 18px 22px; max-width: 760px;
  margin: 8px 0 22px;
}
.emblock .icn {
  font-family: var(--mono); font-size: 24px; color: var(--amber); line-height: 1;
}
.emblock .l {
  font-family: var(--mono); font-size: 10px; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--dim); margin: 0 0 4px;
}
.emblock .v {
  font-family: var(--disp); font-weight: 800; font-size: 22px;
  letter-spacing: 0.02em; text-transform: lowercase; color: var(--text);
  margin: 0;
}
.emblock .v a { color: var(--amber); border-bottom: 1px solid rgba(232, 160, 32, 0.5); text-decoration: none; }
.emblock .h { font-family: var(--mono); font-size: 12px; color: var(--mid); margin: 4px 0 0; letter-spacing: 0.04em; }

/* ============================================================
   Cross-links (.lcross) + update strip (.lupdate).

   Promoted from terms.html inline CSS 2026-05-29: /legal/terms got
   a polished reskin in PR #296 (new markup pattern + hover arrow +
   tighter mobile breakpoint + dedicated focus state + prose lupdate),
   but the redesign was scope-limited to terms — the other 4 trust
   pages (/legal/cookies /refunds /support /privacy) stayed on the
   pre-#296 pattern. Founder feedback 2026-05-29:

     "I noticed that there are 01 Terms of Use, 02 Cookies, 03 Refunds,
      04 Support in the legal page there are buttons but i feel like
      its not consistency in each page to click to move between pages"

   These rules are the new pattern, lifted verbatim from terms inline
   CSS into the shared stylesheet so all 5 legal pages share one CSS
   source. The 4 stragglers' markup is migrated in the same PR.

   Selector scope verified: .lcross / .ll / .n / .t / .lupdate / .ver
   are used nowhere else in the codebase outside /legal/* pages, so
   promoting them to legal.css cannot accidentally hit other surfaces.

   Markup contract:
     <nav class="lcross" aria-label="Other legal pages">
       <a class="ll" href="...">
         <span class="n">01</span>
         <span class="t">Title Case</span>
       </a>
       <a class="ll cur" href="...">...</a>  // current page
       ...
     </nav>
   ============================================================ */
.lcross {
  margin-top: 48px;
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1px; background: var(--b1);
  border: 1px solid var(--b1);
}
.ll {
  background: var(--s1);
  padding: 18px 20px;
  display: flex; flex-direction: column; gap: 4px;
  text-decoration: none; color: inherit;
  transition: background 0.18s ease;
}
.ll:hover { background: var(--adim); }
.ll:focus-visible { outline: 2px solid var(--amber); outline-offset: -2px; background: var(--adim); }
.ll .n {
  font-family: var(--mono); font-size: 10px; font-weight: 600;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--dim);
}
.ll .t {
  font-family: var(--disp); font-size: 13px; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--text);
  display: flex; align-items: center; gap: 8px;
}
.ll .t::after {
  content: '→'; font-family: var(--mono); font-size: 13px; color: var(--mid);
  margin-left: auto;
  transition: transform 0.15s ease, color 0.15s ease;
}
.ll:hover .t { color: var(--amber); }
.ll:hover .t::after { color: var(--amber); transform: translateX(2px); }
.ll.cur { background: var(--adim); }
.ll.cur .t { color: var(--amber); }
.ll.cur .t::after { display: none; }
@media (max-width: 720px) { .lcross { grid-template-columns: 1fr 1fr; } }
@media (max-width: 480px) { .lcross { grid-template-columns: 1fr; } }

/* Update strip (.lupdate): prose pattern from terms reskin.
   "Last updated 2026-05-21 · v2.0" + optional "Send feedback ↗" link.
   Replaces the prior bureaucratic "<b>LAST UPDATED:</b> ... <b>VERSION:</b>"
   middot-separated pattern on the 4 stragglers. */
.lupdate {
  margin-top: 32px;
  padding: 14px 20px;
  background: var(--s2);
  border: 1px solid var(--b1);
  display: flex; justify-content: space-between; align-items: center;
  flex-wrap: wrap; gap: 10px;
  font-family: var(--mono); font-size: 12px; color: var(--mid);
  letter-spacing: 0.04em;
}
.lupdate .ver { color: var(--amber); font-weight: 600; letter-spacing: 0.10em; text-transform: uppercase; }
.lupdate a { color: var(--amber); text-decoration: underline; text-underline-offset: 3px; }

/* Footer (bundle .lfoot) */
.lfoot {
  padding: 28px 40px 24px;
  border-top: 1px solid var(--b1);
  font-family: var(--mono); font-size: 12px; color: var(--dim);
  letter-spacing: 0.10em;
  display: flex; justify-content: space-between; gap: 18px; flex-wrap: wrap;
  margin: 40px auto 0;
  max-width: 1100px;
}
.lfoot a { color: var(--mid); text-decoration: none; border-bottom: 1px solid transparent; transition: color var(--dur-snappy), border-color var(--dur-snappy); }
.lfoot a:hover { color: var(--amber); border-bottom-color: var(--amber); }
@media (max-width: 720px) { .lfoot { padding: 22px 18px; flex-direction: column; gap: 8px; } }

/* Soft warning callout (bundle .callout, renamed to .lcallout to avoid
   clashing with the existing .callout used by Termly terms + privacy
   + cookies and the legacy refunds/support pages before this refactor). */
.lcallout {
  border: 1px solid var(--b1); border-left: 2px solid var(--amber);
  background: var(--adim);
  padding: 16px 20px; max-width: 760px;
  margin: 8px 0 18px;
  display: grid; grid-template-columns: 140px 1fr; gap: 18px; align-items: baseline;
}
.lcallout .l {
  font-family: var(--disp); font-weight: 700; font-size: 11px;
  letter-spacing: 0.20em; text-transform: uppercase; color: var(--amber);
}
.lcallout .v {
  font-family: var(--serif); font-size: 16px; line-height: 1.7; color: var(--text);
}
.lcallout .v b { color: var(--text); font-weight: 700; }
@media (max-width: 600px) { .lcallout { grid-template-columns: 1fr; gap: 6px; } }

/* Inline mailto link (bundle .mailto) */
.mailto {
  font-family: var(--mono); font-size: inherit;
  color: var(--amber); border-bottom: 1px solid rgba(232, 160, 32, 0.5);
  text-decoration: none; padding-bottom: 1px;
}
.mailto:hover { border-bottom-color: var(--amber); }

/* Scroll-fade header (phone walkthrough 2026-05-22 item 10).
   Non-landing pages opt-in by adding `class="header-fade"` to <body>
   plus loading /legal/scroll-fade.js, which toggles `is-scrolled` on
   the body once the user scrolls ~60px past the top. Header sits
   transparent above the content above the fold, then bg + border
   fade back in once content slides under it. Long reading surfaces
   (methodology, legal, hardware) feel less app-shell-y this way; the
   landing keeps its always-visible header by simply not opting in. */
body.header-fade .meth-header,
body.header-fade .legal-header,
body.header-fade .lh {
  transition: background-color 220ms ease-out, border-bottom-color 220ms ease-out, backdrop-filter 220ms ease-out;
  background-color: transparent;
  border-bottom-color: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
body.header-fade.is-scrolled .meth-header {
  background-color: rgba(7, 9, 12, 0.96);
  border-bottom-color: var(--b1);
}
/* The scroll-hide rule for .meth-header .back-home that lived here
   from 2026-05-26 to 2026-05-26 was reverted per founder feedback the
   same day: "don't hide the home button when scrolling down anymore".
   The original intent was to recover vertical space for long-form
   reading, but the founder found the in-and-out behavior less useful
   than keeping the affordance always visible. Plain CSS deletion;
   the body.is-scrolled class is still toggled by scroll-fade.js and
   still drives the header background-fade rules below. */
body.header-fade.is-scrolled .legal-header {
  background-color: rgba(7, 9, 12, 0.96);
  border-bottom-color: var(--b1);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
body.header-fade.is-scrolled .lh {
  background-color: rgba(7, 9, 12, 0.92);
  border-bottom-color: var(--b1);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
@media (prefers-reduced-motion: reduce) {
  body.header-fade .meth-header,
  body.header-fade .legal-header,
  body.header-fade .lh {
    transition: none;
  }
}

/* ============================================================
   SCROLL-DRIVEN REVEALS (2026-05-29).

   Brings landing's fade-up-as-you-scroll pattern to the content pages
   (/methodology, /hardware, /showroom, /pro, /welcome) that were
   essentially motionless documents. Founder ask after the chrome
   unification: "any suggestion to make it feel more premium ... it
   feels static."

   Diagnosis: landing has 32 animations + 45 reveals. The five content
   pages above have near-zero local motion. Bouncing between an alive
   landing and a static methodology read as "static" overall.

   Pattern: elements marked [data-reveal] start at opacity:0 with a
   small translateY(14px) offset. Shared /assets/js/scroll-reveal.js
   attaches an IntersectionObserver that adds .revealed when each
   element's top scrolls into the viewport (threshold:0 + a -10% bottom
   margin). threshold:0, not a fraction, so a section taller than the
   viewport still reveals (15% of a multi-screen section can never be
   on screen at once). One-shot per element.

   Stagger: [data-reveal-index="0|1|2"] for siblings that share a
   scroll position (e.g. 3-card rows) — 60ms desktop, 50ms mobile.

   Reduced-motion: every target marked .revealed at init (no observer).
   No-IntersectionObserver: same fallback.

   Durations + offset values inlined here rather than tokenized; legal.css
   doesn't currently carry --dur-reveal / --stagger-base, and a one-place
   value (only used by these rules) doesn't earn a token per the design
   discipline rule. Matches landing's values (400ms desktop, 300ms
   mobile, 60ms / 50ms stagger). ============================================================ */
[data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.4s ease-out, transform 0.4s ease-out;
  /* Safety net: if the reveal JS never runs (scroll-reveal.js 404s, throws, or
     JS is off), un-hide the content after a delay so a script failure cannot
     leave a section permanently blank. scroll-reveal.js adds .reveal-js-ok the
     moment it runs (well before the delay), which cancels this animation so the
     normal scroll-driven reveal is untouched. */
  animation: dr-safety-reveal 0.01s linear 6s forwards;
}
html.reveal-js-ok [data-reveal] { animation: none; }
@keyframes dr-safety-reveal { to { opacity: 1; transform: translateY(0); } }
[data-reveal][data-reveal-index="0"] { transition-delay: 0ms; }
[data-reveal][data-reveal-index="1"] { transition-delay: 60ms; }
[data-reveal][data-reveal-index="2"] { transition-delay: 120ms; }
[data-reveal][data-reveal-index="3"] { transition-delay: 180ms; }
[data-reveal].revealed { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  [data-reveal] { opacity: 1; transform: none; transition: none; animation: none; }
}
@media (max-width: 880px) {
  [data-reveal] {
    transform: translateY(8px);
    transition: opacity 0.3s ease-out, transform 0.3s ease-out;
  }
  [data-reveal][data-reveal-index="1"] { transition-delay: 50ms; }
  [data-reveal][data-reveal-index="2"] { transition-delay: 100ms; }
  [data-reveal][data-reveal-index="3"] { transition-delay: 150ms; }
}
