/* (c) 2026 Pretty Paperwork Network. All rights reserved. Not licensed for copying, redistribution or AI training. */
/* PPN Chat 2.5D holodeck (holo.js). The space scene keeps its own colors in every palette; the switch, plates and bubbles
   take the room's theme so the layer still belongs to the chat. */
.hd{position:fixed;z-index:40;overflow:hidden;border:var(--line);border-radius:24px;box-shadow:var(--drop);background:#070b24;--px:0;--py:0;contain:layout paint;user-select:none}
.hd[hidden]{display:none}
.hd-stars,.hd-static{position:absolute;inset:0;width:100%;height:100%;display:block}
.hd-stars{transform:scale(1.04) translate(calc(var(--px)*-10px),calc(var(--py)*-7px))}
.hd-static{z-index:9;image-rendering:pixelated;pointer-events:none}.hd-static[hidden]{display:none}
.hd-bg{position:absolute;inset:-3%;width:106%;height:106%;transform:translate(calc(var(--px)*-20px),calc(var(--py)*-12px))}
.hd-truss{transform-origin:0 60px;animation:hd-tr 26s ease-in-out infinite alternate}@keyframes hd-tr{to{transform:rotate(1.6deg) translateY(5px)}}
.hd-sat{animation:hd-sat 74s linear infinite;animation-delay:-22s}@keyframes hd-sat{0%{transform:translate(1080px,170px) rotate(-12deg)}100%{transform:translate(-90px,300px) rotate(8deg)}}
.hd-wr{animation:hd-wr 33s linear infinite;animation-delay:-9s}@keyframes hd-wr{0%{transform:translate(-50px,250px) rotate(0)}100%{transform:translate(1050px,160px) rotate(760deg)}}
.hd-stage{position:absolute;inset:0;transform:translate(calc(var(--px)*12px),calc(var(--py)*7px))}
.hd-floor{position:absolute;inset:0;overflow:visible}
.hd-floor .sd{fill:#0e1b52;stroke:#7fe3ff;stroke-width:2}
.hd-floor .dk{stroke:#a9f0ff;stroke-width:2.5}
.hd-floor .ti{fill:none;stroke:#7fe3ff;stroke-opacity:.42;stroke-width:1.2}
.hd-floor .sw{fill:#a9f0ff;fill-opacity:.13;animation:hd-swp 7s linear infinite}@keyframes hd-swp{to{transform:translateX(120vw)}}
.hd-floor .hdp{fill:#a9f0ff;fill-opacity:0;stroke:#fff;stroke-opacity:0;stroke-width:2;transition:fill-opacity .25s,stroke-opacity .25s}
.hd-floor .hdp.lit{fill-opacity:.2;stroke-opacity:.75}.hd-floor .hdp.spk{fill:var(--accent);fill-opacity:.9;stroke-opacity:1}
/* the chromatic aberration gate */
.hd-ca{position:absolute;transform:translate(-50%,-50%);--ab:3px;animation:hd-ab 5.3s ease-in-out infinite}
.hd-ca .hd-gl{position:absolute;left:12%;right:12%;bottom:-20%;height:20%;border-radius:50%;background:radial-gradient(closest-side,#fff8,#fff0)}
.hd-ca .spin{position:absolute;inset:0;animation:hd-spin 16s linear infinite;mix-blend-mode:screen}
.hd-ca svg{position:absolute;inset:0;width:100%;height:100%;mix-blend-mode:screen;overflow:visible}
.hd-ca svg.r{color:#ff1f4b;stroke:#ff1f4b;transform:translate(calc(var(--ab)*-1),calc(var(--ab)*.4))}.hd-ca svg.g{stroke:#19ff8c}.hd-ca svg.b{stroke:#2a6bff;transform:translate(var(--ab),calc(var(--ab)*-.4))}
@keyframes hd-spin{to{transform:rotateZ(60deg)}}
@keyframes hd-ab{0%,100%{--ab:2px;translate:0 0}38%{--ab:5px;translate:0 -7px}41%{--ab:9px;translate:1px -7px}44%{--ab:4px;translate:0 -7px}72%{--ab:3px;translate:0 3px}}
@property --ab{syntax:'<length>';inherits:true;initial-value:3px}
.hd-ca.kick .spin{animation:hd-spin 16s linear infinite,hd-kick .5s steps(5)}@keyframes hd-kick{0%{filter:blur(1.6px) saturate(2)}50%{transform:scale(1.14)}100%{filter:none}}
/* suits: every figure is two drawn frames plus a personality's own motion */
.hd-suits{position:absolute;inset:0;transform:translate(calc(var(--px)*-12px),calc(var(--py)*-7px))}
.su{position:absolute;width:0;height:0;--h:110px;--w:calc(var(--h)*.73)}
.su .shd{position:absolute;left:calc(var(--w)*-.36);top:calc(var(--h)*-.06);width:calc(var(--w)*.72);height:calc(var(--h)*.11);border-radius:50%;background:#050a2c;opacity:.55}
.su .fig{position:absolute;left:calc(var(--w)*-.5);top:calc(var(--h)*-1);width:var(--w);height:var(--h);transform-origin:50% 95%;will-change:transform;filter:drop-shadow(0 0 2.5px #bfeeff)}
.su .f{position:absolute;inset:0;width:100%;height:100%;overflow:visible}
.su .f1{animation:hd-f var(--t) steps(1) var(--dl) infinite}.su .f0{animation:hd-f0 var(--t) steps(1) var(--dl) infinite}
@keyframes hd-f{0%,62%{opacity:0}63%,100%{opacity:1}}@keyframes hd-f0{0%,62%{opacity:1}63%,100%{opacity:0}}
.su.m-breathe .fig{animation:hd-breathe var(--t) ease-in-out var(--dl) infinite}@keyframes hd-breathe{50%{transform:scaleY(1.02) translateY(-1px)}}
.su.m-bob .fig{animation:hd-bob var(--t) ease-in-out var(--dl) infinite}@keyframes hd-bob{50%{transform:translateY(-6%)}}
.su.m-tap .fig{animation:hd-tap var(--t) steps(3) var(--dl) infinite}@keyframes hd-tap{50%{transform:rotate(-1.4deg)}}
.su.m-sway .fig{animation:hd-sway var(--t) ease-in-out var(--dl) infinite alternate}@keyframes hd-sway{from{transform:rotate(-2.2deg)}to{transform:rotate(2.2deg)}}
.su.m-bounce .fig{animation:hd-bounce var(--t) cubic-bezier(.3,0,.5,1) var(--dl) infinite}@keyframes hd-bounce{0%,100%{transform:scale(1.04,.95)}45%{transform:translateY(-13%) scale(.97,1.04)}}
.su.m-plant .fig{animation:hd-plant var(--t) ease-in-out var(--dl) infinite}@keyframes hd-plant{60%{transform:translateX(1.5%) rotate(.8deg)}}
.su.m-lean .fig{animation:hd-lean var(--t) ease-in-out var(--dl) infinite alternate}@keyframes hd-lean{from{transform:skewX(2deg)}to{transform:skewX(-5deg) translateX(3%)}}
.su.m-proud .fig{animation:hd-proud var(--t) ease-in-out var(--dl) infinite}@keyframes hd-proud{50%{transform:scaleY(1.03)}}
.su.m-float .fig{animation:hd-float var(--t) ease-in-out var(--dl) infinite alternate;transform-origin:50% 50%}@keyframes hd-float{from{transform:translateY(-9%) rotate(-5deg)}to{transform:translateY(-19%) rotate(7deg)}}
.su.in .fig{animation:hd-in .55s var(--spring,ease-out) both}@keyframes hd-in{0%{opacity:0;transform:translateY(-34%) scale(.8,1.25);filter:blur(2px) drop-shadow(5px 0 #ff1f4b) drop-shadow(-5px 0 #2a6bff)}100%{opacity:1}}
.su.talk .fig{animation:hd-talk .46s var(--spring,ease-out)}@keyframes hd-talk{0%{transform:translateY(0)}40%{transform:translateY(-13%) scale(1.05)}100%{transform:none}}
.su .np{position:absolute;left:0;top:calc(var(--h)*.04);transform:translateX(-50%);display:flex;gap:4px;align-items:center;white-space:nowrap;padding:1px 8px;border-radius:9px;background:#070b24e6;color:#fff;font-size:11px;line-height:1.35;max-width:150px}
.su .np b{font-weight:600;overflow:hidden;text-overflow:ellipsis}.su .np i{font-style:normal;font-size:9px;padding:0 4px;border-radius:5px;background:var(--accent);color:var(--accent-ink,#fff)}
.su.talk .np{background:var(--paper);color:var(--ink)}
/* bubbles: tail behind the body, the disclosure label stays on every line */
.hd-bubs{position:absolute;inset:0;z-index:5;pointer-events:none}
.hb-b{position:absolute;max-width:min(270px,62%);padding:8px 13px 7px;background:var(--paper);color:var(--ink);border-radius:18px;box-shadow:0 0 0 3px var(--ink),4px 5px 0 3px #0008;font-size:14px;line-height:1.28;animation:hd-pop .28s var(--spring,ease-out)}
.hb-b::after{content:"";position:absolute;z-index:-1;left:var(--tx,50%);bottom:-11px;width:18px;height:18px;margin-left:-9px;background:var(--paper);box-shadow:3px 3px 0 var(--ink);transform:rotate(45deg)}
.hb-b b{display:block;font-size:12px;color:var(--accent-text,var(--title-a));font-weight:700}.hb-b p{margin:0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4;overflow:hidden}
.hb-b .lt{display:inline-grid;margin:4px 0 0;position:relative}
.hb-b.far::after{display:none}
.hb-b.out{opacity:0;transform:translateY(-6px);transition:.24s}
@keyframes hd-pop{from{opacity:0;transform:translateY(8px) scale(.9)}}
.hd-top{position:absolute;left:12px;top:10px;z-index:6;display:flex;gap:8px;align-items:center;padding:3px 12px;border-radius:12px;background:#070b24cc;color:#fff;font-size:13px}
.hd-rn{font-weight:700;font-size:15px}.hd-rc{opacity:.85}
.hd-peek{display:none;position:absolute;right:12px;top:10px;z-index:6;padding:3px 12px;border-radius:12px;background:var(--paper);color:var(--ink);font-size:13px;font-weight:600}
.hd-pk .hd-peek{display:block}
/* the dimension switch: a tape deck with the cassette waiting above the slot; in 2.5D the tape is seated and the reels turn */
.hd-sw{position:fixed;z-index:44;width:82px;height:50px;padding:0;border:0;background:none;cursor:pointer;line-height:0;--fg:var(--ink);--bg:var(--paper);transition:transform .16s}
.hd-sw[hidden]{display:none}.hd-sw:hover{transform:translateY(-2px) rotate(-1.5deg)}.hd-sw:active{transform:translateY(1px)}
.hd-sw svg{width:100%;height:100%;overflow:visible;border-radius:9px;filter:drop-shadow(3px 3px 0 var(--ink))}
.hd-sw .bd{fill:var(--bg);stroke:var(--fg);stroke-width:3}.hd-sw .slot{fill:var(--fg)}.hd-sw .tk{fill:none;stroke:var(--fg);stroke-width:1.6;stroke-linecap:round;opacity:.5}
.hd-sw .led{fill:var(--bg);stroke:var(--fg);stroke-width:1.6;transition:fill .2s}.hd-sw .lip{fill:var(--bg);stroke:var(--fg);stroke-width:2}
.hd-sw .cas{transform:translate(0,-13px) rotate(-3deg);transform-origin:46px 28px;transition:transform .34s cubic-bezier(.3,1.7,.5,1)}
.hd-sw .sh{fill:var(--accent);stroke:var(--fg);stroke-width:2.4}.hd-sw .lb{fill:var(--paper)}.hd-sw .tx{font:700 8.5px Fredoka,sans-serif;fill:var(--ink)}
.hd-sw .win{fill:var(--paper);stroke:var(--fg);stroke-width:1.6}.hd-sw .reel circle{fill:none;stroke:var(--fg);stroke-width:1.8}.hd-sw .reel path{stroke:var(--fg);stroke-width:1.8}
.hd-sw.in .cas{transform:translate(0,3px)}.hd-sw.in .led{fill:var(--accent)}.hd-sw.in .reel{animation:hd-reel 1.8s linear infinite}@keyframes hd-reel{to{transform:rotate(360deg)}}
.hd-sw:focus-visible{outline:3px solid var(--accent);outline-offset:4px}
/* while help shows: thick double inverted outline, on an irregular pulse */
.hd-sw.hint svg{filter:none;outline:5px solid var(--ink);outline-offset:0;box-shadow:0 0 0 10px var(--paper),0 0 0 15px var(--ink);animation:hd-irr 2.3s steps(1) infinite}
.hd-sw.hint{--fg:var(--paper);--bg:var(--ink)}
@keyframes hd-irr{0%,9%{box-shadow:0 0 0 10px var(--paper),0 0 0 15px var(--ink)}10%,17%{box-shadow:0 0 0 13px var(--ink),0 0 0 19px var(--paper)}18%,46%{box-shadow:0 0 0 10px var(--paper),0 0 0 15px var(--ink)}47%,52%{box-shadow:0 0 0 14px var(--ink),0 0 0 21px var(--paper)}53%,61%{box-shadow:0 0 0 10px var(--paper),0 0 0 15px var(--ink)}62%,70%{box-shadow:0 0 0 12px var(--ink),0 0 0 18px var(--paper)}71%,100%{box-shadow:0 0 0 10px var(--paper),0 0 0 15px var(--ink)}}
.hd-help{position:fixed;z-index:45;max-width:230px;padding:8px 13px;background:var(--ink);color:var(--paper);border-radius:14px;font-size:13.5px;line-height:1.3;pointer-events:none;opacity:0}
.hd-help::after{content:"";position:absolute;z-index:-1;left:calc(50% - 8px);top:-7px;width:16px;height:16px;background:var(--ink);transform:rotate(45deg)}
.hd-help b{display:block}.hd-help[hidden]{display:none}.hd-help.go{animation:hd-help 5s linear both}@keyframes hd-help{0%{opacity:0;transform:translateY(8px)}6%,84%{opacity:1;transform:none}100%{opacity:0}}
@media (max-width:760px){.m-chat .feed{padding-bottom:62px}.hd{border-radius:16px}.hd-sw{width:68px;height:42px}.hb-b{font-size:13px;max-width:72%}.su .np{font-size:10px;max-width:96px}}
@media (prefers-reduced-motion:reduce){.hd *,.hd-sw *,.hd-sw.hint svg{animation:none!important}.hd-sw.in .reel{animation:none}.su .f1{display:none}}
/* popups off the message bar live in the app, under the fixed scene. While the scene is on the app gives up its stacking layer and the bar rises over the scene */
body.hd-on #app{z-index:auto}
body.hd-on #world{z-index:-1}
body.hd-on .m-chat .deck{z-index:46}
/* hype banners sit on the room head, which the scene covers too */
body.hd-on .m-chat .rh.up{z-index:46}
