/* ==========================================================================
   VIVACE LEARN — design tokens + components for the /learn/ lesson pages
   ==========================================================================
   Identity: "Vivace Flow" — palette sampled from the official logo
   (public/img/logo_512_512.png — white treble clef on paper-cut multicolor
   waves). Canonical values + concept roles: SERIES-BIBLE.md §1.5 and
   video-pipeline/src/theme.ts (flow / conceptColors).

   Default theme: warm light (soft tinted cream, warm ink) — lesson pages are
   long-form reading. Dark variant via prefers-color-scheme, overridable by
   the site toggle ([data-theme="dark"|"light"] wins in both directions).

   RTL-READY: logical properties and values only (inline-start/end, block,
   text-align: start). No hard-coded left/right anywhere. Arabic pages set
   dir="rtl" on <html> and everything mirrors for free.

   Scope: everything lives under .learn-page to avoid collisions with
   main.css. Concept accents: set data-concept="pitch|duration|intensity|
   timbre|harmony|melody|tonality|form|listening|notation" on .learn-page
   (or any subtree) to retint the accentable components.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Reset — /learn/ does not load main.css, so it must carry the same base
   reset the rest of the site gets from main.css (`* { margin:0; padding:0;
   box-sizing:border-box }`). Without it the UA's `body { margin: 8px }` framed
   every page with a light band and content-box widths broke the reading column.
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; }
body.learn-page { margin: 0; }

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Vivace Flow palette (logo-exact screen tokens) */
  --lv-flow-orange: #ff8a00;
  --lv-flow-vermilion: #ff4c1d;
  --lv-flow-crimson: #e8102e;
  --lv-flow-magenta: #c21572;
  --lv-flow-rose: #ff6ec7;
  --lv-flow-violet: #8b5cf6;
  --lv-flow-blue: #1b84c4;
  --lv-flow-teal: #0e8c9c;

  /* Deepened variants — text-safe on the light theme (AA on cream) */
  --lv-deep-orange: #a85a00;
  --lv-deep-vermilion: #c23408;
  --lv-deep-crimson: #b30c24;
  --lv-deep-magenta: #9c115c;
  --lv-deep-rose: #c4308f;
  --lv-deep-violet: #6d43d8;
  --lv-deep-blue: #14648f;
  --lv-deep-teal: #0a6b78;

  /* Signature gradients */
  --lv-gradient-flow: linear-gradient(
    135deg,
    #ff8a00 0%,
    #ff4c1d 20%,
    #e8102e 40%,
    #c21572 58%,
    #8b5cf6 78%,
    #0e8c9c 100%
  );
  --lv-gradient-warm: linear-gradient(135deg, #ff8a00 0%, #e8102e 55%, #ff6ec7 100%);
  --lv-gradient-cool: linear-gradient(135deg, #0e8c9c 0%, #1b84c4 50%, #8b5cf6 100%);
  --lv-gradient-pitch: linear-gradient(135deg, #0e8c9c 0%, #ff6ec7 100%);

  /* Light theme (default) — warm tinted cream, warm ink */
  --lv-bg: #fbf6ef;
  --lv-surface: #fffdf9;
  --lv-surface-2: #f5ede1;
  --lv-ink: #241c16;
  --lv-ink-soft: #4d423a;
  --lv-muted: #7a6e64;
  --lv-border: rgba(36, 28, 22, 0.12);
  --lv-shadow: 0 2px 12px rgba(120, 80, 40, 0.08);
  --lv-code-bg: rgba(36, 28, 22, 0.05);

  /* Default accent (violet = key terms / notation, as in the capsules) */
  --lv-accent: var(--lv-flow-violet);
  --lv-accent-ink: var(--lv-deep-violet);
  --lv-accent-soft: rgba(139, 92, 246, 0.1);

  /* Fixed component accents */
  --lv-mistake: var(--lv-flow-vermilion);
  --lv-mistake-ink: var(--lv-deep-vermilion);
  --lv-mistake-soft: rgba(255, 76, 29, 0.09);
  --lv-tip: var(--lv-flow-teal);
  --lv-tip-ink: var(--lv-deep-teal);
  --lv-tip-soft: rgba(14, 140, 156, 0.09);
  --lv-def-soft: rgba(139, 92, 246, 0.08);

  /* Type + rhythm — Poppins is the site-wide face (main.css); the local stack
     is the fallback when the webfont is unavailable. */
  --lv-font: 'Poppins', system-ui, -apple-system, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  --lv-radius-sm: 10px;
  --lv-radius: 20px;
  --lv-radius-lg: 20px;
  --lv-space-1: 0.5rem;
  --lv-space-2: 1rem;
  --lv-space-3: 1.5rem;
  --lv-space-4: 2.5rem;
  --lv-measure: 46rem; /* comfortable reading column */
}

/* Dark theme — OS preference (unless the site toggle forces light) */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --lv-bg: #14100d;
    --lv-surface: #1d1814;
    --lv-surface-2: #26201a;
    --lv-ink: #f3ece3;
    --lv-ink-soft: #cfc4b8;
    --lv-muted: #9a8d80;
    --lv-border: rgba(243, 236, 227, 0.14);
    --lv-shadow: 0 2px 14px rgba(0, 0, 0, 0.45);
    --lv-code-bg: rgba(243, 236, 227, 0.07);
    --lv-accent-ink: #a88df8;
    --lv-accent-soft: rgba(139, 92, 246, 0.16);
    --lv-mistake-ink: #ff7752;
    --lv-mistake-soft: rgba(255, 76, 29, 0.13);
    --lv-tip-ink: #3fb7c6;
    --lv-tip-soft: rgba(14, 140, 156, 0.14);
    --lv-def-soft: rgba(139, 92, 246, 0.12);
  }
}

/* Site toggle wins over the OS preference, both directions */
:root[data-theme='dark'] {
  --lv-bg: #14100d;
  --lv-surface: #1d1814;
  --lv-surface-2: #26201a;
  --lv-ink: #f3ece3;
  --lv-ink-soft: #cfc4b8;
  --lv-muted: #9a8d80;
  --lv-border: rgba(243, 236, 227, 0.14);
  --lv-shadow: 0 2px 14px rgba(0, 0, 0, 0.45);
  --lv-code-bg: rgba(243, 236, 227, 0.07);
  --lv-accent-ink: #a88df8;
  --lv-accent-soft: rgba(139, 92, 246, 0.16);
  --lv-mistake-ink: #ff7752;
  --lv-mistake-soft: rgba(255, 76, 29, 0.13);
  --lv-tip-ink: #3fb7c6;
  --lv-tip-soft: rgba(14, 140, 156, 0.14);
  --lv-def-soft: rgba(139, 92, 246, 0.12);
}

/* Concept accents (bible §1.5 roles) — retint accentable components */
[data-concept='pitch'] { --lv-accent: var(--lv-flow-teal); --lv-accent-ink: var(--lv-deep-teal); --lv-accent-soft: rgba(14, 140, 156, 0.1); }
[data-concept='duration'],
[data-concept='rhythm'] { --lv-accent: var(--lv-flow-orange); --lv-accent-ink: var(--lv-deep-orange); --lv-accent-soft: rgba(255, 138, 0, 0.1); }
[data-concept='intensity'] { --lv-accent: var(--lv-flow-vermilion); --lv-accent-ink: var(--lv-deep-vermilion); --lv-accent-soft: rgba(255, 76, 29, 0.1); }
[data-concept='timbre'] { --lv-accent: var(--lv-flow-magenta); --lv-accent-ink: var(--lv-deep-magenta); --lv-accent-soft: rgba(194, 21, 114, 0.1); }
[data-concept='harmony'],
[data-concept='notation'] { --lv-accent: var(--lv-flow-violet); --lv-accent-ink: var(--lv-deep-violet); --lv-accent-soft: rgba(139, 92, 246, 0.1); }
[data-concept='melody'] { --lv-accent: var(--lv-flow-rose); --lv-accent-ink: var(--lv-deep-rose); --lv-accent-soft: rgba(255, 110, 199, 0.12); }
[data-concept='tonality'] { --lv-accent: var(--lv-flow-blue); --lv-accent-ink: var(--lv-deep-blue); --lv-accent-soft: rgba(27, 132, 196, 0.1); }
[data-concept='form'] { --lv-accent: var(--lv-flow-crimson); --lv-accent-ink: var(--lv-deep-crimson); --lv-accent-soft: rgba(232, 16, 46, 0.09); }
[data-concept='listening'] { --lv-accent: var(--lv-flow-teal); --lv-accent-ink: var(--lv-deep-teal); --lv-accent-soft: rgba(14, 140, 156, 0.1); }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) [data-concept='pitch'],
  :root:not([data-theme='light']) [data-concept='listening'] { --lv-accent-ink: #3fb7c6; }
  :root:not([data-theme='light']) [data-concept='duration'],
  :root:not([data-theme='light']) [data-concept='rhythm'] { --lv-accent-ink: #ffa640; }
  :root:not([data-theme='light']) [data-concept='intensity'] { --lv-accent-ink: #ff7752; }
  :root:not([data-theme='light']) [data-concept='timbre'] { --lv-accent-ink: #e5589f; }
  :root:not([data-theme='light']) [data-concept='harmony'],
  :root:not([data-theme='light']) [data-concept='notation'] { --lv-accent-ink: #a88df8; }
  :root:not([data-theme='light']) [data-concept='melody'] { --lv-accent-ink: #ff8ed3; }
  :root:not([data-theme='light']) [data-concept='tonality'] { --lv-accent-ink: #4da3dd; }
  :root:not([data-theme='light']) [data-concept='form'] { --lv-accent-ink: #f4536b; }
}
:root[data-theme='dark'] [data-concept='pitch'],
:root[data-theme='dark'] [data-concept='listening'] { --lv-accent-ink: #3fb7c6; }
:root[data-theme='dark'] [data-concept='duration'],
:root[data-theme='dark'] [data-concept='rhythm'] { --lv-accent-ink: #ffa640; }
:root[data-theme='dark'] [data-concept='intensity'] { --lv-accent-ink: #ff7752; }
:root[data-theme='dark'] [data-concept='timbre'] { --lv-accent-ink: #e5589f; }
:root[data-theme='dark'] [data-concept='harmony'],
:root[data-theme='dark'] [data-concept='notation'] { --lv-accent-ink: #a88df8; }
:root[data-theme='dark'] [data-concept='melody'] { --lv-accent-ink: #ff8ed3; }
:root[data-theme='dark'] [data-concept='tonality'] { --lv-accent-ink: #4da3dd; }
:root[data-theme='dark'] [data-concept='form'] { --lv-accent-ink: #f4536b; }

/* --------------------------------------------------------------------------
   2. Page frame + typography
   -------------------------------------------------------------------------- */
.learn-page {
  background: var(--lv-bg);
  color: var(--lv-ink);
  font-family: var(--lv-font);
  font-size: 1.0625rem;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}

.learn-container {
  max-width: var(--lv-measure);
  margin-inline: auto;
  padding-inline: var(--lv-space-3);
  padding-block: var(--lv-space-2) var(--lv-space-4);
}

.learn-page h1,
.learn-page h2,
.learn-page h3 {
  color: var(--lv-ink);
  line-height: 1.25;
  text-wrap: balance;
}
.learn-page h1 { font-size: clamp(1.9rem, 4.5vw, 2.6rem); font-weight: 700; }
.learn-page h2 { font-size: 1.45rem; font-weight: 700; margin-block: var(--lv-space-4) var(--lv-space-2); }
.learn-page h3 { font-size: 1.15rem; font-weight: 700; margin-block: var(--lv-space-3) var(--lv-space-1); }

/* H2 signature: short flow-gradient stroke under section titles */
.learn-page h2::after {
  content: '';
  display: block;
  inline-size: 3.5rem;
  block-size: 4px;
  border-radius: 2px;
  margin-block-start: 0.45rem;
  background: var(--lv-gradient-flow);
  opacity: 0.85;
}

/* `:where()` keeps this base rhythm at (0,1,0) specificity. As `.learn-page p`
   (0,1,1) it beat every single-class component rule built on a <p>
   (.learn-hub-ear, .learn-allrow, .learn-hero__lede, .learn-caption,
   .learn-video-section__meta, .learn-hub-card__desc), silently replacing their
   margins with `0 0 1rem` — CTAs glued to the cards above them, ledes glued to
   the H1. Neutralised here, source order lets the components (all declared
   further down) win. */
.learn-page :where(p) { margin-block: 0 var(--lv-space-2); }
/* Underlined accent links belong to the PROSE only. Scoping this to
   .learn-page used to underline the wordmark, the nav cards, the hub cards
   and the footer, because component rules lose to the higher specificity. */
.learn-article a,
.learn-def a,
.learn-summary a,
.learn-faq a,
.learn-mistake a,
.learn-tip a,
.learn-allrow a {
  color: var(--lv-accent-ink);
  text-decoration: underline;
  text-decoration-color: color-mix(in srgb, var(--lv-accent) 45%, transparent);
  text-underline-offset: 3px;
}
.learn-article a:hover,
.learn-def a:hover,
.learn-summary a:hover,
.learn-faq a:hover,
.learn-mistake a:hover,
.learn-tip a:hover,
.learn-allrow a:hover { text-decoration-color: var(--lv-accent); }
/* Belt and braces for every chrome anchor. */
.learn-page .learn-header__brand,
.learn-page .learn-header__link,
.learn-page .learn-nav__card,
.learn-page .learn-hub-card,
.learn-page .learn-hub-card__title a,
.learn-page .learn-langs__item,
.learn-page footer a,
.learn-page .learn-hub-ear a,
.learn-page .learn-exercise-btn { text-decoration: none; }

.learn-allrow { text-align: center; margin-block: var(--lv-space-3) 0; font-weight: 600; }
/* Reader-facing caption line that follows a figure. */
.learn-caption {
  color: var(--lv-muted);
  font-size: 0.92rem;
  margin-block: calc(var(--lv-space-1) * -0.5) var(--lv-space-2);
}
.learn-page strong { color: var(--lv-ink); }
.learn-page code {
  background: var(--lv-code-bg);
  border-radius: 6px;
  padding: 0.1em 0.4em;
  font-size: 0.92em;
}
.learn-page ul,
.learn-page ol { padding-inline-start: 1.4rem; margin-block: 0 var(--lv-space-2); }

/* --------------------------------------------------------------------------
   3. Lesson hero
   -------------------------------------------------------------------------- */
.learn-hero {
  position: relative;
  overflow: hidden;
  background: var(--lv-surface);
  border-block-end: 1px solid var(--lv-border);
  padding-block: var(--lv-space-4) calc(var(--lv-space-4) + 2.2rem);
}
.learn-hero__inner {
  max-width: var(--lv-measure);
  margin-inline: auto;
  padding-inline: var(--lv-space-3);
  position: relative;
  z-index: 1;
}
.learn-hero__eyebrow {
  display: inline-flex;
  /* The eyebrow wraps to two lines on narrow screens ("MODULE 1 · READING
     MUSIC · LESSON 1 OF 7"). `center` floated the dot in the gutter between
     the lines; it must mark the FIRST line. */
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--lv-accent-ink);
  margin-block-end: var(--lv-space-1);
}
.learn-hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-block-start: var(--lv-space-2);
  font-size: 0.9rem;
  color: var(--lv-muted);
}
.learn-hero__chip {
  border: 1px solid var(--lv-border);
  border-radius: 999px;
  padding: 0.15rem 0.75rem;
  background: var(--lv-accent-soft);
  color: var(--lv-accent-ink);
  font-weight: 600;
}
/* Flow waves along the hero's bottom edge (CSS twin of WaveMotif) */
.learn-hero::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  block-size: 3.2rem;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 60' preserveAspectRatio='none'%3E%3Cpath d='M0 38 C150 18 300 58 450 38 C600 18 750 58 900 38 C1050 18 1150 48 1200 34 L1200 60 L0 60 Z' fill='%23FF8A00' opacity='.32'/%3E%3Cpath d='M0 46 C200 26 400 62 600 44 C800 26 1000 60 1200 42 L1200 60 L0 60 Z' fill='%23C21572' opacity='.34'/%3E%3Cpath d='M0 52 C180 38 380 64 620 50 C860 38 1040 62 1200 50 L1200 60 L0 60 Z' fill='%230E8C9C' opacity='.5'/%3E%3C/svg%3E");
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

/* --------------------------------------------------------------------------
   4. Wave separator (between major sections)
   -------------------------------------------------------------------------- */
.learn-wave-sep {
  block-size: 2.4rem;
  margin-block: var(--lv-space-4);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 40' preserveAspectRatio='none'%3E%3Cpath d='M0 22 C150 8 300 34 450 22 C600 8 750 34 900 22 C1050 8 1150 30 1200 20' fill='none' stroke='%23FF8A00' stroke-width='3' opacity='.55' stroke-linecap='round'/%3E%3Cpath d='M0 30 C200 16 400 38 600 28 C800 16 1000 36 1200 26' fill='none' stroke='%23C21572' stroke-width='3' opacity='.5' stroke-linecap='round'/%3E%3Cpath d='M0 36 C180 26 380 40 620 34 C860 26 1040 40 1200 32' fill='none' stroke='%230E8C9C' stroke-width='3' opacity='.6' stroke-linecap='round'/%3E%3C/svg%3E");
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

/* --------------------------------------------------------------------------
   5. Boxed definition (§5.2.2 — the snippet-bait)
   -------------------------------------------------------------------------- */
.learn-def {
  background: var(--lv-def-soft);
  border-inline-start: 4px solid var(--lv-flow-violet);
  border-radius: var(--lv-radius-sm);
  padding: var(--lv-space-2) var(--lv-space-3);
  margin-block: var(--lv-space-3);
  font-size: 1.1rem;
}
.learn-def strong:first-child { color: var(--lv-accent-ink); }

/* --------------------------------------------------------------------------
   6. Figure / illustration
   -------------------------------------------------------------------------- */
.learn-figure {
  margin-block: var(--lv-space-3);
  margin-inline: 0;
}
.learn-figure img {
  display: block;
  max-inline-size: 100%;
  block-size: auto;
  border-radius: var(--lv-radius);
  box-shadow: var(--lv-shadow);
  border: 1px solid var(--lv-border);
}
.learn-figure figcaption {
  margin-block-start: 0.6rem;
  font-size: 0.9rem;
  color: var(--lv-muted);
  text-align: start;
}

/* --------------------------------------------------------------------------
   7. Callouts: common mistake (soft vermilion) + tip (teal)
   -------------------------------------------------------------------------- */
.learn-mistake,
.learn-tip {
  border-radius: var(--lv-radius);
  padding: var(--lv-space-2) var(--lv-space-3);
  margin-block: var(--lv-space-3);
  border: 1px solid transparent;
}
.learn-mistake {
  background: var(--lv-mistake-soft);
  border-color: color-mix(in srgb, var(--lv-mistake) 30%, transparent);
}
.learn-tip {
  background: var(--lv-tip-soft);
  border-color: color-mix(in srgb, var(--lv-tip) 30%, transparent);
}
.learn-mistake__title,
.learn-tip__title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 700;
  margin-block-end: 0.4rem;
}
/* `.learn-page h2` (0-1-1) beats `.learn-mistake__title` (0-1-0): the callout
   titles were rendering in plain ink and the gradient rule of `h2::after`
   became a flex item sitting to the RIGHT of the title. */
.learn-page .learn-mistake__title { color: var(--lv-mistake-ink); }
.learn-page .learn-tip__title { color: var(--lv-tip-ink); }
.learn-page .learn-mistake__title::after,
.learn-page .learn-tip__title::after { display: none; }
.learn-mistake > :last-child,
.learn-tip > :last-child { margin-block-end: 0; }

/* --------------------------------------------------------------------------
   8. FAQ
   -------------------------------------------------------------------------- */
/* The builder emits a plain <section class="learn-faq"> with an <h2> and <p>s,
   not a <details>/<summary>: without this padding the text was glued to the
   box edges on all 28 lesson pages. */
.learn-faq {
  border: 1px solid var(--lv-border);
  border-radius: var(--lv-radius);
  background: var(--lv-surface);
  margin-block: var(--lv-space-2);
  padding: var(--lv-space-2) var(--lv-space-3);
  overflow: hidden;
}
.learn-faq > :last-child { margin-block-end: 0; }
.learn-page .learn-faq__title { margin-block-start: 0; }
.learn-faq summary {
  cursor: pointer;
  list-style: none;
  padding: var(--lv-space-2) var(--lv-space-3);
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--lv-space-2);
}
.learn-faq summary::-webkit-details-marker { display: none; }
.learn-faq summary::after {
  content: '+';
  font-size: 1.3rem;
  line-height: 1;
  color: var(--lv-accent-ink);
  transition: transform 0.2s ease;
}
.learn-faq[open] summary::after { transform: rotate(45deg); }
.learn-faq__body { padding: 0 var(--lv-space-3) var(--lv-space-2); }
.learn-faq__body > :last-child { margin-block-end: 0; }

/* --------------------------------------------------------------------------
   9. Summary (recap) — echoes the capsule RecapList
   -------------------------------------------------------------------------- */
.learn-summary {
  background: var(--lv-surface);
  border: 1px solid var(--lv-border);
  border-radius: var(--lv-radius-lg);
  padding: var(--lv-space-3);
  margin-block: var(--lv-space-3);
  box-shadow: var(--lv-shadow);
}
.learn-summary ul { list-style: none; padding-inline-start: 0; margin: 0; }
.learn-summary li {
  position: relative;
  padding-inline-start: 1.9rem;
  margin-block: 0.55rem;
}
.learn-summary li::before {
  content: '✓';
  position: absolute;
  inset-inline-start: 0;
  inline-size: 1.35rem;
  block-size: 1.35rem;
  display: grid;
  place-items: center;
  border-radius: 50%;
  font-size: 0.8rem;
  font-weight: 800;
  color: #fff;
  background: var(--lv-gradient-cool);
}

/* --------------------------------------------------------------------------
   10. Exercise button
   -------------------------------------------------------------------------- */
.learn-exercise-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.8rem 1.6rem;
  border-radius: 999px;
  background: var(--lv-gradient-flow);
  color: #fff;
  font-weight: 700;
  font-size: 1rem;
  text-decoration: none;
  /* Same shadow weight as the site's primary button (.view-all / .cta-btn). */
  box-shadow: 0 6px 20px rgba(255, 110, 199, 0.3);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.learn-exercise-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 35px rgba(255, 110, 199, 0.5);
  text-decoration: none;
  color: #fff;
}
.learn-exercise-btn:focus-visible {
  outline: 3px solid color-mix(in srgb, var(--lv-flow-violet) 60%, transparent);
  outline-offset: 3px;
}

/* --------------------------------------------------------------------------
   11. Prev / next navigation
   -------------------------------------------------------------------------- */
.learn-nav {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--lv-space-2);
  margin-block: var(--lv-space-4) var(--lv-space-2);
}
.learn-nav__card {
  display: block;
  border: 1px solid var(--lv-border);
  border-radius: var(--lv-radius);
  background: var(--lv-surface);
  padding: var(--lv-space-2) var(--lv-space-3);
  text-decoration: none;
  color: var(--lv-ink);
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.learn-nav__card:hover {
  border-color: var(--lv-accent);
  transform: translateY(-2px);
  text-decoration: none;
}
.learn-nav__card--next { text-align: end; }
.learn-nav__label {
  display: block;
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--lv-muted);
  margin-block-end: 0.3rem;
}
.learn-nav__title { font-weight: 700; color: var(--lv-accent-ink); }
@media (max-width: 560px) {
  .learn-nav { grid-template-columns: 1fr; }
  .learn-nav__card--next { text-align: start; }
  /* Single column: the zero-height placeholder still claimed a row, adding a
     stray 16px gap above the NEXT card on the first and last lessons. */
  .learn-nav__spacer { display: none; }
}

/* --------------------------------------------------------------------------
   12. Site chrome — compact header, language pills, hero lede
   -------------------------------------------------------------------------- */
.learn-header {
  background: var(--lv-surface);
  border-block-end: 1px solid var(--lv-border);
  /* Anchors the sliding #mobileNav panel (position: absolute, top: 100%). */
  position: relative;
  z-index: 50;
}
.learn-header__inner {
  max-width: 75rem;
  margin-inline: auto;
  padding-inline: var(--lv-space-3);
  padding-block: 0.65rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--lv-space-2);
  /* Opaque and above the panel so the menu slides out from *behind* the bar. */
  position: relative;
  z-index: 2;
  background: var(--lv-surface);
}
/* Lesson pages read at --lv-measure (46rem); a 75rem header left the wordmark
   and the nav pills ~230px outside the reading column at 1440/1920. Hubs keep
   the full 75rem because their card grid is that wide. */
.learn-page--lesson .learn-header__inner { max-width: 56rem; }
.learn-header__brand {
  display: inline-flex;
  align-items: center;
  gap: 0.65rem;
  text-decoration: none;
  /* The brand never shrinks away or wraps — it is the only "home" affordance
     visible while the menu is closed. */
  flex: 0 0 auto;
  min-inline-size: 0;
}
.learn-header__brand img { flex: none; }
.learn-header__brand img { border-radius: 10px; display: block; }
.learn-header__wordmark {
  font-weight: 800;
  font-size: 1.15rem;
  letter-spacing: -0.01em;
  color: var(--lv-ink);
  white-space: nowrap;
}
.learn-header__wordmark em {
  font-style: normal;
  font-weight: 700;
  background: var(--lv-gradient-warm);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}
/* Pushed to the far end so the bar keeps its original brand | … | actions
   rhythm now that the theme button lives outside the nav. */
.learn-header__nav { display: inline-flex; align-items: center; gap: 0.5rem; justify-content: flex-end; min-inline-size: 0; margin-inline-start: auto; }
/* Links to the rest of the site: /learn/ must not be a dead end. */
.learn-header__link--site { border-color: transparent; padding-inline: 0.55rem; color: var(--lv-muted); }
.learn-header__link--site:hover { border-color: var(--lv-border); }
/* Header links never wrap inside their pill — a two-line "All lessons" pill was
   the whole mobile-header bug. Below the breakpoint the nav is replaced by the
   hamburger menu instead of being squeezed. */
.learn-header__link { white-space: nowrap; }
.learn-header__link {
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--lv-ink-soft);
  text-decoration: none;
  border-radius: 999px;
  padding: 0.35rem 0.9rem;
  border: 1px solid var(--lv-border);
  transition: border-color 0.15s ease, color 0.15s ease;
}
.learn-header__link:hover { border-color: var(--lv-accent); color: var(--lv-accent-ink); text-decoration: none; }
.learn-theme-btn {
  inline-size: 2.1rem;
  block-size: 2.1rem;
  border-radius: 50%;
  border: 1px solid var(--lv-border);
  background: var(--lv-surface-2);
  cursor: pointer;
  display: grid;
  place-items: center;
  padding: 0;
}
.learn-theme-btn:hover { border-color: var(--lv-accent); }
/* Explicit moon/sun affordance (a bare gradient dot read as decoration). */
.learn-theme-btn__icon {
  inline-size: 1.05rem;
  block-size: 1.05rem;
  background: var(--lv-ink-soft);
  -webkit-mask: var(--lv-icon-moon) center / contain no-repeat;
  mask: var(--lv-icon-moon) center / contain no-repeat;
}
:root[data-theme='dark'] .learn-theme-btn__icon {
  -webkit-mask-image: var(--lv-icon-sun);
  mask-image: var(--lv-icon-sun);
}

/* --------------------------------------------------------------------------
   12b. Mobile navigation — the same mechanism as the rest of the site
   (#hamburger + #mobileNav, .hamburger.active / .mobile-nav.show), restyled
   with the /learn/ tokens. Below --lv-nav-bp the inline nav is replaced by the
   burger menu so nothing wraps or disappears; the brand and the theme button
   stay in the bar at every width.
   -------------------------------------------------------------------------- */
.learn-header__actions {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  flex: none;
}
.learn-header .hamburger {
  display: none; /* desktop: the full nav is visible, no burger */
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  inline-size: 44px;   /* WCAG 2.5.8 touch target */
  block-size: 44px;
  padding: 0;
  margin: 0;
  border: 0;
  border-radius: 12px;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.learn-header .hamburger span {
  display: block;
  inline-size: 24px;
  block-size: 2.5px;
  background: var(--lv-ink-soft);
  border-radius: 2px;
  transform-origin: center;
  transition: transform 0.3s ease, opacity 0.2s ease;
}
.learn-header .hamburger.active span:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
.learn-header .hamburger.active span:nth-child(2) { opacity: 0; }
.learn-header .hamburger.active span:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }
.learn-header .hamburger:hover span { background: var(--lv-accent-ink); }
.learn-header .hamburger:focus-visible { outline: 2px solid var(--lv-accent); outline-offset: 2px; }

.learn-header .mobile-nav {
  position: absolute;
  inset-inline: 0;           /* mirrors for free in RTL */
  inset-block-start: 100%;
  z-index: 1;                /* slides out from behind .learn-header__inner */
  background: var(--lv-surface);
  border-block-end: 1px solid var(--lv-border);
  box-shadow: 0 12px 28px rgba(36, 28, 22, 0.14);
  padding: 0.5rem var(--lv-space-3) 0.85rem;
  transform: translateY(-120%);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1),
              opacity 0.22s ease,
              visibility 0s 0.28s;
}
/* The warm light-theme shadow disappears on the dark surface; the open panel
   must still read as a layer above the article. */
:root[data-theme='dark'] .learn-header .mobile-nav { box-shadow: 0 14px 30px rgba(0, 0, 0, 0.6); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .learn-header .mobile-nav { box-shadow: 0 14px 30px rgba(0, 0, 0, 0.6); }
}
.learn-header .mobile-nav.show {
  transform: translateY(0);
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1),
              opacity 0.22s ease,
              visibility 0s;
}
.learn-header .mobile-nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.learn-page .learn-header .mobile-nav a {
  display: flex;
  align-items: center;
  min-block-size: 44px;
  padding: 0.55rem 0.85rem;
  border-radius: var(--lv-radius-sm);
  color: var(--lv-ink-soft);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.35;
  text-decoration: none;
  transition: background-color 0.18s ease, color 0.18s ease;
}
.learn-page .learn-header .mobile-nav a:hover,
.learn-page .learn-header .mobile-nav a:focus-visible {
  background: var(--lv-accent-soft);
  color: var(--lv-accent-ink);
}
.learn-page .learn-header .mobile-nav a[aria-current='page'] {
  background: var(--lv-accent-soft);
  color: var(--lv-accent-ink);
}
@media (max-width: 992px) {
  .learn-header__nav { display: none; }
  .learn-header .hamburger { display: flex; }
  /* Same touch target as the hamburger it sits next to (WCAG 2.5.8): a 33.6px
     disc beside a 44px burger read as broken, not as a smaller control. */
  .learn-theme-btn { inline-size: 44px; block-size: 44px; }
}
/* Above the breakpoint the panel must not exist at all: no stray tab stops. */
@media (min-width: 993px) {
  .learn-header .mobile-nav { display: none; }
}

:root {
  --lv-icon-moon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z'/%3E%3C/svg%3E");
  --lv-icon-sun: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cg fill='%23000'%3E%3Ccircle cx='12' cy='12' r='4.6'/%3E%3Crect x='11' y='0.6' width='2' height='4' rx='1'/%3E%3Crect x='11' y='19.4' width='2' height='4' rx='1'/%3E%3Crect x='0.6' y='11' width='4' height='2' rx='1'/%3E%3Crect x='19.4' y='11' width='4' height='2' rx='1'/%3E%3Crect x='3' y='4.4' width='2' height='4' rx='1' transform='rotate(-45 4 6.4)'/%3E%3Crect x='19' y='15.6' width='2' height='4' rx='1' transform='rotate(-45 20 17.6)'/%3E%3Crect x='19' y='4.4' width='2' height='4' rx='1' transform='rotate(45 20 6.4)'/%3E%3Crect x='3' y='15.6' width='2' height='4' rx='1' transform='rotate(45 4 17.6)'/%3E%3C/g%3E%3C/svg%3E");
}

.learn-hero__lede {
  color: var(--lv-ink-soft);
  font-size: 1.1rem;
  max-inline-size: 40rem;
  margin-block: 0.6rem 0;
  text-wrap: pretty;
}
.learn-hero__dot {
  /* Without `flex: none` the dot is squeezed by the inline-flex parent at
     320-360px and renders as an ellipse (7.2 x 8.8) under border-radius: 50%. */
  flex: none;
  inline-size: 0.55rem;
  block-size: 0.55rem;
  border-radius: 50%;
  background: var(--lv-accent);
  box-shadow: 0 0 0 4px var(--lv-accent-soft);
  /* Optically centres the dot on the first line now that the parent aligns to
     flex-start (line-height 1.7 of a 0.85rem eyebrow ≈ 23px). */
  margin-block-start: 0.45em;
}
.learn-langs {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  /* No `margin-inline-start: auto`: it shoved the pills to the far edge of
     .learn-hero__meta, detaching them from the level chip (lessons) or from
     the title block entirely (hubs). The parent's `gap` does the spacing. */
  align-items: center;
}
.learn-langs__item {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--lv-ink-soft);
  text-decoration: none;
  border: 1px solid var(--lv-border);
  border-radius: 999px;
  padding: 0.14rem 0.7rem;
  background: var(--lv-surface);
  transition: border-color 0.15s ease, color 0.15s ease;
}
.learn-langs__item:hover { border-color: var(--lv-accent); color: var(--lv-accent-ink); text-decoration: none; }
/* White on raw --lv-accent measured 4.00:1 (teal) / 4.23:1 (violet) — the most
   important pill of the group was the least legible. The deep variant is
   AA-clean in light, and in dark it is the LIGHT tint, so the label flips to
   the page background. */
.learn-langs__item--current {
  background: var(--lv-accent-ink);
  border-color: var(--lv-accent-ink);
  color: #fff;
}
:root[data-theme='dark'] .learn-langs__item--current { color: var(--lv-bg); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .learn-langs__item--current { color: var(--lv-bg); }
}

/* --------------------------------------------------------------------------
   13. Placeholders — illustration figure + video capsule
   -------------------------------------------------------------------------- */
.learn-figure--placeholder .learn-figure__ph {
  position: relative;
  overflow: hidden;
  min-block-size: 10.5rem;
  border-radius: var(--lv-radius);
  border: 1px solid var(--lv-border);
  background: var(--lv-surface);
  box-shadow: var(--lv-shadow);
  display: grid;
  place-items: center;
  padding: var(--lv-space-3);
}
.learn-figure--placeholder .learn-figure__ph::before {
  content: '';
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  block-size: 46%;
  opacity: 0.75;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 60' preserveAspectRatio='none'%3E%3Cpath d='M0 38 C150 18 300 58 450 38 C600 18 750 58 900 38 C1050 18 1150 48 1200 34 L1200 60 L0 60 Z' fill='%23FF8A00' opacity='.30'/%3E%3Cpath d='M0 46 C200 26 400 62 600 44 C800 26 1000 60 1200 42 L1200 60 L0 60 Z' fill='%23C21572' opacity='.32'/%3E%3Cpath d='M0 52 C180 38 380 64 620 50 C860 38 1040 62 1200 50 L1200 60 L0 60 Z' fill='%230E8C9C' opacity='.45'/%3E%3C/svg%3E");
  background-size: 100% 100%;
  background-repeat: no-repeat;
  pointer-events: none;
}
.learn-figure__ph-label {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--lv-muted);
  background: var(--lv-surface);
  border: 1px dashed color-mix(in srgb, var(--lv-accent) 45%, transparent);
  border-radius: 999px;
  padding: 0.35rem 1rem;
}
.learn-figure__ph-label::before {
  content: '';
  inline-size: 0.9rem;
  block-size: 0.9rem;
  border-radius: 50%;
  background: var(--lv-gradient-pitch);
  opacity: 0.9;
}

.learn-video {
  display: flex;
  align-items: center;
  gap: var(--lv-space-2);
  margin-block: var(--lv-space-4);
  padding: var(--lv-space-2) var(--lv-space-3);
  border-radius: var(--lv-radius-lg);
  background:
    linear-gradient(var(--lv-surface), var(--lv-surface)) padding-box,
    var(--lv-gradient-flow) border-box;
  border: 2px solid transparent;
  box-shadow: var(--lv-shadow);
  position: relative;
  overflow: hidden;
}
.learn-video::after {
  content: '';
  position: absolute;
  inset-inline: 0;
  inset-block-end: 0;
  block-size: 1.6rem;
  opacity: 0.55;
  pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 40' preserveAspectRatio='none'%3E%3Cpath d='M0 22 C150 8 300 34 450 22 C600 8 750 34 900 22 C1050 8 1150 30 1200 20' fill='none' stroke='%23FF8A00' stroke-width='3' opacity='.5' stroke-linecap='round'/%3E%3Cpath d='M0 30 C200 16 400 38 600 28 C800 16 1000 36 1200 26' fill='none' stroke='%23C21572' stroke-width='3' opacity='.45' stroke-linecap='round'/%3E%3C/svg%3E");
  background-size: 100% 100%;
  background-repeat: no-repeat;
}
.learn-video__play {
  flex: none;
  inline-size: 3.1rem;
  block-size: 3.1rem;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: #fff;
  font-size: 1.15rem;
  padding-inline-start: 0.2rem;
  background: var(--lv-gradient-warm);
  box-shadow: 0 4px 14px rgba(232, 16, 46, 0.3);
}
[dir='rtl'] .learn-video__play { transform: scaleX(-1); padding-inline-start: 0; padding-inline-end: 0.2rem; }
.learn-video__text { display: grid; gap: 0.15rem; }
.learn-video__text strong { font-size: 1.05rem; }
.learn-video__text span { color: var(--lv-muted); font-size: 0.92rem; }

/* --------------------------------------------------------------------------
   14. Practice block + coming-soon badge
   -------------------------------------------------------------------------- */
.learn-practice {
  margin-block: var(--lv-space-4);
  padding: var(--lv-space-3);
  border-radius: var(--lv-radius-lg);
  background: var(--lv-accent-soft);
  border: 1px solid color-mix(in srgb, var(--lv-accent) 25%, transparent);
}
.learn-practice__title { margin-block: 0 var(--lv-space-1); }
.learn-practice h2.learn-practice__title::after { margin-block-start: 0.4rem; }
.learn-practice__lead { color: var(--lv-ink-soft); margin-block-end: var(--lv-space-2); }
.learn-practice__actions { display: flex; flex-wrap: wrap; gap: var(--lv-space-2); align-items: center; }
.learn-badge-soon {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 1.1rem;
  border-radius: 999px;
  border: 1px dashed color-mix(in srgb, var(--lv-accent) 50%, transparent);
  background: var(--lv-surface);
  color: var(--lv-ink-soft);
  font-weight: 600;
  font-size: 0.95rem;
}
.learn-badge-soon__pill {
  font-size: 0.72rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #fff;
  background: var(--lv-gradient-warm);
  border-radius: 999px;
  padding: 0.14rem 0.6rem;
}

.learn-nav__card--soon { opacity: 0.72; cursor: default; }
.learn-nav__card--soon:hover { border-color: var(--lv-border); transform: none; }

/* --------------------------------------------------------------------------
   15. Footer — the site footer, ported verbatim
   /learn/ used to ship its own footer; the section must wear the same one as
   /, /ear/ and /library/. Since /learn/ does not load main.css, main.css
   §FOOTER and the `.footer-social` block shared by /ear/ + /orchestra/ +
   /andalousie/ are copied here declaration-for-declaration, and the four
   main.css tokens they read (--footer-bg, --text-secondary, --text-primary,
   --border-color) are re-declared locally with main.css's own light/dark
   values. Selectors carry a `.learn-page` prefix ONLY to out-specify this
   file's own typography rules (`.learn-page p`, the anchor rules) — the
   declarations themselves are unchanged, so the render is pixel-identical.
   -------------------------------------------------------------------------- */
.learn-page footer {
  --lv-footer-bg: #ffffff;         /* main.css --footer-bg */
  --lv-footer-fg: #4a4a4a;         /* main.css --text-secondary */
  --lv-footer-ink: #1a1a1a;        /* main.css --text-primary */
  --lv-footer-border: rgba(0, 0, 0, 0.1); /* main.css --border-color */
  text-align: center;
  padding: 2.5rem 2rem;
  position: relative;
  background-color: var(--lv-footer-bg);
  color: var(--lv-footer-fg);
  transition: background-color 0.4s ease, color 0.4s ease;
  border-top: 1px solid var(--lv-footer-border);
  /* Elsewhere the footer inherits 16px/normal from <body>; .learn-page reads
     at 1.0625rem/1.7, which would scale every footer em. Reset to the site's. */
  font-size: 1rem;
  line-height: normal;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .learn-page footer {
    --lv-footer-bg: #0a0a0a;
    --lv-footer-fg: #b0b0b0;
    --lv-footer-ink: #cccccc;
    --lv-footer-border: rgba(255, 255, 255, 0.1);
  }
}
:root[data-theme='dark'] .learn-page footer {
  --lv-footer-bg: #0a0a0a;
  --lv-footer-fg: #b0b0b0;
  --lv-footer-ink: #cccccc;
  --lv-footer-border: rgba(255, 255, 255, 0.1);
}

.learn-page footer .footer-content { margin-bottom: 1rem; }

.learn-page footer p {
  margin: 0 0 0.4rem;
  font-size: 0.9rem;
  line-height: 1.6;
}

.learn-page footer a {
  color: var(--lv-footer-ink);
  font-weight: 600;
  text-decoration: none;
  transition: color 0.3s, transform 0.3s;
}
.learn-page footer a:hover {
  color: #ff6ec7;
  transform: scale(1.05);
}

/* Creator link styling.
   The vivid #ff6ec7 -> #ffa502 gradient painted into the glyphs measured
   2.53:1 (rose) / ~2.0:1 (orange) on the white light-theme footer. Light gets
   a deepened gradient (5.4:1 / 4.9:1); dark keeps the original, which is
   7.8:1 on #0a0a0a. */
.learn-page footer a.creator-link {
  color: #c2185b;
  font-weight: 700;
  text-decoration: none;
  position: relative;
  display: inline-block;
  background: linear-gradient(135deg, #c2185b, #a8590c);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
  transition: all 0.3s ease;
}
:root[data-theme='dark'] .learn-page footer a.creator-link {
  color: #ff6ec7;
  background: linear-gradient(135deg, #ff6ec7, #ffa502);
  -webkit-background-clip: text;
  background-clip: text;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .learn-page footer a.creator-link {
    color: #ff6ec7;
    background: linear-gradient(135deg, #ff6ec7, #ffa502);
    -webkit-background-clip: text;
    background-clip: text;
  }
}
.learn-page footer a.creator-link::after {
  content: '';
  position: absolute;
  bottom: -2px;
  /* Logical inset + mirrored origin: the underline used to grow from the left
     on the Arabic pages, against the reading direction. */
  inset-inline-start: 0;
  width: 100%;
  height: 2px;
  background: linear-gradient(135deg, #ff6ec7, #ffa502);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.3s ease;
}
[dir='rtl'] .learn-page footer a.creator-link::after { transform-origin: left; }
.learn-page footer a.creator-link:hover::after {
  transform: scaleX(1);
  transform-origin: left;
}
[dir='rtl'] .learn-page footer a.creator-link:hover::after { transform-origin: right; }
.learn-page footer a.creator-link:hover {
  transform: translateY(-2px);
  filter: brightness(1.2);
}

/* Social row — copied from public/ear/styles.css */
.learn-page footer .footer-social {
  display: flex;
  justify-content: center;
  gap: 0.75rem;
  margin-top: 0.75rem;
}
.learn-page footer .footer-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  font-size: 1.1rem;
  color: inherit;
  transition: background 0.2s ease, transform 0.2s ease;
}
.learn-page footer .footer-social a:hover {
  background: rgba(255, 110, 199, 0.12);
  transform: translateY(-2px);
}

/* --------------------------------------------------------------------------
   16. Hub (/learn/ index)
   -------------------------------------------------------------------------- */
.learn-hub-container {
  max-width: 75rem;
  margin-inline: auto;
  padding-inline: var(--lv-space-3);
  padding-block: var(--lv-space-3) var(--lv-space-4);
}
/* The hub hero must share the grid's 75rem, not the 46rem reading column:
   at 1440 the H1 started 232px inside the "All lessons" heading right below
   it. Lesson heroes keep --lv-measure. */
.learn-hero--hub .learn-hero__inner { max-width: 75rem; }
.learn-page .learn-hub-heading { margin-block: var(--lv-space-2) var(--lv-space-2); }
/* Flex, not `repeat(auto-fill, minmax(17rem, 1fr))`: that grid went from
   3 columns of 347px at 1120 to 4 columns of 276px at 1200 — cards SHRANK as
   the window grew — and left the 7th card stranded against one edge. Flex
   pins a comfortable card width and centres the short last row. */
.learn-hub-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--lv-space-2);
  margin-block-start: var(--lv-space-2);
  align-items: stretch;
}
.learn-hub-ear {
  text-align: center;
  margin-block: var(--lv-space-4) 0;
  color: var(--lv-muted);
}
.learn-hub-ear a { color: inherit; font-weight: 600; }
.learn-hub-ear a:hover { color: var(--lv-accent-ink); }
.learn-hub-card {
  /* `min-inline-size: 0` so a long word can never push the card past the
     viewport now that the track is a shrinkable flex item. */
  flex: 1 1 19rem;
  min-inline-size: 0;
  max-inline-size: 24rem;
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  border: 1px solid var(--lv-border);
  border-radius: var(--lv-radius);
  background: var(--lv-surface);
  padding: var(--lv-space-3);
  padding-block-start: calc(var(--lv-space-3) + 0.35rem);
  box-shadow: var(--lv-shadow);
  overflow: hidden;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
.learn-hub-card:hover { transform: translateY(-3px); border-color: var(--lv-hub-accent, var(--lv-accent)); }
.learn-hub-card::before {
  content: '';
  position: absolute;
  inset-block-start: 0;
  inset-inline: 0;
  block-size: 5px;
  background: var(--lv-hub-bar, var(--lv-gradient-flow));
}
/* White on the raw concept accent failed AA badly — 2.36:1 on the orange
   "03", 3.33:1 on the vermilion "04". The deep per-concept variant is
   AA-clean in light; in dark it is the light tint, so the digit flips to the
   page background. */
.learn-hub-card__num {
  flex: none;
  inline-size: 2rem;
  block-size: 2rem;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-weight: 800;
  font-size: 0.95rem;
  color: #fff;
  background: var(--lv-hub-ink, var(--lv-accent-ink));
}
:root[data-theme='dark'] .learn-hub-card__num { color: var(--lv-bg); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .learn-hub-card__num { color: var(--lv-bg); }
}
.learn-page .learn-hub-card__title {
  font-size: 1.12rem;
  font-weight: 700;
  line-height: 1.3;
  margin: 0;
}
/* The card is an <article>; only the title holds an <a>, stretched over the
   whole card by ::after so the language pills below stay clickable. */
.learn-page .learn-hub-card__title::after { display: none; }
.learn-hub-card__title a { color: var(--lv-ink); text-decoration: none; }
.learn-hub-card__title a::after { content: ''; position: absolute; inset: 0; }
.learn-hub-card:hover .learn-hub-card__title a { color: var(--lv-hub-ink, var(--lv-accent-ink)); }
.learn-hub-card__desc {
  color: var(--lv-ink-soft);
  font-size: 0.93rem;
  line-height: 1.55;
  margin: 0;
  flex: 1;
}
.learn-hub-card__langs {
  position: relative;
  z-index: 1;
  display: flex;
  gap: 0.3rem;
  flex-wrap: wrap;
}
.learn-hub-card__langs a {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--lv-muted);
  text-decoration: none;
  border: 1px solid var(--lv-border);
  border-radius: 999px;
  padding: 0.05rem 0.55rem;
  background: var(--lv-bg);
}
.learn-hub-card__langs a:hover { color: var(--lv-hub-ink, var(--lv-accent-ink)); border-color: var(--lv-hub-accent, var(--lv-accent)); }

/* --------------------------------------------------------------------------
   17. Reduced motion
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .learn-exercise-btn,
  .learn-nav__card,
  .learn-hub-card,
  .learn-header__link,
  .learn-langs__item,
  .learn-header .hamburger span,
  .learn-header .mobile-nav,
  .learn-header .mobile-nav.show,
  .learn-faq summary::after { transition: none; }
  .learn-exercise-btn:hover,
  .learn-nav__card:hover,
  .learn-hub-card:hover { transform: none; }
}

/* ── Capsule vidéo intégrée ─────────────────────────────────────────────────
   Affichée dès que la leçon a un identifiant YouTube ; sinon c'est le bloc
   .learn-video (placeholder) qui reste. */
/* NOTE: this block previously used --learn-* tokens, which do not exist in
   this file (everything is --lv-*). The fallbacks therefore always applied,
   freezing an off-palette grey that failed AA contrast in dark mode. */
.learn-video-section {
  margin: var(--lv-space-4) 0;
}
.learn-page .learn-video-section__title {
  font-size: 1.15rem;
  margin: 0 0 0.7rem;
}
.learn-video-embed {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--lv-radius);
  overflow: hidden;
  background: #0b0a10;
  box-shadow: var(--lv-shadow);
  border: 1px solid var(--lv-border);
}
.learn-video-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
.learn-video-section__meta {
  margin: 0.65rem 0 0;
  font-size: 0.9rem;
  color: var(--lv-muted);
}
.learn-video-section__meta a {
  color: var(--lv-accent-ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.learn-video-section__meta a:hover {
  color: var(--lv-accent);
}
/* Above 1200px the reading column leaves 230px+ of gutter on each side; the
   capsule is the reason the lesson exists, so let it breathe past the prose.
   Logical margins keep the bleed symmetric in RTL. */
@media (min-width: 1200px) {
  .learn-video-embed {
    inline-size: calc(100% + 8rem);
    max-inline-size: none;
    margin-inline: -4rem;
  }
}
