/* ============================================================
   Karana, Reels-style scroll-lesson player (slp-)
   Overlay lives INSIDE #app, z-index 320, `open` class pattern.
   Flat system: no gradients, no glows, one saffron accent.
   Night beats sit on the token deep navy; text blocks left-aligned.
   ============================================================ */

.slp-overlay,
.slp-overlay * {
  box-sizing: border-box;
}

.slp-overlay {
  position: absolute;
  inset: 0;
  z-index: 320;
  background: var(--bg-app);
  /* Slide in from the right, same direction and duration as every other
     roadmap screen (see KRM_SLIDE_MS/playSlideInTransition in
     roadmap.js) — an episode is always a deeper screen, never the
     nav-visible "home" layer, so unlike those this one never flips to
     sliding in from the left. */
  transform: translateX(100%);
  pointer-events: none;
  transition: transform 460ms cubic-bezier(0.22, 1, 0.36, 1);
}

.slp-overlay.open {
  transform: translateX(0);
  pointer-events: auto;
}

/* Masks the beat content while its images (background art + character
   portraits) preload — see preloadEpisodeImages() in lesson-player.js.
   z-index 4 sits below .slp-top's 5, so the close button stays tappable
   even mid-load; everything else in the scroller (z-index auto/0) sits
   under it. --ep-bg falls back to the app's own background for an episode
   with no palette yet. */
.slp-preload-veil {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background: var(--ep-bg, var(--bg-app));
  color: var(--ep-fg, var(--text-muted));
  opacity: 1;
  transition: opacity 0.25s ease;
}
.slp-preload-veil.slp-preload-veil-hide {
  opacity: 0;
  pointer-events: none;
}
.slp-preload-veil .material-symbols-rounded {
  font-size: 2.25rem;
  opacity: .6;
}
.slp-preload-veil p {
  margin: 0;
  font-size: 0.84375rem;
  font-weight: 700;
  color: inherit;
  opacity: .6;
}

/* ---------- top bar: close · segmented progress · mute ---------- */
.slp-top {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: max(14px, env(safe-area-inset-top)) 16px 10px;
  pointer-events: none;
}

.slp-top>* {
  pointer-events: auto;
}

.slp-close,
.slp-mute,
.slp-save {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border: none;
  border-radius: var(--radius-round, 99px);
  background: rgba(0, 0, 0, 0.35);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: transform 0.1s ease, background-color 0.15s ease;
}

.slp-close:active,
.slp-mute:active,
.slp-save:active {
  transform: scale(0.92);
}

.slp-close .material-symbols-rounded,
.slp-mute .material-symbols-rounded,
.slp-save .material-symbols-rounded {
  font-size: 1.375rem;
}

.slp-close .k-icon,
.slp-mute .k-icon {
  width: 20px;
  height: 20px;
}

/* Saved state: this episode's own accent (same --ep-accent every other
   highlight in this player already uses), not a fixed color. */
.slp-save.is-saved {
  background: var(--ep-accent, #FC9E4F);
  color: #2b1c08;
}

/* ---------- top bar: "more options" menu (mute + save, collapsed) ----------
   One trigger instead of two always-visible icons: 3 bars that spin and
   converge into an X, revealing mute/save stacked vertically beneath it —
   see the click wiring in lesson-player.js (setMenuOpen). */
.slp-menu {
  position: relative;
  flex: 0 0 auto;
}

.slp-menu-toggle {
  position: relative;
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border: none;
  border-radius: var(--radius-round, 99px);
  background: rgba(0, 0, 0, 0.35);
  color: #fff;
  cursor: pointer;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: transform 0.32s cubic-bezier(0.22, 1, 0.36, 1), background-color 0.15s ease;
}
.slp-menu-toggle:active { transform: scale(0.92); }
.slp-menu.is-open .slp-menu-toggle { transform: rotate(90deg); }

.slp-menu-bar {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 16px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
  transform: translate(-50%, -50%) translateY(-5px);
  transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.2s ease;
}
.slp-menu-bar:nth-child(2) { transform: translate(-50%, -50%); }
.slp-menu-bar:nth-child(3) { transform: translate(-50%, -50%) translateY(5px); }

/* Bars converge into an X: top/bottom rotate to meet at center, middle
   fades out — the classic hamburger-to-close morph, layered on top of the
   whole button's own 90° spin above for the "spins into an X" flourish. */
.slp-menu.is-open .slp-menu-bar:nth-child(1) { transform: translate(-50%, -50%) rotate(45deg); }
.slp-menu.is-open .slp-menu-bar:nth-child(2) { opacity: 0; }
.slp-menu.is-open .slp-menu-bar:nth-child(3) { transform: translate(-50%, -50%) rotate(-45deg); }

.slp-menu-items {
  position: absolute;
  top: 48px;
  right: 0;
  z-index: 6;
  width: 40px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Each action button keeps its own .slp-mute/.slp-save circle styling
   (shared with .slp-close above) — only the reveal/collapse is added here,
   staggered slightly per child so they cascade in rather than popping
   together. transform-origin sits at the toggle's corner, top right, so
   the stack visibly grows out of the trigger it came from. */
.slp-menu-items>* {
  transform-origin: top right;
  opacity: 0;
  transform: scale(0.4) translateY(-10px);
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.slp-menu.is-open .slp-menu-items>* {
  opacity: 1;
  transform: scale(1) translateY(0);
  pointer-events: auto;
}
.slp-menu.is-open .slp-menu-items>*:nth-child(2) { transition-delay: 0.04s; }

/* progress segments: done + active = accent, rest = neutral */
.slp-progress {
  flex: 1;
  display: flex;
  gap: 4px;
  pointer-events: none;
}

.slp-seg {
  flex: 1;
  height: 4px;
  border-radius: 99px;
  background: rgba(110, 110, 120, 0.32);
  transition: background-color 0.3s ease;
}

.slp-seg.done {
  background: var(--brand-primary);
}

.slp-seg.active {
  background: var(--brand-primary);
}

body.dark-mode .slp-seg {
  background: rgba(154, 154, 166, 0.28);
}

/* ---------- reels scroller ---------- */
.slp-scroller {
  height: 100%;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  scrollbar-width: none;
  scroll-snap-type: y mandatory;
  -webkit-overflow-scrolling: touch;
}

.slp-scroller::-webkit-scrollbar {
  display: none;
}

.slp-beat {
  height: 100%;
  min-height: 100%;
  max-height: 100%;
  flex-shrink: 0;
  box-sizing: border-box;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  display: flex;
  flex-direction: column;
  /* Must clear .slp-top, which is absolutely positioned above this and ends at
     max(14px, sat) + 40px button + 10px padding. The old value keyed off
     max(48px, sat) + 30px, which on any notched iPhone (sat 44-62px) starts the
     content ABOVE the close button — the character chip in image-mode story
     beats pins to this top edge and landed underneath the X. Same base term as
     .slp-top now, so they cannot drift apart again. */
  padding: calc(max(14px, env(safe-area-inset-top)) + 62px) 22px calc(20px + env(safe-area-inset-bottom));
  background: var(--surface);
}

/* Inner region scrolls on its own when a beat overflows. Content is a
   LEFT-ALIGNED column (asymmetric: visual above-left, text below). */
.slp-beat-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  margin: -40px -24px;
  padding: 40px 24px;
}

.slp-beat-scroll::-webkit-scrollbar {
  display: none;
}

.slp-beat-inner {
  margin: auto 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  /* Trimmed from 16px/6px-14px: every beat that reveals content on tap
     (context's 3 points, a choice's reaction, a quiz's feedback) grows
     taller than its initial render, and this gap/padding was tuned against
     the collapsed state, not the expanded one — content that fit fine
     closed still had to fall back on .slp-beat-scroll's own scroll once
     opened. This alone doesn't guarantee every beat fits on every screen
     (a fully-populated verse card with Devanagari, transliteration and
     translation is genuinely long content), but it's real reclaimed height
     on every beat, for free, and it's what actually closes the gap for the
     realistic case: context beats' point text runs 47-133 characters in
     the real content (checked against spine-gita.json), not arbitrarily
     long. */
  gap: 12px;
  text-align: left;
  padding: 4px 0 10px;
}

.slp-beat-actions {
  flex: 0 0 auto;
  padding-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Recitation hand-off (mantra-meaning episodes only): same outline-pill
   recipe as .slp-pronounce/.slp-verse-context, full width since it sits
   stacked above the primary finish button rather than inline in a verse card. */
.slp-recitation-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 48px;
  border: 1px solid var(--ep-pop, #B5620A);
  border-radius: 10px;
  background: transparent;
  color: var(--ep-pop, #B5620A);
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  font-weight: 600;
  padding: 10px 16px;
  cursor: pointer;
  transition: background-color 0.15s ease, transform 0.1s ease;
}
.slp-recitation-cta:active {
  transform: scale(0.985);
  background: rgba(255, 255, 255, 0.08);
}
.slp-recitation-cta .material-symbols-rounded {
  font-size: 1.25rem;
}

/* continue button, shadcn primary */
.slp-continue {
  width: 100%;
  min-height: 48px;
  padding: 10px 16px;
  border: none;
  border-radius: 10px;
  background: var(--brand-primary);
  color: #fff;
  font-family: var(--font-sans);
  font-size: 1rem;
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
  cursor: pointer;
  transition: background-color 0.15s ease, transform 0.1s ease;
}

.slp-continue:hover {
  background: var(--brand-primary-shadow);
}

.slp-continue:active {
  background: var(--brand-primary-shadow);
  transform: scale(0.985);
}

.slp-continue:disabled {
  opacity: 0.45;
  cursor: default;
}

/* ---------- scene beat (flat indigo, voice-first) ---------- */
.slp-scene,
.slp-complete {
  background: var(--indigo);
  color: #EFF1F0;
}

.slp-scene-visual {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}

.slp-scene-emoji {
  font-size: 4rem;
  line-height: 1;
  animation: slpEmojiFloat 4.5s ease-in-out infinite;
}

@keyframes slpEmojiFloat {

  0%,
  100% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(-7px);
  }
}

/* caption under the visual: sentence case, muted, small */
.slp-scene-caption {
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: normal;
  text-transform: none;
  color: rgba(236, 236, 240, 0.62);
}

.slp-mayu {
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 100%;
}

.slp-mayu-avatar {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  border-radius: 99px;
  background: var(--brand-primary);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  box-shadow: none;
}

.slp-mayu-avatar .k-icon {
  width: 20px;
  height: 20px;
}

.slp-mayu-bubble {
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 12px 12px 12px 4px;
  padding: 10px 16px;
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  font-weight: 600;
  text-align: left;
}

.slp-listen {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.08);
  color: #EFF1F0;
  font-family: var(--font-sans);
  font-size: 0.84375rem;
  font-weight: 600;
  padding: 8px 14px;
  cursor: pointer;
  transition: background-color 0.15s ease, transform 0.1s ease;
}

.slp-listen:active {
  transform: scale(0.97);
  background: rgba(255, 255, 255, 0.14);
}

.slp-listen .material-symbols-rounded {
  font-size: 1.1875rem;
}

.slp-listen .k-icon {
  width: 18px;
  height: 18px;
}

/* narration: left-aligned block, not centered */
.slp-narration {
  margin: 0;
  font-size: 1.09375rem;
  line-height: 1.6;
  max-width: 36ch;
  color: rgba(236, 236, 240, 0.94);
  text-align: left;
}

/* ---------- verse beat (flat cream card) ---------- */
.slp-verse {
  background: var(--bg-app);
}

.slp-verse-card {
  width: 100%;
  background: #FAF7F0;
  color: var(--text-main);
  border: 1px solid #E9E4D8;
  border-radius: var(--radius-xl, 14px);
  /* 24px/14px -> 14px/14px, gap 10 -> 7: a verse with all four fields
     populated (ref, Devanagari, transliteration, translation) is still the
     one beat this app can't unconditionally guarantee fits on every screen
     — see the note on .slp-beat-inner — but every px reclaimed here is real,
     and stacked against the deva/translit/translation trims below it
     closes most of the remaining gap for a normal-length verse. */
  padding: 14px 14px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
}

body.dark-mode .slp-verse-card {
  background: #FAF7F0;
  border-color: #D8D2C2;
  color: var(--text-main);
}

.slp-verse-ref {
  font-size: 0.78125rem;
  font-weight: 500;
  letter-spacing: normal;
  text-transform: none;
  color: #8A7E5F;
}

.slp-verse-deva {
  font-family: var(--font-verse, serif);
  /* 1.625rem -> 1.5rem: a full shloka commonly wraps to two lines at the
     old size, and this is the single largest type on the card. Still
     clearly the display element (bigger than translit/translation), just
     not so large that two lines of it out-costs everything below it. */
  font-size: 1.5rem;
  /* 1.75 -> 1.45: still real room for Devanagari's vowel marks and
     conjuncts (the reason this was set loose in the first place), just not
     loose enough to be the single biggest line-height on the whole card
     when the card also carries a transliteration and a translation
     underneath it. */
  line-height: 1.45;
  font-weight: 600;
}

.slp-verse-translit {
  font-size: 0.90625rem;
  font-style: normal;
  line-height: 1.4;
  color: var(--text-muted);
}

.slp-verse-translation {
  font-size: 1.0625rem;
  line-height: 1.4;
  font-weight: 500;
  max-width: 36ch;
}

.slp-verse-quote {
  font-family: var(--font-title);
  font-size: 1.1875rem;
  line-height: 1.5;
  font-weight: 600;
  font-style: normal;
  max-width: 34ch;
}

.slp-verse-attrib {
  font-size: 0.84375rem;
  color: var(--text-muted);
}

.slp-verse-note {
  font-size: 0.90625rem;
  line-height: 1.4;
  text-align: left;
  color: #4A4438;
  background: rgba(232, 137, 28, 0.08);
  border-radius: 12px;
  padding: 8px 12px;
  max-width: 40ch;
}

.slp-pronounce[hidden],
.slp-verse-context[hidden] {
  display: none;
}

/* Verse card actions: Pronounce and "Read in context" sit side by side and
   wrap to their own lines on narrow screens. */
.slp-verse-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 8px;
}

.slp-verse-context {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--ep-pop, #B5620A);
  border-radius: 10px;
  background: transparent;
  color: var(--ep-pop, #B5620A);
  font-family: var(--font-sans);
  font-size: 0.875rem;
  font-weight: 600;
  padding: 9px 16px;
  cursor: pointer;
  transition: background-color 0.15s ease, transform 0.1s ease;
}

.slp-verse-context:active {
  transform: scale(0.97);
  background: rgba(255, 255, 255, 0.08);
}

.slp-verse-context .material-symbols-rounded {
  font-size: 1.25rem;
}

.slp-pronounce {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid #B5620A;
  border-radius: 10px;
  background: transparent;
  color: #B5620A;
  font-family: var(--font-sans);
  font-size: 0.875rem;
  font-weight: 600;
  padding: 9px 16px;
  cursor: pointer;
  transition: background-color 0.15s ease, transform 0.1s ease;
}

.slp-pronounce:active {
  transform: scale(0.97);
  background: rgba(232, 137, 28, 0.08);
}

.slp-pronounce .material-symbols-rounded {
  font-size: 1.25rem;
}

.slp-pronounce .k-icon {
  width: 18px;
  height: 18px;
}

/* ---------- interactive / quiz / reflect share the surface look ---------- */
.slp-interactive,
.slp-quiz,
.slp-reflect {
  background: var(--surface);
}

.slp-prompt {
  margin: 0;
  font-family: var(--font-title);
  font-size: 1.25rem;
  line-height: 1.45;
  font-weight: 700;
  color: var(--text-main);
  max-width: 32ch;
  text-align: left;
}

/* choice */
.slp-choices {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.slp-choice {
  width: 100%;
  text-align: left;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  color: var(--text-main);
  font-family: var(--font-sans);
  font-size: 0.96875rem;
  font-weight: 500;
  line-height: 1.4;
  padding: 12px 14px;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}

.slp-choice:active {
  transform: scale(0.985);
}

.slp-choice.selected {
  border-color: var(--brand-primary);
  background: var(--brand-primary-light);
}

.slp-reaction {
  width: 100%;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 12px 15px;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--text-main);
  text-align: left;
  animation: slpFadeUp 0.35s ease;
}

@keyframes slpFadeUp {
  from {
    opacity: 0;
    transform: translateY(8px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* dice */
.slp-die {
  width: 118px;
  height: 118px;
  margin: 14px 0 4px;
  background: #FFFFFF;
  border: 1px solid #DDDDE4;
  border-radius: 20px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  padding: 20px;
  cursor: pointer;
  transition: transform 0.15s ease;
}

.slp-die:active {
  transform: scale(0.95);
}

body.dark-mode .slp-die {
  background: #EFF1F0;
  border-color: var(--text-muted);
}

.slp-pip {
  width: 15px;
  height: 15px;
  border-radius: 99px;
  background: #1A1A21;
  place-self: center;
}

.slp-die.slp-rolling {
  animation: slpDieTumble 0.9s cubic-bezier(0.3, 0.7, 0.4, 1);
}

@keyframes slpDieTumble {
  0% {
    transform: rotate(0deg) scale(1) translateY(0);
  }

  22% {
    transform: rotate(150deg) scale(0.82) translateY(-34px);
  }

  48% {
    transform: rotate(330deg) scale(1.08) translateY(8px);
  }

  72% {
    transform: rotate(505deg) scale(0.94) translateY(-14px);
  }

  100% {
    transform: rotate(720deg) scale(1) translateY(0);
  }
}

.slp-die-hint {
  font-size: 0.84375rem;
  font-weight: 500;
  color: var(--text-muted);
}

/* reveal (flip card) */
.slp-flip {
  width: 100%;
  min-height: 210px;
  border: none;
  background: transparent;
  padding: 0;
  perspective: 1000px;
  cursor: pointer;
}

.slp-flip-inner {
  position: relative;
  display: block;
  width: 100%;
  min-height: 210px;
  transform-style: preserve-3d;
  transition: transform 0.6s cubic-bezier(0.4, 0.9, 0.4, 1);
}

.slp-flip.flipped .slp-flip-inner {
  transform: rotateY(180deg);
}

.slp-face {
  position: absolute;
  inset: 0;
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  border-radius: var(--radius-xl, 14px);
  padding: 24px 20px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 12px;
  text-align: left;
  font-family: var(--font-title);
  font-size: 1.125rem;
  line-height: 1.5;
  font-weight: 700;
  color: var(--text-main);
}

.slp-face-front {
  background: var(--surface-alt);
  border: 1px dashed var(--border);
}

.slp-flip-hint {
  font-family: var(--font-sans);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: normal;
  text-transform: none;
  color: var(--text-muted);
}

.slp-face-back {
  background: var(--brand-primary-light);
  border: 1px solid var(--brand-primary);
  transform: rotateY(180deg);
  font-family: var(--font-sans);
  font-size: 1rem;
  font-weight: 500;
}

/* ---------- quiz beat ---------- */
.slp-quiz-q {
  margin: 0;
  font-family: var(--font-title);
  font-size: 1.25rem;
  line-height: 1.45;
  font-weight: 700;
  color: var(--text-main);
  max-width: 32ch;
  text-align: left;
}

.slp-opts {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.slp-opt {
  width: 100%;
  text-align: left;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  color: var(--text-main);
  font-family: var(--font-sans);
  font-size: 0.96875rem;
  font-weight: 500;
  line-height: 1.45;
  padding: 14px 16px;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}

.slp-opt:active:not(:disabled) {
  transform: scale(0.985);
}

.slp-opt.selected {
  border-color: var(--brand-primary);
  background: var(--brand-primary-light);
}

.slp-opt.correct {
  border-color: var(--success);
  background: var(--success-light);
  color: var(--success-ink);
}

.slp-opt.wrong {
  border-color: #D64545;
  background: rgba(214, 69, 69, 0.08);
  color: #A53030;
}

body.dark-mode .slp-opt.correct {
  color: var(--success-ink);
}

body.dark-mode .slp-opt.wrong {
  color: #F3A1A1;
}

.slp-opt:disabled {
  cursor: default;
}

.slp-feedback {
  width: 100%;
  border-radius: 12px;
  border: 1px solid var(--border);
  padding: 15px 18px;
  text-align: left;
  animation: slpFadeUp 0.35s ease;
}

.slp-feedback.ok {
  background: var(--success-light);
  color: var(--success-ink);
}

.slp-feedback.no {
  background: rgba(214, 69, 69, 0.08);
  color: #A53030;
}

body.dark-mode .slp-feedback.ok {
  color: var(--success-ink);
}

body.dark-mode .slp-feedback.no {
  color: #F3A1A1;
}

.slp-fb-head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-title);
  font-size: 1rem;
  font-weight: 700;
}

.slp-fb-head .material-symbols-rounded {
  font-size: 1.3125rem;
}

.slp-fb-head .k-icon {
  width: 19px;
  height: 19px;
}

.slp-fb-exp {
  margin-top: 6px;
  font-size: 0.90625rem;
  line-height: 1.55;
  font-weight: 500;
}

/* ---------- reflect beat ---------- */
.slp-reflect-mark {
  font-size: 2.5rem;
  line-height: 1;
  color: var(--text-muted);
}

.slp-reflect-input {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text-main);
  font-family: var(--font-sans);
  /* 16px minimum on inputs, or iOS zooms the page — see styles.css. */
  font-size: 1rem;
  padding: 14px 16px;
  outline: none;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.slp-reflect-input:focus {
  border-color: var(--brand-primary);
  box-shadow: 0 0 0 2px rgba(232, 137, 28, 0.25);
}

.slp-reflect-input::placeholder {
  color: var(--text-muted);
}

.slp-reflect-hint {
  font-size: 0.8125rem;
  font-style: normal;
  color: var(--text-muted);
}

/* ---------- completion beat (the diya lights, flat) ---------- */
.slp-complete-inner {
  gap: 14px;
  align-items: center;
  text-align: center;
}

.slp-complete-title {
  margin: 0;
  font-family: var(--font-title);
  font-size: 1.625rem;
  font-weight: 700;
  font-style: normal;
  color: #EFF1F0;
}

/* Score used to be an orange SVG ring — a flat brand-orange progress arc
   sitting on top of whatever color this episode's own palette washed the
   card in, which is exactly the "orange looks out of place" complaint. Just
   the number now, no ring: it doesn't fight the episode's own theming and
   still says what it needs to say. */
.slp-score {
  animation: slpFadeUp 0.4s ease;
}

.slp-score-num {
  font-family: var(--font-title);
  font-size: 1.75rem;
  font-weight: 800;
  color: var(--ep-accent, var(--brand-primary));
}

.slp-score-label {
  margin-top: 2px;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ep-fg, rgba(236, 236, 240, 0.7));
  opacity: 0.75;
}

.slp-complete-note {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.90625rem;
  line-height: 1.5;
  color: rgba(236, 236, 240, 0.78);
  max-width: 30ch;
  text-align: left;
}

.slp-complete-note .material-symbols-rounded {
  font-size: 1.25rem;
  color: var(--brand-primary);
}

.slp-complete-note .k-icon {
  width: 18px;
  height: 18px;
  color: var(--brand-primary);
}

/* Hero diya — the exact markup window.getUserDiyaHtml() also feeds the
   streak card and the completion celebration toast, just parked here so it
   stays on screen once that toast fades instead of the page going back to
   empty. Sized down slightly (its native size is tuned for the toast) and
   given room to breathe above the title.

   .slp-complete-rays sits behind it: the same conic-gradient "light catching
   a rotating surface" the diya celebration toast uses (app.js's showCelebration
   scrim / .med-cel-rays), colored from THIS episode's own background
   (--ep-bg) rather than the diya's usual brand-orange glow, so the payoff
   reads as "this episode, finished" and not a generic reused flourish. */
.slp-complete-diya-wrap {
  position: relative;
  width: 100%;
  min-height: 96px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 4px;
}

.slp-complete-rays {
  position: absolute;
  top: 50%; left: 50%;
  width: 180px; height: 180px;
  margin: -90px 0 0 -90px;
  border-radius: 50%;
  background: conic-gradient(
    from 0deg,
    transparent 0 8deg,
    color-mix(in srgb, var(--ep-bg, var(--brand-primary)) 65%, white) 8deg 12deg,
    transparent 12deg 30deg
  );
  animation: slpRaysSpin 9s linear infinite, slpRaysIn 0.7s cubic-bezier(0.16, 1, 0.3, 1) both;
  pointer-events: none;
}
@keyframes slpRaysSpin { to { transform: rotate(360deg); } }
@keyframes slpRaysIn { from { opacity: 0; transform: scale(0.6); } to { opacity: 1; transform: scale(1); } }

.slp-complete-diya {
  position: relative;
  z-index: 1;
  width: 100%;
  min-height: 96px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.slp-complete-diya svg {
  width: 120px;
  height: auto;
}

.slp-score-review-toggle {
  display: flex;
  align-items: center;
  gap: 4px;
  border: none;
  background: none;
  padding: 4px 8px;
  font-family: var(--font-sans);
  font-size: 0.84375rem;
  font-weight: 600;
  color: rgba(236, 236, 240, 0.6);
  cursor: pointer;
}

.slp-score-review-toggle .material-symbols-rounded {
  font-size: 1.125rem;
  transition: transform 0.25s ease;
}

.slp-score-review-toggle.is-open .material-symbols-rounded {
  transform: rotate(180deg);
}

.slp-score-review {
  width: 100%;
  max-width: 320px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  animation: slpFadeUp 0.3s ease;
}

.slp-score-review-item {
  text-align: left;
  padding: 12px 14px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.08);
}

.slp-score-review-q {
  font-size: 0.84375rem;
  font-weight: 600;
  color: var(--ep-fg, #EFF1F0);
  margin-bottom: 6px;
}

.slp-score-review-a {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.84375rem;
  color: rgba(236, 236, 240, 0.82);
}

.slp-score-review-a .material-symbols-rounded {
  font-size: 1.0625rem;
  color: #6FCF97;
}

.slp-score-review-exp {
  margin-top: 6px;
  font-size: 0.78125rem;
  line-height: 1.5;
  color: rgba(236, 236, 240, 0.62);
}

/* Continue-to-next-part becomes the primary action when it's offered; the
   plain "back to the path" exit steps down to an outline so there's still
   one clear default without hiding the option entirely. */
.slp-next-part-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}

.slp-finish-secondary {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.18);
  color: var(--ep-fg, #EFF1F0);
  box-shadow: none;
}

.slp-finish-secondary:hover,
.slp-finish-secondary:active {
  background: rgba(255, 255, 255, 0.06);
}

/* The primary buttons on the completion card ("Back to the path"/"Continue
   to Part N") used var(--brand-primary) unconditionally — the app's generic
   orange, regardless of which episode's own colors the rest of this card
   (background wash, rays, score number) was already using. --ep-accent/
   --ep-accent-fg are the same contrast-safe pair applyPalette already
   computes for this episode; episodes with no palette fall back to the
   plain brand color exactly as before. */
.slp-has-palette .slp-complete .slp-continue {
  background: var(--ep-accent, var(--brand-primary));
  color: var(--ep-accent-fg, #fff);
}
.slp-has-palette .slp-complete .slp-continue:hover,
.slp-has-palette .slp-complete .slp-continue:active {
  background: var(--ep-accent, var(--brand-primary));
  filter: brightness(0.92);
}
.slp-has-palette .slp-complete .slp-recitation-cta {
  border-color: var(--ep-accent, var(--ep-pop, #B5620A));
  color: var(--ep-accent, var(--ep-pop, #B5620A));
}

/* ============================================================
   v3 PANELS (LESSON-SYSTEM.md)
   ============================================================ */

/* moment panels dim the chrome, the interface itself slows down */
.slp-overlay .slp-top {
  transition: opacity 0.8s ease;
}

.slp-overlay.slp-dim-chrome .slp-top {
  opacity: 0.12;
}

/* ---------- warm-up recall tag (sentence case, quiet chip) ---------- */
.slp-warmup-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 8px;
  background: var(--brand-primary-light);
  color: #8A5A10;
  font-size: 0.78125rem;
  font-weight: 600;
  letter-spacing: normal;
  text-transform: none;
}

.slp-warmup-tag .material-symbols-rounded {
  font-size: 1rem;
}

.slp-warmup-tag .k-icon {
  width: 15px;
  height: 15px;
}

body.dark-mode .slp-warmup-tag {
  color: #E0B978;
}

/* ---------- portrait chip (k-avatar or legacy circle + name) ---------- */
.slp-chip {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
}

.slp-chip-circle {
  width: 72px;
  height: 72px;
  border-radius: 99px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  box-shadow: none;
  color: #fff;
  font-family: var(--font-sans);
  font-weight: 600;
  transition: transform 0.2s ease;
}

.slp-chip-emoji {
  font-size: 1.875rem;
  line-height: 1;
}

.slp-chip-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.slp-chip-name {
  font-family: var(--font-title);
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--text-main);
  max-width: 96px;
  line-height: 1.25;
  text-align: center;
}

.slp-chip-sm .slp-chip-circle {
  width: 44px;
  height: 44px;
}

.slp-chip-sm .slp-chip-emoji {
  font-size: 1.125rem;
}

.slp-chip-sm .slp-chip-name {
  font-size: 0.71875rem;
}

.slp-chip-md .slp-chip-circle {
  width: 88px;
  height: 88px;
}

.slp-chip-md .slp-chip-emoji {
  font-size: 2.25rem;
}

.slp-chip-lg .slp-chip-circle {
  width: 116px;
  height: 116px;
}

.slp-chip-lg .slp-chip-emoji {
  font-size: 3rem;
}

.slp-chip-lg .slp-chip-name {
  font-size: 1.3125rem;
  max-width: none;
}

.slp-chip-row {
  display: flex;
  gap: 16px;
  justify-content: flex-start;
  flex-wrap: wrap;
}

/* ---------- story panel (flat indigo, icon tile above-left, big line) ---------- */
.slp-story {
  background: var(--indigo);
  color: #EFF1F0;
}

.slp-story .slp-chip-name {
  color: rgba(236, 236, 240, 0.85);
}

.slp-story-visual {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  min-height: 90px;
}

.slp-story-visual .k-icon-tile {
  background: rgba(255, 255, 255, 0.08);
  color: #EFF1F0;
}

.slp-story-emoji {
  font-size: 4.5rem;
  line-height: 1;
  display: inline-block;
}

.slp-story-line {
  margin: 0;
  font-family: var(--font-title);
  font-size: 1.375rem;
  line-height: 1.45;
  font-weight: 700;
  font-style: normal;
  max-width: 24ch;
  text-align: left;
  color: rgba(236, 236, 240, 0.96);
}

/* visual effects, motion only, no glow filters */
.slp-fx-pan .slp-story-emoji {
  animation: slpFxPan 7s ease-in-out infinite;
}

.slp-fx-glow .slp-story-emoji {
  animation: slpEmojiFloat 4.5s ease-in-out infinite;
}

.slp-fx-none .slp-story-emoji {
  animation: slpEmojiFloat 4.5s ease-in-out infinite;
}

.slp-play .slp-fx-rise .slp-story-emoji {
  animation: slpFxRise 1.5s cubic-bezier(0.22, 1, 0.36, 1) both;
}

.slp-play .slp-fx-fall .slp-story-emoji {
  animation: slpFxFall 1.3s cubic-bezier(0.5, 0, 0.6, 1) both;
}

.slp-play .slp-fx-shake .slp-story-emoji {
  animation: slpFxShake 0.9s ease-in-out 0.4s both;
}

@keyframes slpFxPan {

  0%,
  100% {
    transform: translateX(-16px);
  }

  50% {
    transform: translateX(16px);
  }
}

@keyframes slpFxRise {
  from {
    transform: translateY(42px) scale(0.85);
    opacity: 0;
  }

  to {
    transform: translateY(0) scale(1);
    opacity: 1;
  }
}

@keyframes slpFxFall {
  from {
    transform: translateY(-46px) rotate(-6deg);
    opacity: 0;
  }

  60% {
    transform: translateY(8px) rotate(2deg);
    opacity: 1;
  }

  100% {
    transform: translateY(0) rotate(0deg);
    opacity: 1;
  }
}

@keyframes slpFxShake {

  0%,
  100% {
    transform: translateX(0);
  }

  20% {
    transform: translateX(-9px) rotate(-2deg);
  }

  40% {
    transform: translateX(8px) rotate(2deg);
  }

  60% {
    transform: translateX(-6px);
  }

  80% {
    transform: translateX(4px);
  }
}

/* ---------- context panel (question + tap-reveals) ---------- */
.slp-context {
  background: var(--surface);
}

.slp-context-q {
  margin: 0;
  font-family: var(--font-title);
  font-size: 1.3125rem;
  line-height: 1.4;
  font-weight: 700;
  color: var(--text-main);
  max-width: 26ch;
  text-align: left;
}

.slp-points {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.slp-point {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 14px;
  text-align: left;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--ep-fg, var(--text-main));
  font-family: var(--font-sans);
  padding: 13px 16px;
  cursor: pointer;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.15);
  backdrop-filter: blur(12px);
  transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.slp-point:hover {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.28);
  transform: translateY(-2px);
}

.slp-point:active {
  transform: scale(0.985);
}

.slp-point-emoji {
  font-size: 1.625rem;
  line-height: 1;
  flex: 0 0 auto;
}

.slp-point-emoji .k-icon {
  width: 24px;
  height: 24px;
}

.slp-point-text {
  display: none;
  font-size: 0.96875rem;
  font-weight: 500;
  line-height: 1.45;
  color: var(--ep-fg, #fff);
}

.slp-point-tap {
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.3px;
  color: var(--ep-fg, #ffffff);
  opacity: 0.85;
}

.slp-point.slp-point-open {
  border-color: rgba(255, 255, 255, 0.35);
  background: color-mix(in srgb, var(--ep-bg) 45%, rgba(255, 255, 255, 0.16));
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.22);
  cursor: default;
  transform: none;
}

.slp-point.slp-point-open .slp-point-text {
  display: block;
  animation: slpFadeUp 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

.slp-point.slp-point-open .slp-point-tap {
  display: none;
}

.slp-closer {
  width: 100%;
  font-family: var(--font-sans);
  font-size: 1.03125rem;
  font-weight: 600;
  line-height: 1.45;
  text-align: left;
  color: var(--ep-fg, #ffffff) !important;
  background: color-mix(in srgb, var(--ep-bg, var(--surface)) 62%, rgba(255, 255, 255, 0.14)) !important;
  border: 1px solid rgba(255, 255, 255, 0.28) !important;
  border-radius: 16px !important;
  padding: 14px 18px !important;
  backdrop-filter: blur(16px);
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.22) !important;
  margin-top: 10px;
  animation: slpFadeUp 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}

/* ---------- character introduction ---------- */
.slp-charintro {
  background: var(--surface);
}

.slp-char-epithet,
.slp-has-palette .slp-char-epithet {
  background: var(--ep-accent, var(--brand-primary, #F85E00)) !important;
  color: #ffffff !important;
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 6px 16px;
  border-radius: 999px;
  display: inline-block;
  margin: 6px auto 16px;
  text-align: center;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.22);
}

.slp-char-role {
  margin: 0;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--text-main);
  max-width: 32ch;
  text-align: left;
}

.slp-char-why {
  display: flex;
  align-items: center;
  gap: 8px;
  text-align: left;
  background: var(--brand-primary-light);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 12px 16px;
  font-size: 0.90625rem;
  font-weight: 500;
  line-height: 1.5;
  color: var(--text-main);
  max-width: 100%;
}

.slp-char-why .material-symbols-rounded {
  font-size: 1.25rem;
  color: var(--brand-primary);
  flex: 0 0 auto;
}

.slp-char-why .k-icon {
  width: 18px;
  height: 18px;
  color: var(--brand-primary);
  flex: 0 0 auto;
}

/* ---------- picture quiz (2x2 grid of flat cards) ---------- */
.slp-pquiz {
  background: var(--surface);
}

.slp-pquiz-grid {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.slp-pquiz-opt {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 18px;
  background: rgba(255, 255, 255, 0.08);
  padding: 18px 10px 14px;
  cursor: pointer;
  color: var(--ep-fg, var(--text-main));
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.15);
  backdrop-filter: blur(12px);
  transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.slp-pquiz-opt:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.3);
  transform: translateY(-3px);
}

.slp-pquiz-opt:active:not(:disabled) {
  transform: scale(0.96);
}

.slp-pquiz-opt.selected {
  border-color: var(--brand-primary);
  background: var(--brand-primary-light);
}

.slp-pquiz-opt .slp-chip-circle {
  width: 68px;
  height: 68px;
}

.slp-pquiz-opt .slp-chip-emoji {
  font-size: 1.75rem;
}

.slp-pquiz-opt .slp-chip-name {
  font-size: 0.875rem;
  font-weight: 600;
}

/* correct: others fade, chosen gets golden glow */
.slp-pquiz-grid.slp-solved .slp-pquiz-opt {
  pointer-events: none;
}

.slp-pquiz-grid.slp-solved .slp-pquiz-opt:not(.slp-hit) {
  opacity: 0.3;
  filter: grayscale(0.65);
  transform: scale(0.96);
}

.slp-pquiz-opt.slp-hit {
  border-color: var(--ep-accent, #FC9E4F);
  background: color-mix(in srgb, var(--ep-bg) 40%, rgba(255, 255, 255, 0.18));
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35), 0 0 0 3px color-mix(in srgb, var(--ep-accent, #FC9E4F) 50%, transparent);
  animation: slpWarmPop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.slp-pquiz-opt.slp-hit .slp-chip-circle {
  transform: scale(1.08);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
}

.slp-pquiz-opt.slp-hit .slp-chip-name {
  color: var(--ep-pop, var(--ep-accent, #FC9E4F));
  animation: slpNameRise 0.55s cubic-bezier(0.22, 1, 0.36, 1) 0.15s both;
}

@keyframes slpWarmPop {
  0% {
    transform: scale(1);
  }

  45% {
    transform: scale(1.04);
  }

  100% {
    transform: scale(1);
  }
}

@keyframes slpNameRise {
  from {
    transform: translateY(8px);
    opacity: 0;
  }

  to {
    transform: translateY(0);
    opacity: 1;
  }
}

/* warm wrong: gentle shake then fade back */
.slp-miss {
  animation: slpWarmShake 0.5s ease;
}

.slp-faded {
  opacity: 0.35;
  filter: grayscale(0.5);
}

@keyframes slpWarmShake {

  0%,
  100% {
    transform: translateX(0);
  }

  22% {
    transform: translateX(-7px);
  }

  44% {
    transform: translateX(6px);
  }

  66% {
    transform: translateX(-4px);
  }

  84% {
    transform: translateX(2px);
  }
}

.slp-hint {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  text-align: left;
  background: var(--surface-alt);
  border: 1px dashed var(--border);
  border-radius: 12px;
  padding: 12px 16px;
  font-size: 0.90625rem;
  font-weight: 500;
  line-height: 1.5;
  color: var(--text-main);
  animation: slpFadeUp 0.35s ease;
}

.slp-hint .material-symbols-rounded {
  font-size: 1.25rem;
  color: var(--brand-primary);
  flex: 0 0 auto;
}

.slp-hint .k-icon {
  width: 18px;
  height: 18px;
  color: var(--brand-primary);
  flex: 0 0 auto;
}

/* class display values must not defeat the `hidden` attribute */
.slp-hint[hidden],
.slp-stage-next[hidden],
.slp-gate-note[hidden] {
  display: none;
}

.slp-has-palette .slp-feedback,
.slp-has-palette .slp-reinforce {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(12px);
}

.slp-reinforce {
  width: 100%;
  background: var(--brand-primary-light);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 13px 17px;
  font-size: 0.9375rem;
  font-weight: 500;
  line-height: 1.55;
  text-align: left;
  color: var(--text-main);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.05);
  margin-top: 32px;
  animation: slpReinforcePop 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

@keyframes slpReinforcePop {
  0% { transform: translateY(12px); opacity: 0; }
  100% { transform: translateY(0); opacity: 1; }
}
/* Same slot, different read: a miss has to be distinguishable at a glance from
   the explanation you get for being right, or the box just looks like it
   appeared for no reason. */
.slp-reinforce.slp-reinforce-miss {
  background: color-mix(in srgb, #E5484D 12%, transparent);
  border-color: color-mix(in srgb, #E5484D 45%, transparent);
}

/* ---------- quick check (mcq / tf / fill word-chips) ---------- */
.slp-qcheck {
  background: var(--surface);
}

.slp-qc-opts {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.slp-qc-opts.slp-qc-tf {
  flex-direction: row;
}

.slp-qc-opt {
  flex: 1;
  width: 100%;
  text-align: left;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--ep-fg, var(--text-main));
  font-family: var(--font-sans);
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.5;
  padding: 16px 18px;
  cursor: pointer;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.15);
  backdrop-filter: blur(12px);
  transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.slp-qc-opt:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.3);
  transform: translateY(-2px);
}

.slp-qc-opts.slp-qc-tf .slp-qc-opt {
  text-align: center;
  font-size: 1rem;
  font-weight: 600;
}

.slp-qc-opt:active:not(:disabled) {
  transform: scale(0.985);
}

.slp-qc-opt.selected {
  border-color: var(--brand-primary);
  background: var(--brand-primary-light);
}

.slp-qc-opt:disabled {
  cursor: default;
}

.slp-qc-opt.slp-hit-opt {
  border-color: var(--ep-accent, #FC9E4F);
  background: color-mix(in srgb, var(--ep-bg) 40%, rgba(255, 255, 255, 0.18));
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35), 0 0 0 3px color-mix(in srgb, var(--ep-accent, #FC9E4F) 50%, transparent);
  color: var(--ep-fg, #fff);
  animation: slpWarmPop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.slp-fill-q {
  text-align: left;
}

.slp-fill-q .slp-blank {
  display: inline-block;
  min-width: 84px;
  border-bottom: 2px solid var(--ep-pop, var(--ep-accent, var(--brand-primary)));
  color: var(--ep-pop, var(--ep-accent, var(--brand-primary)));
  font-weight: 700;
  padding: 0 6px 2px;
  transition: background-color 0.3s ease;
}

.slp-fill-q .slp-blank.slp-blank-filled {
  background: color-mix(in srgb, var(--ep-bg) 40%, rgba(255, 255, 255, 0.14));
  border-radius: 8px 8px 0 0;
  animation: slpWarmPop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.slp-words {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: flex-start;
  margin-top: 24px;
}

.slp-word {
  border: 1.5px solid rgba(255, 255, 255, 0.24);
  border-radius: 999px;
  background: color-mix(in srgb, var(--ep-bg, var(--surface)) 35%, rgba(255, 255, 255, 0.16));
  color: var(--ep-fg, #ffffff) !important;
  font-family: var(--font-sans);
  font-size: 1.03125rem;
  font-weight: 700;
  padding: 14px 26px;
  cursor: pointer;
  backdrop-filter: blur(14px);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
  transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.slp-word:hover:not(:disabled) {
  background: color-mix(in srgb, var(--ep-bg, var(--surface)) 25%, rgba(255, 255, 255, 0.26));
  border-color: var(--ep-accent, #F85E00);
  transform: translateY(-3px);
}

.slp-word:active:not(:disabled) {
  transform: scale(0.97);
}

.slp-word:disabled {
  cursor: default;
}

.slp-word.slp-hit-chip {
  border-color: var(--ep-accent, #FC9E4F);
  background: color-mix(in srgb, var(--ep-bg) 40%, rgba(255, 255, 255, 0.18));
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.3), 0 0 0 2px color-mix(in srgb, var(--ep-accent, #FC9E4F) 50%, transparent);
  color: var(--ep-fg, #fff);
  animation: slpWarmPop 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ---------- family / relationship (progressive stages) ---------- */
.slp-family {
  background: var(--surface);
}

.slp-stages {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* The flat `nodes` variant of the family panel. Same card language as
   .slp-stage but shown all at once rather than revealed a branch at a time,
   because a flat list has no branches to step through. See renderFamily. */
.slp-family-list {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.slp-family-node {
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 14px;
  padding: 13px 16px;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--ep-fg, #fff);
  text-align: left;
  backdrop-filter: blur(12px);
}

.slp-stage {
  display: none;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 18px;
  padding: 18px 16px;
  backdrop-filter: blur(12px);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.18);
}

.slp-stage.slp-stage-on {
  display: flex;
  animation: slpFadeUp 0.45s cubic-bezier(0.16, 1, 0.3, 1);
}

.slp-stage-parent {
  font-family: var(--font-title);
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--ep-fg, #fff);
  background: color-mix(in srgb, var(--ep-accent, var(--brand-primary)) 22%, transparent);
  border: 1px solid color-mix(in srgb, var(--ep-accent, var(--brand-primary)) 45%, transparent);
  border-radius: 12px;
  padding: 8px 18px;
}

.slp-stage-arrow {
  font-size: 0.75rem;
  color: var(--ep-fg, #ffffff);
  opacity: 0.65;
  line-height: 1;
}

.slp-stage-kids {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: center;
}

.slp-kid {
  font-size: 0.90625rem;
  font-weight: 600;
  color: var(--ep-fg, #fff);
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 12px;
  padding: 8px 14px;
  backdrop-filter: blur(8px);
}

.slp-stage-note {
  font-size: 0.84375rem;
  font-style: normal;
  line-height: 1.55;
  color: var(--ep-fg, rgba(255, 255, 255, 0.8));
  max-width: 36ch;
  text-align: center;
}

.slp-stage-next {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--ep-pop, var(--ep-accent, var(--brand-primary)));
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.1);
  color: var(--ep-pop, var(--ep-accent, var(--brand-primary)));
  font-family: var(--font-sans);
  font-size: 0.90625rem;
  font-weight: 600;
  padding: 11px 18px;
  cursor: pointer;
  backdrop-filter: blur(12px);
  transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.slp-stage-next:hover {
  background: rgba(255, 255, 255, 0.18);
  transform: translateY(-2px);
}

.slp-stage-next:active {
  transform: scale(0.97);
}

.slp-stage-next .material-symbols-rounded {
  font-size: 1.25rem;
}

.slp-stage-next .k-icon {
  width: 18px;
  height: 18px;
}

/* ---------- map / world (places light in sequence) ---------- */
.slp-map {
  background: var(--indigo);
  color: #EFF1F0;
}

.slp-map-trail {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 4px;
  position: relative;
  padding-left: 8px;
}

.slp-map-step {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  text-align: left;
  padding: 10px 0;
  position: relative;
  opacity: 0.22;
}

.slp-map-step::before {
  /* the connecting route */
  content: '';
  position: absolute;
  left: 8px;
  top: 30px;
  bottom: -14px;
  width: 2px;
  background: rgba(232, 137, 28, 0.4);
}

.slp-map-step:last-child::before {
  display: none;
}

.slp-play .slp-map-step {
  animation: slpMapLight 0.9s ease forwards;
}

@keyframes slpMapLight {
  from {
    opacity: 0.22;
    transform: translateX(-6px);
  }

  to {
    opacity: 1;
    transform: translateX(0);
  }
}

.slp-map-dot {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin-top: 3px;
  border-radius: 99px;
  background: var(--brand-primary);
  box-shadow: none;
}

.slp-map-place {
  font-family: var(--font-title);
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--brand-primary);
}

.slp-map-text {
  font-size: 0.90625rem;
  line-height: 1.55;
  color: rgba(236, 236, 240, 0.86);
  max-width: 36ch;
}

.slp-map-closer {
  opacity: 0;
  margin-top: 18px;
}

.slp-play .slp-map-closer {
  animation: slpFadeUp 0.8s ease forwards;
}

/* ---------- explore (hotspot chips, minTaps gate) ---------- */
.slp-explore {
  background: var(--surface);
}

.slp-explore-scene {
  display: none !important;
}

.slp-explore-emoji {
  font-size: 3.75rem;
  line-height: 1;
  animation: slpEmojiFloat 4.5s ease-in-out infinite;
}

.slp-spots {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  width: 100%;
  margin-top: 12px;
}

.slp-spot {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
  width: 100%;
  min-height: 54px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 14px;
  background: color-mix(in srgb, var(--ep-bg) 40%, rgba(255, 255, 255, 0.1));
  color: var(--ep-fg, #ffffff);
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  font-weight: 600;
  padding: 14px 18px;
  cursor: pointer;
  backdrop-filter: blur(14px);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
  transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
  text-align: left;
}

.slp-spot:last-child:nth-child(odd) {
  grid-column: 1 / -1;
}

.slp-spot:hover {
  background: color-mix(in srgb, var(--ep-bg) 30%, rgba(255, 255, 255, 0.16));
  border-color: rgba(255, 255, 255, 0.35);
  transform: translateY(-2px);
}

.slp-spot:active {
  transform: scale(0.98);
}

.slp-spot.slp-spot-seen {
  border-color: rgba(255, 255, 255, 0.38);
}

.slp-spot.slp-spot-active {
  border-color: rgba(255, 255, 255, 0.5);
  background: color-mix(in srgb, var(--ep-bg) 30%, rgba(255, 255, 255, 0.22));
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.25);
  color: #fff;
}

.slp-spot-out {
  width: 100%;
  background: color-mix(in srgb, var(--ep-bg) 40%, rgba(255, 255, 255, 0.12));
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 16px;
  padding: 16px 20px;
  font-size: 0.9375rem;
  line-height: 1.6;
  text-align: left;
  color: var(--ep-fg, var(--text-main));
  backdrop-filter: blur(12px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.2);
  animation: slpFadeUp 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

.slp-spot-count {
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.3px;
  color: var(--ep-fg, #ffffff);
  opacity: 0.85;
}

/* ---------- reveal panel (darkened → drawn back) ---------- */
.slp-secret {
  background: var(--ep-bg, var(--indigo));
  color: var(--ep-fg, #EFF1F0);
}

.slp-secret .slp-chip-name {
  color: var(--ep-fg, rgba(236, 236, 240, 0.85));
}

.slp-secret-chip {
  filter: grayscale(0.85) brightness(0.6);
  transition: filter 1s ease;
}

.slp-secret.slp-revealed .slp-secret-chip {
  filter: none;
}

.slp-secret-teaser {
  margin: 0;
  font-family: var(--font-title);
  font-size: 1.5rem;
  line-height: 1.45;
  font-weight: 700;
  font-style: normal;
  max-width: 24ch;
  text-align: left;
  color: var(--ep-fg, rgba(236, 236, 240, 0.94));
}

.slp-secret-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--ep-pop, var(--ep-accent, var(--brand-primary)));
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.12);
  color: var(--ep-pop, var(--ep-accent, var(--brand-primary)));
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  font-weight: 600;
  padding: 12px 22px;
  cursor: pointer;
  backdrop-filter: blur(12px);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.2);
  transition: all 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.slp-secret-btn:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: translateY(-2px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.3);
}

.slp-secret-btn:active {
  transform: scale(0.97);
}

.slp-secret-btn .material-symbols-rounded {
  font-size: 1.25rem;
}

.slp-secret-btn .k-icon {
  width: 18px;
  height: 18px;
}

.slp-secret.slp-revealed .slp-secret-btn {
  opacity: 0;
  pointer-events: none;
}

.slp-secret-hidden,
.slp-secret-after {
  display: none;
  margin: 0;
}

.slp-secret.slp-revealed .slp-secret-hidden {
  display: block;
  font-family: var(--font-title);
  font-size: 1.625rem;
  line-height: 1.4;
  font-weight: 700;
  font-style: normal;
  max-width: 24ch;
  text-align: left;
  color: var(--ep-pop, var(--ep-accent, var(--brand-primary)));
  text-shadow: 0 0 26px var(--ep-pop-glow, transparent);
  animation: slpSecretIn 1.1s cubic-bezier(0.22, 1, 0.36, 1);
}

.slp-secret.slp-revealed .slp-secret-after {
  display: block;
  font-size: 0.9375rem;
  line-height: 1.6;
  color: rgba(236, 236, 240, 0.8);
  max-width: 30ch;
  text-align: left;
  animation: slpFadeUp 0.8s ease 0.7s both;
}

@keyframes slpSecretIn {
  from {
    opacity: 0;
    transform: scale(0.96);
  }

  to {
    opacity: 1;
    transform: scale(1);
  }
}

/* ---------- major moment (the interface slows down; flat) ---------- */
.slp-moment {
  background: var(--indigo);
  color: #EFF1F0;
}

.slp-moment .slp-beat-inner {
  gap: 22px;
}

.slp-moment-visual {
  display: none !important;
}

.slp-moment-line {
  margin: 0;
  font-size: 1.125rem;
  line-height: 1.7;
  font-style: normal;
  color: rgba(236, 236, 240, 0.72);
  max-width: 30ch;
  text-align: left;
  opacity: 0;
}

.slp-moment-final {
  margin: 0;
  font-family: var(--font-title);
  font-size: 1.6875rem;
  line-height: 1.4;
  font-weight: 700;
  font-style: normal;
  color: #EFF1F0;
  max-width: 20ch;
  text-align: left;
  opacity: 0;
}

.slp-play .slp-moment-line {
  animation: slpMomentIn 1.6s ease forwards;
}

.slp-play .slp-moment-final {
  animation: slpMomentIn 2s ease forwards;
}

@keyframes slpMomentIn {
  from {
    opacity: 0;
    transform: translateY(14px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Continue stays away until the moment has landed (~2s after the last line) */
.slp-moment .slp-beat-actions {
  opacity: 0;
  pointer-events: none;
  transition: opacity 1.4s ease;
}

.slp-moment.slp-moment-ready .slp-beat-actions {
  opacity: 1;
  pointer-events: auto;
}

/* ---------- meaning (progressive simple lines) ---------- */
.slp-meaning {
  background: var(--ep-bg, var(--surface));
  color: var(--ep-fg, var(--text-main));
}

.slp-meaning-q {
  margin: 0;
  font-family: var(--font-title);
  font-size: 1.375rem;
  line-height: 1.45;
  font-weight: 700;
  color: var(--ep-pop, var(--ep-accent, var(--brand-primary)));
  max-width: 26ch;
  text-align: left;
}

.slp-meaning-line {
  margin: 0;
  font-size: 1.0625rem;
  line-height: 1.65;
  font-weight: 500;
  color: var(--ep-fg, var(--text-main));
  max-width: 32ch;
  text-align: left;
  opacity: 0;
  position: relative;
  padding-top: 14px;
}

.slp-meaning-line::before {
  content: '↓';
  display: block;
  font-size: 0.8125rem;
  color: var(--ep-pop, var(--ep-accent, var(--text-muted)));
  margin-bottom: 6px;
}

.slp-meaning-line:first-of-type::before {
  content: none;
}

.slp-play .slp-meaning-line {
  animation: slpMomentIn 1.1s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

/* ---------- moral (full-screen, minimal, painterly) ---------- */
.slp-moral {
  background: var(--ep-bg, var(--indigo));
  color: var(--ep-fg, #EFF1F0);
}

.slp-moral .slp-beat-inner {
  gap: 24px;
}

.slp-moral-mark {
  display: none !important;
}

.slp-moral-line {
  margin: 0;
  font-family: var(--font-title);
  font-size: 1.625rem;
  line-height: 1.45;
  font-weight: 700;
  font-style: normal;
  color: var(--ep-fg, rgba(236, 236, 240, 0.96));
  max-width: 24ch;
  text-align: left;
  opacity: 0;
}

.slp-play .slp-moral-line {
  animation: slpMomentIn 2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.slp-moral-explain {
  margin: 0;
  font-size: 0.96875rem;
  line-height: 1.65;
  color: var(--ep-fg, rgba(236, 236, 240, 0.75));
  max-width: 32ch;
  text-align: left;
  opacity: 0;
}

.slp-play .slp-moral-explain {
  animation: slpMomentIn 1.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}

.slp-complete .slp-complete-title {
  transition: opacity 0.5s ease, filter 0.5s ease;
}

/* ---------- motion sensitivity ---------- */
@media (prefers-reduced-motion: reduce) {

  .slp-overlay,
  .slp-flip-inner,
  .slp-continue,
  .slp-seg {
    transition: none;
  }

  .slp-scene-emoji,
  .slp-mayu-avatar,
  .slp-die.slp-rolling,
  .slp-story-emoji,
  .slp-explore-emoji,
  .slp-pquiz-opt.slp-hit,
  .slp-miss {
    animation: none;
  }

  .slp-complete-rays {
    animation: none;
  }

  /* staggered entrances become instant appearances */
  .slp-play .slp-fx-rise .slp-story-emoji,
  .slp-play .slp-fx-fall .slp-story-emoji,
  .slp-play .slp-fx-shake .slp-story-emoji {
    animation: none;
  }

  .slp-map-step,
  .slp-map-closer,
  .slp-moment-visual,
  .slp-moment-line,
  .slp-moment-final,
  .slp-meaning-line,
  .slp-moral-mark,
  .slp-moral-line,
  .slp-moral-explain {
    animation: none !important;
    opacity: 1;
    transform: none;
  }
}

/* ------------- hidden progress + scroll-hint continue (founder 2026-07-17) ------------- */

/* The learner never sees lesson progress; close + mute float alone. */
.slp-progress {
  display: none;
}

.slp-top {
  background: transparent;
}

/* Subtle bouncing down-chevron in place of the Continue button. Inherits the
   card's text color so it reads on dark scene cards and light quiz cards alike. */
.slp-continue.slp-scroll-hint {
  background: transparent;
  border: none;
  box-shadow: none;
  color: inherit;
  opacity: 0.45;
  width: 48px;
  height: 44px;
  min-height: 0;
  padding: 0;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  animation: slpHintBounce 2.4s ease-in-out infinite;
}

.slp-continue.slp-scroll-hint:hover,
.slp-continue.slp-scroll-hint:active {
  background: transparent;
  color: inherit;
  transform: none;
  opacity: 0.8;
}

/* Was opacity:0 — fully invisible until the gate cleared (all 3 context
   points opened, a quiz answered, etc.), which on a beat whose content also
   overflows into its own scroll reads as "there is no way forward here at
   all," not just "not yet." Dimmed-but-visible instead: still not
   clickable until the interaction actually completes (the point of gating
   a quiz or a context beat), but always a visible landmark at the bottom
   of the screen rather than a blank gap someone has to discover by
   fighting the scroll. */
.slp-continue.slp-scroll-hint:disabled {
  opacity: 0.25;
  pointer-events: none;
}

@keyframes slpHintBounce {

  0%,
  100% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(6px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .slp-continue.slp-scroll-hint {
    animation: none;
  }
}

/* Quiz check landed (drag past threshold, or a plain tap — see wireQuiz's
   runCheck): the chevron becomes a correct/cancel glyph, popped in. Wins
   over the idle bounce (same element, still carries .slp-scroll-hint for
   layout) with !important since a stray inline style.animation from
   mid-drag could otherwise linger. */
.slp-continue.slp-quiz-checked {
  animation: none !important;
  opacity: 1 !important;
  transform: none !important;
  pointer-events: none;
}
.slp-continue.slp-quiz-checked .material-symbols-rounded {
  display: inline-block;
  animation: slpQuizCheckPop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.slp-continue.slp-quiz-checked.is-correct { color: var(--success, #06D6A0); }
.slp-continue.slp-quiz-checked.is-wrong { color: #D64545; }
@keyframes slpQuizCheckPop {
  0% { transform: scale(0.3); opacity: 0; }
  65% { transform: scale(1.2); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .slp-continue.slp-quiz-checked .material-symbols-rounded { animation: none; }
}

/* With the progress strip hidden, keep close left / mute right. */
.slp-top {
  justify-content: space-between;
}

/* ---------- daily-dose gate (soft goal popup) ----------
   Slides up over the current card when the daily swipe budget is reached.
   Flat, saffron accent, one dismiss + one continue. Never a hard wall. */
.slp-dose {
  position: absolute;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 20px;
  background: rgba(20, 18, 34, 0);
  transition: background 0.26s ease;
  pointer-events: none;
}

.slp-dose.slp-dose-in {
  background: rgba(20, 18, 34, 0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  pointer-events: auto;
}

.slp-dose-card {
  width: 100%;
  max-width: 420px;
  background: var(--surface, #fff);
  color: var(--text-main);
  border-radius: 22px;
  padding: 26px 22px 20px;
  text-align: center;
  transform: translateY(24px);
  opacity: 0;
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.28s ease;
}

.slp-dose.slp-dose-in .slp-dose-card {
  transform: translateY(0);
  opacity: 1;
}

.slp-dose-mark {
  width: 52px;
  height: 52px;
  margin: 0 auto 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(232, 137, 28, 0.14);
  color: var(--brand-primary);
}

.slp-dose-title {
  margin: 0 0 8px;
  font-family: var(--font-sans);
  font-size: 1.1875rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.slp-dose-sub {
  margin: 0 0 20px;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--text-muted, rgba(29, 27, 46, 0.66));
}

.slp-dose-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.slp-dose-more {
  border: 0;
  border-radius: var(--radius-round, 99px);
  padding: 13px 18px;
  background: var(--brand-primary);
  color: #fff;
  font-family: var(--font-sans);
  font-size: 0.9375rem;
  font-weight: 600;
  cursor: pointer;
}

.slp-dose-more:hover {
  background: var(--brand-primary-shadow);
}

.slp-dose-more:active {
  background: var(--brand-primary-shadow);
  transform: scale(0.985);
}

.slp-dose-stop {
  border: 0;
  background: none;
  padding: 8px;
  color: var(--text-muted, rgba(29, 27, 46, 0.6));
  font-family: var(--font-sans);
  font-size: 0.875rem;
  font-weight: 500;
  cursor: pointer;
}

.slp-dose-stop:hover {
  color: var(--text-main);
}

@media (prefers-reduced-motion: reduce) {

  .slp-dose,
  .slp-dose-card {
    transition: opacity 0.2s ease;
    transform: none;
  }
}

/* ============================================================
   PER-EPISODE PALETTE (visual-language overhaul, 2026-07-18)
   lesson-player.js sets --ep-bg / --ep-accent / --ep-muted /
   --ep-surface / --ep-fg on .slp-overlay from episode.palette.
   Every rule falls back to the old flat tokens when the episode
   has no palette (legacy courses, other spines).
   Text on DARK full-color panels uses --ep-fg (white, or navy on a
   cream primary) rather than --ep-muted, which is reserved for the
   light --ep-surface panels where a primary-tinted ink is readable.
   ============================================================ */

/* ---------- story panel ---------- */
.slp-story {
  background: var(--ep-bg, var(--indigo));
  color: var(--ep-fg, #EFF1F0);
}

.slp-story .slp-scene-caption {
  font-size: 0.8125rem;
  font-style: italic;
  color: var(--ep-fg, rgba(236, 236, 240, 0.62));
  opacity: 0.62;
}

.slp-story-line {
  font-size: 1.5rem;
  font-weight: 700;
  max-width: 20ch;
  color: var(--ep-fg, rgba(236, 236, 240, 0.96));
}
/* Longer copy gets smaller type and a wider measure, so the text block stays
   under roughly 340px and the artwork behind it survives. See lenClass() in
   lesson-player.js for the bands and why they are where they are. A 336
   character beat goes from about 550px of text to about 333px. */
.slp-story-line.is-len-md { font-size: 1.3125rem; max-width: 23ch; }
.slp-story-line.is-len-lg { font-size: 1.1875rem; max-width: 26ch; line-height: 1.42; }
.slp-story-line.is-len-xl { font-size: 1.0625rem; max-width: 29ch; line-height: 1.44; }

.slp-story .slp-chip-name {
  color: var(--ep-fg, rgba(236, 236, 240, 0.85));
  opacity: 0.85;
}

.slp-story .slp-story-visual .k-icon-tile {
  color: var(--ep-fg, #EFF1F0);
}

/* image mode: full-bleed art fading into the episode color (dormant
   until visual.imageUrl lands in the data) */
.slp-story-imgmode {
  position: relative;
}

.slp-story-imgmode .slp-story-visual {
  display: none !important;
}

.slp-story-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center top;
  z-index: 0;
}

.slp-story-bg-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  z-index: 0;
  display: block;
}

/* Scene backdrop for the non-story panels (context / explore / meaning / moral
   / moment / reveal / quickCheck / map / family). Reuses the scene the reader
   is already in — see sceneBackdropHtml in lesson-player.js. The scrim is
   heavier than .slp-story-bg-fade's because these panels are a screenful of
   body copy rather than one or two lines, and body copy needs a much quieter
   field behind it than a headline does. */
.slp-scene-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
}
.slp-scene-bg .slp-story-bg-img {
  /* Pushed back so it reads as atmosphere, not as a picture competing with the
     text sitting on it — but only just far enough. An earlier pass used
     brightness(0.5) under a 72/82/92% scrim and the scene was so faint it was
     hard to tell the backdrop had been added at all. */
  filter: saturate(0.85) brightness(0.62);
  transform: scale(1.04);
}
.slp-scene-bg-scrim {
  position: absolute;
  inset: 0;
  /* Ramps down the panel rather than sitting flat: the top is left open so the
     scene is legible behind the heading, and it thickens toward the bottom
     where the body copy lands. That is why the text stays readable at only
     48% at the top. */
  background:
    linear-gradient(to bottom,
      color-mix(in srgb, var(--ep-bg, var(--indigo)) 48%, transparent) 0%,
      color-mix(in srgb, var(--ep-bg, var(--indigo)) 62%, transparent) 45%,
      color-mix(in srgb, var(--ep-bg, var(--indigo)) 80%, transparent) 100%);
}
/* Lift the panel's own content above the backdrop. */
.slp-beat.slp-has-scene-bg > .slp-beat-scroll,
.slp-beat.slp-has-scene-bg > .slp-continue,
.slp-beat.slp-has-scene-bg > .slp-top {
  position: relative;
  z-index: 2;
}

.slp-story-bg-fade {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(to bottom,
      transparent 0%,
      rgba(0, 0, 0, 0.25) 45%,
      rgba(0, 0, 0, 0.82) 75%,
      var(--ep-bg, var(--indigo)) 100%);
  pointer-events: none;
}

.slp-story-imgmode.slp-beat {
  padding: calc(max(40px, env(safe-area-inset-top)) + 12px) 24px calc(14px + env(safe-area-inset-bottom));
}

.slp-story-imgmode .slp-beat-scroll,
.slp-story-imgmode .slp-beat-actions {
  position: relative;
  z-index: 1;
}

.slp-story-imgmode .slp-story-top-chips {
  margin-bottom: auto;
  padding-bottom: 8px;
}

.slp-story-imgmode .slp-beat-inner {
  margin-top: auto;
  margin-bottom: 0;
  padding: 0 0 4px;
  gap: 10px;
}

.slp-story-imgmode .slp-beat-actions {
  padding-top: 10px;
}

/* placeholder painting: until real art lands, palette episodes get a
   painterly color-field built from the episode's 4 colors (sky glow up
   top, color masses at the sides) fading into --ep-bg for the text. */
.slp-has-palette .slp-story:not(.slp-story-imgmode) {
  background:
    linear-gradient(to bottom, transparent 0%, transparent 52%,
      color-mix(in srgb, var(--ep-bg) 82%, black) 100%),
    radial-gradient(90% 55% at 50% -6%,
      color-mix(in srgb, #EFF1F0 88%, var(--ep-bg)) 0%, transparent 62%),
    radial-gradient(70% 60% at -12% 34%,
      color-mix(in srgb, var(--ep-secondary, var(--ep-bg)) 82%, black) 0%, transparent 58%),
    radial-gradient(64% 52% at 112% 44%,
      color-mix(in srgb, var(--ep-secondary, var(--ep-bg)) 68%, #EFF1F0) 0%, transparent 55%),
    radial-gradient(80% 46% at 50% 106%,
      color-mix(in srgb, var(--ep-base, var(--ep-bg)) 55%, var(--ep-bg)) 0%, transparent 70%),
    var(--ep-bg, var(--indigo));
}

.slp-has-palette .slp-story:not(.slp-story-imgmode) .slp-beat-inner {
  margin-top: auto;
  margin-bottom: 0;
}

.slp-has-palette .slp-story:not(.slp-story-imgmode) .slp-story-visual {
  display: none;
  /* the color field IS the visual; no emoji tile on top */
}

.slp-has-palette .slp-story .slp-scene-caption {
  font-style: normal;
  opacity: 0.72;
}

.slp-has-palette .slp-story .slp-story-line {
  font-size: 1.625rem;
  text-shadow: 0 1px 14px color-mix(in srgb, var(--ep-bg) 55%, transparent);
}

/* ---------- character panel (deep color field + soft waves) ---------- */
.slp-charintro {
  background: var(--ep-bg, var(--surface));
  color: var(--ep-fg, var(--text-main));
}

/* palette episodes: darker field with two broad organic waves (top +
   bottom) in a deeper shade, like the art-directed mock */
.slp-has-palette .slp-charintro {
  background: color-mix(in srgb, var(--ep-bg) 72%, black);
  position: relative;
  overflow: hidden;
}

.slp-has-palette .slp-charintro::before,
.slp-has-palette .slp-charintro::after {
  content: '';
  position: absolute;
  left: -25%;
  width: 150%;
  height: 46%;
  background: color-mix(in srgb, var(--ep-bg) 58%, black);
  pointer-events: none;
  z-index: 0;
}

.slp-has-palette .slp-charintro::before {
  top: -22%;
  border-radius: 0 0 52% 48% / 0 0 100% 90%;
  transform: rotate(-4deg);
}

.slp-has-palette .slp-charintro::after {
  bottom: -24%;
  border-radius: 55% 45% 0 0 / 95% 100% 0 0;
  transform: rotate(3deg);
}

.slp-has-palette .slp-charintro .slp-beat-scroll,
.slp-has-palette .slp-charintro .slp-beat-actions {
  position: relative;
  z-index: 1;
}

/* portrait placeholder: painterly cream/mint disc behind the initial
   until char-{id}.webp art arrives */
.slp-has-palette .slp-charintro .slp-beat-inner {
  text-align: center;
  align-items: center;
}

.slp-has-palette .slp-charintro .slp-char-stage {
  justify-content: center;
}

.slp-has-palette .slp-charintro .slp-chip-lg,
.slp-charintro .slp-chip-lg {
  margin: 0 auto;
}

.slp-has-palette .slp-charintro .slp-chip-lg .slp-chip-circle,
.slp-charintro .slp-chip-lg .slp-chip-circle {
  width: 172px;
  height: 172px;
  border-radius: 999px !important;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.38) !important;
  border: 3px solid rgba(255, 255, 255, 0.12);
  overflow: hidden;
}

.slp-charintro .slp-chip-lg .slp-chip-circle .slp-chip-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* inline chip color needs !important; only recolor the initials disc,
   never a real portrait image */
.slp-has-palette .slp-charintro .slp-chip-lg .slp-chip-circle:not(:has(.slp-chip-img)) {
  background:
    radial-gradient(70% 70% at 30% 25%, #EFF1F0 0%, transparent 60%),
    radial-gradient(60% 60% at 78% 20%, color-mix(in srgb, var(--ep-secondary, var(--ep-bg)) 70%, #EFF1F0) 0%, transparent 55%),
    radial-gradient(75% 75% at 50% 90%, color-mix(in srgb, var(--ep-secondary, var(--ep-bg)) 85%, black) 0%, transparent 65%),
    #EFF1F0 !important;
  box-shadow: 0 10px 34px rgba(0, 0, 0, 0.28);
  color: var(--ep-fg, #ffffff);
}

.slp-has-palette .slp-charintro .slp-chip-lg .slp-chip-circle:not(:has(.slp-chip-img)) span {
  color: var(--ep-fg, #ffffff);
}

.slp-char-stage {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 26px 30px;
}

.slp-char-stage .slp-chip {
  position: relative;
  z-index: 1;
}

.slp-char-blobs {
  display: none !important;
}

/* waves replace the small blobs */
.slp-blob-1 {
  width: 190px;
  height: 190px;
  left: -8%;
  top: -6%;
  opacity: 0.15;
}

.slp-blob-2 {
  width: 140px;
  height: 140px;
  right: -12%;
  bottom: -10%;
  opacity: 0.25;
  animation: slpEmojiFloat 6s ease-in-out infinite;
}

.slp-blob-3 {
  width: 96px;
  height: 96px;
  right: 4%;
  top: -14%;
  opacity: 0.35;
  animation: slpEmojiFloat 7.5s ease-in-out 0.8s infinite;
}

@media (prefers-reduced-motion: reduce) {

  .slp-blob-2,
  .slp-blob-3 {
    animation: none;
  }
}

.slp-charintro .slp-chip-lg .slp-chip-name {
  display: none;
}

.slp-char-header {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin-top: 14px;
  margin-bottom: 4px;
}

.slp-char-title {
  font-family: var(--font-title);
  font-size: 2rem;
  font-weight: 700;
  color: var(--ep-fg, #ffffff);
  margin: 0;
  line-height: 1.15;
}

.slp-char-voice {
  width: auto;
  height: auto;
  border-radius: 0;
  border: none;
  background: transparent !important;
  color: var(--ep-fg, #ffffff);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 4px;
  opacity: 0.85;
  transition: transform 0.15s ease, opacity 0.15s ease;
}

.slp-char-voice:hover {
  opacity: 1;
}

.slp-char-voice:active {
  transform: scale(0.92);
}

.slp-char-voice .material-symbols-rounded,
.slp-char-voice .k-icon {
  font-size: 1.5rem;
  width: 24px;
  height: 24px;
}

.slp-charintro .slp-chip-name {
  display: none;
}

.slp-char-epithet,
.slp-has-palette .slp-char-epithet {
  background: var(--ep-accent, var(--brand-primary, #F85E00)) !important;
  color: #ffffff !important;
  font-size: 0.875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 6px 16px;
  border-radius: 999px;
  display: inline-block;
  margin: 6px auto 16px;
  text-align: center;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.22);
}

.slp-charintro .slp-char-role {
  background: transparent;
  color: #ffffff;
  padding: 0;
  border: none;
  box-shadow: none;
  opacity: 0.98;
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.55;
  max-width: 460px;
  margin: 0 auto 20px;
  text-align: center;
}

.slp-charintro .slp-char-why {
  background: var(--ep-surface, rgba(255, 255, 255, 0.12));
  border-color: color-mix(in srgb, var(--ep-fg, #ffffff) 25%, transparent);
  color: var(--ep-fg, var(--text-main));
  font-weight: 600;
}

.slp-charintro .slp-char-why .material-symbols-rounded,
.slp-charintro .slp-char-why .k-icon {
  color: var(--ep-pop, var(--ep-accent, var(--brand-primary)));
}

/* ---------- context panel (light tinted surface; dark ink) ---------- */
/* ---------- context panel (atmospheric color field) ---------- */
.slp-context {
  background: var(--ep-bg, var(--surface));
}

.slp-context .slp-point.slp-point-open {
  border: 1px solid rgba(255, 255, 255, 0.35);
  background: color-mix(in srgb, var(--ep-bg) 45%, rgba(255, 255, 255, 0.18));
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.25);
}

.slp-context .slp-context-q {
  color: var(--ep-fg, var(--text-main));
}

/* ---------- quiz panels: accent ring on the right answer ---------- */
.slp-pquiz-opt.slp-hit {
  border-color: var(--ep-accent, var(--brand-primary));
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35), 0 0 0 3px color-mix(in srgb, var(--ep-accent, var(--brand-primary)) 40%, transparent);
}

.slp-pquiz-opt.slp-hit .slp-chip-name {
  color: var(--ep-pop, var(--ep-accent, var(--brand-primary)));
}

.slp-qc-opt.slp-hit-opt {
  border-color: var(--ep-accent, var(--brand-primary));
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35), 0 0 0 3px color-mix(in srgb, var(--ep-accent, var(--brand-primary)) 40%, transparent);
}

.slp-warmup-tag {
  background: color-mix(in srgb, var(--ep-accent, var(--brand-primary)) 18%, transparent);
  color: var(--ep-pop, var(--ep-accent, var(--brand-primary)));
}

/* ---------- shared art treatment for ALL palette panels ----------
   Same language as the character and story panels: a deepened field with two broad
   organic waves, so every panel in the app reads as a cohesive painterly experience. */
.slp-has-palette .slp-context,
.slp-has-palette .slp-pquiz,
.slp-has-palette .slp-qcheck,
.slp-has-palette .slp-family,
.slp-has-palette .slp-explore,
.slp-has-palette .slp-meaning,
.slp-has-palette .slp-verse,
.slp-has-palette .slp-moment,
.slp-has-palette .slp-moral,
.slp-has-palette .slp-map,
.slp-has-palette .slp-secret,
.slp-has-palette .slp-scene,
.slp-has-palette .slp-complete,
.slp-has-palette .slp-interactive,
.slp-has-palette .slp-quiz,
.slp-has-palette .slp-reflect {
  background: color-mix(in srgb, var(--ep-bg) 72%, black);
  color: var(--ep-fg, #ffffff);
  position: relative;
  overflow: hidden;
}

.slp-has-palette .slp-context::before,
.slp-has-palette .slp-pquiz::before,
.slp-has-palette .slp-qcheck::before,
.slp-has-palette .slp-family::before,
.slp-has-palette .slp-explore::before,
.slp-has-palette .slp-meaning::before,
.slp-has-palette .slp-verse::before,
.slp-has-palette .slp-moment::before,
.slp-has-palette .slp-moral::before,
.slp-has-palette .slp-map::before,
.slp-has-palette .slp-secret::before,
.slp-has-palette .slp-scene::before,
.slp-has-palette .slp-complete::before,
.slp-has-palette .slp-interactive::before,
.slp-has-palette .slp-quiz::before,
.slp-has-palette .slp-reflect::before,
.slp-has-palette .slp-context::after,
.slp-has-palette .slp-pquiz::after,
.slp-has-palette .slp-qcheck::after,
.slp-has-palette .slp-family::after,
.slp-has-palette .slp-explore::after,
.slp-has-palette .slp-meaning::after,
.slp-has-palette .slp-verse::after,
.slp-has-palette .slp-moment::after,
.slp-has-palette .slp-moral::after,
.slp-has-palette .slp-map::after,
.slp-has-palette .slp-secret::after,
.slp-has-palette .slp-scene::after,
.slp-has-palette .slp-complete::after,
.slp-has-palette .slp-interactive::after,
.slp-has-palette .slp-quiz::after,
.slp-has-palette .slp-reflect::after {
  content: '';
  position: absolute;
  left: -25%;
  width: 150%;
  height: 46%;
  background: color-mix(in srgb, var(--ep-bg) 58%, black);
  pointer-events: none;
  z-index: 0;
}

.slp-has-palette .slp-context::before,
.slp-has-palette .slp-pquiz::before,
.slp-has-palette .slp-qcheck::before,
.slp-has-palette .slp-family::before,
.slp-has-palette .slp-explore::before,
.slp-has-palette .slp-meaning::before,
.slp-has-palette .slp-verse::before,
.slp-has-palette .slp-moment::before,
.slp-has-palette .slp-moral::before,
.slp-has-palette .slp-map::before,
.slp-has-palette .slp-secret::before,
.slp-has-palette .slp-scene::before,
.slp-has-palette .slp-complete::before,
.slp-has-palette .slp-interactive::before,
.slp-has-palette .slp-quiz::before,
.slp-has-palette .slp-reflect::before {
  top: -22%;
  border-radius: 0 0 52% 48% / 0 0 100% 90%;
  transform: rotate(-4deg);
}

.slp-has-palette .slp-context::after,
.slp-has-palette .slp-pquiz::after,
.slp-has-palette .slp-qcheck::after,
.slp-has-palette .slp-family::after,
.slp-has-palette .slp-explore::after,
.slp-has-palette .slp-meaning::after,
.slp-has-palette .slp-verse::after,
.slp-has-palette .slp-moment::after,
.slp-has-palette .slp-moral::after,
.slp-has-palette .slp-map::after,
.slp-has-palette .slp-secret::after,
.slp-has-palette .slp-scene::after,
.slp-has-palette .slp-complete::after,
.slp-has-palette .slp-interactive::after,
.slp-has-palette .slp-quiz::after,
.slp-has-palette .slp-reflect::after {
  bottom: -24%;
  border-radius: 55% 45% 0 0 / 95% 100% 0 0;
  transform: rotate(3deg);
}

.slp-has-palette .slp-context .slp-beat-scroll,
.slp-has-palette .slp-pquiz .slp-beat-scroll,
.slp-has-palette .slp-qcheck .slp-beat-scroll,
.slp-has-palette .slp-family .slp-beat-scroll,
.slp-has-palette .slp-explore .slp-beat-scroll,
.slp-has-palette .slp-meaning .slp-beat-scroll,
.slp-has-palette .slp-verse .slp-beat-scroll,
.slp-has-palette .slp-moment .slp-beat-scroll,
.slp-has-palette .slp-moral .slp-beat-scroll,
.slp-has-palette .slp-map .slp-beat-scroll,
.slp-has-palette .slp-secret .slp-beat-scroll,
.slp-has-palette .slp-scene .slp-beat-scroll,
.slp-has-palette .slp-complete .slp-beat-scroll,
.slp-has-palette .slp-interactive .slp-beat-scroll,
.slp-has-palette .slp-quiz .slp-beat-scroll,
.slp-has-palette .slp-reflect .slp-beat-scroll,
.slp-has-palette .slp-moment .slp-beat-actions,
.slp-has-palette .slp-moral .slp-beat-actions,
.slp-has-palette .slp-map .slp-beat-actions,
.slp-has-palette .slp-secret .slp-beat-actions,
.slp-has-palette .slp-scene .slp-beat-actions,
.slp-has-palette .slp-complete .slp-beat-actions,
.slp-has-palette .slp-interactive .slp-beat-actions,
.slp-has-palette .slp-quiz .slp-beat-actions,
.slp-has-palette .slp-reflect .slp-beat-actions {
  position: relative;
  z-index: 1;
}

/* ---------- high-contrast overrides across ALL palette question/interactive screens ---------- */
.slp-has-palette .slp-prompt,
.slp-has-palette .slp-quiz-q,
.slp-has-palette .slp-context-q,
.slp-has-palette .slp-pquiz-opt,
.slp-has-palette .slp-pquiz-opt .slp-chip-name,
.slp-has-palette .slp-chip-name,
.slp-has-palette .slp-qc-opt,
.slp-has-palette .slp-choice,
.slp-has-palette .slp-opt,
.slp-has-palette .slp-word,
.slp-has-palette .slp-point,
.slp-has-palette .slp-point-text,
.slp-has-palette .slp-map-text,
.slp-has-palette .slp-reflect-hint {
  color: var(--ep-fg, #ffffff) !important;
}

.slp-has-palette .slp-choice {
  background: color-mix(in srgb, var(--ep-bg, var(--surface)) 40%, rgba(255, 255, 255, 0.08)) !important;
  border: 1.5px solid rgba(255, 255, 255, 0.18) !important;
  border-radius: 16px !important;
  color: var(--ep-fg, #ffffff) !important;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.18) !important;
  backdrop-filter: blur(14px);
}

.slp-has-palette .slp-choice:hover {
  background: color-mix(in srgb, var(--ep-bg, var(--surface)) 30%, rgba(255, 255, 255, 0.16)) !important;
  border-color: rgba(255, 255, 255, 0.35) !important;
}

.slp-has-palette .slp-choice.selected {
  border-color: var(--ep-accent, #F85E00) !important;
  background: color-mix(in srgb, var(--ep-bg) 35%, rgba(255, 255, 255, 0.22)) !important;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.32), 0 0 0 3px color-mix(in srgb, var(--ep-accent, #F85E00) 45%, transparent) !important;
}

/* ---------- quiz options (.slp-opt) on a palette episode ----------
   Same glass treatment as .slp-choice right above (the closest sibling —
   both are plain text option buttons) — .slp-opt used to fall straight
   through to the generic light-surface .slp-opt rule even inside a
   palette episode, rendering a solid white box on top of the dark palette
   field it doesn't otherwise touch. */
.slp-has-palette .slp-opt {
  background: color-mix(in srgb, var(--ep-bg, var(--surface)) 40%, rgba(255, 255, 255, 0.08)) !important;
  border: 1.5px solid rgba(255, 255, 255, 0.18) !important;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.18) !important;
  backdrop-filter: blur(14px);
}
.slp-has-palette .slp-opt:active:not(:disabled) {
  background: color-mix(in srgb, var(--ep-bg, var(--surface)) 30%, rgba(255, 255, 255, 0.16)) !important;
}
.slp-has-palette .slp-opt.selected,
.slp-has-palette .slp-qc-opt.selected,
.slp-has-palette .slp-pquiz-opt.selected {
  border-color: var(--ep-accent, #F85E00) !important;
  background: color-mix(in srgb, var(--ep-bg) 35%, rgba(255, 255, 255, 0.22)) !important;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.32), 0 0 0 3px color-mix(in srgb, var(--ep-accent, #F85E00) 45%, transparent) !important;
}
/* Correct/wrong keep their own green/red semantics (never the episode's
   accent — right/wrong isn't a theme choice) but need real opacity to read
   against a dark palette field instead of the almost-invisible light-mode
   pastel tints the base .slp-opt.correct/.wrong rules use. */
.slp-has-palette .slp-opt.correct {
  background: color-mix(in srgb, var(--success, #06D6A0) 30%, var(--ep-bg, black)) !important;
  border-color: var(--success, #06D6A0) !important;
  color: #ffffff !important;
}
.slp-has-palette .slp-opt.wrong {
  background: color-mix(in srgb, #D64545 32%, var(--ep-bg, black)) !important;
  border-color: #D64545 !important;
  color: #ffffff !important;
}
.slp-has-palette .slp-feedback,
.slp-has-palette .slp-reinforce {
  background: color-mix(in srgb, var(--ep-bg, var(--surface)) 45%, rgba(255, 255, 255, 0.1)) !important;
  border: 1.5px solid rgba(255, 255, 255, 0.18) !important;
  color: var(--ep-fg, #ffffff) !important;
  backdrop-filter: blur(14px);
}
.slp-has-palette .slp-feedback.ok { border-color: var(--success, #06D6A0) !important; }
.slp-has-palette .slp-feedback.no { border-color: #D64545 !important; }

/* ---------- moment + moral (full color field) ---------- */
.slp-moment {
  background: var(--ep-bg, var(--indigo));
  color: var(--ep-fg, #EFF1F0);
}

/* entrance animations own `opacity`, so translucency lives in the color */
.slp-moment-line {
  color: color-mix(in srgb, var(--ep-fg, #ECECF0) 72%, transparent);
}

.slp-moment-final {
  color: var(--ep-fg, #EFF1F0);
}

.slp-moral {
  background: var(--ep-bg, var(--indigo));
  color: var(--ep-fg, #EFF1F0);
}

.slp-moral-mark {
  display: none !important;
}

.slp-moral-line {
  color: var(--ep-fg, rgba(236, 236, 240, 0.96));
}

.slp-moral-explain {
  color: color-mix(in srgb, var(--ep-fg, #ECECF0) 66%, transparent);
}
/* The closing reflection is now one <p> per paragraph instead of a single
   block. margin:0 above would run them together and undo the split, so put the
   air back between siblings only. */
.slp-moral-explain + .slp-moral-explain {
  margin-top: 15px;
}

/* ---------- meaning ----------
   Question uses the same contrast-checked --ep-pop as everywhere else (see
   the earlier .slp-meaning-q rule) — this used to read var(--ep-bg, ...),
   i.e. the panel's OWN background color, which made the question nearly
   invisible against itself on every palette. */
.slp-meaning-q {
  color: var(--ep-pop, var(--ep-accent, var(--brand-primary)));
}

/* ---------- verse (card takes the episode color) ---------- */
.slp-verse-card,
body.dark-mode .slp-verse-card {
  background: var(--ep-bg, #FAF7F0);
  border-color: color-mix(in srgb, var(--ep-fg, #E9E4D8) 20%, transparent);
  color: var(--ep-fg, var(--text-main));
}

.slp-verse-deva {
  color: var(--ep-fg, inherit);
}

.slp-verse-translit {
  color: var(--ep-fg, var(--text-muted));
  opacity: 0.62;
}

.slp-verse-translation {
  color: var(--ep-pop, var(--ep-accent, inherit));
}

.slp-verse-ref {
  color: var(--ep-fg, #8A7E5F);
  opacity: 0.7;
}

.slp-verse-quote {
  color: var(--ep-fg, inherit);
}

.slp-verse-attrib {
  color: color-mix(in srgb, var(--ep-fg, #ECECF0) 70%, transparent);
}

.slp-verse-note {
  color: var(--ep-fg, #4A4438);
  background: rgba(255, 255, 255, 0.12);
}

.slp-overlay[style] .slp-pronounce {
  border-color: var(--ep-fg, #B5620A);
  color: var(--ep-fg, #B5620A);
}

/* ---------- map (route in accent over the episode color) ---------- */
.slp-map {
  background: var(--ep-bg, var(--indigo));
  color: var(--ep-fg, #EFF1F0);
}

.slp-map-dot {
  background: var(--ep-accent, var(--brand-primary));
}

.slp-map-step::before {
  background: color-mix(in srgb, var(--ep-accent, var(--brand-primary)) 40%, transparent);
}

.slp-map-place {
  color: var(--ep-pop, var(--ep-accent, var(--brand-primary)));
}

.slp-map-text {
  color: var(--ep-fg, rgba(236, 236, 240, 0.86));
  opacity: 0.86;
}

/* ---------- reveal + scene share the color field ---------- */
.slp-secret,
.slp-scene {
  background: var(--ep-bg, var(--indigo));
  color: var(--ep-fg, #EFF1F0);
}

.slp-secret-teaser {
  color: var(--ep-fg, rgba(236, 236, 240, 0.9));
}

.slp-secret.slp-revealed .slp-secret-hidden {
  color: var(--ep-pop, var(--ep-accent, var(--brand-primary)));
}

.slp-secret.slp-revealed .slp-secret-after {
  color: color-mix(in srgb, var(--ep-fg, #ECECF0) 80%, transparent);
}

/* ---------- completion ---------- */
.slp-complete {
  background: var(--ep-bg, var(--indigo));
  color: var(--ep-fg, #EFF1F0);
}

.slp-complete-title {
  color: var(--ep-fg, #EFF1F0);
}

.slp-complete-note {
  color: var(--ep-fg, rgba(236, 236, 240, 0.78));
  opacity: 0.85;
}
