/* 手机宇宙是一个真 WebGL canvas：星球、灯光、景深和星群均由 Three.js 绘制。
   只有 WebGL 初始化失败时才露出这里的静态深空兜底，绝不拿 CSS/PNG 假扮 3D 星球。
   🔴 兜底那张深空图(1.67MB)只许挂在 .cosmos-fallback 上,不许回到 #cosmos 基础规则:
      index.html 写死 data-tab/data-screen ⇒ #cosmos 从解析起就 display:block ⇒ 基础规则上的
      background url() 冷首访就发车,和 app.js 分同一条弱网管道。共享带宽 400kbps 实测
      (measure-weaknet-contention·前后各两趟逐毫秒复现):它把 J1 可交互 31.9s 拖到 44.0s(+12.1s)、
      app.js 下完 19.1s 拖到 30.4s,而它自己 75.7s 才传完 —— WebGL 一接管又整张扔掉。
      walkthrough-gate 的 poor3g 是逐请求延时模型(并发不共享带宽),结构性量不到这件事
      ⇒ 守它的是 test-mobile-cosmos-home 的结构断言,不是秒表。
      装载窗口的过渡底图由 ui/cosmos.js 只从缓存上屏,绝不为它现下网络。 */
#cosmos { display:none; position:fixed; inset:0; z-index:0; width:100%; height:100%; pointer-events:none; opacity:1; background:#01040a; }
#cosmos.cosmos-webgl { background:#01040a; }
#cosmos.cosmos-fallback { background:#01040a url("/assets/cosmos-mobile-deep-space-v4.webp") center center / cover no-repeat; }
#cosmos-home { display:none; }
body[data-tab="chat"][data-screen="list"] #cosmos { display:block; pointer-events:auto; touch-action:none; }
body[data-tab="chat"][data-screen="list"] #cosmos-home { display:flex; position:fixed; z-index:5; inset:0 0 auto; min-height:300px; padding:calc(env(safe-area-inset-top,0px) + 116px) 24px 38px; box-sizing:border-box; align-items:flex-end; pointer-events:none; background:linear-gradient(180deg,rgba(1,4,10,.08) 0%,rgba(1,4,10,.02) 50%,rgba(1,4,10,.78) 100%); }
.cosmos-settings { display:none; }
@media (max-width:720px) {
  /* This is deliberately a dark-only product surface.  The phone's system light
     appearance must never turn the assistant into a white card over a wallpaper. */
  body[data-tab="chat"][data-screen="list"] {
    color-scheme:dark; background:#01040a;
    --bg:#03060d; --bg2:#07101d; --panel:rgba(8,17,31,.76); --panel2:rgba(13,27,47,.88);
    --surface:rgba(6,13,25,.74); --elevated:rgba(10,22,39,.82); --card:rgba(13,27,47,.88);
    --card2:rgba(18,37,64,.92); --ink:#edf5ff; --ink2:#aabdd4; --ink3:#71859f;
    --fg:#edf5ff; --dim:#aabdd4; --faint:#71859f; --line:rgba(138,189,239,.2);
    --line2:rgba(138,189,239,.12); --fill1:rgba(143,194,255,.1);
  }
  /* 手机上的默认视图就是一个助手，不再露出旧的「聊天 / 我」工作台导航。 */
  body[data-tab="chat"][data-screen="list"] #tabnav { display:none; }
  body[data-tab="chat"][data-screen="list"] #cosmos-home { padding-right:70px; }
  body[data-tab="chat"][data-screen="list"] .cosmos-settings { display:grid; place-items:center; pointer-events:auto; position:fixed; z-index:100; top:calc(env(safe-area-inset-top,0px) + 16px); right:18px; width:38px; height:38px; border:1px solid rgba(166,217,255,.34); border-radius:50%; color:#e6f5ff; background:rgba(2,9,20,.55); box-shadow:0 0 28px rgba(76,170,255,.22),inset 0 1px rgba(255,255,255,.13); backdrop-filter:blur(18px) saturate(1.3); font:600 21px/1 var(--sans); }
  body[data-tab="chat"][data-screen="list"] .cosmos-settings:active { transform:scale(.94); background:rgba(22,63,102,.72); }
  /* 按需入口族第二颗:【这个助手自己的设置】(#agentset · 音色/深度/引擎/用我自己的 API key)。
     同一颗玻璃圆键(共用 .cosmos-settings 全部质感),只差一格位置 —— 竖着排,不横着挤:
     横排要把左边额度条的可用宽从 326px 压到 280px,而它在窄屏本来就会挤成重叠文字(见下面 mode-simple 那段的成因)。
     50px = 键高 38 + 间隙 12 ⇒ 两键中心相距 50 > 44(两侧 HIG 热区半宽 22+22),热区不互吃。
     🔴 这条只覆盖 top:其余全部继承上面那条 .cosmos-settings —— 谁改了那颗的质感,这颗自动跟着走,不会漂成两种样子。 */
  body[data-tab="chat"][data-screen="list"] #cosmos-agentset { top:calc(env(safe-area-inset-top,0px) + 66px); }
  /* 🔴 助手设置面弹起来的时候整族让位:这两颗键是 z-index:100,而 #agentset 是 58 —— 不让位它们就【浮在面板之上】
     而且照样可点(点账户那颗 = 面还开着就把 tab 切走了)。body.cosmossheet 由 ui/cosmos-entry.js 按面板自己的
     class 实时同步(锚结构真相,不锚我们自己记的账)。 */
  body.cosmossheet[data-tab="chat"][data-screen="list"] .cosmos-settings { display:none; }
  /* 余额是首页状态，不藏进账户页。实际数字仍完全复用 dashboard 的 quota 渲染逻辑。 */
  body[data-tab="chat"][data-screen="list"] #quotabar:not([hidden]) {
    display:flex !important; position:fixed; z-index:20; top:calc(env(safe-area-inset-top,0px) + 16px); left:18px; right:68px;
    width:auto; max-width:330px; min-height:38px; padding:6px 9px; border:1px solid rgba(157,211,255,.21);
    border-radius:15px; color:#dceeff; background:rgba(4,14,29,.68); box-shadow:inset 0 1px rgba(255,255,255,.09),0 9px 30px rgba(0,0,0,.24);
    backdrop-filter:blur(18px) saturate(1.25); transform:translateZ(0); will-change:transform,opacity;
  }
  body[data-tab="chat"][data-screen="list"] #quotabar .qseg { justify-content:flex-start; gap:4px; }
  /* 🔴 2026-08-18 加了 :not(.uni)。这条规则本身是【承重】的:index.html:497 在 mode-simple 下
     用 `#qseg5,#qseg7{display:none !important}` 把这两段藏了,这里必须顶回来,免费档手机才有得看
     (免费档走静态段路径,把这两段改标成「对话/看图」在用)。
     但它原来【没有档位条件】⇒ 付费档走统一窗口(uni)路径时也照样把两个老段顶出来,
     而 JS 想藏它们只能用内联 display —— 打不过 !important ⇒ 六段并存挤成一行(老板 0818 真机截图,
     那两段显示的是 HTML 默认文案「5小时/本周」和没人填过的「—」,不是任何真数据)。
     ⇒ 统一窗口在用时(uniMode 给额度条挂 .uni)这条自动让位,JS 重新成为唯一真相源。 */
  body.mode-simple[data-tab="chat"][data-screen="list"] #quotabar:not(.uni) #qseg5,
  body.mode-simple[data-tab="chat"][data-screen="list"] #quotabar:not(.uni) #qseg7 { display:flex !important; }
  body[data-tab="chat"][data-screen="list"] #quotabar .qlab,
  body[data-tab="chat"][data-screen="list"] #quotabar .qsub { color:#8eabc9; }
  body[data-tab="chat"][data-screen="list"] #quotabar b { color:#edf6ff; }
  body[data-tab="chat"][data-screen="list"] #quotabar #qkind { color:#89c7ff !important; }
  /* 手机免费额度：只两项，固定为一行紧凑信息。旧的统一窗口可含视频/5h/本周；
     它们不属于免费用户的当前可用额度，且会在窄屏挤成重叠文字。 */
  body.mode-simple[data-tab="chat"][data-screen="list"] #quotabar {
    align-items:center; gap:0; overflow:hidden; white-space:nowrap;
  }
  body.mode-simple[data-tab="chat"][data-screen="list"] #quotabar #qkindseg {
    flex:0 0 auto; max-width:64px; overflow:hidden; text-overflow:ellipsis;
  }
  body.mode-simple[data-tab="chat"][data-screen="list"] #quotabar #qseg5,
  body.mode-simple[data-tab="chat"][data-screen="list"] #quotabar #qseg7 {
    flex:0 1 auto; min-width:0; padding-left:8px; overflow:hidden; text-overflow:ellipsis;
  }
  body.mode-simple[data-tab="chat"][data-screen="list"] #quotabar #qseg5 { flex:1 1 auto; }
  /* 🔴 2026-08-18「拥挤」那一半:统一窗口段(#qwins 里 JS 动态生成的 .qseg)从来没拿到过左内边距,
     于是屏上是「Plus对话 0看图 0视频 0」—— 值和下一个标签贴死在一起。
     静态段(#qseg5/#qseg7)上面那条 padding-left:8px 一直有,动态段漏了。 */
  body.mode-simple[data-tab="chat"][data-screen="list"] #quotabar #qwins > .qseg {
    flex:0 1 auto; min-width:0; padding-left:10px; overflow:hidden; text-overflow:ellipsis;
  }
  body.mode-simple[data-tab="chat"][data-screen="list"] #quotabar #qkindseg { padding-right:2px; }
  body.mode-simple[data-tab="chat"][data-screen="list"] #quotabar .qsub {
    display:inline; margin-left:2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  /* App 可直接恢复到一条对话而不是首页；同一份云端额度仍必须可见，
     仅下移到聊天头部下方，避免和返回/新对话键重叠。
     🔴 2026-08-09：这条原来是 position:fixed —— 浮层不占流，它下面的一切（第一条聊天气泡、
     「谁在动」面板的标题行）都会从它底下穿过去，屏上就是两行字叠在一起（提审截图台拍到）。
     改成占流的一行：位置一个像素没动（header 底 74 + margin-top 8 = 82，与原 fixed 的
     safe+82 逐格相同，且两边都跟随 env(safe-area-inset-top) 因为 header 自己带 safe padding），
     但从此它自己占一行，谁也钻不到它底下。 */
  body[data-tab="chat"][data-screen="chat"] #quotabar:not([hidden]) {
    display:flex !important; position:relative; z-index:20; margin:8px 16px 6px;
    width:auto; min-height:34px; padding:5px 9px; border:1px solid rgba(157,211,255,.19); border-radius:14px;
    color:#dceeff; background:rgba(4,14,29,.66); backdrop-filter:blur(16px) saturate(1.2); transform:translateZ(0);
  }
  body[data-tab="chat"][data-screen="chat"] #quotabar .qlab,
  body[data-tab="chat"][data-screen="chat"] #quotabar .qsub { color:#8eabc9; }
  body[data-tab="chat"][data-screen="chat"] #quotabar b { color:#edf6ff; }
  /* 🔴 2026-08-18 同上:聊天态这一份也加 :not(.uni)(同一个病,两处挂载)。 */
  body.mode-simple[data-tab="chat"][data-screen="chat"] #quotabar:not(.uni) #qseg5,
  body.mode-simple[data-tab="chat"][data-screen="chat"] #quotabar:not(.uni) #qseg7 { display:flex !important; }
}
.cosmos-home-copy { max-width:300px; }
.cosmos-home-kicker { margin:0 0 10px; color:var(--accent); font:600 11px/1 var(--mono); letter-spacing:.2em; }
.cosmos-home-title { margin:0; color:var(--ink); font:600 clamp(34px,9vw,48px)/.98 var(--sans); letter-spacing:-.055em; }
.cosmos-home-state { display:flex; align-items:center; gap:8px; margin:13px 0 0; color:var(--ink2); font:400 14px/1.45 var(--sans); }
.cosmos-home-state::before { content:""; width:7px; height:7px; border-radius:50%; background:var(--accent); box-shadow:0 0 16px var(--accent); }
body[data-tab="chat"][data-screen="list"] #tabnav { z-index:4; background:rgba(10,13,19,.84); backdrop-filter:blur(18px); }
body[data-tab="chat"][data-screen="list"] header { display:none; }
/* 旧列表被移走后，footer 不能再跟普通文档流一起顶到屏幕上方。
   它是宇宙助手的常驻控制台：固定在底部、留出 iPhone 安全区，且不遮挡星空和右上设置入口。 */
body[data-tab="chat"][data-screen="list"] footer {
  display:flex !important; position:fixed; z-index:4; left:0; right:0; bottom:0;
  padding:10px 12px max(10px,env(safe-area-inset-bottom));
  background:linear-gradient(0deg,rgba(2,5,12,.98),rgba(3,7,14,.7));
  border-top:1px solid rgba(148,199,255,.12); backdrop-filter:blur(22px) saturate(1.22);
}
/* 🔴 原生壳冷启动首帧抑制(老板 2026-08-14「有几秒钟还停留在老界面」)。
   上面那条是 `body[…][…] footer` = 特指度 (0,2,1) + !important;要压过它必须更高,
   故这里带上 html[data-native-shell] 凑到 (0,3,1) —— 少写一格就是【规则在文件里、层叠里输了】的假绿,
   所以守它的断言只认真浏览器里的 computed display,不认 grep 到这行(见 test-mobile-native-firstframe)。
   属性由 index.html <head> 内联块按 location.protocol 打上,原生面确认不上岗时当场摘掉 ⇒ 输入条回来。 */
html[data-native-shell="1"] body[data-tab="chat"][data-screen="list"] footer { display:none !important; }
body[data-tab="chat"][data-screen="list"] .compose {
  background:rgba(11,25,45,.86); border:1px solid rgba(151,207,255,.22);
  border-radius:24px; box-shadow:inset 0 1px rgba(255,255,255,.08),0 14px 38px rgba(0,0,0,.34);
}
body[data-tab="chat"][data-screen="list"] .compose textarea,
body[data-tab="chat"][data-screen="list"] .compose button { color:#edf6ff; }
body[data-tab="chat"][data-screen="list"] #talkbar {
  background:linear-gradient(135deg,#629ee8,#8cc4fb); color:#06101d; box-shadow:0 0 22px rgba(103,178,255,.3);
}
body[data-tab="chat"][data-screen="list"] #inmode,
body[data-tab="chat"][data-screen="list"] .iconbtn { color:#bedcff; }

/* The assistant is used from the conversation screen, not only from the list screen.
   Keep the complete active conversation inside the same dark universe; inheriting the
   system light tokens here was the reason the old white header and compose bar survived. */
body[data-tab="chat"][data-screen="chat"] {
  --bg:#03060d; --bg2:#07101d; --panel:rgba(8,17,31,.76); --panel2:rgba(13,27,47,.88);
  --surface:rgba(6,13,25,.74); --elevated:rgba(10,22,39,.82); --card:rgba(13,27,47,.88);
  --card2:rgba(18,37,64,.92); --ink:#edf5ff; --ink2:#aabdd4; --ink3:#71859f;
  --fg:#edf5ff; --dim:#aabdd4; --faint:#71859f; --line:rgba(138,189,239,.2);
  --line2:rgba(138,189,239,.12); --fill1:rgba(143,194,255,.1);
  background:#03060d;
}
body[data-tab="chat"][data-screen="chat"] #cosmos { display:block; }
body[data-tab="chat"][data-screen="chat"] header {
  z-index:5; min-height:74px; padding:calc(env(safe-area-inset-top,0px) + 12px) 16px 12px 54px;
  background:linear-gradient(180deg,rgba(3,7,15,.9),rgba(3,8,18,.52));
  border-bottom:1px solid rgba(152,205,255,.14); backdrop-filter:blur(20px) saturate(1.25);
}
body[data-tab="chat"][data-screen="chat"] #backtolist { color:#b8dfff; }
body[data-tab="chat"][data-screen="chat"] #avatar {
  background:radial-gradient(circle at 34% 28%,#f4d6bb 0%,#84b7ee 34%,#183763 70%,#061123 100%);
  border-color:rgba(220,242,255,.42); box-shadow:0 0 0 1px rgba(84,177,255,.14),0 0 25px rgba(73,151,255,.34);
}
body[data-tab="chat"][data-screen="chat"] .htext h1 { color:#f4f8ff; letter-spacing:-.035em; }
body[data-tab="chat"][data-screen="chat"] #status { color:#a9c8e8; }
body[data-tab="chat"][data-screen="chat"] #newsession.hbtn-new {
  background:rgba(103,180,255,.12); color:#c9e6ff; border:1px solid rgba(152,205,255,.25);
  box-shadow:inset 0 1px rgba(255,255,255,.1),0 7px 23px rgba(0,0,0,.18);
}
body[data-tab="chat"][data-screen="chat"] #logwrap {
  position:relative; z-index:1; background:linear-gradient(180deg,rgba(3,7,14,.05),rgba(3,7,14,.55) 72%,rgba(3,7,14,.82));
}
body[data-tab="chat"][data-screen="chat"] #log { background:transparent; }
body[data-tab="chat"][data-screen="chat"] #welcome { color:#eaf4ff; text-shadow:0 2px 28px rgba(45,119,229,.36); }
body[data-tab="chat"][data-screen="chat"] #welcome .wsub,
body[data-tab="chat"][data-screen="chat"] #welcome .wgreet { color:#c1d2e6; }
body[data-tab="chat"][data-screen="chat"] .wchip {
  background:rgba(8,21,40,.64); border-color:rgba(145,202,255,.23); color:#d8ecff; backdrop-filter:blur(16px);
}
body[data-tab="chat"][data-screen="chat"] .msg,
body[data-tab="chat"][data-screen="chat"] .bubble,
body[data-tab="chat"][data-screen="chat"] .agentmsg {
  background:rgba(9,22,40,.72); border-color:rgba(148,199,255,.14); color:#e9f3ff; backdrop-filter:blur(16px);
}
body[data-tab="chat"][data-screen="chat"] footer {
  position:relative; z-index:5; padding:9px 12px max(10px,env(safe-area-inset-bottom));
  background:linear-gradient(0deg,rgba(2,5,12,.98),rgba(3,7,14,.78));
  border-top:1px solid rgba(148,199,255,.12); backdrop-filter:blur(22px) saturate(1.22);
}
body[data-tab="chat"][data-screen="chat"] .compose {
  background:rgba(11,25,45,.86); border:1px solid rgba(151,207,255,.22);
  border-radius:24px; box-shadow:inset 0 1px rgba(255,255,255,.08),0 14px 38px rgba(0,0,0,.34);
}
body[data-tab="chat"][data-screen="chat"] .compose textarea,
body[data-tab="chat"][data-screen="chat"] .compose button { color:#edf6ff; }
body[data-tab="chat"][data-screen="chat"] #talkbar {
  background:linear-gradient(135deg,#629ee8,#8cc4fb); color:#06101d; box-shadow:0 0 22px rgba(103,178,255,.3);
}
body[data-tab="chat"][data-screen="chat"] #inmode,
body[data-tab="chat"][data-screen="chat"] .iconbtn { color:#bedcff; }
body[data-tab="chat"][data-screen="chat"] #orchpanel,
body[data-tab="chat"][data-screen="chat"] #quotabar,
body[data-tab="chat"][data-screen="chat"] #upgbar {
  position:relative; z-index:4; background:rgba(7,18,34,.76); border-color:rgba(150,205,255,.18);
  color:#dceeff; backdrop-filter:blur(18px);
}

/* Account, consent and onboarding are required product surfaces, not a second visual
   product.  Preserve every control while placing the documents on the same deep-space
   material language as the assistant. */
#authgate, #consentgate, #introgate {
  color:#edf5ff;
  background:
    linear-gradient(180deg,rgba(2,6,14,.64),rgba(2,6,14,.92)),
    #02060d url("/assets/cosmos-mobile-deep-space-v4.webp") center top / cover no-repeat;
}
#authgate .authcard,
#consentgate .introcaps,
#introgate .introcaps {
  background:rgba(8,20,38,.72); border:1px solid rgba(154,209,255,.2);
  box-shadow:inset 0 1px rgba(255,255,255,.08),0 22px 58px rgba(0,0,0,.34);
  backdrop-filter:blur(22px) saturate(1.25);
}
#authgate .authcard { padding:22px 18px; border-radius:24px; }
#authgate .authfield input,
#authgate .authgoogle {
  background:rgba(5,16,31,.82); border-color:rgba(154,209,255,.2); color:#edf5ff;
}
#authgate .authfield input::placeholder { color:#7e97b4; }
#authgate .authbtn,
#introgate .obbtn,
#consentgate .obbtn { background:linear-gradient(135deg,#629ee8,#8cc4fb); color:#06101d; box-shadow:0 0 24px rgba(105,180,255,.26); }
#authgate .authlink,
#introgate .obbtn.ghost,
#consentgate #consent_policy { color:#b9ddff; }
#authgate .authlogo .nm { color:#dff0ff; letter-spacing:.14em; text-shadow:0 0 26px rgba(118,192,255,.46); }
#authgate .authlogo .sub,
#authgate .authfield label,
#authgate .authremember,
#introgate .introbody,
#consentgate .consentbody p { color:#b8cae0; }
/* 🔴🔴 2026-08-14(v455 设置面归一):「我」这一屏也必须锁进同一套深色 token。
   在这之前它【只有背景色和几条 metab 规则】是深的,token 本身仍从 :root 继承 ——
   而 ui/tokens.css 里有一整块 @media (prefers-color-scheme: light) 会把 bg/panel/ink 翻成近白
   ⇒ 手机系统开浅色时,#feed 这块设置抽屉(退出登录 / 我的电脑 / 删除账号 / 语言 / 检查更新 / 麦克风)
     会变成【白卡片】,而它上下左右都是深空 —— 正是本文件上方那句头注要禁的
     "The phone's system light appearance must never turn the assistant into a white card over a wallpaper"。
   从今天起这块面是 App 里唯一的设置面(不再有原生账号面顶在前面),所以这一格必须补齐,
   否则"App 里和浏览器里长得一样"会在浅色手机上当场破功。声明表与上面 chat/list、chat/chat 两块【逐条同源】。 */
body[data-tab="me"] {
  color-scheme:dark; background:#03060d;
  --bg:#03060d; --bg2:#07101d; --panel:rgba(8,17,31,.76); --panel2:rgba(13,27,47,.88);
  --surface:rgba(6,13,25,.74); --elevated:rgba(10,22,39,.82); --card:rgba(13,27,47,.88);
  --card2:rgba(18,37,64,.92); --ink:#edf5ff; --ink2:#aabdd4; --ink3:#71859f;
  --fg:#edf5ff; --dim:#aabdd4; --faint:#71859f; --line:rgba(138,189,239,.2);
  --line2:rgba(138,189,239,.12); --fill1:rgba(143,194,255,.1);
}
body[data-tab="me"] #tabpane-me.metab { background:linear-gradient(180deg,rgba(4,10,20,.26),rgba(3,7,15,.96)); }
body[data-tab="me"] .metab-acct,
body[data-tab="me"] .metab-list,
body[data-tab="me"] #tabnav {
  background:rgba(7,18,34,.78); border-color:rgba(153,205,255,.16); backdrop-filter:blur(18px);
}
body[data-tab="me"] .metab-acct { margin:14px 12px 0; width:calc(100% - 24px); border:1px solid rgba(153,205,255,.18); border-radius:22px; }
body[data-tab="me"] .metab-list { margin:12px; width:calc(100% - 24px); border:1px solid rgba(153,205,255,.14); border-radius:18px; overflow:hidden; }
body[data-tab="me"] .metab-acct,
body[data-tab="me"] .metab-row { color:#edf5ff; }
body[data-tab="me"] .metab-acctsub,
body[data-tab="me"] .metab-rt,
body[data-tab="me"] .metab-ver { color:#a9c4df; }
/* 统一手感：只合成 transform/opacity，绝不靠 width/top/box-shadow 动画触发布局。
   首页、账户、登录、同意和引导都复用它；系统“减少动态效果”仍保留确定的按下反馈。 */
@media (max-width:720px) {
  /* 🪦 额度条 2026-08-13 起不在这张【按下手感】名单里:它退成纯显示(不是按钮),给它按下缩放 = 屏上仍在说"我能按"。
     它自己那条 :not([hidden]) 规则里已经带着 transform:translateZ(0)+will-change,GPU 提层不受影响。 */
  .cosmos-settings, .compose, .metab-acct, .metab-row,
  #authgate .authbtn, #authgate .authgoogle, #introgate .obbtn, #consentgate .obbtn {
    transform:translateZ(0); will-change:transform,opacity;
    transition:transform 160ms cubic-bezier(.2,.75,.25,1),opacity 160ms linear;
  }
  .cosmos-settings:active, .metab-acct:active, .metab-row:active,
  #authgate .authbtn:active, #authgate .authgoogle:active, #introgate .obbtn:active, #consentgate .obbtn:active {
    transform:translateZ(0) scale(.975); opacity:.9;
  }
  #authgate, #consentgate, #introgate, body[data-tab="me"] #tabpane-me.metab { min-height:100dvh; }
}
@media (prefers-reduced-motion: reduce) { #cosmos { opacity:.82; } }

/* ═══ 单击助手黑洞 → 宇宙里浮出【他和你说过的话】(老板 2026-08-07 逐字) ═══
   🔴 这一层【没有第二份聊天数据、也没有第二套渲染】:它就是现役的 #logwrap/#log ——
      app.js renderEntry 渲的那批真气泡(文字/图片/语音/文件按类型各渲各的,点图仍走 #viewer)。
      这里只做【展示层】:把它从旧的聊天详情屏里搬出来,变成一块浮在星空上的发光玻璃。
   🔴 为什么用 `html body[...]` 起头:wechat.css 的 `body[data-tab][data-screen] #logwrap{display:none!important}`
      与本规则特指度相同,靠"后加载"取胜太脆;加一个 html 把特指度真的抬高一格,不赌顺序。
   🔴 平时【存在但不可见不可点】(visibility:hidden + pointer-events:none),不是 display:none ——
      display 切换会让淡出那一半根本没机会播,老板要的是"丝滑隐去"不是"啪一下没了"。 */
html body[data-tab="chat"][data-screen="list"] #logwrap {
  display:flex !important; position:fixed; z-index:6; left:0; right:0;
  top:40vh; bottom:calc(env(safe-area-inset-bottom,0px) + 76px);
  visibility:hidden; opacity:0; pointer-events:none; transform:translateY(26px) scale(.985);
  background:linear-gradient(180deg,rgba(1,4,10,0) 0%,rgba(1,4,10,.42) 22%,rgba(1,4,10,.62) 100%);
  transition:opacity 240ms linear, transform 320ms cubic-bezier(.2,.75,.25,1), visibility 0s linear 300ms;
}
html body.cosmoslog[data-tab="chat"][data-screen="list"] #logwrap {
  visibility:visible; opacity:1; pointer-events:auto; transform:none;
  transition:opacity 260ms linear, transform 340ms cubic-bezier(.2,.75,.25,1), visibility 0s;
}
/* 🔴 记录层收在 `bottom: safe-area + 76px`,这条下沿正好压在 <footer> 里【输入条上方那一档】——
      附件预览 #attachPrev、同意提示条 #consentHint、命令菜单 #slashmenu 都是从那一档往上长的。
   0809 批8 双臂实测(真 Chromium 412×915,挂两张图):
      · 记录层没展开:#logwrap 是 pointer-events:none ⇒ elementFromPoint 打到 BUTTON.rm,附件的「×」点得掉;
      · 记录层展开后:#logwrap 变 pointer-events:auto,盖住 y=823..839 那一带 ⇒ elementFromPoint 打到 DIV#log,
        附件预览既看不见、「×」也点不掉(用户挂得上附件却删不掉、也不知道自己挂了什么)。
   同 0809 批5 那一族:浮层不只是"看着叠字",它把底下那一条的【点击也吃了】,而且不占流 ⇒ 全闸绿。
   🔴 修在哪一层是关键:首页这条 footer 自己是 `position:fixed; z-index:4` = 它【建了一个层叠上下文】,
      所以给里面的 #attachPrev 单独抬 z-index 是抬不出去的(第一版就是这么写的,双臂探针照样红);
      #slashmenu 那个 z-index:41 同理,一直被关在 footer 里,并不像它的数字看上去那样在记录层之上。
      正解=把 footer 整块抬到记录层(6)之上。没挂附件时 footer 高度≈76px 正好贴在记录层下沿之下 ⇒ 常态零视觉变化;
      挂了附件/弹了命令菜单时,长出来的那一档压住聊天记录最下面一条,这是对的先后:输入的东西盖过回看的东西。 */
body[data-tab="chat"][data-screen="list"] footer { z-index:7; }
/* 记录层开着时,首页那块大字标题要给缩小的黑洞让位(真截图上它俩正好叠在一起)。
   🔴 让位不是删信息:大标题收成一行小字,【状态那行照旧显示】—— 连没连上是真事实,不能因为好看就藏。 */
body.cosmoslog[data-tab="chat"][data-screen="list"] #cosmos-home,
body.cosmospop[data-tab="chat"][data-screen="list"] #cosmos-home {
  min-height:0; padding:calc(env(safe-area-inset-top,0px) + 64px) 24px 0; align-items:flex-start; background:none;
}
body.cosmoslog[data-tab="chat"][data-screen="list"] .cosmos-home-kicker,
body.cosmospop[data-tab="chat"][data-screen="list"] .cosmos-home-kicker { display:none; }
body.cosmoslog[data-tab="chat"][data-screen="list"] .cosmos-home-title,
body.cosmospop[data-tab="chat"][data-screen="list"] .cosmos-home-title { font-size:19px; letter-spacing:-.01em; opacity:.74; }
body.cosmoslog[data-tab="chat"][data-screen="list"] .cosmos-home-state,
body.cosmospop[data-tab="chat"][data-screen="list"] .cosmos-home-state { margin-top:3px; font-size:12.5px; opacity:.74; }
body[data-tab="chat"][data-screen="list"] .cosmos-home-title,
body[data-tab="chat"][data-screen="list"] .cosmos-home-state { transition:font-size 260ms cubic-bezier(.2,.75,.25,1), opacity 240ms linear; }
/* 这层里不该出现的旧构件:空状态大光球(与黑洞打架)和右缘实时动态条(那是详情屏的) */
body[data-tab="chat"][data-screen="list"] #welcome,
body[data-tab="chat"][data-screen="list"] #dynbar { display:none !important; }
body[data-tab="chat"][data-screen="list"] #log {
  flex:1; min-height:0; overflow-y:auto; -webkit-overflow-scrolling:touch;
  padding:26px 20px 30px; padding-inline-end:20px; gap:11px; background:transparent;
  /* 上下淡出到透明 —— 文字要"从星空里浮出来",不能有一条硬边把面板框住 */
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 30px,#000 calc(100% - 20px),transparent 100%);
  mask-image:linear-gradient(180deg,transparent 0,#000 30px,#000 calc(100% - 20px),transparent 100%);
}
/* 白色发光高级字体。🔴 可读性优先于高级感(老板同日:「根本看不了云端助手发的任何文字」)——
   发光只用 text-shadow 叠在纯白字上,不降对比度、不加半透明字色。 */
body[data-tab="chat"][data-screen="list"] #log .bubble {
  max-width:88%; color:#f6faff; font-weight:380; letter-spacing:.012em; line-height:1.62;
  text-shadow:0 0 12px rgba(152,206,255,.44),0 0 34px rgba(78,142,255,.22),0 1px 2px rgba(0,0,0,.55);
}
body[data-tab="chat"][data-screen="list"] #log .bubble.me {
  padding:9px 14px; border-radius:17px 17px 5px 17px;
  background:rgba(12,30,56,.46); border:1px solid rgba(160,212,255,.2);
  box-shadow:inset 0 1px rgba(255,255,255,.09),0 10px 30px rgba(0,0,0,.3); backdrop-filter:blur(14px) saturate(1.25);
}
body[data-tab="chat"][data-screen="list"] #log .time { color:rgba(178,206,238,.62); text-shadow:0 0 10px rgba(90,150,230,.3); }
body[data-tab="chat"][data-screen="list"] #log .histsep,
body[data-tab="chat"][data-screen="list"] #log .threadkind { color:rgba(168,200,234,.6); text-shadow:0 0 12px rgba(80,140,220,.28); }
body[data-tab="chat"][data-screen="list"] #log .narration,
body[data-tab="chat"][data-screen="list"] #log .thinking { background:rgba(8,20,38,.4); border-left-color:rgba(150,200,250,.4); }
/* 图片/视频缩略:留发光边,点开仍是现役 #viewer(步②的"点了看大图/吸进黑洞"接在这条口子上) */
body[data-tab="chat"][data-screen="list"] #log .media {
  max-height:34vh; border-radius:15px; border:1px solid rgba(160,212,255,.26); box-shadow:0 12px 34px rgba(0,0,0,.42),0 0 26px rgba(86,158,255,.18);
}
body[data-tab="chat"][data-screen="list"] #log .filechip,
body[data-tab="chat"][data-screen="list"] #log .voice {
  background:rgba(10,24,45,.6); border:1px solid rgba(158,210,255,.22); color:#eaf4ff; backdrop-filter:blur(12px);
}
body[data-tab="chat"][data-screen="list"] #log .me .voice { background:rgba(226,240,255,.92); color:#0a1524; }
/* 空态说的是【我们收到了什么】,不是【世界上有没有】——所以是"还没收到",不是"没有" */
#cosmoslog-empty { display:none; }
body.cosmoslog.cosmoslog-empty[data-tab="chat"][data-screen="list"] #cosmoslog-empty {
  display:block; position:absolute; inset:auto 26px 50%; transform:translateY(50%); text-align:center;
  color:rgba(214,233,255,.78); font:400 14.5px/1.6 var(--sans); letter-spacing:.02em;
  text-shadow:0 0 16px rgba(120,180,255,.4);
}
@media (prefers-reduced-motion: reduce) {
  html body[data-tab="chat"][data-screen="list"] #logwrap { transition:none; transform:none; }
}

/* ═══ 图片弹到黑洞球前 · 捏合缩放拖拽 · 点宇宙别处被吸进去(老板 2026-08-07 逐字)═══
   🔴 这一层【没有第二份媒体】:<img> 的 src 直接用现役 #log 那张图已经到手的 src
      (原生壳里就是 media-src.js 带凭据取回来的 blob:)—— 不重取、不另存。
   🔴 只合成 transform / opacity / filter,一条会触发布局的属性都不动:
      弹出、吸入、捏合三段动画全跑在合成器上,不跟 WebGL 抢主线程。
   🔴 平时是 display:none —— 它没有"淡出"那一半要播(收起是靠吸入那条 transform 走完再摘),
      与 #logwrap 那层的 visibility 写法不同,原因不同,别互抄。 */
#cosmospop { display:none; position:fixed; inset:0; z-index:8; pointer-events:none; }
#cosmospop.on { display:block; }
/* 三块内容(图 / 视频 / 文档面)共用同一副骨架:同样的摆位、同样的 transform 原点、同样的合成属性。
   🔴 可见性只走 .live 这一个 class ——【不用 [hidden]】:作者 CSS 的 display 压得过 UA 的 [hidden],
      本仓为此栽过一次(iOS 壳截图里"藏起来"的付款入口赫然在目)。 */
.cosmospop-node { display:none; position:absolute; left:0; top:0; transform-origin:50% 50%; pointer-events:auto; will-change:transform,opacity,filter; }
.cosmospop-node.live { display:block; }
#cosmospop-img {
  touch-action:none;
  border-radius:15px; border:1px solid rgba(168,216,255,.34); background:rgba(3,9,19,.45); object-fit:contain;
  box-shadow:0 26px 72px rgba(0,0,0,.62),0 0 48px rgba(96,168,255,.26),inset 0 1px rgba(255,255,255,.1);
  -webkit-user-select:none; user-select:none;
}
/* 视频:系统解码、系统控件(绝不把视频帧灌进 WebGL)。touch-action:none = 捏合缩放由我们接,
   而单指前 14px 让给播放控件那件事在 JS 里(cosmos-media.js 的 GESTURE 表),CSS 管不了。 */
#cosmospop-video {
  touch-action:none; object-fit:contain; background:#02060d;
  border-radius:15px; border:1px solid rgba(168,216,255,.34);
  box-shadow:0 26px 72px rgba(0,0,0,.62),0 0 48px rgba(96,168,255,.26),inset 0 1px rgba(255,255,255,.1);
}
/* 文档面:与记录层同族的一块发光玻璃 —— 老板要的是"在宇宙里读",不是"跳出去开一个网页"。 */
#cosmospop-doc {
  flex-direction:column; overflow:hidden; touch-action:none;
  border-radius:18px; border:1px solid rgba(160,212,255,.26); background:rgba(6,15,29,.72);
  box-shadow:0 26px 72px rgba(0,0,0,.6),0 0 46px rgba(90,160,255,.2),inset 0 1px rgba(255,255,255,.08);
  backdrop-filter:blur(20px) saturate(1.2);
}
#cosmospop-doc.live { display:flex; }
.cosmosdoc-head { flex:0 0 auto; padding:11px 15px 9px; border-bottom:1px solid rgba(150,200,250,.16); }
.cosmosdoc-name {
  display:block; color:#f3f9ff; font:500 13.5px/1.35 var(--sans); letter-spacing:.01em;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; text-shadow:0 0 14px rgba(150,205,255,.42);
}
.cosmosdoc-text, .cosmosdoc-frame, .cosmosdoc-pages, .cosmosdoc-card, .cosmosdoc-pagesmore { display:none; }
.cosmosdoc-pages.live { display:block; flex:1 1 auto; min-height:0; width:100%; overflow-y:auto; -webkit-overflow-scrolling:touch; background:#0b1220; }
.cosmosdoc-page { display:block; width:100%; height:auto; margin:0 0 8px; background:#fff; border-radius:4px; }
.cosmosdoc-pagesmore.live { display:block; font-size:12.5px; opacity:.7; margin:4px 0 0; }
/* 发光滚动层:单指滚字(touch-action:pan-y),两指仍然缩放整块面(JS 那半接的) */
.cosmosdoc-text.live {
  display:block; flex:1 1 auto; min-height:0; overflow-y:auto; -webkit-overflow-scrolling:touch; touch-action:pan-y;
  margin:0; padding:14px 15px 18px; white-space:pre-wrap; word-break:break-word; tab-size:2;
  color:#f4f9ff; font:400 12.6px/1.66 var(--mono,ui-monospace,SFMono-Regular,Menlo,Consolas,monospace);
  text-shadow:0 0 12px rgba(150,205,255,.34),0 1px 2px rgba(0,0,0,.5);
  -webkit-user-select:text; user-select:text;
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 16px,#000 calc(100% - 14px),transparent 100%);
  mask-image:linear-gradient(180deg,transparent 0,#000 16px,#000 calc(100% - 14px),transparent 100%);
}
.cosmosdoc-frame.live { display:block; flex:1 1 auto; min-height:0; width:100%; border:0; background:#0b1220; }
.cosmosdoc-card.live { display:flex; flex:1 1 auto; flex-direction:column; align-items:center; justify-content:center; gap:9px; padding:20px 22px; text-align:center; }
.cosmosdoc-icon { font-size:34px; line-height:1; filter:drop-shadow(0 0 16px rgba(130,190,255,.45)); }
.cosmosdoc-cardname { margin:0; color:#eff6ff; font:500 13.5px/1.4 var(--sans); word-break:break-all; }
.cosmosdoc-why { display:none; }
.cosmosdoc-why.live { display:block; margin:0; color:#a9c6e4; font:400 12.4px/1.55 var(--sans); max-width:30ch; }
.cosmosdoc-open { display:none; }
.cosmosdoc-open.live {
  display:inline-block; margin-top:4px; padding:9px 18px; border-radius:20px; border:0; cursor:pointer;
  background:linear-gradient(135deg,#629ee8,#8cc4fb); color:#06101d; font:500 13px/1 var(--sans);
  box-shadow:0 0 22px rgba(103,178,255,.3);
}
.cosmosdoc-trunc, .cosmosdoc-st { display:none; }
.cosmosdoc-trunc.live, .cosmosdoc-st.live {
  display:block; margin:0; padding:8px 15px 11px; color:#a9c6e4;
  font:400 12px/1.5 var(--sans); text-align:center; border-top:1px solid rgba(150,200,250,.12);
}
.cosmosdoc-states { flex:0 0 auto; }
/* 记录层里的视频 = 一张会动的缩略图:控件收起来,点它 = 在宇宙里打开(真控件在弹出层上)。
   两套控件同时露着,他会以为点 ▶ 就地播 —— 那一下其实是把它弹出去,读起来像 bug。 */
body[data-tab="chat"][data-screen="list"] #log video.media::-webkit-media-controls { display:none !important; }
body[data-tab="chat"][data-screen="list"] #log video.media { pointer-events:auto; }
/* 吸入拖尾:四条细光条被同一个奇点拽走。只在吸入那 0.56 秒存在,平时连节点都不参与绘制。 */
.cosmospop-streak { display:none; position:absolute; left:0; top:0; width:3px; height:38px; margin:-19px 0 0 -1.5px; border-radius:2px; opacity:0; transform-origin:50% 50%; background:linear-gradient(180deg,rgba(198,229,255,0),rgba(206,234,255,.9),rgba(198,229,255,0)); }
#cosmospop.sucking .cosmospop-streak { display:block; }
/* 长按图 → 浮出「存到相册」动作条(仅原生壳有存图能力时;能力探针在 ui/cosmos-save.js)。默认不在(display:none),
   .show 才现;它自己 pointer-events:auto(#cosmospop 整层是 none)——点它 = 存图,不会被判成「点宇宙别处」收图。 */
.cosmos-saveaction { display:none; position:fixed; left:50%; bottom:calc(env(safe-area-inset-bottom,0px) + 19%); z-index:9; pointer-events:auto; opacity:0; transform:translateX(-50%) translateY(8px); transition:opacity .18s ease,transform .18s ease; }
.cosmos-saveaction.show { display:block; opacity:1; transform:translateX(-50%) translateY(0); }
.cosmos-saveaction-btn {
  display:inline-flex; align-items:center; padding:11px 24px; border-radius:22px; border:1px solid rgba(168,216,255,.34); cursor:pointer;
  background:linear-gradient(135deg,#629ee8,#8cc4fb); color:#06101d; font:600 14px/1 var(--sans);
  box-shadow:0 12px 36px rgba(0,0,0,.52),0 0 26px rgba(103,178,255,.36); -webkit-user-select:none; user-select:none;
}
.cosmos-saveaction-btn:active { transform:scale(.95); }
