/*
  muplu · the toy tiles and their little animated scenes
  Copyright (c) 2026 Nicola Harvey. All rights reserved. https://muplu.com

  WHY THIS FILE EXISTS
  These tiles used to live in a <style> block in public/index.html and nowhere else,
  because there was nowhere else. With wings there are now five pages that show a toy
  tile (home, and one per wing), and a scene copied five times is a scene that is wrong
  in four places the first time anyone tweaks it. That is the same bug public/toys.json
  was created to kill, wearing different clothes. One file, one source.

  THE PALETTE IS SCOPED TO .toy ON PURPOSE.
  Each wing page sets its own environment (its own background, ink, type, pace). A toy's
  preview must NOT change colour just because of the room it hangs in: FLINCH's scene is
  FLINCH's scene in every wing. So the scene colours are declared on .toy itself, below,
  and the page's own --ink / --coral never reach in.

  What a wing MAY change is the tile's CHROME, by overriding these on its own .toy:
    --tile-ink     the border + hard shadow colour
    --tile-r       corner radius
    --tile-shadow  the offset of the hard shadow (0 for a soft wing)
    --tile-bg      the label background
  The nursery wing softens all four. The play wing leaves them alone. Nothing else about
  a tile is a wing's business.
*/

.toy{
  /* scene palette: fixed, never inherited from the page */
  --coral:#ff5d5d;
  --sky:#4aa8ff;
  --lime:#a8d949;
  --sun:#ffc93c;
  --ink:#17141f;

  /* tile chrome: a wing may override these four */
  --tile-ink:#17141f;
  --tile-r:28px;
  --tile-shadow:6px;
  --tile-bg:#fff;

  position:relative;display:block;text-decoration:none;color:var(--tile-ink);
  border:3px solid var(--tile-ink);border-radius:var(--tile-r);
  background:var(--tile-bg);overflow:hidden;
  box-shadow:0 var(--tile-shadow) 0 var(--tile-ink);
  transition:transform .18s cubic-bezier(.34,1.56,.64,1), box-shadow .18s;
  opacity:0;animation:arrive .5s cubic-bezier(.34,1.56,.64,1) forwards;
}
.toy:nth-child(1){animation-delay:.05s}
.toy:nth-child(2){animation-delay:.15s}
.toy:nth-child(3){animation-delay:.25s}
.toy:nth-child(4){animation-delay:.35s}
.toy:nth-child(5){animation-delay:.45s}
@keyframes arrive{from{opacity:0;transform:translateY(22px) scale(.96)}to{opacity:1;transform:none}}
.toy:hover{transform:translateY(-4px) rotate(-.6deg);box-shadow:0 calc(var(--tile-shadow) + 4px) 0 var(--tile-ink)}
.toy:active{transform:translateY(2px);box-shadow:0 3px 0 var(--tile-ink)}
.toy:focus-visible{outline:3px solid var(--coral);outline-offset:3px}
.scene{height:150px;position:relative;overflow:hidden;border-bottom:3px solid var(--tile-ink)}
.label{padding:14px 18px 16px}
/* h2 AND h3, because the heading level depends on the page, not on the tile. The home
   page spends its h2 on the wing headings, so its tiles are h3; a wing page's own
   heading is the h1, so its tiles are h2. Styling only h2 here is exactly the bug that
   shipped for a minute: every tile on the home page fell back to the browser default,
   which looks like nothing much and reads like a mistake. The tile looks the same either
   way, and that is the point of it being one file. */
.label h2,.label h3{margin:0;font-size:24px;font-weight:800;letter-spacing:.01em}
.label p{margin:2px 0 0;font-size:15px;font-weight:500;opacity:.66}

/* flinch scene: a dot that things whizz past */
.s-flinch{background:var(--ink)}
.s-flinch .player{position:absolute;left:50%;top:58%;width:16px;height:16px;margin:-8px;border-radius:50%;background:#fff;animation:shiver 1.4s linear infinite}
@keyframes shiver{0%,100%{transform:translate(0,0)}25%{transform:translate(2px,-2px)}50%{transform:translate(-2px,1px)}75%{transform:translate(1px,2px)}}
.s-flinch .shot{position:absolute;height:4px;width:56px;border-radius:2px;background:var(--coral)}
.s-flinch .shot:nth-child(2){top:44%;animation:whizz 1.1s linear infinite}
.s-flinch .shot:nth-child(3){top:66%;animation:whizz 1.7s linear .4s infinite reverse}
.s-flinch .shot:nth-child(4){top:54%;width:34px;background:var(--sun);animation:whizz .8s linear .2s infinite}
@keyframes whizz{from{left:-60px}to{left:110%}}

/* gravity scene: orbiting particles */
.s-gravity{background:#0b0d18}
.s-gravity i{position:absolute;left:50%;top:50%;width:7px;height:7px;margin:-3.5px;border-radius:50%;background:var(--sky)}
.s-gravity i:nth-child(1){animation:orbit 2.6s linear infinite}
.s-gravity i:nth-child(2){width:5px;height:5px;background:#9ed0ff;animation:orbit 3.8s linear .6s infinite reverse}
.s-gravity i:nth-child(3){background:#fff;animation:orbit 1.9s linear .3s infinite}
.s-gravity i:nth-child(4){width:4px;height:4px;background:var(--sun);animation:orbit 4.6s linear 1s infinite}
.s-gravity .core{position:absolute;left:50%;top:50%;width:12px;height:12px;margin:-6px;border-radius:50%;background:#fff;box-shadow:0 0 22px 6px rgba(74,168,255,.65)}
@keyframes orbit{from{transform:rotate(0) translateX(46px) rotate(0)}to{transform:rotate(360deg) translateX(46px) rotate(-360deg)}}

/* fluid scene: morphing blob */
.s-fluid{background:linear-gradient(135deg,#062a33,#0d4d56)}
.s-fluid .blob{position:absolute;left:50%;top:50%;width:110px;height:110px;margin:-55px;background:linear-gradient(135deg,var(--sky),var(--lime));filter:blur(1px);animation:morph 5s ease-in-out infinite;opacity:.9}
@keyframes morph{
  0%,100%{border-radius:58% 42% 55% 45%/50% 58% 42% 50%;transform:rotate(0)}
  33%{border-radius:45% 55% 40% 60%/60% 42% 58% 40%;transform:rotate(24deg) scale(1.06)}
  66%{border-radius:52% 48% 60% 40%/44% 56% 44% 56%;transform:rotate(-18deg) scale(.95)}
}

/* hushpaper scene: a paper moon and its little stars */
.s-paper{background:radial-gradient(120% 120% at 70% 20%,#fbf4de,#f4ecd6)}
.s-paper .moon{position:absolute;left:56%;top:46%;width:60px;height:60px;margin:-30px;border-radius:50%;background:radial-gradient(circle at 38% 34%,#f7e08a,#f2d55c);box-shadow:0 0 24px 6px rgba(242,213,92,.5);animation:breathe 4.6s ease-in-out infinite}
.s-paper i{position:absolute;width:5px;height:5px;border-radius:50%;background:#c9a83a;opacity:.7}
.s-paper i:nth-child(2){left:24%;top:34%;animation:twinkle 2.4s ease-in-out infinite}
.s-paper i:nth-child(3){left:34%;top:66%;animation:twinkle 3.2s ease-in-out .6s infinite}
.s-paper i:nth-child(4){left:78%;top:70%;animation:twinkle 2.8s ease-in-out .3s infinite}
@keyframes breathe{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}
@keyframes twinkle{0%,100%{opacity:.2}50%{opacity:.9}}

/* gather scene: snow falling onto a drift that has already been pushed about.
   The mound is deliberately lopsided, because a tidy one would say "this is how it
   should look" and the whole toy is that there is no should. */
.s-gather{background:linear-gradient(#6d6478,#413b4b);overflow:hidden}
.s-gather .drift{position:absolute;left:-6%;right:-6%;bottom:-34px;height:86px;background:#fdf8ee;
  border-radius:56% 40% 52% 46%/74% 66% 40% 46%;transform:rotate(-2deg)}
.s-gather i{position:absolute;width:4px;height:4px;border-radius:50%;background:#fdf8ee;opacity:.9}
.s-gather i:nth-child(1){left:22%;animation:fall 3.6s linear infinite}
.s-gather i:nth-child(2){left:48%;animation:fall 4.6s linear -1.4s infinite}
.s-gather i:nth-child(3){left:69%;animation:fall 4.1s linear -2.7s infinite}
.s-gather i:nth-child(4){left:86%;animation:fall 5.2s linear -3.6s infinite}
@keyframes fall{from{top:-6px;opacity:0}12%{opacity:.9}80%{opacity:.9}to{top:118px;opacity:0}}

/* sandcastle scene: a warm beach under a soft sun, with a little tapered castle and a flag.
   The sibling of the gather scene, sunny where that one is dusk. */
.s-sand{background:linear-gradient(#9fd0e2,#e9dfbc 62%,#e6c079);overflow:hidden}
.s-sand .sun{position:absolute;right:16%;top:20%;width:26px;height:26px;border-radius:50%;
  background:#fff6d8;box-shadow:0 0 16px 6px rgba(255,240,190,.7)}
.s-sand .beach{position:absolute;left:-6%;right:-6%;bottom:-30px;height:78px;background:#e2bd72;
  border-radius:48% 44% 50% 46%/70% 64% 40% 44%}
.s-sand .castle{position:absolute;left:50%;bottom:20px;width:26px;height:30px;margin-left:-13px;
  background:#efd79b;border-radius:4px 4px 0 0}
.s-sand .castle::before{content:"";position:absolute;left:5px;right:5px;top:-12px;height:16px;
  background:#efd79b;border-radius:3px 3px 0 0}
.s-sand .flag{position:absolute;left:50%;bottom:52px;width:9px;height:7px;margin-left:-1px;
  background:#ef7a5a;clip-path:polygon(0 0,100% 50%,0 100%)}
.s-sand .flag::before{content:"";position:absolute;left:-1px;top:0;width:2px;height:14px;background:#8a6a3c}

/* wisp scene: a candlelit dark, a warm moon, and little wisps drifting upward like the
   ones the room lights together. The together wing's one tile. */
.s-wisp{background:radial-gradient(120% 100% at 50% 120%,#241639,#0c0918 72%);overflow:hidden}
.s-wisp .moon{position:absolute;left:50%;top:42%;width:44px;height:44px;margin:-22px 0 0 -22px;border-radius:50%;
  background:radial-gradient(circle at 42% 38%,#fff6dd,#e8c98a 60%,#c99a4e);
  box-shadow:0 0 26px 8px rgba(232,201,138,.4)}
.s-wisp i{position:absolute;width:5px;height:5px;border-radius:50%;background:#ffe6ad;
  box-shadow:0 0 8px 2px rgba(232,184,102,.7);opacity:.85}
.s-wisp i:nth-child(2){left:26%;animation:rise 4.6s ease-in infinite}
.s-wisp i:nth-child(3){left:44%;animation:rise 5.8s ease-in -1.6s infinite}
.s-wisp i:nth-child(4){left:60%;animation:rise 5.1s ease-in -3.1s infinite}
.s-wisp i:nth-child(5){left:74%;animation:rise 6.4s ease-in -2.2s infinite}
.s-wisp i:nth-child(6){left:36%;animation:rise 5.4s ease-in -4s infinite}
@keyframes rise{from{bottom:-8px;opacity:0}18%{opacity:.9}82%{opacity:.9}to{bottom:150px;opacity:0}}

/* predator scene: a white comet lunging at red prey */
.s-predator{background:var(--ink);overflow:hidden}
.s-predator .comet{position:absolute;top:50%;width:14px;height:14px;margin:-7px;border-radius:50%;background:#fff;box-shadow:0 0 12px 4px rgba(255,255,255,.7);animation:lunge 1.7s ease-in-out infinite}
.s-predator .prey{position:absolute;width:12px;height:12px;margin:-6px;border-radius:50%;background:var(--coral);box-shadow:0 0 0 3px rgba(255,211,77,.55)}
.s-predator .prey:nth-child(2){right:24%;top:34%}
.s-predator .prey:nth-child(3){right:32%;top:64%}
.s-predator .prey:nth-child(4){right:18%;top:50%}
@keyframes lunge{0%{left:16%;transform:scale(1)}50%{left:76%;transform:scale(1.28)}100%{left:16%;transform:scale(1)}}

/* lucky dummy scene: a stickman tumbling through pegs */
.s-dummy{background:#fff3d6;position:relative}
.s-dummy .peg{position:absolute;width:10px;height:10px;border-radius:50%;background:var(--ink);opacity:.22}
.s-dummy .peg:nth-child(1){left:24%;top:56%}
.s-dummy .peg:nth-child(2){left:50%;top:40%}
.s-dummy .peg:nth-child(3){left:72%;top:60%}
.s-dummy .dummy{position:absolute;left:46%;top:10%;width:6px;height:26px;background:var(--ink);border-radius:3px;transform-origin:50% 30%;animation:tumble 2.6s ease-in-out infinite}
.s-dummy .dummy::before{content:"";position:absolute;left:-3px;top:-12px;width:12px;height:12px;border-radius:50%;background:var(--ink)}
@keyframes tumble{0%,100%{transform:translateY(0) rotate(-16deg)}50%{transform:translateY(26px) rotate(26deg)}}

/* THE "?" CURIOSITY AFFORDANCE.
   A tile is already one big <a> to play the thing, and you cannot nest an <a> inside an
   <a>. So a tile that also has an explainer page is wrapped in .toy-wrap, and the "?" is a
   SEPARATE sibling link sitting in the corner, above the tile. Clicking the tile plays;
   clicking the "?" opens the idea behind it. Hover (or focus, or tap) the "?" and a short
   teaser card appears. Scoped to .toy-wrap so only tiles that opt in are affected. */
.toy-wrap{position:relative;display:block}
.curio{
  position:absolute;top:10px;right:10px;z-index:4;
  width:26px;height:26px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-family:'Baloo 2',ui-rounded,sans-serif;font-weight:800;font-size:15px;line-height:1;
  color:#eafcff;text-decoration:none;
  background:rgba(4,16,24,.72);border:1.5px solid rgba(127,212,208,.6);
  backdrop-filter:blur(3px);
  box-shadow:0 2px 10px rgba(0,0,0,.4);
  opacity:.75;transition:opacity .2s,transform .2s,box-shadow .2s;
}
/* a bigger invisible hit area so it is comfortable to tap on a phone */
.curio::before{content:"";position:absolute;inset:-9px;border-radius:50%}
.curio:hover,.curio:focus-visible{opacity:1;transform:scale(1.08);box-shadow:0 0 16px rgba(127,212,208,.5);outline:none}
.curio .q{position:relative;z-index:1}
/* No hover teaser: the "?" is just a clean link to the explainer. It used to pop a card,
   but ten tiles all popping the same line was noise, so the popup is gone (18 Jul 2026).
   What it means is the aria-label ("Read the idea behind X") for a screen reader, and the
   universal "?" glyph for everyone else. */
@media (prefers-reduced-motion:reduce){.curio{transition:none}}

/* the mystery tile: a toy that has not hatched yet */
.toy.soon{border-style:dashed;box-shadow:none;background:transparent;cursor:default}
.toy.soon:hover{transform:none}
.s-soon{border-bottom:3px dashed var(--tile-ink);background:transparent}
.s-soon b{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);font-size:56px;font-weight:800;opacity:.25;animation:wobble 2.8s ease-in-out infinite}
@keyframes wobble{0%,100%{transform:translate(-50%,-50%) rotate(-8deg)}50%{transform:translate(-50%,-50%) rotate(8deg)}}

@media (prefers-reduced-motion: reduce){
  .toy,.toy *,.toy *::before,.toy *::after{animation:none!important;transition:none!important}
  .toy{opacity:1}
}

/* hunch scene: a big question mark under a dusk sky, with little thought-sparks
   orbiting it. The daily one: the "?" ticks side to side like a clock's second hand. */
.s-hunch{background:linear-gradient(#1c1538,#33244f 70%,#4a2c4d);overflow:hidden}
.s-hunch .mark{position:absolute;left:50%;top:50%;transform:translate(-50%,-54%);font-size:64px;font-weight:800;
  color:var(--sun);text-shadow:0 0 22px rgba(255,201,60,.45);animation:hunchtick 2.4s ease-in-out infinite}
@keyframes hunchtick{0%,100%{transform:translate(-50%,-54%) rotate(-7deg)}50%{transform:translate(-50%,-54%) rotate(7deg)}}
.s-hunch i{position:absolute;left:50%;top:50%;width:6px;height:6px;margin:-3px;border-radius:50%;background:#f4edff;opacity:.8}
.s-hunch i:nth-child(2){animation:orbit 3.4s linear infinite}
.s-hunch i:nth-child(3){width:4px;height:4px;background:var(--coral);animation:orbit 4.8s linear -1.8s infinite reverse}
.s-hunch i:nth-child(4){width:4px;height:4px;background:var(--lime);animation:orbit 5.6s linear -3s infinite}

/* tend scene: a sprout growing out of shared soil under early stars, over and over.
   The stem rises, the bloom opens, it all breathes back down and begins again,
   because the garden's whole idea is that growing is the show. */
.s-tend{background:linear-gradient(#171130,#2b1f4a 62%,#3d2a52);overflow:hidden}
.s-tend .soil{position:absolute;left:-4%;right:-4%;bottom:-26px;height:56px;background:#3a2c22;
  border-radius:50% 44% 0 0/70% 60% 0 0}
.s-tend .stem{position:absolute;left:50%;bottom:26px;width:5px;margin-left:-2.5px;border-radius:3px;
  background:#5c8c44;transform-origin:50% 100%;animation:tendgrow 5.2s ease-in-out infinite}
@keyframes tendgrow{0%,12%{height:8px}55%,86%{height:64px}100%{height:8px}}
.s-tend .bloom{position:absolute;left:50%;bottom:82px;width:26px;height:26px;margin-left:-13px;border-radius:50%;
  background:radial-gradient(circle at 50% 50%,#6b4a1f 0 26%,var(--sun) 30%);
  box-shadow:0 0 18px rgba(255,201,60,.35);transform:scale(0);animation:tendbloom 5.2s ease-in-out infinite}
@keyframes tendbloom{0%,50%{transform:scale(0)}62%,86%{transform:scale(1)}100%{transform:scale(0)}}
.s-tend .star{position:absolute;width:4px;height:4px;border-radius:50%;background:#f4edff;opacity:.6}
.s-tend .star:nth-child(4){left:22%;top:22%;animation:twinkle 3s ease-in-out infinite}
.s-tend .star:nth-child(5){left:76%;top:30%;animation:twinkle 3.8s ease-in-out .8s infinite}

/* unfold scene: one point of light, breathing */
.s-unfold{background:#041018}
.s-unfold .pt{position:absolute;left:50%;top:50%;width:10px;height:10px;margin:-5px;border-radius:50%;background:#dffcff;box-shadow:0 0 18px 6px rgba(54,182,180,.75);animation:upulse 2.6s ease-in-out infinite;transition:opacity .6s}
.s-unfold .halo{position:absolute;left:50%;top:50%;width:56px;height:56px;margin:-28px;border-radius:50%;border:1px solid rgba(54,182,180,.35);animation:ugrow 2.6s ease-in-out infinite;transition:opacity .6s}
@keyframes upulse{0%,100%{transform:scale(1)}50%{transform:scale(1.35)}}
@keyframes ugrow{0%{transform:scale(.4);opacity:.7}100%{transform:scale(1.4);opacity:0}}

/* UNFOLD'S MEANING, revealed on the tile.
   unfold is a piece of art, not a game, so its tile carries the idea it is built on.
   Hover it (or tab to it, or tap it on a phone) and the point of light dims and unfold's
   own words fade in over the night sky, like the thought behind the picture. The line is
   the artist's statement, verbatim from the piece. It lives here in scenes.css so the
   home tile and the immerse tile show it identically from one source.
   The text is REAL content (not aria-hidden), so a screen reader reads the meaning too;
   only the animated dots are decorative. pointer-events stay off it so the whole tile is
   still one clean click through to unfold. */
.s-unfold .u-meaning{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  margin:0;padding:0 18px;text-align:center;pointer-events:none;
  font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  font-size:15px;line-height:1.55;letter-spacing:.01em;
  color:#eafcff;text-shadow:0 0 16px rgba(54,182,180,.55);
  opacity:0;transition:opacity .55s ease;
}
/* darken the sky behind the words so they read, only while they show */
.s-unfold::after{content:"";position:absolute;inset:0;background:#041018;opacity:0;transition:opacity .55s ease;pointer-events:none}
.toy:hover .s-unfold::after,.toy:focus-visible .s-unfold::after{opacity:.72}
.toy:hover .s-unfold .u-meaning,.toy:focus-visible .s-unfold .u-meaning{opacity:1}
.toy:hover .s-unfold .pt,.toy:hover .s-unfold .halo,
.toy:focus-visible .s-unfold .pt,.toy:focus-visible .s-unfold .halo{opacity:.25}
/* the point of light must sit ABOVE the darkening layer, the words above that */
.s-unfold .pt,.s-unfold .halo{z-index:1}
.s-unfold .u-meaning{z-index:2}
/* touch devices have no hover: show the line softly and always, so a phone can read it
   too. It sits over a permanently-dimmed sky, with the point of light glowing through. */
@media (hover:none){
  .s-unfold::after{opacity:.6}
  .s-unfold .u-meaning{opacity:.9}
  .s-unfold .pt,.s-unfold .halo{opacity:.5}
}
@media (prefers-reduced-motion:reduce){
  .s-unfold .u-meaning,.s-unfold::after,.s-unfold .pt,.s-unfold .halo{transition:none}
}
