/* No data-theme = follow the OS; data-theme (from the `theme` cookie) forces one. */
:root { color-scheme: light dark; }
[data-theme="light"] { color-scheme: light; }
[data-theme="dark"] { color-scheme: dark; }

/* Palette: ink-blue primary for actions/selection, amber only for "up next", green only for "done". */
:root {
  --bg: light-dark(oklch(1 0 0), oklch(0.16 0 0));
  --panel: light-dark(oklch(0.975 0.003 252), oklch(0.13 0 0));
  --surface-2: light-dark(oklch(0.965 0.004 252), oklch(0.2 0.004 252));
  --line: light-dark(oklch(0.915 0.005 252), oklch(0.27 0.006 252));
  --line-strong: light-dark(oklch(0.84 0.008 252), oklch(0.36 0.008 252));
  --ink: light-dark(oklch(0.22 0.012 252), oklch(0.94 0.004 252));
  --muted: light-dark(oklch(0.5 0.012 252), oklch(0.71 0.01 252));
  --faint: light-dark(oklch(0.72 0.01 252), oklch(0.46 0.01 252));

  --primary: oklch(0.53 0.16 252);
  --primary-hover: oklch(0.47 0.16 252);
  --primary-text: light-dark(oklch(0.5 0.16 252), oklch(0.74 0.12 252));
  --primary-soft: light-dark(oklch(0.955 0.025 252), oklch(0.26 0.05 252));

  --next: light-dark(oklch(0.78 0.15 72), oklch(0.8 0.14 75));
  --next-soft: light-dark(oklch(0.975 0.03 85), oklch(0.24 0.04 75));
  --next-text: light-dark(oklch(0.5 0.12 60), oklch(0.84 0.12 80));

  --ok: light-dark(oklch(0.55 0.13 155), oklch(0.72 0.14 155));
  --ok-soft: light-dark(oklch(0.96 0.035 155), oklch(0.25 0.04 155));
  --danger: light-dark(oklch(0.55 0.19 25), oklch(0.72 0.15 25));
  --danger-soft: light-dark(oklch(0.96 0.025 25), oklch(0.26 0.05 25));

  --radius: 8px;
  --radius-lg: 12px;
  --shadow-pop: 0 1px 2px oklch(0 0 0 / 0.04), 0 8px 24px oklch(0 0 0 / 0.08);
  --ease-out: cubic-bezier(0.25, 1, 0.5, 1);
  --z-sticky: 10;
  --z-menu: 30;
  --z-drawer: 40;
}

* { box-sizing: border-box; }
/* The window never scrolls. Scrolling lives in containers: .page-body, card bodies and the lists in them, .login, dialog bodies. */
html, body { height: 100%; margin: 0; overflow: hidden; background: var(--bg); color: var(--ink); }
body { overscroll-behavior: none; font-size: 0.9375rem; line-height: 1.5; -webkit-font-smoothing: antialiased; }

/* One minimal scrollbar everywhere (the approach of the Octacer reference app). Chromium ignores ::-webkit-scrollbar-*
   once scrollbar-width / scrollbar-color are also set on the same element: it falls back to its native thin bar, which
   keeps arrow buttons on Windows. So the standard properties are Firefox-only; Chromium and Safari keep the bar we can style. */
@supports not (-webkit-appearance: none) { * { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; } }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { border: 2px solid transparent; background: var(--line-strong); background-clip: padding-box; }
*::-webkit-scrollbar-thumb:hover { background: var(--muted); background-clip: padding-box; }
.scrollbar-hide { scrollbar-width: none; }
.scrollbar-hide::-webkit-scrollbar { display: none; }
/* Everything that scrolls inside a card (its body, a tab's panel, the lists in it) scrolls without a visible bar: wheel,
   touch and keyboard still work. The page body and dialogs keep the thin bar. */
.card-body, .card-body :is(.section-panel, .lessons) { scrollbar-width: none; }
.card-body::-webkit-scrollbar, .card-body :is(.section-panel, .lessons)::-webkit-scrollbar { display: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; }
h1, h2, h3 { text-wrap: balance; }
:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 4px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.spin { animation: spin 0.9s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Buttons: one vocabulary everywhere. */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 36px; padding: 0 14px; border: 1px solid transparent; border-radius: var(--radius); font-size: 0.875rem; font-weight: 500; white-space: nowrap; transition: background-color 150ms var(--ease-out), border-color 150ms var(--ease-out), color 150ms var(--ease-out); }
.btn:disabled { opacity: 0.55; cursor: not-allowed; }
.btn-primary { background: var(--primary); color: oklch(1 0 0); }
.btn-primary:hover:not(:disabled) { background: var(--primary-hover); }
.btn-secondary { border-color: var(--line-strong); background: var(--bg); color: var(--ink); }
.btn-secondary:hover:not(:disabled) { background: var(--surface-2); }
.btn-sm { height: 30px; padding: 0 10px; font-size: 0.8125rem; gap: 6px; }
.btn-block { width: 100%; height: 40px; }

/* Login */
.login { height: 100dvh; display: grid; overflow-y: auto; overscroll-behavior: contain; padding: 24px 16px; background: var(--panel); }
.login-theme { position: fixed; top: calc(16px + env(safe-area-inset-top)); right: 16px; }
/* margin:auto centers when there is room and still lets a short screen (keyboard open) scroll to the top. */
.login-card { width: 100%; margin: auto; max-width: 380px; padding: 32px; border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--bg); box-shadow: var(--shadow-pop); }
.login-card .logo { margin-bottom: 20px; }
.login-card h1 { margin: 0; font-size: 1.375rem; font-weight: 600; letter-spacing: -0.015em; }
.login-sub { margin: 6px 0 24px; color: var(--muted); font-size: 0.875rem; }
.login-form { display: grid; gap: 16px; }
.field { display: grid; gap: 6px; font-size: 0.8125rem; font-weight: 500; }
.field input { height: 40px; padding: 0 12px; border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--bg); color: var(--ink); font: inherit; font-size: 0.9375rem; transition: border-color 150ms var(--ease-out), box-shadow 150ms var(--ease-out); }
.field input::placeholder { color: var(--muted); }
.field input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-soft); }
.login-foot { margin: 20px 0 0; color: var(--muted); font-size: 0.75rem; text-align: center; }
.field-hint, .login-foot a, .forgot { color: var(--primary); font-size: 0.75rem; font-weight: 400; text-decoration: none; }
.field-hint:hover, .login-foot a:hover, .forgot:hover { text-decoration: underline; }
.forgot { justify-self: end; margin-top: -8px; }
.error { margin: 0; color: var(--danger); font-size: 0.8125rem; }
.callout { display: flex; gap: 8px; align-items: flex-start; margin: 0 0 20px; padding: 10px 12px; border-radius: var(--radius); background: var(--next-soft); color: var(--ink); font-size: 0.8125rem; }
.callout svg { flex: none; margin-top: 2px; color: var(--next-text); }

/* Logo */
.logo { display: grid; place-items: center; flex: none; width: 28px; height: 28px; border-radius: 7px; background: var(--primary); color: oklch(1 0 0); }
.logo-lg { width: 40px; height: 40px; border-radius: 10px; }

/* Shell: sidebar | main. position:relative contains .sr-only (position:absolute) so it cannot stretch the document;
   svh, not dvh, so a phone's toolbar cannot make the shell taller than the visible area. */
.shell { --header-h: 56px; --sidebar-w: 240px; --sidebar-rail: 64px; position: relative; display: flex; height: 100svh; overflow: hidden; }

/* Sidebar: pinned header, scrolling body, pinned footer. */
.sidebar { flex: none; z-index: var(--z-drawer); display: flex; flex-direction: column; width: var(--sidebar-w); overflow-x: hidden; border-right: 1px solid var(--line); background: var(--panel); transition: width 200ms var(--ease-out); }
.sidebar-head { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 8px; height: var(--header-h); padding: 0 12px 0 16px; border-bottom: 1px solid var(--line); }
.brand { display: flex; align-items: center; gap: 10px; min-width: 0; font-weight: 600; font-size: 1rem; letter-spacing: -0.015em; }
.brand-name { white-space: nowrap; }
.sidebar-body { flex: 1; min-height: 0; overflow-y: auto; display: grid; align-content: start; gap: 4px; padding: 16px 12px 12px; }
.sidebar-foot { flex: none; display: grid; gap: 4px; padding: 12px; border-top: 1px solid var(--line); }
.icon-btn { display: grid; place-items: center; flex: none; width: 32px; height: 32px; border: 0; border-radius: 8px; background: none; color: var(--muted); transition: background-color 150ms var(--ease-out), color 150ms var(--ease-out); }
/* Phone-only controls (shown in the phone block below); after .icon-btn so its display:grid does not win. */
.sidebar-close, .sidebar-trigger, .sidebar-backdrop { display: none; }
.icon-btn:hover { background: var(--surface-2); color: var(--ink); }
.icon-btn-danger:hover { background: var(--danger-soft); color: var(--danger); }
.nav-item { display: flex; align-items: center; gap: 10px; width: 100%; height: 40px; padding: 0 8px; border: 0; border-radius: 10px; background: none; color: var(--muted); font-size: 0.875rem; font-weight: 500; text-align: left; white-space: nowrap; transition: background-color 150ms var(--ease-out), color 150ms var(--ease-out), box-shadow 150ms var(--ease-out); }
.nav-item:hover { background: var(--surface-2); color: var(--ink); }
/* Each item leads with an icon tile; the current page lifts onto a raised surface and its tile turns primary. */
/* Theme: two named tabs, the current one raised (icons only on the collapsed rail). */
.theme-tabs { position: relative; display: grid; grid-template-columns: 1fr 1fr; gap: 2px; padding: 3px; border-radius: 10px; background: color-mix(in oklab, var(--panel), var(--ink) 8%); } /* not --surface-2: that is nearly the sidebar's own colour */
/* The raised pill is one element that slides to the chosen tab (down, on the collapsed rail), not a background that swaps. */
.theme-tabs::before { content: ""; position: absolute; top: 3px; bottom: 3px; left: 3px; width: calc((100% - 8px) / 2); border-radius: 8px; background: var(--bg); box-shadow: 0 0 0 1px var(--line), 0 1px 2px oklch(0 0 0 / 0.05); transition: transform 240ms var(--ease-out); }
.theme-tabs[data-value="dark"]::before { transform: translateX(calc(100% + 2px)); }
.theme-tab { position: relative; display: flex; align-items: center; justify-content: center; gap: 6px; height: 32px; border: 0; border-radius: 8px; background: none; color: var(--muted); font-size: 0.8125rem; font-weight: 500; transition: color 150ms var(--ease-out); }
.theme-tab:hover { color: var(--ink); }
.theme-tab[aria-checked="true"] { color: var(--ink); }
.nav-icon { display: grid; place-items: center; flex: none; width: 26px; height: 26px; border-radius: 8px; background: var(--surface-2); transition: background-color 150ms var(--ease-out), color 150ms var(--ease-out); }
.nav-item:hover .nav-icon { background: var(--bg); }
.nav-item[aria-current="page"] { background: var(--bg); color: var(--ink); box-shadow: 0 0 0 1px var(--line), 0 1px 2px oklch(0 0 0 / 0.05); }
.nav-item[aria-current="page"] .nav-icon { background: var(--primary); color: oklch(1 0 0); }
/* Rail: icons only. Desktop only; phones always get the full drawer. */
@media (min-width: 801px) {
  .shell[data-collapsed] .sidebar { width: var(--sidebar-rail); }
  .shell[data-collapsed] .sidebar-head { justify-content: center; padding: 0; }
  .shell[data-collapsed] :is(.brand, .nav-label, .theme-tab-label) { display: none; }
  .shell[data-collapsed] .theme-tabs { grid-template-columns: 1fr; }
  .shell[data-collapsed] .theme-tabs::before { right: 3px; bottom: auto; width: auto; height: calc((100% - 8px) / 2); }
  .shell[data-collapsed] .theme-tabs[data-value="dark"]::before { transform: translateY(calc(100% + 2px)); }
  .shell[data-collapsed] .nav-item { justify-content: center; padding: 0; }
}

/* Main: one header (as tall as the sidebar's) over the page body. Only the body scrolls; content fills the full width. */
.app-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.page { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.app-header { flex: none; display: flex; align-items: center; gap: 12px; height: var(--header-h); padding: 0 24px; border-bottom: 1px solid var(--line); background: var(--bg); }
.header-text { flex: 1; min-width: 0; display: grid; }
.header-title { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.header-title h1 { flex: 0 1 auto; margin: 0; overflow: hidden; font-size: 1rem; font-weight: 600; letter-spacing: -0.01em; line-height: 1.35; text-overflow: ellipsis; white-space: nowrap; }
.header-sub { flex: 1 1 0; min-width: 0; margin: 0; overflow: hidden; color: var(--muted); font-size: 0.8125rem; text-overflow: ellipsis; white-space: nowrap; }
.header-actions, .page-actions { flex: none; display: flex; align-items: center; gap: 8px; }
.crumb { display: inline-flex; align-items: center; gap: 2px; }
.crumbs { display: flex; align-items: center; gap: 2px; margin: 0; overflow: hidden; color: var(--muted); font-size: 0.75rem; line-height: 1.3; white-space: nowrap; }
.crumbs a { transition: color 150ms var(--ease-out); }
.crumbs a:hover { color: var(--ink); }
.crumbs svg { color: var(--faint); }
.page-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 16px; }
.page-content { width: 100%; }
/* A page whose single card fills it (the course page): the body holds still, the card's own content scrolls. */
.page-body.page-fill { display: flex; flex-direction: column; overflow: hidden; }
.page-fill > .page-content { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.hint { display: flex; align-items: center; gap: 6px; margin: 0 0 16px; color: var(--muted); font-size: 0.8125rem; }

/* Progress */
.progress { display: grid; gap: 8px; min-width: min(220px, 100%); }
.progress-label { display: flex; justify-content: space-between; gap: 12px; font-size: 0.8125rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.progress-label b { color: var(--ink); font-weight: 600; }
.bar { height: 6px; border-radius: 3px; background: var(--surface-2); overflow: hidden; }
.course-progress { margin-bottom: 14px; }
.scheme-layout { display: grid; grid-template-columns: 200px 1fr; align-items: center; gap: 24px 32px; }
.scheme-donut { width: 100%; max-width: 200px; justify-self: center; }
.scheme-track { stroke: var(--surface-2); }
.scheme-arc { stroke-linecap: butt; animation: arc-draw 700ms var(--ease-out) backwards; }
@keyframes arc-draw { from { stroke-dasharray: 0 var(--c); } }
.scheme-total-num { fill: var(--ink); font-size: 17px; font-weight: 600; font-variant-numeric: tabular-nums; }
.scheme-total-cap { fill: var(--muted); font-size: 7px; }
.scheme { display: grid; margin: 0; padding: 0; border: 1px solid var(--line); border-radius: var(--radius-lg); list-style: none; overflow: hidden; }
.scheme li { display: grid; grid-template-columns: 1fr auto; align-items: baseline; gap: 10px 16px; padding: 14px 16px; border-bottom: 1px solid var(--line); animation: scheme-in 320ms var(--ease-out) backwards; animation-delay: calc(var(--i) * 70ms + 150ms); }
.scheme li:last-child { border-bottom: 0; }
.scheme-name { display: flex; align-items: baseline; gap: 10px; font-weight: 500; }
.scheme-name i { flex: none; width: 10px; height: 10px; border-radius: 3px; background: var(--c); transform: translateY(1px); }
.scheme-name small { display: block; color: var(--muted); font-size: 0.8125rem; font-weight: 400; }
.scheme b { font-variant-numeric: tabular-nums; font-weight: 600; }
.scheme .bar { grid-column: 1 / -1; }
.scheme .bar span { background: var(--c); transform-origin: left; animation: bar-grow 600ms var(--ease-out) backwards; animation-delay: calc(var(--i) * 110ms); }
@keyframes scheme-in { from { opacity: 0; transform: translateY(6px); } }
@keyframes bar-grow { from { transform: scaleX(0); } }
.scheme-total { margin: 12px 0 0; font-variant-numeric: tabular-nums; }
@media (max-width: 640px) { .scheme-layout { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) { .scheme-arc, .scheme li, .scheme .bar span { animation: none; } }
.lessons-bar { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 0 24px; }
.lessons-bar .progress { flex: 1 1 260px; }
.bar > span { display: block; height: 100%; border-radius: inherit; background: var(--ok); transition: width 400ms var(--ease-out); }

/* Course cards */
.course-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr)); gap: 16px; }
.course-card { position: relative; display: flex; flex-direction: column; gap: 14px; padding: 18px; border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--bg); transition: border-color 150ms var(--ease-out), box-shadow 150ms var(--ease-out); }
.course-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.code { padding: 2px 8px; border-radius: 6px; background: var(--surface-2); font-size: 0.75rem; font-weight: 600; letter-spacing: 0.01em; font-variant-numeric: tabular-nums; }
.credits { color: var(--muted); font-size: 0.75rem; }
.course-card h2 { margin: 0; font-size: 1rem; font-weight: 600; line-height: 1.35; letter-spacing: -0.01em; }
.course-card .category { margin: 4px 0 0; color: var(--muted); font-size: 0.8125rem; }
.instructor { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: 0.8125rem; }
.avatar { flex: none; width: 28px; height: 28px; border-radius: 50%; object-fit: cover; object-position: top; background: var(--surface-2); }
.course-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: auto; padding-top: 14px; border-top: 1px solid var(--line); font-size: 0.8125rem; }
.up-next { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); }
.up-next b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.dot { width: 8px; height: 8px; border-radius: 50%; background: var(--next); }
.course-card.closed { background: var(--panel); }
.course-card.closed h2 { color: var(--muted); }
.tags { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; padding: 0; list-style: none; }
.tags li { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border: 1px dashed var(--line); border-radius: 999px; color: var(--faint); font-size: 0.75rem; }
/* VU enables a section tile only when it has something in it. */
.tags li.on { border: 1px solid var(--primary); background: var(--primary-soft); color: var(--ink); font-weight: 500; }
.tags li.on svg { color: var(--primary-text); }
.tags li:has(> a) { padding: 0; }
.tags li > a { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: inherit; transition: background-color 150ms var(--ease-out); }
.tags li > a:hover { background: var(--primary); color: oklch(1 0 0); }
.tags li > a:hover svg { color: inherit; }

/* Lesson list */
.lessons { margin: 0; padding: 0; list-style: none; overflow: hidden; }
.lesson { display: grid; grid-template-columns: 28px 1fr auto; align-items: center; gap: 14px; padding: 12px 16px; border-bottom: 1px solid var(--line); transition: background-color 150ms var(--ease-out); }
.lesson:last-child { border-bottom: 0; }
.lesson:hover { background: var(--panel); }
.lesson.next { background: var(--next-soft); }
.lesson-main { min-width: 0; display: grid; gap: 4px; }
.lesson-name { overflow: hidden; font-weight: 500; text-overflow: ellipsis; white-space: nowrap; }
a.lesson-name { transition: color 150ms var(--ease-out); }
a.lesson-name:hover { color: var(--primary-text); }
.lesson.locked .lesson-name { color: var(--muted); font-weight: 400; }
.lesson-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; color: var(--muted); font-size: 0.75rem; }
.lesson-meta > span { display: inline-flex; align-items: center; gap: 4px; }
.status { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; border: 1.5px solid var(--line-strong); color: var(--muted); font-size: 0.75rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.status.done { border-color: var(--ok); background: var(--ok); color: oklch(1 0 0); }
.status.next { border-color: var(--next); color: var(--next-text); }
.status.locked { border-style: dashed; color: var(--faint); }
.pill-ok { display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 12px; border-radius: 999px; background: var(--ok-soft); color: var(--ok); font-size: 0.8125rem; font-weight: 600; }
.next-label { color: var(--next-text); font-weight: 600; }

/* Lesson groups: Completed (collapsed <details>), Up next, Remaining. */
.lesson-list { margin: 0; padding: 0; list-style: none; }
.lesson-group + .lesson-group { border-top: 1px solid var(--line); }
.group-head { display: flex; align-items: center; gap: 8px; margin: 0; padding: 10px var(--pad); border-bottom: 1px solid var(--line); background: var(--panel); color: var(--muted); font-size: 0.8125rem; font-weight: 600; list-style: none; }
.group-head::-webkit-details-marker { display: none; }
summary.group-head { cursor: pointer; transition: background-color 150ms var(--ease-out), color 150ms var(--ease-out); }
summary.group-head:hover { background: var(--surface-2); color: var(--ink); }
details.lesson-group:not([open]) > summary.group-head { border-bottom: 0; }
.group-icon.completed { color: var(--ok); }
.group-icon.active { color: var(--next-text); }
.group-more { display: block; padding: 12px var(--pad); border-top: 1px solid var(--line); color: var(--primary-text); font-size: 0.8125rem; font-weight: 500; text-align: center; transition: background-color 150ms var(--ease-out); }
.group-more:hover { background: var(--surface-2); }
.group-count { padding: 0 8px; border-radius: 999px; background: var(--surface-2); color: var(--muted); font-size: 0.75rem; font-variant-numeric: tabular-nums; }
.group-head .chevron { margin-left: auto; transition: transform 150ms var(--ease-out); }
details.lesson-group[open] > summary .chevron { transform: rotate(90deg); }
@media (prefers-reduced-motion: reduce) { .group-head .chevron { transition-duration: 0.01ms; } }

/* Course page: the card body holds a stage that slides the new tab's panel in from the clicked tab's side. */
.card-body.flush > .section-stage { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow-x: clip; }
.section-panel { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow-y: auto; overscroll-behavior: contain; }
.section-panel > * { flex: none; }
/* A list panel: the bar and hint above stay put and only the list scrolls. Any other panel scrolls as a whole. */
.section-panel > .lessons { flex: 0 1 auto; min-height: min(10rem, 100%); overflow-y: auto; overscroll-behavior: contain; border-top: 1px solid var(--line); }
.section-panel:has(> .lessons) > :not(.lessons, dialog) { margin-inline: var(--pad); }
.section-panel:has(> .lessons) > :first-child:not(.lessons) { margin-top: 16px; }
.section-panel:not(:has(> .lessons)) { padding: var(--pad); }
.section-stage[data-dir='next'] .section-panel { animation: panel-in-next 240ms var(--ease-out) both; }
.section-stage[data-dir='prev'] .section-panel { animation: panel-in-prev 240ms var(--ease-out) both; }
@keyframes panel-in-next { from { opacity: 0; transform: translateX(28px); } }
@keyframes panel-in-prev { from { opacity: 0; transform: translateX(-28px); } }
@media (prefers-reduced-motion: reduce) { .section-stage .section-panel { animation: none !important; } }
.activity.next { background: var(--next-soft); }
.activity.next .due b { color: var(--next-text); }
.activity.urgent { background: var(--danger-soft); }
.activity.urgent .due b, .status.urgent { color: var(--danger); }
.status.urgent { border-color: var(--danger); }
.status.missed { border-color: var(--line); border-style: dashed; color: var(--faint); }
.activity.missed .lesson-name { color: var(--muted); font-weight: 400; }
.due b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.pill-sm { height: 24px; padding: 0 10px; font-size: 0.75rem; }
.pill-warn { display: inline-flex; align-items: center; border-radius: 999px; background: var(--next-soft); color: var(--next-text); font-weight: 600; white-space: nowrap; }
.opens { color: var(--next-text); font-weight: 600; font-variant-numeric: tabular-nums; }
.hint b { color: var(--ink); font-weight: 600; }
/* Lesson progress toward a quiz's reading dependency. */
.gate { display: flex; align-items: center; gap: 10px; max-width: 360px; color: var(--muted); font-size: 0.75rem; font-variant-numeric: tabular-nums; }
.gate-bar { flex: 1; height: 4px; border-radius: 999px; background: var(--line); overflow: hidden; }
.gate-bar i { display: block; height: 100%; border-radius: inherit; background: var(--primary); }
.gate span { flex: none; }
.new-label { padding: 1px 8px; border-radius: 999px; background: var(--primary-soft); color: var(--primary-text); font-weight: 600; }
.announcement { border-bottom: 1px solid var(--line); }
.announcement:last-child { border-bottom: 0; }
.announcement > .lesson-main, .ann-row { padding: 12px var(--pad); }
.ann-row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 14px; width: 100%; border: 0; background: none; color: inherit; font: inherit; text-align: left; list-style: none; cursor: pointer; transition: background-color 150ms var(--ease-out); }
.ann-row::-webkit-details-marker { display: none; }
.ann-row:hover { background: var(--panel); }
.ann-row .lesson-name { white-space: normal; }
.ann-row .chevron { color: var(--muted); transition: transform 150ms var(--ease-out); }
.ann-row:hover .chevron { transform: translateX(2px); }
.announcement details[open] > .ann-row .chevron { transform: rotate(90deg); }
/* The text opens inline under its row, indented under the title, with a hairline tying it to the row above. */
.ann-content { padding: 4px var(--pad) 18px; }
.ann-content .prose { max-width: 80ch; }
.announcement details[open] > .ann-row { background: var(--panel); }
@media (prefers-reduced-motion: reduce) { .ann-row, .ann-row .chevron { transition-duration: 0.01ms; } .ann-row:hover .chevron { transform: none; } }

.panels { display: grid; gap: 16px; }
/* Empty state: no border of its own (the card around it is the box); it takes all the room it is given and centres in it on both axes. */
.empty { display: grid; justify-items: center; align-content: center; gap: 6px; padding: 32px 24px; color: var(--muted); text-align: center; }
.section-panel > .empty { flex: 1 1 auto; }
.page-body > .empty { min-height: 100%; }
.empty h2 { margin: 6px 0 0; color: var(--ink); font-size: 1rem; font-weight: 600; }
.empty p { max-width: 44ch; margin: 0; font-size: 0.875rem; }

/* Course run dialog */
.run-dialog { width: min(560px, calc(100vw - 32px)); max-height: 80dvh; padding: 24px; border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--bg); color: var(--ink); box-shadow: var(--shadow-pop); }
.run-dialog::backdrop { background: oklch(0 0 0 / 0.45); }
.run-dialog h2 { margin: 0 0 16px; font-size: 1.0625rem; font-weight: 600; }
.run-summary { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin: 10px 0; color: var(--muted); font-size: 0.8125rem; font-variant-numeric: tabular-nums; }
.run-note { margin: 4px 0 8px; font-size: 0.875rem; }
.run-list { max-height: 45dvh; overflow: auto; margin: 12px 0 20px; padding: 0; border: 1px solid var(--line); border-radius: var(--radius); list-style: none; }
.run-list li { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border-bottom: 1px solid var(--line); font-size: 0.8125rem; }
.run-list li:last-child { border-bottom: 0; }
.run-list li > svg { flex: none; margin-top: 2px; }
.run-list .done > svg { color: var(--ok); }
.run-list .failed > svg { color: var(--danger); }
.run-lesson { display: grid; gap: 2px; flex: 1; }
.run-lesson small { color: var(--danger); }
.run-lesson small.score { color: var(--muted); }
.run-list a { color: var(--primary-text); text-decoration: underline; text-underline-offset: 2px; white-space: nowrap; }
.run-actions { display: flex; justify-content: flex-end; }

/* Lesson viewer */
.viewer-tabs { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; border-bottom: 1px solid var(--line); }
.viewer-tabs [role=tab] { display: inline-flex; align-items: center; gap: 8px; height: 40px; margin-bottom: -1px; padding: 0 12px; border: 0; border-bottom: 2px solid transparent; background: none; color: var(--muted); font-size: 0.875rem; font-weight: 500; transition: color 150ms var(--ease-out), border-color 150ms var(--ease-out); }
.viewer-tabs [role=tab]:hover:not(:disabled) { color: var(--ink); }
.viewer-tabs [role=tab][aria-selected=true] { border-bottom-color: var(--primary); color: var(--ink); }
.viewer-tabs [role=tab]:disabled { color: var(--faint); cursor: not-allowed; }
.viewer-tabs .tab-done { color: var(--ok); }
.viewer-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; padding: 4px 0; }
.tab-status-bar { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px 16px; margin: 16px 0; }
.tab-status { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 0; color: var(--muted); font-size: 0.875rem; }
.tab-status.ok { color: var(--ok); font-weight: 500; }
.mark-complete { display: flex; align-items: center; flex-wrap: wrap; justify-content: flex-end; gap: 10px; }
.content-frame { display: block; width: 100%; height: 72dvh; border: 1px solid var(--line); border-radius: var(--radius-lg); background: oklch(1 0 0); }
/* No background on the frame itself: a dark fill fringes through the rounded corners of a light thumbnail. */
/* The ring keeps the edge visible when a white thumbnail meets a white page. */
.video-frame { aspect-ratio: 16 / 9; overflow: hidden; isolation: isolate; border-radius: var(--radius-lg); box-shadow: 0 0 0 1px var(--line); }
.video-frame iframe { background: oklch(0 0 0); }
.video-frame > * { width: 100%; height: 100%; border: 0; }
.video-facade { position: relative; display: grid; place-items: center; padding: 0; border-radius: inherit; background: var(--surface-2); cursor: pointer; }
.video-facade img { object-fit: cover; }
.video-facade::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, oklch(0 0 0 / 0.55), transparent 35%); pointer-events: none; }
.video-caption { position: absolute; inset: auto 20px 16px; z-index: 1; display: flex; justify-content: space-between; align-items: center; color: oklch(1 0 0); font-size: 0.875rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.video-caption span:last-child { padding: 2px 8px; border-radius: 6px; background: oklch(0 0 0 / 0.6); font-size: 0.8125rem; }
.play-btn { position: relative; z-index: 1; display: grid; place-items: center; width: 72px; height: 72px; padding-left: 4px; border-radius: 50%; background: oklch(0 0 0 / 0.6); color: oklch(1 0 0); transition: background-color 150ms var(--ease-out), transform 150ms var(--ease-out); }
.video-facade:hover .play-btn { background: var(--primary); transform: scale(1.06); }

/* Shared card (components/card.tsx): optional header (title, or tab row), body, footer. */
.card { --pad: 20px; display: flex; flex-direction: column; min-width: 0; border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--bg); }
.card-head { flex: none; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; min-height: 52px; padding: 10px var(--pad); border-bottom: 1px solid var(--line); background: var(--panel); }
.card-title { margin: 0; font-size: 1rem; font-weight: 600; letter-spacing: -0.01em; }
.card-meta { margin: 2px 0 0; color: var(--muted); font-size: 0.8125rem; font-variant-numeric: tabular-nums; }
.card-meta b { color: var(--ink); font-weight: 600; }
.card-body { display: grid; gap: 18px; min-width: 0; padding: var(--pad); }
.card-body.flush { display: flex; flex-direction: column; gap: 0; padding: 0; }
.card-foot { flex: none; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px 12px; padding: 12px var(--pad); border-top: 1px solid var(--line); background: var(--panel); border-radius: 0 0 calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px); }
/* The first strip (title or tabs) takes the card's top corners; the card itself does not clip, so menus can hang out of it. */
.card > :first-child:is(.card-head, .card-tabs) { border-radius: calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px) 0 0; }
/* A card with no header: its body is the first thing in the box, so it takes the rounded corners (strips inside would poke past them). */
.card > .card-body.flush:first-child { border-radius: calc(var(--radius-lg) - 1px); }
.card:not(.card-fill) > .card-body.flush:first-child { overflow: clip; } /* never on a fill card: clip would switch its scrolling off */
.card-fill { flex: 1; min-height: 0; }
.card-fill > .card-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.card-fill > .card-body:last-child { border-radius: 0 0 calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px); }

/* Tab row as a card header: a priority+ row (components/overflow-tabs.tsx). */
.card-tabs { flex: none; display: flex; align-items: center; border-bottom: 1px solid var(--line); background: var(--panel); }
.tabs-track { position: relative; flex: 1; min-width: 0; overflow: hidden; }
.tabs-scroll { display: flex; align-items: center; overflow-x: auto; }
/* No row padding: the first tab starts at the card edge (its underline too) and carries the card padding itself, so its label lines up with the content below. */
.tabs-list { display: flex; align-items: center; gap: 4px; }
.tabs-list > .tab:first-child { padding-left: var(--pad); }
.tab { flex: none; display: inline-flex; align-items: center; height: 44px; padding: 0 12px; border: 0; background: none; box-shadow: inset 0 -2px 0 transparent; color: var(--muted); font-size: 0.875rem; font-weight: 500; white-space: nowrap; transition: color 150ms var(--ease-out), box-shadow 150ms var(--ease-out); }
.tab:hover { color: var(--ink); }
.tab[aria-current] { color: var(--ink); box-shadow: inset 0 -2px 0 var(--primary); }
/* Hidden twin of the row: every tab with the live row's classes, measured to decide what fits. */
.tabs-mirror { position: absolute; top: 0; left: 0; visibility: hidden; pointer-events: none; }
.tabs-more-stand { flex: none; width: 40px; height: 1px; }
.tabs-more-wrap { position: relative; flex: none; padding-right: 8px; }
.tabs-menu { position: absolute; top: calc(100% + 6px); right: 8px; z-index: var(--z-menu); display: grid; gap: 2px; width: 13rem; padding: 4px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); box-shadow: var(--shadow-pop); }
.tabs-menu-item { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 36px; padding: 0 10px; border: 0; border-radius: 6px; background: none; color: var(--muted); font-size: 0.875rem; text-align: left; }
.tabs-menu-item:hover { background: var(--surface-2); color: var(--ink); }
.tabs-menu-item[aria-current] { background: var(--surface-2); color: var(--primary-text); font-weight: 500; }

/* Shared typography for VU HTML (components/rich-html.tsx with className="prose"). */
.prose { min-width: 0; max-width: 72ch; line-height: 1.7; text-wrap: pretty; overflow-wrap: anywhere; }
.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }
.prose p { margin: 0 0 0.9em; }
.prose h1 { margin: 0 0 0.7em; font-size: 1.375rem; font-weight: 600; letter-spacing: -0.015em; line-height: 1.3; }
.prose h2 { margin: 1.8em 0 0.6em; padding-top: 1.2em; border-top: 1px solid var(--line); font-size: 1.125rem; font-weight: 600; letter-spacing: -0.01em; line-height: 1.35; }
.prose > h2:first-child { padding-top: 0; border-top: 0; }
.prose h3 { margin: 1.4em 0 0.5em; font-size: 1rem; font-weight: 600; line-height: 1.4; }
.prose h4, .prose h5, .prose h6 { margin: 1.2em 0 0.4em; font-size: 0.9375rem; font-weight: 600; }
.prose :is(h2, h3, h4) :is(u, em) { text-decoration: none; font-style: normal; }
.prose ul, .prose ol { margin: 0 0 1em; padding-left: 1.4em; }
.prose li { margin: 0.3em 0; padding-left: 0.2em; }
.prose li::marker { color: var(--muted); }
.prose li > :is(ul, ol) { margin: 0.3em 0 0.4em; }
.prose a { color: var(--primary-text); text-decoration: underline; text-underline-offset: 2px; }
.prose strong, .prose b { font-weight: 600; }
.prose img { display: block; max-width: 100%; height: auto; margin: 1em auto; border: 1px solid var(--line); border-radius: var(--radius); }
.prose li img, .prose td img { display: inline-block; margin: 0.3em 0; }
.prose hr { margin: 2em 0; border: 0; border-top: 1px dashed var(--line-strong); }
.prose blockquote { margin: 1em 0; padding: 0.6em 1em; border-radius: var(--radius); background: var(--panel); }
.prose code, .prose pre { font-family: ui-monospace, SFMono-Regular, Consolas, monospace; font-size: 0.875em; }
.prose pre { overflow-x: auto; padding: 12px 14px; border-radius: var(--radius); background: var(--panel); }
.prose .table-wrap { overflow-x: auto; margin: 1em 0; border: 1px solid var(--line); border-radius: var(--radius); }
.prose table { width: max-content; min-width: 100%; border-collapse: collapse; font-size: 0.875rem; }
/* min-width: columns stop at a readable width and the table scrolls inside .table-wrap instead of wrapping letters. */
.prose td, .prose th { min-width: 6.5rem; overflow-wrap: normal; padding: 8px 12px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.prose tr:last-child > * { border-bottom: 0; }
.prose tr:first-child > :is(th, td) { background: var(--panel); font-weight: 600; }
.prose td > :last-child, .prose th > :last-child { margin-bottom: 0; }
.prose .pdf-handout a { display: inline-flex; align-items: center; height: 36px; padding: 0 14px; border-radius: var(--radius); background: var(--primary); color: oklch(1 0 0); font-weight: 500; text-decoration: none; }
.reading { font-size: 0.9375rem; }
.reading-end { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; margin-top: 16px; padding: 14px 18px; border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--panel); color: var(--muted); font-size: 0.875rem; }

/* Quiz */
.quiz-score { display: grid; justify-items: end; margin: 0; }
.quiz-score span { color: var(--muted); font-size: 0.75rem; }
.quiz-score b { font-size: 1.25rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.quiz-timer { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border-radius: 999px; background: var(--surface-2); color: var(--muted); font-size: 0.8125rem; font-weight: 600; font-variant-numeric: tabular-nums; transition: background-color 150ms var(--ease-out), color 150ms var(--ease-out); }
.quiz-timer.low { background: var(--danger-soft); color: var(--danger); }
.card > .bar { margin-top: -6px; }
.card > .bar > span { background: var(--primary); }
.prose.quiz-question { font-size: 1.0625rem; font-weight: 500; line-height: 1.55; }
/* Options and review rows are single lines of VU HTML: no block spacing. */
.quiz-option .prose > *, .quiz-review .prose > * { margin-block: 0; }
.quiz-options { display: grid; gap: 8px; min-width: 0; margin: 0; padding: 0; border: 0; }
.quiz-option { position: relative; display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 12px; padding: 12px 14px; border: 1px solid var(--line-strong); border-radius: var(--radius); cursor: pointer; transition: background-color 150ms var(--ease-out), border-color 150ms var(--ease-out); }
.quiz-option:hover { background: var(--panel); }
.quiz-option input { position: absolute; opacity: 0; pointer-events: none; }
.quiz-option:has(input:focus-visible) { outline: 2px solid var(--primary); outline-offset: 2px; }
.quiz-option:has(input:checked) { border-color: var(--primary); background: var(--primary-soft); }
.quiz-letter { display: grid; place-items: center; width: 26px; height: 26px; border: 1.5px solid var(--line-strong); border-radius: 50%; color: var(--muted); font-size: 0.75rem; font-weight: 600; transition: background-color 150ms var(--ease-out), border-color 150ms var(--ease-out), color 150ms var(--ease-out); }
.quiz-option:has(input:checked) .quiz-letter { border-color: var(--primary); background: var(--primary); color: oklch(1 0 0); }
.quiz-options:disabled .quiz-option { opacity: 0.6; cursor: progress; }
.quiz-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
.quiz-keys { color: var(--muted); font-size: 0.75rem; }
.quiz-keys kbd { padding: 1px 5px; border: 1px solid var(--line-strong); border-bottom-width: 2px; border-radius: 4px; font: inherit; font-size: 0.6875rem; }
.quiz-review { margin: 0; padding: 0; border: 1px solid var(--line); border-radius: var(--radius); list-style: none; }
.quiz-review li { display: grid; grid-template-columns: 22px 1fr; align-items: start; gap: 10px; padding: 10px 12px; border-bottom: 1px solid var(--line); font-size: 0.875rem; }
.quiz-review li:last-child { border-bottom: 0; }
.quiz-review li > svg { margin-top: 3px; }
.quiz-review .right > svg { color: var(--ok); }
.quiz-review .wrong > svg { color: var(--danger); }

/* Loading skeleton */
/* Skeletons: a soft highlight sweeps across (static under reduced motion). */
:root { --sk-base: color-mix(in oklab, var(--surface-2), var(--ink) 6%); --sk-shimmer: linear-gradient(90deg, var(--sk-base) 30%, var(--surface-2) 50%, var(--sk-base) 70%) 100% 0 / 300% 100%; }
.skeleton { display: block; flex: none; max-width: 100%; border-radius: var(--radius); background: var(--sk-shimmer); animation: shimmer 1.5s ease-in-out infinite; }
.skeleton-round { border-radius: 50%; }
.skeleton-pill { border-radius: 999px; }
@keyframes shimmer { to { background-position: 0 0; } }
.sk-lines { display: grid; gap: 8px; min-width: 0; }

/* Skeleton mode: a tab's real view drawn with placeholder data (components in tab-skeleton.tsx). Text goes transparent
   (icons too: they draw with currentColor); every element that holds only text, or an icon with text, becomes a
   shimmering bar, and circles, buttons and pills become shimmering shapes. So the skeleton IS the real layout. */
.is-skeleton, .is-skeleton * { color: transparent !important; }
.is-skeleton { pointer-events: none; user-select: none; }
.is-skeleton :is(span, a, p, b, small, strong, h1, h2, h3):is(:not(:has(*)), :has(> svg)),
.is-skeleton :is(.hint, .progress-label > span) { justify-self: start; max-width: 100%; border-radius: 4px; background: var(--sk-shimmer); animation: shimmer 1.5s ease-in-out infinite; }
.is-skeleton :is(p, small, h1, h2, h3, .hint) { width: fit-content; }
.is-skeleton .hint b { background: none; animation: none; } /* one bar for the whole line, not one inside another */
.is-skeleton :is(.status, .btn, .pill-ok, .pill-warn, .new-label, .group-count) { border-color: transparent; background: var(--sk-shimmer); animation: shimmer 1.5s ease-in-out infinite; }
.is-skeleton .status { border-radius: 50%; }
.is-skeleton .group-head { background: var(--panel); animation: none; } /* the tinted strip stays; only its label becomes a bar */
.is-skeleton :is(.bar > span, .gate-bar i, .scheme-name i) { background: var(--sk-base); animation: none; }
.is-skeleton .scheme-arc { stroke: var(--sk-base); animation: none; }
.is-skeleton :is(.scheme-total-num, .scheme-total-cap) { fill: transparent; }
@media (prefers-reduced-motion: reduce) { .is-skeleton, .is-skeleton * { animation: none !important; } }
.sk-strip { display: grid; gap: 10px; padding: 18px var(--pad, 20px) 16px; border-bottom: 1px solid var(--line); }
.sk-tabs { align-items: center; gap: 28px; padding: 0 var(--pad, 20px); height: 44px; overflow: hidden; }
.sk-viewer-tabs { display: flex; border-bottom: 1px solid var(--line); padding: 0; }
.sk-lesson-body { display: grid; gap: 16px; }
.sk-player { width: 100%; aspect-ratio: 16 / 9; border-radius: var(--radius-lg); }

/* Motion: short and quiet. Content rises in once when a page opens, the first rows/cards follow a beat apart, panels
   (menu, completed group) ease open, cards and buttons answer hover and press. All of it is off under reduced motion. */
:root { interpolate-size: allow-keywords; }
@keyframes rise { from { opacity: 0; transform: translateY(6px); } }
@keyframes menu-in { from { opacity: 0; transform: translateY(-4px) scale(0.98); } }
.page:not(.loading) .page-content { animation: rise 220ms var(--ease-out) both; }
.course-grid > :nth-child(-n+9), .lesson-list > .lesson:nth-child(-n+8) { animation: rise 260ms var(--ease-out) both; }
.course-grid > :nth-child(2), .lesson-list > :nth-child(2) { animation-delay: 30ms; }
.course-grid > :nth-child(3), .lesson-list > :nth-child(3) { animation-delay: 60ms; }
.course-grid > :nth-child(4), .lesson-list > :nth-child(4) { animation-delay: 90ms; }
.course-grid > :nth-child(5), .lesson-list > :nth-child(5) { animation-delay: 120ms; }
.course-grid > :nth-child(6), .lesson-list > :nth-child(6) { animation-delay: 150ms; }
.course-grid > :nth-child(7), .lesson-list > :nth-child(7) { animation-delay: 180ms; }
.course-grid > :nth-child(8), .lesson-list > :nth-child(8) { animation-delay: 210ms; }
.course-grid > :nth-child(9) { animation-delay: 240ms; }
.course-card:hover { border-color: var(--line-strong); box-shadow: 0 1px 2px oklch(0 0 0 / 0.04), 0 6px 16px oklch(0 0 0 / 0.05); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.tabs-menu { transform-origin: top right; animation: menu-in 140ms var(--ease-out); }
.bar > span { transform-origin: left; animation: bar-grow 600ms var(--ease-out) backwards; }
/* Completed group: height eases open (Chromium's ::details-content; elsewhere it simply snaps). */
:is(.lesson-group, .announcement > details)::details-content { height: 0; overflow: clip; transition: height 220ms var(--ease-out), content-visibility 220ms allow-discrete; }
:is(.lesson-group, .announcement > details)[open]::details-content { height: auto; }
@media (prefers-reduced-motion: reduce) {
  .page .page-content, .course-grid > *, .lesson-list > .lesson, .tabs-menu, .bar > span { animation: none; }
  :is(.lesson-group, .announcement > details)::details-content { transition: none; }
}

/* Touch: 44px targets, and no keyboard hints. */
@media (pointer: coarse) {
  .btn { min-height: 44px; }
  .btn-sm { min-height: 40px; }
  .nav-item { height: 44px; }
  .theme-tab { height: 40px; }
  .icon-btn { width: 44px; height: 44px; }
  .viewer-tabs [role=tab] { min-height: 44px; display: inline-flex; align-items: center; }
}
@media (hover: none) { .quiz-keys { display: none; } }

/* Phone: the sidebar is an off-canvas drawer opened from the page header; everything else stacks and tightens. */
@media (max-width: 800px) {
  .sidebar { position: fixed; inset: 0 auto 0 0; width: min(300px, 86vw); padding-top: env(safe-area-inset-top); box-shadow: var(--shadow-pop); transform: translateX(-100%); visibility: hidden; transition: transform 200ms var(--ease-out), visibility 0s linear 200ms; }
  .shell[data-open] .sidebar { transform: none; visibility: visible; transition-delay: 0s; }
  .sidebar-backdrop { display: block; position: fixed; inset: 0; z-index: calc(var(--z-drawer) - 1); background: oklch(0 0 0 / 0.45); opacity: 0; pointer-events: none; transition: opacity 200ms var(--ease-out); }
  .shell[data-open] .sidebar-backdrop { opacity: 1; pointer-events: auto; }
  .sidebar-collapse { display: none; }
  .sidebar-close, .sidebar-trigger { display: grid; }
  .sidebar-trigger { margin-left: -8px; }

  .app-header { height: calc(var(--header-h) + env(safe-area-inset-top)); padding: env(safe-area-inset-top) 12px 0 16px; }
  /* Little room: with breadcrumbs the description steps aside. */
  .header-text:has(.crumbs) .header-sub { display: none; }
  .page-body { padding: 12px 12px calc(12px + env(safe-area-inset-bottom)); }
  .card { --pad: 16px; }
  .course-card { padding: 16px; }
  .refresh-label { display: none; }

  /* Lists: tighter rows, names wrap to two lines instead of cutting off, the action drops under the text. */
  .lesson { grid-template-columns: 28px minmax(0, 1fr); align-items: start; gap: 12px; padding: 14px; }
  .lesson > .lesson-action { grid-column: 2; justify-self: start; }
  .lesson-name { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; white-space: normal; }
  .ann-row { grid-template-columns: minmax(0, 1fr) auto; }
  .lessons-bar { flex-wrap: nowrap; align-items: center; gap: 12px; }
  .lessons-bar .progress { flex: 1 1 0; min-width: 0; }
  .lessons-bar > :not(.progress) { flex: none; }

  .viewer-tabs { flex-wrap: nowrap; margin-inline: -12px; padding-inline: 12px; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
  .viewer-tabs > * { flex: none; }
  .viewer-actions { padding-left: 12px; }

  .tab-status-bar, .mark-complete { align-items: stretch; flex-direction: column; justify-content: flex-start; }
  .content-frame { height: 68dvh; }
  .play-btn { width: 56px; height: 56px; }
  .video-caption { inset: auto 12px 12px; }
  .quiz-option { min-height: 52px; padding: 14px; }
  .quiz-foot .btn { flex: 1; }
  .field input { font-size: 1rem; }
  .login-card { padding: 24px; }

  /* Dialogs become bottom sheets. */
  .run-dialog { width: 100%; max-width: none; margin: auto 0 0; border-bottom: 0; border-radius: var(--radius-lg) var(--radius-lg) 0 0; }
  .run-dialog { max-height: 90dvh; padding: 20px 16px calc(20px + env(safe-area-inset-bottom)); overflow-y: auto; }
  .run-list { max-height: 40dvh; }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar, .sidebar-backdrop { transition-duration: 0.01ms; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; }
  .skeleton { animation: none; }
  .spin { animation-duration: 2.4s; }
}

/* Header back button: optically aligned with the page's left edge. */
.header-back { margin-left: -6px; }

/* Agenda: cards of dated rows (time, what + course, jump button). */
.agenda { flex: none; }
/* Day headers stay at the top of the card while its rows scroll under them. */
.agenda .group-head { position: sticky; top: 0; z-index: 1; }
.agenda-list { margin: 0; padding: 0; list-style: none; }
.agenda-row { display: grid; grid-template-columns: 92px minmax(0, 1fr) auto; align-items: center; gap: 14px; padding: 12px var(--pad); border-bottom: 1px solid var(--line); transition: background-color 150ms var(--ease-out); }
.agenda-row:last-child { border-bottom: 0; }
.agenda-row:hover { background: var(--panel); }
.agenda-time { display: grid; gap: 2px; color: var(--ink); font-size: 0.8125rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.agenda-time small { color: var(--muted); font-size: 0.75rem; font-weight: 400; }
.agenda-main { min-width: 0; display: grid; gap: 4px; }
.agenda-title { font-weight: 500; overflow-wrap: anywhere; }
.ev { padding: 1px 8px; border-radius: 999px; background: var(--primary-soft); color: var(--primary-text); font-weight: 600; }
.ev-closes { background: var(--next-soft); color: var(--next-text); }
.ev-urgent { background: var(--danger-soft); color: var(--danger); }
a.pill-warn:hover { text-decoration: underline; }
@media (max-width: 800px) {
  .agenda-row { grid-template-columns: minmax(0, 1fr) auto; row-gap: 2px; }
  .agenda-time { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 8px; grid-column: 1 / -1; }
}

/* The item an Agenda button linked to: highlighted once, and scrolled to (components/scroll-to-marked.tsx). */
.lesson.marked { background: var(--primary-soft); box-shadow: inset 0 0 0 2px var(--primary); animation: marked-flash 1.6s var(--ease-out) 1; }
@keyframes marked-flash { from { background: color-mix(in oklab, var(--primary-soft), var(--primary) 28%); } }
@media (prefers-reduced-motion: reduce) { .lesson.marked { animation: none; } }
.group-date { color: var(--muted); font-weight: 400; }
/* "N days left" at the far right of a date header; amber when it is 2 days away or less. */
/* A day's urgency as colour: a dot before the date and a tinted "N days left" pill (today red, 1-2 days amber, a week blue, later neutral). */
.tone-now { --tone: var(--danger); --tone-soft: var(--danger-soft); --tone-ink: var(--danger); }
.tone-soon { --tone: var(--next); --tone-soft: var(--next-soft); --tone-ink: var(--next-text); }
.tone-week { --tone: var(--primary); --tone-soft: var(--primary-soft); --tone-ink: var(--primary-text); }
.tone-later { --tone: var(--faint); --tone-soft: transparent; --tone-ink: var(--muted); }
.day-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--tone); }
.group-left { margin-left: auto; padding: 2px 10px; border-radius: 999px; background: var(--tone-soft); color: var(--tone-ink); font-size: 0.75rem; font-weight: 600; font-variant-numeric: tabular-nums; }

/* A pill with an icon: room between the icon and its text. */
.pill-warn { gap: 5px; }
