/* =====================================================================
   救生艇 · base.css —— 机械层样式（结构 / 布局 / 动效骨架）
   ---------------------------------------------------------------------
   分层契约：本文件不允许出现任何颜色字面量。
   所有颜色一律 var(--xxx)（变量定义在 theme.css），或由 theme.css
   以同选择器补写颜色属性（如 .moon 的月面渐变、.spark 的星色）。
   换肤日只替换 theme.css，本文件一行不动。
   样式规格 1:1 迁移自业主验收的 lifeboat-mockup.html，不做视觉发挥。
   ===================================================================== */

/* ================= 基础 ================= */
* { box-sizing: border-box; margin: 0; padding: 0; }
/* 锁死文档级滚动：iOS standalone下否则会出现整页偏移+底部黑边，下拉才复位。
   高度用 var(--standalone-h, 100dvh)：iOS主屏模式的视口bug由app.js钉真实屏高（见app.js顶部注释） */
html, body { height: var(--standalone-h, 100dvh); overflow: hidden; overscroll-behavior: none; }
/* iOS的字体自动膨胀：检测到横向超宽内容会放大全页字体（2.5/2.6首轮验收踩中，
   病根是代码块撑宽，已修）。此处钉死禁用，杜绝这类连锁反应 */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
/* iOS原生点按高亮=半透明黑罩，大块可点区域（中枢抽屉卡）上是一记"黑闪"
   （任务9整改④业主实锤）。全局关掉，按压反馈一律走各自的:active样式 */
html { -webkit-tap-highlight-color: transparent; }
body {
  font-family: var(--sans);
  background: var(--page-bg);
}
svg { display: block; flex-shrink: 0; }
img.ava-glyph { display: block; flex-shrink: 0; }   /* 独立文件头像（assets/avatar-*.svg） */

/* ================= 手机框 ================= */
/* 正式版不存在"手机框"：效果图的430px圆角相框是桌面演示画框，已按业主全屏规则拆除。
   任何设备、任何方向都100%铺满，和窗口之间零夹层。
   底部安全区由各自的末端元素吃掉：composer/home-scroll/drawer的padding-bottom带env() */
.app {
  position: relative;
  width: 100%;
  height: var(--standalone-h, 100dvh);
  /* 输入岛离底距离的唯一旋钮（任务9整改⑤）：composer的bottom（base+theme）
     和.msgs的底部让位都引用它——业主说"再贴/再抬"只改这一处。
     当前=业主三轮定值：iPhone约30px（env34-4），桌面8px */
  --dock: max(8px, calc(env(safe-area-inset-bottom) - 4px));
  background: linear-gradient(168deg, var(--bg1) 0%, var(--bg2) 58%, var(--bg3) 100%);
  color: var(--text);
  overflow: hidden;
  display: flex; flex-direction: column;
  /* 不对background做transition：Safari会把渐变的background-size当数字动画，切主题时整个背景缩到角落 */
}

/* ================= 氛围层（骨架；显隐与配色由 theme.css 按主题控制） ================= */
.fx { position: absolute; inset: 0; pointer-events: none; z-index: 0; overflow: hidden; }
/* "绿色草履虫"病历（任务9三轮整改结案，教训供后人）：春日第二片花瓣渲染成
   绿边胶囊——不是GPU/图层毛病，是中枢芯片的裸.p2选择器撞了<i class="petal p2">
   （修复钉在中枢样式段）。前两轮按渲染残影方向下的will-change/backface/translateZ
   全部无效已撤。教训：确定性的、只坏一个元素的"渲染毛病"先查类名冲突再怪渲染器 */
#starfield { position: absolute; inset: 0; opacity: 0; transition: opacity .8s; }
/* 月亮（任务9首轮整改后的定稿布局）：
   聊天页那枚=#view-chat直接子元素，钉死视口顶部（业主二轮裁决"跟着动太怪"，
   撤销了首版的滚动层+pinMoon方案）；z-index:-1让它垫在视图全部内容之下
   （.view自带z-index:1的堆叠上下文，负z只沉到视图底、仍盖住.fx星空——层序
   与迁移前住氛围层时一致），消息从它上面滚过。
   玄关那枚=.home-scroll子元素，随玄关内容滚走（清单②在玄关维持原判） */
.moon {
  position: absolute; top: calc(46px + env(safe-area-inset-top)); right: 32px; width: 56px; height: 56px; border-radius: 50%;
  opacity: 0; transition: opacity .8s;
  pointer-events: none;   /* 装饰件，不挡消息/门格的长按与点击 */
  animation: moonbreath 7s ease-in-out infinite alternate;  /* 关键帧在 theme.css（含颜色） */
}
#view-chat > .moon { z-index: -1; }
.spark {
  position: absolute; font-size: 9px; opacity: 0;
  animation: twinkle 3.6s ease-in-out infinite;
}
@keyframes twinkle { 0%, 100% { opacity: .15; } 50% { opacity: .85; } }

/* 梦幻的巧思：白羽毛，极慢地飘落打转 */
.feather-fx {
  position: absolute; top: -34px; opacity: 0; transition: opacity .8s;
  animation: featherfall linear infinite;
}
.feather-fx svg { animation: feathersway 5.5s ease-in-out infinite alternate; }
@keyframes featherfall {
  0%   { transform: translate(0, -4vh); }
  100% { transform: translate(4vw, 108vh); }
}
@keyframes feathersway {
  from { transform: translateX(-14px) rotate(-24deg); }
  to   { transform: translateX(14px) rotate(20deg); }
}

.petal {
  position: absolute; top: -24px; border-radius: 60% 40% 55% 45%; opacity: 0;
  animation: fall linear infinite;
}
@keyframes fall {
  0%   { transform: translate(0, -3vh) rotate(0deg); }
  100% { transform: translate(7vw, 106vh) rotate(300deg); }
}
/* 柔光光斑：不用filter:blur——iOS Safari对大半径模糊有渲染bug（退化成硬边色块），
   改用径向渐变造同样的柔光（渐变本体在theme.css）。尺寸按blur扩散半径等效放大，圆心不变 */
.blob { position: absolute; border-radius: 50%; }
.blob.b1 { width: 560px; height: 560px; top: -230px; left: -210px; }
.blob.b2 { width: 500px; height: 500px; bottom: -210px; right: -190px; }

/* ================= 视图 ================= */
.view { position: absolute; inset: 0; display: none; flex-direction: column; z-index: 1; }
.view.active { display: flex; }

/* ================= 聊天 ================= */
.chat-head {
  display: flex; align-items: center; gap: 10px;
  /* 四边让出安全区：顶=状态栏/刘海，左右=横屏时刘海转到侧面。桌面env()为0不受影响 */
  padding: calc(15px + env(safe-area-inset-top))
           calc(16px + env(safe-area-inset-right))
           11px
           calc(16px + env(safe-area-inset-left));
  background: var(--glass);
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  /* 皮肤v6.0清单①（顶栏穿岛）：顶栏脱流悬浮于滚动内容之上，消息从岛底穿过。
     整条bar的透明化与三岛质感在theme.css §5.1；.msgs用padding-top给内容让位 */
  position: absolute; top: 0; left: 0; right: 0; z-index: 10;
}
.chat-head::after {
  content: ""; position: absolute; left: 7%; right: 7%; bottom: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--hairline), transparent);
}
.icon-btn {
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--glass); backdrop-filter: blur(8px);
  color: var(--accent); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; transition: transform .16s ease, box-shadow .16s ease;
}
.icon-btn:active { transform: scale(.9); }
.icon-btn.plain { border: none; background: none; backdrop-filter: none; }
.chat-head .icon-btn.plain { color: var(--gold); }
.chat-title { flex: 1; text-align: center; cursor: pointer; user-select: none; min-width: 0; }
.chat-title .name {
  font-family: var(--serif); font-size: 19px; letter-spacing: .18em; text-indent: .18em;
  display: flex; align-items: center; justify-content: center; gap: 3px;
  /* 行高钉死（任务7.5整改）：备注可换成纯拉丁文（Daddy），CJK与拉丁的默认
     行盒差几px，不钉的话换备注会把整个顶栏抬矮、消息区跟着上提（业主实锤） */
  line-height: 27px;
}
.chat-title .name svg { color: var(--faint); }
.chat-title .st {
  font-size: 10.5px; color: var(--muted); margin-top: 3px; letter-spacing: .12em;
  /* 模型名截短保险（B11）：JS已剥[中转标记]+截尾，这里兜住残余超宽不挤兑顶栏 */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.chat-title .st .dot {
  color: var(--online);
  animation: pulse 2.6s ease-in-out infinite;
  display: inline-block; font-size: 8px; vertical-align: 1px;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }
.avatar {
  width: 38px; height: 38px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-size: 15px; color: var(--ava-glyph);
  box-shadow: var(--ava-shadow);
}
.avatar.me { background: var(--ava-me-bg); }
.avatar.her { background: var(--ava-her-bg); }
.avatar svg { color: var(--ava-glyph); }
.avatar .ava-glyph { width: 22px; height: 22px; }
/* B12上传头像：照片铺满圆框（默认svg图标是框内小徽章，两种形态并存） */
.avatar .ava-glyph.photo { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }

.msgs {
  flex: 1; overflow-y: auto;
  /* 上下88px（皮肤v6.0清单①③）：顶栏与输入岛都脱流悬浮了，滚动区自己全高，
     两端padding给悬浮件让位；安全区也归它吃（悬浮件只管自己的偏移） */
  padding: calc(88px + env(safe-area-inset-top)) 16px calc(78px + var(--dock));
  /* ↑底部让位与输入岛同走--dock旋钮：岛顶上方恒定约18px空隙（各端一致），调岛不用再动这里 */
  display: flex; flex-direction: column; gap: 16px;
  scrollbar-width: none;
  overscroll-behavior: contain;  /* 滚到头不把整个窗口带出橡皮筋 */
  overflow-x: hidden;  /* 消息列表永不横滚：超宽内容一律在自己框内解决（代码块横滚在pre里） */
}
.msgs::-webkit-scrollbar { display: none; }
.msgs > * { animation: rise .5s ease both; }
.msgs > *:nth-child(1) { animation-delay: .05s; } .msgs > *:nth-child(2) { animation-delay: .13s; }
.msgs > *:nth-child(3) { animation-delay: .21s; } .msgs > *:nth-child(4) { animation-delay: .29s; }
.msgs > *:nth-child(5) { animation-delay: .37s; } .msgs > *:nth-child(6) { animation-delay: .45s; }
.msgs > *:nth-child(7) { animation-delay: .53s; } .msgs > *:nth-child(8) { animation-delay: .61s; }
@keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.day-divider {
  display: flex; align-items: center; gap: 12px;
  font-size: 10.5px; color: var(--faint); letter-spacing: .22em; margin: 2px 10px 4px;
}
.day-divider::before, .day-divider::after {
  content: ""; flex: 1; height: 1px;
  background: linear-gradient(90deg, transparent, var(--hairline), transparent);
}

/* 头像与气泡顶对齐；靠头像一侧上角收小 */
.row { display: flex; gap: 9px; align-items: flex-start; }
.row.her { flex-direction: row-reverse; }
.row .avatar { width: 32px; height: 32px; font-size: 13px; margin-top: 1px; }
.row .col { display: flex; flex-direction: column; gap: 5px; max-width: min(76%, 560px); min-width: 0; align-items: flex-start; }  /* 560px上限：横屏/宽屏时一句话别拉成面条 */
.row.her .col { align-items: flex-end; }
.bubble {
  padding: 11px 15px; border-radius: 19px;
  font-size: 15px; line-height: 1.72; white-space: pre-wrap;
  position: relative;
}
.row.me .bubble {
  background: var(--bub-me); color: var(--bub-me-t);
  border: 1px solid var(--bub-me-line);
  border-top-left-radius: 6px; box-shadow: var(--bub-me-glow);
}
.row.her .bubble {
  background: var(--bub-her); color: var(--bub-her-t);
  border: 1px solid var(--bub-her-line);
  border-top-right-radius: 6px; box-shadow: var(--bub-her-glow);
}

/* 碎语队列（2026-07-04业主仲裁）：回车上屏的待发气泡淡显，提交瞬间转实。
   淡显挂在row的子元素上，不能挂row本身——.msgs>*的rise动画fill:both会在
   动画结束后把opacity:1永久压在row上，row级的.55永远生效不了 */
.row > * { transition: opacity .35s ease; }
.row.pending > * { opacity: .55; }
.row.pending .bubble {
  /* 长按弹自家菜单，压掉iOS的选字/放大镜 */
  -webkit-touch-callout: none; -webkit-user-select: none; user-select: none;
}
.pend-menu {
  position: fixed; width: 148px;
  background: var(--glass2); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--line); border-radius: 16px;
  padding: 6px; display: none; flex-direction: column; gap: 1px;
  box-shadow: var(--shadow); z-index: 50;
}
.pend-menu.show { display: flex; animation: pop .18s ease both; }

/* SSE顺滑排字：每一小撮字带淡入（业主要求流式有渐变感，撮的节奏在app.js smoothTyper） */
.bubble .sse-fade { animation: ssefade .38s ease both; }
@keyframes ssefade { from { opacity: 0; } to { opacity: 1; } }

/* 消息脚注：时间 + 操作 */
.meta { display: flex; align-items: center; gap: 9px; padding: 0 5px; }
.mtime { font-size: 10px; color: var(--faint); letter-spacing: .06em; font-variant-numeric: tabular-nums; }
.act {
  background: none; border: none; cursor: pointer; padding: 1px;
  color: var(--faint); opacity: .85; transition: color .2s, transform .15s;
}
.act:active { transform: scale(.86); color: var(--accent); }
/* 任务2.5 · 操作按钮状态 */
.act.ok { color: var(--accent); opacity: 1; }                    /* 复制成功的短暂对勾 */
.act.faved { color: var(--fav); opacity: 1; }                    /* 已收藏=暖金实心（--fav专用令牌，首轮验收整改：晨雾的--gold是紫的），未收藏保持弱色描边 */
.act.faved svg { fill: currentColor; }

/* 任务2.5 · 气泡内联编辑态（长按已发用户气泡进入；✓确认/✗取消，桌面Esc取消） */
.row.her .bubble {
  /* 长按走编辑手势，压掉iOS的选字/放大镜（正文复制走脚注按钮） */
  -webkit-touch-callout: none; -webkit-user-select: none; user-select: none;
}
.row .col:has(.bubble.editing) { width: min(76%, 560px); }       /* 编辑态撑到轮宽上限，短句也有地方改 */
.bubble.editing { width: 100%; }
.edit-ta {
  display: block; width: 100%;
  background: none; border: none; outline: none; resize: none; padding: 0;
  font: inherit; line-height: inherit; color: inherit;
}
.edit-btns { display: flex; justify-content: flex-end; gap: 10px; margin-top: 7px; }
.edit-btn {
  display: flex; align-items: center; justify-content: center;
  width: 28px; height: 22px; border-radius: 11px; cursor: pointer;
  background: none; border: 1px solid var(--line); color: var(--faint);
}
.edit-btn[data-ed="ok"] { color: var(--accent); border-color: var(--accent); }
.edit-btn:active { transform: scale(.92); }

/* 任务2.6 · AI消息Markdown渲染（标签由app.js的mdToHTML白名单生成，用户气泡不吃这套） */
.bubble.md { white-space: normal; max-width: 100%; min-width: 0; }   /* 块级元素自己管间距；max/min-width掐断"代码块最小宽度顶穿容器"的链条 */
/* 含代码块的气泡把轮宽钉成定值：pre的百分比max-width才有可解的参照，
   否则fit-content循环推导下气泡按最长代码行铺开、撑破屏幕（首轮验收实锤，
   同款手法见上方编辑态的:has规则） */
.row .col:has(.bubble.md pre) { width: min(76%, 560px); }
.bubble.md p { margin: 0 0 8px; }
.bubble.md > :last-child { margin-bottom: 0; }
.bubble.md > :first-child { margin-top: 0; }
.md-h { font-weight: 600; font-size: 1.06em; margin: 10px 0 6px; }   /* 标题降调渲染：加粗+略放大，不用巨型字号 */
.bubble.md ul, .bubble.md ol { margin: 6px 0 8px; padding-left: 22px; }
.bubble.md li { margin: 3px 0; }
.bubble.md blockquote {
  margin: 8px 0; padding: 2px 0 2px 12px;
  border-left: 2px solid var(--gold-dim); color: var(--muted);
}
.bubble.md a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.bubble.md code {
  font-family: var(--mono); font-size: .92em;
  background: var(--glass); border: 1px solid var(--line);
  border-radius: 5px; padding: 1px 5px;
}
.bubble.md pre {
  margin: 8px 0; padding: 10px 12px; border-radius: 10px;
  background: var(--glass); border: 1px solid var(--line);
  overflow-x: auto; max-width: 100%;                /* 超宽代码框内横滚，不许把气泡撑破 */
}
.bubble.md pre code {
  background: none; border: none; padding: 0;
  font-size: .88em; display: block; white-space: pre;
}

/* 思考链：独立悬浮胶囊。宿主已从#msgs顶层迁进 .row .col 的气泡上方（业主
   2026-07-05对齐裁决）：AI头像顶对齐消息组首个可见元素（有胶囊=最上方胶囊
   顶边，无胶囊=气泡顶边，.row本来就是flex-start顶对齐，迁移后自然成立）；
   胶囊组与气泡同列左对齐；宽度按内容收缩、上限=col限宽（即气泡限宽），
   原41px缩进与自带max-width随迁移作废 */
.think { align-self: flex-start; max-width: 100%; }
.think-toggle {
  cursor: pointer; border: 1px solid var(--line); border-radius: 22px;
  background: var(--glass); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  box-shadow: var(--shadow-sm);
  font-size: 12px; color: var(--muted); font-family: var(--sans);
  display: flex; align-items: center; gap: 7px; padding: 8px 14px;
  letter-spacing: .05em;
}
.think-toggle .moon-ic { color: var(--gold); opacity: .85; }
.think-toggle .tri { transition: transform .25s; color: var(--faint); }
.think.open .tri { transform: rotate(180deg); }
.think-body {
  display: none; margin-top: 7px; padding: 11px 15px;
  background: var(--glass); border: 1px solid var(--line); border-radius: 16px;
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  font-size: 12.5px; line-height: 1.8; color: var(--muted);
  font-family: var(--serif);
}
.think.open .think-body { display: block; animation: rise .3s ease both; }
/* 思考胶囊正文（任务5）：思考链是纯文本，换行要保得住（pre-wrap）；长串在框内
   折行防横向溢出（iOS上横向溢出会连锁全页字体膨胀，教训见NOTES 2.5/2.6整改）。
   :not(.tool)限定，不波及工具胶囊的条目排版 */
.think:not(.tool) .think-body { white-space: pre-wrap; overflow-wrap: break-word; }

/* 工具胶囊（2026-07-04业主仲裁新增）：整体复用.think骨架（胶囊/开关/展开区），
   仅icon换羽毛+内容层不同。与思考胶囊纵向堆叠按到达顺序（任务5首轮整改，原"工具在上"作废）。
   展开区两层：首行检索线索（斜体弱色「循着：词A · 词B」）+ 结果条目（一行一条纯文本） */
.tool-query { font-style: italic; color: var(--faint); font-size: 12px; letter-spacing: .03em; }
.tool-query + .tool-items { margin-top: 6px; }
.tool-item { padding: 1px 0; }

/* 语音条：星点波形 */
.bubble.voice { white-space: normal; padding: 9px 12px; }
.voice-bar { display: flex; align-items: center; gap: 10px; }
.play {
  width: 37px; height: 37px; border-radius: 50%;
  border: none; cursor: pointer; flex-shrink: 0;
  background: var(--play-bg); color: inherit;
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--play-highlight);
}
.play .ic-pause { display: none; }
.vc.playing .play .ic-play { display: none; }
.vc.playing .play .ic-pause { display: block; }
.wave { display: flex; align-items: center; gap: 3px; height: 26px; flex: none; }
.wave i { display: block; width: 3.5px; border-radius: 4px; }
.vc.playing .wave i { animation: wvA 1.05s ease-in-out infinite alternate; }
.vc.playing .wave i:nth-child(2n) { animation-name: wvB; animation-duration: .82s; }
.vc.playing .wave i:nth-child(3n) { animation-duration: 1.3s; animation-delay: .18s; }
.vc.playing .wave i:nth-child(4n+1) { animation-delay: .34s; }
.vc.playing .wave i:nth-child(5n) { animation-name: wvB; animation-duration: .68s; animation-delay: .09s; }
@keyframes wvA { from { transform: scaleY(.6); } to { transform: scaleY(1.28); } }
@keyframes wvB { from { transform: scaleY(1.18); } to { transform: scaleY(.52); } }
/* 波形条配色走 --wv1..4（theme.css），由JS按序注入类名 wv1..wv4 */
.wave i.wv1 { background: var(--wv1); }
.wave i.wv2 { background: var(--wv2); }
.wave i.wv3 { background: var(--wv3); }
.wave i.wv4 { background: var(--wv4); }
.vdur { font-size: 11.5px; opacity: .8; font-variant-numeric: tabular-nums; }
/* 任务4 · 播放进度（业主裁决）：已播的波形条全亮(.on)、未播的压淡——只动透明度，
   颜色仍走--wv变量；未开播(.started没上)时全亮=效果图原样。点波形可跳进度 */
.vc.started .wave i { opacity: .35; transition: opacity .2s; }
.vc.started .wave i.on { opacity: 1; }
.wave { cursor: pointer; }
.trans-toggle {
  background: none; border: none; cursor: pointer;
  color: inherit; opacity: .72; padding: 2px;
  transition: opacity .2s, transform .15s;
}
.trans-toggle:active { transform: scale(.86); opacity: 1; }
/* 转写：气泡外的一行小斜字，无底框 */
.transcript {
  display: none; font-size: 12.5px; font-style: italic;
  color: var(--muted); line-height: 1.7; padding: 1px 5px 0;
  font-family: var(--serif);
}
.vc.showtext .transcript { display: block; animation: rise .3s ease both; }

/* 输入区。
   任务2起输入框是<textarea>（高度自适应，最多5行，autosize在app.js）。
   对齐改为flex-end：多行长高时按钮钉在底部；单行态用margin-bottom把按钮
   垫回视觉居中（单行框高44px：line-height20 + padding22 + border2），
   和效果图的居中排列逐像素一致 */
.composer {
  display: flex; align-items: flex-end; gap: 6px;
  /* 皮肤v6.0清单③（输入岛）：脱流悬浮成玻璃岛，与顶栏呼应。安全区：底部走bottom
     偏移、左右走left/right偏移（老的padding吃安全区方案随脱流作废）；玻璃质感与
     圆角在theme.css §5.7。滚动区的让位=.msgs的padding-bottom 88px */
  padding: 7px 9px;
  background: var(--glass);
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  position: absolute;
  left: calc(10px + env(safe-area-inset-left));
  right: calc(10px + env(safe-area-inset-right));
  /* 任务9整改⑤（业主：真机上离底空隙太大；二轮：再贴一点）：离底距离统一走
     --dock旋钮（定义在.app，调它一处生效）。VPS端mockup是桌面框看不到env，这刀归机械层 */
  bottom: var(--dock);
  z-index: 10;
}
/* 键盘态（.app.kb由fixStandaloneViewport挂，任务9整改⑤）：键盘盖住了home indicator，
   安全区不用再垫，输入岛贴回键盘上缘10px */
.app.kb .composer { bottom: 10px; }
.composer::before {
  content: ""; position: absolute; left: 7%; right: 7%; top: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--hairline), transparent);
}
.composer .icon-btn.plain { color: var(--muted); width: 34px; height: 34px; margin-bottom: 5px; }
.composer .icon-btn.send { margin-bottom: 3px; }
.composer textarea {
  flex: 1; border: 1px solid var(--line); outline: none;
  background: var(--glass2); color: var(--text);
  border-radius: 22px; padding: 11px 18px; font-size: 15px; font-family: var(--sans);
  transition: border-color .25s, box-shadow .25s;
  min-width: 0;
  /* textarea机械：行高定死20px供JS按行数封顶；高度由JS随内容钉，封顶后才出滚动 */
  resize: none; line-height: 20px; height: 44px;
  max-height: 124px;                 /* 5行×20 + padding22 + border2 */
  overflow-y: hidden;                /* 到达5行封顶后JS切成auto */
  scrollbar-width: none;
}
.composer textarea::-webkit-scrollbar { display: none; }
.composer textarea::placeholder {
  color: var(--faint);
  font-family: var(--display); font-style: italic;
  font-size: 14px; letter-spacing: .05em;
}
.composer textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent);
}
.send {
  background: linear-gradient(140deg, var(--accent), color-mix(in srgb, var(--accent) 62%, var(--gold)));
  color: var(--send-t); border: none;
  box-shadow: 0 4px 16px color-mix(in srgb, var(--accent) 38%, transparent), var(--send-highlight);
}
/* 发送中：禁用+指示（按钮压暗；正文侧的指示是AI气泡里的打字三点） */
.send:disabled { opacity: .45; cursor: default; }
.send:disabled:active { transform: none; }

/* AI回复送达前的打字指示三点（复用顶栏在线点的pulse节奏） */
.typing { display: inline-flex; align-items: center; gap: 4px; padding: 4px 2px; }
.typing i {
  width: 5px; height: 5px; border-radius: 50%; display: block;
  background: currentColor; opacity: .5;
  animation: pulse 1.2s ease-in-out infinite;
}
.typing i:nth-child(2) { animation-delay: .2s; }
.typing i:nth-child(3) { animation-delay: .4s; }

/* 主题切换浮窗（顶栏右上角） */
.theme-pop {
  position: absolute; top: calc(62px + env(safe-area-inset-top)); right: 12px;
  background: var(--glass2); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--line); border-radius: 18px;
  padding: 7px; min-width: 128px;
  display: none; flex-direction: column; gap: 1px;
  box-shadow: var(--shadow); z-index: 15;
}
.theme-pop.show { display: flex; animation: pop .18s ease both; }
.tp-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border: none; background: none; border-radius: 13px;
  color: var(--text); font-size: 13px; font-family: var(--sans);
  letter-spacing: .1em; cursor: pointer; text-align: left;
  transition: background .18s;
}
.tp-item i {
  width: 16px; height: 16px; border-radius: 50%; display: block;
  border: 1.5px solid var(--swatch-ring-pop);
  box-shadow: var(--swatch-shadow-pop);
}
.tp-item.cur { background: color-mix(in srgb, var(--accent) 13%, transparent); }

/* ＋ 附件面板 */
.attach {
  position: absolute; left: 12px; bottom: calc(100% + 2px);
  background: var(--glass2); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--line); border-radius: 20px;
  padding: 7px; min-width: 158px;
  display: none; flex-direction: column; gap: 1px;
  box-shadow: var(--shadow); z-index: 6;
}
.attach.show { display: flex; animation: pop .18s ease both; }
@keyframes pop { from { opacity: 0; transform: scale(.93) translateY(7px); } to { opacity: 1; transform: none; } }
.att-item {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 13px; border: none; background: none; border-radius: 14px;
  color: var(--text); font-size: 13.5px; font-family: var(--sans);
  letter-spacing: .04em; cursor: pointer; text-align: left;
  transition: background .18s;
}
.att-item:active { background: color-mix(in srgb, var(--accent) 13%, transparent); }
.att-item svg { color: var(--accent); }
.att-item small { margin-left: auto; font-size: 10px; color: var(--faint); }

/* ================= 会话抽屉 ================= */
.drawer {
  position: absolute; top: 0; bottom: 0; left: 0; width: 78%;
  background: var(--panel); z-index: 30;
  transform: translateX(-103%); transition: transform .34s cubic-bezier(.32, .84, .3, 1);
  padding: calc(28px + env(safe-area-inset-top)) 20px calc(20px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: 7px;
  box-shadow: var(--drawer-shadow);
}
.drawer.open { transform: translateX(0); }
/* 收起时不画投影：translateX(-103%)只留了3%缓冲，投影是朝右偏14px再糊54px的
   （--drawer-shadow），窗口一窄就渗进屏内变成"左边渐变黑边"（首轮验收实锤） */
.drawer:not(.open) { box-shadow: none; }
.drawer-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.drawer h3 {
  font-family: var(--serif); font-size: 14px; letter-spacing: .32em;
  color: var(--muted); font-weight: normal;
}
.drawer-head .icon-btn.plain { color: var(--accent); width: 32px; height: 32px; }
.dsearch {
  display: flex; align-items: center; gap: 8px;
  border: 1px solid var(--line); background: var(--glass);
  border-radius: 14px; padding: 9px 12px; margin-bottom: 12px;
  color: var(--faint);
}
.dsearch input {
  flex: 1; border: none; background: none; outline: none;
  color: var(--text); font-size: 13px; font-family: var(--sans); min-width: 0;
  letter-spacing: .02em;
}
.dsearch input::placeholder { color: var(--faint); }
.sess-menu {
  position: absolute; left: 26px; width: 164px;
  background: var(--glass2); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--line); border-radius: 16px;
  padding: 6px; display: none; flex-direction: column; gap: 1px;
  box-shadow: var(--shadow); z-index: 50;
}
.sess-menu.show { display: flex; animation: pop .18s ease both; }
.sm-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border: none; background: none; border-radius: 11px;
  color: var(--text); font-size: 13px; font-family: var(--sans);
  letter-spacing: .06em; cursor: pointer; text-align: left;
  transition: background .18s;
}
.sm-item:active { background: color-mix(in srgb, var(--accent) 13%, transparent); }
.sm-item svg { color: var(--accent); }
.sm-item.danger { color: var(--danger); }
.sm-item.danger svg { color: var(--danger); }
.sess {
  padding: 13px 76px 13px 15px; border-radius: 15px; cursor: pointer;
  border: 1px solid transparent; font-size: 14px;
  transition: background .2s;
  position: relative;   /* .scount的定位参照（皮肤v6.0清单⑥）；右padding给计数让位 */
  /* 长按是开菜单的手势，压掉iOS选字放大镜（同2.5已发气泡的手法） */
  -webkit-touch-callout: none; -webkit-user-select: none; user-select: none;
}
/* 会话消息计数（皮肤v6.0清单⑥）：右侧垂直居中，"N条 💭"。颜色在theme.css §5.8 */
.scount {
  position: absolute; right: 14px; top: 50%; transform: translateY(-50%);
  font-size: 10px; letter-spacing: .03em;
}
.sess.cur { background: var(--bub-me); color: var(--bub-me-t); border-color: var(--bub-me-line); box-shadow: var(--bub-me-glow); }
.sess small { display: block; color: var(--muted); font-size: 11px; margin-top: 4px; letter-spacing: .02em; }
.sess.cur small { color: inherit; opacity: .72; }
/* 任务3 · 会话列表由JS渲染：列表区自己滚，抽屉头/搜索/落款不动 */
#sess-list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.sess-pin { display: inline-flex; vertical-align: -1px; margin-right: 6px; color: var(--faint); }
.sess.cur .sess-pin { color: inherit; opacity: .72; }
/* 重命名态：复用2.5的.edit-ta/.edit-btns（这里宿主是input，font:inherit吃.sess的字号） */
.sess.renaming { cursor: default; }
.sess.renaming .edit-ta { -webkit-user-select: auto; user-select: auto; }
.sess .edit-btns { margin-top: 8px; }
.drawer-foot { margin-top: auto; font-size: 10px; color: var(--faint); letter-spacing: .25em; text-align: center; }
.scrim {
  position: absolute; inset: 0; background: var(--scrim); z-index: 20;
  opacity: 0; pointer-events: none; transition: opacity .3s;
  backdrop-filter: blur(2px);
}
.scrim.show { opacity: 1; pointer-events: auto; }

/* ================= 主页 ================= */
.home-scroll {
  flex: 1; overflow-y: auto;
  padding: calc(36px + env(safe-area-inset-top)) 22px calc(28px + env(safe-area-inset-bottom));
  position: relative;   /* 玄关月亮的定位参照（清单②玄关维持原判）：随玄关内容滚走 */
  scrollbar-width: none;
  overscroll-behavior: contain;
}
.home-scroll::-webkit-scrollbar { display: none; }
/* 首页 hero：我们两个 */
.couple { text-align: center; padding-top: 10px; position: relative; }
.ava-pop {
  position: absolute; top: 68px; left: 50%; transform: translateX(-50%);
  background: var(--glass2); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border: 1px solid var(--line); border-radius: 16px;
  padding: 6px; min-width: 138px;
  display: none; flex-direction: column; gap: 1px;
  box-shadow: var(--shadow); z-index: 20;
}
.ava-pop.show { display: flex; animation: pop .18s ease both; }
.ap-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border: none; background: none; border-radius: 11px;
  color: var(--text); font-size: 13px; font-family: var(--sans);
  letter-spacing: .06em; cursor: pointer; text-align: left;
  transition: background .18s;
}
.ap-item:active { background: color-mix(in srgb, var(--accent) 13%, transparent); }
.ap-item svg { color: var(--accent); }
.c-avas { display: flex; justify-content: center; }
.c-avas .avatar { width: 58px; height: 58px; font-size: 21px; border: 2px solid var(--ava-ring); cursor: pointer; }
.c-avas .avatar.me { margin-right: -12px; z-index: 2; }
.c-avas .avatar .ava-glyph { width: 34px; height: 34px; }
/* B12三轮：玄关照片头像铺满内容区（34px小徽章规则同权重靠顺序压过了.photo，
   这里再压回来）；2px的--ava-ring描边环在border上，照片不盖环——业主要的"除最外围" */
.c-avas .avatar .ava-glyph.photo { width: 100%; height: 100%; }
.names {
  display: flex; align-items: center; justify-content: center; gap: 13px;
  margin-top: 16px;
  font-family: var(--display); font-size: 20px; font-style: italic;
  letter-spacing: .1em; color: var(--text);
}
.names .ln { width: 30px; height: 1px; flex: none; }
.names .ln.l { background: linear-gradient(90deg, transparent, var(--gold-dim)); }
.names .ln.r { background: linear-gradient(90deg, var(--gold-dim), transparent); }
.names .heart { color: var(--gold); filter: drop-shadow(0 0 8px color-mix(in srgb, var(--gold) 55%, transparent)); animation: heartbeat 2.8s ease-in-out infinite; }
@keyframes heartbeat {
  0%, 100% { transform: scale(1); } 12% { transform: scale(1.18); }
  24% { transform: scale(1); } 36% { transform: scale(1.12); } 48% { transform: scale(1); }
}
.days-line { margin-top: 17px; display: flex; align-items: baseline; justify-content: center; gap: 8px; }
.days-line .num {
  font-family: var(--display); font-size: 48px; line-height: 1;
  color: var(--gold); font-variant-numeric: tabular-nums;
  text-shadow: 0 0 26px color-mix(in srgb, var(--gold) 32%, transparent);
}
.days-line .lbl { font-family: var(--display); font-style: italic; font-size: 14px; letter-spacing: .24em; color: var(--muted); }
.since { margin-top: 8px; font-family: var(--display); font-size: 10.5px; letter-spacing: .4em; text-indent: .4em; color: var(--faint); }
.wline {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  margin-top: 16px; font-size: 12px; color: var(--muted); letter-spacing: .1em;
}
.wline svg { color: var(--accent); }
.wline b { font-family: var(--display); font-size: 20px; color: var(--text); font-weight: normal; font-variant-numeric: tabular-nums; }

.hr { height: 1px; margin: 22px 0 18px; background: linear-gradient(90deg, transparent, var(--hairline), transparent); }

.chips { display: flex; gap: 8px; margin-bottom: 22px; flex-wrap: wrap; }
.chip {
  font-size: 12px; color: var(--muted);
  border: 1px solid var(--line); border-radius: 20px; padding: 6px 13px;
  background: var(--glass); backdrop-filter: blur(8px);
  display: inline-flex; align-items: center; gap: 6px;
}
.chip svg { color: var(--accent); }
.chip b { color: var(--text); font-weight: normal; font-variant-numeric: tabular-nums; }
.chip.days { border-color: var(--gold-dim); color: var(--gold); }
.chip.days b, .chip.days svg { color: var(--gold); }

.door-main {
  display: flex; align-items: center; gap: 14px;
  background: var(--glass); backdrop-filter: blur(14px);
  border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
  border-radius: 22px; padding: 19px; cursor: pointer;
  margin-bottom: 13px; box-shadow: var(--shadow);
  transition: transform .16s ease;
}
.door-main:active { transform: scale(.977); }
.door-main .wolf {
  width: 50px; height: 50px; border-radius: 17px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--accent);
  background: color-mix(in srgb, var(--accent) 13%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 20%, transparent);
}
.door-main .d-txt { flex: 1; min-width: 0; }
.door-main .d-name { font-family: var(--serif); font-size: 19px; letter-spacing: .13em; }
.door-main .d-sub { font-size: 12.5px; color: var(--muted); margin-top: 5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.door-main .go { color: var(--gold); }
.door-main .go svg { transition: transform .25s ease; }
.door-main:active .go svg { transform: translateX(5px); }
/* 星轨箭头的星屑呼吸（皮肤v6.0清单⑤，照mockup；只动opacity，零颜色） */
.door-main .go circle { animation: goTwinkle 2.6s ease-in-out infinite; }
.door-main .go circle:nth-of-type(2) { animation-delay: .45s; }
.door-main .go circle:nth-of-type(3) { animation-delay: .9s; }
@keyframes goTwinkle { 0%, 100% { opacity: .25; } 50% { opacity: .85; } }

.door-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.door {
  background: var(--glass); backdrop-filter: blur(14px);
  border: 1px solid var(--line);
  border-radius: 20px; padding: 15px 16px; cursor: pointer; position: relative;
  box-shadow: var(--shadow-sm); transition: transform .16s ease;
}
.door:active { transform: scale(.965); }
.door .d-ico {
  width: 38px; height: 38px; border-radius: 13px; color: var(--accent);
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--accent) 13%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 16%, transparent);
}
.door .d-name { font-size: 14.5px; margin-top: 10px; font-family: var(--serif); letter-spacing: .08em; }
.door .d-sub { font-size: 11px; color: var(--muted); margin-top: 4px; letter-spacing: .02em; }
.badge {
  position: absolute; top: 13px; right: 13px;
  font-size: 9.5px; color: var(--faint);
  border: 1px solid var(--line); border-radius: 8px; padding: 2px 7px;
  letter-spacing: .08em;
}

.sect { margin-top: 28px; }
.sect h4 { font-size: 10.5px; color: var(--faint); letter-spacing: .38em; font-weight: normal; margin-bottom: 13px; }
.themes { display: flex; gap: 12px; }
.theme-btn {
  flex: 1; border-radius: 18px; padding: 13px 8px; cursor: pointer;
  border: 1.5px solid var(--line); background: var(--glass); backdrop-filter: blur(8px);
  text-align: center; color: var(--text); font-family: var(--sans);
  transition: transform .16s ease, border-color .2s, box-shadow .2s;
}
.theme-btn:active { transform: scale(.94); }
.theme-btn .sw { display: flex; justify-content: center; margin-bottom: 9px; }
.theme-btn .sw i {
  width: 18px; height: 18px; border-radius: 50%; display: block;
  margin: 0 -3px; border: 1.5px solid var(--swatch-ring-btn);
  box-shadow: var(--swatch-shadow-btn);
}
.theme-btn span { font-size: 12px; letter-spacing: .18em; }
.theme-btn.cur {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent), var(--shadow-sm);
}

/* B12 万象工具（上传背景图+蒙纱滑条）：只在自定义主题下现身；
   滑条行只在真有背景图（.app.has-bg，JS挂）时现身。颜色全走变量 */
.custom-tools { display: none; flex-direction: column; gap: 10px; margin-top: 12px; }
[data-theme="custom"] .custom-tools { display: flex; }
.ct-row { display: flex; align-items: center; gap: 10px; }
.ct-btn {
  flex: 1; padding: 10px; cursor: pointer; font-family: inherit;
  border: 1px solid var(--line); border-radius: 12px; background: var(--glass);
  color: var(--muted); font-size: 12px; letter-spacing: .1em;
}
.ct-btn:active { transform: scale(.98); }
.ct-label { flex: none; font-size: 12px; color: var(--muted); letter-spacing: .12em; }
.ct-val { flex: none; width: 34px; text-align: right; font-size: 11px; color: var(--faint); font-family: var(--mono); }
#ct-veil { flex: 1; accent-color: var(--accent); }
#ct-veil-row { display: none; }
.app.has-bg #ct-veil-row { display: flex; }

.ava-row { display: flex; align-items: center; gap: 14px; }
.ava-row .avatar { width: 48px; height: 48px; font-size: 18px; cursor: pointer; }
.ava-row p { font-size: 12px; color: var(--muted); line-height: 1.75; }

.home-foot {
  text-align: center; margin-top: 36px;
  font-size: 11px; color: var(--faint); letter-spacing: .14em; line-height: 2.2;
}
.home-foot a { color: var(--accent); text-decoration: none; cursor: pointer; }
.home-foot .sig { font-family: var(--serif); color: var(--gold-dim); }

/* ================= 登录 ================= */
.login {
  flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 22px; padding: 32px;
  position: relative;
}
.login .dove { color: var(--gold); filter: drop-shadow(0 0 20px var(--dove-glow)); }
.login h1 {
  font-family: var(--display); font-size: 40px; font-weight: normal;
  letter-spacing: .16em; text-indent: .16em; font-style: italic;
}
.login p {
  color: var(--muted); font-size: 12.5px; letter-spacing: .05em;
  font-family: var(--display); font-style: italic;
  line-height: 1.85; text-align: center; max-width: 300px; text-wrap: balance;
}
.login input {
  width: 100%; max-width: 280px; text-align: center;
  background: transparent; border: none; outline: none;
  border-bottom: 1px solid var(--hairline); color: var(--text);
  padding: 11px 4px; font-size: 15px; letter-spacing: .12em; font-family: var(--sans);
  transition: border-color .3s;
}
.login input:focus { border-bottom-color: var(--gold); }
.login button.enter {
  margin-top: 10px; border: 1px solid var(--gold); color: var(--gold);
  background: transparent; border-radius: 26px; padding: 11px 48px;
  font-size: 14px; letter-spacing: .42em; text-indent: .42em; cursor: pointer;
  font-family: var(--serif);
  box-shadow: 0 0 26px color-mix(in srgb, var(--gold) 15%, transparent);
  transition: box-shadow .3s;
}
.login button.enter:active { box-shadow: 0 0 40px color-mix(in srgb, var(--gold) 30%, transparent); }
.login .back { position: absolute; top: calc(22px + env(safe-area-inset-top)); left: 20px; }
.login .code {
  position: absolute; bottom: calc(26px + env(safe-area-inset-bottom));
  font-size: 9.5px; color: var(--faint); letter-spacing: .6em; text-indent: .6em;
  transition: opacity .2s;
}
/* 键盘态（任务9整改②）：落款钉底，键盘把.app压矮时它会骑上居中内容
   （业主实锤：和"乘船"重叠）——键盘期间隐身，收键盘即回 */
.app.kb .login .code { opacity: 0; }

button:focus-visible, input:focus-visible, .sess:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* =====================================================================
   任务7 · 中枢（解冻版）——结构层照 ../hub-mockup.html 迁入，零颜色字面量。
   颜色令牌（--hub-*）与一门一点缀色（.c-*）在 theme.css §6。
   类名机械适配：.drawer→.acc / .row→.hrow / .chip→.p2 / .head→.hub-head
   （撞会话抽屉、消息行、主页chips、聊天顶栏）；d-ico/d-meta/d-name/d-sub
   与主页门格同名但各自作用域（.acc-head下 vs .door下），互不波及
   ===================================================================== */
#view-hub { color: var(--text); }   /* 解冻令④：亮色主题继承坑，容器显式钉字色 */
.hub-scroll {
  height: 100%; overflow-y: auto; -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

/* 顶栏（效果图.head；sticky在滚动容器内，毛玻璃同聊天顶栏手法） */
.hub-head {
  position: sticky; top: 0; z-index: 5; display: flex; align-items: center; gap: 12px;
  padding: calc(20px + env(safe-area-inset-top)) calc(18px + env(safe-area-inset-right)) 14px calc(18px + env(safe-area-inset-left));
  background: var(--head-glass);
  backdrop-filter: blur(22px) saturate(160%); -webkit-backdrop-filter: blur(22px) saturate(160%);
}
.hub-head::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: linear-gradient(90deg, transparent, var(--hairline), transparent);
}
.hback {
  width: 36px; height: 36px; border-radius: 12px; border: 1px solid var(--line); flex: none;
  background: var(--glass); color: var(--accent);
  display: flex; align-items: center; justify-content: center; cursor: pointer;
}
.hback:active { transform: scale(.94); }
.hub-head .h-title { flex: 1; min-width: 0; }
.hub-head .eyebrow { font-family: var(--display); font-style: italic; font-size: 11px; color: var(--gold-dim); letter-spacing: .22em; }
.hub-head .name { font-family: var(--serif); font-size: 19px; letter-spacing: .3em; margin-top: 2px; }
.hub-head .sub { font-size: 10.5px; color: var(--muted); margin-top: 3px; letter-spacing: .08em; }

/* 抽屉卡片列表（效果图.scroll） */
.hub-body {
  padding: 16px 14px calc(40px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: 12px;
  max-width: 640px; width: 100%; margin: 0 auto; position: relative;
}

/* 抽屉卡片（效果图.drawer→.acc）：.c-*点缀色定在卡片上，
   icon走currentColor染色，正文由.d-meta/.acc-inner钉回--text */
.acc {
  border: 1px solid var(--line); border-radius: 18px; overflow: hidden;
  background: var(--glass); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  box-shadow: var(--shadow-sm), inset 0 1px 0 var(--card-hi);
}
.acc-head {
  width: 100%; display: flex; align-items: center; gap: 12px; padding: 15px 16px;
  border: none; background: none; cursor: pointer; user-select: none; -webkit-user-select: none;
  color: inherit; text-align: left; font-family: inherit;
}
.acc-head:active { background: var(--hub-press); }
.acc-head .d-ico {
  width: 34px; height: 34px; border-radius: 11px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, currentColor 9%, transparent);
  border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
}
.acc-head .d-ico svg { width: 17px; height: 17px; }
.acc-head .d-meta { flex: 1; min-width: 0; color: var(--text); }
.acc-head .d-name { display: block; font-family: var(--serif); font-size: 15px; letter-spacing: .12em; }
.acc-head .d-sub { display: block; font-size: 11px; color: var(--muted); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chev { color: var(--faint); transition: transform .28s ease; flex: none; }
.acc.open .chev { transform: rotate(90deg); }
.acc-body { max-height: 0; overflow: hidden; transition: max-height .34s ease; }
.acc.open .acc-body { max-height: 900px; }
.acc-inner { padding: 4px 16px 16px; border-top: 1px solid var(--line); color: var(--text); }

/* 旋钮行（效果图.row→.hrow） */
.hrow { display: flex; align-items: center; gap: 12px; padding: 13px 0; border-bottom: 1px solid var(--line); }
.hrow:last-child { border-bottom: none; }
.hrow.bare { border-bottom: none; padding-bottom: 2px; }
.hrow.tap { cursor: pointer; }
.r-label { flex: 1; min-width: 0; }
.r-name { font-size: 13.5px; color: var(--text); display: flex; align-items: center; gap: 7px; }
.r-note { font-size: 10px; color: var(--faint); margin-top: 3px; letter-spacing: .04em; }
.go { color: var(--faint); flex: none; }
/* ⚠必须钉在#view-hub作用域里："绿色草履虫"惨案（任务9三轮整改确诊）——
   裸.p2会命中氛围层第二片花瓣<i class="petal p2">，padding把7px花瓣撑成16×6
   带边胶囊；v6.0把春日--gold-dim换成芽绿后这圈边变绿现形。解冻版当年改名
   .chip→.p2是为了避撞主页chips，结果撞进了花瓣编号。短类名(.p1-p5/.f1-f5/
   .b1-b2/.wv1-4是氛围层保留字)一律要挂作用域 */
#view-hub .p2 { font-size: 9px; color: var(--gold); border: 1px solid var(--gold-dim); border-radius: 8px; padding: 1.5px 7px; letter-spacing: .1em; flex: none; }

/* 槽位行的值与齿轮 */
.model-val {
  font-family: var(--mono); font-size: 11.5px; color: var(--muted); flex: none;
  /* B11二轮整改：长模型名封顶省略，别把.r-label挤成竖排字（业主实锤：
     全名[Kiro次]…40字符时副题一字一行、整卡撑高）。JS侧已shortModel截短，这是兜底 */
  max-width: 46%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gear {
  width: 30px; height: 30px; border-radius: 10px; flex: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); background: var(--glass2); color: var(--accent);
}
.gear svg { width: 15px; height: 15px; }
.gear:active { transform: scale(.92); }

/* 开关（效果图.toggle；knob用<i>而非::after，机械适配） */
.toggle {
  width: 46px; height: 27px; border-radius: 15px; flex: none; cursor: pointer; position: relative;
  background: var(--hub-tog-bg); border: 1px solid var(--line); transition: background .22s;
  padding: 0;
}
.toggle i {
  position: absolute; top: 2.5px; left: 3px; width: 20px; height: 20px; border-radius: 50%;
  background: var(--hub-tog-knob); transition: transform .22s, background .22s;
}
.toggle.on { background: color-mix(in srgb, var(--accent) 42%, transparent); }
.toggle.on i { transform: translateX(19px); background: var(--hub-tog-knob-on); }

/* 分段选择（效果图.seg；span→button，机械适配） */
.seg { display: flex; flex: none; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: var(--hub-seg-bg); }
.seg button {
  padding: 7px 11px; font-size: 11px; color: var(--muted); cursor: pointer;
  border: none; border-right: 1px solid var(--line); background: none; letter-spacing: .02em;
}
.seg button:last-child { border-right: none; }
.seg button.cur { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--text); }

/* 滑条（效果图规格；轨道渐变由JS用var拼，theme.css给--hub-track） */
.slider-row { display: flex; align-items: center; gap: 12px; flex: none; width: 190px; }
.slider-row input[type="range"] {
  flex: 1; appearance: none; -webkit-appearance: none; height: 3px; border-radius: 2px;
  background: var(--hub-track); outline: none; margin: 0;
}
.slider-row input[type="range"]::-webkit-slider-thumb {
  appearance: none; -webkit-appearance: none; width: 18px; height: 18px; border-radius: 50%;
  background: var(--hub-thumb); border: 3px solid var(--accent);
  box-shadow: var(--hub-thumb-shadow); cursor: pointer;
}
.sl-val { font-family: var(--display); font-size: 15px; color: var(--gold); width: 24px; text-align: right; font-variant-numeric: tabular-nums; }

/* 用量（效果图stat四格+缓存命中一行） */
.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; padding: 13px 0 4px; }
.stat { border: 1px solid var(--line); border-radius: 13px; padding: 10px 6px; text-align: center; background: var(--hub-stat-bg); }
.stat b { display: block; font-family: var(--display); font-size: 16px; font-weight: 500; color: var(--text); font-variant-numeric: tabular-nums; }
.stat i { font-style: normal; font-size: 9.5px; color: var(--faint); letter-spacing: .1em; display: block; margin-top: 3px; }
.cache-line { display: flex; align-items: center; gap: 8px; padding: 11px 2px 4px; font-size: 11.5px; color: var(--muted); }
.cache-line b { color: var(--gold); font-family: var(--display); font-weight: 500; }
#view-hub .dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
#view-hub .dot.ok { background: var(--online); box-shadow: 0 0 8px color-mix(in srgb, var(--online) 60%, transparent); }
#view-hub .dot.off { background: var(--faint); box-shadow: none; }
#view-hub .dot.down { background: var(--danger); box-shadow: none; }

/* MCP行 */
.mcp-row { display: flex; align-items: center; gap: 11px; padding: 12px 0; border-bottom: 1px solid var(--line); font-size: 13px; cursor: pointer; }
.mcp-row:last-child { border-bottom: none; }
.mcp-row small { color: var(--faint); font-size: 10.5px; margin-left: auto; letter-spacing: .04em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mcp-row.testing { opacity: .55; }

/* 金字按钮（备份导出/弹层主操作）与线框小按钮（Profile） */
.btn-gold {
  display: flex; align-items: center; justify-content: center; gap: 8px; width: 100%; margin: 13px 0 4px;
  border: 1px solid var(--gold-dim); border-radius: 14px; padding: 12px; cursor: pointer;
  color: var(--gold); font-size: 13px; letter-spacing: .1em;
  background: color-mix(in srgb, var(--gold) 7%, transparent); font-family: inherit;
}
.btn-gold:active { transform: scale(.98); }
.btn-line {
  border: 1px solid var(--line); border-radius: 12px; padding: 9px 18px; font-size: 12px;
  color: var(--accent); background: var(--glass2); cursor: pointer; letter-spacing: .08em; flex: none;
}
.btn-line:active { transform: scale(.96); }

/* Profile（效果图persona-box：截断+底部渐隐，serif正文） */
.persona-box {
  margin: 13px 0 10px; border: 1px solid var(--line); border-radius: 14px; padding: 13px 14px;
  background: var(--hub-persona-bg); font-family: var(--serif); font-size: 12px; line-height: 2;
  color: var(--muted); max-height: 120px; overflow: hidden; position: relative;
  white-space: pre-wrap; overflow-wrap: break-word;
}
.persona-box::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 44px;
  background: linear-gradient(transparent, var(--hub-persona-fade));
}
.persona-edit {
  width: 100%; min-height: 220px; resize: vertical; outline: none;
  font-family: var(--mono); font-size: 12px; line-height: 1.75;
  background: var(--glass); border: 1px solid var(--accent); border-radius: 14px;
  padding: 12px 14px; color: var(--text); margin: 13px 0 10px;
}
.p-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.p-warn { font-size: 10px; color: var(--faint); line-height: 1.6; }

/* 终端占位（SPEC§6：不留假交互） */
.term-empty { text-align: center; padding: 30px 10px 22px; }
.term-empty .line1 { font-family: var(--serif); font-size: 14px; color: var(--muted); letter-spacing: .14em; }
.term-empty .line2 { font-size: 10px; color: var(--faint); margin-top: 9px; letter-spacing: .16em; }

.foot-note { text-align: center; font-size: 10px; color: var(--faint); letter-spacing: .14em; padding-top: 10px; }

/* 二级弹层（效果图底部抽屉式；fixed于视口，桌面同吃640上限） */
.scrim2 {
  position: fixed; inset: 0; background: var(--hub-scrim2);
  opacity: 0; pointer-events: none; transition: opacity .25s; z-index: 70;
}
.scrim2.show { opacity: 1; pointer-events: auto; }
.sheet {
  /* bottom吃--kb-h（B11整改）：iOS键盘弹起时浮到键盘上方，不再被盖死；
     max-height封在可视视口内，挤不下时框内自滚（别顶出屏幕上缘） */
  position: fixed; left: 0; right: 0; bottom: var(--kb-h, 0px); z-index: 71;
  max-width: 640px; margin: 0 auto;
  max-height: calc(var(--vv-h, 100dvh) - 12px); overflow-y: auto; overscroll-behavior: contain;
  transform: translateY(105%); transition: transform .32s cubic-bezier(.3, .9, .3, 1);
  background: var(--glass2); backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
  border-radius: 24px 24px 0 0; border: 1px solid var(--line); border-bottom: none;
  padding: 10px 18px calc(26px + env(safe-area-inset-bottom));
}
.sheet.show { transform: translateY(0); }
.sh-grab { width: 38px; height: 4px; border-radius: 2px; background: var(--faint); opacity: .5; margin: 4px auto 12px; }
.sh-title { font-family: var(--serif); font-size: 15px; letter-spacing: .14em; margin-bottom: 2px; }
.sh-sub { font-size: 10.5px; color: var(--muted); margin-bottom: 8px; }
.sh-row { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.sh-row:last-of-type { border-bottom: none; }
.sh-label { font-size: 12.5px; color: var(--muted); width: 64px; flex: none; }
.sh-input {
  flex: 1; border: 1px solid var(--line); border-radius: 12px; outline: none; min-width: 0;
  background: var(--glass); color: var(--text); padding: 9px 12px; font-size: 12px; font-family: var(--mono);
}
.sh-input:focus { border-color: var(--accent); }
.sh-input::placeholder { color: var(--faint); }
.sh-input.cn { font-family: var(--sans); }
.sh-input.gold { color: var(--gold); }
.sh-select {
  flex: 1; display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0;
  border: 1px solid var(--line); border-radius: 12px; background: var(--glass);
  padding: 9px 12px; font-size: 12.5px; cursor: pointer; color: var(--text); font-family: inherit;
}
.sh-select svg { color: var(--faint); flex: none; }
.sh-btn {
  display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 14px; width: 100%;
  border: 1px solid var(--gold-dim); border-radius: 14px; padding: 12px; cursor: pointer;
  color: var(--gold); font-size: 13px; letter-spacing: .12em;
  background: color-mix(in srgb, var(--gold) 7%, transparent); font-family: inherit;
}
.sh-btn:active { transform: scale(.98); }
.sh-btn.busy { opacity: .55; pointer-events: none; }

/* 供应商下拉（效果图未画开态；沿sheet行风格砌，机械必需件，记NOTES） */
.prov-menu { border: 1px solid var(--line); border-radius: 12px; background: var(--glass); margin-top: 8px; overflow: hidden; }
.prov-menu[hidden] { display: none; }
.prov-menu button {
  display: block; width: 100%; text-align: left; padding: 10px 12px; font-size: 12.5px;
  color: var(--text); background: none; border: none; border-bottom: 1px solid var(--line); cursor: pointer;
  font-family: inherit;
}
.prov-menu button:last-child { border-bottom: none; }
.prov-menu button.cur { color: var(--accent); }
.prov-menu button.add { color: var(--gold); }

/* 模型下拉（B11通电后）：透传 /v1/models 的清单菜单，长清单框内自滚 */
.dd-btn {
  flex: none; display: flex; align-items: center; justify-content: center;
  width: 36px; align-self: stretch; cursor: pointer;
  border: 1px solid var(--line); border-radius: 12px; background: var(--glass); color: var(--faint);
}
.prov-menu.model-menu { max-height: 234px; overflow-y: auto; overscroll-behavior: contain; }
.prov-menu.model-menu button { font-family: var(--mono); font-size: 11.5px; }
.prov-menu .menu-note { display: block; padding: 10px 12px; font-size: 12px; color: var(--faint); }

/* 试拨结果提示行（B11整改）：结果钉在按钮下面，不依赖toast（toast曾被键盘吞掉） */
.test-note { margin-top: 10px; text-align: center; font-size: 12px; color: var(--muted); overflow-wrap: break-word; }
.test-note.ok { color: var(--online); }
.test-note.fail { color: var(--danger); }
.test-note[hidden] { display: none; }

/* 钥匙串列表 */
.key-item { display: flex; align-items: center; gap: 11px; padding: 13px 0; border-bottom: 1px solid var(--line); }
.key-item:last-of-type { border-bottom: none; }
.key-meta { flex: 1; min-width: 0; }
.key-name { font-size: 13.5px; }
.key-detail { font-size: 10.5px; color: var(--faint); margin-top: 3px; font-family: var(--mono); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.key-del { color: var(--faint); flex: none; cursor: pointer; background: none; border: none; padding: 2px; font-family: inherit; }
.key-del svg { width: 15px; height: 15px; }
.key-del.arm { color: var(--danger); font-size: 11px; letter-spacing: .04em; }

/* 备注面板还在用的输入框（原素坯件保留） */
.set-input {
  width: 100%; padding: 9px 12px; border-radius: 11px;
  background: var(--glass); border: 1px solid var(--line);
  color: var(--text); font-size: 13.5px; outline: none;
}
.set-input:focus { border-color: var(--accent); }
.set-input::placeholder { color: var(--faint); }
/* 密钥"粘贴即掩码"的一次性动画（SPEC§7） */
.masking { animation: keymask .45s ease both; }
@keyframes keymask { from { opacity: .15; letter-spacing: .3em; } to { opacity: 1; letter-spacing: normal; } }

/* 通用小按钮（二次确认层在用） */
.hub-btn {
  border: 1px solid var(--line); background: var(--glass); color: var(--text);
  font-size: 12.5px; padding: 7px 15px; border-radius: 11px; cursor: pointer;
  letter-spacing: .05em; flex-shrink: 0;
}
.hub-btn:active { transform: scale(.96); }
.hub-btn.danger { color: var(--danger); border-color: var(--danger); }

/* 二次确认层（API Key/Profile专用） */
.confirm-layer {
  position: fixed; inset: 0; z-index: 90; display: none;
  align-items: center; justify-content: center; background: var(--scrim);
  padding: 24px;
}
.confirm-layer.show { display: flex; }
.confirm-box {
  background: var(--glass2, var(--glass)); backdrop-filter: blur(22px); -webkit-backdrop-filter: blur(22px);
  border: 1px solid var(--line); border-radius: 18px; box-shadow: var(--shadow);
  padding: 20px 22px; max-width: 340px; width: 100%;
  animation: pop .18s ease both;
}
.confirm-msg { font-size: 14px; line-height: 1.7; margin-bottom: 16px; }
.confirm-btns { display: flex; gap: 9px; justify-content: flex-end; }

/* toast（PATCH失败回滚提示，SPEC§7） */
.toast {
  /* bottom吃--kb-h（B11整改）：键盘弹起时toast跟着浮上来，不再被键盘吞掉 */
  position: fixed; left: 50%; bottom: calc(64px + env(safe-area-inset-bottom) + var(--kb-h, 0px));
  transform: translateX(-50%) translateY(8px); z-index: 95;
  background: var(--glass2, var(--glass)); backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  border: 1px solid var(--line); border-radius: 13px; box-shadow: var(--shadow);
  padding: 9px 16px; font-size: 12.5px; color: var(--text);
  opacity: 0; pointer-events: none; transition: opacity .25s, transform .25s;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* =====================================================================
   任务7.5 · 备注面板（长按聊天顶栏名字）
   ===================================================================== */
.nick-pop {
  position: fixed; z-index: 60; display: none;
  top: calc(58px + env(safe-area-inset-top)); left: 14px;
  width: min(320px, calc(100vw - 28px));
  background: var(--glass2, var(--glass)); backdrop-filter: blur(22px); -webkit-backdrop-filter: blur(22px);
  border: 1px solid var(--line); border-radius: 17px; box-shadow: var(--shadow);
  padding: 14px;
}
.nick-pop.show { display: block; animation: pop .18s ease both; }
.nick-chips { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 11px; }
.nick-chip {
  border: 1px solid var(--line); background: var(--glass); color: var(--text);
  font-size: 12.5px; padding: 6px 12px; border-radius: 15px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px; letter-spacing: .03em;
}
.nick-chip.cur { background: var(--bub-me); color: var(--bub-me-t); border-color: var(--bub-me-line); box-shadow: var(--bub-me-glow); }
.nick-chip .gdot { width: 6px; height: 6px; border-radius: 50%; background: var(--fav); flex-shrink: 0; }
.nick-note { font-size: 11px; color: var(--faint); margin-top: 10px; letter-spacing: .04em; }
