@import url("https://fonts.googleapis.com/css2?family=Fraunces:wght@500;600&family=Space+Grotesk:wght@500;600&display=swap");

:root {
  color-scheme: light;
  --bg-top: #c0b8b0;
  --bg-bottom: #c0b8b0;
  --ink: #1e2430;
  --muted: #5f6b76;
  /* 2026-08-29: white, not cream. Bruce wants the whole working area plain
     white so nothing competes with the letters. */
  --card: #ffffff;
  --accent: #2f6f65;
  --accent-dark: #21524b;
  --shadow: 0 18px 36px rgba(33, 41, 52, 0.12);
  --radius: 20px;
  --runtime-panel-width: 480px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  /* 2026-05-28: always reserve the vertical scrollbar's gutter so the
     page doesn't shift horizontally when a phase's content grows tall
     enough to trigger the browser scrollbar. Most phases fit in the
     viewport; Phase 8 (reading story, 5 sentence rows) doesn't —
     without this rule, the flex-centered student-shell drifted ~15px
     to the right on phases that didn't need a scrollbar.
     Supported: Chrome 94+, Edge 94+, Firefox 97+, Safari 18.2+.
     Older Safari silently ignores it (falls back to current behavior). */
  scrollbar-gutter: stable;
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: "Fraunces", "Georgia", serif;
  color: var(--ink);
  background: linear-gradient(160deg, var(--bg-top), var(--bg-bottom));
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12px;
  gap: 16px;
}

.student-shell {
  width: min(1200px, 100%);
  display: flex;
  flex-direction: column;
  gap: 8px;
  position: relative;
}

.student-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 16px;
}

.student-title {
  font-size: 1.3rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}

.sound-badge {
  position: absolute;
  top: 6px;
  right: 12px;
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid rgba(47, 111, 101, 0.2);
  border-radius: 14px;
  padding: 8px 12px;
  box-shadow: 0 8px 18px rgba(33, 41, 52, 0.12);
  text-align: left;
  max-width: 220px;
}

.sound-badge-line1 {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.2;
}

.sound-badge-line2 {
  font-size: 0.75rem;
  color: var(--muted);
  line-height: 1.2;
  margin-top: 2px;
}

.student-stage {
  background: var(--card);
  border-radius: var(--radius);
  padding: 12px;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: center;
  text-align: center;
  position: relative;
}

/* Two-column layout for fitting everything above the fold */
.student-stage.two-column-layout {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto 1fr;
  gap: 10px;
  align-items: start;
  text-align: left;
  max-height: calc(100vh - 60px);
}

.student-stage.two-column-layout .student-name-label {
  grid-column: 1 / -1;
}

.stage-left-column {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-start;
}

.stage-right-column {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  text-align: center;
  min-width: 400px;
}

/* Old lesson-nav removed - now using unified-nav-panel */

.student-name-label {
  font-size: 0.85rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
}

.student-name-label.is-hidden {
  display: none;
}

/* Phase Marker */
.phase-marker {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 10px 20px;
  background: rgba(47, 111, 101, 0.08);
  border: 1px solid rgba(47, 111, 101, 0.2);
  border-radius: 999px;
  margin-bottom: 8px;
  transition: all 0.3s ease;
}

.phase-marker-icon {
  font-size: 1.4rem;
  line-height: 1;
  transition: transform 0.3s ease;
}

.phase-marker-label {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--accent-dark);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
}

.phase-marker.phase-active {
  background: rgba(47, 111, 101, 0.12);
  border-color: rgba(47, 111, 101, 0.35);
}

.phase-marker.phase-active .phase-marker-icon {
  transform: scale(1.1);
}

/* Unified Navigation Panel */
.unified-nav-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 14px;
  background: rgba(47, 111, 101, 0.06);
  border: 1px solid rgba(47, 111, 101, 0.2);
  border-radius: 12px;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
  font-size: 0.85rem;
  width: 540px;
  height: 170px;
  overflow: hidden;
}

.unified-nav-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.unified-nav-lesson-row {
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(47, 111, 101, 0.15);
}

.unified-nav-lesson-label {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--ink);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  min-width: 100px;
  text-align: center;
}

.unified-nav-phase-row {
  gap: 16px;
}

.unified-nav-info {
  display: flex;
  align-items: center;
  gap: 4px;
}

.unified-nav-label {
  color: var(--muted);
  font-weight: 500;
  font-size: 0.8rem;
}

.unified-nav-value {
  color: var(--ink);
  font-weight: 600;
  font-size: 0.85rem;
}

.unified-nav-btns {
  display: flex;
  gap: 8px;
  margin-left: auto;
}

.unified-nav-btn {
  padding: 6px 12px;
  font-size: 0.8rem;
  font-weight: 600;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
  background: #ffffff;
  color: var(--accent-dark);
  border: 1px solid rgba(47, 111, 101, 0.3);
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s ease;
}

.unified-nav-btn:hover:not(:disabled) {
  background: rgba(47, 111, 101, 0.08);
  border-color: rgba(47, 111, 101, 0.5);
}

.unified-nav-btn:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.unified-nav-sounds {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
  padding-top: 8px;
  border-top: 1px solid rgba(47, 111, 101, 0.15);
}

.unified-nav-sounds:empty {
  display: none;
  padding-top: 0;
  border-top: none;
}

.progress-sound-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 8px;
  background: #ffffff;
  border: 1px solid rgba(47, 111, 101, 0.25);
  border-radius: 6px;
  font-size: 0.75rem;
  color: var(--ink);
}

.progress-sound-chip.is-current {
  background: rgba(47, 111, 101, 0.15);
  border-color: var(--accent);
  font-weight: 600;
}

.progress-sound-letter {
  font-weight: 600;
  font-size: 0.85rem;
}

.progress-sound-num {
  color: var(--muted);
  font-size: 0.7rem;
}

.student-prompt {
  font-size: clamp(1.9rem, 4vw, 2.8rem);
  font-weight: 600;
  line-height: 1.2;
  min-height: 3.5rem;
}

/* Sound Table - 71 sounds in 8 columns, 9 rows (one empty cell at top of last column) */
.sound-table-container {
  width: fit-content;
  max-width: 100%;
  border: 1px solid rgba(47, 111, 101, 0.2);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.95);
  padding: 8px;
  margin: 8px 0;
}

.sound-table-grid {
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 2px;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
  font-size: 0.75rem;
}

.sound-table-cell {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 2px 6px;
  background: #ffffff;
  border: 1px solid rgba(47, 111, 101, 0.1);
  border-radius: 3px;
  min-height: 20px;
  transition: background 0.2s ease, border-color 0.2s ease;
  font-size: 0.7rem;
}

.sound-table-cell:hover {
  background: rgba(47, 111, 101, 0.05);
}

.sound-table-cell.is-highlighted {
  background: rgba(47, 111, 101, 0.2);
  border-color: var(--accent);
  font-weight: 600;
}

.sound-table-cell.is-current {
  background: rgba(47, 111, 101, 0.35);
  border-color: var(--accent);
  border-width: 2px;
  font-weight: 700;
}

.sound-table-cell.is-new-sound {
  background: rgba(220, 53, 69, 0.15);
  border-color: #dc3545;
  border-width: 2px;
  font-weight: 600;
  color: #dc3545;
}

.sound-table-cell.is-new-sound .sound-table-letter {
  color: #dc3545;
}

/* Wobble levels - progressively darker blue */
/* Use !important to ensure wobble styling overrides is-highlighted */
.sound-table-cell.wobble-1 {
  background: rgba(66, 133, 244, 0.25) !important;
  border-color: rgba(66, 133, 244, 0.5) !important;
}

.sound-table-cell.wobble-2 {
  background: rgba(66, 133, 244, 0.35) !important;
  border-color: rgba(66, 133, 244, 0.6) !important;
}

.sound-table-cell.wobble-3 {
  background: rgba(66, 133, 244, 0.45) !important;
  border-color: rgba(66, 133, 244, 0.7) !important;
}

.sound-table-cell.wobble-4 {
  background: rgba(66, 133, 244, 0.55) !important;
  border-color: rgba(66, 133, 244, 0.8) !important;
}

.sound-table-cell.wobble-5 {
  background: rgba(66, 133, 244, 0.65) !important;
  border-color: rgba(66, 133, 244, 0.9) !important;
  color: #fff;
}

.sound-table-cell.wobble-5 .sound-table-letter,
.sound-table-cell.wobble-5 .sound-table-keyword,
.sound-table-cell.wobble-5 .sound-table-num {
  color: #fff;
}

/* Review reason colors — override is-highlighted when smart selection is active */
.sound-table-cell.review-wobble {
  background: rgba(220, 53, 69, 0.2) !important;
  border-color: rgba(220, 53, 69, 0.6) !important;
}

.sound-table-cell.review-recent {
  background: rgba(47, 111, 101, 0.25) !important;
  border-color: rgba(47, 111, 101, 0.7) !important;
}

.sound-table-cell.review-stale {
  background: rgba(243, 156, 18, 0.25) !important;
  border-color: rgba(243, 156, 18, 0.6) !important;
}

.sound-table-cell.is-empty {
  background: rgba(200, 200, 200, 0.1);
  border-color: transparent;
}

.sound-table-num {
  color: var(--muted);
  font-size: 0.65rem;
  min-width: 20px;
  text-align: right;
}

.sound-table-letter {
  font-weight: 600;
  font-size: 0.85rem;
  color: var(--ink);
}

.sound-table-keyword {
  color: var(--muted);
  font-size: 0.65rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 2026-05-29 — dual mastery dots, first step toward the per-sound
   reading/spelling status map. Two small circles per cell, top dot
   for reading, bottom for spelling. Color set by JS. */
.sound-table-mastery {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  margin-left: auto;       /* push right inside flex cell */
  align-self: center;
}
.mastery-dot {
  display: block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #cbd5e1;     /* default unseen gray */
  border: 1px solid rgba(0, 0, 0, 0.1);
}

.student-interaction {
  width: min(640px, 100%);
  min-height: 0;
  border-radius: 14px;
  border: none;
  background: transparent;
  color: var(--muted);
  font-size: 1.05rem;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px;
  overflow-y: auto;
}

.tile-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  width: 100%;
  max-width: 400px;
}

.tile-grid.is-visible {
  display: grid;
}

.tile {
  aspect-ratio: 1;
  min-height: 100px;
  border-radius: 18px;
  border: 2px solid rgba(47, 111, 101, 0.25);
  background: #ffffff;
  font-size: 2.2rem;
  font-weight: 700;
  color: var(--ink);
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease, background 0.2s ease;
  box-shadow: 0 10px 18px rgba(33, 41, 52, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
}

.tile:hover {
  transform: translateY(-3px);
  border-color: rgba(47, 111, 101, 0.6);
  box-shadow: 0 14px 28px rgba(33, 41, 52, 0.14);
}

.tile.selected {
  background: rgba(47, 111, 101, 0.12);
  border-color: var(--accent);
  border-width: 3px;
  transform: translateY(-2px);
}

.tile:active {
  transform: translateY(0);
}

.interaction-placeholder {
  display: block;
  color: var(--muted);
}

.interaction-placeholder.is-hidden {
  display: none;
}

.student-tiles {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  justify-content: center;
}

.student-tile {
  min-width: 84px;
  min-height: 84px;
  border-radius: 18px;
  border: 2px solid rgba(47, 111, 101, 0.25);
  background: #ffffff;
  font-size: 2rem;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
  box-shadow: 0 10px 18px rgba(33, 41, 52, 0.08);
}

.student-tile:hover {
  transform: translateY(-2px);
  border-color: rgba(47, 111, 101, 0.5);
  box-shadow: 0 14px 24px rgba(33, 41, 52, 0.12);
}

.student-feedback {
  min-height: 22px;
  font-size: 1rem;
  color: var(--accent-dark);
  font-weight: 500;
}

.student-debug {
  display: none;
  font-size: 0.85rem;
  color: var(--muted);
  text-align: center;
}

.student-debug.is-visible {
  display: block;
}

.dev-toggle-btn {
  position: fixed;
  top: 16px;
  right: 16px;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid rgba(47, 111, 101, 0.3);
  background: #ffffff;
  color: var(--muted);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  display: block;
}

.stt-panel {
  display: none;
  margin-top: 20px;
  padding: 16px;
  border: 2px solid rgba(47, 111, 101, 0.25);
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.8);
}

.stt-panel.is-visible {
  display: block;
}

.stt-panel-title {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 12px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.stt-status {
  font-size: 0.85rem;
  color: var(--muted);
  margin-bottom: 8px;
}

.stt-transcript {
  min-height: 40px;
  padding: 10px;
  border: 1px solid rgba(47, 111, 101, 0.2);
  border-radius: 8px;
  background: #ffffff;
  font-size: 0.9rem;
  margin-bottom: 12px;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
}

.stt-panel-actions {
  display: flex;
  gap: 8px;
}

.dev-instruction-controls {
  position: absolute;
  bottom: 16px;
  left: 16px;
  width: min(260px, 90vw);
  background: rgba(255, 255, 255, 0.95);
  border-radius: 14px;
  border: 1px solid rgba(47, 111, 101, 0.25);
  box-shadow: 0 12px 24px rgba(33, 41, 52, 0.16);
  padding: 12px;
  display: none;
  z-index: 12;
}

.dev-control-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.dev-control-block {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 8px;
}

.dev-control-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  min-width: 58px;
}

.dev-control-select {
  flex: 1;
  border: 1px solid rgba(47, 111, 101, 0.25);
  border-radius: 10px;
  padding: 6px 8px;
  font-size: 0.85rem;
  color: var(--ink);
  background: #ffffff;
}

.dev-control-row input[type="checkbox"] {
  width: 18px;
  height: 18px;
  accent-color: var(--accent);
}

.dev-control-transcript {
  min-height: 52px;
  padding: 8px 10px;
  border-radius: 10px;
  border: 1px solid rgba(47, 111, 101, 0.18);
  background: rgba(47, 111, 101, 0.06);
  font-size: 0.85rem;
  color: var(--ink);
  white-space: pre-wrap;
}

.dev-control-status {
  font-size: 0.75rem;
  color: var(--muted);
  min-height: 1em;
}

.dev-control-btn {
  width: 100%;
  border: 1px solid rgba(47, 111, 101, 0.35);
  border-radius: 999px;
  padding: 8px 12px;
  font-size: 0.85rem;
  font-weight: 600;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
  background: #ffffff;
  color: var(--accent-dark);
  cursor: pointer;
}

.student-primary-btn {
  border: none;
  border-radius: 999px;
  padding: 16px 46px;
  font-size: 1.2rem;
  font-weight: 600;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
  background: var(--accent);
  color: #ffffff;
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
  box-shadow: 0 10px 20px rgba(47, 111, 101, 0.22);
}

.student-primary-btn:hover {
  transform: translateY(-2px);
  background: var(--accent-dark);
  box-shadow: 0 14px 26px rgba(33, 82, 75, 0.24);
}

.student-primary-btn:active {
  transform: translateY(0);
}

.student-primary-btn:disabled,
.student-primary-btn.is-disabled {
  opacity: 0.4;
  cursor: not-allowed;
  transform: none;
  box-shadow: 0 10px 20px rgba(47, 111, 101, 0.12);
}

.student-primary-btn:disabled:hover,
.student-primary-btn.is-disabled:hover {
  transform: none;
  background: var(--accent);
}

/* Student Action Button Bar (Repeat, Pause) */
.student-button-bar {
  display: flex;
  gap: 10px;
  justify-content: center;
  margin-top: 4px;
}

.student-action-btn {
  border: 2px solid rgba(47, 111, 101, 0.35);
  border-radius: 999px;
  padding: 8px 18px;
  font-size: 0.9rem;
  font-weight: 600;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
  background: #ffffff;
  color: var(--accent-dark);
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease, background 0.2s ease;
  display: flex;
  align-items: center;
  gap: 6px;
}

.student-action-btn:hover {
  transform: translateY(-2px);
  border-color: rgba(47, 111, 101, 0.6);
  box-shadow: 0 8px 18px rgba(33, 41, 52, 0.12);
  background: rgba(47, 111, 101, 0.05);
}

.student-action-btn:active {
  transform: translateY(0);
}

.student-repeat-btn {
  border-color: rgba(66, 133, 244, 0.5);
  color: #1a73e8;
}

.student-repeat-btn:hover {
  border-color: rgba(66, 133, 244, 0.8);
  background: rgba(66, 133, 244, 0.08);
}

.student-pause-btn {
  border-color: rgba(251, 188, 4, 0.6);
  color: #b36b00;
}

.student-pause-btn:hover {
  border-color: rgba(251, 188, 4, 0.9);
  background: rgba(251, 188, 4, 0.1);
}

/* Global Continue Button - fixed position in bottom-right corner */
.global-continue-btn {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 1000;
  padding: 16px 32px;
  font-size: 1.2rem;
  font-weight: 600;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
  background: linear-gradient(145deg, #34a853, #2d8f47);
  color: #ffffff;
  border: none;
  border-radius: 12px;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(52, 168, 83, 0.4), 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  animation: continueButtonPulse 2s ease-in-out infinite;
}

.global-continue-btn:hover {
  transform: translateY(-2px) scale(1.02);
  box-shadow: 0 6px 20px rgba(52, 168, 83, 0.5), 0 3px 6px rgba(0, 0, 0, 0.15);
}

.global-continue-btn:active {
  transform: translateY(0) scale(0.98);
}

.global-continue-btn:disabled {
  background: #ccc;
  cursor: not-allowed;
  animation: none;
  box-shadow: none;
}

.global-continue-btn.is-hidden {
  display: none !important;
}

@keyframes continueButtonPulse {
  0%, 100% { box-shadow: 0 4px 16px rgba(52, 168, 83, 0.4), 0 2px 4px rgba(0, 0, 0, 0.1); }
  50% { box-shadow: 0 4px 24px rgba(52, 168, 83, 0.6), 0 2px 4px rgba(0, 0, 0, 0.1); }
}

.student-secondary-btn {
  border: 2px solid rgba(47, 111, 101, 0.35);
  border-radius: 999px;
  padding: 12px 32px;
  font-size: 1rem;
  font-weight: 600;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
  background: #ffffff;
  color: var(--accent-dark);
  cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

.student-secondary-btn:hover {
  transform: translateY(-1px);
  border-color: rgba(47, 111, 101, 0.6);
  box-shadow: 0 8px 18px rgba(33, 41, 52, 0.12);
}

.student-secondary-btn:active {
  transform: translateY(0);
}

.dev-mark-btn {
  display: inline-block;
  border: 1px solid rgba(47, 111, 101, 0.35);
  border-radius: 999px;
  padding: 10px 22px;
  font-size: 0.95rem;
  font-weight: 600;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
  background: rgba(255, 255, 255, 0.85);
  color: var(--accent-dark);
  cursor: pointer;
}

.dev-mark-btn.is-hidden {
  display: none;
}

body.dev-inspector-on .dev-mark-btn {
  display: inline-block;
}

.dev-mark-btn:disabled,
.dev-mark-btn.is-disabled {
  opacity: 0.4;
  cursor: not-allowed;
  background: rgba(200, 200, 200, 0.3);
}

.dev-mark-btn:disabled:hover,
.dev-mark-btn.is-disabled:hover {
  transform: none;
  border-color: rgba(47, 111, 101, 0.35);
  box-shadow: none;
}

.explain-modal {
  position: fixed;
  inset: 0;
  background: rgba(30, 36, 48, 0.45);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 20;
}

.explain-card {
  width: min(560px, 100%);
  background: #ffffff;
  border-radius: 20px;
  box-shadow: var(--shadow);
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  text-align: left;
}

.explain-title {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--ink);
}

.explain-body {
  font-size: 0.98rem;
  color: var(--ink);
  line-height: 1.5;
  white-space: pre-line;
}

body.explain-open .explain-modal,
.explain-modal[aria-hidden="false"] {
  display: flex;
}

/* ========================================
   Micro-Lesson Overlay
   Shown after 2nd incorrect answer
   ======================================== */
.micro-lesson-overlay {
  position: fixed;
  inset: 0;
  background: rgba(30, 36, 48, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  z-index: 9000;
  animation: microLessonFadeIn 0.3s ease-out;
}

@keyframes microLessonFadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.micro-lesson-card {
  width: min(480px, 90%);
  background: linear-gradient(135deg, #fff9e6 0%, #ffffff 50%, #e6f7ff 100%);
  border-radius: 24px;
  box-shadow: 0 24px 48px rgba(33, 41, 52, 0.2);
  padding: 32px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  text-align: center;
  border: 3px solid var(--accent);
  animation: microLessonSlideUp 0.3s ease-out;
}

@keyframes microLessonSlideUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.micro-lesson-badge {
  display: inline-block;
  background: var(--accent);
  color: white;
  font-size: 0.85rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 6px 16px;
  border-radius: 20px;
  align-self: center;
}

.micro-lesson-text {
  font-size: 1.4rem;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.5;
  padding: 8px 0;
}

.micro-lesson-continue-btn {
  background: var(--accent);
  color: white;
  font-family: inherit;
  font-size: 1.1rem;
  font-weight: 600;
  padding: 14px 32px;
  border: none;
  border-radius: 12px;
  cursor: pointer;
  transition: background 0.2s, transform 0.1s;
  align-self: center;
}

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

.micro-lesson-continue-btn:active {
  transform: scale(0.98);
}

#flowInspector {
  display: none;
  width: min(420px, 100%);
  background: #ffffff;
  border-radius: 18px;
  border: 1px solid rgba(47, 111, 101, 0.2);
  box-shadow: var(--shadow);
  padding: 20px;
  max-height: calc(100vh - 48px);
  overflow: auto;
}

.inspector-title {
  font-size: 1rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 12px;
}

.inspector-group {
  margin-bottom: 12px;
}

.inspector-label {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 4px;
}

.inspector-value {
  font-size: 0.9rem;
  color: var(--ink);
}

.inspector-mono {
  font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: 0.85rem;
  white-space: pre-wrap;
  word-break: break-word;
}

.student-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.student-panel-input {
  width: 100%;
  border: 1px solid rgba(47, 111, 101, 0.25);
  border-radius: 10px;
  padding: 8px 10px;
  font-size: 0.9rem;
  color: var(--ink);
  background: #ffffff;
}

.student-panel-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.student-panel-btn {
  border: 1px solid rgba(47, 111, 101, 0.35);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 0.8rem;
  font-weight: 600;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
  background: #ffffff;
  color: var(--accent-dark);
  cursor: pointer;
}

.student-panel-btn:hover {
  border-color: rgba(47, 111, 101, 0.6);
}

.student-panel-danger {
  border-color: rgba(138, 45, 45, 0.5);
  color: #8a2d2d;
}

.student-panel-status {
  min-height: 1.1em;
  font-size: 0.8rem;
  color: var(--muted);
}

.student-panel-label {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

.student-panel-history {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.student-panel-session {
  padding: 6px 8px;
  border-radius: 10px;
  background: rgba(47, 111, 101, 0.06);
  border: 1px solid rgba(47, 111, 101, 0.15);
  font-size: 0.78rem;
  color: var(--ink);
  line-height: 1.3;
}

.all-students-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 240px; /* Show ~4 students, scroll for more */
  overflow-y: auto;
  padding: 4px 0;
}

.student-entry {
  padding: 10px 12px;
  border-radius: 10px;
  background: rgba(47, 111, 101, 0.06);
  border: 1px solid rgba(47, 111, 101, 0.15);
  font-size: 0.75rem;
  color: var(--ink);
  line-height: 1.4;
}

.student-entry-name {
  font-weight: 600;
  font-size: 0.85rem;
  margin-bottom: 4px;
  color: var(--accent);
}

.student-entry-detail {
  font-size: 0.7rem;
  color: var(--muted);
  margin: 2px 0;
}

.student-entry-active {
  background: rgba(47, 111, 101, 0.12);
  border-color: var(--accent);
}

body.dev-inspector-on {
  align-items: stretch;
  justify-content: center;
}

body.dev-inspector-on #studentApp {
  flex: 0 1 70%;
  max-width: 70%;
}

/* Flow Inspector Panel Styles */
#flowInspector {
  display: none;
  background: #1e1e2e;
  color: #cdd6f4;
  padding: 1rem;
  overflow-y: auto;
  font-family: 'Segoe UI', system-ui, sans-serif;
  font-size: 0.85rem;
  border-left: 1px solid #45475a;
}

.flow-inspector-title {
  font-size: 1rem;
  font-weight: 600;
  color: #89b4fa;
  margin: 0 0 1rem 0;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid #45475a;
}

.flow-inspector-section {
  margin-bottom: 0.75rem;
}

.flow-inspector-section label {
  display: block;
  font-size: 0.75rem;
  color: #a6adc8;
  margin-bottom: 0.25rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.flow-inspector-section span {
  color: #f5e0dc;
}

.flow-inspector-text {
  color: #cdd6f4;
  background: #313244;
  padding: 0.5rem;
  border-radius: 4px;
  font-size: 0.8rem;
  line-height: 1.4;
}

.flow-inspector-code {
  color: #a6e3a1;
  background: #1e1e2e;
  border: 1px solid #45475a;
  padding: 0.5rem;
  border-radius: 4px;
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 0.75rem;
  line-height: 1.3;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 200px;
  overflow-y: auto;
  margin: 0;
}

body.dev-inspector-on #flowInspector {
  display: block;
  flex: 0 1 30%;
  max-width: 30%;
}

/* Runtime Panel Styles */
#runtimePanel {
  display: none;
  position: fixed;
  top: 0;
  right: 0;
  /* Fixed right panel; #studentApp reserves the same width below. */
  width: var(--runtime-panel-width);
  height: 100vh;
  background: #f8f9fa;
  border-left: 1px solid #dee2e6;
  z-index: 1000;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  font-size: 12px;
  /* Use flexbox for sticky header + scrollable content */
  flex-direction: column;
  overflow: hidden;
}

/* Sticky header section - stays at top */
.runtime-panel-sticky {
  flex-shrink: 0;
  padding: 16px 16px 0 16px;
  background: #f8f9fa;
  border-bottom: 1px solid #dee2e6;
}

/* Scrollable content section */
.runtime-panel-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 12px 16px 16px 16px;
}

/* Collapse header used by the TTS/STT panel — click to fold/unfold
   the panel body so it stops eating space when you're not using it. */
.runtime-collapse-header {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 6px 8px;
  margin-top: 4px;
  background: #e9ecef;
  border: 1px solid #ced4da;
  border-radius: 4px;
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  color: #495057;
  text-align: left;
  font-family: inherit;
}
.runtime-collapse-header:hover { background: #dde2e6; }
.runtime-collapse-arrow {
  display: inline-block;
  transition: transform 0.15s ease;
  font-size: 10px;
}
.runtime-collapse-header[aria-expanded="false"] .runtime-collapse-arrow {
  transform: rotate(-90deg);
}
.runtime-panel-tts.is-collapsed > #runtimePanelTTSBody { display: none; }

/* 2026-08-04: TTS/STT provider config now lives as the LAST section inside
   the scroll body (below the diagnostics), not a pinned bottom pane — so it
   flows with the rest of the panel instead of floating in its own 200px box. */
.runtime-panel-tts {
  padding: 10px 16px 14px 16px;
  background: #f8f9fa;
  border-top: 1px solid #dee2e6;
}

body.dev-inspector-on #runtimePanel {
  display: flex;
}

body.dev-inspector-on #studentApp {
  flex: 0 1 calc(100vw - var(--runtime-panel-width) - 32px);
  max-width: calc(100vw - var(--runtime-panel-width) - 32px);
  margin-right: var(--runtime-panel-width);
}

/* Dev panel on the LOGIN screen too (consistency): leave the 480px right rail
   for the panel and shrink the login card so it doesn't slide under the panel.
   Only when dev mode is on — kids never see this. */
body.dev-inspector-on .login-screen {
  width: calc(100vw - var(--runtime-panel-width));
}
body.dev-inspector-on .login-tablet {
  width: min(1200px, calc(100vw - var(--runtime-panel-width) - 24px));
}

.runtime-panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: none;
}

/* Retired raw diagnostics remain in the DOM for compatibility with their
   existing update code, but no longer appear in the runtime panel. */
#runtimePanel .dev-diag { display: none !important; }

.runtime-panel-title {
  font-size: 14px;
  font-weight: 600;
  color: #495057;
  margin: 0;
}

.runtime-panel-close {
  background: none;
  border: none;
  font-size: 24px;
  color: #6c757d;
  cursor: pointer;
  padding: 0 4px;
  line-height: 1;
}

.runtime-panel-close:hover {
  color: #dc3545;
}

/* Compact Micro Toolbar */
.dev-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  padding: 6px 8px;
  background: #fff;
  border: 1px solid #dee2e6;
  border-radius: 4px;
  margin-bottom: 8px;
  font-family: monospace;
  font-size: 12px;
}

.dev-toolbar-group {
  display: flex;
  align-items: center;
  gap: 2px;
}

.dev-toolbar-label {
  font-size: 10px;
  color: #6c757d;
  margin-right: 2px;
  text-transform: uppercase;
}

.dev-toolbar-value {
  font-size: 11px;
  font-weight: 600;
  color: #495057;
  min-width: 20px;
  text-align: center;
  padding: 0 2px;
}

.dev-toolbar-btn {
  height: 26px;
  min-width: 26px;
  padding: 0 6px;
  font-size: 12px;
  font-family: inherit;
  background: #fff;
  border: 1px solid #ced4da;
  border-radius: 3px;
  cursor: pointer;
  color: #495057;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.dev-toolbar-btn:hover {
  background: #e9ecef;
  border-color: #adb5bd;
}

.dev-toolbar-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.dev-toolbar-btn-correct {
  color: #198754;
  border-color: #198754;
}

.dev-toolbar-btn-correct:hover {
  background: #d1e7dd;
}

.dev-toolbar-btn-incorrect {
  color: #dc3545;
  border-color: #dc3545;
}

.dev-toolbar-btn-incorrect:hover {
  background: #f8d7da;
}

.dev-toolbar-sep {
  width: 1px;
  height: 20px;
  background: #dee2e6;
  margin: 0 4px;
}

.dev-toolbar-input {
  width: 40px;
  height: 26px;
  padding: 0 4px;
  font-size: 12px;
  font-family: monospace;
  border: 1px solid #ced4da;
  border-radius: 3px;
  text-align: center;
}

.dev-toolbar-input:focus {
  outline: none;
  border-color: #86b7fe;
}

/* Inline toolbar variants (2026-05-25 — dev overflow drawer removed,
   everything is now always-visible inline) */
.dev-toolbar-btn-danger {
  color: #dc3545;
  border-color: #dc3545;
}
.dev-toolbar-btn-danger:hover {
  background: #f8d7da;
}

.dev-toolbar-checkbox {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  color: #495057;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}
.dev-toolbar-checkbox input {
  margin: 0;
  cursor: pointer;
}

.dev-toolbar-select {
  height: 24px;
  padding: 0 6px;
  font-size: 11px;
  border: 1px solid #ced4da;
  border-radius: 3px;
  background: #fff;
  max-width: 130px;
}

.runtime-row {
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid #e9ecef;
}

.runtime-label {
  font-size: 10px;
  font-weight: 500;
  color: #6c757d;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 4px;
}

.runtime-label-bold {
  font-weight: 600;
}

.runtime-value {
  color: #212529;
  margin-bottom: 2px;
}

.runtime-subtle {
  font-size: 11px;
  color: #868e96;
}

.runtime-pill {
  display: inline-block;
  background: #e9ecef;
  color: #495057;
  padding: 2px 8px;
  border-radius: 12px;
  font-size: 11px;
  margin-top: 4px;
}

.runtime-students-section {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid #dee2e6;
}

.runtime-words-section {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid #dee2e6;
}

.runtime-words-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  max-height: 150px;
  overflow-y: auto;
  margin: 8px 0;
  padding: 8px;
  background: #f8f9fa;
  border-radius: 6px;
}

.runtime-word-tag {
  display: inline-block;
  padding: 3px 8px;
  font-size: 11px;
  background: #e3f2fd;
  border: 1px solid #90caf9;
  border-radius: 4px;
  color: #1565c0;
}

.runtime-word-tag.used {
  background: #c8e6c9;
  border-color: #81c784;
  color: #2e7d32;
  font-weight: 600;
}

.runtime-word-tag.filtered {
  background: #ffecb3;
  border-color: #ffd54f;
  color: #f57f17;
  text-decoration: line-through;
  opacity: 0.7;
}

.runtime-students-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 200px;
  overflow-y: auto;
  margin: 8px 0;
}

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

.runtime-btn {
  padding: 6px 12px;
  font-size: 11px;
  border: 1px solid #dee2e6;
  background: #fff;
  border-radius: 6px;
  cursor: pointer;
}

.runtime-btn:hover {
  background: #f1f3f4;
}

.runtime-btn-danger {
  border-color: #e74c3c;
  background: #fff5f5;
  color: #c0392b;
}

.runtime-btn-danger:hover:not(:disabled) {
  background: #fee;
}

.runtime-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.runtime-select {
  padding: 4px 8px;
  font-size: 11px;
  border: 1px solid #dee2e6;
  background: #fff;
  border-radius: 4px;
  cursor: pointer;
  margin-left: 8px;
}

.runtime-select:focus {
  outline: 2px solid #007bff;
  outline-offset: 1px;
}

.runtime-checkbox-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  color: #495057;
  cursor: pointer;
}

.runtime-checkbox-label input[type="checkbox"] {
  width: 14px;
  height: 14px;
  cursor: pointer;
}

.runtime-student-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 8px;
  background: #fff;
  border: 1px solid #e9ecef;
  border-radius: 4px;
  cursor: pointer;
}

.runtime-student-item:hover {
  background: #f1f3f4;
}

.runtime-student-item.selected {
  background: #e3f2fd;
  border-color: #90caf9;
}

/* ===== STT Section Styles ===== */

.runtime-stt-section {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid #dee2e6;
}

.runtime-stt-status {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px;
  background: #f8f9fa;
  border-radius: 6px;
  margin: 8px 0;
}

.runtime-stt-status .runtime-subtle {
  margin: 0;
}

.runtime-stt-controls {
  display: flex;
  gap: 8px;
  margin: 10px 0;
}

.runtime-btn-record {
  flex: 1;
  background: rgba(47, 111, 101, 0.1);
  border-color: #2f6f65;
  color: #2f6f65;
  font-weight: 500;
}

.runtime-btn-record:hover {
  background: rgba(47, 111, 101, 0.2);
}

.runtime-btn-record.recording {
  background: #fff3cd;
  border-color: #ffc107;
  color: #856404;
}

.runtime-btn-small {
  padding: 4px 8px;
  font-size: 10px;
}

.runtime-stt-recording {
  padding: 8px;
  background: #fff3cd;
  border-radius: 6px;
  font-size: 12px;
  text-align: center;
  color: #856404;
  margin: 8px 0;
}

.runtime-stt-results {
  margin-top: 10px;
}

.runtime-stt-results-list {
  padding: 10px;
  background: #f8f9fa;
  border-radius: 6px;
  font-size: 12px;
  max-height: 200px;
  overflow-y: auto;
  margin-top: 6px;
}

.runtime-stt-result-item {
  margin-bottom: 10px;
  padding: 8px;
  background: #fff;
  border-radius: 4px;
  border-left: 3px solid #27ae60;
}

.runtime-stt-result-item.has-error {
  border-left-color: #e74c3c;
}

.runtime-stt-result-item strong {
  font-weight: 600;
}

.runtime-stt-log-controls {
  display: flex;
  gap: 8px;
  margin-top: 10px;
}

.runtime-stt-log-controls .runtime-btn {
  flex: 1;
}

/* Pulsing animation for recording button */
@keyframes pulse-recording {
  0% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(255, 87, 34, 0.7);
  }
  50% {
    transform: scale(1.02);
    box-shadow: 0 0 0 10px rgba(255, 87, 34, 0);
  }
  100% {
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(255, 87, 34, 0);
  }
}

.stt-record-btn {
  transition: all 0.2s ease;
}

.stt-record-btn:active {
  transform: scale(0.98);
}

/* Pulsing dot for STT "Sending to..." indicator */
.stt-sending-dot {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #0d6efd;
  animation: stt-sending-pulse 1s ease-in-out infinite;
}

@keyframes stt-sending-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.4; transform: scale(0.7); }
}

body.dev-inspector-on .dev-toggle-btn {
  display: block;
}

body.dev-inspector-on .dev-instruction-controls {
  display: block;
}

/* Old lesson-nav dev controls removed - using unified panel */

.manual-speech-panel {
  display: none;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  background: rgba(255, 255, 255, 0.95);
  border-radius: 12px;
  border: 1px solid rgba(47, 111, 101, 0.25);
  margin-top: 12px;
}

.manual-speech-title {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  font-weight: 600;
}

.manual-speech-phonemes {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
}

.manual-speech-phoneme-btn {
  min-width: 56px;
  min-height: 56px;
  border-radius: 12px;
  border: 2px solid rgba(47, 111, 101, 0.25);
  background: #ffffff;
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 6px;
}

.manual-speech-phoneme-btn:hover {
  transform: translateY(-2px);
  border-color: rgba(47, 111, 101, 0.5);
  box-shadow: 0 6px 12px rgba(33, 41, 52, 0.12);
}

.manual-speech-phoneme-btn.wobbled {
  background: rgba(220, 100, 100, 0.15);
  border-color: rgba(180, 60, 60, 0.5);
}

.phoneme-grapheme {
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--ink);
}

.phoneme-ipa {
  font-size: 0.7rem;
  color: var(--muted);
  font-family: ui-monospace, "SFMono-Regular", Consolas, monospace;
}

.manual-speech-actions {
  display: flex;
  gap: 8px;
  justify-content: center;
  margin-top: 4px;
}

.manual-speech-correct-btn,
.manual-speech-reset-btn {
  border: 1px solid rgba(47, 111, 101, 0.35);
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 0.8rem;
  font-weight: 600;
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
  background: #ffffff;
  color: var(--accent-dark);
  cursor: pointer;
  transition: all 0.2s ease;
}

.manual-speech-correct-btn:hover,
.manual-speech-reset-btn:hover {
  border-color: rgba(47, 111, 101, 0.6);
  transform: translateY(-1px);
}

.manual-speech-correct-btn {
  background: rgba(47, 111, 101, 0.08);
}

.manual-speech-status {
  font-size: 0.75rem;
  color: var(--muted);
  text-align: center;
  min-height: 1em;
}

body.dev-inspector-on .manual-speech-panel {
  display: flex;
}

/* Placement Quiz Styles */
.placement-letter-display,
.placement-word-display {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 32px;
  margin: 20px 0;
}

.placement-letter,
.placement-word {
  font-size: 3rem;
  font-weight: 700;
  color: var(--ink);
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
}

.placement-keyword {
  font-size: 1.1rem;
  color: var(--muted);
  font-style: italic;
}

.placement-response-btns {
  display: flex;
  gap: 16px;
  justify-content: center;
  margin-top: 16px;
  flex-wrap: wrap;
}

@media (max-width: 600px) {
  body {
    padding: 16px;
    flex-direction: column;
  }

  .student-stage {
    padding: 28px 20px;
  }

  body.dev-inspector-on #studentApp,
  body.dev-inspector-on #flowInspector {
    max-width: 100%;
    flex: 1 1 auto;
  }

  #runtimePanel {
    width: min(var(--runtime-panel-width), 100vw);
  }

  body.dev-inspector-on #studentApp {
    margin-right: 0;
  }
}

/* ===== LOGIN SCREEN ===== */
.login-screen {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(160deg, var(--bg-top), var(--bg-bottom));
  z-index: 10000;
}

.login-tablet-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 12px;
}

.login-tablet {
  width: min(1200px, calc(100vw - 24px));
  height: min(768px, calc(100vh - 24px));
  display: flex;
  flex-direction: column;
  background: var(--card);
  border-radius: 12px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
  overflow: hidden;
}

.login-tablet-title {
  font-size: 1.4rem;
  font-weight: 600;
  color: var(--accent);
  text-align: center;
  margin: 0;
  padding: 12px 0 0;
}

.login-tablet-instruction {
  font-size: 1.1rem;
  color: var(--muted, #7f8c8d);
  text-align: center;
  padding: 4px 0 0;
}

/* ── Existing-student picker strip ─────────────────────────────── */
.login-student-picker {
  flex-shrink: 0;
  padding: 6px 16px 4px;
  border-bottom: 1px solid #eef0f3;
  background: #fafbfc;
}
.login-student-picker-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.8rem;
  padding-bottom: 4px;
}
.login-student-picker-title {
  font-weight: 700;
  color: var(--muted, #7f8c8d);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-size: 0.7rem;
}
.login-student-picker-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--muted, #7f8c8d);
  font-size: 0.75rem;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
}
.login-student-picker-toggle input[type="checkbox"] {
  margin: 0;
  cursor: pointer;
}
.login-student-picker-list {
  display: flex;
  gap: 6px;
  overflow-x: auto;
  padding-bottom: 4px;
  scrollbar-width: thin;
}
.login-student-chip {
  flex-shrink: 0;
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  padding: 6px 10px;
  border: 1px solid #d8dce3;
  border-radius: 8px;
  background: #fff;
  cursor: pointer;
  font-family: inherit;
  transition: all 0.15s;
  min-width: 80px;
}
.login-student-chip:hover {
  border-color: var(--accent, #2f6f65);
  background: #ecfdf5;
  transform: translateY(-1px);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.login-student-chip-name {
  font-weight: 600;
  font-size: 0.95rem;
  color: #1f2937;
}
.login-student-chip-meta {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.login-student-chip-badge {
  font-size: 0.6rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  padding: 1px 6px;
  border-radius: 8px;
}
.login-student-chip-badge.src-live_student    { background: #d1fae5; color: #065f46; }
/* 2026-09-21: a test student reads "test", in amber, not the green "live" of a
   real child. Distinct at a glance in the picker, because which one you tapped
   decides whether the dev arrows work and whether the day counts. */
.login-student-chip-badge.src-test_student    { background: #fde68a; color: #7c2d12; }
.login-student-chip-badge.src-simulator       { background: #ddd6fe; color: #5b21b6; }
.login-student-chip-badge.src-dev_test        { background: #fef3c7; color: #92400e; }
.login-student-chip-badge.src-imported        { background: #dbeafe; color: #1e40af; }
.login-student-chip-badge.src-adult_check     { background: #fce7f3; color: #9d174d; }
.login-student-chip-badge.src-fallback_choice { background: #fee2e2; color: #991b1b; }
.login-student-chip-badge.src-legacy          { background: #e5e7eb; color: #4b5563; }
.login-student-chip-badge.src-unknown         { background: #e5e7eb; color: #4b5563; }
.login-student-chip-lesson {
  font-size: 0.65rem;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  color: #6b7280;
  font-weight: 600;
}

/* ── Login: empty state + press-and-hold Teacher button ─────────────── */
.login-empty-state {
  text-align: center;
  color: #6b7280;
  font-size: 0.95rem;
  line-height: 1.5;
  padding: 18px 8px;
}
.login-teacher-btn {
  position: relative;
  overflow: hidden;
  align-self: center;
  margin-top: 16px;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  padding: 9px 20px;
  border: 1px solid #cbd5e1;
  border-radius: 10px;
  background: #f1f5f9;
  color: #334155;
  font-family: inherit;
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  touch-action: none;
  transition: border-color 0.15s, background 0.15s;
}
.login-teacher-btn:hover { border-color: #94a3b8; background: #e2e8f0; }
.login-teacher-btn-label { font-weight: 700; font-size: 0.9rem; position: relative; z-index: 1; }
.login-teacher-btn-hint {
  font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.4px;
  color: #94a3b8; font-weight: 700; position: relative; z-index: 1;
}
/* Hold-to-open fill: JS toggles .holding to run the timed fill. */
.login-teacher-btn::before {
  content: "";
  position: absolute; left: 0; top: 0; bottom: 0; width: 0;
  background: rgba(47, 111, 101, 0.22);
  z-index: 0;
}
.login-teacher-btn.holding::before {
  width: 100%;
  transition: width var(--hold-ms, 1500ms) linear;
}

.login-tablet-top {
  flex: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 16px;
  min-height: 0;
}

.login-tablet-top svg {
  width: 100%;
  height: 100%;
}

.login-tablet-bottom {
  flex: 1.2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 8px 16px 12px;
  gap: 8px;
  min-height: 0;
}

.login-tablet-keyboard {
  width: 100%;
  max-width: 600px;
}

.login-tablet-actions {
  display: flex;
  gap: 8px;
}

/* Keep old .login-card for placement UI fallback */
.login-card {
  background: var(--card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 48px 40px;
  width: min(420px, 90vw);
  text-align: center;
}

.login-title {
  font-size: 1.8rem;
  font-weight: 600;
  color: var(--accent);
  margin: 0 0 32px;
}

.login-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.login-label {
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--muted);
  text-align: left;
}

.login-input {
  padding: 14px 16px;
  font-size: 1.05rem;
  font-family: inherit;
  border: 2px solid #e2ddd4;
  border-radius: 12px;
  background: #faf8f5;
  color: var(--ink);
  transition: all 0.2s;
}

.login-input:focus {
  outline: none;
  border-color: var(--accent);
  background: #fff;
}

.login-btn {
  padding: 16px 32px;
  font-size: 1.1rem;
  font-weight: 600;
  font-family: "Space Grotesk", sans-serif;
  background: var(--accent);
  color: white;
  border: none;
  border-radius: 12px;
  cursor: pointer;
  transition: all 0.2s;
  margin-top: 8px;
}

.login-btn:hover {
  background: var(--accent-dark);
  transform: translateY(-1px);
}

.login-btn:active {
  transform: translateY(0);
}

.login-status {
  margin-top: 16px;
  font-size: 0.9rem;
  color: var(--muted);
  min-height: 20px;
}

.login-toggle {
  display: flex;
  gap: 8px;
  margin-bottom: 24px;
}

.toggle-option {
  flex: 1;
  padding: 10px 16px;
  font-size: 0.95rem;
  font-weight: 500;
  font-family: inherit;
  background: #f0f0f0;
  color: var(--muted);
  border: 2px solid #e2ddd4;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s;
}

.toggle-option.active {
  background: var(--accent);
  color: white;
  border-color: var(--accent);
}

.toggle-option:hover:not(.active) {
  background: #e8e8e8;
}

.login-section {
  margin-top: 16px;
}

.student-name-list {
  max-height: 300px;
  overflow-y: auto;
  border: 2px solid #e2ddd4;
  border-radius: 8px;
  background: #faf8f5;
  margin-top: 8px;
}

.student-name-item {
  padding: 12px 16px;
  border-bottom: 1px solid #e2ddd4;
  cursor: pointer;
  transition: background 0.2s;
  font-size: 1rem;
}

.student-name-item:last-child {
  border-bottom: none;
}

.student-name-item:hover {
  background: #fff;
}

.student-name-item:active {
  background: #f0f7f6;
}

.student-name-empty {
  padding: 32px 16px;
  text-align: center;
  color: var(--muted);
  font-size: 0.9rem;
}

/* ===== PLACEMENT UI (Initial Lesson Selection for New Students) ===== */
.placement-section {
  margin-top: 24px;
  padding-top: 24px;
  text-align: left;
}

.placement-divider {
  height: 1px;
  background: #e2ddd4;
  margin-bottom: 20px;
}

.placement-label {
  font-size: 1rem;
  font-weight: 500;
  color: var(--ink);
  margin-bottom: 16px;
  text-align: center;
}

.placement-options {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 20px;
}

.placement-option {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  background: #faf8f5;
  border: 2px solid #e2ddd4;
  border-radius: 10px;
  cursor: pointer;
  transition: all 0.2s;
}

.placement-option:hover {
  background: #fff;
  border-color: #d0cbc2;
}

.placement-option:has(input:checked) {
  background: #f0f7f6;
  border-color: var(--accent);
}

.placement-option input[type="radio"] {
  width: 18px;
  height: 18px;
  accent-color: var(--accent);
  cursor: pointer;
}

.placement-option-text {
  flex: 1;
  font-size: 0.95rem;
  color: var(--ink);
}

.placement-lesson-input {
  width: 60px;
  padding: 6px 10px;
  font-size: 0.95rem;
  font-family: inherit;
  border: 2px solid #e2ddd4;
  border-radius: 8px;
  background: #fff;
  color: var(--ink);
  text-align: center;
}

.placement-lesson-input:focus {
  outline: none;
  border-color: var(--accent);
}

.placement-lesson-input:disabled {
  background: #eee;
  color: #999;
  cursor: not-allowed;
}

/* ===== SESSION CONTROLS ===== */
.session-controls {
  display: flex;
  flex-direction: row;
  gap: 8px;
  align-items: center;
}

.session-control-btn {
  padding: 6px 12px;
  font-size: 0.75rem;
  font-weight: 500;
  font-family: "Space Grotesk", sans-serif;
  background: var(--accent);
  color: white;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.2s;
  white-space: nowrap;
  min-width: 120px;
}

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

.session-control-btn:active {
  transform: translateY(1px);
}

.session-control-btn:disabled {
  background: #ccc;
  cursor: not-allowed;
  opacity: 0.5;
}

.session-control-debug {
  background: #d97706;
  font-size: 0.8rem;
}

.session-control-debug:hover {
  background: #b45309;
}

/* ===== LETTER COACH (Phase 5 Handwriting) ===== */
.letter-coach-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 16px;
}

.letter-coach-instruction {
  font-size: 1.1rem;
  color: #5f6b76;
  text-align: center;
  min-height: 1.5em;
}

.letter-coach-stage {
  position: relative;
  width: 400px;
  height: 500px;
  border: 2px solid rgba(47, 111, 101, 0.25);
  border-radius: 12px;
  background: #ffffff;
  overflow: hidden;
}

.letter-coach-svg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.letter-coach-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  cursor: crosshair;
  touch-action: none;
}

/* House guide lines */
.letter-coach-guide {
  stroke: #e0e0e0;
  stroke-width: 1;
  stroke-dasharray: 4 4;
}

.letter-coach-guide-top {
  stroke: #ffcccc;
}

.letter-coach-guide-mid {
  stroke: #cce5ff;
}

.letter-coach-guide-base {
  stroke: #333;
  stroke-dasharray: none;
  stroke-width: 1.5;
}

/* Dotted outline (always visible, shows the full letter path) */
.letter-coach-stroke-dotted {
  fill: none;
  stroke: #999;
  stroke-width: 24;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 4 8;
}

/* Active animated stroke (fills inside the dotted outline) */
.letter-coach-stroke-active {
  fill: none;
  stroke: #2f6f65;
  stroke-width: 18;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Start point marker (red circle with number) */
.letter-coach-start-marker {
  fill: #e74c3c;
  stroke: white;
  stroke-width: 2;
}

.letter-coach-start-text {
  fill: white;
  font-size: 12px;
  font-weight: bold;
  text-anchor: middle;
  pointer-events: none;
}

/* Direction arrow */
.letter-coach-direction-arrow {
  fill: none;
  stroke: #3498db;
  stroke-width: 3;
  stroke-linecap: round;
  marker-end: url(#arrowMid);
}

.letter-coach-letter-label {
  font-size: 1.2rem;
  font-weight: 600;
  color: #2c3e50;
  text-transform: uppercase;
}

/* Coach buttons */
.letter-coach-buttons {
  display: flex;
  gap: 12px;
  margin-top: 12px;
}

.letter-coach-btn {
  padding: 10px 20px;
  font-size: 1rem;
  font-weight: 500;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.2s;
}

.letter-coach-btn-primary {
  background: var(--accent);
  color: white;
}

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

.letter-coach-btn-secondary {
  background: #e0e0e0;
  color: #333;
}

.letter-coach-btn-secondary:hover {
  background: #d0d0d0;
}

.letter-coach-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Feedback display */
.letter-coach-feedback {
  padding: 12px 20px;
  border-radius: 8px;
  font-size: 1rem;
  font-weight: 500;
  text-align: center;
}

.letter-coach-feedback-pass {
  background: #d4edda;
  color: #155724;
}

.letter-coach-feedback-fail {
  background: #f8d7da;
  color: #721c24;
}

/* ==========================================
   ARTICULATION CUE CARD - Phase 4 OG guidance
   ========================================== */

.articulation-card {
  width: min(480px, 100%);
  background: linear-gradient(135deg, #f0f7ff 0%, #ffffff 50%, #f5f0ff 100%);
  border: 2px solid rgba(47, 111, 101, 0.2);
  border-radius: 16px;
  padding: 16px 20px;
  margin-bottom: 12px;
  text-align: center;
}

.articulation-cue {
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.4;
}

.articulation-avoid {
  font-size: 0.95rem;
  color: #8b5e3c;
  font-style: italic;
  margin-top: 6px;
  line-height: 1.4;
}

.articulation-spelling-note {
  font-size: 0.9rem;
  color: #5f6b76;
  border-top: 1px solid rgba(0,0,0,0.08);
  padding-top: 8px;
  margin-top: 8px;
  line-height: 1.4;
}

/* ==========================================
   BLENDING ANIMATION - Phase 7 word display
   ========================================== */

.blend-word {
  font-size: 2.8rem;
  font-weight: 600;
  line-height: 1.1;
  color: var(--ink);
  display: flex;
  justify-content: center;
  gap: 0.15em;
}

.blend-segment {
  display: inline-block;
  opacity: 0;
  transform: translateY(8px);
  animation: blend-reveal 0.35s ease-out forwards;
  padding: 0.05em 0.08em;
  border-bottom: 3px solid rgba(47, 111, 101, 0.3);
  border-radius: 2px;
}

.blend-merged .blend-segment {
  border-bottom-color: transparent;
  gap: 0;
  transition: border-bottom-color 0.3s ease, gap 0.3s ease;
}

.blend-merged {
  gap: 0;
  transition: gap 0.3s ease;
}

@keyframes blend-reveal {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ==========================================
   MOUTH COACH - Visual mouth shape coach
   ========================================== */

.mouth-coach-container {
  display: none; /* Hidden by default, shown when enabled */
}

.mouth-coach-container.is-visible {
  display: block;
  margin-bottom: 16px;
}

.mouth-coach-widget {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 16px;
  background: #ffffff;
  border: 2px solid rgba(47, 111, 101, 0.2);
  border-radius: 12px;
}

.mouth-coach-frame {
  width: 120px;
  height: 80px;
  background: #faf5f0;
  border: 2px solid #e0d8d0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.mouth-coach-mouth {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mouth-coach-shape-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.mouth-coach-label {
  font-size: 0.85rem;
  color: #5f6b76;
  text-align: center;
  min-height: 1.2em;
}

/* ===== Avatar Coach Styles ===== */
.avatar-coach-container {
  display: none; /* Hidden by default, shown when enabled */
  position: absolute;
  top: 12px;
  right: 12px;
  width: 180px;
  height: 180px;
  z-index: 100;
  border-radius: 16px;
  overflow: hidden;
  background: #fff;
  border: none;
  outline: none;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.avatar-coach-container.is-visible {
  display: block;
}

.avatar-coach-video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.avatar-coach-video.is-speaking {
  border-color: var(--accent);
  box-shadow: 0 8px 24px rgba(47, 111, 101, 0.3);
}

.avatar-coach-status {
  font-size: 0.75rem;
  color: #5f6b76;
  text-align: center;
  margin-top: 6px;
}

.avatar-coach-status.is-connected {
  color: #2e7d32;
}

.avatar-coach-status.is-error {
  color: #c62828;
}

/* ===== Letter Demo Player ===== */

.letter-demo-wrapper {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 16px;
}

.letter-demo-stage {
  position: relative;
  width: 100%;
  max-width: 620px;
  aspect-ratio: 4 / 3;
  border: 2px solid rgba(47, 111, 101, 0.2);
  border-radius: 12px;
  background: #ffffff;
  overflow: hidden;
}

.letter-demo-svg {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.letter-demo-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  cursor: crosshair;
  touch-action: none;
  display: none;
}

.letter-demo-canvas.is-active {
  display: block;
}

/* Ghost glyph layer */
.letter-demo-ghost {
  opacity: 0.18;
}

/* Active animated stroke (demo playback) */
.letter-demo-stroke-active {
  fill: none;
  stroke: var(--accent, #2f6f65);
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Practice trace stroke (snap-to-path, student tracing).
   Hidden initially via inline style; shown by enablePracticeMode(). */
.letter-demo-stroke-practice {
  fill: none;
  stroke: #e74c3c;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Green start dot — shown during practice mode, pulses to attract attention */
.letter-demo-start-dot {
  fill: #27ae60;
  stroke: #fff;
  stroke-width: 12;
  animation: letterDemoStartPulse 1.2s ease-in-out infinite;
}

@keyframes letterDemoStartPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

/* Label */
.letter-demo-label {
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--ink, #1e2430);
  text-transform: capitalize;
}

/* Buttons */
.letter-demo-buttons {
  display: flex;
  gap: 12px;
}

.letter-demo-btn {
  padding: 12px 28px;
  font-family: inherit;
  font-size: 1rem;
  font-weight: 500;
  border: none;
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.2s, opacity 0.2s;
  min-height: 48px;
}

.letter-demo-btn-primary {
  background: var(--accent, #2f6f65);
  color: #fff;
}

.letter-demo-btn-primary:hover:not(:disabled) {
  background: var(--accent-dark, #21524b);
}

.letter-demo-btn-secondary {
  background: #e8e8e8;
  color: #333;
}

.letter-demo-btn-secondary:hover:not(:disabled) {
  background: #ddd;
}

.letter-demo-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* ══════════════════════════════════════════════════
   Universal Tablet Layout (all phases)
   ══════════════════════════════════════════════════ */

/* When tablet is active, hide header/name and strip the outer card */
.tablet-active-shell .student-header {
  display: none;
}
.tablet-active-shell .student-name-label {
  display: none !important;
}
.tablet-active-shell .sound-table-toggle-btn {
  display: none;
}
.student-stage.tablet-active {
  background: transparent;
  box-shadow: none;
  padding: 0;
  border-radius: 0;
}

/* Bot-right panel layout: name, buttons, progress stacked vertically */
.tablet-right-panel {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: center;
  padding: 8px;
  width: 100%;
}

.tablet-student-name {
  font-family: 'Space Grotesk', sans-serif;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink);
  padding: 2px 0 4px;
}

/* Progress overlay: covers top-half area with sound table */
.tablet-progress-overlay {
  position: absolute;
  inset: 0;
  background: var(--card);
  /* ABOVE the Phase 9 ending layer (z-index 60), not below it.
     Bruce, 2026-09-08: "the button on the right says My Climb, and that's not
     working." It was working -- it was opening BEHIND the frozen ending
     picture, which looks identical to nothing happening. Phase 9 is exactly
     where a child is most likely to want to see how far they have climbed, so
     this has to win. */
  z-index: 70;
  overflow-y: auto;
  padding: 12px;
}

/* A visible way out. The overlay used to rely on pressing Progress again, but
   it covers the SVG that draws the button strip, so there was no way back. */
.tablet-progress-close {
  position: sticky;
  top: 0;
  float: right;
  z-index: 2;
  font-family: Lexend, system-ui, sans-serif;
  font-size: clamp(15px, 2.6vmin, 22px);
  font-weight: 700;
  color: #fff;
  background: #3a78c4;
  border: 2px solid #2f5f9e;
  border-radius: 10px;
  padding: 10px 18px;
  min-height: 44px;
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
.tablet-progress-close:active { background: #2f5f9e; }

/* In unified-layout mode the top-half spans the FULL tablet height
   (the bottom-half is positioned absolute over it). So an overlay with
   inset:0 covers everything — including the standardized 4-button strip
   at the bottom 12%, making the Progress button unreachable to toggle
   off. Pin the overlay's bottom to 12% so the button strip stays
   visible and clickable while the 71-sound grid is shown above it. */
body.cwp-unified-layout .tablet-progress-overlay {
  bottom: 12%;
}

/* Wrapper centers and scales the tablet to fit available space.
   The top padding lowers the tablet from the top of the page so there's
   visible white/page-background space above the black-bordered box.
   Height is reduced by the same amount so the tablet's bottom edge
   stays inside the viewport. */
.tablet-scale-wrap {
  width: 100%;
  height: calc(100vh - 24px - 48px);
  padding-top: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.tablet-container {
  /* Exact tablet pixels — set by JS via CSS custom properties */
  width: var(--tablet-w, 1024px);
  height: var(--tablet-h, 768px);
  display: flex;
  flex-direction: column;
  background: var(--card);
  overflow: hidden;
  border-radius: 12px;
  box-shadow: none;
  /* Scale down to fit if larger than viewport */
  transform-origin: center center;
  flex-shrink: 0;
}

/* Tablet dimension label (shown in dev) */
.tablet-label {
  position: absolute;
  top: 4px;
  left: 8px;
  font-family: 'Space Grotesk', monospace;
  font-size: 11px;
  color: var(--muted);
  opacity: 0.7;
  pointer-events: none;
  z-index: 5;
}

.tablet-top-half {
  position: relative;
  flex: 2;
  display: flex;
  overflow: hidden;
  /* 2026-08-29: no line round the working area. The only outline the child
     should see is the one around the word itself. */
  border-bottom: 0;
  min-height: 0;
}

.tablet-svg-wrap {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.tablet-svg-wrap svg {
  width: 100%;
  height: 100%;
  -webkit-user-select: none;
  user-select: none;
  touch-action: none;
}

.tablet-bottom-half {
  flex: 1;
  display: flex;
  border-top: 1px solid #e4e0d8;
  background: #f8f6f2;
  min-height: 0;
}

.tablet-bot-left {
  flex: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  border-right: 1px solid #e4e0d8;
  overflow: hidden;
}

.tablet-bot-center {
  flex: 3;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}

.tablet-bot-right {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-left: 1px solid #e4e0d8;
  gap: 8px;
  padding: 8px;
}

/* ── Unified layout (body.cwp-unified-layout) ────────────────────────────
   The bottom-third "pictures" box moves to the top-left corner of the
   upper 2/3, and the 5-row guide lines extend BELOW the box all the way
   down to the bottom of the tablet. The keyboard + buttons stay in the
   bottom-right corner only (right 2/3 wide × bottom 1/3 tall).
*/
.tablet-pic-box {
  display: none;
}
body.cwp-unified-layout .tablet-container {
  position: relative;
}
body.cwp-unified-layout .tablet-top-half {
  flex: 1;
  border-bottom: none;
}
body.cwp-unified-layout .tablet-bottom-half {
  /* 2026-05-28: height 33.3% → 25% so the writing zone above is 75% of
     the tablet (matches Phase 1's writing zone — baseline aligns across
     all phases). Width stays 66.67% so picture box keeps left third. */
  position: absolute;
  bottom: 0;
  right: 0;
  width: 66.6667%;
  height: 25%;
  border-top: 1px solid #e4e0d8;
  z-index: 2;
  background: #f8f6f2;
}
body.cwp-unified-layout .tablet-bot-left {
  display: none;
}
body.cwp-unified-layout .tablet-pic-box {
  /* Moved to bottom-left on 2026-05-28. Border flips to border-top. */
  display: block;
  position: absolute;
  bottom: 0;
  left: 0;
  width: 33.3333%;
  height: 25%;
  background: #fafbf6;
  border-right: 1px solid #e4e0d8;
  border-top: 1px solid #e4e0d8;
  z-index: 2;
}

/* When a phase draws the SVG 2×2 button grid in the bottom-left,
   hide the pic-box DIV so the buttons aren't covered by it. JS adds
   this body class via _renderPhase1UnifiedFrame when reserveButtonStrip
   is true. */
body.cwp-has-button-grid .tablet-pic-box {
  display: none;
}

/* Phase 1 (review_letter_to_sound) has no keyboard — the right region
   extends the full tablet height with a button bar drawn inside the SVG.
   Hide the bottom-half overlay so it doesn't cover the lower portion of
   the right region. */
body.cwp-phase1-no-keyboard .tablet-bottom-half {
  display: none;
}

/* Standardized button strip — the in-SVG 4-button strip (Pause / Repeat /
   CV / Progress) is now the canonical action area across all unified
   phases. Hide the legacy tablet-bot-right column (which stacked
   Progress + Preset + per-phase mode buttons) globally so it doesn't
   compete with the strip. */
body.cwp-unified-layout .tablet-bot-right {
  display: none;
}

/* StudentTurnCue — VU-meter style voice-activity dots inside the
   "Speak now" cue. Always visible at a dim baseline so the child can
   see the level meter is on, then fill brighter from left to right
   as their voice drives the AnalyserNode. JS overrides opacity per
   dot per frame; the transition smooths frame-to-frame jitter. */
.cwp-voice-dot {
  opacity: 0.25;
  transition: opacity 0.08s linear;
}

/* Phase 2 (review_sound_to_letter) needs the keyboard, but pushed up by
   12% so the bottom of the screen has the same button strip as Phase 1.
   Hide the side Progress/Preset column so the keyboard fills the full
   width — the keys themselves cap at max-width: 52px so they naturally
   center inside the wider container. */
body.cwp-phase2-keyboard-raised .tablet-bot-right {
  display: none;
}
body.cwp-phase2-keyboard-raised .tablet-bot-center {
  flex: 1 1 100%;
}
body.cwp-phase2-keyboard-raised .tablet-bottom-half {
  /* 2026-05-28b: button strip moved into the bottom-left pic-box (2×2
     grid). Keyboard now fills the full bottom-right 25% — no separate
     strip below. */
  bottom: 0;
  height: 25%;
}

.tablet-bot-center .av-box {
  width: 92%;
  height: 88%;
  border: 2px dashed rgba(0, 0, 0, 0.1);
  border-radius: 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

/* Tablet mode buttons (used across all phases) */
.tablet-mode-btn {
  padding: 10px 20px;
  font-size: 14px;
  font-weight: 700;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  color: #fff;
  width: 100%;
  max-width: 140px;
}

.tablet-mode-btn.listen {
  background: #7c3aed;
}

.tablet-mode-btn.listen:hover {
  background: #6d28d9;
}

.tablet-mode-btn.read {
  background: #059669;
}

.tablet-mode-btn.read:hover {
  background: #047857;
}

.tablet-mode-btn.stop {
  background: #e74c3c;
}

.tablet-mode-btn.stop:hover {
  background: #c0392b;
}

.tablet-mode-btn.progress {
  background: #6b7280;
  font-size: 12px;
}

.tablet-mode-btn.progress:hover {
  background: #4b5563;
}

.tablet-mode-btn.fullscreen {
  background: #374151;
  font-size: 11px;
}

.tablet-mode-btn.fullscreen:hover {
  background: #1f2937;
}

/* Phase-specific button colors */
.tablet-mode-btn.primary {
  background: #2563eb;
}

.tablet-mode-btn.primary:hover {
  background: #1d4ed8;
}

.tablet-mode-btn.correct {
  background: #059669;
}

.tablet-mode-btn.incorrect {
  background: #e74c3c;
}

/* On-screen keyboard in bottom-center */
.tablet-keyboard {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 10px;
  width: 100%;
  height: 100%;
  justify-content: center;
}

/* Full-width preview — toggled via the runtime panel's Layout
   dropdown (cwp_layout_preview = 'fullwidth'). Hides the side
   sound-table panel and the bottom-half (keyboard area + picture
   box) so the SVG's stretched right region fills the viewport.
   The 4 action buttons are rendered as a horizontal strip across
   the bottom of the SVG by the unified frame builder. */
body.cwp-fullwidth-preview .stage-left-column { display: none; }
body.cwp-fullwidth-preview .stage-right-column { flex: 1; width: 100%; }
body.cwp-fullwidth-preview .tablet-bottom-half { display: none; }
body.cwp-fullwidth-preview .tablet-pic-box { display: none; }

/* 2026-08-04: On a TYPING phase in tablet/touch mode (KEYBOARD = tablet, i.e.
   body is NOT .cwp-physical-keyboard), the full-width layout reserves a bottom
   band for the on-screen keyboard. The engine shrinks the SVG content up into
   the top ~70% (_fwContentH, FW_KEYBOARD_BAND_FRAC = 0.30), and this rule pins
   the keyboard into the bottom 30% as a full-width BLACK BAR — so the keyboard
   sits UNDER the student window instead of overlapping it. The `height` here
   MUST match FW_KEYBOARD_BAND_FRAC in the engine. :has(.tablet-keyboard) limits
   this to phases that actually build a keyboard (Phase 2, Phase 6). In
   physical-keyboard (desktop) mode the base display:none wins and the student
   types on a real keyboard (content keeps full height). */
body.cwp-fullwidth-preview .tablet-container { position: relative; }
body.cwp-fullwidth-preview:not(.cwp-physical-keyboard) .tablet-bottom-half:has(.tablet-keyboard) {
  display: flex;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  /* Override the cwp-unified-layout width:66.67% (which reserves the left third
     for the pic-box) — the keyboard bar spans the FULL tablet width. */
  width: 100%;
  height: 30%;
  background: #14181f;
  border-top: 2px solid #000;
  z-index: 6;
}
body.cwp-fullwidth-preview:not(.cwp-physical-keyboard) .tablet-bottom-half:has(.tablet-keyboard) .tablet-bot-left,
body.cwp-fullwidth-preview:not(.cwp-physical-keyboard) .tablet-bottom-half:has(.tablet-keyboard) .tablet-bot-right {
  display: none;
}
body.cwp-fullwidth-preview:not(.cwp-physical-keyboard) .tablet-bottom-half:has(.tablet-keyboard) .tablet-bot-center {
  flex: 1 1 100%;
}
/* 2026-10-23 (overnight lesson walk): the bottom bar (#cwpBottomBar, absolute,
   bottom:0, z-index 35) sat ON TOP of the keyboard band, hiding the whole
   z-x-c-v-b-n-m-⌫ row on every tablet size (1024x768 to 1440x900; also on the
   live BUILD 3165). Start the band where the bar starts and shrink it by the
   same amount; the rows already shrink to fit (.tablet-keyboard-row). The bar
   is max(MIN_TAP_PX, BAR_FRAC) tall -- js/ui/LayoutGeometry.js, 44px / 8.5% --
   or, for the designed bar, the --student-content-bottom it publishes.
   Phones keep their own !important layout (below) and are not changed here. */
body.cwp-fullwidth-preview:not(.cwp-physical-keyboard):not(.cwp-phone-browser) #tabletContainer:has(> #cwpBottomBar) > .tablet-bottom-half:has(.tablet-keyboard) {
  bottom: max(44px, 8.5%);
  height: calc(30% - max(44px, 8.5%));
}
body.cwp-fullwidth-preview:not(.cwp-physical-keyboard):not(.cwp-phone-browser) #tabletContainer:has(> #cwpBottomBar.cwp-designed) > .tablet-bottom-half:has(.tablet-keyboard) {
  bottom: var(--student-content-bottom, max(44px, 8.5%));
  height: calc(30% - var(--student-content-bottom, max(44px, 8.5%)));
}

/* Physical-keyboard mode — set by the engine when localStorage
   cwp_physical_keyboard_mode is 'on', or in 'auto' mode when the
   browser reports pointer:fine + hover:hover (typical desktop).
   Hides the on-screen QWERTY but keeps the .tablet-bot-center
   container so layout doesn't shift. A small hint replaces it so
   the student knows they should type. Physical-key input is already
   wired by Phase 2 / Phase 6 via document.keydown listeners. */
body.cwp-physical-keyboard .tablet-keyboard {
  display: none;
}
/* 2026-05-29: the .tablet-bottom-half container's cream background +
   "⌨ Type on your keyboard" hint sat over the bottom of the writing
   zone and covered the descender of typed letters (g, y, p, j). The
   engine has already expanded the writing zone to use the full tablet
   height in physical-keyboard mode, so the bottom strip is dead space
   — hide it entirely so the full letter is visible. */
body.cwp-physical-keyboard .tablet-bottom-half {
  display: none !important;
}

.tablet-keyboard-row {
  display: flex;
  gap: 6px;
  justify-content: center;
  /* 2026-09-29: the keyboard band is a PERCENTAGE of the tablet (25% in the
     unified layout, 30% in full-width) but the keys were a fixed 60px. Three
     60px rows + gaps + padding need ~220px; the band is only 170px on an iPad
     inside browser chrome and 180px on a Fire HD 8, so the keyboard overflowed
     and .tablet-bot-center's overflow:hidden cut the top and bottom rows off.
     Reported by Bruce, 2026-09-29: "it cuts off part of the keyboard".
     flex-basis 60px keeps today's size wherever there is room; flex-shrink 1
     plus min-height:0 lets the rows give way instead of being clipped. */
  flex: 0 1 60px;
  min-height: 0;
}

.tablet-key {
  flex: 1;
  max-width: 76px;
  /* Follow the row (see .tablet-keyboard-row). A fixed height here was what
     stopped the rows shrinking: a flex item cannot go below its content. */
  height: 100%;
  min-height: 0;
  border: 1px solid #ccc;
  border-radius: 8px;
  background: #fff;
  /* Lexend matches the letters rendered in the writing area, so what
     the student sees on the keys is the same shape they're trying to
     read / type. Bigger + darker for tap clarity. */
  font-family: 'Lexend', sans-serif;
  font-size: min(32px, 4.6vh);
  font-weight: 600;
  color: #000;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 2px rgba(0,0,0,0.1);
}

.tablet-key:hover {
  background: #e8e8e8;
}

.tablet-key:active {
  background: #d0d0d0;
}

.tablet-key.wide {
  max-width: 96px;
  font-size: min(26px, 3.8vh);
}

.tablet-key.enter {
  /* Enter sits inline at the end of the home row, like a real keyboard.
     Slightly wider than a letter so it reads as a special key. */
  flex: 0 0 auto;
  width: auto;
  min-width: 88px;
  max-width: 110px;
  height: 100%;
  min-height: 0;
  background: #2f6f65;
  color: #fff;
  font-size: min(22px, 3.2vh);
  font-weight: bold;
  letter-spacing: 0.5px;
  border: none;
  padding: 0 16px;
}

.tablet-key.enter:hover {
  background: #246058;
}

.tablet-key.enter:active {
  background: #1a4a42;
}

/* Tile grid inside tablet botCenter */
.tablet-bot-center .tile-grid {
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  padding: 8px;
  width: 100%;
  max-width: 300px;
}

.tablet-bot-center .tile-grid .tile {
  font-size: 1.2rem;
  padding: 8px;
  min-height: 40px;
}

/* Phase 1 STT button in tablet mode (smaller) */
.tablet-bot-center .phase1-stt-btn {
  padding: 10px 20px;
  font-size: 14px;
  min-width: 150px;
  margin-top: 8px;
}

/* Phase 8 Dev Controls in runtime panel */
.p8-dev-header {
  font-size: 11px;
  font-weight: 700;
  color: #495057;
  border-top: 1px solid #dee2e6;
  padding-top: 8px;
  margin-top: 8px;
}

.p8-dev-select {
  padding: 4px 6px;
  font-size: 11px;
  border: 1px solid #ccc;
  border-radius: 4px;
  flex: 1;
}

.p8-dev-input {
  padding: 4px 6px;
  font-size: 11px;
  border: 1px solid #ccc;
  border-radius: 4px;
  flex: 1;
}

.p8-dev-btn {
  font-size: 11px;
  padding: 4px 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  background: #f0f0f0;
  cursor: pointer;
}

.p8-dev-btn:hover {
  background: #e0e0e0;
}

/* ══════════════════════════════════════════════════
   Sound Table Toggle (Parent/Teacher view)
   ══════════════════════════════════════════════════ */

.sound-table-toggle-btn {
  position: fixed;
  bottom: 8px;
  left: 8px;
  z-index: 100;
  padding: 6px 12px;
  border: 1px solid #b0a89e;
  border-radius: 6px;
  background: #e8e2da;
  cursor: pointer;
  font-size: 11px;
  font-weight: 600;
  color: #5a5249;
  display: flex;
  align-items: center;
  gap: 4px;
  opacity: 0.5;
  transition: opacity 0.2s;
}

.sound-table-toggle-btn:hover {
  opacity: 1;
}

.stage-left-column {
  position: relative;
  transition: width 0.3s, min-width 0.3s, flex 0.3s;
}

/* Default: collapsed (hidden from student) */
.stage-left-column.collapsed {
  width: 0 !important;
  min-width: 0 !important;
  flex: 0 0 0 !important;
  overflow: hidden;
}

.stage-left-column.collapsed .sound-table-container {
  display: none !important;
}

.settings-link {
  position: fixed;
  bottom: 8px;
  right: 10px;
  font-size: 14px;
  color: rgba(0, 0, 0, 0.25);
  text-decoration: none;
  z-index: 9999;
  padding: 4px 6px;
}
.settings-link:hover {
  color: rgba(0, 0, 0, 0.6);
}

/* Phone-specific full-width overrides */
/* Fill the screen. Was gated on .cwp-phone-browser, so once the phone
   breakpoint was corrected to 500px a tablet stopped matching and sat
   letterboxed in grey: 12px body padding, a 1200px shell cap and a
   calc(100vh - 60px) height cap. Phones are touch devices too, so they
   still get all of this. The phone-only rules below are unchanged. */
body.cwp-fill-screen {
  margin: 0 !important;
  padding: 0 !important;
  width: 100vw !important;
  min-height: 100vh !important;
  min-height: 100dvh !important;
  /* Pin to the viewport as well as filling it. Without the cap the page ran
     ~26px taller than the screen and could be dragged, which on a touch
     device reads as the app sitting loose inside the browser. */
  max-height: 100vh !important;
  max-height: 100dvh !important;
  overflow: hidden !important;
  align-items: stretch !important;
  justify-content: stretch !important;
}

body.cwp-fill-screen #studentApp,
body.cwp-fill-screen #loginScreen,
body.cwp-fill-screen .student-shell {
  /* border-box so the safe-area padding below counts INSIDE the 100vh, rather
     than adding to it and giving the page 26px of drag on a tablet. */
  box-sizing: border-box !important;
  width: 100vw !important;
  max-width: 100vw !important;
  min-height: 100vh !important;
  min-height: 100dvh !important;
  /* Pin to the viewport as well as filling it. Without the cap the page ran
     ~26px taller than the screen and could be dragged, which on a touch
     device reads as the app sitting loose inside the browser. */
  max-height: 100vh !important;
  max-height: 100dvh !important;
  overflow: hidden !important;
  margin: 0 !important;
}

body.cwp-fill-screen .student-stage,
body.cwp-fill-screen .student-stage.two-column-layout {
  box-sizing: border-box !important;
  width: 100vw !important;
  max-width: 100vw !important;
  min-height: 100vh !important;
  min-height: 100dvh !important;
  /* Was max-height:none, which let the stage run 26px past the screen and clip
     the button strip off the bottom of the tablet. */
  max-height: 100vh !important;
  max-height: 100dvh !important;
  overflow: hidden !important;
  margin: 0 !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  padding: env(safe-area-inset-top, 0px)
           env(safe-area-inset-right, 0px)
           env(safe-area-inset-bottom, 0px)
           env(safe-area-inset-left, 0px) !important;
}

body.cwp-fill-screen .stage-left-column,
body.cwp-fill-screen .stage-right-column {
  min-width: 0 !important;
  width: 100% !important;
  max-width: 100% !important;
}

body.cwp-fill-screen .student-interaction,
body.cwp-fill-screen .sound-table-container,
/* The preset label reads "Desktop / Laptop 1440x900 (86%)" -- a dev readout.
   On a real tablet filling the screen it is just confusing to a tester. */
body.cwp-fill-screen #tabletLabel { display: none !important; }

/* The login / student-picker screen has its own caps, independent of the
   student screens: .login-tablet-wrap carries 12px padding and .login-tablet is
   min(1200px, 100vw-24px) x min(768px, 100vh-24px). On a 1280x800 tablet that
   left a grey border all round while every student screen filled the display.
   Reported 2026-08-28: "that's the only screen that's not working". */
body.cwp-fill-screen .login-tablet-wrap {
  padding: 0 !important;
}

/* Login typography for a real tablet. The sizes are desktop rem values --
   1.4rem title, 0.95rem names, 0.6rem badges -- and an 8" screen at 1280 CSS px
   renders those about 2mm tall. Reported 2026-08-28: "when you are adding a
   student, all the fonts, everything is very small". vmin so it tracks the
   display rather than guessing a device. */
body.cwp-fill-screen .login-tablet-title      { font-size: clamp(24px, 4.4vmin, 46px) !important; }
body.cwp-fill-screen .login-tablet-instruction{ font-size: clamp(17px, 3.0vmin, 30px) !important; }
body.cwp-fill-screen .login-empty-state       { font-size: clamp(16px, 2.7vmin, 28px) !important;
                                                line-height: 1.5 !important; }
body.cwp-fill-screen .login-student-chip-name { font-size: clamp(17px, 2.9vmin, 30px) !important; }
body.cwp-fill-screen .login-student-chip-meta { font-size: clamp(13px, 2.1vmin, 22px) !important; }
body.cwp-fill-screen .login-student-chip-badge{ font-size: clamp(11px, 1.7vmin, 18px) !important; }

/* Touch targets, not mouse targets. 44px is the usual minimum; a five-year-old
   or an adult adding a student on an 8" screen needs at least that. */
body.cwp-fill-screen .login-student-chip {
  font-size: clamp(17px, 2.9vmin, 30px) !important;
  padding: clamp(10px, 1.8vmin, 18px) clamp(14px, 2.4vmin, 24px) !important;
  min-height: 52px !important;
}
body.cwp-fill-screen .login-teacher-btn {
  font-size: clamp(18px, 3.2vmin, 32px) !important;
  padding: clamp(14px, 2.4vmin, 24px) clamp(24px, 4vmin, 44px) !important;
  min-height: 60px !important;
}

/* The content sat crammed at the top with the lower two-thirds empty. */
body.cwp-fill-screen .login-tablet-wrap {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
}

body.cwp-fill-screen .login-tablet {
  /* The engine sets this inline: width:1440px; height:900px; scale(0.86) --
     it renders the login tablet at the PRESET size and scales it down to fit.
     .tablet-container already gets transform:none in this block; the login
     tablet was never included, so it stayed scaled inside a grey border. */
  transform: none !important;
  width: 100% !important;
  height: 100% !important;
  max-width: none !important;
  max-height: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}

body.cwp-fill-screen .tablet-scale-wrap {
  width: 100% !important;
  max-width: 100% !important;
}

body.cwp-fill-screen .tablet-scale-wrap {
  /* The 48px top padding reserves room for the preset label
     ("Desktop / Laptop 1440x900"). That is a dev affordance; on a real tablet
     it pushed the app down and pushed the button strip off the bottom. */
  padding: 0 !important;
  height: 100vh !important;
  height: 100dvh !important;
  max-height: 100vh !important;
  max-height: 100dvh !important;
}

body.cwp-fill-screen .tablet-container {
  /* Fill the PARENT, not the viewport. Viewport math assumed the container
     started at the top of the screen; it actually sits ~40px down, so the
     bottom 40px -- the Pause/Repeat/Help/Progress strip -- fell off screen. */
  width: calc(100vw - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px)) !important;
  height: 100% !important;
  max-width: 100vw !important;
  max-height: 100vh !important;
  max-height: 100dvh !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  transform: none !important;
}

body.cwp-phone-browser .tablet-top-half {
  flex: 1 1 66% !important;
  min-height: 0 !important;
}

body.cwp-phone-browser .tablet-bottom-half {
  flex: 0 0 34% !important;
  min-height: 0 !important;
  max-height: 34dvh !important;
  display: flex !important;
  align-items: stretch !important;
}

body.cwp-phone-browser .tablet-bot-left,
body.cwp-phone-browser .tablet-bot-center,
body.cwp-phone-browser .tablet-bot-right {
  min-width: 0 !important;
  min-height: 0 !important;
  padding: 4px !important;
}

body.cwp-phone-browser .tablet-bot-left {
  flex: 0 0 22% !important;
}

body.cwp-phone-browser .tablet-bot-center {
  flex: 1 1 auto !important;
}

body.cwp-phone-browser .tablet-bot-right {
  flex: 0 0 24% !important;
  gap: 4px !important;
  justify-content: flex-start !important;
}

body.cwp-phone-browser .tablet-right-panel {
  gap: 4px !important;
  padding: 4px !important;
  /* Buttons stack vertically — if they ever overflow the 34dvh bottom half,
     let the column scroll instead of spilling out of the tablet. */
  overflow-y: auto !important;
  min-height: 0 !important;
}

body.cwp-phone-browser .tablet-student-name {
  font-size: clamp(9px, 2.2vw, 12px) !important;
  padding: 0 0 2px !important;
  line-height: 1.1 !important;
}

body.cwp-phone-browser .tablet-mode-btn {
  max-width: none !important;
  /* Let buttons shrink on short viewports — previously min-height was a
     hard 34px, which pushed the stack over the bottom-half boundary. */
  min-height: 0 !important;
  height: clamp(26px, 6vw, 38px) !important;
  padding: clamp(2px, 1vw, 6px) clamp(4px, 2vw, 10px) !important;
  font-size: clamp(9px, 2.4vw, 12px) !important;
  line-height: 1.1 !important;
  border-radius: 6px !important;
}

body.cwp-phone-browser .tablet-keyboard {
  gap: 4px !important;
  padding: 4px !important;
}

body.cwp-phone-browser .tablet-keyboard-row {
  gap: 3px !important;
  /* Same fix as .tablet-keyboard-row above: the phone rules set a hard key
     height, which a flex row cannot shrink past, so a landscape phone's ~100px
     keyboard band clipped ~50px of the keys. The height becomes a basis. */
  flex: 0 1 clamp(28px, 7.2vw, 40px) !important;
  min-height: 0 !important;
}

body.cwp-phone-browser .tablet-key {
  max-width: none !important;
  min-width: 0 !important;
  height: 100% !important;
  min-height: 0 !important;
  font-size: clamp(14px, 3.2vw, 18px) !important;
}

body.cwp-phone-browser .tablet-key.enter {
  width: 100% !important;
  height: 100% !important;
  min-height: 0 !important;
}

body.cwp-phone-browser .tablet-bot-center .tile-grid {
  width: 100% !important;
  max-width: none !important;
  gap: 4px !important;
  padding: 4px !important;
}

body.cwp-phone-browser .tablet-bot-center .tile-grid .tile {
  min-height: clamp(34px, 10vw, 56px) !important;
  font-size: clamp(16px, 4vw, 22px) !important;
  padding: 4px !important;
}

body.cwp-phone-browser .tablet-bot-left img,
body.cwp-phone-browser .tablet-bot-left video,
body.cwp-phone-browser .tablet-bot-left canvas,
body.cwp-phone-browser .tablet-bot-right img {
  max-width: 100% !important;
  max-height: 100% !important;
  object-fit: contain !important;
}

body.cwp-phone-browser .tile-grid {
  max-width: none !important;
}

/* ── Adult marking fallback (Phases 1, 3, 7) ────────────────────────────────
   Shown only after speech-to-text has failed to hear the child a few times, so
   the grown-up can settle it and the lesson keeps moving. Fixed-position like
   .global-continue-btn because the tablet's own controls are drawn in SVG and
   are laid out once per phase -- an HTML overlay can appear mid-attempt without
   redrawing anything. */
.cwp-adult-fallback {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1000;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 12px 18px;
  background: rgba(255, 255, 255, 0.96);
  border: 2px solid rgba(47, 111, 101, 0.35);
  border-radius: 16px;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.16);
  font-family: "Space Grotesk", "Trebuchet MS", sans-serif;
}

.cwp-adult-fallback.is-hidden { display: none; }

.cwp-adult-fallback-caption {
  font-size: 0.78rem;
  color: #6b7573;
  letter-spacing: 0.01em;
}

.cwp-adult-fallback-row { display: flex; gap: 12px; }

.cwp-adult-fallback button {
  padding: 12px 24px;
  font-size: 1rem;
  font-weight: 600;
  font-family: inherit;
  border-radius: 999px;
  cursor: pointer;
  min-width: 132px;
  transition: transform 0.15s ease;
}

.cwp-adult-fallback button:hover { transform: translateY(-1px); }
.cwp-adult-fallback button:disabled { opacity: 0.5; cursor: default; transform: none; }

.cwp-adult-fallback .cwp-fallback-yes {
  background: #2f6f65; border: 2px solid #2f6f65; color: #ffffff;
}

.cwp-adult-fallback .cwp-fallback-no {
  background: #ffffff; border: 2px solid rgba(92, 102, 100, 0.45); color: #5c6664;
}


/* Microphone help card — for the GROWN-UP, not the child.
   Shown when the app can tell the microphone is not merely quiet but broken:
   nothing plugged in, permission blocked, held by another app, or connected
   and delivering a flat line. The child's cue says the app cannot hear; this
   says which setting to change, because a five-year-old cannot fix it. */
.cwp-mic-help {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  z-index: 60000;
  max-width: min(520px, calc(100vw - 32px));
  background: #fff;
  color: #1f2937;
  border: 2px solid #b42318;
  border-radius: 12px;
  padding: 16px 18px;
  box-shadow: 0 10px 30px rgba(15, 23, 42, .28);
  font-family: 'Lexend', system-ui, sans-serif;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.cwp-mic-help.is-hidden { display: none; }
.cwp-mic-help-title {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #b42318;
}
.cwp-mic-help-body { font-size: 15px; line-height: 1.45; }
/* "I fixed it" is the outcome we want, so it reads as the primary action. */
.cwp-mic-help-recheck {
  font: inherit;
  font-weight: 700;
  padding: 10px 22px;
  min-height: 44px;
  border: 2px solid #2f6f65;
  border-radius: 9px;
  background: #2f6f65;
  color: #ffffff;
  cursor: pointer;
}
.cwp-mic-help-recheck[disabled] { opacity: 0.6; cursor: default; }

.cwp-mic-help-actions {
  display: flex;
  gap: 12px;
  align-items: stretch;
  justify-content: flex-end;
  flex-wrap: wrap;
}
/* The consequence belongs on the button, not discovered afterwards. */
.cwp-mic-help-skip span {
  display: block;
  font-size: 11.5px;
  font-weight: 400;
  opacity: 0.75;
  margin-top: 2px;
}

/* The way past a microphone nobody is going to fix. Deliberately quieter than
   the OK button: repairing the microphone is the better outcome, and this
   should not look like the obvious thing to press. */
.cwp-mic-help-skip {
  align-self: flex-end;
  font: inherit;
  font-size: 14px;
  padding: 8px 18px;
  min-height: 44px;
  border: 1px solid #9aa3b2;
  border-radius: 9px;
  background: transparent;
  color: #5b6070;
  cursor: pointer;
}
.cwp-mic-help-skip:hover { background: rgba(0,0,0,0.05); }

.cwp-mic-help-close {
  align-self: flex-end;
  font: inherit;
  font-weight: 700;
  padding: 8px 22px;
  min-height: 44px;
  border: 2px solid #3a4a66;
  border-radius: 9px;
  background: #e8e2d6;
  color: #3a4a66;
  cursor: pointer;
}


/* Third option on the adult card, used when the app has given up trying to
   hear. Yes / Not yet record a real answer; Skip moves on without inventing
   evidence either way. */
.cwp-fallback-skip {
  font: inherit;
  font-weight: 600;
  padding: 10px 18px;
  min-height: 44px;
  border: 2px solid #9aa3b2;
  border-radius: 999px;
  background: #fff;
  color: #5b6472;
  cursor: pointer;
}


/* Microphone test inside the Progress screen. For the adult: somewhere to fix
   a muted or blocked mic and SEE that the fix worked, without ending the
   child's session. The dots are the same meter the lesson uses. */
.mic-check {
  margin: 18px auto 4px;
  max-width: 520px;
  background: #fff;
  border: 2px solid #3a4a66;
  border-radius: 12px;
  padding: 14px 16px;
  font-family: 'Lexend', system-ui, sans-serif;
  color: #1f2937;
  display: flex;
  flex-direction: column;
  gap: 10px;
  text-align: left;
}
.mic-check-title {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #3a4a66;
}
.mic-check-row { display: flex; align-items: center; gap: 14px; }
.mic-check-btn {
  font: inherit;
  font-weight: 700;
  padding: 10px 20px;
  min-height: 44px;
  border: 2px solid #3a4a66;
  border-radius: 9px;
  background: #e8e2d6;
  color: #3a4a66;
  cursor: pointer;
  white-space: nowrap;
}
.mic-check-btn:active { filter: brightness(.93); }
.mic-check-meter { display: inline-flex; gap: 7px; align-items: center; color: #1f7a44; }
.mic-check-meter .cwp-voice-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: currentColor;
  opacity: .25;
  box-shadow: 0 0 0 1.5px rgba(58, 74, 102, .35);
  transition: opacity .08s linear;
}
.mic-check-status { font-size: 14px; line-height: 1.45; color: #4a5160; }
.mic-check-status.is-ok  { color: #1f7a44; font-weight: 600; }
.mic-check-status.is-bad { color: #b42318; font-weight: 600; }

/* The tap instruction BEFORE it can be pressed. Same words as the button, but
   flat: no border, no shadow, full-height colour band -- the shape the spec
   reserves for a status readout, so it never invites a press it cannot take. */
.cwp-tap-readout {
  display: inline-block;
  font-weight: 600;
  opacity: 0.92;
}

/* The adult door on the child's Progress screen. Deliberately quieter and
   smaller than the child's Back button, and press-and-hold, so a seven-year-old
   pressing everything does not end up in the teacher area. */
.tablet-progress-adult {
  position: absolute;
  right: 12px;
  bottom: 12px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 16px;
  min-height: 44px;
  border: 1px solid #9aa3b2;
  border-radius: 10px;
  background: rgba(255,255,255,0.9);
  color: #4a5262;
  cursor: pointer;
  z-index: 3;
}
.tablet-progress-adult.is-holding {
  background: #3a78c4;
  border-color: #3a78c4;
  color: #ffffff;
  transition: background 700ms linear, color 200ms linear;
}

/* Paused looks paused. The colour drains out of the working area so a child can
   see at a glance that the app is stopped and waiting for them -- and it comes
   back the instant they press Play. The bottom bar is deliberately EXEMPT: the
   way out must never look disabled. */
/* ... but NOT while My Climb is open. A filter on an ancestor applies to its
   whole subtree and cannot be undone by a descendant, so exempting the overlay
   itself did nothing -- the fix is to stop filtering the ancestor. The LESSON is
   paused; the screen the child just opened is not. */
#tabletContainer.cwp-is-paused:not(.cwp-climb-open) .tablet-top-half,
#tabletContainer.cwp-is-paused:not(.cwp-climb-open) .tablet-bottom-half {
  filter: grayscale(0.85) opacity(0.55);
  transition: filter 260ms ease;
}
#tabletContainer .tablet-top-half,
#tabletContainer .tablet-bottom-half { transition: filter 260ms ease; }
#tabletContainer.cwp-is-paused .cwp-bar { filter: none; }

/* The picture on a bar button. Sits before the word, slightly larger, with a
   little air after it -- the child reads the symbol, the grown-up reads the
   word. */
.cwp-bar-icon {
  display: inline-block;
  margin-right: 0.4em;
  font-size: 1.15em;
  line-height: 1;
  vertical-align: -0.06em;
}

/* ── "This sitting" card in the dev panel (js/ui/SittingCard.js, 2026-09-11) ── */
.sitting-card { font-size: 10.5px; line-height: 1.35; color: #1f2937; display: grid; gap: 3px; }
.sitting-card .sc-row { display: grid; grid-template-columns: 74px 1fr; gap: 6px; align-items: start; }
.sitting-card .sc-k { color: #6c757d; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; font-size: 9.5px; padding-top: 1px; }
.sitting-card code { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 10px; background: #f1f5f9; padding: 0 3px; border-radius: 3px; }
.sitting-card .sc-muted { color: #6c757d; }
.sitting-card .sc-warn { color: #b8402f; font-weight: 600; }
.sitting-card .sc-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: #9ca3af; margin-right: 4px; vertical-align: 0; }
.sitting-card .sc-dot.on { background: #22c55e; }
.sitting-card .sc-day { display: inline-flex; flex-direction: column; align-items: center; margin-right: 4px; font-weight: 700; line-height: 1; }
.sitting-card .sc-day small { font-weight: 400; color: #6c757d; font-size: 8px; margin-top: 1px; }
.sitting-card .sc-day.ok { color: #15803d; }
.sitting-card .sc-day.no { color: #b8402f; }

/* ── "The day" sheet in the dev panel (js/day/DaySheet.js, 2026-09-11) ── */
.day-sheet { font-size: 10.5px; line-height: 1.4; color: #1f2937; display: grid; gap: 2px; }
.day-sheet .ds-head { margin-bottom: 3px; }
.day-sheet .ds-muted { color: #6c757d; }
.day-sheet .ds-row { display: grid; grid-template-columns: 22px 88px 1fr; gap: 6px; align-items: start; padding: 1px 2px; border-radius: 3px; }
.day-sheet .ds-row.current { background: #fff7e6; }
.day-sheet .ds-n { color: #6c757d; font-weight: 700; text-align: right; }
.day-sheet .ds-label { color: #495057; }
.day-sheet .ds-items { display: flex; flex-wrap: wrap; gap: 3px; }
.day-sheet .ds-dot { display: inline-block; padding: 0 6px; border-radius: 999px; border: 1.5px solid #c8ccc6; color: #495057; background: #fff; font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 10px; line-height: 15px; }
.day-sheet .ds-dot.heard { border-color: #3b82f6; color: #1d4ed8; background: #eff6ff; }
.day-sheet .ds-dot.right { border-color: #16a34a; color: #fff; background: #16a34a; }
.day-sheet .ds-dot.wrong { border-color: #dc2626; color: #fff; background: #dc2626; }
.day-sheet .ds-dot.unheard { border-color: #d97706; color: #92400e; background: #fffbeb; }
.day-sheet .ds-dot.not_answered { border-color: #9333ea; color: #6b21a8; background: #f3e8ff; }
.day-sheet .ds-dot.done { border-color: #9ca3af; color: #fff; background: #9ca3af; }
.day-sheet .ds-dot.added { border-style: dashed; }
.day-sheet .ds-dot.new { border-color: #7c3aed; color: #5b21b6; background: #f5f3ff; }
.day-sheet .ds-dot sup { font-size: 8px; margin-left: 1px; }
.day-sheet .ds-attempt-detail { position: relative; display: inline-block; }
.day-sheet .ds-attempt-detail > summary { list-style: none; cursor: pointer; }
.day-sheet .ds-attempt-detail > summary::-webkit-details-marker { display: none; }
.day-sheet .ds-attempt-detail[open] { width: 100%; }
.day-sheet .ds-attempt-popover { margin: 3px 0 5px; padding: 6px 8px; border: 1px solid #cbd5e1; border-radius: 7px; background: #fff; box-shadow: 0 2px 7px rgba(15,23,42,.12); }
.day-sheet .ds-sound-evidence + .ds-sound-evidence { margin-top: 7px; padding-top: 7px; border-top: 1px solid #e2e8f0; }
.day-sheet .ds-sound-meta { margin-bottom: 4px; color: #64748b; font-size: 9px; }
.day-sheet .ds-sound-word { display: flex; flex-wrap: wrap; gap: 3px; }
.day-sheet .ds-sound-part { min-width: 34px; padding: 3px 5px; border-radius: 5px; color: #172033; text-align: center; }
.day-sheet .ds-sound-part b, .day-sheet .ds-sound-part small { display: block; }
.day-sheet .ds-sound-part b { font: 700 14px/16px ui-monospace, SFMono-Regular, Consolas, monospace; }
.day-sheet .ds-sound-part small { font: 700 9px/11px system-ui, sans-serif; }
.day-sheet .ds-sound-part.clear { background: #bbf7d0; border: 1px solid #22c55e; }
.day-sheet .ds-sound-part.close { background: #fef3c7; border: 1px solid #f59e0b; }
.day-sheet .ds-sound-part.low { background: #fecaca; border: 1px solid #ef4444; }
.day-sheet .ds-sound-part.missing { background: #e5e7eb; border: 1px solid #9ca3af; color: #6b7280; }

/* Non-developer accounts (issue #108): the dev side panel never shows. */
html.cwp-no-dev #runtimePanel { display: none !important; }
/* Developer-only event badge: never for non-developers (2026-10-27). */
html.cwp-no-dev #recorderBadge { display: none !important; }

/* ── Phone-only layout fixes (#124). Everything below is gated on body.cwp-phone-browser
   (coarse pointer, short side <= 500px); tablet and laptop are untouched. ───────────── */

/* 1. Fill the screen. The phone rules above force the bottom half to a 34% block, so a phase
   with no keyboard left a third of the screen empty and squeezed the paper into 66%. Keep the
   bottom half only when it holds the keyboard / tiles, and let the paper take the rest. */
body.cwp-phone-browser.cwp-fullwidth-preview .tablet-bottom-half:not(:has(.tablet-keyboard)) {
  display: none !important;
}
body.cwp-phone-browser.cwp-fullwidth-preview .tablet-top-half {
  flex: 1 1 auto !important;
}
/* The tiles sit in the free band above the bar, same arithmetic as the tablet rule above. */
body.cwp-phone-browser.cwp-fullwidth-preview:not(.cwp-physical-keyboard) #tabletContainer:has(> #cwpBottomBar) > .tablet-bottom-half:has(.tablet-keyboard) {
  bottom: var(--student-content-bottom, 48px);
  height: calc(30% - var(--student-content-bottom, 48px));
  max-height: none !important;
}

/* 2. Large letter tiles instead of the full keyboard. */
.tablet-keyboard.cwp-phone-tiles {
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.cwp-phone-tiles .cwp-tile-row {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  gap: 8px;
  align-items: center;
  height: 100%;
}
.cwp-phone-tiles .cwp-tile {
  flex: 1 1 0;
  min-width: 0;
  max-width: 96px;
  border: 2px solid #3a4a66;
  border-radius: 14px;
  background: #fff;
  color: #000;
  font: 700 clamp(20px, 8dvh, 34px)/1 'Lexend', sans-serif;
  display: flex; align-items: center; justify-content: center;
  height: 100%; max-height: 52px; overflow: visible;
  box-shadow: 0 3px 0 rgba(0, 0, 0, 0.25);
  cursor: pointer;
  padding: 0;
}
.cwp-phone-tiles .cwp-tile:active { background: #d0d0d0; transform: translateY(2px); box-shadow: none; }
.cwp-phone-tiles .cwp-tile-act {
  flex: 0 0 auto;
  width: clamp(40px, 11vw, 60px);
  border: 2px solid #3a4a66;
  border-radius: 14px;
  font: 700 clamp(16px, 5dvh, 24px)/1 system-ui, sans-serif;
  display: flex; align-items: center; justify-content: center;
  height: 100%; max-height: 52px;
  background: #e8e2d6;
  color: #1f2a2e;
  cursor: pointer;
  padding: 0;
}
.cwp-phone-tiles .cwp-tile-act.enter { background: #2f6f65; border-color: #2f6f65; color: #fff; }

/* 3. Compact bottom buttons (Stop / Again / Next). Heights are set from StudentBarDesign.js;
   these lift the 44px / 64px floors that the tablet bar keeps. */
body.cwp-phone-browser #cwpBottomBar.cwp-designed { min-height: 0; }
body.cwp-phone-browser #cwpBottomBar.cwp-designed button { min-height: 0; min-width: 3em; padding: 0 .5em; border-radius: 16px; line-height: 1; }

/* 4. Paper edge to edge: no padding round the working area or the tile band. */
body.cwp-phone-browser .tablet-top-half,
body.cwp-phone-browser .tablet-svg-wrap { padding: 0 !important; margin: 0 !important; }
body.cwp-phone-browser .tablet-bottom-half:has(.tablet-keyboard) .tablet-bot-center { padding: 0 4px !important; }

/* 6. The empty outlined presenter box (no video loaded) is only a placeholder; on a phone it
   just eats paper, so hide it unless it actually holds a video / image. */
body.cwp-phone-browser div#cwp-p4-talking-head:not(:has(video, img, canvas)) { display: none !important; }

/* 5. BUILD badge and developer row: both small, side by side, never over the title. */
body.cwp-phone-browser #cwpBuildTag { font-size: 9px !important; padding: 2px 4px !important; top: 2px !important; right: 2px !important; }
body.cwp-phone-browser #cwpReviewNotesRow.cwp-floating { right: 62px !important; top: 2px !important; padding: 1px 3px !important; gap: 2px !important; }
body.cwp-phone-browser #cwpReviewNotesRow.cwp-floating button { font-size: 12px !important; min-height: 20px !important; padding: 0 6px !important; }
body.cwp-phone-browser #cwpReviewNotesRow .cwp-quicknav input { width: 30px; font-size: 11px; padding: 1px; }
body.cwp-phone-browser #cwpReviewNotesRow .cwp-quicknav .qn-pos { display: none; }

/* ── Phone follow-ups, BUILD 3218 (#124) ── */
/* Demo Panel pill: hidden from students (no-dev), otherwise a tiny faint corner tab that no
   longer covers the paper. */
html.cwp-no-dev body.cwp-phone-browser #cwpMobileDemoPanelToggle { display: none !important; }
body.cwp-phone-browser #cwpMobileDemoPanelToggle {
  top: 0 !important; left: 0 !important; padding: 0 5px !important;
  font-size: 9px !important; line-height: 14px !important; opacity: .45;
  border-radius: 0 0 8px 0 !important; box-shadow: none !important;
}
/* Collapse the tile band when it holds no tiles, so the paper can grow. */
body.cwp-phone-browser .tablet-bottom-half:has(.cwp-phone-tiles):not(:has(.cwp-tile)) { display: none !important; }
