/* ============================================
   COMPONENTS — Cards, buttons, badges, sections,
   reader styles, lesson styles, drill styles, SRS
============================================ */

/* ---- Section title ---- */

.section-title {
  font-size: 20px;
  margin-bottom: 15px;
  color: var(--primary);
}

/* ---- Generic card ---- */

.card {
  background: var(--surface);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  margin-bottom: 15px;
  cursor: pointer;
  transition: border-color .2s, transform .2s;
}

.card:hover {
  border-color: var(--primary);
  transform: translateY(-2px);
}

.card h3 {
  font-size: 18px;
  margin-bottom: 5px;
  color: var(--text);
}

.card p {
  font-size: 14px;
  color: var(--text);
  opacity: .8;
}

/* ---- Level badge ---- */

.level-badge {
  display: inline-block;
  background: var(--border);
  color: var(--primary);
  padding: 4px 12px;
  border-radius: var(--radius-sm);
  font-size: 12px;
  margin-top: 10px;
  font-weight: bold;
}

/* ---- Buttons ---- */

.btn-primary {
  background: var(--primary);
  color: #fff;
  padding: 12px;
  border-radius: var(--radius-sm);
  font-size: 16px;
  border: none;
}

.btn-primary:hover {
  background: var(--primary-dark);
}

.btn-accent {
  background: var(--accent);
  color: #fff;
  padding: 12px;
  border-radius: var(--radius-sm);
  font-size: 16px;
  border: none;
}

.btn-accent:hover {
  background: var(--accent-dark);
}

/* A typographic action, not a filled box — matches .wk-back/.level-back. */
.btn-back {
  margin-left: auto;
  background: none;
  color: var(--primary-mid);
  padding: 6px 4px;
  font-size: 14px;
}

.btn-back:hover {
  color: var(--primary);
}

/* ============================================
   READER — Word colors, story cards, story view
============================================ */

/* Word tap base */
.word {
  cursor: pointer;
  padding: 2px 0;
  border-radius: 3px;
  border-bottom: 1px dotted var(--secondary);
  transition: background .2s;
}

.word:hover {
  background: var(--border);
}

/* Unknown — not in deck */
.word-unknown {
  border-bottom: 2px dotted var(--secondary);
  color: var(--text);
}

/* Seen — in deck, 0 reviews */
.word-seen {
  color: var(--secondary);
  border-bottom: 2px dotted var(--secondary);
}

/* Known — 1+ reviews */
.word-known {
  color: var(--primary-mid);
  border-bottom: 2px solid var(--primary-mid);
}

/* Mastered — 3+ reviews */
.word-mastered {
  color: var(--primary);
  font-weight: 500;
  border-bottom: none;
}

/* Library — reading rooms (one per CEFR level, collapsible) */
.reading-room {
  margin-bottom: 28px;
}

.reading-room-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  width: 100%;
  background: none;
  text-align: left;
  border-bottom: 2px solid var(--border);
  padding: 0 0 6px;
  margin-bottom: 14px;
}

.reading-room-header:hover .reading-room-title {
  color: var(--primary-dark);
}

.reading-room-title {
  color: var(--primary);
  font-size: 1.05em;
  text-transform: uppercase;
  letter-spacing: .05em;
}

.reading-room-count {
  font-size: .8em;
  color: var(--muted);
}

.reading-room-arrow {
  font-size: .8em;
  color: var(--secondary);
  flex-shrink: 0;
  margin-left: 12px;
}

.reading-room-body.hidden {
  display: none;
}

.reading-room-empty {
  font-style: italic;
  padding: 4px 0 8px;
}

/* Only rendered once a room passes SEARCH_THRESHOLD in reader.js —
   filters that room's own cards by title as you type. */
.reading-room-search {
  margin: 0 0 16px;
}

.reading-room-search-input {
  width: 100%;
  padding: 10px 14px;
  font-size: .95rem;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
}

.reading-room-search-input:hover {
  border-color: var(--primary-mid);
}

.reading-room-search-input:focus {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
  border-color: var(--primary);
}

/* Library — shelves (one per story type within a room) */
.story-shelf {
  margin-bottom: 20px;
}

.story-shelf-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  width: 100%;
  background: none;
  border: none;
  text-align: left;
  padding: 4px 0 8px;
  cursor: pointer;
}

.story-shelf-header:hover .story-shelf-title {
  color: var(--text);
}

.story-shelf-title {
  color: var(--muted);
  font-size: .85em;
  font-weight: 600;
  margin: 0;
}

.story-shelf-count {
  font-weight: 400;
  opacity: .8;
}

.story-shelf-arrow {
  font-size: .75em;
  color: var(--secondary);
  flex-shrink: 0;
  margin-left: 12px;
}

.story-shelf-body.hidden {
  display: none;
}

/* Story library — book cards */
.story-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 14px;
  margin-bottom: 20px;
}

.story-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0;
  text-align: left;
  cursor: pointer;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: border-color var(--dur-fast) var(--ease-standard);
}

.story-card:hover {
  border-color: var(--primary);
}

/* Switched 2026-08-14 from four flat navy-shade backgrounds + one shared
   book glyph to the disc language (PATH_SHAPES, engine/curriculum.js) —
   see [[preferred-disc-art-language]]. One wash background rather than
   four navy variants: the disc's own two-tone shape now carries per-story
   variety, so the background doesn't need to as well. */
.story-card-cover {
  position: relative;
  height: 84px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--wash);
}

.story-card-cover-icon {
  width: 52px;
  height: 52px;
}

/* Muted deliberately: a shelf can hold dozens of these at once, so the
   disc language's usual orange accent (tuned for a handful of items) is
   toned down to a soft navy instead of full --accent orange here. */
.story-card-cover-icon .ps-accent {
  fill: var(--primary-mid);
}

.story-card-read-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  font-size: 12px;
  line-height: 20px;
  text-align: center;
}

.story-card-body {
  padding: 10px 12px 12px;
}

.story-card-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1em;
  color: var(--text);
  margin-bottom: 6px;
  line-height: 1.3;
}

.story-card-meta {
  font-size: .8em;
  color: var(--muted);
}

.story-card-badge {
  display: inline-block;
  background: var(--border);
  color: var(--primary);
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: .9em;
  font-weight: 600;
}

/* Story reading view */

.story-attribution {
  font-size: .85em;
  font-style: italic;
  color: var(--muted);
  border-top: 1px solid var(--border);
  padding-top: 12px;
  margin: 20px 0 0;
}

.story-attribution em {
  font-style: italic;
}

.story-finish {
  display: flex;
  justify-content: center;
  margin: 28px 0 8px;
}

.story-finish .btn-primary {
  padding: 12px 24px;
}

.story-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

/* Groups Save + Back (or just Back, for a My Text) so a single margin-left:
   auto pushes the pair to the right edge together — giving each button its
   own auto margin would split the leftover space between them instead. */
.story-header-actions {
  display: flex;
  gap: 8px;
  margin-left: auto;
}

.story-title {
  font-family: var(--font-display);
  font-weight: 400;
  margin: 0;
  font-size: 1.4em;
  color: var(--text);
}

.story-level-badge {
  background: var(--primary);
  color: #fff;
  padding: 2px 10px;
  border-radius: var(--radius-sm);
  font-size: .8em;
}

.story-paragraph {
  line-height: 1.8;
  margin-bottom: 12px;
  color: var(--text);
}

.story-paragraph.dialogue {
  margin-left: 16px;
  padding-left: 12px;
  border-left: 3px solid var(--primary);
}

.speaker-label {
  font-weight: 600;
  color: var(--accent);
}

/* ============================================
   LIBRARY — Parlour / Saved / My Texts subnav, and the two sections that
   sit alongside the existing reading-room UI above.
   ============================================ */

.lt-subnav {
  display: flex;
  gap: 20px;
  border-bottom: 2px solid var(--border);
  margin-bottom: 22px;
}

.lt-subnav-btn {
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
  padding: 10px 2px;
  font-family: var(--font-display);
  font-size: 15px;
  color: var(--muted);
  cursor: pointer;
}

.lt-subnav-btn:hover { color: var(--primary-dark); }

.lt-subnav-btn.active {
  color: var(--primary);
  border-bottom-color: var(--primary);
  font-weight: 600;
}

/* ----- Saved ----- */

/* A div standing in for story-card's own <button> root, since a saved card
   needs a second, separate Remove control a nested button couldn't hold. */
.lt-saved-card { display: flex; flex-direction: column; }

.story-card-open {
  background: none;
  border: none;
  padding: 0;
  text-align: left;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  width: 100%;
}

.lt-saved-remove {
  margin: 0 12px 12px;
  padding: 6px 10px;
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 12px;
  color: var(--muted);
  cursor: pointer;
}

.lt-saved-remove:hover { border-color: var(--danger); color: var(--danger); }

/* ----- My Texts ----- */

.lt-index-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.lt-list { display: flex; flex-direction: column; }

.lt-card {
  display: flex;
  align-items: center;
  gap: 10px;
  background: none;
  border: none;
  border-bottom: 1px solid var(--border);
  padding: 4px 4px 4px 10px;
}

.lt-card-main {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
  text-align: left;
  background: none;
  border: none;
  padding: 12px 0;
  cursor: pointer;
}

.lt-card-title { font-family: var(--font-display); font-size: 16px; color: var(--primary); }
.lt-card-meta { font-size: 12px; color: var(--muted); }
.lt-card-coverage { font-size: 12px; color: var(--primary); font-weight: 600; }

.lt-card-actions { display: flex; gap: 6px; flex: 0 0 auto; }

.lt-card-action {
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  font-size: 13px;
  color: var(--muted);
  cursor: pointer;
}

.lt-card-action:hover { border-color: var(--primary); color: var(--primary); }
.lt-card-action-danger:hover { border-color: var(--danger); color: var(--danger); }

/* Add/edit text editor — reuses the Deck editor's input/label/actions
   classes (dk-editor-*) for a consistent form language across the app. */
.lt-text-area { min-height: 220px; resize: vertical; line-height: 1.6; }

.lt-analyse-row { margin: 6px 0 4px; }

.lt-analysis {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 16px;
  margin: 6px 0 16px;
}

.lt-analysis-headline {
  font-family: var(--font-display);
  font-size: 16px;
  color: var(--primary);
  margin-bottom: 4px;
}

.lt-analysis-line { font-size: 13px; color: var(--muted); margin-bottom: 8px; }

.lt-analysis-coverage {
  font-family: var(--font-display);
  font-size: 24px;
  color: var(--primary);
  margin-bottom: 10px;
}

.lt-analysis-breakdown {
  list-style: none;
  font-size: 13px;
  color: var(--text);
  display: flex;
  flex-direction: column;
  gap: 3px;
}

/* Vocabulary selection — nests inside the analysis panel, reusing the
   dk-group-header/-body collapsible primitive from Decks. */
.lt-vocab-group { margin-top: 14px; }

.lt-vocab-category { margin: 12px 0; }

.lt-vocab-category-title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--muted);
  margin-bottom: 6px;
}

.lt-vocab-list {
  list-style: none;
  max-height: 220px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}

.lt-vocab-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  font-size: 13px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
}

.lt-vocab-list li:last-child .lt-vocab-item { border-bottom: 0; }

.lt-vocab-es { color: var(--primary); flex: 0 0 auto; }
.lt-vocab-en {
  color: var(--muted);
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lt-vocab-actions { margin-top: 12px; }

/* ============================================
   DRILLS — Conjugation input rows
============================================ */

.drill-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}

.drill-row:last-child {
  border-bottom: none;
}

.drill-row input {
  width: 120px;
  padding: 8px;
  border: none;
  border-bottom: 2px solid var(--border);
  border-radius: 0;
  background: none;
  text-align: center;
  font-size: 16px;
  color: var(--text);
}

.drill-row input.correct {
  border-bottom-color: var(--success);
  color: var(--success);
}

.drill-row input.wrong {
  border-bottom-style: dashed;
  border-bottom-color: var(--danger);
  color: var(--danger);
}

/* ============================================
   LESSON RENDERER COMPONENTS
============================================ */

/* The level's own mark, carried into the lesson itself — the one place the
   geometric language needs to persist across every step, not just the
   level/unit screens on the way in. */
#lesson-subtitle {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 13px;
}

/* A thin line with an orange segment marking how far in the learner is —
   not a thick filled bar. See parlour_visual_overhaul_spec.md section 19. */
.lsn-progress {
  height: 1px;
  background: var(--border);
  border-radius: 0;
  overflow: visible;
  margin-bottom: 10px;
}

.lsn-progress-bar {
  height: 100%;
  background: var(--accent-dark);
  transition: width var(--dur-base) var(--ease-standard);
}

.lsn-progress-label {
  font-size: 12px;
  color: var(--text);
  opacity: .6;
  margin-bottom: 16px;
}

/* Close button, title block, and the sound toggle in one row — previously
   unstyled (block-stacked on whatever the browser default gave buttons and
   headings), which was fine with just two children but left no sane place
   to put a third. */
.lesson-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.lesson-sound-btn {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: none;
  color: var(--muted);
}

.lesson-sound-btn:hover {
  color: var(--primary);
}

.lesson-sound-btn .icon {
  width: 20px;
  height: 20px;
}

.lesson-sound-btn .icon .ink-line { stroke: currentColor; }

.lsn-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 24px;
  margin-bottom: 15px;
  color: var(--text);
}

.lsn-text {
  line-height: 1.7;
  color: var(--text);
  margin-bottom: 12px;
}

.lsn-hint {
  font-size: 13px;
  color: var(--text);
  opacity: .65;
  margin-top: 10px;
}

.lsn-subtitle {
  font-size: 16px;
  color: var(--text);
  margin: 18px 0 8px;
}

.lsn-subtitle:first-child {
  margin-top: 0;
}

/* End-of-lesson summary — one quiet beat before returning to whatever tab
   the lesson was opened from. Centred and mostly empty, like the page
   headers' own frontispieces, rather than a "results screen" grid — this
   is a close of a lesson, not a scoreboard. */
.lsn-summary {
  text-align: center;
  padding: 24px 0 8px;
}

.lsn-summary-eyebrow {
  font-size: 13px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .06em;
}

.lsn-summary-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 30px;
  color: var(--text);
  margin: 6px 0;
}

.lsn-summary-lesson {
  font-size: 14px;
  color: var(--muted);
}

.lsn-summary-art {
  width: 100%;
  max-width: 260px;
  height: auto;
  max-height: 88px;
  margin: 20px auto;
}

.lsn-summary-stats {
  display: flex;
  justify-content: center;
  gap: 48px;
  margin-top: 8px;
}

.lsn-summary-stat .jr-big {
  margin-bottom: 2px;
}

.lsn-summary-streak {
  font-size: 13px;
  color: var(--muted);
  margin-top: 14px;
}

.lsn-summary-milestone {
  font-size: 14px;
  color: var(--text);
  font-weight: 600;
  margin-top: 8px;
}

.lsn-summary-words {
  margin-top: 24px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

.lsn-summary-words-label {
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 10px;
}

.lsn-word-chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-bottom: 16px;
}

.lsn-word-chip {
  font-size: 13px;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 4px 10px;
}

/* "Quick Reinforce" — see summaryReinforceHtml() in engine/lessons.js.
   Same hairline-divider language as .lsn-summary-words above it, so the
   two read as siblings rather than one being an afterthought. */
.lsn-summary-reinforce {
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}

.lsn-summary-reinforce-label {
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 10px;
}

.lsn-summary-reinforce-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
}

/* Continue stays locked until a gated step is answered */
.btn-primary:disabled,
.btn-primary.is-locked {
  opacity: .4;
  cursor: not-allowed;
}

.btn-primary:disabled:hover,
.btn-primary.is-locked:hover {
  background: var(--primary);
}

/* Shown when a learner runs out of attempts */
.lsn-reveal {
  border: 1px solid var(--border);
  border-left: 4px solid var(--secondary);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  margin-top: 12px;
  line-height: 1.8;
  color: var(--text);
}

.lsn-srs-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}

.lsn-srs-badge {
  margin-left: auto;
  font-size: 13px;
  color: var(--muted);
  font-style: italic;
}

.lsn-srs-toggle {
  display: flex;
  gap: 6px;
  margin-left: auto;
}

.lsn-srs-opt {
  padding: 6px 12px;
  font-size: 13px;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-standard),
              background-color var(--dur-fast) var(--ease-standard),
              color var(--dur-fast) var(--ease-standard);
}

.lsn-srs-opt:hover {
  border-color: var(--primary-mid);
}

.lsn-srs-opt.is-selected {
  border-color: var(--primary);
  background: rgba(16, 42, 71, 0.06);
  color: var(--primary);
  font-weight: 600;
}

.lsn-srs-opt:disabled {
  opacity: .6;
  cursor: not-allowed;
}

.lsn-goal {
  list-style: none;
  padding: 0;
  margin: 0;
}

.lsn-goal li {
  background: var(--bg);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  margin-bottom: 8px;
  color: var(--text);
}

.lsn-goal li::before {
  content: "\25C6 ";
  color: var(--accent);
}

.lsn-tip {
  background: var(--border);
  border-radius: var(--radius-sm);
  padding: 14px;
  margin-bottom: 12px;
}

.lsn-tip strong {
  color: var(--primary);
  display: block;
  margin-bottom: 4px;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .05em;
}

.lsn-tip p {
  color: var(--text);
  line-height: 1.6;
}

.lsn-table {
  width: 100%;
  border-collapse: collapse;
}

.lsn-table td {
  padding: 10px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
}

.lsn-example {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px;
  margin-bottom: 10px;
}

.lsn-es {
  font-size: 19px;
  color: var(--primary);
}

/* Grammar screens only (see stepRenderers.grammar() in engine/lessons.js):
   the target-language side of an example pair, and a table's first
   column, both set apart in italics from the English explaining them —
   the same distinction *word* markup gives inline prose via escMd(). Not
   applied to .lsn-es/.lsn-table generally, since those are shared by
   dialogue, vocabulary and matching steps that were never part of this
   ask. */
.lsn-grammar .lsn-es,
.lsn-grammar .lsn-table td:first-child strong {
  font-style: italic;
}

.lsn-en {
  color: var(--text);
  opacity: .75;
  font-size: 14px;
}

.lsn-pos {
  font-size: 11px;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: .05em;
}

/* The Continue button needs air, or the last line of a story sits on top
   of it. Applies to every step, so it fixes the checklist too. */
.lesson-footer {
  margin-top: 32px;
  display: flex;
  align-items: center;
  gap: 12px;
}

/* .btn-back normally sits alone at the end of a header row, hence its own
   margin-left: auto — here it shares the footer with the primary button, so
   that push is cancelled and the primary button grows to fill the rest. */
.lesson-footer .btn-back {
  margin-left: 0;
  flex-shrink: 0;
}

.lesson-footer .btn-primary {
  flex: 1;
}

.lesson-footer .btn-back:disabled {
  opacity: .35;
  cursor: not-allowed;
}

/* Grammar reference: a closing sentence with the source hyperlinked,
   rather than a bare link floating under the explanation. */
.lsn-reference {
  margin-top: 16px;
  line-height: 1.7;
  color: var(--text);
}

.lsn-reference a {
  color: var(--primary);
  font-weight: 600;
}

.lsn-link {
  display: inline-block;
  margin-top: 8px;
  color: var(--primary);
  font-weight: 600;
}

/* Model answer for a free-writing line, revealed on Check */
.lsn-model {
  display: none;
  margin-top: 8px;
  padding: 10px 12px;
  border-left: 3px solid var(--secondary);
  background: var(--bg);
  border-radius: 0 8px 8px 0;
}

.lsn-model.is-shown {
  display: block;
}

.lsn-model-label {
  display: block;
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 2px;
}

.lsn-vocab {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.lsn-vocab-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border-light);
  background: var(--bg);
}

.lsn-vocab-row:last-child {
  border-bottom: none;
}

.lsn-vocab-row-end {
  display: flex;
  align-items: center;
  gap: 10px;
}

.lsn-vocab-add {
  width: 24px;
  height: 24px;
  flex: none;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--muted);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}

.lsn-vocab-add:hover {
  border-color: var(--primary);
  color: var(--primary);
}

.lsn-dialogue,
.lsn-story {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.lsn-line {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}

.lsn-speaker {
  min-width: 64px;
  font-size: 12px;
  font-weight: 700;
  color: var(--accent);
  text-transform: uppercase;
  padding-top: 4px;
}

.lsn-narration {
  line-height: 1.7;
}

.lsn-question {
  margin-bottom: 15px;
  color: var(--text);
  line-height: 1.6;
  font-size: 16px;
}

.lsn-blank {
  display: inline-block;
  min-width: 70px;
  border-bottom: 2px solid var(--accent);
  text-align: center;
  color: var(--accent);
}

.lsn-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.lsn-tiles {
  flex-direction: row;
  flex-wrap: wrap;
}

/* Bordered, rounded box with a fill-tint highlight for state — reversed
   2026-08-14 (visual identity v2) from the underlined-typographic-object
   treatment. Matches the reference mockup's "Choose the right form". */
.lsn-option {
  position: relative;
  padding: 14px 16px;
  border: 1.5px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  cursor: pointer;
  text-align: left;
  font-size: 17px;
  color: var(--text);
  transition: color var(--dur-fast) var(--ease-standard),
              border-color var(--dur-fast) var(--ease-standard),
              background-color var(--dur-fast) var(--ease-standard),
              transform var(--dur-fast) var(--ease-standard),
              opacity var(--dur-fast) var(--ease-standard);
}

.lsn-option:hover {
  border-color: var(--primary-mid);
}

.lsn-option.selected {
  border-color: var(--primary);
  border-width: 2px;
  background: rgba(16, 42, 71, 0.05);
  color: var(--primary);
}

.lsn-option.correct {
  border-color: var(--success);
  background: var(--success-bg);
  color: var(--success);
  font-weight: 600;
}

.lsn-option.correct::after {
  content: "";
  position: absolute;
  right: 14px;
  top: 50%;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--success);
  transform: translateY(-50%);
}

.lsn-option.wrong {
  border-color: var(--danger);
  background: var(--danger-bg);
  color: var(--danger);
  opacity: .85;
  transform: translateX(-6px);
}

.lsn-option.used {
  opacity: .5;
}

@media (prefers-reduced-motion: reduce) {
  .lsn-option.wrong {
    transform: none;
  }
}

.lsn-tile {
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  cursor: pointer;
  font-size: 16px;
  color: var(--text);
}

.lsn-tile.used {
  opacity: .35;
}

/* The sentence being built. It holds tiles rather than text now — they are
   tapped to be taken back — so it lays out like the bank below it. */
.lsn-target {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  min-height: 48px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  padding: 12px;
  margin-bottom: 12px;
  font-size: 18px;
  color: var(--primary);
}

.lsn-target-empty {
  font-size: 15px;
  color: var(--muted);
}

/* The settled sentence, once checked: plain text, nothing left to tap. */
.lsn-built {
  font-size: 18px;
  color: var(--primary);
}

.lsn-built.is-correct {
  color: var(--success);
}

/* The translation, shown only after the sentence is settled. */
.lsn-build-en {
  margin: -4px 0 12px;
  font-size: 15px;
  color: var(--muted);
}

.lsn-match {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.lsn-match-col {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.lsn-input {
  width: 100%;
  padding: 12px;
  border: none;
  border-bottom: 2px solid var(--border);
  border-radius: 0;
  background: none;
  font-size: 16px;
  color: var(--text);
}

.lsn-input:focus {
  outline: none;
  border-bottom-color: var(--primary-mid);
}

.lsn-input.correct {
  border-bottom-color: var(--success);
}

.lsn-input.wrong {
  border-bottom-style: dashed;
  border-bottom-color: var(--danger);
}

.lsn-write-row {
  margin-bottom: 12px;
}

.lsn-write-row .lsn-en {
  margin-bottom: 6px;
}

.lsn-check {
  margin-top: 12px;
  margin-right: 8px;
  padding: 10px 16px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--primary);
  color: #fff;
  font-size: 15px;
  cursor: pointer;
}

.lsn-check.lsn-secondary {
  background: var(--secondary);
}

/* Listening exercises: the play button is the primary control, not the
   small inline speak-btn, since there is no visible Spanish to attach it
   to. */
.lsn-listen {
  margin-bottom: 16px;
}

.lsn-play {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 14px 20px;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--primary);
  color: #fff;
  font-size: 16px;
  cursor: pointer;
}

/* White on navy here, so the icon takes the button's own colour rather
   than its default navy stroke. */
.lsn-play .icon .ink-line,
.lsn-play .icon .ink-rule { stroke: currentColor; }

.lsn-check:disabled {
  opacity: .6;
  cursor: default;
}

.lsn-feedback {
  margin-top: 15px;
  font-weight: bold;
}

.lsn-checklist {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.lsn-check-item {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px;
  color: var(--text);
  cursor: pointer;
}

.lsn-check-item input {
  margin-top: 3px;
}

/* ============================================
   REVIEW / SRS FLASHCARD
============================================ */

.review-stats {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 16px;
  background: var(--bg);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 16px;
}

.review-stat {
  font-size: 13px;
  color: var(--muted);
}

.review-stat strong {
  font-weight: 700;
  color: var(--text);
  margin-left: 4px;
}

.review-clear-btn {
  margin-left: auto;
  padding: 5px 14px;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted);
  font-size: 12px;
  border: 1px solid var(--border);
  cursor: pointer;
}

.review-clear-btn:hover {
  color: var(--danger);
  border-color: var(--danger);
}

/* Direction switch: which side of the card shows first */

.dk-direction {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-bottom: 16px;
}

.dk-direction-label {
  font-size: 13px;
  color: var(--muted);
}

.dk-direction-label.dk-direction-active {
  color: var(--text);
  font-weight: 700;
}

/* The switch itself is .geo-toggle (styles/geometry.css) — navy circle for
   Spanish-first, orange triangle for English-first, per the shape-state
   system rather than a sliding pill. */

/* Empty state */

.review-empty {
  text-align: center;
  padding: 48px 20px;
}

.review-empty-icon {
  display: flex;
  justify-content: center;
  margin-bottom: 12px;
}

.review-empty-title {
  font-size: 18px;
  color: var(--primary);
  margin-bottom: 8px;
}

.review-empty-text {
  font-size: 14px;
  color: var(--muted);
  line-height: 1.5;
  margin-bottom: 4px;
}

/* Session summary — same quiet "close of an activity" treatment as
   .lsn-summary in engine/lessons.js, just under its own review- prefix
   rather than reusing lsn- classes outside a lesson context. Reuses the
   shared .jr-big/.jr-of stat primitives directly, same as that screen. */
.review-summary {
  text-align: center;
  padding: 40px 20px 24px;
}

.review-summary-eyebrow {
  font-size: 13px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: .06em;
}

.review-summary-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 30px;
  color: var(--text);
  margin: 6px 0 20px;
}

.review-summary-stats {
  display: flex;
  justify-content: center;
  gap: 48px;
}

.review-summary-streak {
  font-size: 13px;
  color: var(--muted);
  margin-top: 14px;
}

.review-summary-milestone {
  font-size: 14px;
  color: var(--text);
  font-weight: 600;
  margin-top: 8px;
}

.review-summary .dk-secondary {
  margin-top: 24px;
}

/* Flashcard */

/* .story-card, .review-stats and .review-card below all had the same
   pure-white --surface fill as .lsn-option/.gd-option before their
   2026-08-19/20 fixes — found by a computed-style DOM scan (getComputedStyle
   against rgb(255,255,255)) covering every tab's markup at once rather than
   spotting them one screen at a time, since the app keeps every tab's DOM
   mounted and just toggles visibility. Same fix, same reasoning: open rows
   on cream, not lifted white cards (see base.css's own --radius comment). */
.review-card {
  display: none;
  flex-direction: column;
  align-items: center;
  background: var(--bg);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  padding: 28px 20px 24px;
  transition: border-color .2s;
}

.review-card-front {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 24px 0 28px;
  width: 100%;
}

.review-card-type {
  font-size: 12px;
  font-weight: 600;
  color: var(--secondary);
  text-transform: uppercase;
  letter-spacing: .06em;
}

.review-card-word {
  font-size: 28px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.2;
}

.review-card-back {
  display: none;
  width: 100%;
  text-align: center;
  padding: 20px 0;
  border-top: 2px solid var(--border);
  margin-bottom: 20px;
}

.review-card-translation {
  font-size: 20px;
  color: var(--primary);
  font-weight: 600;
}

/* Show Answer button */

.review-show-btn {
  display: block;
  width: 100%;
  padding: 14px;
  background: var(--primary);
  color: #fff;
  border: none;
  border-radius: var(--radius-sm);
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
  transition: background .15s;
}

.review-show-btn:hover {
  background: var(--primary-dark);
}

/* Type mode — input + Check stands in for the Show Answer button */

.review-type-input {
  display: flex;
  gap: 8px;
  width: 100%;
}

.review-input {
  flex: 1;
  min-width: 0;
  padding: 12px;
  border: none;
  border-bottom: 2px solid var(--border);
  border-radius: 0;
  background: none;
  font-size: 16px;
  color: var(--text);
}

.review-input.correct {
  border-bottom-color: var(--success);
}

.review-input.wrong {
  border-bottom-style: dashed;
  border-bottom-color: var(--danger);
}

.review-type-input .review-show-btn {
  width: auto;
  padding: 14px 20px;
}

/* Rating buttons */

.review-ratings {
  display: none;
  width: 100%;
  gap: 8px;
  margin-top: 12px;
}

.review-rate {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 12px 4px 10px;
  border-radius: var(--radius-sm);
  border: none;
  color: #fff;
  text-align: center;
  cursor: pointer;
  transition: opacity .15s, transform .1s;
}

.review-rate:hover {
  opacity: .88;
  transform: translateY(-1px);
}

.review-rate:active {
  transform: translateY(0);
}

.review-rate-label {
  font-size: 14px;
  font-weight: 700;
}

.review-rate-time {
  font-size: 11px;
  opacity: .75;
}

/* Four hues read as four categories; these are one scale. Depth of ink
   carries the ordering, and every button is labelled, so nothing here
   depends on colour alone. Reversed 2026-08-14 (visual identity v2): the
   two extremes take the sparing SRS-only red/green (see --success in
   base.css); Hard/Good stay in the navy family. */
.review-rate-again { background: var(--danger); }
.review-rate-hard  { background: var(--secondary); }
.review-rate-good  { background: var(--primary-mid); }
.review-rate-easy  { background: var(--success); }

/* ============================================
   WORD POPUP — tap-to-translate sheet
============================================ */

.wp-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .5);
  z-index: 100;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.wp-sheet {
  background: var(--bg);
  width: 100%;
  max-width: 500px;
  border-radius: var(--radius) var(--radius) 0 0;
  padding: 24px;
  animation: slideUp .3s ease-out;
  max-height: 80vh;
  overflow-y: auto;
}

.wp-header {
  display: flex;
  justify-content: space-between;
  align-items: start;
  margin-bottom: 16px;
}

.wp-word {
  font-size: 28px;
  color: var(--primary);
  margin: 0;
}

.wp-analysis {
  color: var(--secondary);
  font-size: 14px;
  margin: 4px 0 0;
}

.wp-close {
  background: none;
  border: none;
  font-size: 24px;
  cursor: pointer;
  color: var(--secondary);
  line-height: 1;
}

.wp-lemma {
  font-size: 14px;
  color: var(--muted);
  margin-bottom: 8px;
}

.wp-lemma strong { color: var(--primary); }

/* Hungarian word-tap popup only, from HungarianMorphology.ladder() via
   engine/reader.js's _hungarianBreakdownHtml(). Replaces the plain
   .wp-lemma "from X" + .wp-meaning lines when a breakdown is available:
   contextual meaning up top (.wp-contextual, same visual weight as
   .wp-meaning normally carries), then the lemma/POS/gloss, the word's
   build-up as a compact arrow chain, then a per-suffix table. */
.wp-contextual {
  font-size: 20px;
  font-weight: 500;
  color: var(--text);
  margin-bottom: 12px;
}

.wp-lemma-block {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 8px 12px;
  margin-bottom: 10px;
}

.wp-lemma-pos {
  font-weight: 600;
  color: var(--primary);
  font-size: 14px;
}

.wp-lemma-gloss {
  color: var(--muted);
  font-size: 13px;
  margin-top: 2px;
}

.wp-chain {
  color: var(--muted);
  font-size: 13px;
  letter-spacing: .01em;
  margin-bottom: 10px;
}

.wp-suffixes { margin-bottom: 16px; }

.wp-suffix-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 3px 0;
}

.wp-suffix-form {
  font-weight: 600;
  color: var(--primary);
  font-size: 14px;
  min-width: 48px;
}

.wp-suffix-label {
  color: var(--muted);
  font-size: 13px;
}

.wp-why {
  background: var(--bg);
  border-left: 3px solid var(--primary);
  border-radius: var(--radius);
  padding: 8px 12px;
  margin-bottom: 12px;
}

.wp-why-q {
  font-weight: 600;
  color: var(--text);
  font-size: 13px;
  margin-bottom: 2px;
}

.wp-why-a {
  color: var(--muted);
  font-size: 13px;
  line-height: 1.4;
}

/* Hungarian word-tap popup only, from HungarianMorphology.splitCompound()
   via engine/reader.js's _compoundSplitHtml() — a last-resort guess for a
   word not in the dictionary at all, formed by splitting it into two
   known words ("haláltök" -> halál + tök). Always paired with a .wp-why
   caveat (see reader.js), so this only needs to lay out the two parts
   themselves. */
.wp-compound {
  display: flex;
  gap: 16px;
  margin-bottom: 12px;
}

.wp-compound-part {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 8px 12px;
  flex: 1;
}

.wp-compound-form {
  display: block;
  font-weight: 600;
  color: var(--primary);
  font-size: 14px;
}

.wp-compound-gloss {
  display: block;
  color: var(--muted);
  font-size: 13px;
  margin-top: 2px;
}

.wp-meaning {
  font-size: 20px;
  font-weight: 500;
  color: var(--text);
  margin-bottom: 16px;
}

.wp-empty {
  color: var(--muted);
  font-style: italic;
  margin-bottom: 16px;
}

/* Alternate readings — Spanish forms are often genuinely ambiguous */
.wp-alts {
  border-top: 1px solid var(--border);
  padding-top: 12px;
  margin-bottom: 16px;
}

.wp-alts-title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--muted);
  margin-bottom: 8px;
}

.wp-alt { margin-bottom: 8px; }

.wp-alt-lemma {
  font-weight: 600;
  color: var(--primary);
  font-size: 15px;
}

.wp-alt-meta {
  font-weight: 400;
  color: var(--muted);
  font-size: 12px;
  margin-left: 6px;
}

.wp-alt-en {
  font-size: 14px;
  color: var(--text);
}

.wp-cap {
  color: var(--accent);
  font-size: 13px;
  margin-bottom: 10px;
  display: none;
}

/* The Tier 2 "taught in Unit X · Lesson X.Y" cross-link — reuses
   .dk-link-btn's plain-underlined-text look (the app's established quiet
   meta-action treatment) but needs block layout to sit on its own line
   here rather than inline. */
.wp-lesson-link {
  display: block;
  margin: 4px 0 12px;
}

.wp-add {
  width: 100%;
  padding: 14px;
  background: var(--primary);
  color: #fff;
  border: none;
  border-radius: var(--radius-sm);
  font-size: 16px;
  cursor: pointer;
  font-weight: bold;
}

.wp-add.is-saved   { background: var(--secondary); cursor: default; }
.wp-add.is-disabled { background: var(--border); cursor: default; }

.wp-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Deliberately quieter than wp-add: adding to a personal deck is membership
   only, not a commitment to learn the word today, so it should not compete
   with the button that actually starts a review schedule. Background was
   --surface (pure white), standing out against the .wp-sheet popup it
   sits in (already correctly --bg/cream) as its own small white rectangle
   — same fix as everywhere else, found the same way (2026-08-20). */
.wp-add-to-deck {
  width: 100%;
  padding: 12px;
  background: var(--bg);
  border: 1px solid var(--primary);
  color: var(--primary);
  border-radius: var(--radius-sm);
  font-size: 15px;
  cursor: pointer;
}

.wp-add-to-deck:hover { background: var(--border); }

/* ============================================
   LISTEN BUTTONS
   ============================================
   Audio is an offer, not an instruction: the button sits at the end of the
   Spanish it speaks, in the muted ink, and only takes colour on hover. It is
   never rendered at all on a device with no Spanish voice, so there is no
   disabled state to design. */

.speak-btn {
  border: 0;
  background: none;
  /* The glyph is small on purpose, but the target it presents to a thumb is
     not: the padding widens the hit area to about 36x30 and the negative
     margins keep it from opening up the line it sits in. */
  padding: 8px 6px 8px 8px;
  margin: -8px -2px -8px 0;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  opacity: .35;
  vertical-align: middle;
  transition: opacity .15s ease;
}

.speak-btn:hover,
.speak-btn:focus-visible {
  opacity: 1;
}

/* In the word popup the button belongs beside the headword, which is set
   much larger than body copy. */
.wp-speak {
  font-size: 18px;
  padding-left: 10px;
  align-self: center;
}

.lsn-table .speak-btn {
  font-size: 12px;
}

/* ============================================
   MY JOURNEY
   ============================================
   Eight separate readings rather than one score. Each card answers one
   question, and the numbers are large enough to read at a glance because
   that is the whole point of the screen. */

/* One continuous composition, not a grid of cards — eight readings
   separated by a rule rather than boxed individually. See spec section 9:
   "avoid a page composed of card + card + card + card." */
.jr-grid {
  display: flex;
  flex-direction: column;
}

.jr-card {
  background: none;
  border: none;
  border-top: 1px solid var(--border);
  padding-top: var(--space-6);
  margin-top: var(--space-6);
}

.jr-card:first-child {
  border-top: none;
  padding-top: 0;
  margin-top: 0;
}

.jr-card-head { margin-bottom: 14px; }

.jr-card-head h3 {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 600;
  color: var(--primary);
}

.jr-card-head p {
  font-size: 13px;
  color: var(--muted);
  margin-top: 2px;
}

/* The headline number for a card that has one. */
.jr-big {
  font-family: var(--font-display);
  font-size: 34px;
  line-height: 1.1;
  color: var(--primary);
  font-variant-numeric: tabular-nums;
  margin-bottom: 10px;
}

.jr-of {
  font-size: 16px;
  color: var(--muted);
}

/* Rows of label / bar / count, used by curriculum and skills. */
.jr-list { list-style: none; }

.jr-row {
  display: grid;
  grid-template-columns: 1fr 90px auto;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  font-size: 14px;
}

.jr-row-label { color: var(--text); }

.jr-row-value {
  color: var(--muted);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* A skill with no data yet says so, in place of a bar that would read as
   zero — which looks like failure rather than "not built". */
.jr-row-muted .jr-row-label { color: var(--muted); }

.jr-row-note {
  grid-column: 2 / 4;
  font-size: 12px;
  color: var(--muted);
  text-align: right;
}

/* A thin line, not a thick pill — matches .lsn-progress. See spec section 19. */
.jr-track {
  display: block;
  height: 1px;
  border-radius: 0;
  background: var(--border);
  overflow: visible;
}

.jr-fill {
  display: block;
  height: 100%;
  background: var(--primary);
}

.jr-facts {
  list-style: none;
  margin-top: 12px;
  border-top: 1px solid var(--border);
  padding-top: 10px;
}

.jr-facts li {
  font-size: 13px;
  color: var(--muted);
  padding: 3px 0;
}

.jr-facts strong {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.jr-next {
  font-size: 13px;
  color: var(--muted);
  margin-top: 10px;
}

/* Every stat on this screen is counted from something the learner did, so
   every stat also gets somewhere to go do more of it — these three make
   that clickable without dressing it up as a button bar. */
.jr-row-clickable {
  cursor: pointer;
  border-radius: var(--radius-sm);
  margin: 0 -8px;
  padding-left: 8px;
  padding-right: 8px;
}

.jr-row-clickable:hover {
  background: var(--bg-alt, var(--border));
}

.jr-next-link {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-size: 13px;
  color: var(--primary);
  text-decoration: underline;
  text-decoration-style: dotted;
  cursor: pointer;
}

.jr-big-link {
  display: block;
  width: 100%;
  background: none;
  border: none;
  padding: 0;
  text-align: left;
  cursor: pointer;
}

.jr-fact-link {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-decoration-color: var(--border);
}

.jr-empty {
  font-size: 14px;
  color: var(--muted);
}

/* Thirty days, one square each. Inactive days stay visible rather than
   blank: the gaps are as informative as the marks. */
.jr-days {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 5px;
}

.jr-day {
  aspect-ratio: 1;
  border-radius: 3px;
  background: var(--border);
}

.jr-day.is-active { background: var(--primary); }

.jr-milestones { list-style: none; }

.jr-milestone {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  font-size: 14px;
  color: var(--muted);
}

.jr-milestone.is-reached { color: var(--text); }

/* ---- Journey: Account (step 7, cloud backup/restore) ---- */
.jr-account-blurb {
  font-size: 14px;
  color: var(--muted);
  margin-bottom: 12px;
}

.jr-account-login {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.jr-account-login .dk-editor-input { flex: 1 1 160px; }

.jr-account-email {
  font-size: 15px;
  color: var(--text);
  margin-bottom: 12px;
}

.jr-account-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}

.jr-account-status {
  font-size: 13px;
  color: var(--muted);
  min-height: 1.2em;
  margin: 8px 0;
}

.jr-account-logout {
  background: none;
  border: none;
  padding: 0;
  font-size: 13px;
  color: var(--muted);
  text-decoration: underline;
  cursor: pointer;
}

/* ---- First-visit sync prompt (engine/sync.js) — reuses .wp-overlay/
   .wp-sheet and the .jr-account-* rules above for its body ---- */
.sync-prompt-sheet .jr-account-logout {
  display: block;
  margin-top: 14px;
}

.sync-prompt-title {
  font-size: 20px;
  color: var(--text);
  margin: 0;
}

.jr-tick {
  flex: 0 0 20px;
  height: 20px;
  border-radius: 99px;
  border: 1px solid var(--border);
  display: grid;
  place-items: center;
  font-size: 12px;
  color: var(--surface);
}

.jr-milestone.is-reached .jr-tick {
  background: var(--primary);
  border-color: var(--primary);
}

/* ---- Course / language picker ---- */
/* Sits above .jr-grid, not among the progress cards — a course choice is
   the frame the rest of the page is measured inside, not a reading of it. */
.jr-course {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 24px;
}

.jr-course-label {
  font-size: 13px;
  color: var(--muted);
}

.jr-lang-select {
  font: inherit;
  font-size: 15px;
  color: var(--primary);
  background: var(--bg);
  border: none;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  padding: 4px 2px;
  cursor: pointer;
}

.jr-lang-select:hover {
  border-bottom-color: var(--primary-mid);
}

/* ============================================
   DECKS
   ============================================
   The tab is a browser first and a flashcard second. A deck is a way of
   choosing what to study — the schedule underneath stays single, so these
   are windows onto one pile rather than separate piles. */

.dk-explainer {
  font-style: italic;
  color: var(--muted);
  margin: 0 0 16px;
  line-height: 1.5;
}

.dk-top {
  display: flex;
  flex-direction: column;
  gap: 16px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 18px 20px;
  margin-bottom: 24px;
}

/* Three equal-weight numbers rather than the two unevenly-sized cards this
   replaced — due, reviewed today and known are all one glance, not a
   whole screen's worth of vertical space. */
.dk-stats-row {
  display: flex;
  gap: 12px;
}

.dk-stat {
  flex: 1;
  min-width: 0;
  text-align: center;
}

.dk-stat-num {
  font-family: var(--font-display);
  font-size: 30px;
  line-height: 1.1;
  color: var(--primary);
  font-variant-numeric: tabular-nums;
}

.dk-stat-label {
  font-size: 12px;
  color: var(--muted);
  margin-top: 2px;
}

.dk-meta-line { font-size: 13px; color: var(--muted); margin-top: 2px; }

.dk-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* ============================================
   DECK MATCH GAME
   ============================================ */
.dkm-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 4px;
}

.dkm-timer {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.dkm-progress {
  font-size: 13px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.dkm-best-line {
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 14px;
}

.dkm-grid {
  display: flex;
  gap: 8px;
  align-items: flex-start;
}

/* Each column is rendered from its own stable-order array (see
   engine/decks/match.js) rather than one grid filled in DOM order, so a
   tile's position never depends on where its opposite-column pair
   happens to sit — English stays the left column, the target language
   the right, exactly as before, but now a match only ever changes the
   two tiles it touches instead of reflowing the whole grid. */
.dkm-col {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
  min-width: 0;
}

.dkm-tile {
  padding: 14px 10px;
  min-height: 56px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 14px;
  text-align: center;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s, border-color 0.15s, opacity 0.2s;
}

.dkm-tile.is-selected {
  border-color: var(--primary);
  background: rgba(16, 42, 71, 0.05);
}

.dkm-tile.is-wrong {
  border-color: var(--accent-dark);
  background: var(--accent-bg);
  color: var(--accent-dark);
}

.dkm-tile.is-matched {
  opacity: 0;
  pointer-events: none;
}

.dkm-done {
  text-align: center;
  padding: 32px 0;
}

.dkm-done-time {
  font-size: 36px;
  font-weight: 800;
  color: var(--primary);
  font-variant-numeric: tabular-nums;
  margin-bottom: 4px;
}

.dkm-done-count {
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 10px;
}

.dkm-new-best {
  font-size: 14px;
  font-weight: 600;
  color: var(--success, #4CAF50);
  margin-bottom: 20px;
}

.dkm-best {
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 20px;
}

.dkm-done-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 280px;
  margin: 0 auto;
}

/* ============================================
   DECK LEARN MODE
   ============================================ */
.dkl-round-line {
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 2px;
}

.dkl-progress {
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 16px;
}

.dkl-question {
  font-size: 22px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 18px;
}

.dkl-options {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.dkl-option {
  padding: 14px 16px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 15px;
  text-align: left;
}

.dkl-option:hover:not(:disabled) { border-color: var(--primary); }

.dkl-option.is-correct {
  border-color: var(--primary);
  background: rgba(16, 42, 71, 0.05);
  font-weight: 600;
}

.dkl-option.is-wrong {
  border-color: var(--accent-dark);
  color: var(--accent-dark);
}

.dkl-input {
  width: 100%;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 16px;
  background: var(--bg);
  color: var(--text);
}

.dkl-input-correct { border-color: var(--primary); }
.dkl-input-wrong { border-color: var(--accent-dark); color: var(--accent-dark); }

.dkl-feedback {
  font-weight: 700;
  font-size: 15px;
  margin-top: 14px;
  min-height: 1.4em;
}

.dkl-feedback-correct { color: var(--primary); }
.dkl-feedback-wrong { color: var(--accent-dark); }

.dkl-actions {
  display: flex;
  gap: 10px;
  margin-top: 8px;
}

.dkl-actions .btn-primary { flex: 1; }

.dkl-done {
  text-align: center;
  padding: 32px 0;
}

.dkl-done-title {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  margin-bottom: 6px;
}

.dkl-done-stat {
  font-size: 14px;
  color: var(--muted);
  margin-bottom: 20px;
}

.dkl-done-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-width: 280px;
  margin: 0 auto;
}

.dk-dictionary-add {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
}

.dk-dictionary-add .lsn-input {
  width: auto;
  flex: 1;
  min-width: 0;
}

.dk-secondary {
  background: var(--bg);
  border: 1px solid var(--primary);
  color: var(--primary);
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  font-size: 15px;
}

.dk-secondary:hover { background: var(--border); }

.dk-group { margin-bottom: 20px; }

.dk-group-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  width: 100%;
  background: none;
  text-align: left;
  border-bottom: 2px solid var(--border);
  padding: 0 0 10px;
}

.dk-group-header:hover .dk-group-title { color: var(--primary-dark); }

.dk-group-title {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 600;
  color: var(--primary);
}

.dk-group-count {
  margin-left: 8px;
  font-size: 13px;
  color: var(--muted);
}

.dk-group-arrow {
  font-size: .8em;
  color: var(--secondary);
  flex-shrink: 0;
  margin-left: 12px;
}

.dk-group-body { padding-top: 12px; }

.dk-group-body.hidden { display: none; }

.dk-group-blurb { font-size: 13px; color: var(--muted); margin: 2px 0 12px; }

.dk-grid {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
}

/* A deck card has to answer three things at a glance: what it is, what is
   inside it, and how far in you are. The earlier version cramped all three
   onto two lines and read as a list item rather than something to pick up. */
.dk-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  text-align: left;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 18px 20px 16px;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-standard);
}

.dk-card:hover {
  border-color: var(--primary);
}

.dk-card-top {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.dk-num {
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 1px 6px;
  flex: 0 0 auto;
}

.dk-name {
  font-family: var(--font-display);
  font-size: 18px;
  line-height: 1.25;
  color: var(--primary);
  flex: 1 1 auto;
}

/* Due count sits with the title, where it is a property of the deck rather
   than a statistic buried under it. */
.dk-due {
  flex: 0 0 auto;
  background: var(--accent);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  border-radius: var(--radius-pill);
  padding: 2px 9px;
  font-variant-numeric: tabular-nums;
}

/* The first few words, so a deck is not an opaque label. */
.dk-preview {
  font-size: 13px;
  line-height: 1.45;
  color: var(--muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.dk-meter {
  display: block;
  height: 1px;
  border-radius: 0;
  background: var(--border);
  overflow: visible;
}

.dk-fill { display: block; height: 100%; background: var(--primary); }

.dk-meta {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.dk-back {
  background: none;
  border: 0;
  color: var(--primary);
  font-size: 14px;
  padding: 0;
  margin-bottom: 14px;
  cursor: pointer;
}

.dk-back:hover { text-decoration: underline; }

.dk-scope {
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 12px;
}

.dk-detail-head { margin-bottom: 18px; }

.dk-detail-head h3 {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 600;
  color: var(--primary);
}

.dk-detail-head p { font-size: 13px; color: var(--muted); margin: 2px 0 12px; }

/* Review/Match/Learn as one equal-weight row — same size, same border
   treatment, no single one visually "the" primary action. Wraps to 2+1 on
   a narrow screen rather than shrinking illegibly. */
.dk-study-row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 10px;
}

.dk-study-tab {
  flex: 1 1 0;
  min-width: 90px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 14px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}

.dk-study-tab:hover:not(:disabled) { border-color: var(--primary); color: var(--primary); }

.dk-study-tab:disabled { color: var(--muted); cursor: default; opacity: 0.6; }

.dk-study-tab-badge {
  background: var(--primary);
  color: var(--surface);
  font-size: 12px;
  font-weight: 700;
  padding: 1px 7px;
  border-radius: 10px;
}

/* Meta actions — smaller and quieter than the study row above on purpose,
   since neither is "how do I practice this deck," they're bookkeeping. */
.dk-utility-row {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}

.dk-link-btn {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 13px;
  text-decoration: underline;
  padding: 0;
}

.dk-link-btn:hover { color: var(--primary); }

.dk-words-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 20px 0 6px;
}

.dk-words-count {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.dk-words { list-style: none; }

.dk-word {
  display: grid;
  grid-template-columns: 1fr 1fr auto;
  gap: 10px;
  align-items: baseline;
  padding: 9px 0;
  border-bottom: 1px solid var(--border);
  font-size: 15px;
}

/* "All my words" adds a remove button as a fourth column — every other deck
   view keeps the plain three-column layout since removing a word there
   means editing membership, not deleting the card (see the deck editor). */
.dk-words-removable .dk-word { grid-template-columns: 1fr 1fr auto auto; }

.dk-word:last-child { border-bottom: 0; }

.dk-word-es { color: var(--primary); }
.dk-word-en { color: var(--muted); font-size: 14px; }

.dk-word-state {
  font-size: 11px;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

/* A word not yet taken on is legible but plainly not part of your deck. */
.dk-word-not-added .dk-word-es { color: var(--muted); }
.dk-word-mastered .dk-word-state { color: var(--primary); }
.dk-word-known .dk-word-state { color: var(--primary); }

.dk-empty { color: var(--muted); font-size: 14px; }

.dk-detail-desc { font-size: 14px; color: var(--text); margin: 4px 0 8px; }

/* ----- My Decks vs Parlour Decks ----- */
/* The tab bar itself is .lt-subnav/.lt-subnav-btn — the same component the
   Library uses for Parlour/Saved/My Texts, so the two top-level tabs in the
   app look and behave identically. */

.dk-create-btn { padding: 8px 14px; font-size: 14px; flex: 0 0 auto; }

.dk-danger {
  background: none;
  border: 1px solid var(--danger);
  color: var(--danger);
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  font-size: 15px;
}

.dk-danger:hover { background: var(--danger-bg); }

/* ----- Deck editor ----- */

.dk-editor { display: flex; flex-direction: column; gap: 6px; }

.dk-editor-title {
  font-family: var(--font-display);
  font-size: 22px;
  color: var(--primary);
  margin-bottom: 8px;
}

.dk-editor-label {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--muted);
  margin-top: 10px;
}

.dk-editor-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 15px;
  font-family: inherit;
  background: var(--bg);
  color: var(--text);
}

.dk-editor-textarea { resize: vertical; min-height: 50px; }

.dk-editor-words { margin-top: 6px; }

.dk-word-remove {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}

.dk-word-remove:hover { color: var(--danger); }

.dk-editor-actions { margin-top: 18px; }

/* ----- Vocabulary search, shared by the editor and the "Add to deck" picker ----- */

.dk-picker-panel { margin-top: 6px; }

.dk-picker-loading { font-size: 13px; color: var(--muted); }

.dk-picker-results { list-style: none; border: 1px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }

.dk-picker-result {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  padding: 9px 12px;
  background: var(--bg);
  border: none;
  border-bottom: 1px solid var(--border);
  text-align: left;
  cursor: pointer;
}

.dk-picker-results li:last-child .dk-picker-result { border-bottom: 0; }

.dk-picker-result:hover:not(:disabled) { background: var(--border); }
.dk-picker-result:disabled { cursor: default; opacity: .6; }

.dk-picker-result-es { color: var(--primary); font-size: 14px; flex: 0 0 auto; }
.dk-picker-result-en { color: var(--muted); font-size: 13px; flex: 1 1 auto; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dk-picker-result-added { color: var(--primary); flex: 0 0 auto; }

.dk-picker-manual {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 8px 10px;
  background: none;
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  color: var(--muted);
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}

.dk-picker-manual:hover { border-color: var(--primary); color: var(--primary); }

/* ----- "Add to deck" overlay (reused wp-overlay/wp-sheet chrome) ----- */

.dk-picker-sheet { max-width: 420px; }

.dk-picker-list { list-style: none; margin-bottom: 14px; }

.dk-picker-deck {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 4px;
  background: none;
  border: none;
  border-bottom: 1px solid var(--border);
  font-size: 15px;
  color: var(--text);
  cursor: pointer;
  text-align: left;
}

.dk-picker-list li:last-child .dk-picker-deck { border-bottom: 0; }

.dk-picker-deck:hover:not(:disabled) { color: var(--primary); }
.dk-picker-deck:disabled { cursor: default; color: var(--primary); }

.dk-picker-deck-count { font-size: 12px; color: var(--muted); }
.dk-picker-deck:disabled .dk-picker-deck-count { color: var(--primary); }

.dk-picker-create {
  display: flex;
  gap: 8px;
  border-top: 1px solid var(--border);
  padding-top: 14px;
}

.dk-picker-create .dk-editor-input { flex: 1 1 auto; }

/* ============================================
   LEVEL TEST
   ============================================
   Twenty gapped sentences with a dropdown in each. Marked all at once, so
   nothing on the page reacts until the learner asks it to. */

.level-test-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  text-align: left;
  margin-top: 14px;
  padding: 16px 18px;
  background: var(--bg);
  border: 1px dashed var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color .2s;
}

.level-test-row:hover { border-color: var(--primary); border-style: solid; }

/* A passed level is the one thing in the list that is not simply
   "lessons finished", so it gets the solid border rather than the dashed. */
.level-test-row.is-passed {
  border-style: solid;
  border-color: var(--success);
}

.level-test-title {
  font-family: var(--font-display);
  font-size: 17px;
  color: var(--primary);
}

.level-test-meta { font-size: 13px; color: var(--muted); }

.lt-head { margin-bottom: 22px; }

.lt-head h2 {
  font-family: var(--font-display);
  font-size: 26px;
  font-weight: 600;
  color: var(--primary);
}

.lt-head p { color: var(--muted); font-size: 14px; margin-top: 4px; max-width: 62ch; }

.lt-previous { color: var(--secondary); font-size: 13px; margin-top: 8px; }

.lt-questions { list-style: none; }

.lt-question {
  display: grid;
  grid-template-columns: 30px 1fr;
  gap: 10px;
  align-items: baseline;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
  font-size: 16px;
  line-height: 2;
}

.lt-num {
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.lt-select {
  font: inherit;
  font-size: 15px;
  color: var(--primary);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 3px 8px;
  margin: 0 4px;
}

.lt-select:focus { outline: 2px solid var(--primary); outline-offset: 1px; }

.lt-mark { margin-left: 10px; font-size: 14px; }
.lt-right { color: var(--primary); }
.lt-wrong { color: var(--accent-dark); }

.lt-question.is-wrong { background: rgba(220, 78, 46, .04); }

.lt-actions { margin-top: 22px; }

.lt-result {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 20px 22px;
  margin-bottom: 24px;
}

.lt-score {
  font-family: var(--font-display);
  font-size: 40px;
  line-height: 1;
  color: var(--primary);
  font-variant-numeric: tabular-nums;
}

.lt-of { font-size: 18px; color: var(--muted); }

.lt-verdict { margin-top: 10px; font-size: 16px; }
.lt-verdict.is-pass { color: var(--success); }
.lt-verdict.is-fail { color: var(--accent-dark); }

.lt-topics { margin: 8px 0 14px; font-size: 14px; color: var(--muted); }

/* ============================================
   HOME
   ============================================
   Three tiers, in order: one dominant recommendation (the app's opinion —
   serif title, a meter, the screen's one accent colour), an optional quiet
   line of other things worth practising (no accent, easy to skip), then
   three doors, where today stands, and how far the course has come. The
   screen exists to be left quickly, so hierarchy does the work rather than
   labels — everything under the recommendation is a single line of sans. */

/* ---- Continue: the dominant object ---- */

.hm-continue {
  display: flex;
  flex-direction: column;
  width: 100%;
  text-align: left;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 20px 22px 18px;
  margin-bottom: 16px;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-standard);
}

.hm-continue:hover {
  border-color: var(--primary-mid);
}

/* A finished course is a statement rather than a door — nothing to press. */
.hm-continue.is-done {
  cursor: default;
}

.hm-continue.is-done:hover {
  border-color: var(--border);
}

/* The practice nudge is a section with two real buttons in it, not one
   whole-row click like the button version above — no hover affordance on
   the card itself, only on the buttons it actually contains. */
.hm-continue.hm-nudge {
  cursor: default;
}

.hm-continue.hm-nudge:hover {
  border-color: var(--border);
}

/* A button wearing .hm-cta's own look (the one accent-coloured call to
   action on the screen) rather than the plain text span it usually is —
   needed here because the nudge card holds two separate actions instead
   of being one big clickable button. */
.hm-cta-btn {
  background: none;
  border: none;
  padding: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--accent-dark);
  cursor: pointer;
}

.hm-cta-btn:hover {
  text-decoration: underline;
}

.hm-eyebrow {
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--muted);
  margin-bottom: 6px;
}

.hm-continue-title {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1.15;
  color: var(--text);
}

.hm-continue-sub {
  font-size: 13px;
  color: var(--muted);
  margin-top: 4px;
}

.hm-continue .hm-track {
  margin-top: 16px;
}

.hm-continue-foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-top: 10px;
}

/* The one accent on the screen. It marks the single live thing, which is why
   the due count beside it is set in ink rather than competing for the same
   signal. */
.hm-cta {
  font-size: 14px;
  font-weight: 600;
  color: var(--accent-dark);
  white-space: nowrap;
}

.hm-count {
  font-size: 12px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* ---- Meter, shared by the continue card and the course line ---- */

/* A thin line, not a thick pill — matches .lsn-progress. */
.hm-track {
  display: block;
  height: 1px;
  border-radius: 0;
  background: var(--border);
  overflow: visible;
}

.hm-fill {
  display: block;
  height: 100%;
  background: var(--primary);
}

/* ---- Secondary: optional reinforcement, deliberately quiet ---- */
/* No accent colour here — the continue/nudge card above is the one
   accent-bearing thing on the screen, and this tier needs to read as
   obviously subordinate to it, not as a second recommendation. */

.hm-secondary {
  border-top: 1px solid var(--border);
  padding-top: 12px;
  margin-bottom: 16px;
}

.hm-secondary-eyebrow {
  display: block;
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--muted);
  margin-bottom: 8px;
}

.hm-secondary-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.hm-secondary-btn {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 0;
  font-size: 14px;
  color: var(--text);
  cursor: pointer;
}

.hm-secondary-btn:hover {
  color: var(--primary-mid);
}

/* ---- Doors ---- */
/* Open rows, not a stack of cards — same grammar as Lessons/Workshop. */

.hm-doors {
  display: flex;
  flex-direction: column;
  margin-bottom: 20px;
}

.hm-door {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 15px 4px;
  text-align: left;
  background: none;
  border: none;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-standard);
}

.hm-door:hover .hm-door-title {
  color: var(--primary);
}

.hm-door .icon {
  width: 22px;
  height: 22px;
}

.hm-door-body {
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: 1;
  min-width: 0;
}

.hm-door-title {
  font-size: 15px;
  color: var(--text);
}

/* One line only. A story title long enough to wrap would make three doors of
   different heights, and the row is a label, not a description. */
.hm-door-sub {
  font-size: 13px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hm-door-value {
  flex: none;
  font-family: var(--font-display);
  font-size: 22px;
  line-height: 1;
  color: var(--primary);
  font-variant-numeric: tabular-nums;
}

/* ---- The course, in one line ---- */

.hm-progress {
  display: flex;
  flex-direction: column;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-top: 1px solid var(--border);
  padding: 16px 2px 0;
  cursor: pointer;
}

.hm-progress-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  font-size: 14px;
  color: var(--text);
  margin-bottom: 8px;
}

.hm-progress-foot {
  font-size: 13px;
  color: var(--muted);
  margin-top: 8px;
}

.hm-progress:hover .hm-progress-foot {
  color: var(--text);
}

/* ============================================
   BUG REPORT
   ============================================
   A single floating control, present on every screen, so a mistake can be
   flagged the instant it's seen rather than written down for later. Kept
   deliberately quiet — a plain surface button, not a loud red one — since
   the flag glyph's own accent fill already carries the "something needs
   attention" signal; a persistently vivid button on every screen would
   compete with the page it sits on.
*/

.br-flag-btn {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 300;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--bg);
  border: 1px solid var(--border);
  box-shadow: 0 2px 8px rgba(0, 0, 0, .12);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.br-flag-btn:hover {
  border-color: var(--primary-mid);
}

.br-flag-btn .icon {
  width: 20px;
  height: 20px;
}

.br-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .5);
  z-index: 299;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.br-sheet {
  background: var(--bg);
  width: 100%;
  max-width: 460px;
  border-radius: var(--radius) var(--radius) 0 0;
  padding: 24px;
  animation: slideUp .3s ease-out;
}

.br-header {
  display: flex;
  justify-content: space-between;
  align-items: start;
  margin-bottom: 4px;
}

.br-title {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 400;
  color: var(--text);
  margin: 0;
}

.br-close {
  background: none;
  border: none;
  font-size: 24px;
  line-height: 1;
  color: var(--muted);
  cursor: pointer;
}

.br-context {
  font-size: 13px;
  color: var(--muted);
  margin: 0 0 8px;
}

.br-status {
  font-size: 13px;
  color: var(--muted);
  min-height: 18px;
  margin: 0 0 12px;
}

.br-status a {
  color: var(--primary);
}

.br-actions {
  display: flex;
  gap: 10px;
}

.br-primary,
.br-secondary {
  flex: 1;
  padding: 12px 16px;
  border: none;
  border-radius: var(--radius-sm);
  font-size: 15px;
  cursor: pointer;
}

.br-primary {
  background: var(--primary);
  color: #fff;
}

.br-secondary {
  background: none;
  border: 1px solid var(--border);
  color: var(--text);
}

.br-note {
  width: 100%;
  min-height: 90px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font: inherit;
  font-size: 15px;
  color: var(--text);
  background: var(--bg);
  resize: vertical;
  margin-bottom: 14px;
}
