/* ============================================================
   Motion layer — "Energetic", restrained.
   Per the motion-design skill: serves the beat, never fights
   legibility (CLAUDE.md Art. 5). Auto-disabled in ?export (clean
   PDFs) and under prefers-reduced-motion.

   Brand motion identity:
     · signature easing  → expo-out (snappy decelerate)
     · duration palette  → quick / standard / slow
     · entrance pattern  → rise 26px + fade
   ============================================================ */

:root {
  --ease-sig:    cubic-bezier(0.16, 1, 0.3, 1);        /* expo-out */
  --ease-bounce: cubic-bezier(0.175, 0.885, 0.32, 1.275);
  --dur-quick:    160ms;
  --dur-standard: 340ms;
  --dur-slow:     640ms;
}

/* ---- keyframes ---- */
@keyframes riseIn   { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }
@keyframes popIn    { 0% { opacity: 0; transform: scale(0.82); } 65% { opacity: 1; transform: scale(1.05); } 100% { transform: none; } }
@keyframes drawStrike { from { transform: rotate(-2.5deg) scaleX(0); } to { transform: rotate(-2.5deg) scaleX(1); } }
@keyframes qrGlow {
  0%, 100% { box-shadow: 0 0 0 1px var(--line-color), 0 16px 44px rgba(34, 211, 238, 0.16); }
  50%      { box-shadow: 0 0 0 1px var(--line-color), 0 22px 66px rgba(34, 211, 238, 0.38); }
}
@keyframes cursorBlink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

/* ============================================================
   ENTRANCE CHOREOGRAPHY — plays when a slide becomes .present
   Grouped (not per-word) to respect the 1/3 "elements in motion"
   rule and keep total stagger < 500ms.
   ============================================================ */

/* Content slides: eyebrow → title → body, three beats */
.reveal section.present:not(.section-divider) > .eyebrow { animation: riseIn var(--dur-standard) var(--ease-sig) both; }
.reveal section.present:not(.section-divider) > h2       { animation: riseIn var(--dur-standard) var(--ease-sig) both; animation-delay: 80ms; }
.reveal section.present:not(.section-divider) > .content { animation: riseIn var(--dur-slow)     var(--ease-sig) both; animation-delay: 150ms; }

/* Section dividers: eyebrow lifts, then the title rises slower */
.reveal section.section-divider.present:not(#title) > .eyebrow { animation: riseIn var(--dur-standard) var(--ease-sig) both; }
.reveal section.section-divider.present:not(#title) > h1       { animation: riseIn var(--dur-slow) var(--ease-sig) both; animation-delay: 90ms; }

/* Title slide: hero content rises in a stagger; the command "types" the title */
.reveal #title.present .title-hero > * { animation: riseIn var(--dur-slow) var(--ease-sig) both; }
.reveal #title.present .eyebrow      { animation-delay: 40ms; }
.reveal #title.present .title-cmd    { animation-delay: 120ms; }
.reveal #title.present .title-gradient { animation-delay: 280ms; }
.reveal #title.present .title-sub    { animation-delay: 420ms; }
.reveal #title.present .speaker-chip { animation-delay: 540ms; }
.reveal #title.present .title-lang-hint { animation-delay: 640ms; }
/* Ambient: the code glyphs drift slowly (frozen in export / reduced-motion) */
.reveal #title.present .glyph { animation: glyphFloat 9s ease-in-out infinite both; }
.reveal #title.present .glyph.g2 { animation-delay: -2s; }
.reveal #title.present .glyph.g3 { animation-delay: -4s; }
.reveal #title.present .glyph.g4 { animation-delay: -1s; }
.reveal #title.present .glyph.g5 { animation-delay: -5s; }
.reveal #title.present .glyph.g6 { animation-delay: -3s; }
.reveal #title.present .glyph.g7 { animation-delay: -6s; }
.reveal #title.present .glyph.g8 { animation-delay: -2.5s; }
@keyframes glyphFloat { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-16px); } }

/* ---- Hero beats (secondary layer) ---- */

/* The turn: the strike DRAWS through "esa charla" after the line lands */
.reveal #turn.present .strike::after {
  transform-origin: left center;
  animation: drawStrike 440ms var(--ease-sig) both;
  animation-delay: 640ms;
}

/* Judgment: the stat that stings pops in */
.reveal #judgment.present .stat-num {
  animation: popIn var(--dur-slow) var(--ease-bounce) both;
  animation-delay: 220ms;
}

/* Evolution: the three cards cascade (cards are single, not i18n-duplicated) */
.reveal #evolution.present .card { animation: riseIn var(--dur-standard) var(--ease-sig) both; }
.reveal #evolution.present .card:nth-child(1) { animation-delay: 200ms; }
.reveal #evolution.present .card:nth-child(2) { animation-delay: 280ms; }
.reveal #evolution.present .card:nth-child(3) { animation-delay: 360ms; }

/* Coherence: the REPL output snaps in just after the prompt */
.reveal #coherence.present .repl-out { animation: riseIn var(--dur-standard) var(--ease-sig) both; animation-delay: 500ms; }

/* ---- Ambient layer (closing) ---- */
.reveal #thanks.present .qr-card { animation: qrGlow 3.4s ease-in-out infinite; }

/* Terminal cursors — ambient blink (title wink + the REPL prompt) */
.cursor { animation: cursorBlink 1.1s steps(1) infinite; }

/* ============================================================
   FRAGMENT polish — reveal.js handles the reveal; we match the
   house easing. (Built-in fade-up classes used in the HTML.)
   ============================================================ */
.reveal .slides section .fragment.fade-up { transition: all var(--dur-standard) var(--ease-sig); }

/* ---- Gates: the rubric builds row by row (the next slide sweeps it away) ---- */
.reveal #gates.present > .content { animation: none; }
.reveal #gates.present .gates-table tbody tr { animation: fadeIn var(--dur-standard) ease-out both; }
.reveal #gates.present .gates-table tbody tr:nth-child(1) { animation-delay: 180ms; }
.reveal #gates.present .gates-table tbody tr:nth-child(2) { animation-delay: 250ms; }
.reveal #gates.present .gates-table tbody tr:nth-child(3) { animation-delay: 320ms; }
.reveal #gates.present .gates-table tbody tr:nth-child(4) { animation-delay: 390ms; }

/* ---- Section dividers: an underline draws in (recurring motif; not the title) ---- */
.reveal section.section-divider:not(#title) h1 { position: relative; }
.reveal section.section-divider:not(#title) h1::after {
  content: ''; display: block; height: 4px; width: 116px; margin: 22px auto 0;
  border-radius: 3px; transform-origin: center;   /* full width by default → export-safe */
  background: linear-gradient(90deg, var(--primary-color), var(--accent-color));
}
.reveal section.section-divider.present:not(#title) h1::after { animation: drawX 460ms var(--ease-sig) both; animation-delay: 340ms; }
@keyframes drawX { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* ---- Coherence: the REPL "evaluates" — a fresh prompt blinks after the result ---- */
.reveal #coherence.present .repl-next { animation: fadeIn var(--dur-quick) ease-out both; animation-delay: 820ms; }

/* ---- Closing: a one-time scan sweep over the QR, then it rests (stays scannable) ---- */
.reveal #thanks.present .qr-scan { animation: qrScan 1150ms var(--ease-sig) 480ms 1 both; }
@keyframes qrScan { from { transform: translateY(-115%); } to { transform: translateY(280%); } }

/* ---- Automating: the pipeline builds left-to-right, then the honest qualifier ---- */
.reveal #automating.present > .content { animation: none; }
.reveal #automating.present .pipe-step,
.reveal #automating.present .pipe-arrow { animation: riseIn var(--dur-standard) var(--ease-sig) both; }
.reveal #automating.present .pipe > :nth-child(1) { animation-delay: 150ms; }
.reveal #automating.present .pipe > :nth-child(2) { animation-delay: 190ms; }
.reveal #automating.present .pipe > :nth-child(3) { animation-delay: 230ms; }
.reveal #automating.present .pipe > :nth-child(4) { animation-delay: 270ms; }
.reveal #automating.present .pipe > :nth-child(5) { animation-delay: 310ms; }
.reveal #automating.present .pipe > :nth-child(6) { animation-delay: 350ms; }
.reveal #automating.present .pipe > :nth-child(7) { animation-delay: 390ms; }
.reveal #automating.present .pipe > :nth-child(8) { animation-delay: 430ms; }
.reveal #automating.present .pipe > :nth-child(9) { animation-delay: 470ms; }
.reveal #automating.present .qualifier { animation: riseIn var(--dur-standard) var(--ease-sig) both; animation-delay: 540ms; }

/* ---- Adoption + Tools + Rationing: the three cards cascade ---- */
.reveal #adoption.present > .content,
.reveal #tools.present > .content,
.reveal #rationing.present > .content { animation: none; }
.reveal #adoption.present .card,
.reveal #tools.present .card,
.reveal #rationing.present .card { animation: riseIn var(--dur-standard) var(--ease-sig) both; }
.reveal #adoption.present .card:nth-child(1),
.reveal #tools.present .card:nth-child(1),
.reveal #rationing.present .card:nth-child(1) { animation-delay: 180ms; }
.reveal #adoption.present .card:nth-child(2),
.reveal #tools.present .card:nth-child(2),
.reveal #rationing.present .card:nth-child(2) { animation-delay: 260ms; }
.reveal #adoption.present .card:nth-child(3),
.reveal #tools.present .card:nth-child(3),
.reveal #rationing.present .card:nth-child(3) { animation-delay: 340ms; }

/* ---- Cynefin: the four domains cascade (Complex first) ---- */
.reveal #cynefin.present > .content { animation: none; }
.reveal #cynefin.present .cyn { animation: riseIn var(--dur-standard) var(--ease-sig) both; }
.reveal #cynefin.present .cyn:nth-child(1) { animation-delay: 160ms; }
.reveal #cynefin.present .cyn:nth-child(2) { animation-delay: 230ms; }
.reveal #cynefin.present .cyn:nth-child(3) { animation-delay: 300ms; }
.reveal #cynefin.present .cyn:nth-child(4) { animation-delay: 370ms; }

/* ---- Welcome: the match fixture pops in ---- */
.reveal #welcome.present .fixture { animation: popIn var(--dur-slow) var(--ease-bounce) both; animation-delay: 260ms; }

/* ---- Flashlight vote: the two poles pop in, energetic (loud, collective) ---- */
.reveal .flashlight-vote.present .pole { animation: popIn var(--dur-standard) var(--ease-bounce) both; }
.reveal .flashlight-vote.present .pole-on  { animation-delay: 200ms; }
.reveal .flashlight-vote.present .pole-vs  { animation: riseIn var(--dur-quick) var(--ease-sig) both; animation-delay: 320ms; }
.reveal .flashlight-vote.present .pole-off { animation-delay: 380ms; }

/* ---- Bookend: the missing row glows in after the dimmed four ---- */
.reveal #bookend.present .gate-new { animation: riseIn var(--dur-slow) var(--ease-sig) both; animation-delay: 260ms; }

/* ============================================================
   KILL SWITCHES — clean exports + accessibility
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .reveal *, .reveal *::before, .reveal *::after { animation: none !important; }
}

html[data-export] .reveal *,
html[data-export] .reveal *::before,
html[data-export] .reveal *::after {
  animation: none !important;
  transition: none !important;
}
/* Belt-and-suspenders: fragments always visible in the exported PDF */
html[data-export] .reveal .fragment { opacity: 1 !important; transform: none !important; visibility: visible !important; }
/* Keep the exported QR pristine — no scan overlay in the PDF */
html[data-export] .qr-scan { display: none; }
