/* ── Block Content Context ────────────────────────────────────────────
   Slide partials use slide-title, slide-subtitle, stagger, and JS state
   classes that are normally scoped to .module-shell. Outside that shell
   (i.e. in block content) they need their own definitions.
   Uses @apply where possible — raw CSS only where Tailwind can't express it.
──────────────────────────────────────────────────────────────────── */

.block-content-context {
  position: relative;
}

/* ── Typography ─────────────────────────────────────────────── */

.block-content-context .text-sm  { font-size: 1rem !important; }
.block-content-context .text-xs  { font-size: 0.8125rem !important; }


.block-content-context .slide-title {
  font-family: var(--font-heading);
  font-size: 1.45rem;
  font-weight: 700;
  color: var(--color-dark);
  line-height: 1.2;
  margin-bottom: 20px;
}

.block-content-context .slide-subtitle {
  font-size: 1.125rem;
  color: var(--color-dark);
  margin-bottom: 16px;
  font-weight: 500;
  line-height: 1.35;
}

/* ── Stagger — just visible, no animation ───────────────────── */

.block-content-context .stagger {
  opacity: 1;
}

/* ── Full-bleed slides in block context ──────────────────────
   intro/section/takeaway all fill edge-to-edge in the interactive shell;
   in a block lesson's plain white page that reads as flush/unfinished
   without a bit of rounding, same fix intro already had. */

.block-content-context .intro-slide,
.block-content-context .section-slide,
.block-content-context .takeaway-slide {
  border-radius: 1rem;
}

/* reveal_cards' body reveal is a genuine layout change (grid-template-rows:
   0fr -> 1fr, not an opacity/transform illusion) — that's deliberate, see
   _reveal_cards.html.erb, since it's what makes the heading's centring
   respond correctly for any length of body text. In the interactive shell
   that's harmless: auto-rows-fr divides the shell's own bounded height
   proportionally, so a card's outer size is fixed by that allocation
   regardless of what's open inside it. A block lesson has no such bound —
   the page just flows — so auto-rows-fr there falls back to sizing each
   row by its own content, meaning a card's natural height genuinely
   differs open vs closed, visibly growing and pushing the page below it
   down when someone opens one. Giving it a taller floor here means it's
   already reserving enough room up front and doesn't need to grow at all. */

.block-content-context .reveal-card {
  min-height: 18rem;
}

/* takeaway-slide's overflow-y-auto exists for internal scroll if content
   ever runs long inside the bounded-height interactive shell — there's no
   such bound in a block lesson (the page itself scrolls instead), and
   left as auto here it causes an unwanted scrollbar specifically in
   gradient mode: the decorative circles bleed off the edges via negative
   offsets (-top-20 -right-14, etc.), which registers as genuine
   scrollable overflow on the Y-axis once auto is in play. Plain mode
   renders no such circles, which is why only gradient showed this.

   Both axes need overriding together, not just overflow-y: the base
   classes also set overflow-x-hidden, and per the well-known overflow
   quirk (a mismatched hidden/visible pair always computes the "visible"
   axis to auto instead), overflow-y: visible alone silently has no
   effect as long as overflow-x stays hidden. */

.block-content-context .takeaway-slide {
  overflow-x: visible;
  overflow-y: visible;
}

/* ── Accordion ──────────────────────────────────────────────── */
 
.block-content-context details[open] .acc-trigger {
  background: var(--color-highlight);
  color: var(--color-accent-dark);
}
 
.block-content-context details[open] .acc-icon {
  transform: rotate(180deg);
}
 
/* ── Tabs ───────────────────────────────────────────────────── */
 
.block-content-context .tab-btn.active {
  color: var(--color-accent);
  border-bottom-color: var(--color-accent);
}
 
.block-content-context .tab-pane.active {
  display: block;
}
 
/* ── Hotspot ────────────────────────────────────────────────── */
 
.block-content-context .hotspot-btn {
  animation: m-hotPulse 2.5s infinite;
}
 
.block-content-context .hs-tooltip.show {
  display: block;
}
 
/* ── Flip cards ──────────────────────────────────────────────── */
 
.block-content-context .flip-card {
  perspective: 1000px;
}
 
.block-content-context .flip-inner {
  position: relative;
  width: 100%;
  min-height: 180px;
  transition: transform 0.6s;
  transform-style: preserve-3d;
}
 
.block-content-context .flip-card.flipped .flip-inner {
  transform: rotateY(180deg);
}
 

/* Back-face text stays at xs — prevent bumped .text-xs from inflating it further */
.block-content-context .flip-back-content {
  font-size: 0.8125rem !important;
}
 
/* ── Knowledge check / quiz ─────────────────────────────────── */
 
.block-content-context .quiz-opt.correct   { background: var(--color-success-light); border-color: var(--color-success); color: var(--color-success); }
.block-content-context .quiz-opt.incorrect { background: var(--color-error-light); border-color: var(--color-error); color: var(--color-error); }
 
.block-content-context .quiz-feedback.show    { display: block; }
.block-content-context .quiz-feedback.success { background: var(--color-success-light); color: var(--color-success); }
.block-content-context .quiz-feedback.error   { background: var(--color-error-light); color: var(--color-error); }
 
/* ── Matching ───────────────────────────────────────────────── */
 
.block-content-context .matching-item.is-selected {
  border-color: var(--color-accent);
  background: var(--color-highlight);
  color: var(--color-accent-dark);
  box-shadow: 0 0 0 3px var(--color-highlight);
}
 
.block-content-context .matching-item.is-matched {
  border-color: var(--color-success);
  background: var(--color-success-light);
  color: var(--color-success);
  cursor: default;
}
 
.block-content-context .matching-item.is-wrong {
  border-color: var(--color-error);
  background: var(--color-error-light);
  animation: m-shake 0.4s ease;
}
 
/* ── Drag drop ──────────────────────────────────────────────── */
 
.block-content-context .correct-placed {
  background: var(--color-success-light);
  border-color: var(--color-success);
  color: var(--color-success-dark);
  cursor: default;
}
 
.block-content-context .incorrect-placed {
  border-color: var(--color-error);
  animation: m-shake 0.4s ease;
}
 
/* ── True/false ─────────────────────────────────────────────── */
 
.block-content-context .tf-btn--correct {
  border-color: var(--color-success) !important;
  background: var(--color-success-light) !important;
  color: var(--color-success) !important;
}
 
.block-content-context .tf-btn--wrong {
  border-color: var(--color-error) !important;
  background: var(--color-error-light) !important;
  color: var(--color-error) !important;
  animation: m-shake 0.4s ease;
}
 
/* ── Modal open state (gallery, explore) ────────────────────── */
 
.block-content-context .ff-modal.open {
  display: flex;
} 

/* ═══════════════════════════════════════════════════════════════
   SLIDES THAT USE flex-1 TO FILL THE 16:9 SHELL
   In block context there is no parent height, so flex-1 → 0.
   Each type gets an explicit min-height appropriate for its content.
═══════════════════════════════════════════════════════════════ */
 
/* ── Before / After ─────────────────────────────────────────── */
/* flex-1 collapses; template floor is min-h-40 (160px).
   Heading + 5 items at bumped text size needs ~380px. */
 
.block-content-context .comparison-wrap {
  min-height: 380px;
}
 
/* ── Video ───────────────────────────────────────────────────── */
/* video-embed: flex-1 + min-h-40 — too short for a watchable embed. */
 
.block-content-context .video-embed {
  min-height: 340px;
}
 
/* ── Image Full ──────────────────────────────────────────────── */
/* image-full-slide is the root element (no slide-inner wrapper).
   flex-1 collapses entirely in document flow. */
 
.block-content-context .image-full-slide {
  min-height: 400px;
  border-radius: 1rem;
  overflow: hidden;
}
 
/* ── Image Pair ──────────────────────────────────────────────── */
/* Image cells use flex-1 min-h-40 inside a flex-col.
   The cell div carries the .image-pair-img class (added to ERB). */
 
.block-content-context .image-pair-img {
  min-height: 280px;
}
 
/* ── Hotspot area ────────────────────────────────────────────── */
/* flex-1 + min-h-48 (192px). Hotspot buttons are %-positioned
   so the container needs real height to be usable. */
 
.block-content-context .hotspot-area {
  min-height: 360px;
}
 
/* ═══════════════════════════════════════════════════════════════
   CAROUSEL — three modes, same collapse problem
   The outer slide-inner has flex-1 with no parent height.
   Inner viewports also use flex-1/min-h-0 → 0px.
═══════════════════════════════════════════════════════════════ */
 
/* Outer container */
.block-content-context [data-controller="slide-carousel"] {
  min-height: 520px;
  display: flex;
  flex-direction: column;
}
 
/* ── Fullscreen: the card stage (flex-1 inside flex-1 wrapper) ── */
/* Both wrappers collapse. The card stage has class:
   flex-1 relative overflow-hidden rounded-2xl border border-light-dark
   It carries .carousel-stage (added to ERB). */
 
.block-content-context .carousel-stage {
  flex: 0 0 420px;
  height: 420px;
}
 
/* ── Peek: the peekViewport (flex-1 min-h-0) ────────────────── */
 
.block-content-context [data-slide-carousel-target="peekViewport"] {
  flex: 0 0 380px;
  height: 380px;
}

/* Overlay card type: root div is relative flex-1 overflow-hidden —
   absolute-positioned image gives it no intrinsic height. */
.block-content-context [data-slide-carousel-target="card"] > .relative.flex-1 {
  min-height: 280px;
}

/* ── Strip: the detail panel (flex-1 min-h-0 relative) ─────── */
 
.block-content-context [data-slide-carousel-target="stripDetail"] {
  flex: 0 0 380px;
  height: 380px;
}

/* ── Accordion ──────────────────────────────────────────────── */
 
.block-content-context details[open] .acc-trigger {
  background: var(--color-highlight);
  color: var(--color-accent-dark);
}
 
.block-content-context details[open] .acc-icon {
  transform: rotate(180deg);
}
 
/* ── Tabs ───────────────────────────────────────────────────── */
 
.block-content-context .tab-btn.active {
  color: var(--color-accent);
  border-bottom-color: var(--color-accent);
}
 
.block-content-context .tab-pane.active {
  display: block;
}
 
/* ── Hotspot ────────────────────────────────────────────────── */
 
.block-content-context .hotspot-btn {
  animation: m-hotPulse 2.5s infinite;
}
 
.block-content-context .hs-tooltip.show {
  display: block;
}
 
/* ── Flip cards ──────────────────────────────────────────────── */
 
.block-content-context .flip-card {
  perspective: 1000px;
}
 
.block-content-context .flip-inner {
  position: relative;
  width: 100%;
  min-height: 180px;
  transition: transform 0.6s;
  transform-style: preserve-3d;
}
 
.block-content-context .flip-card.flipped .flip-inner {
  transform: rotateY(180deg);
}
 

/* Back-face text stays at xs — prevent bumped .text-xs from inflating it further */
.block-content-context .flip-back-content {
  font-size: 0.8125rem !important;
}
 
/* ── Knowledge check / quiz ─────────────────────────────────── */
 
.block-content-context .quiz-opt.correct   { background: var(--color-success-light); border-color: var(--color-success); color: var(--color-success); }
.block-content-context .quiz-opt.incorrect { background: var(--color-error-light); border-color: var(--color-error); color: var(--color-error); }
 
.block-content-context .quiz-feedback.show    { display: block; }
.block-content-context .quiz-feedback.success { background: var(--color-success-light); color: var(--color-success); }
.block-content-context .quiz-feedback.error   { background: var(--color-error-light); color: var(--color-error); }
 
/* ── Matching ───────────────────────────────────────────────── */
 
.block-content-context .matching-item.is-selected {
  border-color: var(--color-accent);
  background: var(--color-highlight);
  color: var(--color-accent-dark);
  box-shadow: 0 0 0 3px var(--color-highlight);
}
 
.block-content-context .matching-item.is-matched {
  border-color: var(--color-success);
  background: var(--color-success-light);
  color: var(--color-success);
  cursor: default;
}
 
.block-content-context .matching-item.is-wrong {
  border-color: var(--color-error);
  background: var(--color-error-light);
  animation: m-shake 0.4s ease;
}
 
/* ── Drag drop ──────────────────────────────────────────────── */
 
.block-content-context .correct-placed {
  background: var(--color-success-light);
  border-color: var(--color-success);
  color: var(--color-success-dark);
  cursor: default;
}
 
.block-content-context .incorrect-placed {
  border-color: var(--color-error);
  animation: m-shake 0.4s ease;
}
 
/* ── True/false ─────────────────────────────────────────────── */
 
.block-content-context .tf-btn--correct {
  border-color: var(--color-success) !important;
  background: var(--color-success-light) !important;
  color: var(--color-success) !important;
}
 
.block-content-context .tf-btn--wrong {
  border-color: var(--color-error) !important;
  background: var(--color-error-light) !important;
  color: var(--color-error) !important;
  animation: m-shake 0.4s ease;
}
 
/* ── Modal open state (gallery, explore) ────────────────────── */
 
.block-content-context .ff-modal.open {
  display: flex;
} 

/* ═══════════════════════════════════════════════════════════════
   SLIDES THAT USE flex-1 TO FILL THE 16:9 SHELL
   In block context there is no parent height, so flex-1 → 0.
   Each type gets an explicit min-height appropriate for its content.
═══════════════════════════════════════════════════════════════ */
 
/* ── Before / After ─────────────────────────────────────────── */
/* flex-1 collapses; template floor is min-h-40 (160px).
   Heading + 5 items at bumped text size needs ~380px. */
 
.block-content-context .comparison-wrap {
  min-height: 380px;
}
 
/* ── Video ───────────────────────────────────────────────────── */
/* video-embed: flex-1 + min-h-40 — too short for a watchable embed. */
 
.block-content-context .video-embed {
  min-height: 340px;
}
 
/* ── Image Full ──────────────────────────────────────────────── */
/* image-full-slide is the root element (no slide-inner wrapper).
   flex-1 collapses entirely in document flow. */
 
.block-content-context .image-full-slide {
  min-height: 400px;
  border-radius: 1rem;
  overflow: hidden;
}
 
/* ── Image Pair ──────────────────────────────────────────────── */
/* Image cells use flex-1 min-h-40 inside a flex-col.
   The cell div carries the .image-pair-img class (added to ERB). */
 
.block-content-context .image-pair-img {
  min-height: 280px;
}
 
/* ── Hotspot area ────────────────────────────────────────────── */
/* flex-1 + min-h-48 (192px). Hotspot buttons are %-positioned
   so the container needs real height to be usable. */
 
.block-content-context .hotspot-area {
  min-height: 360px;
}
 
/* ═══════════════════════════════════════════════════════════════
   CAROUSEL — three modes, same collapse problem
   The outer slide-inner has flex-1 with no parent height.
   Inner viewports also use flex-1/min-h-0 → 0px.
═══════════════════════════════════════════════════════════════ */
 
/* Outer container */
.block-content-context [data-controller="slide-carousel"] {
  min-height: 520px;
  display: flex;
  flex-direction: column;
}
 
/* ── Fullscreen: the card stage (flex-1 inside flex-1 wrapper) ── */
/* Both wrappers collapse. The card stage has class:
   flex-1 relative overflow-hidden rounded-2xl border border-light-dark
   It carries .carousel-stage (added to ERB). */
 
.block-content-context .carousel-stage {
  flex: 0 0 420px;
  height: 420px;
}
 
/* ── Peek: the peekViewport (flex-1 min-h-0) ────────────────── */
 
.block-content-context [data-slide-carousel-target="peekViewport"] {
  flex: 0 0 380px;
  height: 380px;
}

/* Overlay card type: root div is relative flex-1 overflow-hidden —
   absolute-positioned image gives it no intrinsic height. */
.block-content-context [data-slide-carousel-target="card"] > .relative.flex-1 {
  min-height: 280px;
}

/* ── Strip: the detail panel (flex-1 min-h-0 relative) ─────── */
 
.block-content-context [data-slide-carousel-target="stripDetail"] {
  flex: 0 0 380px;
  height: 380px;
}