/* Piku Print Club, the site. Chapter 2 (Add effects, id #goof): the FX try-on screen (inside the pinned tour phone) and, at the END of this file, the satellites of the step (family badges and drawn pieces round the phone).
   Loaded after screens.css (which it only overrides, never edits). Everything inside the screen scales with --u (one CSS pixel of the 360 wide
   phone layout), and any text that would fall under 11 rendered pixels is held at 11px by a max(): the tray grows instead of the words shrinking. */

/* The kid's colour. The demo kid is Maya (the Monster, teal #1E9A94). As in the app (EffectsPicker.swift): the picked tile and the picked family wear it at 28% over
   white (accent.opacity(0.28): teal gives #C0E3E1, which is --sel in base.css) with an ink ring on the tile, and Done is the colour at 100% with its readable ink on
   top. The app's rule (Color.readableInk) picks whichever of ink and white has the higher contrast: on teal that is ink (4.3:1; white would be 3.4:1). 4.3:1 passes
   only for LARGE bold text, so the word is Nunito 800 and never under 18.67px (14pt), whatever the screen's scale. The colour is only ever a fill. */
.scr-fx{--sel:#C0E3E1}

/* ============ top bar: Cancel, the title (or Clear all / Undo), Done ============ */
.fx-bar .fx-cancel{font-size:max(calc(12px*var(--ffl,1)),calc(17*var(--u)));color:var(--ink78)}
.fx-bar .fx-title{top:calc(8*var(--u));font-size:max(calc(13px*var(--ffl,1)),calc(19*var(--u)))}   /* centred on the same line as Cancel and Done (the bar's content box starts 6u down) */
.fx-bar .fx-title[hidden]{display:none}
/* Done: the kid's colour with the app's ink edge (an ink line just inside the pill, 1.5 pt, and a copy of it printed a hair off register in fluoro pink, a touch
   left and down: RisoEdge, CameraHome.swift). Same shape as the shutter. */
.fx-bar .fx-done{padding:0 max(calc(11px*var(--fl,1)),calc(15*var(--u)));background:var(--teal);color:var(--ink);font-size:max(calc(18.67px*var(--fl,1)),calc(17*var(--u)));font-weight:800;
  box-shadow:inset 0 0 0 calc(1.5*var(--u)) var(--ink),calc(-1.1*var(--u)) calc(.9*var(--u)) 0 var(--pink)}
.fx-bar .fx-done:focus-visible{box-shadow:inset 0 0 0 calc(1.5*var(--u)) var(--ink),0 0 0 5px #fff}
/* Clear all (and Undo, the same button) REPLACES the title while anything is on: a white pill, an ink filled-circle icon and the label, a soft ink shadow
   (titlePill in EffectsPicker.swift: 38 pt tall, 6 pt between icon and word; the padding is tighter than the app's 12 and 16, and Done's than its 22, so the two clear each other on the smallest screens, where Done's word is held at 18.67px) */
.fx-bar .fx-clear{position:absolute;z-index:2;left:50%;top:calc(10*var(--u));translate:-50% 0;display:flex;align-items:center;gap:calc(6*var(--u));height:calc(38*var(--u));padding:0 calc(12*var(--u)) 0 calc(9*var(--u));border:0;border-radius:999px;background:#fff;color:var(--ink);font-weight:700;font-size:max(calc(12px*var(--ffl,1)),calc(15*var(--u)));line-height:1;white-space:nowrap;box-shadow:0 calc(3*var(--u)) calc(12*var(--u)) rgba(30,42,36,.14)}
.fx-bar .fx-clear:focus-visible{box-shadow:0 0 0 5px #fff}
.fx-bar .fx-clear[hidden]{display:none}
.fx-ci{flex:none;display:block;width:max(calc(14px*var(--fl,1)),calc(16*var(--u)));height:max(calc(14px*var(--fl,1)),calc(16*var(--u)))}
.fx-ci circle{fill:var(--ink)}
.fx-ci path{fill:none;stroke:#fff;stroke-width:2.3;stroke-linecap:round;stroke-linejoin:round}
.fx-clear[data-mode=clear] .fx-ci-undo,.fx-clear[data-mode=undo] .fx-ci-clear{display:none}
.fx-clear.pop-in,.fx-title.pop-in{animation:fx-pillin .34s var(--spring-pop) both}
@keyframes fx-pillin{from{opacity:0;scale:.82}to{opacity:1;scale:1}}

/* ============ the picture: a white print card holding the Monster ============ */
.fx-card{flex:none;margin:auto;width:calc(298*var(--u));padding:calc(13*var(--u)) calc(13*var(--u)) calc(16*var(--u));background:#fff;border-radius:calc(16*var(--u));box-shadow:0 calc(10*var(--u)) calc(22*var(--u)) rgba(30,42,36,.16),0 calc(2*var(--u)) calc(5*var(--u)) rgba(30,42,36,.1)}
/* --rl / --rw / --rb place the rig in the picture (left, width, bottom); the pinned print on the wall uses the same three numbers */
.fx-photo,.wprint .pph{--rl:5%;--rw:90%;--rb:10%}   /* v3.8: the face sits in the middle of the picture (it was 8% below the bottom edge, which put the eyes 70% of the way down) */
.fx-photo{position:relative;overflow:hidden;aspect-ratio:3/4;border-radius:calc(7*var(--u));cursor:pointer;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none}
.fx-photo::after{content:"";position:absolute;inset:0;z-index:7;border-radius:inherit;box-shadow:inset 0 0 0 1px rgba(0,0,0,.14);pointer-events:none}
/* the photo's backdrop is a pale pink (a tint of the chapter's pink): teal and mint looks (Wizard, Star Eyes, Bunny Ears, Melon) stay readable on it */
.b-blush{--pbg:#FFD3EB}
.colwrap{position:absolute;inset:0;transition:filter .3s}
.fx-photo .rig,.wprint .colwrap .rig{left:var(--rl);width:var(--rw);bottom:var(--rb);transform-origin:50% 100%}
.fx-photo .rig{transition:scale .5s var(--spring-pop),translate .5s var(--spring-pop)}
/* under a costume the body would show as a floating hem, and a horn can poke out round a bitten slice of toast, so the jersey and the head step out
   (the costume covers head and shoulders anyway; the pasted-back eyes and mouth are their own copies of the head's drawing) */
.rig .b-body,.rig .b-head,.rig .l-brows{transition:opacity .3s}
.rig.costumed .b-body,.rig.costumed .b-head,.rig.costumed .l-brows{opacity:0}   /* a costume has its own pasted eyes, brows included */
.rig .tower{position:absolute;inset:0;transform-origin:50% 84.9%;transition:transform .45s var(--spring-pop)}
.layer{position:absolute;inset:0;pointer-events:none}
.layer.hop{translate:0 var(--hop,-7.8%);transition:translate .18s ease-out}
.l-hat,.l-face,.l-costume{transition:translate .3s var(--spring-pop)}

/* Dizzy: the head rocks and the eyes whirl a few times, then rest (nothing on this page loops for ever) */
.rig .tower.dz{animation:fx-dizzy 1.1s ease-in-out 3}
@keyframes fx-dizzy{0%,100%{rotate:0deg}25%{rotate:-7deg}75%{rotate:7deg}}

/* Warp and cut-outs: a copy of the head's own drawing, cropped, blown up and pasted back with a soft rim */
.l-patch .pt{position:absolute;overflow:visible}
.l-patch .pt svg{display:block;width:100%;height:100%;border-radius:50%;overflow:hidden;-webkit-mask-image:radial-gradient(closest-side,#000 74%,transparent 100%);mask-image:radial-gradient(closest-side,#000 74%,transparent 100%)}
.l-patch .pt.spin svg{animation:fx-spin 1.4s linear 3}
.l-patch .pt.spin.rev svg{animation-direction:reverse}
@keyframes fx-spin{to{rotate:360deg}}
.l-patch .cover{position:absolute;border-radius:50%;background:var(--pink);-webkit-mask-image:radial-gradient(closest-side,#000 86%,transparent 100%);mask-image:radial-gradient(closest-side,#000 86%,transparent 100%)}
/* the faces pasted onto a costume keep more of their own skin opaque, so less of a pink halo shows round them */
.l-patch .pt.soft svg{-webkit-mask-image:radial-gradient(closest-side,#000 84%,transparent 100%);mask-image:radial-gradient(closest-side,#000 84%,transparent 100%)}
/* a hand-drawn spiral eye (Dizzy): no feathering, it turns */
.l-patch .pt.spiral svg{-webkit-mask-image:none;mask-image:none;border-radius:0;overflow:visible}
.l-patch .cover.muz{background:var(--pink)}

/* the Monster opens its mouth while you hold it (or press "Open your mouth") */
.l-mouth svg{position:absolute;inset:0;width:100%;height:100%;opacity:0;scale:.55;transform-origin:50% 58%;transition:opacity .12s ease-out,scale .22s var(--spring-pop)}
.l-mouth.open svg{opacity:1;scale:1}
/* while the mouth is open the real smirk and fang are hidden (the head's mouth group follows --mouth-ink, set in demo-fx.js inkState) */

/* Magic: floaters drift up off the head, pour from the mouth and burst round the eyes. Each is finite and removes itself. */
.l-magic .mg{max-width:none;position:absolute;display:block;pointer-events:none;opacity:0}
.l-magic .mg.drift{animation:fx-drift var(--t,5.5s) ease-out forwards}
.l-magic .mg.fall{animation:fx-fall var(--t,1.5s) ease-in forwards}
.l-magic .mg.burst{animation:fx-burst var(--t,.9s) ease-out forwards}
.l-magic .mg.still{opacity:1}
@keyframes fx-drift{0%{opacity:0;scale:.5}14%{opacity:1;scale:1}76%{opacity:1}100%{opacity:0;translate:var(--dx) var(--dy);rotate:var(--rot)}}
@keyframes fx-fall{0%{opacity:0;scale:.5}10%{opacity:1;scale:1}78%{opacity:1}100%{opacity:0;translate:var(--dx) var(--dy);rotate:var(--rot)}}
@keyframes fx-burst{0%{opacity:0;scale:.4}14%{opacity:1;scale:1}68%{opacity:1}100%{opacity:0;translate:var(--dx) var(--dy);rotate:var(--rot)}}
@keyframes fx-still{0%{opacity:0}15%{opacity:1}80%{opacity:1}100%{opacity:0}}

/* Play with the Monster: three invisible buttons over the brows, eyes and mouth (one tab stop, arrow keys move between them) */
.fx-hots{position:absolute;z-index:3;left:var(--rl);width:var(--rw);bottom:var(--rb);aspect-ratio:904/745;transform-origin:50% 100%;transition:scale .5s var(--spring-pop),translate .5s var(--spring-pop)}
.fx-hots[hidden]{display:none}
.fx-hots button{position:absolute;padding:0;border:0;background:none;border-radius:999px;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
.fx-hots button::after{content:"";position:absolute;inset:-16px -8px}   /* tap area: at least 44px even on a small screen */
.fx-hots .h-brow::after{inset:-24px -8px -6px}
.fx-hots .h-brow{left:27%;top:27%;width:46%;height:9.5%;z-index:2}   /* above the eyes, whose larger hit area would otherwise cover the brows' centre */
.fx-hots .h-eyes{left:29%;top:36.5%;width:42%;height:10%}
.fx-hots .h-mouth{left:31%;top:50%;width:38%;height:14%}
.fx-hots .h-mouth::after{inset:-8px -10px -16px}

.fx-roll{z-index:6;bottom:calc(14*var(--u))}
.fx-roll b{font-size:max(calc(13px*var(--ffl,1)),calc(17*var(--u)))}
.fx-roll span{font-size:max(calc(11px*var(--ffl,1)),calc(13*var(--u)))}

/* "How big" slider (Warp only) */
.fx-size{position:absolute;right:calc(6*var(--u));top:50%;translate:0 -50%;z-index:6;width:calc(36*var(--u));height:calc(196*var(--u));padding:calc(9*var(--u)) 0;border-radius:999px;background:rgba(0,0,0,.32);display:flex;flex-direction:column;align-items:center;gap:calc(8*var(--u));color:#fff;animation:fadein .25s ease-out both}
.fx-size[hidden]{display:none}
.fx-size .ic{width:calc(18*var(--u));height:calc(18*var(--u))}
/* pan-x: a finger moving up or down on this narrow capsule drives the slider; sideways still scrolls. Nothing else on the page is touched. */
.fx-track{position:relative;flex:1;width:calc(5*var(--u));min-width:4px;border-radius:9px;background:rgba(255,255,255,.35);touch-action:pan-x;cursor:ns-resize}
.fx-track::before{content:"";position:absolute;left:-20px;right:-20px;top:-6px;bottom:-6px}
.fx-fill{position:absolute;left:0;right:0;bottom:0;height:calc(var(--v,.6)*100%);border-radius:9px;background:var(--teal)}   /* the kid's colour (the app's SizeSlider accent) */
.fx-knob{position:absolute;left:50%;bottom:calc(var(--v,.6)*100%);width:calc(22*var(--u));height:calc(22*var(--u));min-width:16px;min-height:16px;margin:0 0 calc(-11*var(--u)) calc(-11*var(--u));border-radius:50%;background:#fff;box-shadow:0 1px 4px rgba(0,0,0,.25)}
.fx-dot{width:calc(8*var(--u));height:calc(8*var(--u));min-width:6px;min-height:6px;border:calc(2*var(--u)) solid #fff;border-radius:50%}

/* ============ the docked panel ============ */
.fx-panel{height:auto;min-height:calc(144*var(--u));padding-top:calc(6*var(--u));gap:calc(2*var(--u));justify-content:flex-start}
.fx-panel.one{justify-content:center;padding-top:0}
.fx-panel [hidden]{display:none}
/* group words */
.fx-tabs button,.fx-static span{font-size:max(calc(12px*var(--ffl,1)),calc(15*var(--u)))}
.fx-tabs button::after{content:"";position:absolute;inset:-7px 0}   /* the words are 40u tall; the tap area is at least 44px */
.fx-tabs button span{display:flex;align-items:center}
.pn-tabs.fx-static span{flex:1;display:flex;align-items:center;justify-content:center;position:relative;font-weight:700;color:var(--ink72)}
.pn-tabs.fx-static span.fx-on{font-weight:800;color:var(--ink)}
.pn-tabs.fx-static span.fx-on::before{content:"";position:absolute;left:50%;bottom:0;width:calc(56*var(--u));height:calc(3*var(--u));margin-left:calc(-28*var(--u));border-radius:9px;background:var(--ink)}
/* the chosen group's underline is an ink bar printed with its off-register pink copy, a touch left and down (the app's InkUnderline: risoGhost, offset -1.1, 0.9) */
.scr-fx .pn-tabs button[aria-selected=true]::before,.pn-tabs.fx-static span.fx-on::before{box-shadow:calc(-1.1*var(--u)) calc(.9*var(--u)) 0 var(--pink)}
/* the dots that say "something is on in here": a small ink dot beside the word (the app: Circle().fill(ink), 6 pt, 4 to 5 pt from the label) */
.scr-fx .has-dot::after,.scr-fx i.has-dot{content:"";display:inline-block;width:max(calc(6px*var(--fl,1)),calc(6*var(--u)));height:max(calc(6px*var(--fl,1)),calc(6*var(--u)));border-radius:50%;background:var(--ink);margin-left:max(calc(4px*var(--fl,1)),calc(5*var(--u)))}
.scr-fx i.has-dot::after{display:none}

/* the one sideways row of tiles, with a chevron and a soft edge that say "there is more this way" */
/* the row is 10px taller than the tiles so a focused tile's ring (3px outline, 2px off) is not cut off by the row's edge */
.fx-rowwrap{position:relative;flex:none;height:max(calc(84*var(--u) + 10px),calc(76px*var(--fl,1)))}
.fx-rowwrap::before,.fx-rowwrap::after{content:"";position:absolute;top:0;bottom:0;width:calc(40*var(--u));z-index:2;pointer-events:none;opacity:0;transition:opacity .2s}
.fx-rowwrap::before{left:0;background:linear-gradient(90deg,#fff 35%,rgba(255,255,255,0))}
.fx-rowwrap::after{right:0;background:linear-gradient(270deg,#fff 35%,rgba(255,255,255,0))}
.fx-rowwrap[data-l]::before,.fx-rowwrap[data-r]::after{opacity:1}
.fx-rowwrap .fx-row{height:100%}
.fx-static.fx-row{height:max(calc(84*var(--u) + 10px),calc(76px*var(--fl,1)))}
.fx-row{position:relative;scroll-padding-inline:calc(16*var(--u));overscroll-behavior:auto}
.fx-row .tile{width:auto;min-width:max(calc(76*var(--u)),calc(68px*var(--fl,1)));height:max(calc(84*var(--u)),calc(66px*var(--fl,1)));justify-content:flex-start;gap:calc(4*var(--u));padding:calc(10*var(--u)) max(calc(3px*var(--fl,1)),calc(3*var(--u))) 0;white-space:normal}   /* the app centres a 42 pt picture, 4 pt and one line of name in the 84 pt tile: about 11 pt of air on top */
/* picked: the kid's tint and the app's 2.5 pt ink ring just inside the edge (the tile does not grow) */
.fx-row .tile[aria-pressed=true],.fx-row .tile.fx-on{background:var(--sel);box-shadow:inset 0 0 0 calc(2.5*var(--u)) var(--ink)}
.fx-row .tile .tn{font-size:max(calc(11px*var(--ffl,1)),calc(13*var(--u)));line-height:1.06;text-align:center;overflow:visible;max-width:none;text-wrap:balance}
.fx-row .tile .tp{flex:none;position:relative}
/* the drawing fills the 64 x 42 art box, centred and never cropped: the app fits each drawing's ink in that box (scaledToFit). Laid over the box so the
   grid's auto row can't turn its percentage height into the drawing's own height */
.fx-row .tile .tp img{position:absolute;inset:0;width:100%;height:100%;max-width:none;max-height:none;object-fit:contain}
.fx-more{position:absolute;z-index:3;top:50%;translate:0 -50%;width:calc(30*var(--u));height:calc(30*var(--u));min-width:26px;min-height:26px;padding:0;border:0;border-radius:50%;background:#fff;color:var(--ink);box-shadow:0 1px 1px rgba(30,42,36,.3),0 2px 7px rgba(30,42,36,.22);display:grid;place-items:center}
.fx-more::after{content:"";position:absolute;inset:-9px}
.fx-more.r{right:calc(5*var(--u))}
.fx-more.l{left:calc(5*var(--u))}
.fx-more .ic{width:56%;height:56%;stroke-width:2.6}
.fx-more[hidden]{display:none}

/* (no captions under the tiles any more: the tray is just the tabs and the one row of tiles) */

/* Colour tiles: a square crop of the Monster's picture through the colour (the app shows a live camera snapshot there: 42 pt, radius 10, a hairline of ink at 14%) */
.tile .tp .sw{position:relative;display:block;flex:none;width:calc(42*var(--u));height:calc(42*var(--u));border-radius:calc(10*var(--u));overflow:hidden}
.tile .tp .sw-in{position:absolute;inset:0;display:block;background:#FFD3EB}
.tile .tp .sw svg{display:block;width:100%;height:100%;overflow:hidden}
.tile .tp .sw::after{content:"";position:absolute;inset:0;border-radius:inherit;box-shadow:inset 0 0 0 1px rgba(30,42,36,.14);pointer-events:none}

/* family bar: each family is a riso drawing (a die-cut sticker, 30 pt, with the app's soft shadow), its word, and a small ink dot when something is on */
.fx-fam button{position:relative;height:max(calc(54*var(--u)),calc(44px*var(--fl,1)));font-size:max(calc(11px*var(--ffl,1)),calc(13*var(--u)))}
.fx-fam{padding-bottom:calc(10*var(--u))}
.fx-fam .fam-ic{flex:none;display:block;width:calc(30*var(--u));height:calc(30*var(--u));min-width:26px;min-height:26px;object-fit:contain;pointer-events:none;-webkit-user-drag:none;user-select:none;filter:drop-shadow(0 calc(1*var(--u)) calc(1.5*var(--u)) rgba(30,42,36,.3))}

/* the ring that shows where the "finger" presses during the auto demo */
.scr-fx .tap{position:absolute;left:50%;top:50%;z-index:4;width:calc(56*var(--u));height:calc(56*var(--u));margin:calc(-28*var(--u)) 0 0 calc(-28*var(--u));border:calc(3*var(--u)) solid var(--pink);border-radius:50%;pointer-events:none;animation:fx-tap .75s ease-out forwards}
@keyframes fx-tap{from{opacity:.95;scale:.35}to{opacity:0;scale:1.25}}

/* without script: a still picture with quiet buttons */
html:not(.js) .fx-cancel,html:not(.js) .fx-done{opacity:.6}


/* ============ FX: reduced motion (no drift, no springs, no loops: a still picture and plain fades) ============ */
@media (prefers-reduced-motion:reduce){
  .rig .tower.dz,.l-patch .pt.spin svg{animation:none}
  .rig .tower,.fx-photo .rig,.fx-hots,.l-mouth svg,.colwrap,.layer.hop,.l-hat,.l-face,.l-costume{transition-duration:.01s}
  .l-magic .mg.drift,.l-magic .mg.fall,.l-magic .mg.burst{animation:fx-still var(--t,1.6s) ease-out forwards}
  .fx-clear.pop-in,.fx-title.pop-in,.scr-fx .tap,.fx-size{animation:none}
}


/* ==========================================================================================================================
   v3 STEP: "Add effects". The pink band's words (title, line, chips, Show me) are laid out by css/tour.css; this block only places what is stuck round
   the pinned phone: the four family icons as flat badges and eight real drawn pieces as die-cut stickers. They live in .step-sats, a box exactly on the
   phone (same left, top, width and height as the pinned phone), and every number below is counted from the phone:

     --pu   one unit = 1% of the phone's width (so a piece grows with the phone, never fixed px)
     --w    the piece's width in units, --ar its height / width (the drawing's own shape), --sw the width it really gets (px)
     --x    its CENTRE counted from the phone's centre line, in units    (near the phone)
     --vx   the same, in vw                                               (far from the phone: the free room each side grows with the window)
     --cy   its CENTRE counted from the phone's top, as a share of the phone's height (0 top edge, 1 bottom edge)

   The words sit in the middle of the screen (title left, line + chips + Show me right), so the pieces live in the free bands ABOVE and BELOW them and the badges
   stick on the phone's four corners. The title is about 0.28 of the phone's height (centred), the right-hand words about 0.55, so the left bands are
   cy -0.05 to 0.31 and 0.69 to 1.05, the right ones cy -0.05 to 0.13 and 0.87 to 1.05 (the crown and the stars may use the strip above the phone, right of the nav pill).
   Stacking: pieces are z 1 (under the words, which are z 2), the badges are .sat-over (z 12, the tour's number) and stick on the phone's corners, the phone is z 10.
   Taste: type sits straight on the pink, no white rings, no white cards. Only the drawn pieces keep their white die-cut sticker edge.
   ========================================================================================================================== */
#goof{--pu:calc(var(--tpw) / 100)}

/* position:sticky makes .step-stage a stacking context of its own, so nothing inside it (the badges' z 12) could ever paint over the phone (z 10) while the stage
   itself is under it. This step's badges stick on the phone's corners, so lift THIS stage above the phone: it has no background and no pointer events (only its
   buttons take clicks), so the phone stays fully usable. (The same one-line fix is wanted in css/tour.css for every step: see the report.) */
.tour #goof .step-stage{z-index:11}

/* the halftone sits INSIDE the sticky stage, so it stays where it is while the words are pinned. Two feathered patches in the top-left and bottom-right corners
   only: the words are in the middle band, and each patch stops short of the phone's column (the stage is above the phone now, so dots must never reach it) */
#goof .efx-dots::before,#goof .efx-dots::after{content:"";position:absolute;width:calc(50vw - var(--pw) / 2 - 1vw + 6vw);aspect-ratio:1.6;max-width:1300px;background:url(/assets/brand/halftone-paper.svg) center/contain no-repeat;
  -webkit-mask-image:radial-gradient(closest-side at 50% 50%,#000 25%,transparent 100%);mask-image:radial-gradient(closest-side at 50% 50%,#000 25%,transparent 100%)}
#goof .efx-dots::before{right:auto;left:-6vw;top:-14svh;opacity:.6;scale:-1 1}
#goof .efx-dots::after{left:auto;right:-6vw;bottom:-16svh;opacity:.5}

/* a satellite: an outer box that is placed, tilted and popped in (.pop), an inner box that floats, and the button */
.efx-sat{--w:24;--ar:1;--cy:.5;--x:0;--vx:0;--sw:calc(var(--w) * var(--pu));
  position:absolute;z-index:1;pointer-events:none;width:var(--sw);
  left:calc(50% + var(--x) * var(--pu) + var(--vx) * 1vw - var(--sw) / 2);
  top:max(calc(30px - var(--pt)),calc(var(--cy) * 100% - var(--sw) * var(--ar) / 2))}   /* never above the top of the screen */
/* POP IN PLACE: each floating piece appears right where it sits, with a small spring (grows from a dot, overshoots a touch, settles into its tilt).
   No travelling, no burst. JS (demo-fx.js) arms the section (.efx-armed) and adds .efx-in once the stage is on screen; it takes .efx-in off again when the
   step has scrolled completely away, so the pieces pop again next time. Without script, or with reduced motion, they are simply there. */
.efx-sat{rotate:var(--r,0deg)}
.efx-armed:not(.efx-in) .efx-sat{opacity:0;scale:.15}
.efx-armed:not(.efx-in) .efx-sat *{pointer-events:none!important}
.efx-in .efx-sat{animation:efx-popin .72s cubic-bezier(.3,.9,.4,1) calc(var(--d,0s) * 2.4) both}
@keyframes efx-popin{0%{opacity:0;scale:.15}36%{opacity:1}62%{scale:1.14}84%{scale:.97}100%{opacity:1;scale:1}}
.efx-float{animation:efx-bob var(--fs,6s) ease-in-out var(--fd,0s) infinite}
@keyframes efx-bob{0%,100%{translate:0 0;rotate:0deg}50%{translate:calc(var(--pu) * .4) calc(var(--pu) * -2.2);rotate:2.4deg}}
#goof.is-off .efx-float{animation-play-state:paused}

.efx-piece,.efx-fam{position:relative;display:block;width:100%;padding:0;border:0;background:none;cursor:pointer;pointer-events:auto;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;
  transition:scale .45s var(--spring-pop)}
.efx-piece{display:grid;align-content:center;min-height:44px}   /* thin pieces (glasses) still get a 44px tap box, the drawing stays centred in it */
.efx-piece:disabled,.efx-fam:disabled{cursor:default}
.efx-piece:focus-visible{border-radius:14px}
.efx-fam:focus-visible{border-radius:14px}
.efx-piece:active,.efx-fam:active{scale:.94}
@media (hover:hover){.efx-piece:not(:disabled):hover,.efx-fam:not(:disabled):hover{scale:1.1}}

/* a drawn piece, cut out like a sticker: a white die-cut edge (eight small shadows grow the shape evenly, sized from the phone), then a soft drop shadow */
.efx-piece{--edge:#fff;--e:max(3px,calc(var(--pu) * .62));--e2:calc(var(--e) * .7)}
.efx-piece img{display:block;width:100%;height:auto;max-width:none;-webkit-user-drag:none;
  filter:drop-shadow(var(--e) 0 0 var(--edge)) drop-shadow(calc(var(--e) * -1) 0 0 var(--edge)) drop-shadow(0 var(--e) 0 var(--edge)) drop-shadow(0 calc(var(--e) * -1) 0 var(--edge))
    drop-shadow(var(--e2) var(--e2) 0 var(--edge)) drop-shadow(calc(var(--e2) * -1) calc(var(--e2) * -1) 0 var(--edge)) drop-shadow(var(--e2) calc(var(--e2) * -1) 0 var(--edge)) drop-shadow(calc(var(--e2) * -1) var(--e2) 0 var(--edge))
    drop-shadow(0 calc(var(--pu) * 1.4) calc(var(--pu) * 1.6) rgba(30,42,36,.28))}
/* on: the edge turns sunflower and a small flat ink tick says so (the tray inside the phone shows the same pick). --tx moves the tick in from the corner for a drawing narrower than its box (the pineapple) */
.efx-piece[aria-pressed=true]{--edge:var(--sunflower)}
.efx-piece[aria-pressed=true]::after{content:"";position:absolute;right:var(--tx,-3%);top:-4%;width:max(24px,calc(8 * var(--pu)));aspect-ratio:1;border-radius:50%;background:var(--ink)}
.efx-piece[aria-pressed=true]::before{content:"";position:absolute;z-index:1;right:calc(var(--tx,-3%) + max(24px,calc(8 * var(--pu))) * .3);top:calc(-4% + max(24px,calc(8 * var(--pu))) * .26);width:max(6px,calc(2.1 * var(--pu)));height:max(11px,calc(3.9 * var(--pu)));border:solid var(--paper);border-width:0 max(2px,calc(.6 * var(--pu))) max(2px,calc(.6 * var(--pu))) 0;rotate:42deg}

/* a family badge: the app's own drawn family icon (assets/fx-ui/icon-*.svg, the same four drawings as the family bar inside the phone). Each one is already a die-cut
   sticker with its white edge, so there is no disc and no ring behind it: only a soft drop shadow, sized from the phone. The open family is lifted a touch and gets a
   hard ink shadow, off register like a print (a filter on the drawing, so it never fights the focus ring's box-shadow). */
.efx-fam{display:block;line-height:0}
.efx-fam .fam-ic{display:block;width:100%;height:auto;max-width:none;-webkit-user-drag:none;user-select:none;
  filter:drop-shadow(0 calc(var(--pu) * 1.4) calc(var(--pu) * 1.6) rgba(30,42,36,.28))}
.efx-fam[aria-current=true]{scale:1.1}
.efx-fam[aria-current=true] .fam-ic{filter:drop-shadow(calc(var(--pu) * 1.1) calc(var(--pu) * 1.1) 0 var(--ink)) drop-shadow(0 calc(var(--pu) * 1.6) calc(var(--pu) * 2) rgba(30,42,36,.2))}

/* the four chips beside the words: the same drawings, decorative (the tour's disc, border and tint are switched off: the drawing is its own sticker) */
#goof .step-ico{display:block;width:2.4em;height:2.4em;border:0;border-radius:0;background:none}
#goof .step-ico .fam-ic{display:block;width:100%;height:100%;object-fit:contain;-webkit-user-drag:none;filter:drop-shadow(0 .05em .07em rgba(30,42,36,.3))}

/* ---- DESKTOP (1000 and up). Left side: the wizard hat in the top-left corner, the shades above the title, the pineapple and the party hat below it (counted from the phone AND the window: the phone's size and the window's width do not grow at the same rate).
   Right side: the crown in the top-right corner, the star eyes in the free pocket beside the chips, the bunny ears and the shooting star below Show me. The badges stick on the phone's
   four corners (just outside the bezel, so they never cover the screen's own buttons). ---- */
.p-wizardhat{--w:46;--ar:.9;--vx:-34;--cy:.15;--r:-9deg}
.p-sunglasses{--w:32;--ar:.355;--vx:-20;--cy:.285;--r:-6deg}
.p-pineappleface .efx-piece{--tx:11%}
.p-pineappleface{--w:40;--ar:1;--x:-122;--vx:-5;--cy:.84;--r:8deg}
.p-chefhat{--w:22;--ar:.95;--x:-86;--vx:-2.5;--cy:.8;--r:12deg}
.p-crown{--w:36;--ar:.833;--vx:34;--cy:.0;--r:8deg}
.p-starglasses{--w:32;--ar:.414;--x:66;--vx:14;--cy:.46;--r:7deg}
.p-bunnyears{--w:22;--ar:1.01;--x:88;--vx:6;--cy:.9;--r:-8deg}
.p-stars{--w:28;--ar:.984;--x:122;--vx:5;--cy:.86;--r:10deg}
.b-warp{--w:26;--ar:.771;--x:-64.5;--cy:.08;--r:-8deg}
.b-looks{--w:20;--ar:1.151;--x:-61.5;--cy:.92;--r:7deg}
.b-magic{--w:17;--ar:1.228;--x:59.5;--cy:.062;--r:8deg}
.b-colour{--w:25;--ar:.819;--x:64;--cy:.92;--r:-7deg}

/* a very wide, short window (2 to 1 and wider): the words are big there, so the badges are a little smaller and keep clear of the nav pill and Show me */
@media (min-aspect-ratio:2/1) and (min-width:1000px){.b-warp{--w:23;--x:-63;--cy:.075}.b-magic{--w:16;--x:59;--cy:.06}.b-looks{--w:18;--x:-60.5;--cy:.935}.b-colour{--w:22;--x:62.5;--cy:.935}}

/* a wide AND short window (2.2 to 1 and wider, 820px tall at most): the phone is small there but the words are sized from the width, so the right-hand words
   run taller than the phone and the badges would sit on them. The chips are the same four icons, so the badges rest, and the two low pieces on the right move out. */
@media (min-aspect-ratio:11/5) and (max-height:820px) and (min-width:1000px){
  .efx-fams{display:none}
  .p-bunnyears{--vx:14}
  .p-stars{--vx:17}
}

/* a narrow desktop (1000 to 1199): the phone is only about 300px wide, so the words take most of each side: fewer pieces, kept to the corners */
@media (min-width:1000px) and (max-width:1199.98px){
  .p-chefhat,.p-bunnyears,.p-stars,.p-starglasses{display:none}
}

/* ---- PHONES AND TABLETS (under 1000, or under 700 wide): the words are in the top zone and the phone is below, so there is no room beside it on a narrow
   screen. The family badges stay home (the chips above are the same four icons) and three pieces (four from 560 wide) perch on the phone's top edge, between the
   words and the phone, each as tall as that strip allows (--hmax: a share of the screen's height, whatever the phone's size). A wider tablet (600 and up) also has
   a free side each (the pineapple on the left, the star eyes on the right). ---- */
@media (max-width:999.98px) and (min-height:521px),(max-width:699.98px){
  /* the free strip between the words and the phone's top edge: the zone, minus the stage's top padding (62px), the title (its size is worked out the same way as
     in css/tour.css, this title is 5.9em wide on one row), the row gaps, the line and the chips (none when the screen is short) */
  #goof{--tfs:min(17vw,calc(var(--vh100) * .095),6.4rem,calc((100vw - 2 * var(--pad) - 70px) / 5.9));
    --tl:calc(1.15 * clamp(1.1rem,3.4vw,1.5rem));--tc:calc(2.5 * clamp(.85rem,2.6vw,1.1rem));
    --free:calc(var(--zone) - 62px - .9 * var(--tfs) - 10px - var(--tl) - var(--tc) - 22px)}
  .efx-sat{--hmax:clamp(36px,calc(var(--free) + 2 * var(--pu)),84px);--sw:min(calc(var(--w) * var(--pu)),calc(var(--hmax) / var(--ar)));
    z-index:12;top:calc(2 * var(--pu) - var(--sw) * var(--ar))}
  .efx-pieces .efx-sat{--vx:0}
  .p-wizardhat{--w:32;--x:-33}
  .p-crown{--w:27;--x:0}
  .p-chefhat{--w:19;--x:33}
  .p-bunnyears,.p-sunglasses,.p-starglasses,.p-pineappleface,.p-stars{display:none}
  /* no halftone here: the words fill the top and the phone the rest (the stage is above the phone, dots must never reach it) */
  #goof .efx-dots{display:none}
}
@media ((max-width:999.98px) and (min-height:521px) and (max-height:700px)),((max-width:699.98px) and (max-height:700px)){
  #goof{--tc:0px}
}
/* the words in this step, on a narrow screen: the round Show me from tour.css starts at 520px, but the title and Show me share a row up to 700 (so the title keeps its
   one row), and four chips on 360 wide would wrap to a second row (and sit on the pieces): tighter gaps keep them on one */
@media (max-width:699.98px){
}
@media (max-width:999.98px){
  #goof .step-ico{width:2.05em;height:2.05em}   /* the chips are a row here: a little smaller than beside the words, so four still fit on one line */
}
@media (max-width:429.98px){
  #goof .step-chips{flex-wrap:nowrap;column-gap:.5em}
  #goof .step-chip{gap:.4em}
}
@media ((max-width:999.98px) and (min-height:521px)) and (min-width:560px),((max-width:699.98px) and (min-width:560px)){
  .p-wizardhat{--x:-43}
  .p-crown{--x:-15}
  .p-bunnyears{display:block;--w:21;--x:12}
  .p-chefhat{--x:38}
}
@media ((max-width:999.98px) and (min-height:521px)) and (min-width:600px),((max-width:699.98px) and (min-width:600px)){
  .p-pineappleface,.p-starglasses{display:block;--sw:calc(var(--w) * var(--pu));z-index:1;top:max(calc(16px - var(--pt)),calc(var(--cy) * 100% - var(--sw) * var(--ar) / 2))}
  .p-pineappleface{--w:28;--x:-66;--cy:.62;--r:8deg}
  .p-starglasses{--w:30;--x:66;--cy:.5;--r:7deg}
}

/* a tablet that is wide but not tall (700 to 999 wide, under 960 tall): the strip over the phone is too thin for the perched row, and the phone is small beside
   a lot of free room, so four pieces sit on the sides instead */
@media (min-width:700px) and (max-width:999.98px) and (max-height:959.98px){
  .p-wizardhat,.p-crown,.p-pineappleface,.p-starglasses{display:block;--sw:calc(var(--w) * var(--pu));z-index:1;top:max(calc(16px - var(--pt)),calc(var(--cy) * 100% - var(--sw) * var(--ar) / 2))}
  .p-wizardhat{--w:30;--x:-68;--cy:.2;--r:-9deg}
  .p-crown{--w:28;--x:68;--cy:.16;--r:8deg}
  .p-bunnyears,.p-chefhat{display:none}
}

@media (prefers-reduced-motion:reduce){
  .efx-float{animation:none}
  .efx-piece,.efx-fam{transition-duration:.01s}
}
@media print{.efx-float{animation:none}}

/* ---- PHONES (up to 700 wide): all eight pieces live in the margins beside the phone, four a side, tucked in 8px, like Decorate's stickers (they stay tappable) ---- */
@media (max-width:700px){
  .efx-sat{--sw:min(calc(var(--m) + 8px),76px);z-index:1;top:calc(var(--cy) * 100% - var(--sw) * var(--ar) / 2)}
  .efx-pieces .efx-sat{--vx:0}
  .p-wizardhat,.p-chefhat,.p-sunglasses,.p-pineappleface{display:block;left:calc(var(--m) * -1 + 3px)}
  .p-crown,.p-starglasses,.p-bunnyears,.p-stars{display:block;left:calc(100% - 8px)}
  .p-wizardhat{--cy:.09;--r:-9deg}
  .p-chefhat{--cy:.31;--r:8deg}
  .p-sunglasses{--cy:.52;--r:-7deg}
  .p-pineappleface{--cy:.76;--r:7deg}
  .p-crown{--cy:.1;--r:8deg}
  .p-starglasses{--cy:.29;--r:7deg}
  .p-bunnyears{--cy:.5;--r:-8deg}
  .p-stars{--cy:.7;--r:9deg}
}

