/* Rare Creatures · Electric Oddities · motion
   Every loop, gesture and entrance on the site. Four layers, slowest first:
     1. ambient   orbits, stars, glows, drifting shapes      slow, continuous   (--ambient)
     2. idle      creatures breathing, bobbing, swaying      slow, continuous   (--tempo)
     3. gestures  blinks, waves, hops, peeks                 occasional          (world.js sets data-act)
     4. response  hover/focus lifts, perks, arrows           quick               (--fast)
   Entrances play once per section (world.js adds .is-in).
   Knobs: --tempo and --ambient stretch durations (2 = half speed); --amp scales distances
   and angles (0 = still, 1 = designed, 1.3 = livelier). Mobile and the calm reading pages
   turn --amp down below. prefers-reduced-motion removes all of it at the end of this file. */

:root{--tempo:1;--ambient:1;--amp:1}
body.calm{--amp:.7;--ambient:1.4}
@media (max-width:540px){:root{--amp:.85}}

/* paused when offscreen (world.js toggles .is-awake), when the tab is hidden,
   and while the screenshot lightbox covers the page */
.world-on [data-scene]:not(.is-awake) *,
.world-on [data-scene]:not(.is-awake) *::before,
.world-on [data-scene]:not(.is-awake) *::after,
html.is-hidden *,html.is-hidden *::before,html.is-hidden *::after,
html.lightbox-on body > :not(dialog) *,
html.lightbox-on .sky::before,html.lightbox-on .sky::after{animation-play-state:paused!important}

/* ---------- 1. ambient ---------- */
@keyframes spin{from{rotate:var(--tilt,0deg)}to{rotate:calc(var(--tilt,0deg) + 360deg)}}
@keyframes spin-back{from{rotate:var(--tilt,0deg)}to{rotate:calc(var(--tilt,0deg) - 360deg)}}
@keyframes tilt-drift{from{rotate:calc(var(--tilt,0deg) - 5deg * var(--amp))}to{rotate:calc(var(--tilt,0deg) + 5deg * var(--amp))}}
.ring{animation:tilt-drift calc(var(--period,34s) * var(--ambient)) ease-in-out infinite alternate;animation-delay:var(--delay,0s)}
.ring.spin{animation:spin calc(var(--period,140s) * var(--ambient)) linear infinite}
.ring.spin.back{animation-name:spin-back}

/* riders travel along their ring's ellipse */
@keyframes ride{from{offset-distance:var(--from,0%)}to{offset-distance:calc(var(--from,0%) + 100%)}}
.rider{position:absolute;left:0;top:0;width:var(--s,12px);height:var(--s,12px);border-radius:50%;background:var(--lime);
  offset-path:ellipse(50% 50% at 50% 50%);offset-rotate:0deg;offset-anchor:center;offset-distance:var(--from,0%);
  animation:ride calc(var(--period,24s) * var(--ambient)) linear infinite}
.rider.lilac{background:var(--muted);--s:8px}
.rider.planet{background:none;width:var(--s,26px);height:var(--s,26px);color:var(--muted)}
.ring.spin .rider{animation:none}

@keyframes twinkle{
  0%,62%,100%{opacity:var(--o,.6);scale:1}
  70%{opacity:1;scale:calc(1 + .7 * var(--amp))}
  78%{opacity:calc(var(--o,.6) * .6);scale:.9}}
@keyframes glimmer{0%,100%{opacity:var(--o,.5)}50%{opacity:calc(var(--o,.5) * .35)}}
.star{animation:twinkle calc(var(--tw,9s) * var(--ambient)) ease-in-out var(--td,0s) infinite}
.star.dot{animation-name:glimmer}

@keyframes burst-turn{to{rotate:360deg}}
@keyframes burst-pulse{0%,84%,100%{scale:1}90%{scale:calc(1 + .22 * var(--amp))}}
.burst{animation:burst-pulse calc(9s * var(--ambient)) ease-in-out 2s infinite}
.burst svg{animation:burst-turn calc(48s * var(--ambient)) linear infinite}

@keyframes glow-shift{
  0%{translate:-4% 2%;scale:1;opacity:.8}
  50%{translate:3% -3%;scale:1.08;opacity:1}
  100%{translate:5% 4%;scale:.96;opacity:.75}}
.habitat .glow,.doc-habitat .glow{animation:glow-shift calc(16s * var(--ambient)) ease-in-out infinite alternate}
@keyframes sky-a{from{translate:0 0}to{translate:8vmax 6vmax}}
@keyframes sky-b{from{translate:0 0;opacity:.7}to{translate:-10vmax -8vh;opacity:1}}
.sky::before{animation:sky-a calc(46s * var(--ambient)) ease-in-out infinite alternate}
.sky::after{animation:sky-b calc(58s * var(--ambient)) ease-in-out infinite alternate}

@keyframes drift{
  from{translate:0 0;rotate:var(--r0,0deg)}
  to{translate:calc(var(--dx,14px) * var(--amp)) calc(var(--dy,-18px) * var(--amp));rotate:calc(var(--r0,0deg) + var(--dr,25deg) * var(--amp))}}
.planet.drift,.star.drift{animation:drift calc(var(--dd,14s) * var(--ambient)) ease-in-out var(--td,0s) infinite alternate}

@keyframes mote{
  0%{translate:0 0;opacity:0}
  15%,85%{opacity:var(--o,.5)}
  100%{translate:calc(var(--dx,30px) * var(--amp)) calc(var(--dy,-80px) * var(--amp));opacity:0}}
.sky .mote,.field .mote{position:absolute;left:var(--x);top:var(--y);width:var(--s,4px);height:var(--s,4px);border-radius:50%;
  background:var(--star);opacity:0;animation:mote calc(var(--dd,26s) * var(--ambient)) linear var(--td,0s) infinite}

/* an occasional starburst somewhere in the margins (world.js adds and removes it) */
@keyframes flare{
  0%{opacity:0;scale:.3;rotate:0deg}
  30%{opacity:.95;scale:1}
  100%{opacity:0;scale:1.25;rotate:40deg}}
.sky .flare{position:absolute;left:var(--x);top:var(--y);width:var(--s,26px);height:var(--s,26px);color:var(--spark);
  animation:flare calc(1.6s * var(--tempo)) var(--ease) both}
.sky .flare svg{display:block;width:100%;height:100%}

.divider .planet svg{animation:burst-turn calc(60s * var(--ambient)) linear infinite}

/* section fields: index.html holds the fixed pieces, world.js scatters the rest (data-fill) */
@keyframes fglow-drift{
  0%{translate:0 0;scale:1;opacity:.7}
  50%{translate:calc(26px * var(--amp)) calc(18px * var(--amp));scale:1.14;opacity:1}
  100%{translate:calc(-14px * var(--amp)) calc(30px * var(--amp));scale:.94;opacity:.8}}
/* wander: each piece drifts on its own slow loop through three random waypoints (set by world.js) */
@keyframes wander{
  0%,100%{transform:translate(0,0)}
  25%{transform:translate(calc(var(--w1x,0px) * var(--amp)),calc(var(--w1y,0px) * var(--amp)))}
  50%{transform:translate(calc(var(--w2x,0px) * var(--amp)),calc(var(--w2y,0px) * var(--amp)))}
  75%{transform:translate(calc(var(--w3x,0px) * var(--amp)),calc(var(--w3y,0px) * var(--amp)))}}
@keyframes galaxy-turn{from{rotate:var(--tilt,0deg)}to{rotate:calc(var(--tilt,0deg) + 360deg)}}
.field .fglow{animation:fglow-drift calc(var(--dd,18s) * var(--ambient)) ease-in-out var(--td,0s) infinite alternate,
  wander calc(var(--wd,50s) * var(--ambient)) ease-in-out var(--wt,0s) infinite}
.field .ring:not(.spin){animation:tilt-drift calc(var(--period,34s) * var(--ambient)) ease-in-out var(--delay,0s) infinite alternate,
  wander calc(var(--wd,50s) * var(--ambient)) ease-in-out var(--wt,0s) infinite}
.field .ring.spin{animation:spin calc(var(--period,140s) * var(--ambient)) linear infinite,
  wander calc(var(--wd,50s) * var(--ambient)) ease-in-out var(--wt,0s) infinite}
.field .galaxy{animation:galaxy-turn calc(var(--period,60s) * 3 * var(--ambient)) linear infinite,
  wander calc(var(--wd,50s) * var(--ambient)) ease-in-out var(--wt,0s) infinite}
@keyframes field-a{from{translate:0 0;scale:1}to{translate:8vw 6%;scale:1.1}}
@keyframes field-b{from{translate:0 0;opacity:.6}to{translate:-10vw -8%;opacity:1}}
.field .glow.g1{animation:field-a calc(34s * var(--ambient)) ease-in-out infinite alternate}
.field .glow.g2{animation:field-b calc(42s * var(--ambient)) ease-in-out infinite alternate}

/* the sky's extra life: a slow lime nebula and the odd shooting star (world.js) */
@keyframes nebula{from{translate:0 0;scale:1;opacity:.6}to{translate:var(--dx,-12vmax) var(--dy,10vmax);scale:1.2;opacity:1}}
.sky .nebula{animation:nebula calc(var(--dd,52s) * var(--ambient)) ease-in-out var(--td,0s) infinite alternate}
@keyframes comet{
  0%{transform:translateX(0) scaleX(.3);opacity:0}
  12%{opacity:var(--o,.8);transform:translateX(calc(var(--run,40vmax) * .12)) scaleX(1)}
  100%{transform:translateX(var(--run,40vmax)) scaleX(.6);opacity:0}}
.sky .comet{animation:comet calc(1.5s * var(--tempo)) cubic-bezier(.3,.1,.4,1) both}

/* ---------- 2. idle ---------- */
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(calc(-7px * var(--amp)))}}
@keyframes float{
  0%,100%{transform:translate(0,0) rotate(0deg)}
  33%{transform:translate(calc(3px * var(--amp)),calc(-9px * var(--amp))) rotate(calc(2deg * var(--amp)))}
  66%{transform:translate(calc(-3px * var(--amp)),calc(-4px * var(--amp))) rotate(calc(-2deg * var(--amp)))}}
@keyframes breathe{0%,100%{transform:scale(1)}50%{transform:scale(calc(1 + .022 * var(--amp)))}}
@keyframes sway{0%,100%{transform:rotate(calc(-2deg * var(--amp)))}50%{transform:rotate(calc(2deg * var(--amp)))}}
.critter-bob{transform-origin:50% 100%;animation-duration:calc(var(--idle,6s) * var(--tempo));animation-timing-function:ease-in-out;
  animation-iteration-count:infinite;animation-delay:var(--delay,0s)}
.idle-bob .critter-bob{animation-name:bob;--idle:5.6s}
.idle-float .critter-bob{animation-name:float;--idle:8.4s}
.idle-breathe .critter-bob{animation-name:breathe;--idle:4.6s}
.idle-sway .critter-bob{animation-name:sway;--idle:7.2s}

/* ---------- 3. gestures (one at a time per creature, chosen by world.js) ---------- */
.critter-art{transform-origin:50% 92%;transition:translate .28s var(--spring),rotate .28s var(--spring)}
.critter-art .c-eye{transform-box:fill-box;transform-origin:50% 50%}
.critter-art .c-pupil{transform-box:fill-box}
.critter-art .c-arm,.critter-art .c-antenna,.critter-art .c-stalk,.critter-art .c-head,.critter-art .c-tail{transform-box:view-box}
.critter-art .c-leg{transform-box:fill-box}

@keyframes act-blink{0%,100%{transform:scaleY(1)}45%,55%{transform:scaleY(.08)}}
@keyframes act-sleepy{0%,100%{transform:scaleY(1)}30%,70%{transform:scaleY(.12)}}
.critter[data-blink] .c-eye{animation:act-blink calc(.22s * var(--tempo)) ease-in-out calc(var(--n,0) * 70ms)}
.critter[data-blink="slow"] .c-eye{animation:act-sleepy calc(1.1s * var(--tempo)) ease-in-out}

@keyframes act-glance{
  0%,100%{transform:translate(0,0)}
  15%,45%{transform:translate(calc(-2.6px * var(--amp)),.4px)}
  60%,88%{transform:translate(calc(2.2px * var(--amp)),-.8px)}}
.critter[data-act="glance"] .c-pupil{animation:act-glance calc(2.4s * var(--tempo)) ease-in-out}

/* --wa / --wb are the raised and half-raised arm angles; set per creature below */
@keyframes act-wave{
  0%,100%{rotate:0deg}
  18%,46%{rotate:calc(var(--wa) * var(--amp))}
  32%,60%{rotate:calc(var(--wb) * var(--amp))}
  74%{rotate:calc(var(--wa) * var(--amp) * .92)}}
@keyframes act-wave-l{
  0%,100%{rotate:0deg}
  18%,46%{rotate:calc(var(--wa) * var(--amp) * -1)}
  32%,60%{rotate:calc(var(--wb) * var(--amp) * -1)}
  74%{rotate:calc(var(--wa) * var(--amp) * -.92)}}
.critter{--wa:-112deg;--wb:-78deg}
.critter.c-nub{--wa:-46deg;--wb:-18deg}
.critter.c-pim{--wa:-100deg;--wb:-70deg}
.critter.c-wisp{--wa:-70deg;--wb:-40deg}
.critter.c-drip{--wa:-34deg;--wb:-14deg}
.critter[data-act="wave"] .c-arm-r{animation:act-wave calc(1.7s * var(--tempo)) ease-in-out}
.critter.wave-left[data-act="wave"] .c-arm-r{animation:none}
.critter.wave-left[data-act="wave"] .c-arm-l{animation:act-wave-l calc(1.7s * var(--tempo)) ease-in-out}

@keyframes act-hop{
  0%,100%{transform:translateY(0)}
  30%{transform:translateY(calc(-16% * var(--amp))) rotate(calc(-3deg * var(--amp)))}
  55%{transform:translateY(0)}
  70%{transform:translateY(calc(-4% * var(--amp)))}}
.critter[data-act="hop"] .critter-art{animation:act-hop calc(.9s * var(--tempo)) var(--ease)}

@keyframes act-tilt{0%,100%{transform:rotate(0)}25%,70%{transform:rotate(calc(-8deg * var(--amp)))}}
.critter[data-act="tilt"] .critter-art{animation:act-tilt calc(2.2s * var(--tempo)) ease-in-out}

@keyframes act-lean{0%,100%{transform:none}30%,75%{transform:translateX(calc(5% * var(--amp))) rotate(calc(7deg * var(--amp)))}}
.critter[data-act="lean"] .critter-art{animation:act-lean calc(2.4s * var(--tempo)) ease-in-out}

@keyframes act-wiggle{0%,100%{transform:rotate(0)}20%{transform:rotate(calc(-5deg * var(--amp)))}40%{transform:rotate(calc(5deg * var(--amp)))}60%{transform:rotate(calc(-3deg * var(--amp)))}80%{transform:rotate(calc(2deg * var(--amp)))}}
.critter[data-act="wiggle"] .critter-art{animation:act-wiggle calc(1.1s * var(--tempo)) ease-in-out}

@keyframes act-sway-part{0%,100%{rotate:0deg}25%{rotate:calc(-9deg * var(--amp))}60%{rotate:calc(7deg * var(--amp))}}
.critter[data-act="sway"] .c-antenna{animation:act-sway-part calc(2.4s * var(--tempo)) ease-in-out}

@keyframes act-droop{0%,100%{transform:none}35%,70%{transform:rotate(calc(6deg * var(--amp))) translateY(calc(2% * var(--amp)))}}
.critter[data-act="droop"] .critter-art{animation:act-droop calc(3.2s * var(--tempo)) ease-in-out}
.critter[data-act="droop"] .c-eye{animation:act-sleepy calc(3.2s * var(--tempo)) ease-in-out}

@keyframes act-wobble-l{0%,100%{rotate:0deg}20%{rotate:calc(-12deg * var(--amp))}45%{rotate:calc(8deg * var(--amp))}70%{rotate:calc(-4deg * var(--amp))}}
@keyframes act-wobble-r{0%,100%{rotate:0deg}25%{rotate:calc(10deg * var(--amp))}50%{rotate:calc(-9deg * var(--amp))}75%{rotate:calc(4deg * var(--amp))}}
.critter[data-act="wobble"] .c-stalk-l{animation:act-wobble-l calc(1.5s * var(--tempo)) ease-in-out}
.critter[data-act="wobble"] .c-stalk-r{animation:act-wobble-r calc(1.5s * var(--tempo)) ease-in-out .08s}

@keyframes act-twitch{0%,100%{rotate:0deg}15%{rotate:calc(-10deg * var(--amp))}30%{rotate:calc(8deg * var(--amp))}45%{rotate:0deg}}
@keyframes act-glow{0%,100%{opacity:0}20%,35%{opacity:.85}50%{opacity:0}65%,80%{opacity:.85}}
.critter[data-act="beep"] .c-antenna{animation:act-twitch calc(1.4s * var(--tempo)) ease-in-out}
.critter[data-act="beep"] .c-bulb{animation:act-glow calc(1.4s * var(--tempo)) ease-in-out}

@keyframes act-chart{0%{stroke-dashoffset:64}55%,100%{stroke-dashoffset:0}}
.critter[data-act="chart"] .c-chart{stroke-dasharray:64;animation:act-chart calc(1.8s * var(--tempo)) var(--ease)}

@keyframes act-step{0%,100%{transform:translateY(0)}40%{transform:translateY(calc(-3.5px * var(--amp)))}}
.critter[data-act="shuffle"] .c-leg{animation:act-step calc(.42s * var(--tempo)) ease-in-out calc(var(--n,0) * 80ms) 2}

@keyframes act-nod{0%,100%{rotate:0deg}25%{rotate:calc(-9deg * var(--amp))}55%{rotate:calc(5deg * var(--amp))}75%{rotate:calc(-3deg * var(--amp))}}
.critter[data-act="nod"] .c-head{animation:act-nod calc(2s * var(--tempo)) ease-in-out}
@keyframes act-flick{0%,100%{rotate:0deg}30%{rotate:calc(28deg * var(--amp))}60%{rotate:calc(-10deg * var(--amp))}}
.critter[data-act="flick"] .c-tail{animation:act-flick calc(.8s * var(--tempo)) ease-in-out}

@keyframes act-peek{0%,100%{transform:none}25%,70%{transform:translate(calc(-14% * var(--amp)),calc(4% * var(--amp))) rotate(calc(-6deg * var(--amp)))}}
.critter[data-act="peek"] .critter-art{animation:act-peek calc(2.6s * var(--tempo)) ease-in-out}
.critter.peek-right[data-act="peek"] .critter-art{animation-name:act-peek-r}
.critter.peek-up[data-act="peek"] .critter-art{animation-name:act-peek-up}
@keyframes act-peek-up{0%,100%{transform:none}25%,70%{transform:translateY(calc(-16% * var(--amp))) rotate(calc(-5deg * var(--amp)))}}
@keyframes act-peek-r{0%,100%{transform:none}25%,70%{transform:translate(calc(14% * var(--amp)),calc(4% * var(--amp))) rotate(calc(6deg * var(--amp)))}}

@keyframes act-flutter-l{0%,100%{rotate:0deg}25%,75%{rotate:calc(16deg * var(--amp))}50%{rotate:calc(-6deg * var(--amp))}}
@keyframes act-flutter-r{0%,100%{rotate:0deg}25%,75%{rotate:calc(-16deg * var(--amp))}50%{rotate:calc(6deg * var(--amp))}}
.critter[data-act="flutter"] .c-arm-l{animation:act-flutter-l calc(1.3s * var(--tempo)) ease-in-out}
.critter[data-act="flutter"] .c-arm-r{animation:act-flutter-r calc(1.3s * var(--tempo)) ease-in-out}

@keyframes act-fade{0%,100%{opacity:1}35%,65%{opacity:.45}}
@keyframes act-motes{0%,100%{opacity:1}50%{opacity:.1}}
.critter[data-act="fade"] .critter-art{animation:act-fade calc(2.8s * var(--tempo)) ease-in-out}
.critter[data-act="fade"] .c-mote{animation:act-motes calc(1.4s * var(--tempo)) ease-in-out calc(var(--n,0) * 160ms) 2}

/* a creature's speech bubble pops up now and then */
@keyframes says-in{
  0%{opacity:0;scale:.6;translate:0 8px}
  12%,86%{opacity:1;scale:1;translate:0 0}
  100%{opacity:0;scale:.9;translate:0 -4px}}
.world-on .says[data-speaker]{opacity:0;transform-origin:0 100%}
.world-on .says[data-speaker].is-speaking{animation:says-in calc(3.4s * var(--tempo)) var(--ease) both}
.world-on .says.right[data-speaker]{transform-origin:100% 100%}

/* ---------- 4. responses ---------- */
/* a creature perks up when its card, button or habitat is hovered or focused */
.critter.is-perked .critter-art,
a.card:is(:hover,:focus-visible) .critter .critter-art,
.others a:is(:hover,:focus-visible) .critter .critter-art{translate:0 calc(-9% * var(--amp));rotate:calc(-5deg * var(--amp))}
.critter.pokeable:hover .critter-art{translate:0 calc(-5% * var(--amp))}
.brand:is(:hover,:focus-visible) .critter .critter-art{rotate:calc(10deg * var(--amp));translate:0 -6%}

/* magnetic buttons: delight.js sets --mx/--my (a few px toward the mouse) while it is over one,
   and the arrow leans a little further. Letting go springs back. */
.btn,[data-magnet]{translate:var(--mx,0px) var(--my,0px);
  transition:transform var(--fast) var(--ease),box-shadow var(--fast) var(--ease),background var(--fast),border-color var(--fast),translate .55s var(--spring)}
.btn.is-magnet,[data-magnet].is-magnet{transition:transform var(--fast) var(--ease),box-shadow var(--fast) var(--ease),background var(--fast),border-color var(--fast),translate .12s var(--ease)}
.btn .arrow{translate:calc(var(--mx,0px) * .6) calc(var(--my,0px) * .6);transition:transform var(--fast) var(--ease),translate .55s var(--spring)}
.btn.is-magnet .arrow{transition:transform var(--fast) var(--ease),translate .12s var(--ease)}

/* the pointer label and the easter-egg message */
.pointer-tip{scale:.8;transform-origin:0 0;transition:opacity .14s,scale .2s var(--spring)}
.pointer-tip.is-on{scale:1}
.toast{transition:opacity .35s ease-in}
@keyframes toast-in{from{opacity:0;translate:-50% calc(18px * var(--amp));scale:.9}to{opacity:1;translate:-50% 0;scale:1}}
.toast.is-on{animation:toast-in calc(.5s * var(--tempo)) var(--spring) backwards}

/* ---------- page transitions (View Transitions, where the browser has them) ----------
   The page fades through, the masthead holds still, an app icon flies between its card and
   its badge (delight.js names it). Reduced motion turns this off below. */
@view-transition{navigation:auto}
.masthead{view-transition-name:masthead}
.app-badge .app{view-transition-name:app-icon}
@keyframes vt-out{to{opacity:0}}
@keyframes vt-in{from{opacity:0;translate:0 calc(14px * var(--amp))}}
::view-transition-old(root){animation:vt-out calc(.2s * var(--tempo)) ease-in both}
::view-transition-new(root){animation:vt-in calc(.45s * var(--tempo)) var(--ease) .05s both}
::view-transition-group(masthead){animation-duration:calc(.3s * var(--tempo))}
::view-transition-group(app-icon){animation-duration:calc(.6s * var(--tempo));animation-timing-function:var(--ease)}

/* ---------- entrances (once per section) ---------- */
@keyframes rv-rise{from{opacity:0;translate:0 calc(26px * var(--amp))}to{opacity:1;translate:0 0}}
@keyframes rv-pop{
  0%{opacity:0;scale:.5;translate:0 calc(30px * var(--amp))}
  60%{opacity:1;scale:1.06;translate:0 calc(-4px * var(--amp))}
  100%{opacity:1;scale:1;translate:0 0}}
@keyframes rv-frame{from{opacity:0;clip-path:inset(10% 6% 10% 6% round 24px);scale:.97}to{opacity:1;clip-path:inset(0 0 0 0 round 0);scale:1}}
@keyframes rv-badge{0%{scale:.8}55%{scale:1.08}100%{scale:1}}
@keyframes shine{from{translate:-120% 0}to{translate:120% 0}}
.world-on .rv.is-pending{opacity:0}
.rv.is-in{animation:rv-rise calc(.75s * var(--tempo)) var(--ease) backwards;animation-delay:calc(var(--i,0) * 90ms)}
.rv-pop.is-in{animation-name:rv-pop;animation-duration:calc(.8s * var(--tempo));animation-delay:calc(.15s + var(--i,0) * 90ms)}
.rv-frame.is-in .shot{animation:rv-frame calc(.9s * var(--tempo)) var(--ease) calc(.12s + var(--i,0) * 90ms) backwards}
/* cards come in with a little tilt; list items with a short rise. Both wait --i beats (world.js) */
@keyframes rv-card{from{opacity:0;translate:0 calc(34px * var(--amp));rotate:calc(-1.6deg * var(--amp));scale:.97}to{opacity:1;translate:0 0;rotate:0deg;scale:1}}
@keyframes rv-item{from{opacity:0;translate:0 calc(14px * var(--amp))}to{opacity:1;translate:0 0}}
.cards-grid > .rv.is-in{animation-name:rv-card;animation-duration:calc(.85s * var(--tempo));animation-delay:calc(var(--i,0) * 110ms)}
.rv-item.is-in{animation-name:rv-item;animation-duration:calc(.55s * var(--tempo));animation-delay:calc(var(--i,0) * 80ms)}
.badge::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 30%,color-mix(in srgb,var(--lime) 55%,#fff) 50%,transparent 70%);translate:-120% 0;opacity:.8}
.badge.is-in{animation:rv-badge calc(.55s * var(--tempo)) var(--spring) calc(.35s + var(--i,0) * 90ms) backwards}
.badge.is-in::after{animation:shine calc(.9s * var(--tempo)) var(--ease) calc(.45s + var(--i,0) * 90ms) both}

/* first screen: plays on load with or without JavaScript */
@keyframes line-in{from{opacity:0;translate:0 .35em}to{opacity:1;translate:0 0}}
.hero .display span,.app-hero .display,.doc-top .display{animation:line-in calc(.8s * var(--tempo)) var(--ease) backwards}
.hero .display span:nth-child(2){animation-delay:.12s}
.hero .display span:nth-child(3){animation-delay:.24s}
.hero .lede,.app-hero .lede,.doc-top .lede{animation:rv-rise calc(.8s * var(--tempo)) var(--ease) .3s backwards}
.hero .btn-row,.app-hero .btn-row{animation:rv-rise calc(.8s * var(--tempo)) var(--ease) .42s backwards}
.habitat .lead,.app-badge .critter,.doc-habitat .critter,.stage .critter{animation:rv-pop calc(.9s * var(--tempo)) var(--ease) .35s backwards}
.habitat .peeker{animation:rv-pop calc(.9s * var(--tempo)) var(--ease) .9s backwards}
.habitat .satellite{animation:rv-pop calc(.9s * var(--tempo)) var(--ease) 1.2s backwards}
.stage .shot{animation:rv-frame calc(1s * var(--tempo)) var(--ease) .2s backwards}

/* ---------- reduced motion: a still composition, feedback by colour and outline ---------- */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation:none!important;transition:none!important}
  .btn:hover,.btn:focus-visible,a.card:hover,a.card:focus-visible,.others a:hover,.others a:focus-visible,.cards a:hover,.cards a:focus-visible{transform:none}
  .btn:hover .arrow,.btn:focus-visible .arrow{transform:none}
  .btn:hover,.btn:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb,var(--accent) 40%,transparent)}
  a.card:hover,a.card:focus-visible{box-shadow:0 0 0 2px var(--accent)}
  a.card .go{translate:0 0}
  .critter .critter-art,.critter.is-perked .critter-art{translate:none!important;rotate:none!important}
  .rider{offset-distance:var(--from,30%)}
  .world-on .says[data-speaker]{opacity:1}
  .sky .mote,.sky .flare,.sky .comet,.field .mote{display:none}
  .btn,.btn .arrow,[data-magnet]{translate:none}
  .pointer-tip,.sparks{display:none}
}
@media (prefers-reduced-motion:reduce){@view-transition{navigation:none}}
