/* Block components — cinematic frosted-glass aesthetic.
   Matches err/aoa-academy-design-html/{Lectures-example-template, flashcards-template #1}.html
   Glass-panel pattern reusable across callouts, flashcards, definitions, etc. */

/* ----------------------------------------------------------------------
   Glass panel (reusable surface)
---------------------------------------------------------------------- */
.glass-panel {
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: var(--glass-border);
  border-radius: var(--r-xl);
  box-shadow: var(--glass-shadow);
  padding: 1.75em 2em;
  break-inside: avoid;
}

/* ----------------------------------------------------------------------
   Callouts — 4 variants from grand-language-template.html lines 96-173.
   "1:1 copy of AOA-COURSES-TEMPLATE.pdf p.13". All use --accent (level-tied).

   Used by :::definition, :::important, :::note directives. Type sizes
   below are scaled down ~60% from the 1920x1080 slide template so they
   fit inline in prose without dominating the page. */

/* (1) ОПРЕДЕЛЕНИЕ — definition card */
.callout-definition {
  background: var(--callout-solid-bg);
  border: 1.5px solid var(--accent);
  border-radius: 28px;
  padding: 1.3em 1.6em;
  margin: 1.75em 0;
  break-inside: avoid;
}
.callout-definition .row-top {
  display: flex;
  align-items: center;
  gap: 0.6em;
  margin-bottom: 0.5em;
}
.callout-definition .logo {
  font-size: 1.9em;
  line-height: 1;
  flex-shrink: 0;
  font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif;
}
.callout-definition .label {
  font-family: var(--font-display);
  font-size: 1.3em;
  font-weight: 800;
  letter-spacing: 0.02em;
  color: var(--accent);
  text-transform: uppercase;
  line-height: 1;
}
.callout-definition .body {
  font-size: 1.05em;
  font-weight: 400;
  color: var(--callout-text);
  line-height: 1.45;
  margin: 0;
}
.callout-definition .body > :first-child { margin-top: 0; }
.callout-definition .body > :last-child  { margin-bottom: 0; }

/* (2) ВАЖНО — vertical-label important banner */
.callout-vertical {
  display: flex;
  align-items: stretch;
  gap: 0.7em;
  margin: 1.75em 0;
  min-height: 5em;
  break-inside: avoid;
}
.callout-vertical .v-label {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-family: var(--font-display);
  font-size: 0.75em;
  font-weight: 800;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--accent);
  opacity: 0.45;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.4em 0.2em;
}
.callout-vertical .v-rule {
  width: 2px;
  align-self: stretch;
  background: var(--accent);
  border-radius: 2px;
  margin: 0.5em 0;
}
.callout-vertical .v-body {
  flex: 1;
  padding: 1em 1.4em;
  display: flex;
  align-items: center;
  font-size: 1em;
  color: var(--callout-text);
  font-weight: 500;
  line-height: 1.45;
  background: var(--callout-grad-bg);
  border-radius: 18px;
}
.callout-vertical .v-body > :first-child { margin-top: 0; }
.callout-vertical .v-body > :last-child  { margin-bottom: 0; }

/* (3) ЗАМЕТКА — note with vertical-badge label */
.callout-note {
  display: flex;
  align-items: stretch;
  gap: 0.55em;
  margin: 1.5em 0;
  min-height: 4em;
  break-inside: avoid;
}
.callout-note .n-badge {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  border: 1.5px solid var(--accent);
  border-radius: 12px;
  padding: 0.7em 0.3em;
  font-family: var(--font-display);
  font-size: 0.65em;
  font-weight: 800;
  letter-spacing: 0.35em;
  color: var(--accent);
  text-transform: uppercase;
  display: flex;
  align-items: center;
  justify-content: center;
}
.callout-note .n-rule {
  width: 2px;
  align-self: stretch;
  background: var(--accent);
  border-radius: 2px;
  margin: 0.45em 0;
}
.callout-note .n-body {
  flex: 1;
  padding: 0.85em 1.25em;
  display: flex;
  align-items: center;
  font-size: 0.95em;
  color: var(--callout-text);
  font-weight: 400;
  line-height: 1.45;
  background: var(--callout-grad-bg);
  border-radius: 16px;
}
.callout-note .n-body > :first-child { margin-top: 0; }
.callout-note .n-body > :last-child  { margin-bottom: 0; }

/* (4) ВАЖНО — horizontal compact variant */
.callout-horizontal {
  display: flex;
  align-items: center;
  gap: 0.85em;
  background: var(--callout-grad-bg);
  border-radius: 18px;
  padding: 0.8em 1.4em;
  margin: 1.5em 0;
  break-inside: avoid;
}
.callout-horizontal .h-label {
  font-family: var(--font-display);
  font-size: 0.78em;
  font-weight: 800;
  letter-spacing: 0.3em;
  color: var(--accent);
  text-transform: uppercase;
  flex-shrink: 0;
}
.callout-horizontal .h-rule {
  width: 2px;
  height: 1.6em;
  background: var(--accent);
  border-radius: 2px;
  flex-shrink: 0;
}
.callout-horizontal .h-body {
  font-size: 0.95em;
  color: var(--callout-text);
  font-weight: 500;
  line-height: 1.45;
}
.callout-horizontal .h-body > :first-child { margin-top: 0; }
.callout-horizontal .h-body > :last-child  { margin-bottom: 0; }

/* GitHub-alerts plugin output — route into the closest variant via class.
   Plugin emits .markdown-alert.markdown-alert-{note,tip,important,warning,caution}.
   Map to our variants for visual consistency. */
.markdown-alert {
  display: flex;
  align-items: center;
  gap: 0.85em;
  background: var(--callout-grad-bg);
  color: var(--callout-text);
  border-radius: 18px;
  padding: 0.95em 1.4em;
  margin: 1.5em 0;
  break-inside: avoid;
}
.markdown-alert > :first-child { margin-top: 0; }
.markdown-alert > :last-child  { margin-bottom: 0; }
.markdown-alert-title {
  font-family: var(--font-display);
  font-size: 0.78em;
  font-weight: 800;
  letter-spacing: 0.25em;
  color: var(--accent);
  text-transform: uppercase;
  margin-right: 0.6em;
}
.markdown-alert-important { border-left: 2px solid var(--accent); padding-left: 1em; }
.markdown-alert-caution   { border-left: 2px solid var(--accent); padding-left: 1em; }

/* ----------------------------------------------------------------------
   Dialogue — two-speaker conversation, framed as a chat window.
   Speakers alternate (1,2,1,2), left/right alignment + named avatar
   circles. Driven by :::dialogue.
---------------------------------------------------------------------- */
.dialogue {
  display: grid;
  gap: 0.85em;
  margin: 2em 0;
  padding: 1.4em 1.5em 1.6em;
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  box-shadow: var(--glass-shadow);
  break-inside: avoid;
  position: relative;
}

/* Frame header — chat-window title bar with both speakers + small icon */
.dialogue-header {
  display: flex;
  justify-content: center;
  gap: 0.8em;
  align-items: center;
  margin: -0.2em -0.2em 0.85em;
  padding: 0 0 0.95em;
  border-bottom: 1px solid var(--rule);
  font-family: var(--font-display);
  font-size: 0.75rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--fg-muted);
}
.dialogue-header::before {
  content: "💬";
  font-size: 1.1em;
  margin-right: 0.2em;
  opacity: 0.85;
}
.dialogue-header strong {
  color: var(--accent);
  font-weight: 700;
}
.dialogue-header span {
  color: var(--fg-faint);
  font-weight: 400;
}

/* Lines + bubbles */
.dialogue-line {
  display: flex;
  align-items: flex-end;
  gap: 0.7em;
  max-width: 90%;
}
.dialogue-line.speaker-a { justify-self: start; }
.dialogue-line.speaker-b { justify-self: end; flex-direction: row-reverse; text-align: right; }

.dialogue-avatar {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--accent);
  background: var(--accent-soft);
  border: 1.5px solid var(--accent-dim);
  flex-shrink: 0;
  text-transform: uppercase;
}
.dialogue-line.speaker-b .dialogue-avatar {
  background: var(--surface-subtle);
  border: 1.5px solid var(--rule);
  color: var(--fg-muted);
}

.dialogue-bubble {
  position: relative;
  padding: 0.7em 1.05em;
  border-radius: 18px;
  background: var(--callout-grad-bg);
  color: var(--callout-text);
  font-size: 1rem;
  line-height: 1.5;
  border: 1px solid var(--rule);
}
.dialogue-line.speaker-a .dialogue-bubble {
  border-bottom-left-radius: 4px;
}
.dialogue-line.speaker-b .dialogue-bubble {
  background: var(--accent-soft);
  border: 1px solid var(--accent-dim);
  color: var(--fg);
  border-bottom-right-radius: 4px;
}
.dialogue-bubble > :first-child { margin-top: 0; }
.dialogue-bubble > :last-child  { margin-bottom: 0; }

.dialogue-name {
  display: block;
  font-family: var(--font-display);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.35em;
}
.dialogue-line.speaker-b .dialogue-name { color: var(--fg-muted); }

/* Arabic line (top of bubble) — Tajawal Light, RTL, right-aligned */
.dialogue-ar {
  font-family: var(--font-arabic);
  font-size: 1.45rem;
  line-height: 1.55;
  color: var(--fg);
  direction: rtl;
  text-align: right;
  margin: 0 0 0.15em;
  font-weight: 300;
  font-feature-settings: 'liga' 1, 'calt' 1;
}
.dialogue-line.speaker-b .dialogue-ar { color: var(--fg); }

/* Transliteration (under Arabic) — mono, italic, muted */
.dialogue-tr {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--fg-muted);
  margin: 0;
  font-style: italic;
  letter-spacing: 0.01em;
  direction: ltr;
  text-align: left;
}
.dialogue-line.speaker-b .dialogue-tr { text-align: right; }

/* Optional Russian translation (third pipe field) */
.dialogue-ru {
  font-size: 0.92rem;
  line-height: 1.45;
  color: var(--fg-subtle);
  margin: 0.35em 0 0;
  padding-top: 0.35em;
  border-top: 1px dashed var(--rule);
}

/* ----------------------------------------------------------------------
   Audio pill — from lecture-assetLib-template / grand-language-template.
   Play button + animated waveform + duration. Driven by audio.js.
---------------------------------------------------------------------- */
.audio-pill {
  display: flex;
  align-items: center;
  gap: 1em;
  background: var(--glass-bg);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--rule);
  padding: 0.75em 1.4em 0.75em 0.75em;
  border-radius: var(--r-pill);
  margin: 1.5em 0;
  width: 100%;
  box-sizing: border-box;
  break-inside: avoid;
}
.audio-pill .play-btn {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--accent);
  display: grid;
  place-items: center;
  color: var(--on-accent);
  border: none;
  cursor: pointer;
  flex-shrink: 0;
  transition: transform 0.15s, box-shadow 0.15s;
}
.audio-pill .play-btn:hover {
  transform: scale(1.06);
  box-shadow: 0 0 24px var(--accent-glow);
}
.audio-pill .play-btn svg { width: 18px; height: 18px; fill: currentColor; }
.audio-pill .waveform {
  display: flex;
  gap: 3px;
  align-items: center;
  height: 28px;
  flex: 1;
  min-width: 0;        /* allow shrinking inside narrow containers */
}
.audio-pill .wave-bar {
  width: 3px;
  background: var(--fg-subtle);
  border-radius: 2px;
  transition: background 0.15s, height 0.15s;
}
.audio-pill .wave-bar.active { background: var(--accent); }
.audio-pill .audio-time {
  font-family: var(--font-mono);
  font-size: 0.85em;
  color: var(--fg-muted);
  letter-spacing: 0.02em;
}
.audio-pill .audio-title {
  font-size: 0.88em;
  color: var(--fg-muted);
  margin-left: 0.5em;
  border-left: 1px solid var(--rule);
  padding-left: 0.85em;
}

/* ----------------------------------------------------------------------
   Quiz — multiple choice (A/B/C). Click to reveal correctness.
   Driven by quiz.js. Each .quiz-option has data-correct="true|false".
---------------------------------------------------------------------- */
.quiz-block {
  display: grid;
  gap: 0.8em;
  margin: 2em 0;
  break-inside: avoid;
}
.quiz-question {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--fg);
  margin: 0 0 0.6em;
  letter-spacing: -0.01em;
}
.quiz-kicker {
  display: block;
  font-size: 0.72em;
  font-weight: 700;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.4em;
}
.quiz-option {
  display: flex;
  align-items: center;
  gap: 0.9em;
  background: var(--glass-bg);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 2px solid var(--rule);
  padding: 0.85em 1.2em;
  border-radius: var(--r-md);
  font-size: 1rem;
  font-weight: 500;
  color: var(--fg);
  cursor: pointer;
  text-align: left;
  font-family: var(--font-body);
  width: 100%;
  transition: border-color 0.18s, background 0.18s, transform 0.15s;
}
.quiz-option:hover:not(.revealed) {
  border-color: var(--accent-dim);
  transform: translateY(-1px);
}
.quiz-option .quiz-letter {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--surface-subtle);
  display: grid;
  place-items: center;
  color: var(--accent);
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 0.95rem;
  flex-shrink: 0;
}
.quiz-option.revealed[data-correct="true"] {
  border-color: var(--accent);
  background: var(--accent-dim);
  box-shadow: 0 0 30px var(--accent-dim);
}
.quiz-option.revealed[data-correct="true"] .quiz-letter {
  background: var(--accent);
  color: var(--on-accent);
}
.quiz-option.revealed[data-correct="false"] {
  border-color: #d97373;
  background: rgba(217, 115, 115, 0.10);
  opacity: 0.6;
}
.quiz-option.revealed[data-correct="false"] .quiz-letter {
  background: rgba(217, 115, 115, 0.3);
  color: var(--fg);
}
.quiz-feedback {
  font-size: 0.92em;
  color: var(--accent);
  font-style: italic;
  margin: 0.5em 0 0;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.25s, transform 0.25s;
}
.quiz-block.revealed .quiz-feedback {
  opacity: 1;
  transform: translateY(0);
}

/* ----------------------------------------------------------------------
   Timeline — horizontal nodes with date + Arabic + body.
   Adapted from grand-history-template + lecture-assetLib.
---------------------------------------------------------------------- */
.timeline {
  display: flex;
  justify-content: space-between;
  gap: 1.5em;
  position: relative;
  margin: 2.5em 0;
  padding: 2em 1em 1em;
  break-inside: avoid;
  flex-wrap: wrap;
}
.timeline-line {
  position: absolute;
  top: 2.55em;
  left: 1em;
  right: 1em;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--accent), var(--accent), transparent);
  z-index: 1;
  pointer-events: none;
}
.timeline-node {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  flex: 1;
  min-width: 130px;
  max-width: 200px;
  position: relative;
  z-index: 2;
}
.timeline-node .node-dot {
  width: 24px;
  height: 24px;
  background: var(--bg);
  border: 3px solid var(--accent);
  border-radius: 50%;
  margin-bottom: 0.85em;
}
.timeline-node.active .node-dot {
  background: var(--accent);
  box-shadow: 0 0 20px var(--accent-glow);
  animation: aoa-pulse 2.5s infinite;
}
.timeline-node .node-ar {
  font-family: var(--font-arabic);
  font-size: 2rem;
  color: var(--accent);
  line-height: 1.3;
  margin-bottom: 0.3em;
  direction: rtl;
  text-align: right;
  font-weight: 300;
  font-feature-settings: 'liga' 1, 'calt' 1;
}
.timeline-node .node-date {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--accent);
  margin: 0 0 0.4em;
}
.timeline-node .node-body {
  font-size: 0.85rem;
  color: var(--fg-muted);
  line-height: 1.45;
  margin: 0;
}
@keyframes aoa-pulse {
  0%   { box-shadow: 0 0 0 0 var(--accent-glow); }
  70%  { box-shadow: 0 0 0 14px rgba(0, 0, 0, 0); }
  100% { box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); }
}

/* ----------------------------------------------------------------------
   Root tree — central Arabic root + radiating word panels.
   The Method-of-the-Root visualization. From lecture-assetLib.
---------------------------------------------------------------------- */
.root-tree {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 1.5em;
  align-items: center;
  margin: 2.5em 0;
  padding: 1em;
  break-inside: avoid;
}
.root-tree-hub {
  width: 180px;
  height: 180px;
  border-radius: 50%;
  background: var(--accent-dim);
  border: 2px solid var(--accent);
  box-shadow: 0 0 60px var(--accent-glow);
  display: grid;
  place-items: center;
  font-family: var(--font-arabic);
  font-size: 4rem;
  color: var(--accent);
  direction: rtl;
  line-height: 1;
  text-shadow: 0 0 30px var(--accent-glow);
  justify-self: center;
  font-weight: 300;
  font-feature-settings: 'liga' 1, 'calt' 1;
}
.root-tree-branches {
  display: grid;
  gap: 0.7em;
}
.root-tree-branches.left  { justify-items: end;   text-align: right; }
.root-tree-branches.right { justify-items: start; text-align: left; }
.root-branch {
  display: inline-grid;
  gap: 0.15em;
  background: var(--glass-bg);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  padding: 0.7em 1.1em;
  transition: border-color 0.18s, transform 0.18s, box-shadow 0.18s;
}
.root-branch:hover {
  border-color: var(--accent-dim);
  transform: translateY(-2px);
  box-shadow: 0 8px 24px var(--accent-dim);
}
.root-branch .ar {
  font-family: var(--font-arabic);
  font-size: 1.8rem;
  color: var(--fg);
  direction: rtl;
  font-weight: 300;
  margin: 0;
  line-height: 1.4;
  font-feature-settings: 'liga' 1, 'calt' 1;
}
.root-branch .gloss {
  font-size: 0.82rem;
  color: var(--fg-muted);
  margin: 0;
}

/* ----------------------------------------------------------------------
   Stat card — big gold number + uppercase label
---------------------------------------------------------------------- */
.stat-card {
  text-align: center;
  padding: 1.5em 1em;
  margin: 1.5em 0;
  border-radius: var(--r-lg);
  background: var(--glass-bg);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--rule);
  break-inside: avoid;
}
.stat-card .stat-num {
  font-family: var(--font-display);
  font-size: 4.5rem;
  font-weight: 900;
  color: var(--accent);
  line-height: 1;
  letter-spacing: -0.04em;
  text-shadow: 0 0 40px var(--accent-dim);
  margin: 0;
}
.stat-card .stat-label {
  font-size: 0.82rem;
  letter-spacing: 0.25em;
  text-transform: uppercase;
  color: var(--fg-muted);
  margin: 0.4em 0 0;
  font-weight: 600;
}

/* ----------------------------------------------------------------------
   Flashcard — adapted from flashcards-template #1.html.
   Two-column glass card: text left, big Arabic right.
---------------------------------------------------------------------- */
/* Flashcard — exact layout from flashcards-template #1.html:
   2-column glass card. Left column = kicker + Russian title + subtitle +
   meta rows (plural, root, synonyms). Right column = huge Arabic hero.
   Click to flip → back side shows full word-info page (examples, notes,
   antonyms, conjugations, etc.) matching the AOA app's WordInfoSheet. */
.flashcard {
  position: relative;
  perspective: 2000px;
  /* Vertical breathing room above/below so the card reads as a hero element
     rather than another block of text. Phone-app feel: cap card width around
     560px and auto-center, so it doesn't dominate a wide prose column but
     stays substantial enough to read comfortably on desktop (matches the
     PDF's typography sizes set in print.css). */
  margin: 3em auto;
  min-height: 280px;
  max-width: 560px;
  width: 100%;
  break-inside: avoid;
  cursor: pointer;
}
.flashcard-inner {
  position: relative;
  width: 100%;
  /* CSS Grid stack: both faces share a single cell, so the inner sizes to
     whichever face is taller — content drives the height, never the other
     way round. Replaces the old `position:absolute; inset:0` pattern which
     locked faces to a fixed `min-height` and clipped any overflow. The 3D
     flip still works: `transform-style: preserve-3d` is unaffected by the
     change in 2D layout. */
  display: grid;
  grid-template-areas: 'stack';
  min-height: 280px;        /* floor for empty cards; content can exceed it */
  transition: transform 0.7s cubic-bezier(0.4, 0, 0.2, 1);
  transform-style: preserve-3d;
}
.flashcard.is-flipped .flashcard-inner {
  transform: rotateY(180deg);
}
.flashcard-face {
  grid-area: stack;          /* both faces stack into the same cell */
  position: relative;        /* anchor for absolute children (tabs, hint chip) */
  width: 100%;
  box-sizing: border-box;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  border-radius: var(--r-xl);
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--rule);
  box-shadow: var(--glass-shadow);
  overflow: hidden;
  /* `backdrop-filter` defeats `backface-visibility: hidden` in Chromium/WebKit
     (a filtered element still paints its backface), so the rotated-away face
     bled through the translucent glass back. Reliable fix, independent of that
     bug: *step* each face's opacity (0s change) at the 90° mid-point of the
     0.7s flip — the card is edge-on then, so the swap is invisible. The
     .is-flipped rules below drive it; pointer-events follow so the hidden face
     never intercepts clicks. */
  transition: opacity 0s linear 0.35s;
}
.flashcard-back {
  transform: rotateY(180deg);
  opacity: 0;                 /* hidden until the flip passes edge-on */
  pointer-events: none;
}
.flashcard.is-flipped .flashcard-front { opacity: 0; pointer-events: none; }
.flashcard.is-flipped .flashcard-back  { opacity: 1; pointer-events: auto; }

/* Dialect tabs — chip row pinned to the TOP of each face. Sits above the
   2-column content via padding-top on .flashcard-front (added when the card
   carries .flashcard--has-dialects). Clicks stopPropagation in flashcard.js
   so they swap the dialect without triggering a flip. */
.flashcard-dialects {
  position: absolute;
  top: 0.95em;
  left: 1em;
  right: 1em;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4em;
  z-index: 3;          /* above the flip-hint chip, below modal overlays */
}
.flashcard-dialect {
  font: 700 0.66rem/1 var(--font-body);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  padding: 0.55em 0.95em;
  border-radius: var(--r-pill);
  border: 1px solid var(--rule);
  background: transparent;
  color: var(--fg-muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.flashcard-dialect:hover {
  color: var(--fg);
  border-color: var(--accent-dim);
}
.flashcard-dialect.is-active {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
}
.flashcard-dialect:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* Flip-hint chip — bottom right of each face */
.flashcard-flip-hint {
  position: absolute;
  bottom: 0.9em;
  right: 1em;
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-family: var(--font-body);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  opacity: 0.55;
  pointer-events: none;
  z-index: 2;
}
/* No back content → nothing to flip to → don't show the "Подробнее" hint. */
.flashcard--noflip .flashcard-flip-hint { display: none !important; }

/* All Arabic inside a flashcard uses Tajawal (modern sans), overriding the
   prose Amiri default. `.flashcard [lang="ar"]` (0,2,0) ties .prose :lang(ar)
   but wins by source order (components.css loads after prose.css), and also
   covers the .landing context. */
.flashcard [lang="ar"] { font-family: var(--font-ar-card); }
.flashcard-flip-hint::before {
  content: '↻';
  font-size: 1.2em;
  letter-spacing: 0;
}

/* ── FRONT side ─────────────────────────────────────────────────────
   Vertical, left-aligned stack: tag → Arabic (full width) → Russian →
   transliteration → meta. Stacking (vs. the old text|glyph 2-column grid)
   gives the Arabic word the full card width to breathe. */
.flashcard-front {
  display: flex;
  flex-direction: column;
  align-items: stretch;          /* children fill width; text-align does the left-align */
  justify-content: flex-start;   /* tag sits at the TOP (small space above via padding) */
  gap: 0.5em;
  text-align: left;
  padding: 1.9em 2.4em 2.3em;
}
/* When dialect tabs are present, leave room above for the chip row. */
.flashcard--has-dialects .flashcard-front { padding-top: 4em; }
.flashcard-text {
  display: flex;
  flex-direction: column;
  gap: 0;
  min-width: 0;
  width: 100%;
}
.flashcard-tag {
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 0.15em;            /* small gap before the Arabic word */
  display: block;
}
.flashcard-russian {
  font-family: var(--font-body);   /* Inter — the "Claude" UI font (same family used site-wide) */
  /* Matches the printable PDF (print.css forces 1.75rem on paper). Web min
     ~1.7rem so it's readable on phones; max 2.6rem on desktop to stay close
     to the app's 44px (~2.75rem) base. */
  font-size: clamp(1.7rem, 4vw, 2.6rem);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--fg);
  margin: 0;
  text-shadow: var(--text-shadow-mid);
  word-break: break-word;
  max-width: 100%;
}
.flashcard-subtitle {
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 400;
  color: var(--fg-muted);
  margin: 0.4em 0 0;
  letter-spacing: 0.02em;
}
.flashcard-subtitle .translit {
  font-family: var(--font-mono);
  color: var(--accent);
  font-style: normal;
}
.flashcard-subtitle .dot {
  color: var(--fg-faint);
  margin: 0 0.4em;
}

/* Meta rows: "Множ. число | باصات" */
.flashcard-meta {
  margin-top: 1.6em;
  padding-top: 1.2em;
  border-top: 1px solid var(--rule);
  display: grid;
  gap: 0.6em;
}
.flashcard-meta-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1em;
  font-size: 0.9rem;
}
.flashcard-meta-label {
  color: var(--fg-muted);
  font-family: var(--font-body);
}
.flashcard-meta-value {
  font-family: var(--font-ar-card);   /* Tajawal — flashcards stay on the card font */
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--fg);
  direction: rtl;
  line-height: 1.2;
  font-feature-settings: 'liga' 1, 'calt' 1;
  text-align: right;
}
.flashcard-meta-value.latn {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 1rem;
  direction: ltr;
  color: var(--fg);
}

/* Big Arabic hero — full-width row in the vertical stack, right-aligned. */
.flashcard-hero {
  display: block;
  width: 100%;
  min-width: 0;
  overflow: hidden;              /* safety net: never let the glyph push the card wider */
  container-type: inline-size;   /* size the glyph against the card width, not the viewport */
}
/* `.flashcard .flashcard-arabic-hero` (0,2,0) MUST out-specify
   `.prose :lang(ar)` (0,1,1) — the hero glyph carries lang="ar", so the prose
   rule's 1.45em was shrinking it to ~24px on screen while the PDF's
   `6rem !important` kept it huge. That mismatch is the "tiny in HTML, huge in
   PDF" bug. The doubled-class selector wins everywhere (prose + landing). */
.flashcard .flashcard-arabic-hero {
  font-family: var(--font-ar-card);   /* Tajawal — modern sans for the card word */
  /* Sized smaller than the PDF (print.css still forces 6rem on paper). The
     container query scales the glyph against the card's own column so it always
     fits; the cap keeps it from blowing up on wide cards. */
  font-size: 3.4rem;                              /* fallback when cqi isn't supported */
  font-size: clamp(2.4rem, 15cqi, 4.2rem);        /* tighter on screen than v1 — Ali asked smaller */
  line-height: 1.1;
  color: var(--accent);
  text-align: right;                              /* push the Arabic word to the right edge of the frame */
  direction: rtl;
  text-shadow:
    0 0 40px var(--accent-dim),
    var(--text-shadow-mid);
  margin: 0;
  font-weight: 500;                                /* lighter than the bold v1 */
  font-feature-settings: 'liga' 1, 'calt' 1;
  word-break: break-word;
  max-width: 100%;
}

/* ── BACK side (info page) ──────────────────────────────────────── */
.flashcard-back-inner {
  display: grid;
  grid-template-rows: auto 1fr;
  gap: 1em;
  padding: 2.1em 2.35em 2.65em;
  height: 100%;
  overflow-y: auto;
}
.flashcard-back-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1em;
  padding-bottom: 0.85em;
  border-bottom: 1px solid var(--rule);
}
.flashcard .flashcard-back-arabic {
  font-family: var(--font-ar-card);   /* Tajawal */
  font-size: 3rem;
  font-weight: 300;                   /* light — Ali asked for "light" on the back */
  color: var(--accent);
  direction: rtl;
  line-height: 1;
  margin: 0;
  text-shadow: 0 0 22px var(--accent-dim);   /* slightly tamer glow to match the lighter stroke */
  font-feature-settings: 'liga' 1, 'calt' 1;
}
.flashcard-back-meta {
  text-align: right;
  font-family: var(--font-body);
}
.flashcard-back-translation {
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--fg);
  margin: 0;
}
.flashcard-back-translit {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--fg-muted);
  margin: 0.2em 0 0;
}
.flashcard-back-body {
  display: grid;
  gap: 1em;
  align-content: start;
}
.flashcard-back-section {
  display: grid;
  gap: 0.5em;
}
.flashcard-back-section-label {
  font-family: var(--font-body);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
}
.flashcard-back-field {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1em;
  font-size: 0.9rem;
}
.flashcard-back-field .label { color: var(--fg-muted); }
.flashcard-back-field .value {
  font-family: var(--font-ar-card);   /* Tajawal */
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--fg);
  direction: rtl;
  font-feature-settings: 'liga' 1, 'calt' 1;
}
.flashcard-back-field .value.latn {
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-weight: 600;
  direction: ltr;
}

/* Example sentences on back */
.flashcard-back-example {
  display: grid;
  gap: 0.15em;
  padding: 0.7em 0.9em;
  background: var(--surface-subtle);
  border-radius: var(--r-md);
  border-left: 2px solid var(--accent);
}
.flashcard-back-example .ar {
  font-family: var(--font-ar-card);   /* Tajawal */
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--fg);
  direction: rtl;
  text-align: right;
  line-height: 1.55;
}
.flashcard-back-example .ru {
  font-size: 0.88rem;
  color: var(--fg-muted);
  font-style: italic;
}

.flashcard-back-note {
  font-size: 0.88rem;
  color: var(--fg-muted);
  font-style: italic;
  line-height: 1.55;
  padding: 0.6em 0.85em;
  background: var(--accent-soft);
  border-radius: var(--r-md);
}

/* ----------------------------------------------------------------------
   Flashcard LIST — single-card swipe carousel, mirroring the AOA PWA's
   cards page UX. One card visible at a time, swipeable horizontally; prev
   and next arrow buttons live in the carousel's outer grid columns, so on
   wide desktops they fill the gutters that otherwise look like empty
   space next to a centered card (no more "hole"). The track itself caps
   the card at ~560px for readability; the outer container is wider so the
   buttons can sit outside the card.
---------------------------------------------------------------------- */
.flashcardlist-carousel {
  position: relative;
  width: 100%;
  max-width: 788px;                  /* 760 + the 28px of inline padding below */
  margin: 2.5em auto;
  padding-inline: 0.9em;             /* horizontal breathing room around the list */
  box-sizing: border-box;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  grid-template-areas:
    "prev track next"
    ".    dots  .";
  column-gap: 0.8em;
  row-gap: 0.6em;
  align-items: stretch;
}
.flashcardlist-track {
  grid-area: track;
  position: relative;
  display: flex;
  align-items: stretch;              /* every card stretches to the tallest one */
  gap: 1.6em;                        /* breathing room between cards on swipe */
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  /* overflow-x:auto forces overflow-y to clip too, so give the cards vertical
     AND a little horizontal room — otherwise their borders/soft shadows get
     cut off at the track edges. */
  padding: 0.85em 0.5em 1.05em;
  scroll-padding-inline: 0.5em;
  scrollbar-width: none;
  min-width: 0;
}
.flashcardlist-track::-webkit-scrollbar { display: none; }
.flashcardlist-track:focus-visible {
  outline: 2px solid var(--accent-dim);
  outline-offset: 3px;
  border-radius: var(--r-lg);
}
.flashcardlist-track .flashcard {
  flex: 0 0 100%;                    /* one card per swipe view */
  scroll-snap-align: center;
  scroll-snap-stop: always;
  margin: 0;
  max-width: none;                   /* override the standalone 560px cap */
  min-height: 360px;                 /* baseline so short cards don't look squat */
}
/* Force the single-column STACKED layout (Arabic glyph on top, full width)
   for cards inside the list, on every viewport. The default 2-col front
   squeezes the glyph into a narrow right column, which collapses the
   container-query (`cqi`) font size to ~24px — far smaller than the PDF's
   fixed 6rem. Stacking gives the glyph the card's full width so it renders
   large, matching the AOA app card + the PDF. */
/* List cards inherit the base vertical left-aligned front; just tune padding. */
.flashcardlist-track .flashcard-front { padding: 1.9em 1.9em 2.2em; }
.flashcardlist-track .flashcard--has-dialects .flashcard-front { padding-top: 4em; }
.flashcardlist-track .flashcard-meta { width: 100%; }

/* Prev / next nav buttons in the outer gutters */
.flashcardlist-nav {
  grid-row: 1;
  align-self: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--rule);
  background: var(--bg-elev);
  color: var(--fg);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.15s;
}
.flashcardlist-nav--prev { grid-area: prev; }
.flashcardlist-nav--next { grid-area: next; }
.flashcardlist-nav:hover:not([disabled]) {
  background: var(--accent);
  color: var(--on-accent);
  border-color: var(--accent);
}
.flashcardlist-nav:active:not([disabled]) { transform: scale(0.94); }
.flashcardlist-nav:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
.flashcardlist-nav[disabled] {
  opacity: 0.35;
  cursor: not-allowed;
}

/* ======================================================================
   Private-lesson gate — blurs the locked content + overlays a purchase card.
   `.lesson-gated` lights up via build.mjs when a `<!-- course: slug -->` is
   declared in the source MD. `.is-locked` is on until lesson-gate.js
   confirms the user has purchased.
====================================================================== */
.lesson-gated.is-locked main,
.lesson-gated.is-locked .prose,
.lesson-gated.is-locked .landing {
  filter: blur(12px);
  pointer-events: none;
  user-select: none;
}
.lesson-gate-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: 1.2rem;
  background:
    radial-gradient(60% 50% at 50% 30%, var(--accent-soft), transparent 70%),
    rgba(7, 5, 4, 0.78);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  animation: lesson-gate-fade 0.28s ease-out;
}
@keyframes lesson-gate-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.lesson-gate-card {
  width: 100%;
  max-width: 480px;
  padding: 2.4em 2em 1.8em;
  border-radius: var(--r-lg);
  background:
    radial-gradient(140% 60% at 50% 0%, var(--accent-soft), transparent 60%),
    var(--bg);
  border: 1.5px solid var(--accent);
  box-shadow:
    0 30px 80px -22px var(--accent-glow),
    inset 0 0 0 1px rgba(255, 255, 255, 0.04);
  text-align: center;
  color: var(--fg);
}
.lesson-gate-icon {
  font-size: 2.6rem;
  line-height: 1;
  margin-bottom: 0.4em;
  color: var(--accent);
}
.lesson-gate-title {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--fg);
  margin: 0 0 0.5em;
}
.lesson-gate-sub {
  color: var(--fg-muted);
  font-size: 0.96rem;
  line-height: 1.55;
  margin: 0 0 1.3em;
  max-width: 38ch;
  margin-inline: auto;
}
.lesson-gate-actions {
  display: flex;
  flex-direction: column;
  gap: 0.7em;
  margin-bottom: 1em;
}
.lesson-gate-actions .btn {
  width: 100%;
  justify-content: center;
}
.lesson-gate-fineprint {
  font-size: 0.78rem;
  color: var(--fg-muted);
  letter-spacing: 0.02em;
  margin: 0;
}
:root[data-theme="light"] .lesson-gate-overlay {
  background:
    radial-gradient(60% 50% at 50% 30%, var(--accent-soft), transparent 70%),
    rgba(255, 255, 255, 0.84);
}

/* ======================================================================
   Floating "back to top" button — shared by every layout (page/landing/site).
   Lives in components.css (not landing.css) so it works on lesson pages too.
====================================================================== */
.scroll-top {
  position: fixed;
  right: clamp(0.9rem, 2.5vw, 1.8rem);
  bottom: clamp(0.9rem, 2.5vw, 1.8rem);
  z-index: 60;
  width: 2.85rem;
  height: 2.85rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--accent-dim);
  border-radius: 50%;
  padding: 0;
  background: var(--accent);
  color: var(--on-accent);
  box-shadow:
    0 12px 28px -10px var(--accent-glow),
    inset 0 0 0 1px rgba(255, 255, 255, 0.08);
  cursor: pointer;
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity 0.22s, transform 0.22s, background 0.18s, box-shadow 0.22s;
}
.scroll-top svg {
  width: 1.2rem;
  height: 1.2rem;
  display: block;
}
.scroll-top.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
.scroll-top:hover {
  background: var(--accent);
  transform: translateY(-3px);
  box-shadow:
    0 18px 36px -10px var(--accent-glow),
    inset 0 0 0 1px rgba(255, 255, 255, 0.18);
}
.scroll-top:active { transform: translateY(0); }
.scroll-top:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}
/* Light theme: stronger border, lighter shadow so the gold button still reads
   on a white background. */
:root[data-theme="light"] .scroll-top {
  box-shadow: 0 10px 24px -10px rgba(0, 0, 0, 0.25);
}
/* On phones where a sticky `.mobile-cta` pill bar may sit at the bottom on
   landing/site pages, push the scroll-top button above it so they don't
   stack. The pill is ≤760px-only; outside that range the corner is free. */
@media (max-width: 760px) {
  .scroll-top {
    bottom: 5.4rem;   /* clears the ~4.6rem mobile-cta bar + a small gap */
  }
}
/* Never print the button (PDF export, /tracks pages printed by a buyer). */
@media print {
  .scroll-top { display: none !important; }
}

/* On narrow viewports the card spans full width and the two nav buttons
   drop below the dots, sitting side by side and centered (they meet in the
   middle of a 2-col row with a small gap). 44px gutters are too generous
   when every pixel matters on a phone. */
@media (max-width: 560px) {
  .flashcardlist-carousel {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "track track"
      "dots  dots"
      "prev  next";
    column-gap: 0;
  }
  .flashcardlist-nav {
    grid-row: auto;
    width: 40px;
    height: 40px;
  }
  .flashcardlist-nav--prev { grid-area: prev; justify-self: end;   margin-right: 0.35em; }
  .flashcardlist-nav--next { grid-area: next; justify-self: start; margin-left: 0.35em; }
}

/* dots */
.flashcardlist-dots {
  grid-area: dots;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.5em;
  margin-top: 0;
}
.flashcardlist-dots button {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid var(--rule);
  background: transparent;
  padding: 0;
  cursor: pointer;
  transition: background 0.15s, transform 0.15s;
}
.flashcardlist-dots button:hover { background: var(--accent-dim); }
.flashcardlist-dots button.is-active {
  background: var(--accent);
  border-color: var(--accent);
  transform: scale(1.2);
}

/* ======================================================================
   :::todo — branded checklist
   ====================================================================== */
.todo-card {
  margin: 2em 0;
  padding: 1.4em 1.6em;
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
}
.todo-title {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 1em;
}
.todo-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.7em; }
.todo-item {
  display: flex;
  align-items: flex-start;
  gap: 0.75em;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--fg);
}
.todo-box {
  flex-shrink: 0;
  width: 1.35em;
  height: 1.35em;
  margin-top: 0.05em;
  border: 1.5px solid var(--rule);
  border-radius: 0.4em;
  display: grid;
  place-items: center;
  font-size: 0.85em;
  font-weight: 800;
  color: var(--on-accent);
  transition: background 0.15s, border-color 0.15s;
}
.todo-item.is-done .todo-box { background: var(--accent); border-color: var(--accent); }
.todo-item.is-done .todo-text { color: var(--fg-muted); text-decoration: line-through; text-decoration-color: var(--accent-dim); }
/* interactive (JS-enabled) state: clickable + hover affordance */
.todo-item.is-interactive { cursor: pointer; border-radius: var(--r-sm); transition: background 0.12s; }
.todo-item.is-interactive:hover { background: var(--accent-soft); }
.todo-item.is-interactive:hover .todo-box { border-color: var(--accent); }
.todo-item.is-interactive:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ======================================================================
   :::quote — featured pull-quote
   ====================================================================== */
.pullquote {
  margin: 2.4em 0;
  padding: 1.6em 1.8em 1.6em 2.6em;
  position: relative;
  border-left: 3px solid var(--accent);
  border-radius: var(--r-md);
  background: var(--accent-soft);
}
.pullquote::before {
  content: '\201C';                 /* “ */
  position: absolute;
  top: -0.15em;
  left: 0.3em;
  font-family: var(--font-display);
  font-size: 3.4rem;
  line-height: 1;
  color: var(--accent-dim);
  pointer-events: none;
}
.pullquote-body {
  margin: 0;
  border: 0;
  padding: 0;
  font-family: var(--font-serif, var(--font-display));
  font-size: 1.3rem;
  font-style: italic;
  line-height: 1.5;
  color: var(--fg);
}
.pullquote-cite {
  margin-top: 1em;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.6em;
  font-style: normal;
}
.pullquote-author { font-weight: 700; color: var(--fg); }
.pullquote-author::before { content: '— '; color: var(--accent); }
.pullquote-role { font-size: 0.9rem; color: var(--fg-muted); }
/* *emphasis* inside an already-italic quote: flip upright + gold so it pops */
.pullquote-em { font-style: normal; color: var(--accent-strong); font-weight: 600; }

/* ======================================================================
   :::image — framed figure + caption  (also styles bare markdown images)
   ====================================================================== */
.media-figure {
  margin: 2.2em 0;
  padding: 0.6em;
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  background: var(--glass-bg);
  box-shadow: var(--glass-shadow);
}
.media-figure--bare { padding: 0; border: 0; background: none; box-shadow: none; }
/* The .prose img rule (prose.css) adds its own border/margin/shadow to every
   image; override here (higher specificity) since the figure is the frame. */
.media-figure .media-img {
  display: block;
  width: 100%;
  height: auto;
  margin: 0;
  border: 0;
  box-shadow: none;
  border-radius: var(--r-md);
}
.figure-caption {
  margin-top: 0.7em;
  text-align: center;
  font-size: 0.85rem;
  color: var(--fg-muted);
  font-style: italic;
}

/* ======================================================================
   :::map — static location card (no tile service; offline + PDF safe)
   ====================================================================== */
.map-card {
  position: relative;
  margin: 2.2em 0;
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--glass-bg);
  color: inherit;
  transition: border-color 0.15s, transform 0.15s;
}
.map-card--link:hover { border-color: var(--accent-dim); transform: translateY(-2px); }
/* stretched link covers the whole card; meta/pin sit above for legibility */
.map-link { position: absolute; inset: 0; z-index: 3; text-indent: -9999px; overflow: hidden; }
.map-stage, .map-meta { position: relative; z-index: 1; }
.map-stage {
  position: relative;
  aspect-ratio: 16 / 7;
  display: grid;
  place-items: center;
  overflow: hidden;
}
.map-image { width: 100%; height: 100%; object-fit: cover; }
.map-stage--empty {
  background:
    radial-gradient(circle at 50% 40%, var(--accent-soft), transparent 70%),
    repeating-linear-gradient(0deg, var(--rule) 0 1px, transparent 1px 26px),
    repeating-linear-gradient(90deg, var(--rule) 0 1px, transparent 1px 26px),
    var(--bg-elev);
}
.map-pin {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -100%);
  color: var(--accent);
  filter: drop-shadow(0 3px 5px rgba(0,0,0,0.45));
}
.map-stage:not(.map-stage--empty) .map-pin { color: #fff; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.6)); }
.map-meta {
  display: flex;
  flex-direction: column;
  gap: 0.25em;
  padding: 1em 1.2em;
}
.map-name { font-family: var(--font-display); font-weight: 700; font-size: 1.1rem; color: var(--fg); }
.map-coords { font-family: var(--font-mono); font-size: 0.82rem; color: var(--fg-muted); }
.map-note { font-size: 0.9rem; color: var(--fg-muted); }
.map-open { margin-top: 0.3em; font-size: 0.8rem; font-weight: 700; letter-spacing: 0.04em; color: var(--accent); }

/* ======================================================================
   :::chart — build-time inline SVG (pie / donut / bar / line / radar)
   ====================================================================== */
.chart-figure {
  margin: 2.4em 0;
  padding: 1.5em 1.4em 1.3em;
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
}
.chart-title {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent);
  text-align: center;
  margin-bottom: 1em;
}
.chart-canvas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 1.4em;
}
.chart-svg { width: 100%; max-width: 360px; height: auto; overflow: visible; }
.chart-svg--pie, .chart-svg--radar { max-width: 260px; }
/* shared text + axis styling */
.chart-svg text { font-family: var(--font-body); fill: var(--fg); }
.chart-axis { stroke: var(--rule); stroke-width: 1; }
.chart-axis-label { font-size: 13px; fill: var(--fg-muted); }
.chart-bar-val { font-size: 14px; font-weight: 700; fill: var(--fg); }
.chart-bar { transition: opacity 0.15s; }
/* line */
.chart-line { stroke: var(--accent); stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.chart-area { fill: var(--accent-soft); }
.chart-dot { fill: var(--accent); stroke: var(--bg); stroke-width: 1.5; }
/* pie / donut */
.chart-donut-total { font-family: var(--font-display); font-weight: 800; font-size: 26px; fill: var(--fg); }
.chart-legend { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5em; min-width: 130px; }
.chart-legend-item { display: flex; align-items: center; gap: 0.55em; font-size: 0.98rem; color: var(--fg); }
.chart-swatch { width: 0.85em; height: 0.85em; border-radius: 3px; flex-shrink: 0; }
.chart-legend-label { flex: 1; }
.chart-legend-val { font-weight: 700; color: var(--fg-muted); }
/* radar */
.chart-radar-grid { fill: none; stroke: var(--rule); stroke-width: 1; }
.chart-radar-axis { stroke: var(--rule); stroke-width: 1; }
.chart-radar-area { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 2; }
.chart-radar-dot { fill: var(--accent); }
.chart-radar-label { font-size: 13px; fill: var(--fg); }
.chart-radar-val { font-weight: 700; font-size: 13.5px; fill: var(--accent-strong); }

/* ----------------------------------------------------------------------
   Note — subtle aside (less prominent than callout)
---------------------------------------------------------------------- */
.note-block {
  position: relative;
  padding: 1.1em 1.3em 1.1em 2.8em;
  margin: 1.5em 0;
  border-radius: var(--r-md);
  background: rgba(255, 255, 255, 0.025);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--rule);
  color: var(--fg-muted);
  font-size: 0.97em;
  font-style: italic;
  break-inside: avoid;
}
.note-block::before {
  content: '✎';
  position: absolute;
  left: 1em;
  top: 1em;
  font-size: 1.15em;
  color: var(--accent);
  font-style: normal;
  opacity: 0.7;
}
.note-block > :first-child { margin-top: 0; }
.note-block > :last-child  { margin-bottom: 0; }

/* ----------------------------------------------------------------------
   Important — prominent banner
---------------------------------------------------------------------- */
.important-block {
  position: relative;
  padding: 1.5em 1.8em 1.5em 4.2em;
  margin: 2.25em 0;
  border-radius: var(--r-lg);
  background:
    linear-gradient(135deg, var(--accent-soft) 0%, transparent 100%),
    var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--accent-dim);
  box-shadow:
    0 30px 60px rgba(0, 0, 0, 0.4),
    inset 0 0 0 1px var(--accent-dim);
  color: var(--fg);
  break-inside: avoid;
}
.important-block::before {
  content: '★';
  position: absolute;
  left: 1.25em;
  top: 1.1em;
  font-size: 1.7em;
  color: var(--accent);
  filter: drop-shadow(0 0 12px var(--accent-glow));
}
.important-block::after {
  content: 'IMPORTANT';
  position: absolute;
  top: -0.65em;
  left: 3em;
  font-family: var(--font-body);
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.25em;
  color: var(--on-accent);
  background: var(--accent);
  padding: 0.4em 0.85em;
  border-radius: var(--r-pill);
}
.important-block > :first-child { margin-top: 0; }
.important-block > :last-child  { margin-bottom: 0; }

/* ----------------------------------------------------------------------
   Definition — glossary term + body
---------------------------------------------------------------------- */
.definition {
  display: grid;
  gap: 0.5em;
  padding: 1.4em 1.6em;
  margin: 1.75em 0;
  border-radius: var(--r-md);
  background: var(--glass-bg);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--rule);
  border-top: 3px solid var(--accent);
  break-inside: avoid;
}
.definition-term {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--accent);
  margin: 0;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-shadow: 0 0 20px var(--accent-dim);
}
.definition-term::after {
  content: ' —';
  color: var(--fg-faint);
  font-weight: 400;
}
.definition-body {
  color: var(--fg-muted);
  font-size: 1em;
  margin: 0;
  line-height: 1.6;
}
.definition-body > :first-child { margin-top: 0; }
.definition-body > :last-child  { margin-bottom: 0; }

/* ----------------------------------------------------------------------
   Roadmap — numbered steps with arrow connectors
---------------------------------------------------------------------- */
.roadmap {
  margin: 2.5em 0;
  display: grid;
  gap: 1em;
  break-inside: avoid;
}
.roadmap-step {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: 1.25em;
  align-items: center;
  padding: 1.2em 1.5em;
  background: var(--glass-bg);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  transition: transform 0.25s, box-shadow 0.25s, border-color 0.25s;
}
.roadmap-step:hover {
  transform: translateY(-2px);
  box-shadow: 0 18px 50px -10px var(--accent-dim);
  border-color: var(--accent-dim);
}
.roadmap-step-num {
  width: 64px;
  height: 64px;
  border-radius: var(--r-pill);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 1.55rem;
  font-weight: 800;
  background: var(--accent-soft);
  color: var(--accent);
  border: 1px solid var(--accent-dim);
  text-shadow: 0 0 20px var(--accent-glow);
}
.roadmap-step-body { display: grid; gap: 0.2em; }
.roadmap-step-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.15rem;
  color: var(--fg);
  margin: 0;
  letter-spacing: -0.01em;
}
.roadmap-step-meta {
  font-size: 0.88rem;
  color: var(--fg-muted);
  margin: 0;
}
.roadmap-arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  color: var(--accent);
  opacity: 0.5;
  line-height: 0.5;
  margin-block: -0.6em;
}

/* ----------------------------------------------------------------------
   Blockquote
---------------------------------------------------------------------- */
.prose blockquote {
  position: relative;
  margin: 2em 0;
  padding: 1.1em 1.6em;
  border-left: 3px solid var(--accent);
  background: var(--surface-subtle);
  border-radius: 0 var(--r-md) var(--r-md) 0;
  font-style: italic;
  color: var(--fg-muted);
  break-inside: avoid;
}
.prose blockquote::before {
  content: "\201C";
  position: absolute;
  left: 0.3em;
  top: -0.05em;
  font-size: 3.5em;
  line-height: 1;
  color: var(--accent);
  opacity: 0.2;
  font-family: Georgia, serif;
  pointer-events: none;
}
.prose blockquote > :first-child { margin-top: 0; }
.prose blockquote > :last-child  { margin-bottom: 0; }

/* ----------------------------------------------------------------------
   Code
---------------------------------------------------------------------- */
.prose pre,
.prose pre.shiki {
  background: var(--bg-code) !important;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  padding: 1.2em 1.4em;
  overflow-x: auto;
  font-size: 0.9em;
  line-height: 1.6;
  font-family: var(--font-mono);
  break-inside: avoid;
  position: relative;
}
.prose pre code {
  background: none;
  padding: 0;
  font-family: var(--font-mono);
  font-feature-settings: 'liga' 0;
}
.prose p code,
.prose li code,
.prose td code,
.prose th code {
  background: var(--accent-soft);
  color: var(--accent);
  padding: 0.15em 0.5em;
  border-radius: var(--r-sm);
  font-size: 0.88em;
  font-family: var(--font-mono);
  font-weight: 500;
  border: 1px solid var(--accent-dim);
}

.copy-btn {
  position: absolute;
  top: 0.6em;
  right: 0.6em;
  padding: 0.35em 0.85em;
  font-size: 0.72em;
  font-family: var(--font-body);
  font-weight: 700;
  background: var(--bg-elev);
  color: var(--fg-muted);
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.prose pre:hover .copy-btn { opacity: 1; }
.copy-btn:hover { color: var(--accent); border-color: var(--accent); }
.copy-btn.copied { color: var(--accent); border-color: var(--accent); }

/* ----------------------------------------------------------------------
   Details / Toggle
---------------------------------------------------------------------- */
.prose details {
  margin: 1.5em 0;
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--glass-bg);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  overflow: hidden;
}
.prose details > summary {
  cursor: pointer;
  font-weight: 700;
  list-style: none;
  outline: none;
  padding: 1em 1.25em;
  display: flex;
  align-items: center;
  gap: 0.6em;
  transition: background 0.15s;
  font-family: var(--font-display);
}
.prose details > summary:hover {
  background: var(--bg-elev-hi);
}
.prose details > summary::-webkit-details-marker { display: none; }
.prose details > summary::before {
  content: "›";
  display: inline-block;
  font-size: 1.4em;
  line-height: 1;
  transition: transform 0.2s;
  color: var(--accent);
  font-weight: 700;
}
.prose details[open] > summary::before { transform: rotate(90deg); }
.prose details[open] > summary { border-bottom: 1px solid var(--rule); }
.prose details > :not(summary) {
  padding: 0.6em 1.25em 1em 1.9em;   /* extra left padding so the toggle body sits indented */
}

/* ----------------------------------------------------------------------
   Tables
---------------------------------------------------------------------- */
.prose table {
  width: 100%;
  border-collapse: collapse;
  margin: 2em 0;
  font-size: 0.95em;
  font-feature-settings: 'tnum' 1;
  background: var(--glass-bg);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  overflow: hidden;
}
.prose th,
.prose td {
  padding: 0.85em 1.1em;
  border-bottom: 1px solid var(--rule);
  text-align: left;
  vertical-align: top;
}
.prose tr:last-child td { border-bottom: none; }
.prose th {
  background: var(--bg-elev);
  font-weight: 700;
  font-family: var(--font-display);
  font-size: 0.78em;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--accent);
}
.prose tr { break-inside: avoid; }
.prose tbody tr:hover { background: var(--bg-elev-hi); }

/* ----------------------------------------------------------------------
   Footnotes
---------------------------------------------------------------------- */
.footnotes {
  margin-top: 4em;
  padding-top: 1.75em;
  border-top: 1px solid var(--rule);
  font-size: 0.88em;
  color: var(--fg-muted);
}
.footnotes ol { padding-left: 1.5em; }
.footnotes li { margin-bottom: 0.5em; }
.footnote-ref a {
  text-decoration: none;
  border-bottom: none;
  font-size: 0.85em;
  vertical-align: super;
  padding: 0 0.2em;
  color: var(--accent);
}

/* ----------------------------------------------------------------------
   Table of Contents
---------------------------------------------------------------------- */
.toc {
  background: var(--glass-bg);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  padding: 1.4em 1.8em;
  margin: 2.5em 0 3em;
  font-family: var(--font-body);
  font-size: 0.95em;
}
.toc::before {
  content: "Содержание";
  display: block;
  font-weight: 700;
  font-size: 0.72em;
  text-transform: uppercase;
  letter-spacing: 0.25em;
  color: var(--accent);
  margin-bottom: 0.9em;
}
/* When toc.js attaches a real <button class="toc-toggle">, the script also
   adds `.toc--enhanced` so the static pseudo label hides — the button now
   plays that role and is interactive. Class-based (not :has) for broader
   browser support. */
.toc--enhanced::before { display: none; }
.toc-toggle {
  display: flex;
  align-items: center;
  gap: 0.7em;
  width: 100%;
  background: transparent;
  border: none;
  border-radius: var(--r-sm);
  padding: 0.35em 0.5em;
  margin: -0.35em -0.5em 0.9em;
  font: inherit;
  font-weight: 700;
  font-size: 0.72em;
  text-transform: uppercase;
  letter-spacing: 0.25em;
  color: var(--accent);
  cursor: pointer;
  transition: background 0.15s;
}
.toc-toggle:hover { background: var(--accent-soft); }
.toc-toggle:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.toc-toggle-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  flex-shrink: 0;
}
.toc-toggle-icon svg { display: block; }
/* Collapsed: hide the body. On mobile/inline TOC this is a simple vertical
   fold (toggle stays horizontal). Desktop adds a horizontal collapse — see
   the @media block lower in this file. */
.toc--collapsed > ul,
.toc--collapsed > ol { display: none; }
.toc--collapsed { padding-block: 0.6em; }
.toc--collapsed .toc-toggle { margin-bottom: 0; }
.toc ul { list-style: none; padding-left: 1.1em; margin: 0.25em 0; }
.toc > ul { padding-left: 0; }
.toc li { margin: 0.35em 0; position: relative; }
.toc a {
  display: block;
  color: var(--fg-muted);
  text-decoration: none;
  border-bottom: none;
  padding: 0.3em 0.55em 0.3em 0.7em;
  border-left: 2px solid transparent;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  margin-left: -0.7em;        /* pull the rail flush with the TOC edge */
  transition: color 0.15s, background 0.15s, border-color 0.15s, transform 0.15s;
}
.toc a:hover {
  color: var(--accent);
  background: var(--accent-soft);
  border-left-color: var(--accent-dim);
}
/* Active section (set by toc.js as the reader scrolls) — visually clear so the
   reader always sees "where am I" at a glance: gold left rail + soft gold bg +
   bold text + a slight push-right to read as "you are here". */
.toc a.is-current {
  color: var(--accent);
  font-weight: 700;
  background: var(--accent-soft);
  border-left-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent-dim);
  transform: translateX(2px);
}
/* Parent section of the currently-active subsection. Subtler than is-current
   so the reader can still tell which one is the live target. */
.toc li.is-parent > a:not(.is-current) {
  color: var(--fg);
  border-left-color: var(--accent-dim);
}
/* "You are here" caret marker rendered to the left of the active link. */
.toc a.is-current::before {
  content: "";
  position: absolute;
  left: -1.4em;
  top: 50%;
  transform: translateY(-50%);
  width: 0;
  height: 0;
  border-top: 0.4em solid transparent;
  border-bottom: 0.4em solid transparent;
  border-left: 0.5em solid var(--accent);
  filter: drop-shadow(0 0 6px var(--accent-glow));
}

/* TOC as a sticky LEFT SIDEBAR on lessons that include [[toc]].
   `:has()` scopes this to pages WITH a TOC only — everything else keeps the
   centered single column. Below 901px (and in print, where the page box is
   ~794px) the sidebar layout doesn't apply, so the TOC flows inline at its
   original position. */
@media (min-width: 901px) {
  .prose:has(.toc) {
    /* RECORDING-FRIENDLY layout. Pages that include [[toc]] are lessons that
       get screen-recorded with a camera overlay on the RIGHT-MIDDLE side, so
       the block sits LEFT of centre: small left margin (breathing room from
       the viewport edge) and a LARGE right gap reserved for the camera.
       Content column is sized for comfortable reading (~80–90ch), not the
       full 160ch measure used on non-TOC pages — wide reading lines look
       cramped once the camera covers part of the page. */
    max-width: min(100% - 2rem, calc(220px + 2.5rem + 90ch));
    margin-left: clamp(2rem, 6vw, 6rem);
    margin-right: auto;
    padding-left: 0;
    display: grid;
    grid-template-columns: 220px minmax(0, 1fr);
    column-gap: 2.5rem;
    align-items: start;
  }
  .prose:has(.toc) > * { grid-column: 2; min-width: 0; }
  .prose:has(.toc) > .toc {
    grid-column: 1;
    grid-row: 1 / 9999;          /* span all rows → sits alongside everything */
    position: sticky;
    /* Clear the sticky top nav (~68px) so the TOC's top isn't hidden behind it. */
    top: 5.5rem;
    align-self: start;
    margin: 0;
    max-height: calc(100vh - 6.5rem);
    overflow-y: auto;
    font-size: 0.85em;
    padding: 1.2em 1.4em;
  }
  /* When user collapses the TOC: shrink the sidebar column to a narrow bar
     (~36px) so the reading column gets ~180px of freed width. The bar shows
     the hamburger icon + a vertical "СОДЕРЖАНИЕ" label. Click to reopen. */
  .prose:has(.toc--collapsed) {
    grid-template-columns: 36px minmax(0, 1fr);
    column-gap: 2rem;
  }
  .prose:has(.toc--collapsed) > .toc {
    padding: 0.9em 0.3em;
    width: 36px;
    min-width: 36px;
    overflow: hidden;
    transition: width 0.2s ease, padding 0.2s ease;
  }
  /* Vertical layout in collapsed mode — hamburger on top, vertical label below. */
  .toc--collapsed .toc-toggle {
    flex-direction: column;
    gap: 0.8em;
    padding: 0.35em 0;
    margin: 0;
    width: 100%;
    text-align: center;
    justify-content: flex-start;
  }
  .toc--collapsed .toc-toggle-label {
    writing-mode: vertical-rl;
    transform: rotate(180deg);   /* read bottom-to-top → natural for left rail */
    letter-spacing: 0.3em;
    line-height: 1;
  }
}
/* When jumping to a heading (TOC click / #anchor), keep it below the sticky
   nav instead of scrolling it underneath. */
.prose h1[id], .prose h2[id], .prose h3[id], .prose h4[id],
.prose h1, .prose h2, .prose h3, .prose h4 {
  scroll-margin-top: 5.5rem;
}

/* ----------------------------------------------------------------------
   Heading anchor permalinks
---------------------------------------------------------------------- */
.prose h1 .header-anchor,
.prose h2 .header-anchor,
.prose h3 .header-anchor,
.prose h4 .header-anchor {
  text-decoration: none;
  border-bottom: none;
  color: inherit;
}
.prose h1 .header-anchor:hover,
.prose h2 .header-anchor:hover,
.prose h3 .header-anchor:hover,
.prose h4 .header-anchor:hover {
  color: var(--accent);
}

/* ----------------------------------------------------------------------
   Site navigation chrome (top-bar with brand + buttons)
---------------------------------------------------------------------- */
.site-nav {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1em;
  padding: 1em 2em;
  background: var(--nav-bg);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-bottom: 1px solid var(--rule);
}
.site-nav .brand {
  display: flex;
  align-items: center;
  gap: 0.85em;
}
.site-nav .brand-logo {
  width: 36px;
  height: 36px;
  border: 2px solid var(--accent);
  border-radius: var(--r-sm);
  display: grid;
  place-items: center;
  font-weight: 800;
  font-size: 0.78rem;
  color: var(--accent);
  font-family: var(--font-display);
  letter-spacing: 0.05em;
}
.site-nav .brand-text {
  font-size: 0.72rem;
  letter-spacing: 0.3em;
  color: var(--fg-muted);
  font-weight: 500;
  text-transform: uppercase;
}
.site-nav-right { display: flex; gap: 0.5em; }
.site-nav button {
  background: transparent;
  color: var(--fg);
  border: 1px solid var(--rule);
  border-radius: var(--r-pill);
  padding: 0.5em 1.1em;
  font-size: 0.82rem;
  font-weight: 600;
  font-family: var(--font-body);
  cursor: pointer;
  letter-spacing: 0.02em;
  transition: all 0.18s;
}
.site-nav button:hover {
  border-color: var(--accent);
  color: var(--accent);
  transform: translateY(-1px);
}
.site-nav .pdf-export {
  background: var(--accent);
  color: var(--on-accent);
  border-color: transparent;
}
.site-nav .pdf-export:hover {
  background: var(--accent-strong);
  color: var(--on-accent);
}

/* Admin indicator — shown only when copyright.js detected an admin unlock */
[data-aoa-admin="true"] .site-nav .brand::after {
  content: 'ADMIN';
  display: inline-block;
  margin-left: 0.6em;
  padding: 0.18em 0.55em;
  border-radius: var(--r-pill);
  font-size: 0.6rem;
  font-weight: 800;
  letter-spacing: 0.2em;
  background: var(--accent);
  color: var(--on-accent);
}

/* ======================================================================
   Responsive — components.css had NO media queries, so the flip-card and
   timeline (built for desktop) overflowed phones. Keep these last.
   Shared by the prose reader AND the landing/site layouts.
   ====================================================================== */

/* Flashcard — the 2-column front (text | big Arabic glyph) can't fit a
   phone. Stack it: glyph on top, text below, centered. The faces are
   absolutely positioned, so the container min-height must grow to fit. */
@media (max-width: 600px) {
  .flashcard, .flashcard-inner { min-height: 360px; }
  /* The front is already a vertical left-aligned stack (base layout); on mobile
     just tighten padding. The chip row stays left-aligned to match the stack. */
  .flashcard-front {
    gap: 0.45em;
    padding: 1.7em 1.5em 2.2em;
  }
  .flashcard--has-dialects .flashcard-front { padding-top: 3.85em; }
  .flashcard-dialects {
    top: 0.85em;
    left: 0.7em;
    right: 0.7em;
  }
  .flashcard-dialect { padding: 0.5em 0.8em; font-size: 0.6rem; }
  .flashcard .flashcard-arabic-hero { font-size: clamp(2.2rem, 18cqi, 3.8rem); }
  .flashcard-meta { width: 100%; }
  .flashcard-flip-hint { bottom: 0.7em; right: 0.8em; }
}

/* Timeline — horizontal on desktop, VERTICAL on small screens (logical:
   each milestone reads top-to-bottom with the rail running down the left). */
@media (max-width: 640px) {
  .timeline {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 1.4em 0;
  }
  /* rail runs down the CENTER */
  .timeline-line {
    top: 1.4em;
    bottom: 1.4em;
    left: 50%;
    right: auto;
    width: 2px;
    height: auto;
    transform: translateX(-50%);
    background: linear-gradient(180deg, transparent, var(--accent) 8%, var(--accent) 92%, transparent);
  }
  /* each node: [content] [dot on the center rail] [content]; content alternates
     sides so it never crosses the line. (child 1 of .timeline is .timeline-line,
     so the nodes are children 2..5 — nth-child math accounts for that.) */
  .timeline-node {
    display: grid;
    grid-template-columns: 1fr 24px 1fr;
    column-gap: 0.9em;
    row-gap: 0.1em;
    align-items: start;
    min-width: 0;
    width: 100%;
    max-width: none;      /* desktop base caps nodes at 200px — lift it so they span the block */
    padding: 0.7em 0;
  }
  .timeline-node .node-dot { grid-column: 2; grid-row: 1 / -1; align-self: start; justify-self: center; margin: 0; }
  /* default — content to the RIGHT of the rail */
  .timeline-node .node-ar { grid-column: 3; grid-row: 1; text-align: left; margin-bottom: 0.1em; }
  .timeline-node .node-date { grid-column: 3; grid-row: 2; text-align: left; }
  .timeline-node .node-body { grid-column: 3; grid-row: 3; text-align: left; }
  /* alternate nodes — content to the LEFT of the rail */
  .timeline-node:nth-child(odd) .node-ar,
  .timeline-node:nth-child(odd) .node-date,
  .timeline-node:nth-child(odd) .node-body { grid-column: 1; text-align: right; }
}

/* Horizontal callout (e.g. ВАЖНО / ГАРАНТИЯ) — on a phone the wide letter-spaced
   label eats horizontal room, cramping the body. Flip the label to a vertical
   rail so the body gets the full remaining width and reads comfortably. */
@media (max-width: 560px) {
  .callout-horizontal {
    align-items: stretch;
    gap: 0.85em;
    padding: 0.9em 1.15em;
  }
  .callout-horizontal .h-label {
    writing-mode: vertical-rl;
    text-orientation: mixed;
    letter-spacing: 0.18em;
    line-height: 1;
    align-self: center;
  }
  .callout-horizontal .h-rule {
    height: auto;          /* short bar → full-height vertical divider */
    align-self: stretch;
  }
  .callout-horizontal .h-body { min-width: 0; }
}

/* Root tree — the 3-column hub layout (1fr | hub | 1fr) needs ~480px, so it
   overflowed phones. Stack it: the root glyph on top, derivative cards below. */
@media (max-width: 600px) {
  .root-tree {
    grid-template-columns: 1fr;
    justify-items: center;
    gap: 1.1em;
  }
  .root-tree-hub { order: -1; width: 130px; height: 130px; }
  .root-tree-branches { width: 100%; gap: 0.6em; }
  .root-tree-branches.left,
  .root-tree-branches.right { justify-items: stretch; text-align: center; }
  .root-branch { width: 100%; max-width: 320px; margin-inline: auto; }

  /* Wide multi-column tables: scroll horizontally instead of overflowing the
     page (so every column stays reachable on a phone — never clipped). */
  .prose table { display: block; overflow-x: auto; width: 100%; -webkit-overflow-scrolling: touch; }
}

/* ======================================================================
   :::whiteboard — iPad-style writable canvas asset
   ====================================================================== */
.whiteboard {
  margin: 2em 0;
  padding: 0.85em;
  background: var(--bg-elev);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
  /* `--wb-ink` is the default stroke colour for the "ink" swatch — it
     adapts to theme via .whiteboard--light/.whiteboard--dark. */
  --wb-ink: #f4ece0;
  --wb-paper: #1b160f;
  --wb-grid: rgba(255, 255, 255, 0.04);
  break-inside: avoid;
}
.whiteboard--light {
  --wb-ink: #1b160f;
  --wb-paper: #f7f1e5;
  --wb-grid: rgba(0, 0, 0, 0.04);
}

.whiteboard-title {
  margin: 0 0 0.4em;
  padding-inline: 0.4em;
  font-size: 0.95em;
  font-weight: 700;
  color: var(--fg);
}
.whiteboard-prompt {
  margin: 0 0 0.6em;
  padding: 0.5em 0.8em;
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  color: var(--fg-muted);
  font-size: 0.88em;
  line-height: 1.45;
}

/* ---- Toolbar ---- */
.whiteboard-toolbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.25em;
  padding: 0.35em;
  margin-bottom: 0.55em;
  background: var(--bg-code);
  border: 1px solid var(--rule);
  border-radius: var(--r-sm);
}
.wb-tool {
  display: inline-grid;
  place-items: center;
  width: 2em;
  height: 2em;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--fg-muted);
  cursor: pointer;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
.wb-tool:hover {
  background: var(--bg-elev-hi);
  color: var(--fg);
  border-color: var(--rule);
}
.wb-tool.is-active {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent-dim);
}
.wb-tool svg { width: 1em; height: 1em; display: block; }
.wb-tool-grow { flex: 1; }
.wb-sep {
  width: 1px;
  height: 1.4em;
  background: var(--rule);
  margin-inline: 0.25em;
}
.wb-colors {
  display: inline-flex;
  align-items: center;
  gap: 0.2em;
}
.wb-color {
  width: 1.45em;
  height: 1.45em;
  padding: 0;
  border-radius: 50%;
  border: 1.5px solid transparent;
  background: var(--c, currentColor);
  cursor: pointer;
  transition: transform 140ms ease, border-color 140ms ease, box-shadow 140ms ease;
}
.wb-color[data-wb-color="ink"] {
  background: var(--wb-ink);
}
.wb-color:hover { transform: scale(1.1); }
.wb-color.is-active {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--bg-elev), 0 0 10px var(--accent-glow);
}
.wb-width {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  color: var(--fg-muted);
  padding-inline: 0.25em;
}
.wb-width svg { width: 0.9em; height: 0.9em; }
.wb-width input[type="range"] {
  width: 80px;
  accent-color: var(--accent);
}

/* ---- Surface ---- */
.whiteboard-surface {
  position: relative;
  width: 100%;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--wb-paper)
    /* subtle dot grid in the page tint so the surface feels like paper */
    radial-gradient(var(--wb-grid) 1px, transparent 1px) 0 0 / 18px 18px;
  border: 1px solid var(--rule);
  touch-action: none;     /* essential: stops the browser from scrolling instead of drawing */
  cursor: crosshair;
}
.whiteboard-surface canvas {
  display: block;
  width: 100%;
  height: 100%;
}
.whiteboard-placeholder {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  text-align: center;
  padding: 1em;
  color: var(--fg-subtle);
  font-size: 0.85em;
  pointer-events: none;
  transition: opacity 200ms ease;
}
.whiteboard[data-wb-has-strokes="true"] .whiteboard-placeholder { opacity: 0; }

.whiteboard-footnote {
  margin: 0.55em 0.5em 0;
  font-size: 0.7em;
  color: var(--fg-subtle);
  text-align: right;
}
.whiteboard-footnote.is-saving { color: var(--accent); }

/* Eraser cursor — a small circle outline so the user sees what they're erasing. */
.whiteboard-surface[data-wb-mode="eraser"] {
  cursor: cell;
}

/* Print: the canvas renders fine in puppeteer's PDF as long as we've
   replayed the saved strokes before capture (whiteboard.js handles
   that on __AOA_PDF_MODE). Hide the toolbar + placeholder in print. */
@media print {
  .whiteboard-toolbar,
  .whiteboard-placeholder,
  .whiteboard-footnote {
    display: none !important;
  }
  .whiteboard {
    break-inside: avoid;
    page-break-inside: avoid;
  }
}

/* Each width slider shows the numeric value to its right (so the
   learner sees "12" or "2.5" without having to fiddle). Pen and
   eraser get independent inputs that swap based on active tool. */
.wb-width-val {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.6em;
  padding: 0 0.4em;
  font-size: 0.78em;
  font-variant-numeric: tabular-nums;
  color: var(--fg-muted);
  background: var(--bg-elev-hi);
  border-radius: 4px;
  margin-left: 0.25em;
}
.wb-width--eraser input[type="range"] { accent-color: var(--fg-muted); }
.wb-width--chalk  input[type="range"] { accent-color: var(--wb-ink); }

/* ----- Whiteboard: lock button + locked-state overlay -----
   When the user clicks the padlock the board enters "view only" mode:
   the surface stops capturing pointer events (so no accidental smudges
   on top of carefully drawn work), the cursor goes back to default, a
   small "Заблокировано" badge appears in the bottom-right corner, and
   the lock icon flips closed. Click again to unlock. */
.wb-tool--lock[aria-pressed="true"] {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent-dim);
}
.whiteboard[data-wb-locked="true"] .whiteboard-surface {
  pointer-events: none;
  cursor: default;
}
.whiteboard[data-wb-locked="true"] .whiteboard-surface::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,0.04) 0%, rgba(0,0,0,0.10) 100%);
  pointer-events: none;
}
.whiteboard-lock-badge {
  position: absolute;
  bottom: 0.6em;
  right: 0.6em;
  display: none;
  align-items: center;
  gap: 0.35em;
  padding: 0.35em 0.7em;
  background: rgba(0,0,0,0.6);
  color: #fff;
  border-radius: var(--r-pill);
  font-size: 0.72em;
  letter-spacing: 0.06em;
  pointer-events: none;
  backdrop-filter: blur(6px);
}
.whiteboard-lock-badge svg { width: 0.9em; height: 0.9em; }
.whiteboard[data-wb-locked="true"] .whiteboard-lock-badge { display: inline-flex; }

/* ----- Whiteboard: drag-to-resize handle below the surface -----
   A thin strip with a centered grip pill. Drag down to grow the
   board, drag up to shrink. Keyboard ↑ / ↓ also adjusts (±20px) for
   accessibility. Persisted per-board in localStorage so the chosen
   height survives reload. */
.whiteboard-resize {
  height: 0.85rem;
  cursor: row-resize;
  user-select: none;
  touch-action: none;
  display: grid;
  place-items: center;
  margin-top: -0.15rem;
}
.whiteboard-resize:focus-visible { outline: none; }
.wb-resize-grip {
  display: inline-block;
  width: 3.5em;
  height: 3px;
  border-radius: 2px;
  background: var(--rule-hi);
  transition: background 160ms ease, width 160ms ease, height 160ms ease, box-shadow 160ms ease;
}
.whiteboard-resize:hover .wb-resize-grip,
.whiteboard-resize:focus-visible .wb-resize-grip {
  background: var(--accent);
  width: 5em;
  height: 4px;
  box-shadow: 0 0 14px var(--accent-glow);
}
.whiteboard-resize.is-dragging .wb-resize-grip {
  background: var(--accent);
  width: 6em;
  height: 4px;
  box-shadow: 0 0 16px var(--accent-glow);
}
/* While dragging force row-resize cursor everywhere so it doesn't
   flicker as the pointer crosses out of the 0.85rem strip. */
body.is-resizing-whiteboard, body.is-resizing-whiteboard * {
  cursor: row-resize !important;
  user-select: none !important;
}

/* =========================================================================
 * :::board — Miro/FigJam-style Excalidraw embed skeleton.
 *
 * Same CSS as the converter copy in aoa-academy/public/css/components.css
 * — keep these two blocks in sync when you edit either side.
 * ========================================================================= */
.aoa-board-figure {
  margin: 1.8em 0;
  display: block;
  width: 100%;
  isolation: isolate;
}
.aoa-board-caption {
  font-size: .92em;
  color: var(--text-soft, rgba(244, 236, 224, 0.62));
  margin: 0 0 .55em;
  font-style: italic;
}
.aoa-board-skeleton {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  border: 1px solid rgba(244, 236, 224, 0.08);
  border-radius: 14px;
  background:
    radial-gradient(circle at 24% 18%, rgba(212, 164, 55, 0.10), transparent 55%),
    radial-gradient(circle at 78% 82%, rgba(212, 164, 55, 0.06), transparent 55%),
    #0e0a06;
  overflow: hidden;
}
.aoa-board-skeleton::before {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(90deg, transparent 0, transparent 49.6%, rgba(244, 236, 224, 0.025) 50%, transparent 50.4%) 0 0 / 64px 100%,
    linear-gradient(0deg,  transparent 0, transparent 49.6%, rgba(244, 236, 224, 0.025) 50%, transparent 50.4%) 0 0 / 100% 64px;
  pointer-events: none;
  mask-image: radial-gradient(ellipse at center, black 35%, transparent 75%);
}
.aoa-board-skeleton-inner {
  text-align: center;
  padding: 28px 24px;
  max-width: 420px;
}
.aoa-board-skeleton-glyph {
  display: block;
  font-family: 'Amiri', serif;
  font-size: 56px;
  line-height: 1;
  color: #d4a437;
  opacity: .8;
  margin-bottom: 12px;
}
.aoa-board-skeleton-title {
  margin: 0 0 6px;
  font-weight: 600;
  color: #f4ece0;
  font-size: 16px;
}
.aoa-board-skeleton-sub {
  margin: 0 0 14px;
  font-size: 12.5px;
  color: rgba(244, 236, 224, 0.55);
}
.aoa-board-skeleton-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 999px;
  background: rgba(212, 164, 55, 0.12);
  color: #d4a437;
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  border: 1px solid rgba(212, 164, 55, 0.32);
  transition: background-color .15s ease, border-color .15s ease;
}
.aoa-board-skeleton-link:hover {
  background: rgba(212, 164, 55, 0.22);
  border-color: rgba(212, 164, 55, 0.55);
}
.aoa-board-figure[data-aoa-board-mounted="true"] .aoa-board-skeleton { display: none; }

.aoa-board-noscript {
  margin-top: 10px;
  padding: 10px 14px;
  border-radius: 10px;
  background: rgba(244, 236, 224, 0.04);
  font-size: 12.5px;
  color: rgba(244, 236, 224, 0.7);
}
.aoa-board-noscript a {
  color: #d4a437;
  text-decoration: underline;
}

.aoa-board-mount {
  position: relative;
  width: 100%;
  border-radius: 14px;
  overflow: hidden;
  border: 1px solid rgba(244, 236, 224, 0.08);
}
