/* ══════════════════════════════════════════════════════════════════
   engine.css — shared chrome + pattern styling for interactive HTML
   lectures. Generic across units - contains no lecture content, no
   unit-specific text, no hardcoded correct-answers.

   One CUSTOMIZE marker in this file (search for it): the print-mode
   rule that names which slide is this lecture's Notes slide.

   Pairs with engine.js. See patterns_and_build_reference.md for what
   each .pattern-* class expects in its HTML, and lecture_template.html
   for a minimal working skeleton that wires both files together.
   ══════════════════════════════════════════════════════════════════ */

:root {
  --green:   #1B4332;
  --gold:    #C9972B;
  --gold-lt: #E8C060;
  --white:   #FFFFFF;
  --offwhite:#F4F4F0;
  --text:    #1A1A1A;
  --muted:   #5A5A5A;
  --border:  #D4D4CC;
  --correct: #1B6B3A;
  --wrong:   #8B1A1A;
  --serif:   "Source Serif 4", Georgia, serif;
  --sans:    "DM Sans", "Helvetica Neue", sans-serif;
  --hh: 44px;
}
.reveal-viewport { background: var(--white); }
.reveal { font-family: var(--sans); }
.reveal .slides { color: var(--text); }
.reveal .slides section { padding: 0 !important; height: 720px; }
.reveal h1,.reveal h2,.reveal h3 {
  font-family:var(--serif); font-weight:600;
  text-transform:none; letter-spacing:-0.01em; color:var(--text); margin:0;
}
.reveal .fragment { opacity:0; transition:opacity .4s ease; }
.reveal .fragment.visible { opacity:1; }

/* ── Global header (demo: no PDF/draw/notes chrome) ── */
#global-header {
  position:fixed; top:0; left:0; right:0;
  height:var(--hh); background:var(--green);
  display:flex; align-items:center; justify-content:space-between;
  padding:0 20px 0 18px; z-index:9999; pointer-events:none;
}
#global-header::after {
  content:''; position:absolute; bottom:0; left:0; right:0;
  height:2px; background:var(--gold);
}
#gh-unit {
  font-family:var(--sans); font-size:11px; font-weight:500;
  letter-spacing:0.1em; text-transform:uppercase;
  color:rgba(255,255,255,0.7);
}
#gh-section {
  font-family:var(--sans); font-size:11px;
  color:var(--gold-lt); letter-spacing:0.04em;
}
#slide-num {
  position:fixed; top:calc(var(--hh) + 8px); right:14px;
  z-index:9999; font-family:var(--sans);
  font-size:11px; font-weight:600;
  color:var(--green); opacity:0.55;
  font-variant-numeric:tabular-nums; pointer-events:none;
}
#global-header.hidden, #slide-num.hidden { display:none; }

/* ── Demo badge (persistent, all non-title slides) ── */
#demo-badge {
  position:fixed; top:calc(var(--hh) + 8px); left:14px;
  z-index:9999; font-family:var(--sans); font-size:10px; font-weight:600;
  letter-spacing:0.08em; text-transform:uppercase;
  color:var(--gold); opacity:0.75; pointer-events:none;
}
#demo-badge.hidden { display:none; }

/* ── Time remaining (top-left, in the header's left cluster) ──
   Ported from the L7-L11 convention: probed from real audio-file
   durations rather than hand-entered numbers, so it can never drift from
   what's actually recorded. */
.time-remaining {
  font-family:var(--sans); font-size:11px; font-weight:500; color:rgba(255,255,255,.75);
  font-variant-numeric:tabular-nums; border-left:1px solid rgba(255,255,255,.25); padding-left:10px; margin-left:10px;
}

/* ── Speed control widget ──
   Top-right, just under the header. NOT bottom-right (Reveal's own
   progress bar + nav arrows own that corner) - same reasoning as the
   L7-L11 convention this is ported from. */
#speed-control {
  position:fixed; top:calc(var(--hh) + 8px); right:14px; z-index:9999;
  display:flex; align-items:center; gap:6px; background:#fff; border:1.5px solid var(--border);
  border-radius:8px; padding:5px; box-shadow:0 2px 10px rgba(0,0,0,.12);
  font-family:var(--sans);
}
#speed-control.hidden { display:none; }
#speed-control button {
  border:1.5px solid transparent; background:var(--offwhite); color:var(--text);
  font-size:12px; font-weight:600; padding:6px 11px; border-radius:6px; cursor:pointer;
  transition:border-color .15s, background .15s, color .15s;
}
#speed-control button:hover { background:#FDF8EC; }
#speed-control button.active { border-color:var(--gold); background:#FDF8EC; color:var(--green); }
#play-pause-btn {
  display:flex; align-items:center; justify-content:center;
  width:30px; height:30px; padding:0 !important; font-size:11px;
}
.speed-divider { width:1px; height:20px; background:var(--border); flex-shrink:0; }

/* ── Fullscreen toggle ──
   Bottom-left, not bottom-right - same reasoning as speed-control's own
   placement note just above: Reveal's nav arrows + progress bar own the
   bottom-right corner. Bottom-left is genuinely empty (the old audio-bar
   that used to live there was removed once play/pause moved into
   #speed-control), so no existing chrome to collide with. */
#fullscreen-btn {
  position:fixed; bottom:14px; left:14px; z-index:9999;
  background:var(--green); color:#fff; border:none; border-radius:6px;
  font-family:var(--sans); font-size:11px; font-weight:500;
  padding:7px 14px; cursor:pointer;
  display:inline-flex; align-items:center; gap:6px;
  box-shadow:0 2px 10px rgba(0,0,0,.12);
  opacity:.85; transition:opacity .15s, background .15s;
}
#fullscreen-btn:hover { background:#2D6A4F; opacity:1; }

/* ── Voice tag (fixed chrome, not slide content) ──
   Originally positioned inside each slide's .slide-body, which Reveal
   scales along with everything else - while the header/speed-control/
   demo-badge are all fixed, unscaled chrome. At most viewport sizes
   those two coordinate systems stayed clear of each other by luck; at
   some they don't, and the badge visibly collided with the header. Real
   fix: promote it to actual fixed chrome, driven by data-voice via JS,
   exactly like the rest of the header. */
#voice-tag-chrome {
  position:fixed; top:calc(var(--hh) + 60px); right:14px; z-index:9999;
  display:inline-flex; align-items:center; gap:6px;
  font-family:var(--sans); font-size:11px; font-weight:500;
  padding:5px 12px; border-radius:20px;
  background:var(--offwhite); border:1px solid var(--border);
  color:var(--muted); box-shadow:0 2px 10px rgba(0,0,0,.08);
}
#voice-tag-chrome.real { border-color:var(--green); color:var(--green); background:#EBF5EE; }
#voice-tag-chrome.ai   { border-color:var(--gold);  color:#8a6314; background:#FDF8EC; }
#voice-tag-chrome.hidden { display:none; }

/* ── Slide body / title ── */
.slide-body {
  width:100%; height:100%;
  display:flex; flex-direction:column;
  padding:calc(var(--hh) + 44px) 48px 24px;
  box-sizing:border-box; overflow:hidden; position:relative;
}
.slide-title {
  font-family:var(--serif); font-size:clamp(18px,2.2vw,28px);
  font-weight:600; color:var(--green); line-height:1.15;
  margin:0 0 14px; flex-shrink:0; text-wrap:balance;
}
.slide-title em { font-style:italic; color:var(--gold); font-weight:300; }

.image-wrap { position:relative; width:100%; height:100%; }
.image-wrap img, .image-wrap svg:not(.overlay) {
  width:100%; height:100%; object-fit:contain; display:block;
}
.image-wrap svg.overlay {
  position:absolute; top:0; left:0; width:100%; height:100%; pointer-events:none;
}
.image-wrap svg.overlay.clickable { pointer-events:auto; }

/* ── Pattern A_image (S04) ── */
.pattern-a .slide-body { padding-left:40px; padding-right:40px; padding-bottom:18px; }
.pattern-a .slide-title { font-size:clamp(14px,1.8vw,22px); margin-bottom:8px; }
.pattern-a .image-wrap { height:calc(720px - var(--hh) - 44px - 18px - 40px - 18px); overflow:hidden; }

/* Ping animations */
@keyframes ripple-out  { 0%{r:10;opacity:.85} 100%{r:52;opacity:0} }
@keyframes ripple-out2 { 0%{r:10;opacity:.6}  100%{r:52;opacity:0} }
@keyframes beacon      { 0%,100%{opacity:1;r:8} 50%{opacity:.5;r:11} }
.ping-ring { fill:none; stroke:#DC2626; stroke-width:3.5; opacity:0; pointer-events:none; }
.ping-ring.go   { animation:ripple-out  1.5s ease-out infinite; }
.ping-ring.go.d { animation:ripple-out2 1.5s ease-out .5s infinite; }
.ping-dot { fill:#DC2626; opacity:0; pointer-events:none; }
.ping-dot.go { animation:beacon 1.1s ease-in-out infinite; }
/* Hybrid pings render larger (native ~1376px image space) */
.hybrid-ping.ping-ring { stroke-width:7; }

/* Static marker badges (S05/S08 — always visible A–F letters) */
.marker-badge circle { fill:var(--gold); stroke:#fff; stroke-width:3; }
.marker-badge text {
  fill:#fff; font-family:var(--sans); font-weight:700; font-size:22px;
  text-anchor:middle; dominant-baseline:central;
}

/* ── Pattern B (concept) ── */
.pattern-b .slide-body { justify-content:center; align-items:flex-start; padding-left:64px; padding-right:120px; text-align:left; }
.concept-eyebrow { font-family:var(--sans); font-size:11px; font-weight:500; letter-spacing:0.14em; text-transform:uppercase; color:var(--gold); margin:0 0 16px; flex-shrink:0; }
.concept-text { font-family:var(--serif); font-size:clamp(20px,2.8vw,36px); font-weight:300; line-height:1.35; color:var(--text); max-width:860px; text-wrap:balance; }
.concept-phrase { display:block; margin-bottom:6px; }
.concept-rule { width:48px; height:3px; background:var(--gold); border:none; margin:20px 0; flex-shrink:0; }
.concept-note { font-family:var(--sans); font-size:clamp(13px,1.4vw,16px); color:var(--muted); max-width:680px; line-height:1.55; margin:0; flex-shrink:0; text-wrap:balance; }

/* ── Pattern C (list) ── */
.pattern-c .list-items { display:flex; flex-direction:column; gap:10px; flex:1; min-height:0; justify-content:center; }
.list-card { background:var(--offwhite); border-left:4px solid var(--border); border-radius:0 6px 6px 0; padding:12px 20px; transition:border-color .3s,opacity .4s,background .3s; flex-shrink:0; }
.list-card.c-active { border-left-color:var(--gold); background:#FDF8EC; }
.list-card.c-past   { opacity:.35; }
.list-card .item-label { font-family:var(--sans); font-size:10px; font-weight:500; letter-spacing:0.12em; text-transform:uppercase; color:var(--gold); margin-bottom:3px; }
.list-card .item-text  { font-family:var(--sans); font-size:clamp(12px,1.5vw,16px); color:var(--text); line-height:1.4; }

/* ── Pattern AL (S05 — split panel: annotated image + synced list) ── */
.pattern-al .slide-body { padding-left:40px; padding-right:40px; }
.al-grid { display:grid; grid-template-columns:1.5fr 1fr; gap:20px; flex:1; min-height:0; }
.al-image-col .image-wrap { height:calc(720px - var(--hh) - 44px - 18px - 40px - 18px); }
.al-list-col { display:flex; flex-direction:column; gap:8px; justify-content:center; min-height:0; overflow:hidden; }
.al-list-col .list-card { padding:9px 16px; }
.al-list-col .item-text { font-size:clamp(11px,1.3vw,14px); }

/* ── Pattern E (MCQ + drag) ── */
.pattern-e .slide-body { padding-top:calc(var(--hh) + 44px); }
.mcq-question { font-family:var(--serif); font-size:clamp(15px,2vw,22px); font-weight:400; color:var(--text); line-height:1.4; margin:0 0 16px; flex-shrink:0; text-wrap:balance; }
.mcq-options  { display:grid; grid-template-columns:1fr 1fr; gap:10px; flex-shrink:0; }
.mcq-opt { background:var(--offwhite); border:2px solid var(--border); border-radius:8px; padding:14px 18px; cursor:pointer; transition:border-color .2s,background .2s,transform .1s; text-align:left; font-family:var(--sans); font-size:clamp(12px,1.4vw,15px); color:var(--text); line-height:1.4; display:flex; align-items:flex-start; gap:10px; }
.mcq-opt:hover:not(.answered) { border-color:var(--gold); background:#FDF8EC; transform:translateY(-1px); }
.mcq-opt .opt-key { font-weight:600; color:var(--green); flex-shrink:0; font-size:.9em; margin-top:1px; min-width:16px; }
.mcq-opt.correct { border-color:var(--correct); background:#EBF5EE; }
.mcq-opt.correct .opt-key { color:var(--correct); }
.mcq-opt.wrong   { border-color:var(--wrong); background:#F5EBEB; opacity:.65; }
.mcq-opt.wrong .opt-key { color:var(--wrong); }
.mcq-feedback { margin-top:12px; padding:11px 16px; border-radius:6px; font-family:var(--sans); font-size:clamp(12px,1.3vw,14px); line-height:1.5; display:none; flex-shrink:0; }
.mcq-feedback.show { display:block; }
.fb-correct { background:#EBF5EE; border-left:4px solid var(--correct); color:#0f3320; }
.fb-wrong   { background:#F5EBEB; border-left:4px solid var(--wrong); color:#3a0f0f; }
.mcq-continue { margin-top:8px; font-family:var(--sans); font-size:11px; color:var(--muted); display:none; flex-shrink:0; }
.mcq-continue.show { display:block; }

.drag-check-btn { font-family:var(--sans); font-size:clamp(11px,1.2vw,13px); font-weight:500; background:var(--green); color:#fff; border:none; border-radius:6px; padding:8px 18px; cursor:pointer; margin-top:14px; transition:background .2s,opacity .2s; flex-shrink:0; }
.drag-check-btn:hover:not(:disabled) { background:#2D6A4F; }
.drag-check-btn:disabled { opacity:.45; cursor:not-allowed; }
.drag-btn-row { display:flex; gap:10px; margin-top:14px; align-items:center; }
.drag-try-btn { font-family:var(--sans); font-size:clamp(11px,1.2vw,13px); font-weight:500; background:#fff; color:var(--green); border:1.5px solid var(--green); border-radius:6px; padding:7px 16px; cursor:pointer; transition:background .2s; display:none; }
.drag-try-btn:hover { background:var(--offwhite); }
.drag-try-btn.show { display:inline-block; }
.drag-chip { background:#FDF8EC; border:2px solid var(--gold); border-radius:6px; padding:10px 14px; font-family:var(--sans); font-size:clamp(12px,1.4vw,15px); color:var(--text); cursor:grab; user-select:none; transition:transform .15s, box-shadow .15s, border-color .25s, background .25s; box-shadow:0 1px 3px rgba(0,0,0,0.08); display:flex; align-items:center; gap:8px; }
.drag-chip:hover { transform:translateY(-1px); box-shadow:0 3px 8px rgba(0,0,0,0.12); }
.drag-chip.sortable-ghost { opacity:.4; }
.drag-chip.sortable-chosen { cursor:grabbing; }
.drag-chip.correct { background:#EBF5EE; border-color:var(--correct); }
.drag-chip.wrong   { background:#F5EBEB; border-color:var(--wrong); animation:shake .4s; }
.drag-chip .chip-hint { display:none; font-family:var(--sans); font-size:10px; font-style:italic; color:var(--wrong); margin-top:4px; line-height:1.3; font-weight:400; }
.drag-chip.wrong .chip-hint { display:block; }
.drag-chip-content { display:flex; flex-direction:column; gap:0; }
@keyframes shake { 0%,100% { transform:translateX(0); } 25% { transform:translateX(-4px); } 75% { transform:translateX(4px); } }
.drag-cat-grid { display:grid; grid-template-columns:0.85fr 1.15fr; gap:18px; flex:1; min-height:0; align-items:start; }
.drag-cat-pool { display:flex; flex-direction:column; gap:8px; padding:14px; background:var(--offwhite); border-radius:8px; border:1px dashed var(--border); min-height:200px; }
.drag-cat-pool-label { font-family:var(--sans); font-size:10px; font-weight:500; letter-spacing:0.12em; text-transform:uppercase; color:var(--gold); margin:0 0 4px; }
.drag-cat-targets { display:flex; flex-direction:column; gap:12px; }
.drag-cat-row { display:flex; flex-direction:column; gap:6px; }
.drag-cat-target-label { font-family:var(--sans); font-size:clamp(11px,1.3vw,14px); color:var(--text); line-height:1.35; text-align:left; }
.drag-cat-drop { min-height:42px; width:100%; box-sizing:border-box; border:2px dashed var(--border); border-radius:6px; background:#FAFAF6; display:flex; align-items:center; justify-content:center; padding:4px; transition:border-color .2s, background .2s; }
.drag-cat-drop.sortable-over { border-color:var(--gold); background:#FDF8EC; }
.drag-cat-drop .drag-chip { width:100%; box-sizing:border-box; justify-content:center; font-size:clamp(11px,1.3vw,14px); padding:7px 10px; }

/* ── Pattern Explore (S08) ── */
.pattern-explore .slide-body { padding-left:40px; padding-right:40px; }
.explore-grid { display:grid; grid-template-columns:1.2fr 1fr; gap:24px; flex:1; min-height:0; }
.explore-image-col .image-wrap { height:calc(720px - var(--hh) - 44px - 18px - 40px - 18px); position:relative; }
.hotspot { cursor:pointer; }
.hotspot .hotspot-hit { fill:transparent; }
.hotspot .hotspot-badge { fill:var(--green); stroke:#fff; stroke-width:3; transition:fill .2s, r .2s; }
.hotspot text { fill:#fff; font-family:var(--sans); font-weight:700; font-size:22px; text-anchor:middle; dominant-baseline:central; pointer-events:none; }
.hotspot:hover .hotspot-badge, .hotspot.active .hotspot-badge { fill:var(--gold); r:18; }
.explore-result-col { display:flex; flex-direction:column; justify-content:center; align-items:center; gap:14px; background:var(--offwhite); border-radius:10px; padding:20px; }
.explore-caption { font-family:var(--sans); font-size:12px; color:var(--muted); text-align:center; margin:0; min-height:2.6em; }
.field-diagram { width:100%; max-width:300px; }
.field-quad { fill:#1A1A1A; opacity:0; transition:opacity .35s ease; }
.field-quad.shaded { opacity:.85; }
.field-outline { fill:none; stroke:var(--border); stroke-width:2; }
.field-macula { fill:#fff; stroke:var(--green); stroke-width:1.5; display:none; }
.field-macula.show { display:block; }
.explore-defect-name { font-family:var(--sans); font-size:13px; color:var(--green); text-align:center; margin:0; min-height:2.4em; font-weight:500; }
.explore-hint { position:absolute; bottom:10px; left:10px; background:rgba(255,255,255,0.92); border:1px solid var(--border); border-radius:6px; padding:6px 12px; font-family:var(--sans); font-size:11px; color:var(--muted); }

/* ── Pattern Reflect (S09) ── */
.pattern-reflect .slide-body { padding-left:64px; padding-right:64px; justify-content:center; }
.reflect-block { margin-bottom:20px; }
.reflect-prompt { font-family:var(--serif); font-size:clamp(15px,1.9vw,20px); color:var(--text); line-height:1.4; margin:0 0 10px; text-wrap:balance; }
.reflect-textarea { width:100%; min-height:70px; box-sizing:border-box; border:1.5px solid var(--border); border-radius:8px; padding:10px 14px; font-family:var(--sans); font-size:13px; color:var(--text); resize:vertical; }
.reflect-textarea:focus { outline:none; border-color:var(--gold); }
.reflect-save-row { display:flex; align-items:center; gap:10px; margin-top:8px; }
.reflect-save-btn { font-family:var(--sans); font-size:12px; font-weight:500; background:var(--green); color:#fff; border:none; border-radius:6px; padding:7px 16px; cursor:pointer; }
.reflect-save-btn:hover { background:#2D6A4F; }
.reflect-saved { font-family:var(--sans); font-size:12px; color:var(--correct); opacity:0; transition:opacity .3s; }
.reflect-saved.show { opacity:1; }

/* ── Pattern Notes (S10) ── */
.pattern-notes .slide-body { padding-left:64px; padding-right:64px; justify-content:center; align-items:center; }
.notes-card { background:#fff; border:1.5px solid var(--border); border-radius:10px; padding:28px 36px; max-width:640px; width:100%; box-shadow:0 4px 16px rgba(0,0,0,0.06); }
.notes-card h3 { font-family:var(--serif); font-size:19px; color:var(--green); margin:0 0 4px; }
.notes-card .notes-date { font-family:var(--sans); font-size:11px; color:var(--muted); margin:0 0 18px; }
.notes-item { margin-bottom:14px; }
.notes-item .notes-q { font-family:var(--sans); font-size:11px; font-weight:600; letter-spacing:.04em; color:var(--gold); text-transform:uppercase; margin:0 0 4px; }
.notes-item .notes-a { font-family:var(--sans); font-size:14px; color:var(--text); line-height:1.5; margin:0; white-space:pre-wrap; }
.notes-item .notes-a.empty { color:var(--muted); font-style:italic; }
.print-btn { margin-top:18px; font-family:var(--sans); font-size:12px; font-weight:500; background:var(--green); color:#fff; border:none; border-radius:6px; padding:9px 20px; cursor:pointer; }
.print-btn:hover { background:#2D6A4F; }

/* ── Print stylesheet (S10 only) ── */
@media print {
  body.printing-notes #global-header,
  body.printing-notes #slide-num,
  body.printing-notes #demo-badge,
  body.printing-notes .print-btn,
  body.printing-notes #fullscreen-btn,
  body.printing-notes #speed-control,
  body.printing-notes #voice-tag-chrome,
  body.printing-notes .reveal .controls,
  body.printing-notes .reveal .progress { display:none !important; }
  body.printing-notes .reveal .slides section { display:none !important; }
  /* CUSTOMIZE: replace "10" with whichever slide number is this lecture's
     Pattern Notes (printable auto-generated summary) slide - the one that
     should still render, full-page, when the print button is used. */
  body.printing-notes .reveal .slides section[data-slide="56"] {
    display:flex !important; position:static !important; height:auto !important;
    width:auto !important; transform:none !important; opacity:1 !important;
  }
  body.printing-notes .notes-card { box-shadow:none !important; }
}

/* ── Title slide shortcut legend ── */
.shortcut-legend { display:grid; grid-template-columns:auto 1fr; gap:6px 12px; align-items:center; font-family:var(--sans); font-size:11px; color:var(--muted); margin-top:18px; max-width:380px; }
.shortcut-legend kbd { font-family:var(--sans); font-size:10px; font-weight:600; background:var(--offwhite); border:1px solid var(--border); border-radius:4px; padding:2px 7px; color:var(--green); min-width:14px; text-align:center; box-shadow:0 1px 0 var(--border); }
.shortcut-legend span { line-height:1.4; }
.vid-placeholder { flex-direction:column; align-items:center; justify-content:center; height:100%; color:rgba(255,255,255,0.3); }
.vid-placeholder .cam { font-size:40px; }

/* ── Video unmute affordance (S01) — muted autoplay is the only reliable
   cross-browser autoplay; sound needs an explicit tap regardless. ── */
.unmute-btn { position:absolute; bottom:14px; right:14px; z-index:5; background:rgba(0,0,0,0.55); color:#fff; border:1px solid rgba(255,255,255,0.4); border-radius:20px; padding:7px 14px; font-family:var(--sans); font-size:11px; cursor:pointer; display:flex; align-items:center; gap:6px; }
.unmute-btn:hover { background:rgba(0,0,0,0.75); }

/* ── Pattern Flip (S11 — flip-card glossary) ── */
.pattern-flip .slide-body { padding-left:40px; padding-right:40px; }
.flip-grid { display:grid; grid-template-columns:repeat(3, 1fr); gap:16px; flex:1; min-height:0; align-content:center; }
.flip-card { perspective:1000px; height:150px; cursor:pointer; }
.flip-card-inner { position:relative; width:100%; height:100%; transition:transform .5s; transform-style:preserve-3d; }
.flip-card.flipped .flip-card-inner { transform:rotateY(180deg); }
.flip-card-face { position:absolute; inset:0; backface-visibility:hidden; border-radius:10px; display:flex; flex-direction:column; align-items:center; justify-content:center; padding:14px; text-align:center; }
.flip-card-front { background:var(--offwhite); border:2px solid var(--gold); }
.flip-card-front .flip-term { font-family:var(--serif); font-size:clamp(20px,2.6vw,30px); font-weight:600; color:var(--green); }
.flip-card-front .flip-hint { font-family:var(--sans); font-size:10px; color:var(--muted); margin-top:8px; letter-spacing:.06em; text-transform:uppercase; }
.flip-card-back { background:var(--green); color:#fff; transform:rotateY(180deg); }
.flip-card-back .flip-full { font-family:var(--sans); font-weight:600; font-size:clamp(11px,1.3vw,13px); margin-bottom:6px; color:var(--gold-lt); }
.flip-card-back .flip-def { font-family:var(--sans); font-size:clamp(10px,1.2vw,12px); line-height:1.4; }

/* ── Pattern Canvas (S12 — saltatory conduction) ── */
.pattern-canvas .slide-body { padding-left:40px; padding-right:40px; }
.canvas-wrap { flex:1; min-height:0; display:flex; flex-direction:column; gap:10px; align-items:center; justify-content:center; }
#saltatory-canvas { width:100%; max-width:820px; height:auto; background:var(--offwhite); border-radius:10px; border:1px solid var(--border); }
.canvas-controls { display:flex; align-items:center; gap:16px; width:100%; max-width:820px; flex-wrap:wrap; }
.canvas-run-btn { font-family:var(--sans); font-size:12px; font-weight:500; background:var(--green); color:#fff; border:none; border-radius:6px; padding:9px 18px; cursor:pointer; }
.canvas-run-btn:hover { background:#2D6A4F; }
.canvas-slider-wrap { display:flex; align-items:center; gap:10px; flex:1; min-width:220px; }
.canvas-slider-wrap input[type=range] { flex:1; }
.canvas-slider-label { font-family:var(--sans); font-size:11px; color:var(--muted); white-space:nowrap; }
.canvas-readout { font-family:var(--sans); font-size:12px; color:var(--green); font-weight:500; width:100%; max-width:820px; text-align:center; min-height:1.4em; }

/* ── Pattern PingDemo (S14 — ping style gallery) ── */
.pattern-pingdemo .slide-body { padding-left:40px; padding-right:40px; }
.pingdemo-grid { display:grid; grid-template-columns:1.4fr 1fr; gap:24px; flex:1; min-height:0; }
.pingdemo-image-col .image-wrap { height:calc(720px - var(--hh) - 44px - 18px - 40px - 18px); }
.pingdemo-info-col { display:flex; flex-direction:column; justify-content:center; gap:12px; background:var(--offwhite); border-radius:10px; padding:24px; }
.pingdemo-label { font-family:var(--sans); font-size:15px; font-weight:600; color:var(--green); margin:0; }
.pingdemo-desc { font-family:var(--sans); font-size:13px; color:var(--text); line-height:1.5; margin:0; min-height:3.2em; }
.pingdemo-hint { font-family:var(--sans); font-size:11px; color:var(--muted); margin:10px 0 0; }
.pingdemo-footnote { font-family:var(--sans); font-size:11px; color:var(--gold); font-style:italic; line-height:1.5; margin:14px 0 0; border-top:1px solid var(--border); padding-top:12px; }

/* B: gold ripple variant — same keyframes as the red ping, just recoloured */
.ping-ring-gold { fill:none; stroke:#C9972B; stroke-width:3.5; opacity:0; pointer-events:none; }
.ping-ring-gold.go { animation:ripple-out 1.5s ease-out infinite; }
.ping-ring-gold.go.d { animation:ripple-out2 1.5s ease-out .5s infinite; }
.ping-dot-gold { fill:#C9972B; opacity:0; pointer-events:none; }
.ping-dot-gold.go { animation:beacon 1.1s ease-in-out infinite; }

/* C: hand-drawn texta circle — draws itself in once, then holds (no loop) */
.texta-circle {
  fill:none; stroke:#C9972B; stroke-width:7; stroke-linecap:round;
  stroke-dasharray:340; stroke-dashoffset:340;
  animation:texta-draw 0.7s ease-out forwards;
}
@keyframes texta-draw { to { stroke-dashoffset:0; } }

/* D: textbook arrow + label callout */
.arrow-line { stroke:#1B4332; stroke-width:3; opacity:0; animation:fade-in 0.4s ease-out forwards; }
.arrow-label { font-family:var(--sans); font-size:20px; font-weight:600; fill:#1B4332; opacity:0; animation:fade-in 0.4s ease-out 0.15s forwards; }
@keyframes fade-in { to { opacity:1; } }

/* E: pointing finger — emoji, gentle bounce toward the target */
.finger-emoji { font-size:56px; animation:finger-bounce 1s ease-in-out infinite; }
@keyframes finger-bounce { 0%,100% { transform:translateY(0); } 50% { transform:translateY(-10px); } }

/* F: soft pulsing glow, no ring — quiet spotlight instead of a beacon */
.soft-glow { animation:glow-breathe 2.2s ease-in-out infinite; transform-origin:836px 588px; }
@keyframes glow-breathe { 0%,100% { opacity:.75; transform:scale(1); } 50% { opacity:1; transform:scale(1.15); } }

/* ── Pattern Embed (S13 — links out to the Socratic tutor) ── */
.pattern-embed .slide-body { padding-left:40px; padding-right:40px; align-items:center; }
.embed-panel { flex:1; min-height:0; width:100%; max-width:900px; display:flex; flex-direction:column; gap:10px; }
.embed-frame-wrap { position:relative; flex:1; min-height:0; border:1px solid var(--border); border-radius:10px; overflow:hidden; background:var(--offwhite); }
.embed-frame-wrap iframe { width:100%; height:100%; border:none; display:block; }
/* Reveal's own base stylesheet sets `.reveal a{position:relative}` on
   every link, which outranks a plain `.embed-open-link{position:absolute}`
   rule on specificity alone (class+element beats a single class) - so
   without the .reveal prefix here, this link silently drops out of
   position. Matches the real DOM nesting, not just a specificity hack. */
.reveal .embed-open-link { position:absolute; top:10px; right:10px; background:rgba(255,255,255,0.95); border:1px solid var(--border); border-radius:6px; padding:6px 12px; font-family:var(--sans); font-size:11px; color:var(--green); text-decoration:none; font-weight:500; }
.embed-open-link:hover { background:#fff; border-color:var(--gold); }
.embed-fallback-note { font-family:var(--sans); font-size:11px; color:var(--muted); text-align:center; }

/* Slido's own widget is narrow/tall (its suggested embed code is
   300x400), unlike the tutor embed's wide panel - centre it at a modest
   width rather than stretching it to the full slide width. */
.slido-frame-wrap { max-width:460px; margin:0 auto; width:100%; }
/* MS Forms renders a bit cramped at Slido's narrower width for even a
   simple question (title + question text + options all need room) -
   a moderate width, still centred, rather than the full 900px panel. */
.msforms-frame-wrap { max-width:640px; margin:0 auto; width:100%; }

/* ── Pattern Widget (S15 — embedded interactive widget, e.g. VEP averaging) ── */
.pattern-widget .slide-body { padding-left:40px; padding-right:40px; align-items:center; }
.widget-frame-wrap { flex:1; min-height:0; width:100%; max-width:1000px; border-radius:10px; overflow:hidden; border:1px solid var(--border); }
.widget-frame-wrap iframe { width:100%; height:100%; border:none; display:block; }
.widget-fallback-note { font-family:var(--sans); font-size:11px; color:var(--muted); text-align:center; margin:10px 0 0; flex-shrink:0; }
.widget-fallback-note a { color:var(--green); font-weight:500; }
.widget-fallback-note code { background:var(--offwhite); padding:1px 5px; border-radius:4px; font-size:10px; }

/* ── Pattern Table (S16 — comparison table; reuses list-card active/past mechanics) ── */
.pattern-table .slide-body { padding-left:40px; padding-right:40px; justify-content:center; }
.compare-header, .compare-row { display:grid; grid-template-columns:1fr 1.15fr 1.15fr; gap:16px; align-items:center; }
.compare-header { padding:0 20px 10px; }
.compare-header span { font-family:var(--sans); font-size:11px; font-weight:600; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
.compare-row .compare-feature { font-family:var(--sans); font-size:13px; font-weight:600; color:var(--green); }
.compare-row .compare-val { font-family:var(--sans); font-size:13px; color:var(--text); line-height:1.4; }
.compare-table-body { display:flex; flex-direction:column; gap:10px; }

/* ── Pattern Vignette (S17 — case vignette) ── */
.pattern-vignette .slide-body { padding-left:64px; padding-right:64px; justify-content:center; }
.vignette-card { background:var(--offwhite); border-left:4px solid #4A6FA5; border-radius:0 8px 8px 0; padding:20px 24px; margin-bottom:20px; }
.vignette-eyebrow { font-family:var(--sans); font-size:10px; font-weight:600; letter-spacing:.12em; text-transform:uppercase; color:#4A6FA5; margin:0 0 8px; }
.vignette-text { font-family:var(--serif); font-style:italic; font-size:clamp(14px,1.7vw,18px); color:var(--text); line-height:1.55; margin:0; }
.vignette-rule-box { background:#FDF8EC; border:1.5px solid var(--gold); border-radius:8px; padding:16px 20px; }
.vignette-rule-label { font-family:var(--sans); font-size:10px; font-weight:600; letter-spacing:.1em; text-transform:uppercase; color:var(--gold); margin:0 0 6px; }
.vignette-rule-text { font-family:var(--sans); font-size:14px; color:var(--text); line-height:1.5; margin:0; }

/* ── Pattern GradedLoc (S18 — graded localization; reuses Explore's hotspot mechanics) ── */
.pattern-gradedloc .slide-body { padding-left:40px; padding-right:40px; }
.gradedloc-grid { display:grid; grid-template-columns:1.2fr 1fr; gap:24px; flex:1; min-height:0; }
.gradedloc-image-col .image-wrap { height:calc(720px - var(--hh) - 44px - 18px - 40px - 18px); position:relative; }
.gradedloc-hotspot { cursor:pointer; }
.gradedloc-hotspot .hotspot-hit { fill:transparent; }
.gradedloc-hotspot .hotspot-badge { fill:var(--green); stroke:#fff; stroke-width:3; transition:fill .2s; }
.gradedloc-hotspot.correct .hotspot-badge { fill:var(--gold); r:19; }
.gradedloc-hotspot.wrong .hotspot-badge { fill:var(--wrong); }
.gradedloc-hotspot text { fill:#fff; font-family:var(--sans); font-weight:700; font-size:22px; text-anchor:middle; dominant-baseline:central; pointer-events:none; }
.gradedloc-result-col { display:flex; flex-direction:column; justify-content:center; gap:14px; background:var(--offwhite); border-radius:10px; padding:24px; }
.gradedloc-question { font-family:var(--serif); font-size:clamp(14px,1.7vw,18px); color:var(--text); line-height:1.4; margin:0; }
.gradedloc-feedback { font-family:var(--sans); font-size:13px; line-height:1.5; padding:12px 16px; border-radius:6px; display:none; }
.gradedloc-feedback.show { display:block; }
.gradedloc-feedback.correct { background:#EBF5EE; border-left:4px solid var(--correct); color:#0f3320; }
.gradedloc-feedback.wrong { background:#F5EBEB; border-left:4px solid var(--wrong); color:#3a0f0f; }

/* ── Pattern NumericCheck (S19 — short-answer/numeric recall, local checking only) ── */
.pattern-numeric .slide-body { padding-left:64px; padding-right:64px; justify-content:center; }
.numeric-input-row { display:flex; align-items:center; gap:12px; margin:16px 0; }
.numeric-input-row input { font-family:var(--sans); font-size:16px; padding:10px 14px; border:1.5px solid var(--border); border-radius:8px; width:120px; }
.numeric-input-row input:focus { outline:none; border-color:var(--gold); }
.numeric-input-row span { font-family:var(--sans); font-size:14px; color:var(--muted); }
.numeric-check-btn { font-family:var(--sans); font-size:12px; font-weight:500; background:var(--green); color:#fff; border:none; border-radius:6px; padding:9px 18px; cursor:pointer; }
.numeric-check-btn:hover { background:#2D6A4F; }

/* ── Pattern Waveform (S20 — annotated waveform reveal; static/vector, distinct from the S15 live simulation) ── */
.pattern-waveform .slide-body { padding-left:40px; padding-right:40px; align-items:center; }
.waveform-svg { width:100%; max-width:700px; }
.waveform-path { fill:none; stroke:var(--green); stroke-width:3; }
.waveform-label-group { opacity:0; transition:opacity .4s; }
.waveform-label-group.show { opacity:1; }
.waveform-label-group text { font-family:var(--sans); font-size:15px; font-weight:600; fill:#8a6314; }
.waveform-label-group line { stroke:var(--gold); stroke-width:1.5; stroke-dasharray:3,3; }
.waveform-label-group circle { fill:var(--gold); }

/* ── Pattern Confidence (S21 — confidence rating + MCQ; extends pattern-e) ── */
.confidence-row { display:flex; gap:10px; margin:16px 0; }
.confidence-btn { font-family:var(--sans); font-size:12px; font-weight:500; background:var(--offwhite); border:1.5px solid var(--border); border-radius:20px; padding:8px 18px; cursor:pointer; transition:border-color .2s,background .2s; }
.confidence-btn:hover { border-color:var(--gold); }
.confidence-btn.selected { border-color:var(--gold); background:#FDF8EC; font-weight:600; color:#8a6314; }
.confidence-mcq-options { opacity:.35; pointer-events:none; transition:opacity .3s; }
.confidence-mcq-options.enabled { opacity:1; pointer-events:auto; }

/* ── Pattern Branch (S22 — simplified single-slide branching scenario demo) ── */
.pattern-branch .slide-body { padding-left:64px; padding-right:64px; }
.branch-choice-row { display:flex; gap:12px; margin:16px 0; }
.branch-choice-btn { font-family:var(--sans); font-size:13px; font-weight:500; background:var(--offwhite); border:1.5px solid var(--gold); border-radius:8px; padding:12px 22px; cursor:pointer; color:var(--green); transition:background .2s; }
.branch-choice-btn:hover { background:#FDF8EC; }
.branch-choice-btn.chosen { background:var(--green); color:#fff; border-color:var(--green); }
.branch-outcome { background:var(--offwhite); border-left:4px solid var(--green); border-radius:0 8px 8px 0; padding:16px 20px; margin-top:12px; display:none; }
.branch-outcome.show { display:block; }
.branch-outcome p { font-family:var(--sans); font-size:14px; color:var(--text); line-height:1.5; margin:0; }
.branch-followup { margin-top:14px; }
