@charset "UTF-8";
:root{color-scheme:dark;--bg:#08070d;--ink:#eae3f4;--muted:#93879f;--purple:#b482ff;--line:#b482ff25;font-family:Inter,"Segoe UI","Microsoft YaHei",sans-serif;font-size:14px;color:var(--ink);background:var(--bg)}*{box-sizing:border-box}body{margin:0;overflow:hidden}button,a{-webkit-tap-highlight-color:transparent}button{font:inherit;cursor:pointer;color:var(--ink);background:#131019cc;border:1px solid #b482ff30;padding:12px 17px;border-radius:7px;transition:background .2s,border-color .2s,transform .2s;touch-action:none}button:hover{background:#261a36;border-color:#b482ff88}button:active{transform:scale(.97)}button:focus-visible,a:focus-visible{outline:2px solid var(--purple);outline-offset:4px}[hidden]{display:none!important}#world{position:fixed;inset:0;width:100%;height:100%;touch-action:none;outline:none;background:radial-gradient(ellipse at 48% 48%,#160d24 0%,#0b0812 35%,#08070d 72%)}header{position:fixed;top:35px;left:42px;right:42px;display:flex;justify-content:space-between;align-items:center;pointer-events:none}header>*{pointer-events:auto}.brand{display:flex;align-items:center;gap:16px;text-decoration:none;color:var(--ink)}.brand i{width:15px;height:15px;background:var(--purple);box-shadow:6px 6px 0 #b482ff25}.brand b{font-weight:500;font-size:25px;margin-left:5px}.brand span{letter-spacing:.25em;font-size:12px;color:var(--muted)}.status{display:flex;align-items:center;gap:10px;color:#b4a8c0;font-size:13px}.status button{margin-left:20px;font-size:13px;color:#c0b3ce;background:transparent}.live-dot{display:inline-block;width:5px;height:5px;background:var(--purple);box-shadow:0 0 10px #b482ff80;border-radius:50%}.intro{position:fixed;left:43px;top:133px;pointer-events:none}.eyebrow{font-size:10px;letter-spacing:.22em;color:#8b789e}.intro h1{font-size:29px;letter-spacing:.2em;font-weight:400;margin:14px 0 15px}.intro p{font-size:13px;color:#a297ae}.coordinates{margin-top:27px;font-size:11px;letter-spacing:.05em;color:#776a86;display:flex;gap:12px}.divider{opacity:.5}.tools{position:fixed;right:36px;top:50%;transform:translateY(-50%);display:flex;flex-direction:column;gap:5px;padding:6px;background:#0e0b14c9;border:1px solid var(--line);border-radius:10px}.tools button{border:0;background:transparent;width:39px;height:39px;padding:0;font-size:21px;color:#c3aadf}.tools span{height:1px;background:var(--line);margin:4px 8px}footer{position:fixed;bottom:32px;left:43px;right:43px;display:flex;align-items:flex-end;justify-content:space-between;gap:20px;pointer-events:none}footer button{pointer-events:auto}.foot-left{display:grid;gap:9px}.foot-left>div{display:flex;align-items:center;gap:9px;font-size:12px}.foot-left small,.scale small{font-size:11px;color:#766a83}.foot-left #latency{color:#766a83;margin-left:5px}#geo-note{max-width:280px;line-height:1.5;color:#6e627c}.walk{position:absolute;left:50%;transform:translateX(-50%);display:flex;align-items:center;flex-direction:column;gap:10px}.walk>span{font-size:12px;color:#8e7e9f;letter-spacing:.15em}.arrows{display:flex;align-items:end;gap:5px}.arrows>div{display:flex;flex-direction:column;gap:5px}.arrows button{width:37px;height:34px;padding:0;color:#baa5ce;font-size:17px}.walk small{font-size:10px;letter-spacing:.13em;color:#64576f}.scale{display:flex;align-items:flex-end;flex-direction:column;gap:10px;color:#a998bb;font-size:11px}.scale i{height:6px;border:1px solid #9b82b6;border-top:0;width:100px}#hint{position:fixed;bottom:186px;left:50%;transform:translateX(-50%);font-size:12px;color:#84718e;white-space:nowrap;pointer-events:none;transition:opacity .4s}aside{position:fixed;right:42px;top:142px;width:230px;padding:23px;background:#120e1be8;border:1px solid #b482ff26;border-radius:12px;backdrop-filter:blur(16px)}aside h2{display:flex;gap:12px;align-items:center;font-size:16px;font-weight:400;margin:22px 0}aside h2 i{width:10px;height:10px;background:var(--purple)}aside strong{font-size:30px;font-weight:300;color:#d5b6fa}aside p{font-size:12px;color:var(--muted);margin:8px 0 25px}aside button{width:100%;text-align:left}aside button span{float:right;color:var(--purple)}aside .plain{border:0;text-align:center;color:#796b89;background:transparent;font-size:12px;margin-top:5px}#entry{position:fixed;inset:0;background:radial-gradient(ellipse at 50% 45%,#1b102b,#08070d 60%);display:flex;align-items:center;justify-content:center;z-index:10;transition:opacity .7s}#entry.dismiss{opacity:0;pointer-events:none}.entry-inner{text-align:center;display:flex;flex-direction:column;align-items:center;width:min(500px,90vw)}.entry-mark{height:67px;display:flex;align-items:center;gap:18px;margin-bottom:34px}.entry-mark i{height:11px;width:11px;background:#b482ff35;animation:breathe 2s infinite}.entry-mark i:nth-child(2){height:20px;width:20px;background:var(--purple);box-shadow:0 0 35px #b482ff44;animation-delay:.4s}.entry-mark i:nth-child(3){animation-delay:.8s}.entry-inner h2{font-weight:300;font-size:36px;line-height:1.7;letter-spacing:.1em;margin:24px 0 15px}.entry-inner p{color:#a28cb6;font-size:13px}.entry-inner small{margin-top:33px;color:#685873;font-size:11px}.entry-inner button{width:205px;margin-top:20px;padding:15px 20px;text-align:left;background:#a270df;color:#0d0716;border-color:#b889ee}.entry-inner button span{float:right}.entry-bottom{position:absolute;bottom:35px;font-size:11px;letter-spacing:.15em;color:#5f516b}.loading-line{width:165px;height:1px;background:#382447;position:relative;overflow:hidden;margin:16px}.loading-line:after{content:"";position:absolute;width:50px;height:1px;background:var(--purple);animation:load 1.5s infinite}#toast{position:fixed;top:95px;left:50%;transform:translateX(-50%);padding:12px 20px;background:#21152fe8;border:1px solid #b482ff40;border-radius:8px;opacity:0;pointer-events:none;font-size:13px;transition:opacity .3s;z-index:11}#toast.show{opacity:1}@keyframes breathe{50%{opacity:.4;transform:translateY(-4px)}}@keyframes load{from{left:-50px}to{left:165px}}@media(max-width:700px){header{top:22px;left:22px;right:22px}.brand{gap:10px}.brand span{display:none}.status{font-size:11px}.status button{margin-left:4px;padding:9px;font-size:11px}.intro{left:23px;top:104px}.intro h1{font-size:24px}.intro .eyebrow{font-size:9px}.intro p{font-size:11px}.coordinates{margin-top:15px;font-size:10px}.tools{right:15px}footer{bottom:22px;left:23px;right:23px}.foot-left{max-width:150px;gap:7px}.foot-left small{font-size:9px}#geo-note{font-size:9px}.scale small{display:none}.scale{margin-bottom:118px}.walk{left:auto;right:0;transform:none}.walk>span{display:none}.walk small{font-size:8px}.arrows button{width:35px;height:35px}.entry-inner h2{font-size:29px}#hint{bottom:210px;font-size:10px;max-width:80vw;white-space:normal;text-align:center;line-height:1.8}aside{right:22px;top:213px;width:210px;padding:18px}.foot-left>div{font-size:10px;gap:5px}}
@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important}}

.entry-inner h2{white-space:pre-line}

#world{cursor:crosshair;background:#08070d}#world.over-traveler{cursor:pointer}#world.dragging{cursor:grabbing}.arrows button.pressed{background:#8e54cd;color:#fff;border-color:#d4adff;box-shadow:0 0 20px #b482ff44}.tools button[aria-pressed=true]{color:#e1bdff;background:#b482ff19}#stop{font-size:11px;padding:6px 12px;pointer-events:auto}#motion{letter-spacing:.03em}.scale small{max-width:240px;text-align:right;line-height:1.6}@media(max-width:700px){.walk #motion{display:none}.scale{margin-bottom:160px}}
/* Relief edition: typography and a calm, continuous threshold into the world. */
body{background:#08070d}header,.intro,footer,.tools,#hint{transition:opacity .9s,transform .9s}body:not(.in-world)>header,body:not(.in-world)>.intro,body:not(.in-world)>footer,body:not(.in-world)>.tools,body:not(.in-world)>#hint{opacity:0;pointer-events:none;transform:translateY(14px)}body:not(.in-world)>header *,body:not(.in-world)>footer *{pointer-events:none}#world{transition:opacity .9s,transform .9s}body:not(.in-world) #world{opacity:.85;transform:scale(1.02)}#entry{background:linear-gradient(90deg,#08070df2 0%,#08070de0 28%,#08070d60 63%,#08070d33),linear-gradient(0deg,#08070d 0%,transparent 20%,transparent 80%,#08070dba);transition:opacity 1.05s,transform 1.05s}#entry.dismiss{opacity:0;transform:scale(1.04)}.entry-shell{width:100%;height:100%;padding:42px 6vw;display:flex;flex-direction:column;justify-content:space-between}.entry-heading{display:flex;justify-content:space-between;align-items:center}.entry-heading>span{font-size:11px;letter-spacing:.16em;color:#8c7c9f}.entry-inner{width:min(570px,90vw);align-items:flex-start;text-align:left;margin-left:4vw;padding:25px 0}.entry-inner>.eyebrow{color:#b69acb;font-size:10px;letter-spacing:.24em}.entry-mark{position:absolute;left:73%;top:42%;height:auto;gap:24px;transform:rotate(-12deg)}.entry-mark i{animation:relief-breathe 9s ease-in-out infinite;width:7px;height:7px;background:#b482ff80}.entry-mark i:nth-child(2){width:17px;height:17px;box-shadow:0 0 50px #b482ff88}.entry-inner h2{font-family:"Microsoft YaHei","Segoe UI",sans-serif;font-size:clamp(32px,3.4vw,54px);letter-spacing:.06em;line-height:1.55;font-weight:300;margin:29px 0 17px}.entry-inner .entry-copy{font-size:13px;line-height:2.2;color:#a498b1;letter-spacing:.08em;margin:0 0 31px}#entry-form{width:min(350px,100%)}#entry-form label{display:flex;justify-content:space-between;color:#c2b1d0;font-size:11px;margin-bottom:12px}#entry-form label span{font-size:9px;letter-spacing:.17em;color:#776284}#name{width:100%;font:inherit;color:#f0e4ff;background:#100b18ad;border:1px solid #b482ff40;border-radius:3px;padding:17px 15px;outline:none}#name::placeholder{font-size:12px;color:#776484}#name:focus{border-color:#bc89ec;box-shadow:0 0 0 3px #b482ff12}#enter{width:100%;margin-top:12px;border-radius:3px;padding:17px 18px;background:linear-gradient(115deg,#c1a1e8,#9e72ce);font-size:13px;letter-spacing:.1em;color:#170c23;box-shadow:0 4px 32px #a270df12}#enter:hover{background:linear-gradient(115deg,#d3b9f1,#b38bdf);transform:translateY(-1px)}#enter:disabled{opacity:.65;cursor:wait}#entry-status{font-size:11px;line-height:1.8;min-height:20px;max-width:350px;color:#a58cb8;margin:14px 0 0}.entry-inner small{font-size:10px;color:#766481;margin-top:15px}.entry-bottom{position:static;display:flex;justify-content:space-between;align-items:center;color:#867290;font-size:10px;letter-spacing:.08em}.entry-bottom a{color:#9d83b4;text-decoration:none}.loading-line{margin:12px 0 0;width:350px;max-width:100%}.entry-inner #cancel-entry{background:none;border:0;padding:5px 0;color:#b59dc7;width:auto;font-size:11px;margin:8px 0 0}.loading-line[hidden]+#cancel-entry{display:none}.identity{font-family:monospace;overflow-wrap:anywhere;font-size:10px;color:#927ca7;max-width:285px}aside .identity{display:block;margin:-12px 0 20px;line-height:1.7}aside h2{overflow-wrap:anywhere}#sound{font-size:11px;padding:9px 11px;margin-left:12px}.credits{max-width:720px;margin:10vh auto;padding:30px;line-height:1.9}.credits a{color:#cda5f4}body:has(.credits){overflow:auto}@keyframes relief-breathe{50%{transform:translateY(-8px);box-shadow:0 0 65px #b482ff55}}@media(max-width:700px){.entry-shell{padding:25px 24px}.entry-heading>span{font-size:9px}.entry-inner{margin-left:0;width:100%;padding:18px 0}.entry-inner h2{font-size:31px;margin:24px 0 15px}.entry-inner .entry-copy{font-size:12px;margin-bottom:23px}.entry-mark{left:auto;right:35px;top:22%;opacity:.5}.entry-bottom{font-size:8px;gap:15px}.entry-bottom>span:nth-child(2){display:none}.entry-inner small{font-size:9px}#entry-form{width:100%;max-width:360px}#identity{max-width:160px;font-size:8px}#sound{margin:0;padding:8px 6px}.status{gap:6px}.intro p{max-width:240px}.foot-left{gap:5px}}@media(max-height:740px){.entry-shell{padding-top:22px;padding-bottom:22px}.entry-inner h2{font-size:32px;margin:16px 0 10px}.entry-inner .entry-copy{margin-bottom:18px}.entry-inner{padding:10px 0}.entry-inner small{margin-top:8px}.entry-mark{top:36%}}@media(prefers-reduced-motion:reduce){#world,#entry,header,.intro,footer,.tools{transition:none}.entry-mark i{animation:none}}
@media(max-width:700px){footer{display:block}.foot-left{width:160px;max-width:160px}.foot-left>div{flex-wrap:wrap;row-gap:3px}.scale{position:absolute;right:0;bottom:155px;margin:0;max-width:120px}.scale i{max-width:120px}.entry-inner h2{font-size:clamp(25px,7.6vw,31px)}.walk{bottom:0}.status #online{max-width:78px;line-height:1.5}.coordinates{max-width:255px;flex-wrap:wrap}.foot-left #identity{line-height:1.6}}

/* App 外壳元素（.dock / .app-status）只在 public/mobile.css 的移动端媒体查询里有样式，
   桌面端必须留空，否则会露出裸文本。移动端 mobile.css 在本文件之后加载，同权重覆盖为 flex/block。 */
.dock,.app-status,.cam-pad,#rotate{display:none}

/* =============================================================================
   W11 · 车 B —— 页脚信息层重排（桌面档 ≥701px；手机档仍由 mobile.css 全权接管）
   -----------------------------------------------------------------------------
   爷爷真机反馈：「桌面右下角图例文字互相压着发糊」。王炸本体 1280×720 实测：
     · .foot-left 5 行 11px 密集小字（y 563.5 / 588.5 / 612.5 / 636.5 / 671.5）；
     · #identity 印完整 UUID 并折成 2 行（h=26）；
     · .scale small（240px 宽）折 2 行，第二行只剩「为旅人」3 字孤儿（h=35.2）；
     · 11px 前景 #766a83 / #6e627c 在 #08070d 上只有 3.98 / 3.54:1（AA 正文要 4.5:1）。
   几何上并没有互相覆盖 —— 是「行多 + 孤儿 + 对比度低」造成的糊。
   本段只做四件事：收行（5→3）/ 收短 UUID（app.js 文案）/ 消孤儿 / 提对比度；
   全部在 CSS + app.js 文本层完成，index.html 的页脚 DOM 一行未动。
   ========================================================================== */
:root{--foot-ink:#a998bb}
/* B-4：页脚 11px 正文统一到一个前景色，对 #08070d 用 WCAG 相对亮度公式算得 7.545:1
   （详见 work/verify/w11b-footer-static.mjs 的实算输出）；不再用 #766a83 / #6e627c 的 3.98 / 3.54。 */
.foot-left small,.scale small{color:var(--foot-ink)}
.foot-left #latency{color:var(--foot-ink)}
#geo-note{color:var(--foot-ink)}
.scale{color:var(--foot-ink)}
/* B-3：图例折行时按行均衡（text-wrap:balance）→ 不可能再出现 ≤3 字孤儿行；
   上限放宽到 300px 让整句一行落定（实测整句 267.2px），即便换字体被截到 300px 也只是两行均衡。 */
.scale small{max-width:300px;line-height:1.5;text-wrap:balance}

@media(min-width:701px){
  /* B-5：footer 容器收缩为零高 —— 沿用 mobile.css 第 08 段「footer 收缩为零尺寸容器」的同一做法。
     左右两块信息仍以 flex-end 贴着底边（视觉零变化），容器自身矩形退化成一条线，
     于是 footer / .foot-left / .scale 三者与 #dv-toolbar（桌面 y 654..698 / x 384.9..895.1）重叠 = 0.0%。 */
  body>footer{height:0}
  /* B-1：左上信息层 2 列 × 3 行（DOM 里 5 个子元素：连接行 / 步速 / 停留 / 身份 / 地理 = 5 → 3 行）。
     grid-column:1/-1 让「地理定位」整行铺满，前两行左列 = 连接·停留，右列 = 步速·身份。 */
  .foot-left{
    display:grid;
    grid-template-columns:auto auto;
    grid-auto-flow:row;
    grid-auto-rows:min-content;
    column-gap:20px;row-gap:6px;
    align-items:center;justify-content:start;
    max-width:341px;
  }
  /* 任意一行都不许折行：scrollHeight 永远 ≤ clientHeight + 1 */
  .foot-left>*{white-space:nowrap}
  .foot-left>div{line-height:15px}
  /* B-1/B-2：15px 行高 ⇒ 每行 15px 高，单行不折（#identity 也收成 15px 单行） */
  .foot-left small{font-size:11px;line-height:15px}
  .foot-left #identity{font-size:11px;line-height:15px;max-width:none;overflow-wrap:normal}
  #geo-note{grid-column:1/-1;max-width:none;line-height:15px}
}
/* ============================================================================
   14 沉浸模式（hud 模块 · W17）
   单一真源：body.dv-zen（见 public/modules/hud/index.js）。
   语义：把「周围所有文字与组件」折叠掉，只留世界本身 + 一枚退出胶囊 + 两个摇杆本体。
   选择器一律带 body.dv-zen 前缀（id 级 (1,1,0) 起），稳赢原来的单类 / 元素选择器：
   不靠书写顺序、不用 !important。
   ============================================================================ */
body.dv-zen .intro,
body.dv-zen .tools,
body.dv-zen header,
body.dv-zen footer,
body.dv-zen #hint,
body.dv-zen .app-status,
body.dv-zen #person,
body.dv-zen #dv-toolbar,
body.dv-zen #dv-bag-panel,
body.dv-zen #dv-war-panel,
body.dv-zen #dv-chat-layer,
body.dv-zen #dv-chat-composer,
body.dv-zen #dv-npc-layer,
body.dv-zen #dv-npc-bar,
body.dv-zen #dv-scan-layer,
body.dv-zen #dv-scan-alert,
body.dv-zen #dv-scan-toast,
body.dv-zen #dv-bag-toast,
body.dv-zen #toast,
body.dv-zen .dock-caption,
body.dv-zen .cam-label{
  visibility:hidden;pointer-events:none;
}

/* 14.1 入口：玩法下拉里的「沉浸模式」一行（hud 自建，随 #play-menu 一起被工具栏搬走） */
#dv-zen-toggle{
  display:flex;align-items:center;justify-content:center;gap:6px;
  width:100%;min-height:30px;margin-top:8px;padding:0 10px;
  border:1px solid #ffffff1f;border-radius:9px;
  background:#141020a6;color:#cfc4e6;
  font-size:12px;font-weight:500;letter-spacing:.05em;
}
#dv-zen-toggle:hover{background:#241a36;border-color:#b482ff80;color:#ecdcff}
#dv-zen-toggle[aria-pressed=true]{border-color:#b482ffa6;background:#2a1c3f;color:#f4ecff}

/* 14.2 出口：只有沉浸态才浮出来的小胶囊。放右上角 —— 沉浸时 #dv-toolbar / .tools 都已折叠，
   那里必然空着，不会和左下 .dock / 右下 .cam-pad 两个摇杆打架。 */
#dv-zen-exit{
  position:fixed;z-index:60;
  top:calc(env(safe-area-inset-top,0px) + 14px);right:calc(env(safe-area-inset-right,0px) + 16px);
  display:inline-flex;align-items:center;gap:7px;
  min-height:32px;padding:0 13px;border-radius:999px;
  border:1px solid #ffffff24;background:#0d0a14e6;color:#cfc4e6;
  font-size:12px;font-weight:500;letter-spacing:.06em;
  visibility:hidden;transform:translateY(-6px);pointer-events:none;
  transition:transform .26s cubic-bezier(.22,.61,.36,1);
}
#dv-zen-exit::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--purple);box-shadow:0 0 9px #b482ffcc}
body.in-world.dv-zen #dv-zen-exit{visibility:visible;transform:translateY(0);pointer-events:auto}
#dv-zen-exit:hover{border-color:#b482ff80;color:#ecdcff}

/* 回应的等待与距离反馈，在桌面卡片与手机底部抽屉共用。 */
#person #wave-label{float:none}
#person #wave>span{color:inherit}
#person #wave:disabled{cursor:default;transform:none;background:#21182e;color:#bdb0ca;border-color:#665079}
#person #wave-status{margin:10px 0 0;font-size:11px;line-height:1.6;min-height:1.6em;color:#a898bb}

#person-handle{display:none}

.entry-retry{display:inline-block;margin-top:10px;color:#c2a5df;font-size:12px;line-height:1.8;text-underline-offset:3px}
