:root {
  color-scheme: light;
  --bg: #f7f5f0;
  --card-bg: #ffffff;
  --text: #403F4C;        /* Gunmetal — primary text */
  --muted: #96BBBB;        /* Ash Grey — borders, backgrounds, inactive-state decoration. NOT used for text (see --muted-text) — at full strength it's ~2:1 against this background, well under WCAG AA. */
  --muted-text: color-mix(in srgb, var(--muted) 60%, black); /* Ash Grey, darkened for actual text (labels, captions, notes) — ~5:1 against --card-bg, passes AA. Every `color:` use of muted styling should reference this, not --muted directly. */
  --border: #96BBBB;        /* Ash Grey — borders, inactive states */
  --accent: #618985;        /* Deep Teal — primary/interactive accent (buttons, active icons, header bars) */
  --accent-text: #ffffff;
  --error-bg: #fbeaea;
  --error-text: #8a2c2c;
  --pearl-beige: #F2E3BC;   /* reading progress bar fill — this specific use only, not a general accent */
  --camel: #C19875;        /* small accent — streak flame badge only */
  /* Semantic status colors — deliberately NOT part of the palette above.
     Odin's target-met state and success flashes keep their original green
     regardless of accent/palette changes, per this session's explicit
     "leave existing semantic status colors alone" instruction. */
  --success-bg: #e9f3ec;
  --success-text: #3f6b52;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}

.card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 2rem;
  width: 100%;
  max-width: 360px;
}

.card h1 {
  margin: 0 0 1.25rem;
  font-size: 1.25rem;
}

label {
  display: block;
  font-size: 0.85rem;
  margin-bottom: 0.3rem;
  color: var(--muted-text);
}

input[type="email"],
input[type="password"] {
  width: 100%;
  padding: 0.6rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 1rem;
  margin-bottom: 1rem;
}

button {
  width: 100%;
  padding: 0.7rem;
  border: none;
  border-radius: 6px;
  background: var(--accent);
  color: var(--accent-text);
  font-size: 1rem;
  cursor: pointer;
}

button:hover {
  opacity: 0.92;
}

.error {
  background: var(--error-bg);
  color: var(--error-text);
  border-radius: 6px;
  padding: 0.6rem 0.8rem;
  margin-bottom: 1rem;
  font-size: 0.9rem;
}

.muted {
  color: var(--muted-text);
  font-size: 0.9rem;
}

a {
  color: var(--accent);
}

/* --- Checklist / dashboard layout ------------------------------------ */

body.dashboard {
  display: block;
  padding: 1.5rem 1rem 3rem;
}

.page {
  max-width: 900px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.sidebar {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* CSS Grid's default row-tracking (grid-auto-flow: row) forces every card
   in a row to match the row's tallest card, so a short card (Mia, Odin,
   Vocab) leaves dead space before the next row can start — the columns
   don't pack independently. CSS multi-column layout fixes this without
   restructuring checklist.php's flat list of cards into two hardcoded
   column wrappers: each column fills top-to-bottom from actual rendered
   heights (column-fill's default "balance" behavior), so a short card
   just lets the next one slide up, in either column, without the other
   column's heights mattering at all. break-inside: avoid keeps a single
   card from being split across the column boundary; margin-bottom
   replaces the flex/grid `gap` (multicol has no vertical-gap-within-a-
   column concept, only column-gap between columns) for spacing between
   stacked cards in the same column. */
@media (min-width: 700px) {
  .sidebar {
    display: block;
    columns: 2;
    column-gap: 1rem;
  }

  .sidebar > * {
    break-inside: avoid;
    margin-bottom: 1rem;
  }
}

.sidebar > .off-banner {
  column-span: all;
}

.sidebar-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.25rem;
}

.sidebar-card-header h2 {
  margin: 0;
}

.page-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.page-header h1 {
  margin: 0;
  font-size: 1.4rem;
}

.page-header .muted {
  display: block;
}

.track-card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1.25rem 1.5rem;
}

.track-card h2 {
  margin: 0 0 0.25rem;
  font-size: 1.05rem;
}

/* A sub-section heading within a card (e.g. Writing's "Commonplace book /
   Fluency writing", below the card's own h2) — no rule existed for a bare
   h3 directly inside .track-card, so it fell back to the browser default
   h3 size, which renders larger than the card's intentionally-shrunk h2
   above it. Sized clearly smaller and muted so it reads as subordinate,
   not competing with the card title. */
.track-card h3 {
  margin: 0.85rem 0 0.4rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--muted-text);
}

/* Writing card's two sub-sections (Assignment, Fluency writing) — a plain
   divider is enough separation in the compact sidebar card (bare/no extra
   boxing, matching the Today strip's chip convention); the drawer's
   equivalent two sections use the heavier .book-detail bordered-box
   treatment instead, since there's more room there and the constraint was
   explicitly "clearly bordered/labeled sections" for the drawer. */
.writing-section + .writing-section {
  border-top: 2px solid var(--border);
  padding-top: 1rem;
  margin-top: 1rem;
}

.track-card .track-note {
  margin: 0 0 1rem;
  color: var(--muted-text);
  font-size: 0.9rem;
}

.track-card.is-muted {
  background: #fbfaf7;
  opacity: 0.75;
}

.track-card.is-muted .track-note {
  margin-bottom: 0;
}

.track-card.is-success {
  background: var(--success-bg);
  border-color: var(--success-text);
}

.off-schedule-tag {
  display: inline-block;
  color: var(--muted-text);
  font-size: 0.8rem;
  font-style: italic;
  margin-bottom: 1rem;
}

.off-banner {
  background: var(--card-bg);
  border: 1px dashed var(--border);
  border-radius: 10px;
  padding: 1.5rem;
  text-align: center;
  color: var(--muted-text);
}

.off-banner strong {
  color: var(--text);
  display: block;
  margin-bottom: 0.25rem;
  font-size: 1.05rem;
}

.field-row {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}

.field-row > div {
  flex: 1;
  min-width: 140px;
}

select,
textarea,
input[type="number"],
input[type="text"],
input[type="url"] {
  width: 100%;
  padding: 0.55rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 1rem;
  font-family: inherit;
  margin-bottom: 1rem;
}

textarea {
  resize: vertical;
  min-height: 4.5rem;
}

.track-card button {
  width: auto;
  padding: 0.55rem 1.25rem;
}

.secondary-button {
  display: inline-block;
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 6px;
  padding: 0.55rem 1.25rem;
  margin-bottom: 1rem;
  font-size: 1rem;
  text-decoration: none;
  text-align: center;
  cursor: pointer;
}

.drawer-trigger {
  width: auto;
  flex-shrink: 0;
  background: transparent;
  color: var(--accent);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.3rem 0.8rem;
  font-size: 0.8rem;
  cursor: pointer;
}

.required-badge,
.freepick-badge {
  display: inline-block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border-radius: 4px;
  padding: 0.1rem 0.4rem;
  margin-left: 0.4rem;
  vertical-align: middle;
}

.required-badge {
  background: var(--accent);
  color: var(--accent-text);
}

.freepick-badge {
  background: var(--bg);
  color: var(--muted-text);
  border: 1px solid var(--border);
}

.book-detail {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1rem 1.1rem;
  margin-bottom: 1rem;
}

.book-detail h3 {
  margin: 0 0 0.5rem;
  font-size: 1rem;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.book-detail p {
  margin: 0 0 0.75rem;
  font-size: 0.9rem;
}

.book-detail .book-note {
  color: var(--muted-text);
  font-style: italic;
}

.history-heading {
  margin-bottom: 0.3rem;
}

.history-list {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.85rem;
}

.history-list li {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.3rem 0;
  border-top: 1px solid var(--border);
}

.history-list li:first-child {
  border-top: none;
}

.history-list .history-date {
  color: var(--muted-text);
  white-space: nowrap;
}

.streak-badge,
.progress-badge {
  display: inline-block;
  border-radius: 999px;
  padding: 0.2rem 0.75rem;
  font-size: 0.85rem;
  margin-bottom: 1rem;
  margin-right: 0.4rem;
}

.progress-badge {
  background: var(--bg);
  border: 1px solid var(--border);
}

/* Camel — small accent, the reading streak flame badge only. */
.streak-badge {
  background: color-mix(in srgb, var(--camel) 20%, var(--card-bg));
  border: 1px solid var(--camel);
}

.page-progress {
  margin-bottom: 1rem;
}

.page-progress-label {
  font-size: 0.85rem;
  color: var(--muted-text);
  margin-bottom: 0.35rem;
}

.progress-track {
  background: color-mix(in srgb, var(--border) 35%, white);
  border-radius: 999px;
  height: 0.6rem;
  overflow: hidden;
}

.progress-fill {
  background: var(--pearl-beige);
  height: 100%;
  border-radius: 999px;
}

.chore-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.chore-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

/* .chore-item is flex, but its checkbox+label live inside a .toggle-form
   child (Vocab and Chores both use this exact structure) — without this,
   the form itself falls back to block layout and the global `label {
   display: block }` rule drops the label to its own line under the
   checkbox instead of sitting inline next to it. */
.toggle-form {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.chore-item label {
  margin: 0;
  font-size: 1rem;
  color: var(--text);
}

.chore-item input[type="checkbox"] {
  width: 1.15rem;
  height: 1.15rem;
  accent-color: var(--accent);
}

.chore-item.completed label {
  color: var(--muted-text);
  text-decoration: line-through;
}

.flash {
  border-radius: 6px;
  padding: 0.5rem 0.8rem;
  font-size: 0.85rem;
  margin-bottom: 1rem;
}

.flash-success {
  background: var(--success-bg);
  color: var(--success-text);
}

.flash-error {
  background: var(--error-bg);
  color: var(--error-text);
}

.upload-results {
  margin-top: 1rem;
}

.admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.admin-table th,
.admin-table td {
  text-align: left;
  padding: 0.5rem 0.6rem;
  border-bottom: 1px solid var(--border);
}

.admin-table th {
  color: var(--muted-text);
  font-weight: 600;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.admin-table .secondary-button {
  padding: 0.35rem 0.75rem;
  font-size: 0.85rem;
  margin-bottom: 0;
}

.admin-table td > input,
.admin-table td > select {
  margin-bottom: 0;
}

.admin-table .sort-order-input {
  width: 4.5rem;
}

/* --- Drawer (slide-out detail panel) ---------------------------------- */

body.drawer-open {
  overflow: hidden;
}

.drawer-overlay {
  position: fixed;
  inset: 0;
  background: rgba(30, 28, 24, 0.45);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease, visibility 0.2s ease;
  z-index: 40;
}

.drawer-overlay.is-open {
  opacity: 1;
  visibility: visible;
}

.drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(440px, 100%);
  background: var(--card-bg);
  box-shadow: -8px 0 24px rgba(30, 28, 24, 0.18);
  transform: translateX(100%);
  transition: transform 0.25s ease;
  z-index: 50;
  overflow-y: auto;
  padding: 1.25rem;
}

.drawer.is-open {
  transform: translateX(0);
}

/* Deep Teal header bar — the drawer's fixed top strip is the one place in
   this UI shaped like a literal "header bar," per the palette's accent role. */
.drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: -1.25rem -1.25rem 1rem;
  padding: 1rem 1.25rem;
  background: var(--accent);
  border-radius: 0;
}

.drawer-header h2 {
  margin: 0;
  font-size: 1.1rem;
  color: var(--accent-text);
}

.drawer-close {
  width: auto;
  background: transparent;
  border: none;
  color: var(--accent-text);
  font-size: 1.5rem;
  line-height: 1;
  padding: 0.25rem 0.5rem;
  cursor: pointer;
  opacity: 0.85;
}

.drawer-close:hover {
  opacity: 1;
}

/* Desktop: the drawer occupies ~75% of the viewport, wide enough to read
   imported assignment/rubric/requirements content comfortably, with the
   sidebar staying visible (and undimmed — the overlay only covers the
   remaining strip, not the area under the drawer) alongside it. Reuses
   the sidebar's own 700px breakpoint rather than introducing a third,
   since this is the same "desktop layout" transition. */
@media (min-width: 700px) {
  .drawer {
    width: 75vw;
  }

  .drawer-overlay {
    right: 75vw;
  }
}

/* Near-full-screen on narrow/mobile viewports, per this session's explicit
   requirement — not just a squeezed version of the desktop panel. */
@media (max-width: 640px) {
  .drawer {
    width: 100%;
  }
}

/* --- Projects -------------------------------------------------------- */

.project-list {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.project-list li {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.5rem 0;
  border-top: 1px solid var(--border);
}

.project-list li:first-child {
  border-top: none;
}

.status-badge {
  display: inline-block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  border-radius: 4px;
  padding: 0.1rem 0.4rem;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--muted-text);
}

.status-badge.status-in_progress {
  background: var(--border);
  color: var(--text);
  border-color: var(--border);
}

.status-badge.status-done {
  background: var(--accent);
  color: var(--accent-text);
  border-color: var(--accent);
}

/* --- Project due-date badge (checklist.php, student-facing) ------------
   Three urgency tiers built on project_is_overdue() (app/digest.php) —
   the same calculation that drives the admin dashboard's Behind badge —
   plus a purely presentational "approaching" tier layered on top for
   visual escalation as a due date gets close. Bold and badge-shaped in
   every tier, not just when urgent, per this session's "catch a kid's
   eye" ask — calm is still prominent, just quieter in color. */
.due-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.85rem;
  font-weight: 700;
  padding: 0.3rem 0.7rem;
  border-radius: 8px;
  border: 1px solid var(--border);
}

.due-badge.calm {
  background: var(--bg);
  color: var(--text);
  border-color: var(--border);
}

.due-badge.approaching {
  background: color-mix(in srgb, var(--camel) 20%, var(--card-bg));
  color: color-mix(in srgb, var(--camel) 75%, black);
  border-color: var(--camel);
}

.due-badge.overdue {
  background: var(--camel);
  color: var(--text);
  border-color: var(--camel);
}

/* --- Today strip (checklist.php) ---------------------------------------
   Compact "what's due today" summary above the per-topic cards. Bare
   title-only chips by design — the cards below stay the page's primary
   focus, this is a glance, not a second copy of each card's detail. Chip
   states reuse the same two-tier convention already used elsewhere
   (.badge.on-track's solid Deep Teal fill / .badge.no-signal's outlined
   Ash Grey) rather than inventing a third visual language for "met" vs
   "not yet." The alert line reuses Camel — the same accent .due-badge and
   .badge.behind already use for "needs attention" — for both due-date and
   pacing alerts, deliberately not a second color, so the two kinds read
   as one severity, not two. */
.today-strip {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
}

.today-alert {
  background: color-mix(in srgb, var(--camel) 20%, var(--card-bg));
  border: 1px solid var(--camel);
  border-radius: 8px;
  color: color-mix(in srgb, var(--camel) 75%, black);
  font-size: 0.85rem;
  font-weight: 700;
  padding: 0.5rem 0.75rem;
  margin-bottom: 0.6rem;
}

.today-alert div + div {
  margin-top: 0.3rem;
}

.today-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.today-row + .today-row {
  margin-top: 0.5rem;
}

.today-row-label {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--muted-text);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  min-width: 5.5rem;
}

.chip {
  display: inline-flex;
  align-items: center;
  font-size: 0.8rem;
  font-weight: 600;
  padding: 0.25rem 0.7rem;
  border-radius: 999px;
  border: 1px solid var(--border);
}

.chip-met {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-text);
}

.chip-pending {
  background: var(--bg);
  border-color: var(--border);
  color: var(--muted-text);
}

/* --- Admin sidebar (persistent left nav, docs/dashboard-mockup.html) --- */

.admin-layout {
  display: flex;
  align-items: flex-start;
  min-height: 100vh;
}

.admin-sidebar {
  width: 240px;
  flex-shrink: 0;
  min-height: 100vh;
  background: var(--card-bg);
  border-right: 1px solid var(--border);
  padding: 1.25rem 0.875rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.admin-sidebar h1 {
  font-size: 1rem;
  font-weight: 700;
  margin: 0 0.5rem 1.1rem;
  color: var(--text);
}

.admin-sidebar .nav-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.6rem;
  border-radius: 8px;
  font-size: 0.875rem;
  color: var(--muted-text);
  text-decoration: none;
}

.admin-sidebar .nav-item:hover {
  background: var(--bg);
}

.admin-sidebar .nav-item.active {
  background: var(--accent);
  color: var(--accent-text);
  font-weight: 600;
}

.nav-group {
  margin-top: 0.35rem;
}

.nav-group-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.55rem 0.6rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted-text);
  cursor: pointer;
  border-radius: 8px;
}

.nav-group-header:hover {
  background: var(--bg);
}

.nav-group-header .chev {
  transition: transform 0.15s ease;
  font-size: 0.7rem;
  color: var(--border);
}

.nav-group.open .chev {
  transform: rotate(90deg);
}

.nav-group-items {
  display: none;
  flex-direction: column;
  padding-left: 0.875rem;
  border-left: 1px solid var(--border);
  margin-left: 1rem;
}

.nav-group.open .nav-group-items {
  display: flex;
}

.nav-group-items a {
  padding: 0.45rem 0.6rem;
  font-size: 0.8rem;
  color: var(--muted-text);
  text-decoration: none;
  border-radius: 6px;
}

.nav-group-items a:hover {
  background: var(--bg);
  color: var(--text);
}

.nav-group-items a.active {
  color: var(--accent);
  font-weight: 600;
}

.admin-main {
  flex: 1;
  min-width: 0;
}

@media (max-width: 720px) {
  .admin-layout {
    flex-direction: column;
  }

  .admin-sidebar {
    width: 100%;
    min-height: auto;
    border-right: none;
    border-bottom: 1px solid var(--border);
  }
}

/* --- Admin dashboard (card grid + on-track badge) ---------------------- */

.student-toggle {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1.1rem;
}

.student-toggle a {
  display: inline-block;
  border: 1px solid var(--border);
  background: var(--card-bg);
  padding: 0.4rem 1.1rem;
  border-radius: 20px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted-text);
  text-decoration: none;
}

.student-toggle a.active {
  background: var(--text);
  border-color: var(--text);
  color: #fff;
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 0.75rem;
  margin-bottom: 1.75rem;
}

.card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 0.875rem 1rem;
}

/* Three visually distinct card states — on track (Deep Teal), behind
   (Camel), no signal (Ash Grey) — so a card with no real digest flag
   never reads as "behind" by omission. Only Projects (no target concept
   at all, not just "no signal today") gets neither class nor badge. */
.card.on-track {
  border-color: var(--accent);
}

.card.behind {
  border-color: var(--camel);
}

/* Same value as the default .card border above — kept as an explicit
   rule (not just falling through to the default) so "no signal" reads
   as a deliberate third state in the markup, not a missing style. */
.card.no-signal {
  border-color: var(--border);
}

.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.35rem;
  gap: 0.5rem;
}

.card-label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--text);
}

.card-icon {
  width: 22px;
  height: 22px;
  border-radius: 6px;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  flex-shrink: 0;
}

.badge {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.625rem;
  font-weight: 700;
  padding: 0.2rem 0.5rem;
  border-radius: 20px;
  border: 1px solid transparent;
  white-space: nowrap;
}

/* On track — solid Deep Teal fill (unchanged from the original single-state badge). */
.badge.on-track {
  background: var(--accent);
  color: var(--accent-text);
}

/* Behind — Camel (the palette's other small-accent color, already used
   for the reading streak badge), tinted/outlined rather than
   solid-filled so it reads as distinct from "on track" by shape too,
   not color alone. */
.badge.behind {
  background: color-mix(in srgb, var(--camel) 20%, var(--card-bg));
  border-color: var(--camel);
  color: color-mix(in srgb, var(--camel) 75%, black);
}

/* No signal — Ash Grey, reusing the same tint/border/--muted-text
   convention used everywhere else in this app for muted content, so it
   reads as "nothing to report," not "behind." */
.badge.no-signal {
  background: var(--bg);
  border-color: var(--border);
  color: var(--muted-text);
}

.card-line {
  font-size: 0.78rem;
  color: var(--muted-text);
  margin-top: 0.2rem;
}

.section-title {
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--muted-text);
  margin: 0 0 0.6rem;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

/* --- Admin submissions (collapsible per-topic logs) --------------------- */

.submissions {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  margin-bottom: 1.5rem;
}

.sub-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  cursor: pointer;
  border-top: 1px solid var(--border);
}

.sub-row:first-child {
  border-top: none;
}

.sub-row.emphasis {
  background: var(--bg);
}

.sub-row-label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text);
}

.sub-row .chev {
  color: var(--border);
  font-size: 0.7rem;
  transition: transform 0.15s ease;
}

.sub-row.open .chev {
  transform: rotate(90deg);
}

.sub-body {
  display: none;
  padding: 0.25rem 1rem 0.875rem 2.75rem;
  flex-direction: column;
  gap: 0.5rem;
}

.sub-row.open + .sub-body {
  display: flex;
}

.sub-entry {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  font-size: 0.78rem;
  color: var(--muted-text);
}

.sub-entry a {
  color: color-mix(in srgb, var(--accent) 75%, black);
  text-decoration: none;
  font-weight: 600;
  flex-shrink: 0;
}

.jump {
  font-size: 0.7rem;
  color: color-mix(in srgb, var(--accent) 75%, black);
  background: var(--bg);
  padding: 0.15rem 0.55rem;
  border-radius: 20px;
  text-decoration: none;
  font-weight: 700;
}

/* --- Admin preview-date banner ---------------------------------------- */

.preview-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem;
  background: var(--border);
  color: var(--text);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  font-size: 0.9rem;
}

.preview-banner form {
  margin: 0;
}

.preview-banner .secondary-button {
  margin-bottom: 0;
  padding: 0.35rem 0.9rem;
  font-size: 0.85rem;
  background: var(--card-bg);
}

/* --- Admin test-digest preview ----------------------------------------- */

.digest-preview {
  white-space: pre-wrap;
  font-size: 0.85rem;
  background: color-mix(in srgb, var(--border) 35%, white);
  border-radius: 8px;
  padding: 1rem;
}
