:root{--red:#a2352e;--paper:#e8e0d1;--ink:#15120f}*{box-sizing:border-box}html,body,#viewer{margin:0;width:100%;height:100%;overflow:hidden;background:#0c0b09;color:var(--paper);font-family:Inter,"Noto Serif SC",sans-serif}body.viewer-fullscreen{position:fixed;inset:0}#viewer.fullscreen-fallback{position:fixed;inset:0;width:100vw;height:100dvh;z-index:9999}#viewer:fullscreen,#viewer:-webkit-full-screen{width:100vw;height:100vh}canvas{position:absolute;inset:0;width:100%;height:100%;touch-action:none;outline:0}.wash{position:absolute;inset:0;pointer-events:none;background:radial-gradient(circle at 50% 45%,transparent 35%,rgba(4,3,2,.42) 100%)}.grain{position:absolute;inset:0;pointer-events:none;opacity:.15;background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.15'/%3E%3C/svg%3E")}header{position:absolute;top:0;left:0;right:0;padding:28px 35px;display:grid;grid-template-columns:46px 1fr auto;align-items:start;gap:18px;background:linear-gradient(rgba(5,4,3,.72),transparent);pointer-events:none}header>*{pointer-events:auto}.back{width:38px;height:38px;display:grid;place-items:center;border:1px solid rgba(255,255,255,.25);border-radius:50%;color:white;text-decoration:none}header span{font-size:8px;color:#b8a98f;letter-spacing:.2em}header h1{font:400 21px "Noto Serif SC";letter-spacing:.08em;margin:5px 0}.lang-switch{display:flex;gap:8px;align-items:center}.lang-switch button{border:0;background:none;color:#aaa;font-size:10px;padding:5px;cursor:pointer}.lang-switch button.active{color:#fff;border-bottom:1px solid var(--red)}.lang-switch i{height:12px;width:1px;background:#777}.caption{position:absolute;left:35px;bottom:35px;width:min(360px,calc(100% - 70px));padding:20px 45px 20px 20px;border-left:2px solid var(--red);background:rgba(16,13,10,.65);backdrop-filter:blur(12px);transition:.4s}.caption.hidden{transform:translateX(calc(-100% - 40px));opacity:0}.caption-index{font-size:9px;color:#b49362}.caption p{font:12px/1.9 "Noto Serif SC";margin:8px 0;color:#d2c9bb}.caption button{position:absolute;right:12px;top:10px;background:none;border:0;color:#aaa;font-size:18px;cursor:pointer}.viewer-tools{position:absolute;right:28px;top:50%;transform:translateY(-50%);display:flex;flex-direction:column;gap:10px}.viewer-tools button{width:54px;height:54px;border:1px solid rgba(255,255,255,.18);border-radius:50%;background:rgba(17,14,11,.6);backdrop-filter:blur(10px);color:#e5dac8;cursor:pointer;display:grid;place-content:center;gap:2px}.viewer-tools span{font-size:17px}.viewer-tools em{font:normal 8px "Noto Serif SC"}.loading,.error,.gesture-guide{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#11100d;z-index:20;transition:opacity .8s,visibility .8s}.error[hidden]{display:none}.loading.done{opacity:0;visibility:hidden}.seal-loader{width:55px;height:55px;display:grid;place-items:center;background:var(--red);font:26px "Noto Serif SC";animation:breathe 2s ease-in-out infinite}.loading p{font:13px "Noto Serif SC";letter-spacing:.16em;margin:24px}.loading>div{width:180px;height:1px;background:#36322c}.loading i{display:block;width:0;height:100%;background:#b79760;transition:width .2s}.loading b{font:normal 9px Inter;color:#8c8274;margin-top:10px}.error{background:#17130f;text-align:center;padding:30px}.error span{font:60px "Noto Serif SC";color:var(--red)}.error h2{font:400 25px "Noto Serif SC"}.error p{max-width:500px;color:#9d958a;font-size:12px}.error button,.gesture-guide button{background:var(--red);color:white;border:0;padding:12px 24px;font:12px "Noto Serif SC";cursor:pointer}.gesture-guide{background:rgba(13,11,9,.9);backdrop-filter:blur(16px);z-index:30}.gesture-guide.dismissed{opacity:0;visibility:hidden}.gesture-guide h2{font:400 30px "Noto Serif SC";margin:25px 0 8px}.gesture-guide p{font:11px "Noto Serif SC";color:#aaa;margin:0 0 25px}.finger{position:absolute;width:15px;height:58px;border:1px solid #d5c7b1;border-radius:10px;top:27%;animation:gesture 2.3s ease-in-out infinite}.finger.two{margin-left:35px;animation-delay:.1s}@keyframes breathe{50%{transform:scale(.93);opacity:.75}}@keyframes gesture{0%,100%{transform:translate(-20px,8px)}50%{transform:translate(20px,-8px)}}@media(max-width:650px){header{padding:18px;grid-template-columns:40px 1fr auto}.caption{left:18px;bottom:18px;width:calc(100% - 90px)}.viewer-tools{right:12px;top:auto;bottom:18px;transform:none}.viewer-tools button{width:46px;height:46px}.viewer-tools button em{display:none}header h1{font-size:16px}}
.viewer-tools .sound-toggle{touch-action:manipulation;-webkit-tap-highlight-color:transparent}.viewer-tools .sound-toggle.is-playing{border-color:rgba(162,53,46,.8);color:#fff;background:rgba(162,53,46,.34)}.viewer-tools .sound-toggle.is-playing span{animation:breathe 1.8s ease-in-out infinite}.viewer-tools .sound-toggle.has-audio-error{border-color:rgba(162,53,46,.9)}
:root{--viewer-viewport-height:100dvh}html.viewer-fullscreen,body.viewer-fullscreen{width:100%;height:var(--viewer-viewport-height);overflow:hidden;overscroll-behavior:none}#viewer.fullscreen-fallback{position:fixed!important;inset:0;width:100vw;height:var(--viewer-viewport-height);max-width:none;max-height:none;z-index:9999}#viewer:fullscreen,#viewer:-webkit-full-screen{position:fixed;inset:0;width:100%;height:100%;max-width:none;max-height:none}.fullscreen-fallback header,#viewer:fullscreen header,#viewer:-webkit-full-screen header{padding-top:max(18px,env(safe-area-inset-top));padding-left:max(18px,env(safe-area-inset-left));padding-right:max(18px,env(safe-area-inset-right))}.fullscreen-fallback .viewer-tools,#viewer:fullscreen .viewer-tools,#viewer:-webkit-full-screen .viewer-tools{right:max(12px,env(safe-area-inset-right));bottom:max(18px,env(safe-area-inset-bottom))}
.calibration-panel{position:absolute;z-index:40;left:24px;top:108px;width:min(390px,calc(100vw - 110px));max-height:calc(100vh - 140px);overflow:auto;padding:20px;border:1px solid rgba(206,184,145,.28);background:rgba(16,13,10,.92);box-shadow:0 24px 70px rgba(0,0,0,.45);backdrop-filter:blur(18px);transition:.35s}.calibration-panel.collapsed{opacity:0;visibility:hidden;transform:translateX(-24px)}.calibration-heading{display:flex;align-items:start;justify-content:space-between;margin-bottom:16px}.calibration-heading small{color:#b49362;font:8px Inter;letter-spacing:.2em}.calibration-heading h2{margin:5px 0 0;font:400 18px "Noto Serif SC"}.calibration-heading kbd{padding:4px 7px;border:1px solid #51493e;border-radius:3px;color:#968a79;font:9px Inter}.calibration-panel fieldset{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:0 0 14px;padding:12px;border:1px solid #39332b}.calibration-panel legend{padding:0 7px;color:#b9aa91;font:10px "Noto Serif SC"}.calibration-panel label{display:grid;gap:5px;color:#8f8577;font:9px Inter;letter-spacing:.04em}.calibration-panel input{width:100%;min-width:0;padding:8px;border:1px solid #40382e;background:#0d0b09;color:#eee4d3;font:11px Inter;outline:0}.calibration-panel input:focus{border-color:#a2352e;box-shadow:0 0 0 1px rgba(162,53,46,.25)}.calibration-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px 8px}.calibration-panel>p{min-height:16px;margin:14px 0 10px;color:#9b9184;font:9px Inter}.calibration-panel>p[data-state=saved]{color:#91ad7b}.calibration-panel>p[data-state=error]{color:#db7469}.calibration-actions{display:flex;flex-wrap:wrap;gap:7px}.calibration-actions button{padding:9px 11px;border:1px solid #4a4135;background:transparent;color:#c8bda9;cursor:pointer;font:10px "Noto Serif SC"}.calibration-actions button:hover{border-color:#a2352e}.calibration-actions .save{margin-left:auto;border-color:#a2352e;background:#a2352e;color:#fff}.calibration-actions button:disabled{cursor:wait;opacity:.5}@media(max-width:650px){.calibration-panel{left:10px;right:66px;top:86px;width:auto;max-height:calc(100vh - 170px);padding:15px}.calibration-grid{grid-template-columns:1fr 1fr}.calibration-actions .save{margin-left:0}}
.calibration-panel .rotation-fieldset{display:grid;grid-template-columns:1fr;gap:9px}.calibration-panel .axis-control{display:grid;grid-template-columns:18px minmax(0,1fr) 68px;align-items:center;gap:8px}.calibration-panel .axis-control b{color:#d4c4aa;font:600 10px Inter}.calibration-panel input[type=range]{height:18px;padding:0;border:0;background:transparent;accent-color:#a2352e;box-shadow:none}.calibration-panel .axis-number{text-align:right}
body[data-developer-mode=true] .lang-switch{display:none}
/* ===== 3D 展厅背景图 back.png =====
   viewer 页面 overflow:hidden 无滚动，背景天然固定；
   cover 完整覆盖可视区域且不拉伸变形，center 适配横/竖屏裁切 */
#viewer{background:#0c0b09 url("/static/back.png") no-repeat center center;background-size:cover}
/* 桌面端(屏幕宽度>=768px)横向 landscape：cover 铺满，居中裁切上下 */
@media(min-width:768px){#viewer{background-position:center center}}
/* 移动端(屏幕宽度<768px)纵向 portrait：cover 铺满，定位偏上保留主体 */
@media(max-width:767px){#viewer{background-position:center top}}
