/* ============================================================
   inbox.css — Web 收件箱（金蔷薇主题 codex/golden-rose-home）
   基于原 docs/17 §6 视觉基线重构：暗夜鎏金 + serif 展示字。
   tokens.css 为三页共用（inbox/admin/authorize），保持不动；
   暗金令牌同样在 tokens.css 的 html[data-theme="rose"] 里（U-03：
   三页统一恒暗，不再在本文件覆写 :root），本文件只写收件箱独有的
   结构与装饰：
   - 花冠金蔷薇（inline SVG）作为首页主视觉：平时完全静止，
     提交时金粒从发送钮汇聚到花冠，粉落定后花冠整朵点亮一下
   - 采集框初始为胶囊型：左上传符号、右箭头提交
   - 组件类名与 DOM 钩子不变，纯视觉层重构
   ============================================================ */

/* —— 收件箱尺度令牌（U-06）：顶栏高与拉手高在多处参与计算
   （面板留白、clip 区），改一处要同步改其余几处，故显式命名 —— */
:root {
  --topbar-h: 56px;       /* 顶栏内容高（不含 safe-area） */
  --handle-h: 46px;       /* 抽屉拉手的可视高 */
  /* 收件箱的内容栏宽：设置、AI 对话、我的作品的标题与叉叉据此落在同一条竖线上 */
  --content-max: 760px;
}

/* ============ 金蔷薇（inline SVG）：静态为主，提交后亮一下 ============ */
/* 平时完全静止。提交时 capture.js 先撒金粉，等粉汇聚到花冠再给 svg.rose 加 .play，
   于是顺序是「金粉汇到花上 → 整朵点亮一下」。点亮只有两层：花瓣走 screen 加光、
   花外一圈光晕，都不扫过画面；两层错开半拍、各自慢起慢落，光是一点点漫上来的。
   花瓣那层掩膜在花冠轮廓内（#gdSil），只亮花瓣，不在背景上留出方块。
   .plant 自身不带 transform 属性（位移在内层那个 g），所以摇曳的 rotate 不会把花推出画布。 */
.rose .litGlow, .rose .litHalo { opacity: 0; }
.rose .litHalo { transform-box: fill-box; transform-origin: center; }

.rose.play .plant { transform-box: view-box; transform-origin: 50% 50%;
                    animation: swayOnce 2.6s ease-in-out 1 both; }
@keyframes swayOnce { 0% { transform: rotate(0deg); } 34% { transform: rotate(-1.1deg); }
                      70% { transform: rotate(.8deg); } 100% { transform: rotate(0deg); } }
/* 花瓣先亮：约 0.6s 涌到顶、留住一会儿、再用一秒多慢慢落回原来的明度，不留一层白。
   峰值压在 .42——再高就把金色洗成奶油色，不像发光像褪色；慢一点也就不生硬了 */
.rose.play .litGlow { animation: litBloom 2s ease-in-out 1 both; }
@keyframes litBloom { 0% { opacity: 0; } 30% { opacity: .42; } 56% { opacity: .3; }
                      100% { opacity: 0; } }
/* 光晕晚半拍跟上并往外胀：花先亮、光再漫开，两层错开才有厚度而不是一起闪 */
.rose.play .litHalo { animation: haloBloom 2.4s ease-out .12s 1 both; }
@keyframes haloBloom { 0% { opacity: 0; transform: scale(.95); }
                       28% { opacity: .46; transform: scale(1); }
                       100% { opacity: 0; transform: scale(1.08); } }
/* 底衬那圈只轻轻胀一点，别抢上面两层 */
.rose.play .glowPulse { transform-box: fill-box; transform-origin: center;
                        animation: glowOnce 2.4s ease-in-out 1 both; }
@keyframes glowOnce { 0%, 100% { transform: scale(1); } 26% { transform: scale(1.05); } }

/* —— 提交金粒：capture.js 动态生成，从发送钮喷出、沿弧线汇聚到花冠上，落定后花冠才亮 —— */
/* 粒子本体只有 2–4px，亮不亮靠这两层发光撑：内圈近白、外圈暖金 */
.gold-spark { position: fixed; z-index: 90; border-radius: 50%; pointer-events: none;
              box-shadow: 0 0 4px rgba(255, 249, 228, .95), 0 0 11px rgba(244, 202, 114, .8); }

/* —— 点金蔷薇：touch-bloom.js 在两朵花的瓣圈内放一小团反光 + 一撮金粉 —— */
/* 反光是「碰着了」的落点，比金粉更短，胀开即散，所以只在指尖那一小块地方亮一下 */
.touch-flash { position: fixed; z-index: 89; width: 56px; height: 56px; margin: -28px 0 0 -28px;
               border-radius: 50%; pointer-events: none; opacity: 0;
               background: radial-gradient(circle, rgba(255, 248, 222, .5) 0%,
                           rgba(244, 202, 114, .17) 38%, rgba(226, 176, 74, 0) 70%); }

/* ============ 基底 ============ */
html { background: var(--bg); }
body { background: transparent; }
/* iOS Safari 不支持 background-attachment: fixed（滚动/回弹会露出纯黑底）：
   改用 fixed 伪元素承载暖金渐变，铺满整个可视区，顶/底安全区也连续不露黑 */
body::before { content: ""; position: fixed; inset: 0; z-index: -1;
               background: radial-gradient(1100px 760px at 50% 30%, #241a09 0%, #150f07 48%, var(--bg) 100%); }
::selection { background: rgba(226, 176, 74, .32); }

/* —— 顶栏：暖黑玻璃 + 金色发丝线（§4.1）；sticky 常驻，滚到哪里都在 —— */
header { position: sticky; top: 0; z-index: 50;
         padding-top: env(safe-area-inset-top);
         background: rgba(14, 10, 5, .78);
         border-bottom: 1px solid rgba(226, 176, 74, .14);
         backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
.topbar-inner { max-width: var(--content-max); margin: 0 auto; padding: 0 24px;
                display: flex; align-items: center; gap: 8px; height: var(--topbar-h); }
.brand { font-family: var(--font-display); font-size: var(--fs-display); font-weight: 600;
         color: var(--rose-brand); letter-spacing: 1px; }
/* 品牌名做成可点回主页的按钮：剥掉全局 button 外观，只留文字与指针。
   不要在这里写 `font: inherit`——简写会把 .brand 的 serif 展示字重置回正文字体 */
.brandbtn { border: none; background: transparent; padding: 0; min-height: 0;
            border-radius: var(--radius-note); }
.brandbtn:hover { color: var(--accent-hover); border: none; background: transparent; }
.brandbtn:active { transform: none; }
.userchip { display: inline-flex; align-items: center; gap: 8px; max-width: 220px;
            border: none; background: transparent; min-height: 44px; padding: 6px 10px;
            border-radius: 999px; }
.userchip:hover { background: var(--surface-2); }
.userchip .uname { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.userchip::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex: none;
                    box-shadow: 0 0 8px rgba(226, 176, 74, .8); }
.menu-note { padding: 8px 10px 4px; font-size: var(--fs-small); color: var(--text-2); text-align: center;
             border-bottom: 1px solid var(--border); margin-bottom: 4px; }
.menuwrap { position: relative; }
.menu { position: absolute; right: 0; top: calc(100% + 6px); background: var(--surface);
        border: 1px solid var(--border-strong); border-radius: var(--radius-ctl); box-shadow: var(--shadow-pop);
        min-width: 160px; padding: 6px; z-index: 40; }
.menu-item { display: flex; width: 100%; align-items: center; min-height: 40px;
             padding: 6px 10px; border: none; background: transparent; border-radius: 8px;
             color: var(--text); font-size: 14px; cursor: pointer; text-decoration: none; }
.menu-item[hidden] { display: none; }  /* 否则 display 会盖掉 [hidden] */
.menu-item:hover { background: var(--surface-2); }
.menu-item.danger { color: var(--bad); }

main { max-width: var(--content-max); margin: 0 auto; padding: 24px 24px calc(16px + env(safe-area-inset-bottom)); }
.spacer { flex: 1; }
.muted { color: var(--text-2); }
.small { font-size: var(--fs-small); line-height: 1.5; color: var(--text-2); }
.help { font-size: var(--fs-caption); line-height: 1.5; color: var(--text-2); margin: 8px 2px 0; }
.num { font-variant-numeric: tabular-nums; }
.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
h2, .card-title { font-size: var(--fs-h2); font-weight: 600; margin: 0 0 12px; }
.card h2, .card .list-head h2, .onboard-title, .empty-title {
  font-family: var(--font-display); letter-spacing: .3px; }
label { display: block; font-size: var(--fs-small); color: var(--text-2); margin: 14px 0 6px; }

/* —— 各页面共用的页头：标题在左、叉叉在右。
   同一套字号/行高/按钮，页面之间只换标题文字与中间的动作 —— */
.page-head { flex: none; display: flex; align-items: center; gap: 10px; min-height: 44px; }
.page-title { font-family: var(--font-display); font-size: var(--fs-h1); font-weight: 600;
              letter-spacing: .5px; line-height: 1.3; min-width: 0;
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* —— 未登录时的产品说明页在 landing.css（#loginView），本文件只管登录后的收件箱 —— */

/* ============ 首页三层：顶部条目抽屉 / 中间金蔷薇 / 底部胶囊采集框 ============ */
#homeView { display: flex; flex-direction: column;
            /* 顶栏 + main 上下内边距（24+16）；顶栏高走令牌，不再重复写死（U-06） */
            min-height: calc(100dvh - var(--topbar-h) - 40px - env(safe-area-inset-top) - env(safe-area-inset-bottom)); }
.home-main { display: flex; flex-direction: column; flex: 1; min-height: 0; position: relative; }

/* —— 顶部：条目抽屉。收起时只剩一个从顶边垂下来的半圆拉手 —— */
.drawer { position: relative; z-index: 30; display: flex; justify-content: center; }
/* 拉手 z 高于面板(45)：拖动中它是页面前缘的拉环，要画在面板之上 */
.drawer-handle { position: relative; z-index: 46; width: 150px; min-height: var(--handle-h); padding: 6px 0 8px;
                 margin-top: -24px;  /* 抵消 main 顶边距，让半圆贴住顶栏下沿 */
                 touch-action: none;  /* 拖拽把手：按住下拖不能触发页面滚动 */
                 border: 1px solid var(--border-strong); border-top: none;
                 border-radius: 0 0 75px 75px;
                 background: linear-gradient(180deg, rgba(56, 39, 17, .92) 0%, rgba(24, 16, 8, .96) 100%);
                 color: var(--text-2);
                 display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
                 box-shadow: 0 6px 18px rgba(0, 0, 0, .5), inset 0 1px 0 rgba(226, 176, 74, .12);
                 transition: color var(--t-fast), box-shadow var(--t-fast); }
.drawer-handle::after { content: ""; position: absolute; inset: -6px 0 -4px; }  /* 半圆视觉小，命中区扩到 ≥44px */
.drawer-handle:hover { color: var(--accent);
                       box-shadow: 0 6px 22px rgba(226, 176, 74, .18), inset 0 1px 0 rgba(226, 176, 74, .25); }
.drawer-handle svg { flex: none; }
/* 拉手文字（已收集）：替代数字徽标 */
.handle-label { font-size: 12px; line-height: 1; letter-spacing: 3px; text-indent: 3px; }
.drawer-panel { position: fixed; inset: 0; z-index: 45; display: flex; flex-direction: column;
                background: linear-gradient(170deg, rgba(26, 18, 9, .985) 0%, rgba(14, 9, 4, .995) 100%);
                /* 顶部让出 sticky 顶栏（含发丝线 1px）+ 与设置/舞台同样的呼吸位：
                   各页页头从同一高度开始 */
                padding: calc(var(--topbar-h) + 1px + 24px + env(safe-area-inset-top)) 0
                         calc(16px + env(safe-area-inset-bottom));
                backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
                /* 「圆弧拉手拖着整页下拉」：面板钉在终位、不整块位移，clip 可视区恒为
                   [顶栏下沿, 拉手上沿]，由 item-list.js 的 rAF 逐帧驱动——拉手
                   （transform 下移）就是页面前缘的拉环；收起时拉手带着前缘反向卷回。
                   clip 不走 CSS transition：拖拽要 1:1 跟手，且必须与拉手同帧同位 */
                visibility: hidden; }
.drawer-body { width: 100%; max-width: var(--content-max); margin: 0 auto; padding: 0 24px;
               display: flex; flex-direction: column; flex: 1; min-height: 0; }
#drawerHead { margin-bottom: 8px; }
.drawer-scroll { overflow-y: auto; overflow-x: hidden; min-height: 0; overscroll-behavior: contain; flex: 1;
                 /* 顶部/右侧留边：卡片右上角红点（12px）有一半溢出卡片，不能被滚动容器裁掉 */
                 padding: 8px 8px 8px 0; }

/* —— 中间：金蔷薇（视觉中心，平时完全静止，提交时播一次回馈动画） —— */
.rose-stage { flex: 1; min-height: 200px; display: flex; flex-direction: column;
              align-items: center; justify-content: center; user-select: none; }
.rose-caption { font-family: var(--font-display); font-size: var(--fs-h1); font-weight: 600;
                margin-top: 14px; letter-spacing: 3px;
                background: linear-gradient(180deg, var(--rose-hi) 0%, var(--accent) 58%, var(--rose-deep) 100%);
                -webkit-background-clip: text; background-clip: text; color: transparent; }
.rose-sub { font-size: var(--fs-caption); color: var(--text-2); margin-top: 4px; letter-spacing: 1px; }

/* —— 底部：胶囊采集框吸底常驻；向上渐隐遮住滚动穿过的内容 —— */
.dock { position: sticky; bottom: 0; margin-top: 12px; z-index: 20; }
.dock::before { content: ""; position: absolute; inset: -22px -24px -16px; z-index: -1;
                background: linear-gradient(to top, var(--bg) 58%, rgba(10, 7, 5, 0));
                pointer-events: none; }

/* ============ 采集卡：金蔷薇 + 胶囊输入 ============ */
#captureCard { background: transparent; border: none; box-shadow: none;
               padding: 0; margin: 0; }
.rose-wrap { display: flex; justify-content: center; }
.rose { display: block; width: clamp(260px, 40vh, 420px); height: auto;
        /* 点亮用的光晕比 viewBox 宽，允许溢出到页面里，否则花外那圈光会被方框切平 */
        overflow: visible;
        filter: drop-shadow(0 0 30px rgba(232, 169, 60, .13)); }

/* 采集框：没点进来是单行胶囊，一点进来（或框里已经有东西）就长成圆角矩形。
   两态共用同一套 DOM：capmain 只放文字，capbar 只放「文件钮｜链接胶囊｜发送钮」。
   胶囊态把 capbar 用负 margin 整行提上来，正好叠在文字行那条带上——文件钮在左、发送钮
   在右，位置和不展开时一样；展开时它整行落回文字下方，两个按钮横向一步都不走。
   圆角只走 28 → 30 这一档：胶囊的"圆"本来就等于半个框高，形变时是框在长高、不是角在转。
   写成 999px 会被浏览器夹到半高，插值中途那串大数字全被夹成同一个形状，快到末尾才突然
   松开——走查看到的"四个角卡"就是这个夹取过程，不是掉帧。
   点进来那一下由 capture.js 的 focusin 挂 .open，形态不看测量：空框一离开焦点必回胶囊，
   不会再出现卡在圆角矩形回不去的情况（2026-09-17）。 */
.smartbox { --cap-bar: 44px;      /* capbar 行高，胶囊态按它整行上叠 */
            --cap-left: 52px;     /* 胶囊态左端文件钮让出的宽度 */
            --cap-right: 60px;    /* 胶囊态右端发送钮让出的宽度（含 ::before 扩出来的命中区） */
            --pill-r: calc((var(--cap-bar) + 12px) / 2);   /* 胶囊态框高 56 的一半 */
            --t-morph: 90ms;
            display: flex; flex-direction: column;
            border: 1px solid var(--border-strong); border-radius: var(--pill-r);
            background: linear-gradient(165deg, rgba(56, 39, 17, .58) 0%, rgba(24, 16, 8, .92) 100%);
            padding: 5px 6px;
            box-shadow: 0 10px 34px rgba(0, 0, 0, .45), inset 0 1px 0 rgba(255, 225, 160, .07);
            transition: border-radius var(--t-morph) var(--ease),
                        border-color var(--t-fast), box-shadow var(--t-fast); }
.smartbox.open { border-radius: 30px; }
.smartbox:focus-within { border-color: var(--rose-deep);
                         box-shadow: 0 0 0 3px rgba(226, 176, 74, .12),
                                     0 8px 30px rgba(226, 176, 74, .10); }
/* 上排：文字独占一行，光标一进来就在这一行，从胶囊到矩形都在这里长高 */
.capmain { display: flex; min-width: 0; }
.smartbox textarea { flex: 1; min-width: 0; border: none; box-shadow: none; resize: none;
                     min-height: var(--cap-bar); max-height: 220px;
                     padding: 10px 12px; line-height: 24px;
                     background: transparent; color: var(--text); caret-color: var(--accent);
                     transition: padding-left calc(var(--t-morph) * .55) var(--ease)
                                            calc(var(--t-morph) * .45),
                                 padding-right calc(var(--t-morph) * .55) var(--ease)
                                             calc(var(--t-morph) * .45); }
.smartbox textarea:focus { box-shadow: none; }
/* 占位提示只在没人动它的胶囊态露脸：一点进来就淡掉，展开的那一行留给用户自己的字 */
.smartbox textarea::placeholder { color: #8a7554; transition: color var(--t-fast) var(--ease); }
.smartbox.open textarea::placeholder { color: transparent; }
/* 胶囊态：文字行两端让给叠在同一行的文件钮与发送钮。让位晚起步（延 45%、走 55%）：
   --ease 前段快，按钮在 45% 那一点已经离开字形带，此后收让位既不会把文字压在按钮底下，
   也不会在框停住之后还留一段慢慢爬的尾巴（总时长只有 --t-morph，钉帧量过 clip）。 */
.smartbox:not(.open) textarea { padding-left: var(--cap-left); padding-right: var(--cap-right); }
/* 下排：文件钮在左、发送钮在右，中间放链接胶囊（胶囊多了一行装不下就横向滚） */
.capbar { display: flex; align-items: center; gap: 6px; height: var(--cap-bar); padding: 0 2px;
          transition: margin-top var(--t-morph) var(--ease); }
/* 胶囊态整条 capbar 压在文字行上，它本身不能把点在输入框上的鼠标吃掉（实测点在左半边
   命中的是 capbar）；只让两个按钮重新接收点击，空的胶囊区顺带也不响应 */
.smartbox:not(.open) .capbar { margin-top: calc(-1 * var(--cap-bar)); pointer-events: none; }
.smartbox:not(.open) .capbar .uploadpick,
.smartbox:not(.open) .capbar .capsubmit { pointer-events: auto; }
.chipzone { display: flex; align-items: center; gap: 6px; flex: 1; min-width: 0;
            overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
            opacity: 0;   /* 展开途中 capbar 还压在文字行上，胶囊先别露脸 */
            transition: none; }
/* 胶囊比按钮行晚一拍淡进来，避免粘贴多链接时胶囊从文字上擦过去。淡入挂在 chipzone
   自己身上：胶囊每次输入都由 innerHTML 重建，动画放子元素上会一路闪。 */
.smartbox.open .chipzone { opacity: 1; transition: opacity calc(var(--t-morph) * .45) var(--ease)
                                       calc(var(--t-morph) * .55); }
.chipzone::-webkit-scrollbar { display: none; }
/* 一条链接一个胶囊，横向排成一行，多了就横滚：行高恒定，多贴几条链接不会把框撑得抖动 */
.smartbox .chiprow { padding: 0; flex: none; flex-wrap: nowrap; }
.smartbox .chip { flex: none; }
.uploadpick { width: 40px; min-width: 40px; min-height: 40px; border: none; background: transparent;
              border-radius: 50%; color: #d9b56a; flex: none; }
.uploadpick:hover { background: rgba(226, 176, 74, .12); color: var(--accent-hover); border: none; }
/* 发送按钮调小（走查反馈）：36px 视觉圆钮，::before 把命中区扩到 ≥44px */
.capsubmit { width: 36px; min-width: 36px; height: 36px; min-height: 36px; padding: 0;
             border-radius: 50%; border: 1px solid var(--rose-deep); flex: none;
             background: linear-gradient(180deg, #f4ca72 0%, #dfab4e 60%, #c9973a 100%);
             color: var(--on-accent); position: relative;
             box-shadow: 0 2px 12px rgba(226, 176, 74, .35), inset 0 1px 0 rgba(255, 240, 200, .55); }
.capsubmit::before { content: ""; position: absolute; inset: -4px; border-radius: 50%; }
/* 触屏设备上传钮保持 44px 触控目标（U-01）；发送钮视觉 36px，命中区已由 ::before 扩足 */
@media (pointer: coarse) {
  .uploadpick { width: 44px; min-width: 44px; min-height: 44px; }
}
.capsubmit:hover { filter: brightness(1.07); border-color: var(--rose-deep); }
.capsubmit.busy svg { opacity: 0; }
.capsubmit.busy::after { content: ""; position: absolute; left: calc(50% - 9px); top: calc(50% - 9px);
                         width: 18px; height: 18px; border-radius: 50%;
                         border: 2px solid rgba(36, 23, 3, .3); border-top-color: var(--on-accent);
                         animation: rot .8s linear infinite; }
.capmeta { display: flex; align-items: center; gap: 8px; padding: 0 12px; min-height: 0; flex-wrap: wrap; }
.capmeta:not(:has(span:not(:empty))) { height: 0; overflow: hidden; }
/* 不支持的格式要说得看得见：这一行是采集框里唯一的告警位 */
.capmeta .warn { color: var(--warn); }
/* —— 链接/文件/录音 chips —— */
.chiprow { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 14px 8px; }
/* 胶囊横滚出视区时钉在行右缘的 +N 徽标：sticky 跟着滚动容器走 */
.chipmore { position: sticky; right: 4px; flex: none; align-self: center;
            background: var(--surface-2); border: 1px solid var(--border);
            border-radius: 999px; padding: 2px 8px; font-size: var(--fs-caption);
            color: var(--text-2); }
.chip { display: inline-flex; align-items: center; gap: 4px; background: rgba(243, 233, 210, .06);
        border: 1px solid var(--border-strong); border-radius: var(--radius-pill);
        padding: 4px 8px 4px 12px; font-size: var(--fs-caption); max-width: 100%; color: var(--text); }
.chip .lbl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 280px; }
.xbtn { width: 22px; height: 22px; min-height: 0; border: none; background: transparent;
        border-radius: 50%; color: var(--text-2); padding: 0; font-size: var(--fs-caption); line-height: 1;
        position: relative; flex: none; display: inline-flex; align-items: center; justify-content: center; }
.xbtn::after { content: ""; position: absolute; inset: -11px; }
.xbtn:hover { background: var(--bad-soft); color: var(--bad); }
/* —— 上下文选项与歧义说明 —— */
.ctxopts { display: flex; align-items: center; gap: 8px; padding: 0 10px 8px; }
.multiplenote { margin: 8px 10px 0; }
.opttoggle { position: relative; display: inline-flex; align-items: center; gap: 8px;
             min-height: 44px; padding: 4px 10px; cursor: pointer; font-size: var(--fs-body); }
.opttoggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.opttoggle .switch { margin-left: 0; width: 36px; height: 20px; }
.opttoggle .switch i { width: 16px; height: 16px; }
.opttoggle input:checked ~ .switch { background: var(--ok); }
.opttoggle input:checked ~ .switch i { transform: translateX(16px); }
.opttoggle input:focus-visible ~ .switch { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ============ 条目流：单一时间倒序 + 搜索组（在抽屉面板内滚动） ============ */
.listtoolbar { display: flex; align-items: center; gap: 8px; min-height: 44px; }
#searchToggle { flex: none; }
/* 搜索框从放大镜图标处向左生长：宽度由 item-list.js 设 px，transition 驱动；
   与图标同排、行高不变，下方条目不被推动 */
/* overflow: clip（旧浏览器回退 hidden）：槽不是滚动容器，focus() 无法横向滚动它；
   输入框 min-width:0 跟随槽宽，不存在被裁掉的溢出部分 */
.searchslot { display: flex; align-items: center; flex: none; width: 0;
              overflow: hidden; overflow: clip;
              opacity: 0; transition: width .3s var(--ease), opacity .18s var(--ease); }
.listtoolbar.search-open .searchslot { opacity: 1; }
.searchslot .search { flex: 1; min-width: 0; }
.itemgroup { margin-bottom: 20px; }
.itemgroup:last-of-type { margin-bottom: 0; }
.grouptitle { font-size: var(--fs-small); font-weight: 600; color: var(--text-2);
              margin: 0 0 8px; display: flex; align-items: center; gap: 8px;
              letter-spacing: .4px; }
/* 三个分组标题前各一枚小色点：一眼分清谁要动、谁在等、谁完事了。
   点要小——它是分类记号，不是警示灯；「搜索结果」那一组不属于三种状态，不给点。 */
.g-attention > .grouptitle::before, .g-pending > .grouptitle::before,
.g-done > .grouptitle::before { content: ""; flex: none; width: 6px; height: 6px;
                                border-radius: 50%; }
.g-attention > .grouptitle::before { background: var(--bad); }
.g-pending > .grouptitle::before { background: var(--info); }
.g-done > .grouptitle::before { background: var(--ok); }
/* 已完成默认只露最新三条，其余折叠（点标题下的按钮展开） */
ul.items.collapsed > li:nth-child(n+4) { display: none; }
.grouptoggle { margin-top: 10px; }
ul.items { list-style: none; margin: 0; padding: 0;
           display: flex; flex-direction: column; gap: 10px; }
ul.items > li { position: relative; background: var(--surface); border: 1px solid var(--border);
                border-radius: var(--radius-inner); box-shadow: var(--shadow-card);
                padding: 12px 16px; cursor: pointer; min-width: 0;
                transition: border-color var(--t-fast), background var(--t-fast),
                            box-shadow var(--t-fast); }
ul.items > li:hover { background: var(--surface-2); border-color: var(--border-strong); }
ul.items > li.pre { opacity: 0; }
ul.items > li.enter { animation: enter var(--t-slow) var(--ease) backwards; }
@keyframes enter { from { opacity: 0; transform: translateY(4px); } }
.item-main { display: flex; gap: 12px; align-items: baseline; min-width: 0; }
.item-title { font-weight: 600; font-size: var(--fs-body); color: var(--text); flex: 1; min-width: 0;
              overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.item-time { font-size: var(--fs-caption); color: var(--text-2); flex: none; }
.item-aux { display: flex; gap: 8px; align-items: center; margin-top: 5px;
            font-size: var(--fs-small); color: var(--text-2); flex-wrap: wrap; min-width: 0; }
.item-aux .grow { flex: 1; }
.item-aux .msg { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.item-aux .msg.bad { color: var(--bad); }
.item-aux .msg.warn { color: var(--warn); }
.item-aux .src { flex: none; color: var(--text-2); }
.item-aux .primary-inline { flex: none; min-height: 30px; padding: 2px 10px; font-size: var(--fs-small); }
.itembar { position: relative; height: 3px; border-radius: 2px; background: var(--surface-2);
           margin-top: 8px; overflow: hidden; }
.itembar > i { position: absolute; inset: 0 auto 0 0; background: var(--accent);
               border-radius: 2px; transition: width 300ms var(--ease); }
.itembar.indeterminate > i { width: 40%; animation: slidebar 1.4s var(--ease) infinite; }
@keyframes slidebar { from { left: -40%; } to { left: 100%; } }
.skel { height: 64px; border-radius: var(--radius-inner); border: 1px solid var(--border);
        background: linear-gradient(100deg, var(--surface-2) 40%, var(--surface) 50%, var(--surface-2) 60%);
        background-size: 200% 100%; animation: shimmer 1.2s linear infinite; list-style: none; }
@keyframes shimmer { to { background-position: -200% 0; } }
.empty { text-align: center; padding: 40px 16px; }
.empty-title { font-size: var(--fs-display); font-weight: 600; margin-bottom: 8px; }

/* ============ 详情：返回 + 更多菜单；标题区不放状态堆叠 ============ */
.detail { animation: enter var(--t-slow) var(--ease) backwards;
          /* 抵消 main 顶边距：返回栏直接贴住顶栏下沿，消除中间无文字色带 */
          margin-top: -24px; }
/* 返回/更多栏 sticky 在顶栏正下方：长文下滚也随时能返回（走查反馈） */
.detail-top { display: flex; align-items: center; gap: 12px;
              position: sticky; top: calc(var(--topbar-h) + env(safe-area-inset-top)); z-index: 25;
              margin: 0 -24px; padding: 8px 24px 10px;
              background: linear-gradient(180deg, rgba(10, 7, 5, .96) 0%, rgba(10, 7, 5, .88) 78%, rgba(10, 7, 5, 0) 100%); }
.back { margin-left: -16px; }
.detail-title { font-family: var(--font-display); font-weight: 600; font-size: var(--fs-h1);
                margin-top: 10px; overflow-wrap: anywhere; letter-spacing: .3px; }
.detail-meta { font-size: var(--fs-small); margin-top: 4px; }

/* —— 四阶段状态图：圆点连线，固定四步 —— */
.stepper { display: flex; align-items: flex-start; margin: 20px 0 14px; }
.step { display: flex; flex-direction: column; align-items: center; gap: 6px;
        flex: 1; min-width: 0; position: relative; }
.sball { width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--border-strong);
         display: flex; align-items: center; justify-content: center; font-size: 11px;
         color: transparent; background: var(--surface); flex: none; position: relative;
         transition: all var(--t-slow) var(--ease); }
.slabel { font-size: var(--fs-caption); color: var(--text-2); white-space: nowrap; }
.sline { position: absolute; top: 10px; left: calc(-50% + 18px); right: calc(50% + 18px);
         height: 2px; background: var(--border); transition: background var(--t-slow); }
.step:first-child .sline { display: none; }
.step.done .sball { background: var(--ok); border-color: var(--ok); color: var(--on-ok); }
.step.done .slabel { color: var(--ok); }
.step.done .sline { background: var(--ok); }
/* 不需要的步骤：空心圆圈里一道横线，连线照常通过（关了自动整理时的「整理」） */
.step.skipped .sball { color: var(--text-2); font-weight: 700; }
.step.skipped .slabel { color: var(--text-2); }
.step.skipped .sline { background: var(--ok); }
.step.running .sball { border-color: var(--accent); }
.step.running .sball::after { content: ""; position: absolute; width: 10px; height: 10px;
                              border-radius: 50%; background: var(--accent);
                              animation: breathe 1.6s var(--ease) infinite; }
.step.running .slabel { color: var(--accent); font-weight: 600; }
.step.running .sline { background: linear-gradient(90deg, var(--ok) 0%, var(--ok) 30%,
                       var(--accent) 55%, var(--ok) 80%); background-size: 200% 100%;
                       animation: flowline 1.6s linear infinite; }
@keyframes flowline { from { background-position: 100% 0; } to { background-position: -100% 0; } }
.step.waiting .sball { border-color: var(--info); }
.step.waiting .sball::after { content: ""; position: absolute; width: 8px; height: 8px;
                              border-radius: 50%; background: var(--info); opacity: .8; }
.step.waiting .slabel { color: var(--info); }
.step.attention .sball { border-color: var(--warn); color: var(--warn); font-weight: 700; }
.step.attention .slabel { color: var(--warn); }
.step.failed .sball { border-color: var(--bad); color: var(--bad); font-weight: 700; }
.step.failed .slabel { color: var(--bad); }
.step.published-flash .sball { animation: pop-in 220ms var(--ease); }
@keyframes pop-in { 0% { transform: scale(.6); opacity: 0; } 100% { transform: scale(1); opacity: 1; } }

/* —— 当前阶段面板 —— */
.stagepanel { background: var(--surface-2); border-radius: var(--radius-inner);
              padding: 14px 16px; margin: 0 0 16px; }
.stagepanel .panelhead { display: flex; align-items: baseline; gap: 12px; }
.stagepanel .paneltitle { font-weight: 600; font-size: var(--fs-body); }
.stagepanel .panelpct { margin-left: auto; font-size: var(--fs-small); color: var(--text-2); }
.stagepanel .panelbar { height: 4px; border-radius: 2px; background: var(--border);
                        margin-top: 10px; overflow: hidden; position: relative; }
.stagepanel .panelbar > i { position: absolute; inset: 0 auto 0 0; background: var(--accent);
                            transition: width 300ms var(--ease); }
.stagepanel .panelbar.indeterminate > i { width: 40%; animation: slidebar 1.4s var(--ease) infinite; }
.stagepanel .panelnote { font-size: var(--fs-small); color: var(--text-2); margin-top: 8px; }
.stagepanel .panelaction { margin-top: 12px; display: flex; gap: 8px; flex-wrap: wrap; }
.stagepanel.tone-attention { background: var(--warn-soft); }
.stagepanel.tone-failed { background: var(--bad-soft); }
.auxcard { border: 1px solid var(--border); border-radius: var(--radius-inner);
           padding: 10px 12px; margin: 10px 0 0; background: var(--surface); }

/* —— 页签与正文 —— */
.readtabs { display: flex; gap: 4px; margin: 6px 0 0; border-bottom: 1px solid var(--border); }
.readtabs button { border: none; background: transparent; padding: 8px 14px; border-radius: 0;
                   color: var(--text-2); min-height: 44px; margin-bottom: -1px; font-size: 14px;
                   border-bottom: 2px solid transparent;
                   transition: color var(--t-fast), border-color var(--t-fast); }
.readtabs button.active { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }
.readpane { padding-top: 14px; max-width: 720px; }
.readbody { font-size: 14px; line-height: 1.75; min-width: 0; overflow-wrap: anywhere; }
.readbody h4 { font-size: var(--fs-small); margin: 18px 0 8px; color: var(--text-2); font-weight: 600; }
.readbody ul { margin: 6px 0; padding-left: 20px; }
.readbody li { margin: 4px 0; }
.readbody blockquote { margin: 6px 0; padding: 8px 14px; border-left: 3px solid var(--accent-soft);
                       background: var(--surface-2); border-radius: 0 8px 8px 0; }
.para { margin: 0 0 14px; }
.para:target, .para.highlight { background: var(--accent-soft); border-radius: 6px; }
.parahead { font-size: 15px; font-weight: 600; margin: 20px 0 8px; }
.loclink { font-size: 11px; color: var(--accent); background: var(--accent-soft); border: none;
           border-radius: 999px; padding: 2px 9px; cursor: pointer; margin-left: 6px; min-height: 0; }
.srcmeta { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px;
           font-size: var(--fs-small); color: var(--text-2); overflow-wrap: anywhere; }
.srcmeta a { color: var(--accent); text-decoration: none; word-break: break-all; }
.srcactions { display: flex; gap: 8px; justify-content: flex-end; margin: 0 0 10px; }

/* —— 开关（设置页） —— */
.asrtoggle { position: relative; display: flex; gap: 12px; align-items: center; margin-top: 14px; padding: 12px 14px;
             border: 1px solid var(--border); border-radius: var(--radius-ctl);
             background: var(--surface-2); cursor: pointer; }
.asrtoggle:hover { border-color: var(--border-strong); }
.asrtoggle[hidden] { display: none; }
.asrtoggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch { width: 40px; height: 22px; border-radius: 999px; background: var(--switch-off-track); flex: none;
          position: relative; margin-left: auto; transition: background var(--t-fast); }
.switch i { position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%;
            background: var(--switch-off-knob);
            box-shadow: 0 1px 3px rgb(0 0 0 / 0.4);
            transition: transform var(--t-fast) var(--ease); }
.asrtoggle input:checked ~ .switch { background: var(--ok); }
.asrtoggle input:checked ~ .switch i { transform: translateX(18px); }
.asrtoggle input:focus-visible ~ .switch { outline: 2px solid var(--accent); outline-offset: 2px; }
.asrtoggle-text { position: relative; flex: 1; min-width: 0; }
.asrtoggle-text b { display: flex; align-items: center; gap: 6px; margin-bottom: 2px; font-size: var(--fs-body); }
.asrtoggle-text .infotip { position: absolute; left: 0; right: 0; bottom: calc(100% + 10px); z-index: 30;
                           display: block; padding: 10px 12px; font-size: var(--fs-small); line-height: 1.55;
                           color: var(--text-2); background: var(--surface); border: 1px solid var(--border-strong);
                           border-radius: var(--radius-inner); box-shadow: var(--shadow-pop); }
.asrtoggle-text .infotip[hidden] { display: none; }
.asrtoggle-text .infotip::after { content: ""; position: absolute; bottom: -6px; left: var(--tail, 20px);
                                  width: 10px; height: 10px; background: var(--surface);
                                  border-right: 1px solid var(--border-strong); border-bottom: 1px solid var(--border-strong);
                                  transform: rotate(45deg); }
.infobtn { position: relative; flex: none; width: 20px; height: 20px; min-height: 0; padding: 0;
           border: none; background: transparent; color: var(--text-2); border-radius: 50%; }
.infobtn::after { content: ""; position: absolute; inset: -12px; }
.infobtn:hover, .infobtn[aria-expanded="true"] { color: var(--accent); background: var(--accent-soft); }

/* —— 折叠组件 —— */
details.disclosure { background: var(--surface-2); border: 1px solid var(--border);
                     border-radius: var(--radius-inner); margin-top: 12px;
                     scroll-margin-top: calc(76px + env(safe-area-inset-top)); }
details.disclosure > summary { cursor: pointer; list-style: none; display: flex; align-items: center;
                               gap: 8px; min-height: 44px; padding: 10px 14px;
                               font-weight: 600; font-size: 14px; border-radius: var(--radius-inner); }
details.disclosure > summary::-webkit-details-marker { display: none; }
details.disclosure > summary::before { content: "▸"; color: var(--text-2); flex: none;
                                       font-size: var(--fs-caption);
                                       transition: transform var(--t-slow) var(--ease); }
details.disclosure[open] > summary::before { transform: rotate(90deg); }
details.disclosure > summary:hover { color: var(--accent); }
.disclosure-body { padding: 0 14px 14px; }
details.disclosure.slim { margin-top: 6px; }
details.disclosure.slim > summary { min-height: 32px; padding: 4px 8px; font-weight: 500;
                                    font-size: var(--fs-caption); color: var(--text-2); }
details.disclosure.slim .disclosure-body { padding: 0 8px 8px; }

/* —— 设置页 ——
   字阶统一走 tokens 令牌：页标题 --fs-h1 / 卡片标题 --fs-h2 / 分区标题 --fs-body /
   表单 label 与说明 --fs-small / 时间等弱信息 --fs-caption；不再混用裸像素 */
#settingsView { transform-origin: 50% 0; }
#settingsView.slide-in { animation: settings-open .34s var(--ease) backwards; }
@keyframes settings-open {
  from { clip-path: inset(0 0 100% 0); transform: translateY(-10px); opacity: .4; }
  to   { clip-path: inset(0 0 0 0); transform: none; opacity: 1; }
}
#settingsView.slide-out { animation: settings-close .32s var(--ease) forwards;
  /* 浮层化收起：不再在流内占位，homeView 可立即点亮——从抽屉进设置返回时，
     设置页直接向上滑走露出底下的条目抽屉，不再先闪主页再播下拉动画。
     top/left/width 由 hideSettings 按收起前它在流内的实际矩形写死：
     这里若改用 left/right + max-width 自行居中，宽度会跟着断点上限和
     滚动条消失后的可视区变化，收起瞬间整页横向扩张，就不再是直上直下。
     overflow 用 hidden：浮层自带纵向滚动条会挤掉约 15px 内容宽度 */
  position: fixed; bottom: 0; z-index: 47; overflow: hidden; background: var(--bg); }
@keyframes settings-close {
  from { clip-path: inset(0 0 0 0); transform: none; opacity: 1; }
  to   { clip-path: inset(0 0 100% 0); transform: translateY(-10px); opacity: .4; }
}
#settingsView > .page-head { margin-bottom: 16px; }
#settingsView h2 { font-size: var(--fs-h2); font-weight: 600; margin: 0 0 12px; }
#settingsView h3 { font-size: var(--fs-body); font-weight: 600; margin: 0; }
#settingsView .list-head h3 { flex: 1; }
#settingsView .subhead { margin-top: 26px; }
#settingsView .subhead + .help { margin-top: 6px; }
#settingsView .btnrow { margin-top: 14px; }
#profileList { margin-top: 4px; }
/* 内容平台分区：平台名做小标题，首个紧跟卡片标题不重复分隔线 */
.plat-head { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--border); }
#settingsView h2 + .plat-head { margin-top: 6px; padding-top: 0; border-top: none; }
.defrow { display: flex; align-items: center; gap: 10px; margin-top: 12px; flex-wrap: wrap; }
.defrow label { margin: 0; white-space: nowrap; flex: none; }
.defrow select { flex: 1; min-width: 0; width: auto; }
/* 桌面宽下第一个下拉会被拉到六百多像素，和一个模型名不相称 */
.defrow select:first-of-type { max-width: 360px; }
.pcard { display: flex; align-items: center; gap: 12px; border: 1px solid var(--border);
         border-radius: var(--radius-inner); padding: 14px 16px; margin-top: 12px; }
.pcard-main { flex: 1; min-width: 0; }
.pcard-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pcard-model { font-weight: 600; }
.pwrow { display: flex; gap: 8px; }
.pwrow input { flex: 1; }
.pwrow .eye { min-width: 60px; }
.bili-state { display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px;
              border-radius: var(--radius-inner); background: var(--surface-2); margin: 12px 0; }
.bili-ico { width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center;
            justify-content: center; font-weight: 700; flex: none; font-size: var(--fs-body); }
.st-ok { background: var(--ok-soft); color: var(--ok); }
.st-bad { background: var(--bad-soft); color: var(--bad); }
.st-warn { background: var(--warn-soft); color: var(--warn); }
.st-info { background: var(--info-soft); color: var(--info); }
/* 未连接/未配置不给「⋯」这种像更多菜单的符号：空圆虚线框，读作「这里还没有东西」 */
.bili-ico:empty { background: transparent; border: 1px dashed var(--border-strong); }
.bili-main { flex: 1; min-width: 0; }
.bili-title { font-weight: 600; }
.bili-desc { font-size: var(--fs-small); color: var(--text-2); margin-top: 2px; line-height: 1.5;
             overflow-wrap: anywhere; }
.devrow { display: flex; align-items: center; gap: 10px; padding: 10px 12px;
          border: 1px solid var(--border); border-radius: var(--radius-inner); margin-top: 8px; }
.devrow .devmain { flex: 1; min-width: 0; }
.devrow .devname { font-weight: 600; }
.devrow .devmeta { font-size: var(--fs-caption); color: var(--text-2); }
/* 插件下载入口（docs/26）：设置页与新手指导共用 .pd */
.pd { margin-top: 12px; }
/* .btn 是 inline-flex：直接放在块容器里会坐在文字基线上，下方留一段
   降部空隙，整块看起来比按钮本身高出一截。套一层 .row（flex）消掉它，
   按钮与同卡片下方「更新登录态」等默认档按钮同为 44px。 */
.pd-row { display: flex; }
.pd-btn { flex: none; }
.pd-btn svg { flex: none; }
.pd-steps { margin-top: 10px; }
.pd-steps code { font-size: .95em; color: var(--text); }
.pd-note { margin-top: 8px; }
/* 平台区块：小标题（.plat-head）已负责分隔，块内不再叠大间距 */
.platblock { margin-top: 4px; }

/* —— 初始化向导 —— */
.onboard { border: 1px solid var(--border); border-radius: var(--radius-card);
           background: var(--surface); box-shadow: var(--shadow-card); padding: 20px;
           margin-bottom: 20px; }
.onboard-title { font-size: var(--fs-h2); font-weight: 600; }
.onboard-sub { font-size: var(--fs-small); color: var(--text-2); margin: 4px 0 12px; }
.obsteps { display: flex; flex-direction: column; gap: 10px; }
.obstep { border: 1px solid var(--border); border-radius: var(--radius-inner); padding: 12px 14px; }
.obstep.done { border-color: var(--ok); }
.obstep-current { font-weight: 600; }
.obstate { display: inline-flex; align-items: center; gap: 6px; font-size: var(--fs-caption); }
.obstate::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--border-strong); }
.obstate.done::before { background: var(--ok); }
.obstate.pending::before { background: var(--border-strong); }
.obbody { margin-top: 8px; }
.obradio { display: flex; align-items: center; gap: 8px; padding: 6px 4px; min-height: 44px; }

/* —— 处理记录 —— */
.record-summary { display: flex; flex-direction: column; gap: 8px; }
.record-row { display: flex; gap: 10px; align-items: baseline; }
.record-stage { flex: none; width: 3.5em; font-weight: 600; }
.record-msg { flex: 1; min-width: 0; }
.techgrid { display: grid; grid-template-columns: max-content 1fr; gap: 4px 14px;
            font-size: var(--fs-caption); color: var(--text-2); overflow-wrap: anywhere; }
.techgrid b { font-weight: 500; }
.flash { animation: flashbg 1s var(--ease) 2; }
@keyframes flashbg { 50% { background: var(--accent-soft); } }

/* ============ 响应式（390/768/1440 走查） ============ */
@media (min-width: 1440px) {
  :root { --content-max: 720px; }
}
@media (max-width: 720px) {
  main, .topbar-inner { padding-left: 16px; padding-right: 16px; }
  .drawer-body { padding: 0 16px; }
  .card { padding: 18px; }
  .back { margin-left: -10px; }
  .detail-top { margin: 0 -16px; padding: 8px 16px 10px; }
  .rose { width: clamp(220px, 34vh, 320px); }
  .dock::before { inset: -22px -16px -16px; }
}
@media (max-width: 420px) {
  .step .slabel { font-size: 11px; }
  .sball { width: 20px; height: 20px; }
  .sline { top: 9px; left: calc(-50% + 16px); right: calc(50% + 16px); }
  .rose { width: clamp(190px, 30vh, 260px); }
  .rose-caption { font-size: var(--fs-display); }
  .smartbox.open { border-radius: 24px; }
}
@media (prefers-reduced-motion: reduce) {
  .rose .plant, .rose .glowPulse, .rose .litGlow, .rose .litHalo { animation: none !important; }
  .step.running .sline { animation: none; background: var(--accent); }
  .itembar.indeterminate > i, .stagepanel .panelbar.indeterminate > i { animation: none; left: 30%; }
  ul.items > li.enter, .detail { animation: none; }
  ul.items > li.pre { opacity: 1; }
}

/* ============ 作品：选材料 → 澄清 → 生成 → 预览 → 分享（docs/20 §3） ============ */
/* 选择条浮在抽屉面板下沿之上，不占列表的位置：占位会把条目整片顶上去（走查反馈）。
   仍然挂在面板里，所以跟着面板一起被 clip 收放，抽屉收起就跟着没，不会飘在采集框上。
   一进选择态就出现，0 篇也在。 */
.share-selbar { position: absolute; left: 0; right: 0; margin-inline: auto;
                bottom: calc(18px + env(safe-area-inset-bottom));
                width: fit-content; max-width: calc(100vw - 32px);
                display: flex; align-items: center; gap: 8px; flex-wrap: nowrap;
                padding: 8px 12px; white-space: nowrap;
                background: var(--surface); border: 1px solid var(--border-strong);
                border-radius: 999px; box-shadow: var(--shadow-2, 0 8px 28px rgba(0,0,0,.10));
                font-size: var(--fs-small); }
/* 条子压在列表上了，就给滚动区补一段底部留白：最后一条也滚得上去 */
body.share-selecting .drawer-scroll { padding-bottom: 78px; }
.share-selbar .btn { padding-inline: 12px; }
.share-selbar .spacer { flex: 1; min-width: 6px; }
.share-selbar[hidden] { display: none; }
/* 提示↔计数换的是同一格文字，格子宽度恒定：条子居中，文字一长短就把右边两个按钮横向推走 */
.share-selbar .seltext { min-width: 92px; display: inline-flex; }
.share-selbar .selcount, .share-selbar.has-sel .selhint { display: none; }
.share-selbar.has-sel .selcount { display: inline; }
.share-selbar .selhint { color: var(--text-2); }
.share-selbar .selcount .num { color: var(--accent); }
/* 一篇没选时两个动作还没得点：默认的 .5 半透明压在金底上仍像可按，再压一档 */
.share-selbar .btn:disabled { opacity: .38; }
/* 「操作」先问一句要对这批做什么：下载、重跑还是删除，就地一个小菜单，不另开一层弹窗。
   浮层在 main 下、z-index 高于抽屉那层（.drawer 是 z-index 30 的上下文），才点得到 */
.share-menu { position: fixed; left: 50%; transform: translateX(-50%); bottom: 88px; z-index: 41;
              display: flex; flex-direction: column; gap: 2px; min-width: 196px; padding: 6px;
              background: var(--surface); border: 1px solid var(--border-strong);
              border-radius: var(--radius-card); box-shadow: var(--shadow-pop); }
.share-menu[hidden] { display: none; }
/* 选中态不加圆框，点一下整张卡片四周亮起来：一圈描边 + 外发光 + 内侧一点反光，
   一次加光到位，不额外挂动画（走查反馈：加动画的点亮像闪一下）。
   整条收在 body.share-selecting 作用域下：退出多选态光是作用域没的就一次全灭，
   不用 JS 去清 .picked（审查 U-01：反向漏光），行重画时由 shares.js 补标记 */
body.share-selecting ul.items li.item.picked { background: var(--accent-soft);
                                               border-color: var(--accent);
                                               box-shadow: 0 0 0 1.5px var(--accent),
                                                           0 0 20px rgba(226, 176, 74, .3),
                                                           inset 0 0 22px rgba(226, 176, 74, .1); }
ul.items li.item { position: relative; }
body.share-selecting ul.items li.item { cursor: copy; }
/* 「多选」是个开关，按下必须亮：文案不动（多一个字就把同排的搜索钮横向推走），
   只把幽灵态换成描边 + 底色 + 一圈光，一次到位 */
#selectToggle.on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent);
                   box-shadow: 0 0 0 1px var(--accent), 0 0 16px rgba(226, 176, 74, .22);
                   transition: background var(--t-fast), border-color var(--t-fast),
                               color var(--t-fast), box-shadow var(--t-fast); }

/* ============ 分享创作：金蔷薇压成背景，中间只剩和 AI 的对话（docs/20 §3） ============ */
/* 整页盖一层强遮罩：底下还是首页那朵蔷薇，只是退成背景；输入框沿用首页胶囊那一副。
   只做压暗、不加模糊——模糊会让花在字后面糊成一片，走查反馈是「太模糊」 */
#shareStage, #sharesView { position: fixed; inset: 0; z-index: 36; display: flex; flex-direction: column;
                           padding: calc(var(--topbar-h) + 1px + 24px + env(safe-area-inset-top)) 0
                                    calc(16px + env(safe-area-inset-bottom));
                           animation: stage-in .16s var(--ease) backwards; }
#shareStage[hidden], #sharesView[hidden] { display: none; }
@keyframes stage-in { from { opacity: 0; } }
.stage-scrim { position: absolute; inset: 0; z-index: -1;
               background: linear-gradient(180deg, rgba(6, 4, 2, .84) 0%, rgba(6, 4, 2, .92) 100%); }
/* 对话舞台上不再摆采集框和抽屉拉手：两个输入框叠着会打架 */
body.share-open .dock, body.share-open .drawer { display: none; }
/* 栏宽收在自己的内边距里，与 main / drawer-body 同一套盒模型：
   标题左缘和叉叉右缘在各页面之间逐像素对齐 */
.stage-inner { position: relative; width: 100%; max-width: var(--content-max); margin: 0 auto;
               padding: 0 24px; flex: 1; min-height: 0;
               display: flex; flex-direction: column; gap: 10px; }
.stage-scroll { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
                display: flex; flex-direction: column; gap: 12px; padding: 2px 6px 2px 0; }
/* 话还少的时候贴着输入框那头摆，别在中间留一大片空；内容一溢出 auto 自己归零，不挡滚动 */
.stage-scroll > :first-child { margin-top: auto; }
/* 还没开说的状态（草稿/空列表/零会话）改成上下留白均分：开场构图居中，
   不像对话沉在输入框边上；一旦有来回就回到贴底那套 */
.stage-scroll.centered > :last-child { margin-bottom: auto; }
.stage-dock { flex: none; display: flex; flex-direction: column; gap: 8px; }

/* —— 对话流：AI 在左、你在右，材料/需求/成品作为卡片夹在中间 —— */
.t-msg { max-width: 68ch; padding: 13px 15px; border-radius: 14px; font-size: var(--fs-body);
         line-height: 1.6; overflow-wrap: anywhere; }
.t-msg.ai { align-self: flex-start; background: var(--surface-2); border: 1px solid var(--border); }
.t-msg.me { align-self: flex-end; background: var(--accent-soft); border: 1px solid var(--border-strong); }
.t-msg .munder { margin: 0; }
.t-q { margin-top: 12px; }
.t-q p { margin: 0; font-size: 14px; }
.qreason { color: var(--text-2); font-size: var(--fs-small); margin-top: 3px; }
.t-opts { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
/* 每个选项单独一行：整行可点，选中点亮 */
.t-opt { display: flex; align-items: center; gap: 9px; padding: 9px 12px; text-align: left;
         border: 1px solid var(--border-strong); border-radius: var(--radius-ctl); font-size: var(--fs-body);
         cursor: pointer; background: var(--surface); }
.t-opt input { width: auto; min-height: 0; margin: 0; flex: none; }
.t-opt:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.t-opt--other { border-style: dashed; }
/* 一次一题的问答卡：右上角往左／往右切上一题、下一题 */
.q-step .t-q { margin-top: 0; }
.q-step-head { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
.q-step-pos { font-size: var(--fs-small); color: var(--text-2); }
.q-step-head .spacer { flex: 1; }
.q-nav:disabled { opacity: .32; }
.q-other { margin-top: 8px; }
.q-other[hidden] { display: none; }
.q-other-input { font-size: var(--fs-body); min-height: 40px; resize: vertical; }
.tag-ai, .tag-block { display: inline-block; font-size: 11px; padding: 1px 6px; border-radius: 999px;
                      background: var(--info-soft); color: var(--info); margin-left: 6px; }
.tag-block { background: var(--warn-soft); color: var(--warn); }

.t-card { border: 1px solid var(--border); border-radius: var(--radius-card); background: var(--surface);
          padding: 14px 16px; }
.t-card > h4 { margin: 0 0 10px; font-size: var(--fs-small); font-weight: 600; letter-spacing: .4px;
               color: var(--text-2); }
.t-mats { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; font-size: var(--fs-small); }
.t-mats li { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.t-mats .mtitle { color: var(--text); overflow-wrap: anywhere; }
.t-mats .mmeta { color: var(--text-2); }
.t-mats li.warn { color: var(--warn); }
.brief-dl { margin: 0; display: grid; gap: 8px; }
.brief-dl dt { font-size: var(--fs-small); color: var(--text-2); }
.brief-dl dd { margin: 1px 0 0; font-size: 14px; overflow-wrap: anywhere; }
.pv-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pv-row .spacer { flex: 1; }
.pv-body { margin-top: 12px; }
.pv-body[hidden] { display: none; }
.share-frame { display: block; width: 100%; height: 62vh; border: 1px solid var(--border);
               border-radius: var(--radius-ctl); background: var(--surface); }
.share-link { font-size: var(--fs-small); margin: 10px 0 0; word-break: break-all; }

/* —— 需要看一眼的原因与随状态出现的按钮：钉在输入框上方，轮询重画对话流也不动它 —— */
.stage-status { flex: none; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.stage-status[hidden] { display: none; }
.stage-status .reason { font-size: var(--fs-small); color: var(--warn); }
.stage-actions { flex: none; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.stage-actions[hidden] { display: none; }
/* 对话输入框：左端没有文件钮，胶囊态不用为它让出那 52px */
#stageBox { --cap-left: 14px; }
#stageHint { margin: 0; padding: 0 4px; }
#stageHint:empty { display: none; }

/* —— 折叠件共用的三角：右+下两条边转 45° 朝下，摊开转成朝上 —— */
summary { list-style: none; cursor: pointer; }
summary::-webkit-details-marker { display: none; }
.proc-chev { flex: none; width: 7px; height: 7px; margin: 0 2px 2px 0;
             border-right: 1.6px solid var(--text-2); border-bottom: 1.6px solid var(--text-2);
             transform: rotate(45deg); transition: transform .16s var(--ease); }
details[open] > summary .proc-chev { transform: rotate(-135deg); margin: 2px 2px 0 0; }

/* —— 顶部：这一版的方向，折起来也留一行能对照 —— */
.stage-plan { flex: none; }
.stage-plan[hidden] { display: none; }
.plan { border: 1px solid var(--border); border-radius: var(--radius-ctl); background: var(--surface-2);
        padding: 0 12px; }
.plan > summary { display: flex; align-items: center; gap: 10px; min-height: 42px; }
.plan-title { flex: none; font-size: var(--fs-small); font-weight: 600; letter-spacing: .4px;
              color: var(--text-2); }
.plan-title .num { font-weight: 400; color: var(--text-2); margin-left: 3px; }
.plan-digest { flex: 1; min-width: 0; font-size: var(--fs-small); color: var(--text);
               overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.plan[open] .plan-digest { display: none; }
.plan .brief-dl { padding: 2px 0 13px; }
/* 摊开时两栏摆，别让它把上半屏占满：这一栏是拿来对照的，不是主角 */
@media (min-width: 721px) {
  .plan .brief-dl { grid-template-columns: 1fr 1fr; gap: 10px 22px; align-items: start; }
}

/* —— 贴着输入框的问答卡：回答就是紧接着的动作，不用回对话流里翻 —— */
.stage-ask { flex: none; max-height: 46vh; overflow-y: auto; overscroll-behavior: contain;
             padding-right: 6px; }
.stage-ask[hidden] { display: none; }
.stage-ask .t-card { border-color: var(--border-strong); }
.q-dots { display: inline-flex; align-items: center; gap: 5px; margin-left: 9px; }
.q-dot { width: 6px; height: 6px; border-radius: 999px; background: var(--border-strong);
         transition: background .16s var(--ease), box-shadow .16s var(--ease); }
.q-dot.done { background: var(--accent); }
.q-dot.now { box-shadow: 0 0 0 3px var(--accent-soft); }
.q-foot { display: flex; align-items: center; gap: 10px; margin-top: 13px; }
.q-done { font-size: var(--fs-small); color: var(--text-2); }
.q-done.all { color: var(--ok); }
.q-foot #askSubmit { margin-left: auto; }

/* —— 过程信息：服务端真实在跑的那一步，跑完自己折回一行 —— */
.t-proc { padding: 0 14px; }
.t-proc > summary { display: flex; align-items: center; gap: 9px; min-height: 44px; }
.proc-sum { font-size: var(--fs-body); }
.proc-sum[data-live] { color: var(--accent); }
.proc-cost { font-size: var(--fs-caption); color: var(--text-2); font-variant-numeric: tabular-nums; }
.proc-steps { list-style: none; margin: 0; padding: 0 0 13px; display: grid; gap: 8px;
              font-size: var(--fs-small); color: var(--text-2); }
.proc-steps li { display: flex; align-items: center; gap: 9px; }
.proc-steps li.ok, .proc-steps li.now, .proc-steps li.bad { color: var(--text); }
.proc-steps .num { color: var(--text-2); }
.proc-mark { flex: none; width: 13px; height: 13px; border-radius: 999px;
             border: 1.5px solid var(--border-strong);
             transition: background .18s var(--ease), border-color .18s var(--ease), box-shadow .18s var(--ease); }
.proc-steps li.ok .proc-mark { background: var(--ok); border-color: var(--ok); }
.proc-steps li.bad .proc-mark { background: var(--bad); border-color: var(--bad); }
.proc-steps li.now .proc-mark { border-color: var(--accent); background: var(--accent); }
.proc-steps[data-live] li.now .proc-mark { animation: proc-breathe 1.7s var(--ease) infinite; }
@keyframes proc-breathe {
  0%, 100% { box-shadow: 0 0 0 0 var(--accent-soft); }
  55% { box-shadow: 0 0 0 5px var(--accent-soft); }
}

/* —— 答完的问题轮次：折成一行，摊开时当初选的那项亮着 —— */
.t-round { margin-top: 12px; border: 1px solid var(--border); border-radius: var(--radius-ctl);
           background: var(--surface); padding: 0 12px; }
.t-round > summary { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; min-height: 38px; }
.t-round-q { flex: none; font-size: var(--fs-small); color: var(--text-2); }
.t-round-a { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.t-chip { max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
          font-size: var(--fs-caption); padding: 2px 9px; border-radius: 999px;
          background: var(--accent-soft); border: 1px solid var(--border); }
.t-round .t-q:first-of-type { margin-top: 2px; }
.t-round .t-q { margin-top: 14px; padding-bottom: 2px; }
.t-round .t-opt { cursor: default; opacity: .58; }
.t-round .t-opt--chosen { opacity: 1; border-color: var(--accent); background: var(--accent-soft); }
.t-dot { flex: none; width: 15px; height: 15px; border-radius: 999px;
         border: 1.5px solid var(--border-strong); }
.t-opt--chosen .t-dot { border-color: var(--accent);
                        background: radial-gradient(circle at 50% 50%, var(--accent) 0 3.5px, transparent 4px); }
.t-free { margin-top: 7px; padding-left: 24px; font-size: 14px; overflow-wrap: anywhere; }

/* —— 以前和 AI 的对话 —— */
.conv-note { flex: none; margin: 0; font-size: var(--fs-small); color: var(--text-2); }
.conv-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; align-content: start; }
.conv-list li.work { display: flex; align-items: baseline; gap: 4px 12px; flex-wrap: wrap;
                     padding: 12px 14px; cursor: pointer; border: 1px solid var(--border);
                     border-radius: var(--radius-card); background: var(--surface); }
.conv-list li.work:hover { border-color: var(--text-2); }
.conv-list li.work:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.conv-list .wtitle { font-weight: 600; overflow-wrap: anywhere; }
.conv-list .wmeta { font-size: var(--fs-caption); color: var(--text-2); margin-left: auto; white-space: nowrap; }

@media (max-width: 720px) {
  .stage-inner { padding: 0 16px; }
  .share-frame { height: 48vh; }
  .t-msg { max-width: none; }
  .stage-ask { max-height: 42vh; }
  .t-chip { max-width: 160px; }
}
@media (prefers-reduced-motion: reduce) {
  #shareStage, #sharesView { animation: none; }
  .proc-steps li.now .proc-mark { animation: none; }
  .proc-chev, .q-dot, .proc-mark { transition: none; }
}

/* ============ agent 自由对话面板（js/agent.js；docs/27） ============ */
/* 面板的结构和 class 全部复用上面分享舞台那一套（stage-* / smartbox / t-card / proc-*），
   这里只补三件面板特有的：遮罩层本身、定宽的会话切换条与它的下拉列表、过程行里的工具文本。
   颜色一律取 tokens.css 的 rose 令牌，不新增任何变量。 */
#agentView { position: fixed; inset: 0; z-index: 36; display: flex; flex-direction: column;
             padding: calc(var(--topbar-h) + 1px + 24px + env(safe-area-inset-top)) 0
                      calc(16px + env(safe-area-inset-bottom));
             animation: stage-in .1s var(--ease) backwards; }
#agentView[hidden] { display: none; }
/* 面板盖住首页那副采集框和抽屉拉手：两个输入框叠着会打架（同分享舞台） */
body.agent-open .dock, body.agent-open .drawer { display: none; }
/* 对话输入框左端没有文件钮，胶囊态不用为它让出那 52px（同 #stageBox） */
#agentBox { --cap-left: 14px; }
#agentHint { margin: 0; padding: 0 4px; }
#agentHint:empty { display: none; }

/* —— 会话切换条：定宽 + 省略号。切到哪一段、名字多长都不推动旁边的按钮
   （走查硬要求：交互过程中不许横向跳动；顶栏多一个按钮是一次性的布局变化，另说） —— */
.agent-switchwrap { flex: none; }
.agent-switchbtn { width: 200px; justify-content: flex-start; }
.agent-switch-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 下拉是绝对定位的浮层，开合都不占顶栏那一条的位置 */
.agent-sessions { width: min(400px, calc(100vw - 40px)); min-width: 0; padding: 8px; }
.agent-sess-head { display: flex; align-items: center; gap: 8px; padding: 0 2px 8px;
                   margin-bottom: 4px; border-bottom: 1px solid var(--border); }
ul.agent-sess-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px;
                     max-height: 46vh; overflow-y: auto; overscroll-behavior: contain; }
.agent-sess-empty { padding: 8px 6px; font-size: var(--fs-small); }
.agent-sess { display: flex; align-items: center; gap: 4px; border-radius: var(--radius-ctl); }
.agent-sess[data-now] { background: var(--accent-soft); }
/* 标题与时间分两行：横向只有一格会伸缩，行尾两个动作钮就被钉死在右边 */
.agent-sess-open { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start;
                   gap: 2px; min-height: 44px; padding: 7px 8px; border: none; background: transparent;
                   text-align: left; border-radius: var(--radius-ctl); }
.agent-sess-open:hover { background: var(--surface-2); border: none; }
.agent-sess-title { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
                    font-size: var(--fs-body); }
.agent-sess-meta { font-size: var(--fs-caption); color: var(--text-2); }
.agent-sess-acts { flex: none; display: flex; align-items: center; gap: 2px; }
button.agent-sess-act { width: 32px; min-width: 32px; height: 32px; min-height: 0; padding: 0; }

/* —— 过程行：只写真发出来的事件，长文本就地换行，不撑破卡片 —— */
.agent-proc-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.agent-tool { color: var(--text-2); }
.agent-toolname { color: var(--text); margin-left: 7px; }
.agent-tooltext { color: var(--text-2); font-size: var(--fs-caption); margin-left: 9px; }

/* —— 面板内的说明与错误：错误借语义色，排队和离线都只是普通一行 —— */
.stage-status .agent-note { font-size: var(--fs-small); color: var(--text-2); line-height: 1.5; }
.t-msg.agent-err { border-color: var(--bad); background: var(--bad-soft); }

/* —— 第一次使用的提示：把「读得多」和「Key 在中转站会出境」说在前面 —— */
.agent-first-p { margin: 0 0 10px; font-size: var(--fs-small); line-height: 1.65; color: var(--text-2); }
.agent-first-p:last-of-type { margin-bottom: 0; }

@media (max-width: 720px) {
  .agent-switchbtn { width: 132px; }
  /* 窄屏上切换条靠近屏幕中间，下拉按 right:0 绝对定位会往左溢出屏幕：
     改成贴着可视区两侧，标题就不再被切掉一半 */
  .agent-sessions { position: fixed; left: 16px; right: 16px; width: auto;
                    top: calc(var(--topbar-h) + 56px); }
}
@media (prefers-reduced-motion: reduce) {
  #agentView { animation: none; }
}
