/* Canticle app shell (M2 skeleton) — design system inherited from the engine (UX-SPEC §0).
   Self-hosted fonts (SIL OFL), candle-lit palette, ≥44px targets, reduced-motion path. */

/* THE TYPE SPINE (DESIGN-ELEVATION C1, 2026-07-07) — the two faces the design docs unanimously endorsed:
   Fraunces (variable, optical-size serif — the candle-lit display voice) + Atkinson Hyperlegible Next
   (variable — the Braille Institute's low-vision body face: disambiguated I/l/1, 0/O, rn/m, large x-height).
   Self-hosted (INV-03), OFL notices ship beside the files; latin + latin-ext subsets (the German door). */
@font-face {
  font-family: 'Fraunces';
  font-style: normal; font-weight: 100 900; font-display: swap;
  src: url('fonts/Fraunces-VF-roman-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal; font-weight: 100 900; font-display: swap;
  src: url('fonts/Fraunces-VF-roman-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Fraunces';
  font-style: italic; font-weight: 100 900; font-display: swap;
  src: url('fonts/Fraunces-VF-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Fraunces';
  font-style: italic; font-weight: 100 900; font-display: swap;
  src: url('fonts/Fraunces-VF-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Atkinson Hyperlegible Next';
  font-style: normal; font-weight: 200 800; font-display: swap;
  src: url('fonts/AtkinsonHyperlegibleNext-VF-roman-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Atkinson Hyperlegible Next';
  font-style: normal; font-weight: 200 800; font-display: swap;
  src: url('fonts/AtkinsonHyperlegibleNext-VF-roman-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Atkinson Hyperlegible Next';
  font-style: italic; font-weight: 200 800; font-display: swap;
  src: url('fonts/AtkinsonHyperlegibleNext-VF-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Atkinson Hyperlegible Next';
  font-style: italic; font-weight: 200 800; font-display: swap;
  src: url('fonts/AtkinsonHyperlegibleNext-VF-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ============================================================================
   THEME SYSTEM (AURORA-THEMES drive). One token contract, three singer-selectable
   looks: aurora (default) · candle (the calm dark base) · paper (warm-paper day).
   A theme = a [data-theme] attribute on <html> swapping ONE token block — every
   shell component already reads var(--…), so all screens theme cohesively for free.
   The accents (gold/teal/green/blue, INV-08) live in the theme-INVARIANT spine, so
   a theme can never recolour target/home/voice away. The engine iframe is sealed:
   the sing-screen INTERIOR keeps the locked candle-lit note look in every theme (by
   design — calm holds where you sing). high-contrast (body.high-contrast) stays an
   orthogonal a11y override that wins over any theme.  See SETTINGS-ARCHITECTURE.md.
   ============================================================================ */
:root {
  /* ── SPINE — theme-invariant ── */
  /* INV-08 semantic accents (gold = target, teal = home/tonic, green = success, blue = voice). Never red. */
  --gold:#b07d2a; --gold-bright:#d9a44a; --teal:#2f827a; --teal-bright:#62bc9f;
  --green:#3f9d5a; --green-bright:#52b06f; --blue:#1f6ad6;
  /* VISUAL-2: green finally gets the bright dark-theme twin gold+teal always had — small green TEXT
     (.prec-praise, .dv-spark-n, .traj-fact b, .sv-ic) measured 3.3-3.9:1 via --ink-green=--green; the
     twin clears AA on bg/panel/panel-2 (7.05/5.82/5.23). Fills/large text keep --green (hue unchanged). */
  --teal-rgb:47,130,122; --green-rgb:63,157,90;   /* teal warmed 2026-07-06 (Nick device note: teal read too contrasty on the warm ground) — rgb tracks --teal; the 6x teal + 7x green alpha-washes follow the tokens */
  /* AA-safe ink twins for accent TEXT on light grounds (the two-token rule) */
  --gold-ink:#8a5e14; --green-ink:#2a6e3c; --teal-ink:#2f6d61;  /* VISUAL-2: green-ink 2f7a43->2a6e3c — 4.17:1 on the report vellum, now 4.9+ on every paper ground; teal-ink warmed 1a6675->2f6d61 (5.1:1 on cream) 2026-07-06 */
  /* text-accent tokens — resolve to BRIGHT on dark themes, to the dark inks on paper (set per theme) */
  --ink-gold:var(--gold-bright); --ink-green:var(--green-bright); --ink-teal:var(--teal); --ink-blue:var(--blue);
  --serif:'Fraunces','Hoefler Text',Baskerville,'Palatino Linotype',Palatino,Georgia,'Times New Roman',serif;
  --sans:'Atkinson Hyperlegible Next','Avenir Next',Avenir,'Segoe UI',system-ui,-apple-system,Roboto,'Helvetica Neue',Arial,sans-serif;

  /* ── THE TYPE SCALE (DESIGN-ELEVATION C4) — one named ramp, 26 ad-hoc px retired into 9 steps.
     BLV-first: the sub-legible tier (9.5–11.5px) is gone; captions rise to 14; body reads at 18
     (the documented floor), verses at --fs-lead. Weight-led hierarchy carries the rest. ── */
  --fs-micro:12.5px;   /* chips, badges, kbd — the hard floor (was 9.5–12) */
  --fs-caption:14px;   /* metadata, captions, footnotes (was 12.5–13.5) */
  --fs-small:15.5px;   /* secondary UI: buttons, links, meta rows (was 14–15.5) */
  --fs-body:18px;      /* reading text — the low-vision floor (was 16–17) */
  --fs-lead:19px;      /* verses + card titles (was 18–19) */
  --fs-h3:21px;        /* section heads (was 20–21) */
  --fs-h2:24px;        /* view heads (was 22–24) */
  --fs-h1:28px;        /* page heads (was 26–28) */
  --fs-display:34px;   /* the wordmark tier */
  --lh-tight:1.15; --lh-base:1.5; --lh-loose:1.65;
  --atmos:1;    /* Aurora atmosphere multiplier (Calm 0 · Soft .6 · Vivid 1); DEFAULT = Vivid (Nick's call); inert in other themes */

  /* ── DEFAULT GROUND = AURORA (so the app is fully themed even before/without JS) ── */
  --bg:#13100b; --panel:#2a2218; --panel-2:#332a1d; --cream:#f4ead4; --muted:#ac9a78; --line:#3a2f22;
  --edge-light:rgba(244,234,212,.07);
  /* elevation fallback = the aurora recipe (the per-theme blocks below override) */
  --elev-1: inset 0 1px 0 var(--edge-light), 0 2px 6px rgba(0,0,0,.32), 0 10px 28px rgba(0,0,0,.22);
  --elev-2: inset 0 1px 0 var(--edge-light), 0 4px 10px rgba(0,0,0,.38), 0 16px 40px rgba(0,0,0,.28);
  --elev-3: 0 12px 48px rgba(0,0,0,.55);
  --elev-sheet: 0 -8px 40px rgba(0,0,0,.5);
}

/* ── SHELL-POLISH — SHAPE-LANGUAGE SCALE ──
   Name every corner radius so the front door reads from ONE source, the same value-keyed
   way the engine does (--r-N = N px; --r-pill/--r-circle the two round ends). Each token =
   today's EXACT value — this is a VALUE-PRESERVING fold (nothing shifts; the render is byte-
   identical), the same display-only token discipline as the engine's radius scale + the
   polish-2 --edge-sheen fold. --gold-bright-rgb names the gold-bright channel triple so the
   alpha washes that already equal --gold-bright (#d9a44a) stop being a floating magic number. */
:root {
  --r-2:2px; --r-3:3px; --r-6:6px; --r-8:8px; --r-10:10px; --r-11:11px; --r-12:12px;
  --r-13:13px; --r-14:14px; --r-16:16px; --r-18:18px; --r-40:40px; --r-pill:999px; --r-circle:50%;
  --ink-on-gold:#1b140a;  /* C9-a: the highest-frequency un-tokened color, written two ways (1b140a/1a1305) — ONE ink for text on gold fills */
  --gold-bright-rgb:217,164,74; --gold-rgb:176,125,42;  /* VISUAL-AURORA-1: --r-13 + the base-gold channel twin join the scale (same value-preserving principle) */
}

/* ── THEME TOKEN BLOCKS — the ONLY thing a theme swaps ── */
/* ELEVATION (DESIGN-ELEVATION C2): one light source, three steps, tuned PER THEME so every theme
   gets appropriate depth — aurora = lit top-edge + deep warm ambient; candle = the same physics,
   dimmer; paper = a soft sepia letterpress cast + the hairline (NEVER a bright top-highlight on a
   light ground). Decorative and behind content: no contrast or colour-semantics impact (INV-08). */
html[data-theme="aurora"] {           /* C — living light, the default dark */
  --bg:#13100b; --panel:#2a2218; --panel-2:#332a1d; --cream:#f4ead4; --muted:#ac9a78; --line:#3a2f22;
  --edge-light:rgba(244,234,212,.07);
  --elev-1: inset 0 1px 0 var(--edge-light), 0 2px 6px rgba(0,0,0,.32), 0 10px 28px rgba(0,0,0,.22);
  --elev-2: inset 0 1px 0 var(--edge-light), 0 4px 10px rgba(0,0,0,.38), 0 16px 40px rgba(0,0,0,.28);
  --elev-3: 0 12px 48px rgba(0,0,0,.55);
  --elev-sheet: 0 -8px 40px rgba(0,0,0,.5);
}
html[data-theme="candle"] {           /* A — Illuminated Quires: the current candle-lit dark look */
  --bg:#15110c; --panel:#2a2218; --panel-2:#332a1d; --cream:#f3e9d6; --muted:#a5947a; --line:#3a2f22;  /* VISUAL-2: muted 9c8a6e->a5947a — was 4.21:1 on panel-2 (.set-theme-desc), now 4.78 */
  --edge-light:transparent;
  --elev-1: 0 2px 6px rgba(0,0,0,.28), 0 10px 28px rgba(0,0,0,.18);
  --elev-2: 0 4px 10px rgba(0,0,0,.34), 0 16px 40px rgba(0,0,0,.24);
  --elev-3: 0 12px 48px rgba(0,0,0,.55);
  --elev-sheet: 0 -8px 40px rgba(0,0,0,.5);
}
html[data-theme="paper"] {            /* B — Hymnal Leaf: warm-paper day. --cream holds the dark text ink here. */
  --bg:#f4ecd8; --panel:#fbf6e9; --panel-2:#efe6cf; --cream:#2a2218; --muted:#6b5e47; --line:#ddd0ad;
  --edge-light:transparent;
  --ink-gold:var(--gold-ink); --ink-green:var(--green-ink); --ink-teal:var(--teal-ink); --green-rgb:47,122,67;
  --elev-1: 0 1px 2px rgba(74,58,32,.10), 0 6px 18px rgba(74,58,32,.08);
  --elev-2: 0 2px 4px rgba(74,58,32,.14), 0 12px 30px rgba(74,58,32,.12);
  --elev-3: 0 12px 40px rgba(74,58,32,.28);
  --elev-sheet: 0 -8px 32px rgba(74,58,32,.22);
}

* { box-sizing: border-box; }
html, body { margin: 0; }

/* a11y: skip link (keyboard) + high-contrast palette variant (UX-SPEC §7.2, D4) */
.skip-link { position: absolute; left: -9999px; top: 0; z-index: 100; background: var(--gold-bright); color: var(--ink-on-gold); font-weight: 600; padding: 10px 16px; border-radius: 0 0 var(--r-10) 0; }
.skip-link:focus { left: 0; }
body.high-contrast {
  --bg: #0a0805; --panel: #241d14; --panel-2: #2f2517; --cream: #fdf8ee; --muted: #d2c099;
  --gold: #e0ad52; --gold-bright: #f3c873; --line: #6a583c;
  /* VISUAL-2: HC forces a near-black ground but never overrode the INK trio — a paper-theme user
     tapping High contrast (the exact low-vision overlap persona) got paper's DARK inks on black
     (2.47-3.52:1 measured). The inks now follow the forced ground. */
  --ink-gold: var(--gold-bright); --ink-teal: var(--teal-bright); --ink-green: var(--green-bright);
  /* C2: high-contrast wins over theme — depth is decorative; HC gets clean strong edges, no casts */
  --elev-1: none; --elev-2: none;
}
body {
  background: var(--bg); color: var(--cream); font-family: var(--sans);
  font-size: var(--fs-body); line-height: 1.5; -webkit-text-size-adjust: 100%;
  min-height: 100dvh;
}
.view { min-height: 100dvh; }
.view[hidden] { display: none; }
/* A862 SAFE-AREA (non-trainer pages): clear the device status bar / notch in PORTRAIT so the top content (e.g. the
   song page's "‹ Library" button) is never under the phone chrome. env(safe-area-inset-top) is 0 on desktop AND in
   landscape (status bar hidden), so this is a no-op there — landscape song-details + the trainer are unchanged. */
.wrap { max-width: 760px; margin: 0 auto; padding: calc(16px + env(safe-area-inset-top, 0px)) 18px 48px; }

/* buttons / links / a11y baseline — NEVER a white underline anywhere (FIX A) */
button { font-family: inherit; cursor: pointer; }
a { color: inherit; text-decoration: none; }
/* SHELL-POLISH: a 3px gold focus ring to match the engine's (stronger, more visible — better a11y, one hand). */
:focus-visible { outline: 3px solid var(--gold-bright); outline-offset: 2px; border-radius: var(--r-6); }
.link { background: none; border: none; color: var(--ink-gold); font-size: var(--fs-small); text-decoration: none; padding: 8px; min-height: 44px; }
.link:hover { color: var(--cream); }

/* ════════════════════════════════════════════════════════════════════════════
   SHELL-POLISH — ICON HAND. One line-icon vocabulary lifted from the engine
   (A984/A985) so the front door and the trainer read from the SAME hand: 24-grid,
   2px round stroke, currentColor (themes correctly + never red, INV-08). Display-
   only; em-sized so each icon scales with its label. .bic = inline-before-a-label
   (carries its own gap); .nic = margin-free (spacing from the parent's flex gap);
   .nicf = the few genuinely-filled marks. Mirrors the engine's .bic/.nic/.nicf. */
.bic, .nic, .nicf { flex: 0 0 auto; overflow: visible; }
.bic { width: 1.06em; height: 1.06em; vertical-align: -.17em; margin-right: .44em; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.bic.warn { stroke: var(--gold-bright); }
.nic { width: 1.2em; height: 1.2em; vertical-align: -.2em; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.nicf { width: 1.06em; height: 1.06em; vertical-align: -.17em; fill: currentColor; stroke: none; }
/* the feeling-pulse faces (Nick's pick: line-SVG, one hand across the whole shell) — same 24-grid/2px-round/
   currentColor convention; the smile/flat/frown carry the meaning, the aria-label carries it to a screen reader. */
.face { width: 1.12em; height: 1.12em; flex: 0 0 auto; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
/* C7 iconography unification (ORDER 5): line-SVG twins that replaced the former text-glyph/emoji icons.
   All decorative + aria-hidden beside real text labels; currentColor only (INV-08 — theme + high-contrast safe). */
.back { display: inline-flex; align-items: center; }                 /* seat the chevron-left beside the label */
.wpath-ic svg { display: block; width: 1.2em; height: 1.2em; }        /* welcome-hero marks (mic / book / flame) */
.sg-caret svg { width: .9em; height: .9em; vertical-align: middle; }  /* the profile dropdown caret, caret-sized */
/* icon-only buttons — center the mark, size it off the button box (not its font-size). */
.set-mv, .set-rm, .set-bar-exit, .sheet-x { display: inline-flex; align-items: center; justify-content: center; }
.set-mv svg, .set-rm svg, .set-bar-exit svg, .sheet-x svg { width: 20px; height: 20px; }
/* Phase 2 durability (RL-141): calm Export/Restore + A2HS nudge — no red, ≥44px targets, token colors. */
.backup-row { display: flex; flex-wrap: wrap; gap: 12px; margin: 6px 0 2px; }
.link-btn { background: none; border: none; color: var(--muted); font: inherit; font-size: var(--fs-caption); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; padding: 10px 4px; min-height: 44px; }
.link-btn:hover { color: var(--ink-gold); }
.a2hs-nudge { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 4px 0 10px; padding: 10px 14px; border-radius: var(--r-12); background: var(--panel); border: 1px solid var(--line, #6a583c); color: var(--cream); font-size: var(--fs-small); }
.a2hs-nudge button { background: var(--gold-bright); color: var(--ink-on-gold); border: none; border-radius: var(--r-8); padding: 8px 14px; font-weight: 600; min-height: 44px; cursor: pointer; }
/* RL-142/144/145: the "Start here" on-ramp + More disclosure — calm, text-first, no red, ≥44px targets. */
.rail-rec { font-size: var(--fs-caption); font-weight: 400; color: var(--ink-gold); letter-spacing: .02em; }
/* Two-column on-ramp (RL-145): a CSS GRID that fills left→right top→down (grid-auto-flow: row), so DOM order =
   reading order = focus order (WCAG 1.3.2) and the easiest∩most-loved stays first DOM node AND top-left. auto-fit +
   minmax gives TWO columns where there's room and ONE on narrow phones / large text / high zoom (WCAG 1.4.10
   reflow) — automatically, no media query, no order:/flex/multi-column reordering. max-width caps it at 2 columns
   (3 × 14rem > the cap); 14rem keeps long titles ("Great Is Thy Faithfulness") from cramping. */
.onramp-list { list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr)); grid-auto-flow: row; gap: 8px 14px; max-width: 40rem; }
.onramp-item { margin: 0; }
.onramp-link { display: block; padding: 12px 14px; min-height: 44px; border-radius: var(--r-12); background: var(--panel); border: 1px solid var(--line, #6a583c); color: var(--cream); text-decoration: none; }
.onramp-link:hover { border-color: var(--gold-bright); }
.onramp-title { display: block; font-family: var(--serif, Georgia, serif); font-size: var(--fs-body); font-weight: 600; }
.onramp-first { display: block; font-size: var(--fs-caption); color: var(--muted); margin-top: 1px; }
.onramp-diff { display: block; font-size: var(--fs-micro); color: var(--muted); margin-top: 4px; }
.onramp-tier { color: var(--ink-gold); font-weight: 600; }
.more-btn { background: none; border: none; color: var(--ink-gold); font: inherit; font-size: var(--fs-lead); font-weight: 600; cursor: pointer; padding: 6px 0; min-height: 44px; }
.more-btn:hover { color: var(--cream); }
.rail-sub { font-size: var(--fs-small); color: var(--muted); margin: 6px 0 8px; font-weight: 600; }
[hidden] { display: none !important; }   /* RL-97: hidden content is removed from layout AND the tab order */
.back {
  background: transparent; border: 1px solid var(--line); color: var(--cream);
  font-size: var(--fs-small); padding: 0 14px; min-height: 44px; border-radius: var(--r-10); margin-bottom: 14px;
}
.back:hover { color: var(--ink-gold); border-color: var(--gold); }

/* ===== HOME / SEARCH ===== */
.home-head { max-width: 700px; margin: 0 auto; padding: calc(26px + env(safe-area-inset-top, 0px)) 18px 8px; }
.wordmark {
  font-family: var(--serif); font-weight: 600; font-size: clamp(34px, 9vw, 52px);
  letter-spacing: .01em; margin: 0; line-height: 1; color: var(--cream);
}
.tagline { font-family: var(--serif); font-style: italic; font-size: var(--fs-lead); color: var(--muted); margin: 6px 0 18px; }
/* A862: the sticky search must also stick BELOW the status bar in portrait (env=0 in landscape/desktop → unchanged). */
.search-row { position: sticky; top: calc(8px + env(safe-area-inset-top, 0px)); z-index: 5; }
.search {
  width: 100%; font-family: var(--sans); font-size: var(--fs-body); color: var(--cream);
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-12);
  padding: 0 16px; min-height: 48px; -webkit-appearance: none;
}
.search::placeholder { color: var(--muted); }
.search:focus { border-color: var(--gold); }
.count { color: var(--muted); font-size: var(--fs-caption); margin: 10px 2px 4px; }

.cards { max-width: 700px; margin: 0 auto; padding: 4px 18px 40px; display: grid; gap: 12px; }
@media (min-width: 560px) { .cards { grid-template-columns: 1fr 1fr; } }   /* two columns; each box only as wide as the difficulty row needs */
.card {
  display: block; width: 100%; min-width: 0; text-align: left; min-height: 44px; text-decoration: none;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-14);
  padding: 14px 16px; color: var(--cream); transition: border-color var(--dur-2) var(--ease-out), background var(--dur-2) var(--ease-out);
}
.card:hover { border-color: var(--gold); background: var(--panel-2); }
.card .title { font-family: var(--serif); font-weight: 600; font-size: var(--fs-h3); line-height: 1.15; }
.card .firstline { font-family: var(--serif); font-style: italic; color: var(--muted); font-size: var(--fs-small); margin-top: 2px;
  padding-left: 1.6em; text-indent: -0.4em; text-wrap: pretty; }   /* clean opening line; wraps within the box, never forces width */
.card .meta { display: flex; align-items: center; gap: 8px 10px; margin-top: 9px; flex-wrap: wrap; }
.card .meta .diff { flex-basis: 100%; }   /* difficulty on its own row; key/range/tune chips stack underneath */
/* VISUAL-2: the earlier duplicate .noresults def removed — the fuller rule below always won the cascade */

/* difficulty marker (FIX B) — LABELED "Difficulty" + a worded tier + a segmented meter + N/5.
   Deliberately NOT stars (stars read as a quality rating). Gold/neutral only — never red (INV-08).
   The tier word + N/5 carry the meaning so it's never color-only. */
.diff { display: inline-flex; align-items: center; gap: 7px; font-size: var(--fs-caption); color: var(--cream); }
.diff-lab { color: var(--muted); font-size: var(--fs-micro); letter-spacing: .12em; text-transform: uppercase; }
.diff-tier { font-weight: 500; }
.diff-meter { display: inline-flex; gap: 3px; }
.diff-seg { width: 13px; height: 6px; border-radius: var(--r-2); background: var(--line); }
.diff-seg.on { background: var(--gold); }
.diff-n { color: var(--muted); font-size: var(--fs-micro); }

/* chips (color is never the only signal — chips carry text) */
.chip {
  font-size: var(--fs-micro); color: var(--cream); background: rgba(var(--teal-rgb),.16);
  border: 1px solid rgba(var(--teal-rgb),.5); border-radius: var(--r-pill); padding: 3px 10px; white-space: nowrap;
}
.chip.key { background: rgba(var(--gold-rgb),.14); border-color: rgba(var(--gold-rgb),.5); }

/* ===== SONG PAGE ===== */
.song-title { font-family: var(--serif); font-weight: 600; font-size: clamp(28px, 8vw, 40px); line-height: 1.1; margin: 4px 0 0; }
.song-first { font-family: var(--serif); font-style: italic; font-size: var(--fs-lead); color: var(--muted); margin: 6px 0 14px; }
.song-facts { display: flex; flex-wrap: wrap; gap: 8px 10px; align-items: center; margin-bottom: 6px; }
.song-byline { color: var(--muted); font-size: var(--fs-small); margin: 10px 0 18px; }
.song-byline .bl-row { display: block; }                 /* each part (Words / Music / Tune) its own short line */
.song-byline .bl-lab { color: var(--muted); }            /* label visually quiet */
.song-byline .bl-val { color: var(--cream); }            /* value regular — hierarchy carried by colour, not weight */
.sing {
  display: block; width: 100%; min-height: 54px; margin: 4px 0 24px;
  background: var(--gold); color: var(--ink-on-gold); font-family: var(--sans); font-weight: 600; font-size: var(--fs-h3);
  letter-spacing: .04em; border: none; border-radius: var(--r-14); transition: background var(--dur-2) var(--ease-out);
}
.sing:hover { background: var(--gold-bright); }
.verses h2 { font-family: var(--sans); font-size: var(--fs-caption); letter-spacing: .16em; text-transform: uppercase; color: var(--muted); margin: 18px 0 6px; }
/* POLISH M1 — responsive lyric lines that fit the viewport in both orientations, with clean (hanging-indent)
   wrapping so a long line never merges into a wall of prose. clamp() = the shell's responsive idiom (cf .wordmark):
   smaller on a narrow phone, capped at the original 19px, floor 16px (never tiny). */
.verse { font-family: var(--serif); font-size: clamp(16px, 4.3vw, 19px); line-height: 1.5; color: var(--cream); margin: 0 0 18px; display: flex; gap: 8px; align-items: baseline; }
.verse .vn { color: var(--ink-gold); font-weight: 600; flex: none; }
.verse .vlines { flex: 1; min-width: 0; }
.verse .vl { display: block; padding-left: 1.15em; text-indent: -1.15em; }   /* hanging indent: a wrapped phrase reads as one indented continuation, not a new line */
.verse .vl + .vl { margin-top: 3px; }   /* faint separation so each hymn line is distinct */

/* ===== TRAINER ===== */
.trainer { display: flex; flex-direction: column; height: 100dvh; }
.trainer-bar { display: flex; align-items: center; gap: 12px; padding: 8px 12px; background: var(--panel); border-bottom: 1px solid var(--line); }
.trainer-bar .back { margin: 0; }
.trainer-title { font-family: var(--serif); font-size: var(--fs-lead); color: var(--cream); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.trainer-frame { flex: 1 1 auto; width: 100%; border: 0; background: var(--bg); }
/* C8a THE THRESHOLD (DESIGN-ELEVATION): a brief warm veil over the sing screen while the engine paints —
   the flash-cut becomes an arrival. Shell layer only (wraps the iframe; the sealed staff untouched).
   pointer-events:none so it can never gate a tap (P-ii); lifts on the frame's load + a hard 800ms
   ceiling so it can never wedge; reduced-motion never shows it at all. */
.trainer { position: relative; }
.trainer-veil { position: absolute; inset: 0; z-index: 4; background: var(--bg); opacity: 1;
  pointer-events: none; transition: opacity .22s var(--ease-out); }
.trainer-veil.lift { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .trainer-veil { display: none; } }
html.rm .trainer-veil { display: none; }
/* §4.2 landscape immersive lives INSIDE the engine (header→thin strip, roll fills, controls→one
   pausing drawer, Play/Mic pinned). Collapse the shell's own bar so the engine gets the full screen;
   the engine's own back/library control + browser-back return to the shell. */
@media (orientation: landscape) and (max-height: 600px) { .trainer-bar { display: none; } }

/* ===== HOME TOOLBAR (Filters + Sort) ===== */
.toolbar { display: flex; gap: 8px; align-items: center; margin-top: 10px; flex-wrap: wrap; }
.tool {
  display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 14px;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-10);
  color: var(--cream); font-size: var(--fs-small); font-family: var(--sans);
}
.tool:hover { border-color: var(--gold); }
.tool .tool-ic { color: var(--ink-gold); font-size: var(--fs-body); }
.tool.sort { gap: 8px; color: var(--muted); }
.tool.sort select { background: transparent; color: var(--cream); border: none; font-family: var(--sans); font-size: var(--fs-small); min-height: 44px; }
/* Theme the native dropdown popup where the browser honours it (Chrome/Firefox/Android) so the option list matches
   paper/candle/aurora instead of the OS default; the closed select stays transparent. Ignored on iOS wheel pickers. */
.tool.sort select option { background: var(--panel); color: var(--cream); }
.badge { background: var(--gold); color: var(--ink-on-gold); font-size: var(--fs-micro); font-weight: 600; border-radius: var(--r-pill); padding: 1px 7px; }

/* ===== RAILS + COLLECTIONS ===== */
.rail { max-width: 760px; margin: 22px auto 0; padding: 0 18px; }
.rail-h { font-family: var(--serif); font-weight: 600; font-size: var(--fs-h2); color: var(--cream); margin: 0 0 10px; }
.rail-scroll { display: flex; gap: 12px; overflow-x: auto; padding: 2px 0 12px; scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch; }
/* Top hymns: a responsive WRAPPING grid — everything visible at a glance, never a horizontal scrollbar */
.rail-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; padding: 2px 0 12px; }
.rail-grid .rcard { width: auto; }
.rail-scroll::-webkit-scrollbar { height: 6px; }
.rail-scroll::-webkit-scrollbar-thumb { background: var(--line); border-radius: var(--r-pill); }
.rcard {
  display: block;   /* load-bearing since the quick-add wrap: an inline <a> paints its card background as broken line-boxes */
  flex: 0 0 auto; width: 210px; scroll-snap-align: start; text-decoration: none;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-14); padding: 13px 15px;
  color: var(--cream); transition: border-color var(--dur-2) var(--ease-out), background var(--dur-2) var(--ease-out);
}
.rcard:hover { border-color: var(--gold); background: var(--panel-2); }
.rcard-title { font-family: var(--serif); font-weight: 600; font-size: var(--fs-lead); line-height: 1.15; }
.rcard-first { font-family: var(--serif); font-style: italic; color: var(--muted); font-size: var(--fs-caption); margin-top: 3px; }
.rcard-meta { color: var(--muted); font-size: var(--fs-micro); margin-top: 8px; }
.rail-empty { color: var(--muted); font-size: var(--fs-small); }
.collections { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (min-width: 560px) { .collections { grid-template-columns: 1fr 1fr 1fr; } }
.ccard {
  display: flex; flex-direction: column; justify-content: center; min-height: 76px; text-decoration: none;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-14); padding: 13px 15px;
  color: var(--cream); transition: border-color var(--dur-2) var(--ease-out), background var(--dur-2) var(--ease-out);
}
.ccard:hover { border-color: var(--gold); background: var(--panel-2); }
.ccard-label { font-family: var(--serif); font-weight: 600; font-size: var(--fs-lead); }
.ccard-n { color: var(--muted); font-size: var(--fs-micro); margin-top: 3px; }
/* RL-154 By-season / By-theme browse rails — a real <ul>; two columns, reflowing to ONE at narrow widths AND at
   200% zoom (the em-based breakpoint catches zoom that a px width may not). DOM order = reading/focus order. */
.browse-list { list-style: none; margin: 0; padding: 2px 0 12px; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 34em) { .browse-list { grid-template-columns: 1fr; } }
.browse-list .bcard {
  display: flex; align-items: center; justify-content: space-between; gap: 10px; text-decoration: none;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-12); padding: 11px 15px; min-height: 30px;
  color: var(--cream); transition: border-color var(--dur-2) var(--ease-out), background var(--dur-2) var(--ease-out);
}
.browse-list .bcard:hover { border-color: var(--gold); background: var(--panel-2); }
.browse-list .bcard-label { font-family: var(--serif); font-weight: 600; font-size: var(--fs-body); }
.browse-list .bcard-n { color: var(--muted); font-size: var(--fs-micro); }

/* Continue practicing card */
.cont-card {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; text-decoration: none;
  background: linear-gradient(180deg, var(--panel-2), var(--panel)); border: 1px solid var(--gold);
  border-radius: var(--r-14); padding: 14px 16px; color: var(--cream); min-height: 44px;
}
.cont-card:hover { border-color: var(--gold-bright); }
.cont-title { font-family: var(--serif); font-weight: 600; font-size: var(--fs-h3); }
.cont-sub { color: var(--muted); font-size: var(--fs-caption); margin-top: 2px; }
.cont-go { color: var(--ink-gold); font-weight: 600; font-size: var(--fs-small); white-space: nowrap; }
/* RL-164 progress-over-time — the calm "hymns you can sing with confidence" set. No streak/score chrome; the % is
   quiet self-metadata. Real <ul>; two-column grid reflowing to one at narrow/200% zoom; DOM order = reading order. */
.conf-note { color: var(--muted); font-size: var(--fs-caption); font-style: italic; margin: 2px 2px 10px; }
.conf-list { list-style: none; margin: 0; padding: 0 0 12px; display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 34em) { .conf-list { grid-template-columns: 1fr; } }
.conf-card { display: flex; flex-direction: column; justify-content: center; min-height: 56px; text-decoration: none;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-12); padding: 11px 15px; color: var(--cream); }
.conf-card:hover { border-color: var(--gold); background: var(--panel-2); }
.conf-title { font-family: var(--serif); font-weight: 600; font-size: var(--fs-lead); }
.conf-sub { color: var(--muted); font-size: var(--fs-micro); margin-top: 3px; }

/* THE GARDEN (Improvement Track, Concept A) — gentle, observation-first; no numbers, no badges, never alarm. */
.gd-note { color: var(--muted); font-size: var(--fs-caption); font-style: italic; margin: 2px 2px 8px; line-height: 1.5; }
.gd-hear { background: none; border: 1px solid var(--line); color: var(--ink-gold); font-size: var(--fs-small); border-radius: var(--r-pill);
  padding: 7px 16px; min-height: 44px; cursor: pointer; margin: 0 0 10px; }
.gd-hear:hover { border-color: var(--gold); background: var(--panel); }
.gd-list { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.gd-list li { color: var(--cream); font-size: var(--fs-small); line-height: 1.55; padding: 9px 13px; border-radius: var(--r-12);
  background: var(--panel); border: 1px solid var(--line); }
/* SHELL-POLISH: the garden bullet is the line-hand leaf (a currentColor-tinted mask, not the 🌱 emoji),
   so the Garden rail reads in the same hand as the rest of the chrome. Green = growth (INV-08), never alarm. */
.gd-list li::before { content: ""; display: inline-block; width: .95em; height: .95em; margin-right: .5em; vertical-align: -.12em;
  background: var(--ink-green);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5.5 19.5c0-7.5 5.6-13.6 14-14 .5 8.5-5.6 14.6-14 14z'/%3E%3Cpath fill='none' stroke='%23000' stroke-width='1.4' d='M7 18 17 7'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5.5 19.5c0-7.5 5.6-13.6 14-14 .5 8.5-5.6 14.6-14 14z'/%3E%3Cpath fill='none' stroke='%23000' stroke-width='1.4' d='M7 18 17 7'/%3E%3C/svg%3E") center / contain no-repeat; }
.gd-quiet { color: var(--cream); font-size: var(--fs-small); line-height: 1.55; margin: 2px 0 10px; }
.gd-sugg { color: var(--cream); font-size: var(--fs-small); line-height: 1.55; margin: 4px 0 4px; }
/* C6 THE GARDEN, ALIVE (DESIGN-ELEVATION): each noticing TAKES ROOT — a soft one-shot staggered settle-in
   on the FIRST render of a visit only (.gd-enter, stamped once). The sprig beside the note DRAWS itself and
   its settling arc rests PARTIAL — deliberately never a full arc, never a fraction: growth noticed, never
   metered (the Garden charter: no number, no score, no filled-to-100 ring). Reduced-motion rests at the
   final frame, which IS the partial position — no meaning lives in the motion. */
.gd-enter .gd-list li { animation: gd-take-root .55s var(--ease-settle) both; transform-origin: left center; }
.gd-enter .gd-list li:nth-child(2) { animation-delay: .09s; }
.gd-enter .gd-list li:nth-child(3) { animation-delay: .18s; }
.gd-enter .gd-list li:nth-child(4) { animation-delay: .27s; }
.gd-enter .gd-sugg { animation: gd-take-root .55s var(--ease-settle) .36s both; }
@keyframes gd-take-root { from { opacity: 0; transform: translateY(5px) scale(.985); } to { opacity: 1; transform: none; } }
.gd-sprig { width: 22px; height: 22px; vertical-align: -6px; margin-left: 2px;
  fill: none; stroke-width: 1.8; stroke-linecap: round; }
.gd-sprig .sp-stem { stroke: var(--ink-green); }
.gd-sprig .sp-arc { stroke: var(--ink-teal); opacity: .55; stroke-dasharray: 44; stroke-dashoffset: 17; }   /* rests PARTIAL — never 0 ("full") */
.gd-enter .gd-sprig .sp-stem { stroke-dasharray: 30; stroke-dashoffset: 30; animation: gd-draw .9s var(--ease-draw) .25s forwards; }
.gd-enter .gd-sprig .sp-arc { stroke-dashoffset: 44; animation: gd-arc 1.1s var(--ease-settle) .45s forwards; }
@keyframes gd-draw { to { stroke-dashoffset: 0; } }
@keyframes gd-arc { to { stroke-dashoffset: 17; } }
@media (prefers-reduced-motion: reduce) {
  .gd-enter .gd-list li, .gd-enter .gd-sugg { animation: none; }
  .gd-enter .gd-sprig .sp-stem { animation: none; stroke-dasharray: none; }
  .gd-enter .gd-sprig .sp-arc { animation: none; stroke-dashoffset: 17; }
}
html.rm .gd-enter .gd-list li, html.rm .gd-enter .gd-sugg { animation: none; }
html.rm .gd-enter .gd-sprig .sp-stem { animation: none; stroke-dasharray: none; }
html.rm .gd-enter .gd-sprig .sp-arc { animation: none; stroke-dashoffset: 17; }
.gd-sugg .gd-card { display: inline-flex; min-height: 0; padding: 4px 10px; margin: 0 2px; vertical-align: middle; border-radius: var(--r-10); }
.gd-sugg .gd-card .conf-title { font-size: var(--fs-body); }

.results-head { max-width: 700px; margin: 12px auto 4px; padding: 0 18px; color: var(--muted); font-size: var(--fs-caption); letter-spacing: .04em; text-transform: uppercase; }
.home-foot { max-width: 760px; margin: 34px auto 24px; padding: 0 18px; color: var(--muted); font-size: var(--fs-caption); text-align: center; }
.foot-toggle { background: none; border: 1px solid var(--line); color: var(--muted); border-radius: var(--r-pill); padding: 6px 12px; min-height: 44px; font-size: var(--fs-micro); margin: 0 10px 8px 0; }
.foot-toggle:hover { border-color: var(--gold); color: var(--cream); }
.foot-toggle[aria-pressed="true"] { border-color: var(--gold); color: var(--ink-gold); }
.no-scroll { overflow: hidden; }

/* no-results recovery */
.noresults { max-width: 700px; margin: 0 auto; text-align: center; color: var(--muted); padding: 26px 18px; }
.nr-chips { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; margin: 12px 0; }
.chip-btn { display: inline-block; text-decoration: none; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-pill); color: var(--cream); font-size: var(--fs-caption); padding: 8px 14px; min-height: 44px; }
.chip-btn:hover { border-color: var(--gold); }
.nr-tip { font-size: var(--fs-caption); }
.nr-alt { margin-top: 14px; }
.nr-alt a { color: var(--ink-gold); text-decoration: underline; text-underline-offset: 3px; }

/* ===== FILTERS SHEET ===== */
.sheet { position: fixed; inset: 0; z-index: 50; }
.sheet-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,.55); }
.sheet-body {
  position: absolute; left: 0; right: 0; bottom: 0; max-height: 82dvh; overflow-y: auto;
  background: var(--panel); border-top: 1px solid var(--line); border-radius: var(--r-18) var(--r-18) 0 0;
  padding: 8px 18px max(18px, env(safe-area-inset-bottom)); max-width: 640px; margin: 0 auto;
  animation: sheet-up var(--dur-2) ease;
}
@keyframes sheet-up { from { transform: translateY(12px); opacity: .6; } to { transform: none; opacity: 1; } }
.sheet-head { display: flex; align-items: center; justify-content: space-between; position: sticky; top: 0; background: var(--panel); padding: 8px 0; }
.sheet-head h2 { font-family: var(--serif); font-size: var(--fs-h2); margin: 0; }
.sheet-x { background: none; border: none; color: var(--muted); font-size: var(--fs-h1); line-height: 1; min-height: 44px; min-width: 44px; }
.fgroup { margin: 6px 0 14px; }
.fgroup h3 { font-family: var(--sans); font-size: var(--fs-micro); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); margin: 0 0 8px; }
.fchips { display: flex; flex-wrap: wrap; gap: 8px; }
.fchip { background: var(--panel-2); border: 1px solid var(--line); color: var(--cream); font-size: var(--fs-caption); border-radius: var(--r-pill); padding: 8px 14px; min-height: 44px; }
.fchip:hover { border-color: var(--gold); }
.fchip.on { background: rgba(176,125,42,.22); border-color: var(--gold); color: var(--ink-gold); }
.sheet-foot { display: flex; align-items: center; justify-content: space-between; position: sticky; bottom: 0; background: var(--panel); padding: 12px 0 4px; border-top: 1px solid var(--line); }
.apply { background: var(--gold); color: var(--ink-on-gold); font-family: var(--sans); font-weight: 600; font-size: var(--fs-body); border: none; border-radius: var(--r-12); min-height: 48px; padding: 0 22px; }
.apply:hover { background: var(--gold-bright); }

/* ===== SONG PAGE richness ===== */
.alt-titles { color: var(--muted); font-size: var(--fs-caption); font-style: italic; margin: 2px 0 0; }
.set-voice { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-12); padding: 12px 14px; margin: 0 0 18px; font-size: var(--fs-small); color: var(--cream); }
.set-voice.on { border-color: rgba(var(--green-rgb),.5); }
.set-voice .sv-ic { color: var(--ink-green); font-weight: 700; margin-right: 6px; }
.detail-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-bottom: 8px; }
.detail-row .why { color: var(--muted); font-size: var(--fs-small); font-style: italic; }
.factors { margin: 4px 0 14px; }
.factors summary { color: var(--ink-gold); font-size: var(--fs-small); cursor: pointer; min-height: 36px; display: inline-flex; align-items: center; }
/* A864: ensure the disclosure actually COLLAPSES its content (the custom `summary { display:inline-flex }` defeats
   the UA's default content-hiding, so the breakdown + factor table would show when closed). Force it explicitly. */
.factors:not([open]) > :not(summary) { display: none; }
/* the formatted difficulty breakdown, folded inside the disclosure (revealed on expand). Calm, never red. */
.factors .why { color: var(--cream); font-size: var(--fs-small); line-height: 1.45; margin: 8px 0 2px; }
.factors dl { display: grid; grid-template-columns: auto 1fr; gap: 4px 16px; margin: 8px 0 0; font-size: var(--fs-small); }
.factors dt { color: var(--muted); }
.factors dd { margin: 0; color: var(--cream); }
.sc-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }
.meta-section { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.meta-section .sc-chips { margin: 0; }
.meta-head { font-family: var(--sans); font-size: var(--fs-micro); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); margin: 0 0 8px; }
.chip.sc { background: rgba(var(--teal-rgb),.14); border-color: rgba(var(--teal-rgb),.45); }
.chip.theme { text-decoration: none; }
.chip.theme:hover { border-color: var(--gold); }
.chip.fits { background: rgba(var(--green-rgb),.16); border-color: rgba(var(--green-rgb),.5); color: var(--cream); }
.chip.fits.stretch { background: rgba(var(--gold-bright-rgb),.14); border-color: rgba(var(--gold-bright-rgb),.45); }  /* Drive-2 tier 3: a friendly stretch — gold (invitation), never red (INV-08) */
.provenance { color: var(--muted); font-size: var(--fs-caption); margin: 22px 0 8px; }
#song-recs { margin-left: 0; margin-right: 0; padding: 0; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}

/* ─── Launch 1: Progress & Profiles ─── */
/* A863: clearer separation from the search box below (was a 2px gap → felt crowded/overlapping on a phone). */
/* C3: the profile row lives below the door now — it carries the home content inset itself */
.singers { display: flex; align-items: center; gap: 8px; max-width: 760px; margin: 14px auto 0; padding: 0 18px; font-size: var(--fs-caption); color: var(--muted); flex-wrap: wrap; }
.sg-label { letter-spacing: .04em; }
.sg-wrap { display: inline-flex; }
/* HOME PROFILE LINK (dashboard-elevation #1) — a persistent premium door into #/you, beside the name.
   A gold-washed identity chip with a rising-spark icon; lit a touch in aurora, AA-safe ink in every theme. */
/* calm chip (review nit): icon + text on a hairline, no filled gradient/glow — so the explore link complements
   the identity selector beside it rather than out-shouting it. Still premium (gold ink + the rising-spark icon). */
.sg-explore { display: inline-flex; align-items: center; gap: 6px; font: inherit; font-size: var(--fs-caption); font-weight: 600;
  color: var(--ink-gold); text-decoration: none; padding: 5px 13px 5px 11px; min-height: 38px; border-radius: var(--r-40);
  border: 1px solid var(--line); background: none; cursor: pointer; }
.sg-explore .nic { width: 1.05em; height: 1.05em; color: var(--gold-bright); }
.sg-explore:hover { border-color: var(--gold); background: rgba(var(--gold-bright-rgb),.06); }
body.high-contrast .sg-explore { border-color: var(--gold-bright); background: var(--panel); }
.sg-current { font: inherit; font-weight: 600; color: var(--cream); background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-40); padding: 5px 14px; min-height: 38px; display: inline-flex; align-items: center; gap: 2px; cursor: pointer; }
.sg-caret { display: inline-block; transition: transform var(--dur-2) ease; }
.sg-current[aria-expanded="true"] .sg-caret { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .sg-caret { transition: none; } }
/* A863 r2: an in-flow COLLAPSE/EXPAND panel (was an absolute overlay that COVERED the search and never collapsed —
   `display:flex` overrode the `hidden` attribute, so it was always-shown + grew with each singer). Now: flex-basis
   100% → reflows onto its own line below the row (pushes the search DOWN, never oversteps it); max-height + scroll →
   a long list is BOUNDED (never grows the page); and `.sg-menu[hidden]{display:none}` makes the toggle actually
   collapse it (constant resting height regardless of singer count). */
.sg-menu { flex-basis: 100%; order: 9; display: flex; flex-direction: column; gap: 2px; width: 100%; max-width: 260px;
  max-height: 38vh; overflow-y: auto; -webkit-overflow-scrolling: touch; margin-top: 6px;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-12); padding: 5px; box-shadow: var(--elev-2); }
.sg-menu[hidden] { display: none; }
.sg-opt { font: inherit; text-align: left; color: var(--cream); background: none; border: 0; border-radius: var(--r-8); padding: 9px 11px; min-height: 44px; display: flex; align-items: center; cursor: pointer; }
.sg-opt:hover { background: rgba(255,255,255,.06); }
.sg-opt.on { color: var(--ink-gold); font-weight: 600; }
.sg-opt i { color: var(--muted); font-style: normal; font-size: var(--fs-micro); }
.sg-add { border-top: 1px solid var(--line); margin-top: 3px; color: var(--ink-gold); }

/* RL-146 Phase 3 — accessible listbox switcher (role=listbox/option; ✓ + bold for the active singer, never colour
   alone; focus ring ≥3:1; ≥44px option rows). */
.sg-listbox { list-style: none; margin: 4px 0 0; padding: 4px; flex-basis: 100%; order: 9; width: 100%; max-width: 280px;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-12); box-shadow: var(--elev-2); }
.sg-listbox[hidden] { display: none; }
.sg-listbox:focus-visible { outline: 3px solid var(--gold-bright); outline-offset: 2px; }
.sg-opt[role="option"] { display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 8px 10px; border-radius: var(--r-8); color: var(--cream); cursor: pointer; }
.sg-opt[role="option"].on { color: var(--ink-gold); font-weight: 700; }   /* bold + ✓ glyph, not colour alone */
.sg-opt[role="option"].focus { background: rgba(var(--gold-bright-rgb),.18); outline: 2px solid var(--gold-bright); outline-offset: -2px; }
.sg-check { width: 1em; display: inline-block; color: var(--ink-gold); }
.sg-kind { color: var(--muted); font-size: var(--fs-micro); font-weight: 400; }
.sg-actions { flex-basis: 100%; order: 10; margin-top: 4px; }
.sg-actions[hidden] { display: none; }

/* RL-146 Phase 4 — manager + delete confirm (focus-trapped role=dialog; calm, NO red, ≥44px). */
.mgr-overlay, .del-overlay { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center; padding: 18px; background: rgba(10,8,5,.6); }
.del-overlay { z-index: 1010; }
.mgr-card, .del-card { width: 100%; max-width: 30rem; max-height: 90vh; overflow: auto; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-16); padding: 18px; color: var(--cream); }
.mgr-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.mgr-title { font-family: var(--serif); font-size: var(--fs-h2); margin: 0; }
.mgr-x { background: none; border: 1px solid var(--line); color: var(--cream); border-radius: var(--r-10); min-height: 44px; padding: 0 14px; cursor: pointer; }
.mgr-rows { list-style: none; margin: 12px 0; padding: 0; }
.mgr-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.mgr-name { font-family: var(--serif); font-size: var(--fs-lead); }
.mgr-kind { color: var(--muted); font-size: var(--fs-caption); }
.mgr-row-act { display: flex; gap: 10px; flex-wrap: wrap; }
.mgr-sub { font-size: var(--fs-small); margin: 14px 0 8px; }
.mgr-field { display: block; font-size: var(--fs-caption); color: var(--muted); margin-bottom: 10px; }
.mgr-field input { display: block; width: 100%; margin-top: 4px; min-height: 44px; font: inherit; color: var(--cream); background: var(--bg); border: 1px solid var(--line); border-radius: var(--r-10); padding: 0 12px; }
.mgr-kind[class] legend { color: var(--muted); font-size: var(--fs-caption); }
fieldset.mgr-kind { border: 1px solid var(--line); border-radius: var(--r-10); padding: 8px 12px; margin: 0 0 12px; display: flex; flex-wrap: wrap; gap: 12px; }
fieldset.mgr-kind label { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; }
.mgr-add-btn, .del-go, .del-keep { font: inherit; font-weight: 600; min-height: 44px; padding: 0 16px; border-radius: var(--r-10); cursor: pointer; }
.mgr-add-btn, .del-go { background: var(--gold-bright); color: var(--ink-on-gold); border: none; }
.del-title { font-family: var(--serif); font-size: var(--fs-h3); margin: 0 0 8px; }   /* NO red — calm */
.del-msg { color: var(--cream); font-size: var(--fs-small); margin: 0 0 12px; }
.del-btns { display: flex; gap: 12px; justify-content: flex-end; margin-top: 14px; }
.del-keep { background: var(--panel-2); color: var(--cream); border: 1px solid var(--gold); }

.song-progress { margin: 4px 0 10px; }
.pg-head { font-family: var(--serif); font-size: var(--fs-lead); margin: 0 0 8px; color: var(--cream); }
.pg-card { background: linear-gradient(180deg, rgba(var(--gold-bright-rgb),.12), rgba(var(--gold-bright-rgb),.04)); border: 1px solid rgba(var(--gold-bright-rgb),.32); border-radius: var(--r-14); padding: 12px 14px; margin-bottom: 10px; }
.pg-card-h { font-size: var(--fs-micro); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-gold); margin-bottom: 4px; }
.pg-row { color: var(--cream); font-size: var(--fs-small); }
.pg-row b { color: var(--ink-gold); }
.pg-kind { color: var(--cream); margin: 5px 0 0; font-size: var(--fs-caption); line-height: 1.5; }
.pg-tomorrow { color: var(--muted); margin: 7px 0 0; font-size: var(--fs-caption); line-height: 1.5; font-style: italic; }  /* Q-55: the one gentle scheduling line — quieter than the praise above it */
/* THE SHELF WITH AN OPEN DOOR (NEXT-DRIVE M3) — calm front-door block */
.open-door { max-width: 760px; margin: 8px auto 4px; padding: 0 18px; }
.od-h { font-family: var(--sans); font-size: var(--fs-caption); letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin: 0 0 10px; }
.od-door { display: block; text-decoration: none; border: 1px solid rgba(var(--gold-bright-rgb),.45); background: linear-gradient(180deg, rgba(var(--gold-bright-rgb),.10), rgba(var(--gold-bright-rgb),.04)); border-radius: var(--r-14); padding: 18px; transition: border-color var(--dur-2) var(--ease-out); }
.od-door:hover { border-color: var(--gold); }
.od-door-title { display: block; font-family: var(--serif); font-size: var(--fs-h3); color: var(--cream); margin-bottom: 4px; }
.od-door-sub { display: block; font-size: var(--fs-caption); line-height: 1.5; color: var(--muted); }
.od-helper { font-size: var(--fs-caption); color: var(--muted); margin: 8px 2px 0; line-height: 1.5; }
.od-reassure { font-size: var(--fs-caption); color: var(--ink-gold); margin: 8px 2px 0; line-height: 1.5; }  /* the first-timer confidence line at the door — calm/warm, never red (INV-08) */
.od-echo { font-style: italic; color: var(--muted); margin: 0 0 10px; font-size: var(--fs-caption); }
.od-continue { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; text-decoration: none; border: 1px solid rgba(var(--gold-bright-rgb),.4); border-radius: var(--r-12); padding: 13px 16px; }
.od-continue:hover { border-color: var(--gold); }
.od-cont-label { font-size: var(--fs-micro); letter-spacing: .04em; text-transform: uppercase; color: var(--muted); flex-basis: 100%; }
.od-cont-title { font-family: var(--serif); font-size: var(--fs-body); color: var(--cream); flex: 1; }
.od-revisit { font-size: var(--fs-caption); color: var(--muted); margin: 10px 2px 0; line-height: 1.5; }
.pg-focus { color: var(--cream); margin: 5px 0 0; font-size: var(--fs-caption); line-height: 1.5; }  /* the coach's ONE growth focus — same weight as the praise, never alarm-styled */
.pg-trend { color: var(--cream); margin: 6px 0 0; font-size: var(--fs-caption); line-height: 1.5; opacity: .93; }  /* the gentle pitch-accuracy trend — process-praise, never a score-as-verdict; silent on a dip */
.pg-path { color: var(--ink-gold); margin: 6px 0 0; font-size: var(--fs-small); line-height: 1.5; font-style: italic; }  /* THE PATH (Concept B): a soft per-hymn progression sentence; never a number/score */
.pg-traj { color: var(--ink-teal); margin: 6px 0 0; font-size: var(--fs-caption); line-height: 1.5; }  /* THE DEEPENED COACH trajectory line — carryover / personal best / journey; monotone, positive-only, never a score */
.pg-pulse { border: 1px solid var(--line); border-radius: var(--r-12); margin: 9px 0 2px; padding: 7px 10px 9px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pg-pulse legend { color: var(--muted); font-size: var(--fs-caption); padding: 0 4px; }
.pg-feel { background: none; border: 1px solid var(--line); border-radius: var(--r-pill); font-size: var(--fs-h2); line-height: 1; min-width: 44px; min-height: 44px; cursor: pointer; padding: 4px 8px; display: inline-flex; align-items: center; justify-content: center; }
.pg-feel:hover, .pg-feel:focus-visible { border-color: var(--gold); background: var(--panel); }
.pg-feel-skip { background: none; border: none; color: var(--muted); font-size: var(--fs-caption); min-height: 44px; padding: 4px 8px; cursor: pointer; margin-left: auto; }
.pg-feel-skip:hover, .pg-feel-skip:focus-visible { color: var(--cream); text-decoration: underline; }
.pg-feelack { color: var(--cream); margin: 8px 0 2px; font-size: var(--fs-small); line-height: 1.5; }  /* the warm word after a Feeling Pulse — never red (INV-08) */
.pg-speakrow { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 10px; }
.pg-voicetoggle-lbl { font-size: var(--fs-caption); color: var(--muted); display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.pg-speak { margin-top: 10px; background: none; border: 1px solid rgba(var(--gold-bright-rgb),.35); color: var(--cream); border-radius: var(--r-8); padding: 6px 12px; font-size: var(--fs-caption); cursor: pointer; }
.pg-speak:hover { border-color: var(--gold); }
.pg-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.pg-item { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-12); padding: 10px 6px; text-align: center; }
.pg-item b { display: block; font-family: var(--serif); font-size: var(--fs-h3); color: var(--ink-gold); line-height: 1.1; }
.pg-item span { display: block; font-size: var(--fs-micro); letter-spacing: .04em; color: var(--muted); margin-top: 3px; }
.pg-when { color: var(--muted); font-size: var(--fs-micro); margin: 7px 0 0; }
@media (max-width: 460px) { .pg-stats { grid-template-columns: repeat(2, 1fr); } }

/* ─── L4 Listen Beautifully ─── */
.cta-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.listen { font: inherit; font-weight: 600; color: var(--ink-gold); background: var(--panel); border: 1px solid rgba(var(--gold-bright-rgb),.5); border-radius: var(--r-40); padding: 11px 18px; cursor: pointer; min-height: 44px; }
.listen:hover { background: rgba(var(--gold-bright-rgb),.1); }
.listen.playing { color: var(--ink-on-gold); background: var(--gold-bright); border-color: var(--gold-bright); }

/* ════ THE SUNDAY SET (feat-sunday-set) — calm shelf + builder + step-through bar. Gold/teal/green palette only
   (INV-08, never red); ≥44px touch targets; focus rings inherit the global :focus-visible; theme-aware via vars. ════ */
.set-add.in-set { color: var(--ink-green); border-color: rgba(var(--green-rgb),.55); background: rgba(var(--green-rgb),.08); }
.sunday-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.sunday-plan { white-space: nowrap; }
.sunday-sing { margin-top: 12px; font: inherit; font-weight: 700; color: var(--ink-on-gold); background: var(--gold-bright); border: none; border-radius: var(--r-40); padding: 13px 22px; min-height: 48px; cursor: pointer; }
.sunday-sing:hover { background: var(--gold); }
.set-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin: 4px 0 18px; }
.set-list { list-style: none; margin: 0; padding: 0; max-width: 760px; }
.set-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--line); }
.set-row-card { flex: 1 1 auto; display: flex; align-items: center; gap: 12px; min-height: 44px; text-decoration: none; color: var(--cream); }
.set-row-card:hover { color: var(--ink-gold); }
.set-row-n { flex: 0 0 auto; width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center; border-radius: var(--r-circle); background: var(--panel-2); color: var(--muted); font-size: var(--fs-caption); font-weight: 700; }
.set-row-title { font-family: var(--serif); font-weight: 600; font-size: var(--fs-lead); }
.set-row-ctl { flex: 0 0 auto; display: flex; gap: 4px; }
.set-mv, .set-rm { width: 44px; min-height: 44px; background: none; border: 1px solid var(--line); border-radius: var(--r-10); color: var(--ink-gold); font-size: var(--fs-body); cursor: pointer; }
.set-mv:hover, .set-rm:hover { border-color: var(--gold); background: var(--panel-2); }
.set-mv:disabled { color: var(--muted); opacity: .4; cursor: default; }
.set-mv:disabled:hover { border-color: var(--line); background: none; }
.you-setlink { margin: 2px 0 0; }
/* the step-through bar — a thin shell strip ABOVE the iframe, sibling of the trainer bar (never over the canvas) */
.set-bar { display: flex; align-items: center; gap: 10px; padding: 6px 12px; background: var(--panel-2); border-bottom: 1px solid var(--line); }
.set-bar-pos { flex: 1 1 auto; color: var(--ink-gold); font-weight: 600; font-size: var(--fs-small); }
.set-bar-next { font: inherit; font-weight: 700; color: var(--ink-on-gold); background: var(--gold-bright); border: none; border-radius: var(--r-40); padding: 8px 16px; min-height: 44px; cursor: pointer; }
.set-bar-next:hover { background: var(--gold); }
.set-bar-exit { width: 44px; min-height: 44px; background: none; border: 1px solid var(--line); border-radius: var(--r-10); color: var(--muted); font-size: var(--fs-small); cursor: pointer; }
.set-bar-exit:hover { color: var(--ink-gold); border-color: var(--gold); }
@media (orientation: landscape) and (max-height: 600px) { .set-bar { display: none; } }

/* PITCH PHASE 2a — the Precision Report panel ("the bird"): calm, scannable, low-vision-first; gold/teal/green
   only, NEVER red (INV-08). A dismissible after-the-song review overlay. */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
#precision-overlay { position: fixed; inset: 0; z-index: 9998; display: flex; align-items: center; justify-content: center;
  background: rgba(10,8,5,.72); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); padding: 16px; }
#precision-overlay .prec-card { background: var(--panel); color: var(--cream); border: 1px solid rgba(var(--gold-bright-rgb),.45);
  border-radius: var(--r-18); box-shadow: var(--elev-3); max-width: 560px; width: 100%; max-height: 92vh; overflow: auto; padding: 22px 22px 18px; }
#precision-overlay .prec-head { font-family: var(--serif, Georgia, serif); font-weight: 600; font-size: var(--fs-h2); color: var(--ink-gold); margin: 0 0 8px; }
#precision-overlay .prec-summary { font-size: var(--fs-lead); line-height: 1.45; color: var(--cream); margin: 0 0 14px; }   /* leads — warm + process-first */
#precision-overlay .prec-figure { margin: 4px 0 14px; }
#precision-overlay .prec-ribbon { display: block; width: 100%; height: 150px; background: linear-gradient(180deg,#faf3e3,#efe4cc);
  border-radius: var(--r-12); border: 1px solid rgba(156,138,110,.4); }
/* legend names the two visual kinds in plain words (gold block = the notes · line = your voice) */
#precision-overlay .prec-legend { display: flex; gap: 20px; justify-content: center; flex-wrap: wrap; margin: 9px 0 1px; font-size: var(--fs-caption); color: var(--cream); }
#precision-overlay .prec-key { display: inline-flex; align-items: center; gap: 7px; }
#precision-overlay .prec-sw { display: inline-block; width: 20px; height: 13px; border-radius: var(--r-3); }
#precision-overlay .prec-sw-notes { background: rgba(var(--gold-bright-rgb),.34); border: 1px solid rgba(var(--gold-rgb),.75); }
#precision-overlay .prec-sw-voice { height: 0; border-radius: 0; border-top: 3px solid var(--green, #3f9d5a); }
#precision-overlay .prec-caption { font-size: var(--fs-caption); color: var(--muted); text-align: center; margin: 4px 0 0; line-height: 1.4; }
#precision-overlay .prec-steady { color: var(--ink-green); font-size: var(--fs-small); margin: 0 0 6px; }
#precision-overlay .prec-drift { color: var(--ink-gold); font-size: var(--fs-small); margin: 0 0 6px; }
#precision-overlay .prec-vib { color: var(--ink-teal); font-size: var(--fs-small); margin: 0 0 6px; }
#precision-overlay .prec-cents { color: var(--muted); font-size: var(--fs-caption); margin: 2px 0 16px; }                      /* quiet, secondary */
#precision-overlay .prec-close { font: inherit; font-weight: 600; color: var(--ink-on-gold); background: var(--gold-bright);
  border: none; border-radius: var(--r-40); padding: 11px 22px; cursor: pointer; min-height: 44px; }
body.high-contrast #precision-overlay .prec-card { border-color: var(--gold-bright); }
body.high-contrast #precision-overlay .prec-summary { color: #fff; }
body.high-contrast #precision-overlay .prec-ribbon { background: #fff; border-color: var(--gold-bright); }
body.high-contrast #precision-overlay .prec-legend { color: #fff; }
body.high-contrast #precision-overlay .prec-sw-notes { background: rgba(var(--gold-bright-rgb),.5); border-color: #6a4a10; }
body.high-contrast #precision-overlay .prec-sw-voice { border-top-color: #15522a; }
@media (prefers-reduced-motion: reduce) { #precision-overlay { backdrop-filter: none; -webkit-backdrop-filter: none; } }
/* MOTION-CONCEPT #1 — the after-song report RISES IN once on mount: a calm backdrop fade + an opacity+lift on
   the card. The overlay is freshly created each sing, so each keyframe plays exactly once (no rAF/JS needed).
   COSMETIC ONLY: role="dialog" + focus to the forward action fire synchronously in JS, never gated by this.
   Reduced-motion / high-contrast → the :391 + html.rm resets zero it and it rests at the final frame (both fill).
   GPU-cheap (opacity + transform); never red. */
#precision-overlay { animation: prec-fade .16s ease both; }
@keyframes prec-fade { from { opacity: 0; } to { opacity: 1; } }
#precision-overlay .prec-card { animation: prec-rise .24s var(--ease-out) both; }
@keyframes prec-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

/* FEEDBACK-VISUAL Concept A — THE ILLUMINATED LEAF (phrase-stacked overview, canticlePhraseStack-gated).
   One row per musical line, read top-to-bottom like a hymnal leaf. Each row sits on the SAME cream "vellum"
   as the single ribbon (theme-independent, so the gold/green/teal/amber inks stay legible across aurora/
   candle/paper exactly like the shipped ribbon). The best in-tune RUN glows IN PLACE on its own line. */
#precision-overlay .prec-figure-stack { margin: 4px 0 14px; }
#precision-overlay .prec-stack-lines { display: flex; flex-direction: column; gap: 9px; }
#precision-overlay .prec-pline { position: relative; border-radius: var(--r-12); padding: 4px 8px 6px;
  background: linear-gradient(180deg,#faf3e3,#efe4cc); border: 1px solid rgba(156,138,110,.4);
  /* HYMNAL INDENT: a shorter poetic line steps in from the left (--prec-indent set per row, 0..2 by syllable length),
     the printed-hymnal convention; margin (not padding) so the whole tile narrows + the right edge stays put.
     Geometry only — no ink, no colour, so it can't clutter or alarm (INV-08). */
  --prec-indent-step: clamp(14px, 3.5vw, 28px);
  margin-left: calc(var(--prec-indent, 0) * var(--prec-indent-step)); }
#precision-overlay .prec-pline svg { display: block; width: 100%; height: 74px; }
#precision-overlay .prec-lrm { display: block; font-size: var(--fs-micro); letter-spacing: .04em; text-transform: uppercase;
  color: rgba(74,61,44,.7); margin: 2px 0 0 2px; }
/* the in-tune run glows in place — gold→green wash + a lit border (no red; calm, a reward not an alarm, INV-08) */
#precision-overlay .prec-pline.run { border-color: rgba(var(--gold-rgb),.62); box-shadow: 0 0 0 1px rgba(var(--gold-bright-rgb),.3) inset, 0 0 18px rgba(var(--gold-bright-rgb),.12) inset; }
#precision-overlay .prec-pline.run::before { content: ""; position: absolute; inset: 0; border-radius: var(--r-12); pointer-events: none;
  background: linear-gradient(90deg, rgba(var(--gold-bright-rgb),.16), rgba(var(--green-rgb),.10) 55%, transparent); }
#precision-overlay .prec-run-mark { position: absolute; top: 4px; right: 7px; z-index: 1; font-size: var(--fs-micro); font-weight: 700;
  color: var(--ink-on-gold); background: linear-gradient(95deg,var(--gold-bright),#9fd9bf); border-radius: var(--r-40); padding: 2px 9px; }
#precision-overlay .prec-words { position: relative; height: 17px; margin: 1px 0 0; }
#precision-overlay .prec-words span { position: absolute; transform: translateX(-50%); font-size: var(--fs-micro); line-height: 1.2;
  color: var(--muted); white-space: nowrap; max-width: 17vw; overflow: hidden; text-overflow: ellipsis; }
/* high-contrast: a white vellum + darker ink, mirroring the single ribbon's HC treatment */
body.high-contrast #precision-overlay .prec-pline { background: #fff; border-color: var(--gold-bright); }
body.high-contrast #precision-overlay .prec-lrm { color: var(--ink-on-gold); }
body.high-contrast #precision-overlay .prec-pline.run { border-color: #6a4a10; }
body.high-contrast #precision-overlay .prec-words span { color: #2a2218; }
body.high-contrast #precision-overlay .prec-run-mark { background: var(--gold-bright); color: var(--ink-on-gold); }
@media (prefers-reduced-motion: reduce) { #precision-overlay .prec-pline.run::before { transition: none; } }
/* narrow screens: dense syllabic lines crowd the lyric labels — shrink them so adjacent syllables breathe
   (the note contour + voice trace stay the primary read; the words are a soft anchor beneath). */
@media (max-width: 460px) {
  #precision-overlay .prec-pline { padding: 4px 5px 6px; --prec-indent-step: clamp(10px, 3vw, 18px); }
  #precision-overlay .prec-words span { font-size: var(--fs-micro); max-width: 13vw; }
}

/* THE DEEPENED COACH overlay (canticleCoachDepth) — KR-first: the specific success leads, the picture is evidence,
   ONE focus as an invitation, a trajectory + return line, quiet stats. Gold/teal/green only, NEVER red (INV-08). */
#precision-overlay .prec-deep .prec-head { font-size: var(--fs-h3); }
#precision-overlay .prec-success { margin: 2px 0 14px; }
#precision-overlay .prec-success-line { font-size: var(--fs-body); line-height: 1.5; color: var(--cream); margin: 0 0 4px; }
#precision-overlay .prec-success-line:last-child { margin-bottom: 0; }
#precision-overlay .prec-star { color: var(--ink-gold); font-size: var(--fs-body); margin-right: 7px; }
#precision-overlay .prec-deep .prec-figure { margin: 0 0 12px; }
#precision-overlay .prec-deep .prec-ribbon { height: 116px; }
#precision-overlay .prec-focus { margin: 4px 0 0; padding: 11px 13px; border: 1px solid rgba(var(--gold-bright-rgb),.32);
  border-radius: var(--r-11); background: rgba(var(--gold-bright-rgb),.07); }
#precision-overlay .prec-focus-k { font-size: var(--fs-micro); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-gold); margin: 0 0 4px; }
#precision-overlay .prec-focus p { font-size: var(--fs-small); line-height: 1.55; color: var(--cream); margin: 0; }
#precision-overlay .prec-traj { color: var(--ink-teal); font-size: var(--fs-small); line-height: 1.5; margin: 12px 2px 0; }
#precision-overlay .prec-return { color: var(--muted); font-size: var(--fs-caption); line-height: 1.5; font-style: italic; margin: 7px 2px 0; }
#precision-overlay .prec-stats { color: var(--muted); font-size: var(--fs-caption); margin: 13px 2px 14px; }
#precision-overlay .prec-actions { display: flex; gap: 9px; justify-content: flex-end; flex-wrap: wrap; }
#precision-overlay .prec-read { font: inherit; font-size: var(--fs-caption); color: var(--cream); background: none;
  border: 1px solid rgba(var(--gold-bright-rgb),.4); border-radius: var(--r-40); padding: 10px 18px; cursor: pointer; min-height: 44px; }
#precision-overlay .prec-read:hover { border-color: var(--gold-bright); }
body.high-contrast #precision-overlay .prec-success-line { color: #fff; }
body.high-contrast #precision-overlay .prec-focus { border-color: var(--gold-bright); background: rgba(var(--gold-bright-rgb),.14); }
body.high-contrast #precision-overlay .prec-focus p { color: #fff; }
body.high-contrast #precision-overlay .prec-traj { color: #bfe9da; }
body.high-contrast #precision-overlay .prec-read { color: #fff; border-color: var(--gold-bright); }

/* A873 SCRIPTURE — clickable reference chip + the WEB passage comment-box. Calm, gold-accented, NEVER red (INV-08);
   readable size; high-contrast default unaffected. The box is a dismissible bottom-sheet that scrolls for long
   passages and clears the safe-area. */
.sc-link { cursor: pointer; gap: 5px; }
.sc-link:hover { background: rgba(var(--gold-rgb),.24); border-color: var(--gold); }
.sc-link .sc-ic { font-size: var(--fs-micro); opacity: .85; }
#scripture-box { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: flex-end; justify-content: center; }
.sc-backdrop { position: absolute; inset: 0; background: rgba(10,8,5,.66); }
.sc-panel { position: relative; width: 100%; max-width: 620px; max-height: 88vh; display: flex; flex-direction: column;
  background: var(--panel); color: var(--cream); border: 1px solid rgba(var(--gold-bright-rgb),.4); border-radius: var(--r-18) var(--r-18) 0 0;
  box-shadow: var(--elev-sheet); animation: sheet-up var(--dur-2) ease;
  padding-bottom: max(10px, env(safe-area-inset-bottom, 0px)); }
.sc-bar { display: flex; align-items: center; gap: 12px; position: sticky; top: 0; background: var(--panel);
  border-bottom: 1px solid var(--line); padding: 12px 16px; border-radius: var(--r-18) var(--r-18) 0 0; }
.sc-close { font: inherit; font-weight: 600; color: var(--ink-gold); background: transparent; border: 1px solid var(--line);
  border-radius: var(--r-40); padding: 0 14px; min-height: 44px; cursor: pointer; white-space: nowrap; }
.sc-close:hover { color: var(--cream); border-color: var(--gold); }
.sc-ref { font-family: var(--serif); font-weight: 600; font-size: var(--fs-h3); margin: 0; color: var(--cream); }
.sc-body { overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 12px 18px; }
.sc-v { font-family: var(--serif); font-size: var(--fs-lead); line-height: 1.6; color: var(--cream); margin: 0 0 9px; text-wrap: pretty; }
.sc-vn { color: var(--ink-gold); font-weight: 600; font-size: var(--fs-caption); vertical-align: super; margin-right: 6px; }
.sc-net { color: var(--ink-gold); font-weight: 600; font-size: 0.78em; vertical-align: middle; }
.sc-foot { border-top: 1px solid var(--line); padding: 12px 18px 4px; }
.sc-attr { color: var(--muted); font-size: var(--fs-micro); line-height: 1.45; margin: 0; }   /* REQUIRED NET attribution — calm, never red */
@media (prefers-reduced-motion: reduce) { .sc-panel { animation: none; } }

/* RL-94: CC-BY / non-PD attribution — calm, never alarms (INV-08). */
.credit { border-top: 1px solid var(--line, #e5ddd0); }
.credit .credit-line { font-size: var(--fs-small); color: var(--cream); margin: 4px 0; }  /* VISUAL-2: was var(--ink) — NEVER DEFINED, fell to a paper-brown literal = 1.49:1 on dark themes; CC-BY attribution must be legible (license obligation) */
.credit .credit-notice { font-size: var(--fs-micro); color: var(--muted, #7a6f5f); line-height: 1.5; margin: 4px 0; }
.credit .credit-license { font-size: var(--fs-micro); color: var(--muted, #7a6f5f); margin: 4px 0; }

/* Singer journey (RL-167) — calm, self-to-self; never a scoreboard. Matches the rail/card system. */
.jr-note { color: var(--muted); font-size: var(--fs-small); margin: 2px 0 10px; line-height: 1.5; }
.jr-stats { list-style: none; padding: 0; margin: 0 0 8px; display: flex; flex-direction: column; gap: 7px; }
.jr-stats li { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-12); padding: 10px 13px; color: var(--cream); font-size: var(--fs-small); line-height: 1.45; }
.jr-stats b { color: var(--ink-gold); font-weight: 600; }
.jr-sub { font-size: var(--fs-small); color: var(--cream); margin: 14px 0 7px; }
.jr-win { background: linear-gradient(180deg, var(--panel-2, var(--panel)), var(--panel)); border: 1px solid var(--gold); border-radius: var(--r-12); padding: 10px 13px; color: var(--cream); font-size: var(--fs-small); line-height: 1.45; margin: 8px 0; }
.jr-win b { color: var(--ink-gold); }
/* Q-20 first-run reassurance — a warm welcome for a nervous newcomer; calm, never alarming, reads cleanly aloud */
.reassure-rail { border: 1px solid var(--gold); border-radius: var(--r-14); background: linear-gradient(180deg, var(--panel-2, var(--panel)), var(--panel)); padding: 14px 16px; margin-bottom: 14px; }
.reassure-rail .rail-h { margin-top: 2px; color: var(--ink-gold); }
.reassure-p { color: var(--cream); font-size: var(--fs-small); line-height: 1.55; margin: 8px 0; }
.reassure-foot { color: var(--muted); font-size: var(--fs-small); margin-bottom: 2px; }
.jr-autonomy { margin-top: -2px; }
/* Q-21 "Look how far you've come" mastery-evidence panel — a calm native <details>; gold-warm, never alarming */
.jr-evidence { border: 1px solid var(--gold); border-radius: var(--r-12); margin: 4px 0 12px; background: linear-gradient(180deg, var(--panel-2, var(--panel)), var(--panel)); overflow: hidden; }
.jr-evidence-sum { cursor: pointer; padding: 11px 14px; font-size: var(--fs-small); font-weight: 600; color: var(--ink-gold); list-style: none; }
.jr-evidence-sum::-webkit-details-marker { display: none; }
.jr-evidence-sum::after { content: '▾'; float: right; color: var(--muted); font-weight: 400; transition: transform var(--dur-2) ease; }
.jr-evidence[open] .jr-evidence-sum::after { transform: rotate(180deg); }
.jr-evidence-sum:focus-visible { outline: 2px solid var(--gold-bright); outline-offset: -2px; }
.jr-evidence-body { padding: 2px 14px 13px; }
.jr-evidence-body h3 { margin-top: 4px; outline: none; }
.jr-evidence-lead { color: var(--cream); font-size: var(--fs-small); line-height: 1.5; margin: 2px 0 9px; }
.jr-evidence-list { list-style: none; padding: 0; margin: 0 0 10px; display: flex; flex-direction: column; gap: 7px; }
.jr-evidence-list li { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-11); padding: 9px 12px; color: var(--cream); font-size: var(--fs-small); line-height: 1.45; }
.jr-evidence-reassure { color: var(--cream); font-size: var(--fs-small); line-height: 1.55; margin: 4px 0 8px; }
.jr-evidence-note { margin-bottom: 2px; }
@media (prefers-reduced-motion: reduce) { .jr-evidence-sum::after { transition: none; } }
.jr-areas { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 7px; }
.jr-areas li { color: var(--cream); font-size: var(--fs-small); line-height: 1.5; padding: 8px 2px; }
.jr-areas b { color: var(--cream); }
.jr-program { margin: 0; padding: 0 0 0 1.3em; display: flex; flex-direction: column; gap: 9px; }
.jr-program li { color: var(--cream); font-size: var(--fs-small); line-height: 1.5; }
.jr-program b { color: var(--ink-gold); font-weight: 600; }
.jr-links { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.jr-go { color: var(--ink-gold); text-decoration: none; white-space: nowrap; }
.jr-locked { color: var(--muted); font-size: var(--fs-small); line-height: 1.5; background: var(--panel); border: 1px dashed var(--line); border-radius: var(--r-12); padding: 11px 14px; }

/* RELEASE-POLISH (RELEASE-PLAN M-1..M-3): footer identity links + the static pages */
.foot-links { display: flex; gap: 6px 18px; justify-content: center; flex-wrap: wrap; margin-top: 10px; }
.foot-links a { color: var(--muted); font-size: var(--fs-caption); text-decoration: underline; text-underline-offset: 3px; padding: 8px 2px; min-height: 44px; display: inline-flex; align-items: center; }
.foot-links a:hover { color: var(--ink-gold); }
.page-body { max-width: 640px; }
.page-h { font-family: var(--serif, inherit); font-size: var(--fs-h1); line-height: 1.2; margin: 8px 0 16px; }
.page-body h3 { font-family: var(--serif, inherit); font-size: var(--fs-h3); line-height: 1.3; color: var(--cream); margin: 22px 0 6px; }  /* labeled Credits sections */
.page-body p, .page-body li { color: var(--cream); font-size: var(--fs-body); line-height: 1.55; }
.page-body p { margin: 0 0 14px; }
.page-body a { color: var(--ink-gold); text-decoration: underline; text-underline-offset: 3px; }
.page-list { padding-left: 20px; margin: 0 0 14px; }
.page-list li { margin: 0 0 10px; }
.page-aside { color: var(--muted); font-size: var(--fs-small); border-top: 1px solid var(--line); padding-top: 12px; margin-top: 18px; }

/* ============================================================================
   AURORA THEME — the bold default's structural layer (scoped under
   html[data-theme="aurora"] so it is wholly inert in candle/paper). Every effect
   here is decorative, aria-hidden (the DOM layer carries aria-hidden), behind
   content, never over the live staff, and resolves to a still frame under reduced
   motion. INV-08 untouched (the accents are spine tokens).
   ============================================================================ */

/* The living-light layer: 3 soft drifting pools of gold / teal / green (= the
   staff's target/home/voice, so the ambient light speaks the note look's language).
   Sits at z-index:-1 (above the page background, below all content). */
.aurora { position: fixed; inset: 0; z-index: -1; pointer-events: none; overflow: hidden;
  opacity: var(--atmos); transition: opacity .4s ease; }
html:not([data-theme="aurora"]) .aurora { display: none; }
/* will-change promotes each pool to its own GPU layer → the drift is a compositor-only
   transform (no per-frame repaint), so the Vivid default stays cheap on low-end phones. */
.aurora i { position: absolute; display: block; border-radius: var(--r-circle); will-change: transform; }
.aurora .a1 { width: 62vw; height: 62vw; max-width: 460px; max-height: 460px; left: -16vw; top: -12vh;
  background: radial-gradient(circle, rgba(var(--gold-bright-rgb),.34), transparent 66%); animation: au-drift1 16s ease-in-out infinite alternate; }
.aurora .a2 { width: 58vw; height: 58vw; max-width: 420px; max-height: 420px; right: -18vw; top: 8vh;
  background: radial-gradient(circle, rgba(var(--teal-rgb),.30), transparent 66%); animation: au-drift2 19s ease-in-out infinite alternate; }
.aurora .a3 { width: 66vw; height: 60vw; max-width: 480px; max-height: 440px; left: -10vw; bottom: -18vh;
  background: radial-gradient(circle, rgba(var(--green-rgb),.22), transparent 66%); animation: au-drift3 22s ease-in-out infinite alternate; }
@keyframes au-drift1 { 0% { transform: translate(0,0) scale(1); } 100% { transform: translate(5vw,4vh) scale(1.12); } }
@keyframes au-drift2 { 0% { transform: translate(0,0) scale(1); } 100% { transform: translate(-5vw,3vh) scale(1.1); } }
@keyframes au-drift3 { 0% { transform: translate(0,0) scale(1); } 100% { transform: translate(4vw,-4vh) scale(1.14); } }

/* ════════════════════════════════════════════════════════════════════════════
   SING-POLISH — the landing ENTRANCE: a crafted, precise one-shot reveal over a
   deepened static field. TWO easing curves only (restraint reads as high-end):
   "settle" = a calm decelerate ("light settling into place"), "draw" = symmetric
   in-out ("a ruled line, drawn"). Every animated property is opacity / transform /
   text-shadow (compositor-cheap, no layout), and the ground detail (grain + vignette)
   is painted ONCE — net standing cost after the ~750ms entrance is ZERO (no rAF).
   Everything resolves to the static resting frame under reduced-motion / high-
   contrast (a11y wins over atmosphere — same contract as the drift, :633–643).
   ════════════════════════════════════════════════════════════════════════════ */
:root { --ease-settle: cubic-bezier(.22,.61,.36,1); --ease-draw: cubic-bezier(.65,0,.35,1);
  /* SHELL-POLISH: the engine's motion vocabulary (A984/A985) brought to the front door so the shell and
     the trainer move with one hand. --ease-settle/--ease-draw above are the cherished home choreography —
     LEFT UNTOUCHED; these are ADDITIVE. --ease-out = workhorse decelerate · --ease-bloom = celebratory
     overshoot · --dur-1..5 = the duration scale. --lift = the hover-rise, zeroed under reduced-motion. */
  --ease-out: cubic-bezier(.2,.7,.3,1); --ease-bloom: cubic-bezier(.2,1.3,.4,1);
  --dur-1: .12s; --dur-2: .18s; --dur-3: .2s; --dur-4: .24s; --dur-5: .36s;
  --lift: -2px; --lift-sm: -1px; }

/* Ground detail — the "crafted, layered" depth, with NO extra animation frame. Both are
   children of .aurora, so they inherit its --atmos opacity AND every degrade gate above. */
.aurora::before {   /* vignette — the light pools toward the content (composed, photographic) */
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(125% 95% at 50% 32%, transparent 52%, rgba(8,6,3,.5)); }
.aurora::after {    /* fine grain — file://-safe inline SVG (INV-02), static, one composited layer */
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }

/* A focused soft glow behind the wordmark so the word reads as LIT, not merely coloured. */
html[data-theme="aurora"] .wm-wrap { position: relative; display: inline-block; }
html[data-theme="aurora"] .wm-aura {
  position: absolute; z-index: -1; left: 50%; top: 52%; width: 264px; height: 116px;
  transform: translate(-50%,-50%); border-radius: var(--r-circle); pointer-events: none;
  background: radial-gradient(circle, rgba(var(--gold-bright-rgb),calc(.30 * var(--atmos))), transparent 66%); }
/* One precise luminous hairline under the wordmark — the crisp ruled line against the soft glow. */
html[data-theme="aurora"] .lumrule {
  height: 2px; width: 92px; margin: 9px 0 3px; border-radius: var(--r-2); transform-origin: left;
  background: linear-gradient(90deg, var(--gold-bright), var(--teal-bright));
  opacity: calc(.85 * var(--atmos)); }
html:not([data-theme="aurora"]) .wm-aura,
html:not([data-theme="aurora"]) .lumrule { display: none; }

/* ── The choreography (one-shot): .lit raises the field, .enter reveals the content. ── */
.aurora.lit { animation: au-rise .7s var(--ease-settle) both; }
@keyframes au-rise { from { opacity: 0; } to { opacity: var(--atmos); } }

/* the wordmark rises and GATHERS LIGHT late — "light rising like a held note" (Aurora of the Voice) */
#view-home.enter .wordmark { animation: wm-rise .78s var(--ease-settle) .10s both; }
@keyframes wm-rise {
  from { opacity: 0; transform: translateY(14px); text-shadow: 0 0 8px rgba(var(--gold-bright-rgb),0); }
  62%  { text-shadow: 0 0 14px rgba(var(--gold-bright-rgb),.10); }
  to   { opacity: 1; transform: translateY(0); text-shadow: 0 0 26px rgba(var(--gold-bright-rgb),.18); } }
#view-home.enter .wm-aura  { animation: au-rise .95s var(--ease-settle) .18s both; }
#view-home.enter .lumrule  { animation: rule-draw .56s var(--ease-draw) .30s both; }   /* DRAWN, no bounce */
@keyframes rule-draw { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* content fades up IN PLACE, 80–90ms stagger, NO overshoot (precision over flash) */
#view-home.enter .tagline         { animation: rise-up .58s var(--ease-settle) .40s both; }
#view-home.enter .search-row      { animation: rise-up .52s var(--ease-settle) .50s both; }
#view-home.enter #open-door       { animation: rise-up .52s var(--ease-settle) .58s both; }
#view-home.enter #start-here-rail { animation: rise-up .52s var(--ease-settle) .66s both; }
/* VISUAL-2: the narrowed home actually shows welcome-hero + most-known + explore-more — they popped in
   unstaged after the tagline/search rise; now they join the same choreography. */
#view-home.enter #welcome-hero    { animation: rise-up .52s var(--ease-settle) .58s both; }
#view-home.enter #most-known      { animation: rise-up .52s var(--ease-settle) .66s both; }
#view-home.enter #explore-more    { animation: rise-up .52s var(--ease-settle) .74s both; }
@keyframes rise-up { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

/* ── Degrade — a11y wins: hide the aurora-only flourishes under high-contrast; under reduced
   motion (OS preference OR the in-app html.rm toggle) kill the entrance and rest at the final
   static frame (no offset, hairline drawn, wordmark lit). The aurora field is already display:none
   under high-contrast (:634), so au-rise on it is inert there. ── */
body.high-contrast .wm-aura, body.high-contrast .lumrule { display: none; }
@media (prefers-reduced-motion: reduce) {
  .aurora.lit, #view-home.enter .wordmark, #view-home.enter .wm-aura, #view-home.enter .lumrule,
  #view-home.enter .tagline, #view-home.enter .search-row, #view-home.enter #open-door,
  #view-home.enter #start-here-rail { animation: none !important; }
  html[data-theme="aurora"] .lumrule { transform: scaleX(1); }
  html[data-theme="aurora"] .wordmark { text-shadow: 0 0 26px rgba(var(--gold-bright-rgb),.18); } }
html.rm .aurora.lit, html.rm #view-home.enter .wordmark, html.rm #view-home.enter .wm-aura,
html.rm #view-home.enter .lumrule, html.rm #view-home.enter .tagline, html.rm #view-home.enter .search-row,
html.rm #view-home.enter #open-door, html.rm #view-home.enter #start-here-rail { animation: none !important; }
html.rm[data-theme="aurora"] .lumrule { transform: scaleX(1); }

/* Atmosphere intensity (Calm · Soft · Vivid) → scales the whole aurora layer. */
html[data-intensity="calm"]  { --atmos: 0; }
html[data-intensity="soft"]  { --atmos: .6; }
html[data-intensity="vivid"] { --atmos: 1; }

/* Wordmark as a light source: gold→teal gradient text + a focused glow behind it.
   Forced-colors + no-background-clip fallbacks keep it a solid, legible word. */
html[data-theme="aurora"] .wordmark {
  background: linear-gradient(96deg, #c8933f, #f0cd84 52%, var(--gold-bright) 100%);  /* C9-b: ONE lit gold tone (was gold->teal — a gold word + a teal syllable) */
  -webkit-background-clip: text; background-clip: text; color: transparent;
  text-shadow: 0 0 26px rgba(var(--gold-bright-rgb),.18); }
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  html[data-theme="aurora"] .wordmark { color: var(--cream); background: none; } }
@media (forced-colors: active) {
  html[data-theme="aurora"] .wordmark { color: CanvasText; background: none; -webkit-text-fill-color: CanvasText; text-shadow: none; } }

/* Lit-vellum edge light: a 1px top highlight on the surface components (Aurora only). */
html[data-theme="aurora"] .card,
html[data-theme="aurora"] .rcard,
html[data-theme="aurora"] .ccard,
html[data-theme="aurora"] .bcard,
html[data-theme="aurora"] .conf-card,
html[data-theme="aurora"] .cont-card,
html[data-theme="aurora"] .od-door,
html[data-theme="aurora"] .onramp-link,
html[data-theme="aurora"] .search,
html[data-theme="aurora"] .set-group,
html[data-theme="aurora"] .set-theme-opt,
html[data-theme="aurora"] .od-continue,
html[data-theme="aurora"] .welcome-hero,
html[data-theme="aurora"] .wpath,
html[data-theme="aurora"] .welcome-how,
html[data-theme="aurora"] .reassure-rail,
html[data-theme="aurora"] .pg-card,
html[data-theme="aurora"] .pg-item { box-shadow: inset 0 1px 0 var(--edge-light); }
/* the after-song report card keeps its key shadow AND gains the same lit top edge (VISUAL-AURORA-1) */
html[data-theme="aurora"] #precision-overlay .prec-card { box-shadow: inset 0 1px 0 var(--edge-light), 0 12px 48px rgba(0,0,0,.55); }

/* high-contrast + reduced-motion both quiet the aurora (a11y wins over atmosphere). */
body.high-contrast .aurora { display: none; }
/* VIVID-DEFAULT SAFEGUARD: reduced motion (the OS preference OR the explicit in-app toggle)
   FREEZES the drift AND dims the wash toward calm — so the Vivid default never imposes motion
   or a heavy glow on a motion-sensitive user. The aurora is additive; nothing depends on it. */
@media (prefers-reduced-motion: reduce) { .aurora i { animation: none; } .aurora { opacity: calc(var(--atmos) * .3); } }
html.rm .aurora i { animation: none; }
html.rm .aurora { opacity: calc(var(--atmos) * .3); }
html.rm *, html.rm *::before, html.rm *::after {
  animation-duration: .01ms !important; animation-iteration-count: 1 !important;
  transition-duration: .01ms !important; scroll-behavior: auto !important; }

/* ── Range light-bloom — the one signature "your voice finds itself" moment, fired
   from the engine's canticle:rangeEstablished message. OPT-IN (off by default).
   A single expanding ring + a warm gold→green wash, then it settles. Mirrored to a
   role=status line for SR/reduced-motion users (the meaning never lives in motion). */
.range-bloom { position: fixed; inset: 0; z-index: 60; pointer-events: none; display: grid; place-items: center; }
.range-bloom .rb-glow { width: 40vmin; height: 40vmin; border-radius: var(--r-circle);
  background: radial-gradient(circle, rgba(var(--gold-bright-rgb),.42), rgba(var(--green-rgb),.20) 45%, transparent 72%);
  animation: rb-bloom 1.7s ease-out forwards; }
.range-bloom .rb-ring { position: absolute; width: 22vmin; height: 22vmin; border-radius: var(--r-circle);
  border: 2px solid rgba(var(--gold-bright-rgb),.5); animation: rb-ring 1.7s ease-out forwards; }
@keyframes rb-bloom { 0% { transform: scale(.4); opacity: 0; } 30% { opacity: 1; } 100% { transform: scale(1.1); opacity: 0; } }
@keyframes rb-ring { 0% { transform: scale(.4); opacity: .7; } 100% { transform: scale(2.4); opacity: 0; } }
@media (prefers-reduced-motion: reduce) {
  .range-bloom .rb-glow { animation: none; opacity: .5; }
  .range-bloom .rb-ring { display: none; } }
html.rm .range-bloom .rb-glow { animation: none; opacity: .5; }
html.rm .range-bloom .rb-ring { display: none; }

/* ============================================================================
   SETTINGS SCREEN (#/settings) — the reorganized, fully SR-navigable preferences
   surface (SETTINGS-ARCHITECTURE.md). Seven grouped sections; defaults surfaced,
   advanced knobs tucked under a "More" disclosure. Calm, single column, ≥44px.
   ============================================================================ */
.set-wrap { max-width: 640px; }
.set-title { font-family: var(--serif); font-weight: 600; font-size: clamp(28px,7vw,38px); line-height: 1.1; margin: 4px 0 4px; color: var(--cream); }
.set-intro { color: var(--muted); font-size: var(--fs-small); line-height: 1.5; margin: 0 0 18px; }
.set-group { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-16); padding: 4px 16px 8px; margin: 0 0 14px; }
.set-group-h { font-family: var(--serif); font-weight: 600; font-size: var(--fs-h3); color: var(--cream); margin: 14px 2px 6px; }
.set-row { display: flex; align-items: center; gap: 14px; padding: 11px 0; border-top: 1px solid var(--line); }
.set-group-h + .set-row, .set-row:first-of-type { border-top: 0; }
.set-row .set-main { flex: 1 1 auto; min-width: 0; }
.set-label { display: block; color: var(--cream); font-size: var(--fs-body); line-height: 1.3; }
.set-desc { display: block; color: var(--muted); font-size: var(--fs-caption); line-height: 1.4; margin-top: 2px; }
.set-row .set-control { flex: 0 0 auto; }

/* On/off switch — text-labelled (never colour-only), ≥44px. */
.set-switch { font: inherit; font-size: var(--fs-caption); font-weight: 600; min-width: 64px; min-height: 44px; padding: 6px 14px;
  border-radius: var(--r-pill); border: 1px solid var(--line); background: none; color: var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; gap: 7px; }
.set-switch::before { content: ""; width: 9px; height: 9px; border-radius: var(--r-circle); background: var(--muted); }
.set-switch[aria-checked="true"] { border-color: var(--gold); color: var(--ink-gold); }
.set-switch[aria-checked="true"]::before { background: var(--green); }
.set-switch:hover { border-color: var(--gold); }

/* Theme picker — a radiogroup of three cards (swatch + name + check; not colour-only). */
.set-themes { display: flex; flex-direction: column; gap: 10px; padding: 8px 0 4px; }
.set-theme-opt { display: flex; align-items: center; gap: 13px; width: 100%; text-align: left; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: var(--r-14); padding: 12px 14px; min-height: 56px; color: var(--cream); }
.set-theme-opt:hover { border-color: var(--gold); }
.set-theme-opt[aria-checked="true"] { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold); }
.set-theme-sw { flex: 0 0 auto; width: 40px; height: 40px; border-radius: var(--r-10); border: 1px solid rgba(255,255,255,.12); }
.set-theme-sw.t-aurora { background: radial-gradient(circle at 30% 30%, #d9a44a55, transparent 60%), radial-gradient(circle at 75% 70%, #5dcaa555, transparent 60%), #13100b; }
.set-theme-sw.t-candle { background: linear-gradient(160deg, #2a2218, #15110c); }
.set-theme-sw.t-paper  { background: linear-gradient(160deg, #fbf6e9, #ece1c9); border-color: #ddd0ad; }
.set-theme-meta { flex: 1 1 auto; min-width: 0; }
.set-theme-name { display: block; font-family: var(--serif); font-size: var(--fs-lead); font-weight: 600; }
.set-theme-desc { display: block; color: var(--muted); font-size: var(--fs-caption); margin-top: 1px; }
.set-theme-check { flex: 0 0 auto; width: 1.4em; text-align: center; color: var(--ink-gold); font-weight: 700; font-size: var(--fs-body); }

/* Segmented control (Aurora atmosphere: Calm · Soft · Vivid). */
.set-seg { display: inline-flex; gap: 0; border: 1px solid var(--line); border-radius: var(--r-pill); overflow: hidden; }
.set-seg button { font: inherit; font-size: var(--fs-caption); min-height: 44px; padding: 6px 14px; border: 0; background: none; color: var(--muted); cursor: pointer; }
.set-seg button + button { border-left: 1px solid var(--line); }
.set-seg button[aria-checked="true"] { background: var(--panel-2); color: var(--ink-gold); font-weight: 600; }

/* "More" disclosure + link rows + notes. */
.set-more { border-top: 1px solid var(--line); margin-top: 2px; }
.set-more > summary { color: var(--ink-gold); font-size: var(--fs-small); font-weight: 600; cursor: pointer; padding: 12px 2px; min-height: 44px; list-style: none; display: flex; align-items: center; gap: 6px; }
.set-more > summary::-webkit-details-marker { display: none; }
.set-more > summary::before { content: "▸"; transition: transform var(--dur-2) ease; }
.set-more[open] > summary::before { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) { .set-more > summary::before { transition: none; } }
.set-linkrow { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 0; border-top: 1px solid var(--line); color: var(--cream); font-size: var(--fs-body); text-decoration: none; min-height: 44px; }
.set-linkrow:hover { color: var(--ink-gold); }
.set-linkrow .set-arrow { color: var(--muted); }
.set-note { color: var(--muted); font-size: var(--fs-caption); line-height: 1.5; padding: 10px 0 4px; border-top: 1px solid var(--line); }
.set-note b { color: var(--cream); font-weight: 600; }
.set-action { font: inherit; font-size: var(--fs-small); font-weight: 600; min-height: 44px; padding: 10px 16px; border-radius: var(--r-pill);
  border: 1px solid var(--line); background: var(--panel-2); color: var(--cream); cursor: pointer; }
.set-action:hover { border-color: var(--gold); color: var(--ink-gold); }
.set-actions { display: flex; flex-wrap: wrap; gap: 10px; padding: 8px 0 4px; }
.set-trainer-link { color: var(--ink-gold); text-decoration: none; font-weight: 600; }
.set-trainer-link:hover { text-decoration: underline; }
/* The footer Settings entry (replaces the lone contrast button's prominence). */
.foot-settings { background: none; border: 1px solid var(--line); color: var(--muted); border-radius: var(--r-pill); padding: 6px 14px; min-height: 44px; font-size: var(--fs-micro); margin: 0 10px 8px 0; text-decoration: none; display: inline-flex; align-items: center; gap: 6px; }
.foot-settings:hover { border-color: var(--gold); color: var(--cream); }

/* ============================================================================
   PROD-UI FIXES — top placement for Settings + the logo as a home link on every
   screen (Issues 2 & 3). The wordmark/brand is an <a href="#/"> everywhere it
   appears; Settings sits TOP-RIGHT (home) and in each inner screen's appbar.
   ============================================================================ */
.home-topbar { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
a.wordmark { text-decoration: none; display: inline-block; flex: 0 1 auto; min-width: 0; }
.topbar-set, .appbar-set { font-family: var(--sans); font-size: var(--fs-caption); color: var(--ink-gold); text-decoration: none;
  border: 1px solid var(--line); border-radius: var(--r-pill); padding: 9px 13px; min-height: 44px;
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; flex: 0 0 auto; }
.topbar-set:hover, .appbar-set:hover { border-color: var(--gold); color: var(--cream); }

/* Inner-screen app bar (song · page · settings): brand → home (left), Settings (right). */
.appbar { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 0 0 10px; }
.appbar-brand { font-family: var(--serif); font-weight: 600; font-size: var(--fs-h2); letter-spacing: .01em; line-height: 1;
  color: var(--cream); text-decoration: none; }
.appbar-brand:hover { color: var(--ink-gold); }
/* Aurora: the brand reads as lit gradient text wherever it appears (with the forced-colors fallback). */
html[data-theme="aurora"] .appbar-brand {
  background: linear-gradient(96deg, #c8933f, #f0cd84 52%, var(--gold-bright) 100%);  /* C9-b: ONE lit gold tone (was gold->teal — a gold word + a teal syllable) */
  -webkit-background-clip: text; background-clip: text; color: transparent; }
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  html[data-theme="aurora"] .appbar-brand { color: var(--cream); background: none; } }
@media (forced-colors: active) {
  html[data-theme="aurora"] .appbar-brand { color: CanvasText; background: none; -webkit-text-fill-color: CanvasText; } }

/* ═══ PRAGMATIC-IA + FEEDBACK (PRAGMATIC-IA-REDESIGN.md) — flag-on surfaces only; every selector below styles new
   elements that are `hidden`/absent flag-off, so the flag-off render is untouched. Palette = gold/teal/green/
   neutral only, NEVER red (INV-08). ═══ */
/* the single "Explore more →" link on the narrowed home */
.explore-more { margin-top: 14px; }
.explore-link { display: inline-flex; align-items: center; gap: 6px; font-family: var(--serif); font-weight: 600;
  font-size: var(--fs-lead); color: var(--ink-gold); text-decoration: none; padding: 12px 18px; min-height: 44px;
  border: 1px solid rgba(var(--gold-bright-rgb),.45); border-radius: var(--r-12); background: linear-gradient(180deg, rgba(var(--gold-bright-rgb),.08), rgba(var(--gold-bright-rgb),.03)); }
.explore-link:hover { border-color: var(--gold); }
.explore-sub { font-size: var(--fs-caption); color: var(--muted); margin: 8px 2px 0; line-height: 1.5; }
/* reserved breathing room for the WS-5 demo animation + first-run onboarding (ships empty) */
.demo-slot { max-width: 760px; margin: 18px auto 0; padding: 0 18px; min-height: 8px; }
.demo-slot[data-demo="reserved"]:not(:empty) { min-height: 0; }
/* the #/browse header */
.browse-back { margin: 14px auto 2px; }
.browse-h { max-width: 760px; margin: 4px auto 2px; padding: 0 18px; font-family: var(--serif); font-weight: 600;
  font-size: var(--fs-h1); color: var(--cream); }
/* the #/you stats page */
#view-you .you-h { font-family: var(--serif); font-weight: 600; font-size: var(--fs-h1); color: var(--cream); margin: 6px 0 4px; }
/* the flagship heading is focused programmatically (tabindex=-1) for SR announcement on route — suppress the 3px
   gold focus box so it doesn't read as a giant input on the empty/populated dashboard (review nit; a11y-safe: the
   heading isn't keyboard-reachable, the SR still announces it). */
#view-you .you-h:focus { outline: none; }
/* VISUAL-2: the same suppression for every routed heading focusHeading() targets — the 3px gold ring
   painted on the song title / browse h1 / set h1 / wordmark after EVERY navigation and read as a giant
   misplaced input (a11y-safe: programmatic focus only, not keyboard-reachable; SR announcement kept). */
.song-title:focus, #browse-h:focus, #set-h:focus { outline: none; }
a.wordmark:focus:not(:focus-visible) { outline: none; }  /* the wordmark IS a real keyboard target — keep its keyboard ring, kill only the programmatic-focus ring (reviewer catch) */
#view-you .you-note { color: var(--muted); font-size: var(--fs-small); line-height: 1.5; margin: 0 0 14px; }
#view-you .you-empty { color: var(--cream); font-size: var(--fs-small); line-height: 1.55; padding: 12px 14px;
  border-radius: var(--r-12); background: var(--panel); border: 1px solid var(--line); }
/* ════════════════════════════════════════════════════════════════════════════
   THE AURORA PROFILE DASHBOARD (#/you) — the reflective trajectory surface dressed
   in the Aurora language. The single global .aurora field (fixed, z-index:-1) already
   glows behind every view; here each section reads as a calm LIT PANEL on that field,
   the personal-best BLOOMS once ("your voice finds itself"), and the one gentle
   tendency rides a teal (home/tonic) accent. Tokens + classes only; gold = target ·
   teal = home · green = success — NEVER red (INV-08). Every motion is one-shot and
   resolves to the still frame under reduced-motion / high-contrast (the :391 + html.rm
   resets zero it for free). LEGIBLE FIRST (STOP-RULE): the glow is always BEHIND the
   words, never over them; the numbers stay quiet metadata.
   ════════════════════════════════════════════════════════════════════════════ */
#view-you .wrap { position: relative; }   /* content sits above the global aurora field */
/* each #/you section = a calm lit panel: a faintly translucent surface (the field breathes through
   WITHOUT costing legibility — the inner cards keep their solid panels) + a luminous top hairline. */
#view-you .rail { max-width: 100%; margin: 22px 0 0; padding: 16px 16px 14px; position: relative; overflow: hidden;
  background: linear-gradient(180deg, rgba(var(--gold-bright-rgb),.05), transparent 70%), var(--you-panel, rgba(42,34,24,.62));
  border: 1px solid var(--line); border-radius: var(--r-16); }
#view-you .rail::before { content: ""; position: absolute; left: 0; top: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(var(--gold-bright-rgb),.55), rgba(93,202,165,.4), transparent); }
html[data-theme="candle"] #view-you .rail { --you-panel: rgba(42,34,24,.7); }
html[data-theme="paper"]  #view-you .rail { --you-panel: rgba(251,246,233,.8); }
body.high-contrast #view-you .rail { background: var(--panel); border-color: var(--gold-bright); }
body.high-contrast #view-you .rail::before { background: var(--gold-bright); }
/* one calm gold→teal stroke under each section heading — the "lit vellum" accent (paper uses the dark inks) */
#view-you .rail .rail-h { position: relative; }
#view-you .rail .rail-h::after { content: ""; display: block; height: 2px; width: 48px; margin-top: 7px;
  border-radius: var(--r-2); background: linear-gradient(90deg, var(--gold-bright), var(--teal-bright)); opacity: .65; }
html[data-theme="paper"] #view-you .rail .rail-h::after { background: linear-gradient(90deg, var(--gold-ink), var(--teal-ink)); opacity: .85; }
body.high-contrast #view-you .rail .rail-h::after { background: var(--gold-bright); opacity: 1; }
/* the trajectory ("in tune, sing by sing") */
.traj-head { color: var(--cream); font-size: var(--fs-body); line-height: 1.55; margin: 2px 0 10px; }
.traj-head b { color: var(--ink-gold); }
.traj-fig { margin: 6px 0 12px; padding: 10px 8px 6px; border-radius: var(--r-12); background: var(--panel); border: 1px solid var(--line); }
.traj-cap { color: var(--muted); font-size: var(--fs-caption); text-align: center; margin: 6px 0 0; line-height: 1.4; }
.traj-svg { filter: drop-shadow(0 0 5px rgba(var(--gold-bright-rgb),.18)); }   /* a soft glow so the line reads as LIT */
html:not([data-theme="aurora"]) .traj-svg, body.high-contrast .traj-svg { filter: none; }
.traj-fact { color: var(--cream); font-size: var(--fs-small); line-height: 1.55; margin: 4px 0; }
.traj-fact b { color: var(--ink-green); }
.traj-fact .link { color: var(--ink-gold); }
.traj-sub { font-family: var(--serif); font-weight: 600; font-size: var(--fs-body); color: var(--cream); margin: 12px 0 6px; }
/* THE BLOOM — the personal-best run, softened with a calm gold radial BEHIND the words ("your voice finds
   itself"). One earned wow: a reward, never an alarm; aria-hidden glow, the plain line stays legible. */
.traj-bloom { position: relative; margin: 10px 0; padding: 12px 14px; border-radius: var(--r-12); overflow: hidden;
  border: 1px solid rgba(var(--gold-bright-rgb),.42);
  background: radial-gradient(120% 140% at 18% 30%, rgba(var(--gold-bright-rgb),.15), transparent 62%), var(--panel); }
.traj-bloom-glow { position: absolute; inset: 0; pointer-events: none; z-index: 0; opacity: 0;
  background: radial-gradient(60% 80% at 22% 42%, rgba(var(--gold-bright-rgb),.30), rgba(var(--green-rgb),.10) 50%, transparent 72%);
  animation: traj-bloom-in 1.2s var(--ease-settle) .15s forwards; }
@keyframes traj-bloom-in { from { opacity: 0; transform: scale(.92); } to { opacity: .9; transform: scale(1); } }
.traj-best { position: relative; z-index: 1; margin: 0; font-size: var(--fs-small); }
.traj-best b { color: var(--ink-gold); }
body.high-contrast .traj-bloom { background: var(--panel); border-color: var(--gold-bright); }
body.high-contrast .traj-bloom-glow { display: none; }
/* THE ONE GENTLE NUDGE — the cross-session tendency, on a calm teal (home) accent. Forward-only copy; a card, never a scold. */
.traj-tend { color: var(--cream); font-size: var(--fs-small); line-height: 1.55; margin: 10px 0 2px; padding: 11px 14px;
  border-radius: var(--r-12); border: 1px solid var(--line); border-left: 3px solid var(--teal-bright);
  background: linear-gradient(90deg, rgba(var(--teal-rgb),.10), transparent 70%), var(--panel); }
html[data-theme="paper"] .traj-tend { border-left-color: var(--teal-ink); }
/* AURORA entrance — one calm content rise per #/you mount (#view-you.you-enter, dataset-guarded in JS). Pure
   opacity+transform; the :391 / html.rm resets rest it at the final frame for reduced-motion / high-contrast. */
#view-you.you-enter .wrap { animation: you-rise .52s var(--ease-settle) both; }
@keyframes you-rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }

/* ════════════════════════════════════════════════════════════════════════════
   DASHBOARD-ELEVATION #2 — "Explore your singing" (#/you) bespoke data-viz.
   Aurora "lit-panel + gold→teal data-field" language. ALL chart colour via these
   classes (var() is unreliable in SVG presentation attributes); geometry only in
   SVG attributes; NO per-element style=. Every animated mark RESTS at its final
   (visible) state, so the :391 reduced-motion blanket + html.rm leave the data
   fully legible. INV-08: never red — the scale is amber → teal → green only.
   ════════════════════════════════════════════════════════════════════════════ */
:root {
  --dv-stroke: var(--gold); --dv-grid: var(--line);  /* VISUAL-2: was referenced by .dv-dist-base but never defined -> stroke:none, the histogram baseline never drew */ --dv-stroke-bright: var(--gold-bright);
  --dv-win: var(--green); --dv-grow: var(--teal-bright); --dv-soft: #cf8f2c;   /* success / growth / a-touch-off */
  --dv-area: rgba(var(--gold-bright-rgb),.10);
  --dv-glow: rgba(var(--gold-bright-rgb),.18);
  --dv-track: var(--line); --dv-bloom: rgba(var(--gold-bright-rgb),.30); }
html[data-theme="paper"] { --dv-stroke: var(--gold-ink); --dv-win: var(--green-ink); --dv-grow: var(--teal-ink); --dv-soft: #9a6a14; --dv-area: rgba(176,125,42,.12); }

/* — the HERO: signature stat tiles (quiet honest numbers, never grades) — */
.you-hero { margin: 16px 0 4px; position: relative; }
.you-tiles { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; }
.you-tile { display: flex; flex-direction: column; gap: 2px; padding: 16px 16px 14px; border-radius: var(--r-14);
  background: linear-gradient(180deg, var(--you-panel, rgba(42,34,24,.7)), transparent), var(--panel); border: 1px solid var(--line); position: relative; overflow: hidden; }
.you-tile::before { content: ""; position: absolute; left: 0; top: 0; right: 0; height: 1px; background: linear-gradient(90deg, transparent, rgba(var(--gold-bright-rgb),.35), transparent); }
.you-tile-n { font-family: var(--serif); font-weight: 600; font-size: var(--fs-display); line-height: 1.05; color: var(--ink-gold); }
.you-tile-run .you-tile-n, .you-tile-songs .you-tile-n { color: var(--ink-green); }
.you-tile-lab { font-size: var(--fs-caption); color: var(--muted); line-height: 1.35; }
html[data-theme="aurora"] .you-tile { box-shadow: 0 1px 0 rgba(var(--gold-bright-rgb),.05), 0 8px 24px rgba(0,0,0,.18); }
body.high-contrast .you-tile { background: var(--panel); border-color: var(--gold-bright); box-shadow: none; }
body.high-contrast .you-tile-n { color: var(--cream); }

/* — the EMPTY state: designed silence, never a dead screen — */
.you-hero.is-empty { margin: 18px 0 8px; }
.you-empty-art { text-align: center; padding: 26px 18px 28px; border-radius: var(--r-16);
  background: radial-gradient(120% 120% at 50% 10%, rgba(var(--gold-bright-rgb),.08), transparent 60%), var(--panel); border: 1px solid var(--line); }
.dv-empty-svg { display: block; width: 100%; max-width: 360px; height: auto; margin: 0 auto 8px; }
.dv-empty-line { stroke: var(--dv-stroke); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; stroke-opacity: .5;
  stroke-dasharray: 1; stroke-dashoffset: 0; animation: dv-draw 1.4s var(--ease-draw) .2s both; }
.dv-empty-dot { fill: var(--dv-grow); opacity: .55; }
.dv-empty-dot-last { fill: var(--dv-stroke-bright); opacity: 1; animation: dv-bloom-pulse 2.2s var(--ease-settle) .9s both; }
.you-empty-lead { font-family: var(--serif); font-size: var(--fs-h3); color: var(--cream); margin: 6px 0 4px; }
.you-empty-sub { color: var(--muted); font-size: var(--fs-small); line-height: 1.55; max-width: 42ch; margin: 0 auto 14px; }
.you-empty-cta { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; color: var(--ink-gold); text-decoration: none;
  border: 1px solid rgba(var(--gold-bright-rgb),.4); border-radius: var(--r-40); padding: 10px 18px; min-height: 44px; }
.you-empty-cta:hover { border-color: var(--gold); background: rgba(var(--gold-bright-rgb),.08); }
body.high-contrast .you-empty-art { background: var(--panel); border-color: var(--gold-bright); }

/* — shared chart figure + card chrome — */
.dv-fig { margin: 6px 0 14px; }
.traj-svg, .dv-range, .dv-dist, .dv-field, .dv-empty-svg { display: block; width: 100%; height: auto; }
.dv-card { position: relative; margin: 14px 0; padding: 14px 15px 12px; border-radius: var(--r-12);
  background: linear-gradient(180deg, var(--you-panel, rgba(42,34,24,.55)), transparent), var(--panel); border: 1px solid var(--line); overflow: hidden; }
.dv-card-h { font-family: var(--serif); font-weight: 600; font-size: var(--fs-body); color: var(--cream); margin: 0 0 9px; }
.dv-card-cap { color: var(--muted); font-size: var(--fs-caption); line-height: 1.45; margin: 8px 0 0; }
.dv-card-note { color: var(--cream); font-size: var(--fs-small); line-height: 1.5; margin: 7px 0 0; }
.dv-card-note b { color: var(--ink-green); }
.you-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 12px; margin: 14px 0; }
.you-grid .dv-card { margin: 0; }
body.high-contrast .dv-card { background: var(--panel); border-color: var(--gold-bright); }

/* — G1 the growth TREND: gold line draws on, soft area wash, glow dots by hit-rate — */
.dv-trend-area { fill: var(--dv-area); }
.dv-trend-line { stroke: var(--dv-stroke); stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round;
  stroke-dasharray: 1; stroke-dashoffset: 0; animation: dv-draw 1s var(--ease-draw) .2s both; }
.dv-dot { stroke: var(--panel); stroke-width: 1; }
.dv-dot-win { fill: var(--dv-win); } .dv-dot-grow { fill: var(--dv-grow); } .dv-dot-soft { fill: var(--dv-soft); }
html[data-theme="aurora"] .dv-trend { filter: drop-shadow(0 0 5px var(--dv-glow)); }
@keyframes dv-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }

/* — G2 the BLOOM: a soft radial glow that scales in around the personal best (the .dv-bloom-glow above).
   The concentric-ring overlay was clipped by the card's overflow:hidden (review MAJOR 1) → removed; the glow
   is the wow and it survives the clip. .dv-bloom just hosts the glow + the legible sentence. — */
.dv-bloom { position: relative; }

/* — G3 the cross-session TENDENCY: a calm teal card with a soft one-shot glow-in — */
.dv-tend { border-left: 3px solid var(--teal-bright); }
.dv-tend-glow { position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background: radial-gradient(70% 120% at 4% 50%, rgba(var(--teal-rgb),.16), transparent 64%); opacity: .9; animation: dv-glow-in 1.2s var(--ease-settle) .2s both; }
.dv-tend .traj-tend { position: relative; z-index: 1; margin: 0; border: 0; padding: 0; background: none; }
html[data-theme="paper"] .dv-tend { border-left-color: var(--teal-ink); }
@keyframes dv-glow-in { from { opacity: 0; } to { opacity: .9; } }

/* — G4 the RANGE arc: a vessel of light that fills lo→hi, comfortable band lit warmer — */
.dv-rng-track { fill: var(--dv-track); }
.dv-rng-reach { fill: var(--dv-stroke); transform-box: fill-box; transform-origin: left center; animation: dv-fill .9s var(--ease-draw) .2s both; }
/* the comfortable band is the singer's HOME/easy zone → TEAL by the colour law (teal = home/tonic), which also
   gives it clear contrast against the gold reach (review MAJOR 3 — it was gold-on-gold, invisible). */
.dv-rng-comfort { fill: var(--teal-bright); opacity: .95; }
html[data-theme="paper"] .dv-rng-comfort { fill: var(--teal-ink); }
body.high-contrast .dv-rng-comfort { fill: var(--teal-bright); opacity: 1; stroke: var(--bg); stroke-width: 0.75; }
.dv-rng-lab { fill: var(--cream); font-family: var(--sans); font-size: var(--fs-micro); font-weight: 600; }
html[data-theme="aurora"] .dv-range { filter: drop-shadow(0 0 5px var(--dv-glow)); }
@keyframes dv-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* — G5 PER-SONG sparks: first→best bars, fill grows on; each row deep-links — */
.dv-spark-list { list-style: none; margin: 6px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.dv-spark { display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 10px; text-decoration: none;
  padding: 9px 12px; border-radius: var(--r-10); border: 1px solid var(--line); background: var(--panel);
  transition: border-color var(--dur-2) var(--ease-out), background var(--dur-2) var(--ease-out), transform var(--dur-1) var(--ease-out); }
.dv-spark:hover { border-color: var(--gold); background: var(--panel-2); transform: translateY(var(--lift-sm)); }
.dv-spark:active { transform: translateY(0); }
.dv-spark-t { color: var(--cream); font-size: var(--fs-small); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dv-spark-svg { width: 120px; height: 12px; }
.dv-spark-track { fill: var(--dv-track); }
.dv-spark-fill { fill: var(--dv-win); transform-box: fill-box; transform-origin: left center; animation: dv-fill .8s var(--ease-draw) .25s both; }
.dv-spark-from { stroke: var(--muted); stroke-width: 1.5; }
.dv-spark-n { color: var(--ink-green); font-size: var(--fs-caption); font-weight: 600; white-space: nowrap; }
@media (max-width: 460px) { .dv-spark { grid-template-columns: 1fr auto; } .dv-spark-svg { display: none; } }

/* — G6 the SPREAD histogram: bars grow up; quiet metadata — */
.dv-bar { transform-box: fill-box; transform-origin: center bottom; animation: dv-grow .7s var(--ease-out) .2s both; }
.dv-bar-win { fill: var(--dv-win); } .dv-bar-grow { fill: var(--dv-grow); } .dv-bar-soft { fill: var(--dv-soft); }
.dv-bar-lab { fill: var(--muted); font-family: var(--sans); font-size: var(--fs-micro); }
.dv-dist-base { stroke: var(--dv-grid); stroke-width: 1; }
html[data-theme="aurora"] .dv-dist { filter: drop-shadow(0 0 4px var(--dv-glow)); }   /* tie the spread into the Aurora lit language (review nit) */
@keyframes dv-grow { from { transform: scaleY(0); } to { transform: scaleY(1); } }

/* — G7 the PRACTICE field: a calm constellation of days, fading in — */
.dv-day { fill: var(--dv-grow); opacity: .7; animation: dv-fade-in 1.1s var(--ease-settle) .2s both; }
.dv-card-stat { color: var(--cream); font-size: var(--fs-small); margin: 9px 0 0; }
.dv-card-stat b { font-family: var(--serif); color: var(--ink-gold); font-size: var(--fs-body); }
@keyframes dv-fade-in { from { opacity: 0; } to { opacity: .7; } }
@keyframes dv-bloom-pulse { from { opacity: 0; transform: scale(.5); } to { opacity: 1; transform: scale(1); } }

/* reduced-motion / html.rm — rest EVERY animated mark at its final, fully-legible state (the :391 blanket also
   kills animations under the OS preference; this covers the in-app html.rm toggle explicitly). */
html.rm .dv-trend-line, html.rm .dv-empty-line { stroke-dashoffset: 0; animation: none; }
html.rm .dv-rng-reach, html.rm .dv-spark-fill { transform: scaleX(1); animation: none; }
html.rm .dv-bar { transform: scaleY(1); animation: none; }
html.rm .dv-day { opacity: .7; animation: none; }
html.rm .dv-tend-glow, html.rm .dv-empty-dot-last, html.rm .dv-bloom-glow { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .dv-trend-line, .dv-empty-line { stroke-dashoffset: 0; }
  .dv-rng-reach, .dv-spark-fill { transform: scaleX(1); }
  .dv-bar { transform: scaleY(1); }
}
/* PRAGMATIC after-song panel — verdict + the ONE focus + praise; the % stays quiet metadata */
#precision-overlay .prec-focus { color: var(--ink-gold); font-size: var(--fs-small); line-height: 1.5; margin: 0 0 8px; }
#precision-overlay .prec-focus-lab { color: var(--ink-gold); font-weight: 600; }
#precision-overlay .prec-praise { color: var(--ink-green); font-size: var(--fs-small); line-height: 1.5; margin: 0 0 12px; }
#precision-overlay .prec-meta { color: var(--muted); font-size: var(--fs-caption); margin: 2px 0 14px; }   /* % — quiet, never the headline */
#precision-overlay .prec-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
#precision-overlay .prec-again { font: inherit; font-weight: 600; color: var(--ink-on-gold); background: var(--gold-bright);
  border: none; border-radius: var(--r-40); padding: 11px 22px; cursor: pointer; min-height: 44px; }
#precision-overlay .prec-progress { font: inherit; font-weight: 600; color: var(--ink-gold); text-decoration: none;
  border: 1px solid var(--line); border-radius: var(--r-40); padding: 10px 18px; min-height: 44px; display: inline-flex; align-items: center; }
#precision-overlay .prec-progress:hover { border-color: var(--gold); color: var(--cream); }
body.high-contrast #precision-overlay .prec-focus { color: #fff; }
body.high-contrast #precision-overlay .prec-praise { color: #fff; }

/* ════════════════════════════════════════════════════════════════════════════
   SHELL-POLISH — MOTION. A tasteful, GPU-cheap (transform-only) hover-lift on the
   surface cards + buttons, a press that settles back, and a gentle per-view entrance
   on the inner screens — all reading from the engine's ease/duration vocabulary. The
   home keeps its own crafted entrance (untouched); the trainer iframe is excluded.
   Reduced-motion (OS preference OR the in-app html.rm toggle) zeroes the lift token
   AND the global blanket (:362) kills the transitions/animations → the surface rests
   at its static frame. INV-08 untouched (no colour change; never red).
   ════════════════════════════════════════════════════════════════════════════ */
/* Surfaces — restate the transition to include transform, then rise on hover. */
.card, .rcard, .ccard, .browse-list .bcard, .conf-card, .cont-card, .onramp-link, .od-door, .od-continue {
  box-shadow: var(--elev-1);   /* C2: the resting cast — lifted vellum, not a hollow outline */
  transition: border-color var(--dur-2) var(--ease-out), background var(--dur-2) var(--ease-out), transform var(--dur-1) var(--ease-out), box-shadow var(--dur-1) var(--ease-out); }
.card:hover, .rcard:hover, .ccard:hover, .browse-list .bcard:hover, .conf-card:hover, .cont-card:hover, .onramp-link:hover, .od-door:hover, .od-continue:hover {
  transform: translateY(var(--lift)); box-shadow: var(--elev-2); }   /* C2: the 2px rise finally casts */
/* Controls — a smaller rise. Covers the home/filter/dialog/overlay button-pills too, so the press
   feedback is ONE vocabulary across every control, not just the home surfaces. */
.tool, .more-btn, .gd-hear, .chip-btn, .listen, .foot-toggle, .foot-settings, .set-theme-opt, .set-action, .back, .sing,
.sg-current, .sg-explore, .apply, .mgr-add-btn, .del-go, .del-keep, .prec-close, .prec-again, .prec-progress, .sc-close {
  transition: border-color var(--dur-2) var(--ease-out), background var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out), transform var(--dur-1) var(--ease-out); }
.tool:hover, .more-btn:hover, .gd-hear:hover, .chip-btn:hover, .listen:hover, .foot-toggle:hover, .foot-settings:hover, .set-theme-opt:hover, .set-action:hover, .back:hover, .sing:hover,
.sg-current:hover, .sg-explore:hover, .apply:hover, .mgr-add-btn:hover, .del-go:hover, .del-keep:hover, .prec-close:hover, .prec-again:hover, .prec-progress:hover, .sc-close:hover {
  transform: translateY(var(--lift-sm)); }
/* Press settles back to the surface (matches the engine's button:active). */
.card:active, .rcard:active, .ccard:active, .browse-list .bcard:active, .conf-card:active, .cont-card:active, .onramp-link:active, .od-door:active, .od-continue:active,
.tool:active, .more-btn:active, .gd-hear:active, .chip-btn:active, .listen:active, .foot-toggle:active, .set-theme-opt:active, .set-action:active, .back:active, .sing:active,
.sg-current:active, .sg-explore:active, .apply:active, .mgr-add-btn:active, .del-go:active, .del-keep:active, .prec-close:active, .prec-again:active, .prec-progress:active, .sc-close:active { transform: translateY(0); }
/* Gentle per-view entrance on the inner screens (home keeps its own choreography; trainer iframe excluded). */
#view-song:not([hidden]) .wrap, #view-page:not([hidden]) .wrap, #view-settings:not([hidden]) .wrap, #view-you:not([hidden]) .wrap {
  animation: rise-up var(--dur-4) var(--ease-out) both; }
/* Reduced-motion: zero the lift (the blanket already kills the transitions/animations). */
@media (prefers-reduced-motion: reduce) { :root { --lift: 0px; --lift-sm: 0px; } }
html.rm { --lift: 0px; --lift-sm: 0px; }

/* WELCOME HERO — landing introduction + direction paths (DC-LANDING). Warm, compact, candle-lit; reflows to one
   column on phones; the primary "Start singing" path is gold-emphasised. No animation beyond a quiet hover. */
.welcome-hero { margin: 6px 0 18px; padding: 18px 18px 16px; border-radius: var(--r-16);
  background: linear-gradient(180deg, var(--panel-2), var(--panel)); border: 1px solid var(--line); }
.welcome-h { margin: 0 0 8px; font-family: var(--serif, Georgia, serif); font-size: var(--fs-h2); font-weight: 600; color: var(--ink-gold); line-height: 1.25; }
.welcome-lead { margin: 0 0 14px; font-size: var(--fs-small); line-height: 1.5; color: var(--cream); max-width: 64ch; }
.welcome-paths { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.wpath { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; text-align: left;
  padding: 14px 15px; min-height: 64px; border-radius: var(--r-13); background: var(--panel); border: 1px solid var(--line);
  color: var(--cream); text-decoration: none; cursor: pointer; font: inherit; }
.wpath:hover { border-color: var(--gold-bright); }
.wpath-go { background: linear-gradient(180deg, rgba(var(--gold-bright-rgb),.18), rgba(var(--gold-rgb),.10)); border-color: var(--gold); }
.wpath-go:hover { border-color: var(--gold-bright); }
.wpath-ic { font-size: var(--fs-h2); line-height: 1; margin-bottom: 4px; }
.wpath-t { font-size: var(--fs-body); font-weight: 600; color: var(--cream); }
.wpath-go .wpath-t { color: var(--ink-gold); }
.wpath-d { font-size: var(--fs-caption); color: var(--muted); line-height: 1.35; }
.welcome-how { margin-top: 12px; padding: 12px 14px; border-radius: var(--r-12); background: var(--panel); border: 1px solid var(--line); }
.welcome-steps { margin: 0; padding-left: 22px; display: grid; gap: 7px; }
.welcome-steps li { font-size: var(--fs-small); line-height: 1.45; color: var(--cream); }
.welcome-steps b { color: var(--ink-gold); }
.welcome-note { margin: 10px 0 0; font-size: var(--fs-caption); color: var(--muted); }
@media (max-width: 640px) { .welcome-paths { grid-template-columns: 1fr; } .welcome-h { font-size: var(--fs-h3); } }

/* ═══ F-D ONE-SYSTEM selection (NIGHT-4 J5) — DORMANT canticleOneLibrary='1' (default OFF) ═══
   Flag-ON the home cards gain the heart (the SAME canticleSongPrefs store + heart glyph the engine
   song-menu modal uses) and share the Aurora card language with the modal rows. Flag-OFF renders NONE
   of these classes (byte-equivalent DOM), so every rule below is inert while the seam is dormant.
   Heart = gold (favorite/target vocabulary, INV-08 — never red). */
.card-wrap { position: relative; min-width: 0; }
.card-heart { position: absolute; top: 8px; right: 8px; width: 38px; height: 38px; display: inline-flex;
  align-items: center; justify-content: center; background: none; border: none; border-radius: 50%;
  color: var(--muted); cursor: pointer; padding: 0;
  transition: color var(--dur-2, .15s) ease, background var(--dur-2, .15s) ease; }
.card-heart svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round; }
.card-heart:hover { color: var(--gold-bright); }
.card-heart:active { background: rgba(255, 255, 255, .06); }
.card-heart.on { color: var(--gold-bright); }
.card-heart.on svg { fill: currentColor; stroke: none; }
.card-heart:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
/* (the Aurora edge-light rule already matches .card inside .card-wrap — no restatement needed) */

/* feat-sunday-set — quick-add '+' overlaid on a card (a SIBLING of the card link, not nested → no
   nested-interactive; left-click toggles add-to-set without opening the song). Gold "+" by default;
   green "✓" when the hymn is in the set. ≥44px tap target (40px on the narrower rail card); the title
   is padded so the glyph never overlaps the words; honours theme + high-contrast + reduced-motion.
   With the dormant one-library heart ON (.has-heart), the '+' steps left so the two never collide. */
.rcard-wrap { position: relative; display: block; min-width: 0; }
.card-add { position: absolute; top: 8px; right: 8px; z-index: 2; width: 44px; height: 44px;
  display: inline-flex; align-items: center; justify-content: center; padding: 0; margin: 0; border: 0;
  background: transparent; cursor: pointer; color: var(--ink-gold); -webkit-tap-highlight-color: transparent; }
.card-add .bic { width: 21px; height: 21px; margin: 0; box-sizing: content-box; padding: 6px;
  stroke: currentColor; stroke-width: 2.2; border-radius: var(--r-circle); background: rgba(var(--gold-bright-rgb), .14);
  transition: background var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out), transform var(--dur-2) var(--ease-out); }
.card-add:hover .bic { background: rgba(var(--gold-bright-rgb), .26); transform: translateY(var(--lift-sm, -1px)); }
.card-add.in-set { color: var(--ink-green); }
.card-add.in-set .bic { background: rgba(var(--green-rgb), .16); }
.card-add:focus-visible { outline: 3px solid var(--gold-bright); outline-offset: 1px; border-radius: var(--r-circle); }
.card-wrap.has-heart .card-add { right: 50px; }
.card-wrap.has-heart .card { padding-right: 96px; }   /* heart (right) + the '+' beside it — title never runs under */
.rcard-wrap .card-add { top: 6px; right: 8px; width: 40px; height: 40px; }
.rcard-wrap .card-add .bic { width: 18px; height: 18px; padding: 5px; }
/* reserve exactly the button's footprint on the title row so it never crowds or leaves an awkward gap;
   only the top row is reserved — the first-line + meta below the button use the full card width */
.card-wrap .card .title { padding-right: 44px; }
.rcard-wrap .rcard-title { padding-right: 36px; }
body.high-contrast .card-add .bic { background: rgba(var(--gold-bright-rgb), .30); }
body.high-contrast .card-add.in-set .bic { background: rgba(var(--green-rgb), .30); }
@media (prefers-reduced-motion: reduce) { .card-add .bic { transition: none; } }
