/* ══════════════════════════════════════════════════════════════
   MMGY MOTION LAYER
   Entrance animations + click-through build steps.

   Two ideas, and only two:

   1. .fx           — an element animates in when its SLIDE becomes active.
                      Stagger siblings with .fx-1 … .fx-12.
                      Choose the motion with a .fx--* modifier.

   2. [data-step]   — an element stays hidden until the presenter CLICKS.
                      Put data-steps on the <section> to turn the slide into
                      a build. Steps animate with the same .fx-- vocabulary.

   Rules of the system (do not break these):
   • The VISIBLE state is the base style. We animate *from* hidden, never to
     it — so print, reduced-motion and no-JS all show finished content.
   • Nothing loops forever on slide content. Ambient loops are reserved for
     status affordances (the hotspot pulse) and are disabled at print.
   • Motion is fast and confident: 0.6–0.9s, one easing curve.
     Never fade something in over two seconds. This is a pitch, not a screensaver.
   ══════════════════════════════════════════════════════════════ */

:root {
  --fx-dur: 0.7s;
  --fx-dur-slow: 0.95s;
  --fx-ease: cubic-bezier(0.2, 0.7, 0.2, 1);   /* decisive out-quint-ish */
  --fx-ease-draw: cubic-bezier(0.6, 0, 0.4, 1); /* for line draws          */
  --fx-shift: 48px;                             /* default travel distance */
}

/* ── The motions ─────────────────────────────────────────────── */
@keyframes fx-up    { from { opacity: 0; transform: translateY(var(--fx-shift)); } to { opacity: 1; transform: none; } }
@keyframes fx-down  { from { opacity: 0; transform: translateY(calc(-1 * var(--fx-shift))); } to { opacity: 1; transform: none; } }
@keyframes fx-left  { from { opacity: 0; transform: translateX(-64px); } to { opacity: 1; transform: none; } }
@keyframes fx-right { from { opacity: 0; transform: translateX(64px); }  to { opacity: 1; transform: none; } }
@keyframes fx-in    { from { opacity: 0; } to { opacity: 1; } }
@keyframes fx-scale { from { opacity: 0; transform: scale(1.06); } to { opacity: 1; transform: none; } }
/* Wipes — the signature MMGY reveal. Content is uncovered, not faded. */
@keyframes fx-wipe    { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes fx-wipe-up { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes fx-wipe-dn { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
/* Rules and bars growing from their origin */
@keyframes fx-grow-x { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes fx-grow-y { from { transform: scaleY(0); } to { transform: scaleY(1); } }
/* SVG stroke draw — pair with .fx--draw on a <path> that has a --len set,
   or let mmgy-deck.js measure it for you. */
@keyframes fx-draw { from { stroke-dashoffset: var(--len, 1000); } to { stroke-dashoffset: 0; } }

/* ── 1. Slide-entrance animations ────────────────────────────── */
/* `backwards`, not `both` — see the note on the step rule below. A finished
   animation with `both` squats on the computed value from the animation
   origin, which no author rule can override. */
[data-deck-active] .fx { animation: fx-up var(--fx-dur) var(--fx-ease) backwards; }

[data-deck-active] .fx--down    { animation-name: fx-down; }
[data-deck-active] .fx--left    { animation-name: fx-left; }
[data-deck-active] .fx--right   { animation-name: fx-right; }
[data-deck-active] .fx--in      { animation-name: fx-in; }
[data-deck-active] .fx--scale   { animation-name: fx-scale; }
[data-deck-active] .fx--wipe    { animation-name: fx-wipe;    animation-duration: var(--fx-dur-slow); }
[data-deck-active] .fx--wipe-up { animation-name: fx-wipe-up; animation-duration: var(--fx-dur-slow); }
[data-deck-active] .fx--wipe-dn { animation-name: fx-wipe-dn; animation-duration: var(--fx-dur-slow); }
[data-deck-active] .fx--grow-x  { animation-name: fx-grow-x; transform-origin: left center; }
[data-deck-active] .fx--grow-y  { animation-name: fx-grow-y; transform-origin: bottom center; }
[data-deck-active] .fx--draw    { animation-name: fx-draw; animation-duration: 1.4s; animation-timing-function: var(--fx-ease-draw); }

/* Travel distance modifiers */
.fx--near { --fx-shift: 20px; }
.fx--far  { --fx-shift: 96px; }

/* Stagger. 120ms apart — quick enough to read as one gesture. */
[data-deck-active] .fx-1  { animation-delay: .10s; }
[data-deck-active] .fx-2  { animation-delay: .22s; }
[data-deck-active] .fx-3  { animation-delay: .34s; }
[data-deck-active] .fx-4  { animation-delay: .46s; }
[data-deck-active] .fx-5  { animation-delay: .58s; }
[data-deck-active] .fx-6  { animation-delay: .70s; }
[data-deck-active] .fx-7  { animation-delay: .82s; }
[data-deck-active] .fx-8  { animation-delay: .94s; }
[data-deck-active] .fx-9  { animation-delay: 1.06s; }
[data-deck-active] .fx-10 { animation-delay: 1.18s; }
[data-deck-active] .fx-11 { animation-delay: 1.30s; }
[data-deck-active] .fx-12 { animation-delay: 1.42s; }

/* Auto-stagger: put .fx-auto on a container and every direct child with .fx
   picks up an index-based delay. mmgy-deck.js sets --i. */
[data-deck-active] .fx-auto > .fx { animation-delay: calc(.10s + var(--i, 0) * .09s); }

/* ══════════════════════════════════════════════════════════════
   2. CLICK-THROUGH BUILDS
   ══════════════════════════════════════════════════════════════
   <section class="slide" data-steps>
     <h2 class="t-display t-h3">Always visible</h2>
     <div data-step>Revealed on click 1</div>
     <div data-step class="fx--left">Revealed on click 2</div>
     <div data-step="2">Also click 2 — same number groups elements</div>
     <p data-step-until="2">Disappears once step 2 arrives</p>
   </section>

   Numbering: bare data-step auto-numbers in DOM order; an explicit
   data-step="N" pins the element to that beat and resets the auto counter,
   so you can interleave freely. mmgy-deck.js normalises both on load.
   ────────────────────────────────────────────────────────────── */

/* Hidden until reached. visibility keeps it out of the a11y tree and
   stops it catching clicks; opacity does the visual work. */
[data-steps] [data-step]:not([data-step-on]) {
  opacity: 0;
  visibility: hidden;
}
/* Suppress descendant entrance animations while the step is closed, so
   they replay from the top when the step opens (changing animation-name
   away from `none` restarts the animation — that's the whole trick). */
[data-steps] [data-step]:not([data-step-on]) * { animation: none !important; }

/* The reveal itself. Higher specificity than the .fx rules above so a
   step always wins over a slide-entrance animation on the same element.

   fill-mode is `backwards`, NOT `both`, and that matters: a finished
   animation with `both` keeps applying its `to` frame from the animation
   origin, which outranks every author declaration — so `opacity:.28` from
   data-step-dim below could never take effect. `backwards` covers the delay
   and then hands the element back to its base style, which is already the
   visible one. */
[data-deck-active][data-steps] [data-step][data-step-on] {
  animation: fx-up var(--fx-dur) var(--fx-ease) backwards;
}
[data-deck-active][data-steps] [data-step][data-step-on].fx--down    { animation-name: fx-down; }
[data-deck-active][data-steps] [data-step][data-step-on].fx--left    { animation-name: fx-left; }
[data-deck-active][data-steps] [data-step][data-step-on].fx--right   { animation-name: fx-right; }
[data-deck-active][data-steps] [data-step][data-step-on].fx--in      { animation-name: fx-in; }
[data-deck-active][data-steps] [data-step][data-step-on].fx--scale   { animation-name: fx-scale; }
[data-deck-active][data-steps] [data-step][data-step-on].fx--wipe    { animation-name: fx-wipe;    animation-duration: var(--fx-dur-slow); }
[data-deck-active][data-steps] [data-step][data-step-on].fx--wipe-up { animation-name: fx-wipe-up; animation-duration: var(--fx-dur-slow); }
[data-deck-active][data-steps] [data-step][data-step-on].fx--wipe-dn { animation-name: fx-wipe-dn; animation-duration: var(--fx-dur-slow); }
[data-deck-active][data-steps] [data-step][data-step-on].fx--grow-x  { animation-name: fx-grow-x; transform-origin: left center; }
[data-deck-active][data-steps] [data-step][data-step-on].fx--grow-y  { animation-name: fx-grow-y; transform-origin: bottom center; }
[data-deck-active][data-steps] [data-step][data-step-on].fx--draw    { animation-name: fx-draw; animation-duration: 1.4s; animation-timing-function: var(--fx-ease-draw); }
/* Steps land instantly by default; .fx-N still works to offset within a beat. */

/* Elements that retire as the build progresses. */
[data-steps] [data-step-until][data-step-spent] {
  opacity: 0;
  visibility: hidden;
  transition: opacity .45s var(--fx-ease), visibility .45s;
}
[data-steps] [data-step-until] { transition: opacity .45s var(--fx-ease); }

/* Dimming instead of hiding: the previous beat greys back so the new one
   reads as current. Use on list rows and numbered columns. */
[data-steps] [data-step-dim] { transition: opacity .45s var(--fx-ease); }
[data-steps] [data-step-dim][data-step-spent] { opacity: .28; }

/* ── Build progress ticks (optional) ─────────────────────────────
   Rendered into <div class="build-ticks"></div> by mmgy-deck.js on any
   slide that has steps. Sits with the slide, not the chrome. */
.build-ticks { display: flex; gap: 10px; align-items: center; }
.build-ticks__tick {
  width: 28px; height: 4px; background: currentColor; opacity: .22;
  transition: opacity .3s, background-color .3s;
}
.build-ticks__tick.is-on { background: var(--mmgy-red); opacity: 1; }

/* ── Accessibility & output safety ───────────────────────────────
   Reduced motion: no travel, no wipes. Content still appears, instantly.
   Print: everything on, everything still. Steps are fully built so a PDF
   of a build slide shows the finished thought.                            */
@media (prefers-reduced-motion: reduce) {
  [data-deck-active] .fx,
  [data-deck-active][data-steps] [data-step][data-step-on] {
    animation: fx-in .01s backwards !important;
  }
  .hot__dot::after { animation: none !important; }
}

@media print {
  .fx,
  [data-steps] [data-step],
  [data-steps] [data-step-until],
  [data-steps] [data-step-dim] {
    animation: none !important;
    transition: none !important;
    opacity: 1 !important;
    visibility: visible !important;
    transform: none !important;
    clip-path: none !important;
  }
  .build-ticks { display: none !important; }
}
