/* Ush Kutchum . css/fx.css : motion. Linked with media="(prefers-reduced-motion: no-preference)", so everything here is optional.
   The static end states of every effect live in app.css; this file only adds movement. Only transform and opacity animate.
   Sections are owned by the later steps (E2 core and effects, E3 intro, story, simulator). Add rules inside your own section.
   Quality gating: html[data-fx="0"] and html[data-fx="1"] switch the heavier effects off (written by js/boot.js and js/ush-core.js). */

/* A . shared keyframes (names are the contract; later steps fill and reuse them) ------------------ */
@keyframes shimmer{0%{background-position:120% 0}100%{background-position:-120% 0}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.45}}
@keyframes pop{0%{transform:translateY(-6px) scale(.98);opacity:.2}100%{transform:none;opacity:1}}
@keyframes flip{0%{transform:rotateY(90deg) scale(.9);opacity:0}100%{transform:none;opacity:1}}
@keyframes flash{0%{opacity:0}25%{opacity:.35}100%{opacity:0}}
@keyframes burst{0%{transform:scale(1)}40%{transform:scale(1.06)}100%{transform:scale(1.14)}}
@keyframes shake{0%,100%{transform:translateX(0) rotate(0)}20%{transform:translateX(-5px) rotate(-1.5deg)}40%{transform:translateX(5px) rotate(1.5deg)}60%{transform:translateX(-4px) rotate(-1deg)}80%{transform:translateX(4px) rotate(1deg)}}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}
@keyframes march{to{background-position:24px 0}}
@keyframes draw{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}
@keyframes drift{0%{transform:translate3d(0,-8px,0) rotate(0)}100%{transform:translate3d(10px,12px,0) rotate(40deg)}}
@keyframes toast-in{from{transform:translateY(10px);opacity:0}to{transform:none;opacity:1}}
@keyframes ice-in{from{opacity:0}to{opacity:1}}
@keyframes ice-out{from{opacity:1}to{opacity:0}}
/* filled by later steps: coin-fall (story beat 1), embers and lick (burn), crack (thaw), sweep (strip) */

/* B . skeletons and live indicators (E1) ------------------------------------------------------------ */
html:not([data-fx="0"]) .banner-slot::before,html:not([data-fx="0"]) .stats:empty::before{background-image:linear-gradient(100deg,transparent 30%,rgba(255,255,255,.07) 50%,transparent 70%);background-size:200% 100%;animation:shimmer 1.6s linear infinite}
html:not([data-fx="0"]) .dot:not(.idle){animation:pulse 2.4s ease-in-out infinite}
html:not([data-fx="0"]) .chip-now .dot{animation:pulse 1.4s ease-in-out infinite}
html:not([data-fx="0"]) .card.flip{animation:flip .9s var(--ease-out)}
html:not([data-fx="0"]) .hero .bubble{animation:pop .6s var(--spring) both}
html:not([data-fx="0"]) .scrib use{stroke-dasharray:1;stroke-dashoffset:0}
.draw use{animation:draw .9s var(--ease-out) both}

/* C . intro (E3 owns this section; the static composition is in app.css) ------------------------------ */
html:not([data-fx="0"]) .intro-hint{animation:pulse 2s ease-in-out infinite}
html:not([data-fx="0"]) .tear-line{border-top-color:transparent;background:repeating-linear-gradient(90deg,rgba(255,255,255,.85) 0 12px,transparent 12px 24px) 0 0/auto 3px no-repeat;height:3px;border:0;animation:march .9s linear infinite}
html:not([data-fx="0"]) .tear-arrow{animation:bob 1.4s ease-in-out infinite}
.if img{pointer-events:none;-webkit-user-drag:none}
#intro.shake .intro-frame{animation:shake .45s ease-in-out}
#intro.ripped .intro-frame{animation:burst .55s var(--ease-out) both}
#intro.ripped .flash{animation:flash .22s ease-out both}

/* D . scroll story (E3 owns this section: camera, overlay layers per stage[data-beat], badge) -------------
   Layers live inside #stage (built by js/ush-story.js, aria-hidden). Only transform and opacity animate; animations run only for the active
   beat and only at effects level 2 or 3 (js/ush-story.js keeps .fx2 on the stage); at level 0 and 1 the layers are hidden and the camera jumps. */
@keyframes coin-fall{0%{transform:translateY(0) rotate(0);opacity:0}10%{opacity:1}100%{transform:translateY(105vh) rotate(260deg);opacity:1}}
@keyframes lock-drop{from{transform:translateY(-140%) rotate(-12deg);opacity:0}to{transform:none;opacity:1}}
@keyframes ray{0%,100%{transform:rotate(calc(var(--i)*36deg)) scaleY(.55);opacity:.55}50%{transform:rotate(calc(var(--i)*36deg)) scaleY(1);opacity:1}}
@keyframes bill-fly{0%{transform:translate(0,0) rotate(0);opacity:0}15%{opacity:1}100%{transform:translate(190px,-170px) rotate(28deg);opacity:0}}
@keyframes coin-flow{0%{transform:translateX(0) scale(1);opacity:0}15%{opacity:1}100%{transform:translateX(250px) scale(.4);opacity:0}}
@keyframes lick{0%{transform:scaleY(.82) skewX(-3deg)}100%{transform:scaleY(1.12) skewX(3deg)}}
@keyframes ember{0%{transform:translateY(0);opacity:0}15%{opacity:1}100%{transform:translateY(-6000%);opacity:0}}
@keyframes stamp-in{from{transform:rotate(-8deg) scale(1.9);opacity:0}to{transform:rotate(-8deg) scale(1);opacity:1}}
.stage-img{transition:transform 1.1s var(--ease-out)}
.story-stage:not(.fx2) .stage-img{transition:none}
.sg{position:absolute;inset:0;overflow:hidden;pointer-events:none}
.sg-clock{position:absolute;left:14px;top:14px;display:flex;align-items:baseline;gap:8px;padding:6px 14px;border:2px solid var(--text);border-radius:var(--wonky);background:var(--panel);color:var(--text);transform:rotate(-3deg);box-shadow:var(--shadow-2)}
.sg-clock b{font:400 30px/1 var(--f-display);font-variant-numeric:tabular-nums}
.sg-clock .marker{font-size:16px;color:var(--grape-t)}
.sg-l{position:absolute;inset:0;opacity:0;transition:opacity .5s var(--ease-out)}
.story-stage:not(.fx2) .sg-l{display:none}
.story-stage[data-beat="1"] .sg-l1,.story-stage[data-beat="2"] .sg-l2,.story-stage[data-beat="3"] .sg-l3,.story-stage[data-beat="4"] .sg-l4,.story-stage[data-beat="5"] .sg-l5,.story-stage[data-beat="6"] .sg-l6{opacity:1}
.sg-flake,.sg-lock,.sg-star,.sg-arrow,.sg-flame{fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.sg-coin,.sg-flow{position:absolute;top:-8%;left:calc(var(--i)*12% + 6%);width:30px;height:30px;border-radius:50%;background:var(--foil-gold);border:2px solid var(--gold-edge);color:var(--on-gold);font:400 17px/26px var(--f-display);text-align:center}
.sg-vig{position:absolute;inset:0;background:radial-gradient(closest-side,transparent 55%,rgba(127,227,255,.4))}
.sg-flake{position:absolute;left:calc(6% + var(--i)*15%);top:calc(8% + var(--i)*12%);width:26px;height:26px;color:var(--ice-t)}
.sg-lock{position:absolute;left:50%;top:14%;width:72px;height:72px;margin-left:-36px;color:var(--text)}
.sg-rib{position:absolute;left:-6%;right:-6%;bottom:14%;padding:8px;text-align:center;background:var(--tint-ice);color:var(--ice-t);border-block:2px solid var(--ice-t);font:400 22px/1 var(--f-display);text-transform:uppercase;letter-spacing:.06em;transform:rotate(-4deg)}
.sg-spot{position:absolute;left:0;top:0;translate:var(--fx,0px) var(--fy,0px);width:80%;aspect-ratio:1;margin:-40% 0 0 -40%;background:radial-gradient(closest-side,rgba(255,255,255,.5),rgba(255,95,162,.25) 45%,transparent 70%)}
.sg-burst{position:absolute;left:0;top:0;translate:var(--fx,0px) var(--fy,0px)}
.sg-burst i{position:absolute;left:-2px;top:-130px;width:4px;height:80px;border-radius:2px;background:linear-gradient(var(--foil-gold),transparent);transform-origin:50% 130px;transform:rotate(calc(var(--i)*36deg))}
.sg-star{position:absolute;width:34px;height:34px;color:var(--foil-gold);left:0;top:0;translate:calc(var(--fx,0px) + var(--i)*64px - 100px) calc(var(--fy,0px) - 120px + var(--i)*34px)}
.sg-bill{position:absolute;left:40%;top:56%;width:72px;height:36px;border-radius:4px;background:var(--ok-t);border:2px solid rgba(0,0,0,.4);color:#06210f;font:700 20px/32px system-ui,sans-serif;text-align:center;opacity:0}
.sg-stamp{position:absolute;right:8%;bottom:14%;padding:6px 12px;border:3px solid var(--red-t);border-radius:6px;background:var(--panel);color:var(--red-t);font:400 24px/1 var(--f-display);text-transform:uppercase;transform:rotate(-8deg)}
.sg-flow{top:62%;left:8%;opacity:0}
.sg-chip{position:absolute;right:8%;top:58%;padding:8px 14px;border:2px solid var(--text);border-radius:99px;background:var(--cap);color:#fff;font:400 22px/1 var(--f-display)}
.sg-arrow{position:absolute;left:30%;top:40%;width:80px;height:50px;color:var(--foil-gold);transform:rotate(-14deg)}
.sg-l6::before{content:"";position:absolute;inset:auto 0 0;height:55%;background:radial-gradient(ellipse at 50% 100%,rgba(255,110,40,.6),transparent 70%)}
.sg-flame{position:absolute;bottom:-6%;left:calc(var(--i)*20% - 6%);width:132px;height:160px;color:var(--flame-t);fill:rgba(255,148,77,.78);stroke-width:1.4;transform-origin:50% 100%}
.sg-ember{position:absolute;bottom:6%;left:calc(var(--i)*9% + 5%);width:6px;height:6px;border-radius:50%;background:var(--flame-t);opacity:0}
.sg-gone{bottom:auto;top:12%}
.story-stage.fx2[data-beat="1"] .sg-coin{animation:coin-fall 3.2s linear infinite;animation-delay:calc(var(--i)*-.4s)}
.story-stage.fx2[data-beat="2"] .sg-flake{animation:drift 7s ease-in-out infinite alternate;animation-delay:calc(var(--i)*-1.1s)}
.story-stage.fx2[data-beat="2"] .sg-lock{animation:lock-drop .8s var(--spring) both}
.story-stage.fx2[data-beat="3"] .sg-spot{animation:pulse 1.6s ease-in-out infinite}
.story-stage.fx2[data-beat="3"] .sg-burst i{animation:ray 1.8s ease-in-out infinite;animation-delay:calc(var(--i)*-.18s)}
.story-stage.fx2[data-beat="3"] .sg-star{animation:pop .6s var(--spring) both;animation-delay:calc(var(--i)*.12s)}
.story-stage.fx2[data-beat="4"] .sg-bill{animation:bill-fly 2.4s ease-out infinite;animation-delay:calc(var(--i)*-.48s)}
.story-stage.fx2[data-beat="4"] .sg-stamp,.story-stage.fx2[data-beat="6"] .sg-gone{animation:stamp-in .5s var(--spring) .3s both}
.story-stage.fx2[data-beat="5"] .sg-flow{animation:coin-flow 2.4s ease-in infinite;animation-delay:calc(var(--i)*-.4s)}
.story-stage.fx2[data-beat="5"] .sg-arrow{animation:bob 1.4s ease-in-out infinite}
.story-stage.fx2[data-beat="6"] .sg-flame{animation:lick 1.1s ease-in-out infinite alternate;animation-delay:calc(var(--i)*-.23s)}
.story-stage.fx2[data-beat="6"] .sg-ember{animation:ember 2.6s ease-out infinite;animation-delay:calc(var(--i)*-.26s)}
.beat-badge{margin:0}

/* E . freeze layer, burn flame, toasts (E2 and E3 own this section) --------------------------------------- */
.freeze-fx.in{animation:ice-in .6s var(--ease-out) both}
.freeze-fx.out{animation:ice-out .8s var(--ease-out) both}
html[data-fx="1"] .freeze-fx .fx-flake{display:none}
html:not([data-fx="0"]):not([data-fx="1"]) .fx-flake{animation:drift 7s ease-in-out infinite alternate}
html:not([data-fx="0"]):not([data-fx="1"]) .fx-flake:nth-child(odd){animation-duration:9s}
.toast{animation:toast-in .25s var(--ease-out) both}

/* F . reveals: the effects layer adds .rv to elements below the fold and .in when they enter ---------- */
html:not([data-fx="0"]) .rv{opacity:0;translate:0 16px;transition:opacity .55s var(--ease-out),translate .55s var(--ease-out)}
html:not([data-fx="0"]) .rv.in{opacity:1;translate:none}

/* G . grain (quality 2 and up; the tile is assets/grain.png, 8 KB) ---------------------------------------- */
html[data-fx]:not([data-fx="0"]):not([data-fx="1"]) body::after{content:"";position:fixed;inset:0;z-index:1;pointer-events:none;opacity:.05;background:url(../assets/grain.png) 0 0/96px 96px}

/* H . cost calculator and freeze simulator (E3; js/ush-sim.js): polish only, the layout comes from app.css */
.calc-v{font-variant-numeric:tabular-nums lining-nums;font-weight:800}
.sim-cap{margin:0 0 var(--s-2);color:var(--mute)}
.sim-rows li.new{animation:pop .45s var(--ease-out)}

