:root {
  color-scheme: light;
  --bg: #f6f7fb;
  --bg-subtle: #fafbfd;
  --surface: #ffffff;
  --border: #e2e5ec;
  --text: #1c1f26;
  --text-muted: #6b7280;
  --primary: #1b6783;
  --primary-dark: #17576e;
  --on-primary: #ffffff; /* text on --primary fills; 6.3:1 in light mode */
  --danger: #dc2626;
  --success: #16a34a;
  --warning: #d97706;

  --radius-sm: 8px;
  --radius: 12px;
  --radius-lg: 16px;

  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 28px;

  --text-xs: 12px;
  --text-sm: 13px;
  --text-base: 14px;
  --text-md: 16px;
  --text-lg: 18px;
  --text-xl: 22px;

  --tint-primary-bg: #e9f3f7;
  --tint-warning-bg: #fef3c7;
  --tint-danger-bg: #fee2e2;
  --tint-danger-border: #fecaca;
  --shadow-card: 0 1px 2px rgba(15, 17, 21, 0.04), 0 1px 6px rgba(15, 17, 21, 0.04);
  --shadow-card-hover: 0 4px 16px rgba(15, 17, 21, 0.08);
  --sk-base: #e8ebf1; /* skeleton loading shimmer */
  --sk-hi: #f5f7fb;
}

/* Dark theme. Two copies on purpose (CSS can't share one rule between a media
   query and an attribute selector): the explicit [data-theme="dark"] choice
   from the settings menu, and the device default when the user hasn't chosen
   ("system"). Keep the two blocks identical. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #14161c;
  --bg-subtle: #1a1d25;
  --surface: #1d2029;
  --border: #2e323d;
  --text: #eef0f4;
  --text-muted: #9aa1ae;
  --primary: #6cb6d0;
  --primary-dark: #55a5c4;
  --on-primary: #0c2229; /* light primary needs dark text */
  --danger: #f87171;
  --success: #4ade80;
  --warning: #fbbf24;

  --tint-primary-bg: #1d2e34;
  --tint-warning-bg: #3a2f14;
  --tint-danger-bg: #3a1f1f;
  --tint-danger-border: #5c2b2b;
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 6px rgba(0, 0, 0, 0.24);
  --shadow-card-hover: 0 4px 20px rgba(0, 0, 0, 0.4);
  --sk-base: #272b36;
  --sk-hi: #343948;
}
:root[data-theme="dark"] select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%239aa1ae' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) {
    color-scheme: dark;
    --bg: #14161c;
    --bg-subtle: #1a1d25;
    --surface: #1d2029;
    --border: #2e323d;
    --text: #eef0f4;
    --text-muted: #9aa1ae;
    --primary: #6cb6d0;
    --primary-dark: #55a5c4;
    --on-primary: #0c2229; /* light primary needs dark text */
    --danger: #f87171;
    --success: #4ade80;
    --warning: #fbbf24;

    --tint-primary-bg: #1d2e34;
    --tint-warning-bg: #3a2f14;
    --tint-danger-bg: #3a1f1f;
    --tint-danger-border: #5c2b2b;
    --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 6px rgba(0, 0, 0, 0.24);
    --shadow-card-hover: 0 4px 20px rgba(0, 0, 0, 0.4);
    --sk-base: #272b36;
    --sk-hi: #343948;
  }

  :root:not([data-theme="light"]):not([data-theme="dark"]) select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%239aa1ae' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
}

.page {
  max-width: 1000px;
  margin: 0 auto;
  padding: var(--space-6) var(--space-5) 60px;
}

header.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px var(--space-5);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
  gap: var(--space-2);
}

header.topbar h1 { font-size: var(--text-lg); margin: 0; }
header.topbar nav { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
header.topbar nav a {
  color: var(--text-muted);
  text-decoration: none;
  font-size: var(--text-base);
}
header.topbar nav a:hover { color: var(--primary); }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-5);
  margin-bottom: var(--space-5);
  box-shadow: var(--shadow-card);
  transition: box-shadow 0.15s ease;
}

.card h2 { margin-top: 0; font-size: var(--text-md); }
.card h3 { font-size: var(--text-sm); color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; }

details.card summary {
  cursor: pointer;
  list-style: none;
}
details.card summary::-webkit-details-marker { display: none; }
details.card summary h2 {
  display: inline-block;
  margin: 0;
}
details.card summary h2::before {
  content: "▸ ";
  color: var(--text-muted);
  font-size: var(--text-sm);
}
details.card[open] summary h2::before { content: "▾ "; }
details.card > *:not(summary) { margin-top: var(--space-4); }

textarea { resize: vertical; max-width: 100%; }

button {
  font: inherit;
  cursor: pointer;
  border: none;
  border-radius: var(--radius-sm);
  padding: 9px 16px;
  background: var(--primary);
  color: var(--on-primary);
  transition: background 0.15s, transform 0.05s;
}
button:hover { background: var(--primary-dark); }
button:active { transform: translateY(1px); }
button:disabled { background: #a5a6b5; cursor: not-allowed; transform: none; }
button.secondary { background: var(--surface); color: var(--text); border: 1px solid var(--border); }
button.secondary:hover { background: var(--bg); }
button.danger, button.danger-text { background: transparent; color: var(--danger); border: 1px solid var(--tint-danger-border); }
button.danger-text:hover { background: var(--tint-danger-bg); }

input, select, textarea {
  font: inherit;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 20%, transparent);
}

/* Native selects otherwise keep OS-chrome (bezels, mismatched arrow box)
   even with the background/border above applied - appearance: none strips
   that so the field reads as part of the same design as inputs/buttons.
   The open options list itself is still OS-rendered (no CSS can reach it
   cross-browser), but the field itself now matches at rest and on click. */
select {
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  padding-right: 34px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%236b7280' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 10px 6px;
}

label { font-size: var(--text-sm); color: var(--text-muted); display: block; margin-bottom: var(--space-1); }

.row { display: flex; gap: var(--space-3); align-items: flex-end; flex-wrap: wrap; }
.field { display: flex; flex-direction: column; gap: var(--space-1); }

.badge {
  display: inline-block;
  font-size: var(--text-xs);
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--tint-primary-bg);
  color: var(--primary);
}
.badge.warning { background: var(--tint-warning-bg); color: var(--warning); }
.badge.danger { background: var(--tint-danger-bg); color: var(--danger); }
.badge .dismiss-reteach-btn {
  background: transparent;
  color: inherit;
  border: none;
  padding: 0;
  line-height: 1;
  font-size: var(--text-xs);
  opacity: 0.7;
}
.badge .dismiss-reteach-btn:hover { opacity: 1; }

.error-banner {
  background: var(--tint-danger-bg);
  border: 1px solid var(--tint-danger-border);
  color: var(--danger);
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-4);
  font-size: var(--text-base);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
}

.chooser {
  display: flex;
  gap: var(--space-5);
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 40px;
}
.chooser .card { width: 300px; }

.settings-corner { display: flex; justify-content: flex-end; padding: var(--space-4) var(--space-5) 0; }
.settings-inline, .settings-corner { display: flex; }
.settings-wrap { position: relative; }
button.settings-btn {
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0;
  background: transparent; color: var(--text-muted);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
}
button.settings-btn:hover, button.settings-btn[aria-expanded="true"] { background: var(--bg); color: var(--primary); }
.settings-popover {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 60;
  min-width: 230px; padding: var(--space-3);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-card-hover);
  text-align: left;
}
.settings-popover[hidden] { display: none; }
.settings-group + .settings-group { margin-top: var(--space-3); }
.settings-label { font-size: var(--text-xs); color: var(--text-muted); margin-bottom: 6px; }
.seg { display: flex; }
.seg-btn {
  flex: 1; background: transparent; color: var(--text);
  border: 1px solid var(--border); padding: 6px 8px; font-size: var(--text-sm);
  border-radius: 0; margin-left: -1px;
}
.seg-btn:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); margin-left: 0; }
.seg-btn:last-child { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.seg-btn.active { background: var(--primary); color: var(--on-primary); border-color: var(--primary); position: relative; }
.seg-btn:hover:not(.active) { background: var(--bg); }
.settings-account { border-top: 1px solid var(--border); padding-top: var(--space-3); }
.settings-account button { width: 100%; }
.settings-confirm p { margin: 0 0 var(--space-2); font-size: var(--text-sm); }
.settings-account [hidden] { display: none !important; }
.settings-confirm-actions { display: flex; gap: var(--space-2); }
.settings-confirm-actions button { flex: 1; width: auto; }

.chat-window {
  height: 400px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--space-4);
  background: var(--bg-subtle);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.msg { max-width: 80%; padding: 10px 14px; border-radius: 14px; font-size: var(--text-base); line-height: 1.45; }
.msg.user { align-self: flex-end; background: var(--primary); color: var(--on-primary); }
.msg.assistant { align-self: flex-start; background: var(--tint-primary-bg); color: var(--text); }
.msg.system { align-self: center; background: var(--tint-warning-bg); color: var(--warning); font-size: var(--text-sm); }
.msg.msg-formatted { max-width: 90%; }
.msg.msg-formatted p { margin: 0 0 8px; }
.msg.msg-formatted p:last-child { margin-bottom: 0; }
.msg.msg-formatted .math-line { margin: 4px 0; }
.msg.msg-formatted ol, .msg.msg-formatted ul { margin: 4px 0 10px; padding-left: 22px; }
.msg.msg-formatted li { margin-bottom: 4px; }

/* Math-symbol toolbar - always visible under the chat input, to insert
   symbols that are hard to type on a regular keyboard (roots, exponents,
   comparison operators, degrees). Kept to one row - scrolls horizontally
   rather than wrapping if it's ever too narrow to fit. */
.symbol-toolbar {
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;
  gap: 6px;
  margin-top: 10px;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-subtle);
}
.symbol-toolbar button {
  flex: 0 0 auto;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 6px);
  padding: 6px 12px;
  font-size: var(--text-base);
  line-height: 1.2;
  cursor: pointer;
}
.symbol-toolbar button:hover { background: var(--bg); border-color: var(--primary); }

/* Standalone formula/equation lines within AI-generated explanations (see
   LoopAPI.formatExplanationHtml) - set apart from surrounding prose so a
   calculation doesn't get lost in a wall of text. */
.reteach-explanation p { margin: 0 0 8px; }
.reteach-explanation p:last-child { margin-bottom: 0; }
.reteach-explanation ol, .reteach-explanation ul { margin: 4px 0 10px; padding-left: 22px; }
.reteach-explanation li { margin-bottom: 4px; }
.math-line {
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: var(--text-md);
  line-height: 1.7;
  background: var(--bg-subtle);
  border-left: 3px solid var(--primary);
  border-radius: var(--radius-sm);
  padding: 6px 12px;
  margin: 4px 0 10px;
}

.confidence-card { background: var(--bg-subtle); }
.practice-problem { margin-bottom: var(--space-4); padding-bottom: var(--space-4); border-bottom: 1px solid var(--border); }
.practice-problem:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; }

table { width: 100%; border-collapse: collapse; font-size: var(--text-base); }
th, td { padding: 8px 10px; border-bottom: 1px solid var(--border); text-align: left; }
th { color: var(--text-muted); font-weight: 600; font-size: var(--text-xs); text-transform: uppercase; }

.heat-cell { position: relative; text-align: center; border-radius: 4px; font-weight: 600; }
.heat-cell-clickable { cursor: pointer; }
.heat-cell-clickable:hover { outline: 2px solid var(--primary); outline-offset: -2px; }
/* Top-left badge: distinct misconceptions no longer "current" on this
   subtopic - a different color (success green) from the main red count, so
   it reads as separate information rather than diluting the cell's own
   severity. The cell itself always stays red by count, regardless. */
.heat-cell-resolved-badge {
  position: absolute;
  top: -5px;
  left: -5px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 999px;
  background: var(--success);
  color: white;
  font-size: 10px;
  font-weight: 700;
  line-height: 15px;
  text-align: center;
}

.heatmap-table th, .heatmap-table td { padding: 10px 12px; }
.heatmap-topic-row th { font-size: var(--text-md); text-transform: none; letter-spacing: normal; color: var(--text); background: var(--bg); padding-top: 14px; }
.heatmap-subtopic-name { font-size: var(--text-base); font-weight: 500; padding-left: 22px; }

/* Sign up/log in view toggle (also reused by index.html) */
.view-toggle { gap: var(--space-2); }
.view-toggle-btn.active { background: var(--primary); color: var(--on-primary); border-color: var(--primary); }
/* Needs its own hover: the generic button.secondary:hover (background: var(--bg)) is more specific than .active
   and would otherwise paint the selected tab page-colored (near-black in dark mode) under its on-primary text. */
.view-toggle-btn.active:hover { background: var(--primary-dark); color: var(--on-primary); border-color: var(--primary-dark); }

.progress-bar-track { background: var(--bg); border-radius: 999px; height: 10px; overflow: hidden; }
.progress-bar-fill { background: var(--primary); height: 100%; }

.quote { font-style: italic; color: var(--text-muted); }

/* Confusion-feed items: the tutor's reply is tucked behind this toggle
   instead of always shown, to cut down on how much text each item takes. */
.feed-reply-details { margin-top: 4px; }
.feed-reply-details summary { cursor: pointer; color: var(--primary); font-size: var(--text-sm); }
.muted { color: var(--text-muted); font-size: var(--text-sm); }

/* Example quotes (e.g. chat-engagement low-effort messages) - clicking a
   rate badge opens a panel in its own row directly under that student's
   row (not a single panel always pinned to the bottom of the table),
   labeled with whose examples they are. */
.link-btn { background: none; border: none; padding: 0; cursor: pointer; }
.link-btn:hover .badge { outline: 1px solid currentColor; }
.examples-panel {
  margin: 6px 0;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-subtle);
}
.examples-list { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.examples-list > li { padding-left: 10px; border-left: 2px solid var(--border); }
.examples-list .example-text { color: var(--text); line-height: 1.4; }
.examples-sublist { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }

.working-ahead-topic { margin-bottom: 16px; }
.working-ahead-topic:last-child { margin-bottom: 0; }
.working-ahead-list { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.working-ahead-list li { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 6px 0; border-bottom: 1px solid var(--border); }
.working-ahead-list li:last-child { border-bottom: none; }

.loading { color: var(--text-muted); font-size: var(--text-sm); }

/* ---- Skeleton loading (built by LoopAPI.skeleton in api.js) ---- */
@keyframes sk-shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }
.sk {
  background: linear-gradient(90deg, var(--sk-base) 30%, var(--sk-hi) 50%, var(--sk-base) 70%);
  background-size: 200% 100%;
  animation: sk-shimmer 1.4s linear infinite;
  border-radius: var(--radius-sm);
}
@media (prefers-reduced-motion: reduce) { .sk { animation: none; } }
.sk-contents { display: contents; }
.sk-wrap { flex: 1; min-width: 0; } /* fill flex parents (e.g. the pacing progress row) instead of collapsing to 0 width */
.sk-line { height: 12px; margin-bottom: 10px; }
.sk-line:last-child { margin-bottom: 0; }
.sk-title { height: 16px; width: 45%; margin-bottom: 14px; }
.sk-btn { height: 30px; width: 90px; margin-top: 14px; border-radius: var(--radius-sm); }
.sk-bar { height: 10px; width: 100%; border-radius: 999px; }
.sk-card { min-height: 130px; }
.sk-row { display: flex; align-items: center; gap: var(--space-3); padding: 12px 14px; margin-bottom: 8px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.sk-row .sk-line { margin: 0; flex: 1; }
.sk-dot { width: 18px; height: 18px; flex: none; border-radius: 5px; }
.sk-heat { display: grid; grid-template-columns: 2.2fr repeat(3, 1fr); gap: 8px; align-items: center; }
.sk-heat .sk { height: 22px; }
.msg.assistant.sk-msg { width: 280px; max-width: 80%; }
/* The bubble background is already a tint, so the generic shimmer would vanish into it - use the brand color at low opacity. */
.sk-msg .sk { background: linear-gradient(90deg, color-mix(in srgb, var(--primary) 22%, transparent) 30%, color-mix(in srgb, var(--primary) 40%, transparent) 50%, color-mix(in srgb, var(--primary) 22%, transparent) 70%); background-size: 200% 100%; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

/* ---- 404 page ---- */
.not-found { text-align: center; padding-top: 12vh; }
.not-found-code { font-size: 96px; font-weight: 700; line-height: 1; color: var(--primary); letter-spacing: -2px; }
.not-found h1 { font-size: var(--text-xl); margin: var(--space-4) 0 var(--space-2); }
.not-found p { margin: 0 0 var(--space-5); }
.button-link {
  display: inline-block; padding: 9px 18px; border-radius: var(--radius-sm);
  background: var(--primary); color: var(--on-primary); text-decoration: none; font-size: var(--text-base); font-weight: 600;
}
.button-link:hover { background: var(--primary-dark); }

.history-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(15, 17, 21, 0.35);
  z-index: 40;
}
.history-overlay.open { display: block; }

.history-sidebar {
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  width: 300px;
  max-width: 85vw;
  background: var(--surface);
  border-right: 1px solid var(--border);
  box-shadow: 4px 0 24px rgba(15, 17, 21, 0.12);
  transform: translateX(-100%);
  transition: transform 0.2s ease;
  z-index: 50;
  padding: var(--space-5);
  overflow-y: auto;
}
.history-sidebar.open { transform: translateX(0); }

.history-sidebar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-4);
}
.history-sidebar-header h2 { margin: 0; font-size: var(--text-md); }

.history-item {
  display: block;
  padding: 10px 10px;
  border-radius: var(--radius-sm);
  text-decoration: none;
  color: var(--text);
  margin-bottom: 2px;
}
.history-item:hover { background: var(--bg); }
.history-item .topic-name { font-size: var(--text-base); font-weight: 500; }
.history-item .time-ago { font-size: var(--text-xs); color: var(--text-muted); margin-top: 2px; }

/* Topic accordion (student topic picker) */
.topic-accordion { display: flex; flex-direction: column; gap: var(--space-2); margin: var(--space-3) 0; }
.topic-item {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-subtle);
}
.topic-item summary {
  cursor: pointer;
  list-style: none;
  padding: var(--space-3) var(--space-4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}
.topic-item summary::-webkit-details-marker { display: none; }
.topic-item summary::before { content: "▸"; color: var(--text-muted); margin-right: var(--space-2); }
.topic-item[open] summary::before { content: "▾"; }
.topic-item summary .topic-name { flex: 1; font-weight: 500; }
.topic-item summary .topic-progress { color: var(--text-muted); font-size: var(--text-sm); }
.topic-item .topic-body { padding: 0 var(--space-4) var(--space-4); }
.subtopic-list { margin: var(--space-2) 0; padding-left: 20px; }
.subtopic-list > li { margin-bottom: var(--space-2); }
.objectives-list { margin: var(--space-1) 0; padding-left: 18px; color: var(--text-muted); font-size: var(--text-sm); }

/* Teacher pacing timeline (pacing.html) - one continuous, topic-grouped list
   instead of three disconnected Current/Past/Upcoming cards, with a progress
   bar for at-a-glance "how far along are we" context. */
.pacing-progress { display: flex; align-items: center; gap: var(--space-3); }
.pacing-progress-bar { flex: 1; height: 8px; border-radius: 999px; background: var(--border); overflow: hidden; }
.pacing-progress-fill { height: 100%; background: var(--primary); border-radius: 999px; }
.pacing-subtopic-row { display: flex; align-items: center; gap: var(--space-2); padding: 4px 8px; margin: 1px 0; border-radius: var(--radius-sm); }
.pacing-subtopic-row .pacing-name { flex: 1; min-width: 0; text-align: left; }
.pacing-subtopic-row > .badge { flex-shrink: 0; white-space: nowrap; }
.pacing-subtopic-row.is-done .pacing-name { color: var(--text-muted); }
.pacing-subtopic-row.is-current { background: var(--tint-primary-bg); padding: 6px 10px; }
.pacing-subtopic-row.is-current .pacing-name { font-weight: 600; color: var(--primary); }

/* The done-checkbox is its own button, separate from the row's jump target -
   checking/unchecking never moves the pointer, and vice versa. */
.pacing-checkbox {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  padding: 0;
  border-radius: 6px;
  background: transparent;
  border: 1px solid var(--border);
  color: transparent;
  font-size: var(--text-sm);
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pacing-checkbox:hover { background: var(--bg-subtle); border-color: var(--primary); }
.pacing-checkbox.is-checked { background: var(--success); border-color: var(--success); color: white; }

/* Student pacing page's personal flag toggle - same square slot as the
   teacher's done-checkbox, but a star glyph (always visible, not hidden
   until checked) since it's a different concept: "I want to review this",
   not "this was taught". */
.pacing-flag-btn { color: var(--text-muted); font-size: var(--text-base); }
.pacing-flag-btn.is-flagged { background: var(--tint-warning-bg); border-color: var(--warning); color: var(--warning); }

/* The rest of a non-current row is a real <button> (see subtopicRowHtml in
   pacing.js) - reset button chrome so it reads as a plain list item that
   happens to be clickable, not a colored pill, with a quiet hover/focus
   affordance and a trailing arrow instead of a labeled button. */
.pacing-row-main {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  background: transparent;
  color: var(--text);
  border: 1px solid transparent;
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  padding: 4px 6px;
  transition: background 0.1s, border-color 0.1s;
}
.pacing-row-main:hover, .pacing-row-main:focus-visible { background: var(--bg-subtle); border-color: var(--border); }
.pacing-row-main:active { transform: none; }
.pacing-jump-icon { flex-shrink: 0; color: var(--text-muted); }
.pacing-row-main:hover .pacing-jump-icon, .pacing-row-main:focus-visible .pacing-jump-icon { color: var(--primary); }

/* Subtopic picker row (student topic accordion's "Review this", student-pacing's
   past/current/upcoming entries) - name+objectives on the left, action button on
   the right. flex-start keeps the button anchored next to the subtopic name
   rather than centered against the full height of a long objectives list, and
   min-width:0 on the text column lets it wrap instead of squeezing the button
   (the button must never shrink/wrap - "Review this" wrapping into two lines
   was the visible bug this fixes, especially with longer English text). */
.subtopic-pick-row { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); list-style: none; }
.subtopic-pick-row > span { flex: 1; min-width: 0; }
.subtopic-pick-row > button,
.subtopic-pick-row > a { flex-shrink: 0; white-space: nowrap; }
.subtopic-current { font-weight: 600; color: var(--primary); }

/* Classrooms */
.classroom-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--space-4); margin-bottom: var(--space-5); }
.classroom-card { position: relative; }
h3.classroom-card-title { margin: 0; padding-right: 28px; text-transform: none; letter-spacing: normal; font-size: var(--text-md); color: var(--text); }
.classroom-delete-btn { position: absolute; top: var(--space-4); right: var(--space-4); }
.icon-danger-btn {
  flex: 0 0 auto;
  background: transparent;
  color: var(--text-muted);
  border: 1px solid transparent;
  padding: 4px 9px;
  border-radius: var(--radius-sm);
  line-height: 1;
}
.icon-danger-btn:hover { background: var(--tint-danger-bg); color: var(--danger); border-color: var(--tint-danger-border); }
.join-code-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-top: var(--space-4);
  padding: var(--space-3);
  background: var(--bg-subtle);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.join-code-label { font-size: var(--text-xs); color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; margin-bottom: 2px; }
.join-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--text-lg); letter-spacing: 0.1em; font-weight: 600; color: var(--primary); }
.classroom-actions { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-2); margin-top: var(--space-3); }
.classroom-actions > a { display: block; }
.classroom-actions button { width: 100%; font-size: var(--text-sm); padding: 8px 10px; white-space: nowrap; }
.classroom-actions > *:nth-child(3) { grid-column: 1 / -1; }
.roster-list { list-style: none; padding: 0; margin: 0; }
.roster-list li { display: flex; justify-content: space-between; align-items: center; padding: 6px 0; border-bottom: 1px solid var(--border); }
.roster-list li:last-child { border-bottom: none; }

@media (hover: hover) {
  .card:hover { box-shadow: var(--shadow-card-hover); }
}

@media (max-width: 640px) {
  .page { padding: var(--space-4) var(--space-3) 40px; }
  .chooser { margin-top: var(--space-5); }
  .chooser .card { width: 100%; }
  .classroom-grid { grid-template-columns: 1fr; }
  header.topbar { flex-direction: column; align-items: flex-start; }
  .row { align-items: stretch; }
  .row button { width: 100%; }
  .subtopic-pick-row { flex-direction: column; align-items: stretch; }
  .subtopic-pick-row > button,
  .subtopic-pick-row > a { width: 100%; }
  .subtopic-pick-row > a button { width: 100%; }
}
