/* Hirakana.gg shared styles */
:root {
  --bg: #F5F1E6;
  --bg-2: #EFE9DA;
  --ink: #0F0E13;
  --ink-2: #1B1A22;
  --muted: #6B6864;
  --line: #1B1A2218;
  --line-strong: #1B1A2233;
  --coral: #FF6B4A;
  --coral-soft: rgba(231,185,147,0.14);
  --cyan: #2EC4D9;
  --magenta: #E84A8A;
  --yellow: #F2C94C;
  --paper: #FFFCF4;
  --green: #37a974;
  --grid: rgba(201, 196, 139, 0.18);

  /* Per-page accent. Pages opt into a theme via a body class
     (.theme-yellow / .theme-cyan). The default is coral. --accent-rgb
     is the bare "r, g, b" triplet so rules can compose rgba() values. */
  --accent: var(--coral);
  --accent-soft: var(--coral-soft);
  --accent-rgb: 255, 107, 74;
}

body.theme-yellow {
  --accent: #B8901F;
  --accent-soft: rgba(242, 201, 76, 0.22);
  --accent-rgb: 242, 201, 76;
}
body.theme-cyan {
  --accent: #0E7D8F;
  --accent-soft: rgba(46, 196, 217, 0.20);
  --accent-rgb: 46, 196, 217;
}
/* The Final Test + Diploma pages opt into magenta. Note --accent itself is
   green: it's the "you made it" color, while --accent-soft / --accent-rgb
   stay magenta for halos & hover states (matches the page's blood-and-laurel
   identity). Do not "fix" the apparent mismatch — it's deliberate. */
body.theme-magenta {
  --accent: #37a974;
  --accent-soft: rgba(232, 74, 138, 0.18);
  --accent-rgb: 232, 74, 138;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: 'Inter', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  overflow-x: hidden;
}

body.grid-on::before {
  content: "";
  position: fixed;
  inset: 0;
  background-image:
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: 40px 40px;
  pointer-events: none;
  z-index: 0;
  mask-image: radial-gradient(ellipse at center, black 30%, transparent 75%);
  -webkit-mask-image: radial-gradient(ellipse at center, black 30%, transparent 75%);
}

.mono { font-family: 'JetBrains Mono', ui-monospace, monospace; }
.jp { font-family: 'Noto Sans JP', serif; }

/* Header */
.topbar {
  position: relative;
  z-index: 5;
  background: var(--ink);
  color: var(--paper);
  height: 64px;
  display: flex;
  align-items: center;
  padding: 0 24px;
  border-bottom: 1px solid #000;
}
.topbar .left, .topbar .right {
  flex: 1; display: flex; align-items: center; gap: 10px;
}
.topbar .right { justify-content: flex-end; }
.topbar .center { flex: 0; text-align: center; line-height: 1.1; }
.topbar .center .crumb {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.18em;
  color: rgba(255,255,255,0.45);
  text-transform: uppercase;
}
.topbar .center .name {
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.02em;
}
.topbar .name .gg { color: var(--coral); }
.topbar .pill {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.6);
  padding: 5px 9px;
  border: 1px solid rgba(255,255,255,0.18);
  border-radius: 4px;
}
.topbar .pill.btn {
  background: transparent;
  color: rgba(255,255,255,0.85);
  cursor: pointer;
  font-family: 'JetBrains Mono', monospace;
  text-decoration: none;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.topbar .pill.btn:hover { color: #fff; border-color: rgba(255,255,255,0.4); }
.topbar .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--coral);
  box-shadow: 0 0 0 3px rgba(255,107,74,0.18);
  animation: pulse 1.6s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

/* Floating back link — replaces the dark topbar on game pages */
.back-link {
  position: fixed;
  top: 16px; left: 24px;
  z-index: 10;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 15px 30px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-2);
  text-decoration: none;
  transition: border-color 0.15s ease, color 0.15s ease, transform 0.12s ease;
}
.back-link:hover {
  border-color: var(--ink);
  color: var(--ink);
  transform: translateX(-2px);
}

.page {
  position: relative;
  z-index: 1;
  max-width: 1080px;
  margin: 0 auto;
  padding: 56px 32px 96px;
}
.page.narrow { max-width: 760px; }

/* Section header */
.sect-h {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 22px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted);
}
.sect-h .line { flex: 1; height: 1px; background: var(--line-strong); }

/* Buttons */
.btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: var(--ink);
  color: var(--paper);
  border: none;
  border-radius: 6px;
  font-family: 'Inter', sans-serif;
  font-weight: 600;
  font-size: 16px;
  padding: 16px 28px;
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
  width: 100%;
  letter-spacing: 0.01em;
}
.btn-primary:hover { background: #414141 }
.btn-primary[disabled] { opacity: 0.9; cursor: not-allowed; transform: none; background: #a9a39a}
.btn-primary .sub {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 400;
  opacity: 0.6;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.btn-primary.accent { background: var(--accent)}

.btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 6px 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink-2);
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.btn-ghost:hover { border-color: var(--ink); color: var(--ink); }

/* Toggle pills (Hiragana / Katakana, etc) */
.pillgroup {
  display: inline-flex;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  padding: 4px;
  gap: 4px;
}
.pillgroup button {
  background: transparent;
  border: none;
  padding: 8px 16px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
  cursor: pointer;
  border-radius: 5px;
  transition: background 0.15s ease, color 0.15s ease;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.pillgroup button .glyph {
  font-family: 'Noto Sans JP', serif;
  font-size: 14px;
  letter-spacing: 0;
}
.pillgroup button.on {
  background: var(--ink);
  color: var(--paper);
}
.pillgroup button.on .glyph { color: var(--accent); }

/* Eyebrow label */
.eyebrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.28em;
  color: var(--muted);
  text-transform: uppercase;
}

/* Tape label (90s touch) */
.tape {
  display: none;
  background: var(--yellow);
  color: var(--ink);
  padding: 2px 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  transform: rotate(-1.5deg);
  border: 1px solid var(--ink);
}

/* Bottom CMYK marks */
.reg-marks {
  position: fixed;
  bottom: 12px; left: 12px;
  display: flex; gap: 6px;
  z-index: 2;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--muted);
  align-items: center;
}
.reg-marks .swatch {
  width: 9px; height: 9px; display: inline-block;
  border: 1px solid var(--ink);
}
.reg-marks .c { background: var(--cyan); }
.reg-marks .m { background: var(--magenta); }
.reg-marks .y { background: var(--yellow); }
.reg-marks .k { background: var(--ink); }
.reg-marks .reg-howto {
  background: transparent;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  cursor: pointer;
  text-transform: uppercase;
}
.reg-marks .reg-howto:hover { color: var(--ink) }

.corner-build {
  position: fixed;
  bottom: 12px; right: 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--muted);
  z-index: 2;
}

/* Card surface */
.surface {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 22px 24px;
}
.surface.coral-frame {
  border: 1px solid var(--accent);
  box-shadow: 4px 4px 0 0 var(--accent);
}
.surface.ink-frame {
  border: 1px solid var(--ink);
  box-shadow: 4px 4px 0 0 var(--ink);
}

/* Kana cell — shared base */
.kanacell {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 10px 4px 14px;
  text-align: center;
  font-family: 'Noto Sans JP', serif;
  font-size: 22px;
  color: var(--ink);
  user-select: none;
}
.kanacell .romaji {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--muted);
  margin-top: 4px;
  letter-spacing: 0.06em;
}
.kanacell.new {
  background: var(--accent-soft);
  border-color: rgba(var(--accent-rgb), 0.4);
  color: var(--accent);
}
.kanacell.new .romaji { color: var(--accent); opacity: 0.85; }
.kanacell.dim { opacity: 0.5; }

/* Stat row */
.statrow {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  text-align: center;
}
.statrow .stat .lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 4px;
}
.statrow .stat .val {
  font-family: 'JetBrains Mono', monospace;
  font-size: 28px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1;
}
.statrow .stat.coral .val { color: var(--accent); }
.statrow .stat.magenta .val { color: var(--magenta); }
.statrow .stat.yellow .val { color: #B8901F; }

/* Footer ribbon */
.ribbon {
  margin-top: 64px;
  border-top: 1px dashed var(--line-strong);
  padding-top: 22px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.18em;
  color: var(--muted);
  text-transform: uppercase;
  flex-wrap: wrap;
  gap: 10px;
}
.ribbon .marquee {
  overflow: hidden;
  white-space: nowrap;
  flex: 1;
  margin: 0 14px;
  mask-image: linear-gradient(90deg, transparent, black 10%, black 90%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, black 10%, black 90%, transparent);
}
.ribbon .marquee-track {
  display: inline-block;
  padding-left: 100%;
  animation: marquee 28s linear infinite;
}
@keyframes marquee {
  0% { transform: translateX(0); }
  100% { transform: translateX(-100%); }
}
.ribbon .marquee-track span { margin-right: 32px; color: var(--ink-2); }

/* ================================================================
   Setup heading — shared by Learn Kana + Read Kana state-setup
   ================================================================ */
.setup-head { text-align: center; margin-bottom: 50px; }
.setup-head .crumb-row {
  display: flex; align-items: center; justify-content: center; gap: 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 0.28em; color: var(--muted);
  text-transform: uppercase; margin-bottom: 14px;
}
.setup-head .crumb-row .bar { width: 28px; height: 1px; background: var(--line-strong); }
.setup-head h1 {
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 600; font-size: 44px; letter-spacing: -0.02em;
  margin: 0 0 6px;
}
.setup-head .meta {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: var(--muted); letter-spacing: 0.06em;
}

/* State containers (shared) */
.state { display: none; }
.state.active { display: block; }

/* Shake animation (shared) */
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-6px); }
  75% { transform: translateX(6px); }
}

/* ================================================================
   Home page
   ================================================================ */

/* Hero */
.hero {
  text-align: center;
  margin: 24px 0 48px;
  position: relative;
}
.hero .eyebrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.32em;
  color: var(--muted);
  text-transform: uppercase;
  margin-bottom: 18px;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.hero .eyebrow .bar {
  display: inline-block;
  width: 28px; height: 1px; background: var(--line-strong);
}
.hero h1 {
  font-family: 'Inter', sans-serif;
  font-weight: 700;
  margin-bottom: 70px;
  font-size: clamp(40px, 6vw, 70px);
  letter-spacing: -0.025em;
  line-height: 1.02;
  margin: 0 auto;
  max-width: 14ch;
  text-wrap: balance;
}
.hero h1 em {
  font-style: normal;
  color: var(--magenta);
  position: relative;
  white-space: nowrap;
}
.hero h1 em::after {
  content: "";
  position: absolute;
  left: -2px; right: -2px; bottom: 4px;
  height: 10px;
  background: var(--magenta);
  opacity: 0.18;
  z-index: -1;
  border-radius: 2px;
}

/* Floating kana scattered in hero */
.kana-flecks {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: -1;
  opacity: 0.5;
}
.kana-flecks span {
  position: absolute;
  font-family: 'Noto Sans JP', serif;
  color: var(--ink);
  opacity: 0.06;
  user-select: none;
}

/* Intro card */
.intro {
  margin: 0 auto 35px;
  max-width: 580px;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 28px;
  align-items: start;
  padding: 22px 24px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 6px;
  box-shadow: 0 1px 0 rgba(0,0,0,0.02);
}
.intro .clock {
  font-family: 'JetBrains Mono', monospace;
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  padding: 12px 14px;
  text-align: center;
  min-width: 88px;
  background: var(--bg);
}
.intro .clock .num {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
  line-height: 1;
}
.intro .clock .lbl {
  font-size: 10px;
  letter-spacing: 0.2em;
  color: var(--muted);
  text-transform: uppercase;
  margin-top: 6px;
}
.intro .copy {
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink-2);
  text-wrap: pretty;
}
.intro .copy .small {
  display: block;
  margin-top: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.04em;
}

/* Cards */
.cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}
@media (max-width: 760px) {
  .cards { grid-template-columns: 1fr; }
}
.card {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  padding: 28px 26px 24px;
  text-decoration: none;
  color: inherit;
  display: block;
  overflow: hidden;
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
  min-height: 320px;
  box-shadow: 4px 4px 0 0 var(--ink);
}
.card:hover {
  transform: translate(-2px, -2px);
  box-shadow: 6px 6px 0 0 var(--ink);
}
.card:active {
  transform: translate(2px, 2px);
  box-shadow: 0 0 0 0 var(--ink);
}
.card .num {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--muted);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.card .num .badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--paper);
  font-size: 10px;
  padding-left: 1px;
  font-weight: 700;
}
.card.c1 .badge { background: var(--coral); }
.card.c2 .badge { background: var(--cyan); color: var(--paper); }
.card .arrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  color: var(--muted);
  transition: transform 0.18s ease, color 0.18s ease;
}
.card:hover .arrow {
  color: var(--ink);
  transform: translateX(4px);
}
.card h2 {
  font-family: 'Inter', sans-serif;
  font-weight: 700;
  font-size: 32px;
  letter-spacing: -0.02em;
  line-height: 1.05;
  margin: 18px 0 6px;
}
.card .sub {
  font-size: 14px;
  color: var(--muted);
  line-height: 1.5;
  margin: 0 0 22px;
  max-width: 32ch;
}
.card .art {
  position: relative;
  height: 130px;
  border-top: 1px dashed var(--line-strong);
  margin-top: 14px;
  padding-top: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.card .meta {
  position: absolute;
  top: 14px; right: 18px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.2em;
  color: var(--muted);
  text-transform: uppercase;
}

/* Card 1: kana grid teaser */
.kana-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 6px;
  width: 100%;
}
.kana-grid .cell {
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'Noto Sans JP', serif;
  font-size: 20px;
  color: var(--ink);
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 4px;
  transition: background 0.4s ease, color 0.4s ease;
}
.kana-grid .cell.hot {
  background: rgba(242, 201, 76, 0.22);
  border-color: #f2c94c;
  color: #b8901f;
}

/* Card 2: transcribe teaser */
.transcribe {
  width: 100%;
  text-align: center;
  position: relative;
}
.transcribe .word {
  font-family: 'Noto Sans JP', serif;
  font-size: 34px;
  letter-spacing: 0.04em;
  margin-bottom: 15px;
  color: var(--ink);
  line-height: 1;
}
.transcribe .word .typed { color: var(--coral); }
.transcribe .input {
  margin: 12px auto 0;
  width: 75%;
  height: 32px;
  border: 1px solid var(--line-strong);
  border-radius: 18px;
  display: flex;
  align-items: center;
  padding: 0 14px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--ink-2);
  background: var(--bg);
  justify-content: center;
}
.transcribe .input .caret {
  display: inline-block;
  width: 1px; height: 14px;
  background: var(--ink);
  margin-left: 2px;
  animation: blink 1s steps(1) infinite;
}
@keyframes blink {
  50% { opacity: 0; }
}

/* ================================================================
   Learn Kana
   ================================================================ */

.memorize-frame .glyph { font-family: 'Noto Sans JP', serif; }

.controls {
  display: flex; justify-content: space-between; align-items: center;
  margin: 48px 0 28px; gap: 14px; flex-wrap: wrap;
}

/* Kana row table */
.row-table {
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  overflow: hidden;
}
.row-line {
  display: grid;
  grid-template-columns: 36px repeat(5, 1fr);
  gap: 0;
  align-items: stretch;
  border-bottom: 1px solid var(--line);
  transition: background 0.12s ease;
  cursor: pointer;
}
.row-line:last-child { border-bottom: none; }
.row-line:hover { background: var(--bg); }
.row-line.derived { background: rgba(27,26,34,0.025); }
.row-line.derived:hover { background: var(--bg); }
.row-line.prior { background: var(--accent-soft); }
.row-line.selected { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.row-line.custom-selected { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.row-line .lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 700;
  color: var(--muted);
  letter-spacing: 0.08em;
  display: flex; align-items: center; justify-content: center;
  border-right: 1px solid var(--line);
}
.row-line .glyph {
  text-align: center;
  padding: 14px 4px;
  font-family: 'Noto Sans JP', serif;
  font-size: 28px;
  color: var(--ink);
  border-right: 1px solid var(--line);
  line-height: 1;
}
.row-line .glyph.combo { font-size: 24px; }
.row-line .glyph .r {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--muted);
  margin-top: 5px;
  letter-spacing: 0.06em;
}
.row-line .glyph.empty { color: transparent; cursor: default; }
.row-line .count {
  display: flex; align-items: center; justify-content: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--muted);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.row-line.prior .glyph { color: var(--accent); }
.row-line.prior .glyph .r { color: var(--accent); opacity: 0.75; }
.row-line.selected .glyph,
.row-line.custom-selected .glyph { color: var(--accent); }
.row-line.selected .glyph .r,
.row-line.custom-selected .glyph .r { color: var(--accent); opacity: 0.85; }
.row-line.prior .count,
.row-line.selected .count,
.row-line.custom-selected .count { color: var(--accent); }

/* Locked rows: dimmed, not clickable. Hover/click affordances are
   suppressed because the row can't be selected until the previous row
   is cleared with zero mistakes. A single banner (.row-lock-banner) is
   inserted above the first locked row to explain the unlock condition;
   subsequent locked rows stay quiet so the message doesn't repeat. */
.row-line.locked {
  cursor: not-allowed;
  background: repeating-linear-gradient(
    135deg,
    rgba(27,26,34,0.02) 0 6px,
    rgba(27,26,34,0.05) 6px 12px
  );
}
.row-line.locked:hover { background: repeating-linear-gradient(
    135deg,
    rgba(27,26,34,0.02) 0 6px,
    rgba(27,26,34,0.05) 6px 12px
  ); }
.row-line.locked .glyph,
.row-line.locked .glyph .r,
.row-line.locked .lbl { color: var(--muted); opacity: 0.55; }
.row-line.locked .glyph.empty { opacity: 1; }
/* Banner inserted above the first locked row. Sits between two row-line
   elements, full width of the table, with the same diagonal-stripe
   background so it visually belongs to the locked region below it. */
.row-lock-banner {
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
  background: repeating-linear-gradient(
    135deg,
    rgba(27,26,34,0.02) 0 6px,
    rgba(27,26,34,0.05) 6px 12px
  );
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: center;
  line-height: 1.4;
}

/* End-screen action grid + tip.
   Default state ("Next row" available): three equal-width buttons, the
   third (Next row) is the primary black CTA, the first two are paper-tone
   secondary. When `try-again-primary` is on the grid (gated next-row),
   "Try again" promotes to the black primary and "Next row" goes muted. */
.done-actions {
  margin-top: 28px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 12px;
}
.done-action-secondary {
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--line-strong);
}
.done-action-secondary:hover { background: var(--bg); }
.done-actions.try-again-primary .done-action-secondary.is-primary-action {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
.done-actions.try-again-primary .done-action-secondary.is-primary-action:hover {
  background: #414141;
}
#doneNextBtn.is-locked,
#doneNextBtn:disabled {
  background: var(--paper);
  color: var(--muted);
  border: 1px dashed var(--line-strong);
  opacity: 0.65;
  cursor: not-allowed;
  transform: none;
}
.done-tip {
  margin-top: 14px;
  padding: 12px 14px;
  border: 1px dashed var(--line-strong);
  border-radius: 6px;
  background: var(--bg);
  color: var(--muted);
  font-family: 'Inter', sans-serif;
  font-size: 13px;
  line-height: 1.5;
  text-align: center;
}
.done-tip-link {
  background: transparent;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--ink);
  font-weight: 600;
  text-decoration: underline;
  cursor: pointer;
}
.done-tip-link:hover { color: var(--accent); }

/* Section divider for combos */
.combo-divider {
  padding: 20px;
  font-family: 'Poppins', 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.22em;
  color: var(--ink);
  text-transform: uppercase;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
  text-align: center;
}

/* Memorize state */
.mem-stack { display: grid; gap: 28px; }
.memorize-frame {
  border: 1px solid var(--ink);
  border-radius: 6px;
  background: var(--paper);
  padding: 28px 24px 24px;
  position: relative;
}
.memorize-frame .label {
  position: absolute;
  top: -10px; left: 50%; transform: translateX(-50%);
  background: var(--yellow);
  color: var(--ink);
  padding: 2px 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  white-space: nowrap;
  border: 1px solid var(--accent);
}
.memorize-frame .row {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 14px;
  text-align: center;
}
.memorize-frame .row.combo-row { grid-template-columns: repeat(3, 1fr); }
.memorize-frame .glyph {
  font-size: 64px;
  color: var(--ink);
  line-height: 1;
}
.memorize-frame .glyph.combo { font-size: 52px; }
.memorize-frame .glyph .r {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--muted);
  margin-top: 10px;
  letter-spacing: 0.16em;
}

.also-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.28em;
  color: var(--muted);
  text-transform: uppercase;
  margin: 28px 0 14px;
}
.also-grid {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 6px;
}
@media (max-width: 760px) { .also-grid { grid-template-columns: repeat(6, 1fr); } }
.also-grid .kanacell { font-size: 18px; padding: 8px 2px 10px; }
.also-grid .kanacell.combo { font-size: 14px; }

/* Quiz state */
.quiz-card {
  position: relative;
  overflow: visible;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  padding: 40px 24px 32px;
  text-align: center;
  box-shadow: 4px 4px 0 0 var(--ink);
}

/* ========== Tape-label slap FX (correct / wrong / skip) ========== */
.fx-tape-slap {
  position: absolute;
  top: 22px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  padding: 4px 10px;
  border: 1.5px solid var(--ink);
  box-shadow: 2px 2px 0 0 var(--ink);
  pointer-events: none;
  opacity: 0;
  z-index: 6;
  white-space: nowrap;
  border-radius: 5px;
}
.fx-tape-slap.correct {
  left: -220px;
  background: #2EAA6E;
  color: var(--paper);
  transform: rotate(-5deg);
}
.fx-tape-slap.wrong {
  right: -220px;
  background: #ff4747;
  color: var(--paper);
  transform: rotate(5deg);
}
.fx-tape-slap.skip {
  right: -220px;
  background: var(--accent);
  color: var(--paper);
  transform: rotate(5deg);
}
.fx-tape-slap.correct.show { animation: fx-slap-l 540ms cubic-bezier(0.18,0.89,0.32,1.28) forwards; }
.fx-tape-slap.wrong.show   { animation: fx-slap-r 540ms cubic-bezier(0.18,0.89,0.32,1.28) forwards; }
.fx-tape-slap.skip.show    { animation: fx-slap-r 540ms cubic-bezier(0.18,0.89,0.32,1.28) forwards; }
@keyframes fx-slap-l {
  0%   { opacity: 0; left: -220px; transform: rotate(-22deg) scale(1.5); }
  40%  { opacity: 1; left: 22px;   transform: rotate(-3deg)  scale(1.05); }
  60%  { opacity: 1; left: 22px;   transform: rotate(-6deg)  scale(0.97); }
  100% { opacity: 1; left: 22px;   transform: rotate(-5deg)  scale(1); }
}
@keyframes fx-slap-r {
  0%   { opacity: 0; right: -220px; transform: rotate(22deg) scale(1.5); }
  40%  { opacity: 1; right: 22px;   transform: rotate(3deg)  scale(1.05); }
  60%  { opacity: 1; right: 22px;   transform: rotate(6deg)  scale(0.97); }
  100% { opacity: 1; right: 22px;   transform: rotate(5deg)  scale(1); }
}

/* card shakes only on a real fail */
.quiz-card.fx-card-shake,
.word-card.fx-card-shake { animation: fx-card-shake 340ms ease forwards; }
@keyframes fx-card-shake {
  0%, 100% { transform: translateX(0) rotate(0); }
  20%      { transform: translateX(-8px) rotate(-0.6deg); }
  40%      { transform: translateX(8px)  rotate(0.4deg); }
  60%      { transform: translateX(-5px) rotate(-0.3deg); }
  80%      { transform: translateX(4px)  rotate(0.2deg); }
}
.quiz-card .glyph {
  font-family: 'Noto Sans JP', serif;
  font-size: 110px;
  color: var(--ink);
  line-height: 1;
  margin: 16px 0 8px;
}
.quiz-card .glyph.combo { font-size: 92px; }
.quiz-card .correct-answer {
  font-family: 'JetBrains Mono', monospace;
  font-size: 20px;
  color: var(--muted);
  letter-spacing: 0.18em;
  height: 32px;
  opacity: 0;
  margin-top: 32px;
  margin-bottom: 18px;
  transition: opacity 0.15s ease;
}
.quiz-card .correct-answer.visible { opacity: 1; }
.quiz-input {
  width: 100%;
  max-width: 320px;
  margin: 0 auto;
  display: block;
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 14px 22px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 16px;
  text-align: center;
  color: var(--ink);
  outline: none;
  transition: border-color 0.15s ease, background 0.2s ease;
}
.quiz-input:focus { border-color: var(--ink); }
.quiz-input:disabled,
.quiz-input.is-locked {
  border-color: var(--line-strong);
  background: rgba(15, 14, 19, 0.04);
  color: var(--muted);
  cursor: not-allowed;
  opacity: 0.5;
}
/* Flash classes are declared AFTER :disabled so they keep visual priority
   when the input is disabled mid-animation (e.g. the green confirm flash). */
.quiz-input.flash-correct { border-color: #2EAA6E; background: rgba(46,170,110,0.08); color: #2EAA6E; }
.quiz-input.flash-wrong { background: rgba(var(--accent-rgb), 0.08); }
.quiz-input.shake { animation: shake 0.35s ease; }

.quiz-skip {
  margin-top: 18px;
  display: flex; justify-content: center; align-items: center; gap: 10px;
  flex-wrap: wrap;
}
.quiz-skip .hint {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--muted);
  text-transform: uppercase;
}

/* ============================================================
   Shared "under the input" controls used by all three games.
   Desktop: keyboard hints only (physical keyboard is the input).
   Mobile:  Skip button only (no physical keyboard, no hints to give).
   ============================================================ */
.kbd-hints {
  margin-top: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 22px;
  flex-wrap: wrap;
}
.kbd-hint {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
}
.kbd-key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 26px;
  height: 26px;
  padding: 0 7px;
  border: 1.5px solid var(--ink);
  border-bottom-width: 3px;
  border-radius: 5px;
  background: var(--paper);
  font-family: 'Inter', sans-serif;
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: 0;
  line-height: 1;
  transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}
/* "Press me" pulse — used on the continue-key after a wrong / skip reveal. */
.kbd-key.is-pulse {
  animation: kbd-pulse 1.1s ease-in-out infinite;
}
@keyframes kbd-pulse {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 1);
  }
  50% {
    box-shadow: 0 0 0 9px rgba(var(--accent-rgb), 0);
  }
}

.quiz-actions {
  margin-top: 14px;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

/* Desktop: keyboard does the work — hide the touch buttons. */
@media (min-width: 721px) {
  .quiz-actions { display: none; }
}
/* Mobile: no physical keyboard — hide the keyboard hints. */
@media (max-width: 720px) {
  .kbd-hints { display: none; }
}
.btn-ghost.next-word-state {
  background: var(--accent);
  color: var(--paper);
  border-color: var(--accent);
  animation: nextpulse 1.2s ease-in-out infinite;
}
@keyframes nextpulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(var(--accent-rgb), 0.5); }
  50%      { box-shadow: 0 0 0 6px rgba(var(--accent-rgb), 0); }
}

.progressbar {
  height: 2px;
  background: var(--line);
  margin: 20px 0 30px;
  position: relative;
  overflow: hidden;
}
.progressbar .fill {
  position: absolute; left: 0; top: 0; height: 100%;
  background: var(--ink);
  transition: width 0.3s ease;
}

.hud-pop { animation: pop 0.2s ease; }
@keyframes pop {
  0% { transform: scale(1); }
  50% { transform: scale(1.18); }
  100% { transform: scale(1); }
}

/* Done state */
.weak-section { margin-top: 28px; }
.weak-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}
@media (max-width: 600px) { .weak-list { grid-template-columns: 1fr; } }
.weak-item {
  display: flex; align-items: center; justify-content: space-between;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 10px 14px;
}
.weak-item .left {
  display: flex; align-items: baseline; gap: 10px;
}
.weak-item .jp {
  font-family: 'Noto Sans JP', serif;
  font-size: 22px;
  color: var(--ink);
  line-height: 1;
}
.weak-item .ro {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.1em;
}
.weak-item .badges {
  display: flex; gap: 4px;
}
.weak-item .badge {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 3px 7px;
  border-radius: 3px;
}
.weak-item .badge.wrong { background: rgba(var(--accent-rgb), 0.16); color: var(--accent); }
.weak-item .badge.skip { background: rgba(27,26,34,0.08); color: var(--ink-2); }

/* ================================================================
   Read Kana
   ================================================================ */

/* Big choice cards — kana picker */
.kana-pick {
  display: grid; grid-template-columns: 1fr 1fr; gap: 14px;
  margin-bottom: 28px;
}
.kana-pick button {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  padding: 22px 14px 16px;
  cursor: pointer;
  text-align: center;
  transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
}
/* Tiny "?" tucked in the corner — opens the syllabary's reading-rules lesson.
   Stops propagation in JS so a click here never selects the syllabary. */
.kana-pick-help {
  position: absolute;
  top: 8px; right: 8px;
  width: 26px; height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  color: var(--muted);
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  padding: 0;
  line-height: 1;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.12s ease;
}
.kana-pick-help:hover {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
  transform: scale(1.08);
}
.kana-pick button.on .kana-pick-help {
  border-color: var(--accent);
  color: var(--accent);
}
.kana-pick button.on .kana-pick-help:hover {
  background: var(--accent);
  color: var(--paper);
}
.kana-pick button .glyph {
  display: block;
  font-family: 'Noto Sans JP', serif;
  font-size: 56px;
  line-height: 1;
  color: var(--ink);
  margin-bottom: 12px;
}
.kana-pick button .lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.22em;
  color: var(--muted);
  text-transform: uppercase;
}
.kana-pick button.on {
  border-color: var(--cyan);
  background: var(--accent-soft);
  box-shadow: 4px 4px 0 0 var(--cyan);
  transform: translate(-2px,-2px);
}
.kana-pick button.on .glyph { color: var(--accent); }
.kana-pick button.on .lbl { color: var(--accent); }

/* Time chooser */
.time-row {
  display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 32px;
}
.time-row button {
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 8px 18px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.16em;
  color: var(--ink-2);
  cursor: pointer;
  transition: all 0.12s ease;
}
.time-row button.on {
  border-color: var(--cyan);
  color: var(--accent);
  background: var(--accent-soft);
}

.field-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
}

.ganbatte {
  text-align: center;
  margin-top: 56px;
  font-family: 'Noto Sans JP', serif;
  font-size: 14px;
  color: var(--muted);
  letter-spacing: 0.2em;
  opacity: 0.6;
}

/* Play state */
.play-stats { display: grid; grid-template-columns: repeat(3, 1fr); }
.play-stats .stat .lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: center;
  margin-bottom: 4px;
}
.play-stats .stat .val {
  font-family: 'JetBrains Mono', monospace;
  font-size: 28px;
  font-weight: 500;
  color: var(--ink);
  text-align: center;
  line-height: 1;
}
.play-stats .stat.coral .val { color: var(--accent); }
.play-stats .stat.muted .val { color: var(--ink-2); opacity: 0.8 }
.play-stats .stat.yellow .val { color: #B8901F; }
.play-stats .stat.magenta .val { color: var(--magenta); }
.play-stats .stat.warning .val { color: var(--ink); animation: pulse 0.8s ease-in-out infinite; }

.play-progress {
  height: 2px;
  background: var(--line-strong);
  margin: 20px 0 30px;
  position: relative;
  overflow: hidden;
}
.play-progress .fill {
  position: absolute; left: 0; top: 0; height: 100%;
  background: var(--ink);
  transition: width 0.3s linear;
}

.word-card {
  position: relative;
  overflow: visible;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  padding: 40px 24px 32px;
  text-align: center;
  box-shadow: 4px 4px 0 0 var(--ink);
}
.word-card .word {
  font-family: 'Noto Sans JP', serif;
  font-size: 86px;
  color: var(--ink);
  letter-spacing: 0.04em;
  line-height: 1;
  margin: 0;
}
.word-card .word .typed { color: var(--accent); opacity: 0.45; }
.word-card .romaji-hint {
  font-family: 'JetBrains Mono', monospace;
  font-size: 16px;
  color: var(--accent);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  margin-top: 12px;
  opacity: 0;
  transition: opacity 0.2s ease;
}
.word-card.show-hint .romaji-hint { opacity: 1; }

.play-input {
  width: 100%;
  max-width: 320px;
  margin: 36px auto 0;
  display: block;
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 14px 22px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 16px;
  text-align: center;
  color: var(--ink);
  outline: none;
  transition: border-color 0.15s ease, background 0.2s ease;
}
.play-input:focus { border-color: var(--ink); }
.play-input:disabled,
.play-input.is-locked {
  border-color: var(--line-strong);
  background: rgba(15, 14, 19, 0.04);
  color: var(--muted);
  cursor: not-allowed;
  opacity: 0.5;
}
.play-input.shake { animation: shake 0.35s ease; }

.play-skip {
  display: flex; justify-content: center; align-items: center; gap: 10px;
  margin-top: 18px;
}
.play-skip .hint {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--muted);
  text-transform: uppercase;
}

/* Floating ghosted kana behind the play area */
.play-flecks {
  position: fixed; inset: 64px 0 0 0;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
}
.play-flecks span {
  position: absolute;
  font-family: 'Noto Sans JP', serif;
  color: var(--ink);
  opacity: 0.04;
  user-select: none;
}

/* Results state */
.results-card {
  text-align: center;
  padding: 36px 24px 28px;
}
.results-card .big {
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 600;
  font-size: 56px;
  color: var(--ink);
  line-height: 1;
  letter-spacing: -0.02em;
}
.results-card .big .accent { color: var(--accent); }
.results-card .sub {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.22em;
  color: var(--muted);
  text-transform: uppercase;
  margin-top: 8px;
}

.results-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  margin: 32px 0 0;
  border-top: 1px solid var(--line);
  padding-top: 24px;
}
.results-stats .stat .lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: center;
  margin-bottom: 6px;
}
.results-stats .stat .val {
  font-family: 'JetBrains Mono', monospace;
  font-size: 26px;
  font-weight: 500;
  color: var(--ink);
  text-align: center;
  line-height: 1;
}
.results-stats .stat.coral .val { color: var(--accent); }
.results-stats .stat.yellow .val { color: #B8901F; }
.results-stats .stat.magenta .val { color: var(--magenta); }

/* English translation reveal under the word (transcribe.twig logic) */
.word-card .word-translation {
  font-family: 'Inter', sans-serif;
  font-weight: 400;
  font-size: 18px;
  color: var(--muted);
  margin-top: 20px;
  letter-spacing: 0.7px;
  opacity: 0;
}
.word-card.show-translation .word-translation { opacity: 1; }

/* Flash on correct (green), wrong (red), skip (themed accent) */
.play-input.flash-correct {
  border-color: #2EAA6E;
  background: rgba(46,170,110,0.10);
  color: #2EAA6E;
}
.play-input.flash-wrong {
  border-color: #ff4747;
  background: rgba(255,71,71,0.12);
  color: #ff4747;
  animation: shake 0.35s ease;
}
.play-input.flash-skip {
  border-color: var(--accent);
  background: rgba(var(--accent-rgb), 0.14);
  color: var(--accent);
}

/* Skip button transformed to "Next word" after a reveal */
.btn-ghost.reveal-state {
  background: var(--accent);
  color: var(--paper);
  border-color: var(--accent);
  animation: nextpulse 1.2s ease-in-out infinite;
}
/* Red treatment when the reveal was triggered by a wrong answer
   (mirrors Learn Kana's .btn-ghost.next-word-state.is-fail). The
   --accent-rgb override turns the keyframed nextpulse halo red too. */
.btn-ghost.reveal-state.is-fail {
  background: #ff4747;
  border-color: #ff4747;
  --accent-rgb: 255, 71, 71;
}

/* Timer-bar danger state (last 10s) */
.play-progress .fill.danger { animation: pulse 0.8s ease-in-out infinite; }

/* HUD score pop on correct */
.play-stats .stat .val.pop { animation: pop 0.2s ease; }

/* "New best score!" badge */
.best-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 14px;
  padding: 5px 12px;
  background: var(--yellow);
  color: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 999px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 700;
  transform: rotate(-1deg);
}
.best-badge svg { width: 12px; height: 12px; }

/* Skipped / missed list at end */
.missed-section { margin-top: 28px; }
.missed-list {
  display: grid;
  gap: 6px;
}
.missed-item {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 14px;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 10px 14px;
}
.missed-item .missed-jp {
  font-family: 'Noto Sans JP', serif;
  font-size: 22px;
  color: var(--ink);
  line-height: 1;
}
.missed-item .missed-romaji {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  color: var(--accent);
  letter-spacing: 0.1em;
}
.missed-item .missed-en {
  font-family: 'Inter', sans-serif;
  font-size: 13px;
  color: var(--muted);
  text-align: right;
}

/* ================================================================
   Coachmark tutorial (shared by Learn Kana, Read Kana, Final Test,
   and the Home tour). Spotlight + tip + arrow nub.
   ================================================================ */
.coach-spotlight {
  position: absolute;
  border-radius: 8px;
  background: transparent;
  box-shadow: 0 0 0 9999px rgba(15, 14, 19, 0.62);
  z-index: 200;
  pointer-events: auto;
  transition: top 0.32s ease, left 0.32s ease, width 0.32s ease, height 0.32s ease;
  display: none;
  outline: 2px solid rgba(255, 255, 255, 0.3);
  outline-offset: 4px;
}
.coach-spotlight.active { display: block; }
/* On the magenta page the white outline disappears against the paper highlight,
   so trade it for the page accent. */
body.theme-magenta .coach-spotlight { outline-color: var(--accent); }

.coach-tip {
  position: absolute;
  z-index: 201;
  background: var(--paper);
  border: 1px solid var(--ink);
  border-radius: 8px;
  box-shadow: 6px 6px 0 0 var(--ink);
  padding: 18px 20px 14px;
  width: 320px;
  max-width: calc(100vw - 32px);
  display: none;
  animation: tipPop 0.22s cubic-bezier(0.18, 0.89, 0.32, 1.28);
}
.coach-tip.active { display: block; }
@keyframes tipPop {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.coach-tip .step-num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.28em;
  color: var(--accent);
  text-transform: uppercase;
  margin-bottom: 8px;
}
.coach-tip h3 {
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 600;
  font-size: 18px;
  color: var(--ink);
  margin: 0 0 8px;
  letter-spacing: -0.01em;
}
.coach-tip p {
  font-size: 14px;
  line-height: 1.55;
  color: var(--ink-2);
  margin: 0 0 14px;
}
.coach-tip kbd {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  padding: 1px 5px;
  border: 1px solid var(--line-strong);
  border-radius: 3px;
  background: var(--bg);
  color: var(--ink-2);
}
.coach-tip .actions {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
}
.coach-tip .actions .right { display: flex; gap: 6px; }
.coach-tip button {
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 6px 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-2);
  cursor: pointer;
  transition: all 0.15s ease;
}
.coach-tip .c-skip { border-color: transparent; color: var(--muted); }
.coach-tip .c-skip:hover { color: var(--ink); }
.coach-tip .c-prev:not([disabled]):hover { border-color: var(--ink); color: var(--ink); }
.coach-tip .c-next {
  background: var(--ink); color: var(--paper); border-color: var(--ink);
}
.coach-tip .c-next:hover { transform: translate(-1px, -1px); box-shadow: 2px 2px 0 0 var(--accent); }
.coach-tip button[disabled] { opacity: 0.3; cursor: not-allowed; }

.coach-tip::before {
  content: '';
  position: absolute;
  width: 12px; height: 12px;
  background: var(--paper);
  border-left: 1px solid var(--ink);
  border-top: 1px solid var(--ink);
  transform: rotate(45deg);
}
.coach-tip[data-pos="below"]::before { top: -7px; left: 28px; }
.coach-tip[data-pos="above"]::before {
  bottom: -7px; left: 28px;
  border: none;
  border-right: 1px solid var(--ink); border-bottom: 1px solid var(--ink);
}

/* ================================================================
   Home page — extras (postal-stamp intro, 3-card layout, Final-test
   teaser, community stats panel, stats marquee variant).
   The base .intro / .cards / .ribbon styles live further up.
   ================================================================ */
.intro.intro-stamp {
  max-width: 720px;
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 36px;
  align-items: center;
  padding: 8px 16px 16px;
  background: transparent;
  border: none;
  box-shadow: none;
}

.seal-wrap {
  position: relative;
  width: 220px; height: 220px;
  color: #cec9c2;
  transform: rotate(-9deg);
  flex-shrink: 0;
}
.seal-rim {
  width: 100%; height: 100%;
  display: block;
  animation: seal-spin 80s linear infinite;
  transform-origin: 50% 50%;
}
.seal-rim circle, .seal-rim text { opacity: 0.92; }

.seal-core {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center;
  pointer-events: none;
}
.seal-num {
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 700;
  font-size: 76px;
  color: var(--ink);
  line-height: 0.85;
  letter-spacing: -0.04em;
}
.seal-h {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 700; font-size: 13px;
  letter-spacing: 0.32em;
  color: var(--ink);
  margin-top: 4px;
}
.seal-divider {
  width: 60px; height: 1px;
  background: #cec9c2;
  opacity: 0.55;
  margin: 8px 0 6px;
}
.seal-bottom {
  font-family: 'JetBrains Mono', monospace;
  font-size: 8px;
  letter-spacing: 0.28em;
  color: #9d978d;
  text-transform: uppercase;
  opacity: 0.7;
}

.seal-copy {
  font-size: 15px; line-height: 1.55;
  color: var(--ink-2);
}
.seal-copy .seal-eyebrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.3em;
  color: var(--muted);
  text-transform: uppercase;
  margin-bottom: 12px;
}
.seal-copy h3 {
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 700; font-size: 24px;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 0 0 10px;
  line-height: 1.30;
  text-wrap: balance;
}
.seal-copy p { margin: 0 0 6px; }
.seal-copy strong { color: var(--ink); }
.seal-copy .small {
  display: block;
  margin-top: 12px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.04em;
}

@keyframes seal-spin {
  to { transform: rotate(360deg); }
}

@media (max-width: 680px) {
  .intro.intro-stamp {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
    gap: 20px;
  }
  .postmark-lines { display: none; }
}

/* 3-card layout — Step 1, Step 2, Final test */
.cards.cards-3 {
  grid-template-columns: 1fr 1fr 1fr;
  gap: 16px;
}
@media (max-width: 980px) {
  .cards.cards-3 { grid-template-columns: 1fr; }
}

.card.c3 .badge { background: var(--magenta); color: var(--paper); }

/* Final-test teaser art: a single glyph with a draining timer bar */
.clear-preview {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 18px 0;
}
.clear-glyph {
  font-family: 'Noto Sans JP', serif;
  font-size: 54px;
  line-height: 1;
  color: var(--ink);
  letter-spacing: -0.02em;
}
.clear-timer {
  width: 78%;
  height: 4px;
  background: rgba(0, 0, 0, 0.15);
  border-radius: 999px;
  overflow: hidden;
}
.clear-timer-fill {
  height: 100%;
  width: 100%;
  background: var(--magenta);
  border-radius: 999px;
  transform-origin: left center;
  animation: clear-drain 5s linear infinite;
}
@keyframes clear-drain {
  0%   { transform: scaleX(1);   background: var(--magenta); }
  100% { transform: scaleX(0);   background: var(--magenta); }
}

/* Community stats panel under the seal copy */
.seal-stats {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px dashed var(--line-strong);
}
.ss-title {
  margin: 0 0 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.ss-live {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: 'JetBrains Mono', monospace;
  font-weight: 700;
  font-size: 9px;
  letter-spacing: 0.22em;
  color: var(--green);
  text-transform: uppercase;
  padding: 2px 7px 2px 6px;
}
.ss-live-dot {
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--green);
  animation: ss-pulse 2.2s ease-out infinite;
  margin-right: 4px;
  margin-top: -2px;
}
@keyframes ss-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(55, 169, 116, 0.55); }
  70%  { box-shadow: 0 0 0 6px rgba(55, 169, 116, 0); }
  100% { box-shadow: 0 0 0 0 rgba(55, 169, 116, 0); }
}

.ss-grid {
  display: flex;
  align-items: stretch;
  gap: 8px;
  flex-wrap: wrap;
}
.ss-stat {
  flex: 1 1 0;
  min-width: 110px;
  position: relative;
  padding: 10px 12px 10px 14px;
  background: #FAF6EC;
  border-radius: 4px;
  overflow: hidden;
  border: 1px solid #eae6e0;
}

.ss-num {
  display: block;
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 700;
  font-size: 24px;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  margin-top: 3px;
  margin-bottom: 5px;
}
.ss-lbl {
  display: block;
  margin-top: 4px;
  font-family: 'JetBrains Mono', monospace;
  font-weight: 600;
  font-size: 9px;
  letter-spacing: 0.16em;
  color: var(--muted);
  text-transform: uppercase;
  white-space: nowrap;
}

@media (max-width: 680px) {
  .ss-grid { gap: 6px; }
  .ss-stat { min-width: 0; padding: 9px 10px 9px 12px; }
  .ss-num { font-size: 20px; }
}

/* Stats variant of the kana ribbon (home only) */
.ribbon.ribbon-stats .marquee-track span.stat-item {
  margin-right: 18px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.ribbon.ribbon-stats .marquee-track span.stat-item b {
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin-right: 6px;
  font-variant-numeric: tabular-nums;
  text-transform: none;
}
.ribbon.ribbon-stats .marquee-track span.stat-sep {
  margin-right: 18px;
  color: var(--muted);
  font-weight: 700;
}

/* ================================================================
   Learn Kana — extras
   ================================================================ */

/* Memorize-frame label variant when arriving via the "Next row" button */
.memorize-frame .label.is-new {
  background: var(--accent);
  color: var(--bg);
}

/* Custom-mode memorize: compact list (one row per line) instead of giant frames */
.custom-row-list {
  display: grid;
  gap: 10px;
}
.custom-row {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 14px;
  align-items: center;
  background: var(--paper);
  border: 1px solid var(--accent);
  border-radius: 6px;
  padding: 10px 14px 12px;
  box-shadow: 3px 3px 0 0 var(--accent);
}
.custom-row .row-label {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  text-align: center;
  padding-right: 14px;
  border-right: 1px solid var(--line);
}
.custom-row .row-label .count {
  display: block;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.16em;
  color: var(--muted);
  margin-top: 4px;
}
.custom-row .chars {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: baseline;
}
.custom-row .chars .glyph {
  font-family: 'Noto Sans JP', serif;
  font-size: 30px;
  line-height: 1;
  color: var(--ink);
  text-align: center;
}
.custom-row .chars .glyph.combo { font-size: 24px; }
.custom-row .chars .glyph .r {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  color: var(--muted);
  margin-top: 4px;
  letter-spacing: 0.06em;
}

/* Next-word button: yellow accent by default (skip), red on a real fail.
   Re-feeds --accent-rgb so the keyframed nextpulse halo turns red. */
.btn-ghost.next-word-state.is-fail {
  background: #ff4747;
  border-color: #ff4747;
  --accent-rgb: 255, 71, 71;
}

/* ================================================================
   Final Test — extras (per-kana timer, ready gate, ink stamps,
   gate seal, intro prose, warning strip, debug button)
   ================================================================ */

/* Per-kana timer bar (5s drain) */
.timerbar {
  height: 6px;
  background: rgba(232, 74, 138, 0.15);
  border-radius: 999px;
  margin: 18px 0 8px;
  position: relative;
  overflow: hidden;
}
.timerbar .fill {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 100%;
  background: var(--magenta);
  border-radius: 999px;
  transform-origin: left center;
  transition: background 0.2s linear;
}
.timerbar .fill.warn   { background: var(--magenta); }
.timerbar .fill.danger { background: #ff4747; }

/* Final Test pushes the input down so the timer bar has room above it */
body.theme-magenta .quiz-input { margin-top: 80px; }

/* Pre-roll gate: heavy blur over the card until Enter */
.ready-gate {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 10;
  border-radius: 6px;
  background: rgba(255, 252, 244, 0.35);
  backdrop-filter: blur(16px) saturate(0.9);
  -webkit-backdrop-filter: blur(16px) saturate(0.9);
  cursor: pointer;
  user-select: none;
}
.ready-gate.active { display: flex; }
.ready-gate-text {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: var(--ink);
  color: var(--paper);
  border: none;
  border-radius: 6px;
  font-family: 'Inter', sans-serif;
  font-weight: 600;
  font-size: 16px;
  box-shadow: 4px 4px 0 0 rgba(0, 0, 0, 0.2);
  padding: 16px 28px;
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
  width: 100%;
  letter-spacing: 0.01em;
  max-width: 280px;
}
.ready-gate .sub {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 400;
  opacity: 0.6;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* Ink stamps — FAILED / PASSED slammed onto the card */
.ink-stamp {
  position: absolute;
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 700;
  font-size: 20px;
  letter-spacing: 0.18em;
  padding: 8px 16px 10px;
  border-width: 5px;
  border-style: double;
  border-radius: 6px;
  text-transform: uppercase;
  pointer-events: none;
  user-select: none;
  line-height: 1;
  z-index: 7;
  text-shadow: 0 0 1px currentColor;
  opacity: 0;
}
.ink-stamp.show {
  animation: stamp-slam 600ms cubic-bezier(0.18, 0.89, 0.32, 1.28) forwards;
}
.ink-stamp .sub {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.2em;
  margin-top: 6px;
  opacity: 0.85;
  color: var(--muted);
}
.ink-stamp.failed {
  color: #d92121;
  border-color: #d92121;
  transform: rotate(-9deg) scale(2);
}
.ink-stamp.passed {
  color: #2EAA6E;
  border-color: #2EAA6E;
  transform: rotate(-7deg) scale(2);
}
@keyframes stamp-slam {
  0%   { opacity: 0; transform: rotate(0deg) scale(3); }
  60%  { opacity: 1; }
  100% { opacity: 0.92; }
}
.ink-stamp.failed.show { animation: stamp-slam-failed 400ms forwards; }
@keyframes stamp-slam-failed {
  0%   { opacity: 0; transform: rotate(0deg) scale(3); }
  100% { opacity: 0.92; transform: rotate(-9deg) scale(1); }
}
.ink-stamp.passed.show { animation: stamp-slam-passed 600ms cubic-bezier(0.18, 0.89, 0.32, 1.28) forwards; }
@keyframes stamp-slam-passed {
  0%   { opacity: 0; transform: rotate(0deg) scale(3); }
  100% { opacity: 0.92; transform: rotate(-7deg) scale(1); }
}

/* Fail screen — extends the regular results card */
.fail-card { position: relative; }
.fail-card .ink-stamp.failed {
  top: 24px;
  right: 18px;
}
.fail-card .results-stats .stat .val.failed-glyph {
  font-family: 'Noto Sans JP', serif;
  color: #d92121;
  font-size: 32px;
  line-height: 1;
}
.fail-card .results-stats .stat .val.failed-glyph .ro {
  display: block;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.18em;
  color: #d92121;
  margin-top: 8px;
}
.fail-card .results-stats .stat .val.failed-glyph .reason {
  display: none;
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.22em;
  color: #d92121;
  margin-top: 4px;
  text-transform: uppercase;
}

/* "The gate" — dramatic seal-style intro ring with a 0→208 counter */
.gate {
  position: relative;
  width: 340px; height: 340px;
  margin: 18px auto 38px;
  color: var(--ink-2);
}
.gate-rim {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
}
.gate-rim.outer { animation: gate-spin 70s linear infinite; transform-origin: 50% 50%; }
.gate-rim.inner {
  width: 240px; height: 240px;
  inset: auto;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  animation: gate-spin-rev 110s linear infinite;
  transform-origin: 50% 50%;
}
.gate-rim.inner circle { stroke: var(--magenta); opacity: 0.55; }
.gate-rim text { fill: var(--ink-2); opacity: 0.85; }

@keyframes gate-spin {
  to { transform: rotate(360deg); }
}
@keyframes gate-spin-rev {
  from { transform: translate(-50%, -50%) rotate(0deg); }
  to   { transform: translate(-50%, -50%) rotate(-360deg); }
}

/* Concentric pulsing ring behind the glyph — heartbeat */
.gate-pulse {
  position: absolute;
  inset: 70px;
  border: 2px solid var(--magenta);
  border-radius: 50%;
  opacity: 0.18;
  pointer-events: none;
  animation: gate-pulse 2.4s ease-in-out infinite;
}
.gate-pulse.delay { animation-delay: 1.2s; opacity: 0.10; }
@keyframes gate-pulse {
  0%, 100% { transform: scale(0.92); opacity: 0.10; }
  50%      { transform: scale(1.06); opacity: 0.42; }
}

.gate-core {
  position: absolute;
  inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  pointer-events: none;
  text-align: center;
}
.gate-glyph {
  font-family: 'Noto Sans JP', serif;
  font-size: 70px;
  line-height: 1;
  color: var(--ink);
  letter-spacing: -0.02em;
  margin-bottom: 12px;
  /* fade-on-swap is handled in JS via opacity toggling */
  transition: opacity 0.05s linear;
}
.gate-counter {
  display: flex; flex-direction: column;
  align-items: center; gap: 4px;
}
.gate-counter .num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 24px;
  font-weight: 700;
  color: var(--magenta);
  letter-spacing: 0.04em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.gate-counter .num .slash { color: var(--muted); margin: 0 6px; font-weight: 400; }
.gate-counter .num .total { color: var(--ink); }
.gate-counter .num.locked { animation: counter-lock 600ms ease-out 1; }
@keyframes counter-lock {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.18); color: var(--ink); }
  100% { transform: scale(1); }
}
.gate-counter .lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 9px;
  letter-spacing: 0.32em;
  color: var(--muted);
  text-transform: uppercase;
}

/* Tiny corner ticks — "targeting reticle" framing */
.gate-tick {
  position: absolute;
  width: 14px; height: 14px;
  border: 1px solid var(--magenta);
  opacity: 0.5;
}
.gate-tick.tl { top: 0;    left: 0;    border-right: none; border-bottom: none; }
.gate-tick.tr { top: 0;    right: 0;   border-left: none;  border-bottom: none; }
.gate-tick.bl { bottom: 0; left: 0;    border-right: none; border-top: none; }
.gate-tick.br { bottom: 0; right: 0;   border-left: none;  border-top: none; }

/* Intro prose — no card; centred dramatic copy */
.intro-prose {
  text-align: center;
  font-family: 'Inter', sans-serif;
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 45ch;
  margin: 0 auto 30px;
  text-wrap: pretty;
}
.intro-prose p { margin: 0 0 12px; }
.intro-prose strong.flame { color: var(--magenta); }
.intro-prose .whisper {
  margin-top: 16px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  letter-spacing: 0.26em;
  color: var(--muted);
  text-transform: uppercase;
}

/* Warning strip — three monolithic numbers, replaces marquee ribbon */
.warning-strip {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  border-top: 1px solid var(--line-strong);
  border-bottom: 1px solid var(--line-strong);
  margin-top: 70px;
  background:
    repeating-linear-gradient(
      45deg,
      transparent 0 14px,
      rgba(232, 74, 138, 0.04) 14px 28px
    );
}
.warning-cell {
  text-align: center;
  padding: 22px 12px 20px;
  border-right: 1px dashed var(--line-strong);
  position: relative;
}
.warning-cell:last-child { border-right: none; }
.warning-cell .num {
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 700;
  font-size: 38px;
  color: var(--ink);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.warning-cell .num .unit {
  font-size: 18px;
  color: var(--muted);
  font-weight: 500;
  margin-left: 1px;
}
.warning-cell .lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.24em;
  color: var(--muted);
  text-transform: uppercase;
  margin-top: 10px;
}
.warning-cell.beat .num   { color: var(--magenta); animation: beat 1.4s ease-in-out infinite; transform-origin: center; }
.warning-cell.danger .num { color: #d92121; }
.warning-cell.danger::after {
  content: "";
  position: absolute;
  inset: 6px;
  background:
    repeating-linear-gradient(-45deg,
      transparent 0 6px,
      rgba(217, 33, 33, 0.05) 6px 12px);
  pointer-events: none;
}
@keyframes beat {
  0%, 70%, 100% { transform: scale(1); }
  8%  { transform: scale(1.10); }
  16% { transform: scale(0.96); }
  24% { transform: scale(1.06); }
  34% { transform: scale(1); }
}

.start-cta { position: relative; }

@media (max-width: 760px) {
  .gate { width: 280px; height: 280px; }
  .gate-rim.inner { width: 200px; height: 200px; }
  .gate-glyph { font-size: 52px; }
  .warning-cell .num { font-size: 28px; }
  .warning-cell .num .unit { font-size: 14px; }
}

/* ================================================================
   Diploma page — vertically-centered single column, certificate
   card with holo/foil hover, ink seal, dp-* button family.
   Body opt-in: <body class="diploma-body ...">
   ================================================================ */
body.diploma-body { display: flex; flex-direction: column; }

.diploma-page {
  max-width: 880px;
  margin: 0 auto;
  padding: 48px 24px;
  width: 100%;
  box-sizing: border-box;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.dp-state { display: none; }
.dp-state.active { display: block; }

/* Diploma fades in once the data arrives */
#dp-diploma { opacity: 0; transition: opacity 0.55s ease; }
#dp-diploma.is-ready { opacity: 1; }

/* Locked state */
.dp-locked {
  text-align: center;
  padding: 80px 24px;
  margin-top: -60px;
}
.dp-locked .lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; letter-spacing: 0.3em;
  color: var(--muted);
  text-transform: uppercase;
  margin-bottom: 18px;
}
.dp-locked h1 {
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 700; font-size: 32px;
  margin: 0 0 14px; letter-spacing: -0.02em;
}
.dp-locked p {
  color: var(--muted); font-size: 15px; max-width: 46ch;
  margin: 0 auto 28px; line-height: 1.6;
}
.dp-locked-actions { display: inline-flex; gap: 12px; flex-wrap: wrap; justify-content: center; position: relative; }

.dp-btn {
  display: inline-block;
  padding: 14px 22px;
  border-radius: 6px;
  font: 600 14px 'Inter', sans-serif;
  letter-spacing: -0.01em;
  text-decoration: none;
  cursor: pointer;
  border: 1px solid var(--ink);
  transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
}
.dp-btn-primary { background: var(--ink); color: var(--paper); box-shadow: 4px 4px 0 0 var(--ink); }
.dp-btn-primary:hover { background: var(--magenta); border-color: var(--magenta); transform: translate(-2px, -2px); box-shadow: 6px 6px 0 0 var(--ink); }
.dp-btn-secondary { background: var(--paper); color: var(--ink); box-shadow: 4px 4px 0 0 var(--ink); }
.dp-btn-secondary:hover { transform: translate(-2px, -2px); box-shadow: 6px 6px 0 0 var(--ink); }
.dp-btn[disabled] { opacity: 0.6; cursor: wait; }

/* Diploma card — flexible sizing, content-driven height */
.diploma-wrap {
  display: flex;
  justify-content: center;
  perspective: 1600px;
}
.diploma {
  position: relative;
  background: var(--paper);
  width: 100%;
  max-width: 720px;
  padding: 56px 56px 44px;
  border: 2px solid var(--ink);
  border-radius: 6px;
  overflow: hidden;
  box-sizing: border-box;
  --diploma-edge: rgba(15, 14, 19, 0.45);
  display: flex;
  flex-direction: column;
}
.diploma::before {
  content: ""; position: absolute; inset: 12px;
  border: 1px solid var(--diploma-edge);
  border-radius: 2px; pointer-events: none;
}
.diploma::after {
  content: ""; position: absolute; inset: 19px;
  border: 1px dashed rgba(232, 74, 138, 0.32);
  border-radius: 2px; pointer-events: none;
}
.diploma .corner-flourish {
  position: absolute;
  font-family: 'Noto Sans JP', serif;
  font-size: 78px;
  color: var(--magenta);
  opacity: 0.07;
  line-height: 1;
  pointer-events: none; user-select: none;
}
.diploma .corner-flourish.tl { top: 24px; left: 30px; }
.diploma .corner-flourish.br { bottom: 24px; right: 30px; }

.diploma-eyebrow {
  text-align: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 0.36em;
  color: var(--muted);
  text-transform: uppercase;
  margin-bottom: 14px;
}
.diploma-title {
  text-align: center;
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 700; font-size: 38px;
  letter-spacing: -0.01em;
  margin: 0 0 6px;
  color: var(--ink); line-height: 1.05;
}
.diploma-subtitle {
  text-align: center;
  font-family: 'Noto Sans JP', serif;
  font-size: 17px; color: var(--magenta);
  letter-spacing: 0.4em; margin-bottom: 22px;
}
.diploma-rule {
  width: 50%; height: 0;
  margin: 0 auto 18px; border: none;
  border-top: 1px solid rgba(15, 14, 19, 0.35);
  position: relative;
}
.diploma-rule::after {
  content: "✦"; position: absolute;
  top: -10px; left: 50%; transform: translateX(-50%);
  background: var(--paper); color: var(--magenta);
  padding: 0 10px; font-size: 13px;
}
.diploma-text {
  text-align: center;
  font-family: 'Noto Sans JP', 'Inter', serif;
  font-size: 14px; line-height: 1.65;
  color: var(--ink-2);
  margin: 18px auto 14px;
  max-width: 56ch;
}
.diploma-name {
  text-align: center;
  font-family: 'Caveat', 'Poppins', cursive;
  font-weight: 700; font-size: 56px;
  color: var(--ink); line-height: 1.05;
  margin: 6px 0 16px; letter-spacing: 0;
}
.diploma-name .underline { display: inline-block; padding: 0 26px 4px; }

.diploma-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin: 22px auto 14px;
  max-width: 100%;
}
.diploma-stats .stat-cell {
  position: relative; text-align: center;
  background: var(--bg);
  border: 1.5px solid var(--ink);
  border-radius: 4px;
  padding: 12px 8px 10px;
}
.diploma-stats .stat-cell .val {
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 700; font-size: 22px;
  color: var(--ink); line-height: 1;
  letter-spacing: -0.01em;
}
.diploma-stats .stat-cell .lbl {
  font-family: 'JetBrains Mono', monospace;
  font-size: 8px; letter-spacing: 0.22em;
  color: var(--muted); text-transform: uppercase;
  margin-top: 6px;
  line-height: 1.3;
}
@media (max-width: 520px) {
  .diploma-stats { grid-template-columns: repeat(2, 1fr); }
}

.diploma-footer {
  margin-top: 32px;
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: end; gap: 18px;
  padding-top: 16px;
}
.diploma-footer .sig-block, .diploma-footer .date-block { text-align: center; }
.diploma-footer .signature {
  font-family: 'Caveat', cursive;
  font-weight: 700; font-size: 34px;
  color: var(--ink); line-height: 1;
  margin-bottom: 2px; letter-spacing: 0.5px;
  transform: rotate(-2deg);
}
.diploma-footer .sig-line, .diploma-footer .date-line {
  height: 1px; background: rgba(15, 14, 19, 0.4);
  margin: 6px 12% 8px;
}
.diploma-footer .sig-label, .diploma-footer .date-label {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--muted);
}
.diploma-footer .date-day {
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 600; font-size: 15px; color: var(--ink);
}
.diploma-footer .date-time {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: var(--muted);
  letter-spacing: 0.12em; margin-top: 2px;
}

/* Mini ink-seal in the footer */
.diploma-seal {
  position: relative; width: 110px; height: 110px;
  color: #cec9c2; transform: rotate(-7deg); flex-shrink: 0;
}
.diploma-seal-rim {
  width: 100%; height: 100%; display: block;
  animation: diploma-seal-spin 100s linear infinite;
  transform-origin: 50% 50%;
}
.diploma-seal-rim circle, .diploma-seal-rim text { opacity: 0.92; }
.diploma-seal-core {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  text-align: center; pointer-events: none;
}
.diploma-seal-core .glyph {
  font-family: 'Noto Sans JP', serif;
  font-size: 26px; color: var(--magenta);
  line-height: 0.95; letter-spacing: -0.02em;
}
.diploma-seal-core .lbl {
  font-family: 'JetBrains Mono', monospace;
  font-weight: 700; font-size: 8px;
  letter-spacing: 0.28em; color: var(--magenta);
  margin-top: 3px;
}
.diploma-seal-core .divider {
  width: 26px; height: 1px;
  background: #cec9c2; opacity: 0.55;
  margin: 4px 0 3px;
}
.diploma-seal-core .bottom {
  font-family: 'JetBrains Mono', monospace;
  font-size: 6px; letter-spacing: 0.24em;
  color: #9d978d; text-transform: uppercase;
  opacity: 0.7;
}
@keyframes diploma-seal-spin { to { transform: rotate(360deg); } }

/* 3D tilt + holo shimmer on hover. --tx/--ty are pushed by JS on pointermove. */
@property --tx { syntax: "<number>"; inherits: false; initial-value: 0; }
@property --ty { syntax: "<number>"; inherits: false; initial-value: 0; }
.diploma {
  --tx: 0; --ty: 0;
  --gx: calc(70% - var(--tx) * 40%);
  --gy: calc(30% + var(--ty) * 40%);
  transform: rotateX(calc(var(--ty) * -10deg))
             rotateY(calc(var(--tx) *  10deg));
  will-change: transform;
  transition: transform 0.05s linear;
}
.diploma-holo, .diploma-glare, .diploma-foil {
  position: absolute; inset: 0;
  pointer-events: none; border-radius: inherit;
  opacity: 0.55; transition: opacity 0.6s ease;
}
.diploma-holo {
  z-index: 5; mix-blend-mode: color-dodge;
  background:
    radial-gradient(ellipse 70% 100% at var(--gx) var(--gy),
      hsla(50, 100%, 88%, 0.60) 0%, hsla(45, 100%, 65%, 0.45) 18%,
      hsla(32, 95%, 55%, 0.28) 38%, transparent 65%),
    linear-gradient(calc(115deg + var(--tx) * 30deg),
      transparent 0%, hsla(45, 100%, 70%, 0.20) 22%,
      hsla(32, 100%, 60%, 0.32) 35%, hsla(50, 100%, 88%, 0.32) 48%,
      hsla(28, 100%, 55%, 0.32) 60%, hsla(45, 100%, 70%, 0.20) 75%,
      transparent 100%);
}
.diploma-glare {
  z-index: 6; mix-blend-mode: soft-light;
  background: radial-gradient(circle at var(--gx) var(--gy),
    rgba(255, 235, 180, 0.70) 0%, rgba(255, 220, 150, 0.22) 14%, transparent 38%);
}
.diploma-foil {
  z-index: 4; mix-blend-mode: overlay;
  background: repeating-linear-gradient(calc(115deg + var(--tx) * 20deg),
    rgba(255, 220, 150, 0.08) 0px, rgba(255, 220, 150, 0.08) 1px,
    transparent 1px, transparent 7px);
}
.diploma:hover .diploma-holo,
.diploma:hover .diploma-glare,
.diploma:hover .diploma-foil,
.diploma.is-tilting .diploma-holo,
.diploma.is-tilting .diploma-glare,
.diploma.is-tilting .diploma-foil { opacity: 1; }

/* First-time arrival: gentle pop-in */
@keyframes dp-arrive {
  0%   { opacity: 0; transform: translateY(40px) scale(0.85); }
  60%  { opacity: 1; transform: translateY(-6px) scale(1.02); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}
.diploma-wrap.is-arriving { animation: dp-arrive 1.1s cubic-bezier(0.34, 1.4, 0.64, 1) both; }

.dp-actions {
  margin-top: 28px;
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
  position: relative;
}

/* Snapshot mode: freeze the diploma flat for clean image capture */
.diploma.is-snapshot {
  transform: none !important;
  transition: none !important;
}
.diploma.is-snapshot .diploma-holo,
.diploma.is-snapshot .diploma-glare,
.diploma.is-snapshot .diploma-foil { display: none; }
.diploma.is-snapshot .diploma-seal-rim { animation: none !important; }

/* ================================================================
   Lesson modal — used by Read Kana to teach reading rules that
   aren't in the gojūon table (sokuon, chōonpu, extended combos).
   Two flavours: a multi-slide lesson, and a soft-block "nudge"
   shown the first time a player launches a syllabary they haven't
   read the lesson for.
   ================================================================ */
.lesson-overlay {
  position: fixed; inset: 0;
  z-index: 220;
  display: flex; align-items: center; justify-content: center;
  background: rgba(15, 14, 19, 0.55);
  padding: 20px;
  animation: lesson-fade 0.18s ease;
}
.lesson-overlay[hidden] { display: none; }
@keyframes lesson-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.lesson-modal {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--ink);
  border-radius: 8px;
  box-shadow: 8px 8px 0 0 var(--ink);
  width: 100%;
  max-width: 540px;
  max-height: calc(100vh - 40px);
  display: flex;
  flex-direction: column;
  animation: lesson-pop 0.22s cubic-bezier(0.18, 0.89, 0.32, 1.28);
}
@keyframes lesson-pop {
  from { opacity: 0; transform: translateY(12px) scale(0.96); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.lesson-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px 12px;
  border-bottom: 1px solid var(--line);
  gap: 12px;
}
.lesson-eyebrow {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.28em;
  color: var(--accent);
  text-transform: uppercase;
}
.lesson-close {
  background: transparent;
  border: none;
  font-size: 24px;
  line-height: 1;
  color: var(--muted);
  cursor: pointer;
  padding: 0 4px;
  transition: color 0.15s ease, transform 0.12s ease;
}
.lesson-close:hover { color: var(--ink); transform: scale(1.1); }

.lesson-progress {
  height: 2px;
  background: var(--line);
  position: relative;
  overflow: hidden;
}
.lesson-progress .bar {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: var(--accent);
  transition: width 0.3s ease;
}

.lesson-body {
  padding: 22px 24px 18px;
  overflow-y: auto;
  flex: 1;
}
.lesson-body h3 {
  font-family: 'Poppins', 'Inter', sans-serif;
  font-weight: 600;
  font-size: 22px;
  margin: 0 0 12px;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.lesson-body p {
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--ink-2);
  margin: 0 0 14px;
}
.lesson-body p:last-child { margin-bottom: 0; }
.lesson-body strong { color: var(--ink); }
.lesson-body em {
  font-style: normal;
  background: rgba(var(--accent-rgb), 0.18);
  color: var(--accent);
  padding: 1px 5px;
  border-radius: 3px;
  font-weight: 600;
}

/* Example block: kana → romaji → english breakdown */
.lesson-example {
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  padding: 14px 16px;
  margin: 14px 0;
  display: grid;
  gap: 10px;
}
.lesson-example .row {
  display: grid;
  grid-template-columns: minmax(80px, auto) auto 1fr;
  gap: 14px;
  align-items: baseline;
}
.lesson-example .jp {
  font-family: 'Noto Sans JP', serif;
  font-size: 26px;
  color: var(--ink);
  line-height: 1;
}
.lesson-example .jp .small {
  color: var(--accent);
  font-weight: 700;
}
.lesson-example .ro {
  font-family: 'JetBrains Mono', monospace;
  font-size: 13px;
  letter-spacing: 0.08em;
  color: var(--ink-2);
}
.lesson-example .ro b {
  color: var(--accent);
  font-weight: 700;
}
.lesson-example .en {
  font-size: 13px;
  color: var(--muted);
  font-style: italic;
}

/* Construction list — used by the extended-combos slides to show how
   each compound kana is built. Two stacked rows per entry: the kana
   construction up top (large), the romaji + example below (small). */
.lesson-combo-list {
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  padding: 14px 16px;
  margin: 14px 0;
  display: grid;
  gap: 14px;
}
.lesson-combo-row { display: grid; gap: 4px; }
.lesson-combo-row .combo-jp {
  font-family: 'Noto Sans JP', serif;
  font-size: 24px;
  color: var(--ink);
  line-height: 1;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}
.lesson-combo-row .combo-jp .op {
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  color: var(--muted);
  font-weight: 400;
  margin: 0 2px;
}
.lesson-combo-row .combo-jp .res {
  color: var(--accent);
  font-weight: 700;
}
.lesson-combo-row .combo-ro {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--muted);
}
.lesson-combo-row .combo-ro b {
  color: var(--accent);
  font-weight: 700;
}
.lesson-combo-row .combo-ro .ex {
  margin-left: 8px;
  font-style: italic;
  color: var(--muted);
  letter-spacing: 0;
}

.lesson-callout {
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  border-radius: 0 4px 4px 0;
  padding: 10px 14px;
  margin: 14px 0 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink-2);
}

.lesson-foot {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 20px 16px;
  border-top: 1px solid var(--line);
  gap: 12px;
}
.lesson-step {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  letter-spacing: 0.22em;
  color: var(--muted);
  text-transform: uppercase;
}
.lesson-actions {
  display: flex; gap: 8px;
}
.lesson-foot .btn-primary {
  width: auto;
  padding: 10px 22px;
  font-size: 13px;
}


.lesson-foot .btn-ghost {
  border-radius: 5px;
  font-family: "Inter";
  letter-spacing: 0;
  font-weight: 600;
  text-transform: inherit;
  font-size: 13px;
}

#nudgeSkip {
  font-size: 13px;
  font-weight: 300;
}

/* Nudge variant: small soft-block shown on first launch */
.lesson-modal.lesson-nudge { max-width: 460px; }
.lesson-nudge .lesson-body { padding: 28px 28px 18px; }
.lesson-nudge .lesson-foot { border-top: none; padding: 8px 28px 24px; justify-content: flex-end; }
.lesson-nudge .lesson-eyebrow { color: var(--accent); }

/* ================================================================
   Mobile-only responsive tweaks (consolidated)
   Breakpoint: 720px to match the existing mobile/desktop split that
   toggles .quiz-actions vs .kbd-hints.
   ================================================================ */
@media (max-width: 720px) {
  /* (1) reg-marks: drop the fixed positioning so they flow at the
     bottom of the page instead of overlaying content. */
  .reg-marks {
    position: relative;
    bottom: auto; left: auto;
    margin: 28px auto 18px;
    justify-content: center;
    flex-wrap: wrap;
  }

  /* (4) Memorize-frame glyphs shrink so longer rows fit comfortably
     on a phone-width column. */
  .memorize-frame .glyph { font-size: 50px; }
  .memorize-frame .glyph.combo { font-size: 42px; }

  /* (6) Quiz / Word card — about 20% smaller in height so the kana
     and the input both stay above the on-screen keyboard. The fx tape
     slaps rest at left: -220px / right: -220px (off-screen, opacity 0)
     and animate inward; on mobile that off-screen layout box can push
     the iOS layout viewport wider than the visual viewport, which
     produces the few-pixel horizontal scroll. Clipping the cards
     constrains the slap layout box to the card itself. The cards' own
     box-shadow lives outside the border-box so it stays visible. */
  .quiz-card,
  .word-card { overflow: hidden; }
  .quiz-card { padding: 22px 18px 22px; }
  .quiz-card .glyph { font-size: 62px; margin: 8px 0 4px; }
  .quiz-card .glyph.combo { font-size: 68px; }
  .quiz-card .correct-answer { font-size: 16px; height: 24px; margin-top: 18px; margin-bottom: 10px; }
  .quiz-card .quiz-input { margin-top: 6px; }

  .word-card { padding: 22px 18px 22px; }
  .word-card .word { font-size: 48px; margin-top: 20px; letter-spacing: 0 }
  .word-card .romaji-hint { font-size: 14px; margin-top: 8px; margin-bottom: 15px; }
  .word-card .word-translation { font-size: 16px; margin-top: 12px; }
  .word-card .play-input { margin-top: 22px; }

  /* (9) Smaller floating "← Home" button + extra page top padding so
     the button doesn't cover the page heading. */
  .back-link {
    top: 22px; left: 14px;
    padding: 10px 15px;
    font-size: 10px;
  }
  .page { padding-top: 60px; }
  /* Hide the home button (and the burger menu) while a quiz state is
     active. .page padding-top tightens to 30px so the quiz card sits as
     high as possible — the user-visible area is constrained by the OS
     keyboard so every pixel above the input matters. :has() is supported
     by every mobile browser we target (iOS Safari 15.4+, Chrome 105+);
     older browsers fall through to "always shown", which is harmless. */
  body:has(#state-quiz.active) .back-link,
  body:has(#state-play.active) .back-link,
  body:has(#state-quiz.active) .lk-burger-slot,
  body:has(#state-play.active) .lk-burger-slot { display: none; }
  body:has(#state-quiz.active) .page,
  body:has(#state-play.active) .page { padding-top: 30px; }

  /* (10) Done / results title — 40px max so it doesn't overflow the
     card on narrow viewports. */
  .results-card .big { font-size: 40px; }

  /* (11) Stack the bottom action buttons on the end-screen instead of
     squeezing 3 columns. The layout uses inline grid-template-columns
     on the wrapper, so we override at the parent of .btn-primary
     groups inside any end-screen state. */
  #state-done > div[style*="grid-template-columns"],
  #state-results > div[style*="grid-template-columns"],
  #state-fail > div[style*="grid-template-columns"] {
    grid-template-columns: 1fr !important;
  }

  /* (12) Hide the right-hand "selected meta" caption in Learn Kana — it
     duplicates info already on screen and crowds the row. */
  #selectionMeta { display: none; }

  /* (5) Inline confirm button on the answer input. The button is
     overlaid on the right edge so it visually feels like part of the
     pill input. */
  .quiz-input-wrap {
    position: relative;
    width: 100%;
    max-width: 320px;
    margin: 0 auto;
    display: block;
  }
  .quiz-input-wrap .quiz-input,
  .quiz-input-wrap .play-input {
    width: 100%;
    max-width: none;
    margin: 0;
  }
  .quiz-input-confirm {
    position: absolute;
    top: 50%;
    right: 4px;
    transform: translateY(-50%);
    height: calc(100% - 8px);
    min-width: 52px;
    padding: 0 14px;
    border: none;
    background: var(--ink);
    color: var(--paper);
    border-radius: 999px;
    font-family: 'JetBrains Mono', monospace;
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
  }
  .quiz-input-confirm:active { transform: translateY(-50%) scale(0.96); }
  .quiz-input-confirm[disabled] { opacity: 0.5; cursor: not-allowed; }
}

/* (5) Confirm button is mobile-only — hide on desktop. */
@media (min-width: 721px) {
  .quiz-input-confirm { display: none; }
}

/* (2) Mobile burger menu — replaces the floating stats card and friends
   button on small viewports. The menu items themselves are injected by
   learnkana-api.js; this just provides layout, animation, and the
   responsive show/hide rules. */
.lk-burger-slot { display: none; }
.lk-home-logo { display: none; }
@media (max-width: 720px) {
  /* Hide the original floating widgets on mobile. */
  .lk-slot { display: none !important; }
  .lk-friends-slot { display: none !important; }

  .lk-burger-slot {
    display: block;
    position: fixed;
    top: 14px;
    right: 14px;
    z-index: 30;
    font-family: 'Inter', system-ui, sans-serif;
    /* Constrain the slot to the burger button's footprint and clip the
       translated-off-screen items so they can't push the iOS layout
       viewport wider than the visual viewport. The shadow on the menu
       items is small enough to live inside this padding. */
    width: 44px;
  }
  .lk-burger-items { overflow: visible; }
  .lk-burger-btn {
    width: 44px;
    height: 44px;
    border-radius: 10px;
    background: var(--paper);
    border: 1px solid var(--line-strong);
    box-shadow: 4px 4px 0 0 var(--ink);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    color: var(--ink);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
    position: relative;
  }
  .lk-burger-btn:active {
    transform: translate(2px, 2px);
    box-shadow: 0 0 0 0 var(--ink);
  }
  /* Logged-out state: the burger is replaced by a single login button.
     Re-uses the burger button's box styling and just sizes the SVG. */
  .lk-burger-login svg { width: 20px; height: 20px; display: block; color: var(--ink); }
  .lk-burger-icon, .lk-burger-icon::before, .lk-burger-icon::after {
    content: "";
    display: block;
    width: 18px;
    height: 2px;
    background: var(--ink);
    border-radius: 2px;
    transition: transform 0.28s cubic-bezier(0.65, 0, 0.35, 1),
                opacity 0.2s ease, top 0.28s ease;
  }
  .lk-burger-icon {
    position: relative;
  }
  .lk-burger-icon::before,
  .lk-burger-icon::after {
    position: absolute;
    left: 0;
  }
  .lk-burger-icon::before { top: -6px; }
  .lk-burger-icon::after  { top:  6px; }
  .lk-burger-slot.is-open .lk-burger-icon { background: transparent; }
  .lk-burger-slot.is-open .lk-burger-icon::before {
    top: 0; transform: rotate(45deg);
  }
  .lk-burger-slot.is-open .lk-burger-icon::after {
    top: 0; transform: rotate(-45deg);
  }

  /* Notification dot — appears on the burger button when there's a
     pending friend invite to surface, mirroring the existing badge. */
  .lk-burger-dot {
    position: absolute;
    top: -4px; right: -4px;
    width: 12px; height: 12px;
    border-radius: 50%;
    background: var(--magenta, #E84A8A);
    border: 2px solid var(--paper);
    box-sizing: border-box;
  }

  .lk-burger-items {
    position: absolute;
    top: calc(100% + 10px);
    right: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
    pointer-events: none;
  }
  .lk-burger-item {
    width: 44px; height: 44px;
    border-radius: 10px;
    background: var(--paper);
    border: 1px solid var(--line-strong);
    box-shadow: 4px 4px 0 0 var(--ink);
    color: var(--ink);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 0;
    /* Closed-state rest position: tucked up behind the burger button
       and shrunk. We use translateY + scale (no translateX) on purpose
       — translateX past the viewport edge would push the iOS layout
       viewport wider, breaking the page. */
    transform: translateY(-30px) scale(0.7);
    opacity: 0;
    transition: transform 0.42s cubic-bezier(0.34, 1.56, 0.64, 1),
                opacity 0.22s ease;
    position: relative;
    pointer-events: none;
  }
  .lk-burger-item svg { width: 20px; height: 20px; display: block; }
  .lk-burger-item .lk-burger-item-badge {
    position: absolute;
    top: -6px; right: -6px;
    min-width: 18px; height: 18px;
    padding: 0 5px;
    background: var(--magenta, #E84A8A);
    color: var(--paper);
    border-radius: 999px;
    font: 700 10px 'JetBrains Mono', monospace;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 2px solid var(--paper);
    box-sizing: border-box;
  }

  .lk-burger-slot.is-open .lk-burger-items { pointer-events: auto; }
  .lk-burger-slot.is-open .lk-burger-item {
    transform: translateY(0) scale(1);
    opacity: 1;
    pointer-events: auto;
  }
  /* Stagger so items sling in one after another. */
  .lk-burger-slot.is-open .lk-burger-item:nth-child(1) { transition-delay: 0.04s; }
  .lk-burger-slot.is-open .lk-burger-item:nth-child(2) { transition-delay: 0.14s; }
  /* When closing, reverse the order so the bottom one leaves first. */
  .lk-burger-slot:not(.is-open) .lk-burger-item:nth-child(1) { transition-delay: 0.10s; }
  .lk-burger-slot:not(.is-open) .lk-burger-item:nth-child(2) { transition-delay: 0.02s; }
}

/* Mobile-only layout extras (eyebrow trim, end-screen tweaks, viewport-
   bottom reg-marks). */
@media (max-width: 720px) {
  /* (Hero) trim the eyebrow row to just "learnkana.gg" — the
     ひらがな / カタカナ flanks crowd narrow viewports. */
  .hero { margin: 0 0 15px; }
  .hero .eyebrow .eyebrow-kana { display: none; }
  /* Hero headline needs a bit more line-height on mobile so accents
     (em underline) don't crash into the next line. */
  .hero h1 { line-height: 1.15; }

  /* Seal block on the homepage: the spinning rim is too big to look
     good on a phone, and the heading is bolder than necessary on a
     small screen. */
  .seal-wrap { display: none; }
  .seal-copy h3 { font-weight: 600; margin-bottom: 20px; }

  /* Homepage mobile logo — mirrors the burger button on the right
     (top: 14px, ~48px square) but lives in the document flow so it
     scrolls away naturally rather than tracking the viewport. */
  .lk-home-logo {
    display: inline-block;
    position: absolute;
    top: 14px;
    left: 14px;
    z-index: 5;
    width: 48px;
    height: 48px;
    border-radius: 10px;
    overflow: hidden;
    line-height: 0;
  }
  .lk-home-logo img {
    width: 100%;
    height: 100%;
    display: block;
  }

  /* End-screen results — extra page top padding so the title clears
     the home button, and tighter stat labels so they don't wrap on
     three columns. */
  body:has(#state-done.active) .page,
  body:has(#state-results.active) .page,
  body:has(#state-fail.active) .page { padding-top: 80px; }
  .results-stats .stat .lbl,
  .results-card .stat .lbl,
  .statrow .stat .lbl,
  .play-stats .stat .lbl {
    font-size: 10px;
    letter-spacing: 0.1em;
  }

  /* (1 cont.) reg-marks should sit at the bottom of the viewport on
     short pages and at the bottom of the content on long pages — never
     fixed/sticky. Rather than turning body into a flex container
     (which broke the .page max-width on small screens), we just give
     <main> a min-height so it fills the viewport minus the reg-marks
     row. Then on short pages the reg-marks naturally land at the
     viewport bottom; on long pages they sit below the content as
     normal. */
  body.grid-on > main.page { min-height: calc(100vh - 80px); }
  .kana-flecks { opacity: 0 }
  .statrow .stat .val, .play-stats .stat .val { font-size: 24px; }
  .setup-head .crumb-row {
    margin-top: 15px;
  }
}
