:root{font-family:ui-rounded,'SF Pro Rounded','Avenir Next',system-ui,sans-serif;color:#244868;background:#abdcf6;font-synthesis:none;--ink:#244868;--cream:#fffbea;--blue:#239eda;--green:#2bb97a}*{box-sizing:border-box}body{margin:0}button,input{font:inherit}button{cursor:pointer;touch-action:manipulation;color:inherit;border:0}button:disabled{cursor:default}button:focus-visible,input:focus-visible,[tabindex]:focus-visible{outline:4px solid #ffda49;outline-offset:4px}button{transition:transform .15s,filter .15s}button:hover{filter:brightness(1.05)}button:active{transform:scale(.96)}button img{pointer-events:none}h1,h2,p{margin-top:0}h1{font-size:36px;line-height:1.12;letter-spacing:-1px}h2{font-size:26px}p{line-height:1.5}h1:focus{outline:0}.icon{width:48px;height:48px;object-fit:contain;display:inline-block;vertical-align:middle;flex:none}.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}[hidden]{display:none!important}#app{position:relative;height:100svh;min-height:640px;overflow:hidden;background:linear-gradient(#b9e5fa,#e9f8e9 70%,#c6dfb6)}#header{position:absolute;top:max(14px,env(safe-area-inset-top));left:24px;right:24px;z-index:8;display:flex;align-items:center;justify-content:space-between;gap:20px;padding:8px 12px;border-radius:26px;background:#f4fcffdd;box-shadow:0 4px 0 #468cba20,0 8px 24px #164a7c16;backdrop-filter:blur(14px)}.player-chip{display:flex;align-items:center;gap:10px;background:transparent;min-width:165px;text-align:left}.player-chip>.icon{width:60px;height:60px;border-radius:50%;background:#bde8f1}.player-chip b{display:block;font-size:17px;max-width:160px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.player-chip small{display:flex;gap:5px;align-items:center;font-weight:800;font-size:15px}.player-chip small .icon{width:23px;height:23px}.top-links{display:flex;gap:12px;align-items:center}.top-link{display:flex;flex-direction:column;gap:2px;align-items:center;justify-content:center;min-width:80px;min-height:72px;background:transparent;border-radius:18px;font-size:12px;font-weight:800;padding:4px 12px}.top-link.selected{background:#fff;box-shadow:0 4px 0 #8ec4e1}.top-link .icon{width:44px;height:44px}.header-tools{display:flex;gap:12px}.utility-button{min-width:52px;min-height:56px;background:transparent;display:flex;flex-direction:column;align-items:center;justify-content:center;font-size:10px;font-weight:800}.utility-button .icon{width:39px;height:39px}#map-scroll{position:absolute;inset:0;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;overscroll-behavior-x:contain}#map-scroll::-webkit-scrollbar{display:none}#map-stage{position:relative;top:var(--map-top,0px);height:calc(100% - var(--map-top,0px));width:max(100%, calc((100svh - var(--map-top,0px)) * 1.6));min-width:1024px}#map-stage::before{content:"";position:absolute;left:0;right:0;bottom:calc(100% - 4px);height:calc(var(--map-top,0px) + 4px);background:url(/assets/world/town-map-v3.webp) center top/100% auto no-repeat;transform:scaleY(-1);filter:blur(5px)}#map-art{width:100%;height:100%;display:block;object-fit:fill}#destinations{position:absolute;inset:0;pointer-events:none}.destination{position:absolute;transform:translate(-50%,-50%);pointer-events:auto;display:flex;align-items:center;flex-direction:column;background:transparent;padding:0;min-width:88px;filter:drop-shadow(0 4px 5px #1e4c6a44)}.destination:active{transform:translate(-50%,-50%) scale(.93)}.destination>.icon{width:60px;height:60px;background:#fff9e8;border:3px solid white;border-radius:21px;padding:5px;box-shadow:0 4px #91b9c888}.destination>span{background:white;padding:5px 14px 7px;border-radius:13px;font-size:16px;font-weight:850;white-space:nowrap;margin-top:-1px;box-shadow:0 3px #70a3ba88}.destination.ready>.icon{width:76px;height:76px;background:#fff1a1;border:4px solid #ffe063;box-shadow:0 0 0 6px #fffceaaa,0 7px #dbb65099}.destination.ready>span{background:#fff4ae}.destination i{position:absolute;right:-14px;top:-8px}.destination i .icon{width:37px;height:37px}#world{position:absolute;top:15%;left:0;width:100%;height:77%;pointer-events:none}body[data-screen=home] #world{z-index:2;left:0;top:auto;bottom:10px;width:260px;height:370px}#panel{position:absolute;inset:0;pointer-events:none;z-index:3}#panel button,#panel input,#panel form{pointer-events:auto}.explorer-foreground{position:absolute;left:calc(var(--stand-x,129.5px) - 129.5px);bottom:calc(var(--stand-y,79px) - 69px);width:320px;height:365px;pointer-events:none}.hero-hit{position:absolute;left:36px;bottom:0;width:175px;height:310px;background:transparent;border-radius:80px}.mission-invite{position:absolute;right:26px;bottom:28px;min-height:106px;display:flex;gap:16px;align-items:center;padding:15px 16px;border:3px solid #fff;border-radius:26px;background:#f5fcf5f5;box-shadow:0 6px #528f8990,0 12px 25px #29515322;text-align:left}.mission-invite>span{display:grid;gap:4px}.mission-invite small{font-size:13px;color:#438281;font-weight:700}.mission-invite b{font-size:20px}.invite-pictures{display:flex;align-items:center;width:125px;position:relative}.invite-pictures .icon{width:49px;height:49px;margin-left:-9px}.invite-pictures .icon:first-child{margin-left:0}.invite-play{width:66px;height:66px}.map-pan-hint{display:none}.explorer-card,.star-card,.reward-card,.collection-panel{position:absolute;top:25%;left:6%;width:355px;padding:25px;background:#fffbeded;border:2px solid white;border-radius:28px;box-shadow:0 8px 0 #73a6a620}.explorer-card h1{font-size:32px}.explorer-card label,legend{display:block;font-size:18px;font-weight:800;margin:15px 0 10px}.explorer-card label small{font-size:12px;font-weight:500}input{width:100%;border:2px solid #9ec8d1;border-radius:15px;padding:13px 16px;color:#244868;background:white}fieldset{padding:0;border:0;margin:15px 0 24px}.badges{display:flex;gap:18px}.badge{padding:5px;width:68px;height:68px;background:white;border:3px solid #d2e6e6;border-radius:20px}.badge.selected{border-color:#31a98b;background:#ddf2da;box-shadow:0 4px #72bc95}.primary{display:flex;gap:12px;align-items:center;justify-content:center;min-height:62px;padding:10px 18px;background:#31ad7b;color:white;border:2px solid #75d8b0;border-radius:20px;box-shadow:0 5px #268261;font-size:18px;font-weight:800;width:100%}.primary .icon{width:39px;height:39px}.primary .icon:last-child:not(:first-child){margin-left:auto}.listen{display:flex;gap:9px;align-items:center;justify-content:center;padding:8px 15px;border-radius:18px;background:#e0f0f8;font-weight:750;min-height:56px}.listen .icon{width:37px;height:37px}.explorer-card>.listen,.star-card>.listen,.collection-panel>.listen{margin:18px auto 0}.back{position:absolute;top:125px;left:25px;background:transparent;padding:0}.back .icon{width:58px;height:58px}.instruction{position:absolute;left:4%;top:32%;width:310px;border-radius:28px;background:#fffdf0f5;padding:22px;box-shadow:0 7px #a2c5ba44}.mission-top{display:flex;align-items:center;justify-content:space-between;gap:15px}.mission-top .listen{padding:6px;min-width:60px;min-height:60px;border-radius:50%}.progress-dots{display:flex;gap:8px}.progress-dots>span{background:#dce7e7;border-radius:50%;padding:3px;width:43px;height:43px;opacity:.5}.progress-dots>span.current{opacity:1;background:#ffedb1;box-shadow:0 0 0 3px #f9cf55}.progress-dots>span.done{opacity:1}.progress-dots .icon{width:37px;height:37px}.visual-instruction{display:flex;flex-wrap:wrap;align-items:center;gap:5px;margin:23px 0 14px}.visual-instruction h1{font-size:25px;line-height:1.2;width:calc(100% - 58px);margin:0}.visual-instruction .target-picture{display:block;width:105px;height:105px;margin:12px auto 0}.visual-instruction>.icon:first-child{width:47px;height:47px}#feedback{font-size:15px;margin:6px 0 0;display:flex;align-items:center;gap:10px}#feedback .icon{width:30px;height:30px}#scene-targets{position:absolute;left:0;top:15%;width:100%;height:77%;pointer-events:none;z-index:2}#scene-targets button{pointer-events:auto}.object-target{position:absolute;transform:translate(-50%,-50%);min-width:64px;min-height:64px;border:3px solid #fff6d1b0;background:#fff5bf1a;border-radius:50%;box-shadow:0 0 0 5px #fffbed25;transition:background .15s}.object-target:active{transform:translate(-50%,-50%) scale(.94)}.object-target:hover{background:#ffedab88}.object-target.found{background:#9ce19a66;border-color:#71c798}.object-target .icon{width:45px;height:45px}.object-target.hint{box-shadow:0 0 0 10px #ffe16788;border-color:#ffdb57;animation:hint 1.8s ease-in-out 3}@keyframes hint{50%{box-shadow:0 0 0 17px #ffe16733}}.reward-card,.star-card{text-align:center}.reward-star{width:135px;height:135px;margin:0 auto 12px}.reward-card h1{font-size:38px}.found-pictures{display:flex;justify-content:center;gap:15px;margin:20px 0}.found-pictures .icon{width:64px;height:64px}.text-button{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:10px 14px;margin-top:15px;min-height:54px;background:transparent;font-size:16px;font-weight:700}.text-button .icon{width:37px;height:37px}.collection-star .icon{width:120px;height:120px}.collection-star:not(.earned-star){filter:grayscale(1);opacity:.35}.star-card h2{font-size:21px;margin-top:15px}.collection-items{display:flex;gap:10px;justify-content:center;margin:36px 0}.collection-items button{position:relative;background:#e3f4e4;border-radius:22px;width:88px;height:100px}.collection-items .icon{width:65px;height:65px}.collection-items .tiny-speaker{width:23px;height:23px;position:absolute;right:0;bottom:0;background:white;border-radius:50%;padding:2px}.empty-collection{text-align:center;padding:10px}.empty-collection>.icon{width:135px;height:135px}.empty-collection p{font-size:16px;margin-top:15px}.memory-photo{background:#fff;padding:10px 10px 0;transform:rotate(-3deg);margin:20px 0;box-shadow:0 4px 15px #24486820;border-radius:5px}.memory-photo>img{width:100%;height:115px;object-fit:cover}.memory-photo>div{font-size:14px;font-weight:700}.memory-photo>div>.icon{width:25px;height:25px}.memory-photo .found-pictures{margin:10px 0;padding-bottom:10px}dialog{border:3px solid white;border-radius:30px;background:#fffbed;color:var(--ink);max-width:440px;width:90%;padding:30px;box-shadow:0 20px 90px #163e7377}dialog::backdrop{background:#1a446c66;backdrop-filter:blur(5px)}dialog .close{position:absolute;top:8px;right:8px;padding:0;background:transparent}dialog .close .icon{width:47px;height:47px}.preview-picture{display:block;width:110px;height:110px;margin:0 auto 18px}.place-preview{text-align:center}.place-preview .listen{margin:15px auto 25px}.place-preview p{color:#547085}.secondary{width:100%;background:#e3e9ed;border-radius:17px;padding:17px;font-size:15px;margin:12px 0 20px}.parent-panel p{font-size:14px}#parent-gate label{display:block;font-size:18px;font-weight:800;margin:20px 0 10px}#gate-feedback{font-size:14px;margin:10px 0}#notice{position:absolute;left:50%;bottom:20px;transform:translateX(-50%);z-index:30;background:#fffbed;box-shadow:0 8px 30px #214e5c33;padding:14px 20px;border-radius:20px;max-width:90%;opacity:0;pointer-events:none;font-size:15px}#notice.shown{opacity:1}#loading{position:absolute;inset:0;z-index:40;background:#bfe7f2;display:flex;align-items:center;justify-content:center;flex-direction:column;text-align:center;padding:30px}#loading .loading-puppy{width:220px;height:auto;aspect-ratio:274/198;margin-bottom:14px;object-fit:contain;background:#bfe7f2}
#loading .loading-bar{width:min(260px,70vw);height:14px;border-radius:7px;background:#fff9;box-shadow:inset 0 2px 3px #3b6e7422;overflow:hidden;margin-top:4px}
#loading .loading-bar i{display:block;height:100%;width:calc(var(--p,0)*100%);min-width:14px;border-radius:7px;background:linear-gradient(90deg,#ffd166,#f5a623);transition:width .3s}#loading p{max-width:420px}#loading .primary{max-width:260px}
@media(max-width:1000px){#header{left:14px;right:14px;gap:8px;padding:7px}.player-chip{min-width:130px}.player-chip b{max-width:100px;font-size:14px}.top-link{min-width:66px;padding:3px 8px}.top-links{gap:5px}.header-tools{gap:3px}.mission-invite{gap:10px}.invite-pictures{width:96px}.invite-pictures .icon{width:40px;height:40px}.mission-invite b{font-size:17px}.mission-invite{right:20px}.explorer-card,.star-card,.reward-card,.collection-panel{width:310px;left:3%;padding:20px}.instruction{left:3%;width:275px}}
@media(max-width:900px){#app{min-height:740px}#header{top:max(10px,env(safe-area-inset-top));left:8px;right:8px;gap:3px;padding:6px;border-radius:20px}.player-chip{min-width:0;padding:0}.player-chip>.icon{width:43px;height:43px}.player-chip>span{display:none}.top-links{gap:0;flex:1;justify-content:space-evenly}.top-link{min-width:48px;min-height:61px;padding:2px 3px;font-size:9px;border-radius:13px}.top-link .icon{width:37px;height:37px}.header-tools{gap:0}.utility-button{padding:2px;min-width:34px;min-height:48px;font-size:8px}.utility-button .icon{width:30px;height:30px}.destination>.icon{width:63px;height:63px}.destination>span{font-size:16px}.map-pan-hint{display:block;position:absolute;right:6px;top:50%;margin-top:-30px;width:60px;height:60px;padding:6px;background:transparent;filter:drop-shadow(0 3px 5px #1e4c6a55);animation:pan-hint 1.1s ease-in-out infinite;transition:opacity .3s}.map-pan-hint .icon{width:48px;height:48px}
@keyframes pan-hint{0%,100%{transform:translateX(0)}50%{transform:translateX(9px)}}
body.map-at-end .map-pan-hint{opacity:0;pointer-events:none}.mission-invite{left:14px;right:14px;bottom:max(25px,env(safe-area-inset-bottom));min-height:95px;padding:12px;gap:8px;border-radius:23px}.invite-pictures{width:88px}.invite-pictures .icon{width:36px;height:36px;margin-left:-7px}.invite-play{width:53px;height:53px;margin-left:auto}.mission-invite b{font-size:16px}.mission-invite small{font-size:12px}body[data-screen=home] #world{bottom:calc(max(25px,env(safe-area-inset-bottom)) + 53px);left:-15px;width:175px;height:250px}.explorer-foreground{bottom:calc(var(--stand-y,calc(max(25px,env(safe-area-inset-bottom)) + 100px)) - 46px);height:250px;width:225px;left:calc(var(--stand-x,72.5px) - 87.5px)}.hero-hit{left:24px;width:125px;height:235px}body:not([data-screen=home]) #world{top:13%;height:46%}.explorer-card,.star-card,.reward-card,.collection-panel{left:5%;width:90%;top:auto;bottom:24px;padding:18px 22px;border-radius:25px}.explorer-card h1{font-size:25px;margin-bottom:10px}.explorer-card label{font-size:15px;margin-top:0}.explorer-card input{padding:9px 13px}.explorer-card fieldset{margin:10px 0 16px}.explorer-card legend{font-size:15px;margin:0 0 6px}.badge{width:57px;height:57px}.badge .icon{width:42px;height:42px}.primary{min-height:55px;font-size:17px;padding:7px 14px}.primary .icon{width:35px;height:35px}.explorer-card>.listen,.star-card>.listen,.collection-panel>.listen{position:absolute;right:18px;top:10px;margin:0;font-size:0;padding:5px;min-height:45px}.explorer-card>.listen .icon,.star-card>.listen .icon,.collection-panel>.listen .icon{width:32px;height:32px}.back{top:94px;left:12px}.back .icon{width:52px;height:52px}body[data-screen=mission] #world,#scene-targets{top:17%;height:52%}.instruction{top:auto;bottom:24px;left:5%;width:90%;padding:16px 20px}.mission-top .listen{min-width:52px;min-height:52px}.mission-top .listen .icon{width:35px;height:35px}.visual-instruction{flex-wrap:nowrap;margin:12px 0 0;gap:7px}.visual-instruction>.icon:first-child{display:none}.visual-instruction h1{font-size:22px;width:auto;flex:1}.visual-instruction .target-picture{width:60px;height:60px;margin:0}#feedback{font-size:13px;margin-top:4px}#feedback .icon{width:24px;height:24px}.object-target{min-width:60px;min-height:60px}.reward-star{width:85px;height:85px;margin-bottom:6px}.reward-card h1{font-size:29px;margin-bottom:10px}.found-pictures{margin:12px 0}.found-pictures .icon{width:47px;height:47px}.reward-card .text-button{margin-top:9px;padding:3px}.star-card h1,.collection-panel h1{font-size:27px}.collection-star .icon{width:80px;height:80px}.star-card h2{font-size:18px}.collection-panel h1{margin-bottom:12px}.empty-collection>.icon{width:80px;height:80px}.empty-collection p{margin:5px 0 10px}.collection-items{margin:18px 0}.memory-photo{margin:12px 0}.memory-photo>img{height:85px}}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{transition:none!important;animation:none!important;scroll-behavior:auto!important}}
@media(max-width:900px){.utility-button{min-width:44px;min-height:48px}.player-chip{min-height:48px;min-width:44px}}

@media(min-width:600px) and (max-width:900px){.explorer-card,.star-card,.reward-card,.collection-panel,.instruction{width:420px;left:calc(50% - 210px)}.mission-invite{left:auto;width:420px}.player-chip>span{display:block}.top-link{min-width:70px;font-size:12px}.top-link .icon{width:44px;height:44px}.top-links{justify-content:center;gap:12px}.utility-button{min-width:48px}.utility-button .icon{width:38px;height:38px}}

/* Original generated Explorer reference is framed as a portrait. */
.player-chip>.icon{object-fit:cover;object-position:center top}

/* The sniffing puppy (keyed Grok animation, docs/living-map-v2.md) sits at about
   40% of the Explorer's height, paws on the Explorer's shoe line, just to its
   right. The frame is wider than the sitting puppy to leave room for its trot. */
.puppy{position:absolute;left:169px;bottom:67px;width:130px;pointer-events:none}
.puppy img{display:block;width:100%;height:auto}
@media(max-width:900px){.puppy{left:120px;bottom:44px;width:87px}}

/* The Explorer on the home map (explorer-player.js) replaces the 3D figure there,
   drawn at its measured size and shoe line (223 px tall on desktop, 150 px on
   phone/iPad) so the puppy stays at her feet. If her clips fail, the 3D figure returns. */
/* Her canvas is placed from the clip geometry (--ex-*, set by app.js from geometry.json): each screen gives
   only her figure height (--fig) and where her feet stand (--feet-x from the left, --feet-y from the bottom). */
#explorer{display:none;position:absolute;z-index:2;pointer-events:none;--fig:calc(223px*var(--hero-scale,1));--feet-x:var(--stand-x,129.5px);--feet-y:var(--stand-y,79.4px);left:calc(var(--feet-x) - var(--fig)*var(--ex-cx,.3807));bottom:calc(var(--feet-y) - var(--fig)*var(--ex-bm,.0108));width:calc(var(--fig)*var(--ex-wr,.7549));height:calc(var(--fig)*var(--ex-hr,1.0282))}
body[data-screen=home]:not([data-explorer-fallback]) #explorer{display:block}
body[data-screen=home]:not([data-explorer-fallback]) #world{visibility:hidden}
.clip-source{position:absolute;left:0;bottom:0;width:1px;height:1px;opacity:0;pointer-events:none}
/* On phone/iPad the full-width mission card covers the lower map, so she and the puppy stand just above it:
   on the overlook paving in front of the bench, not on its seat. */
@media(max-width:900px){#explorer{--fig:calc(150px*var(--hero-scale,1));--feet-x:var(--stand-x,72.5px);--feet-y:var(--stand-y,calc(max(25px,env(safe-area-inset-bottom)) + 99.6px))}}

/* The map is always as tall as the app, so the Explorer group (her canvas, the puppy, her tap area
   and greeting) is scaled by --hero-scale (app.js) to stay at the same share of the scene on every
   screen: 27% of its height, as on the 820 px desktop reference. Both layers grow about her feet. Her
   canvas is sized rather than transformed: Safari composites a transformed canvas as a stretched
   bitmap of its unscaled box, which blurs her; sizing the box gives it real pixels to draw into. */
.explorer-foreground{transform:scale(var(--hero-scale,1));transform-origin:129.5px calc(100% - 69px)}
@media(max-width:900px){.explorer-foreground{transform-origin:87.5px calc(100% - 46px)}}

/* Walk-in film: full screen over everything, cropped to fill (the action is centred); Skip in the corner. */
#film{position:fixed;inset:0;z-index:50;background:#0b1a24}
#film video{width:100%;height:100%;object-fit:cover;display:block}
.film-skip{position:absolute;right:max(16px,env(safe-area-inset-right));bottom:max(16px,env(safe-area-inset-bottom));padding:12px 24px;border-radius:20px;background:#fffbede6;color:var(--ink);font-size:17px;font-weight:800;box-shadow:0 4px #0003}

/* The dollhouse: a square picture as large as fits under the header, standing on the bottom edge. Its
   flat sky and lawn continue to the screen edges (sides feathered into them). The Explorer and the puppy
   stand on its lawn (the bottom 28%), left of centre; room buttons cover the four rooms. */
:root{--scene:min(calc(100vw - 24px),calc(100svh - 124px))}
.house-scene{position:absolute;left:50%;bottom:0;width:var(--scene);height:var(--scene);margin-left:calc(var(--scene)/-2)}
body[data-screen=house] #app{background:linear-gradient(to top,#86ba1a 0 calc(var(--scene)*.29),#52befd 0)}
/* One Grok painting of the dollhouse in its garden (grok-image.py, widened by grok-extend.py). app.js sets its
   position and size from house.js, measured by place-square.py so the original dollhouse square lines up with
   the scene and the room buttons. */
.dollhouse{position:absolute;left:-150%;top:0;width:400%;height:100%;max-width:none}
.dollhouse-detail{-webkit-mask-image:linear-gradient(to right,transparent,#000 6%,#000 94%,transparent);mask-image:linear-gradient(to right,transparent,#000 6%,#000 94%,transparent)}   /* the 4K middle fades into the wide painting */
.room-spot{position:absolute;padding:0;background:transparent;border-radius:18px;pointer-events:auto}
.room-spot:hover,.room-spot:focus-visible{background:#fff5}
.room-star{position:absolute;right:6%;top:8%;width:22%;height:auto;max-width:48px;filter:drop-shadow(0 3px 4px #0004)}
.house-scene .house-puppy{left:36.14%;bottom:7.73%;width:15%}
body[data-screen=house]:not([data-explorer-fallback]) #explorer{display:block;z-index:4;--fig:calc(var(--scene)*.26);--feet-x:calc(50% - var(--scene)*.2);--feet-y:calc(var(--scene)*.08)}
body[data-screen=house] #world,body[data-screen=film] #world{visibility:hidden}
body[data-screen=house] .back{z-index:5}

/* A room of the house: the square picture (widened, like the dollhouse) with its toys and furniture as
   buttons. Toys get a soft contact shadow, glow once found, and shake when they are not the one asked
   for. The Explorer and the puppy stand in the room's reserved corner (room.json). */
/* The room: its painting for this orientation, sized and placed by layoutRoom() (app.js). */
.room-scene{position:absolute;left:0;top:0;width:100%;height:100%}
/* One 5:2 Grok painting of the room (grok-image.py), placed from room.json like the dollhouse. */
.room-backdrop{position:absolute;left:-100%;top:0;width:300%;height:100%;max-width:none}
body[data-screen=room] #app{background:var(--room-ceiling,#f4c9c2)}
.item{position:absolute;padding:0;background:transparent;border-radius:12px}
.item.spot:focus-visible{background:#fff4}
.item.toy img{display:block;width:100%;height:100%;filter:drop-shadow(0 5px 4px #5a2e1a55)}
.item.toy.found img{filter:drop-shadow(0 0 10px #fff7b0) drop-shadow(0 0 4px #ffd84a) drop-shadow(0 5px 4px #5a2e1a55)}
.item.toy.nope{animation:nope .45s ease-in-out}
@keyframes nope{20%,60%{transform:translateX(-6%)}40%,80%{transform:translateX(6%)}}
@media(prefers-reduced-motion:reduce){.item.toy.nope{animation:none}}
.room-scene .room-puppy{position:absolute}
body[data-screen=room]:not([data-explorer-fallback]) #explorer{display:block;z-index:4;--fig:var(--room-fig,200px);--feet-x:var(--room-feet-x,80px);--feet-y:var(--room-feet-y,10px)}
body[data-screen=room] #world{visibility:hidden}
body[data-screen=room] .back{z-index:5}
.room-task{position:absolute;z-index:5;left:50%;transform:translateX(-50%);top:112px;width:min(980px,calc(100% - 190px));display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px 14px;padding:10px 16px;border-radius:24px;background:#fffdf0f2;box-shadow:0 6px #a2c5ba44;text-align:center}
.room-task p{margin:0;font-size:19px;line-height:1.25}
.room-task .task-picture{width:64px;height:64px;object-fit:contain}
.room-task .listen{padding:6px;min-width:56px;min-height:56px;border-radius:50%}
.room-task .progress-dots span{display:flex;align-items:center;justify-content:center}
.room-task .progress-dots img{width:32px;height:32px;object-fit:contain}
.room-task.done .task-star{width:56px;height:56px}
.room-task.done .primary{width:auto}
@media(max-width:900px){.room-task{top:154px;width:calc(100% - 24px);padding:10px 12px;gap:8px 12px}.room-task .task-picture{width:56px;height:56px}.room-task p{font-size:17px}.room-task.done .primary{width:auto}.room-task .progress-dots img{width:26px;height:26px}}
/* The task card: the thing asked for beside what to do with it, the crayons (Color It) and the things found so far
   below; the mouth that says it again hangs half out of the card's left side, the refresh button (new things to
   find) half out of its right side. */
.room-task:not(.done){display:grid;grid-template-columns:auto 1fr;align-items:center;gap:8px 14px;width:max-content;max-width:min(560px,calc(100% - 190px));padding:12px 44px 12px 44px}
.room-task:not(.done) .task-picture{grid-column:1}
.room-task:not(.done) p{grid-column:2;text-align:left}
.room-task:not(.done) .palette,.room-task:not(.done) .progress-dots{grid-column:1/-1;justify-self:center}
.room-task .listen:is([data-action=ask],[data-action=room-new]){position:absolute;left:-30px;top:calc(50% - 30px);width:60px;height:60px;min-width:0;min-height:0;padding:7px;border:3px solid #fff;box-shadow:0 4px 0 #468cba30,0 6px 14px #164a7c26}
.room-task .listen[data-action=room-new]{left:auto;right:-30px;background:#fff6d6}
.room-task .listen:is([data-action=ask],[data-action=room-new]) .icon{width:40px;height:40px}
@media(max-width:900px){
 .room-task:not(.done){max-width:calc(100% - 64px);padding:10px 34px 10px 34px;gap:6px 12px}
 .room-task .listen:is([data-action=ask],[data-action=room-new]){left:-26px;top:calc(50% - 26px);width:52px;height:52px;padding:6px}
 .room-task .listen[data-action=room-new]{left:auto;right:-26px}
 .room-task .listen:is([data-action=ask],[data-action=room-new]) .icon{width:34px;height:34px}
}
/* Narrow phones: the eight crayons in two even rows. */
@media(max-width:430px){.room-task .palette{display:grid;grid-template-columns:repeat(4,auto);gap:6px 10px}}
/* Phones held sideways (short screens): the task in one row just below the header, so the room keeps its height. */
@media(max-height:500px) and (orientation:landscape){
 .room-task:not(.done){top:calc(var(--map-top,94px) + 2px);grid-auto-flow:column;grid-template-columns:none;padding:6px 32px 6px 32px;gap:10px}
 .room-task:not(.done) .palette,.room-task:not(.done) .progress-dots,.room-task:not(.done) p{grid-column:auto}
 .room-task:not(.done) .task-picture{width:44px;height:44px}
 .room-task:not(.done) p{font-size:15px}
 .room-task:not(.done) .progress-dots>span{width:36px;height:36px}
 .room-task:not(.done) .progress-dots img{width:24px;height:24px}
 .room-task:not(.done) .palette{display:flex;flex-wrap:nowrap;gap:4px}
 .room-task:not(.done) .crayon{width:28px;height:28px}
 .room-task .listen:is([data-action=ask],[data-action=room-new]){left:-22px;top:calc(50% - 22px);width:44px;height:44px;padding:5px}
 .room-task .listen[data-action=room-new]{left:auto;right:-22px}
 .room-task .listen:is([data-action=ask],[data-action=room-new]) .icon{width:30px;height:30px}
}
/* Feed Me: foods can be dragged (no page gestures meanwhile), follow the finger, glide back, and vanish once eaten. */
.drag-room{touch-action:none}
.drag-room .item.toy.food{cursor:grab}
.item.toy.dragging{z-index:6;transition:none;cursor:grabbing}
.item.toy.returning{transition:transform .3s ease}
.item.toy.eaten{visibility:hidden}
/* Color It: the object to paint glows softly; paint lies over the grey sprite, clipped to its shape; a row of crayons. */
.item.toy.paintable canvas.paint{position:absolute;inset:0;width:100%;height:100%;mix-blend-mode:multiply;pointer-events:none}
.item.toy.current-paint img{filter:drop-shadow(0 0 8px #fff6) drop-shadow(0 0 3px #ffe07a) drop-shadow(0 5px 4px #5a2e1a55)}
.drag-room .item.toy.paintable{cursor:crosshair}
.palette{display:flex;flex-wrap:wrap;justify-content:center;gap:6px}
.crayon{width:40px;height:40px;border-radius:50%;background:var(--c);border:3px solid #fff;box-shadow:0 2px 4px #0003;padding:0}
.crayon.picked{transform:scale(1.18);box-shadow:0 0 0 3px #244868,0 2px 4px #0003}
.swatch-word{text-transform:none}
@media(max-width:900px){.palette{max-width:none}.crayon{width:34px;height:34px}}
/* The house and its rooms size themselves to the window, so they never need the map's minimum height (which ran past
   short windows and cut off the Explorer's feet). */
body[data-screen=house] #app,body[data-screen=room] #app{min-height:0}

/* Screen transitions (transition.js; rule in CLAUDE.md): the new screen opens as a soft bubble from where the child
   tapped while the old one dims and drifts back; with reduced motion, a quick crossfade; without the View
   Transitions API, a cream curtain fades out and in. */
html[data-transition=bubble]::view-transition-image-pair(root){isolation:auto}
html[data-transition=bubble]::view-transition-old(root){animation:scene-out .7s ease-in both;transform-origin:var(--tap-x) var(--tap-y)}
html[data-transition=bubble]::view-transition-new(root){animation:scene-in .7s cubic-bezier(.3,.7,.2,1) both;mix-blend-mode:normal}
@keyframes scene-in{from{clip-path:circle(0 at var(--tap-x) var(--tap-y))}to{clip-path:circle(150vmax at var(--tap-x) var(--tap-y))}}
@keyframes scene-out{to{transform:scale(1.06);filter:brightness(.78) blur(3px)}}
html[data-transition=fade]::view-transition-old(root),html[data-transition=fade]::view-transition-new(root){animation-duration:.2s}
#curtain{position:fixed;inset:0;z-index:100;background:#fffbea;opacity:0;pointer-events:none;transition:opacity .2s}
#curtain.on{opacity:1;pointer-events:auto}
/* A room chosen on the dollhouse glows while the Explorer names it. */
.room-spot.chosen{background:#fff6;box-shadow:0 0 0 4px #ffe06a,0 0 28px #fff3b0;animation:chosen 1s ease-in-out infinite}
@keyframes chosen{50%{box-shadow:0 0 0 7px #ffe06a,0 0 40px #fff3b0}}
@media(prefers-reduced-motion:reduce){.room-spot.chosen{animation:none}.map-pan-hint{animation:none}}
.house-life{position:absolute;inset:0;pointer-events:none}
.life{position:absolute;display:block;object-fit:fill;-webkit-mask-size:100% 100%;mask-size:100% 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}
#map-life{position:absolute;inset:0;pointer-events:none}
@media(prefers-reduced-motion:reduce){.house-life,#map-life{display:none}}
/* ---- Backpack (backpack.js): a pocket per room, the Explorer beside it saying the words ---- */
body[data-screen=backpack] #app{background:radial-gradient(ellipse at 20% 100%,#ffe9b8 0 30%,transparent 60%),linear-gradient(#bfe7f7,#fdf3dc 75%)}
body[data-screen=backpack] #world{visibility:hidden}
body[data-screen=backpack]:not([data-explorer-fallback]) #explorer{display:block;z-index:4;--fig:min(52svh,440px);--feet-x:min(15vw,170px);--feet-y:24px}
.backpack{position:absolute;top:calc(var(--map-top,110px) + 8px);right:24px;bottom:24px;left:max(290px,calc(min(15vw,170px)*2 + 20px));display:flex;flex-direction:column;gap:10px;pointer-events:auto}
.backpack-top{display:flex;align-items:center;gap:12px}
/* Wide screens: the top row stops short of the music button floating at the right. */
@media(min-width:901px){.backpack-top{padding-right:56px}}
.backpack-top h1{margin:0;font-size:32px}
.backpack-count{display:flex;align-items:center;gap:4px;background:#fff8e1;border:3px solid #fff;border-radius:22px;padding:3px 14px 3px 6px;box-shadow:0 3px #e6c67c88;font-size:22px}
.backpack-count .icon{width:42px;height:42px}
.listen.round{margin-left:auto;width:60px;height:60px;min-height:60px;padding:6px;border-radius:50%}
.pocket-tabs{display:flex;gap:8px;margin-bottom:-12px;position:relative;z-index:1}
.pocket-tab{flex:1;min-width:0;display:flex;align-items:center;gap:8px;padding:8px 12px 18px;border-radius:22px 22px 0 0;background:#f2dfb5;color:#6b4e1f;font-weight:800;font-size:16px;box-shadow:inset 0 -6px #e0c58f}
.pocket-tab img{width:44px;height:44px;object-fit:contain;flex:none}
.pocket-tab span{display:flex;flex-direction:column;align-items:flex-start;gap:2px;min-width:0}
.pocket-tab b{white-space:nowrap}
.pocket-tab small{font-size:13px;background:#fff9;border-radius:10px;padding:1px 7px}
h1[tabindex="-1"]:focus-visible{outline:0}
.pocket-tab.open{background:#fff4d9;box-shadow:none}
.pocket-tab:active{transform:none}
.pocket{flex:1;min-height:0;overflow-y:auto;background:#fff4d9;border-radius:0 0 28px 28px;padding:14px;box-shadow:0 8px 0 #d9b56d55;outline:3px dashed #e3c17f;outline-offset:-10px}
.things{display:grid;grid-template-columns:repeat(auto-fill,minmax(112px,1fr));gap:12px;padding:8px}
.thing{position:relative;display:flex;flex-direction:column;align-items:center;gap:4px;padding:10px 6px 8px;min-height:124px;border-radius:22px;background:#fff;box-shadow:0 4px #e9cf9c}
.thing img{width:84px;height:84px;object-fit:contain}
.thing span{font-size:16px;font-weight:800;line-height:1.1;text-align:center}
.thing .thing-star{position:absolute;top:4px;right:4px;width:30px;height:30px}
.thing.mystery{background:#fbf1dc;box-shadow:inset 0 0 0 2px #ecd6a6}
.thing.mystery img{filter:brightness(0) opacity(.13)}
.thing.mystery b{position:absolute;top:32px;font-size:34px;color:#c9a55e}
.thing.bounce{animation:bounce .45s ease}
@keyframes bounce{40%{transform:scale(1.12) rotate(-3deg)}70%{transform:scale(.97)}}
.backpack-play{flex:none;width:auto;align-self:flex-end;padding:10px 22px}
.backpack-play.beckon{animation:beckon .8s ease 2}
@keyframes beckon{50%{transform:scale(1.07);box-shadow:0 5px #268261,0 0 0 8px #ffe06a}}
@media(prefers-reduced-motion:reduce){.thing.bounce,.backpack-play.beckon{animation:none}}
@media(max-width:900px){
 .backpack{left:12px;right:12px;bottom:calc(12px + env(safe-area-inset-bottom));top:calc(var(--map-top,90px) + 4px);gap:8px}
 .backpack-top h1{font-size:26px}
 .pocket-tab{flex-direction:column;gap:2px;padding:6px 4px 16px;font-size:12px}
 .pocket-tab img{width:38px;height:38px}
 .pocket-tab span{align-items:center}
 .things{grid-template-columns:repeat(auto-fill,minmax(92px,1fr));gap:8px;padding:6px}
 .thing{min-height:108px;padding:8px 4px 6px}
 .thing img{width:68px;height:68px}
 .thing span{font-size:14px}
 .thing.mystery b{top:26px}
 .backpack-play{align-self:stretch}
 body[data-screen=backpack] #explorer{display:none!important}
}
@media(min-width:901px) and (max-aspect-ratio:1/1){
 .backpack{left:24px;top:calc(var(--map-top,110px) + 8px);bottom:calc(min(40svh,380px) + 10px)}
 body[data-screen=backpack]:not([data-explorer-fallback]) #explorer{--fig:min(36svh,360px);--feet-x:50%;--feet-y:14px}
}
/* ---- Choosing your Explorer (avatars.js); the video Explorer on the Explorer, Stars and Photo book screens ---- */
.chip-face{border-radius:50%;background:#bde8f1;object-fit:cover;object-position:50% 12%}
.player-chip>.chip-face{width:45px;height:45px}
.avatar-picker{margin:6px 0 4px}
.avatars{display:grid;grid-template-columns:repeat(5,1fr);gap:7px}
.avatar{aspect-ratio:1;padding:0;border-radius:50%;background:#e8f5fa;border:3px solid #d2e6e6;overflow:hidden}
.avatar img{width:100%;height:100%;object-fit:cover;object-position:50% 10%}
.avatar.selected{border-color:#31a98b;box-shadow:0 0 0 4px #9ee0c3}
body[data-screen=explorer] #world,body[data-screen=stars] #world,body[data-screen=photos] #world{visibility:hidden}
body:is([data-screen=explorer],[data-screen=stars],[data-screen=photos]):not([data-explorer-fallback]) #explorer{display:block;z-index:2;--fig:min(62svh,520px);--feet-x:62%;--feet-y:30px}
@media(max-width:900px){
 .avatars{grid-template-columns:repeat(5,1fr);gap:5px}
 .avatar{border-width:2px}
 body:is([data-screen=explorer],[data-screen=stars],[data-screen=photos]):not([data-explorer-fallback]) #explorer{--fig:min(28svh,230px);--feet-x:50%;--feet-y:calc(100svh - var(--map-top,90px) - min(28svh,230px) - 8px)}
}
/* Phones: the "Let's play" card is just "Let's play" and its play button, at the right, leaving the map and the
   Explorer in view (the button's label still says what it does). */
@media(max-width:599px){
 .mission-invite{left:auto;right:12px;min-height:0;padding:7px 8px 7px 12px;gap:8px;border-width:2px;border-radius:20px;box-shadow:0 4px #528f8990,0 8px 18px #29515322}
 .mission-invite>span{gap:1px}
 .invite-pictures,.mission-invite b{display:none}
 .mission-invite{padding-left:18px}
 .mission-invite small{font-size:17px;font-weight:800;color:#244868}
 .invite-play{width:42px;height:42px;margin-left:2px}
}
/* The sound button (a music note) floats at the right, just below the header, out of the bar. */
#header{--hp:12px}
.sound-float{position:absolute;top:calc(100% + 8px);right:calc(var(--hp) + 4px);width:52px;height:52px;padding:6px;display:flex;align-items:center;justify-content:center;border-radius:50%;background:#f4fcffee;box-shadow:0 3px 0 #468cba30,0 6px 16px #164a7c22;backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px)}
.sound-float .icon{width:38px;height:38px}
.back{top:calc(var(--map-top,108px) + 8px)}
@media(max-width:1000px){#header{--hp:7px}}
@media(max-width:900px){
 #header{--hp:6px}
 .sound-float{width:46px;height:46px;right:calc(var(--hp) + 7px)}
 .sound-float .icon{width:34px;height:34px}
 .back{top:calc(var(--map-top,89px) - 1px);left:12px}
 .backpack{top:calc(var(--map-top,90px) + 56px)}
}
/* Backpack views (backpack.js, PRD §13.4): the Places / Kinds switch, the shelf of places, a place's back chip,
   and the kinds. */
.backpack-top{flex-wrap:wrap;row-gap:8px}
.backpack-modes{display:flex;gap:4px;padding:4px;border-radius:22px;background:#f2dfb5;margin-left:auto}
.backpack-modes .mode{display:flex;align-items:center;gap:6px;min-height:48px;padding:4px 14px 4px 8px;border-radius:18px;background:transparent;font-weight:800;font-size:15px;color:#6b4e1f}
.backpack-modes .mode .icon{width:34px;height:34px}
.backpack-modes .mode.on{background:#fff4d9;box-shadow:0 3px #d9b56d88;color:var(--ink)}
.backpack-top .listen.round{margin-left:0}
.shelf-wrap{border-radius:28px}
.place-shelf{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:14px;padding:8px}
.place-badge{display:flex;flex-direction:column;align-items:center;gap:4px;padding:14px 8px 12px;border-radius:24px;background:#fff;box-shadow:0 4px #e9cf9c}
.place-badge .icon{width:84px;height:84px}
.place-badge b{font-size:17px}
.place-badge small{font-size:14px;font-weight:800;background:#fff4d9;border-radius:10px;padding:2px 10px}
.place-badge.soon{background:#fbf1dc;box-shadow:inset 0 0 0 2px #ecd6a6}
.place-badge.soon .icon{filter:grayscale(.7) opacity(.55)}
.place-badge.soon b{color:#9a8660}
.place-badge.soon small{background:transparent;color:#c9a55e;font-size:20px;padding:0}
.bp-back{display:flex;align-items:center;gap:8px;align-self:flex-start;padding:4px 16px 4px 4px;border-radius:24px;background:#fff8e1;box-shadow:0 3px #e6c67c88;font-weight:800;font-size:17px}
.bp-back .icon{width:40px;height:40px}
.kinds{display:flex;flex-direction:column;gap:6px}
.kind-head{display:flex;align-items:center;gap:10px;padding:4px 14px 4px 4px;margin:6px 8px 0;border-radius:20px;background:#fff8e1;align-self:flex-start}
.kind-head img{width:44px;height:44px;object-fit:contain}
.kind-head b{font-size:19px}
.kind-head small{font-size:13px;font-weight:800;background:#fff;border-radius:10px;padding:2px 8px}
.thing .where{font-style:normal;font-size:11px;font-weight:700;color:#8a6d3b;line-height:1.1;text-align:center}
@media(max-width:900px){
 .backpack-top h1{font-size:24px}
 .backpack-modes{order:3;margin-left:0;flex:1}
 .backpack-modes .mode{flex:1;justify-content:center;min-height:44px;font-size:14px}
 .backpack-modes .mode .icon{width:28px;height:28px}
 .backpack-top .listen.round{margin-left:auto}
 .place-shelf{grid-template-columns:repeat(3,1fr);gap:8px;padding:4px}
 .place-badge{padding:10px 4px 8px;border-radius:18px}
 .place-badge .icon{width:56px;height:56px}
 .place-badge b{font-size:13px;text-align:center}
 .place-badge small{font-size:12px;padding:1px 6px}
 .place-badge.soon small{font-size:16px}
 .bp-back{font-size:15px}
 .bp-back .icon{width:34px;height:34px}
 .kind-head b{font-size:16px}
}
/* My Explorer: a classroom, the Explorer standing in front of the green chalkboard (classroom-v1). Wide screens use
   the wide painting (the board about 60% across, where the Explorer stands); narrow ones the tall painting, sized so
   its floor meets the Explorer's feet above the card. */
body[data-screen=explorer] #app{background:#f0d6a8 var(--classroom-wide,url(/assets/world/classroom-v1/classroom-wide.webp)) center bottom/cover no-repeat}
body[data-screen=explorer] .explorer-card{top:calc(var(--map-top,108px) + 12px);left:max(6%,108px);max-height:calc(100svh - var(--map-top,108px) - 24px);overflow-y:auto}
#profile-form .primary{margin-top:14px}
@media(max-width:900px){
 body[data-screen=explorer] #app{min-height:0;background:#f0d6a8 var(--classroom-tall,url(/assets/world/classroom-v1/classroom-tall.webp)) center top/cover no-repeat}
 /* Phones and upright tablets: the faces are a column down the right; the card below holds the name, the badge and
    Let's go; the Explorer stands on the classroom floor between them (app.js sets --card-top). */
 body[data-screen=explorer] .explorer-card{top:auto;left:12px;right:92px;width:auto;bottom:max(16px,env(safe-area-inset-bottom));max-height:none;padding:14px 16px}
 body[data-screen=explorer] .avatar-picker{position:fixed;z-index:4;top:calc(var(--map-top,89px) + 60px);right:10px;max-height:calc(100svh - var(--map-top,89px) - 60px - max(16px,env(safe-area-inset-bottom)));width:74px;margin:0;padding:7px;border-radius:26px;background:#fffbedd9;box-shadow:0 6px 0 #73a6a620;overflow-y:auto;pointer-events:auto;scrollbar-width:none}
 body[data-screen=explorer] .avatar-picker legend{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
 body[data-screen=explorer] .avatars{display:flex;flex-direction:column;align-items:center;gap:7px}
 body[data-screen=explorer] .avatar{width:58px;height:58px;flex:none;border-width:3px}
 body[data-screen=explorer]:not([data-explorer-fallback]) #explorer{--fig:var(--ex-fig,260px);--feet-x:calc((100vw - 84px)/2);--feet-y:var(--ex-feet,330px)}
}
/* My Explorer, wide screens: the Explorer at a child's height beside the classroom's desks, not the map's size. */
@media(min-width:901px){body[data-screen=explorer]:not([data-explorer-fallback]) #explorer{--fig:min(42svh,380px);--feet-y:max(40px,5svh)}}
