/* StackForge design system — token-based so a future palette/type change
   happens here once and propagates to every server-rendered page. See
   docs/CONTENT_GOVERNANCE_POLICY.md sibling doc set for the design brief. */

/* Self-hosted variable fonts (OFL-licensed, license files kept alongside
   the woff2 in the same folder) — one file per family covers the whole
   weight axis, no external font CDN, no CSP/network dependency at all. */
@font-face {
  font-family: "Vazirmatn";
  src: url("/assets/fonts/vazirmatn/Vazirmatn-Variable.woff2") format("woff2-variations"),
       url("/assets/fonts/vazirmatn/Vazirmatn-Variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "JetBrains Mono Variable";
  src: url("/assets/fonts/jetbrains-mono/JetBrainsMono-Variable.woff2") format("woff2-variations"),
       url("/assets/fonts/jetbrains-mono/JetBrainsMono-Variable.woff2") format("woff2");
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

/* Shabnam — distinct display face for headings/brand so headlines read as
   a deliberate pairing against Vazirmatn body text, not "the same font
   everywhere." Static weights (Shabnam has no variable build), OFL. */
@font-face {
  font-family: "Shabnam";
  src: url("/assets/fonts/shabnam/Shabnam-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Shabnam";
  src: url("/assets/fonts/shabnam/Shabnam-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

/* Parastoo and Tanha — same OFL-licensed Rastikerdar family as Vazir/
   Shabnam above (license file confirmed alongside each, /assets/fonts/
   {parastoo,tanha}/OFL.txt), added on request. Not used by any element by
   default — available as opt-in utility classes (.font-parastoo,
   .font-tanha) below so they don't silently change the existing --font-
   body/--font-display design tokens. NOTE: two other fonts from the same
   upload (Iranian Sans, Yekan) were deliberately NOT added here — their
   embedded font metadata says "All rights reserved" by a commercial
   foundry (Nevisa / Weblogma respectively) with no OFL or other open
   license text bundled, unlike every other font on this page. This is a
   real commercial platform (paid courses via Zarinpal) — do not wire
   those two into this stylesheet until their license is confirmed. */
@font-face {
  font-family: "Parastoo";
  src: url("/assets/fonts/parastoo/Parastoo.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Parastoo";
  src: url("/assets/fonts/parastoo/Parastoo-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Tanha";
  src: url("/assets/fonts/tanha/Tanha.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Iranian Sans / Yekan — LOCAL PREVIEW ONLY, added on explicit request to
   compare candidate faces before a real deploy decision. These are the two
   fonts flagged above as commercially licensed ("All rights reserved" in
   their own embedded metadata, no OFL/license file bundled) — they are
   wired in here ONLY so they're selectable from the font-switcher
   (font-switcher.js / #font-switcher below) on a local dev machine. Do
   NOT ship this stylesheet to a real deployment while these two blocks
   are active unless a commercial license has actually been purchased —
   see the comment above the Parastoo/Tanha block for the original finding. */
@font-face {
  font-family: "IranianSans";
  src: url("/assets/fonts/iransans/IranianSans.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Yekan";
  src: url("/assets/fonts/yekan/Yekan.woff") format("woff"),
       url("/assets/fonts/yekan/Yekan.ttf") format("truetype");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #eef1f4;
  --surface: #ffffff;
  --surface-2: #e4e9ed;
  --ink: #16202b;
  --ink-soft: #4b5a68;
  --ink-faint: #7c8b98;
  --accent: #c95f22;
  --accent-ink: #ffffff;
  --accent-soft: #f3d9c4;
  --line: #d7dee4;
  --success: #2f8f5b;
  --success-soft: #e1f1e7;
  --warning: #b5791a;
  --warning-soft: #f8ecd6;
  --critical: #c0392b;
  --critical-soft: #fbe4e1;
  --info: #2563a8;
  --info-soft: #dfeaf6;
  --shadow: 0 1px 2px rgba(22, 32, 43, 0.06), 0 8px 24px -12px rgba(22, 32, 43, 0.12);
  /* Trial swap (on request): Parastoo/Tanha as the live primary faces,
     Vazirmatn/Shabnam kept as fallback in the same stack so nothing
     breaks if either newly-added weight fails to load. Revert to
     "Vazirmatn"/"Shabnam" first in each stack to go back to the previous
     default. */
  --font-body: "Parastoo", "Vazirmatn", Tahoma, "Segoe UI", sans-serif;
  --font-display: "Tanha", "Shabnam", "Vazirmatn", Tahoma, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono Variable", ui-monospace, "Cascadia Code", Consolas, monospace;
}

/* Font-switcher (public/assets/font-switcher.js + the #font-switcher select
   in the header) — lets a real person compare candidate faces live across
   the whole site instead of guessing from a static sample. Each option
   overrides both --font-body and --font-display together so body text and
   headings stay a consistent pairing while previewing. */
:root[data-font="vazirmatn"] {
  --font-body: "Vazirmatn", Tahoma, "Segoe UI", sans-serif;
  --font-display: "Shabnam", "Vazirmatn", Tahoma, "Segoe UI", sans-serif;
}
:root[data-font="iransans"] {
  --font-body: "IranianSans", "Vazirmatn", Tahoma, "Segoe UI", sans-serif;
  --font-display: "IranianSans", "Vazirmatn", Tahoma, "Segoe UI", sans-serif;
}
:root[data-font="yekan"] {
  --font-body: "Yekan", "Vazirmatn", Tahoma, "Segoe UI", sans-serif;
  --font-display: "Yekan", "Vazirmatn", Tahoma, "Segoe UI", sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #10161d;
    --surface: #182230;
    --surface-2: #1f2b3a;
    --ink: #e7edf2;
    --ink-soft: #93a4b4;
    --ink-faint: #64758a;
    --accent: #f08a46;
    --accent-ink: #191008;
    --accent-soft: #3a2a1e;
    --line: #2a3543;
    --success: #4caf7d;
    --success-soft: #16281f;
    --warning: #e0ac44;
    --warning-soft: #2c2311;
    --critical: #e0645a;
    --critical-soft: #33201d;
    --info: #6ba6e0;
    --info-soft: #182636;
    --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 12px 28px -14px rgba(0, 0, 0, 0.6);
  }
}

:root[data-theme="dark"] {
  --bg: #10161d;
  --surface: #182230;
  --surface-2: #1f2b3a;
  --ink: #e7edf2;
  --ink-soft: #93a4b4;
  --ink-faint: #64758a;
  --accent: #f08a46;
  --accent-ink: #191008;
  --accent-soft: #3a2a1e;
  --line: #2a3543;
  --success: #4caf7d;
  --success-soft: #16281f;
  --warning: #e0ac44;
  --warning-soft: #2c2311;
  --critical: #e0645a;
  --critical-soft: #33201d;
  --info: #6ba6e0;
  --info-soft: #182636;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 12px 28px -14px rgba(0, 0, 0, 0.6);
}

:root[data-theme="light"] {
  --bg: #eef1f4;
  --surface: #ffffff;
  --surface-2: #e4e9ed;
  --ink: #16202b;
  --ink-soft: #4b5a68;
  --ink-faint: #7c8b98;
  --accent: #c95f22;
  --accent-ink: #ffffff;
  --accent-soft: #f3d9c4;
  --line: #d7dee4;
  --success: #2f8f5b;
  --success-soft: #e1f1e7;
  --warning: #b5791a;
  --warning-soft: #f8ecd6;
  --critical: #c0392b;
  --critical-soft: #fbe4e1;
  --info: #2563a8;
  --info-soft: #dfeaf6;
  --shadow: 0 1px 2px rgba(22, 32, 43, 0.06), 0 8px 24px -12px rgba(22, 32, 43, 0.12);
}

* { box-sizing: border-box; }

body {
  font-family: var(--font-body);
  background: var(--bg);
  color: var(--ink);
  margin: 0;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

h1, h2, h3 { text-wrap: balance; margin-top: 0; font-family: var(--font-display); font-weight: 700; }

header {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  color: var(--ink);
  padding: 14px 24px;
  min-height: 64px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  position: sticky;
  top: 0;
  z-index: 10;
}
header > div:first-child {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.1rem;
}
header > div:first-child::before {
  content: "SF";
  width: 30px;
  height: 30px;
  border: 1.5px solid var(--accent);
  color: var(--accent);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 0.85rem;
  display: grid;
  place-items: center;
  flex: none;
}
header nav { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
header a {
  color: var(--ink-soft);
  text-decoration: none;
  margin-inline-start: 4px;
  padding: 6px 10px;
  font-size: 0.88rem;
}
header a:hover { color: var(--accent); }
header .muted { margin-inline-start: 8px; }

/* Account avatar dropdown — native <details>/<summary>, no JS, same
   disclosure pattern already used for the Lab solution reveal. Placed last
   in the nav's flex order so it lands at the visual left end under RTL. */
.account-menu { position: relative; margin-inline-start: 8px; }
.account-menu > summary {
  list-style: none;
  cursor: pointer;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  display: grid;
  place-items: center;
  font-weight: 700;
  font-size: 0.95rem;
  font-family: var(--font-display);
}
.account-menu > summary::-webkit-details-marker,
.account-menu > summary::marker { display: none; content: ""; }
.account-menu .account-menu-body {
  position: absolute;
  inset-inline-end: 0;
  top: 42px;
  background: var(--surface);
  border: 1px solid var(--line);
  min-width: 180px;
  padding: 8px;
  z-index: 20;
  display: flex;
  flex-direction: column;
}
.account-menu .account-menu-body a,
.account-menu .account-menu-body span { padding: 8px 10px; margin-inline-start: 0; }

.theme-toggle {
  background: var(--surface-2);
  color: var(--ink-soft);
  border: 1px solid var(--line);
  width: 34px;
  height: 34px;
  padding: 0;
  margin: 0 0 0 4px;
  font-size: 1rem;
  line-height: 1;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
}
.theme-toggle:hover { filter: brightness(1.1); border-color: var(--accent); }

.font-switcher-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0 4px;
  font-size: 0.82rem;
  color: var(--ink-soft);
}
.font-switcher-label select {
  background: var(--surface-2);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 4px 6px;
  font-size: 0.82rem;
}

main { max-width: 1180px; margin: 32px auto 80px; padding: 0 16px; }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  padding: 20px 22px;
  margin-bottom: 16px;
  box-shadow: var(--shadow);
}

.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 0.76rem;
  font-weight: 600;
  padding: 3px 10px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; flex: none; }
.badge.ok { background: var(--success-soft); color: var(--success); }
.badge.ok::before { background: var(--success); }
.badge.warn { background: var(--warning-soft); color: var(--warning); }
.badge.warn::before { background: var(--warning); }
.badge.critical { background: var(--critical-soft); color: var(--critical); }
.badge.critical::before { background: var(--critical); }

label { display: block; font-size: 0.85rem; color: var(--ink-soft); margin: 14px 0 4px; }
label:first-of-type { margin-top: 0; }

input, select, button, textarea {
  font-family: inherit;
  font-size: 0.92rem;
  padding: 9px 12px;
  margin: 0;
  width: 100%;
  box-sizing: border-box;
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line);
}
input:focus, select:focus, textarea:focus { border-color: var(--accent); }

button, input[type="submit"] {
  background: var(--accent);
  color: var(--accent-ink);
  border: 1px solid var(--accent);
  font-weight: 600;
  cursor: pointer;
  width: auto;
  padding: 9px 20px;
  margin-top: 14px;
}
button:hover { filter: brightness(1.05); }

table { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
td, th { padding: 9px 4px; border-bottom: 1px solid var(--line); text-align: right; font-variant-numeric: tabular-nums; }
tr:last-child td { border-bottom: none; }

.error { color: var(--critical); font-size: 0.9rem; }
.success { color: var(--success); font-size: 0.9rem; }
.muted { color: var(--ink-faint); font-size: 0.85rem; }

code, .mono { font-family: var(--font-mono); }

/* Opt-in per-element font utilities — see the @font-face comment near the
   top of this file for why these two are the only newly-added fonts wired
   in, and why they're utility classes rather than new design tokens. */
.font-parastoo { font-family: "Parastoo", var(--font-body); }
.font-tanha { font-family: "Tanha", var(--font-body); }

/* Raw lesson/lab body — content is Markdown source, not HTML-rendered yet
   (see docs/CONTENT_GOVERNANCE_POLICY.md), so preserve whitespace/line
   breaks. Prose reads in the site's chosen body font (same as the rest of
   the page, including whatever the font-switcher currently has selected);
   only genuine code elements (real <pre>/<code> tags — legacy HTML-format
   lessons only, see raw-md--html below) stay monospace so PowerShell/bash
   snippets remain legible/aligned. */
.raw-md {
  white-space: pre-wrap;
  font-family: var(--font-body);
  font-size: 0.92rem;
  line-height: 1.75;
  background: var(--surface-2);
  border: 1px solid var(--line);
  padding: 18px 20px;
  overflow-x: auto;
  color: var(--ink);
}

/* Real code (PowerShell/bash snippets etc.) is English content inside an
   RTL page — render it LTR, left-aligned, and in a fixed dark "terminal"
   palette (independent of the site's light/dark theme, same way a
   terminal emulator looks the same regardless of the desktop theme around
   it) so it reads like an actual shell rather than reflowed RTL prose. */
.raw-md pre, .raw-md code {
  font-family: var(--font-mono);
  direction: ltr;
  text-align: left;
  unicode-bidi: isolate;
}

.raw-md pre {
  background: #0d1117;
  color: #c9d1d9;
  border: 1px solid #30363d;
  border-radius: 6px;
  padding: 14px 16px;
  overflow-x: auto;
}

.raw-md pre code { background: transparent; padding: 0; border: none; }

/* Syntax token colors (App\Support\SyntaxHighlight) — fixed dark palette,
   same reasoning as .raw-md pre above: a terminal reads the same regardless
   of the site's light/dark theme. */
.tok-comment { color: #8b949e; font-style: italic; }
.tok-string { color: #a5d6ff; }
.tok-cmdlet { color: #d2a8ff; font-weight: 600; }
.tok-flag { color: #ffa657; }
.tok-variable { color: #7ee787; }
.tok-number { color: #79c0ff; }

.raw-md code {
  background: #161b22;
  color: #c9d1d9;
  padding: 2px 6px;
  border-radius: 4px;
}

.card > .raw-md:last-child { margin-bottom: -2px; }

/* App\Support\MarkdownBlocks — the general heading/list/paragraph/inline-
   emphasis converter that finally turns "## 3. Theory" and "- **X:** ..."
   (previously shown to students as literal characters, see that class's
   docblock) into real <h2>/<ul>/<strong> here. white-space:pre-wrap stays
   on .raw-md above (still needed for content this pass doesn't touch), so
   these block elements get their own margins reset rather than relying on
   browser defaults, which would otherwise stack awkwardly with pre-wrap. */
.raw-md h2, .raw-md h3, .raw-md h4 {
  margin: 28px 0 12px;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--line);
  color: var(--ink);
}
.raw-md > h2:first-child, .raw-md > h3:first-child { margin-top: 0; }
.raw-md h3 { font-size: 1.02rem; border-bottom-style: dashed; }
.raw-md h4 { font-size: 0.96rem; border-bottom: none; }
.raw-md p { margin: 0 0 14px; }
.raw-md ul { margin: 0 0 14px; padding-inline-start: 22px; }
.raw-md li { margin-bottom: 6px; }
.raw-md strong { color: var(--ink); font-weight: 700; }
.raw-md em { color: var(--ink-soft); }

/* Content-type visual variety (task #106): section headings recognized by
   keyword (App\Support\MarkdownBlocks::HEADING_KEYWORDS) get a distinct
   icon + accent color so a Common Mistakes section doesn't look identical
   to a Real Production Examples section or a plain Theory paragraph —
   directly the platform owner's own complaint that every explanation
   looked the same and was tiring to read. */
.raw-md .lesson-h--mistake { color: var(--warning); border-bottom-color: var(--warning-soft); }
.raw-md .lesson-h--danger { color: var(--critical); border-bottom-color: var(--critical-soft); }
.raw-md .lesson-h--example { color: var(--accent); border-bottom-color: var(--accent-soft); }
.raw-md .lesson-h--security { color: var(--info); border-bottom-color: var(--info-soft); }
.raw-md .lesson-h--tip { color: var(--success); border-bottom-color: var(--success-soft); }
.raw-md .lesson-h--practice { color: var(--info); border-bottom-color: var(--info-soft); }

/* Legacy MS-LMS lessons (body_md is a full HTML document, see the
   raw-md--html comment in resources/views/lessons/show.php): their own
   embedded <style> controls font/spacing already, but never resets
   white-space, so it was still inheriting pre-wrap from .raw-md above —
   turning every soft line-wrap in the SOURCE .html file into a forced
   visual break. Off here, plus justify now that real <p> tags can reflow
   normally. */
.raw-md.raw-md--html {
  white-space: normal;
  text-align: justify;
}

/* Hidden-answer disclosure — used both for a Lab's full solution
   (lessons/lab.php) and for inline "correct answer" text inside a
   Lesson's self-check Quiz section (App\Support\AnswerReveal). Native
   <details>/<summary>, no JS: CSP forbids inline scripts anyway, and this
   needs none — a real click is what reveals it, not a CSS trick a
   determined student could bypass by reading page source, since the
   content is genuinely absent from the rendered DOM until opened. */
/* Course progress summary — folds what used to be a separate per-course
   dashboard page into a box at the top of the lesson list itself. */
.progress-box { margin: 14px 0; }
.progress-box-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
  font-size: 0.92rem;
}
.progress-bar {
  height: 8px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 4px;
  overflow: hidden;
}
.progress-bar-fill { height: 100%; background: var(--accent); }

/* Lesson search bar + results — dashboard/lessons.php */
.lesson-search-bar { display: flex; gap: 8px; align-items: flex-start; }
.lesson-search-bar input[type="search"] { flex: 1; margin: 0; }
.lesson-search-bar button { width: auto; white-space: nowrap; }
.lesson-search-results {
  list-style: none;
  margin: 10px 0;
  padding: 0;
  border: 1px solid var(--line);
  background: var(--surface-2);
}
.lesson-search-results li { padding: 8px 14px; border-bottom: 1px solid var(--line); }
.lesson-search-results li:last-child { border-bottom: none; }
.lesson-search-results:empty { display: none; }

/* Level/Module grouping for the course curriculum — native <details>,
   nested one inside the other, matching the level_or_part →
   module_or_milestone → chapter_or_lesson hierarchy in curriculum_nodes. */
.curriculum-group { margin: 10px 0; border: 1px solid var(--line); }
.curriculum-group > summary {
  cursor: pointer;
  padding: 10px 14px;
  font-weight: 600;
  background: var(--surface-2);
}
.curriculum-group--module { margin: 8px 10px; border-color: var(--line); }
.curriculum-group--module > summary { font-weight: 500; font-size: 0.92rem; }
.curriculum-group table { margin: 0; }

details.lab-solution,
details.answer-reveal {
  margin-top: 14px;
  border: 1px dashed var(--line);
  border-radius: 8px;
  background: var(--surface);
}
details.lab-solution > summary,
details.answer-reveal > summary {
  cursor: pointer;
  padding: 10px 14px;
  font-weight: 700;
  color: var(--accent);
  list-style: none;
}
details.lab-solution > summary::-webkit-details-marker,
details.answer-reveal > summary::-webkit-details-marker { display: none; }
details.lab-solution > summary::before,
details.answer-reveal > summary::before { content: '▸ '; }
details.lab-solution[open] > summary::before,
details.answer-reveal[open] > summary::before { content: '▾ '; }
details.lab-solution > .raw-md { margin: 0 14px 14px; }
details.answer-reveal > .answer-reveal-body { margin: 0 14px 14px; white-space: pre-wrap; }

/* German-course tools (public/assets/german-tools.js): control bar,
   dictionary quick-lookup box, and the text-selection popup. Scoped to
   whatever page renders <div data-german-tools> — currently DE-LMS lesson
   pages only. */
.german-tools-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin-bottom: 10px;
  padding: 10px 14px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 0.9rem;
}
.german-tools-voice select { margin-inline-start: 4px; }
.german-tools-speed { display: flex; gap: 4px; }
.german-tools-speed-btn {
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  color: var(--ink-soft);
  cursor: pointer;
  font-size: 0.85rem;
}
.german-tools-speed-btn.active {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}

.german-tools-dict {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  padding: 10px 14px;
  background: var(--surface);
  border: 1px dashed var(--line);
  border-radius: 8px;
}
.german-tools-dict-input {
  flex: 1 1 220px;
  min-width: 160px;
}
.german-tools-dict-specials { display: flex; gap: 4px; }
.german-tools-dict-specials button {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface-2);
  color: var(--ink);
  cursor: pointer;
  font-size: 0.95rem;
}
.german-tools-dict-link {
  flex-basis: 100%;
  font-size: 0.85rem;
}

.german-tools-popup {
  position: absolute;
  z-index: 50;
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-width: 280px;
  padding: 8px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: var(--shadow);
}
/* Without this, [hidden]'s UA-stylesheet `display:none` loses to the
   `display: flex` above (same specificity, our rule comes later in source
   order) — the popup would stay visually visible even after JS set the
   `hidden` attribute back on. */
.german-tools-popup[hidden] {
  display: none;
}
.german-tools-popup-btn {
  display: inline-block;
  padding: 6px 10px;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--accent-soft);
  color: var(--ink);
  cursor: pointer;
  font-size: 0.85rem;
  text-align: center;
  text-decoration: none;
}
.german-tools-popup-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.german-tools-popup-result {
  font-size: 0.85rem;
  padding: 6px 8px;
  background: var(--surface-2);
  border-radius: 6px;
  white-space: pre-wrap;
}

/* Inline retrieval-practice widgets (App\Support\InlineExercises +
   public/assets/inline-exercises.js) — small, low-stakes, never gates
   anything, so visually lighter-weight than a real Quiz/Lab card. */
.inline-check {
  margin: 14px 0;
  padding: 10px 14px;
  background: var(--accent-soft);
  border-radius: 8px;
  border: 1px solid var(--accent);
}
.inline-check-question { margin: 0 0 8px; font-weight: 600; }
.inline-check-row { display: flex; gap: 8px; flex-wrap: wrap; }
.inline-check-input { flex: 1 1 160px; direction: ltr; text-align: left; }
.inline-check-result { margin: 8px 0 0; font-size: 0.9rem; }
.inline-check-result.correct { color: var(--success); font-weight: 600; }
.inline-check-result.wrong { color: var(--critical); font-weight: 600; }
.inline-check-confidence-btn {
  margin-inline-start: 6px;
  padding: 4px 10px;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  font-size: 0.82rem;
}

/* Quiz confidence-rating row (resources/views/lessons/quiz.php) — the
   student rates how sure they are of each answer before submitting, so
   quiz_result.php can flag overconfidence (high confidence + wrong) and
   underconfidence (low confidence + right) per question. */
.quiz-confidence-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px dashed var(--line);
  font-size: 0.85rem;
}
.quiz-confidence-option {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
}
.calibration-note { margin-top: 4px; font-size: 0.82rem; }
.calibration-note.overconfident { color: var(--critical); }
.calibration-note.underconfident { color: var(--warning); }
.calibration-note.well-calibrated { color: var(--success); }

/* App\Support\DictationExercises + german-tools.js's wireDictation() */
.dictation-check {
  margin: 14px 0;
  padding: 10px 14px;
  background: var(--surface-2);
  border-radius: 8px;
  border: 1px solid var(--line);
}
.dictation-play-btn {
  padding: 6px 14px;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--accent-soft);
  color: var(--ink);
  cursor: pointer;
  font-size: 0.9rem;
}
.dictation-hint { margin: 8px 0; font-size: 0.85rem; }

/* App\Support\LessonMetaHeader — separates a Lesson's Level/Module/
   Node-Code/Duration metadata and its Learning Objectives from the actual
   lesson content, so it's clear at a glance where the real content
   starts. */
.lesson-meta-box {
  margin-bottom: 16px;
  padding: 14px 18px;
  background: var(--surface-2);
  border-radius: 10px;
  border: 1px solid var(--line);
}
.lesson-meta-title {
  margin: 0 0 10px;
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
}
.lesson-meta-grid {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 4px 12px;
  margin: 0;
}
.lesson-meta-grid dt {
  color: var(--ink-faint);
  font-weight: 600;
  white-space: nowrap;
}
.lesson-meta-grid dd {
  margin: 0;
  color: var(--ink-soft);
}

.lesson-objectives-box {
  margin-bottom: 20px;
  padding: 14px 18px;
  background: var(--success-soft);
  border-inline-start: 4px solid var(--success);
  border-radius: 8px;
}
.lesson-objectives-title {
  margin: 0 0 8px;
  font-weight: 700;
  color: var(--success);
}
.lesson-objectives-body {
  white-space: pre-wrap;
  line-height: 1.9;
}

/* App\Support\GrammarRules — inline callout inside a Lesson, plus the
   aggregated Grammar Hub page (resources/views/grammar/show.php). */
.grammar-rule-box {
  margin: 16px 0;
  padding: 12px 16px;
  background: var(--warning-soft);
  border-inline-start: 4px solid var(--warning);
  border-radius: 8px;
}
.grammar-rule-title { margin: 0 0 6px; font-weight: 700; color: var(--warning); }
.grammar-rule-summary { line-height: 1.8; }

.grammar-hub-item {
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}
.grammar-hub-item:last-child { border-bottom: none; }
.grammar-hub-source { margin: 0 0 6px; font-size: 0.85rem; }
.grammar-hub-item .grammar-rule-title { color: var(--warning); }

/* App\Support\VocabularyAudioButton */
.vocab-audio-widget {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 14px 0;
  padding: 10px 14px;
  background: var(--surface-2);
  border-radius: 8px;
  border: 1px solid var(--line);
}
.vocab-audio-btn {
  padding: 6px 14px;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--accent-soft);
  color: var(--ink);
  cursor: pointer;
  font-size: 0.9rem;
}
.vocab-audio-hint { font-size: 0.82rem; }

/* App\Support\ReadingPassage — always-visible reading exercise */
.reading-block {
  margin: 16px 0;
  padding: 14px 18px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.reading-controls { display: flex; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.reading-play-btn, .reading-translate-btn {
  padding: 6px 12px;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--accent-soft);
  color: var(--ink);
  cursor: pointer;
  font-size: 0.85rem;
}
/* German is LTR — inheriting the page's RTL direction (see .raw-md pre's
   same fix for code) reversed word order and mirrored end-of-sentence
   punctuation (a "?" visually landing on the wrong side), reported by a
   real user reading a lesson. */
.reading-text { line-height: 2; white-space: pre-wrap; direction: ltr; text-align: left; unicode-bidi: isolate; }
.reading-translation {
  margin-top: 10px;
  padding: 10px 12px;
  background: var(--surface-2);
  border-radius: 6px;
  line-height: 1.9;
}

/* App\Support\ListeningPassage + App\Support\ListeningQuestion —
   audio-first, exercises-section listening comprehension */
.listening-passage {
  margin: 16px 0;
  padding: 14px 18px;
  background: var(--surface-2);
  border: 1px dashed var(--line);
  border-radius: 10px;
}
.listening-passage-controls { display: flex; gap: 8px; flex-wrap: wrap; }
.listening-passage-play-btn, .listening-passage-reveal-btn,
.listen-play-btn, .listen-reveal-text-btn {
  padding: 6px 12px;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--accent-soft);
  color: var(--ink);
  cursor: pointer;
  font-size: 0.85rem;
}
.listening-passage-text { margin-top: 10px; line-height: 1.9; white-space: pre-wrap; direction: ltr; text-align: left; unicode-bidi: isolate; }

.listen-check {
  margin: 14px 0;
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.listen-check-header {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.listen-check-number { font-weight: 700; color: var(--accent); }
.listen-question-text { margin: 0 0 10px; padding: 8px 10px; background: var(--surface-2); border-radius: 6px; }
.listen-reveal-answer-btn {
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface-2);
  color: var(--ink-soft);
  cursor: pointer;
  font-size: 0.82rem;
}

/* dashboard/lessons.php — a Module with no written chapters yet (see
   docs/CONTENT_GOVERNANCE_POLICY.md section 15) still gets one visible,
   searchable row instead of silently rendering an empty table. */
.lesson-row--empty td { opacity: 0.7; }
.lesson-row--empty em { font-style: normal; color: var(--ink-faint); }

/* Module Exam / Level Exam row (curriculum_nodes.has_exam_gate) */
.exam-row td:first-child { font-weight: 600; }
.exam-row { background: var(--accent-soft); }
.lesson-row-purpose { margin: 0.25em 0 0; font-size: 0.85em; }

/* ==========================================================================
   Public landing page (home/index.php) + public course detail/syllabus
   page (home/course.php) — reachable without an account. Illustration
   gradients are fixed hex values independent of the light/dark theme
   token, same reasoning as .raw-md pre's fixed terminal palette above:
   a colorful hero image shouldn't invert with the page theme.
   ========================================================================== */

.hero {
  padding: 56px 8px 44px;
  text-align: center;
  animation: heroIn 0.6s ease both;
}
.hero-eyebrow {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: var(--accent);
  background: var(--accent-soft);
  padding: 4px 14px;
  border-radius: 999px;
  margin-bottom: 18px;
}
.hero h1 {
  font-size: clamp(1.7rem, 4vw, 2.6rem);
  margin: 0 0 14px;
}
.hero p.lead {
  max-width: 640px;
  margin: 0 auto;
  color: var(--ink-soft);
  font-size: 1.05rem;
}

.course-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 24px;
  margin: 8px 0 40px;
}

/* Landing page grouped by course family (task from 2026-08-16): a flat grid
   of 17 courses made it hard to find "the Microsoft ones" or "the Linux
   one" at a glance. Each category renders as its own horizontally
   scrollable row instead, with prev/next buttons for overflow and a
   "show all" link that re-renders the same page as a full grid scoped to
   just that category (HomeController::landing() via ?category=). */
.category-row { margin: 0 0 36px; }
.category-row-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.category-row-header h2 { margin: 0; font-size: 1.25rem; }
.category-row-actions { display: flex; align-items: center; gap: 10px; }
.cat-scroll-btn {
  width: 34px;
  height: 34px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--ink);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
}
.cat-scroll-btn:hover { background: var(--surface-2); border-color: var(--accent); }
.cat-show-all {
  font-size: 0.86rem;
  font-weight: 700;
  color: var(--ink-soft);
  text-decoration: none;
  white-space: nowrap;
}
.cat-show-all:hover { color: var(--accent); }
.category-row-track {
  display: flex;
  gap: 20px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: 6px;
  scrollbar-width: thin;
}
.category-row-item {
  flex: 0 0 280px;
  scroll-snap-align: start;
}
.category-row-item .course-card { height: 100%; }
.category-expanded-header {
  display: flex;
  align-items: baseline;
  gap: 16px;
  margin: 8px 0 18px;
}
.category-expanded-header h2 { margin: 0; font-size: 1.4rem; }
.back-to-categories {
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--accent);
  text-decoration: none;
}
.back-to-categories:hover { text-decoration: underline; }

.course-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
  transition: transform 0.28s ease, box-shadow 0.28s ease;
  animation: cardIn 0.5s ease both;
}
.course-card:hover, .course-card:focus-visible {
  transform: translateY(-8px);
  box-shadow: 0 4px 8px rgba(22, 32, 43, 0.1), 0 22px 40px -18px rgba(22, 32, 43, 0.28);
}
.course-card-media {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
}
.course-illustration { display: block; width: 100%; height: 100%; }
.course-card-media .badge {
  position: absolute;
  top: 12px;
  inset-inline-start: 12px;
  background: rgba(15, 20, 25, 0.45);
  color: #fff;
  backdrop-filter: blur(2px);
}
.course-card-body {
  padding: 18px 20px 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
}
.course-card-body h3 { margin: 0; font-size: 1.15rem; }
.course-tagline { color: var(--ink-soft); font-size: 0.92rem; margin: 0; }
.course-card-footer {
  margin-top: auto;
  padding-top: 10px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 0.82rem;
  color: var(--ink-faint);
}
.course-cta {
  font-weight: 700;
  font-size: 0.86rem;
}
.theme-violet .course-cta, .theme-violet .course-tagline-icon { color: #7c3aed; }
.theme-emerald .course-cta, .theme-emerald .course-tagline-icon { color: #059669; }
.theme-blue .course-cta, .theme-blue .course-tagline-icon { color: #2563eb; }
.theme-amber .course-cta, .theme-amber .course-tagline-icon { color: #c2790a; }
.theme-teal .course-cta, .theme-teal .course-tagline-icon { color: #0d9488; }
.theme-indigo .course-cta, .theme-indigo .course-tagline-icon { color: #4f46e5; }
.theme-fuchsia .course-cta, .theme-fuchsia .course-tagline-icon { color: #c026d3; }
.theme-sky .course-cta, .theme-sky .course-tagline-icon { color: #0284c7; }
.theme-cyan .course-cta, .theme-cyan .course-tagline-icon { color: #0891b2; }
.theme-lime .course-cta, .theme-lime .course-tagline-icon { color: #65a30d; }
.theme-orange .course-cta, .theme-orange .course-tagline-icon { color: #c2410c; }
.theme-red .course-cta, .theme-red .course-tagline-icon { color: #dc2626; }
.theme-rose .course-cta, .theme-rose .course-tagline-icon { color: #e11d48; }
.theme-gold .course-cta, .theme-gold .course-tagline-icon { color: #a16207; }
.theme-slate .course-cta, .theme-slate .course-tagline-icon { color: #475569; }
.theme-purple .course-cta, .theme-purple .course-tagline-icon { color: #9333ea; }
.theme-green .course-cta, .theme-green .course-tagline-icon { color: #16a34a; }
.theme-maroon .course-cta, .theme-maroon .course-tagline-icon { color: #9f1239; }
.theme-coral .course-cta, .theme-coral .course-tagline-icon { color: #e0522f; }

/* Per-course visual identity beyond the landing page (task #106, other
   half): theme_color used to stop mattering the moment a student clicked
   into a course — the dashboard's course-lesson-list page and every
   individual lesson page looked identical no matter which course they
   belonged to. --course-accent carries each course's own color into that
   "my courses" list, its lesson-list landing page, and every lesson page
   (.course-scope wraps each of those in resources/views/dashboard/list.php,
   dashboard/lessons.php and lessons/show.php), scoped narrowly to page
   chrome (.course-title, the top card's accent border, action links) —
   deliberately NOT to .raw-md lesson content, whose headings already have
   their own content-type coloring from MarkdownBlocks (--warning/
   --critical/--accent/--info/--success), which this must not overwrite. */
.theme-violet { --course-accent: #7c3aed; --course-accent-soft: #ede9fe; }
.theme-emerald { --course-accent: #059669; --course-accent-soft: #d1fae5; }
.theme-blue { --course-accent: #2563eb; --course-accent-soft: #dbeafe; }
.theme-amber { --course-accent: #c2790a; --course-accent-soft: #fef3c7; }
.theme-teal { --course-accent: #0d9488; --course-accent-soft: #ccfbf1; }
.theme-lab { --course-accent: var(--accent); --course-accent-soft: var(--accent-soft); }
/* Added when the platform grew from 5 to 17 real courses (task #106): the
   original 5 hues ran out and were being reused across up to 4 unrelated
   courses at once (e.g. MS-LMS/Azure/PowerShell/Kubernetes all "blue"). */
.theme-indigo { --course-accent: #4f46e5; --course-accent-soft: #e0e7ff; }
.theme-fuchsia { --course-accent: #c026d3; --course-accent-soft: #fae8ff; }
.theme-sky { --course-accent: #0284c7; --course-accent-soft: #e0f2fe; }
.theme-cyan { --course-accent: #0891b2; --course-accent-soft: #cffafe; }
.theme-lime { --course-accent: #65a30d; --course-accent-soft: #ecfccb; }
.theme-orange { --course-accent: #c2410c; --course-accent-soft: #ffedd5; }
.theme-red { --course-accent: #dc2626; --course-accent-soft: #fee2e2; }
.theme-rose { --course-accent: #e11d48; --course-accent-soft: #ffe4e6; }
.theme-gold { --course-accent: #a16207; --course-accent-soft: #fef9c3; }
.theme-slate { --course-accent: #475569; --course-accent-soft: #f1f5f9; }
.theme-purple { --course-accent: #9333ea; --course-accent-soft: #f3e8ff; }
.theme-green { --course-accent: #16a34a; --course-accent-soft: #dcfce7; }
.theme-maroon { --course-accent: #9f1239; --course-accent-soft: #fde0e4; }
.theme-coral { --course-accent: #e0522f; --course-accent-soft: #ffe4dc; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-violet { --course-accent: #a78bfa; --course-accent-soft: #2e1f57; }
  :root:not([data-theme="light"]) .theme-emerald { --course-accent: #34d399; --course-accent-soft: #113325; }
  :root:not([data-theme="light"]) .theme-blue { --course-accent: #60a5fa; --course-accent-soft: #172a45; }
  :root:not([data-theme="light"]) .theme-amber { --course-accent: #fbbf24; --course-accent-soft: #2e2410; }
  :root:not([data-theme="light"]) .theme-teal { --course-accent: #2dd4bf; --course-accent-soft: #0f2e2b; }
  :root:not([data-theme="light"]) .theme-indigo { --course-accent: #818cf8; --course-accent-soft: #26265e; }
  :root:not([data-theme="light"]) .theme-fuchsia { --course-accent: #e879f9; --course-accent-soft: #4a1152; }
  :root:not([data-theme="light"]) .theme-sky { --course-accent: #38bdf8; --course-accent-soft: #0c2d43; }
  :root:not([data-theme="light"]) .theme-cyan { --course-accent: #22d3ee; --course-accent-soft: #083344; }
  :root:not([data-theme="light"]) .theme-lime { --course-accent: #a3e635; --course-accent-soft: #1a2e05; }
  :root:not([data-theme="light"]) .theme-orange { --course-accent: #fb923c; --course-accent-soft: #431407; }
  :root:not([data-theme="light"]) .theme-red { --course-accent: #f87171; --course-accent-soft: #450a0a; }
  :root:not([data-theme="light"]) .theme-rose { --course-accent: #fb7185; --course-accent-soft: #4c0519; }
  :root:not([data-theme="light"]) .theme-gold { --course-accent: #facc15; --course-accent-soft: #422006; }
  :root:not([data-theme="light"]) .theme-slate { --course-accent: #94a3b8; --course-accent-soft: #0f172a; }
  :root:not([data-theme="light"]) .theme-purple { --course-accent: #c084fc; --course-accent-soft: #3b0764; }
  :root:not([data-theme="light"]) .theme-green { --course-accent: #4ade80; --course-accent-soft: #052e16; }
  :root:not([data-theme="light"]) .theme-maroon { --course-accent: #fb7185; --course-accent-soft: #3f0a17; }
  :root:not([data-theme="light"]) .theme-coral { --course-accent: #ff8a70; --course-accent-soft: #431a10; }
}
:root[data-theme="dark"] .theme-violet { --course-accent: #a78bfa; --course-accent-soft: #2e1f57; }
:root[data-theme="dark"] .theme-emerald { --course-accent: #34d399; --course-accent-soft: #113325; }
:root[data-theme="dark"] .theme-blue { --course-accent: #60a5fa; --course-accent-soft: #172a45; }
:root[data-theme="dark"] .theme-amber { --course-accent: #fbbf24; --course-accent-soft: #2e2410; }
:root[data-theme="dark"] .theme-teal { --course-accent: #2dd4bf; --course-accent-soft: #0f2e2b; }
:root[data-theme="dark"] .theme-indigo { --course-accent: #818cf8; --course-accent-soft: #26265e; }
:root[data-theme="dark"] .theme-fuchsia { --course-accent: #e879f9; --course-accent-soft: #4a1152; }
:root[data-theme="dark"] .theme-sky { --course-accent: #38bdf8; --course-accent-soft: #0c2d43; }
:root[data-theme="dark"] .theme-cyan { --course-accent: #22d3ee; --course-accent-soft: #083344; }
:root[data-theme="dark"] .theme-lime { --course-accent: #a3e635; --course-accent-soft: #1a2e05; }
:root[data-theme="dark"] .theme-orange { --course-accent: #fb923c; --course-accent-soft: #431407; }
:root[data-theme="dark"] .theme-red { --course-accent: #f87171; --course-accent-soft: #450a0a; }
:root[data-theme="dark"] .theme-rose { --course-accent: #fb7185; --course-accent-soft: #4c0519; }
:root[data-theme="dark"] .theme-gold { --course-accent: #facc15; --course-accent-soft: #422006; }
:root[data-theme="dark"] .theme-slate { --course-accent: #94a3b8; --course-accent-soft: #0f172a; }
:root[data-theme="dark"] .theme-purple { --course-accent: #c084fc; --course-accent-soft: #3b0764; }
:root[data-theme="dark"] .theme-green { --course-accent: #4ade80; --course-accent-soft: #052e16; }
:root[data-theme="dark"] .theme-maroon { --course-accent: #fb7185; --course-accent-soft: #3f0a17; }
:root[data-theme="dark"] .theme-coral { --course-accent: #ff8a70; --course-accent-soft: #431a10; }

.course-scope > .card:first-child,
.course-scope .course-scope-card { border-top: 3px solid var(--course-accent); }
.course-scope .course-title { color: var(--course-accent); }
.course-scope .progress-bar-fill { background: var(--course-accent); }
.course-scope .lesson-search-bar input:focus { border-color: var(--course-accent); }
.course-scope .card:last-child a { color: var(--course-accent); }

.illustration-float { animation: floatY 5s ease-in-out infinite; transform-origin: center; }
.illustration-float-delayed { animation: floatY 5s ease-in-out infinite; animation-delay: 0.7s; transform-origin: center; }
.illustration-blink { animation: blink 1.1s step-end infinite; }

@keyframes floatY {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-7px); }
}
@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}
@keyframes heroIn {
  from { opacity: 0; transform: translateY(-10px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes cardIn {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: translateY(0); }
}
.course-grid .course-card:nth-child(1) { animation-delay: 0.02s; }
.course-grid .course-card:nth-child(2) { animation-delay: 0.08s; }
.course-grid .course-card:nth-child(3) { animation-delay: 0.14s; }
.course-grid .course-card:nth-child(4) { animation-delay: 0.2s; }
.course-grid .course-card:nth-child(5) { animation-delay: 0.26s; }

@media (prefers-reduced-motion: reduce) {
  .illustration-float, .illustration-float-delayed, .illustration-blink,
  .hero, .course-card { animation: none; }
}

/* Course detail / syllabus page */
.course-detail-hero {
  border-radius: 18px;
  overflow: hidden;
  position: relative;
  margin-bottom: 24px;
  box-shadow: var(--shadow);
}
.course-detail-hero .course-illustration { width: 100%; height: 220px; }
.course-detail-hero-body {
  padding: 22px 26px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: none;
}
.course-detail-hero-body h1 { margin: 0 0 6px; font-size: 1.6rem; }
.course-detail-hero-body .course-tagline { font-size: 1.02rem; }

.highlight-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
}
.highlight-list li {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  font-size: 0.94rem;
  line-height: 1.6;
}
.highlight-list li::before {
  content: "✓";
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--success-soft);
  color: var(--success);
  font-size: 0.75rem;
  display: grid;
  place-items: center;
  margin-top: 2px;
}

.syllabus-tree ul { list-style: none; margin: 0; padding-inline-start: 22px; }
.syllabus-tree > ul { padding-inline-start: 0; }
.syllabus-tree li { position: relative; padding: 6px 0; }
.syllabus-node-level {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.02rem;
  padding: 10px 0 6px;
  border-top: 1px solid var(--line);
  margin-top: 4px;
}
.syllabus-tree > ul > li:first-child > .syllabus-node-level { border-top: none; margin-top: 0; }
.syllabus-node-module { font-weight: 600; color: var(--ink); }
.syllabus-node-lesson {
  color: var(--ink-soft);
  font-size: 0.9rem;
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.syllabus-node-lesson::before { content: "–"; color: var(--ink-faint); }
.syllabus-node-code { font-family: var(--font-mono); font-size: 0.78rem; color: var(--ink-faint); }

.course-detail-cta {
  position: sticky;
  bottom: 16px;
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
  padding: 14px 18px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow);
}
.course-detail-cta form { width: auto; margin: 0; }
.course-detail-cta button, .course-detail-cta a.button-like {
  margin: 0;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
}
.back-link { display: inline-block; color: var(--ink-soft); text-decoration: none; font-size: 0.88rem; }
.back-link:hover { color: var(--accent); }

/* Previous/next Lesson links on the Lesson page itself, so a student
   reading e.g. Lesson 26 can move to 25/27 without returning to the
   course's lesson list first. Appears both above and below the Lesson
   content; the empty <span> in the "no previous Lesson" case keeps the
   next-Lesson link pinned to its side of the row via space-between. */
.lesson-nav {
  display: flex;
  gap: 12px;
  margin: 14px 0;
}
.lesson-nav-link {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  text-decoration: none;
  color: var(--ink);
  min-width: 0;
}
.lesson-nav-link:hover { border-color: var(--accent); }
.lesson-nav-link--next { justify-content: flex-end; text-align: left; }
.lesson-nav-arrow { flex: none; font-size: 1.2rem; color: var(--accent); }
.lesson-nav-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.lesson-nav-label { font-size: 0.74rem; color: var(--ink-soft); }
.lesson-nav-title {
  font-size: 0.88rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (max-width: 560px) {
  .lesson-nav { flex-direction: column; }
}

/* Stays reachable while scrolling a long syllabus (some courses run to
   hundreds of lessons) — sticks just under the header, which is itself
   sticky at top:0, hence the matching offset. */
.detail-top-bar {
  position: sticky;
  top: 64px;
  z-index: 5;
  background: var(--bg);
  padding: 10px 0;
  margin-bottom: 6px;
}

/* Landing/detail page footer */
.site-footer {
  margin-top: 56px;
  padding-top: 40px;
  border-top: 1px solid var(--line);
}
.site-footer-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 32px;
  padding-bottom: 28px;
}
.site-footer-brand h4 {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: 1.1rem;
}
.site-footer-brand p { color: var(--ink-soft); font-size: 0.88rem; max-width: 36ch; margin: 0; }
.site-footer-col h5 {
  margin: 0 0 12px;
  font-size: 0.82rem;
  color: var(--ink-faint);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.site-footer-col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.site-footer-col a { color: var(--ink-soft); text-decoration: none; font-size: 0.9rem; }
.site-footer-col a:hover { color: var(--accent); }
.site-footer-bottom {
  border-top: 1px solid var(--line);
  padding: 16px 0 32px;
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  font-size: 0.82rem;
  color: var(--ink-faint);
}
@media (max-width: 720px) {
  .site-footer-grid { grid-template-columns: 1fr; }
}

/* New Admin course: figures and embedded animations (static files under /course-assets) */
.na-lesson { text-align: justify; line-height: 2; }
.na-lesson figure { margin: 1.4rem 0; }
.na-lesson .na-fig img { width: 100%; height: auto; display: block; border: 1px solid var(--line, #cdd6d3); border-radius: 12px; }
.na-lesson figcaption { text-align: center; font-size: .9rem; opacity: .8; margin-top: .4rem; }
.na-lesson .na-anim { border: 2px solid var(--accent, #0f7d6a); border-radius: 10px; overflow: hidden; }
.na-lesson .na-anim figcaption { text-align: start; font-weight: 700; padding: .4rem .8rem; margin: 0; opacity: 1; }
.na-lesson .na-anim iframe { width: 100%; height: 680px; border: 0; display: block; }
.na-lesson table { display: block; overflow-x: auto; }
.na-lesson .na-anim figcaption { display: flex; align-items: center; justify-content: space-between; gap: .6rem; }
.na-anim-full { font: inherit; font-size: .85rem; cursor: pointer; border: 1px solid var(--accent, #0f7d6a); border-radius: 6px; background: transparent; color: inherit; padding: .15rem .6rem; }
.na-lesson .na-anim iframe { height: 520px; overflow: hidden; }
.na-anim:fullscreen { background: #fff; display: flex; flex-direction: column; border: 0; border-radius: 0; }
.na-anim:fullscreen iframe { flex: 1; height: auto; }
