/* Snow Place Like You — the figures, the globe, the gift box with its five windows, and the desk scene they are opened on.
   Seasonal colours sit on the jeepao palette: pine green, holly red, gold, cream. */
:root{--pine:#1d3a2b;--pine-d:#12261b;--pine-l:#2a5139;--holly:#a8322a;--holly-d:#6e1f1b;--foil:#e6c27a;
  --goldbar:linear-gradient(90deg,#8a6a2c,#f7dc9a 32%,#d9ad5c 58%,#7c5c24);
  --plate:"Bodoni Moda","Trirong",serif}

/* ---------- figure: face photo behind the window of the front sprite; .back shows the back sprite ---------- */
.doll{position:relative;display:block;height:var(--dh,150px);aspect-ratio:var(--ar,.62);flex:none}
.dl-front{position:absolute;inset:0}
.dl-art{position:absolute;inset:0;width:100%;height:100%;display:block;pointer-events:none;-webkit-user-drag:none}
.dl-back{display:none}
.doll.back .dl-front{display:none}.doll.back .dl-back{display:block}
.doll.flip .dl-art{transform:scaleX(-1)}   /* the second figure faces the first: lowered arms together */
.dl-face{position:absolute;overflow:hidden;border-radius:46%;background:#d8c9ae;display:grid;place-items:center}
.dl-face img{width:100%;height:100%;object-fit:cover;display:block}
.dl-face.is-add{background:repeating-linear-gradient(45deg,#e9dcc3 0 6px,#e0d1b4 6px 12px)}
.dl-face.is-add b{font:900 2.2em/1 var(--dot);color:var(--rust)}

/* ---------- base: red lacquer, gold bands, an engraved gold plate ---------- */
.gbase{position:relative;width:calc(var(--g) * .74);height:calc(var(--g) * .42);margin:0 auto;filter:drop-shadow(0 calc(var(--g) * .05) calc(var(--g) * .05) rgba(10,7,5,.55))}
.gb-top{position:absolute;left:5%;right:5%;top:0;height:24%;border-radius:50%;background:var(--goldbar);box-shadow:inset 0 2px 2px rgba(255,255,255,.5),inset 0 -3px 4px rgba(70,40,10,.5)}
.gb-top::after{content:"";position:absolute;inset:16% 7% 30%;border-radius:50%;background:radial-gradient(#3a1a12,#1c0c08)}
.gb-body{position:absolute;left:0;right:0;top:11%;bottom:9%;display:grid;place-items:center;clip-path:polygon(6% 0,94% 0,100% 100%,0 100%);
  background:var(--grain-soft),linear-gradient(90deg,#5a1512,#b33a30 28%,#96281f 55%,#4a100e)}
.gb-band{position:absolute;left:0;right:0;height:7%;background:repeating-linear-gradient(90deg,rgba(60,35,8,.35) 0 2px,transparent 2px 14px) var(--turn,0) 0/56px 100%,var(--goldbar)}
.gb-band.a{top:9%}.gb-band.b{bottom:5%}
.gb-plate{position:relative;width:60%;height:46%;margin-top:3%;padding:0 5%;border-radius:calc(var(--g) * .02);display:grid;place-items:center;
  background:linear-gradient(170deg,#f7dc9a,#d9ad5c 55%,#b8873e);box-shadow:inset 0 0 0 1px rgba(90,60,15,.55),inset 0 0 0 calc(var(--g) * .012) rgba(255,240,200,.35),0 1px 2px rgba(0,0,0,.4)}
.gb-plate b{display:block;width:100%;overflow:hidden;white-space:nowrap;text-align:center;font:600 calc(var(--g) * .078 * var(--nk,1))/1.5 var(--plate);letter-spacing:.03em;color:#3b2318;
  text-shadow:0 1px 0 rgba(255,244,210,.6)}
.gb-plate b.th{font-size:calc(var(--g) * .066 * var(--nk,1));line-height:2;letter-spacing:0}   /* room above and below for Thai vowels and tone marks */
.gb-plate.is-empty b{opacity:.45;font-weight:500}
.gb-foot{position:absolute;left:-2%;right:-2%;bottom:0;height:13%;border-radius:calc(var(--g) * .02);background:var(--goldbar);box-shadow:inset 0 1px 1px rgba(255,255,255,.5),inset 0 -2px 3px rgba(70,40,10,.5)}

/* ---------- glass ball ---------- */
.globe{position:relative;width:var(--g)}
.globe .gbase{margin-top:calc(var(--g) * -.085);z-index:2}
.gl-ball{position:relative;width:var(--g);height:var(--g);border-radius:50%}
.gl-in{position:absolute;inset:0;border-radius:50%;overflow:hidden;background:radial-gradient(circle at 34% 28%,rgba(255,244,222,.2),rgba(96,128,108,.16) 55%,rgba(14,30,22,.5))}
.gl-snow{position:absolute;left:-10%;right:-10%;bottom:-38%;height:76%;border-radius:50%;background:radial-gradient(circle at 42% 8%,#fffdf6,#efe6d6 55%,#d8cbb4)}
.gl-dolls{position:absolute;inset:0}
.gl-dolls .doll{position:absolute;bottom:30%;--dh:calc(var(--g) * .48)}
.gl-dolls .p0{right:50%;margin-right:-9%}.gl-dolls .p1{left:50%;margin-left:-9%}   /* close together, as if holding hands */
.gl-glass{position:absolute;inset:0;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle at 29% 25%,rgba(255,255,255,.55) 0 2.5%,rgba(255,255,255,0) 13%),radial-gradient(circle,rgba(255,255,255,0) 62%,rgba(255,244,222,.13) 90%,rgba(255,244,222,.3));
  box-shadow:inset 0 0 0 1.5px rgba(255,244,222,.42),inset calc(var(--g) * -.05) calc(var(--g) * -.07) calc(var(--g) * .16) rgba(8,18,13,.4),inset calc(var(--g) * .04) calc(var(--g) * .05) calc(var(--g) * .12) rgba(255,250,235,.14)}
.gl-glass::before{content:"";position:absolute;inset:6%;border-radius:50%;border:calc(var(--g) * .022) solid transparent;border-top-color:rgba(255,255,255,.42);transform:rotate(-38deg)}
.gl-ball.no-glass .gl-glass{display:none}
.gdome{position:relative;width:var(--g);height:var(--g);border-radius:50%;background:radial-gradient(circle at 34% 28%,rgba(255,244,222,.1),rgba(120,150,130,.05) 60%,rgba(14,30,22,.12))}

/* ---------- figure pack: our own Christmas star design; the strip above the dotted line tears off ---------- */
.fpack{position:relative;width:var(--fw,56px);aspect-ratio:.68;color:#fff8ee;filter:drop-shadow(0 calc(var(--fw,56px) * .05) calc(var(--fw,56px) * .07) rgba(10,7,5,.5))}
.fpack.is-red{--c1:#c0392f;--c2:#8e241f}.fpack.is-green{--c1:#356a4c;--c2:#1d3a2b}
.fp-strip{position:absolute;left:0;right:0;top:0;height:13%;display:grid;place-items:center;border-radius:calc(var(--fw,56px) * .04) calc(var(--fw,56px) * .04) 0 0;
  background:repeating-linear-gradient(90deg,rgba(0,0,0,.2) 0 1px,rgba(255,255,255,.1) 1px 3px),linear-gradient(var(--c1),var(--c2));
  transform-origin:100% 100%;transition:transform .7s cubic-bezier(.4,0,.2,1),opacity .5s .2s}
.fp-strip span{font:400 calc(var(--fw,56px) * .058)/1 var(--mono);letter-spacing:.14em;white-space:nowrap}
.fp-body{position:absolute;left:0;right:0;top:13%;bottom:0;overflow:hidden;border-radius:0 0 calc(var(--fw,56px) * .04) calc(var(--fw,56px) * .04);
  background:linear-gradient(105deg,rgba(255,255,255,0) 32%,rgba(255,255,255,.16) 46%,rgba(255,255,255,0) 60%),linear-gradient(170deg,var(--c1),var(--c2));
  border-top:calc(var(--fw,56px) * .014) dashed rgba(255,244,222,.8);box-shadow:inset 0 0 0 1px rgba(255,255,255,.1)}
.fp-body::after{content:"";position:absolute;left:0;right:0;bottom:0;height:7%;background:repeating-linear-gradient(90deg,rgba(0,0,0,.22) 0 1px,rgba(255,255,255,.12) 1px 3px)}
.fp-art{position:absolute;left:8%;right:8%;top:3%;height:62%}
.fp-art svg{display:block;width:100%;height:100%}
.fp-name{position:absolute;left:0;right:0;top:66%;display:flex;flex-direction:column;align-items:center;line-height:1}
.fp-name b{font:900 calc(var(--fw,56px) * .112)/1 var(--dot);font-variation-settings:"ROND" 100;letter-spacing:.05em;color:#f7dc9a}
.fp-name i{margin-top:-.28em;font:400 calc(var(--fw,56px) * .16)/1 var(--script);font-style:normal;color:#fff8ee}
.fp-foot{position:absolute;left:8%;right:8%;bottom:9.5%;display:flex;justify-content:space-between;font:400 calc(var(--fw,56px) * .052)/1 var(--mono);opacity:.85}
.fp-foot i{font-style:normal}

/* ---------- glitter sachet, key ---------- */
.gpack{position:relative;width:var(--gw,44px);aspect-ratio:.76;padding-top:22%;display:flex;flex-direction:column;align-items:center;gap:6%;border-radius:2px;color:#3b2318;
  background:var(--grain-soft),linear-gradient(175deg,#e3c79c,#c79d6e);box-shadow:0 3px 6px rgba(10,7,5,.45)}
.gp-crimp{position:absolute;left:0;right:0;top:0;height:12%;background:repeating-linear-gradient(90deg,rgba(0,0,0,.2) 0 1px,transparent 1px 3px)}
.gpack span{font:700 calc(var(--gw,44px) * .2)/1 var(--mono)}
.gpack b{font:400 calc(var(--gw,44px) * .19)/1 var(--mono);color:var(--rust)}
.gpack small{font:400 calc(var(--gw,44px) * .1)/1 var(--mono);opacity:.7}
.wkey{position:relative;display:block;width:var(--kw,30px);height:calc(var(--kw,30px) * 3.5);filter:drop-shadow(0 2px 3px rgba(10,7,5,.5))}   /* a long winding key: ring, collar, shaft, bit */
.wkey b{position:absolute;left:0;top:0;width:100%;aspect-ratio:1;border-radius:50%;border:calc(var(--kw,30px) * .17) solid #d9ad5c;box-shadow:inset 0 0 0 1px rgba(90,60,15,.5),0 0 0 1px rgba(90,60,15,.4)}
.wkey i{position:absolute;left:39%;width:22%;top:27%;bottom:0;background:var(--goldbar);border-radius:0 0 2px 2px}
.wkey i::before{content:"";position:absolute;left:-55%;right:-55%;top:4%;height:7%;border-radius:2px;background:var(--goldbar)}
.wkey i::after{content:"";position:absolute;left:100%;bottom:4%;width:150%;height:16%;border-radius:0 2px 2px 0;background:#c99a4a;box-shadow:0 calc(var(--kw,30px) * -.32) 0 #c99a4a}

/* ---------- the gift box: sign on the head, two doors, the tray of windows ---------- */
.xbox{position:relative;width:var(--bw);height:calc(var(--bw) * .942);perspective:calc(var(--bw) * 2.6);filter:drop-shadow(0 calc(var(--bw) * .07) calc(var(--bw) * .08) rgba(10,7,5,.6))}
.xb-head{position:absolute;left:0;right:0;top:0;height:calc(var(--bw) * .168);background:url(/img/scene/box-head.webp) 0 0/100% 100% no-repeat}
.xb-well{position:absolute;left:0;right:0;top:calc(var(--bw) * .168);bottom:0;border-radius:0 0 4px 4px;background:var(--grain-soft),linear-gradient(#5d1814,#43100d);box-shadow:inset 0 0 0 3px var(--pine-d),inset 0 8px 14px rgba(0,0,0,.5)}
.xb-tray{position:absolute;inset:0}
.xb-door{position:absolute;top:calc(var(--bw) * .168);bottom:0;width:50%;transform-style:preserve-3d;transition:transform 1.15s cubic-bezier(.5,0,.2,1)}
.xb-door.l{left:0;transform-origin:0 50%}.xb-door.r{right:0;transform-origin:100% 50%}
.xb-out,.xb-inn{position:absolute;inset:0;overflow:hidden;backface-visibility:hidden;-webkit-backface-visibility:hidden}
.xb-out{background:url(/img/scene/box-door-l.webp) 0 0/100% 100% no-repeat}
.xb-door.r .xb-out{background-image:url(/img/scene/box-door-r.webp)}
.xb-inn{transform:rotateY(180deg);background:var(--grain-soft),linear-gradient(#9a2c25,#7a211c)}
.xb-inn .k-stars{position:absolute;inset:0}.xb-inn .k-stars svg{display:block;width:100%;height:100%}
.xb-seal{display:none}

/* windows: 1 2 on top, 3 4 below, 5 the wide one in the middle (placed by scene.js, in tray px). Behind each flap, the card
   insert with one cut-out per thing */
.slot{position:absolute;padding:0;border:0;background:none;color:inherit;perspective:700px;cursor:pointer;-webkit-tap-highlight-color:transparent}
.slot:disabled{cursor:default}
.sl-cave{position:absolute;inset:0;border-radius:5px;overflow:hidden;background:var(--grain-soft),linear-gradient(160deg,#93302a,#74201b);box-shadow:inset 0 0 0 1px rgba(0,0,0,.45),inset 0 2px 0 rgba(255,190,170,.14)}
.cut{position:absolute;border-radius:5px;background:radial-gradient(120% 100% at 50% 0%,#2c0f0c,#150605);box-shadow:inset 0 4px 7px rgba(0,0,0,.8),inset 0 0 0 1px rgba(0,0,0,.55),0 1px 0 rgba(255,190,170,.2)}
.cut-dome{border-radius:50%}
.cut-pack::after,.cut-base::after{content:"";position:absolute;left:100%;top:50%;width:8px;height:20px;margin:-10px 0 0 -1px;border-radius:0 10px 10px 0;background:#1a0807;box-shadow:inset 0 3px 4px rgba(0,0,0,.7)}   /* finger notch */
.sl-flap{position:absolute;inset:0;border-radius:5px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4%;transform-origin:0 50%;
  background:var(--grain-soft),linear-gradient(160deg,#2c573d,#1f4230);color:var(--foil);box-shadow:inset 0 1px 0 rgba(255,255,255,.08),0 1px 3px rgba(0,0,0,.4);
  transition:transform .75s cubic-bezier(.3,.9,.3,1),filter .75s}
.s2 .sl-flap,.s4 .sl-flap{transform-origin:100% 50%}.s5 .sl-flap{transform-origin:50% 0}
.sl-perf{position:absolute;inset:5px;border:1.5px dashed rgba(230,194,122,.8);border-radius:4px}
.sl-flap b{font:900 40px/1 var(--dot);font-variation-settings:"ROND" 100}
.sl-flap span{font:400 14px/1 var(--mono);color:#d86a5c}
.slot.poked .sl-flap{transform:scale(.94);filter:brightness(.85)}
.slot.torn .sl-flap{transform:rotateY(-128deg);filter:brightness(.62)}
.slot.torn.s2 .sl-flap,.slot.torn.s4 .sl-flap{transform:rotateY(128deg)}
.slot.torn.s5 .sl-flap{transform:translateY(-12%) rotateX(96deg);opacity:0;transition:transform .75s cubic-bezier(.3,.9,.3,1),filter .75s,opacity .35s .4s}   /* the big flap comes right off, so it never covers the sign */
.slot:not(:disabled):not(.torn):hover .sl-flap{filter:brightness(1.12)}
/* the next thing to tap: a gold frame that breathes (scene.js guide()) */
.slot.next .sl-flap{animation:nextframe 1.4s ease-in-out infinite}
@keyframes nextframe{0%,100%{box-shadow:0 0 0 2px rgba(247,200,110,.95),0 0 10px 2px rgba(247,200,110,.55)}50%{box-shadow:0 0 0 3px rgba(255,226,150,1),0 0 22px 6px rgba(247,200,110,.8)}}
.thing.next>*{animation:nextglow 1.4s ease-in-out infinite}   /* the glow follows the thing's own outline (a figure glows round the figure) */
@keyframes nextglow{0%,100%{filter:drop-shadow(0 0 1.5px #ffe08a) drop-shadow(0 0 5px rgba(255,205,90,.85))}50%{filter:drop-shadow(0 0 2.5px #fff0b8) drop-shadow(0 0 12px rgba(255,205,90,1))}}
.gl-key.next::before{content:"";position:absolute;left:50%;top:50%;width:30px;height:30px;margin:-15px 0 0 -15px;border-radius:50%;pointer-events:none;mix-blend-mode:screen;
  background:radial-gradient(closest-side,rgba(255,226,140,.95),rgba(255,200,90,.45) 55%,rgba(255,200,90,0));animation:keyglow 1.4s ease-in-out infinite}
@keyframes keyglow{50%{opacity:.45;transform:scale(.85)}}

/* ---------- the desk scene ---------- */
body[data-view="scene"]{overflow:hidden;background:#1d0c06;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}
body[data-view="scene"] ::selection{background:transparent}   /* double-tapping on a computer selected the whole page (a blue wash) */
.view{position:fixed;inset:0;overflow:hidden;touch-action:none;user-select:none;-webkit-user-select:none;background:#1d0c06}
.wood{position:absolute;inset:0;width:100%;height:100%;display:block}
.gv-glow{position:absolute;inset:0;pointer-events:none;background:radial-gradient(70% 50% at 72% 4%,rgba(224,168,103,.26),rgba(224,168,103,0) 70%),radial-gradient(90% 70% at 50% 52%,rgba(8,5,4,0) 35%,rgba(8,5,4,.62))}
.stage{position:absolute;left:0;top:0;width:400px;height:800px;transform-origin:0 0}
.stage>.xbox{position:absolute;z-index:2;transform-origin:50% 0;transition:transform .95s var(--ease),opacity .6s;cursor:pointer}
.is-open .stage>.xbox,.is-build .stage>.xbox{cursor:default;transform:translateY(-2px)}   /* a nudge when it opens, so the doors are always repainted open */
.gview:not(.is-closed) .xb-door.l{transform:rotateY(-116deg)}.gview:not(.is-closed) .xb-door.r{transform:rotateY(116deg)}

.is-done .gv-glow{opacity:0;transition:opacity 1s}
.is-closed .stage>.xbox{animation:boxidle 2.6s ease-in-out infinite}
@keyframes boxidle{50%{translate:0 -5px}}

/* the things: each lies in its cut-out in the box, at its real size next to the others */
.thing{position:absolute;left:0;top:0;transform-origin:50% 100%;will-change:transform;z-index:14;cursor:pointer;touch-action:none}
.thing.pop{animation:popin .4s var(--ease)}
@keyframes popin{from{opacity:0;scale:.86}}
.thing.lift{animation:lift .42s var(--ease)}
@keyframes lift{40%{translate:0 -7px;scale:1.07}}
.thing.drag{z-index:22;filter:drop-shadow(0 14px 12px rgba(10,7,5,.5))}
.thing.no{animation:nope .36s}
@keyframes nope{25%{translate:-6px 0}75%{translate:6px 0}}
.thing.gone{opacity:0;pointer-events:none;transition:opacity .25s!important}
.it-ticket .ticket{--tw:70px}.it-post .postcard{--pw:132px}   /* these two set their own size on themselves: say it here (same numbers as SIZE in scene.js) */
.it-post{width:88px;height:132px}
.it-post .postcard{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) rotate(-90deg)}
.it-key{width:74px;height:24px}
.it-ticket{width:70px;height:88px}   /* in the box the photobooth card stands upright, top of window 3 */
.it-ticket .ticket{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%)}
.sl-div{position:absolute;left:7px;right:7px;height:3px;border-radius:2px;background:linear-gradient(#1a0706,#1a0706 50%,rgba(255,190,170,.22) 50%);box-shadow:0 1px 1px rgba(0,0,0,.3)}
.it-tree{height:var(--th,58px);aspect-ratio:160/200}.it-tree img{display:block;width:100%;height:100%;pointer-events:none}
.it-key .wkey{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) rotate(90deg)}
.th-ticket,.th-postcard{filter:drop-shadow(0 1px 2px rgba(10,7,5,.5))}
.is-done .th-ticket,.is-done .th-postcard{filter:drop-shadow(0 4px 5px rgba(10,7,5,.55))}

/* where the globe is built (three.js canvas, or the flat stand-in), with the touch areas laid over it */
.gwrap{position:absolute;z-index:8;opacity:0;pointer-events:none;transform-origin:50% calc(100% - 6px);transition:opacity .6s,transform 1.1s var(--ease)}
.is-build .gwrap,.is-done .gwrap{opacity:1;pointer-events:auto}
/* done: her shop table seen from the side; the globe stands on it (--tx/--ty/--ts from scene.js fit()), tap it for the big view */
.tablebg{position:absolute;inset:0;background:url(/img/scene/table-bg.webp) no-repeat;opacity:0;pointer-events:none;transition:opacity 1.2s ease .2s,filter .6s}
.is-done .tablebg{opacity:1}
.tableblur{position:absolute;inset:-40px;background:url(/img/scene/table-bg.webp) 50% 85%/cover;filter:blur(24px) brightness(.45);opacity:0;pointer-events:none;transition:opacity 1.2s ease .2s}
.is-done .tableblur{opacity:1}
.is-done .gwrap{transform:translate(var(--tx),var(--ty)) scale(var(--ts))}
.is-done .gl-touch,.is-done .gl-turn{cursor:zoom-in}
.is-done.big .gwrap{transform:translate(var(--zx),var(--zy)) scale(var(--zs))}
.is-done.big .gl-touch{cursor:grab}.is-done.big .gl-turn{cursor:ew-resize}
.big .tablebg{filter:brightness(.4) blur(4px)}
.big .th-ticket,.big .th-postcard{opacity:0;pointer-events:none;transition:opacity .3s}
.is-done .th-ticket .ticket{transform:translate(-50%,-50%) perspective(320px) rotateX(var(--tk-tilt,56deg));transform-origin:50% 100%}   /* lying flat on the table */
.is-done .it-post .postcard{transform:translate(-50%,-50%) perspective(420px) rotateX(var(--pc-tilt,48deg))}

.skip .gwrap,.skip .stage>.xbox,.skip .xb-door{transition:none}
.g3-canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.gl-touch{position:absolute;border-radius:50%;pointer-events:none;touch-action:none}
.sealed .gl-touch{pointer-events:auto;cursor:grab}
.sealed .gl-touch:active{cursor:grabbing}
.gl-turn{position:absolute;pointer-events:none;touch-action:none}
.is-done .gl-turn{pointer-events:auto;cursor:ew-resize}
.gl-key{position:absolute;width:44px;height:44px;padding:0;border:0;border-radius:50%;background:none;pointer-events:none;cursor:pointer}
.is-done .gl-key{pointer-events:auto}
.gwrap.wob{animation:wob .5s ease-out}
@keyframes wob{20%{translate:5px 0}55%{translate:-3px 0}80%{translate:1px 0}}
.g3-flat{position:absolute;inset:0;display:flex;align-items:flex-end;justify-content:center;padding-bottom:6px}
.g3-flat .gbase,.g3-flat .gl-ball,.g3-flat .gl-dolls .doll,.g3-flat .gl-glass{visibility:hidden}
.g3-flat.has-base .gbase,.g3-flat.has-base .gl-ball,.g3-flat.has-doll0 .p0,.g3-flat.has-doll1 .p1,.g3-flat.has-dome .gl-glass{visibility:visible}

/* tearing a foil pack open */
.reveal{position:absolute;inset:-200px;z-index:30;background:rgba(8,5,4,.8);opacity:0;transition:opacity .3s;cursor:pointer}
.reveal.in{opacity:1}
.reveal>*{position:absolute}
.rv-rays{left:calc(50% - 230px);top:calc(200px + 105px);width:460px;height:460px;border-radius:50%;background:radial-gradient(rgba(224,168,103,.4),rgba(224,168,103,0) 66%);opacity:0;transition:opacity .6s}
.rv-pack{left:calc(50% - 85px);top:calc(200px + 205px);--fw:170px;transition:transform .7s var(--ease),opacity .5s}
.reveal.in .rv-pack{animation:packin .5s var(--ease)}
@keyframes packin{from{transform:translateY(60px) scale(.5);opacity:0}}
.reveal.torn .fp-strip{transform:translate(24%,-170%) rotate(42deg);opacity:0}
.reveal.out .rv-pack{transform:translateY(300px) rotate(-8deg);opacity:0}
.rv-doll{left:0;right:0;top:calc(200px + 205px);display:grid;place-items:center;opacity:0;transform:translateY(110px) scale(.55);transition:transform .75s var(--ease),opacity .3s}
.reveal.out .rv-doll,.reveal.out .rv-rays,.reveal.out .rv-name{opacity:1}
.reveal.out .rv-doll{transform:none}
.reveal.bye .rv-doll{opacity:0;transition:none}
.rv-name{left:0;right:0;top:calc(200px + 478px);margin:0;text-align:center;opacity:0;transition:opacity .5s .3s}
.rv-name b{display:block;font:500 22px/1.3 var(--thai)}
.rv-name span{font:400 12px/1.4 var(--mono);letter-spacing:.2em;color:var(--amber)}
.spark{position:absolute;z-index:40;width:var(--sz);height:var(--sz);margin:calc(var(--sz) / -2);background:#f7dc9a;pointer-events:none;
  clip-path:polygon(50% 0,60% 40%,100% 50%,60% 60%,50% 100%,40% 60%,0 50%,40% 40%);animation:spark 1.1s ease-out forwards}
@keyframes spark{to{transform:translate(var(--dx),var(--dy)) rotate(200deg) scale(.2);opacity:0}}

/* hint, preview bar, zoom, corner buttons */
.hint{position:fixed;left:50%;bottom:calc(18px + env(safe-area-inset-bottom));z-index:9500;transform:translateX(-50%);margin:0;max-width:92vw;padding:10px 16px;border-radius:999px;
  background:rgba(18,9,6,.82);border:1px solid var(--faint);color:var(--cream);font:400 14px var(--thai);white-space:nowrap;pointer-events:none;backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
.hint:empty{display:none}
.gview .hint{bottom:auto;top:calc(64px + env(safe-area-inset-top))}   /* the desk below is where the things line up: the hint sits above the box */
/* the hint is the voice of the scene: plain warm text with a small gold star, no pill, so it never looks like a button;
   the preview bar above is a quiet tool strip (her call 2026-11-12: they fought for attention) */
.gview .hint{top:calc(78px + env(safe-area-inset-top));padding:0 12px;border:0;border-radius:0;background:none;backdrop-filter:none;-webkit-backdrop-filter:none;
  font:500 clamp(11px,3.3vw,15px)/1.4 var(--thai);color:#fbecd0;text-shadow:0 1px 2px rgba(0,0,0,.9),0 0 14px rgba(0,0,0,.85);white-space:nowrap;text-align:center;max-width:96vw}   /* one line: Thai must not break mid-word */
.gview .hint::before,.gview .hint::after{content:"✦";margin-right:.45em;color:#e6c27a;font-size:.85em}
.gview .hint::after{margin:0 0 0 .45em}   /* a star at each end of every line */
.gview.intro .hint{top:auto}
.hint.pop{animation:hintin .45s var(--ease)}
@keyframes hintin{from{opacity:0;transform:translate(-50%,10px)}}
.preview-bar{position:fixed;left:10px;top:calc(10px + env(safe-area-inset-top));z-index:25;display:flex;align-items:center;gap:6px;opacity:.82;
  padding:4px 4px 4px 14px;border-radius:999px;background:rgba(18,9,6,.82);border:1px solid rgba(224,168,103,.35);font:400 12px var(--thai);color:var(--amber);white-space:nowrap}
.zoom{position:fixed;inset:0;z-index:40;display:grid;place-items:center;padding:20px;background:rgba(8,5,4,.72);opacity:0;transition:opacity .2s;cursor:zoom-out}
.zoom.in{opacity:1}
.zoom>.postcard,.zoom>.ticket{transform:scale(.9) rotate(-1.5deg);transition:transform .3s var(--ease)}
.zoom.in>.postcard,.zoom.in>.ticket{transform:rotate(-1deg)}
.zoom-x{position:absolute;right:14px;top:calc(14px + env(safe-area-inset-top));width:44px;height:44px;display:grid;place-items:center;border-radius:50%;border:1px solid var(--faint);background:rgba(18,13,11,.6);cursor:pointer}
.gv-snd{position:fixed;right:10px;top:calc(10px + env(safe-area-inset-top));z-index:26;width:44px;height:44px;display:grid;place-items:center;border-radius:50%;border:1px solid var(--faint);background:rgba(18,9,6,.72);cursor:pointer}
.gv-bar{position:fixed;left:50%;bottom:calc(14px + env(safe-area-inset-bottom));z-index:24;transform:translateX(-50%);display:flex;gap:8px;white-space:nowrap}
.gv-bar .chip{background:rgba(18,9,6,.82);font-size:13px;min-height:40px}

/* ---------- builder ---------- */
.dl-pair{display:flex;justify-content:center;gap:12px;margin:4px 0 12px}
.dl-slot{flex:1;max-width:190px;display:flex;flex-direction:column;align-items:center;gap:1px;padding:12px 8px 8px;border-radius:16px;border:1px solid var(--faint);transition:border-color .2s,background .2s}
.dl-slot.now{border-color:var(--amber);background:rgba(224,168,103,.07)}
.dl-pickme{all:unset;display:block;cursor:pointer;border-radius:12px;--dh:min(44vw,176px)}
.dl-pickme:focus-visible{outline:2px solid var(--amber);outline-offset:4px}
.dl-no{margin-top:6px;font:400 11px/1.4 var(--mono);letter-spacing:.22em;color:var(--amber)}
.dl-name{font:300 13px/1.4 var(--thai);color:var(--muted)}
.dl-picks{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;max-width:420px;margin:0 auto}   /* four outfits fill the row: nothing looks missing on the right */
.dl-opt{aspect-ratio:.64;padding:5px 3px;border-radius:12px;border:1px solid var(--faint);background:rgba(242,237,228,.04);cursor:pointer}
.dl-opt img{display:block;width:100%;height:100%;object-fit:contain;pointer-events:none}
.dl-opt[aria-pressed="true"]{border-color:var(--amber);background:rgba(224,168,103,.16)}
.word-stage{display:grid;place-items:center;padding:8px 0 2px}
.box-stage .xbox{margin:6px auto}

/* ---------- the opening: D walk into the shop, B lights down + windows lit, A the ribbon, C snow ---------- */
.shopbg{position:absolute;inset:0;background:url(/img/scene/shop-bg.webp) no-repeat;will-change:transform;transition:transform 1.9s cubic-bezier(.45,0,.2,1),filter 1.4s ease,opacity 1s}
.gview .wood{display:none}                                  /* her shop is the room now */
.gview.walk .shopbg{transform:var(--walk);filter:brightness(.62) blur(1.5px)}
.gview.lights .shopbg{filter:brightness(.4) saturate(.85) blur(2px)}
.gview.intro .hint{top:auto;bottom:calc(22px + env(safe-area-inset-bottom))}
.is-done .shopbg{opacity:0}
.skip .shopbg{transition:none}
.xb-lights{position:absolute;left:0;right:0;top:calc(var(--bw) * .168);bottom:0;pointer-events:none;z-index:3}
.xb-lights i{position:absolute;border-radius:3px;opacity:0;mix-blend-mode:screen;transition:opacity .9s ease;
  background:radial-gradient(closest-side,rgba(255,214,140,.95),rgba(255,180,90,.55) 60%,rgba(255,170,80,0));box-shadow:0 0 calc(var(--bw) * .05) rgba(255,190,110,.5)}
.lights .xb-lights i{opacity:1}
.gview:not(.is-closed) .xb-lights{opacity:0;transition:opacity .3s}
.flake{position:absolute;z-index:35;width:var(--sz);height:var(--sz);margin:calc(var(--sz) / -2);border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,#fff 40%,rgba(255,255,255,.4) 70%,rgba(255,255,255,0));opacity:0;animation:flake 3s ease-out forwards}
@keyframes flake{0%{opacity:0;transform:translate(0,0) scale(.4)}12%{opacity:1}30%{transform:translate(var(--ux),var(--uy)) scale(1)}100%{opacity:0;transform:translate(calc(var(--ux) + var(--fx)),calc(var(--uy) + var(--fy))) scale(.8)}}
/* done: the opened box sits small on the counter behind the table */
.is-done .stage>.xbox{opacity:0;pointer-events:none;transform:translateY(-40px)}
/* the closed box on the table: a block in 3D, turned so its front (her drawing), its top and its right side show */
.tbox{--w:120px;--d:calc(var(--w) * .42);position:absolute;z-index:6;width:var(--w);height:calc(var(--w) * .943);perspective:calc(var(--w) * 7);pointer-events:none;opacity:0;transition:opacity 1s ease .5s;
  filter:brightness(.78) drop-shadow(0 calc(var(--w) * .04) calc(var(--w) * .05) rgba(0,0,0,.55))}
.is-done .tbox{opacity:1}
.big .tbox{opacity:0;transition:opacity .3s}
.tb-cube{position:absolute;inset:0;transform-style:preserve-3d;transform-origin:50% 100% calc(var(--d) / -2);transform:rotateX(-16deg) rotateY(var(--turn,-34deg))}
.tb-cube i{position:absolute;display:block;backface-visibility:hidden}
.tb-front{left:0;top:0;width:var(--w);height:calc(var(--w) * .943);background:url(/img/scene/box-front.webp) 0 0/100% 100% no-repeat;transform:translateZ(calc(var(--d) / 2))}
.tb-top{left:0;top:calc(var(--w) * .062);width:var(--w);height:var(--d);transform-origin:50% 0;transform:translateZ(calc(var(--d) / -2)) rotateX(90deg);
  background:linear-gradient(160deg,#c23a30,#8e231d);box-shadow:inset 0 0 0 calc(var(--w) * .012) #d9ad5c,inset 0 0 0 calc(var(--w) * .022) #9e2a24,inset 0 0 0 calc(var(--w) * .026) rgba(217,173,92,.7)}
.tb-side{left:var(--w);top:calc(var(--w) * .062);width:var(--d);height:calc(var(--w) * .881);transform-origin:0 50%;transform:translateZ(calc(var(--d) / 2)) rotateY(90deg);
  background:linear-gradient(90deg,#7a1c17,#5e1511);box-shadow:inset 0 0 0 calc(var(--w) * .012) #b98a3e,inset 0 0 0 calc(var(--w) * .03) #6a1813,inset 0 0 0 calc(var(--w) * .034) rgba(185,138,62,.6)}
.tablefg{position:absolute;inset:0;background:url(/img/scene/table-bg.webp) no-repeat;pointer-events:none;opacity:0;transition:opacity 1.2s ease .2s;z-index:9}
.is-done .tablefg{opacity:1}
.big .tablefg{opacity:0}

/* ?table: her panel for arranging the finished table */
.tedit{position:fixed;right:10px;top:70px;z-index:60;width:min(300px,86vw);max-height:calc(100vh - 150px);display:flex;flex-direction:column;border-radius:14px;background:rgba(24,13,8,.94);border:1px solid rgba(224,168,103,.5);color:var(--cream);font:400 13px/1.4 var(--thai);box-shadow:0 10px 30px rgba(0,0,0,.6);user-select:auto;-webkit-user-select:auto}
.te-head{display:flex;justify-content:space-between;align-items:center;padding:10px 14px;border-bottom:1px solid rgba(224,168,103,.25)}
.te-head b{color:var(--amber);font-weight:600}
.te-min{width:32px;height:32px;border-radius:8px;border:1px solid rgba(224,168,103,.4);background:none;color:var(--cream);cursor:pointer}
.te-body{overflow:auto;padding:6px 14px 14px}
.tedit.min .te-body{display:none}
.te-body p{margin:6px 0;color:#c8b59a;font-size:12px}
.te-body h4{margin:12px 0 4px;color:var(--amber);font:600 13px var(--thai)}
.te-body label{display:flex;justify-content:space-between;margin-top:4px}
.te-body label span:last-child{color:var(--amber);font-variant-numeric:tabular-nums}
.te-body input[type=range]{width:100%;accent-color:#d9ad5c}
.te-btns{display:grid;gap:8px;margin-top:14px}
.te-btns button{padding:10px;border-radius:8px;border:1px solid #d9ad5c;background:none;color:#d9ad5c;font:inherit;cursor:pointer}
.te-btns button.main{background:#d9ad5c;color:#2b1a12;font-weight:600}
.tedit-on .is-done .tbox,.tedit-on.is-done .tbox,.tedit-on.is-done .th-ticket,.tedit-on.is-done .th-postcard,.tedit-on.is-done .gwrap{cursor:move}

/* the preview bar: small and quiet, still a 44px tap target */
.preview-bar{padding:2px 2px 2px 12px;background:rgba(12,6,4,.55);border-color:rgba(224,168,103,.18);font-size:11px;color:rgba(224,168,103,.85)}
.preview-bar .chip{min-height:36px;padding:0 12px;font-size:12px;border-color:rgba(242,237,228,.18);background:none;position:relative}
.preview-bar .chip::after{content:"";position:absolute;inset:-4px}
.preview-bar .chip svg{width:14px;height:14px}
.gv-snd{opacity:.82}
