/* ============================================================
   LANGUAGE.CSS — the Language Library, its drills and its scenarios
   ============================================================ */

/* ── The language pair selector ───────────────────────────── */

.lang-pair-bar {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.5rem 0.1rem 0;
}

.lang-pair-side { flex: 1; min-width: 0; }

.lang-pair-label {
  display: block;
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  margin-bottom: 0.25rem;
}

.lang-pill-row { display: flex; gap: 0.2rem; }

.lang-pill {
  flex: 1;
  padding: 0.25rem 0.1rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-tertiary);
  font-size: 0.66rem;
  font-weight: 800;
  cursor: pointer;
  font-family: var(--font-sans);
  transition: color 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}

.lang-pill:hover { color: var(--text-primary); border-color: var(--color-primary); }

.lang-pill.is-active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--text-on-primary);
}

/* The other side's language, so it is visibly not available here. */
.lang-pill.is-dim { opacity: 0.35; }

.lang-swap-btn {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  margin-top: 0.85rem;
  border: 1px solid var(--border-color);
  border-radius: 50%;
  background: var(--bg-surface);
  color: var(--text-secondary);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.lang-swap-btn:hover { color: var(--color-primary); border-color: var(--color-primary); }
.lang-swap-btn i, .lang-swap-btn svg { width: 15px; height: 15px; }

/* ── Tabs, list, rows ─────────────────────────────────────── */

.lang-tabs { display: flex; gap: 0.25rem; padding: 0.5rem 0.75rem 0; }
.lang-tabs-admin { padding: 0 0 1rem; }

.lang-tab {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.35rem 0.7rem;
  border: 1px solid transparent;
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--text-tertiary);
  font-size: 0.75rem;
  font-weight: 700;
  cursor: pointer;
  font-family: var(--font-sans);
}

.lang-tab i, .lang-tab svg { width: 14px; height: 14px; }
.lang-tab:hover { color: var(--text-primary); background: var(--bg-surface-hover); }
.lang-tab.is-active { background: var(--color-primary-subtle); border-color: var(--color-primary); color: var(--color-primary); }

.lang-tagbar { display: flex; flex-wrap: wrap; gap: 0.25rem; padding: 0.6rem 0.75rem 0; }

.lang-tag-chip {
  padding: 0.15rem 0.5rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--text-tertiary);
  font-size: 0.68rem;
  font-weight: 650;
  cursor: pointer;
  font-family: var(--font-sans);
}

.lang-tag-chip span { opacity: 0.6; margin-left: 0.2rem; }
.lang-tag-chip.is-active { background: var(--color-primary-subtle); border-color: var(--color-primary); color: var(--color-primary); }

.lang-list-actions { padding: 0.6rem 0.75rem; }
.lang-rows { display: flex; flex-direction: column; gap: 2px; padding: 0 0.5rem 1rem; }

.lang-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.5rem 0.6rem;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  cursor: pointer;
  text-align: left;
  font-family: var(--font-sans);
  transition: background 0.14s ease, border-color 0.14s ease;
}

.lang-row:hover { background: var(--bg-surface-hover); }
.lang-row.is-active { background: var(--color-primary-subtle); border-color: var(--color-primary); }

.lang-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.lang-row-term { font-weight: 700; font-size: 0.9rem; color: var(--text-primary); }
.lang-row-gloss { font-size: 0.72rem; color: var(--text-tertiary); }
.lang-row-meta { display: flex; align-items: center; gap: 0.35rem; flex-shrink: 0; }

.lang-pos {
  font-size: 0.6rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-accent);
  background: rgba(6, 182, 212, 0.12);
  border-radius: var(--radius-full);
  padding: 0.1rem 0.4rem;
  margin-left: 0.4rem;
}

.lang-fill {
  font-size: 0.65rem;
  font-weight: 800;
  color: var(--text-tertiary);
  background: var(--bg-surface-hover);
  border-radius: var(--radius-full);
  padding: 0.1rem 0.35rem;
}

.lang-warn { color: var(--color-warning); display: inline-flex; }
.lang-warn i, .lang-warn svg { width: 14px; height: 14px; }
.lang-warn-text { color: var(--color-warning); font-weight: 700; font-size: 0.75rem; }
.lang-ok-text { color: var(--color-success); font-weight: 700; font-size: 0.75rem; }

.lang-empty { padding: 1.5rem 0.75rem; text-align: center; color: var(--text-tertiary); font-size: 0.8rem; }

/* ── Side-by-side comparison ──────────────────────────────── */

.lang-compare {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1rem;
}

@media (max-width: 820px) { .lang-compare { grid-template-columns: 1fr; } }

.lang-col {
  background: var(--bg-surface);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 1rem 1.1rem;
}

/* The one being learned gets the accent edge — at a glance you know which
   column is the answer and which is the crib. */
.lang-col.is-study { border-left: 3px solid var(--color-primary); }
.lang-col.is-empty { opacity: 0.7; }

.lang-col-head { display: flex; align-items: center; gap: 0.45rem; margin-bottom: 0.6rem; }

.lang-col-code {
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.05em;
  color: var(--text-on-primary);
  background: var(--color-primary);
  border-radius: var(--radius-sm);
  padding: 0.1rem 0.35rem;
}

.lang-col-name { font-weight: 700; font-size: 0.85rem; color: var(--text-primary); }

.lang-col-role {
  margin-left: auto;
  font-size: 0.6rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-tertiary);
}

.lang-col-empty { color: var(--text-tertiary); font-size: 0.8rem; font-style: italic; }
.lang-term { font-size: 1.35rem; font-weight: 800; color: var(--text-primary); margin-bottom: 0.35rem; }
.lang-def { color: var(--text-secondary); line-height: 1.6; margin: 0 0 0.75rem; font-size: 0.875rem; }

.lang-block { margin-top: 0.85rem; }
.lang-block h4 {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.66rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-tertiary);
  margin: 0 0 0.35rem;
}
.lang-block h4 i, .lang-block h4 svg { width: 12px; height: 12px; }
.lang-block p { margin: 0; font-size: 0.82rem; color: var(--text-secondary); line-height: 1.55; }

.lang-block-warn p { color: var(--color-warning); }

.lang-examples { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }
.lang-examples li {
  border-left: 2px solid var(--border-color);
  padding-left: 0.6rem;
  display: flex;
  flex-direction: column;
}
.lang-ex-text { font-size: 0.85rem; color: var(--text-primary); }
.lang-ex-gloss { font-size: 0.75rem; color: var(--text-tertiary); font-style: italic; }

.lang-other-row { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.lang-other {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  cursor: pointer;
  font-family: var(--font-sans);
  text-align: left;
}
.lang-other:hover { border-color: var(--color-primary); }
.lang-other-term { font-weight: 700; color: var(--text-primary); font-size: 0.85rem; }
.lang-other-def { color: var(--text-tertiary); font-size: 0.72rem; }

.lang-problems {
  background: var(--color-warning-bg);
  border: 1px solid var(--color-warning-subtle);
  border-radius: var(--radius-md);
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
}
.lang-problems strong { display: flex; align-items: center; gap: 0.35rem; color: var(--color-warning); font-size: 0.85rem; }
.lang-problems ul { margin: 0.4rem 0 0 1.1rem; padding: 0; color: var(--text-secondary); font-size: 0.8rem; }

/* ── Admin ────────────────────────────────────────────────── */

.admin-hub-head { display: flex; align-items: center; margin-bottom: 1rem; }

.lang-admin-bar { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 1rem; }
.lang-admin-count { color: var(--text-tertiary); font-size: 0.78rem; font-weight: 600; }

.lang-admin-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.lang-admin-table th {
  text-align: left;
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-tertiary);
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--border-color);
}
.lang-admin-table td { padding: 0.55rem 0.6rem; border-bottom: 1px solid var(--border-color-subtle); color: var(--text-secondary); }
.lang-admin-table td strong { color: var(--text-primary); }
.lang-admin-actions { text-align: right; white-space: nowrap; }
.lang-admin-actions .btn { padding: 0.25rem 0.4rem; }
.lang-admin-actions i, .lang-admin-actions svg { width: 14px; height: 14px; }

.lang-mini-pill {
  display: inline-block;
  font-size: 0.6rem;
  font-weight: 800;
  color: var(--color-primary);
  background: var(--color-primary-subtle);
  border-radius: var(--radius-sm);
  padding: 0.05rem 0.3rem;
  margin-right: 0.2rem;
}

.lang-form-hint { color: var(--text-tertiary); font-size: 0.8rem; margin: 0 0 0.75rem; display: flex; align-items: center; gap: 0.4rem; }

.lang-form-lang {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  margin-bottom: 0.6rem;
  background: var(--bg-surface);
}
.lang-form-lang > summary {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 0.8rem;
  cursor: pointer;
  font-weight: 700;
  color: var(--text-primary);
  font-size: 0.85rem;
}
.lang-form-preview { margin-left: auto; color: var(--text-secondary); font-weight: 600; font-size: 0.8rem; }
.lang-form-preview.is-empty { color: var(--text-tertiary); font-style: italic; font-weight: 500; }
.lang-form-body { padding: 0 0.8rem 0.8rem; }

.lang-add-row { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-bottom: 1rem; }
.lang-add-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.35rem 0.65rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--text-secondary);
  font-size: 0.75rem;
  font-weight: 650;
  cursor: pointer;
  font-family: var(--font-sans);
}
.lang-add-btn:hover { border-color: var(--color-primary); color: var(--color-primary); background: var(--color-primary-subtle); }
.lang-add-btn i, .lang-add-btn svg { width: 14px; height: 14px; }

.lang-item-card {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 0.85rem 1rem;
  margin-bottom: 0.75rem;
  background: var(--bg-surface);
}
.lang-item-head { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.6rem; }
.lang-item-num { font-weight: 900; color: var(--text-tertiary); opacity: 0.5; }
.lang-item-kind { display: inline-flex; align-items: center; gap: 0.3rem; font-weight: 700; font-size: 0.8rem; color: var(--color-primary); }
.lang-item-kind i, .lang-item-kind svg { width: 14px; height: 14px; }
.lang-item-tools { margin-left: auto; display: flex; gap: 0.15rem; }
.lang-item-tools .btn { padding: 0.2rem 0.35rem; }
.lang-item-tools i, .lang-item-tools svg { width: 14px; height: 14px; }

.lang-opt-row { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.35rem; }
.lang-opt-row .form-input { flex: 1; }
.lang-opt-note { max-width: 40%; }
.lang-pair-arrow { color: var(--text-tertiary); display: inline-flex; }
.lang-pair-arrow i, .lang-pair-arrow svg { width: 14px; height: 14px; }

/* ── The drill runner ─────────────────────────────────────── */

/* One question at a time is the right idea, and it was being shown at laptop
   size on whatever screen you had: a 620px column pinned to the top of a
   1080px-tall pane, with two thirds of the display empty below it and the
   Check button stranded at the far bottom edge. Everything below scales from
   these four tokens, so the drill grows with the window instead of sitting
   in the corner of it. The lower bound of each clamp is exactly what the
   size used to be, so a small window is unchanged. */
.la-shell {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--bg-body);
  --la-measure: clamp(620px, 56vw, 1000px);
  --la-prompt: clamp(1.45rem, 0.95rem + 1.5vw, 2.6rem);
  --la-answer: clamp(0.95rem, 0.75rem + 0.55vw, 1.4rem);
  --la-pad: clamp(0.85rem, 0.55rem + 0.75vw, 1.5rem);
}

.la-top { display: flex; align-items: center; gap: 1rem; padding: 0.85rem 1.25rem; border-bottom: 1px solid var(--border-color); }

.la-progress { flex: 1; height: clamp(10px, 0.6vw, 16px); border-radius: 999px; background: var(--bg-surface-hover); overflow: hidden; }
.la-progress-fill { height: 100%; border-radius: 999px; background: var(--color-success); transition: width 0.3s ease; }

.la-hearts { display: flex; gap: 0.3rem; color: var(--color-danger); }
.la-heart { width: clamp(18px, 1.3vw, 26px); height: clamp(18px, 1.3vw, 26px); }
.la-heart.is-lost { opacity: 0.25; }

/* `safe center` puts the question in the middle of the screen, where the eye
   already is, and falls back to the top edge the moment the content is taller
   than the pane -- which plain `center` does not: it would clip the prompt
   off the top of a long match grid with no way to scroll back to it. */
.la-body {
  flex: 1;
  overflow-y: auto;
  display: flex;
  justify-content: center;
  align-items: safe center;
  padding: clamp(2rem, 4vh, 4rem) 1.25rem;
}
.la-card { width: 100%; max-width: var(--la-measure); }

.la-kind {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.66rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-primary);
  margin-bottom: 0.75rem;
}
.la-kind i, .la-kind svg { width: 13px; height: 13px; }

.la-prompt {
  font-size: var(--la-prompt);
  font-weight: 800;
  color: var(--text-primary);
  margin: 0 0 clamp(1.25rem, 2.2vh, 2.25rem);
  line-height: 1.25;
  text-wrap: balance;
}

.la-blank-line {
  font-size: calc(var(--la-prompt) * 0.62);
  color: var(--text-primary);
  margin-bottom: 1rem;
  line-height: 1.9;
}
.la-blank-slot {
  display: inline-block;
  min-width: 90px;
  text-align: center;
  border-bottom: 2px solid var(--color-primary);
  padding: 0 0.4rem;
  font-weight: 700;
  color: var(--color-primary);
}

.la-lane {
  min-height: 58px;
  border-bottom: 2px dashed var(--border-color);
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  align-content: flex-start;
  padding-bottom: 0.6rem;
  margin-bottom: 1.25rem;
}
.la-lane-hint { color: var(--text-tertiary); font-size: 0.8rem; align-self: center; }

.la-pool { display: flex; flex-wrap: wrap; gap: 0.4rem; }

.la-tile {
  padding: calc(var(--la-pad) * 0.6) var(--la-pad);
  border: 1px solid var(--border-color);
  border-bottom-width: 3px;
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  color: var(--text-primary);
  font-size: var(--la-answer);
  font-weight: 650;
  cursor: pointer;
  font-family: var(--font-sans);
  transition: transform 0.1s ease, border-color 0.15s ease;
}
.la-tile:hover { border-color: var(--color-primary); }
.la-tile:active { transform: translateY(1px); }
.la-tile.is-placed { border-color: var(--color-primary); background: var(--color-primary-subtle); }

.la-options { display: flex; flex-direction: column; gap: clamp(0.5rem, 1vh, 0.9rem); }
.la-option {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: var(--la-pad) calc(var(--la-pad) * 1.2);
  border: 1px solid var(--border-color);
  border-bottom-width: 3px;
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  color: var(--text-primary);
  font-size: var(--la-answer);
  cursor: pointer;
  text-align: left;
  font-family: var(--font-sans);
}
.la-option:hover { border-color: var(--color-primary); }
.la-option.is-picked { border-color: var(--color-primary); background: var(--color-primary-subtle); }
.la-option-key {
  width: calc(var(--la-answer) * 1.7); height: calc(var(--la-answer) * 1.7);
  flex-shrink: 0;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: calc(var(--la-answer) * 0.72); font-weight: 800; color: var(--text-tertiary);
}

.la-typed .form-input {
  font-size: calc(var(--la-answer) * 1.1);
  padding: var(--la-pad) calc(var(--la-pad) * 1.2);
}

.la-match { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(0.75rem, 1.5vw, 1.5rem); }
.la-match-col { display: flex; flex-direction: column; gap: clamp(0.4rem, 0.9vh, 0.75rem); }
.la-match-btn {
  padding: calc(var(--la-pad) * 0.75) var(--la-pad);
  font-size: var(--la-answer);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  color: var(--text-primary);
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: 0.88rem;
}
.la-match-btn.is-picked { border-color: var(--color-primary); background: var(--color-primary-subtle); }
.la-match-btn.is-done { opacity: 0.45; }

.la-feedback { margin-top: clamp(1.25rem, 2vh, 2rem); padding: var(--la-pad) calc(var(--la-pad) * 1.2); border-radius: var(--radius-md); }
.la-feedback.is-right { background: var(--color-success-bg); }
.la-feedback.is-wrong { background: var(--color-danger-bg); }
.la-correct { font-size: 0.95rem; color: var(--text-primary); font-weight: 700; }
.la-correct em { font-style: normal; font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-tertiary); display: block; }
.la-note { margin-top: 0.5rem; display: flex; gap: 0.4rem; align-items: flex-start; font-size: 0.82rem; color: var(--text-secondary); }
.la-note i, .la-note svg { width: 14px; height: 14px; flex-shrink: 0; margin-top: 2px; }

.la-foot { border-top: 1px solid var(--border-color); }
/* Tracks the card, so Check sits under the last answer rather than in a
   620px strip inside a 1900px bar. */
.la-foot-inner {
  max-width: var(--la-measure);
  margin: 0 auto;
  padding: clamp(1rem, 1.6vh, 1.6rem) 1.25rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.la-foot-inner.is-right { background: var(--color-success-bg); }
.la-foot-inner.is-wrong { background: var(--color-danger-bg); }
.la-verdict { display: flex; align-items: center; gap: 0.5rem; font-weight: 800; }
.la-foot-inner.is-right .la-verdict { color: var(--color-success); }
.la-foot-inner.is-wrong .la-verdict { color: var(--color-danger); }
.la-verdict i, .la-verdict svg { width: 20px; height: 20px; }

.la-summary { max-width: min(var(--la-measure), 760px); margin: 0 auto; text-align: center; }
.la-summary-icon {
  width: clamp(72px, 6vw, 110px); height: clamp(72px, 6vw, 110px);
  margin: 0 auto 1rem; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-surface-hover);
}
.la-summary-icon i, .la-summary-icon svg { width: 46%; height: 46%; }
.la-summary-icon.score-perfect { color: var(--color-success); background: var(--color-success-bg); }
.la-summary-icon.score-partial { color: var(--color-warning); background: var(--color-warning-bg); }
.la-summary-icon.score-low { color: var(--color-danger); background: var(--color-danger-bg); }
.la-summary h2 { font-size: 1.6rem; font-weight: 800; color: var(--text-primary); margin: 0 0 0.35rem; }
.la-summary-score { font-size: 2.6rem; font-weight: 900; }
.la-summary-score.score-perfect { color: var(--color-success); }
.la-summary-score.score-partial { color: var(--color-warning); }
.la-summary-score.score-low { color: var(--color-danger); }
.la-summary p { color: var(--text-secondary); }

.la-review { text-align: left; margin: 1.5rem 0; }
.la-review h3 { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-tertiary); margin-bottom: 0.5rem; }
.la-review-row { display: flex; align-items: center; gap: 0.5rem; padding: 0.45rem 0.6rem; border-radius: var(--radius-sm); background: var(--bg-surface); margin-bottom: 0.3rem; font-size: 0.85rem; }
.la-review-row i, .la-review-row svg { width: 14px; height: 14px; color: var(--text-tertiary); flex-shrink: 0; }
.la-review-given { color: var(--color-danger); text-decoration: line-through; }
.la-review-expected { color: var(--color-success); font-weight: 700; }

.la-summary-actions { display: flex; gap: 0.75rem; justify-content: center; margin-top: 1.5rem; }

/* ── The scenario battle ──────────────────────────────────── */














@media (max-width: 640px) {
  .la-match { grid-template-columns: 1fr; }
}

/* ── The card board (pane 1) ──────────────────────────────── */

.lang-board { padding: 0.75rem 0.6rem 0; display: flex; flex-direction: column; gap: 0.4rem; }

.lang-board-title {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.66rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--text-tertiary);
  margin: 0.85rem 0 0.15rem;
}
.lang-board-title:first-child { margin-top: 0; }
.lang-board-title i, .lang-board-title svg { width: 13px; height: 13px; }

/* --- Collapsible sections ---
   The heading became a button, so it needs every one of the UA's button
   defaults undone: without font: inherit it renders in the system face at
   13px and the whole board changes shape. Nothing below alters how the
   heading looks -- only what it can do. */
.lang-board-title {
  background: none;
  border: 0;
  padding: 0;
  width: 100%;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.lang-board-title:hover { color: var(--text-secondary); }
.lang-board-title:focus-visible {
  outline: 2px solid var(--accent-primary, var(--text-secondary));
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* Same spring as the tree's chevron in the coding library, so the two
   libraries open the same way. */
.lang-board-caret {
  transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.lang-board-caret.expanded { transform: rotate(90deg); }

/* And the same open: rows from 0fr to 1fr, which animates a height nobody
   has to measure, with the content fading in just behind the space. */
.lang-board-group {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows 0.7s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
}
.lang-board-group.collapsed {
  grid-template-rows: 0fr;
  /* The board is a flex column with a gap, and that gap is still paid around
     a zero-height child. Take one back so two closed sections sit as close
     as two headings used to. */
  margin-bottom: -0.4rem;
}
.lang-board-group-inner {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;            /* the gap .lang-board used to give these cards */
  overflow: hidden;
  opacity: 1;
  transition: opacity 0.7s ease 0.08s;
}
.lang-board-group.collapsed .lang-board-group-inner {
  opacity: 0;
  transition: opacity 0.7s ease;
}

@media (prefers-reduced-motion: reduce) {
  .lang-board-caret,
  .lang-board-group,
  .lang-board-group-inner { transition: none !important; }
}

.lang-card {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  width: 100%;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
  cursor: pointer;
  text-align: left;
  font-family: var(--font-sans);
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.12s ease;
}

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

.lang-card.is-active {
  border-color: var(--color-primary);
  background: var(--color-primary-subtle);
}

/* A drill with nothing written for it yet still opens — its page explains
   what to do about that — but it should not look ready. */
.lang-card.is-empty { opacity: 0.6; }

.lang-card-icon {
  width: 34px;
  height: 34px;
  flex-shrink: 0;
  border-radius: var(--radius-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--color-primary-subtle);
  color: var(--color-primary);
}
.lang-card-icon i, .lang-card-icon svg { width: 17px; height: 17px; }

.lang-card-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.lang-card-name { font-weight: 700; font-size: 0.85rem; color: var(--text-primary); }
.lang-card-desc {
  font-size: 0.7rem;
  color: var(--text-tertiary);
  line-height: 1.35;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.lang-card-chip {
  flex-shrink: 0;
  font-size: 0.68rem;
  font-weight: 800;
  color: var(--text-tertiary);
  background: var(--bg-surface-hover);
  border-radius: var(--radius-full);
  padding: 0.1rem 0.42rem;
}

/* The button that stood here moved to the header, so this is one line of
   text now and does not need the room a button needed under it. */
.lang-board-foot {
  padding: 0.75rem 0.6rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  align-items: flex-start;
}
.lang-board-hint { font-size: 0.68rem; color: var(--text-tertiary); }

/* Sits in the header's corner, away from the title and the Back button. */
.lang-admin-btn { margin-left: auto; flex-shrink: 0; }

/* --- The tail of a capped list --- */
.lang-more {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  padding: 0.9rem 0 0.4rem;
}
.lang-more-hint { font-size: 0.72rem; color: var(--text-tertiary); }

/* --- The chip cloud's tail --- */
.lang-tag-more {
  background: none;
  border: 1px dashed var(--border-color);
  color: var(--text-tertiary);
  font-family: inherit;
  font-size: 0.68rem;
  padding: 0.2rem 0.5rem;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.lang-tag-more:hover { color: var(--text-primary); border-color: var(--text-tertiary); }

/* --- What the drills know about a word ---
   Four states, and the colour has to survive being the only thing on a row
   that is coloured, so it reads as a status rather than as decoration. */
.lang-recall-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.22rem;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0.1rem 0.34rem;
  border-radius: 999px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.lang-recall-badge i, .lang-recall-badge svg { width: 10px; height: 10px; }
.lang-recall-new     { color: var(--text-tertiary); border-color: var(--border-color); }
.lang-recall-due     { color: var(--color-warning); border-color: color-mix(in srgb, var(--color-warning) 45%, transparent); }
.lang-recall-learning{ color: var(--accent-primary, #818cf8); border-color: color-mix(in srgb, var(--accent-primary, #818cf8) 45%, transparent); }
.lang-recall-known   { color: var(--color-success, #34d399); border-color: color-mix(in srgb, var(--color-success, #34d399) 45%, transparent); }

/* --- Admin's search and its capped table --- */
.lang-admin-search { flex: 1; min-width: 180px; max-width: 340px; }
.lang-admin-more {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  padding: 0.85rem 0 0.2rem;
}
.lang-admin-table td .lang-recall-badge { margin-left: 0.4rem; vertical-align: middle; }

/* ── Dictionary entries ───────────────────────────────────── */

.lang-filterbar { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap; margin: 1rem 0 0.5rem; }
.lang-filter-select { max-width: 200px; }

.lang-entries { display: flex; flex-direction: column; gap: 0.4rem; margin-top: 0.75rem; }

.lang-entry {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.7rem 0.9rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--bg-surface);
}
.lang-entry:hover { border-color: var(--color-primary); }
.lang-entry-main { flex: 1; min-width: 0; }
.lang-entry-head { display: flex; align-items: center; gap: 0.45rem; flex-wrap: wrap; margin-bottom: 0.2rem; }
.lang-entry-term { font-weight: 800; font-size: 1rem; color: var(--text-primary); }
.lang-entry-gloss { font-size: 0.8rem; color: var(--text-tertiary); font-style: italic; }
.lang-entry-def { font-size: 0.82rem; color: var(--text-secondary); line-height: 1.5; }
.lang-entry-warn {
  display: flex; align-items: center; gap: 0.3rem;
  margin-top: 0.3rem; font-size: 0.75rem; color: var(--color-warning);
}
.lang-entry-warn i, .lang-entry-warn svg { width: 12px; height: 12px; flex-shrink: 0; }
/* A usage note is an aside, not a caution -- same line, none of the alarm. */
.lang-entry-note {
  display: flex; align-items: flex-start; gap: 0.3rem;
  margin-top: 0.3rem; font-size: 0.75rem; color: var(--text-tertiary);
  line-height: 1.45;
}
.lang-entry-note i, .lang-entry-note svg {
  width: 12px; height: 12px; flex-shrink: 0; margin-top: 0.15rem;
}
.lang-entry-tools { display: flex; gap: 0.2rem; flex-shrink: 0; }

.lang-pop-body { max-height: 55vh; overflow-y: auto; text-align: left; }
.lang-pop-lang { margin-bottom: 1rem; }
.lang-pop-head { display: flex; align-items: center; gap: 0.4rem; font-weight: 700; font-size: 0.8rem; color: var(--text-primary); margin-bottom: 0.4rem; }

.lang-pickrow { display: flex; flex-wrap: wrap; gap: 0.3rem; margin: 0.75rem 0 1rem; }
.lang-pick {
  padding: 0.25rem 0.6rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-full);
  background: transparent;
  color: var(--text-secondary);
  font-size: 0.78rem;
  font-weight: 650;
  cursor: pointer;
  font-family: var(--font-sans);
}
.lang-pick:hover { border-color: var(--color-primary); color: var(--color-primary); }
.lang-pick.is-active { background: var(--color-primary); border-color: var(--color-primary); color: var(--text-on-primary); }

/* ── Rules panels ─────────────────────────────────────────── */

.lang-rules { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-top: 1.25rem; }
@media (max-width: 820px) { .lang-rules { grid-template-columns: 1fr; } }

.lang-rules-block {
  background: var(--bg-surface);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 1rem 1.1rem;
}
.lang-rules-block h3 {
  display: flex; align-items: center; gap: 0.4rem;
  font-size: 0.68rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--text-tertiary); margin: 0 0 0.5rem;
}
.lang-rules-block h3 i, .lang-rules-block h3 svg { width: 13px; height: 13px; }
.lang-rules-block ol, .lang-rules-block ul { margin: 0 0 0 1.1rem; padding: 0; }
.lang-rules-block li { font-size: 0.82rem; color: var(--text-secondary); line-height: 1.6; }
.lang-rules-block p { margin: 0; font-size: 0.82rem; color: var(--text-secondary); line-height: 1.55; }

.lang-powerlist { list-style: none; margin: 0.4rem 0 0 !important; }
.lang-powerlist li { display: flex; align-items: center; gap: 0.4rem; padding: 0.2rem 0; }
.lang-powerlist i, .lang-powerlist svg { width: 14px; height: 14px; color: var(--color-accent); flex-shrink: 0; }
.lang-powerlist span { font-weight: 800; color: var(--color-accent); }

/* ── The drill clock ──────────────────────────────────────── */

.la-clock {
  font-family: var(--font-mono, monospace);
  font-size: 0.9rem;
  font-weight: 800;
  color: var(--text-secondary);
  min-width: 46px;
  text-align: right;
}
.la-clock.is-low { color: var(--color-danger); }

/* ── The battlefield ──────────────────────────────────────── */


/* Them across and above, you near and below — the framing a turn-based
   battle has always used, so it reads before anything is explained. */




/* ── The text box and commands ────────────────────────────── */







/* ── Bag / power popup rows ───────────────────────────────── */


/* ============================================================
   THE RUN — pixel-art visual-novel frame
   ------------------------------------------------------------
   Deliberately NOT the app's design system. This is the one screen that is a
   game rather than a tool, and it borrows the shape those games have used for
   thirty years: a scene banner, a stacked menu over it, and a dialogue box
   underneath. Its own palette and its own two pixel faces, scoped under
   .lq-shell so none of it leaks into the rest of the app.
   ============================================================ */

.lq-shell {
  --lqInk: #efeaf5;
  --lqDim: #9b93ad;
  --lqPanel: #2a2536;
  --lqPanelHi: #3d3650;
  --lqEdge: #15111e;
  --lqLine: #574d6b;
  --lqHot: #ff5f6d;
  --lqGold: #ffd166;
  --lqCyan: #7ee8e0;

  height: 100%;
  overflow-y: auto;
  background: #0d0a14;
  /* The film-strip perforations either side of the reference's frame. */
  background-image:
    repeating-linear-gradient(180deg, rgba(255,255,255,0.035) 0 26px, transparent 26px 60px),
    repeating-linear-gradient(180deg, rgba(255,255,255,0.035) 0 26px, transparent 26px 60px);
  background-size: 62px 60px, 62px 60px;
  background-position: 14px 0, calc(100% - 14px) 0;
  background-repeat: repeat-y, repeat-y;
  color: var(--lqInk);
  font-family: 'Pixelify Sans', 'Courier New', monospace;
  image-rendering: pixelated;
}

/* A COLUMN THAT FILLS, not a stack that floats. The scene was a fixed 400px
   and the dialogue box a fixed 220px inside a shell that is 100% tall, so on
   any normal screen the whole mode sat in the top half with several hundred
   pixels of nothing under it. The scene takes the slack now and the box sits
   where a dialogue box belongs, against the bottom. */
.lq-frame {
  max-width: 1180px;
  min-height: 100%;
  margin: 0 auto;
  padding: 1.25rem 5rem 1.5rem;
  display: flex;
  flex-direction: column;
}

/* ── Day plate and stat strip ─────────────────────────────── */

.lq-topline { display: flex; align-items: flex-end; gap: 0; margin-bottom: -2px; }

/* The angled tab the reference hangs its day-of-week in. */
.lq-daytag {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 2.2rem 0.5rem 1rem;
  background: var(--lqPanel);
  border: 2px solid var(--lqEdge);
  clip-path: polygon(0 0, 100% 0, calc(100% - 22px) 100%, 0 100%);
  font-family: 'Press Start 2P', 'Pixelify Sans', monospace;
  font-size: 1.05rem;
  letter-spacing: 0.06em;
  z-index: 2;
}

.lq-moon { font-size: 1.5rem; line-height: 1; color: #e8e2f2; }

.lq-stats {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 1.1rem;
  padding: 0.55rem 0.9rem 0.5rem 1.6rem;
  margin-left: -20px;
  font-size: 1rem;
  letter-spacing: 0.04em;
}

.lq-stat { display: inline-flex; align-items: center; gap: 0.25rem; }
.lq-stat b { font-weight: 400; }
.lq-ico-st { color: var(--lqGold); }
.lq-ico-pw { color: var(--lqCyan); }
.lq-ico-wk { color: var(--lqDim); }

/* ── The player's own gauges ───────────────────────────────────
   Small, inline, and beside the numbers rather than instead of them: the exact
   figure still matters when you are deciding whether one more block is worth
   it, but the bar is what you read mid-fight. Matched to the foe bar's height
   and border so both sides of a fight are stated the same way. */
.lq-stat-bar { gap: 0.45rem; }
.lq-gauge {
  width: 76px;
  height: 10px;
  flex-shrink: 0;
  background: rgba(0, 0, 0, 0.6);
  border: 2px solid var(--lqEdge);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05);
}
.lq-gauge-fill {
  display: block;
  height: 100%;
  background: var(--lqCyan);
  /* Stepped, so a draining bar reads as a pixel gauge ticking down rather than
     as a smooth CSS transition on a retro screen. */
  transition: width 0.25s steps(8), background 0.2s steps(2);
}
.lq-gauge-sta .lq-gauge-fill { background: #6ee7a5; }
.lq-gauge-sta.is-low .lq-gauge-fill { background: var(--lqGold); }
.lq-gauge-sta.is-crit .lq-gauge-fill { background: var(--lqHot); }
.lq-gauge-pwr .lq-gauge-fill { background: var(--lqCyan); }
.lq-stat-foe { margin-left: auto; color: var(--lqHot); }

/* ── The scene banner ─────────────────────────────────────── */

.lq-scene {
  position: relative;
  flex: 1 1 auto;
  min-height: 300px;
  border: 2px solid var(--lqEdge);
  overflow: hidden;
}

/* The scene art fills the banner; everything else sits on top of it. */
.lq-art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* Depth: the ground darkens toward the dialogue box and the corners fall away,
   so the portrait reads as standing IN the scene rather than pasted on it. */
.lq-scene::after {
  content: '';
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, transparent 68%, rgba(0,0,0,0.42) 100%),
    radial-gradient(ellipse at 50% 42%, transparent 52%, rgba(0,0,0,0.4) 100%);
  pointer-events: none;
}

/* The location label. This lost its rule in an earlier cleanup and had been
   rendering unstyled ever since — effectively invisible against a lit sky. */
.lq-scenetag {
  position: absolute;
  top: 0.6rem;
  left: 0.7rem;
  z-index: 2;
  font-family: 'Press Start 2P', monospace;
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  color: rgba(255, 255, 255, 0.72);
  text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.8);
}

/* The portrait sits where the reference's art does. */
.lq-foe {
  position: absolute;
  right: 2rem;
  bottom: 0;
  width: 260px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  z-index: 2;
}

/* A head-and-shoulders silhouette standing on the ground line, backlit by the
   city behind it. The dashed transparent box this replaces read as a cut-out
   pasted over the buildings rather than as somebody in the scene. */
/* JUST THE PERSON NOW. The arch, the border and the inner glow were a frame
   built to hold a glyph -- something had to make a smiley in a box read as a
   character standing there. With a drawn figure in it that frame is a capsule
   around somebody who is meant to be in the room, so it goes; only the pool of
   light they stand in is kept. */
.lq-foe-art {
  width: 186px;
  height: 244px;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: radial-gradient(ellipse 60% 30% at 50% 98%, rgba(255, 217, 138, 0.22), transparent 70%);
}

/* A drawn person, not a glyph in a box. The svg is an 18x24 pixel grid, so it
   scales by whole pixels and must never be smoothed -- crispEdges is on the
   element itself, and this keeps the browser from resampling it on the way up. */
.lq-person {
  width: 100%;
  height: 100%;
  display: block;
  image-rendering: pixelated;
  filter: drop-shadow(0 6px 0 rgba(0, 0, 0, 0.45));
}

.lq-foe-bar {
  order: -1;
  width: 200px;
  height: 12px;
  background: rgba(0, 0, 0, 0.78);
  border: 2px solid var(--lqEdge);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.6);
}
.lq-foe-fill { height: 100%; background: var(--lqHot); transition: width 0.3s ease; }

.lq-help {
  position: absolute;
  right: 0.5rem;
  bottom: 0.5rem;
  width: 30px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #efeaf5;
  color: #1a1524;
  border: 2px solid var(--lqEdge);
  font-family: 'Press Start 2P', monospace;
  font-size: 0.85rem;
  cursor: help;
}

/* ── The stacked choice menu ──────────────────────────────── */

/* ANCHORED, AND OPAQUE. It used to sit dead centre at 82% width with items at
   0.93 alpha and no borders, so it landed straight across the middle of the
   art, the skyline showed through the text, and four options separated by a
   4px gap read as one grey slab rather than as a list you choose from.

   Centred, which is where it was and where it belongs -- the fault was never
   the position, it was that you could see the skyline through the text. */
.lq-menu {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  /* SIZED TO ITS CONTENT, because this one window serves two very different
     menus. The road offers four short commands; a conversation offers the
     actual replies, which are whole phrases (lqReplyMenu uses the answer text
     as the label). A fixed width either cramps the sentences or leaves the
     commands floating in an oversized box. max-content with a generous cap
     gives a tight box for GO FOR A RUN and a wide one for a sentence,
     from the same rule. */
  width: max-content;
  min-width: 232px;
  max-width: min(560px, 68%);
  display: flex;
  flex-direction: column;
  background: var(--lqPanel);
  border: 2px solid var(--lqEdge);
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.07),
              0 6px 0 rgba(0, 0, 0, 0.45);
  z-index: 3;
}

.lq-mi {
  display: block;
  width: 100%;
  padding: 0.7rem 1rem;
  border: none;
  background: rgba(58, 51, 74, 0.93);
  color: var(--lqInk);
  font-family: 'Press Start 2P', 'Pixelify Sans', monospace;
  font-size: 1.05rem;
  letter-spacing: 0.05em;
  line-height: 1.5;
  cursor: pointer;
  text-align: center;
  transition: background 0.1s steps(2), color 0.1s steps(2);
}

.lq-mi:hover, .lq-mi:focus-visible {
  background: rgba(120, 108, 150, 0.96);
  outline: none;
}

.lq-mi.is-danger:hover { background: rgba(150, 70, 82, 0.96); }
.lq-mi.is-off { opacity: 0.35; cursor: not-allowed; }
.lq-mi.is-off:hover { background: rgba(58, 51, 74, 0.93); }

/* Long reply text is prose, not a label — let it wrap and shrink. */
/* Scoped: .lq-mi is also the end-of-run actions, which are fine as they are.

   Left-aligned with room for a caret, the way a pixel menu marks its
   selection -- centred text with nothing pointing at it gives no sense of
   which row you are on until the fill moves under the pointer. The rows are
   divided by a hairline rather than a gap, because a gap let the scene
   through and broke the window back into floating bars. */
.lq-menu .lq-mi {
  position: relative;
  padding: 0.62rem 0.9rem 0.62rem 2.1rem;
  background: transparent;
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  text-align: left;
}
.lq-menu .lq-mi + .lq-mi { box-shadow: inset 0 2px 0 rgba(0, 0, 0, 0.35); }
/* DRAWN, NOT TYPED. This was a 'B8' glyph, which Press Start 2P does not
   have -- so it fell back to tofu: a hollow box, wider than the arrow it stood
   in for, landing on top of the label. A pixel font covers very little beyond
   ASCII, so anything decorative has to be a shape rather than a character. */
.lq-menu .lq-mi::before {
  content: '';
  position: absolute;
  left: 0.9rem;
  top: 50%;
  margin-top: -5px;
  width: 0;
  height: 0;
  border-left: 7px solid var(--lqGold);
  border-top: 5px solid transparent;
  border-bottom: 5px solid transparent;
  opacity: 0;
  transition: opacity 0.1s steps(2);
}
.lq-menu .lq-mi:hover::before,
.lq-menu .lq-mi:focus-visible::before { opacity: 1; }
.lq-menu .lq-mi:hover,
.lq-menu .lq-mi:focus-visible { background: var(--lqPanelHi); }
.lq-menu .lq-mi.is-danger:hover { background: #5c2f38; }
.lq-menu .lq-mi.is-danger:hover::before { border-left-color: var(--lqHot); }
.lq-menu .lq-mi.is-off:hover { background: transparent; }
.lq-menu .lq-mi.is-off:hover::before { opacity: 0; }

/* ── The battle command row ───────────────────────────────── */

.lq-cmdbar {
  position: absolute;
  left: 0.75rem;
  bottom: 0.75rem;
  display: flex;
  align-items: center;
  gap: 4px;
  z-index: 3;
}

.lq-cmdicon {
  width: 58px;
  height: 58px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  line-height: 1;
  background: rgba(30, 25, 42, 0.9);
  border: 2px solid var(--lqLine);
  color: var(--lqInk);
  cursor: pointer;
  transition: background 0.1s steps(2), border-color 0.1s steps(2);
}

.lq-cmdicon:hover, .lq-cmdicon:focus-visible {
  background: rgba(120, 108, 150, 0.95);
  border-color: #efeaf5;
  outline: none;
}

.lq-cmdicon.is-off { opacity: 0.35; cursor: not-allowed; }

/* The label the reference shows beside the highlighted command. */
.lq-cmdbar:hover .lq-cmdlabel { opacity: 1; }
.lq-cmdlabel {
  margin-left: 0.5rem;
  font-family: 'Press Start 2P', monospace;
  font-size: 1rem;
  letter-spacing: 0.05em;
  color: #fff;
  text-shadow: 2px 2px 0 #000;
  opacity: 0;
  transition: opacity 0.12s ease;
  pointer-events: none;
  white-space: nowrap;
}

.lq-cmdicon:hover ~ .lq-cmdlabel { opacity: 1; }

/* ── The dialogue box ─────────────────────────────────────── */

.lq-speaker { height: 46px; display: flex; align-items: flex-end; margin-top: 1.25rem; }

.lq-name {
  display: inline-block;
  padding: 0.5rem 1.4rem;
  background: var(--lqPanel);
  border: 2px solid var(--lqEdge);
  border-bottom: none;
  font-family: 'Pixelify Sans', monospace;
  font-size: 1.6rem;
  color: var(--lqInk);
}

.lq-name.is-foe { color: var(--lqHot); }

.lq-boxwrap { position: relative; }

.lq-autoskip {
  position: absolute;
  right: 0.25rem;
  top: -2rem;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  background: none;
  border: none;
  color: var(--lqDim);
  font-family: 'Press Start 2P', monospace;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  cursor: pointer;
}

.lq-check {
  width: 13px;
  height: 13px;
  background: var(--lqDim);
  display: inline-block;
}

.lq-autoskip.is-on { color: var(--lqCyan); }
.lq-autoskip.is-on .lq-check { background: var(--lqCyan); }

/* Sized to what it holds. 220px was reserved whether or not there was a line,
   so an idle box was a tall empty panel with a lone ellipsis in the corner of
   it. Enough for two lines of dialogue, and it grows for more. */
.lq-box {
  position: relative;
  min-height: 118px;
  padding: 1.25rem 1.6rem 2.1rem;
  background: #191426;
  border: 2px solid var(--lqEdge);
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.05);
}

.lq-box.is-clickable { cursor: pointer; }

.lq-line {
  margin: 0;
  font-size: 1.75rem;
  line-height: 1.6;
  color: var(--lqInk);
  letter-spacing: 0.02em;
}

.lq-line.lq-dim { color: var(--lqDim); }
.lq-hl { font-style: normal; color: var(--lqHot); }

/* The blinking advance arrow. */
.lq-next {
  position: absolute;
  right: 1.5rem;
  bottom: 1rem;
  font-size: 1.5rem;
  color: var(--lqInk);
  animation: lqBlink 1s steps(2, start) infinite;
}

@keyframes lqBlink { 50% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .lq-next { animation: none; } }

/* ── The end card ─────────────────────────────────────────── */

.lq-end { text-align: center; }

.lq-end-head {
  font-family: 'Press Start 2P', monospace;
  font-size: 1.2rem;
  letter-spacing: 0.05em;
  color: var(--lqGold);
  margin-bottom: 1.25rem;
}

.lq-end-grid {
  display: grid;
  grid-template-columns: repeat(3, auto auto);
  gap: 0.4rem 1rem;
  justify-content: center;
  align-items: baseline;
  margin-bottom: 1.5rem;
  font-size: 1.15rem;
}

.lq-end-grid span { color: var(--lqDim); font-size: 0.78rem; letter-spacing: 0.08em; }
.lq-end-grid b { color: var(--lqInk); font-weight: 400; text-align: left; }

.lq-end-actions { display: flex; gap: 4px; justify-content: center; max-width: 520px; margin: 0 auto; }
.lq-end-actions .lq-mi { font-size: 0.85rem; }

@media (max-width: 900px) {
  .lq-frame { padding: 1rem 1.5rem 2rem; }
  .lq-scene { height: 300px; }
  .lq-foe { width: 180px; right: 0.5rem; }
  .lq-foe-art { width: 118px; height: 156px; font-size: 3.4rem; border-radius: 60px 60px 6px 6px; }
  .lq-line { font-size: 1.3rem; }
  .lq-mi { font-size: 0.8rem; }
  .lq-end-grid { grid-template-columns: auto auto; }
}

/* The admin's tab row and its one global action share a line. */
.lang-admin-head {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.lang-admin-head .lang-tabs-admin { padding: 0; margin: 0; flex: 1; }

/* The starter-pack offer, shown beside whatever is empty rather than only in
   Admin — nobody goes looking in Admin for the reason a page is blank. */
.lang-seed-offer {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 1rem 1.15rem;
  margin-top: 1rem;
  border: 1px dashed var(--color-primary);
  border-radius: var(--radius-md);
  background: var(--color-primary-subtle);
}

.lang-seed-offer > i,
.lang-seed-offer > svg {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  color: var(--color-primary);
}

.lang-seed-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.lang-seed-body strong { color: var(--text-primary); font-size: 0.9rem; }
.lang-seed-body span { color: var(--text-secondary); font-size: 0.8rem; line-height: 1.45; }
.lang-seed-offer .btn { flex-shrink: 0; }

@media (max-width: 640px) {
  .lang-seed-offer { flex-direction: column; align-items: flex-start; }
}

/* The pack offer at the HEAD of the board. The footer sat under ten cards, so
   the one control that fixes a wing full of zeros was itself below the fold. */
.lang-seed-banner {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  width: 100%;
  padding: 0.7rem 0.8rem;
  margin-bottom: 0.6rem;
  border: 1px dashed var(--color-primary);
  border-radius: var(--radius-md);
  background: var(--color-primary-subtle);
  cursor: pointer;
  text-align: left;
  font-family: var(--font-sans);
  transition: background 0.15s ease, border-color 0.15s ease;
}

.lang-seed-banner:hover { background: var(--color-primary-glow); border-style: solid; }
.lang-seed-banner > i, .lang-seed-banner > svg { width: 20px; height: 20px; flex-shrink: 0; color: var(--color-primary); }
.lang-seed-banner-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.lang-seed-banner-body strong { color: var(--text-primary); font-size: 0.85rem; }
.lang-seed-banner-body span { color: var(--text-secondary); font-size: 0.7rem; line-height: 1.35; }
.lang-seed-banner-go { color: var(--color-primary); }

/* The "+10" beside the stamina, so a raised maximum is visibly a reward for
   winning conversations rather than a number that drifted. */
.lq-grown {
  font-style: normal;
  margin-left: 0.3rem;
  padding: 0 0.25rem;
  font-size: 0.8em;
  color: #1a1524;
  background: var(--lqGold);
}

/* ============================================================
   THE DRILL, IN THE SAME WORLD AS THE RUN
   ------------------------------------------------------------
   The drill runner was wearing the app's chrome — its tokens, its sans face,
   its rounded surfaces — while the run next door is a pixel game. Two visual
   languages inside one library, reached from two cards on the same board.

   It borrows the run's palette and its two faces here, scoped under .la-shell
   so nothing leaks. Structure is untouched: this is a re-skin, not a rebuild,
   because the drill's layout already works and only its clothes were wrong.
   ============================================================ */

.la-shell {
  --lqInk: #efeaf5;
  --lqDim: #9b93ad;
  --lqPanel: #2a2536;
  --lqPanelHi: #3d3650;
  --lqEdge: #15111e;
  --lqLine: #574d6b;
  --lqHot: #ff5f6d;
  --lqGold: #ffd166;
  --lqCyan: #7ee8e0;

  background: #0d0a14;
  background-image:
    repeating-linear-gradient(180deg, rgba(255,255,255,0.035) 0 26px, transparent 26px 60px),
    repeating-linear-gradient(180deg, rgba(255,255,255,0.035) 0 26px, transparent 26px 60px);
  background-size: 62px 60px, 62px 60px;
  background-position: 14px 0, calc(100% - 14px) 0;
  background-repeat: repeat-y, repeat-y;
  color: var(--lqInk);
  font-family: 'Pixelify Sans', 'Courier New', monospace;
  image-rendering: pixelated;
}

.la-top {
  border-bottom: 2px solid var(--lqEdge);
  background: rgba(20, 16, 30, 0.75);
}

.la-progress {
  height: 12px;
  border-radius: 0;
  background: rgba(0, 0, 0, 0.55);
  border: 2px solid var(--lqEdge);
}
.la-progress-fill { border-radius: 0; background: var(--lqCyan); }

.la-heart { color: var(--lqHot); }
.la-clock { font-family: 'Press Start 2P', monospace; font-size: 0.8rem; color: var(--lqInk); }
.la-clock.is-low { color: var(--lqHot); }

/* The skin sets its own sizes, so it has to scale from the same tokens the
   layout does -- otherwise the card grew and everything printed on it stayed
   the size it was on a laptop. Pixelify Sans runs small for its point size,
   hence the multipliers above 1. */
.la-kind {
  font-family: 'Press Start 2P', monospace;
  font-size: clamp(0.62rem, 0.5rem + 0.35vw, 0.95rem);
  letter-spacing: 0.08em;
  color: var(--lqCyan);
}

/* THE QUESTION IS NOT CHROME. Everything the skin dresses up -- the labels,
   the buttons, the verdict -- is furniture, and a pixel face suits furniture.
   The question is the one thing on screen that has to be read exactly, often
   in a language you do not know yet, and Pixelify Sans blurs precisely the
   distinctions that matter there: quotation marks, the difference between
   "unsa" and "unsaon", a word you are being asked to reproduce letter for
   letter. Content gets the app's own text face; the game keeps its clothes.

   Inter sets larger than Pixelify at the same px, so the 1.3 multiplier that
   compensated for the pixel face comes back off. */
.la-prompt {
  font-family: var(--font-sans);
  font-size: var(--la-prompt);
  font-weight: 750;
  letter-spacing: -0.015em;
  color: var(--lqInk);
}

.la-blank-line {
  font-family: var(--font-sans);
  color: var(--lqInk);
  font-size: calc(var(--la-prompt) * 0.62);
  font-weight: 500;
}
.la-blank-slot { border-bottom-color: var(--lqCyan); color: var(--lqCyan); }

.la-lane { border-bottom: 2px dashed var(--lqLine); }
.la-lane-hint { color: var(--lqDim); font-family: var(--font-sans); }

/* Word tiles as chunky keys, the way the run's commands are. */
.la-tile,
.la-option,
.la-match-btn {
  border-radius: 0;
  background: rgba(58, 51, 74, 0.95);
  border: 2px solid var(--lqEdge);
  border-bottom-width: 4px;
  color: var(--lqInk);
  font-family: 'Pixelify Sans', monospace;
  font-size: calc(var(--la-answer) * 1.22);
  transition: background 0.1s steps(2), border-color 0.1s steps(2);
}

.la-tile:hover,
.la-option:hover,
.la-match-btn:hover { background: rgba(120, 108, 150, 0.96); border-color: var(--lqEdge); }

.la-tile.is-placed,
.la-option.is-picked,
.la-match-btn.is-picked {
  background: rgba(126, 232, 224, 0.2);
  border-color: var(--lqCyan);
}

.la-match-btn.is-done { opacity: 0.4; }

.la-option-key {
  border-radius: 0;
  border: 2px solid var(--lqLine);
  color: var(--lqDim);
  font-family: 'Press Start 2P', monospace;
  font-size: calc(var(--la-answer) * 0.62);
}

.la-typed .form-input {
  border-radius: 0;
  background: #191426;
  border: 2px solid var(--lqEdge);
  color: var(--lqInk);
  font-family: var(--font-sans);
  font-size: calc(var(--la-answer) * 1.05);
  font-weight: 600;
}

.la-feedback { border-radius: 0; border: 2px solid var(--lqEdge); }
.la-feedback.is-right { background: rgba(126, 232, 224, 0.14); }
.la-feedback.is-wrong { background: rgba(255, 95, 109, 0.14); }
.la-correct { color: var(--lqInk); font-size: calc(var(--la-answer) * 1.05); font-family: var(--font-sans); font-weight: 650; }
.la-correct em { color: var(--lqDim); font-family: 'Press Start 2P', monospace; font-size: calc(var(--la-answer) * 0.58); }
.la-note { color: var(--lqDim); font-size: calc(var(--la-answer) * 0.8); font-family: var(--font-sans); line-height: 1.5; }

.la-foot { border-top: 2px solid var(--lqEdge); background: rgba(20, 16, 30, 0.75); }
.la-foot-inner.is-right { background: rgba(126, 232, 224, 0.12); }
.la-foot-inner.is-wrong { background: rgba(255, 95, 109, 0.12); }
.la-verdict { font-family: 'Press Start 2P', monospace; font-size: clamp(0.72rem, 0.58rem + 0.4vw, 1.05rem); }
.la-foot-inner.is-right .la-verdict { color: var(--lqCyan); }
.la-foot-inner.is-wrong .la-verdict { color: var(--lqHot); }

/* The footer buttons are the run's menu items, so they read as one game. */
.la-foot .btn {
  border-radius: 0;
  border: 2px solid var(--lqEdge);
  border-bottom-width: 4px;
  background: rgba(58, 51, 74, 0.95);
  color: var(--lqInk);
  font-family: 'Press Start 2P', monospace;
  font-size: clamp(0.72rem, 0.58rem + 0.4vw, 1.05rem);
  padding: clamp(0.6rem, 0.4rem + 0.5vw, 1.05rem) clamp(1rem, 0.7rem + 0.9vw, 2rem);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.la-foot .btn:hover:not(:disabled) { background: rgba(120, 108, 150, 0.96); color: #fff; }
.la-foot .btn:disabled { opacity: 0.35; }
.la-foot .btn-ghost { background: transparent; border-color: var(--lqLine); color: var(--lqDim); }

.la-summary h2 { font-family: 'Press Start 2P', monospace; font-size: clamp(1.1rem, 0.85rem + 0.75vw, 1.9rem); color: var(--lqGold); }
.la-summary p { color: var(--lqDim); font-family: var(--font-sans); }
.la-summary-icon { border-radius: 0; border: 2px solid var(--lqEdge); background: rgba(58, 51, 74, 0.9); }
.la-summary-score { font-family: 'Press Start 2P', monospace; font-size: clamp(2rem, 1.4rem + 1.8vw, 3.6rem); }
.la-summary-score.score-perfect { color: var(--lqCyan); }
.la-summary-score.score-partial { color: var(--lqGold); }
.la-summary-score.score-low { color: var(--lqHot); }

.la-review h3 { font-family: 'Press Start 2P', monospace; font-size: 0.6rem; color: var(--lqDim); }
.la-review-row { border-radius: 0; background: #191426; border: 2px solid var(--lqEdge); font-size: calc(var(--la-answer) * 0.9); font-family: var(--font-sans); }
.la-review-given { color: var(--lqHot); }
.la-review-expected { color: var(--lqCyan); }

.la-summary-actions .btn {
  border-radius: 0;
  border: 2px solid var(--lqEdge);
  border-bottom-width: 4px;
  background: rgba(58, 51, 74, 0.95);
  color: var(--lqInk);
  font-family: 'Press Start 2P', monospace;
  font-size: 0.72rem;
}
.la-summary-actions .btn:hover { background: rgba(120, 108, 150, 0.96); }

/* The back control, matching the run's. */
.la-top .btn-back-dark {
  border-radius: 0;
  border: 2px solid var(--lqEdge);
  background: var(--lqPanel);
  color: var(--lqInk);
  font-family: 'Press Start 2P', monospace;
  font-size: 0.6rem;
}

/* Two packs on offer where there used to be one, so they need to sit as a pair
   rather than as a button with another button beside it. */
.lang-seed-actions { display: flex; gap: 0.5rem; flex-wrap: wrap; flex-shrink: 0; }
