:root {
  --bg: #0a0a0a;
  --bg-card: #131313;
  --bg-card-hover: #1c1c1c;
  --border: #262626;
  --text: #e5e5e5;
  --text-dim: #888;
  --text-faint: #8a8a8a;
  --accent: #4A9EDB;
  --accent-dim: #003356;
  --error: #ef4444;
  --success: #4A9EDB;
  --grade-again: #ef4444;
  --grade-hard: #f59e0b;
  --grade-easy: #06b6d4;
  /* How much bigger handwriting (ktav yad) renders than the printed Hebrew it replaces. Cursive is
     the script being LEARNED, and its strokes are thinner, so it gets a little more room. One knob
     for every cursive context in the app. */
  --cursive-scale: 1.1;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
  font-family: -apple-system, 'Inter', 'Segoe UI', sans-serif;
  background: var(--bg);
  color: var(--text);
  line-height: 1.6;
  min-height: 100vh;
  padding: 26px 20px 32px;
  font-size: 17px;
}

/* Respect the OS "reduce motion" setting: kill the infinite pulses, the reveal flip, and every
   transition so nothing auto-animates for motion-sensitive users (WCAG 2.2.2 / 2.3.3). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

.container { max-width: 960px; margin: 0 auto; }

.hebrew {
  font-family: 'Frank Ruhl Libre', 'David', 'David CLM', 'Times New Roman', serif;
  direction: rtl;
}

header {
  border-bottom: 1px solid var(--border);
  padding-bottom: 20px;
  margin-bottom: 32px;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
}

h1 {
  font-size: 32px;
  font-weight: 600;
  letter-spacing: -0.3px;
}

.subtitle {
  color: var(--text-dim);
  font-size: 15px;
  text-transform: uppercase;
  letter-spacing: 1px;
}

.nav {
  display: flex;
  gap: 16px;
  font-size: 13px;
}

.nav a {
  color: var(--text-dim);
  text-decoration: none;
  transition: color 0.15s;
}

.nav a:hover, .nav a.active { color: var(--accent); }

h2 {
  font-size: 17px;
  text-transform: uppercase;
  letter-spacing: 1.5px;
  color: var(--text-dim);
  margin: 48px 0 20px;
  font-weight: 500;
}

.intro {
  color: var(--text-dim);
  font-size: 18px;
  line-height: 1.7;
  margin-bottom: 28px;
  max-width: 720px;
}

.lessons {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 16px;
  margin-bottom: 40px;
}

.lesson-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 20px;
  text-decoration: none;
  color: var(--text);
  transition: all 0.2s;
  position: relative;
}

.lesson-card:hover {
  background: var(--bg-card-hover);
  border-color: var(--accent-dim);
  transform: translateY(-1px);
}

.lesson-card .num {
  font-size: 11px;
  color: var(--accent);
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
}

.lesson-card .title-fr {
  font-size: 18px;
  font-weight: 500;
  margin: 8px 0 6px;
}

.lesson-card .title-he {
  font-size: 22px;
  color: var(--text-dim);
  font-family: 'Frank Ruhl Libre', 'David', serif;
  direction: rtl;
  line-height: 1.4;
}

.lesson-card .meta {
  margin-top: 16px;
  font-size: 13px;
  color: var(--text-faint);
}

.lesson-card .progress-dot {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--border);
}

.lesson-card .progress-dot.done { background: var(--accent); }

.grid-letters {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: 10px;
}

.letter-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 18px 12px;
  text-align: center;
  cursor: pointer;
  transition: all 0.2s;
  perspective: 600px;
  user-select: none;
}

.letter-card:hover {
  border-color: var(--accent-dim);
  background: var(--bg-card-hover);
}

.letter-card.flipped { border-color: var(--accent); }

.letter-card .he {
  font-size: 42px;
  font-family: 'Frank Ruhl Libre', 'David', serif;
  line-height: 1;
  margin-bottom: 6px;
  color: var(--text);
}

.letter-card .name {
  font-size: 13px;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 1px;
  margin-top: 8px;
  display: none;
}

.letter-card .translit {
  font-size: 12px;
  color: var(--text-dim);
  margin-top: 4px;
  display: none;
}

.letter-card .sound {
  font-size: 11px;
  color: var(--text-faint);
  margin-top: 4px;
  font-style: italic;
  display: none;
}

.letter-card.flipped .name,
.letter-card.flipped .translit,
.letter-card.flipped .sound { display: block; }

.letter-card.flipped .he { color: var(--accent); }

.word-list {
  display: grid;
  gap: 12px;
}

.word-row {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 18px 28px;
  /* Right-to-left row: the Hebrew reads from the right edge (the reading habit we want to build),
     the play + plus buttons fall to the left, and the transliteration + translation stack directly
     under the Hebrew word — same right anchor — so each line sits exactly below the word it renders.
     In an RTL grid the first column is the rightmost: 1fr content on the right, two auto button
     columns on the left. */
  direction: rtl;
  display: grid;
  grid-template-columns: 1fr auto auto;
  grid-template-areas:
    "he       plus play"
    "translit plus play"
    "fr       plus play";
  align-items: center;
  column-gap: 24px;
  row-gap: 4px;
  transition: background 0.15s;
}
/* Place by selector, not HTML source order: some lessons (mastery, batch-generated) interleave the
   play button between .he and .translit — named areas keep the layout identical everywhere. */
.word-row .icon-btn { grid-area: play; justify-self: center; }
.word-row .srs-btn  { grid-area: plus; justify-self: center; }
.word-row .he { grid-area: he; }
.word-row .translit { grid-area: translit; }
.word-row .fr { grid-area: fr; }

.srs-btn {
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-dim);
  border-radius: 50%;
  cursor: pointer;
  font-size: 0;
  font-family: inherit;
  transition: all 0.15s;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
.srs-btn::before {
  content: "";
  width: 12px;
  height: 12px;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 5v14M5 12h14' stroke='black' stroke-width='2.5' stroke-linecap='round'/></svg>") no-repeat center / contain;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 5v14M5 12h14' stroke='black' stroke-width='2.5' stroke-linecap='round'/></svg>") no-repeat center / contain;
  display: block;
}
.srs-btn:hover { border-color: var(--accent); color: var(--accent); }
.srs-btn.active {
  border-color: var(--accent);
  background: var(--accent);
  color: #fff;
}
.srs-btn.active::before {
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M5 12l5 5L20 7' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' fill='none'/></svg>") no-repeat center / contain;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M5 12l5 5L20 7' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round' fill='none'/></svg>") no-repeat center / contain;
}
html.light .srs-btn.active { color: #fff; }

.word-row:hover { background: var(--bg-card-hover); }

.word-row .he {
  /* --he-size is the single source of truth for this context's Hebrew size, in ONE place, so the
     cursive rule can derive from it instead of restating it. Media queries override the variable,
     never the font-size, which is what keeps cursive in step at every breakpoint. */
  --he-size: 36px;
  font-size: var(--he-size);
  font-family: 'Frank Ruhl Libre', 'David', serif;
  direction: rtl;
  text-align: right;
  line-height: 1.4;
}

.word-row .translit,
.word-row .fr {
  position: relative;
  cursor: pointer;
  user-select: none;
  perspective: 800px;
  min-height: 36px;
  display: flex;
  align-items: center;
  /* Latin / French read left-to-right, but the box hugs the right edge so the line sits directly
     under the right-anchored Hebrew word above it. */
  direction: ltr;
  justify-content: flex-end;
}
.word-row .translit .reveal-front,
.word-row .fr .reveal-front { text-align: right; }

.word-row .translit { font-size: 17px; color: var(--text-dim); font-style: italic; letter-spacing: 0.3px; }
.word-row .fr { font-size: 18px; }

.word-row .translit > .reveal-inner,
.word-row .fr > .reveal-inner {
  display: block;
  width: 100%;
  position: relative;
  transform-style: preserve-3d;
  transition: transform 0.5s ease;
  transform-origin: center;
}

.word-row .translit:not(.revealed) > .reveal-inner,
.word-row .fr:not(.revealed) > .reveal-inner {
  transform: rotateY(180deg);
}

.word-row .reveal-front,
.word-row .reveal-back {
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  display: block;
  padding: 8px 12px;
  border-radius: 6px;
  width: 100%;
}

.word-row .reveal-front {
  position: relative;
}

.word-row .reveal-back {
  position: absolute;
  inset: 0;
  background: var(--bg-card-hover);
  border: 1px dashed var(--border);
  color: var(--text-faint);
  font-size: 12px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  font-style: normal;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: rotateY(180deg);
}

/* Textblock reveal cards */
.tb-translit, .tb-fr {
  position: relative;
  perspective: 800px;
  cursor: pointer;
  user-select: none;
  display: inline-block !important;
  background: transparent !important;
}

.tb-translit > .reveal-inner,
.tb-fr > .reveal-inner {
  display: inline-block;
  position: relative;
  transform-style: preserve-3d;
  transition: transform 0.5s ease;
}
.tb-translit:not(.revealed) > .reveal-inner,
.tb-fr:not(.revealed) > .reveal-inner {
  transform: rotateY(180deg);
}
.tb-translit .reveal-front,
.tb-translit .reveal-back,
.tb-fr .reveal-front,
.tb-fr .reveal-back {
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  padding: 6px 12px;
  border-radius: 6px;
  display: inline-block;
}
.tb-translit .reveal-back,
.tb-fr .reveal-back {
  position: absolute;
  inset: 0;
  background: var(--bg-card-hover);
  border: 1px dashed var(--border);
  color: var(--text-faint);
  font-size: 11px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  font-style: normal;
  text-align: center;
  transform: rotateY(180deg);
}

.btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  padding: 8px 14px;
  border-radius: 3px;
  cursor: pointer;
  font-size: 12px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  transition: all 0.15s;
  font-family: inherit;
}

.btn:hover { border-color: var(--accent); color: var(--accent); }

/* Universal round play button — applies to both `<button class="btn icon-btn">`
   (early lessons) AND `<button class="icon-btn">` (mastery lessons + Tanakh).
   Exclude .srs-btn which has its own round style. */
button.icon-btn:not(.srs-btn) {
  width: 40px;
  height: 40px;
  padding: 0;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0;                /* hide ▶ unicode */
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--border);
  position: relative;
  cursor: pointer;
  font-family: inherit;
  transition: all 0.2s ease;
}
button.icon-btn:not(.srs-btn)::before {
  content: "";
  width: 12px;
  height: 12px;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M8 5v14l11-7z'/></svg>") no-repeat center / contain;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M8 5v14l11-7z'/></svg>") no-repeat center / contain;
  margin-left: 2px;            /* optical centering — triangle has visual weight on right */
}
button.icon-btn:not(.srs-btn):hover {
  border-color: var(--accent);
  background: var(--accent);
  color: #fff;
  transform: scale(1.05);
}
button.icon-btn:not(.srs-btn):active { transform: scale(0.95); }
button.icon-btn:not(.srs-btn).playing {
  border-color: var(--accent);
  background: var(--accent);
  color: #fff;
  animation: pulse-play 1.2s ease-in-out infinite;
}
@keyframes pulse-play {
  0%, 100% { box-shadow: 0 0 0 0 rgba(74, 158, 219, 0.5); }
  50%      { box-shadow: 0 0 0 6px rgba(74, 158, 219, 0); }
}
html.light button.icon-btn:not(.srs-btn):hover,
html.light button.icon-btn:not(.srs-btn).playing { color: #fff; }

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #000;
}

.btn-primary:hover {
  background: transparent;
  color: var(--accent);
}

.toolbar {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.quiz {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 32px;
  text-align: center;
  margin-top: 32px;
}

.quiz .he-display {
  font-size: 96px;
  font-family: 'Frank Ruhl Libre', 'David', serif;
  margin: 24px 0;
  color: var(--text);
  line-height: 1;
}

.quiz .options {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 8px;
  max-width: 540px;
  margin: 0 auto;
}

.quiz-option {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 14px;
  cursor: pointer;
  transition: all 0.15s;
  font-size: 14px;
  color: var(--text);
  font-family: inherit;
}

.quiz-option:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.quiz-option.correct {
  background: var(--accent-dim);
  border-color: var(--accent);
  color: var(--accent);
}

.quiz-option.wrong {
  background: rgba(239, 68, 68, 0.15);
  border-color: var(--error);
  color: var(--error);
}

.quiz .feedback {
  margin-top: 24px;
  font-size: 14px;
  min-height: 20px;
  color: var(--text-dim);
}

.quiz .score {
  position: absolute;
  top: 16px;
  right: 16px;
  font-size: 13px;
  color: var(--text-dim);
}

.quiz { position: relative; }

.section-divider {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 40px 0;
}

.tip {
  background: var(--bg-card);
  border-left: 2px solid var(--accent);
  padding: 14px 18px;
  font-size: 13px;
  color: var(--text-dim);
  margin: 20px 0;
}

.tip strong { color: var(--text); font-weight: 500; }

footer {
  margin-top: 64px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-faint);
  text-align: center;
}

.back {
  display: inline-block;
  font-size: 13px;
  color: var(--text-dim);
  text-decoration: none;
  margin-bottom: 16px;
}

.back:hover { color: var(--accent); }

.voice-banner {
  background: #1a1a0e;
  border-bottom: 1px solid #5a4a10;
  color: #eedb8a;
  padding: 14px 20px;
  font-size: 13px;
  position: sticky;
  top: 0;
  z-index: 50;
  line-height: 1.5;
}

.voice-banner-inner {
  max-width: 880px;
  margin: 0 auto;
}

.voice-banner-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 6px;
}

.voice-banner-title {
  font-weight: 600;
  font-size: 14px;
  color: #fcd34d;
}

.voice-banner-sub {
  margin-bottom: 12px;
  opacity: 0.9;
}

.voice-banner-os {
  background: rgba(0,0,0,0.25);
  border: 1px solid #3a2f10;
  border-radius: 4px;
  padding: 8px 12px;
  margin-bottom: 8px;
}

.voice-banner-os summary {
  cursor: pointer;
  font-weight: 600;
  color: #fcd34d;
  user-select: none;
  list-style: none;
  padding: 4px 0;
}

.voice-banner-os summary::-webkit-details-marker { display: none; }

.voice-banner-os summary::before {
  content: '▶';
  display: inline-block;
  margin-right: 8px;
  transition: transform 0.15s;
  font-size: 10px;
  opacity: 0.7;
}

.voice-banner-os[open] summary::before {
  transform: rotate(90deg);
}

.voice-banner-os .os-icon {
  display: inline-block;
  margin-right: 4px;
}

.voice-banner-steps {
  margin: 10px 0 8px 28px;
  padding: 0;
}

.voice-banner-steps li {
  margin: 6px 0;
}

.voice-banner-steps strong {
  color: #fcd34d;
}

.voice-banner-steps kbd {
  background: #2a2510;
  border: 1px solid #5a4a10;
  border-radius: 3px;
  padding: 1px 6px;
  font-size: 11px;
  font-family: ui-monospace, monospace;
  color: #fcd34d;
}

.voice-banner-verify {
  background: rgba(0,0,0,0.4);
  border: 1px solid #3a2f10;
  border-radius: 3px;
  padding: 8px 12px;
  margin: 8px 0;
  font-size: 12px;
}

.voice-banner-verify pre {
  margin: 6px 0;
  padding: 6px 10px;
  background: #0a0a05;
  border-radius: 3px;
  font-family: ui-monospace, monospace;
  font-size: 11px;
  overflow-x: auto;
  color: #d4c878;
  white-space: pre-wrap;
  word-break: break-all;
}

.voice-banner-verify code {
  background: #0a0a05;
  padding: 1px 6px;
  border-radius: 2px;
  font-family: ui-monospace, monospace;
  color: #fcd34d;
}

.voice-banner-link {
  display: inline-block;
  margin-top: 6px;
  color: #fcd34d;
  text-decoration: underline;
  font-size: 12px;
  opacity: 0.85;
}

.voice-banner-foot {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid #3a2f10;
  font-size: 12px;
  opacity: 0.85;
}

.voice-banner-close {
  background: transparent;
  border: 1px solid #5a4a10;
  color: #eedb8a;
  width: 28px;
  height: 28px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 18px;
  line-height: 1;
  flex-shrink: 0;
}

.voice-banner-close:hover {
  background: #2a2510;
}

.forvo-icon {
  display: inline-block;
  margin: 0 2px;
}

a.btn.icon-btn.forvo-link {
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

a.btn.icon-btn.forvo-link:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.niqqud-toggle {
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 6px 12px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  font-family: inherit;
  letter-spacing: 0.5px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  transition: all 0.15s;
}

.niqqud-toggle:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.niqqud-toggle .dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  display: inline-block;
}

.niqqud-toggle[aria-pressed="false"] .dot {
  background: var(--text-faint);
}

/* Cursive (ktav yad) toggle — same chrome as the niqqud toggle */
.cursive-toggle {
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 6px 12px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  font-family: inherit;
  letter-spacing: 0.5px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: all 0.15s;
}
.cursive-toggle:hover { border-color: var(--accent); color: var(--accent); }
.cursive-toggle .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-faint); display: inline-block; }
.cursive-toggle[aria-pressed="true"] .dot { background: var(--accent); }

/* When cursive is on, lesson Hebrew renders in the handwriting font. Scoped to the same .he
   content the niqqud toggle already governs; index/home have no toggle so body.cursive is never
   set there.
   Size: this used to say `font-size: 1.15em`, which was a bug, not a nudge. `em` on font-size
   resolves against the PARENT, so 1.15em against a 17px .word-row rendered cursive at ~19.6px
   where print was 36px — cursive came out at 54% of print, which is exactly what reads as "tiny".
   Measured (canvas ink height of ascender/descender-free words at 36px): KtavYad's letter bodies
   are already ~16% TALLER than Frank Ruhl's at the same px, so no compensation is owed. The 1.1
   scale below is for legibility of an unfamiliar script with thin handwriting strokes, nothing
   more. Derived from each context's --he-size so a breakpoint only ever changes one number. */
body.cursive .word-row .he,
body.cursive .tb-he,
body.cursive .stich-words .he,
body.cursive .mini-quiz .he {
  font-family: 'KtavYad', cursive;
  font-size: calc(var(--he-size, 1em) * var(--cursive-scale));
}

/* Text-block Hebrew (renderTextBlock). These four properties used to be written inline by app.js,
   which meant the cursive rule above could never win against them — the toggle silently did
   nothing on text-block pages. They live here so the toggle reaches them like everywhere else. */
.tb-he {
  --he-size: 30px;
  font-size: var(--he-size);
  font-family: 'Frank Ruhl Libre', 'David', serif;
  direction: rtl;
  text-align: right;
  line-height: 1.5;
  cursor: pointer;
}

body.no-niqqud .he,
body.no-niqqud [style*="direction: rtl"] {
  letter-spacing: 0.5px;
}

@media (max-width: 600px) {
  body { padding: 20px 14px; }
  .word-row {
    padding: 16px 18px;
    column-gap: 14px;
    row-gap: 2px;
  }
  .quiz .he-display { font-size: 64px; }
}

/* ============ Universal Exercises Engine ============ */
#exercises-block { margin-top: 40px; }
.ex-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; padding: 4px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 6px; }
.ex-tab { background: transparent; border: 1px solid transparent; color: var(--text-dim); padding: 8px 14px; border-radius: 4px; cursor: pointer; font-size: 13px; transition: all 0.15s; }
.ex-tab:hover { background: var(--bg-card-hover); color: var(--text); }
.ex-tab.active { background: var(--accent-dim); border-color: var(--accent); color: var(--accent); }
#ex-stage { background: var(--bg-card); border: 1px solid var(--border); border-radius: 6px; padding: 24px; min-height: 280px; }
.ex-stats { margin-top: 12px; padding: 10px 16px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 4px; font-size: 13px; color: var(--text-dim); text-align: center; font-family: 'JetBrains Mono', monospace; }

/* Flashcards */
.flashcard { background: var(--bg-card-hover); border: 1px solid var(--border); border-radius: 6px; padding: 60px 24px; text-align: center; cursor: pointer; min-height: 220px; display: flex; align-items: center; justify-content: center; transition: transform 0.15s; }
.flashcard:hover { border-color: var(--accent); transform: translateY(-2px); }
.fc-side { width: 100%; }
.fc-he { font-family: 'Frank Ruhl Libre', serif; font-size: 56px; direction: rtl; color: var(--text); margin-bottom: 12px; }
.fc-fr { font-size: 32px; color: var(--accent); margin-bottom: 12px; }
.fc-translit { font-size: 16px; color: var(--text-dim); font-style: italic; margin-bottom: 20px; }
.fc-hint { font-size: 11px; color: var(--text-faint); }
.fc-controls { display: flex; gap: 8px; margin-top: 16px; flex-wrap: wrap; justify-content: center; }
.fc-counter { text-align: center; margin-top: 12px; font-size: 12px; color: var(--text-dim); font-family: 'JetBrains Mono', monospace; }

/* Multiple/Reverse/Audio */
.ex-prompt { text-align: center; padding: 24px 16px; }
.ex-q-he { font-family: 'Frank Ruhl Libre', serif; font-size: 48px; direction: rtl; color: var(--text); margin-bottom: 8px; }
.ex-q-fr { font-size: 32px; color: var(--accent); margin-bottom: 8px; }
.ex-q-tr { font-size: 14px; color: var(--text-dim); font-style: italic; }
.ex-options { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-top: 16px; }
.ex-options-he .ex-option { min-height: 80px; }
.ex-option { background: var(--bg-card-hover); border: 1px solid var(--border); color: var(--text); padding: 14px 16px; border-radius: 4px; cursor: pointer; font-size: 14px; transition: all 0.15s; text-align: center; }
.ex-option:hover:not(:disabled) { border-color: var(--accent); background: var(--bg-card); }
.ex-option:disabled { cursor: not-allowed; opacity: 0.6; }
.ex-option.correct { background: rgba(0, 113, 185,0.15); border-color: var(--accent); color: var(--accent); opacity: 1; }
.ex-option.wrong { background: rgba(239,68,68,0.15); border-color: var(--error); color: var(--error); opacity: 1; }
.ex-feedback { text-align: center; margin-top: 16px; font-size: 14px; color: var(--text-dim); min-height: 20px; }

/* Typing */
.ex-input-row { display: flex; gap: 8px; margin-top: 16px; flex-wrap: wrap; }
.ex-input { flex: 1; min-width: 200px; background: var(--bg-card-hover); border: 1px solid var(--border); color: var(--text); padding: 12px 14px; border-radius: 4px; font-size: 16px; font-family: inherit; }
.ex-input:focus { outline: none; border-color: var(--accent); }
.ex-hint { margin-top: 8px; font-size: 12px; color: var(--text-faint); text-align: center; }

/* Memory grid */
.memory-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.memory-card { aspect-ratio: 1; background: var(--bg-card-hover); border: 1px solid var(--border); border-radius: 4px; cursor: pointer; position: relative; perspective: 600px; transition: transform 0.15s; }
.memory-card:hover { border-color: var(--accent); }
.memory-back, .memory-front { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 8px; text-align: center; backface-visibility: hidden; transition: transform 0.4s; }
.memory-back { background: var(--bg-card-hover); color: var(--text-dim); font-size: 24px; }
.memory-front { transform: rotateY(180deg); background: var(--bg-card); color: var(--text); }
.memory-card.flipped .memory-back { transform: rotateY(180deg); }
.memory-card.flipped .memory-front { transform: rotateY(360deg); }
.memory-card.matched { opacity: 0.4; pointer-events: none; }
.memory-card.matched .memory-front { background: rgba(0, 113, 185,0.2); color: var(--accent); }

@media (max-width: 600px) {
  .ex-options { grid-template-columns: 1fr; }
  .memory-grid { grid-template-columns: repeat(3, 1fr); }
  .fc-he { font-size: 36px; }
  .ex-q-he { font-size: 32px; }
}

/* ============ Top Fixed Controls ============ */
#floating-controls {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  flex-direction: row;
  gap: 8px;
  z-index: 100;
  padding: 12px 20px;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  justify-content: flex-end;
  align-items: center;
  backdrop-filter: blur(8px);
}
.fc-btn {
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 8px 14px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  transition: all 0.15s;
}
.fc-btn:hover { border-color: var(--accent); color: var(--accent); }
.fc-btn.fc-home { text-decoration: none; margin-right: auto; }
@media print { #floating-controls, .niqqud-toggle, .cursive-toggle, .nav, footer button, .ex-tabs, #ex-stage, #exercises-block, #voice-banner { display: none !important; } body { background: white !important; color: black !important; padding-top: 32px !important; } .he, .word-row { color: black !important; } .word-row .translit, .word-row .fr { filter: none !important; color: inherit !important; text-shadow: none !important; background: transparent !important; } }
@media (max-width: 600px) {
  #floating-controls { padding: 8px 10px; gap: 4px; flex-wrap: wrap; }
  .fc-btn { font-size: 11px; padding: 6px 10px; }
}

/* ============ Word Tokens (clickable Hebrew words) ============ */
.word-token { cursor: pointer; padding: 0 2px; border-radius: 3px; transition: background 0.15s, color 0.15s; }
.word-token:hover { background: rgba(0, 113, 185,0.2); color: var(--accent); }

/* ============ SR Heatmap (index) ============ */
.streak-day { aspect-ratio: 1; background: var(--bg); border: 1px solid var(--border); border-radius: 2px; }
.streak-day.active { background: var(--accent); border-color: var(--accent); }

/* ============ Light Mode ============ */
html.light {
  --bg: #fafafa;
  --bg-card: #ffffff;
  --bg-card-hover: #f3f4f6;
  --border: #e5e7eb;
  --text: #1a1a1a;
  --text-dim: #525252;
  --text-faint: #6b7280;
  --accent: #0071B9;
  --accent-dim: #d0e7f4;
  --error: #dc2626;
  --success: #0071B9;
}

html.light .lesson-card:hover { box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06); }
html.light .word-row { box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03); }
html.light .quiz-option.correct { background: #d0e7f4; color: #003356; border-color: #0071B9; }
html.light .quiz-option.wrong { background: #fee2e2; color: #991b1b; border-color: #dc2626; }
html.light .ex-option.correct { background: #d0e7f4; color: #003356; border-color: #0071B9; }
html.light .sit-option.correct { background: #d0e7f4; color: #003356; border-color: #0071B9; }
html.light .sit-option.wrong { background: #fee2e2; color: #991b1b; border-color: #dc2626; }
html.light .ex-produce-btn.primary { color: #003356; }
html.light .ex-option.wrong { background: #fee2e2; color: #991b1b; border-color: #dc2626; }
html.light .btn-primary { color: #fff; }
html.light .btn-primary:hover { background: transparent; color: var(--accent); }
html.light .voice-banner { background: #fef9c3; color: #713f12; border-bottom-color: #ca8a04; }
html.light .voice-banner-title { color: #854d0e; }
html.light .voice-banner-os { background: rgba(255,255,255,0.5); border-color: #ca8a04; }
html.light .voice-banner-os summary { color: #854d0e; }
html.light .voice-banner-steps strong { color: #854d0e; }
html.light .voice-banner-steps kbd { background: #fff; border-color: #ca8a04; color: #713f12; }
html.light .voice-banner-verify { background: rgba(0,0,0,0.06); border-color: #ca8a04; }
html.light .voice-banner-verify pre { background: #fff8d0; color: #713f12; }
html.light .voice-banner-verify code { background: #fff8d0; color: #854d0e; }
html.light .voice-banner-link { color: #854d0e; }
html.light .voice-banner-foot { border-top-color: #ca8a04; }
html.light .voice-banner-close { color: #713f12; border-color: #ca8a04; }
html.light .voice-banner-close:hover { background: #fde68a; }
html.light .fc-btn { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); }
html.light .memory-back { background: var(--bg-card-hover); color: var(--text-dim); }

.theme-toggle {
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text-dim);
  padding: 6px 12px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  font-family: inherit;
  letter-spacing: 0.5px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: all 0.15s;
}
.theme-toggle:hover { border-color: var(--accent); color: var(--accent); }
.theme-toggle .ico { font-size: 14px; line-height: 1; }

/* ============ SRS Badge & Review Modal ============ */
.fc-badge { display: inline-block; min-width: 18px; padding: 0 6px; margin-left: 4px; font-size: 11px; line-height: 18px; border-radius: 9px; background: var(--bg-card-hover); color: var(--text-dim); text-align: center; }
.fc-badge-due { background: var(--accent); color: #fff; }
html.light .fc-badge-due { color: #fff; }

#srs-modal { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; padding: 20px; }
.srs-overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.55); backdrop-filter: blur(6px); }
html.light .srs-overlay { background: rgba(0,0,0,0.35); }
.srs-card { position: relative; background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; padding: 36px 32px 28px; max-width: 520px; width: 100%; min-height: 500px; box-shadow: 0 24px 48px rgba(0,0,0,0.4); text-align: center; display: flex; flex-direction: column; }
.srs-close { position: absolute; top: 12px; right: 14px; width: 32px; height: 32px; border-radius: 50%; background: transparent; border: 1px solid var(--border); color: var(--text-dim); font-size: 20px; line-height: 1; cursor: pointer; }
.srs-close:hover { border-color: var(--accent); color: var(--accent); }
.srs-topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; gap: 12px; }
.srs-progress { font-size: 12px; color: var(--text-faint); letter-spacing: 1.5px; text-transform: uppercase; }
.srs-niqqud-toggle { background: var(--bg-card-hover); border: 1px solid var(--border); color: var(--text-dim); padding: 6px 12px; border-radius: 4px; cursor: pointer; font-size: 11px; font-family: inherit; letter-spacing: 0.5px; text-transform: uppercase; display: inline-flex; align-items: center; gap: 8px; transition: all 0.15s; }
.srs-niqqud-toggle:hover { border-color: var(--accent); color: var(--accent); }
.srs-niqqud-toggle .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); display: inline-block; }
.srs-niqqud-toggle[aria-pressed="false"] .dot { background: var(--text-faint); }
.srs-he { font-family: 'Frank Ruhl Libre', 'David', serif; font-size: 64px; line-height: 1.3; direction: rtl; text-align: center; margin: 12px 0 8px; cursor: pointer; }
.srs-listen { background: transparent; border: 1px solid var(--border); color: var(--text-dim); width: 38px; height: 38px; border-radius: 50%; cursor: pointer; font-size: 14px; margin: 0 auto 18px; flex-shrink: 0; }
.srs-listen:hover { border-color: var(--accent); color: var(--accent); }
.srs-answer { padding: 18px 0 22px; border-top: 1px solid var(--border); margin-top: 8px; min-height: 110px; box-sizing: border-box; visibility: hidden; }
.srs-answer.revealed { visibility: visible; }
.srs-translit { color: var(--text-dim); font-style: italic; font-size: 18px; margin-bottom: 6px; }
.srs-fr { font-size: 20px; }
.srs-actions { margin-top: auto; padding-top: 16px; min-height: 78px; box-sizing: border-box; display: flex; flex-direction: column; justify-content: flex-end; }
.srs-show { width: 100%; padding: 14px; font-size: 14px; }
.srs-grade { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; }
.srs-g { padding: 12px 8px; border-radius: 6px; border: 1px solid var(--border); background: var(--bg-card-hover); color: var(--text); cursor: pointer; font-family: inherit; font-size: 13px; transition: all 0.15s; }
.srs-g:hover { transform: translateY(-1px); }
.srs-g-again { border-color: var(--grade-again); color: var(--grade-again); }
.srs-g-hard  { border-color: var(--grade-hard); color: var(--grade-hard); }
.srs-g-good  { border-color: var(--accent); color: var(--accent); }
.srs-g-easy  { border-color: var(--grade-easy); color: var(--grade-easy); }
@media (max-width: 600px) {
  .srs-he { font-size: 44px; }
  .srs-grade { grid-template-columns: repeat(2, 1fr); }
}

/* =====================================================================
 * MOBILE RESPONSIVE — universal, applies to all 498 lesson + index pages
 * Uses html-prefixed selectors to beat inline !important overrides in
 * prayer/shabbat/songs pages.
 * ===================================================================== */

/* =====================================================================
 * VERSES GRID — row-major RTL (better for printing long songs/tehilim,
 * less vertical scrolling than column-major). Overrides any inline
 * column-count rules in prayer/song pages.
 * ===================================================================== */
html .verses-grid {
  column-count: unset !important;
  column-gap: unset !important;
  display: grid !important;
  grid-template-columns: repeat(3, 1fr) !important;
  gap: 18px !important;
  direction: rtl !important;
}
html .verses-grid .verse {
  break-inside: avoid !important;
  page-break-inside: avoid !important;
}

/* Print: 2 columns, tight gap, avoid splitting verses */
@media print {
  html .verses-grid {
    grid-template-columns: repeat(2, 1fr) !important;
    gap: 10px !important;
  }
  html .verses-grid .verse {
    break-inside: avoid !important;
    page-break-inside: avoid !important;
  }
}

/* Tablet — 2-column verses, narrower hero, smaller padding */
@media (max-width: 1024px) {
  .container { max-width: 100%; padding: 18px 20px; box-sizing: border-box; }
  html .verses-grid { grid-template-columns: repeat(2, 1fr) !important; }
  .hero-row { grid-template-columns: 1fr !important; }
  .hero-cta { width: 100%; }
  .mini-stats { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)) !important; }
  .tehilim-grid { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)) !important; }
  .lessons { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)) !important; }
}

/* Mobile — single column, larger Hebrew, condensed layout */
@media (max-width: 700px) {
  body { font-size: 15px; -webkit-text-size-adjust: 100%; }
  .container { padding: 14px 12px; }

  /* HEADERS / TITLES */
  header { flex-direction: column !important; align-items: flex-start !important; gap: 10px !important; }
  header h1, .container > h1 { font-size: 22px !important; line-height: 1.2 !important; }
  h1 { font-size: 22px !important; line-height: 1.2 !important; }
  h2 { font-size: 18px !important; line-height: 1.25 !important; }
  h3 { font-size: 15px !important; }
  .subtitle { font-size: 12px !important; line-height: 1.4 !important; }
  .nav { font-size: 13px !important; gap: 10px !important; flex-wrap: wrap; }

  /* VERSES GRID (prayer/shabbat/songs/tehilim) — single column, beats inline overrides */
  html .verses-grid { grid-template-columns: 1fr !important; gap: 8px !important; direction: ltr !important; }
  html .verses-grid .verse { padding: 12px 14px !important; margin-bottom: 0 !important; direction: rtl; break-inside: avoid; }
  html .verses-grid .stich { direction: ltr !important; }
  html .verses-grid .stich > * { direction: rtl; }
  html .verses-grid .stich-words { gap: 10px 14px !important; }
  html .verses-grid .word { min-width: 40px !important; }
  html .verses-grid .word .he { font-size: 22px !important; line-height: 1.25 !important; margin-bottom: 2px !important; }
  html .verses-grid .word .tr { font-size: 12px !important; }
  html .verses-grid .word .fr { font-size: 11px !important; line-height: 1.3 !important; }
  html .verses-grid .stich-translation { font-size: 14px !important; padding: 6px 10px !important; }
  html .verses-grid .verse-num { font-size: 10px !important; letter-spacing: 1px !important; }
  html .verses-grid .stich-chords { font-size: 12px !important; padding: 4px 8px !important; }

  /* INTRO + LESSON + ABOUT CARDS */
  .t-intro, .chant-tip, .pardes-card { padding: 16px 14px !important; font-size: 14px !important; line-height: 1.55 !important; }
  .chant-tip h3, .pardes-card h3 { font-size: 13px !important; margin-bottom: 10px !important; }
  .chant-tip ul { padding-left: 18px !important; }
  .chant-tip li { font-size: 13px !important; line-height: 1.5 !important; margin-bottom: 8px !important; }
  .pardes-card p { font-size: 13px !important; line-height: 1.55 !important; }
  .pardes-card .pardes-level { padding: 14px 12px !important; margin-bottom: 12px !important; }
  .pardes-card .pardes-intro { font-size: 13px !important; }

  /* FOOTER */
  footer { font-size: 12px !important; padding: 16px 0 !important; }

  /* CHORDS (songs pages — tuning, voicings) */
  .t-chord { padding: 12px !important; }
  .t-chord .tuning-row { flex-wrap: wrap !important; gap: 8px !important; }
  .t-chord .progression { font-size: 13px !important; flex-wrap: wrap !important; }
  .active-voicings { padding: 12px !important; }
  .voicings-grid { grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)) !important; gap: 8px !important; }
  .voicing-card { padding: 8px !important; }
  .voicing-card svg { max-width: 100%; height: auto; }
  .voicing-name { font-size: 12px !important; }

  /* INDEX — hero, stats, action bar, search, chip nav, cards */
  .hero-row { padding: 16px 18px !important; gap: 12px !important; }
  .hero-title { font-size: 18px !important; }
  .hero-sub { font-size: 12px !important; }
  .hero-cta { padding: 12px 18px !important; font-size: 14px !important; }
  .mini-stats { grid-template-columns: repeat(2, 1fr) !important; gap: 6px !important; }
  .mini-stat { padding: 10px 12px !important; }
  .mini-stat .val { font-size: 16px !important; }
  .mini-stat .lbl { font-size: 9px !important; }
  .action-bar { gap: 6px !important; }
  .action-bar button, .action-bar a { font-size: 12px !important; padding: 8px 12px !important; }
  .mega-cat { margin: 20px 0 16px !important; }
  .mega-cat-header { flex-wrap: wrap !important; gap: 8px !important; }
  .mega-cat-title { font-size: 17px !important; }
  .mega-cat-stat { font-size: 11px !important; }
  .mega-cat-bar { min-width: 60px !important; }

  /* TEHILIM/PRAYER/SONG CARDS GRID */
  .tehilim-grid { grid-template-columns: 1fr !important; gap: 8px !important; }
  .tehilim-card { padding: 14px 16px !important; }
  .tehilim-card .ps { font-size: 11px !important; }
  .tehilim-card .he { font-size: 20px !important; }
  .tehilim-card .ti { font-size: 12px !important; }

  /* CLASSIC LESSON CARDS (Foundations and other lesson categories) */
  .lessons { grid-template-columns: 1fr !important; gap: 8px !important; }
  .lesson-card { padding: 14px 16px !important; }
  .lesson-card .num { font-size: 11px !important; }
  .lesson-card .title-fr { font-size: 15px !important; }
  .lesson-card .title-he { font-size: 18px !important; }
  .lesson-card .meta { font-size: 11px !important; }

  /* WORD ROWS (used in classic lesson pages) */
  .word-row { font-size: 14px !important; padding: 10px 12px !important; }
  /* Override the size VARIABLE, not font-size: the cursive rule reads --he-size, so handwriting
     stays proportional here instead of being frozen at the desktop value (or, worse, beaten by an
     !important it cannot see). */
  .word-row .he { --he-size: 22px !important; }
  .word-row .translit { font-size: 12px !important; }
  .word-row .fr { font-size: 13px !important; }

  /* EXERCISES */
  .ex-input { font-size: 16px !important; padding: 10px 12px !important; }
  .ex-tabs { flex-wrap: wrap !important; gap: 6px !important; }

  /* SRS REVIEW */
  .srs-card { padding: 22px 18px !important; min-height: 360px !important; }
}

/* Very narrow phones (< 380px) */
@media (max-width: 380px) {
  .container { padding: 10px 8px; }
  html .verses-grid .word .he { font-size: 20px !important; }
  .mini-stats { grid-template-columns: 1fr 1fr !important; }
  header h1, .container > h1, h1 { font-size: 20px !important; }
}

/* =====================================================================
 * Prayer/Shabbat verse cards — verse-num title ALWAYS at top of card,
 * never overlapping Hebrew, never separated by a column break.
 * Uses html-prefixed selectors to beat inline !important in prayer pages.
 * ===================================================================== */
html .verses-grid .verse {
  display: flex !important;
  flex-direction: column !important;
  break-inside: avoid !important;
  -webkit-column-break-inside: avoid !important;
  page-break-inside: avoid !important;
}
html .verses-grid .verse-num {
  order: -1 !important;
  flex: 0 0 auto !important;
  position: static !important;
  display: block !important;
  width: 100% !important;
  margin: 0 0 8px !important;
  padding: 0 !important;
  border: none !important;
  background: transparent !important;
  break-after: avoid !important;
  -webkit-column-break-after: avoid !important;
  page-break-after: avoid !important;
  text-align: right !important;  /* RTL: title aligns with Hebrew on the right edge */
  direction: ltr !important;     /* but the label itself is Latin */
  font-size: 10px !important;
  letter-spacing: 1px !important;
  text-transform: uppercase !important;
  color: var(--text-faint) !important;
  opacity: 0.7 !important;
  font-weight: 600 !important;
}

/* =====================================================================
 * CUSTOM SCROLLBARS — matches app aesthetic (emerald accent, themed)
 * Works in Chrome/Safari/Edge/Opera (webkit-*) + Firefox (scrollbar-*).
 * ===================================================================== */

/* Firefox + modern CSS — body, html, all scrollable elements */
* {
  scrollbar-width: thin;
  scrollbar-color: var(--border) transparent;
}
*:hover {
  scrollbar-color: var(--accent) transparent;
}

/* WebKit — track, thumb, corner */
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 6px;
  border: 2px solid transparent;
  background-clip: padding-box;
  transition: background 0.15s;
}
::-webkit-scrollbar-thumb:hover {
  background: var(--accent);
  background-clip: padding-box;
  border: 2px solid transparent;
}
::-webkit-scrollbar-corner {
  background: transparent;
}

/* Tehilim/prayer/song card grids — when overflowing on tablet */
.tehilim-grid::-webkit-scrollbar,
.lessons::-webkit-scrollbar {
  height: 8px;
}

/* Light mode adjustment — thumbs a touch darker for visibility on bright bg */
html.light ::-webkit-scrollbar-thumb {
  background: rgba(0, 0, 0, 0.18);
  background-clip: padding-box;
  border: 2px solid transparent;
}
html.light ::-webkit-scrollbar-thumb:hover {
  background: var(--accent);
  background-clip: padding-box;
  border: 2px solid transparent;
}
html.light * {
  scrollbar-color: rgba(0, 0, 0, 0.18) transparent;
}
html.light *:hover {
  scrollbar-color: var(--accent) transparent;
}

/* ============================================================
   Cursive track (ktav yad) — Culmus KtavYadCLM, GPL+FontException
   ============================================================ */
/* Frank Ruhl Libre — self-hosted (was Google Fonts). Same per-subset woff2 as Google's css2
   (one variable file per subset, weight range 400-700). Removes the last external dependency so
   the CSP can drop all external font/style hosts. */
@font-face {
  font-family: 'Frank Ruhl Libre'; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url('frank-ruhl-he.woff2') format('woff2');
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F;
}
@font-face {
  font-family: 'Frank Ruhl Libre'; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url('frank-ruhl-lext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Frank Ruhl Libre'; font-style: normal; font-weight: 400 700; font-display: swap;
  src: url('frank-ruhl-lat.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'KtavYad';
  src: url('KtavYadCLM-MediumItalic.ttf') format('truetype');
  font-display: swap;
}
.ktav { font-family: 'KtavYad', cursive; direction: rtl; }

/* print <-> cursive comparison grid */
.cur-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; margin: 18px 0; }
.cur-card {
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px;
  padding: 16px 12px 14px; text-align: center; cursor: pointer; transition: all 0.18s;
  position: relative;
}
.cur-card:hover { border-color: var(--accent); background: var(--bg-card-hover); transform: translateY(-2px); }
.cur-card .cc-cursive { font-family: 'KtavYad', cursive; direction: rtl; font-size: 58px; line-height: 1; color: var(--text); margin-bottom: 6px; }
.cur-card .cc-print { font-family: 'Frank Ruhl Libre', 'David', serif; direction: rtl; font-size: 26px; color: var(--text-dim); margin-bottom: 8px; }
.cur-card .cc-name { font-size: 13px; font-weight: 600; color: var(--text); letter-spacing: 0.3px; }
.cur-card .cc-translit { font-size: 12px; color: var(--accent); font-family: ui-monospace, monospace; margin-top: 2px; }
.cur-card .cc-hint { font-size: 11px; color: var(--text-dim); margin-top: 8px; line-height: 1.35; min-height: 30px; }
.cur-card .cc-listen { position: absolute; top: 8px; left: 8px; font-size: 13px; opacity: 0; transition: opacity 0.18s; }
.cur-card:hover .cc-listen { opacity: 0.6; }

/* big cursive quiz prompt */
.cur-quiz-glyph { font-family: 'KtavYad', cursive; direction: rtl; font-size: 110px; line-height: 1.1; text-align: center; color: var(--text); margin: 8px 0 4px; }

/* reading drill: tap a handwritten word to reveal print + meaning */
.cur-read { display: flex; flex-direction: column; gap: 10px; margin: 16px 0; }
.cur-read-row {
  display: grid; grid-template-columns: 1.2fr 1fr 1fr auto; align-items: center; gap: 12px;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 6px; padding: 12px 16px; cursor: pointer;
}
.cur-read-row:hover { border-color: var(--accent); }
.cur-read-row .crr-cursive { font-family: 'KtavYad', cursive; direction: rtl; font-size: 40px; line-height: 1; color: var(--text); }
.cur-read-row .crr-print, .cur-read-row .crr-fr { color: var(--text-dim); opacity: 0; transition: opacity 0.2s; }
.cur-read-row.revealed .crr-print, .cur-read-row.revealed .crr-fr { opacity: 1; }
.cur-read-row .crr-print { font-family: 'Frank Ruhl Libre', 'David', serif; direction: rtl; font-size: 24px; color: var(--text); }
.cur-read-row .crr-fr { font-size: 14px; }
@media (max-width: 700px) {
  .cur-read-row { grid-template-columns: 1fr auto; }
  .cur-read-row .crr-print, .cur-read-row .crr-fr { font-size: 18px; }
}

/* ===== Quick-Say (type English -> Hebrew + translit) =====
   The result card mirrors the lesson word-row: the Hebrew anchors on the RIGHT, the
   transliteration and meaning stack directly beneath it, and the controls sit on one row below.
   Same reading habit in both places — the right edge is always where Hebrew starts. */
.qs-box { width: 100%; }

/* --- Input field: leading alef, focus ring, clear button --- */
.qs-field { position: relative; display: flex; align-items: center; }
.qs-field-icon {
  position: absolute; left: 15px; top: 50%; transform: translateY(-50%);
  font-family: 'Frank Ruhl Libre', 'David', serif; font-size: 20px; line-height: 1;
  color: var(--text-faint); pointer-events: none; transition: color .18s ease;
}
.qs-field:focus-within .qs-field-icon { color: var(--accent); }
.qs-input {
  width: 100%; box-sizing: border-box;
  padding: 14px 16px; font-size: 16px; font-family: inherit;
  color: var(--text); background: var(--bg-card);
  border: 1.5px solid var(--border); border-radius: 12px;
  outline: none; transition: border-color .18s ease, box-shadow .18s ease, background .18s ease;
}
/* Only the translator field wears the accent at rest (it is the live thing on the page);
   `.qs-input` is reused by the plain phrase search, which should stay quiet. */
.qs-field .qs-input { border-color: var(--accent-dim); padding-left: 42px; padding-right: 42px; }
.qs-input::placeholder { color: var(--text-faint); }
.qs-input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-dim); background: var(--bg-card-hover); }
.qs-clear {
  position: absolute; right: 9px; top: 50%; transform: translateY(-50%);
  width: 27px; height: 27px; border-radius: 50%; padding: 0;
  display: none; align-items: center; justify-content: center;
  background: transparent; border: none; color: var(--text-faint);
  font-family: inherit; font-size: 19px; line-height: 1; cursor: pointer;
  transition: color .15s ease, background .15s ease;
}
.qs-field.has-value .qs-clear { display: inline-flex; }
.qs-clear:hover { color: var(--accent); background: var(--bg-card-hover); }

.qs-results { margin-top: 14px; display: flex; flex-direction: column; gap: 10px; }
.qs-hint { color: var(--text-dim); font-size: 13px; padding: 10px 2px; line-height: 1.55; }
.qs-hint em { color: var(--accent); font-style: normal; }
.qs-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.qs-chip {
  cursor: pointer; font: inherit; font-size: 13px;
  background: var(--bg-card); color: var(--text-dim);
  border: 1px solid var(--border); border-radius: 999px; padding: 6px 13px;
  transition: border-color .15s, color .15s, background .15s;
}
.qs-chip:hover { border-color: var(--accent); color: var(--accent); }
.qs-offline { color: var(--error); }

/* --- Result card --- */
.qs-card {
  display: grid; direction: rtl;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "text text" "tools actions" "break break";
  align-items: center; column-gap: 12px; row-gap: 12px;
  padding: 16px 18px; background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 14px;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.qs-card:hover { border-color: var(--accent-dim); box-shadow: 0 3px 16px rgba(0,0,0,0.18); }
html.light .qs-card:hover { box-shadow: 0 3px 16px rgba(0,0,0,0.06); }
/* --he-size sits on the shared PARENT, not on .qs-he: the printed line and the cursive echo are
   siblings, so a variable declared on one would never reach the other. */
.qs-text { grid-area: text; min-width: 0; --he-size: 27px; }
.qs-he {
  font-family: 'Frank Ruhl Libre', serif; font-size: var(--he-size); line-height: 1.4; color: var(--text);
  direction: rtl; text-align: right; overflow-wrap: break-word;
}
/* Latin lines read left-to-right but hug the RIGHT edge, so they sit under the word they gloss
   instead of drifting to the opposite side of the card. */
.qs-tr, .qs-en { direction: ltr; text-align: right; }
.qs-tr { font-size: 14px; color: var(--accent); margin-top: 5px; }
.qs-en { font-size: 13px; color: var(--text-dim); margin-top: 5px; display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
/* Inline grammar under a one-word result (gender/number, and the dictionary form when it differs).
   Filled asynchronously — `:empty` keeps it out of the layout entirely until it has something to
   say, so a card whose grammar never arrives looks exactly like a card that never asked. */
.qs-gnp { direction: ltr; text-align: right; margin-top: 6px;
  display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
.qs-gnp:empty { display: none; }

/* Present tense under a verb card. Four cells that wrap to two on a phone rather than a table:
   the point is to take the whole paradigm in at a glance, and a four-column table at 390px puts
   each form in about 80px, which is narrower than שׁוֹמְרוֹת. */
.qs-cj { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 8px; }
.qs-cj:empty { display: none; }
.qs-cj-title { font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-faint); margin-bottom: 6px; text-align: right; }
.qs-cj-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; direction: rtl; }
.qs-cj-cell { text-align: center; }
.qs-cj-tag { font-size: 10px; letter-spacing: .03em; color: var(--text-faint); direction: ltr; }
.qs-cj-he { font-family: 'Frank Ruhl Libre', 'David', serif; font-size: 19px; line-height: 1.6;
  unicode-bidi: isolate; }
body.cursive .qs-cj-he { font-family: 'KtavYad', cursive; font-size: 22px; }
.qs-cj-tr { font-size: 11px; color: var(--accent); direction: ltr; unicode-bidi: isolate; }

@media (max-width: 560px) {
  .qs-cj-grid { grid-template-columns: repeat(2, 1fr); gap: 10px 8px; }
  .qs-cj-he { font-size: 20px; }
}
.qs-gnp-g { font-size: 11px; letter-spacing: .03em; color: var(--text-faint);
  border: 1px solid var(--border); border-radius: 6px; padding: 2px 7px; }
.qs-gnp-r { font-family: 'Frank Ruhl Libre', 'David', serif; font-size: 15px; color: var(--text-dim); }

.qs-tag {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-faint); border: 1px solid var(--border); border-radius: 6px; padding: 1px 6px;
}
/* All tags stay in the blue accent family (no off-brand green/amber); the ✓ / word marks
   already distinguish curated vs phonetic without relying on color. */
.qs-tag-online { color: var(--accent); border-color: var(--accent-dim); }
.qs-tag-curated { color: var(--accent); border-color: var(--accent); font-weight: 600; }
.qs-tag-phonetic { color: var(--text-dim); border-color: var(--border); }

/* --- Loading: a card-shaped shimmer, so nothing jumps when the real card lands.
   Keeps the `.qs-loading` class — the translator probe synchronises on it. --- */
.qs-loading {
  display: flex; flex-direction: column; align-items: flex-end; gap: 9px;
  padding: 18px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 14px;
}
.qs-sk {
  display: block; height: 12px; border-radius: 6px;
  background: linear-gradient(90deg, var(--bg-card-hover) 25%, var(--border) 50%, var(--bg-card-hover) 75%);
  background-size: 300% 100%; animation: qs-shimmer 1.3s ease-in-out infinite;
}
.qs-sk.sk-0 { height: 23px; width: 46%; }
.qs-sk.sk-1 { width: 30%; }
.qs-sk.sk-2 { width: 38%; height: 10px; }
@keyframes qs-shimmer { from { background-position: 150% 0; } to { background-position: -150% 0; } }

.qs-sub {
  display: flex; align-items: center; gap: 10px;
  font-size: 10px; text-transform: uppercase; letter-spacing: .09em;
  color: var(--text-faint); margin: 8px 2px 0;
}
.qs-sub::after { content: ''; flex: 1 1 auto; height: 1px; background: var(--border); }
.qs-online-btn {
  align-self: flex-start; margin-top: 2px; cursor: pointer;
  background: none; border: 1px dashed var(--accent-dim); color: var(--accent);
  font: inherit; font-size: 13px; padding: 8px 14px; border-radius: 10px;
  transition: background .15s, color .15s;
}
.qs-online-btn:hover:not(:disabled) { background: var(--accent); color: #fff; border-style: solid; }
.qs-online-btn:disabled { opacity: .6; cursor: default; }
@media (max-width: 700px) {
  .qs-text { --he-size: 28px; }
  .qs-card { padding: 15px 14px; column-gap: 8px; }
}

/* ============ Hub: hamburger menu + modal translator + preferences ============ */
.hub-actions { margin-left: auto; display: inline-flex; align-items: center; gap: 8px; }
/* Beat the mobile `header { flex-direction: column !important }` rule: the home top bar is
   always a single row — date on the left, translator + menu on the right. */
header.home-topbar { flex-direction: row !important; align-items: center !important; flex-wrap: nowrap !important; gap: 12px; }
.hub-hdate { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.hub-hdate .hd-he { font-family: 'Frank Ruhl Libre', 'David', serif; font-size: 18px; color: var(--text); }
.hub-hdate .hd-tr { font-size: 11px; color: var(--text-faint); letter-spacing: .3px; }
.hub-translate { width: 42px; height: 42px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; cursor: pointer;
  transition: border-color .15s, background .15s; padding: 0; }
.hub-translate span { font-family: 'Frank Ruhl Libre', 'David', serif; font-size: 22px; color: var(--accent); line-height: 1; }
.hub-translate:hover { border-color: var(--accent); background: var(--bg-card-hover); }
.hub-burger { width: 42px; height: 42px; display: inline-flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 5px; background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 8px; cursor: pointer; transition: border-color .15s; padding: 0; }
.hub-burger:hover { border-color: var(--accent); }
.hub-burger span { display: block; width: 18px; height: 2px; background: var(--text-dim); border-radius: 2px; transition: transform .22s ease, opacity .18s ease; }
.hub-burger:hover span { background: var(--accent); }
.hub-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.hub-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.hub-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

#hub-menu { position: fixed; inset: 0; z-index: 10000; pointer-events: none; }
#hub-menu.open { pointer-events: auto; }
.hub-menu-backdrop { position: absolute; inset: 0; background: rgba(0,0,0,0.5); backdrop-filter: blur(4px);
  opacity: 0; transition: opacity .25s ease; }
#hub-menu.open .hub-menu-backdrop { opacity: 1; }
.hub-menu-panel { position: absolute; top: 0; right: 0; height: 100%; width: 290px; max-width: 84vw;
  background: var(--bg-card); border-left: 1px solid var(--border); box-shadow: -18px 0 44px rgba(0,0,0,0.4);
  transform: translateX(100%); transition: transform .26s cubic-bezier(.4,0,.2,1); padding: 20px 14px; display: flex; flex-direction: column; gap: 4px; }
#hub-menu.open .hub-menu-panel { transform: translateX(0); }
.hub-menu-head { font-size: 12px; letter-spacing: 1px; text-transform: uppercase; color: var(--text-faint); padding: 4px 12px 12px; }
.menu-item { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%;
  padding: 13px 14px; background: transparent; border: 1px solid transparent; border-radius: 8px; cursor: pointer;
  color: var(--text); font-family: inherit; font-size: 15px; text-align: left; transition: background .14s, border-color .14s; }
.menu-item:hover { background: var(--bg-card-hover); border-color: var(--border); }
.menu-hint { font-size: 12px; color: var(--text-faint); }

/* Home-only "Find a lesson" block at the top of the drawer (search + category jumps). */
.hub-menu-panel { overflow-y: auto; }
.hub-find { border-bottom: 1px solid var(--border); padding-bottom: 10px; margin-bottom: 8px; }
.hub-find-input { width: 100%; padding: 11px 13px; background: var(--bg); border: 1px solid var(--border);
  border-radius: 8px; color: var(--text); font-family: inherit; font-size: 14px; transition: border-color .14s; }
.hub-find-input:focus { outline: none; border-color: var(--accent); }
.hub-find-list { max-height: 46vh; overflow-y: auto; margin-top: 8px; display: flex; flex-direction: column; gap: 2px; }
.hub-find-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%;
  padding: 10px 12px; background: transparent; border: 1px solid transparent; border-radius: 8px; cursor: pointer;
  color: var(--text); font-family: inherit; font-size: 14px; text-align: left; text-decoration: none;
  transition: background .14s, border-color .14s; }
.hub-find-row:hover { background: var(--bg-card-hover); border-color: var(--border); }
.hub-find-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.hub-find-sub { font-size: 10px; color: var(--text-faint); flex: 0 0 auto; text-transform: uppercase; letter-spacing: .04em; }
.hub-find-n { font-size: 12px; color: var(--text-faint); flex: 0 0 auto; }
.hub-find-empty { padding: 12px; color: var(--text-faint); font-size: 13px; }

/* Shared modal shell (translator + preferences) */
.hub-modal { position: fixed; inset: 0; z-index: 10001; display: flex; align-items: center; justify-content: center; padding: 20px; }
.hub-overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.55); backdrop-filter: blur(6px); }
html.light .hub-overlay { background: rgba(0,0,0,0.32); }
.hub-card { position: relative; background: var(--bg-card); border: 1px solid var(--border); border-radius: 14px;
  padding: 26px 24px 24px; width: 100%; box-shadow: 0 24px 56px rgba(0,0,0,0.42); animation: hub-pop .18s ease; }
@keyframes hub-pop { from { opacity: 0; transform: translateY(10px) scale(.98); } to { opacity: 1; transform: none; } }
.qs-modal-card { max-width: 620px; }
.prefs-card { max-width: 480px; }
.hub-install-card { max-width: 440px; }
.install-steps { margin: 4px 0 0; padding-left: 1.4em; display: flex; flex-direction: column; gap: 12px; }
.install-steps li { color: var(--text); font-size: 15px; line-height: 1.5; padding-left: 4px; }
.install-steps li::marker { color: var(--accent); font-weight: 700; }
.install-steps strong { color: var(--accent); }
.hub-close { position: absolute; top: 12px; right: 14px; width: 32px; height: 32px; border-radius: 50%; background: transparent;
  border: 1px solid var(--border); color: var(--text-dim); font-size: 20px; line-height: 1; cursor: pointer; transition: all .14s; }
.hub-close:hover { border-color: var(--accent); color: var(--accent); }
.hub-title { font-size: 21px; font-weight: 600; letter-spacing: -0.2px; margin: 0 40px 4px 0; }
.hub-sub { color: var(--text-dim); font-size: 13px; margin-bottom: 16px; }
#qs-modal-mount .qs-results { max-height: 60vh; overflow-y: auto; }

/* Preferences controls */
.pref-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 15px 2px; border-top: 1px solid var(--border); }
.pref-row.col { flex-direction: column; align-items: stretch; gap: 10px; }
.pref-row:first-of-type { border-top: none; }
.pref-label { font-size: 15px; color: var(--text); }
.pref-hint { font-size: 12px; color: var(--text-faint); margin-top: 2px; }
.seg { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; flex: 0 0 auto; }
.seg-btn { padding: 7px 14px; background: transparent; border: none; border-left: 1px solid var(--border); color: var(--text-dim);
  font-family: inherit; font-size: 13px; cursor: pointer; transition: all .14s; }
.seg-btn:first-child { border-left: none; }
.seg-btn.on { background: var(--accent); color: #fff; }
.seg-btn:not(.on):hover { color: var(--accent); }
.lang-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.lang-chip { padding: 7px 13px; background: transparent; border: 1px solid var(--border); border-radius: 20px; color: var(--text-dim);
  font-family: inherit; font-size: 13px; cursor: pointer; transition: all .14s; }
.lang-chip.on { background: var(--accent-dim); border-color: var(--accent); color: var(--text); }
.lang-chip:hover { border-color: var(--accent); }
.pref-switch { position: relative; width: 46px; height: 26px; border-radius: 20px; background: var(--bg-card-hover);
  border: 1px solid var(--border); cursor: pointer; flex: 0 0 auto; transition: background .18s, border-color .18s; padding: 0; }
.pref-switch .knob { position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%; background: var(--text-faint); transition: transform .18s ease, background .18s; }
.pref-switch.on { background: var(--accent-dim); border-color: var(--accent); }
.pref-switch.on .knob { transform: translateX(20px); background: var(--accent); }

/* Cursive echo line inside a translator card */
/* Cursive echo under the printed Hebrew. Sized off the printed line it echoes (same knob as every
   other cursive context) rather than a standalone px that drifts out of step with it. */
.qs-he-cursive { font-family: 'KtavYad', cursive; direction: rtl; text-align: right;
  font-size: calc(var(--he-size, 27px) * var(--cursive-scale)); line-height: 1.25; color: var(--text-dim); margin-top: 4px; }

@media (max-width: 700px) {
  .hub-title { font-size: 19px; }
  .hub-card { padding: 22px 16px 18px; }
  #qs-modal-mount .qs-results { max-height: 66vh; }
}

/* Home trigger that opens the translator modal */
.qs-open-btn { display: flex; align-items: center; gap: 14px; width: 100%; margin: 0 0 22px; padding: 14px 16px;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px; cursor: pointer;
  font-family: inherit; text-align: left; transition: border-color .15s, background .15s; }
.qs-open-btn:hover { border-color: var(--accent); background: var(--bg-card-hover); }
.qs-open-icon { flex: 0 0 auto; width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center;
  font-family: 'Frank Ruhl Libre', 'David', serif; font-size: 24px; color: var(--accent);
  background: var(--accent-dim); border-radius: 10px; }
.qs-open-text { flex: 1 1 auto; display: flex; flex-direction: column; font-size: 15px; color: var(--text); }
.qs-open-sub { font-size: 12px; color: var(--text-faint); margin-top: 2px; }

/* Home uses the hamburger hub; the per-lesson niqqud pill has nothing to act on here. */
body.home .niqqud-toggle { display: none; }
body.home .cursive-toggle { display: none; }

/* The hamburger hub replaces the floating control bar on every page; its buttons stay in the
   DOM (hidden) so the menu can trigger them. */
#floating-controls { display: none !important; }
.hub-back { width: 42px; height: 42px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; cursor: pointer;
  text-decoration: none; transition: border-color .15s, background .15s; }
.hub-back span { font-size: 22px; color: var(--text-dim); line-height: 1; }
.hub-back:hover { border-color: var(--accent); background: var(--bg-card-hover); }
.hub-back:hover span { color: var(--accent); }

/* Word-by-word breakdown (deep morphology via the Dicta Worker) */
.qs-break { padding: 8px 14px; background: transparent; border: 1px solid var(--border);
  border-radius: 20px; color: var(--text-dim); font-family: inherit; font-size: 12.5px; cursor: pointer;
  transition: border-color .15s, color .15s, background .15s; }
.qs-break:hover { border-color: var(--accent); color: var(--accent); }
.qs-break.on { background: var(--accent-dim); border-color: var(--accent); color: var(--text); }
.qs-break-out { grid-area: break; width: 100%; }
.qs-break-out:empty { display: none; }
/* On-demand "natural version" (the LLM idiomatic layer). Kept in the accent family, dashed like
   the other opt-in online action, so it reads as "ask for more" rather than a primary result. */
.qs-nat { margin-top: 10px; }
.qs-nat-btn {
  cursor: pointer; background: none; border: 1px dashed var(--accent-dim); color: var(--accent);
  font: inherit; font-size: 13px; padding: 7px 14px; border-radius: 10px;
  transition: background .15s, color .15s, border-style .15s;
}
.qs-nat-btn:hover:not(.loading) { background: var(--accent); color: #fff; border-style: solid; }
.qs-nat-btn.loading { opacity: .7; cursor: default; }
.qs-nat-out { margin-top: 6px; }
.qs-nat-out:empty { display: none; }
/* Ask for a gendered / plural reading. Reuses the app's segmented control rather than inventing a
   third button shape, so "pick one of these" looks the same here as everywhere else — and the
   accent-fill contrast rule at the end of this file already covers .seg-btn.on. */
.qs-form { margin-top: 12px; display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; }
.qs-form-lbl { font-size: 13px; color: var(--text-dim); }
.qs-form-btn { font-size: 12.5px; padding: 6px 11px; }
.qs-form.loading .qs-form-btn { opacity: .7; cursor: default; }
/* Full-width so results start on their own line under the chips, not squeezed beside them. */
.qs-form-out { flex: 1 0 100%; margin-top: 2px; }
.qs-form-out:empty { display: none; }
@media (max-width: 700px) {
  .qs-form-lbl { flex: 1 0 100%; }
  .qs-form-btn { padding: 7px 9px; }
}
.mw-grid { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
.mw { flex: 1 1 auto; min-width: 92px; padding: 11px 9px; background: var(--bg-card-hover);
  border: 1px solid var(--border); border-radius: 10px; text-align: center;
  transition: border-color .15s ease; --he-size: 22px; }
.mw:hover { border-color: var(--accent-dim); }
.mw-he { font-family: 'Frank Ruhl Libre', 'David', serif; font-size: var(--he-size); color: var(--text); line-height: 1.2; }
/* Was 18px against a 22px printed form — the cursive a learner is decoding was the smallest thing
   in the cell. Same knob as everywhere else now. */
.mw-cursive { font-family: 'KtavYad', cursive; direction: rtl;
  font-size: calc(var(--he-size) * var(--cursive-scale)); color: var(--text-dim); margin-top: 2px; }
.mw-tr { font-size: 12px; color: var(--accent); margin-top: 3px; }
.mw-gloss { font-size: 13px; color: var(--text); margin-top: 2px; }
.mw-root { font-family: 'Frank Ruhl Libre', 'David', serif; font-size: 14px; color: var(--text-faint); margin-top: 4px; }
.mw-morph { font-size: 11px; color: var(--text-dim); margin-top: 5px; }
.mw-gnp { font-size: 10px; color: var(--text-faint); margin-top: 1px; }

/* --- Card tools row: listen · copy · save (right, under the Hebrew) + break (far left) ---
   Round icon buttons in the same visual language as the lesson play button, so the same
   gesture means the same thing on a lesson row and on a translation. */
.qs-tools { grid-area: tools; display: flex; align-items: center; gap: 8px; }
.qs-actions { grid-area: actions; display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
.qs-tool {
  width: 40px; height: 40px; padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--border); color: var(--text-dim);
  font-size: 0; cursor: pointer; transition: all .2s ease;
}
.qs-tool::before {
  content: ""; width: 16px; height: 16px; background: currentColor;
  -webkit-mask: var(--qs-icon) no-repeat center / contain;
          mask: var(--qs-icon) no-repeat center / contain;
}
.qs-tool:hover { border-color: var(--accent); background: var(--accent); color: #fff; transform: scale(1.05); }
.qs-tool:active { transform: scale(0.95); }
.qs-copy { --qs-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M16 1H4a2 2 0 0 0-2 2v14h2V3h12V1zm3 4H8a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2zm0 16H8V7h11v14z'/></svg>"); }
.qs-save { --qs-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M17 3H7a2 2 0 0 0-2 2v16l7-3 7 3V5a2 2 0 0 0-2-2zm0 15-5-2.18L7 18V5h10v13z'/></svg>"); }
/* Confirmed states: the icon itself changes (a tick, a filled bookmark), so the feedback does
   not depend on colour alone. */
.qs-copy.done {
  --qs-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/></svg>");
  border-color: var(--accent); background: var(--accent-dim); color: var(--accent);
  animation: qs-pop .32s ease;
}
.qs-copy.failed { border-color: var(--error); color: var(--error); }
.qs-save.on {
  --qs-icon: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M17 3H7a2 2 0 0 0-2 2v16l7-3 7 3V5a2 2 0 0 0-2-2z'/></svg>");
  border-color: var(--accent); background: var(--accent-dim); color: var(--accent);
  cursor: default; animation: qs-pop .32s ease;
}
.qs-copy.done:hover, .qs-save.on:hover { background: var(--accent-dim); color: var(--accent); transform: none; }
@keyframes qs-pop { 0% { transform: scale(1); } 45% { transform: scale(1.16); } 100% { transform: scale(1); } }

/* Personal phrasebook (My phrases) */
.phrases-card { max-width: 520px; }
.ph-tabs, .ph-search { margin-bottom: 12px; }
.ph-search { width: 100%; }
.ph-list { max-height: 58vh; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; }
.ph-empty { color: var(--text-dim); font-size: 14px; text-align: center; padding: 26px 8px; }
.ph-row { display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px; background: var(--bg-card-hover);
  border: 1px solid var(--border); border-radius: 10px; }
.ph-tools { flex: 0 0 auto; display: flex; flex-direction: column; gap: 8px; margin-top: 2px; }
.ph-play { flex: 0 0 auto; }
.ph-text { flex: 1 1 auto; min-width: 0; }
.ph-he { font-family: 'Frank Ruhl Libre', 'David', serif; font-size: 22px; color: var(--text); line-height: 1.3; text-align: right; }
/* Same right-anchoring as a translator card: the latin lines read left-to-right but sit under
   the Hebrew they gloss, instead of drifting to the opposite edge of the row. */
.ph-tr, .ph-en, .ph-date { direction: ltr; text-align: right; }
.ph-tr { font-size: 13px; color: var(--accent); margin-top: 3px; }
.ph-en { font-size: 13px; color: var(--text-dim); margin-top: 2px; }
.ph-date { font-size: 11px; color: var(--text-faint); margin-top: 3px; }
.ph-note { width: 100%; margin-top: 8px; padding: 6px 9px; background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 7px; color: var(--text); font-family: inherit; font-size: 13px; }
.ph-note:focus { border-color: var(--accent); outline: none; }
.ph-del { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; background: transparent; border: 1px solid var(--border);
  color: var(--text-dim); font-size: 16px; line-height: 1; cursor: pointer; transition: all .14s; }
.ph-del:hover { border-color: #ef4444; color: #ef4444; }

/* Keyboard focus for the (now focusable) reveal cells */
.word-row .translit:focus-visible, .word-row .fr:focus-visible,
.tb-translit:focus-visible, .tb-fr:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px;
}

/* Lesson header on mobile: one compact top row (title + back/translator/menu), then the
   01-05 nav and the niqqud pill on a second row — instead of ~5 stacked rows. */
@media (max-width: 700px) {
  header.lesson-topbar { flex-direction: row !important; flex-wrap: wrap !important; align-items: center !important; }
  header.lesson-topbar > div:first-child { flex: 1 1 auto; min-width: 0; order: 1; }
  header.lesson-topbar > .hub-actions { order: 2; }
  header.lesson-topbar > .nav { order: 3; flex: 0 1 auto; }
  header.lesson-topbar > .niqqud-toggle { order: 4; margin-left: auto; }
  header.lesson-topbar > .cursive-toggle { order: 5; }
}

/* =====================================================================
 * PRODUCTION PRACTICE — Sentence Builder / Frames / Situations
 * Launchers live in the lesson exercise panel; each opens a focused modal
 * that reuses the SRS shell (.srs-overlay / .srs-card). Theme-aware via tokens.
 * ===================================================================== */

/* Launch row inside the exercise panel (production comes first, above the tabs) */
.ex-produce { margin-bottom: 16px; padding: 14px 16px; background: var(--bg-card); border: 1px solid var(--border); border-radius: 6px; }
.ex-produce-label { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-faint); margin-bottom: 10px; }
.ex-produce-row { display: flex; flex-wrap: wrap; gap: 10px; }
.ex-produce-btn { background: var(--bg-card-hover); border: 1px solid var(--border); color: var(--text); padding: 10px 16px; border-radius: 6px; cursor: pointer; font-family: inherit; font-size: 14px; transition: all .15s; }
.ex-produce-btn:hover { border-color: var(--accent); color: var(--accent); }
.ex-produce-btn.primary { background: var(--accent-dim); border-color: var(--accent); color: var(--accent); }

/* Modal shell (mirrors #srs-modal positioning) */
#prod-modal { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center; padding: 20px; }
#prod-modal .prod-card { max-width: 600px; min-height: auto; text-align: left; }

/* Sentence Builder */
.sb-prompt { font-size: 18px; color: var(--text); margin: 6px 0 16px; }
.sb-answer { min-height: 56px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding: 12px; background: var(--bg); border: 1px dashed var(--border); border-radius: 8px; direction: rtl; }
.sb-placeholder { color: var(--text-faint); font-size: 14px; direction: ltr; }
.sb-tray { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; direction: rtl; }
.sb-tile { font-family: 'Frank Ruhl Libre', 'David', serif; font-size: 22px; line-height: 1.2; padding: 8px 14px; background: var(--bg-card-hover); border: 1px solid var(--border); border-radius: 8px; color: var(--text); cursor: pointer; transition: all .13s; }
.sb-tile:hover:not(:disabled) { border-color: var(--accent); transform: translateY(-1px); }
.sb-tile:disabled { cursor: default; opacity: 0.85; }
.sb-placed { background: var(--accent-dim); border-color: var(--accent); }
.sb-feedback { min-height: 20px; margin-top: 14px; font-size: 14px; }
.sb-feedback.ok { color: var(--accent); }
.sb-feedback.bad { color: #ef4444; }
html.light .sb-feedback.bad { color: #dc2626; }
.sb-breakdown { display: none; margin-top: 14px; }
.sb-actions { display: flex; gap: 10px; justify-content: flex-end; }
.sb-actions .btn { flex: 0 0 auto; }

/* Substitution Frames */
.fr-frame { font-family: 'Frank Ruhl Libre', 'David', serif; font-size: 30px; text-align: center; margin: 8px 0 6px; color: var(--text); }
.fr-blank { color: var(--accent); border-bottom: 2px dashed var(--accent); padding: 0 10px; }
.fr-sub { text-align: center; color: var(--text-dim); font-size: 14px; margin-bottom: 18px; }
.fr-slots { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; }
.fr-slot { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 10px 16px; background: var(--bg-card-hover); border: 1px solid var(--border); border-radius: 10px; cursor: pointer; font-family: inherit; transition: all .14s; }
.fr-slot span[dir="rtl"] { font-family: 'Frank Ruhl Libre', 'David', serif; font-size: 22px; color: var(--text); }
.fr-slot-fr { font-size: 12px; color: var(--text-faint); }
.fr-slot:hover { border-color: var(--accent); }
.fr-slot.on { background: var(--accent-dim); border-color: var(--accent); }
.fr-result { display: flex; align-items: center; justify-content: center; gap: 12px; min-height: 60px; margin: 18px 0 6px; }
.fr-full { font-family: 'Frank Ruhl Libre', 'David', serif; font-size: 28px; color: var(--text); }
.fr-play { flex: 0 0 auto; }

/* Situations */
.sit-q { font-size: 17px; color: var(--text); margin: 6px 0 16px; }
.sit-options { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.sit-option { font-family: 'Frank Ruhl Libre', 'David', serif; font-size: 22px; padding: 14px 12px; background: var(--bg-card-hover); border: 1px solid var(--border); border-radius: 8px; color: var(--text); cursor: pointer; transition: all .14s; }
.sit-option:hover:not(:disabled) { border-color: var(--accent); }
.sit-option:disabled { cursor: default; }
.sit-option.correct { background: var(--accent-dim); border-color: var(--accent); color: var(--accent); }
.sit-option.wrong { background: rgba(239,68,68,0.15); border-color: #ef4444; color: #ef4444; }
.sit-feedback { min-height: 20px; margin-top: 14px; font-size: 14px; }
.sit-feedback.ok { color: var(--accent); }
.sit-feedback.bad { color: #ef4444; }
html.light .sit-feedback.bad { color: #dc2626; }

@media (max-width: 600px) {
  #prod-modal .prod-card { padding: 22px 16px 18px !important; }
  .sb-tile, .sit-option { font-size: 20px; }
  .sit-options { grid-template-columns: 1fr; }
  .fr-frame, .fr-full { font-size: 24px; }
}

/* Text-on-accent contrast (WCAG 1.4.3). White on the dark-theme accent (#4A9EDB) is ~2.9:1;
   on accent-FILLED controls use black text in dark mode. The darker light accent (#0071B9)
   keeps white. Placed last so it wins over the base rules at equal specificity. */
.srs-btn.active,
.fc-badge-due,
.seg-btn.on,
.qs-online-btn:hover:not(:disabled),
.qs-tool:hover,
.qs-nat-btn:hover:not(.loading) { color: #000; }
html.light .srs-btn.active,
html.light .fc-badge-due,
html.light .seg-btn.on,
html.light .qs-online-btn:hover:not(:disabled),
html.light .qs-tool:hover,
html.light .qs-nat-btn:hover:not(.loading) { color: #fff; }
/* accent text on accent-dim bg was borderline (~4.47:1) — brighten in dark only. */
.quiz-option.correct { color: #7ec2f0; }

/* ---------------------------------------------------------------- autoscroll
   The liturgy pages (songs, tehilim, prayers, shabbat) get a play button that
   creeps the page down while both hands stay on the instrument. Docked bottom
   centre: these pages carry no other floating control, and centre is where a
   thumb lands when the phone is on a stand. Built by assets/autoscroll.js. */
.as-bar {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 18px;
  z-index: 90;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  border-radius: 999px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
}
.light .as-bar { box-shadow: 0 6px 24px rgba(0, 0, 0, 0.12); }
.as-bar.is-playing { border-color: var(--accent); }

.as-play {
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--border);
  cursor: pointer;
  font-family: inherit;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
/* The glyph is a mask, like the lesson play buttons: a text ▶ renders soft and
   sits off-centre, and swapping it for ❚❚ would change the button's width. */
.as-play::before {
  content: "";
  width: 14px;
  height: 14px;
  margin-left: 2px;                 /* optical centring of the triangle */
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M8 5v14l11-7z'/></svg>") no-repeat center / contain;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M8 5v14l11-7z'/></svg>") no-repeat center / contain;
}
.as-play.as-playing::before {
  margin-left: 0;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M6 5h4v14H6zM14 5h4v14h-4z'/></svg>") no-repeat center / contain;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M6 5h4v14H6zM14 5h4v14h-4z'/></svg>") no-repeat center / contain;
}
.as-play:hover { background: var(--accent); color: #fff; border-color: var(--accent); }
.as-play.as-playing { background: var(--accent); color: #fff; border-color: var(--accent); }

.as-step {
  width: 32px;
  height: 32px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text-dim);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  font-family: inherit;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.as-step:hover:not(:disabled) { color: var(--accent); border-color: var(--accent); }
.as-step:disabled { opacity: 0.35; cursor: default; }

.as-readout {
  min-width: 20px;
  text-align: center;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
  cursor: default;
}
.as-bar.is-playing .as-readout { color: var(--accent); }
.as-play:focus-visible,
.as-step:focus-visible,
.as-readout:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (max-width: 700px) { .as-bar { bottom: 12px; } }
@media print { .as-bar { display: none !important; } }

/* ===== Chord chart: shuffle bar (assets/chords.js) =====
   The rest of the chord-chart CSS still lives in each song page's <style> block.
   Only what the shared module adds is defined here. */
.cx-bar { margin-top: 14px; border-top: 1px solid var(--border); padding-top: 12px;
  font-family: -apple-system, 'Inter', sans-serif; }
.cx-controls { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cx-btn { background: var(--bg); border: 1px solid var(--border); color: var(--text);
  padding: 6px 12px; border-radius: 4px; font-size: 12px; cursor: pointer;
  font-family: inherit; transition: background .15s, border-color .15s, color .15s; }
.cx-btn:hover { border-color: var(--accent); color: var(--accent); }
.cx-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.cx-btn.cx-primary { border-color: var(--accent); color: var(--accent); font-weight: 600; }
.cx-btn.cx-primary:hover { background: var(--accent); color: #0a0a0a; }
html.light .cx-btn.cx-primary:hover { color: #fff; }
.cx-btn.cx-on { background: var(--accent); color: #0a0a0a; border-color: var(--accent); }
html.light .cx-btn.cx-on { color: #fff; }
.cx-btn.cx-ghost { color: var(--text-dim); font-size: 11px; }
.cx-field { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: var(--text-faint); }
.cx-field span { text-transform: uppercase; letter-spacing: 1px; }
.cx-field select { background: var(--bg); border: 1px solid var(--border); color: var(--text);
  padding: 4px 6px; border-radius: 4px; font-size: 12px; font-family: inherit;
  cursor: pointer; max-width: 190px; }
.cx-field select:hover, .cx-field select:focus { border-color: var(--accent); outline: none; }
.cx-note { margin-top: 11px; padding: 10px 13px; border-left: 2px solid var(--accent);
  background: var(--bg-card-hover, var(--bg-card)); border-radius: 0 4px 4px 0;
  font-size: 12.5px; line-height: 1.55; color: var(--text-dim); }
.cx-note .cx-head { color: var(--text); font-size: 13px; margin-bottom: 3px; }
.cx-note .cx-degrees { font-family: 'JetBrains Mono', 'Consolas', monospace;
  font-size: 11.5px; color: var(--accent); letter-spacing: .4px; margin-bottom: 6px; }
.cx-note .cx-why { margin-top: 4px; }
.cx-note .cx-dim { color: var(--text-faint); }
.cx-extras { margin-top: 7px; display: flex; flex-direction: column; gap: 3px; }
.cx-extras span { font-size: 11.5px; color: var(--text-faint); }
.cx-extras span::before { content: '+ '; color: var(--accent); }
.cx-warn { margin-top: 9px; font-size: 11.5px; color: var(--text-faint); line-height: 1.5; }
.tt-custom-badge.tt-gen { opacity: .62; font-weight: 400; }
@media (max-width: 700px) {
  .cx-controls { gap: 6px; }
  .cx-field select { max-width: 140px; }
}
@media print { .cx-bar { display: none !important; } }
