/* assets/css/app.css — small supplements to the Tailwind utility classes */

/* ---------------------------------------------------------------------
 * EduLink UI Modernization Blueprint — Phase 2.2 / Phase 4
 * Semantic design tokens as CSS custom properties. tailwind.config.js
 * maps colors like `primary`, `app-body`, `surface`, `heading`, `body`,
 * `muted`, `sidebar`, `success`/`warning`/`danger`/`info` straight to
 * these variables, so a page written with e.g. bg-surface text-heading
 * automatically repaints correctly in dark mode — no dark: variant
 * needed on that page. Dark values live under html.dark (Tailwind
 * darkMode:'class', toggled by the theme control in includes/header.php
 * and persisted to localStorage under "edulink_theme").
 * ------------------------------------------------------------------- */
:root {
  /* -------------------------------------------------------------------
   * "Claude.ai Visual System" pass — replaces the prior TailAdmin
   * indigo/slate palette with a warm, editorial palette in the spirit
   * of claude.ai: cream/parchment surfaces, a terracotta/clay accent
   * (Anthropic's own brand hue, ~#DA7756, darkened here for AA text
   * contrast), and near-black warm neutrals for body copy instead of
   * cool blue-grays. Every value below was checked against its most
   * common pairing for WCAG AA (>=4.5:1 for body-size text, >=3:1 for
   * large/UI-component contrast) — see the button/badge rules further
   * down for how --ed-on-accent is used to keep text on solid-color
   * buttons readable in both themes.
   * ------------------------------------------------------------------- */
  --ed-primary:        #B1502E; /* clay/terracotta — 4.8:1 on --ed-body-bg, 5.2:1 on white */
  --ed-primary-hover:  #96401F;
  --ed-on-accent:      #FFFFFF; /* text color to place on top of a solid accent-colored fill */
  --ed-body-bg:        #F9F6F1; /* warm cream page background */
  --ed-sidebar-bg:     #F3EEE5;
  --ed-sidebar-active: #F0DFD2;
  --ed-card-bg:        #FFFFFF;
  --ed-border:         #E4DDD0;
  --ed-heading:        #221F1B;
  --ed-body-text:      #44403A;
  --ed-muted-text:     #6B665C;
  --ed-success:        #2F7D5D;
  --ed-success-bg:     #E7F3EC;
  --ed-warning:        #96601A;
  --ed-warning-bg:     #FBF1DF;
  --ed-danger:         #B23B2E;
  --ed-danger-bg:      #FBEAE7;
  --ed-info:           #3D6E93;
  --ed-info-bg:        #EAF2F7;
  /* "Analytics Button Colors and Skill Analysis Removal" blueprint —
     Phase 1. Certificate reuses --ed-success but that token has no
     hover shade yet (only a light --ed-success-bg tint, meant for
     badges/backgrounds, not a solid-button hover state) — added here
     rather than repurposing --ed-success-bg for it. Plan Analytics
     needed an entirely new semantic color (purple) — none of the
     existing tokens are unclaimed, and reusing e.g. --ed-info would
     collide with its existing meaning elsewhere. */
  --ed-success-hover:  #256B4E;
  --ed-purple:         #7C5CBF;
  --ed-purple-hover:   #6947A8;
  /* "Advanced Features Column Background" — shared roadmap table
     (.ta-table, student + teacher) Advanced Features column/header,
     Advanced mode only. A soft tint pulled from --ed-primary itself
     (not reusing --ed-danger-bg, which happens to be a close hex
     neighbor by coincidence but carries an unrelated "error state"
     meaning) so the column reads as "brand-tinted zone", not a status
     color. See .ta-table.is-advanced-mode .ta-col-advanced below. */
  --ed-advanced-col-bg: #FBEFE7;
}

html.dark {
  --ed-primary:        #E08659; /* lightened clay for AA contrast on dark backgrounds */
  --ed-primary-hover:  #EDA37D;
  --ed-on-accent:      #1B1A18; /* dark mode's brighter accent fills need dark, not white, text */
  --ed-body-bg:        #262624; /* warm charcoal, not pure black/navy */
  --ed-sidebar-bg:     #1F1E1C;
  --ed-sidebar-active: #3A2E27;
  --ed-card-bg:        #30302E;
  --ed-border:         #45433D;
  --ed-heading:        #F2EFE9;
  --ed-body-text:      #C9C4B8;
  --ed-muted-text:     #9C9689;
  --ed-success:        #5FB98A;
  --ed-success-bg:     rgba(95, 185, 138, 0.15);
  --ed-warning:        #E0A83D;
  --ed-warning-bg:     rgba(224, 168, 61, 0.15);
  --ed-danger:         #E67C71;
  --ed-danger-bg:      rgba(230, 124, 113, 0.15);
  --ed-info:           #6FA8CC;
  --ed-info-bg:        rgba(111, 168, 204, 0.15);
  --ed-success-hover:  #4CA57A;
  --ed-purple:         #B79AE8;
  --ed-purple-hover:   #C9AEEF;
  /* Same rgba(primary, low-opacity) pattern as --ed-success-bg/
     --ed-warning-bg/etc. above, built from dark mode's own --ed-primary
     (#E08659 -> 224,134,89) rather than reusing the light-mode hex, so
     it stays a visible-but-subtle tint against the dark card background. */
  --ed-advanced-col-bg: rgba(224, 134, 89, 0.14);
}

html.dark body { color-scheme: dark; }

/* ---------------------------------------------------------------------
 * Phase 1 — shared "ed-" component classes (EduLink visual system)
 * Plain CSS (not @apply): app.css is loaded as-is via <link>, with no
 * PostCSS/Tailwind build step processing it today, so these mirror the
 * equivalent Tailwind utilities in raw CSS. The same class names are
 * also defined with @apply in assets/css/src/tailwind.css for the
 * production Tailwind CLI build (see package.json) — keep both in sync
 * if you change one.
 * ------------------------------------------------------------------- */

.ed-page-shell {
  max-width: 80rem;      /* max-w-7xl */
  margin-left: auto;
  margin-right: auto;
  padding-left: 1rem;
  padding-right: 1rem;
  padding-top: 1.5rem;
  padding-bottom: 1.5rem;
}
@media (min-width: 640px) {
  .ed-page-shell { padding-left: 1.5rem; padding-right: 1.5rem; }
}
@media (min-width: 1024px) {
  .ed-page-shell { padding-left: 2rem; padding-right: 2rem; }
}

.ed-section-title {
  font-size: 1.125rem;
  font-weight: 800;
  color: var(--ed-heading);
  letter-spacing: -0.01em;
}

.ed-card {
  background: var(--ed-card-bg);
  border: 1px solid var(--ed-border);
  border-radius: 16px;       /* "Claude.ai Visual System" pass: slightly softer than the prior 14px */
  box-shadow: 0 1px 2px rgba(34, 31, 27, 0.04);
  padding: 1.25rem;          /* p-5 */
  color: var(--ed-body-text);
}

/* "Two-Tab Plan Page" blueprint — Section 5/11. Reusable two-tab (or
   more) navigation component: .ed-tabs is the row, .ed-tab each link,
   .ed-tab-active the current one, .ed-tab-count an optional trailing
   badge. Uses semantic tokens (not fixed colors) so it stays correct
   in light/dark mode. Both tabs remain visible and equal-width on
   mobile (Section 5 "Mobile behavior") — no dropdown collapse. */
.ed-tabs {
  display: flex;
  gap: 0.25rem;
  border-bottom: 1px solid var(--ed-border);
}
.ed-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  flex: 1 1 0;
  padding: 0.75rem 1rem;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--ed-muted-text);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color .15s ease, border-color .15s ease, background-color .15s ease;
}
.ed-tab:hover { color: var(--ed-heading); background: var(--ed-body-bg); }
.ed-tab-active,
.ed-tab-active:hover {
  color: var(--ed-primary);
  border-bottom-color: var(--ed-primary);
  background: transparent;
}
.ed-tab-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  height: 1.25rem;
  padding: 0 0.375rem;
  border-radius: 999px;
  font-size: 0.6875rem;
  font-weight: 700;
  background: var(--ed-body-bg);
  color: var(--ed-muted-text);
}
.ed-tab-active .ed-tab-count { background: color-mix(in srgb, var(--ed-primary) 15%, var(--ed-card-bg)); color: var(--ed-primary); }
@media (max-width: 640px) {
  .ed-tab { padding: 0.75rem 0.5rem; font-size: 0.8125rem; }
}

.ed-card-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 0.875rem;
  margin-bottom: 0.875rem;
  border-bottom: 1px solid var(--ed-border);
}
.ed-card-header h3 { font-size: 0.9375rem; font-weight: 700; color: var(--ed-heading); }
.ed-card-header p { font-size: 0.8125rem; color: var(--ed-muted-text); margin-top: 2px; }

.ed-btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  background: var(--ed-primary);
  color: var(--ed-on-accent);
  font-size: 0.875rem;
  font-weight: 600;
  padding: 0.625rem 1rem;
  border-radius: 10px;      /* Phase 2.1: button radius 8-10px */
  border: none;
  cursor: pointer;
  transition: background-color .15s ease;
}
.ed-btn-primary:hover { background: var(--ed-primary-hover); }
.ed-btn-primary:disabled { opacity: .6; cursor: not-allowed; }

.ed-btn-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  background: var(--ed-card-bg);
  color: var(--ed-body-text);
  font-size: 0.875rem;
  font-weight: 600;
  padding: 0.625rem 1rem;
  border-radius: 9px;
  border: 1px solid var(--ed-border);
  cursor: pointer;
  transition: background-color .15s ease;
}
.ed-btn-secondary:hover { background: var(--ed-body-bg); }
.ed-btn-secondary:disabled { opacity: .6; cursor: not-allowed; }

.ed-btn-danger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  background: var(--ed-card-bg);
  color: var(--ed-danger);
  font-size: 0.875rem;
  font-weight: 600;
  padding: 0.625rem 1rem;
  border-radius: 10px;
  border: 1px solid var(--ed-danger-bg);
  cursor: pointer;
  transition: background-color .15s ease;
}
.ed-btn-danger:hover { background: var(--ed-danger-bg); }

/* ---------------------------------------------------------------------
 * "Analytics Button Colors and Skill Analysis Removal" blueprint —
 * Phase 1. Three action-specific button colors for the row-level
 * analytics links added by the "Clickable Student Analytics Rows"
 * blueprint (§0.12 of the codebase summary) — Plan/Roadmap, Plan
 * Analytics, and Certificate previously all shared the generic
 * .ed-btn-secondary class (white/card-colored background), which
 * made three different destinations visually indistinguishable and
 * used a white background the blueprint explicitly disallows for
 * these three. Same shape/sizing as .ed-btn-primary (solid color,
 * white text, no white background anywhere) — only the color+token
 * differs per action, and the same class is used on both
 * includes/analytics-dashboard-view.php and
 * includes/quiz-history-table-view.php so the same action is always
 * the same color everywhere it appears, desktop and mobile alike.
 * ------------------------------------------------------------------- */
.ed-btn-roadmap,
.ed-btn-plan-analytics,
.ed-btn-certificate {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  color: var(--ed-on-accent);
  font-weight: 600;
  padding: 0.625rem 1rem;
  border-radius: 10px;      /* Phase 2.1: button radius 8-10px, same as every other .ed-btn-* */
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease, box-shadow .15s ease;
}
.ed-btn-roadmap:disabled,
.ed-btn-plan-analytics:disabled,
.ed-btn-certificate:disabled { opacity: .6; cursor: not-allowed; }
/* Phase 1's "visible focus ring" — none of the other .ed-btn-* classes
   define one of their own (they rely on the browser default), but
   these three are new enough, and used densely enough in a table/card
   list, to make it explicit rather than assume the default outline is
   enough against a solid color background. */
.ed-btn-roadmap:focus-visible,
.ed-btn-plan-analytics:focus-visible,
.ed-btn-certificate:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 2px;
}

.ed-btn-roadmap {
  background: var(--ed-primary);
  border-color: var(--ed-primary);
}
.ed-btn-roadmap:hover { background: var(--ed-primary-hover); border-color: var(--ed-primary-hover); }

.ed-btn-plan-analytics {
  background: var(--ed-purple);
  border-color: var(--ed-purple);
}
.ed-btn-plan-analytics:hover { background: var(--ed-purple-hover); border-color: var(--ed-purple-hover); }

.ed-btn-certificate {
  background: var(--ed-success);
  border-color: var(--ed-success);
}
.ed-btn-certificate:hover { background: var(--ed-success-hover); border-color: var(--ed-success-hover); }

.ed-input, .ed-select {
  width: 100%;
  border: 1px solid var(--ed-border);
  border-radius: 9px;       /* Phase 2.1: input radius 8-10px */
  padding: 0.625rem 1rem;
  background: var(--ed-body-bg);
  font-size: 0.875rem;
  color: var(--ed-heading);
  outline: none;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.ed-input:focus, .ed-select:focus {
  border-color: var(--ed-primary);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--ed-primary) 16%, transparent);
  background: var(--ed-card-bg);
}
.ed-input:disabled, .ed-select:disabled { opacity: .6; cursor: not-allowed; }

.ed-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 0.75rem;
  font-weight: 700;
  padding: 0.25rem 0.625rem;
  border-radius: 999px;
  letter-spacing: .01em;
}
.ed-badge-brand    { background: var(--ed-info-bg); color: var(--ed-info); }
.ed-badge-success  { background: var(--ed-success-bg); color: var(--ed-success); }
.ed-badge-warning  { background: var(--ed-warning-bg); color: var(--ed-warning); }
.ed-badge-danger   { background: var(--ed-danger-bg); color: var(--ed-danger); }
.ed-badge-neutral  { background: var(--ed-body-bg); color: var(--ed-muted-text); border: 1px solid var(--ed-border); }

/* "Syllabus Learning Relationships Control Center" blueprint, Parts
   18-20 — direction-coded text for relationship-line targets
   (assets/js/syllabus-learning-relationships.js's own DIRECTION map).
   Backward (review/prerequisite) reuses the warning tone, forward
   (next/challenge) reuses the success tone, lateral (practice) reuses
   the info tone — same three-token palette every other status badge
   in this app already draws from, just applied as text color rather
   than a filled pill here since these sit inline next to a quiz title. */
.syl-lr-dir-back    { color: var(--ed-warning); font-weight: 600; }
.syl-lr-dir-forward { color: var(--ed-success); font-weight: 600; }
.syl-lr-dir-lateral { color: var(--ed-info); font-weight: 600; }

/* Blueprint: "Question-by-Question Quiz Progress Sidebar" (u213_400
   follow-up) — the Learning Path sidebar's expandable per-Question
   tracker for the CURRENT Quiz
   (assets/js/syllabus-learning-runtime.js's
   renderQuizQuestionsTracker()). Every rule below is presentation
   only, driven entirely by the server's own quiz_progress[].status
   (build_syllabus_learning_quiz_progress(),
   private/includes/syllabus-learning-runtime.php) — reuses the SAME
   three-token success/danger/warning/info palette every other status
   surface in this app draws from (see .syl-lr-dir-* just above,
   .ed-badge-* above that), no new colors introduced. Color is never
   the only signal for the current row: it also gets a distinct icon
   (●) and an explicit "Current" text tag, so this remains legible
   under a color-vision deficiency or in print/grayscale. */
.syl-q-progress-toggle {
  display: flex; align-items: center; gap: 0.3rem; width: 100%;
  text-align: left; font-size: 0.75rem; font-weight: 600;
  color: var(--ed-body-text); padding: 0.125rem 0; background: none; border: 0;
}
.syl-q-progress-toggle:hover { color: var(--ed-primary); }
.syl-q-progress-summary {
  font-size: 0.6875rem; color: var(--ed-muted-text); margin: 0.125rem 0 0.375rem;
}
.syl-q-progress-bar-track {
  height: 6px; border-radius: 999px; background: var(--ed-body-bg);
  border: 1px solid var(--ed-border); overflow: hidden; margin-bottom: 0.5rem;
}
.syl-q-progress-bar-fill {
  height: 100%; background: var(--ed-primary); border-radius: 999px;
  transition: width 150ms ease;
}
.syl-q-progress-list {
  max-height: 220px; overflow-y: auto; display: flex; flex-direction: column;
  gap: 2px; padding-right: 2px;
}
.syl-q-progress-row {
  display: flex; align-items: center; gap: 0.375rem;
  font-size: 0.6875rem; line-height: 1.2; border-radius: 6px;
  padding: 0.25rem 0.375rem; border: 1px solid transparent;
  color: var(--ed-body-text);
}
.syl-q-progress-icon   { flex-shrink: 0; width: 1rem; text-align: center; font-weight: 700; }
.syl-q-progress-label  { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.syl-q-progress-current-tag {
  flex-shrink: 0; font-size: 0.625rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .02em; color: var(--ed-on-accent); background: var(--ed-primary);
  border-radius: 999px; padding: 0.0625rem 0.375rem;
}
.syl-q-progress-correct    { background: var(--ed-success-bg); border-color: var(--ed-success); color: var(--ed-success); }
.syl-q-progress-incorrect  { background: var(--ed-danger-bg);  border-color: var(--ed-danger);  color: var(--ed-danger); }
.syl-q-progress-current    { background: var(--ed-info-bg);    border-color: var(--ed-primary); color: var(--ed-primary); font-weight: 700; }
.syl-q-progress-unanswered { background: transparent;          border-color: var(--ed-border);  color: var(--ed-muted-text); }
/* A blank/empty submitted answer (build_syllabus_learning_quiz_
   progress()'s 'skipped' status — grade_single_syllabus_learning_
   question()'s pre-existing is_skipped flag, previously collapsed into
   'incorrect' for display only). Amber, distinct from red, per the
   blueprint's own status table. */
.syl-q-progress-skipped    { background: var(--ed-warning-bg); border-color: var(--ed-warning); color: var(--ed-warning); }
.syl-q-progress-quiz-complete-badge {
  display: inline-flex; align-items: center; gap: 0.1875rem; font-size: 0.6875rem;
  font-weight: 700; color: var(--ed-success);
}

/* "Analytics TailAdmin Visual Update" pass — icon-chip KPI card +
 * trend badge, extended site-wide to any stat-card row that wants it
 * (see student/dashboard.php, teacher/dashboard.php,
 * includes/analytics-overview-view.php). */
.ed-kpi-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3rem;
  height: 3rem;
  border-radius: 12px;
  background: var(--ed-body-bg);
  color: var(--ed-primary);
  font-size: 1.05rem;
}
.ed-change-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0.55rem;
  border-radius: 9999px;
  font-size: 0.75rem;
  font-weight: 600;
}
.ed-change-up   { background: var(--ed-success-bg); color: var(--ed-success); }
.ed-change-down { background: var(--ed-danger-bg);  color: var(--ed-danger); }

/* Phase 7.5 — empty states */
.ed-empty-state {
  text-align: center;
  padding: 2.5rem 1.5rem;
  color: var(--ed-muted-text);
}
.ed-empty-state .ed-empty-icon {
  width: 48px; height: 48px; margin: 0 auto 0.75rem;
  border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  background: var(--ed-body-bg);
  color: var(--ed-muted-text);
  font-size: 1.25rem;
}
.ed-empty-state h4 { font-size: 0.9375rem; font-weight: 700; color: var(--ed-heading); margin-bottom: 0.25rem; }
.ed-empty-state p { font-size: 0.8125rem; max-width: 26rem; margin: 0 auto 1rem; }

/* Phase 7.3 — directory tables */
.ed-table { width: 100%; border-collapse: collapse; font-size: 0.875rem; }
.ed-table thead th {
  text-align: left;
  font-size: 0.6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--ed-muted-text);
  background: var(--ed-body-bg);
  padding: 0.625rem 1rem;
  border-bottom: 1px solid var(--ed-border);
}
.ed-table thead th:first-child { border-top-left-radius: 10px; }
.ed-table thead th:last-child { border-top-right-radius: 10px; }
.ed-table tbody td {
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--ed-border);
  color: var(--ed-body-text);
  vertical-align: middle;
}
.ed-table tbody tr:last-child td { border-bottom: none; }
.ed-table tbody tr:hover td { background: var(--ed-body-bg); }

/* Journey TailAdmin-Table Visual Update — card wrapper + header bar for
   a table grouped under a date-section heading (e.g. "This Week"),
   built on the existing .ed-table above rather than a new table style.
   Zero-padding card (unlike the default .ed-card) since the header bar
   and table supply their own padding, edge to edge. */
.ed-table-card { background: var(--ed-card-bg); border: 1px solid var(--ed-border); border-radius: 16px; overflow: hidden; }
.ed-table-card-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem; padding: 1rem 1.25rem; border-bottom: 1px solid var(--ed-border);
}

/* Phase 6.1 — metric/stat card */
.ed-stat-card { display: flex; align-items: center; gap: 1rem; }
.ed-avatar {
  width: 2.25rem; height: 2.25rem; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 0.75rem;
  background: var(--ed-sidebar-active); color: var(--ed-primary);
  flex-shrink: 0;
}

.thread-list::-webkit-scrollbar,
.message-pane::-webkit-scrollbar {
  width: 8px;
}
.thread-list::-webkit-scrollbar-thumb,
.message-pane::-webkit-scrollbar-thumb {
  background: var(--ed-border);
  border-radius: 999px;
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  letter-spacing: .01em;
}
.badge-unread   { background: var(--ed-info-bg); color: var(--ed-info); }
.badge-urgent   { background: var(--ed-danger-bg); color: var(--ed-danger); }
.badge-parent   { background: var(--ed-success-bg); color: var(--ed-success); }
.badge-student  { background: var(--ed-info-bg); color: var(--ed-primary); }
.badge-resolved { background: var(--ed-body-bg); color: var(--ed-muted-text); }
.badge-lowscore { background: var(--ed-danger-bg); color: var(--ed-danger); }

.bubble-mine {
  background: var(--ed-primary);
  color: var(--ed-on-accent);
  border-radius: 16px 16px 4px 16px;
}
.bubble-theirs {
  background: var(--ed-card-bg);
  border: 1px solid var(--ed-border);
  border-radius: 16px 16px 16px 4px;
  color: var(--ed-body-text);
}
.bubble-system {
  background: var(--ed-warning-bg);
  border: 1px solid var(--ed-border);
  color: var(--ed-warning);
  border-radius: 10px;
}

.thread-row.active {
  background: var(--ed-sidebar-active);
  border-left: 3px solid var(--ed-primary);
}

/* Phase 2/3: Print Conversation — everything else on the page is hidden
   while printing; only #print-area (populated just-in-time by JS with
   the current conversation) is shown. */
@media print {
  body * { visibility: hidden; }
  #print-area, #print-area * { visibility: visible; }
  #print-area {
    display: block !important;
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    padding: 20px;
  }
}

/* "EduLink Blueprint: Learning Insights Reports System" — Phase 20
   "Print and Report Formatting". Its own rule rather than reusing
   #print-area above (that mechanism needs JS to copy content into a
   hidden div first) — the report page's real DOM is already exactly
   what should print, it just needs the sidebar/nav/header and every
   interactive control hidden. Scoped to #li-report-print-root so it
   only ever applies on the two Learning Insights report pages. */
@media print {
  #li-report-print-root, #li-report-print-root * { visibility: visible; }
  #li-report-print-root {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    padding: 0;
  }
  .li-report-hide-print,
  .li-report-controls { display: none !important; }
  /* The "Show Details" toggle is a screen-only affordance (Phase 6
     "collapsed by default") — print always shows the full breakdown
     regardless of whether it was expanded on screen (Phase 20 "Show:
     ... All major report sections"). */
  #li-report-print-root #li-sec-details.hidden { display: block !important; }
}

/* ═══════════════════════════════════════════════════════════════════
   Three-Step Plan Creation Blueprint — Phase 13 "Styling". Reuses the
   existing semantic tokens (--ed-primary, --ed-success, --ed-muted-text,
   --ed-border, --ed-card-bg) rather than introducing new colors — every
   state below is light/dark-mode-aware automatically the same way
   .ed-card/.ed-btn-primary already are (§7 of the codebase summary).
   ═══════════════════════════════════════════════════════════════════ */

.plan-progress-nav .plan-step-connector {
  position: relative;
}
.plan-progress-nav .plan-step-connector::after {
  content: '';
  position: absolute;
  top: 18px; /* vertical center of the 36px step circle */
  left: calc(50% + 28px);
  right: calc(-50% + 28px);
  height: 2px;
  background: var(--ed-border);
}

.plan-step-circle {
  border: 2px solid var(--ed-border);
  color: var(--ed-muted-text);
  background: var(--ed-card-bg);
}
.plan-step-desc { color: var(--ed-muted-text); }
.plan-step-state-label { color: var(--ed-muted-text); }

/* Complete: filled success, checkmark, connector segment after it turns solid. */
.plan-step-complete .plan-step-circle {
  background: var(--ed-success);
  border-color: var(--ed-success);
  color: var(--ed-on-accent);
}
.plan-step-complete .plan-step-state-label { color: var(--ed-success); }
a.plan-step-complete:hover .plan-step-desc,
a.plan-step-complete:focus-visible .plan-step-desc { color: var(--ed-body-text); }

/* Current: strong primary treatment — the strongest visual element among the three steps. */
.plan-step-current .plan-step-circle {
  background: var(--ed-primary);
  border-color: var(--ed-primary);
  color: var(--ed-on-accent);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--ed-primary) 18%, transparent);
}
.plan-step-current .plan-step-state-label { color: var(--ed-primary); }

/* In progress: highlighted but not as strong as "current" — a distinct third visual state, not a re-skin of complete or current. */
.plan-step-in-progress .plan-step-circle {
  background: var(--ed-warning-bg);
  border-color: var(--ed-warning);
  color: var(--ed-warning);
}
.plan-step-in-progress .plan-step-state-label { color: var(--ed-warning); }

/* Locked/not-started: muted, never styled to look clickable (it isn't — rendered as <span>, not <a>). */
.plan-step-locked { opacity: 0.55; cursor: default; }
.plan-step-locked .plan-step-circle { background: var(--ed-card-bg); }

a.plan-step-complete,
a.plan-step-current,
a.plan-step-in-progress {
  border-radius: 10px;
  padding: 2px;
  margin: -2px;
  transition: background-color 150ms ease;
}
a.plan-step-complete:hover,
a.plan-step-current:hover,
a.plan-step-in-progress:hover {
  background: var(--ed-body-bg);
}
a.plan-step-complete:focus-visible,
a.plan-step-current:focus-visible,
a.plan-step-in-progress:focus-visible {
  outline: 2px solid var(--ed-primary);
  outline-offset: 2px;
}

/* Mobile vertical list: same state classes, no connector line needed. */
.plan-step-mobile .plan-step-circle { width: 1.75rem; height: 1.75rem; }

/* ═══════════════════════════════════════════════════════════════════
   Plans Page Visual Refresh Blueprint — Phase 1 "Design tokens".
   Student-only (student/plans.php + includes/plan-directory-result-view.php's
   student branch) — reuses existing --ed-* custom properties, no new
   color system. The blueprint's Phase 4b referenced a --ed-border-strong
   token that doesn't exist anywhere else in this file; the draft-card
   border below uses the existing --ed-border instead.
   ═══════════════════════════════════════════════════════════════════ */

.ed-stat-pill {
  background: var(--ed-card-bg);
  border: 1px solid var(--ed-border);
  border-radius: 10px;
  padding: 0.75rem 1rem;
  flex: 1;
  min-width: 110px;
}
.ed-stat-pill .value { font-size: 22px; font-weight: 600; margin: 0; line-height: 1.2; }
.ed-stat-pill .label { font-size: 12px; color: var(--ed-muted-text); margin: 0 0 4px; }

.ed-stepper-track { flex: 1; height: 1px; background: var(--ed-border); margin: 0 12px; min-width: 24px; }
.ed-stepper-track.done { background: var(--ed-primary); }

/* ═══════════════════════════════════════════════════════════════════
   Plans Directory Flex-Reflow, Row-Action Sizing & Stepper Redesign
   Blueprint — Phase 4a. Redesigned "Create a Learning Plan" stepper
   card (student/plans.php only). Reuses existing --ed-* tokens only.
   ═══════════════════════════════════════════════════════════════════ */
.ed-create-plan-steps { display: flex; align-items: stretch; gap: 0; }
.ed-create-plan-step { flex: 1 1 0; display: flex; flex-direction: column; gap: 0.6rem; min-width: 150px; }
.ed-create-plan-step-top { display: flex; align-items: center; gap: 0; }
.ed-create-plan-step-circle {
  width: 2.5rem; height: 2.5rem; border-radius: 9999px;
  display: flex; align-items: center; justify-content: center;
  font-size: 1rem; font-weight: 700; flex-shrink: 0;
  border: 2px solid var(--ed-border);
  background: var(--ed-card-bg);
  color: var(--ed-muted-text);
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}
.ed-create-plan-step.is-done .ed-create-plan-step-circle { background: var(--ed-primary); border-color: var(--ed-primary); color: var(--ed-on-accent); }
.ed-create-plan-step.is-current .ed-create-plan-step-circle { border-color: var(--ed-primary); color: var(--ed-primary); background: color-mix(in srgb, var(--ed-primary) 10%, var(--ed-card-bg)); }
.ed-create-plan-step-line { flex: 1 1 auto; height: 2px; background: var(--ed-border); margin: 0 4px; min-width: 16px; }
.ed-create-plan-step.is-done .ed-create-plan-step-line { background: var(--ed-primary); }
.ed-create-plan-step-eyebrow { font-size: 0.6875rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ed-muted-text); }
.ed-create-plan-step.is-current .ed-create-plan-step-eyebrow { color: var(--ed-primary); }
.ed-create-plan-step-title { font-size: 0.9375rem; font-weight: 700; color: var(--ed-heading); line-height: 1.3; }
.ed-create-plan-step-desc { font-size: 0.8125rem; color: var(--ed-muted-text); line-height: 1.4; }
@media (max-width: 700px) {
  .ed-create-plan-steps { flex-direction: column; gap: 1.1rem; }
  .ed-create-plan-step { flex-direction: row; align-items: center; gap: 0.9rem; }
  .ed-create-plan-step-top { flex-direction: column; }
  .ed-create-plan-step-line { display: none; }
}

.ed-progress-track { height: 6px; background: var(--ed-body-bg); border-radius: 20px; overflow: hidden; }
.ed-progress-fill  { height: 100%; border-radius: 20px; background: var(--ed-success); transition: width 200ms ease; }

/* Phase 4 card variants. */
.ed-plan-card-active { border-left: 3px solid var(--ed-success); }
.ed-plan-card-draft  { border: 1px dashed var(--ed-border); }
.ed-plan-icon-chip {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: var(--ed-info-bg);
  color: var(--ed-primary);
}
.ed-plan-icon-chip.muted { background: var(--ed-body-bg); color: var(--ed-muted-text); }

/* ═══════════════════════════════════════════════════════════════════
   Plans Directory Flex-Reflow Blueprint — Phase 1. Renamed from
   .ed-table* to .ed-plan-table* (see §0 — the old name collided with
   the pre-existing Phase 7.3 directory-table class). Rows/cells are
   flex boxes instead of native table layout, so as the viewport
   narrows, cells wrap onto new lines and their own text wraps onto
   more lines, instead of clipping or forcing horizontal scroll.
   ═══════════════════════════════════════════════════════════════════ */
.ed-plan-table-card { overflow: hidden; }
.ed-plan-table-wrap { overflow-x: visible; }
.ed-plan-table, .ed-plan-table thead, .ed-plan-table tbody { display: block; width: 100%; }
.ed-plan-table { font-size: 0.875rem; }
.ed-plan-table tr { display: flex; flex-wrap: wrap; align-items: flex-start; width: 100%; }
.ed-plan-table thead tr { background: var(--ed-body-bg); border-bottom: 1px solid var(--ed-border); }
.ed-plan-table th {
  flex: 1 1 150px;
  min-width: 110px;
  text-align: left;
  padding: 0.75rem 1.25rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ed-muted-text);
}
.ed-plan-table tbody tr { border-bottom: 1px solid var(--ed-border); }
.ed-plan-table tbody tr:last-child { border-bottom: none; }
.ed-plan-table tbody tr:hover { background: var(--ed-body-bg); }
.ed-plan-table td {
  flex: 1 1 150px;
  min-width: 110px;
  padding: 1rem 1.25rem;
  vertical-align: middle;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.ed-plan-table th:nth-child(1), .ed-plan-table td:nth-child(1) { flex: 2.2 1 240px; } /* Plan */
.ed-plan-table th:nth-child(2), .ed-plan-table td:nth-child(2) { flex: 1.6 1 200px; } /* Progress */
.ed-plan-table th:nth-child(3), .ed-plan-table td:nth-child(3) { flex: 0.7 1 130px; white-space: nowrap; } /* Created At — "Simplify Plans Tables" Phase 15: compact, nowrap */
.ed-plan-table th:last-child, .ed-plan-table td:last-child { flex: 1.6 1 240px; }     /* Actions */

.ed-plan-table td::before {
  content: attr(data-label);
  display: none;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ed-muted-text);
  margin-bottom: 0.25rem;
}
@media (max-width: 700px) {
  .ed-plan-table thead { display: none; }
  .ed-plan-table td { flex: 1 1 100%; }
  .ed-plan-table td::before { display: block; }
}

/* ---- Row actions. "Simplify Plans Tables for Teachers and Students"
   blueprint — Phase 15: action labels are now longer and more varied
   ("Build Learning Roadmap", "Review Student Progress") than the old
   fixed 9.25rem/ellipsis sizing (tuned for short labels like "Open
   Plan") could show without clipping — min-width keeps rows visually
   aligned without truncating text; wrapping is allowed if a label
   still doesn't fit. ---- */
.ed-plan-table-actions { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.ed-action-btn-primary { min-width: 9.25rem; justify-content: center; text-align: center; white-space: normal; line-height: 1.25; }
/* Phase 12: message button is now icon + visible text (was icon-only
   with title/aria-label as the only text) — auto width instead of a
   fixed square, but keeps the same unread-count dot positioning. */
.ed-action-btn-message { display: inline-flex; align-items: center; gap: 0.4rem; position: relative; white-space: nowrap; }
.ed-action-btn-message .ed-unread-dot {
  position: absolute; top: -6px; right: -6px;
  min-width: 16px; height: 16px; padding: 0 3px; border-radius: 999px;
  background: var(--ed-danger); color: var(--ed-on-accent);
  font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
}
/* Retained for any other/future icon-only square action button. */
.ed-action-btn-icon { position: relative; width: 2.375rem; height: 2.375rem; padding: 0; flex-shrink: 0; }
.ed-action-btn-icon .ed-unread-dot {
  position: absolute; top: -4px; right: -4px;
  min-width: 16px; height: 16px; padding: 0 3px; border-radius: 999px;
  background: var(--ed-danger); color: var(--ed-on-accent);
  font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
}

/* Plans Directory TailAdmin-Table Blueprint — Phase 3 (optional).
   Icon slot for .ed-stat-pill, matching the reference mockup's
   metric-card pattern. .ed-stat-pill's own layout rules are unchanged
   (assets/css/app.css, Plans Page Visual Refresh Phase 1) — this only
   adds the icon box and switches the pill to a column layout so the
   icon sits above the label/value. */
.ed-stat-pill { display: flex; flex-direction: column; gap: 0.5rem; }
.ed-stat-pill-icon {
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 0.625rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ed-body-bg);
  color: var(--ed-primary);
  font-size: 1.05rem;
}

/* ---------------------------------------------------------------------
 * "Roadmap Steps TailAdmin Data Table" pass — the same TailAdmin
 * "Data Tables" pattern (https://demo.tailadmin.com/data-tables) used
 * by student/plan-roadmap.php's Roadmap Steps section. Deliberately a
 * distinct, richer class family from .ed-table/.ed-table-card (Plans
 * Directory pass) rather than extending those — this one adds a
 * search/entries toolbar, sortable-look column headers, and an
 * expandable per-row detail row, none of which the simpler .ed-table*
 * pattern has. Colors are var(--ed-primary)/var(--ed-primary-hover) —
 * the template this was built from used its own separate --ta-brand
 * variable, but that value (#465FFF) is identical to this app's
 * existing --ed-primary post-re-theme, so no new token was introduced.
 * Status/skill badges reuse the existing .ed-badge* classes and
 * render_badge() rather than a parallel .ta-badge* family.
 * ------------------------------------------------------------------- */
.ta-card { border-radius: 1rem; border: 1px solid var(--ed-border); background: var(--ed-card-bg); overflow: hidden; }
.ta-card-header { padding: 1.25rem 1.5rem; display: flex; align-items: center; justify-content: space-between; gap: .75rem; flex-wrap: wrap; border-bottom: 1px solid var(--ed-border); }
.ta-card-title { font-size: 1rem; font-weight: 600; color: var(--ed-heading); }

.ta-dt-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; padding: 1rem 1.5rem; }
.ta-dt-toolbar-left { display: flex; align-items: center; gap: .5rem; font-size: .875rem; color: var(--ed-muted-text); }
.ta-dt-entries-select {
  height: 2.25rem; border-radius: .5rem; border: 1px solid var(--ed-border); background: var(--ed-card-bg);
  color: var(--ed-heading); padding: 0 .6rem; font-size: .8125rem; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236B665C' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right .5rem center; padding-right: 1.75rem;
}
.ta-dt-search-wrap { position: relative; }
.ta-dt-search { height: 2.25rem; border-radius: .5rem; border: 1px solid var(--ed-border); background: var(--ed-card-bg); color: var(--ed-heading); padding: 0 .75rem 0 2.25rem; font-size: .8125rem; min-width: 200px; }
.ta-dt-search::placeholder { color: var(--ed-muted-text); }
.ta-dt-search:focus { outline: 2px solid var(--ed-primary); outline-offset: 1px; border-color: var(--ed-primary); }
.ta-dt-search-icon { position: absolute; left: .7rem; top: 50%; transform: translateY(-50%); color: var(--ed-muted-text); font-size: .8rem; pointer-events: none; }

.ta-table-wrap { overflow-x: auto; }
.ta-table { width: 100%; min-width: 720px; table-layout: fixed; border-collapse: collapse; }
.ta-table thead { background: var(--ed-body-bg); border-bottom: 1px solid var(--ed-border); }
.ta-table thead th { padding: .75rem 1rem; text-align: left; font-size: .75rem; font-weight: 600; letter-spacing: .03em; text-transform: uppercase; color: var(--ed-muted-text); white-space: normal; overflow-wrap: break-word; vertical-align: bottom; }
/* Sort icons are decorative only on this table — roadmap steps stay in
   roadmap sequence and are never client-sortable (same principle as
   includes/analytics-roadmap-comprehension-view.php's "steps stay in
   roadmap order" rule) — cursor stays default, no click handler. */
.ta-table th.ta-sortable { cursor: default; user-select: none; }
.ta-th-flex { display: flex; align-items: center; gap: .4rem; }
.ta-sort-icons { display: inline-flex; flex-direction: column; gap: 1px; line-height: 0; }
.ta-sort-icons i { font-size: 8px; color: var(--ed-border); }
.ta-sort-icons i.ta-sort-active { color: var(--ed-primary); }
/* "EduLink Roadmap Table and Messaging Fix" blueprint — Phase 2/4/15.
 * Was 6 columns (Step/Unit/Duration/Mastery Target/Status/Actions);
 * Duration, Mastery Target, and Status are no longer shown as
 * standalone columns (their underlying data/behavior is unchanged —
 * see student/plan-roadmap.php and teacher/plan-view.php's docblocks
 * for exactly where each one still lives). New 4-column layout: Step /
 * Unit / Actions / Advanced Features, the last of which is
 * mode-responsive rather than always-visible. Shared by both roles'
 * roadmap tables (`.ta-table`) — no separate CSS system introduced.
 *
 * "Responsive Homework Tables for Students and Teachers" blueprint —
 * Phase 1. These fixed 9%/58%/33% column proportions only ever made
 * sense for the roadmap tables' 3 visible columns (Step/Unit/Actions).
 * They are now scoped to `.ta-roadmap-table` (added alongside `.ta-table`
 * on student/plan-roadmap.php and teacher/plan-view.php only) instead
 * of every `.ta-table`, so they no longer leak into the 6- and
 * 7-column Homework tables, which use the separate `.homework-table`
 * system below instead. */
.ta-roadmap-table th:nth-child(1), .ta-roadmap-table td:nth-child(1) { width: 9%; }  /* Step */
.ta-roadmap-table th:nth-child(2), .ta-roadmap-table td:nth-child(2) { width: 58%; } /* Unit */
.ta-roadmap-table th:nth-child(3), .ta-roadmap-table td:nth-child(3) { width: 33%; } /* Actions */
.ta-roadmap-table th.ta-col-advanced, .ta-roadmap-table td.ta-col-advanced {
  width: 0; padding: 0; border: none; overflow: hidden; opacity: 0;
  transition: width .15s ease, opacity .1s ease;
}
/* Advanced mode: Advanced Features column takes real width, the other
 * three shrink to make room (percentages are the blueprint's own
 * "starting points, not hard requirements"). */
.ta-roadmap-table.is-advanced-mode th:nth-child(1), .ta-roadmap-table.is-advanced-mode td:nth-child(1) { width: 8%; }
.ta-roadmap-table.is-advanced-mode th:nth-child(2), .ta-roadmap-table.is-advanced-mode td:nth-child(2) { width: 38%; }
.ta-roadmap-table.is-advanced-mode th:nth-child(3), .ta-roadmap-table.is-advanced-mode td:nth-child(3) { width: 25%; }
.ta-roadmap-table.is-advanced-mode th.ta-col-advanced, .ta-roadmap-table.is-advanced-mode td.ta-col-advanced {
  width: 29%; padding: .9rem 1rem; opacity: 1; overflow: visible;
  /* "Advanced Features Column Background" blueprint — Option 1
     (terracotta tint) chosen from the color-options mockup. Applies to
     both the header and body cells so the whole column reads as one
     shaded zone, matching the mockup's .opt1 .adv-col treatment.
     Token is theme-aware (see :root / html.dark above), so this stays
     correct in dark mode with no separate dark: rule needed here. */
  background: var(--ed-advanced-col-bg);
}
/* Basic mode: header text itself is hidden (not just narrowed) so an
 * empty "Advanced Features" label never sits over a collapsed column. */
.ta-roadmap-table:not(.is-advanced-mode) .advanced-features-header,
.ta-roadmap-table:not(.is-advanced-mode) .advanced-features-cell { display: none; }
.ta-table tbody tr.ta-row { border-bottom: 1px solid var(--ed-border); }
.ta-table tbody tr.ta-row:hover { background: var(--ed-body-bg); }
.ta-table tbody tr:last-child { border-bottom: none; }
.ta-table tbody td { padding: .9rem 1rem; font-size: .875rem; color: var(--ed-body-text); vertical-align: top; overflow-wrap: break-word; word-break: break-word; }
.ta-cell-primary { color: var(--ed-heading); font-weight: 600; font-size: .875rem; }
.ta-cell-sub { color: var(--ed-muted-text); font-size: .8125rem; margin-top: .15rem; }

.ta-btn-primary { display: inline-flex; align-items: center; justify-content: center; gap: .4rem; background: var(--ed-primary); color: var(--ed-on-accent); font-weight: 500; font-size: .8125rem; padding: .45rem .9rem; border-radius: .5rem; border: none; cursor: pointer; transition: background .15s ease; }
.ta-btn-primary:hover { background: var(--ed-primary-hover); }
.ta-btn-primary:disabled { opacity: .5; cursor: not-allowed; }
.ta-btn-outline { display: inline-flex; align-items: center; justify-content: center; gap: .4rem; background: var(--ed-card-bg); color: var(--ed-body-text); font-weight: 500; font-size: .8125rem; padding: .45rem .9rem; border-radius: .5rem; border: 1px solid var(--ed-border); cursor: pointer; transition: background .15s ease; }
.ta-btn-outline:hover { background: var(--ed-body-bg); }

/* ---------------------------------------------------------------------
 * Responsive Homework tables ("Responsive Homework Tables for Students
 * and Teachers" blueprint).
 *
 * Homework tables (public/student/homework.php, public/teacher/homework.php)
 * share `.ta-table` for common visual styling (borders, header, hover,
 * badge spacing) but get their own layout system here instead of the
 * roadmap tables' fixed-percentage `.ta-roadmap-table` rules above —
 * Homework has 6 (student) / 7 (teacher) columns, a different content
 * shape entirely from the roadmap's 3-4 column layout.
 * ------------------------------------------------------------------- */

/* Phase 2 — content-based sizing instead of table-layout: fixed. */
.homework-table {
  table-layout: auto;
  width: 100%;
  min-width: 0;
}

/* Phase 6 — natural word wrapping. Overrides .ta-table tbody td's
   word-break: break-word (which can chop a word mid-letter) with a
   normal wrap-at-spaces-first approach, falling back to
   overflow-wrap: anywhere only for a single unbroken token (e.g. a
   long username) that has no natural break point. */
.homework-table th,
.homework-table td {
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: normal;
  hyphens: auto;
}
/* Compact values that should stay on one line whenever possible. */
.homework-table .homework-col-score,
.homework-table .homework-col-assigned-date {
  white-space: nowrap;
}

/* "Teacher and Student Homework Pagination, Basic/Advanced Search,
   Sorting, and Row Numbers" blueprint — Section 14. Shared by both
   student and teacher tables (unlike the width:1% columns below,
   which are declared separately per role) since the `#` column is now
   identical either way. */
.homework-table .homework-col-number {
  width: 3.5rem;
  text-align: center;
  white-space: nowrap;
}

/* Phase 3 — student column guidance. Quiz/Plan get the most flexible
   space; Assigned By wraps instead of forcing the table wider; Status/
   Score/Actions stay compact-to-fixed. */
.homework-table-student .homework-col-quiz { min-width: 11rem; }
.homework-table-student .homework-col-plan { min-width: 9rem; }
.homework-table-student .homework-col-assigned-by { min-width: 7rem; }
.homework-table-student .homework-col-status { width: 1%; white-space: nowrap; }
.homework-table-student .homework-col-score { width: 1%; white-space: nowrap; }
.homework-table-student .homework-col-actions { min-width: 11rem; }

/* Phase 4 — teacher column guidance. Same idea, with a wider Actions
   minimum since the teacher row can show up to four buttons (Open
   Plan / Preview Quiz / View Results / Remove) instead of three. */
.homework-table-teacher .homework-col-student { min-width: 8rem; }
.homework-table-teacher .homework-col-quiz { min-width: 12rem; }
.homework-table-teacher .homework-col-plan { min-width: 9rem; }
.homework-table-teacher .homework-col-assigned-date,
.homework-table-teacher .homework-col-status,
.homework-table-teacher .homework-col-score { width: 1%; }
.homework-table-teacher .homework-col-actions { min-width: 13rem; }

/* Phase 5 — Actions column + buttons. */
.homework-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 0.5rem;
  min-width: 0;
}
.homework-actions .ed-btn-primary,
.homework-actions .ed-btn-secondary {
  width: auto;
  max-width: 100%;
  min-width: max-content;
  white-space: normal;
  overflow-wrap: normal;
  word-break: normal;
  text-align: center;
  line-height: 1.25;
  min-height: 2.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Phase 9 — responsive filter bar (status tabs / student select /
   search / Search button) above each Homework table. */
@media (max-width: 640px) {
  .homework-filter-form { align-items: stretch; }
  .homework-filter-controls {
    width: 100%;
    display: grid;
    grid-template-columns: 1fr;
  }
  .homework-filter-controls .ed-input,
  .homework-filter-controls select,
  .homework-filter-controls .ed-btn-secondary {
    width: 100%;
  }
}

/* Phase 7/8 — mobile stacked rows (~767px and below). Each <tr> becomes
   a bordered card; each <td> becomes a label/value row using
   data-label; Actions becomes a responsive button grid. */
@media (max-width: 767px) {
  .homework-table-wrap {
    overflow-x: visible;
  }
  .homework-table {
    display: block;
    min-width: 0;
  }
  .homework-table thead {
    display: none;
  }
  .homework-table tbody {
    display: grid;
    gap: 1rem;
  }
  .homework-table tbody tr {
    display: block;
    border: 1px solid var(--ed-border);
    border-radius: 0.875rem;
    background: var(--ed-card-bg);
    overflow: hidden;
  }
  .homework-table tbody td {
    display: grid;
    grid-template-columns: minmax(6.5rem, 35%) minmax(0, 1fr);
    gap: 0.75rem;
    width: 100%;
    min-width: 0;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--ed-border);
  }
  .homework-table tbody td::before {
    content: attr(data-label);
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--ed-muted-text);
    text-transform: uppercase;
    letter-spacing: 0.03em;
  }
  .homework-table tbody td:last-child {
    border-bottom: 0;
  }

  /* Phase 8 — Actions cell spans the full card width with its label
     stacked above a responsive button grid, rather than the two-column
     label/value grid every other cell uses. */
  .homework-table td.homework-col-actions {
    display: block;
  }
  .homework-table td.homework-col-actions::before {
    display: block;
    margin-bottom: 0.625rem;
  }
  .homework-actions {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.5rem;
  }
  .homework-actions .ed-btn-primary,
  .homework-actions .ed-btn-secondary {
    width: 100%;
    min-width: 0;
  }
}

/* Very small screens — one action button per row instead of two. */
@media (max-width: 420px) {
  .homework-actions {
    grid-template-columns: 1fr;
  }
}

/* "Remove Homework Rows Immediately Without Refreshing" blueprint —
 * Phase 13 (optional). Brief, non-blocking fade/collapse applied by
 * homework-actions.js right before a successfully-removed row is
 * taken out of the DOM. The row is only ever removed AFTER the server
 * confirms success (never optimistically), so this is purely a visual
 * polish on top of already-correct data, not a substitute for it. */
.homework-row-removing {
  opacity: 0;
  transform: translateY(-0.25rem);
  transition: opacity 160ms ease, transform 160ms ease;
}
@media (prefers-reduced-motion: reduce) {
  .homework-row-removing {
    transition: none;
  }
}

.ta-detail-row td { background: var(--ed-body-bg); padding: 1.25rem 1.5rem !important; }

/* "Unit Edit Form Background" — the per-unit editor (Unit Title,
 * Description, Estimated Hours, Mastery Target, Skills / Topics,
 * Learning Notes), shown inside .ta-detail-row when "Edit Roadmap" is
 * toggled on. Uses the same --ed-advanced-col-bg tint as the Advanced
 * Features column above it (Option 1 from the color-options mockup) so
 * the two "advanced-only" surfaces read as one consistent zone rather
 * than two different shades. Shared by both live roadmap tables —
 * .unit-edit-form appears identically in student/plan-roadmap.php and
 * teacher/plan-view.php, so this one rule covers both.
 */
.unit-edit-form { background: var(--ed-advanced-col-bg); border-radius: .75rem; padding: 1rem 1.1rem; }


.ta-dt-footer { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; padding: 1rem 1.5rem; border-top: 1px solid var(--ed-border); }
.ta-dt-footer-text { font-size: .8125rem; color: var(--ed-muted-text); }
.ta-dt-pagination { display: flex; align-items: center; gap: .375rem; }
.ta-dt-page-btn { min-width: 2rem; height: 2rem; display: inline-flex; align-items: center; justify-content: center; border-radius: .4rem; font-size: .8125rem; font-weight: 500; border: 1px solid transparent; color: var(--ed-body-text); background: transparent; cursor: pointer; padding: 0 .5rem; }
.ta-dt-page-btn:hover { background: var(--ed-body-bg); }
.ta-dt-page-btn.ta-active { background: var(--ed-primary); color: var(--ed-on-accent); }
.ta-dt-page-btn:disabled { color: var(--ed-muted-text); opacity: .5; cursor: not-allowed; }

.ed-row-details-summary { list-style: none; }
.ed-row-details-summary::-webkit-details-marker { display: none; }
.ed-row-details-summary:hover { text-decoration: underline; }

/* ---------------------------------------------------------------------
 * "Claude.ai Visual System" pass — global fallback for plain, unclassed
 * tables and lists. Many admin pages render a bare <table class="w-full
 * text-sm"> (already using semantic tokens like text-muted/border-ed-
 * border/bg-app-body per-cell, just without the richer .ta-table/
 * .ed-table treatment) rather than one of the named table components
 * above. Scoped with :not(.ta-table, .ed-table, .ed-plan-table) and
 * kept to low-specificity element selectors so it only fills gaps —
 * any page's own utility classes (padding, borders, etc.) still win —
 * and existing designed tables are completely unaffected. */
table:not(.ta-table):not(.ed-table):not(.ed-plan-table) {
  border-collapse: collapse;
}
table:not(.ta-table):not(.ed-table):not(.ed-plan-table) thead tr {
  background: var(--ed-body-bg);
}
table:not(.ta-table):not(.ed-table):not(.ed-plan-table) th {
  color: var(--ed-muted-text);
  font-weight: 600;
  text-align: left;
}
table:not(.ta-table):not(.ed-table):not(.ed-plan-table) th,
table:not(.ta-table):not(.ed-table):not(.ed-plan-table) td {
  padding: 0.625rem 0.75rem;
}
table:not(.ta-table):not(.ed-table):not(.ed-plan-table) tbody tr:hover {
  background: var(--ed-body-bg);
}

/* Bulleted/numbered content lists (About/Terms/Privacy-style prose,
 * plus any dashboard list using Tailwind's list-disc/list-decimal)
 * get a branded marker instead of the browser default, so a list
 * reads as clearly "on-brand" as a card or button does. Doesn't touch
 * <ul>/<ol> used as pure layout scaffolding (nav menus, card grids)
 * since those never carry list-disc/list-decimal in this codebase. */
.list-disc > li::marker,
.list-decimal > li::marker {
  color: var(--ed-primary);
  font-weight: 600;
}






/* teacher/quiz-preview.php — "Show All Quiz Questions at Once" blueprint.
   Brief highlight applied to the first unanswered question card when a
   teacher cancels "Submit anyway?" so they can see which one it jumped
   to; fades on its own, no JS timer dependency beyond removing the class. */
.qp-highlight { animation: qp-highlight-pulse 1.6s ease-out; }
@keyframes qp-highlight-pulse {
  0% { box-shadow: 0 0 0 3px var(--ed-primary); }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* "Detailed Report Live Progress and Activity Stream" blueprint,
 * Phase 7/8 — the expanded progress panel (includes/learning-
 * recommendation-cta-view.php) and its typing indicator. The three-dot
 * indicator pulses to show the activity log is "about to type" a new
 * event; respects prefers-reduced-motion by simply not animating
 * (still visible, just static) rather than hiding the information it
 * conveys. */
.ed-lr-activity-panel { max-width: 42rem; }
.ed-lr-typing-dot {
  display: inline-block;
  width: 0.35rem;
  height: 0.35rem;
  margin-right: 0.15rem;
  border-radius: 9999px;
  background: var(--ed-muted, #94a3b8);
  animation: ed-lr-typing-bounce 1.2s infinite ease-in-out both;
}
.ed-lr-typing-dot:nth-child(2) { animation-delay: 0.15s; }
.ed-lr-typing-dot:nth-child(3) { animation-delay: 0.3s; }
@keyframes ed-lr-typing-bounce {
  0%, 80%, 100% { opacity: 0.35; transform: scale(0.85); }
  40% { opacity: 1; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .ed-lr-typing-dot { animation: none; opacity: 0.7; }
}

/* "Persistent Animated Progress Indicator During Long Report
 * Generation" blueprint — a continuously-rotating ring immediately
 * beside the percentage in the detailed-report progress panel's
 * header (includes/learning-recommendation-cta-view.php), so the
 * page never reads as frozen during the long early stage where the
 * percent itself doesn't move for many seconds. Deliberately CSS-only
 * (no JS timer driving the rotation) — an `animation: ... infinite`
 * rule can't drift, pause, or be blocked by a slow/failed poll the
 * way a JS-timed frame-cycle could, which matters for something whose
 * entire job is to prove the page is still alive. JS only ever adds
 * .ed-lr-activity-spinner--stopped once, when the job reaches a
 * terminal state (see learning-recommendations.js's stop()).
 */
.ed-lr-percent-group {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem; /* ~8px — "within 8-12px of the percentage" */
}
.ed-lr-percent-value--active {
  display: inline-block;
  animation: ed-lr-percent-pulse 1s ease-in-out infinite;
}
@keyframes ed-lr-percent-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.08); }
}
.ed-lr-activity-spinner {
  display: inline-block;
  width: 1.15rem;
  height: 1.15rem;
  border-radius: 9999px;
  border: 2.5px solid var(--ed-primary, #2563eb);
  border-right-color: transparent;
  border-top-color: transparent;
  opacity: 0.85;
  animation: ed-lr-spinner-rotate 0.7s linear infinite;
}
.ed-lr-activity-spinner--stopped {
  animation: none;
  opacity: 0;
  visibility: hidden;
}
@keyframes ed-lr-spinner-rotate {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  /* Same "stay visible, just don't move" rule as .ed-lr-typing-dot
     above — a solid ring/steady percentage still communicates "there
     is an indicator here", it just doesn't spin/pulse for anyone who
     has asked their OS not to animate things. */
  .ed-lr-percent-value--active { animation: none; }
  .ed-lr-activity-spinner { animation: none; border-right-color: var(--ed-primary, #2563eb); border-top-color: var(--ed-primary, #2563eb); opacity: 0.6; }
}

/* =======================================================================
 * "Live HTML/CSS/JavaScript Visuals for Every How-To Step" blueprint —
 * annotation/containment chrome ONLY (per that blueprint's §26 CSS
 * isolation rule). Anything reproducing actual TeeCarbon UI inside a
 * How-To visual (buttons, cards, inputs) uses the real .ed-btn-*/
 * .ed-card/.ed-input/.ed-badge-* classes already defined above — never
 * duplicated here. These classes exist only for: the outer card shell,
 * the "STEP PREVIEW" badge, the highlight ring + "CLICK HERE" callout,
 * and small layout-only containers specific to a demo fixture
 * (.how-to-sidebar-demo, .how-to-roadmap-unit-demo, etc.) that have no
 * real-page equivalent to borrow from.
 * ===================================================================== */

.how-to-visual {
  position: relative;
  background: var(--ed-body-bg);
  border: 1px solid var(--ed-border);
  border-radius: 14px;
  padding: 1.5rem 1rem 1.25rem;
  max-width: 480px;
}

.how-to-visual-badge {
  position: absolute;
  top: 10px;
  right: 12px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ed-muted-text);
  background: var(--ed-card-bg);
  border: 1px solid var(--ed-border);
  border-radius: 999px;
  padding: 3px 10px;
}

.how-to-visual-body {
  pointer-events: none; /* §24/§25 — every control inside a visual is inert; nothing here should be clickable except via how-to-visuals.js's own explicit, opted-in data-how-to-action handlers below */
}
.how-to-visual-body [data-how-to-action] {
  pointer-events: auto;
  cursor: pointer;
}
.how-to-visual-body [data-how-to-mode-value] {
  pointer-events: auto;
  cursor: pointer;
}

/* Highlight ring + "CLICK HERE" callout — wraps whichever element a
   step's 'target' option names (how_to_visual_target(), how-to-visuals.php). */
.how-to-visual-target {
  position: relative;
  display: inline-block;
  outline: 2px dashed var(--ed-primary);
  outline-offset: 4px;
  border-radius: 10px;
}
.how-to-visual-target-label {
  position: absolute;
  top: -26px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ed-primary);
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 4px;
}

/* Sidebar demo fixture (includes/how-to-visual-components/sidebar.php) */
.how-to-sidebar-demo {
  background: var(--ed-card-bg);
  border: 1px solid var(--ed-border);
  border-radius: 12px;
  padding: 0.75rem;
  max-width: 260px;
}
.how-to-sidebar-brand {
  font-weight: 800;
  font-size: 13px;
  color: var(--ed-heading);
  margin-bottom: 0.5rem;
}
.how-to-sidebar-group-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--ed-muted-text);
  margin: 0.5rem 0 0.25rem;
}
.how-to-sidebar-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 8px;
  border-radius: 8px;
  font-size: 13px;
  color: var(--ed-body-text);
}
.how-to-sidebar-row-active {
  background: var(--ed-body-bg);
  color: var(--ed-primary);
  font-weight: 700;
}
.how-to-sidebar-dot {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: currentColor;
  opacity: 0.6;
}

/* Roadmap-unit demo fixture */
.how-to-roadmap-unit-demo h3 {
  font-size: 15px;
  font-weight: 700;
  color: var(--ed-heading);
  margin: 0.25rem 0 0.15rem;
}
.how-to-roadmap-unit-demo p {
  font-size: 12px;
  color: var(--ed-muted-text);
  margin: 0 0 0.75rem;
}
.how-to-roadmap-unit-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.how-to-roadmap-nonowner-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--ed-muted-text);
  margin: 0;
}
.how-to-roadmap-nonowner-text {
  font-size: 12px;
  color: var(--ed-muted-text);
  margin: 2px 0 0;
}
.how-to-mode-toggle {
  display: flex;
  gap: 4px;
  margin-bottom: 0.75rem;
}
.how-to-mode-toggle .mode-toggle-btn {
  font-size: 11px;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--ed-border);
  background: var(--ed-card-bg);
  color: var(--ed-muted-text);
}
.how-to-mode-toggle .mode-toggle-btn.how-to-mode-active {
  background: var(--ed-primary);
  color: #fff;
  border-color: var(--ed-primary);
}

/* Quiz Settings demo fixture */
.how-to-quiz-settings-collapsed {
  font-size: 13px;
  font-weight: 600;
  color: var(--ed-body-text);
  background: var(--ed-card-bg);
  border: 1px solid var(--ed-border);
  border-radius: 10px;
  padding: 8px 14px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.how-to-quiz-settings-demo {
  background: var(--ed-card-bg);
  border: 1px solid var(--ed-border);
  border-radius: 12px;
  padding: 0.9rem;
  max-width: 300px;
}
.how-to-quiz-settings-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--ed-heading);
  margin: 0 0 0.5rem;
}
.how-to-quiz-settings-field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: 12px;
  color: var(--ed-body-text);
  margin-bottom: 0.4rem;
}
.how-to-quiz-settings-field .ed-input,
.how-to-quiz-settings-field .ed-select {
  max-width: 110px;
  padding: 3px 8px;
  font-size: 12px;
}
.how-to-quiz-settings-save-row {
  margin-top: 0.6rem;
}

/* Plan-directory demo fixture */
.how-to-plan-directory-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 0.6rem;
}
.how-to-tab {
  font-size: 12px;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--ed-border);
  background: var(--ed-card-bg);
  color: var(--ed-muted-text);
}
.how-to-tab-active {
  background: var(--ed-primary);
  color: #fff;
  border-color: var(--ed-primary);
}
.how-to-plan-search-field {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--ed-card-bg);
  border: 1px solid var(--ed-border);
  border-radius: 10px;
  padding: 8px 12px;
  font-size: 12px;
  color: var(--ed-muted-text);
  margin-bottom: 0.6rem;
}
.how-to-input-placeholder {
  color: var(--ed-muted-text);
}
.how-to-plan-result-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--ed-card-bg);
  border: 1px solid var(--ed-border);
  border-radius: 10px;
  padding: 10px 12px;
}
.how-to-plan-result-title {
  font-size: 13px;
  font-weight: 700;
  color: var(--ed-heading);
  margin: 0 0 2px;
}
.how-to-plan-create-demo {
  text-align: center;
  padding: 1rem 0;
}

/* Journey demo fixture */
.how-to-journey-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 0.6rem;
}
.how-to-journey-entry {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--ed-card-bg);
  border: 1px solid var(--ed-border);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 13px;
  color: var(--ed-heading);
}
.how-to-journey-entry-meta {
  display: block;
  font-size: 11px;
  font-weight: 400;
  color: var(--ed-muted-text);
}

/* Communication demo fixture */
.how-to-comm-composer {
  background: var(--ed-card-bg);
  border: 1px solid var(--ed-border);
  border-radius: 10px;
  padding: 0.75rem;
  max-width: 300px;
}
.how-to-comm-context {
  font-size: 11px;
  color: var(--ed-muted-text);
  margin: 0 0 0.5rem;
}
.how-to-comm-composer textarea {
  width: 100%;
  margin-bottom: 0.5rem;
  resize: none;
}
.how-to-comm-feed-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--ed-card-bg);
  border: 1px solid var(--ed-border);
  border-radius: 10px;
  padding: 10px 12px;
}
.how-to-comm-feed-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--ed-heading);
}

@media (max-width: 480px) {
  .how-to-visual { max-width: 100%; padding: 1.25rem 0.75rem 1rem; }
  .how-to-sidebar-demo, .how-to-quiz-settings-demo, .how-to-comm-composer { max-width: 100%; }
}

/* Quick View gets a smaller version of the same component (blueprint
   §21) rather than a second component — just visually shrunk. */
.how-to-visual-compact {
  transform: scale(0.72);
  transform-origin: top left;
  margin-bottom: -1.5rem; /* offset the visual gap the scale-down leaves */
}

/* "Syllabus Learning Relationships Control Center" blueprint, Part 35
 * ("Mobile behavior") — this feature was already built without any
 * drag-and-drop dependency (badges/buttons + a shared modal/drawer,
 * same tap-to-open pattern as everything else on this page), so the
 * only genuinely missing piece is comfortable touch-target sizing and
 * edge-to-edge dialogs on a phone-width viewport, rather than a
 * separate mobile layout. Map mode (Part 16) needs nothing extra here
 * either — it was already vertically-stacked cards, never a real
 * graph, per that Part's own "Start simple" instruction, so it already
 * degrades to a single column on a narrow screen with no changes.
 */
@media (max-width: 640px) {
  /* The Add-Relationship modal, Suggest-Relationships drawer, and
     Learning Path Settings drawer are all centered fixed-position
     dialogs with a max-w-* cap — on a phone that cap plus the
     surrounding p-4 leaves cramped side margins, so this widens them
     to genuinely edge-to-edge instead. The inspector drawer already
     anchors to the trailing edge (items-center justify-end) and stays
     that way — collapsing it to centered on mobile would fight its
     own slide-in affordance. */
  #syl-lr-add-modal > div,
  #syl-lr-suggest-drawer > div,
  #syl-lr-settings-drawer > div {
    max-width: 100%;
    max-height: 92vh;
  }
  #syl-lr-add-modal,
  #syl-lr-suggest-drawer,
  #syl-lr-settings-drawer,
  #syl-lr-inspector-drawer {
    padding: 0.5rem;
  }

  /* Larger tap targets for the filter bar, badges, and per-Quiz row
     action buttons — Part 35's own "List mode must be fully functional
     on touch." Applied narrowly to this feature's own buttons/badges,
     not a site-wide button-size change. */
  .syl-lr-filter-btn,
  .syl-lr-badge-toggle,
  .syl-lr-add-btn,
  .syl-lr-inspect-btn {
    min-height: 32px;
    padding-top: 0.375rem;
    padding-bottom: 0.375rem;
  }

  /* The per-Quiz row's action-button column (+ Add Relationship /
     Details / Edit Relationships) sits to the right of the title on a
     wide screen; on a phone that squeezes the title, so it drops below
     as a full-width row of buttons instead. */
  #syl-lr-hierarchy .ed-card > div.flex.items-start.justify-between {
    flex-direction: column;
  }
  #syl-lr-hierarchy .ed-card .flex.flex-col.gap-1.items-end {
    align-items: stretch;
    width: 100%;
    flex-direction: row;
    flex-wrap: wrap;
  }
}

/* "TeeCarbon Deterministic Math Visual Engine" blueprint, PART 31/48.
   Named rule constraining .tc-math-visual to the pixel maximums PART
   31 specifies (this was NOT added in the Parts 31-45 pass — see that
   pass's own changelog note "still open" — JSXGraph board sizing had
   been following whatever CSS the containing .ed-card/.tc-math-visual-
   container already applied, which is reasonable but not the explicit
   rule PART 31 describes). `responsive_size` per template
   ('compact' | 'coordinate', see math-visual-templates.php's own
   registry) selects between the two --coordinate variant and the
   plain default; math-visual-renderer.js does not currently add a
   template-specific class itself, so this rule applies the PART 31
   DEFAULT (420px) to every .tc-math-visual and the wider COORDINATE
   max (480px) only inside a container a page has explicitly marked
   `.tc-math-visual-container--coordinate` (opt-in, since most current
   Release 1 templates render fine at the default). */
.tc-math-visual {
  width: 100%;
  max-width: 420px;
  margin-left: auto;
  margin-right: auto;
}
.tc-math-visual-container--compact .tc-math-visual {
  max-width: 320px;
}
.tc-math-visual-container--coordinate .tc-math-visual {
  max-width: 480px;
}

/* PART 48 — the visible accessible-description text block
   math-visual-renderer.js's render() now appends after every diagram
   (see its own PART 48 comment). Deliberately still visible to
   sighted users too (not screen-reader-only) — PART 48's own wording
   is "do not make essential information available only through the
   diagram," and a small, muted caption serves both a screen-reader
   user and a sighted user who wants the diagram's content restated in
   words. */
.tc-math-visual-description {
  font-size: 0.75rem;
  line-height: 1.1rem;
  color: var(--ed-text-muted, #6b7280);
  margin-top: 0.375rem;
  text-align: center;
}

/* "TeeCarbon Worksheets" blueprint, Phase 1 (u213_422) — Worksheet
   print layout (blueprint §15), REVISED in the u213_422 completion
   pass to make the three print buttons genuinely independent (the
   completion audit found all three previously just called a bare
   window.print() with no mode actually consumed, and the old
   `#tw-solution-sheet.hidden { display: block !important; }` rule
   force-showed the Solution Sheet on EVERY print regardless of which
   button was clicked — Print Worksheet could leak answers). Own
   #tw-print-root mechanism rather than the generic #print-area toggle
   above, matching the same per-feature choice the Learning Insights
   Reports print rules (#li-report-print-root, above) already made:
   this page has its own screen-only controls (search/filter UI,
   sidebar, navbar, the "Show/Hide Solution Sheet" button, print
   buttons themselves) that must never appear on paper.

   Mode is set on #tw-print-root's own `data-print-mode` attribute by
   twWorksheetPrint() (includes/syllabus-topic-worksheet-view.php's
   own inline script) immediately before calling window.print(), and
   cleared again on the browser's `afterprint` event. Three values:
     - 'worksheet' (also the default/unset state, e.g. a raw Ctrl+P
       that never went through one of our buttons) — worksheet body
       only, Solution Sheet NEVER rendered, regardless of its on-screen
       shown/hidden state. This is the safe default specifically so a
       Student (or anyone) printing via the browser's own shortcut can
       never accidentally leak answers.
     - 'solutions' — Solution Sheet only, worksheet body hidden.
     - 'both' — everything, Solution Sheet forced onto its own page via
       .tw-print-page-break regardless of on-screen state.
   Every one of these selectors is an ID + attribute selector (higher
   specificity than a bare `.hidden` utility class), so they reliably
   override the on-screen collapsed state either direction (force show
   OR force hide) without needing to touch the DOM/class list at print
   time. */
@media print {
  #tw-print-root, #tw-print-root * { visibility: visible; }
  #tw-print-root {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    padding: 0;
  }
  .tw-hide-print { display: none !important; }

  /* Default / 'worksheet' mode: the Solution Sheet is never printed,
     full stop — overrides ANY on-screen shown/revealed state. */
  #tw-print-root:not([data-print-mode="solutions"]):not([data-print-mode="both"]) #tw-solution-sheet {
    display: none !important;
  }

  /* 'solutions' mode: Solution Sheet only — the worksheet body
     (header/instructions/sections/questions) is suppressed, and the
     Solution Sheet itself starts at the top of the page rather than
     forcing a leading blank page via the 'both'-mode page-break. */
  #tw-print-root[data-print-mode="solutions"] .tw-worksheet-body { display: none !important; }
  #tw-print-root[data-print-mode="solutions"] #tw-solution-sheet {
    display: block !important;
    break-before: avoid;
    page-break-before: avoid;
  }

  /* 'both' mode: everything prints, Solution Sheet forced visible
     (overriding an unrevealed on-screen state) and starting on its
     own page (blueprint §15). */
  #tw-print-root[data-print-mode="both"] #tw-solution-sheet {
    display: block !important;
  }

  /* blueprint §15 — "Solution sheet should begin on a separate
     printed page" — only actually applies in 'both' mode; 'solutions'
     mode above explicitly cancels this so a solutions-only printout
     doesn't start with a blank leading page. */
  .tw-print-page-break { break-before: page; page-break-before: always; }
  /* blueprint §15 — the printed Worksheet header carries blank
     Student Name / Date / Topic lines; those are pure screen clutter
     everywhere else, so this block is print-only in both directions. */
  .tw-print-only { display: block !important; }
}
.tw-print-only { display: none; }
.tw-fill-lines p { margin: 0.25rem 0; }

/* =======================================================================
 * "TOC as a Visual Learning Path with Simple Progress Tracking"
 * blueprint — Parts 7/19. Exactly THREE status colors anywhere in this
 * block (green/red/neutral) — no yellow, blue, or mastery-band colors
 * belong here; see includes/syllabus-toc-progress.php's own docblock
 * for the three-state model these classes render.
 * ===================================================================== */
.toc-progress-node {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 999px;
  flex-shrink: 0;
  border: 2px solid var(--ed-border);
  background: transparent;
}
.toc-progress-complete.toc-progress-node { background: var(--ed-success); border-color: var(--ed-success); }
.toc-progress-incomplete.toc-progress-node { background: var(--ed-danger); border-color: var(--ed-danger); }
.toc-progress-not-started.toc-progress-node { background: transparent; border-color: var(--ed-border); }

/* Same three states used as a badge/pill (question rows, quiz rows —
   more legible at small sizes than the bare dot alone). */
.toc-progress-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.6875rem;
  font-weight: 600;
  padding: 0.05rem 0.45rem;
  border-radius: 999px;
  white-space: nowrap;
}
.toc-progress-badge.toc-progress-complete { color: var(--ed-success); background: var(--ed-success-bg); }
.toc-progress-badge.toc-progress-incomplete { color: var(--ed-danger); background: var(--ed-danger-bg); }
.toc-progress-badge.toc-progress-not-started { color: var(--ed-muted-text); background: transparent; border: 1px dashed var(--ed-border); }

/* The connecting vertical line between major TOC nodes (Part 7) — the
   line itself always stays neutral; only the node dot at each end
   carries status color (Part 7: "Do not introduce extra colors for
   the path"). */
.toc-path-line {
  width: 2px;
  min-height: 1.1rem;
  background: var(--ed-border);
  margin: 0 auto;
}

/* Current-position marker (Part 9/19) — never a fourth status color,
   just an outline/badge layered on top of whatever the node's own
   green/red/neutral color already is. */
.toc-progress-current {
  box-shadow: 0 0 0 3px var(--ed-primary);
}
.toc-current-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ed-on-accent);
  background: var(--ed-primary);
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
}

/* u213_720 — Large Course Navigator (My Learning, 50+ topics only).
   Uses the existing tokens; a course under 50 topics never gets these classes. */
.toc-course-navigator {
  /* Phase 31 — stays in reach while a long course scrolls, just below the
     4rem site bar (sticky top-0 h-16); rows keep a scroll margin so a
     revealed row is never hidden under it. */
  position: sticky;
  top: 4.5rem;
  z-index: 30;
  box-shadow: 0 4px 12px -8px rgba(0, 0, 0, 0.25);
}
.toc-course-navigator-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 0.5rem;
}
.toc-course-navigator-title {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ed-muted-text);
}
.toc-course-navigator-count { font-size: 0.8125rem; font-weight: 600; color: var(--ed-heading); }
.toc-course-navigator .ta-dt-search { width: 100%; min-width: 0; }
.toc-course-navigator-controls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 0.5rem;
}
.toc-course-filters {
  display: flex;
  gap: 0.375rem;
  flex-wrap: wrap;
}
.toc-course-filter {
  min-height: 2.25rem;
  padding: 0.25rem 0.75rem;
  border-radius: 999px;
  border: 1px solid var(--ed-border);
  background: var(--ed-card-bg);
  color: var(--ed-heading);
  font-size: 0.8125rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}
.toc-course-filter[aria-pressed="true"] {
  background: var(--ed-primary);
  border-color: var(--ed-primary);
  color: var(--ed-on-accent);
}
.toc-course-filter:focus-visible { outline: 2px solid var(--ed-primary); outline-offset: 2px; }
.toc-course-tools { display: flex; gap: 0.375rem; flex-wrap: wrap; }
.toc-course-results { margin-top: -0.5rem; }
.toc-course-results-count { font-size: 0.75rem; font-weight: 600; color: var(--ed-muted-text); padding: 0.25rem 0; }
.toc-course-result {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.375rem 0;
  border-bottom: 1px solid var(--ed-border);
  font-size: 0.875rem;
}
.toc-course-group + .toc-course-group { border-top: 1px solid var(--ed-border); }
.toc-course-group, .toc-course-row, .toc-course-subunit { scroll-margin-top: 16rem; }
.toc-course-group-head { display: flex; align-items: center; gap: 0.5rem; }
.toc-course-group-toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;
  padding: 0.5rem 0.25rem;
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
  color: var(--ed-heading);
  flex-wrap: wrap;
}
.toc-course-group-toggle:focus-visible { outline: 2px solid var(--ed-primary); outline-offset: 2px; border-radius: 0.375rem; }
.toc-course-group-caret { width: 1rem; flex-shrink: 0; font-size: 0.7rem; color: var(--ed-muted-text); }
.toc-course-group-name { font-weight: 700; overflow-wrap: anywhere; }
.toc-course-group-count { margin-left: auto; flex-shrink: 0; font-size: 0.75rem; font-weight: 600; color: var(--ed-muted-text); white-space: nowrap; }
.toc-course-group-body { padding: 0 0 0.5rem 0.75rem; }
.toc-course-subunit { margin: 0.25rem 0 0.25rem 0.25rem; }
.toc-course-subunit-name { display: flex; gap: 0.5rem; font-size: 0.8125rem; font-weight: 700; color: var(--ed-heading); padding: 0.375rem 0; }

/* Phase 29 — compact topic rows: marker · name · status · one action. */
.toc-course-row { padding: 0.375rem 0; border-bottom: 1px solid var(--ed-border); }
.toc-course-row-main { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; flex-wrap: wrap; }
.toc-course-row-name { display: flex; align-items: center; gap: 0.5rem; min-width: 0; flex: 1 1 14rem; flex-wrap: wrap; }
.toc-course-row-name a, .toc-course-row-name button, .toc-course-row-name span.font-semibold { white-space: normal; overflow-wrap: anywhere; }
.toc-course-row-side { display: flex; align-items: center; gap: 0.375rem; flex-wrap: wrap; }
.toc-course-row-current { background: color-mix(in srgb, var(--ed-primary) 7%, transparent); border-radius: 0.5rem; padding-left: 0.375rem; padding-right: 0.375rem; }
.toc-course-status { font-size: 0.6875rem; font-weight: 700; color: var(--ed-muted-text); white-space: nowrap; }
.toc-course-status-incomplete { color: var(--ed-warning, #b45309); }
.toc-course-status-complete { color: var(--ed-success, #2f7d5b); }
.toc-course-here { letter-spacing: 0.04em; }
.toc-course-schoolwork { font-size: 0.6875rem; font-weight: 600; color: var(--ed-heading); background: var(--ed-app-body, rgba(0,0,0,.05)); border: 1px solid var(--ed-border); border-radius: 999px; padding: 0.05rem 0.45rem; white-space: nowrap; }
.toc-course-more { margin: 0.25rem 0 0 1.5rem; }
.toc-course-more > summary { cursor: pointer; font-size: 0.75rem; font-weight: 600; color: var(--ed-muted-text); min-height: 1.75rem; display: inline-flex; align-items: center; }
.toc-course-more > summary:focus-visible { outline: 2px solid var(--ed-primary); outline-offset: 2px; border-radius: 0.25rem; }
.toc-course-more-body { padding: 0.25rem 0 0.25rem 0; }
.toc-course-target { outline: 2px solid var(--ed-primary); outline-offset: 2px; border-radius: 0.375rem; }

/* Phase 32 — phones: a compact toolbar, filters scroll sideways in one row. */
@media (max-width: 640px) {
  .toc-course-navigator { top: 4.25rem; padding: 0.75rem; }
  .toc-course-navigator-head { margin-bottom: 0.375rem; }
  .toc-course-filters { flex-wrap: nowrap; overflow-x: auto; width: 100%; padding-bottom: 0.25rem; -webkit-overflow-scrolling: touch; }
  .toc-course-navigator-controls { margin-top: 0.375rem; gap: 0.375rem; }
  .toc-course-filter { min-height: 2rem; padding: 0.2rem 0.65rem; font-size: 0.75rem; }
  .toc-course-tools { width: 100%; flex-wrap: nowrap; overflow-x: auto; }
  .toc-course-tools .ed-btn-secondary { white-space: nowrap; }
  .toc-course-more { margin-left: 0; }
}
/* Phase 51 — pre-existing 375px overflow of the TOC action-button row (every
   course size, since u213_7xx): let the row's buttons wrap on narrow screens
   instead of pushing the page sideways. Same buttons, same order. */
@media (max-width: 480px) {
  #toc-tree .toc-node > div > .flex-shrink-0 { flex-shrink: 1; min-width: 0; }
}

/* Overall syllabus progress bar (Part 8). */
.toc-overall-progress-track {
  width: 100%;
  height: 0.5rem;
  border-radius: 999px;
  background: var(--ed-border);
  overflow: hidden;
}
.toc-overall-progress-fill {
  height: 100%;
  background: var(--ed-success);
  border-radius: 999px;
  transition: width 0.3s ease;
}

/* Expandable Quiz/Question detail (Part 11). */
.toc-quiz-detail {
  border-left: 2px solid var(--ed-border);
  margin-left: 0.6rem;
  padding-left: 0.4rem;
}
.toc-quiz-row + .toc-quiz-row { border-top: 1px solid var(--ed-border); }

/* Continue Learning card (Part 10). */
.toc-continue-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  border: 1px solid var(--ed-border);
  background: var(--ed-body-bg);
  border-radius: 0.75rem;
  padding: 0.85rem 1rem;
}

/* u213_723 — Topic Learning grouped actions (My Learning Course Map only;
   toc-topic-learning.js). Token colors only; compact, wraps on phones. */
.toc-tl-actions { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0.6rem; }
.toc-tl-group { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 0.25rem; padding-left: 0.45rem; border-left: 2px solid var(--ed-border); }
.toc-tl-group-label { font-size: 0.625rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ed-muted-text); margin-right: 0.1rem; }
.toc-tl-group a { padding: 0.2rem 0.6rem; font-size: 0.75rem; line-height: 1.2; min-height: 1.75rem; display: inline-flex; align-items: center; }
.toc-tl-group a:focus-visible { outline: 2px solid var(--ed-primary); outline-offset: 2px; }
.toc-course-more-body .toc-tl-actions { display: flex; margin-top: 0.35rem; }
@media (max-width: 640px) {
  .toc-tl-group a { min-height: 2.25rem; }
}

/* u213_723 — Topic Learning page (/student/topic-learning.php; Phases 54-59).
   Token colors only; readable blocks, wraps on phones. */
.tlv-tabs { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 1rem; border-bottom: 1px solid var(--ed-border); }
.tlv-tab { padding: 0.5rem 0.85rem; font-size: 0.875rem; font-weight: 600; color: var(--ed-muted-text); border-bottom: 2px solid transparent; min-height: 2.5rem; display: inline-flex; align-items: center; }
.tlv-tab:hover { color: var(--ed-body-text); }
.tlv-tab-current { color: var(--ed-primary); border-bottom-color: var(--ed-primary); }
.tlv-tab:focus-visible, .tlv-chip:focus-visible, .tlv-hint summary:focus-visible { outline: 2px solid var(--ed-primary); outline-offset: 2px; }
.tlv-section { margin-bottom: 1.5rem; }
.tlv-h2 { font-size: 1.05rem; font-weight: 800; color: var(--ed-heading); margin: 0 0 0.6rem; }
.tlv-h3 { font-size: 1rem; font-weight: 700; color: var(--ed-heading); margin: 0 0 0.4rem; }
.tlv-body .ed-card { margin-bottom: 0.75rem; }
.tlv-text { margin: 0 0 0.4rem; color: var(--ed-body-text); line-height: 1.55; }
.tlv-lead { margin: 0 0 0.6rem; color: var(--ed-body-text); line-height: 1.6; font-size: 0.95rem; }
.tlv-meta { font-size: 0.8rem; color: var(--ed-muted-text); margin: 0.25rem 0 0; }
.tlv-facet { margin-top: 0.6rem; padding-left: 0.65rem; border-left: 3px solid var(--ed-border); }
.tlv-facet-warn { border-left-color: var(--ed-warning); background: var(--ed-warning-bg); padding: 0.45rem 0.65rem; border-radius: 0.35rem; }
.tlv-facet-muted .tlv-text { color: var(--ed-muted-text); }
.tlv-facet-label { font-size: 0.7rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ed-muted-text); margin: 0 0 0.2rem; }
.tlv-chips { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.tlv-chip { display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.2rem 0.6rem; min-height: 1.9rem; border: 1px solid var(--ed-border); border-radius: 999px; font-size: 0.8rem; color: var(--ed-body-text); background: var(--ed-card-bg); }
a.tlv-chip:hover { border-color: var(--ed-primary); color: var(--ed-primary); }
.tlv-chip-role { font-size: 0.65rem; text-transform: uppercase; color: var(--ed-muted-text); }
.tlv-chain-list { list-style: none; margin: 0; padding: 0; }
.tlv-chain-list li { padding: 0.1rem 0; color: var(--ed-body-text); }
.tlv-chain-arrow { display: block; font-size: 0.75rem; color: var(--ed-muted-text); }
.tlv-relations, .tlv-list { margin: 0.3rem 0 0; padding-left: 1.1rem; list-style: disc; color: var(--ed-body-text); }
.tlv-step-no { color: var(--ed-primary); }
.tlv-transform { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin: 0.4rem 0; }
.tlv-transform-arrow { color: var(--ed-muted-text); }
.tlv-math { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.9rem; background: var(--ed-body-bg); border: 1px solid var(--ed-border); border-radius: 0.3rem; padding: 0.15rem 0.45rem; overflow-wrap: anywhere; }
.tlv-parts { margin: 0.5rem 0 0; padding-left: 1.2rem; list-style: decimal; display: grid; gap: 0.3rem; }
.tlv-hints { margin-top: 0.6rem; }
.tlv-hint { border: 1px solid var(--ed-border); border-radius: 0.35rem; padding: 0.35rem 0.6rem; margin-top: 0.3rem; background: var(--ed-card-bg); }
.tlv-hint summary { cursor: pointer; font-size: 0.85rem; font-weight: 600; color: var(--ed-primary); min-height: 1.75rem; display: flex; align-items: center; }
.tlv-question { margin-bottom: 0.75rem; }
.tlv-question-part { margin: 0.6rem 0 0 0.75rem; padding-left: 0.75rem; border-left: 2px solid var(--ed-border); }
.tlv-q-text { margin: 0 0 0.5rem; color: var(--ed-body-text); line-height: 1.5; }
.tlv-q-no { font-weight: 700; color: var(--ed-heading); }
.tlv-choices { border: 0; margin: 0; padding: 0; display: grid; gap: 0.3rem; }
.tlv-choice { display: flex; align-items: center; gap: 0.5rem; min-height: 2.25rem; color: var(--ed-body-text); }
.tlv-answer { width: 100%; max-width: 100%; }
.tlv-q-principles { margin-top: 0.5rem; }
.tlv-your-answer { margin-top: 0.4rem; }
.tlv-form-actions, .tlv-start-form { margin: 0.75rem 0 1rem; }
.tlv-flash { margin: 0 0 0.75rem; padding: 0.5rem 0.75rem; border-radius: 0.35rem; background: var(--ed-success-bg); color: var(--ed-body-text); }
@media (max-width: 640px) {
  .tlv-tab { flex: 1 1 auto; justify-content: center; }
  .tlv-question-part { margin-left: 0.25rem; }
}

/* u213_723 — Topic Learning review (/teacher/topic-learning-review.php; Phases 62-64).
   Token colors only. */
.tlr-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 0.6rem; margin-bottom: 0.75rem; }
.tlr-label { display: block; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; color: var(--ed-muted-text); margin: 0.5rem 0 0.2rem; }
.tlr-field { width: 100%; max-width: 100%; }
.tlr-filters, .tlr-actions, .tlr-record { margin-bottom: 0.75rem; }
.tlr-row { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; margin-top: 0.5rem; }
.tlr-form { display: inline-block; margin: 0.25rem 0.25rem 0.25rem 0; }
.tlr-edit .tlr-form { display: block; }
.tlr-edit { border-top: 1px solid var(--ed-border); margin-top: 0.5rem; padding-top: 0.4rem; }
.tlr-edit summary { cursor: pointer; font-size: 0.85rem; font-weight: 600; color: var(--ed-primary); min-height: 2rem; display: flex; align-items: center; }
.tlr-edit summary:focus-visible { outline: 2px solid var(--ed-primary); outline-offset: 2px; }
.tlr-part { margin-left: 1rem; }
.tlr-section { margin-bottom: 1.25rem; }
.tlr-h2 { font-size: 1.05rem; font-weight: 800; color: var(--ed-heading); margin: 0 0 0.5rem; }
.tlr-h3 { font-size: 0.95rem; font-weight: 700; color: var(--ed-heading); margin: 0 0 0.3rem; overflow-wrap: anywhere; }
.tlr-versions, .tlr-list { margin: 0.2rem 0; padding-left: 1rem; list-style: disc; font-size: 0.85rem; color: var(--ed-body-text); }
.tlr-table-wrap { overflow-x: auto; }
.tlr-table { width: 100%; font-size: 0.8rem; border-collapse: collapse; }
.tlr-table th { text-align: left; color: var(--ed-muted-text); font-weight: 700; padding: 0.35rem; border-bottom: 1px solid var(--ed-border); }
.tlr-table td { padding: 0.35rem; border-bottom: 1px solid var(--ed-border); color: var(--ed-body-text); vertical-align: top; }
.tlr-pager { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem; font-size: 0.85rem; }
.tlr-flash { margin: 0 0 0.75rem; padding: 0.5rem 0.75rem; border-radius: 0.35rem; color: var(--ed-body-text); }
.tlr-flash-ok { background: var(--ed-success-bg); }
.tlr-flash-err { background: var(--ed-danger-bg); }
.tlr-preview-banner { margin: 0 0 1rem; padding: 0.6rem 0.8rem; border-radius: 0.35rem; background: var(--ed-info-bg); color: var(--ed-body-text); font-size: 0.875rem; }

/* Dual-Path Book Integration blueprint, Phase 186 — the Book import / debug center tables stack into label / value cards on
   phones (the browser harness found every one of them overflowing a 390 px viewport). Scoped to .bi-table; every cell already
   carries data-label. Long tokens (hashes, correlation ids, codes) wrap instead of widening the page. */
.bi-table td, .bi-table th { overflow-wrap: anywhere; word-break: break-word; }
.bi-table input, .bi-table select, .bi-table textarea { max-width: 100%; }
@media (max-width: 767px) {
  .bi-table, .bi-table tbody, .bi-table tr { display: block; width: 100%; }
  .bi-table thead { display: none; }
  .bi-table caption { display: block; text-align: left; padding: 0.25rem 0; }
  .bi-table tbody tr { border: 1px solid var(--ed-border); border-radius: 0.75rem; margin-bottom: 0.75rem; overflow: hidden; background: var(--ed-card-bg); }
  .bi-table tbody td { display: grid; grid-template-columns: minmax(5.5rem, 35%) minmax(0, 1fr); gap: 0.5rem; width: 100%; padding: 0.5rem 0.75rem; text-align: left; }
  .bi-table tbody td::before { content: attr(data-label); font-size: 0.75rem; font-weight: 700; color: var(--ed-muted-text); text-transform: uppercase; letter-spacing: 0.03em; }
  .bi-table tbody td[colspan] { display: block; }
  .bi-table tbody td[colspan]::before { content: none; }
  .bi-table tbody th[scope="row"], .bi-table tbody th[scope="rowgroup"] { display: block; padding: 0.5rem 0.75rem 0; text-align: left; }
  .bi-table tbody th[scope="row"] + td { display: block; }
  .bi-table tbody th[scope="row"] + td::before { content: none; }
}
.bi-pre { white-space: pre-wrap; overflow-wrap: anywhere; max-width: 100%; }
