/* ============================================================
   The Commands of Christ — styles
   ============================================================ */

:root {
  --bg: #EAE5D7;
  --panel: #fffdf8;            /* warm cream, matches disciple.me body */
  --ink: #444847;             /* disciple.me signature text color */
  --muted: #8d857a;           /* warm taupe */
  --line: #e2dbc8;            /* warm cream border */
  --accent: #5a5a5a;          /* overridden per-category via JS */
  --accent-tint: #eeeeee;
  --accent-ink: #333333;
  --deep: #2b3733;            /* immersive session background (per-category) */
  --soft: #9cbeb2;            /* immersive text/accent tint (per-category) */
  --radius: 16px;
  --shadow: 0 10px 30px rgba(40, 38, 33, 0.08);
  --shadow-lg: 0 18px 50px rgba(40, 38, 33, 0.16);
  --font: "Roboto", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-head: "Roboto Condensed", "Roboto", system-ui, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  -webkit-font-smoothing: antialiased;
}

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}


/* homepage primary actions — soft filled pills inside the stat card */
.home-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(8px, 3vw, 12px);
  margin: 18px 0 0;
}
.home-action-btn {
  border: none;
  background: #ded7c4;
  color: var(--ink);
  border-radius: 999px;
  padding: 9px clamp(14px, 4.5vw, 20px);
  font-family: var(--font-head);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: clamp(12px, 3.5vw, 14px);
  cursor: pointer;
  white-space: nowrap;
  transition: transform 0.15s, background 0.2s, color 0.2s;
}
.home-action-btn:hover { background: var(--bg); }

/* Reset + Share — outlined pills fixed to the bottom-right, but hidden until
   you've scrolled to the end of the page so they never sit over content */
.home-corner {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 20;
  display: flex;
  gap: 12px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.25s ease, visibility 0.25s ease;
}
.home-corner.at-end {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
.home-corner-btn {
  border: 2px solid var(--bg);
  background: transparent;
  color: var(--ink);
  border-radius: 999px;
  padding: 8px 22px;
  font-family: var(--font-head);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
  font-size: 14px;
  cursor: pointer;
  transition: background 0.2s, transform 0.15s;
}
.home-corner-btn:hover { background: var(--bg); }
.sound-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  padding: 0;
  border-radius: 999px;
}
.sound-toggle .snd-icon { width: 18px; height: 18px; }

/* ---------- Layout ---------- */
#app {
  flex: 1;
  width: 100%;
  max-width: 1000px;
  margin: 0 auto;
  padding: 30px clamp(20px, 6vw, 24px) 60px;
}
/* homepage: lighter warm-white backdrop + vertically centered poster */
body[data-screen="home"] { background: #fffdf7; }
/* session: keep the page behind the immersive overlay dark so re-rendering the
   next card never flashes the light page background through its fade-in */
body[data-screen="session"] { background: var(--deep); }
body[data-screen="home"] #app {
  display: flex;
  flex-direction: column;
  justify-content: center;
  max-width: 1060px;
}
/* summary: no card, so center it in the viewport like the homepage poster */
body[data-screen="summary"] { background: #fffdf7; }
body[data-screen="summary"] #app {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

/* the immersive session (.imm) handles its own entrance/exit (imm-enter / imm-out,
   gated to the first and last card) — this generic ink-in is only for Home/Summary */
.screen:not(.imm) { animation: screenInk 0.5s cubic-bezier(.2,.7,.2,1) both; }
/* ink reveal: the screen settles in from a blur (matches the card transitions) */
@keyframes screenInk {
  from { opacity: 0; filter: blur(16px); }
  to   { opacity: 1; filter: blur(0); }
}
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---------- Home: poster masthead + honeycomb ---------- */
.home-poster {
  position: relative;
  display: grid;
  grid-template-columns: minmax(300px, 400px) 1fr;
  align-items: center;
  gap: 30px;
  padding: 14px 0 56px;
  animation-duration: 2s;   /* home inks in at 4x the default .screen speed */
}
/* Disciple.Me brand mark — sits inline before the "Memorization Game" line */
.brand-mark {
  display: block;
  height: 15px;
  width: auto;
  flex: none;
}
.masthead .poster-title {
  font-family: var(--font-head);
  text-transform: uppercase;
  font-size: clamp(28px, 4vw, 44px);
  line-height: 1.02;
  margin: 0 0 16px;
  font-weight: 400;
  letter-spacing: 0;
}
.masthead .poster-title strong { font-weight: 700; display: block; }
.poster-sub {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-head);
  text-transform: uppercase;
  letter-spacing: .12em;
  font-size: 16px;
  font-weight: 400;
  color: #79715e;
  margin: 6px 0 18px;
}
.poster-intro {
  color: #79715e;
  font-size: 16px;
  line-height: 1.56;
  max-width: 400px;
  margin: 0 0 22px;
}

.statcard {
  background: #f2efe6;
  border: none;
  border-radius: 30px;
  padding: 22px clamp(18px, 5vw, 26px) 24px;
  text-align: center;                 /* centered on every width, matching mobile */
}
.statmetrics { display: flex; gap: clamp(12px, 4vw, 34px); justify-content: center; }
.metric .n { font-family: var(--font-head); font-weight: 700; font-size: clamp(28px, 8vw, 36px); line-height: 1; color: var(--ink); }
.metric .l {
  font-family: var(--font-head);
  font-size: clamp(11px, 3.4vw, 15px); text-transform: uppercase; letter-spacing: .06em; color: #79715e; margin-top: 4px;
}
/* segmented mastery bar under the metrics — each category color fills its share */
.mastery-bar {
  display: flex;
  gap: 2px;
  height: 10px;
  margin: 16px 0 2px;
  border-radius: 99px;
  overflow: hidden;
  background: #e2dbc8;              /* track shown through the gaps + empty tail */
}
.mb-seg { min-width: 0; }
.mb-empty { background: transparent; }
.clear-progress-btn {
  display: block;
  margin: 14px 0 0;
  padding: 0;
  border: none;
  background: none;
  font-family: var(--font);
  font-size: 12px;
  color: var(--muted);
  text-decoration: underline;
  cursor: pointer;
}
.clear-progress-btn:hover { color: var(--ink); }

/* honeycomb of flat-top hexes in offset columns (mirrors the poster) */
.comb { display: flex; align-items: center; justify-content: center; --w: 172px; }
.hexcol { display: flex; flex-direction: column; }
.hexcol + .hexcol { margin-left: calc(var(--w) * -0.25); }
.hex {
  position: relative;
  width: var(--w);
  height: calc(var(--w) * 0.866);
  padding: 0;
  border: none;
  cursor: pointer;
  background: var(--c);
  color: var(--ink);
  clip-path: polygon(25% 0, 75% 0, 100% 50%, 75% 100%, 25% 100%, 0 50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  font-family: var(--font);
  transform: scale(.88);            /* shrunk within its cell so hexes sit apart */
  transition: transform 0.4s, filter 0.4s, padding-top 0.4s;
}
/* On reveal the name + stat block stay a single flex-centered group, so the
   whole thing sits vertically centered in the hex (the name simply lifts to
   make room as the stat eases in below it). */
.hex:hover,
.hex:focus-visible { filter: brightness(1.04); z-index: 2; padding-top: 10px; }
.hex:active { transform: scale(.87); }
/* subtle bounce-pop on tap (fired from JS, then the session loads) */
.hex.pop { animation: hexpop 0.42s cubic-bezier(.34,1.4,.64,1); z-index: 2; }
@keyframes hexpop {
  0%   { transform: scale(.88); }
  30%  { transform: scale(.855); }
  62%  { transform: scale(.925); }
  100% { transform: scale(.88); }
}
.hname {
  font-family: var(--font-head);
  text-transform: uppercase;
  font-weight: 700;
  font-size: 20px;
  line-height: 1.05;
  text-align: center;
  padding: 0 10px;
}
/* mastered count + progress bar — collapsed by default, revealed on hover.
   Name stays centred at rest (no flex gap); the stat block reveals with a
   growing top-margin so the name lifts and the bar/label ease in below it. */
.hstat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;                  /* breathing room between divider and count */
  width: 100%;               /* full width so the label never clips; bar is sized below */
  max-height: 0;
  margin-top: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 0.6s ease, margin-top 0.6s ease, opacity 0.48s ease;
}
.hex:hover .hstat,
.hex:focus-visible .hstat { max-height: 80px; margin-top: 16px; opacity: 1; }
.hbar {
  width: 74%; height: 3px; border-radius: 999px;
  background: rgba(68, 72, 71, 0.22); overflow: hidden;
}
.hbar > i {
  display: block; height: 100%; width: 0; border-radius: 999px; background: var(--ink);
  transition: width 1.2s cubic-bezier(.2,.8,.2,1) 0.2s;   /* grows out on hover */
}
.hex:hover .hbar > i,
.hex:focus-visible .hbar > i { width: var(--pct, 0%); }
.hmastered {
  font-family: var(--font-head);
  text-transform: uppercase;
  letter-spacing: .1em;
  font-size: 16px;
  color: var(--ink);
  white-space: nowrap;
}
/* completed category: a check mark instead of the bar + count */
.hcheck {
  display: block;
  color: var(--ink);
}
.hcheck svg { width: 16px; height: 16px; display: block; }

@media (max-width: 820px) {
  /* the stacked mobile layout is often taller than the viewport, so vertically
     centering it (desktop's short, wide hero treatment) just pushes everything
     down and leaves a large empty gap up top — start from the top instead */
  body[data-screen="home"] #app { justify-content: flex-start; }
  .home-poster { grid-template-columns: minmax(0, 1fr); gap: 34px; text-align: center; padding-top: 40px; }
  .masthead { display: flex; flex-direction: column; align-items: center; }
  .poster-intro, .statcard { margin-inline: auto; max-width: 420px; width: 100%; }
  .home-actions, .statmetrics { justify-content: center; }
  .comb { --w: min(132px, 32vw); }
  /* below the sideways two-column layout the honeycomb is touch-driven —
     :hover sticks after a tap, so suppress the hex reveal until it returns */
  .hex:hover { transform: scale(.88); filter: none; }
  .hex:hover .hstat { max-height: 0; margin-top: 0; opacity: 0; }
  .hex:hover .hbar > i { width: 0; }
}

/* ---------- Section title with accent ---------- */
.section-head {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 20px;
}
.back-btn {
  border: 1px solid var(--line);
  background: var(--panel);
  border-radius: 999px;
  padding: 8px 16px;
  cursor: pointer;
  font-family: var(--font);
  font-weight: 600;
  font-size: 14px;
  color: var(--ink);
  transition: background 0.2s, transform 0.15s;
}
.back-btn:hover { background: var(--bg); transform: translateX(-2px); }
.section-head h2 {
  margin: 0;
  font-size: 24px;
  font-weight: 700;
}
.cat-chip {
  padding: 5px 14px;
  border-radius: 999px;
  color: #fff;
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

/* ---------- Mode cards ---------- */
.mode-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 16px;
}
.mode-card {
  text-align: left;
  border: 1.5px solid var(--line);
  background: var(--panel);
  border-radius: var(--radius);
  padding: 20px;
  cursor: pointer;
  font-family: var(--font);
  color: var(--ink);
  transition: transform 0.2s cubic-bezier(.2,.8,.2,1), box-shadow 0.2s, border-color 0.2s;
  position: relative;
  overflow: hidden;
}
.mode-card::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 5px;
  background: var(--accent);
}
.mode-card:hover { box-shadow: var(--shadow-lg); border-color: transparent; }
.mode-card .m-emoji { font-size: 26px; }
.mode-card h3 { margin: 10px 0 6px; font-size: 17px; }
.mode-card p { margin: 0; color: var(--muted); font-size: 13.5px; line-height: 1.45; }

/* ---------- Session ---------- */
.session-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 18px;
}
.session-top .meta { color: var(--muted); font-size: 13px; font-weight: 600; }

/* in-game mode switcher — sits inside the card as a tab row */
.mode-switch {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 18px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--line);
}
.mode-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1.5px solid var(--line);
  background: var(--bg);
  color: var(--muted);
  border-radius: 999px;
  padding: 8px 14px;
  font-family: var(--font);
  font-weight: 500;
  font-size: 13.5px;
  cursor: pointer;
  transition: transform 0.15s, background 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.2s;
}
.mode-pill .mp-emoji { font-size: 14px; }
.mode-pill:hover { border-color: var(--accent); color: var(--accent-ink); }
.mode-pill.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 700;
  box-shadow: var(--shadow);
}
@media (max-width: 520px) {
  .mode-switch { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; padding-bottom: 4px; }
  .mode-pill { flex: 0 0 auto; }
}

.progress-line {
  height: 8px;
  background: var(--line);
  border-radius: 999px;
  overflow: hidden;
  margin-bottom: 22px;
}
.progress-line .bar {
  height: 100%;
  background: var(--accent);
  border-radius: 999px;
  transition: width 0.5s cubic-bezier(.2,.8,.2,1);
}

/* completed-so-far list (below the card) */
.completed { margin-top: 24px; }
.completed-head {
  font-family: var(--font-head);
  text-transform: uppercase;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0;
  color: var(--muted);
  margin-bottom: 10px;
}
.completed-list { display: flex; flex-direction: column; gap: 2px; }
/* plain lines on the background — no card wrapping */
.completed-item {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 5px 2px;
  font-size: 14.5px;
  animation: fadeUp 0.3s ease both;
}
.completed-item::before {
  content: "";
  width: 9px; height: 9px;
  border-radius: 2px;
  background: var(--dot);
  flex: 0 0 auto;
}
.completed-item .ci-text { flex: 1; color: var(--ink); }
.completed-item .ci-ref {
  color: var(--muted);
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
}

.card {
  background: var(--panel);
  border-radius: 22px;
  box-shadow: var(--shadow);
  border-top: 6px solid var(--accent);
  padding: 34px 30px 30px;
  min-height: 260px;
  display: flex;
  flex-direction: column;
  animation: cardIn 0.45s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes cardIn {
  from { opacity: 0; transform: translateY(24px) rotateX(6deg); }
  to   { opacity: 1; transform: none; }
}
.card.shake { animation: shake 0.4s; }
@keyframes shake {
  10%,90% { transform: translateX(-2px); }
  20%,80% { transform: translateX(4px); }
  30%,50%,70% { transform: translateX(-8px); }
  40%,60% { transform: translateX(8px); }
}

.card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.card-cat {
  font-size: 26px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: uppercase;
  line-height: 1;
  color: var(--accent-ink);
}
.card-hint { font-size: 12.5px; color: var(--muted); text-align: right; }

.words {
  font-size: clamp(21px, 3.4vw, 30px);
  font-weight: 600;
  line-height: 1.5;
  margin: 14px 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 12px;
}
.word {
  display: inline-block;
  transition: opacity 0.4s, filter 0.4s, transform 0.35s, background 0.35s, color 0.35s, box-shadow 0.35s;
}
.word.hidden-word { color: var(--muted); }
/* masked word: real text kept, blurred (same look as the Reveal mode) so the
   layout width always equals the revealed word. A tighter blur keeps the smudge's
   VISUAL width close to the finished word too, so revealing doesn't visibly
   "tighten" the line (the blur halo no longer bleeds far past each word). */
.word .mask { display: inline-block; filter: blur(6px); transition: filter 0.5s cubic-bezier(.2,.7,.2,1); }
.word .mask.shown { filter: none; }
/* ink-bloom: a revealed word settles in like ink on parchment.
   `revealing` blooms up from nothing; `settling` sharpens a visible smudge
   (the faded-word and spoken-recital reveals) without flashing to empty. */
.word.revealing { animation: inkBloom 0.5s cubic-bezier(.2,.7,.2,1) both; }
.word.settling  { animation: inkSettle 0.5s cubic-bezier(.2,.7,.2,1) both; }
@keyframes inkBloom {
  0%   { opacity: 0; filter: blur(12px); transform: translateY(5px); }
  60%  { opacity: 1; }
  100% { opacity: 1; filter: blur(0); transform: translateY(0); }
}
@keyframes inkSettle {
  0%   { filter: blur(9px); transform: translateY(3px); }
  100% { filter: blur(0); transform: translateY(0); }
}
/* heavy blur: hidden word is a full-opacity, unreadable smudge */
.word.faded { filter: blur(9px); }
.word.tappable.faded { cursor: pointer; }
.blank {
  display: inline-block;
  min-width: 1.2ch;
  border-bottom: 3px solid var(--accent);
  color: transparent;
  border-radius: 2px;
}

/* first-letter typing: given prefix + input for the rest */
.type-word { display: inline-flex; align-items: baseline; }
.type-prefix { color: var(--ink); font-weight: 600; }
.rest-input {
  font: inherit;
  border: none;
  border-bottom: 3px solid var(--accent);
  background: transparent;
  padding: 0 1px 1px;
  margin-left: 0;
  color: var(--accent-ink);
  outline: none;
  min-width: 1ch;
  transition: border-color 0.2s, color 0.2s;
}
.rest-input.ok { border-color: #5fa898; color: #3d7d6e; }
.rest-input.bad { border-color: #e8615a; animation: nudge 0.3s; }

/* letter-typing inputs */
.letter-input {
  width: 1.5em;
  height: 1.5em;
  text-align: center;
  border: 2px solid var(--line);
  border-bottom: 3px solid var(--accent);
  background: var(--accent-tint);
  border-radius: 8px;
  font: inherit;
  font-size: 0.8em;
  color: var(--accent-ink);
  padding: 0;
  margin-right: 3px;
  outline: none;
  transition: border-color 0.2s, transform 0.15s, box-shadow 0.2s;
}
.letter-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-tint);
  transform: translateY(-2px);
}
.letter-input.ok {
  border-color: #5fa898;
  background: #e4f0ec;
  color: #3d7d6e;
}
.letter-input.bad { border-color: #e8615a; animation: nudge 0.3s; }
@keyframes nudge { 25%{transform:translateX(-3px)} 75%{transform:translateX(3px)} }

/* fill-the-blank input — underline only, matching the Type mode inputs */
.blank-input {
  font: inherit;
  border: none;
  border-bottom: 3px solid var(--accent);
  background: transparent;
  padding: 0 1px 1px;
  margin: 0 1px;
  color: var(--accent-ink);
  outline: none;
  min-width: 1ch;
  transition: border-color 0.2s, color 0.2s;
}
.blank-input.ok { border-color: #5fa898; color: #3d7d6e; }
.blank-input.bad { border-color: #e8615a; animation: nudge 0.3s; }

.reference {
  margin-top: 18px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.ref-badge {
  display: inline-block;
  background: var(--accent-tint);
  color: var(--accent-ink);
  font-weight: 700;
  font-size: 14px;
  padding: 10px 16px;
  border-radius: 999px;
  cursor: help;
  text-decoration: none;
}

/* ---------- Controls ---------- */
.controls {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 26px;
}
.btn {
  border: none;
  border-radius: 14px;
  padding: 16px 30px;
  font-family: var(--font);
  font-weight: 700;
  font-size: 17px;
  cursor: pointer;
  transition: transform 0.15s, filter 0.2s, box-shadow 0.2s;
}
.btn:active { transform: scale(0.97); }
.btn.primary { background: var(--accent); color: #fff; box-shadow: var(--shadow); }
.btn.primary:hover { filter: brightness(1.06); }
.btn.ghost { background: var(--panel); border: 1.5px solid var(--line); color: var(--ink); }
.btn.ghost:hover { background: var(--bg); }
.btn:disabled { opacity: 0.4; cursor: default; }

/* ---------- Spaced-repetition rating ---------- */
.rating {
  margin-top: 22px;
  border-top: 1px dashed var(--line);
  padding-top: 18px;
  animation: fadeUp 0.35s ease both;
}
.rating .rate-q { font-size: 13px; color: var(--muted); margin-bottom: 10px; font-weight: 600; }
.rate-row { display: flex; gap: 10px; flex-wrap: wrap; }
.rate {
  flex: 1;
  min-width: 72px;
  border: none;
  border-radius: 12px;
  padding: 12px 8px;
  font-family: var(--font);
  font-weight: 600;
  font-size: 16px;
  cursor: pointer;
  color: #444847;
  transition: transform 0.15s, filter 0.2s;
}
.rate small { display: block; font-weight: 400; font-size: 16px; opacity: 1; }
.rate:hover { filter: brightness(1.05); }
.rate.miss { background: #f89592; }
.rate.got  { background: #9cbeb2; }

/* ---------- Summary ---------- */
/* no card: sits directly on the page background, centered in the viewport */
.summary {
  text-align: center;
  max-width: 440px;
  margin: 0 auto;
  padding: 30px 20px;
}
.summary .big { font-size: 54px; margin: 6px 0; }
.summary h2 { margin: 0 0 4px; font-size: 26px; }
.summary p { color: var(--muted); margin: 4px 0 0; text-wrap: balance; }
.summary .controls { justify-content: center; }
.summary .btn {
  border: none;
  background: #ded7c4;
  color: var(--ink);
  border-radius: 999px;
  font-family: var(--font-head);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: 14px;
  padding: 14px 26px;
  box-shadow: none;
  transition: transform 0.15s, background 0.2s;
}
.summary .btn.primary,
.summary .btn.ghost { background: #ded7c4; color: var(--ink); }
.summary .btn:hover { background: var(--bg); }

/* Mastery ring — the category-complete / session summary hero */
.summary-ring { padding: 4px 0 0; }
.sum-ring-wrap { margin: 0 0 14px; }
.mastery-ring { width: 150px; height: 150px; display: block; margin: 0 auto; }
.mastery-ring .mr-track { fill: none; stroke: var(--line); stroke-width: 3.4; }
.mastery-ring .mr-arcs circle { stroke-linecap: butt; }
.mastery-ring .mr-n { font-family: var(--font-head); font-weight: 700; font-size: 9px; fill: var(--ink); }
/* the "6/7" fraction is a char wider than a bare count — trim it to stay centered */
.mastery-ring .mr-n.mr-frac { font-size: 8px; letter-spacing: -0.3px; }
.mastery-ring .mr-of { font-family: var(--font); font-size: 3.5px; fill: var(--muted); }
.summary-ring h2 { margin: 4px 0 4px; }
.stat-row {
  display: flex;
  justify-content: center;
  gap: 26px;
  margin: 24px 0 28px;
  flex-wrap: wrap;
}
.stat { }
.stat .n { font-size: 28px; font-weight: 700; color: var(--accent-ink); }
.stat .l { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }

.empty {
  text-align: center;
  color: var(--muted);
  padding: 50px 20px;
}
.empty .big { font-size: 40px; }

/* ---------- Reference tooltip ---------- */
.ref-tip {
  position: fixed;
  z-index: 100;
  max-width: 260px;
  background: #444847;
  color: #fff;
  padding: 10px 13px;
  border-radius: 10px;
  font-size: 13px;
  line-height: 1.4;
  box-shadow: var(--shadow-lg);
  opacity: 0;
  transform: translateY(6px);
  pointer-events: none;
  transition: opacity 0.18s, transform 0.18s;
}
.ref-tip.show { opacity: 1; transform: translateY(0); pointer-events: auto; }
.ref-tip .rt-ref { font-weight: 700; margin-bottom: 3px; }
.ref-tip a { color: #8fd0ff; text-decoration: none; font-weight: 600; font-size: 12px; }
.ref-tip a:hover { text-decoration: underline; }

/* ---------- Confetti ---------- */
.confetti {
  position: fixed;
  width: 9px; height: 14px;
  top: -20px;
  z-index: 90;
  pointer-events: none;
  border-radius: 2px;
  animation: fall linear forwards;
}
@keyframes fall {
  to { transform: translateY(105vh) rotate(720deg); opacity: 0.9; }
}

/* ---------- Mastered count-up (inside the "Got it" button) ---------- */
/* On "Got it", the green button's label morphs into the category count and
   ticks up in place. Per the Figma design (node 1499:218), "5 MASTERED" is a
   single uniform string — Roboto Condensed Bold at 29px (~1.8em on the 16px
   button), the number and the word the SAME size and weight. The two spans
   exist only so the number can animate; visually they read as one label. */
.rate.got.celebrating {
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.28em;   /* the space between "5" and "MASTERED" */
}
.rate.got .mc-count,
.rate.got .mc-word {
  font-size: 1.8em;
  font-weight: 700;
  line-height: 1;
}
.rate.got .mc-count {
  font-variant-numeric: tabular-nums;
}
/* Duolingo-style reveal: as "Got it" morphs into "N MASTERED", the whole label
   rises up and fades in (both spans move as one unit so they read as one word). */
.rate.got.celebrating .mc-count,
.rate.got.celebrating .mc-word {
  animation: masteredRise 0.42s cubic-bezier(.2,.7,.2,1) both;
}
@keyframes masteredRise {
  from { opacity: 0; transform: translateY(0.7em); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .rate.got.celebrating .mc-count,
  .rate.got.celebrating .mc-word { animation: none; }
}
/* "Missed it" stays put at full size and full color — only its interactivity
   is gone, so the row still reads as a real choice, not a loss. */
.rate.miss.dim {
  pointer-events: none;
}

@media (max-width: 520px) {
  .hex { --w: min(150px, 33vw); }   /* scale the comb down so it never overflows tiny screens */
  .card { padding: 26px 20px; }
  .stat-row { gap: 18px; }
}

/* ---------- Headings: Roboto Condensed Bold, no tracking or shadow ---------- */
.intro h2,
.section-head h2,
.summary h2,
.mode-card h3,
.hex .h-name,
.card-cat,
.cat-chip {
  font-family: var(--font-head);
  font-weight: 700;
  letter-spacing: 0;
  text-shadow: none;
}
/* disciple.me headings are uppercase Roboto Condensed */
.intro h2,
.section-head h2,
.summary h2 {
  text-transform: uppercase;
}

/* ============================================================
   Immersive session — dark category-tinted screen + floating dock
   ============================================================ */
.imm {
  position: fixed;
  inset: 0;
  z-index: 30;
  background: var(--deep);
  color: var(--soft);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}
/* ink dissolve, reserved for entering/leaving the session (not per-card):
   the first card settles in from a blur… */
.imm.imm-enter { animation: immIn 1.6s cubic-bezier(.2,.7,.2,1) both; }  /* home→game mode inks in at 4x the default .screen speed */
@keyframes immIn { from { opacity: 0; filter: blur(16px); } to { opacity: 1; filter: blur(0); } }
/* …and the whole session blurs away before the close button or the final card exits it */
.imm.imm-out { animation: immOut 0.3s ease forwards; }
@keyframes immOut { from { opacity: 1; filter: blur(0); } to { opacity: 0; filter: blur(16px); } }

/* top bar: category (left) · reference (centered) · close (right) */
.imm-top {
  position: relative;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 22px 26px 12px;
}
.imm-topleft { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.imm-cat {
  font-family: var(--font-head);
  text-transform: uppercase;
  font-weight: 700;
  font-size: 22px;
  letter-spacing: .01em;
}
/* category heading as a dropdown */
.imm-cat-wrap { min-width: 0; min-height: 40px; display: flex; align-items: center; position: relative; }
.imm-cat-select {
  flex: 0 0 auto;
  max-width: 100%;
  -webkit-appearance: none;
  appearance: none;
  border: none;
  background-color: transparent;
  color: var(--soft);
  cursor: pointer;
  padding: 0 22px 0 1px;
  text-overflow: ellipsis;
  transition: opacity .2s;
}
/* caret, tinted to the category color so it matches the heading text —
   Lucide's chevron-down, masked so it inherits the category color like text */
.imm-cat-wrap::after {
  content: "";
  position: absolute;
  right: 2px;
  top: 50%;
  width: 16px; height: 16px;
  transform: translateY(-50%);
  background-color: var(--soft);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>") no-repeat center;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>") no-repeat center;
  mask-size: contain;
  -webkit-mask-size: contain;
  pointer-events: none;
}
.imm-cat-select:hover { opacity: .82; }
.imm-cat-select:focus { outline: none; }
.imm-cat-select option {
  color: var(--ink);
  background: var(--panel);
  text-transform: none;
  font-weight: 600;
  font-size: 15px;
}
/* reference — centered across the whole bar on desktop, restyled as plain type */
/* centered nav: prev/next arrows around the position counter + reference */
.imm-nav {
  position: absolute;
  left: 50%;
  top: 22px;                /* align with the close button's top (imm-top padding) */
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  white-space: nowrap;
}
/* 40px box (matching the close button) so the reference line centers on the
   same vertical axis as it, instead of sitting high */
.imm-nav-line { display: flex; align-items: center; gap: 10px; min-height: 40px; }
/* "All Categories": the current card's category, tagged under the reference line */
.imm-verse-cat {
  font-family: var(--font-head);
  text-transform: uppercase;
  letter-spacing: .12em;
  font-size: 20px;      /* match the reference line */
  font-weight: 400;
  color: var(--soft);
  opacity: .72;
  text-indent: .12em;   /* offset the trailing letter-spacing so it reads centered */
}
.imm-arrow {
  all: unset;
  cursor: pointer;
  color: var(--soft);
  font-size: 16px;
  line-height: 1;
  padding: 0 2px;
  transition: opacity .2s;
}
.imm-arrow:hover { opacity: .65; }
.imm-arrow:disabled { opacity: .28; cursor: default; }
.imm-pos {
  color: var(--soft);
  font-family: var(--font-head);
  font-weight: 400;
  font-size: 20px;
  letter-spacing: .12em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}
.imm-sep {
  color: var(--soft);
  font-family: var(--font-head);
  font-weight: 400;
  font-size: 20px;
  opacity: .4;
  user-select: none;
}
.imm-ref {
  background: none;
  border: none;
  padding: 0;
  color: var(--soft);
  font-family: var(--font-head);
  font-weight: 400;
  font-size: 20px;
  letter-spacing: .12em;
  text-transform: uppercase;
  white-space: nowrap;
  text-decoration: none;
  cursor: help;
}
.imm-ref:hover { opacity: .82; }
/* only drop the whole nav under the category dropdown when JS detects it would
   actually overlap the dropdown or the close button — not on a fixed breakpoint */
.imm-top.stack-ref .imm-nav {
  position: static;
  transform: none;
  left: auto;
  top: auto;
  margin-top: 3px;
}
.imm-top-right { display: flex; gap: 8px; }
.imm-icon {
  width: 40px; height: 40px;
  border-radius: 999px;
  border: 1.5px solid var(--soft);
  background: transparent;
  color: var(--soft);
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: transform .15s;
}
.imm-icon svg { width: 18px; height: 18px; }

/* stage — the verse, centered in the space above the mastered list */
.imm-stage {
  position: relative;
  flex: 1;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center;
  padding: 24px 26px;
  gap: 18px;
}
.imm-stage.shake { animation: shake 0.4s; }
.imm-stage .words {
  color: #fffdf7;
  font-weight: 700;
  margin: 0;
  justify-content: center;
  font-size: clamp(28px, 4.6vw, 46px);
}
/* exercise elements recolored for the dark background */
.imm-stage .type-prefix { color: #fffdf7; }
.imm-stage .rest-input,
.imm-stage .blank-input,
.imm-stage .letter-input {
  background: transparent;
  border-color: rgba(255,255,255,.7);
  color: #fffdf7;
}
.imm-stage .rest-input.ok,
.imm-stage .blank-input.ok,
.imm-stage .letter-input.ok {
  background: transparent; color: #fffdf7; border-color: #fffdf7;
}
.imm-stage .blank-input.bad,
.imm-stage .rest-input.bad,
.imm-stage .letter-input.bad { border-color: #ffd7d3; }

/* mastered-in-category list — "Mastered n/total" + a two-column table,
   centered just above the dock */
.imm-mastered {
  flex: 0 0 auto;
  width: 100%;
  max-width: 500px;
  margin: 0 auto;
  padding: 6px 26px 14px;
  text-align: center;
}
/* the count label, styled the same whether it's a static line or a toggle */
.imm-mastered-label,
.imm-mastered-head {
  font-family: var(--font-head);
  text-transform: uppercase;
  letter-spacing: .1em;
  font-size: 16px;
  font-weight: 700;
  color: var(--soft);
  margin: 0;
}
.imm-mastered-head {
  all: unset;
  box-sizing: border-box;
  display: inline-flex; align-items: center; gap: 8px;
  cursor: pointer;
  padding: 4px 6px;
  font-family: var(--font-head); text-transform: uppercase; letter-spacing: .1em;
  font-size: 16px; font-weight: 700; color: var(--soft);
}
.imm-m-chev { width: 16px; height: 16px; vertical-align: -2px; transition: transform .3s ease; }
.imm-mastered.open .imm-m-chev { transform: rotate(180deg); }

/* collapsible body — the list, which scrolls when open and folds shut when not */
.imm-mastered-body {
  max-height: 24vh;
  overflow-y: auto;
  margin-top: 10px;
  transition: max-height .32s ease, opacity .28s ease, margin-top .28s ease;
}
.imm-mastered:not(.open) .imm-mastered-body {
  max-height: 0;
  opacity: 0;
  margin-top: 0;
  overflow: hidden;
}
/* trailing space so the bottom fade falls on empty room, not the last (or only) row */
.imm-mastered-list { display: flex; flex-direction: column; padding-bottom: 44px; }
.imm-mastered-item {
  display: flex; align-items: baseline; justify-content: space-between; gap: 20px;
  padding: 7px 0;
  border-bottom: 1px solid rgba(255,255,255,.14);
  text-align: left;
  color: var(--soft);
}
.imm-mastered-item:last-child { border-bottom: none; }
.imm-m-text { font-size: 16px; line-height: 1.4; }
.imm-m-ref { font-size: 16px; opacity: .85; white-space: nowrap; }

/* Soft-fade the scroll edges so a clipped row dissolves into the background,
   hinting there's more of the list below (or above, once scrolled). */
.imm-mastered-body.fade-bottom {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 46px), transparent);
          mask-image: linear-gradient(to bottom, #000 calc(100% - 46px), transparent);
}
.imm-mastered-body.fade-top {
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 46px);
          mask-image: linear-gradient(to bottom, transparent, #000 46px);
}
.imm-mastered-body.fade-top.fade-bottom {
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 46px, #000 calc(100% - 46px), transparent);
          mask-image: linear-gradient(to bottom, transparent, #000 46px, #000 calc(100% - 46px), transparent);
}

/* dock — a floating dark panel of mode pills + action buttons */
.imm-dock {
  width: min(700px, calc(100% - 40px));
  margin: 0 auto 24px;
  background: #3C3F3E;
  color: #fff;
  border-radius: 30px;
  box-shadow: 0 4px 32px rgba(0,0,0,.25);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
/* rises in from below once the screen's ink-fade (immIn, 0.4s) has settled —
   only on the session's first card; every later card swaps in place (no slide) */
.imm-dock.dock-enter {
  animation: dockSlideUp 0.4s cubic-bezier(.2,.7,.2,1) both;
  animation-delay: 0.4s;
}
@keyframes dockSlideUp {
  from { opacity: 0; transform: translateY(40px); }
  to   { opacity: 1; transform: translateY(0); }
}
.imm-dock .mode-switch {
  display: flex;
  gap: 8px;
  width: 100%;
  margin: 0;
  padding: 0;
  border-bottom: none;
  flex-wrap: nowrap;
}
.imm-dock .mode-pill {
  flex: 1;
  min-width: 0;
  height: 40px;
  justify-content: center;
  padding: 0 8px;
  border: none;
  border-radius: 50px;
  background: #2f2f2f;
  color: var(--soft);
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 16px;
  text-transform: uppercase;
  letter-spacing: .02em;
  transition: background .2s, color .2s, transform .15s;
}
.imm-dock .mode-pill:hover { background: color-mix(in srgb, var(--soft) 20%, #2f2f2f); color: var(--soft); border: none; }
.imm-dock .mode-pill.active { background: var(--soft); color: #444847; box-shadow: none; border: none; }
.imm-dock .mode-pill.active:hover { background: var(--soft); color: #444847; filter: brightness(1.03); }

.imm-row { display: flex; width: 100%; }
/* Mode switch: cross-fade the exercise (verse stage + its larger buttons) out
   then back in, instead of an instant swap. Toggled from rebuildCard(). */
.imm-stage, .imm-row { transition: opacity 0.16s ease; }
.imm-stage.mode-fade, .imm-row.mode-fade { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
  .imm-stage, .imm-row { transition: none; }
}
.imm-row .controls { display: flex; width: 100%; gap: 14px; margin: 0; flex-wrap: nowrap; }
.imm-row .btn {
  flex: 1;
  min-width: 0;
  height: 65px;
  padding: 0 16px;
  border-radius: 50px;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 16px;
  text-transform: uppercase;
  letter-spacing: .02em;
  box-shadow: none;
}
.imm-row .btn.primary { background: var(--soft); color: #444847; }
.imm-row .btn.primary:hover { filter: brightness(1.03); }
.imm-row .btn.ghost { background: #2f2f2f; color: var(--soft); border: none; }
.imm-row .btn.ghost:hover { background: color-mix(in srgb, var(--soft) 20%, #2f2f2f); }

/* recall-rating row reuses the dock's action-row slot */
.imm-dock .rating { border-top: none; padding-top: 0; margin: 0; text-align: center; }
.imm-dock .rate-q { color: var(--soft); opacity: .9; }
.imm-dock .rate-row { justify-content: center; gap: 12px; width: 100%; }
.imm-dock .rate {
  height: 65px;                 /* match the action-button row height */
  border-radius: 50px;
  font-family: var(--font-head);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .02em;
}
/* on completion, the mode-pill row becomes the recall prompt in the same slot,
   so the dock keeps its exact two-row height instead of growing another row */
.imm-dock .mode-switch.as-rating {
  flex-direction: column;
  gap: 0;
  justify-content: center;
  align-items: center;
  min-height: 40px;
  text-align: center;
  animation: fadeUp 0.3s ease both;
}
.imm-dock .mode-switch.as-rating .rate-q {
  margin: 0; color: var(--soft); font-size: 24px; font-weight: 400; opacity: 1;
}

@media (max-width: 520px) {
  .imm-top { padding: 18px 18px 10px; }
  .imm-cat { font-size: 20px; }
  .imm-ref, .imm-pos { font-size: 15px; letter-spacing: .1em; }
  .imm-sep { font-size: 15px; }
  .imm-stage { padding: 18px; }
  .imm-mastered { padding: 4px 18px 14px; }
  .imm-mastered-label { font-size: 15px; }
  .imm-m-text, .imm-m-ref { font-size: 15px; }
  .imm-dock { width: calc(100% - 24px); margin-bottom: 16px; padding: 14px; gap: 12px; }
  .imm-dock .mode-pill { font-size: 13px; letter-spacing: 0; padding: 0 4px; }
  .imm-row .btn { height: 58px; font-size: 15px; }
  .imm-dock .rate { height: 58px; font-size: 14px; }   /* keep the rating row level with the actions */
  /* the sub-label must stay on one line — the narrow button clips a wrap */
  .rate small { font-size: 11px; white-space: nowrap; }
  .imm-dock .mode-switch.as-rating .rate-q { font-size: 19px; }
  /* five mode pills: let the row scroll rather than crush the labels */
  .imm-dock .mode-switch { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .imm-dock .mode-pill { flex: 1 0 auto; }
}

/* ============================================================
   Recite Aloud — spoken recitation + encouragement + motion prefs
   ============================================================ */

/* small helper line under the verse (recite hint / status) */
.stage-note {
  font-size: 14px;
  line-height: 1.45;
  color: var(--soft);
  opacity: .82;
  max-width: 42ch;
  margin: 2px auto 0;
}
/* taken out of the stage's centered flow so its height never shifts the
   verse text — pinned near the bottom of the stage instead */
.recite-status {
  position: absolute;
  left: 50%;
  bottom: 10px;
  transform: translateX(-50%);
  margin: 0;
  width: 100%;
}

/* the mic while it's listening — a soft, breathing halo */
.btn.listening { animation: pulseMic 1.3s ease-in-out infinite; }
@keyframes pulseMic {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255,255,255,0); }
  50%      { box-shadow: 0 0 0 6px rgba(255,255,255,.16); }
}

@media (prefers-reduced-motion: reduce) {
  .word.revealing, .word.settling { animation-duration: 0.001s; }
  .btn.listening { animation: none; }
  .imm { animation-duration: 0.001s; }
  .imm.imm-out { animation: none; }
  .screen { animation-duration: 0.001s; }
  .imm-dock.dock-enter { animation-duration: 0.001s; animation-delay: 0s; }
}

/* ============================================================
   Startup sound prompt
   ============================================================ */
.sound-modal {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  background: rgba(43, 41, 33, .5);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  animation: soundIn 0.3s ease both;
}
.sound-modal.closing { animation: soundOut 0.26s ease forwards; }
@keyframes soundIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes soundOut { to { opacity: 0; } }
.sound-card {
  background: var(--panel);
  border-radius: 24px;
  box-shadow: var(--shadow-lg);
  padding: 30px 30px 26px;
  max-width: 340px; width: 100%;
  text-align: center;
  animation: soundPop 0.36s cubic-bezier(.2,.9,.3,1.2) both;
}
@keyframes soundPop { from { transform: translateY(10px) scale(.96); opacity: 0; } to { transform: none; opacity: 1; } }
.sound-q { color: var(--ink); font-size: 17px; line-height: 1.5; margin: 4px 0 22px; font-weight: 500; }
.sound-btns { display: flex; gap: 10px; }
.sound-yes, .sound-no {
  flex: 1; border: none; border-radius: 999px; padding: 13px 10px;
  font-family: var(--font-head); font-weight: 700; text-transform: uppercase;
  letter-spacing: .06em; font-size: 14px; cursor: pointer;
  transition: filter .2s, background .2s;
}
.sound-yes { background: #6D6E6B; color: #FFFDF6; }
.sound-yes:hover { filter: brightness(1.15); }
.sound-no { background: #e2dbc8; color: var(--ink); }
.sound-no:hover { background: var(--bg); }
@media (prefers-reduced-motion: reduce) {
  .sound-modal, .sound-card { animation-duration: 0.001s; }
}
