
:root {
    --bg-base: #030307;
    --neb-1: rgba(56, 38, 100, 0.26);
    --neb-2: rgba(30, 46, 108, 0.23);
    --neb-3: rgba(64, 34, 84, 0.30);
    --neb-4: rgba(14, 18, 44, 0.28);
    --star-alpha: 0.74;
    --grid-alpha: 0.42;
    --grid-line: rgba(58, 186, 168, 0.075);
}

/* ============================================================
   新背景(缺陷海/驻波)挂载 —— 原 cosmos 星云保留在 DOM 里当备份:
   .void-bg-on 时旧背景退场、新 canvas 接管;去掉 html 上的 .void-bg-on
   即整体回退到原 cosmos(不用回滚代码)。
   ============================================================ */
.void-bg {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
}

/* 首页:canvas 放进 .intro-bg(z-index:0 那层)而不是 .page-cosmos(首页没有),
   亮模式不显示(外圈星点是暗底设计的) */
html.void-bg-on.home-page[data-theme="light"] .void-bg,
html.void-bg-on.intro-page[data-theme="light"] .void-bg {
    display: none;
}

html.void-bg-on .page-cosmos .cosmos {
    display: none;
}

/* ============================================================
   正文"去框":新背景(缺陷海/驻波)下文字直接浮在背景上。
   撤掉 .main / .post-entry 的底色、边框、投影 —— 只在 void-bg-on 时生效,
   摘掉类即整体回退(连同样式)。
   ============================================================ */
html.void-bg-on .main {
    background: transparent;
    box-shadow: none;
    border: 1px solid transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

/* 暗模式的青色描边 + 大投影(custom.css 按 [data-theme=dark] 写的),
   选择器特异性更高,这里对齐它的写法压掉 */
:root[data-theme="dark"] html.void-bg-on .main,
html.void-bg-on[data-theme="dark"] .main {
    box-shadow: none;
}

html.void-bg-on .main::before {
    opacity: 0 !important;      /* 暗模式的青色描边框一并撤 */
}

/* shell-page(经过 start 登录进来的页面)的 .main 是一块毛玻璃卡
   (底色+边框+圆角+blur+投影),一并撤。
   ★ 原规则是 :root[data-theme].shell-page .main(特异性 = 4 个类级),
     这里必须 ≥ 它:用 html.void-bg-on.shell-page .main(3 类级+1 类型)+ !important
     保底 —— 压不过它去框就是一句空话。 */
html.void-bg-on .shell-page .main,
html.void-bg-on.shell-page .main,
:root[data-theme].shell-page html.void-bg-on .main {
    background: transparent !important;
    border: 1px solid transparent !important;
    border-radius: 0 !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    box-shadow: none !important;
}

/* void-bg 撤卡片底色/投影/边框，但给 entry-card.css 的左侧竖线让位：
   border-left 用 accent-line 竖线（见 entry-card.css 同名规则，那里是后加载的兜底，
   这里是 void-bg 的主动声明 —— 两处保持一致）。 */
html.void-bg-on .post-entry {
    background: transparent;
    border: 1px solid transparent;
    border-left: 2px solid var(--accent-line, rgba(34, 211, 238, 0.38));
    box-shadow: none;
}

html.void-bg-on .post-entry:hover,
html.void-bg-on .post-entry:focus-within {
    border-color: transparent;
    border-left-color: var(--accent, rgb(34, 211, 238));
    transform: none;
}

html.void-bg-on .post-entry:active {
    transform: none;
}

/* ============================================================
   亮模式(奶白波底)下的 HUD / 组件配色和谐:
   暗模式的 HUD 是"深底上的浅字"(青白发光);亮模式底是奶白,
   同样写法会糊掉。这里把 HUD 的墨色/线色翻成"浅底上的深字",
   青色 accent 换成深青(在奶白上可读),发光全部收敛。
   只在 html.void-bg-on[data-theme="light"] 生效。
   ============================================================ */
html.void-bg-on[data-theme="light"] .page-hud {
    --hud-ink: #3a3f48;
    --hud-ink-dim: rgba(58, 63, 72, 0.62);
    --hud-line-soft: rgba(58, 63, 72, 0.22);
    --hud-line-on: rgba(58, 63, 72, 0.60);
    --hud-rail: rgba(58, 63, 72, 0.22);
    --hud-cover: rgba(244, 241, 233, 0.92);
    --hud-glow: 0;
    text-shadow: none;
}

/* 磁力光标 accent:奶白底上用深青,发光收敛 */
html.void-bg-on[data-theme="light"] {
    --mc-color: rgb(14, 116, 122);
}

html.void-bg-on[data-theme="light"] .hud-toc {
    --hud-toc-ink: rgba(58, 63, 72, 0.92);
    --hud-toc-dim: rgba(58, 63, 72, 0.70);
    --hud-toc-line: rgba(58, 63, 72, 0.22);
    --hud-toc-on: rgba(58, 63, 72, 0.62);
    --hud-toc-cyan: rgb(14, 116, 122);
}

/* HUD 上的白色实心字(青底按钮等)在亮模式保持白字,但底色块换深青 */
html.void-bg-on[data-theme="light"] .hud-toc .toc-item.is-on,
html.void-bg-on[data-theme="light"] .hud-left .is-on {
    box-shadow: none;
}

/* ECHO 对话框:墨绿描边 + 浅纸底 + 墨绿字 */
html.void-bg-on[data-theme="light"] .echo-say {
    background: rgba(240, 246, 242, 0.94);
    border-color: rgba(24, 92, 82, 0.42);
    color: rgb(24, 92, 82);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

html.void-bg-on[data-theme="light"] .echo-say__who {
    color: rgb(24, 92, 82);
}

/* 顶栏 header 的毛玻璃在亮模式下换暖色 */
html.void-bg-on[data-theme="light"] .header,
:root[data-theme="light"].shell-page html.void-bg-on .header {
    background: color-mix(in srgb, #f4f1e9 76%, transparent);
}

/* HUD 内写死的浅色(logo/run/face)在亮模式翻成深色 */
html.void-bg-on[data-theme="light"] .hud-logo {
    color: #3a3f48;
    text-shadow: none;
}

html.void-bg-on[data-theme="light"] .hud-logo:hover {
    color: #20242b;
}

html.void-bg-on[data-theme="light"] .hud-run {
    stroke: #3a3f48;
}

html.void-bg-on[data-theme="light"] .hud-face {
    fill: rgba(58, 63, 72, 0.05);
    stroke: rgba(58, 63, 72, 0.30);
}

html.void-bg-on[data-theme="light"] .page-hud text,
html.void-bg-on[data-theme="light"] .page-hud .hud-val,
html.void-bg-on[data-theme="light"] .page-hud button {
    text-shadow: none;
}

/* HUD 大框(halo/line)亮模式:墨绿细线,halo(发光层)发暗 ——
   从"白光晕"改成墨绿薄晕,run 扫描线(白)换墨绿。
   ★ page-hud.css 是【单独的 link,在主样式表之后】加载 ——
     同特异性下它会赢 ⇒ 这里全部挂 !important 才压得住。 */
html.void-bg-on[data-theme="light"] .page-hud {
    --hud-halo-a: 0.06;
    --hud-line-a: 0.34;
}

html.void-bg-on[data-theme="light"] .page-hud .hud-halo {
    stroke: rgb(24, 92, 82) !important;
}

html.void-bg-on[data-theme="light"] .page-hud .hud-line {
    stroke: rgba(24, 92, 82, 0.55) !important;
}

html.void-bg-on[data-theme="light"] .page-hud .hud-run {
    stroke: rgb(24, 92, 82) !important;
    opacity: 0.5;
}

html.void-bg-on[data-theme="light"] .hud-run {
    stroke: rgb(24, 92, 82) !important;
}

/* 左下投影节点的扫描框(hud-proj__scan/line/beam):
   青白混色线在奶白底上发白发亮 → 墨绿发暗 */
html.void-bg-on[data-theme="light"] .hud-proj__line {
    stroke: rgba(24, 92, 82, 0.62) !important;
}

/* ============================================================
   左下四个组件面板(时钟/音乐/番茄钟/待办+分类页)亮模式墨绿分支
   —— hud-left.css 里大量硬编码 rgba(234,243,255,*) 白色系,
      奶白底上白字白边看不见,全部翻成墨绿/深灰系。
   ============================================================ */

/* 面板头部:分隔线/英文副标题 */
html.void-bg-on[data-theme="light"] .hud-proj__head {
    border-bottom-color: rgba(24, 92, 82, 0.22) !important;
}

html.void-bg-on[data-theme="light"] .hud-proj__en {
    color: rgba(24, 92, 82, 0.62) !important;
}

/* 待办文字 / 时钟副行 / 日历格 / 播放器副行 · 通用淡白字 → 深灰墨绿 */
html.void-bg-on[data-theme="light"] .hud-left__todo,
html.void-bg-on[data-theme="light"] .hud-left__clock span,
html.void-bg-on[data-theme="light"] .hud-left__calgrid i,
html.void-bg-on[data-theme="light"] .hud-left__calhead span,
html.void-bg-on[data-theme="light"] .hud-player__meta span,
html.void-bg-on[data-theme="light"] .hud-player__time,
html.void-bg-on[data-theme="light"] .hud-plist__row,
html.void-bg-on[data-theme="light"] .hud-cat__row,
html.void-bg-on[data-theme="light"] .hud-plist__hint,
html.void-bg-on[data-theme="light"] .hud-plist__note,
html.void-bg-on[data-theme="light"] .hud-cat__foot {
    color: rgba(58, 63, 72, 0.72) !important;
}

html.void-bg-on[data-theme="light"] .hud-left__calgrid i.w {
    color: rgba(58, 63, 72, 0.30) !important;
}

/* 日历"今天"格:墨绿底白字 → 墨绿底 + 白字保留(底够深) */
html.void-bg-on[data-theme="light"] .hud-left__calgrid i.today {
    background: rgba(24, 92, 82, 0.85) !important;
    color: #ffffff !important;
}

/* 记事本/日历翻页按钮:白边白底 → 墨绿细边 + 墨绿薄底 */
html.void-bg-on[data-theme="light"] .hud-left__note,
html.void-bg-on[data-theme="light"] .hud-left__calhead button {
    border-color: rgba(24, 92, 82, 0.30) !important;
    background: rgba(24, 92, 82, 0.05) !important;
}

html.void-bg-on[data-theme="light"] .hud-left__note:focus {
    border-color: rgba(24, 92, 82, 0.62) !important;
}

/* 播放器/列表行:白底纹 → 墨绿薄底 */
html.void-bg-on[data-theme="light"] .hud-player,
html.void-bg-on[data-theme="light"] .hud-plist__row,
html.void-bg-on[data-theme="light"] .hud-cat__row,
html.void-bg-on[data-theme="light"] .hud-music {
    background-color: rgba(24, 92, 82, 0.05) !important;
    border-color: rgba(24, 92, 82, 0.18) !important;
}

html.void-bg-on[data-theme="light"] .hud-plist__row:hover,
html.void-bg-on[data-theme="light"] .hud-cat__row:hover {
    background-color: rgba(24, 92, 82, 0.12) !important;
    color: rgb(24, 92, 82) !important;
}

/* 分类首页卡(主分类大卡)与激活列表行 */
html.void-bg-on[data-theme="light"] .hud-cat__home {
    border-color: rgba(24, 92, 82, 0.45) !important;
    background: rgba(24, 92, 82, 0.08) !important;
    color: rgb(24, 92, 82) !important;
}

html.void-bg-on[data-theme="light"] .hud-cat__home span {
    color: rgba(24, 92, 82, 0.62) !important;
}

html.void-bg-on[data-theme="light"] .hud-plist__row.is-on {
    border-color: rgba(24, 92, 82, 0.60) !important;
    background: rgba(24, 92, 82, 0.16) !important;
    color: rgb(24, 92, 82) !important;
}

/* 分类页粘性标签:深底白字 → 墨绿底白字 */
html.void-bg-on[data-theme="light"] .hud-cat__act {
    background: rgba(24, 92, 82, 0.92) !important;
    color: #ffffff !important;
}

/* 播放器进度条:青白混色 → 墨绿 */
html.void-bg-on[data-theme="light"] .hud-player__track {
    background: rgba(24, 92, 82, 0.18) !important;
}

html.void-bg-on[data-theme="light"] .hud-player__track i {
    background: rgb(24, 92, 82) !important;
}

/* 播放按钮圆钮:墨绿描边 */
html.void-bg-on[data-theme="light"] .hud-player__btn {
    border-color: rgba(24, 92, 82, 0.50) !important;
    background: rgba(24, 92, 82, 0.10) !important;
    color: rgb(24, 92, 82) !important;
}

html.void-bg-on[data-theme="light"] .hud-player__btn:hover {
    background: rgba(24, 92, 82, 0.18) !important;
}

html.void-bg-on[data-theme="light"] .hud-proj__beam line {
    stroke: rgba(24, 92, 82, 0.55) !important;
}

html.void-bg-on[data-theme="light"] .hud-proj__beam circle {
    fill: rgba(24, 92, 82, 0.55) !important;
    stroke: rgba(24, 92, 82, 0.55) !important;
}

html.void-bg-on[data-theme="light"] .hud-proj__scan {
    opacity: 0.5;
}

/* 扫描纹理(pattern 里的 rect 硬编码青白 rgba(234,243,255,0.05)),
   奶白底上完全看不见 → 亮模式换墨绿纹理并加浓 */
html.void-bg-on[data-theme="light"] #hud-proj-scan rect {
    fill: rgba(24, 92, 82, 0.10) !important;
}

/* ECHO 在奶白底上不可见 → 翻墨绿,"靠深不靠亮"显形(原版同一套映射) */
html.void-bg-on[data-theme="light"] .pn-edge {
    stroke: rgba(24, 92, 82, 0.78);
}

html.void-bg-on[data-theme="light"] .pn-rail__spine {
    stroke: rgba(24, 92, 82, 0.35);
}

html.void-bg-on[data-theme="light"] .pn-rail__stop {
    stroke: rgba(24, 92, 82, 0.65);
}

html.void-bg-on[data-theme="light"] .pn-leg {
    stroke: rgba(24, 92, 82, 0.45);
}

html.void-bg-on[data-theme="light"] .pn-eye__case {
    fill: rgba(24, 92, 82, 0.14);
    stroke: rgba(24, 92, 82, 0.72);
}

html.void-bg-on[data-theme="light"] .pn-plane {
    fill: rgba(24, 92, 82, 0.05);
}

html.void-bg-on[data-theme="light"] .pn-plane__circuit path {
    stroke: rgba(24, 92, 82, 0.18);
}

html.void-bg-on[data-theme="light"] .pn-plane__circuit path:nth-child(6n+1),
html.void-bg-on[data-theme="light"] .pn-plane__circuit path:nth-child(6n+4) {
    stroke: rgba(24, 92, 82, 0.32);
}

html.void-bg-on[data-theme="light"] .pn-plane__pad {
    fill: rgba(24, 92, 82, 0.5);
}

html.void-bg-on[data-theme="light"] .pn-eye__frame {
    stroke: rgba(24, 92, 82, 0.5);
}

html.void-bg-on[data-theme="light"] .pn-eye__blades {
    fill: rgba(24, 92, 82, 0.30);
    stroke: rgba(24, 92, 82, 0.6);
}

html.void-bg-on[data-theme="light"] .pn-eye__iris__ring {
    fill: rgba(24, 92, 82, 0.16);
    stroke: rgba(24, 92, 82, 0.7);
}

html.void-bg-on[data-theme="light"] .pn-eye__halo {
    /* 径向渐变 stop-color 在 SVG 内部,CSS 改不动;
       亮模式用 filter 把青色光晕调成墨绿,暗模式不受影响 */
    filter: hue-rotate(150deg) saturate(0.6) brightness(0.85);
}

html.void-bg-on[data-theme="light"] .pn-eye__core {
    fill: rgb(24, 92, 82);
}

html.void-bg-on[data-theme="light"] .pn-eye__glint {
    fill: rgba(244, 248, 244, 0.9);
}

html.void-bg-on[data-theme="light"] .pn-eye__lid {
    fill: rgba(24, 92, 82, 0.85);
}

/* 番茄钟/左栏里的白字按钮(青底白字)在亮模式换深青底 */
html.void-bg-on[data-theme="light"] .hud-left {
    color: #3a3f48;
}

html.void-bg-on[data-theme="light"] .hud-left__name {
    color: rgba(58, 63, 72, 0.62);
}

/* ============================================================
   亮模式墨绿系(用户定色):墨绿 rgb(24,92,82)
   —— 图标、目录卡底、组件卡文字、搜索框文字。
   ============================================================ */

/* ============================================================
   亮模式墨绿系(用户定色):墨绿 rgb(24,92,82)
   —— 图标、目录卡底、组件卡文字、搜索框文字、ECHO 摄像头。
   ★ ECHO 摄像头(proj-node 的 SVG)在暗模式是"发光"语义(青色亮线);
     奶白底上发光看不见 —— 亮模式翻成【发暗】的墨绿:深色实线、
     不透明度拉高、去掉一切 glow,浅底上靠"深"而不是"亮"来显形。
   ============================================================ */

/* 番茄钟/左栏里的白字按钮(青底白字)在亮模式换深青底 */

/* HUD 各处 svg 图标(导航/动作/笔/主题旋钮) */
html.void-bg-on[data-theme="light"] .page-hud svg,
html.void-bg-on[data-theme="light"] .hud-left svg {
    color: rgb(24, 92, 82);
}

html.void-bg-on[data-theme="light"] .hud-nav__name,
html.void-bg-on[data-theme="light"] .hud-left__name {
    color: rgba(24, 92, 82, 0.78);
}

/* 目录卡片背景:深灰卡 → 墨绿薄雾卡(奶白上的浅墨绿玻璃) */
html.void-bg-on[data-theme="light"] .hud-toc__panel {
    background:
        linear-gradient(180deg, rgba(24, 92, 82, 0.06), rgba(24, 92, 82, 0) 42%),
        rgba(236, 243, 239, 0.80);
    border-color: rgba(24, 92, 82, 0.26);
}

/* 回到顶部小按钮:原样式写死暗底白字(hud-toc.css 的
   rgba(8,12,22,.78) / rgba(234,243,255,*)),亮模式墨绿重着色 */
html.void-bg-on[data-theme="light"] .hud-toc__top {
    background: rgba(236, 243, 239, 0.85);
    border-color: rgba(24, 92, 82, 0.30);
    color: rgba(24, 92, 82, 0.92);
}
html.void-bg-on[data-theme="light"] .hud-toc__top:hover,
html.void-bg-on[data-theme="light"] .hud-toc__top:focus-visible {
    border-color: rgb(14, 116, 122);
    background: rgba(14, 116, 122, 0.12);
    color: rgb(14, 116, 122);
}

/* 组件卡片文字(音乐播放器/番茄钟等):白字 → 墨绿字 */
html.void-bg-on[data-theme="light"] .hud-card,
html.void-bg-on[data-theme="light"] .hud-panel,
html.void-bg-on[data-theme="light"] .hud-left__mod,
html.void-bg-on[data-theme="light"] .hud-left__ico,
html.void-bg-on[data-theme="light"] .hud-timer,
html.void-bg-on[data-theme="light"] .hud-timer * {
    color: rgb(24, 92, 82);
}

/* 搜索框文字 */
html.void-bg-on[data-theme="light"] .hud-search .search-box input {
    color: rgb(24, 92, 82);
    border-color: rgba(24, 92, 82, 0.34);
    background: rgba(244, 246, 244, 0.6);
}

html.void-bg-on[data-theme="light"] .hud-search .search-box input::placeholder {
    color: rgba(24, 92, 82, 0.5);
}

html.void-bg-on[data-theme="light"] .hud-search__clear {
    color: rgba(24, 92, 82, 0.66);
}

/* 回到顶部按钮:亮模式墨绿圆钮 + 白色图标 */
html.void-bg-on[data-theme="light"] .top-link {
    background: rgb(24, 92, 82);
    color: #f2f6f2;
}

html.void-bg-on[data-theme="light"] .top-link:hover {
    color: #ffffff;
}

html.void-bg-on[data-theme="light"] .top-link svg {
    fill: #f2f6f2;
}

.cosmos {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    border-radius: inherit;
}

.cosmos-nebula {
    background-color: var(--bg-base, #030307);
    background-image:
        radial-gradient(52% 42% at 16% 24%, var(--neb-1) 0%, transparent 66%),
        radial-gradient(46% 50% at 76% 14%, var(--neb-2) 0%, transparent 68%),
        radial-gradient(64% 56% at 62% 86%, var(--neb-3) 0%, transparent 72%),
        radial-gradient(40% 40% at 38% 52%, var(--neb-4) 0%, transparent 74%),
        linear-gradient(162deg, var(--bg-base, #030307) 0%, #04040a 45%, var(--bg-base, #030307) 100%);
    opacity: var(--bg-power, 1);
    animation: cosmos-nebula 46s ease-in-out infinite alternate;
}

.cosmos-nebula::after {
    content: "";
    position: absolute;
    inset: -60%;
    border-radius: inherit;
    opacity: var(--star-alpha, 0.34);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='170' height='170'%3E%3Cg fill='%23ffffff'%3E%3Ccircle cx='14' cy='26' r='0.85' opacity='.42'/%3E%3Ccircle cx='63' cy='12' r='0.6' opacity='.28'/%3E%3Ccircle cx='104' cy='41' r='1' opacity='.46'/%3E%3Ccircle cx='152' cy='22' r='0.55' opacity='.24'/%3E%3Ccircle cx='31' cy='79' r='0.7' opacity='.32'/%3E%3Ccircle cx='86' cy='96' r='0.9' opacity='.42'/%3E%3Ccircle cx='139' cy='112' r='0.6' opacity='.26'/%3E%3Ccircle cx='22' cy='139' r='0.95' opacity='.36'/%3E%3Ccircle cx='74' cy='152' r='0.5' opacity='.22'/%3E%3Ccircle cx='126' cy='159' r='0.75' opacity='.32'/%3E%3C/g%3E%3C/svg%3E");
    background-size: 170px 170px;
    animation: cosmos-twinkle 7s ease-in-out infinite alternate, cosmos-drift 240s linear infinite;
}

@keyframes cosmos-twinkle {
    0% { opacity: calc(var(--star-alpha, 0.34) * 0.72); }
    50% { opacity: var(--star-alpha, 0.34); }
    100% { opacity: calc(var(--star-alpha, 0.34) * 1.18); }
}

@keyframes cosmos-drift {
    from { transform: translate(0, 0); }
    to { transform: translate(-170px, -120px); }
}

@keyframes cosmos-nebula {
    from { background-position: 0% 0%, 0% 0%, 0% 0%, 0% 0%, 0% 0%; }
    to { background-position: 6% 3%, -5% 4%, 4% -3%, -3% -4%, 0% 0%; }
}

.cosmos-grid {
    opacity: var(--grid-alpha, 0.5);
    background-image:
        repeating-linear-gradient(0deg, var(--grid-line) 0px, var(--grid-line) 1px, transparent 1px, transparent 26px),
        repeating-linear-gradient(90deg, var(--grid-line) 0px, var(--grid-line) 1px, transparent 1px, transparent 26px);
    transform: none;
    -webkit-mask-image: radial-gradient(44% 34% at 42% 60%, #000 0%, rgba(0, 0, 0, 0.5) 42%, transparent 76%);
    mask-image: radial-gradient(44% 34% at 42% 60%, #000 0%, rgba(0, 0, 0, 0.5) 42%, transparent 76%);
    animation: cosmos-grid-drift 14s linear infinite;
}

@keyframes cosmos-grid-drift {
    from { background-position: 0 0, 0 0; }
    to { background-position: 0 26px, 0 0; }
}

.cosmos-nebula,
.cosmos-grid {
    position: absolute;
    inset: 0;
    pointer-events: none;
    border-radius: inherit;
}

.page-cosmos {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
}

.proj-node {
    width: clamp(88px, 9vw, 132px);
    pointer-events: none;
    opacity: 0.9;
}

.intro-page .proj-node {
    position: absolute;
    left: 100vw;
    top: 0;
    z-index: 34;
}

:root[data-theme].shell-page .proj-node {
    position: fixed;
    left: 0;
    top: 0;
    z-index: -1;
}

:root[data-theme].shell-page .header {
    background: color-mix(in srgb, var(--theme) 72%, transparent);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
}

.proj-node svg {
    display: block;
    width: 100%;
    height: auto;
    overflow: visible;
}

/* ============================================================
   ECHO · 第十代(第一步):摄像头滑轨
   ─────────────────────────────────────────────────────────
   设计改为滑轨方案:旧底座全部退场,画面只剩幕描线 + 滑轨
   + 光圈核。摄像头中心是正三角,之后沿滑轨自由滑动(不再跟鼠标)。
   A=(0,160)(左下,页面纵边界上)沿与水平成30°向右上移 16;
   B=(160,0)(右上,页面横边界上)沿与竖直成30°向左下移 16。
   A'B' 即滑轨 —— 平行于斜边,略靠内,两端有挡块。
   ============================================================ */
.pn-leg {
    stroke: rgba(160, 235, 255, 0.3);
    stroke-width: 1;
}

.pn-edge {
    stroke: rgba(160, 235, 255, 0.62);
    stroke-width: 1.1;
}

/* 轨道装饰:凹槽底里的导轨脊线(比凹口边线更细更淡,才有"埋在槽里"
   的层次)+ 两端止挡短线(垂直于轨,像滑轨限位块)。都只装饰,
   不参与交互。 */
.pn-rail__spine {
    stroke: rgba(160, 235, 255, 0.28);
    stroke-width: 0.7;
    stroke-dasharray: 3 4;
    stroke-linecap: round;
}

.pn-rail__stop {
    stroke: rgba(160, 235, 255, 0.55);
    stroke-width: 1.4;
    stroke-linecap: round;
}

/* 框本身凹进去的滑槽:斜边两端各让出一小段直线,中段内凹 ——
   框的轮廓一条 path 画完(凹口左右对称),凹进去的 A'B' 就是滑轨,
   摄像头之后沿它滑动。不再叠任何线/槽底填充。 */

/* ECHO 说话时 .proj-node 加 is-talking:光圈叶片转速加倍(正在"发声") */
:root[data-theme].shell-page .proj-node.is-talking .pn-eye__blades {
    animation-duration: 5s;
}

/* 信号核(眼睛):光圈语言 —— 外壳环 + 三片实心光圈叶片(青,
   随 is-talking 转动/张合)+ 内环,中心一枚实心三角亮芯(朝上,
   与外三角同向,是"光点"不是眼球)。
   亮芯用渐变(CSS 改不动 SVG 内 stop,直给),呼吸走 opacity。 */
/* 底座 = 光平面:框的内腔整个是一块发淡光的平面(沿框轮廓闭合),
   滑轨凹槽就是光面上凹出来的槽。低透明度青,微微呼吸 */
.pn-plane {
    fill: rgba(34, 211, 238, 0.05);
    stroke: none;
    animation: pn-eye-glow 3.4s ease-in-out infinite;
}

/* 光平面装饰:能量母线矩阵 —— 横竖两组传导线铺满内腔(被斜边裁齐),
   母线端头发光端子;数据流点沿母线流动(每条相位错开) */
.pn-plane__circuit path {
    fill: none;
    stroke: rgba(160, 235, 255, 0.16);
    stroke-width: 0.5;
}

.pn-plane__pad {
    fill: rgba(160, 235, 255, 0.5);
    animation: pn-eye-glow 3.4s ease-in-out infinite;
}

.pn-plane__circuit path:nth-child(6n+1),
.pn-plane__circuit path:nth-child(6n+4) {
    stroke: rgba(160, 235, 255, 0.28);
    stroke-width: 0.7;
    stroke-dasharray: 6 10;
    animation: pn-plane-flow 3.2s linear infinite;
}

@keyframes pn-plane-flow {
    to { stroke-dashoffset: -64; }
}

.pn-eye__case {
    fill: rgba(6, 10, 18, 0.72);
    stroke: rgba(160, 235, 255, 0.55);
    stroke-width: 1.1;
    stroke-linejoin: round;
}

/* 内描边框:嵌套三角的第二道轮廓,给它"机构感"而不是一张圆脸 */
.pn-eye__frame {
    fill: none;
    stroke: rgba(34, 211, 238, 0.4);
    stroke-width: 0.7;
}

/* 光圈叶片:三片实心三角(半透明青,叠出光圈开合感),整体慢转 */
.pn-eye__blades {
    fill: rgba(80, 210, 240, 0.3);
    stroke: rgba(140, 235, 250, 0.55);
    stroke-width: 0.6;
    stroke-linejoin: round;
    transform-origin: 0 1px;
    animation: pn-rotate 12s linear infinite;
}

/* 内环:叶片聚合处的接收环 */
.pn-eye__iris__ring {
    fill: rgba(6, 14, 22, 0.55);
    stroke: rgba(160, 235, 255, 0.5);
    stroke-width: 0.8;
    stroke-linejoin: round;
}

.pn-eye__halo {
    fill: url(#pnCoreGrad);
    animation: pn-eye-glow 3.4s ease-in-out infinite;
}

.pn-eye__core {
    fill: #f2feff;
    animation: pn-eye-glow 3.4s ease-in-out infinite;
}

.pn-eye__lid {
    fill: rgba(6, 12, 20, 0.88);
    transform: scaleY(0);
    transform-origin: 0 -22px;
    animation: pn-blink 5.6s ease-in-out infinite;
}

@keyframes pn-rotate {
    to { transform: rotate(360deg); }
}

@keyframes pn-pulse {
    0%, 100% { opacity: 0.4; }
    50% { opacity: 1; }
}

@keyframes pn-eye-glow {
    0%, 100% { opacity: 0.6; }
    50% { opacity: 1; }
}

@keyframes pn-blink {
    0%, 92.6%, 100% { transform: scaleY(0); }
    94.5% { transform: scaleY(1); }
    96.4% { transform: scaleY(0.15); }
    98.2% { transform: scaleY(1); }
}

.echo-say {
    display: none;
}

:root[data-theme].shell-page .echo-say {
    position: fixed;
    left: calc(clamp(88px, 9vw, 132px) + 6px);
    top: 70px;
    z-index: 60;
    max-width: 178px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 7px 10px 8px;
    border: 1px solid rgba(160, 235, 255, 0.26);
    border-radius: 2px 11px 11px 11px;
    background: rgba(6, 10, 18, 0.84);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    color: rgba(234, 243, 255, 0.92);
    font-size: 12px;
    line-height: 1.55;
    letter-spacing: 0.01em;
    opacity: 0;
    transform: translateX(-5px);
    transition: opacity 0.22s ease, transform 0.22s ease;
    pointer-events: none;
}

:root[data-theme].shell-page .echo-say.is-on {
    opacity: 1;
    transform: none;
}

.echo-say__who {
    font-size: 9px;
    letter-spacing: 0.2em;
    color: rgba(34, 211, 238, 0.85);
}

/* 浅色模式:ECHO 对话框改成纸面便签 —— 深墨字、浅灰蓝描边,
   青色署名压深到可读;不再沿用暗模式那套黑底荧光 */
:root[data-theme="light"].shell-page .echo-say {
    border-color: rgba(70, 90, 100, 0.35);
    background: rgba(250, 248, 242, 0.92);
    color: rgba(40, 46, 52, 0.92);
    box-shadow: 0 2px 10px rgba(60, 70, 80, 0.10);
}
:root[data-theme="light"].shell-page .echo-say__who {
    color: rgba(8, 110, 130, 0.9);
}

.echo-hot {
    display: none;
}

:root[data-theme].shell-page .echo-hot {
    position: fixed;
    /* 热区中心 = 信号核中心(滑轨中点 = 65.66/168 ≈ 宽的 39%),与 .pos 同步 */
    left: calc(clamp(88px, 9vw, 132px) * 0.3906 - 22px);
    top: calc(clamp(88px, 9vw, 132px) * 0.3906 - 22px);
    width: 44px;
    height: 44px;
    display: block;
    z-index: 61;
    border-radius: 50%;
    cursor: pointer;
}

.echo-black {
    position: fixed;
    inset: 0;
    z-index: 99998;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    background: #000;
    color: rgba(34, 211, 238, 0.92);
    font-family: var(--hud-font, ui-monospace, SFMono-Regular, Menlo, monospace);
    text-align: center;
    opacity: 0;
    transition: opacity 0.4s ease;
}

.echo-black[hidden] {
    display: none;
}

.echo-black.is-on {
    opacity: 1;
}

.echo-black__code {
    font-size: 13px;
    letter-spacing: 0.22em;
}

.echo-black__who {
    font-size: 10px;
    letter-spacing: 0.4em;
    color: rgba(34, 211, 238, 0.5);
}

.echo-black__note {
    font-size: 11px;
    letter-spacing: 0.16em;
    color: rgba(234, 243, 255, 0.45);
}

/* ECHO 待机呼吸:浮标整体极低频的亮度起伏(6s 一轮,幅度很小)。
   它已经会看光标(pn-eye/pupil),这里只加"活着"的那口气;
   reduced-motion 时关掉(hud-echo.js 的 still 分支不管这个,纯 CSS 媒体查询兜底)。 */
:root[data-theme].shell-page .proj-node svg {
    animation: echo-breathe 6s ease-in-out infinite;
}

@keyframes echo-breathe {
    0%, 100% { opacity: 0.78; }
    50% { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    :root[data-theme].shell-page .proj-node svg {
        animation: none;
    }
}

body.intro-page.page-out .scene {
    transform: translateX(-100vw);
}

body.intro-page.page-out .tablet {
    transform: translateX(-100vw);
    opacity: 1;
    transition: transform .55s cubic-bezier(.22, .61, .36, 1), opacity .26s ease;
}

body.intro-page.page-out .statusbar-toggle {
    transform: translateX(calc(-50% - 100vw));
    transition: color .18s ease, border-color .18s ease, opacity .3s ease,
        transform .55s cubic-bezier(.22, .61, .36, 1);
}

body.page-out {
    pointer-events: none;
    overflow: hidden;
}



:root[data-theme].shell-page {
    background: var(--bg-base, #030307);
}

/* ★ 亮模式底色:--bg-base 是暗海军蓝,内容页 body 不满一屏时
     底部露出这条深色带(爆发期暗角一压就读成"页面下面有黑边")。
     亮模式把 html 底色换成奶白纸色,露边也不再发黑。 */
:root[data-theme="light"].shell-page {
    background: #f4f1e9;
}

:root[data-theme].shell-page body {
    background: transparent;
}

:root[data-theme].shell-page .main {
    background: color-mix(in srgb, var(--theme) 86%, transparent);
    border: 1px solid var(--border);
    border-radius: 18px;
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
    padding: clamp(16px, 2.4vh, 30px) clamp(16px, 2.6vw, 36px);
    margin: clamp(12px, 2.2vh, 28px) auto;
}

/* 灵动感层的亮色覆盖:fill 色值换成墨绿系(动画本身共用) */
html.void-bg-on[data-theme="light"] .page-hud .hud-face {
    animation-name: hud-face-idle-light !important;
}
@keyframes hud-face-idle-light {
    0%, 100% { fill: rgba(58, 63, 72, 0.05); }
    38% { fill: rgba(58, 63, 72, 0.10); }
    55% { fill: rgba(58, 63, 72, 0.04); }
}
html.void-bg-on[data-theme="light"] .page-hud .hud-line,
html.void-bg-on[data-theme="light"] .page-hud .hud-band-line {
    animation-name: hud-line-breathe !important;
}
html.void-bg-on[data-theme="light"] .page-hud .hud-logo {
    animation: hud-logo-noise-light 8.9s ease-in-out infinite !important;
}
@keyframes hud-logo-noise-light {
    0%, 100% { text-shadow: 0 0 24px rgba(24, 92, 82, 0.14); }
    47% { text-shadow: 0 0 24px rgba(24, 92, 82, 0.10); }
    62% { text-shadow: 0 0 24px rgba(24, 92, 82, 0.18); }
}
@media (prefers-reduced-motion: reduce) {
    html.void-bg-on[data-theme="light"] .page-hud .hud-face,
    html.void-bg-on[data-theme="light"] .page-hud .hud-line,
    html.void-bg-on[data-theme="light"] .page-hud .hud-band-line,
    html.void-bg-on[data-theme="light"] .page-hud .hud-logo {
        animation: none !important;
    }
}

@media (prefers-reduced-motion: reduce) {
    .cosmos-nebula,
    .cosmos-nebula::after,
    .cosmos-grid,
    .pn-eye__halo,
    .pn-eye__lid,
    .pn-eye__blades {
        animation: none !important;
    }
}

/* ============================================================
   pjax 切换的正文过场:page-out 时 main 淡出下移,
   换入后 main 淡入上浮 —— HUD/背景/ECHO 不参与(它们在 main 外)。
   ============================================================ */
body.page-out .main {
    opacity: 0;
    transform: translateY(18px);
    transition: opacity 0.3s ease, transform 0.35s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.main {
    transition: opacity 0.4s ease, transform 0.45s cubic-bezier(0.22, 0.61, 0.36, 1);
}

@media (prefers-reduced-motion: reduce) {
    body.page-out .main {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

/* ============================================================
   ECHO 底座装饰(pn-deco):不规则框内部的机械细节
   ─────────────────────────────────────────────────────────
   都在 .pn-deco 组里,只装饰不交互:
   · tick     直角处的三角定位标(两个角各一枚,像冲压定位点)
   · strip    左上角两条"指示灯排"(5 格小方块,1 格高亮慢闪)
   · bar      右下角两根"状态条"(底槽 + 一段亮段来回跑)
   · arc/dot  右上斜边内侧的弧形刻度线 + 流动小点(数据感)
   ============================================================ */
.pn-deco__tick {
    fill: rgba(160, 235, 255, 0.4);
}

.pn-deco__cell {
    fill: rgba(160, 235, 255, 0.22);
}

.pn-deco__cell--hot {
    fill: rgba(34, 211, 238, 0.85);
    animation: pn-deco-blink 2.6s ease-in-out infinite;
}

/* 指示灯排的相位差:同一排内,hot 格闪自己那一拍;
   两条排之间靠 SVG 里位置不同自然错开,这里再给竖排加半拍延迟 */
.pn-deco__strip:nth-of-type(2) .pn-deco__cell--hot {
    animation-delay: -1.3s;
}

@keyframes pn-deco-blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.2; }
}

.pn-deco__bar rect {
    fill: rgba(160, 235, 255, 0.14);
}

/* 状态条:亮段在 20 单位长的槽里来回跑。
   槽长 20、亮段长 6,单程位移 14(6+14=20 恰好一端到另一端),
   ease-in-out 到头停一下再折回,像往复巡检。 */
.pn-deco__bar .pn-deco__barseg {
    fill: rgba(34, 211, 238, 0.75);
    animation: pn-deco-run 5.2s cubic-bezier(.45, 0, .55, 1) infinite alternate;
}

@keyframes pn-deco-run {
    from { transform: translate(0, 0); }
    to { transform: translate(14px, 0); }
}

.pn-deco__bar:last-child .pn-deco__barseg {
    animation-name: pn-deco-run-y;
    animation-delay: -2.6s;   /* 与横条错开半程,两根不同时折返 */
}

@keyframes pn-deco-run-y {
    from { transform: translate(0, 0); }
    to { transform: translate(0, 14px); }
}

.pn-deco__arc {
    fill: none;
    stroke: rgba(160, 235, 255, 0.3);
    stroke-width: 0.6;
    stroke-dasharray: 2 3;
}

.pn-deco__arc--soft {
    stroke: rgba(160, 235, 255, 0.16);
}

.pn-deco__dot {
    fill: rgba(34, 211, 238, 0.9);
    animation: pn-eye-glow 2.2s ease-in-out infinite;
}

.pn-deco__dot--d1 {
    animation-delay: 1.1s;
}

/* 亮模式:青色发光 → 墨绿发暗(与整台摄像头同一套翻法) */
html.void-bg-on[data-theme="light"] .pn-deco__tick {
    fill: rgba(24, 92, 82, 0.55);
}

html.void-bg-on[data-theme="light"] .pn-deco__cell {
    fill: rgba(24, 92, 82, 0.28);
}

html.void-bg-on[data-theme="light"] .pn-deco__cell--hot {
    fill: rgba(24, 92, 82, 0.85);
}

html.void-bg-on[data-theme="light"] .pn-deco__bar rect {
    fill: rgba(24, 92, 82, 0.2);
}

html.void-bg-on[data-theme="light"] .pn-deco__bar .pn-deco__barseg {
    fill: rgba(24, 92, 82, 0.8);
}

html.void-bg-on[data-theme="light"] .pn-deco__arc {
    stroke: rgba(24, 92, 82, 0.4);
}

html.void-bg-on[data-theme="light"] .pn-deco__arc--soft {
    stroke: rgba(24, 92, 82, 0.2);
}

html.void-bg-on[data-theme="light"] .pn-deco__dot {
    fill: rgba(24, 92, 82, 0.85);
}

@media (prefers-reduced-motion: reduce) {
    .pn-deco__cell--hot,
    .pn-deco__bar .pn-deco__barseg,
    .pn-deco__dot {
        animation: none !important;
    }
}
