Files
CyberGril/web/src/styles/components.css
T
白栖知andmultica-agent cef8ae5581 HEL-824: land verified fixes on 4321aeb (small-screen first-press, real-time reading clock)
- 6 modified + handoff JSON per CHANGES-HEL-824.json, all hashes verified against git 4321aeb and package bytes
- rework_browser_check: skip full-text sheet at micro height (<420px design hides the control); migrate stale 返回日子 selector to 结束交谈 · 回到日子
- fresh run evidence: web build 25/25 unit tests, backend 142/142 (py3.12), all four browser checks PASS incl. new compact first-press and 700ms slow-frame sections (slow_frames_new_turn_to_reply_s=2.32s), layout regression 320/390/1024/1600 both themes

Co-authored-by: multica-agent <github@multica.ai>
2026-10-24 07:39:26 +08:00

821 lines
74 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Approved HEL-746 R2 component styles; edit here, never add override sheets. */
*{box-sizing:border-box;margin:0;padding:0;scrollbar-width:thin;scrollbar-color:var(--scroll-thumb) var(--scroll-track)}
html{color-scheme:dark}
*::-webkit-scrollbar{width:8px;height:8px}
*::-webkit-scrollbar-track{background:var(--scroll-track);border-radius:8px}
*::-webkit-scrollbar-thumb{background:var(--scroll-thumb);border:2px solid var(--scroll-track);border-radius:8px}
@media(hover:hover) and (pointer:fine){*::-webkit-scrollbar-thumb:hover{background:var(--scroll-hover)}}
@media(forced-colors:active){*{scrollbar-color:auto}*::-webkit-scrollbar-thumb{background:ButtonText}*::-webkit-scrollbar-track{background:Canvas}}
html,body{height:100%;overflow:hidden;background:var(--bg-0);transition:background-color var(--dur-theme) var(--ease-in-out)}
body{font-family:var(--font-sans);color:var(--text-1);font-size:var(--fs-body);line-height:1.7;-webkit-font-smoothing:antialiased;letter-spacing:.01em}
button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer;background:none;border:0}
button:disabled{cursor:not-allowed;opacity:.42}
svg{display:block}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
.ico{width:18px;height:18px;flex:none}
/* ============================================================
背景空间(R1 原样)
============================================================ */
.space{position:fixed;inset:0;overflow:hidden;transition:transform var(--dur-stage) var(--ease-out),filter var(--dur-stage) var(--ease-out)}
.layer{position:absolute;inset:-6%;will-change:transform;transition:transform 1.2s var(--ease-out)}
.scene{position:absolute;inset:0;opacity:0;transition:opacity var(--dur-theme) var(--ease-in-out)}
html[data-theme="moon"] .scene.moon,html[data-theme="fog"] .scene.fog{opacity:1}
.scene.moon .sky{position:absolute;inset:0;background:radial-gradient(120% 80% at 24% 12%,#24386f 0%,rgba(36,56,111,0) 55%),linear-gradient(180deg,#081028 0%,#0e1a3e 46%,#16264f 72%,#0b1430 100%)}
.scene.fog .sky{position:absolute;inset:0;background:radial-gradient(90% 70% at 12% 92%,rgba(176,108,220,.55) 0%,rgba(176,108,220,0) 60%),radial-gradient(80% 60% at 92% 8%,rgba(92,92,210,.45) 0%,rgba(92,92,210,0) 60%),linear-gradient(170deg,#1a1240 0%,#2b1d5c 45%,#3e2b78 70%,#1c1338 100%)}
.moon-disc{position:absolute;left:17%;top:14%;width:78px;height:78px;border-radius:50%;filter:blur(.4px);background:radial-gradient(circle at 50% 50%,#ffffff 0%,#f4f8ff 50%,#e2ecff 64%,rgba(226,236,255,.5) 68%,rgba(226,236,255,0) 71%);box-shadow:0 0 60px 18px rgba(170,205,255,.28),0 0 220px 90px rgba(120,160,255,.18);animation:moonBreath 14s var(--ease-drift) infinite alternate;transition:opacity var(--dur-stage)}
.moon-halo{position:absolute;left:calc(17% - 276px);top:calc(14% - 276px);width:630px;height:630px;border-radius:50%;background:radial-gradient(circle,rgba(160,200,255,.20) 0%,rgba(160,200,255,.06) 40%,rgba(160,200,255,0) 70%);transition:opacity var(--dur-stage)}
@keyframes moonBreath{from{filter:blur(.4px) brightness(.9);transform:scale(1)}to{filter:blur(.4px) brightness(1.05);transform:scale(1.03)}}
.ribbon{position:absolute;border-radius:50%;filter:blur(48px);opacity:.5}
.ribbon.r1{left:-10%;top:18%;width:80%;height:22%;background:linear-gradient(90deg,rgba(150,110,255,0),rgba(190,140,255,.75),rgba(255,160,220,.0));transform:rotate(-8deg);animation:ribbon1 38s var(--ease-drift) infinite alternate}
.ribbon.r2{right:-14%;top:44%;width:70%;height:18%;background:linear-gradient(90deg,rgba(120,140,255,0),rgba(150,160,255,.65),rgba(230,170,255,0));transform:rotate(10deg);animation:ribbon2 46s var(--ease-drift) infinite alternate}
.ribbon.r3{left:20%;bottom:-6%;width:70%;height:30%;background:radial-gradient(closest-side,rgba(240,170,255,.55),rgba(240,170,255,0));animation:ribbon1 52s var(--ease-drift) infinite alternate-reverse}
@keyframes ribbon1{from{transform:translate3d(-4%,0,0) rotate(-8deg) scaleY(1)}to{transform:translate3d(6%,-3%,0) rotate(-3deg) scaleY(1.25)}}
@keyframes ribbon2{from{transform:translate3d(3%,0,0) rotate(10deg)}to{transform:translate3d(-7%,4%,0) rotate(4deg)}}
.skyline{position:absolute;left:0;right:0;bottom:0;height:46%}
.skyline svg{width:100%;height:100%}
.scene.moon .skyline.far{opacity:.34;filter:blur(2px)}
.scene.moon .skyline.near{opacity:.42;filter:blur(1px);height:30%}
.scene.fog .skyline.far{opacity:.22;filter:blur(3px)}
.scene.fog .skyline.near{opacity:.34;filter:blur(1.8px);height:32%}
.skyline .win{animation:winBlink 9s steps(1) infinite}
@keyframes winBlink{0%,100%{opacity:1}50%{opacity:.35}}
.mist{position:absolute;left:-30%;width:160%;border-radius:50%;filter:blur(40px)}
.scene.moon .mist{background:radial-gradient(closest-side,rgba(150,180,240,.22),rgba(150,180,240,0))}
.scene.fog .mist{background:radial-gradient(closest-side,rgba(205,170,255,.34),rgba(205,170,255,0))}
.mist.m1{bottom:2%;height:26%;animation:mistA 64s linear infinite alternate}
.mist.m2{bottom:18%;height:18%;animation:mistB 48s linear infinite alternate}
.mist.m3{bottom:-8%;height:30%;animation:mistA 80s linear infinite alternate-reverse}
.scene.fog .mist.m4{top:30%;height:40%;opacity:.7;animation:mistB 70s linear infinite alternate}
@keyframes mistA{from{transform:translate3d(-6%,0,0)}to{transform:translate3d(8%,-2%,0)}}
@keyframes mistB{from{transform:translate3d(6%,0,0)}to{transform:translate3d(-8%,2%,0)}}
#motes{position:absolute;inset:0;width:100%;height:100%}
.bokeh{position:absolute;border-radius:50%;filter:blur(22px)}
.scene.moon .bokeh{background:rgba(170,210,255,.13)}
.scene.fog .bokeh{background:rgba(240,190,255,.16)}
.bokeh.b1{left:3%;top:64%;width:180px;height:180px}
.bokeh.b2{right:4%;top:6%;width:120px;height:120px}
.bokeh.b3{left:44%;bottom:-4%;width:240px;height:240px;opacity:.7}
.vignette{position:absolute;inset:0;pointer-events:none;background:radial-gradient(120% 90% at 50% 45%,rgba(0,0,0,0) 55%,rgba(0,0,8,.55) 100%)}
.depth-veil{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity var(--dur-stage) var(--ease-out);background:radial-gradient(70% 70% at 50% 42%,rgba(0,0,0,0) 30%,rgba(2,4,16,.55) 100%)}
.window-glow{position:fixed;pointer-events:none;border-radius:50%;filter:blur(30px);background:radial-gradient(closest-side,var(--window-glow),rgba(0,0,0,0));transition:all var(--dur-stage) var(--ease-out),background var(--dur-theme)}
body.talk .space{transform:scale(1.06)}
body.talk .depth-veil{opacity:1}
body.talk .moon-disc,body.talk .moon-halo{opacity:.35}
/* 进入日子 / 设置:空间轻推近 1.03 并压暗,仍在同一主题空间里 */
body.paned .space{transform:scale(1.03)}
body.paned .depth-veil{opacity:.7}
body.creating .space{transform:scale(1.02);filter:saturate(.9)}
body.creating .depth-veil{opacity:.5}
/* ============================================================
通用组件
============================================================ */
.glass{background:var(--glass);border:1px solid var(--glass-line);-webkit-backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));backdrop-filter:blur(var(--glass-blur)) saturate(var(--glass-sat));box-shadow:inset 0 1px 0 var(--glass-hi),0 18px 50px -20px rgba(0,0,10,.55);transition:background-color var(--dur-theme) var(--ease-in-out),border-color var(--dur-theme) var(--ease-in-out),box-shadow var(--dur-ui)}
html[data-theme="fog"] .glass{box-shadow:inset 0 1px 0 var(--glass-hi),inset 0 0 36px rgba(210,170,255,.10),0 18px 50px -20px rgba(10,0,30,.55)}
.glass.read{background:var(--glass-read)}
.chip{display:inline-flex;align-items:center;gap:6px;height:32px;padding:0 14px;border-radius:var(--radius-pill);font-size:var(--fs-meta);color:var(--text-2);white-space:nowrap}
.chip svg{width:15px;height:15px;opacity:.85}
.tag-demo{display:inline-flex;align-items:center;height:22px;padding:0 9px;border-radius:var(--radius-pill);font-size:var(--fs-tiny);color:var(--text-3);border:1px dashed var(--glass-line);white-space:nowrap}
.tag{display:inline-flex;align-items:center;gap:5px;height:22px;padding:0 9px;border-radius:var(--radius-pill);font-size:var(--fs-tiny);color:var(--text-2);background:rgba(255,255,255,.06);white-space:nowrap}
.tag.accent{color:var(--accent);background:var(--accent-soft)}
.tag.ok{color:var(--ok);background:rgba(159,232,207,.1)}
.tag.warn{color:var(--warn);background:rgba(255,215,156,.1)}
.tag.danger{color:var(--danger);background:rgba(255,159,179,.1)}
.tag svg{width:12px;height:12px}
.btn-primary{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:10px;height:52px;padding:0 26px;border-radius:var(--radius-pill);background:var(--accent);color:var(--on-accent);font-weight:500;font-size:15.5px;letter-spacing:.04em;box-shadow:0 0 0 1px rgba(255,255,255,.25) inset,0 0 26px -2px var(--accent-glow),0 10px 30px -12px var(--accent-glow);transition:transform var(--dur-fast) var(--ease-out),box-shadow var(--dur-ui),background-color var(--dur-theme),opacity var(--dur-ui)}
.btn-primary:hover:not(:disabled){box-shadow:0 0 0 1px rgba(255,255,255,.3) inset,0 0 38px 2px var(--accent-glow),0 10px 30px -12px var(--accent-glow)}
.btn-primary:disabled{box-shadow:none}
.btn-primary svg{width:18px;height:18px}
.btn-primary.sm,.btn-ghost.sm,.btn-danger.sm{height:40px;padding:0 18px;font-size:14px}
.btn-ghost{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:48px;padding:0 22px;border-radius:var(--radius-pill);border:1px solid var(--glass-line);color:var(--text-1);font-size:14.5px;transition:background-color var(--dur-ui),transform var(--dur-fast) var(--ease-out)}
.btn-ghost:hover:not(:disabled){background:var(--accent-soft)}
.btn-ghost svg{width:16px;height:16px}
.btn-danger{display:inline-flex;align-items:center;justify-content:center;gap:8px;height:48px;padding:0 22px;border-radius:var(--radius-pill);border:1px solid var(--danger);color:var(--danger);font-size:14.5px;transition:background-color var(--dur-ui)}
.btn-danger:hover:not(:disabled){background:rgba(255,159,179,.1)}
.btn-text{display:inline-flex;align-items:center;gap:6px;color:var(--text-2);font-size:13.5px;padding:4px 2px}
.btn-text:hover{color:var(--text-1)}
.btn-text svg{width:14px;height:14px}
.btn-primary:active:not(:disabled),.btn-ghost:active:not(:disabled),.btn-round:active,.nav-item:active,.btn-danger:active{transform:scale(.97)}
.btn-round{width:52px;height:52px;border-radius:50%;display:grid;place-items:center;color:var(--text-1);flex:none;transition:transform var(--dur-fast) var(--ease-out),background-color var(--dur-ui),color var(--dur-ui)}
.btn-round svg{width:21px;height:21px}
.btn-round:hover{background:var(--accent-soft)}
.btn-round.sm{width:40px;height:40px}
.btn-round.sm svg{width:18px;height:18px}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.spin{width:16px;height:16px;border-radius:50%;border:2px solid currentColor;border-right-color:transparent;animation:spin .9s linear infinite;flex:none}
@keyframes spin{to{transform:rotate(360deg)}}
/* 表单 */
.field{display:block;margin:0 0 18px}
.field > span{display:block;font-size:13px;color:var(--text-2);margin-bottom:7px}
.field small{display:block;font-size:12px;color:var(--text-3);margin-top:6px;line-height:1.6}
.field.err small.msg{color:var(--danger)}
.input,.select,.textarea{width:100%;height:46px;border-radius:var(--radius-field);background:var(--field);border:1px solid var(--field-line);padding:0 14px;font-size:15px;color:var(--text-1);outline:none;transition:border-color var(--dur-ui),box-shadow var(--dur-ui),background-color var(--dur-theme)}
.textarea{height:auto;min-height:96px;padding:12px 14px;line-height:1.7;resize:vertical}
.select{appearance:none;background-image:linear-gradient(45deg,transparent 50%,var(--text-3) 50%),linear-gradient(135deg,var(--text-3) 50%,transparent 50%);background-position:calc(100% - 20px) 20px,calc(100% - 15px) 20px;background-size:5px 5px;background-repeat:no-repeat}
.select option{background:var(--bg-1);color:var(--text-1)}
.input:focus,.select:focus,.textarea:focus{border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-soft)}
.field.err .input,.field.err .select{border-color:var(--danger)}
.input[readonly]{color:var(--text-2);background:transparent;border-style:dashed}
.row2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.seg{display:inline-flex;padding:3px;border-radius:var(--radius-pill);gap:2px;background:var(--field);border:1px solid var(--field-line)}
.seg button{height:38px;padding:0 18px;border-radius:var(--radius-pill);font-size:14px;color:var(--text-2);transition:background-color var(--dur-ui),color var(--dur-ui)}
.seg button[aria-pressed="true"]{color:var(--on-accent);background:var(--accent);box-shadow:0 0 16px -4px var(--accent-glow)}
.check{display:flex;gap:10px;align-items:flex-start;font-size:14px;color:var(--text-2);cursor:pointer;line-height:1.6}
.check input{appearance:none;width:20px;height:20px;border-radius:6px;border:1.5px solid var(--glass-line);flex:none;margin-top:1px;display:grid;place-items:center;transition:background-color var(--dur-ui),border-color var(--dur-ui)}
.check input:checked{background:var(--accent);border-color:var(--accent)}
.check input:checked::after{content:"";width:9px;height:5px;border-left:2px solid var(--on-accent);border-bottom:2px solid var(--on-accent);transform:rotate(-45deg) translate(1px,-1px)}
.toggle{width:44px;height:26px;border-radius:13px;background:rgba(255,255,255,.12);position:relative;flex:none;transition:background-color var(--dur-ui)}
.toggle::after{content:"";position:absolute;left:3px;top:3px;width:20px;height:20px;border-radius:50%;background:#fff;transition:transform var(--dur-ui) var(--ease-out)}
.toggle[aria-pressed="true"]{background:var(--accent)}
.toggle[aria-pressed="true"]::after{transform:translateX(18px)}
.progress{height:6px;border-radius:3px;background:rgba(255,255,255,.08);overflow:hidden}
.progress i{display:block;height:100%;width:0;border-radius:3px;background:var(--accent);box-shadow:0 0 12px var(--accent-glow);transition:width 400ms var(--ease-out)}
/* 状态行(进行中 / 成功 / 失败) */
.status{display:none;align-items:center;gap:8px;font-size:13.5px;padding:10px 14px;border-radius:14px;margin:12px 0 0}
.status.show{display:flex}
.status.busy{color:var(--text-2);background:rgba(255,255,255,.04)}
.status.ok{color:var(--ok);background:rgba(159,232,207,.08)}
.status.fail{color:var(--danger);background:rgba(255,159,179,.08)}
.status svg{width:16px;height:16px;flex:none}
.status .grow{flex:1}
/* ============================================================
顶栏
============================================================ */
.topbar{position:fixed;top:calc(var(--view-top) + 22px);left:32px;right:32px;display:flex;align-items:center;justify-content:space-between;z-index:30;pointer-events:none;transition:opacity var(--dur-panel)}
.topbar > *{pointer-events:auto}
.who{display:flex;align-items:center;gap:12px}
.who .name{font-size:19px;font-weight:400;letter-spacing:.14em;max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.who .presence{font-size:var(--fs-meta);color:var(--text-2);letter-spacing:.04em;white-space:nowrap;text-shadow:0 1px 12px var(--pool)}
.end-talk{display:inline-flex;align-items:center;gap:7px;height:30px;padding:0 13px;border-radius:15px;background:var(--glass);border:1px solid var(--glass-line);color:var(--text-1);font-size:12px;white-space:nowrap;-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);transition:transform 160ms var(--ease-out);animation:chip-in 420ms var(--ease-out) 200ms both}
.end-talk:active{transform:scale(.97)}
.end-talk svg{width:14px;height:14px}
@keyframes chip-in{from{opacity:0;transform:translateY(-4px)}}
.dot{width:7px;height:7px;border-radius:50%;background:var(--accent);box-shadow:0 0 10px 2px var(--accent-glow);animation:dotPulse 3.6s var(--ease-drift) infinite}
body.offline .dot{background:var(--text-3);box-shadow:none;animation:none}
@keyframes dotPulse{0%,100%{opacity:.65}50%{opacity:1}}
.who .state{font-size:var(--fs-meta);color:var(--text-3)}
.env{display:flex;align-items:center;gap:10px}
.clock{font-family:var(--font-num);font-weight:300;font-size:22px;letter-spacing:.04em;color:var(--text-1);margin-left:4px}
.clock small{font-size:12px;color:var(--text-3);margin-left:6px;font-family:var(--font-sans)}
.theme-switch{display:flex;padding:3px;border-radius:var(--radius-pill);gap:2px}
.theme-switch button{height:28px;padding:0 12px;border-radius:var(--radius-pill);font-size:12.5px;color:var(--text-3);display:flex;align-items:center;gap:6px;transition:color var(--dur-ui),background-color var(--dur-ui)}
.theme-switch button i{width:9px;height:9px;border-radius:50%;display:block}
.theme-switch button[data-t="moon"] i{background:linear-gradient(135deg,#d9ecff,#5a7fd6)}
.theme-switch button[data-t="fog"] i{background:linear-gradient(135deg,#f3c8ff,#6c4fd0)}
.theme-switch button[aria-pressed="true"]{color:var(--text-1);background:var(--accent-soft);box-shadow:0 0 14px -4px var(--accent-glow)}
body.creating .topbar .who,body.creating .topbar .env > :not(.theme-switch){opacity:0;pointer-events:none}
/* 断线横幅 */
.netbar{position:fixed;left:50%;top:70px;transform:translate(-50%,-10px);z-index:48;display:flex;align-items:center;gap:10px;height:42px;padding:0 8px 0 16px;border-radius:var(--radius-pill);font-size:13.5px;color:var(--text-1);opacity:0;pointer-events:none;transition:opacity var(--dur-ui),transform var(--dur-ui) var(--ease-out)}
.netbar.show{opacity:1;transform:translate(-50%,0);pointer-events:auto}
.netbar .spin{color:var(--warn)}
.netbar .warn-dot{width:8px;height:8px;border-radius:50%;background:var(--danger);display:none}
.netbar.failed .spin{display:none}
.netbar.failed .warn-dot{display:block}
.netbar .btn-ghost{height:30px;padding:0 12px;font-size:12.5px;display:none}
.netbar.failed .btn-ghost{display:inline-flex}
.netbar small{color:var(--text-3);font-size:12px}
/* ============================================================
共同空间:一间房、一台镜头(HEL-799 对坐动态小样,获认可 01a16810)
远:她的房间与雨夜城市;中:她;近:你这一侧的桌沿、茶杯与烛灯。
两张参考静帧按她的脸对齐,镜头在两者之间推近/退回;人物不变形,也不是人物视频。
动效预算:界面反馈 160ms · 文字 420–680ms · 镜头弹簧约 0.85s · 环境循环 6–47s
============================================================ */
.room{position:fixed;inset:0;overflow:hidden;background:#04060f;z-index:0}
.room.failed{background:transparent}
.r-cam{position:absolute;inset:0;transition:transform 1.4s var(--ease-out)}
/* Each plate box covers its whole picture (so a mask never clips it to 1600×1000); .po is the 1600×1000 design origin. */
.plate{position:absolute;will-change:transform;contain:layout style}
.plate-room{left:-640px;top:-112px;width:2240px;height:1260px;transform-origin:640px 112px}
.plate-talk{left:-118px;top:-10px;width:1792px;height:1008px;transform-origin:118px 10px;visibility:hidden}
.plate-room .po{left:640px;top:112px}.plate-talk .po{left:118px;top:10px}
.po{position:absolute;width:1600px;height:1000px}
.plate .photo{position:absolute;max-width:none;user-select:none;-webkit-user-drag:none}
.plate-room .photo{left:-640px;top:-112px;width:2240px;height:1260px;filter:saturate(.9) brightness(.8) contrast(1.05)}
.plate-talk .photo{left:-118px;top:-10px;width:1792px;height:1008px;filter:saturate(.92) brightness(.9) contrast(1.04)}
.r-tint{position:absolute;inset:0;transition:opacity .9s var(--ease-in-out)}
.r-tint i,.po>i{position:absolute;pointer-events:none;display:block}
html[data-theme="moon"] .r-tint.fog,html[data-theme="fog"] .r-tint.moon{opacity:0}
/* Her side, close: the HEL-798 still, unchanged (stage px = plate px). */
.plate-talk .r-tint .night{inset:0;mix-blend-mode:multiply}
.plate-talk .r-tint .night::before{content:"";position:absolute;left:-118px;top:-10px;width:118px;bottom:0}
.plate-talk .r-tint .night2{inset:-10px 0 0;mix-blend-mode:color;-webkit-mask:linear-gradient(90deg,#000 0 40%,transparent 56%);mask:linear-gradient(90deg,#000 0 40%,transparent 56%)}
.plate-talk .r-tint .beam{left:120px;top:40px;width:560px;height:1040px;transform:skewX(18deg);filter:blur(30px);mix-blend-mode:screen}
.plate-talk .moon .night{background:linear-gradient(100deg,#1c2f7fcc 0%,#1b2c78aa 28%,#1a2a7044 46%,transparent 60%)}
.plate-talk .moon .night::before{background:#1c2f7fcc}
.plate-talk .moon .night2{background:linear-gradient(180deg,#24357ccc 0%,#24357c66 18%,transparent 34%)}
.plate-talk .moon .beam{background:linear-gradient(180deg,#a9c8ff22,#a9c8ff10 55%,transparent)}
.plate-talk .fog .night{background:linear-gradient(100deg,#3b2a7ccc 0%,#3a2874aa 28%,#38266a44 46%,transparent 60%)}
.plate-talk .fog .night::before{background:#3b2a7ccc}
.plate-talk .fog .night2{background:linear-gradient(180deg,#5a3a92cc 0%,#5a3a9266 18%,transparent 34%)}
.plate-talk .fog .beam{background:linear-gradient(180deg,#e6c4ff1c,#e6c4ff0c 55%,transparent);transform:skewX(-8deg)}
/* Her side, far: the room still turned to the same rainy night. Coordinates are plate px. */
.plate-room .r-tint{inset:auto;left:-640px;top:-112px;width:2240px;height:1260px}
.plate-room .r-tint .night{inset:0;mix-blend-mode:multiply}
.plate-room .r-tint .night2{inset:0;mix-blend-mode:color;-webkit-mask:radial-gradient(ellipse 150px 210px at 1915px 459px,transparent 70%,#000 100%),linear-gradient(180deg,#000 0 27%,transparent 40%);mask:radial-gradient(ellipse 150px 210px at 1915px 459px,transparent 70%,#000 100%),linear-gradient(180deg,#000 0 27%,transparent 40%);-webkit-mask-composite:source-in;mask-composite:intersect}
.plate-room .moon .night{background:radial-gradient(ellipse 330px 420px at 1930px 560px,#ffffff 0 30%,#ffffff00 100%),linear-gradient(97deg,#16225cf2 0%,#1a2768e0 30%,#1c2c74b0 50%,#2a3a8a70 62%,#ffffff00 80%),linear-gradient(180deg,#00000000 50%,#1a204c66 100%)}
.plate-room .moon .night2{background:linear-gradient(180deg,#24357ce6 0%,#24357ccc 22%,#24357c55 40%)}
.plate-room .fog .night{background:radial-gradient(ellipse 330px 420px at 1930px 560px,#ffffff 0 30%,#ffffff00 100%),linear-gradient(97deg,#2c1f5ef2 0%,#32246ae0 30%,#3a2a78b0 50%,#4a3a8a70 62%,#ffffff00 80%),linear-gradient(180deg,#00000000 50%,#2a1c4c66 100%)}
.plate-room .fog .night2{background:linear-gradient(180deg,#5a3a92e6 0%,#5a3a92cc 22%,#5a3a9255 40%)}
.plate canvas.r-rain{position:absolute;left:0;top:0;width:1600px;height:1000px;pointer-events:none}
/* Weather in the window: a slow cloud veil (moon) or folding violet mist (fog). Atmosphere, not a weather report. */
.r-mist{border-radius:50%;filter:blur(38px);mix-blend-mode:screen;opacity:0;transition:opacity 1.2s var(--ease-in-out);animation:r-mist 34s var(--ease-in-out) infinite alternate}
.r-mist.m2{animation-duration:47s;animation-delay:-20s}
.plate-talk .r-mist{left:-60px;top:120px;width:560px;height:120px}.plate-talk .r-mist.m2{top:250px;left:120px;width:460px}
.plate-room .r-mist{left:660px;top:20px;width:420px;height:90px}.plate-room .r-mist.m2{top:120px;left:760px;width:360px}
html[data-theme="moon"] .r-mist{background:#b9c8ff;opacity:.07}
html[data-theme="fog"] .r-mist{background:linear-gradient(90deg,#c69cff,#ff9fd8 60%,#9cc0ff);opacity:.32}
@keyframes r-mist{from{transform:translateX(-60px) scaleY(.8)}to{transform:translateX(90px) scaleY(1.25)}}
.spill{inset:0;mix-blend-mode:screen;animation:breathe-light 9s var(--ease-in-out) infinite alternate}
.plate-talk .spill{background:radial-gradient(ellipse 520px 380px at 1290px 40px,#ffcf8a30,transparent 70%),radial-gradient(ellipse 760px 260px at 1180px 900px,#ffb97a2a,transparent 70%)}
.plate-room .spill{background:radial-gradient(ellipse 360px 300px at 1420px 150px,#ffcf8a38,transparent 70%),radial-gradient(ellipse 600px 240px at 1250px 760px,#ffb97a22,transparent 70%)}
html[data-theme="fog"] .spill{filter:hue-rotate(-28deg) saturate(1.1)}
@keyframes breathe-light{from{opacity:.75}to{opacity:1}}
.flame-glow{width:90px;height:90px;margin:-45px 0 0 -45px;border-radius:50%;background:radial-gradient(circle,#ffd9a0aa,#ffb46a44 35%,transparent 70%);mix-blend-mode:screen;animation:flicker 3.2s steps(1,end) infinite,flame 2.4s var(--ease-in-out) infinite alternate}
.flame-glow+.flame-glow{animation-delay:-1.1s,-.7s}
@keyframes flicker{0%,100%{opacity:.9}17%{opacity:.72}18%{opacity:.95}46%{opacity:.8}47%{opacity:1}79%{opacity:.78}}
@keyframes flame{to{transform:scale(1.12) translateY(-3px)}}
.mote{left:var(--x);top:var(--y);width:4px;height:4px;border-radius:50%;background:#ffe2b8;box-shadow:0 0 8px 2px #ffd59a88;opacity:0;animation:mote var(--d) linear var(--dl) infinite}
@keyframes mote{0%{transform:translate(0,0);opacity:0}15%{opacity:.7}80%{opacity:.5}100%{transform:translate(-40px,-160px);opacity:0}}
.r-moon{position:absolute;left:0;top:0;width:44px;height:44px;margin:-22px 0 0 -22px;border-radius:50%;background:radial-gradient(circle at 42% 40%,#fbfdff 0%,#e4ecff 55%,#c9d6f5 100%);filter:blur(.6px);box-shadow:0 0 22px 6px #cfe0ff88,0 0 90px 40px #8fb0ff33,0 0 220px 120px #5f7fe022;transform-origin:50% 50%;will-change:transform;transition:opacity 1s var(--ease-in-out)}
html[data-theme="fog"] .r-moon{opacity:0}
.r-vignette{position:absolute;inset:0;pointer-events:none;background:radial-gradient(ellipse 62% 74% at 54% 42%,transparent 52%,#050918aa 100%),linear-gradient(180deg,#050918aa 0%,transparent 13%)}
html[data-theme="fog"] .r-vignette{background:radial-gradient(ellipse 62% 74% at 54% 42%,transparent 52%,#0e0820aa 100%),linear-gradient(180deg,#0e0820aa 0%,transparent 13%)}
/* Your side: the table edge, a cup and a small candle. Drawn for the viewport, never stretched. */
.r-near{position:absolute;inset:0;pointer-events:none;--near-y:0px;transform:translate3d(0,var(--near-y),0);transition:transform var(--dur-space) var(--ease-space),translate 1.4s var(--ease-out),opacity var(--dur-space) var(--ease-out)}
.near-c{position:absolute;inset:0;width:100%;height:100%;transition:opacity .9s var(--ease-in-out)}
html[data-theme="moon"] .near-c[data-theme-layer="fog"],html[data-theme="fog"] .near-c[data-theme-layer="moon"]{opacity:0}
.steam{position:absolute;left:var(--steam-x);top:var(--steam-y);width:calc(var(--u) * 40px);height:calc(var(--u) * 170px);margin-left:calc(var(--u) * -20px);border-radius:50%;background:radial-gradient(ellipse at 50% 80%,#d2e1ff33,transparent 70%);filter:blur(calc(var(--u) * 9px));transform-origin:50% 100%;animation:steam 7s var(--ease-in-out) infinite}
.steam.s2{margin-left:calc(var(--u) * 14px);animation-duration:9s;animation-delay:-4s}
@keyframes steam{0%{transform:translateY(20%) scaleX(.7) skewX(0);opacity:0}30%{opacity:.9}70%{opacity:.5}100%{transform:translateY(-30%) scaleX(1.3) skewX(-14deg);opacity:0}}
.candle{position:absolute;left:var(--candle-x);top:var(--candle-y);width:calc(var(--u) * 380px);height:calc(var(--u) * 380px);margin:calc(var(--u) * -190px) 0 0 calc(var(--u) * -190px);border-radius:50%;background:radial-gradient(circle,#ffdca0cc 0,#ffbe7866 12%,#ffaa6420 40%,transparent 70%);mix-blend-mode:screen;animation:flicker 2.8s steps(1,end) infinite,flame 2s var(--ease-in-out) infinite alternate}
.r-veil{position:absolute;inset:0;background:radial-gradient(ellipse at 50% 40%,#02061433,#020614cc 90%);opacity:0;pointer-events:none;transition:opacity var(--dur-space) var(--ease-out)}
html[data-mode="pane"] .r-veil{opacity:.75}html[data-mode="record"] .r-veil{opacity:.35}
html[data-mode="home"] .r-near{--near-y:3.5vh}
html[data-mode="pane"] .r-near,html[data-mode="record"] .r-near{--near-y:7vh;opacity:.7}
/* Tap target over her, only while you are across the room. */
.her-hit{position:fixed;z-index:5;left:0;top:0;width:10px;height:10px;border-radius:40% 40% 30% 30%;display:flex;align-items:flex-start;justify-content:center}
.her-hit span{margin-top:-34px;padding:5px 12px;border-radius:14px;font-size:12px;background:var(--glass);border:1px solid var(--glass-line);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);opacity:0;transform:translateY(4px);transition:opacity var(--dur-ui) var(--ease-out),transform var(--dur-ui) var(--ease-out);pointer-events:none;white-space:nowrap}
.her-hit:focus-visible span{opacity:1;transform:none}
html:not([data-mode="home"]) .her-hit{visibility:hidden}
.room-labels{position:fixed;z-index:6;left:32px;top:calc(var(--view-top) + 72px);display:flex;flex-direction:column;align-items:flex-start;gap:8px;pointer-events:none}
.room-labels .chip{color:var(--text-1)}
.observe{display:none;max-width:min(420px,60vw);white-space:normal;height:auto !important;min-height:32px;padding:6px 14px !important;line-height:1.5}
.observe.show{display:inline-flex}
.ref-note{position:fixed;z-index:6;right:40px;bottom:calc(var(--view-bottom) + 14px + var(--safe-bottom));font-size:11px;color:var(--text-3);opacity:.8;letter-spacing:.04em;pointer-events:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:calc(50vw - 200px);text-shadow:0 1px 8px var(--pool)}
html[data-mode="pane"] .ref-note{opacity:0}
/* ============================================================
首页
============================================================ */
.home{position:fixed;left:6.5vw;top:50%;width:min(420px,32vw);transform:translateY(-44%);z-index:12;text-shadow:0 2px 18px var(--pool);animation:home-in 520ms var(--ease-out) 200ms both}
/* Back across the room: the words come back after the camera has started to retreat. */
@keyframes home-in{from{opacity:0;transform:translate(-24px,-44%);filter:blur(6px)}}
.home .letter,.home .btn-primary,.home .btn-round{text-shadow:none}
.home .eyebrow{font-size:var(--fs-meta);color:var(--text-3);letter-spacing:.2em;margin-bottom:14px}
.home .whisper{font-size:var(--fs-whisper);font-weight:300;line-height:1.5;letter-spacing:.04em;color:var(--text-1);text-wrap:balance}
.home .meta{margin-top:14px;color:var(--text-2);font-size:14px;display:flex;flex-wrap:wrap;gap:8px 14px;align-items:center}
.home .meta span{display:inline-flex;align-items:center;gap:6px}
.letter{margin-top:34px;padding:18px 20px 16px;border-radius:var(--radius-card);display:block;width:100%;text-align:left;transition:transform var(--dur-ui) var(--ease-out),background-color var(--dur-theme),border-color var(--dur-theme)}
.letter:hover{transform:translateY(-2px)}
.letter .lh{display:flex;align-items:center;justify-content:space-between;font-size:var(--fs-meta);color:var(--text-3);margin-bottom:6px}
.letter .lh b{font-weight:500;color:var(--accent);display:inline-flex;align-items:center;gap:6px}
.letter .lh b::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px var(--accent-glow)}
.letter.read .lh b{color:var(--text-2)}
.letter.read .lh b::before{background:var(--text-3);box-shadow:none}
.letter p{color:var(--text-1);font-size:15px;line-height:1.75;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.away{margin-top:12px;display:flex;align-items:center;gap:8px;font-size:13.5px;color:var(--text-2);padding:2px 4px;text-align:left}
.away svg{width:14px;height:14px}
.away:hover{color:var(--text-1)}
.cta{margin-top:30px;display:flex;align-items:center;gap:12px}
.cta .btn-round{border:1px solid var(--glass-line)}
.first-note{margin-top:22px;font-size:13.5px;color:var(--text-2);line-height:1.8;display:none}
body.data-empty .letter,body.data-empty .away,body.data-empty .home .meta{display:none}
body.data-empty .first-note{display:block}
/* 返回时的「你不在的这两天」 */
.welcome{position:fixed;left:9vw;top:50%;width:min(460px,36vw);transform:translate(-20px,-50%);z-index:22;border-radius:26px;padding:26px 26px 22px;opacity:0;pointer-events:none;transition:opacity var(--dur-panel) var(--ease-out),transform var(--dur-panel) var(--ease-out)}
body.welcoming .welcome{opacity:1;transform:translate(0,-50%);pointer-events:auto}
body.welcoming .home{opacity:0;pointer-events:none;filter:blur(4px)}
.welcome .eyebrow{font-size:12.5px;color:var(--text-3);letter-spacing:.18em}
.welcome h2{font-size:24px;font-weight:300;letter-spacing:.04em;margin:8px 0 4px}
.welcome .sub{font-size:13.5px;color:var(--text-2)}
.welcome ul{list-style:none;margin:16px 0 4px}
.welcome li{display:grid;grid-template-columns:76px 1fr;gap:10px;padding:10px 0;border-top:1px solid rgba(255,255,255,.06);font-size:14.5px}
.welcome li time{color:var(--text-3);font-size:12.5px;font-family:var(--font-num)}
.welcome li small{display:block;color:var(--text-3);font-size:12px}
.welcome .note{font-size:12px;color:var(--text-3);margin:10px 0 16px;line-height:1.6}
.welcome .acts{display:flex;gap:10px;flex-wrap:wrap}
/* 主动消息(首页 / 区域页 中的轻提醒) */
.reach{position:fixed;z-index:24;right:6vw;bottom:calc(var(--view-bottom) + 120px + var(--safe-bottom));width:min(340px,80vw);border-radius:20px 20px 6px 20px;padding:14px 16px 12px;opacity:0;transform:translateY(10px) scale(.98);pointer-events:none;transition:opacity 240ms var(--ease-out),transform 240ms var(--ease-out)}
body.paned .reach{right:28px;bottom:calc(var(--view-bottom) + 72px + var(--safe-bottom));border-radius:20px}
.reach.show{opacity:1;transform:none;pointer-events:auto}
.reach .rh{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--text-3)}
.reach .rh b{font-weight:500;color:var(--accent)}
.reach p{font-size:14.5px;line-height:1.7;margin:6px 0 6px}
.reach .basis{font-size:11.5px;color:var(--text-3);display:flex;align-items:center;gap:6px}
.reach .basis svg{width:12px;height:12px}
.reach .acts{display:flex;gap:8px;margin-top:10px}
.reach .acts .btn-primary{height:36px;padding:0 16px;font-size:13.5px}
.reach .acts .btn-ghost{height:36px;padding:0 14px;font-size:13px}
/* ============================================================
交流:话落在你这一侧的桌面,在她的目光下方(HEL-799 / HEL-793 阅读方式)
当前一两句;长回复自动续读,可暂停、前后回看、回到读到的地方、看全文与完整记录
============================================================ */
.conversation{position:fixed;z-index:14;left:50%;bottom:calc(var(--view-bottom) + var(--nav-space) + var(--safe-bottom));width:min(940px,88vw);transform:translateX(-50%);display:flex;flex-direction:column;align-items:center;transition:opacity 220ms var(--ease-out);animation:talk-in 620ms var(--ease-out) 300ms both}
@keyframes talk-in{from{opacity:0;transform:translate(-50%,14px)}}
/* While a reading sheet is open she stays across the table; the table words step aside (the sheet has them all). */
html[data-mode="record"] .conversation{opacity:0;pointer-events:none}
.stage{position:relative;width:100%;height:var(--stage-h);display:flex;flex-direction:column;justify-content:flex-end;align-items:center;gap:6px;text-align:center}
.stage::before{content:"";position:absolute;left:4%;right:4%;top:0;bottom:-40%;background:radial-gradient(ellipse 50% 55% at 50% 64%,color-mix(in srgb,var(--pool) 62%,transparent),transparent 100%);pointer-events:none;z-index:-1}
.line{width:100%;display:flex;flex-direction:column;align-items:center;gap:3px}
.line .by{display:inline-flex;align-items:center;gap:7px;font-size:12px;letter-spacing:.08em;color:var(--text-2);max-width:100%}
.line .by b{font-weight:400;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:16em}
/* Identity never rests on position or colour alone: her name with a lit dot, "你" with an open ring. */
.line .by i{width:7px;height:7px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px var(--accent);flex:none}
.line[data-role="user"] .by i{background:transparent;box-shadow:none;border:1px solid var(--user)}
.line .state{font-style:normal;color:var(--text-3);font-size:11px;letter-spacing:0}
.line p{font-size:23px;font-weight:350;line-height:1.5;letter-spacing:.02em;max-width:900px;overflow-wrap:anywhere;text-shadow:0 2px 18px var(--pool),0 0 2px color-mix(in srgb,var(--pool) 60%,transparent);color:var(--text-1)}
.line[data-role="user"] p{color:var(--user);font-size:20px;font-weight:300}
/* Previous line: tag and words on one row, quiet (HEL-798). Fixed size; the hand-off is a crossfade of two copies. */
.line.is-prev{flex-direction:row;justify-content:center;gap:10px;opacity:.6;margin-bottom:4px}
.line.is-prev p{font-size:15px;font-weight:300;color:var(--user);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:min(680px,72vw)}
.line.is-prev[data-role="companion"] p{color:var(--text-2)}
.ink span{display:inline;animation:ink 460ms var(--ease-out) both;animation-delay:calc(var(--i) * 14ms)}
@keyframes ink{from{opacity:0;filter:blur(3px)}}
.line.waiting .state::after{content:"";display:inline-block;width:18px;height:6px;margin-left:5px;background:radial-gradient(circle,var(--accent) 1.5px,transparent 2px) 0 50%/6px 6px repeat-x;animation:r-dots 1.4s linear infinite;vertical-align:middle;opacity:.8}
@keyframes r-dots{50%{opacity:.25}}
.talk-status{display:flex;align-items:center;justify-content:center;gap:10px;min-height:20px;margin-top:4px;font-size:12px;color:var(--text-2);text-shadow:0 1px 10px var(--pool);text-align:center}
.talk-status .retry{color:var(--accent);text-decoration:underline;text-underline-offset:3px}
.reader-bar{display:flex;align-items:center;justify-content:center;gap:4px;height:30px;margin:4px 0 6px;font-size:12px;color:var(--text-3)}
.reader-bar>button{height:28px;padding:0 9px;border-radius:14px;white-space:nowrap;display:inline-flex;align-items:center;gap:5px;color:var(--text-2);transition:background-color 160ms var(--ease-out),color 160ms var(--ease-out),transform 160ms var(--ease-out)}
.reader-bar>button:active:not(:disabled){transform:scale(.97)}
.reader-bar .icon{width:28px;padding:0;justify-content:center}.reader-bar svg{width:14px;height:14px}
.reader-bar .count{position:relative;min-width:72px;height:28px;display:inline-flex;align-items:center;justify-content:center;font-variant-numeric:tabular-nums;font-size:11px;color:var(--text-3)}
/* The dwell meter lives under the count: one quiet line, as in the approved still. */
.reader-bar .count::after{content:"";position:absolute;left:0;right:0;bottom:3px;height:2px;border-radius:1px;background:#ffffff1c}
.reader-bar .count i{position:absolute;left:0;right:0;bottom:3px;height:2px;border-radius:1px;background:var(--accent);box-shadow:0 0 6px var(--accent);transform-origin:left;transform:scaleX(0);z-index:1}
.reading-paused .reader-bar .count i{opacity:.3}.reading-held .reader-bar .count i{opacity:.5}
.reader-bar .flow[aria-pressed="false"]{color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent-glow)}
.reader-bar .stop{color:var(--accent)}
.reader-bar .latest{color:var(--on-accent);background:var(--accent);box-shadow:0 0 16px var(--accent-glow)}
.single-page .reader-bar .icon,.single-page .reader-bar .count span{visibility:hidden}
.composer{width:min(640px,100%);min-height:50px;border-radius:25px;display:flex;align-items:center;gap:6px;padding:0 6px 0 8px;background:linear-gradient(90deg,var(--input-a),var(--input-b) 70%,var(--input-c));border:1px solid var(--glass-line);-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);box-shadow:0 10px 40px #02051466,inset 0 1px 0 #ffffff12;transition:border-color var(--dur-ui) var(--ease-out),box-shadow var(--dur-ui) var(--ease-out)}
.composer .round{width:38px;height:38px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;flex:none;color:var(--text-2);transition:transform 160ms var(--ease-out),color 160ms var(--ease-out),background-color 160ms var(--ease-out)}
.composer .round:active:not(:disabled),.composer .voice-button:active:not(:disabled){transform:scale(.97)}
.composer .round svg,.composer .voice-button svg{width:18px;height:18px}
.composer textarea{flex:1;min-width:0;resize:none;height:38px;max-height:88px;border:0;background:transparent;line-height:1.6;padding:8px 4px;outline:none;color:var(--text-1);font-size:15px}
.composer textarea::placeholder{color:var(--text-3)}
.composer:focus-within{border-color:var(--accent-glow);box-shadow:0 0 0 1px var(--accent-soft),0 0 30px var(--accent-soft)}
.composer .send:not(:disabled){color:var(--accent)}
.composer .cam.on,.composer .log-btn.on{color:var(--accent);background:var(--accent-soft)}
body.offline .composer .send{opacity:.4;pointer-events:none}
.voice-button{width:38px;height:38px;border-radius:50%;display:grid;place-items:center;background:var(--accent);color:var(--on-accent);box-shadow:0 0 18px var(--accent-glow);flex:none;transition:transform 160ms var(--ease-out),background-color var(--dur-theme)}
.voice-button.denied{background:rgba(255,255,255,.08);color:var(--text-3);box-shadow:none}
.voice-row{display:flex;align-items:center;justify-content:center;gap:12px;font-size:12px;color:var(--text-2);margin-bottom:6px;text-shadow:0 1px 10px var(--pool)}.voice-row button{color:var(--accent);padding:4px 2px}
.voice-wave{display:inline-flex;gap:3px;align-items:center;height:14px}.voice-wave i{width:2px;height:100%;background:var(--accent);border-radius:2px;animation:r-wave 1.1s var(--ease-in-out) infinite}.voice-wave i:nth-child(2){animation-delay:.15s}.voice-wave i:nth-child(3){animation-delay:.3s}.voice-wave i:nth-child(4){animation-delay:.45s}
@keyframes r-wave{50%{transform:scaleY(.3)}}
/* 完整记录与全文:房间里的阅读面,她仍在桌对面;不是模态框,导航始终可以直接切换 */
.record{position:fixed;z-index:20;top:calc(var(--view-top) + 84px);left:4vw;width:min(470px,36vw);height:calc(var(--view-h) - 150px - var(--safe-bottom));border-radius:26px;display:flex;flex-direction:column;overflow:hidden;box-shadow:0 25px 100px #02041270,inset 0 1px 0 #ffffff10;animation:sheet-in 240ms var(--ease-out)}
.record.full{z-index:21}
@keyframes sheet-in{from{opacity:0;transform:translateY(12px) scale(.985)}}
.record header{display:flex;justify-content:space-between;align-items:center;gap:20px;padding:20px 22px 14px 26px;border-bottom:1px solid var(--glass-line);flex:none}
.record header .eyebrow{font-size:11px;letter-spacing:.18em;color:var(--text-3);margin-bottom:3px}
.record header h2{font-size:20px;font-weight:350;letter-spacing:.04em}
.record .scroll{flex:1;min-height:0;overflow:auto;overscroll-behavior:contain;padding:18px 26px 32px;scrollbar-gutter:stable;line-height:1.9}
.record .guide{font-size:13px;color:var(--text-2);margin-bottom:8px}
.record .message{padding:14px 0;border-bottom:1px solid var(--glass-line);scroll-margin:80px}
.record .message .author{display:flex;align-items:center;gap:7px;color:var(--accent);font-size:12px;margin-bottom:6px;overflow-wrap:anywhere}
.record .message .author i{width:7px;height:7px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px var(--accent);flex:none}
.record .message[data-role="user"] .author{color:var(--text-2)}.record .message[data-role="user"] .author i{background:none;box-shadow:none;border:1px solid var(--user)}
.record .message p{font-size:15px;white-space:pre-wrap;overflow-wrap:anywhere}
.record .message .incomplete{display:block;font-size:12px;color:var(--warn)}
.record .message .tagm{font-size:10.5px;color:var(--accent);margin-left:6px}
.record .message.fail p{color:var(--text-2)}
.record .message.hl{box-shadow:inset 3px 0 0 var(--accent);padding-left:12px}
/* ============================================================
底部导航:小巧、透光,选中处亮起微光(HEL-799)
============================================================ */
.nav{position:fixed;left:50%;bottom:calc(var(--view-bottom) + 6px + var(--safe-bottom));transform:translateX(-50%);display:flex;gap:4px;padding:3px;border-radius:17px;z-index:25;background:color-mix(in srgb,var(--surface) 40%,transparent);transition:transform 420ms var(--ease-out),opacity 280ms var(--ease-out)}
body.creating .nav{opacity:0;pointer-events:none;transform:translate(-50%,20px)}
.nav-item{position:relative;width:64px;height:26px;border-radius:13px;display:inline-flex;align-items:center;justify-content:center;gap:6px;font-size:12px;letter-spacing:.04em;color:var(--text-3);transition:color 160ms var(--ease-out),background-color 160ms var(--ease-out),box-shadow 160ms var(--ease-out),transform 160ms var(--ease-out)}
.nav-item svg{width:14px;height:14px}
.nav-item[aria-current="page"]{color:var(--text-1);background:var(--accent-soft);box-shadow:0 0 14px var(--accent-glow)}
.nav-item[aria-current="page"] svg{color:var(--accent)}
.nav-item .badge{position:absolute;top:3px;right:8px;width:6px;height:6px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px var(--accent-glow);display:none}
.nav-item.unread .badge{display:block}
@media(hover:hover) and (pointer:fine){.nav-item:hover:not([aria-current="page"]),.reader-bar>button:hover:not(:disabled){background:#ffffff0d;color:var(--text-1)}.her-hit{cursor:pointer}.her-hit:hover span{opacity:1;transform:none}}
/* ============================================================
区域面板:日子 / 设置(同一主题空间里升起的阅读面)
============================================================ */
.pane{position:fixed;z-index:16;left:var(--pane-l);top:calc(var(--view-top) + var(--pane-t));bottom:calc(var(--view-bottom) + var(--pane-b) + var(--safe-bottom));width:var(--pane-w);border-radius:28px;display:flex;flex-direction:column;overflow:hidden;opacity:0;pointer-events:none;transition:background-color var(--dur-theme)}
/* Ordinary panels switch quickly; only the room itself keeps the slow spatial move. */
.pane.open{opacity:1;pointer-events:auto;animation:pane-in 240ms var(--ease-out)}
@keyframes pane-in{from{opacity:0;transform:translateY(12px) scale(.99)}}
.pane > header{display:flex;align-items:center;gap:16px;padding:18px 18px 14px 28px;border-bottom:1px solid rgba(255,255,255,.06);flex:none}
.pane > header h2{font-size:var(--fs-title);font-weight:400;letter-spacing:.1em;white-space:nowrap}
.pane > header .grow{flex:1}
.pane > header .tabs{margin-left:8px}
.pane .presence{display:none;align-items:center;gap:8px;font-size:12.5px;color:var(--text-3)}
.pane .presence i{width:6px;height:6px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px var(--accent-glow)}
.tabs{display:inline-flex;padding:3px;border-radius:var(--radius-pill);gap:2px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.06)}
.tabs button{height:34px;padding:0 16px;border-radius:var(--radius-pill);font-size:13.5px;color:var(--text-2);letter-spacing:.06em;transition:background-color var(--dur-ui),color var(--dur-ui)}
.tabs button[aria-selected="true"]{color:var(--text-1);background:var(--accent-soft);box-shadow:0 0 14px -6px var(--accent-glow)}
.pane .cols{flex:1;display:grid;grid-template-columns:400px 1fr;min-height:0;position:relative}
.pane .list{overflow:auto;padding:14px 18px 28px 22px;border-right:1px solid rgba(255,255,255,.06);scrollbar-width:thin;overscroll-behavior:contain}
.pane .detail{overflow:auto;padding:26px 34px 34px;scrollbar-width:thin;overscroll-behavior:contain;position:relative}
.pane .back{display:none}
/* 生活时间线 */
.legend{display:flex;flex-wrap:wrap;gap:6px 14px;font-size:12px;color:var(--text-3);margin:4px 0 10px}
.legend span{display:inline-flex;align-items:center;gap:6px}
.k{width:9px;height:9px;border-radius:50%;flex:none;display:inline-block}
.k.done{background:var(--text-2)}
.k.now{background:var(--accent);box-shadow:0 0 10px var(--accent-glow);animation:dotPulse 2.4s infinite}
.k.plan{border:1.5px dashed var(--text-2);background:transparent}
.grp{font-size:12px;color:var(--text-3);letter-spacing:.14em;margin:18px 4px 6px;display:flex;justify-content:space-between}
.ev{display:grid;grid-template-columns:52px 14px 1fr;gap:8px;align-items:start;width:100%;text-align:left;padding:10px 10px;border-radius:14px;font-size:14.5px;line-height:1.6;transition:background-color var(--dur-ui)}
.ev:hover{background:rgba(255,255,255,.04)}
.ev[aria-current="true"]{background:var(--accent-soft)}
.ev time{font-family:var(--font-num);font-size:12.5px;color:var(--text-3);padding-top:2px}
.ev .k{margin-top:7px}
.ev .tt{display:block}
.ev .sub{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px}
.ev.told .tt{color:var(--text-2)}
.ev.plan .tt{color:var(--text-2);font-style:normal}
.ev.now .tt{color:var(--text-1)}
.away-card{border-radius:18px;padding:14px 16px;background:var(--accent-soft);margin:6px 0 4px;font-size:13.5px;color:var(--text-2);line-height:1.7;transition:box-shadow var(--dur-panel)}
.away-card b{display:block;font-weight:500;color:var(--text-1);font-size:14.5px;margin-bottom:2px}
.away-card.flash{box-shadow:0 0 0 2px var(--accent),0 0 24px -4px var(--accent-glow)}
.more{display:flex;justify-content:center;margin:16px 0 4px}
.empty{padding:40px 12px;text-align:center;color:var(--text-2);font-size:14.5px;line-height:1.8}
.empty .glyph{width:54px;height:54px;margin:0 auto 14px;border-radius:50%;border:1px dashed var(--glass-line);display:grid;place-items:center;color:var(--accent)}
.empty .glyph svg{width:22px;height:22px}
.empty small{display:block;color:var(--text-3);font-size:12.5px;margin-top:6px}
/* 详情 */
.d-empty{height:100%;display:grid;place-items:center;text-align:center;color:var(--text-3);font-size:14px}
.d-empty .glyph{width:64px;height:64px;margin:0 auto 12px;border-radius:50%;background:radial-gradient(circle,var(--accent-soft),transparent 70%);display:grid;place-items:center;color:var(--accent)}
.d-kicker{display:flex;flex-wrap:wrap;align-items:center;gap:8px;font-size:12.5px;color:var(--text-3)}
.d-title{font-size:24px;font-weight:300;letter-spacing:.03em;line-height:1.5;margin:10px 0 6px}
.d-meta{font-size:13px;color:var(--text-3);display:flex;flex-wrap:wrap;gap:6px 16px}
.quote{margin:22px 0 6px;padding:16px 20px;border-left:2px solid var(--accent);background:rgba(255,255,255,.035);border-radius:0 16px 16px 0;font-size:15.5px;line-height:1.85;color:var(--text-1)}
.quote small{display:block;color:var(--text-3);font-size:12px;margin-top:8px}
.d-sec{font-size:12.5px;color:var(--text-3);letter-spacing:.14em;margin:26px 0 10px}
.links{display:flex;flex-wrap:wrap;gap:8px}
.link-chip{display:inline-flex;align-items:center;gap:8px;min-height:36px;padding:6px 14px;border-radius:14px;border:1px solid var(--glass-line);font-size:13.5px;color:var(--text-1);text-align:left;transition:background-color var(--dur-ui)}
.link-chip:hover{background:var(--accent-soft)}
.link-chip svg{width:14px;height:14px;color:var(--accent);flex:none}
.d-foot{margin-top:28px;padding-top:14px;border-top:1px solid rgba(255,255,255,.06);font-size:12px;color:var(--text-3);line-height:1.7}
.pending{border:1px dashed var(--warn);color:var(--warn);border-radius:14px;padding:10px 14px;font-size:12.5px;line-height:1.7;margin-top:14px}
/* 回忆 */
.mem{display:block;width:100%;text-align:left;padding:12px 14px;border-radius:16px;background:rgba(255,255,255,.035);border:1px solid rgba(255,255,255,.06);margin:8px 0;font-size:14.5px;line-height:1.65;transition:background-color var(--dur-ui),border-color var(--dur-ui)}
.mem:hover{background:rgba(255,255,255,.06)}
.mem[aria-current="true"]{border-color:var(--accent);background:var(--accent-soft)}
.mem small{display:block;color:var(--text-3);font-size:12px;margin-top:3px}
.growth{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:6px}
.growth > div{padding:14px 16px;border-radius:16px;background:rgba(255,255,255,.035);border:1px solid rgba(255,255,255,.06)}
.growth h4{font-weight:400;font-size:12.5px;color:var(--text-3);letter-spacing:.12em;margin-bottom:6px}
.growth ul{list-style:none;font-size:14px;line-height:1.9}
.growth li small{color:var(--text-3);font-size:11.5px;margin-left:6px}
/* 设置 */
.pane-manage .cols{grid-template-columns:220px 1fr}
.snav{overflow:auto;padding:14px 12px 24px 16px;border-right:1px solid rgba(255,255,255,.06)}
.snav button{display:flex;align-items:center;gap:10px;width:100%;height:44px;padding:0 14px;border-radius:14px;font-size:14px;color:var(--text-2);text-align:left;transition:background-color var(--dur-ui),color var(--dur-ui)}
.snav button svg{width:17px;height:17px;flex:none}
.snav button:hover{background:rgba(255,255,255,.04)}
.snav button[aria-current="true"]{color:var(--text-1);background:var(--accent-soft)}
.snav button[aria-current="true"] svg{color:var(--accent)}
.snav button .dirty{margin-left:auto;width:6px;height:6px;border-radius:50%;background:var(--warn);display:none}
.snav button.is-dirty .dirty{display:block}
.snav hr{border:0;border-top:1px solid rgba(255,255,255,.06);margin:10px 8px}
.sec-body{display:none}
.sec-body.on{display:block}
.sec-body h3{font-size:22px;font-weight:300;letter-spacing:.06em;margin-bottom:4px}
.sec-body .lead{font-size:13.5px;color:var(--text-2);margin-bottom:22px;line-height:1.75;max-width:560px}
.card{border-radius:18px;padding:18px 20px;background:rgba(255,255,255,.035);border:1px solid rgba(255,255,255,.07);margin:0 0 14px}
.card h4{font-size:13px;font-weight:400;color:var(--text-3);letter-spacing:.12em;margin-bottom:10px;display:flex;align-items:center;gap:8px}
.card h4 svg{width:14px;height:14px}
.pillars{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:4px 0 10px}
.pillars div{text-align:center;padding:10px 4px;border-radius:12px;background:rgba(255,255,255,.04)}
.pillars small{display:block;font-size:11.5px;color:var(--text-3)}
.pillars b{display:block;font-weight:300;font-size:22px;letter-spacing:.12em}
.lean{display:flex;flex-wrap:wrap;gap:8px;margin:4px 0 10px}
.lean span{padding:6px 14px;border-radius:var(--radius-pill);border:1px solid var(--glass-line);font-size:14px}
.kv{display:grid;grid-template-columns:120px 1fr;gap:8px 16px;font-size:14px}
.kv dt{color:var(--text-3)}
.lock{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--text-3)}
.lock svg{width:13px;height:13px}
.actions{position:sticky;bottom:-34px;margin:22px -34px -34px;padding:16px 34px 20px;display:flex;align-items:center;gap:10px;background:linear-gradient(180deg,rgba(0,0,0,0),var(--glass-read) 30%);z-index:2}
.actions .grow{flex:1;font-size:12.5px;color:var(--text-3)}
.actions .grow.dirty{color:var(--warn)}
.svc{display:grid;grid-template-columns:1fr auto;gap:10px 14px;align-items:center;padding:14px 0;border-top:1px solid rgba(255,255,255,.06)}
.svc:first-of-type{border-top:0}
.svc .nm{font-size:14.5px}
.svc .nm small{display:block;color:var(--text-3);font-size:12px}
.svc .input{grid-column:1 / -1;height:42px;font-size:14px;font-family:var(--font-num)}
.svc .res{grid-column:1 / -1;font-size:12.5px;display:none}
.svc .res.show{display:flex;align-items:center;gap:6px}
.svc .res.ok{color:var(--ok)}.svc .res.fail{color:var(--danger)}.svc .res.busy{color:var(--text-2)}
.checklist{list-style:none;margin:10px 0 0;font-size:13.5px}
.checklist li{display:flex;align-items:center;gap:10px;padding:6px 0;color:var(--text-2)}
.checklist li i{width:18px;height:18px;border-radius:50%;display:grid;place-items:center;flex:none;border:1px solid var(--glass-line);font-style:normal;font-size:11px}
.checklist li.ok i{background:rgba(159,232,207,.15);border-color:var(--ok);color:var(--ok)}
.checklist li.fail{color:var(--danger)}
.checklist li.fail i{background:rgba(255,159,179,.15);border-color:var(--danger);color:var(--danger)}
.checklist li.run i{border-color:var(--accent);border-right-color:transparent;animation:spin .9s linear infinite}
.compare{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:12px}
.compare figure{border-radius:14px;overflow:hidden;position:relative;aspect-ratio:4/3;background:rgba(255,255,255,.04)}
.compare img{width:100%;height:100%;object-fit:cover}
.compare figcaption{position:absolute;left:10px;bottom:8px;font-size:12px;padding:2px 10px;border-radius:999px;background:rgba(8,10,28,.55)}
.compare .new img{filter:hue-rotate(-14deg) saturate(1.15) brightness(1.05)}
.bk{display:flex;align-items:center;justify-content:space-between;padding:10px 0;border-top:1px solid rgba(255,255,255,.06);font-size:14px}
.bk:first-of-type{border-top:0}
.bk small{color:var(--text-3);font-size:12px;margin-left:8px}
.opt-row{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:8px 0}
.opt{border-radius:18px;padding:12px;text-align:left;border:1px solid var(--glass-line);transition:border-color var(--dur-ui),box-shadow var(--dur-ui)}
.opt .sw{height:64px;border-radius:12px;margin-bottom:10px}
.opt[data-t="moon"] .sw{background:radial-gradient(circle at 30% 30%,#e9f2ff 0 7%,rgba(160,200,255,.25) 12%,transparent 30%),linear-gradient(180deg,#0b1636,#1c2d5f)}
.opt[data-t="fog"] .sw{background:radial-gradient(80% 60% at 20% 90%,rgba(220,150,255,.7),transparent 70%),linear-gradient(170deg,#1c1342,#43307a)}
.opt[aria-pressed="true"]{border-color:var(--accent);box-shadow:0 0 18px -6px var(--accent-glow)}
.opt b{font-weight:500;font-size:14px}.opt span{display:block;font-size:12px;color:var(--text-3)}
.switch-row{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px 0;border-top:1px solid rgba(255,255,255,.06);font-size:14.5px}
.switch-row small{display:block;color:var(--text-3);font-size:12px}
.city-list{list-style:none;margin:8px 0 0;border-radius:14px;overflow:hidden;border:1px solid var(--field-line)}
.city-list li button{display:flex;justify-content:space-between;width:100%;padding:11px 14px;font-size:14px;text-align:left;border-top:1px solid rgba(255,255,255,.05)}
.city-list li:first-child button{border-top:0}
.city-list li button:hover,.city-list li button[aria-pressed="true"]{background:var(--accent-soft)}
.city-list small{color:var(--text-3)}
/* ============================================================
首建
============================================================ */
.create{position:fixed;inset:var(--view-top) 0 auto;height:var(--view-h);z-index:60;display:grid;grid-template-columns:minmax(0,1fr) minmax(460px,560px);gap:6vw;align-items:center;padding:84px 9vw 48px;opacity:0;pointer-events:none;transition:opacity var(--dur-panel) var(--ease-out)}
body.creating .create{opacity:1;pointer-events:auto}
.create .story{max-width:440px}
.create .story .eyebrow{font-size:13px;color:var(--text-3);letter-spacing:.2em;margin-bottom:14px}
.create .story h1{font-size:var(--fs-whisper);font-weight:300;line-height:1.5;letter-spacing:.04em}
.create .story p{margin-top:16px;color:var(--text-2);font-size:14.5px;line-height:1.85}
.create .story .single{margin-top:22px;display:flex;gap:10px;font-size:12.5px;color:var(--text-3);line-height:1.7}
.create .story .single svg{width:16px;height:16px;flex:none;margin-top:3px;color:var(--accent)}
.wiz{border-radius:28px;display:flex;flex-direction:column;max-height:calc(var(--view-h) - 132px);overflow:hidden}
.wiz .steps{display:flex;gap:6px;padding:20px 28px 0}
.wiz .steps span{flex:1;height:3px;border-radius:2px;background:rgba(255,255,255,.1);transition:background-color var(--dur-ui),box-shadow var(--dur-ui)}
.wiz .steps span.on{background:var(--accent);box-shadow:0 0 8px var(--accent-glow)}
.wiz .steplabel{padding:10px 28px 0;font-size:12px;color:var(--text-3);letter-spacing:.12em}
.wiz .wbody{overflow:auto;padding:10px 28px 8px;flex:1}
.wiz .wbody h2{font-size:22px;font-weight:300;letter-spacing:.06em;margin:4px 0 6px}
.wiz .wbody .lead{font-size:13.5px;color:var(--text-2);line-height:1.8;margin-bottom:20px}
.wiz .wfoot{display:flex;align-items:center;gap:10px;padding:16px 28px 22px;border-top:1px solid rgba(255,255,255,.06)}
.wiz .wfoot .grow{flex:1}
.wstep{display:none;animation:stepIn var(--dur-panel) var(--ease-out)}
.wstep.on{display:block}
@keyframes stepIn{from{opacity:0;transform:translateX(16px)}to{opacity:1;transform:none}}
.wstep.back-in{animation-name:stepBack}
@keyframes stepBack{from{opacity:0;transform:translateX(-16px)}to{opacity:1;transform:none}}
.gen{display:flex;align-items:center;gap:10px;margin:-4px 0 18px}
.sum{border-radius:16px;background:rgba(255,255,255,.035);border:1px solid rgba(255,255,255,.07);padding:4px 18px;margin-bottom:14px}
.sum .r{display:flex;justify-content:space-between;gap:12px;padding:11px 0;border-top:1px solid rgba(255,255,255,.06);font-size:14px}
.sum .r:first-child{border-top:0}
.sum .r span:first-child{color:var(--text-3)}
.sum .r b{font-weight:400;text-align:right}
.phases{list-style:none;margin:8px 0 0}
.phases li{display:flex;align-items:center;gap:12px;padding:10px 0;font-size:14.5px;color:var(--text-3)}
.phases li i{width:20px;height:20px;border-radius:50%;border:1.5px solid var(--glass-line);flex:none;display:grid;place-items:center;font-style:normal;font-size:11px}
.phases li.run{color:var(--text-1)}
.phases li.run i{border-color:var(--accent);border-right-color:transparent;animation:spin .9s linear infinite}
.phases li.ok{color:var(--text-2)}
.phases li.ok i{border-color:var(--ok);color:var(--ok);background:rgba(159,232,207,.12)}
.phases li.fail{color:var(--danger)}
.phases li.fail i{border-color:var(--danger);color:var(--danger)}
.born{text-align:center;padding:16px 0 8px}
.born .halo{width:96px;height:96px;margin:6px auto 18px;border-radius:50%;background:radial-gradient(circle,var(--window-glow) 0%,var(--accent-soft) 45%,transparent 70%);display:grid;place-items:center}
.born .halo i{width:12px;height:12px;border-radius:50%;background:var(--accent);box-shadow:0 0 22px 6px var(--accent-glow)}
.born h2{font-size:24px !important}
.born p{color:var(--text-2);font-size:14px;line-height:1.85;margin-top:6px}
/* ============================================================
通用弹层:确认 / 授权
============================================================ */
.scrim{position:fixed;inset:0;z-index:70;background:rgba(2,4,16,.45);opacity:0;pointer-events:none;transition:opacity var(--dur-ui)}
.scrim.open{opacity:1;pointer-events:auto}
.modal{position:fixed;left:50%;top:calc(var(--view-top) + var(--view-h) / 2);max-height:calc(var(--view-h) - 32px);overflow:auto;z-index:72;width:min(460px,calc(100vw - 32px));border-radius:26px;padding:26px 26px 22px;transform:translate(-50%,-46%) scale(.97);opacity:0;pointer-events:none;transition:opacity var(--dur-ui) var(--ease-out),transform var(--dur-ui) var(--ease-out)}
.modal.open{opacity:1;transform:translate(-50%,-50%);pointer-events:auto}
.modal .mi{width:44px;height:44px;border-radius:50%;display:grid;place-items:center;background:var(--accent-soft);color:var(--accent);margin-bottom:14px}
.modal.danger .mi{background:rgba(255,159,179,.12);color:var(--danger)}
.modal .mi svg{width:20px;height:20px}
.modal h3{font-size:19px;font-weight:400;letter-spacing:.04em;margin-bottom:8px}
.modal .mb{font-size:14px;color:var(--text-2);line-height:1.8}
.modal .mb ul{margin:8px 0 0 18px}
.modal .confirm-field{margin-top:14px}
.modal .acts{display:flex;justify-content:flex-end;gap:10px;margin-top:22px}
.modal .acts button{height:44px}
.toast{max-width:calc(100vw - 24px);text-align:center;position:fixed;left:50%;top:76px;transform:translate(-50%,-8px);z-index:80;padding:8px 16px;border-radius:var(--radius-pill);font-size:13px;color:var(--text-1);opacity:0;pointer-events:none;transition:opacity var(--dur-ui),transform var(--dur-ui) var(--ease-out);display:flex;align-items:center;gap:8px;white-space:nowrap}
.toast.show{opacity:1;transform:translate(-50%,0)}
.toast.ok::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--ok)}
.toast.fail::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--danger)}
/* ============================================================
演示控制台(原型专用,非产品界面)
============================================================ */
.demo{position:fixed;left:20px;bottom:24px;z-index:90}
.demo > button{height:34px;padding:0 14px;border-radius:999px;border:1px dashed var(--glass-line);font-size:12px;color:var(--text-3);background:rgba(4,6,18,.55);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}
.demo .menu{position:absolute;left:0;bottom:44px;width:300px;max-height:calc(100vh - 120px);overflow:auto;border-radius:18px;padding:12px;display:none;background:var(--glass-solid);border:1px solid var(--glass-line);box-shadow:0 20px 60px -20px #000}
.demo.open .menu{display:block}
.demo h5{font-weight:400;font-size:11.5px;color:var(--text-3);letter-spacing:.14em;margin:10px 4px 6px}
.demo h5:first-child{margin-top:2px}
.demo .g{display:flex;flex-wrap:wrap;gap:6px}
.demo .g button{height:30px;padding:0 10px;border-radius:10px;font-size:12px;color:var(--text-2);background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.06)}
.demo .g button:hover{color:var(--text-1);background:var(--accent-soft)}
.demo .g button[aria-pressed="true"]{color:var(--on-accent);background:var(--accent)}
.demo p{font-size:11px;color:var(--text-3);margin:10px 4px 0;line-height:1.6}
/* ============================================================
手机(≤720px)
============================================================ */
@media (max-width:720px){
:root{--fs-whisper:21px;--fs-line:17px}
.topbar{top:calc(var(--view-top) + 14px);left:18px;right:14px}
.who .name{font-size:17px}
.who .state,.env .chip.place,.env .chip.weather,.env .tag-demo,.clock small{display:none}
.env{gap:6px}
.clock{font-size:17px}
.theme-switch button{padding:0 9px;height:26px;font-size:12px}
.theme-switch button span{display:none}
.moon-disc{left:5%;top:12%;width:36px;height:36px}
.moon-halo{left:calc(5% - 182px);top:calc(12% - 182px);width:400px;height:400px}
.netbar{top:56px;max-width:calc(100vw - 24px);font-size:12.5px}
.netbar small{display:none}
:root{--stage-h:132px;--nav-space:60px}
.r-vignette,html[data-theme="fog"] .r-vignette{background:radial-gradient(ellipse 95% 70% at 55% 38%,transparent 55%,color-mix(in srgb,var(--bg-0) 66%,transparent) 100%),linear-gradient(180deg,color-mix(in srgb,var(--bg-0) 66%,transparent) 0%,transparent 10%)}
.who .presence{display:none}
.who .name{max-width:96px}
.end-talk{width:28px;height:28px;padding:0;justify-content:center}
.end-talk span{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}
.room-labels{left:14px;top:calc(var(--view-top) + 52px)}
.ref-note{top:calc(var(--view-top) + 50px);right:14px;bottom:auto;font-size:10px;opacity:.65;max-width:calc(100vw - 28px)}
.home{left:20px;right:20px;top:auto;bottom:calc(var(--view-bottom) + var(--nav-space) + 6px + var(--safe-bottom));width:auto;transform:none;max-height:calc(var(--view-h) - 140px);overflow:auto;animation-name:home-in-phone}
@keyframes home-in-phone{from{opacity:0;transform:translateY(16px)}}
.home .eyebrow{margin-bottom:8px}
.home .whisper{line-height:1.55}
.home .meta{display:none}
.letter{margin-top:14px;padding:12px 15px 10px;border-radius:18px}
.letter p{font-size:13px;line-height:1.7}
.away{margin-top:8px;font-size:12px}
.cta{position:static;margin-top:10px}
.cta .btn-primary{flex:1;height:46px}
.cta .btn-round{width:46px;height:46px}
.first-note{font-size:13px;margin-top:12px}
.welcome{left:12px;right:12px;width:auto;top:auto;bottom:90px;transform:translateY(20px);max-height:calc(100vh - 160px);overflow:auto;padding:22px 20px 18px;background:var(--glass-solid)}
body.welcoming .welcome{transform:none}
.welcome li{grid-template-columns:64px 1fr}
.reach{left:12px;right:12px;width:auto;bottom:calc(var(--view-bottom) + 300px + var(--safe-bottom));border-radius:20px}
body.paned .reach{left:12px;right:12px;bottom:calc(var(--view-bottom) + 72px + var(--safe-bottom))}
.conversation{width:calc(100% - 20px)}
.line p{font-size:18px;line-height:1.55}.line[data-role="user"] p{font-size:16px}.line.is-prev p{font-size:13px;max-width:70vw}
.reader-bar{gap:0;margin:2px 0 6px;font-size:11px}.reader-bar>button{padding:0 7px;height:34px}.reader-bar .icon{width:34px}.reader-bar .count{min-width:56px}
.reader-bar .latest span{max-width:9em;overflow:hidden;text-overflow:ellipsis}
.composer{min-height:48px;padding:0 4px}.composer textarea{font-size:16px}
.composer .round{width:36px;height:36px}
.nav{padding:3px}
.nav-item{width:70px;height:40px}
.record,.record.full{left:10px;right:10px;width:auto;top:calc(var(--view-top) + 60px);height:calc(var(--view-h) - 128px - var(--safe-bottom));border-radius:22px;background:var(--glass-solid)}
.record header{padding:14px 18px 12px}.record .scroll{padding:14px 18px 26px}
.pane,.wiz,.modal{background:var(--glass-solid)}
/* 区域面板 → 全屏层;列表与详情改为推入 */
.pane{left:8px;right:8px;width:auto;top:calc(var(--view-top) + 54px);bottom:calc(var(--view-bottom) + 60px + var(--safe-bottom));border-radius:24px}
.pane > header{flex-wrap:wrap;gap:10px;padding:14px 14px 12px 18px}
.pane > header h2{font-size:18px}
.pane > header .tabs{order:3;width:100%;margin:0;display:flex}
.pane > header .tabs button{flex:1}
.pane > header .tag-demo{display:none}
.pane .presence{display:flex}
.pane .cols,.pane-manage .cols{grid-template-columns:1fr}
.pane .list,.snav{border-right:0;padding:8px 12px 24px 14px}
.pane .detail{position:absolute;inset:0;transform:translateX(102%);transition:transform var(--dur-panel) var(--ease-out);background:var(--surface);padding:12px 18px 28px;z-index:3}
.pane.has-detail .detail{transform:none}
.pane .back{display:inline-flex;margin:0 0 8px -4px}
.d-empty{display:none}
.d-title{font-size:21px}
.quote{font-size:15px}
.growth{grid-template-columns:1fr}
.actions{bottom:-28px;margin:22px -18px -28px;padding:14px 18px 18px;background:var(--surface)}
.actions .grow{display:none}
.actions button{flex:1}
.row2{grid-template-columns:1fr}
.kv{grid-template-columns:96px 1fr}
.pillars b{font-size:19px}
.compare{grid-template-columns:1fr 1fr}
.create{display:flex;flex-direction:column;padding:56px 0 var(--safe-bottom);overflow:hidden}
.create .story{flex:none;padding:4px 22px 14px;max-width:none}
.create .story h1{font-size:21px}
.create .story p{font-size:13.5px;margin-top:8px}
.create .story .single{display:none}
.wiz .wbody{overflow:auto;min-height:0}
.wiz{margin:0 8px;max-height:none;border-radius:24px 24px 0 0;min-height:0;flex:1;overflow:hidden}
.wiz .wbody{padding:8px 18px 8px}
.wiz .steps{padding:16px 18px 0}
.wiz .steplabel{padding:8px 18px 0}
.wiz .wfoot{flex:none;padding:12px 18px 18px;background:var(--surface)}
.wiz .wfoot .grow{display:none}
.wiz .wfoot button{flex:1}
.create.at-story .story{display:block}
.demo{left:50%;bottom:auto;top:16px;transform:translateX(-50%)}
.demo .dl{display:none}
.demo .menu{left:50%;transform:translateX(-50%);bottom:auto;top:40px;width:min(300px,calc(100vw - 24px));max-height:70vh}
.demo > button{height:28px;padding:0 10px;font-size:11px}
}
@media (max-width:1100px) and (min-width:721px){
:root{--pane-w:calc(100vw - 10vw); --mini-pw:0px}
.pane .presence{display:flex}
.pane .cols{grid-template-columns:340px 1fr}
.pane-manage .cols{grid-template-columns:200px 1fr}
.home{width:min(400px,40vw)}
.env .weather{display:none}
.ref-note{top:calc(var(--view-top) + 64px);right:32px;bottom:auto;max-width:calc(100vw - 64px)}
.record,.record.full{width:min(440px,52vw)}
}
/* ============================================================
减少动效 / 隐藏页暂停
============================================================ */
html.reduced *, html.reduced *::before, html.reduced *::after{animation:none !important}
html.reduced .space, html.reduced .home, html.reduced .conversation, html.reduced .record, html.reduced .pane, html.reduced .pane .detail, html.reduced .welcome, html.reduced .reach, html.reduced .modal, html.reduced .create, html.reduced .nav{transition-duration:200ms !important;transition-delay:0ms !important}
/* Reduced motion: the camera no longer travels; the two stills crossfade at rest and the rain stays one frame. */
html.reduced .r-cam, html.reduced .r-near, html.reduced .r-veil, html.reduced .r-tint, html.reduced .near-c, html.reduced .r-moon{transition:opacity 200ms linear !important}
html.reduced body.talk .space, html.reduced body.paned .space{transform:none}
html.reduced .k.now{box-shadow:0 0 10px var(--accent-glow)}
html.paused *, html.paused *::before, html.paused *::after{animation-play-state:paused !important}
/* Keyboard shortcuts (snap): land on the target state with no transition; ambient loops keep running. */
html.snap *, html.snap *::before, html.snap *::after{transition:none !important}
/* Short visual viewport = keyboard open or a squat window. Her face yields first, the words never do. */
html.compact{--stage-h:78px;--nav-space:54px}
html.compact .topbar{top:calc(var(--view-top) + 10px)}
html.compact .ref-note,html.compact .who .presence,html.compact .env .weather{display:none}
html.compact .line.is-prev{display:none}
html.compact .line p{font-size:16px;line-height:1.55}
html.compact .reader-bar{margin:0 0 4px}
html.compact .nav-item{height:36px}
html.compact .record{top:calc(var(--view-top) + 48px);height:calc(var(--view-h) - 104px - var(--safe-bottom))}
/* Typing only lets the navigation step aside; the dialogue keeps its place, so a press that blurs the input
(send, full text, pause, review) is released on the same button it started on. */
html.compact.typing[data-mode="talk"] .nav{transform:translate(-50%,150%);opacity:0;pointer-events:none}
html.compact .home .eyebrow,html.compact .home .meta,html.compact .home .away,html.compact .home .letter p,html.compact .home .first-note,html.compact .home .demo-label{display:none}
html.compact .home .whisper{font-size:18px}
html.compact .letter{margin-top:6px;padding:7px 12px}
html.micro .reader-bar .count,html.micro .reader-bar .read-all,html.micro .talk-status{display:none}
html.micro .home .letter{display:none}
/* Tier 2 (slow device, measured): no backdrop blur, the most expensive compositor effect; no per-frame mask. */
html[data-tier="2"] .glass,html[data-tier="2"] .composer,html[data-tier="2"] .nav,html[data-tier="2"] .record{-webkit-backdrop-filter:none;backdrop-filter:none;background:var(--glass-read)}
html[data-tier="2"] .mote,html[data-tier="2"] .r-mist{display:none}
[hidden]{display:none!important}
p,button,h1,h2,h3,dd{overflow-wrap:anywhere}
.entry{position:fixed;inset:0;display:grid;place-items:center;padding:24px;z-index:60;overflow:auto}
.entry .card{max-width:540px;background:var(--glass-read)}
.entry h1{font-size:var(--fs-whisper);font-weight:300}
.entry p{color:var(--text-2);margin:18px 0}
.error-text{color:var(--danger);font-size:13px;margin-top:12px}
.demo-label{font-size:11px;color:var(--text-3)}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition-duration:120ms!important;transition-delay:0ms!important}}
body:has(textarea:focus) .space *{animation-play-state:paused!important}
/* Birth explanations share the read surface and typography with existing forms. */
.calendar{margin:12px 0}
.color-sections section{border-top:1px solid var(--glass-line);padding-top:16px;margin-top:16px}
.color-sections h4{color:var(--text-1);margin-bottom:8px}
.birth-help, .color-sections details{font-size:13px;color:var(--text-2);margin-top:10px}
.birth-help summary, .color-sections summary{cursor:pointer;color:var(--accent)}
@media(max-height:480px){.create .story p,.create .story .single{display:none}.create .story{padding-bottom:4px}.create .story h1{font-size:18px}}