/* The desk around the page: kraft paper, the theme label taped to the sheet, and the gremlin. */
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; }
body.kraft { min-height: 100vh; background: #D9C3A0 var(--grain); color: #1F2A44; font-family: Nunito, system-ui, sans-serif; overflow-x: hidden; }

#stage { position: relative; min-height: 100vh; padding: 72px 48px 150px; user-select: none; -webkit-user-select: none;
  --wand: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28'><polygon points='14,2 17,10.5 26,10.8 19,16.2 21.5,25 14,20 6.5,25 9,16.2 2,10.8 11,10.5' fill='%23F2C14E' stroke='%231F2A44' stroke-width='1.6' stroke-linejoin='round'/></svg>") 14 14, pointer; }
#wordAsk input { user-select: text; -webkit-user-select: text; }
.sheet { position: relative; max-width: 1000px; min-height: 520px; margin: 0 auto; padding: 48px 56px 44px; background: var(--paper, #F7F2E7) var(--grain); filter: drop-shadow(2px 4px 0 rgb(31 42 68 / .18)); transition: background-color 600ms, max-width 600ms; }
#carry { position: absolute; inset: 0; pointer-events: none; display: block; z-index: 12; }
#carry > .piece { position: absolute; top: 0; left: 0; margin: 0; }
#fx { position: fixed; top: 0; left: 0; pointer-events: none; z-index: 14; }

/* Pieces you can wish on: hovering lifts one and cuts a dashed line around it; the cursor becomes a wand star. */
.site.armed, .site.armed .piece { cursor: var(--wand); }
.piece:focus { outline: none; }
/* Hovering lifts a piece a little and tips it, like picking up a paper cut-out. */
.site.armed .piece:not(.stuck) { transition: translate 220ms cubic-bezier(.3, 1.4, .5, 1), rotate 220ms cubic-bezier(.3, 1.4, .5, 1); }
.site.armed .piece:not(.stuck):hover, .site.armed .piece:not(.stuck):focus-visible, .piece.chosen { outline: 2.5px dashed color-mix(in srgb, var(--ink) 40%, transparent); outline-offset: 6px; border-radius: 4px; translate: 0 -4px; rotate: -0.6deg; }
.piece.brewing { animation: v-shiver 90ms linear infinite alternate; }
.piece.nudge { animation: nudge 460ms cubic-bezier(.3, 1.6, .5, 1); }
@keyframes nudge { 35% { translate: 0 -7px; } }

/* While the gremlin works, the pieces it will change wobble in the wish's mood and glow in its colour. */
.piece[class*="vibe-"] { filter: drop-shadow(0 0 10px var(--tint)) drop-shadow(0 0 3px var(--tint)); }
.vibe-float { animation: v-float 1.1s ease-in-out infinite alternate; }
@keyframes v-float { to { translate: 0 -10px; } }
.vibe-sag { transform-origin: 50% 100%; animation: v-sag 1.2s ease-in-out infinite alternate; }
@keyframes v-sag { to { scale: 1.05 .88; } }
.vibe-rock { animation: v-rock .7s ease-in-out infinite alternate; }
@keyframes v-rock { from { rotate: -4deg; } to { rotate: 4deg; } }
.vibe-shiver { animation: v-shiver 90ms linear infinite alternate; }
@keyframes v-shiver { from { translate: -1.5px 0; } to { translate: 1.5px .5px; } }
.vibe-spin { animation: v-spin 1.4s ease-in-out infinite alternate; }
@keyframes v-spin { from { rotate: -14deg; } to { rotate: 14deg; } }
.vibe-bounce { animation: v-bounce .45s cubic-bezier(.3, .7, .4, 1) infinite alternate; }
@keyframes v-bounce { to { translate: 0 -12px; } }
.vibe-melt { transform-origin: 50% 100%; animation: v-melt 1.6s ease-in-out infinite alternate; }
@keyframes v-melt { to { scale: 1.06 .9; translate: 0 6px; } }
.vibe-glow { animation: v-glow .9s ease-in-out infinite alternate; }
@keyframes v-glow { to { filter: drop-shadow(0 0 22px var(--tint)) drop-shadow(0 0 6px var(--tint)); } }

/* The gremlin. It sits on the sheet's corner, breathing, eyes on your pointer. */
.gremlin { position: fixed; top: 0; left: 0; width: 100px; height: 112px; z-index: 36; cursor: grab; touch-action: none; user-select: none; --px: 0px; --py: 0px; }
.gremlin svg { width: 100%; height: 100%; display: block; overflow: visible; filter: drop-shadow(1.5px 2.5px 0 rgb(31 42 68 / .25)); transform-origin: 50% 90%; }
.gremlin .pupils { transform: translate(var(--px), var(--py)); transition: transform 120ms; }
.gremlin .wand { transform: rotate(-22deg); transform-origin: 74px 62px; transition: transform 250ms; }
.gremlin:not(.busy):not(.dragging) svg { animation: breathe 2.8s ease-in-out infinite; }
.gremlin:not(.busy):hover svg { animation: wiggle 300ms 2 alternate; }
.gremlin:not(.busy):hover .wand { transform: rotate(-40deg); }
@keyframes breathe { 50% { transform: scale(1.03, .97); } }
@keyframes wiggle { from { transform: rotate(-6deg); } to { transform: rotate(6deg); } }
.gremlin.busy { cursor: default; }
.gremlin.dragging { cursor: grabbing; z-index: 30; }
.gremlin.dragging svg { transform: scale(1.12) rotate(-8deg); animation: none; }
.gremlin.hopping svg { animation: hop 600ms cubic-bezier(.3, .7, .3, 1); }
@keyframes hop { 40% { transform: translateY(-34px) scale(.94, 1.06); } 85% { transform: translateY(0) scale(1.08, .9); } }
.gremlin.rummaging svg { animation: rummage 160ms infinite alternate; }
.gremlin.rummaging .wand { animation: zap 300ms infinite alternate; }
@keyframes rummage { from { transform: rotate(-7deg) translateY(0); } to { transform: rotate(7deg) translateY(-4px); } }
@keyframes zap { from { transform: rotate(-60deg); } to { transform: rotate(10deg); } }
/* The bubble sits to the gremlin's left, so it never runs off the top of the screen. */
.gbubble { position: absolute; right: 88%; top: 6px; transform: translateY(4px); max-width: 260px; width: max-content; padding: 7px 12px; background: #FFFDF8 var(--grain); border-radius: 12px 12px 3px 12px; font: 400 16px/1.2 "Permanent Marker", cursive; color: #1F2A44; filter: drop-shadow(1.5px 2.5px 0 rgb(31 42 68 / .22)); opacity: 0; transition: opacity 180ms, transform 180ms; pointer-events: none; }
.gbubble.on { opacity: 1; transform: none; }
.gbubble img { display: block; height: 76px; width: auto; }
.gbubble.right { right: auto; left: 88%; border-radius: 12px 12px 12px 3px; }
.gbubble.above { right: auto; left: 50%; top: auto; bottom: 96%; translate: -50% 0; border-radius: 12px; } /* no room either side (a phone, next to the bag) */
.splash { position: absolute; z-index: 11; border-radius: 50%; pointer-events: none; opacity: .5; animation: splash 800ms cubic-bezier(.2, .7, .3, 1) forwards; }
@keyframes splash { from { transform: scale(0); opacity: .6; } to { transform: scale(1); opacity: 0; } }

/* The wish: a note that pops out under the gremlin. */
#wordAsk { position: fixed; z-index: 40; width: 310px; padding: 12px; background: #FFFDF8 var(--grain); border-radius: 4px; transform: rotate(-2deg); filter: drop-shadow(1.5px 2.5px 0 rgb(31 42 68 / .25)); animation: note-in 260ms cubic-bezier(.3, 1.5, .5, 1); }
@keyframes note-in { from { transform: rotate(-8deg) translateY(-10px) scale(.9); opacity: 0; } }
#wordAsk input { width: 100%; border: 0; border-bottom: 2.5px solid #1F2A44; background: none; font: 400 22px "Permanent Marker", cursive; color: #1F2A44; outline: none; padding: 2px 0 4px; }
#wordAsk .chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
#wordAsk .chips button { border: 0; border-radius: 3px; padding: 4px 9px; background: #E8E0CF; color: #1F2A44; font: 800 13px Nunito, sans-serif; cursor: pointer; }
#wordAsk .chips button:hover { background: #1F2A44; color: #FFFDF8; }
#wordAsk .chips .more { background: none; box-shadow: inset 0 0 0 1.5px #1F2A44; }
#wordAsk .chips .thinking { width: 84px; height: 24px; border-radius: 3px; background: #E8E0CF; animation: pic-wait 700ms ease-in-out infinite alternate; }

/* Keepsakes: earlier versions of pictures, dropped on the desk. */
#shelf { position: fixed; left: 18px; bottom: 10px; z-index: 6; display: flex; align-items: flex-end; gap: 2px; max-width: calc(100vw - 200px); }
#shelf img { cursor: pointer; width: 58px; height: 58px; object-fit: contain; filter: drop-shadow(1.5px 2px 0 rgb(31 42 68 / .25)); animation: flutter 700ms cubic-bezier(.3, 1.2, .5, 1); transition: transform 150ms; }
#shelf img:hover { transform: scale(1.5) translateY(-10px); }
@keyframes flutter { from { transform: translateY(-160px) rotate(40deg); opacity: 0; } }

#mute { position: fixed; z-index: 35; right: 18px; bottom: 12px; width: 30px; height: 30px; padding: 3px; border: 0; background: none; cursor: pointer; opacity: .55; }
#mute:hover { opacity: .9; }
#mute svg { width: 100%; height: 100%; fill: #1F2A44; stroke: #1F2A44; stroke-width: 1.8; stroke-linecap: round; }
#mute .waves { fill: none; }
#mute.off .waves { display: none; }
/* Who this is: fixed on the desk, untouched by any wish. */
#me { position: fixed; top: 10px; left: 14px; z-index: 20; display: flex; align-items: center; gap: 10px; padding: 5px 8px 5px 12px; border-radius: 6px; background: #D9C3A0 var(--grain); color: #1F2A44; }
#me b { font-size: 18px; font-weight: 900; letter-spacing: -0.01em; }
/* The page opens with his name in big type; the strip only repeats it once that has scrolled away. */
#me b, #me span { transition: opacity 200ms; }
#me:not(.named) b, #me:not(.named) span { display: none; }
#me span { font-size: 13px; font-weight: 700; color: rgb(31 42 68 / .6); }
#me a { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; color: #1F2A44; transition: background 150ms; }
#me a:hover { background: rgb(31 42 68 / .1); }
#me svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; stroke-linecap: round; }

@media (max-width: 700px) {
  #stage { padding: 64px 12px 150px; }
  .sheet { padding: 26px 18px 28px; }
  #me span { display: none; }
  .gremlin { width: 58px; height: 64px; }
  #shelf { max-width: calc(100vw - 110px); }
  #shelf img { width: 40px; height: 40px; }
}

/* Paper doll: the bag in the bottom-left corner (beside the page on a wide screen), things poking out of it,
   each tucked behind the bag's front; big until a section is out. On phones the page leaves room for it. Wish
   keepsakes move to the right edge. */
body.doll #shelf { left: auto; right: 10px; bottom: auto; top: 64px; flex-direction: column; }
#bag { position: fixed; left: 16px; bottom: 6px; z-index: 34; width: 220px; transition: width 450ms cubic-bezier(.3, .7, .3, 1); }
#bag.small { width: 160px; }
#bag .front { position: relative; z-index: 2; display: block; width: 100%; pointer-events: none; filter: drop-shadow(2px 3px 0 rgb(31 42 68 / .25)); }
#bag .items { position: absolute; z-index: 1; left: 2%; right: 2%; top: var(--mouth, 22%); height: 0; display: flex; align-items: flex-start; justify-content: space-between; }
#bag .item { position: relative; flex: 0 0 27%; aspect-ratio: 1; margin: 0 -4%; padding: 0; border: 0; background: none; cursor: pointer; transform: translateY(-72%) rotate(var(--r, 0deg)); transition: transform 240ms cubic-bezier(.3, 1.5, .5, 1); }
#bag .item img { width: 100%; height: 100%; object-fit: contain; filter: drop-shadow(1px 2px 0 rgb(31 42 68 / .25)); }
#bag .item.peek { transform: translateY(-115%) rotate(0deg) scale(1.3); }
#bag .hint { position: absolute; bottom: 100%; left: -6px; translate: 0 -6px; white-space: nowrap; padding: 3px 9px; border-radius: 3px; background: #FFFDF8 var(--grain); color: #1F2A44; font: 400 15px/1.2 "Permanent Marker", cursive; filter: drop-shadow(1px 2px 0 rgb(31 42 68 / .2)); opacity: 0; transition: opacity 150ms; pointer-events: none; }
#bag .item.peek .hint { opacity: 1; }
#bag .hint:empty { display: none; }
/* A lifted thing's part rises out of the bag behind it, its heading already in the thing's world. */
#bag .sign { position: absolute; z-index: 0; opacity: 0; translate: 0 40px; scale: .5; transform-origin: 50% 100%; transition: opacity 180ms, translate 300ms cubic-bezier(.3, 1.5, .5, 1), scale 300ms cubic-bezier(.3, 1.5, .5, 1); pointer-events: none; filter: drop-shadow(1.5px 2.5px 0 rgb(31 42 68 / .22)); } /* placed over the lifted thing by app.js */
#bag .sign.on { opacity: 1; translate: 0 0; scale: 1; }
/* On a wide screen the page moves over when it has to, so the bag keeps a margin of its own beside it. */
@media (min-width: 701px) { body.doll .sheet { margin-left: max(200px, (100% - 1000px) / 2); } }
#bag.rummaging { animation: bag-shake 280ms ease-in-out infinite alternate; }
/* One stitched patch per part of the page; each fills with the thing that first brought that part out. */
#bag .patches { position: absolute; z-index: 3; left: 12%; right: 12%; bottom: 9%; display: flex; justify-content: space-between; pointer-events: none; }
#bag .patches span { width: 21%; aspect-ratio: 1; display: grid; place-items: center; border: 1.5px dashed rgb(31 42 68 / .4); border-radius: 4px; background: rgb(255 253 248 / .25); }
#bag .patches span:has(img) { border-style: solid; border-color: rgb(31 42 68 / .25); background: #FFFDF8 var(--grain); rotate: -3deg; }
#bag .patches img { width: 86%; height: 86%; object-fit: contain; animation: flutter 700ms cubic-bezier(.3, 1.2, .5, 1); }
@keyframes bag-shake { from { rotate: -3deg; } to { rotate: 3deg; } }
/* Something typed waits beside Aman while he's drawn holding it: it bobs inside a dashed cut line, and a ring fills
   as the drawing goes. The gremlin's wand keeps working meanwhile. */
.pending { position: absolute; z-index: 13; animation: bob 1.3s ease-in-out infinite alternate; }
.pending img { position: absolute; left: 15%; top: 15%; width: 70%; height: 70%; object-fit: contain; filter: drop-shadow(1px 2px 0 rgb(31 42 68 / .25)); }
.pending svg { position: absolute; inset: 0; width: 100%; height: 100%; rotate: -90deg; overflow: visible; }
.pending .cut { fill: rgb(255 253 248 / .6); stroke: rgb(31 42 68 / .4); stroke-width: 2.5; stroke-dasharray: 4 5; transform-box: fill-box; transform-origin: center; animation: spin 9s linear infinite; }
.pending .fill { fill: none; stroke: #8672B8; stroke-width: 5; stroke-linecap: round; stroke-dasharray: 100; stroke-dashoffset: 100; }
.pending.snip img { animation: snip 280ms cubic-bezier(.3, 1.6, .5, 1); }
.pending .scissors { transform-box: view-box; transform-origin: 50px 50px; }
.pending .scissors line { stroke: #3B4458; stroke-width: 2.6; stroke-linecap: round; }
.pending .scissors circle { fill: #FFFDF8; stroke: #C8553D; stroke-width: 2.2; }
@keyframes bob { to { translate: 0 -8px; } }
@keyframes spin { to { rotate: 360deg; } }
@keyframes snip { 40% { rotate: -10deg; scale: 1.12; } }
.gremlin.working .wand { animation: zap 300ms infinite alternate; }
@media (max-width: 700px) {
  body.doll .sheet { margin-bottom: 170px; }
  #bag { width: 130px; transition: width 450ms cubic-bezier(.3, .7, .3, 1), translate 300ms cubic-bezier(.3, .7, .3, 1); }
  #bag.small { width: 96px; }
  #bag .hint { font-size: 13px; }
  #bag .patches { bottom: auto; top: 30%; } /* high enough to stay in view while the bag is tucked */
  body.doll:not(.pulled) .c-stack[data-id="end"] { margin-top: 190px; } /* before the first pull, say hi sits clear of the big bag */
  /* After the first pull, the bag, the gremlin and the sound button sit on a strip of desk along the bottom, so the
     words scroll clear of them instead of under them. */
  body.doll.pulled::after { content: ''; position: fixed; z-index: 30; left: 0; right: 0; bottom: 0; height: 62px; background: #D9C3A0 var(--grain); box-shadow: 0 -2px 0 rgb(31 42 68 / .12); pointer-events: none; }
  #bag.small:not(.open) { translate: 0 58%; } /* tucked into the strip while you read; a tap lifts it back */
}
