:root {
  color-scheme: light;
  --bg: #e7ebef;
  --bg-soft: #f8fafc;
  --panel: #fcfdfe;
  --panel-2: #eff3f7;
  --border: rgba(18, 34, 50, 0.11);
  --border-strong: rgba(18, 34, 50, 0.22);
  --text: #0c151e;
  --muted: #6e7b88;
  --up: #c93a2b;      /* A股红涨 */
  --down: #0a7a52;    /* A股绿跌 */
  --accent: #2a5fd0;
  --accent-2: #4a7be8;
  --radius: 14px;
  --shadow: 0 8px 24px rgba(16, 32, 48, 0.10);
  --chrome: rgba(248, 250, 252, 0.90);
  --nav-bg: rgba(248, 250, 252, 0.98);
  --field-bg: #f8fafc;
  --surface-2: #eff3f7;
  --chart-bg: rgba(18, 34, 50, 0.035);
  --chart-grid-strong: rgba(18, 34, 50, 0.22);
  --chart-grid-weak: rgba(18, 34, 50, 0.09);
  --chart-label: #667786;
  --chart-tooltip-bg: rgba(248, 250, 252, 0.94);
  --chart-avg: #9a6a06;
  --scrollbar-thumb: rgba(18, 34, 50, 0.22);
  --body-bg:
    radial-gradient(900px 420px at 88% -12%, rgba(42, 95, 208, 0.09), transparent 64%),
    var(--bg);
}

/* 旧版仅保留两套配色：冷白钢蓝为默认，深空镭射可切换。
   两套配色只替换颜色令牌，不改变布局、间距与交互。 */

html[data-theme="aura"] {
  color-scheme: dark;
  --bg: #07090f;
  --bg-soft: #0f131b;
  --panel: #161b26;
  --panel-2: #181d29;
  --border: rgba(150, 165, 255, 0.11);
  --border-strong: rgba(150, 165, 255, 0.26);
  --text: #eef0fa;
  --muted: #757b96;
  --up: #ff6b63;
  --down: #3abe8e;
  --accent: #8c9bff;
  --accent-2: #63e2ff;
  --shadow: 0 8px 30px rgba(0, 0, 0, 0.42);
  --chrome: rgba(15, 19, 27, 0.88);
  --nav-bg: rgba(7, 9, 15, 0.98);
  --field-bg: #0f131b;
  --surface-2: #161b26;
  --chart-bg: rgba(3, 5, 9, 0.30);
  --chart-grid-strong: rgba(150, 165, 255, 0.18);
  --chart-grid-weak: rgba(150, 165, 255, 0.07);
  --chart-label: #8c93ad;
  --chart-tooltip-bg: rgba(7, 9, 15, 0.90);
  --chart-avg: #f0c96c;
  --scrollbar-thumb: rgba(150, 165, 255, 0.18);
  --body-bg:
    radial-gradient(1000px 470px at 88% -12%, rgba(140, 155, 255, 0.10), transparent 62%),
    radial-gradient(820px 380px at -8% 108%, rgba(99, 226, 255, 0.06), transparent 62%),
    var(--bg);
}

html[data-theme="day"] {
  color-scheme: light;
  --bg: #e7ebef;
  --bg-soft: #f8fafc;
  --panel: #fcfdfe;
  --panel-2: #eff3f7;
  --border: rgba(18, 34, 50, 0.11);
  --border-strong: rgba(18, 34, 50, 0.22);
  --text: #0c151e;
  --muted: #6e7b88;
  --up: #c93a2b;
  --down: #0a7a52;
  --accent: #2a5fd0;
  --accent-2: #4a7be8;
  --shadow: 0 8px 24px rgba(16, 32, 48, 0.10);
  --chrome: rgba(248, 250, 252, 0.90);
  --nav-bg: rgba(248, 250, 252, 0.98);
  --field-bg: #f8fafc;
  --surface-2: #eff3f7;
  --chart-bg: rgba(18, 34, 50, 0.035);
  --chart-grid-strong: rgba(18, 34, 50, 0.22);
  --chart-grid-weak: rgba(18, 34, 50, 0.09);
  --chart-label: #667786;
  --chart-tooltip-bg: rgba(248, 250, 252, 0.94);
  --chart-avg: #9a6a06;
  --scrollbar-thumb: rgba(18, 34, 50, 0.22);
  --body-bg:
    radial-gradient(900px 420px at 88% -12%, rgba(42, 95, 208, 0.09), transparent 64%),
    var(--bg);
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  height: 100%;
  overflow-x: clip;
}

body {
  background: var(--body-bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
               "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", sans-serif;
  font-size: 14px;
  line-height: 1.55;
}

/* ---------- 顶栏 ---------- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 64px;
  padding: 10px 22px;
  background: var(--chrome);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
  position: static;   /* 移动端: 顶栏随内容滚走, 让添加栏吸顶到最顶 */
  z-index: 20;
  white-space: nowrap;
}

.brand { display: flex; align-items: center; gap: 10px; }

.brand-dot {
  width: 12px; height: 12px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  box-shadow: 0 0 12px rgba(91, 140, 255, 0.7);
}

.brand h1 { font-size: 17px; font-weight: 600; letter-spacing: 0.5px; }

.badge {
  font-size: 12px;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
}

.badge-live {
  color: #ffd166;
  border-color: rgba(255, 209, 102, 0.4);
  background: rgba(255, 209, 102, 0.08);
}

.badge-closed { color: var(--muted); }
.badge-gray { color: var(--muted); }

.updated { color: var(--muted); font-size: 12px; }

.topbar-right {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* 今日财经早报: 顶栏右侧小胶囊按钮 */
.news-pill {
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  color: var(--accent);
  background: rgba(91, 140, 255, 0.10);
  border: 1px solid rgba(91, 140, 255, 0.4);
  border-radius: 999px;
  padding: 0 14px;
  cursor: pointer;
  white-space: nowrap;
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}

@media (hover: hover) {
  .news-pill:hover {
    color: var(--text);
    background: rgba(91, 140, 255, 0.2);
    border-color: var(--accent);
  }
}
.news-pill:focus-visible,
.topbar .settings-btn:focus-visible {
  outline-color: var(--accent);
}
.topbar .settings-btn {
  min-height: 44px;
  padding: 0 14px;
}

/* ---------- 布局(移动端优先: 底部 Tab + 单列) ---------- */
.layout {
  max-width: 1400px;
  margin: 0 auto;
  /* 2026-10-25 需求 97: 底部留白 112 → 24px。要让开固定 Tab 导航的 58px 现在由
     .beian-footer 自己的下内边距承担(页脚是正文最后一块), 这里再留 112px 只会变成
     一大片空档、把备案号推得离内容很远。 */
  padding: 14px 14px 24px;
}

.content { min-width: 0; }
.home-kpis { display: none; }
.home-shell { min-width: 0; }
.home-main { min-width: 0; }
.home-side { display: none; }

/* 页签内容区 */
.tabpage { display: none; }
.tabpage.active { display: block; }

/* 移动端底部导航 */
.tabnav {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 30;
  height: 58px; display: flex;
  background: var(--nav-bg); backdrop-filter: blur(12px);
  border-top: 1px solid var(--border);
  padding-bottom: env(safe-area-inset-bottom, 0);
}
.tabnav .tn {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px; min-height: 58px; border: 0; background: transparent; color: var(--muted);
  font: inherit; font-size: 11px; cursor: pointer; user-select: none;
  outline: 2px solid transparent; outline-offset: -3px;
}
.tabnav .tn .tn-ic { font-size: 19px; line-height: 1; }
.tabnav .tn.active { color: var(--accent); }
.tabnav .tn:focus-visible { outline-color: var(--accent); }

/* 桌面左侧导航(默认隐藏) */
.sidebar { display: none; }

/* 「我的」页 */
.me-page { max-width: 480px; margin: 0 auto; display: flex; flex-direction: column; gap: 10px; padding-top: 8px; }
.me-user {
  display: flex; align-items: center; gap: 14px;
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 16px; margin-bottom: 4px;
}
.me-av {
  width: 46px; height: 46px; border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  display: flex; align-items: center; justify-content: center; font-size: 19px; font-weight: 700; color: #fff;
}
.me-name { font-size: 16px; font-weight: 600; }
.me-meta { font-size: 12px; color: var(--muted); margin-top: 3px; }
.me-item {
  display: flex; align-items: center; gap: 12px;
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 14px 16px; color: var(--text); font-size: 14px; cursor: pointer; text-align: left;
  transition: border-color 0.15s, background 0.15s;
}
.me-item:hover { border-color: var(--border-strong); background: var(--panel-2); }
.me-item .me-ic { font-size: 17px; width: 24px; text-align: center; }
.me-item.me-danger { color: var(--up); border-color: rgba(255, 77, 94, 0.4); }
/* 「飞书配置」入口的灰化(2026-09-20 需求 63): 没绑邮箱时飞书整块不可用 ⇒ 入口整行置灰。
   写在 .me-item:hover 之后才能压住 hover 的高亮(它本来会让这一行重新变亮, 看着像能点)。 */
.me-item.me-locked { color: var(--muted); }
.me-item.me-locked .me-ic { opacity: 0.5; }
.me-item.me-locked:hover { border-color: var(--border); background: var(--panel); }
/* 邮箱绑定入口的「未绑定」小标(2026-09-14): 老账号与 admin 都没邮箱, 需要一眼看见 */
.me-badge { margin-left: auto; flex: none; font-size: 11px; padding: 1px 7px; border-radius: 9px;
            color: #d9b26a; background: rgba(217, 178, 106, 0.14);
            border: 1px solid rgba(217, 178, 106, 0.45); }
#me-theme-current { color: var(--accent); background: var(--panel-2); border-color: var(--border-strong); }
/* 图形验证码 + 邮箱验证码行(登录/注册/找回页与「邮箱绑定」弹窗共用) */
.cap-row { display: flex; gap: 8px; align-items: stretch; }
.cap-row input { flex: 1; min-width: 0; }
.cap-img { flex: none; width: 132px; height: 44px; border-radius: 6px; overflow: hidden;
           border: 1px solid var(--border); cursor: pointer; background: #f4f6f8; }
.cap-img svg { display: block; width: 100%; height: 100%; }
.code-row { display: flex; gap: 8px; align-items: stretch; }
.code-row input { flex: 1; min-width: 0; }
.code-row button { flex: none; width: 116px; padding: 0 6px; font-size: 12px;
                   white-space: nowrap; border: 1px solid var(--border); border-radius: 6px;
                   background: var(--panel-2); color: var(--muted); cursor: pointer; }
.code-row button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.code-row button:disabled { color: var(--muted); opacity: 0.6; cursor: not-allowed; }
/* AI Router 全体用量面板(「我的」页, 仅管理员可见) */
.me-router {
  display: flex; flex-direction: column; gap: 6px;
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 12px 14px; margin-bottom: 4px;
}
.me-router-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 2px; }
.me-router-title { font-size: 13px; font-weight: 600; color: var(--accent); }
.me-router-note { line-height: 1.5; }
/* AI Router 全体用量汇总(2026-09-04 三项改进): 去掉逐用户记录, 只显示今日/累计总 token */
.me-router-total { display: flex; flex-wrap: wrap; gap: 30px; padding: 10px 2px 4px; }
.me-router-total .mt-item { display: flex; flex-direction: column; gap: 3px; }
.me-router-total .mt-item span { font-size: 11px; color: var(--muted); }
.me-router-total .mt-item b { font-size: 22px; font-weight: 700; color: var(--accent); line-height: 1.15; }

/* 桌面端(≥900px): 左侧栏 + 多列卡片网格 */
@media (min-width: 900px) {
  .layout { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 18px; padding: 18px 22px 56px; }
  .tabnav { display: none; }
  /* 桌面端: 顶栏吸顶, 添加栏在顶栏下方吸顶 */
  .topbar { position: sticky; top: 0; }
  .addbar { top: 64px; }
  .sidebar {
    display: flex; flex-direction: column; padding: 14px 10px;
    position: sticky; top: 70px; height: calc(100vh - 90px);
    background: var(--bg-soft); border: 1px solid var(--border); border-radius: 14px;
  }
  .sb-logo { display: flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 700; padding: 6px 10px 16px; }
  .sb-item {
    display: flex; align-items: center; gap: 10px; padding: 11px 12px;
    width: 100%; min-height: 44px; border: 0; border-radius: 10px;
    background: transparent; color: var(--muted); font: inherit; font-size: 13px;
    text-align: left; cursor: pointer; margin-bottom: 4px;
    outline: 2px solid transparent; outline-offset: -2px;
  }
  .sb-item .sb-ic { font-size: 16px; width: 22px; text-align: center; }
  @media (hover: hover) {
    .sb-item:hover { background: var(--panel); color: var(--text); }
  }
  .sb-item:focus-visible { outline-color: var(--accent); }
  .sb-item.active { background: var(--panel); color: var(--accent); }
  .sb-user { margin-top: auto; display: flex; align-items: center; gap: 10px; padding: 10px; border-top: 1px solid var(--border); }
  .sb-av {
    width: 34px; height: 34px; border-radius: 50%;
    background: linear-gradient(135deg, var(--accent), var(--accent-2));
    display: flex; align-items: center; justify-content: center; font-size: 14px; font-weight: 700; color: #fff;
  }
  .sb-uname { font-size: 13px; color: var(--text); }
  .sb-urole { font-size: 11px; color: var(--muted); }
  .cards { grid-template-columns: repeat(3, 1fr); }
  .home-kpis {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 12px;
    margin: 0 0 14px;
  }
  .home-kpi {
    min-width: 0;
    padding: 13px 15px;
    background: linear-gradient(180deg, var(--panel) 0%, var(--bg-soft) 100%);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: var(--shadow);
  }
  .home-kpi-label {
    overflow: hidden;
    color: var(--muted);
    font-size: 11px;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .home-kpi-value {
    overflow: hidden;
    margin-top: 5px;
    color: var(--text);
    font-size: 23px;
    font-weight: 650;
    font-variant-numeric: tabular-nums;
    line-height: 1.15;
    letter-spacing: -0.02em;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .home-kpi-value small {
    margin-left: 4px;
    color: var(--muted);
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0;
  }
  .home-kpi-note {
    overflow: hidden;
    margin-top: 3px;
    color: var(--muted);
    font-size: 10.5px;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .home-kpi-move { font-size: 18px; letter-spacing: 0; }
  /* 桌面 AI 页: 聊天面板**铺满内容区**(2026-10-03 需求 78)。
     原口径 `max-width:680px; margin:0 auto` 会把对话框挤成屏幕中间一条竖条、两侧大片空白,
     用户要的是"铺满整块屏幕、能看得更宽"。高度按「顶栏 ≈56px(与既有 .addbar{top:54px} 同源,
     同为桌面顶栏高度口径) + .layout 上内边距 18px + 下内边距 30px = 104px」算, 正好填满可视区;
     `min-height: 460px` 沿用基础 .chat-panel 的兜底, 防极矮窗口把面板压塌。 */
  .tabpage#tab-ai .chat-panel { max-width: none; margin: 0; height: calc(100vh - 104px); }
}

/* PC 监控页右栏: 移植 v2 的最近触发 / 快捷入口 / 会员额度。
   只在宽桌面展开，避免 900~1319px 时把三列股票卡片压得过窄；
   手机端 .home-side 保持 display:none，原布局完全不变。 */
@media (min-width: 1320px) {
  .home-shell {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 280px;
    gap: 14px;
    align-items: start;
  }
  .home-shell .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .home-side {
    display: flex;
    flex-direction: column;
    gap: 12px;
    position: sticky;
    top: 138px;
    max-height: calc(100vh - 156px);
    overflow-y: auto;
    padding-right: 2px;
    scrollbar-width: thin;
  }
  .home-side-panel {
    background: linear-gradient(180deg, var(--panel) 0%, var(--bg-soft) 100%);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    overflow: hidden;
  }
  .home-side-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 13px 15px 9px;
  }
  .home-side-head h3 { font-size: 13px; font-weight: 600; color: var(--text); }
  .home-side-head > span {
    font-size: 11px;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
  }
  .home-side-events { padding: 0 15px 12px; }
  .home-side-event {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    width: 100%;
    padding: 9px 0;
    border: 0;
    border-top: 1px solid var(--border);
    background: transparent;
    color: var(--text);
    text-align: left;
    cursor: pointer;
  }
  .home-side-event:first-child { border-top: 0; padding-top: 2px; }
  .home-side-event:hover .home-side-event-name { color: var(--accent); }
  .home-side-event-time {
    flex: 0 0 36px;
    padding-top: 1px;
    color: var(--muted);
    font-size: 10px;
    line-height: 1.3;
    font-variant-numeric: tabular-nums;
  }
  .home-side-event-time i { display: block; font-style: normal; opacity: .78; }
  .home-side-event-body { flex: 1; min-width: 0; }
  .home-side-event-name {
    overflow: hidden;
    color: var(--text);
    font-size: 12px;
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .home-side-event-label {
    overflow: hidden;
    margin-top: 1px;
    color: var(--muted);
    font-size: 10.5px;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .home-side-event-price {
    flex: none;
    padding-top: 1px;
    font-size: 11.5px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
  }
  .home-side-event-price.up { color: var(--up); }
  .home-side-event-price.down { color: var(--down); }
  .home-side-empty { padding: 2px 0 8px; color: var(--muted); font-size: 12px; }

  .home-side-list { padding: 0 15px 5px; }
  .home-side-row {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    padding: 10px 0;
    border: 0;
    border-top: 1px solid var(--border);
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 12.5px;
    text-align: left;
    cursor: pointer;
  }
  .home-side-row:first-child { border-top: 0; }
  .home-side-row:hover .home-side-name { color: var(--accent); }
  .home-side-row:focus-visible,
  .home-side-event:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
  .home-side-ic { flex: none; width: 17px; text-align: center; font-size: 15px; }
  .home-side-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .home-side-count { flex: none; color: var(--muted); font-size: 10.5px; font-variant-numeric: tabular-nums; }
  .home-side-arrow { flex: none; color: var(--muted); font-size: 17px; line-height: 1; }

  .home-side-meta { padding: 0 15px 11px; }
  .home-side-meta > div {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding: 4.5px 0;
    color: var(--muted);
    font-size: 12px;
  }
  .home-side-meta b { color: var(--text); font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; }
}

/* ---------- 区块标题 ---------- */
.section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;   /* 无标题时数量靠左、工具栏靠右, 均匀排布 */
  flex-wrap: wrap;
  gap: 10px;
  margin: 6px 0 12px;
}

.section-head h2 { font-size: 15px; font-weight: 600; }

.count-pill {
  font-size: 12px;
  color: var(--muted);
  background: var(--panel);
  border: 1px solid var(--border);
  padding: 2px 10px;
  border-radius: 999px;
}

/* 记录区「清空」按钮(2026-10-25 需求 96): 与计数胶囊同排, 空列表时禁用 */
.head-actions { display: flex; align-items: center; gap: 8px; }
.btn-clear {
  font-size: 12px;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 4px 10px;
  line-height: 1.2;
  cursor: pointer;
}
.btn-clear:hover:not(:disabled) { color: #ff6b6b; border-color: #ff6b6b; }
.btn-clear:disabled { opacity: .45; cursor: default; }

.events-head { margin-top: 26px; }

/* ---------- 添加股票栏 ---------- */
.add-stock-bar {
  display: flex;
  gap: 10px;
  margin-bottom: 16px;
}

.add-stock-bar input {
  flex: 1;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 12px;
  padding: 11px 16px;
  font-size: 14px;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.add-stock-bar input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(91, 140, 255, 0.15);
}

/* 添加监控栏: 吸顶 + 输入提示 */
.addbar {
  position: sticky;
  top: 0;                 /* 滚动时吸顶到最顶部 */
  z-index: 12;
  background: var(--bg);
  padding: 10px 0 8px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 12px;
}
.addhint {
  font-size: 11px;
  color: var(--muted);
  margin-top: 5px;
  padding-left: 2px;
  line-height: 1.5;
  display: none;              /* 平时隐藏, 聚焦输入框时显示 */
}
.addbar:focus-within .addhint { display: block; }

/* 首次激活清单：限制在首页主流程上方的一条短面板，不遮挡行情。 */
.activation-card {
  margin: 0 0 14px;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background:
    linear-gradient(135deg,
      color-mix(in srgb, var(--accent) 7%, var(--panel)),
      var(--panel) 48%,
      var(--bg-soft));
  box-shadow: var(--shadow);
}
.activation-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
}
.activation-kicker {
  color: var(--accent);
  font-size: 11px;
  font-weight: 650;
  letter-spacing: .08em;
}
.activation-head h2 {
  margin-top: 2px;
  color: var(--text);
  font-size: 15px;
  line-height: 1.4;
}
.activation-collapse {
  flex: none;
  min-width: 52px;
  min-height: 44px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--bg-soft);
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
  outline: 2px solid transparent;
  outline-offset: 2px;
}
.activation-collapse:focus-visible { outline-color: var(--accent); }
.activation-body { margin-top: 12px; }
.activation-card.collapsed .activation-body { display: none; }
.activation-progress-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}
.activation-track {
  flex: 1;
  height: 6px;
  overflow: hidden;
  border-radius: 999px;
  background: var(--panel-2);
}
.activation-track > span {
  display: block;
  width: 0;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  transition: width .22s ease;
}
#activation-progress-text {
  flex: none;
  color: var(--muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.activation-steps {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 8px;
  list-style: none;
}
.activation-step {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  gap: 8px;
  width: 100%;
  min-height: 78px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: color-mix(in srgb, var(--bg-soft) 88%, transparent);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
  outline: 2px solid transparent;
  outline-offset: 2px;
}
.activation-step:focus-visible { outline-color: var(--accent); }
.activation-step.done {
  cursor: default;
  background: color-mix(in srgb, var(--accent) 7%, var(--bg-soft));
}
.activation-step.current {
  border-color: color-mix(in srgb, var(--accent) 48%, var(--border));
}
.activation-step-mark {
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid var(--border-strong);
  color: var(--muted);
  background: var(--panel);
  font-size: 12px;
  font-weight: 700;
}
.activation-step.done .activation-step-mark {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--bg);
}
.activation-step-copy { min-width: 0; }
.activation-step-label {
  display: block;
  font-size: 12.5px;
  font-weight: 650;
  line-height: 1.35;
}
.activation-step-desc {
  display: block;
  margin-top: 3px;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.45;
  overflow-wrap: anywhere;
}
.activation-note {
  min-height: 0;
  margin-top: 9px;
  color: var(--muted);
  font-size: 11.5px;
  line-height: 1.5;
}
.activation-note:empty { display: none; }
.activation-card.completed {
  border-color: color-mix(in srgb, var(--down) 38%, var(--border));
  background: color-mix(in srgb, var(--down) 7%, var(--panel));
}
.activation-card.completed .activation-kicker { color: var(--down); }
@media (prefers-reduced-motion: reduce) {
  .activation-track > span { transition: none; }
}

/* ---------- 按钮 ---------- */
.btn {
  border: none;
  cursor: pointer;
  border-radius: 12px;
  padding: 11px 20px;
  font-size: 14px;
  font-weight: 500;
  transition: transform 0.12s, box-shadow 0.12s, opacity 0.12s;
  white-space: nowrap;
}

.btn:active { transform: translateY(1px); }

.btn-primary {
  color: #fff;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  box-shadow: 0 4px 14px rgba(91, 140, 255, 0.35);
}

.btn-primary:hover { box-shadow: 0 6px 20px rgba(91, 140, 255, 0.5); }
.btn-primary:disabled { opacity: 0.55; cursor: default; }

.btn-ghost {
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border-strong);
}

.btn-ghost:hover { color: var(--text); }

/* 按钮置灰态(2026-09-17, BUGS #57): 「生成绑定码」不再用"藏起来"表达不可用, 而是**置灰 + 旁边写清
   原因**。.btn-ghost / .btn-danger 原先没有 :disabled 样式, 不加的话置灰后跟可点的长得一模一样。 */
.btn:disabled { cursor: default; transform: none; }
.btn-ghost:disabled, .btn-ghost:disabled:hover { color: var(--muted); opacity: 0.45; border-color: var(--border); }
.btn-danger:disabled, .btn-danger:disabled:hover { opacity: 0.45; }

.btn-icon { padding: 11px 14px; }

/* ---------- 股票卡片 ---------- */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 14px;
}

.card {
  background: linear-gradient(180deg, var(--panel) 0%, var(--bg-soft) 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 16px 14px;
  box-shadow: var(--shadow);
  transition: transform 0.15s, border-color 0.15s;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.card:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
}

.card-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.card-name { font-size: 15px; font-weight: 600; }
.card-code { color: var(--muted); font-size: 12px; }

.card-spacer { flex: 1; }

.btn-remove {
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 12px;
  padding: 3px 8px;
  border-radius: 8px;
  transition: color 0.15s, background 0.15s;
}

.btn-remove:hover { color: var(--up); background: rgba(255, 77, 94, 0.1); }

.card-price-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.card-price {
  font-size: 26px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.5px;
}

.price-up { color: var(--up); }
.price-down { color: var(--down); }

.pct-pill {
  font-size: 12px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 8px;
}

.pill-up { color: var(--up); background: rgba(255, 77, 94, 0.12); }
.pill-down { color: var(--down); background: rgba(0, 196, 140, 0.12); }
.pill-flat { color: var(--muted); background: rgba(139, 147, 167, 0.12); }

.card-stale {
  font-size: 11px;
  color: var(--muted);
}

.card-ma-row {
  display: flex;
  gap: 12px;
  font-size: 12px;
  color: var(--muted);
}

.ma-item { display: flex; flex-direction: column; align-items: center; gap: 1px; }
.ma-item b {
  color: var(--text);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.ma-item .ma-side-above { color: var(--up); }
.ma-item .ma-side-below { color: var(--down); }

.card-chart {
  width: 100%;
  height: 200px;
  display: block;
  border-radius: 8px;
  background: var(--chart-bg);
  cursor: pointer;   /* 提示可点击查看日K线 */
}

.card-targets { display: flex; flex-wrap: wrap; gap: 6px; }

.t-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 10px;
  color: var(--text);
}

.t-chip.done { opacity: 0.45; text-decoration: line-through; }

/* 触发条件 chip 的 label 可点击编辑(hover 高亮提示可点) */
.t-chip .t-chip-edit {
  cursor: pointer;
  border-radius: 999px;
  padding: 0 2px;
}

.t-chip .t-chip-edit:hover {
  color: var(--accent);
  background: rgba(91, 140, 255, 0.12);
}

.t-chip .chip-close {
  background: none;
  border: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
  padding: 0;
}

.t-chip .chip-close:hover { color: var(--up); }

.btn-add-trigger {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  background: transparent;
  color: var(--accent);
  border: 1px dashed rgba(91, 140, 255, 0.5);
  border-radius: 999px;
  padding: 4px 12px;
  cursor: pointer;
  transition: background 0.15s;
}

.btn-add-trigger:hover { background: rgba(91, 140, 255, 0.1); }

/* ---------- 卡片折叠视图(工具栏「⤢ 折叠」: 仅显示 名称+现价+涨跌幅; 单卡 .expanded 恢复完整显示) ---------- */
/* 与既有 .chat-panel.collapsed 互不冲突: 选择器限定在 .cards.collapsed 下;
   :not(.expanded) 让被单独展开的卡片自动回落基础 .card 样式(完整显示均线/明细/分时/触发条件) */
.cards.collapsed .card:not(.expanded) .card-ma-row,
.cards.collapsed .card:not(.expanded) .card-oh-row,
.cards.collapsed .card:not(.expanded) .card-ind-row,
.cards.collapsed .card:not(.expanded) .card-chart,
.cards.collapsed .card:not(.expanded) .card-targets { display: none; }

.cards.collapsed .card:not(.expanded) {
  padding: 12px 14px 10px;
  gap: 6px;
}

.cards.collapsed .card:not(.expanded) .card-price { font-size: 22px; }

/* ---------- 事件列表 ---------- */
.events {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 320px;
  overflow-y: auto;
}

.event {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 10px 14px;
}

.event-icon {
  font-size: 15px;
  line-height: 1.5;
  flex-shrink: 0;
}

.event-body { min-width: 0; }
.event-title { font-size: 13px; font-weight: 500; }
.event-meta { font-size: 12px; color: var(--muted); margin-top: 2px; }

/* ---------- 操作记录 ---------- */
.userops-head { margin-top: 26px; }

/* 2026-10-25 需求 98: 与「已触发事件」同款限高滚动列表(原来只渲染 2 条 + 滑动条翻页)。
   320px 约 4~5 条; 更早的记录在面板内向上滚即可, 不再有"第 X~Y 条"的翻页概念。 */
.userops-window {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 320px;
  overflow-y: auto;
}

.userop {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 10px 14px;
}

.userop-head {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: none;
  min-width: 96px;
}

.userop-tag {
  font-size: 11px;
  font-weight: 600;
  padding: 1px 8px;
  border-radius: 999px;
  flex: none;
}

.userop-add { color: var(--down); background: rgba(0, 196, 140, 0.12); }
.userop-edit { color: var(--accent); background: rgba(91, 140, 255, 0.12); }
.userop-del { color: var(--up); background: rgba(255, 77, 94, 0.12); }

.userop-name {
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}

.userop-body { min-width: 0; flex: 1; }
.userop-detail { font-size: 13px; font-weight: 500; }
.userop-meta { font-size: 12px; color: var(--muted); margin-top: 2px; }

/* ---------- 空态 ---------- */
.empty-hint {
  color: var(--muted);
  text-align: center;
  padding: 26px 0;
  font-size: 13px;
}

/* ---------- 聊天面板 ---------- */
.chat-panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  height: calc(100vh - 80px);
  min-height: 460px;
  overflow: hidden;
}

.chat-head {
  padding: 14px 16px 10px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 8px;
}

.chat-head h2 { font-size: 15px; }
/* 2026-09-04 聊天头副标题: 蓝色11px(小一号)、整句一行完整显示不截断(极端超窄省略兜底) */
.chat-sub {
  font-size: 11px;
  font-weight: 500;
  color: var(--accent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

/* 右上角工具区(清空 / 放大) */
.chat-tools {
  margin-left: auto;
  display: flex;
  gap: 4px;
  flex: none;
}
.chat-max {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  padding: 5px 7px;
  border-radius: 6px;
  flex: none;
}
.chat-max:hover { color: var(--accent); background: rgba(127, 127, 127, 0.12); }

/* 聊天头「?」帮助按钮: 圆形实底徽标(蓝底白字), 与边框/强调色主题协调(区别于右侧矩形清空按钮) */
.chat-help {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: none;
  border-radius: 50%;
  font-size: 12px;
  font-weight: 600;
  color: #fff;
  background: var(--accent);
  line-height: 1;
  cursor: pointer;
  flex: none;
}
.chat-help:hover {
  color: #fff;
  filter: brightness(1.15);
}
/* 2026-09-04: 「?」旁小字「帮助」(同开帮助弹窗, 与蓝圆钮一组) */
.chat-help-txt {
  font-size: 11px;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
}
.chat-help-txt:hover { color: var(--accent); }

/* AI 对话放大弹窗(2026-10-03 需求 78 起为**真全屏**: 顶栏聊天头右侧 ⛶ 进入, ✕ / Esc 退出) */
.chat-modal-mask {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(5, 7, 12, 0.55);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;              /* 真全屏: 遮罩不再留边距 */
}
.chat-modal {
  /* 用 100%/100%(相对 inset:0 的遮罩)而不是 100vw/100vh: vw **含纵向滚动条宽度**,
     桌面上会让这个 fixed 元素比可视区宽出一条滚动条的量, 平白多出一条横向滚动条。 */
  width: 100%;
  height: 100%;
  background: var(--panel);
  border: none;
  border-radius: 0;
  box-shadow: var(--shadow);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  animation: msg-in 0.18s ease;
}
.chat-modal-head {
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 8px;
}
/* 2026-10-03 需求 79: 弹窗头原来那条给 h2 设 15px 字号的规则, 随标题一起删除(HTML 里已无 h2)。 */
/* 2026-09-04 放大弹窗副标题: 与主聊天头同款 蓝+11px+一行完整 */
.chat-modal-sub {
  font-size: 11px;
  font-weight: 500;
  color: var(--accent);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.chat-modal-head .chat-max { margin-left: auto; }
.chat-modal-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
.chat-modal-body .chat-messages { flex: 1; min-height: 0; }
.chat-modal-body .chat-input-row { border-top: 1px solid var(--border); }
.chat-modal-body .chat-examples { padding: 10px 16px 8px; }
.chat-modal-body .msg { max-width: 92%; font-size: 14px; }

/* 消息区外壳(2026-10-03 需求 84): 「↓ 回到最新」按钮要钉在消息区右下角,
   而 #chat-messages 自身是 overflow-y:auto 的滚动容器 —— 按钮若塞进它里面会被一起滚走。
   所以给消息区加一层定位外壳, 按钮与消息**并列**: 滚动的只有消息, 按钮不滚。
   外壳同时接管"占据剩余高度"这件事(嵌套 flex 下必须 min-height:0, 否则内层滚不动)。
   **搬运清单**: toggleChatModal 搬的是这个外壳(.chat-messages-wrap), 不再是 #chat-messages。 */
.chat-messages-wrap {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.chat-messages-wrap .chat-messages { flex: 1; min-height: 0; }

/* 「↓ 回到最新消息」: 只有"往上翻了历史"时才出现(判定见 app.js updateChatScrollBtn)。
   不复用 .chat-max —— 那个类会被当成聊天头工具按钮搬进全屏头部。 */
.chat-scroll-bottom {
  position: absolute;
  right: 14px;
  bottom: 10px;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--panel-2);
  border: 1px solid var(--border-strong);
  color: var(--text);
  font-size: 14px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: var(--shadow);
  z-index: 5;
}

.chat-scroll-bottom:hover { color: var(--accent); border-color: var(--accent); }

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 14px 14px 6px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.msg {
  max-width: 88%;
  padding: 9px 13px;
  border-radius: 14px;
  font-size: 13px;
  white-space: pre-wrap;
  word-break: break-word;
  animation: msg-in 0.18s ease;
}

@keyframes msg-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

.msg-user {
  align-self: flex-end;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: #fff;
  border-bottom-right-radius: 4px;
}

.msg-ai {
  align-self: flex-start;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-bottom-left-radius: 4px;
}

.msg-error {
  align-self: flex-start;
  color: var(--up);
  background: rgba(255, 77, 94, 0.08);
  border: 1px solid rgba(255, 77, 94, 0.3);
}

/* Markdown 渲染的 AI 回复(msg-md) */
.msg-md { white-space: normal; overflow-wrap: anywhere; word-break: break-word; }
.msg-md > *:first-child { margin-top: 0; }
.msg-md > *:last-child { margin-bottom: 0; }
.msg-md h1, .msg-md h2, .msg-md h3, .msg-md h4 {
  margin: 7px 0 4px;
  font-size: 14px;
  line-height: 1.35;
}
.msg-md h1 { font-size: 16px; }
.msg-md h2 { font-size: 15px; }
.msg-md p { margin: 4px 0; line-height: 1.5; }
.msg-md ul, .msg-md ol { margin: 4px 0; padding-left: 20px; }
.msg-md li { margin: 2px 0; line-height: 1.45; }
.msg-md strong { font-weight: 700; }
.msg-md code {
  background: rgba(127, 127, 127, 0.18);
  border-radius: 4px;
  padding: 1px 5px;
  font-size: 12px;
  font-family: ui-monospace, SFMono-Regular, Consolas, "Courier New", monospace;
}
.msg-md pre {
  background: rgba(0, 0, 0, 0.25);
  border-radius: 8px;
  padding: 8px 10px;
  white-space: pre-wrap;
  word-break: break-word;
  overflow-wrap: anywhere;
  overflow-x: hidden;
  margin: 6px 0;
}
.msg-md pre code { background: none; padding: 0; }
.msg-md table { border-collapse: collapse; margin: 6px 0; width: 100%; font-size: 12px; }
.msg-md th, .msg-md td { border: 1px solid var(--border); padding: 4px 8px; text-align: left; }
.msg-md th { background: rgba(127, 127, 127, 0.15); }
.msg-md tr:nth-child(even) td { background: rgba(127, 127, 127, 0.06); }
.msg-md hr { border: none; border-top: 1px solid var(--border); margin: 8px 0; }
.msg-md blockquote {
  border-left: 3px solid var(--accent);
  margin: 6px 0;
  padding: 2px 10px;
  color: var(--muted);
}
.msg-md a { color: var(--accent); text-decoration: underline; }

.typing {
  align-self: flex-start;
  color: var(--muted);
  font-size: 12px;
  padding: 6px 4px;
}

.typing .dot {
  display: inline-block;
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--muted);
  margin-right: 4px;
  animation: blink 1.2s infinite;
}

.typing .dot:nth-child(2) { animation-delay: 0.2s; }
.typing .dot:nth-child(3) { animation-delay: 0.4s; }

@keyframes blink { 0%, 60%, 100% { opacity: 0.25; } 30% { opacity: 1; } }

/* 快捷问法(2026-10-03 需求 82): 手机上要控制在**两行以内** —— 尺寸收小是"同一行/两行"的
   代价(与需求 78/81 的顶栏/工具栏同一思路: 靠收尺寸买行数, 不靠 flex-end+overflow-x)。
   注意: gap / font-size / padding 三个数值与 app.js 的 CHIP_*_PX 常量**必须一致**
   (估算器在页签不可见时按它们兜底), 改一处要改两处。 */
.chat-examples {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  padding: 3px 14px 8px;
}

/* 作用域限定在快捷问法内, 不动通用 .chip(将来别的模块可能复用它)。
   white-space:nowrap 让"两行"的口径唯一 —— 没有它, 单颗长 chip 会自己内部折行,
   "行数"就没法按 offsetTop 判定。 */
.chat-examples .chip {
  font-size: 11px;
  padding: 3px 9px;
  white-space: nowrap;
}

.chip {
  font-size: 12px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 999px;
  padding: 4px 12px;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}

.chip:hover { color: var(--accent); border-color: var(--accent); }

/* 共享机器人绑定码(2026-09-17 需求 59): 6 位数字放大 + 拉开字距, 方便对着抄到飞书里;
   右侧「复制」按钮做一键复制(clipboard 不可用的 http 场景由 JS 兜底)。 */
.shared-code-big {
  font-size: 30px;
  font-weight: 700;
  letter-spacing: 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  color: var(--accent);
  vertical-align: middle;
}

.shared-code-copy {
  font-size: 12px;
  padding: 3px 10px;
  margin-left: 8px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--muted);
  cursor: pointer;
  vertical-align: middle;
}

.shared-code-copy:hover { color: var(--accent); border-color: var(--accent); }

/* AI 对话的消息日期分隔(2026-09-17 需求 59): 同一天的消息共用一个日期标签,
   换天(或跨设备恢复历史)时才插一条, 免得每条消息都顶一个时间戳。 */
.chat-day {
  align-self: center;
  font-size: 11px;
  color: var(--muted);
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 10px;
  margin: 2px 0;
}

.chat-input-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px;
  padding: 10px 14px 14px;
  border-top: 1px solid var(--border);
}

/* finesse · component: chat-composer · register=product
 * states: default · hover · focus-visible · active · disabled · loading · error · success
 * tokens: inherited */
.chat-attach {
  position: relative;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  padding: 0;
  background: var(--bg-soft);
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 14px;
  display: grid;
  place-items: center;
  cursor: pointer;
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: background-color .16s ease, border-color .16s ease,
              color .16s ease, transform .12s ease;
}
.chat-attach svg {
  display: block;
  width: 20px;
  height: 20px;
}
@media (hover: hover) {
  .chat-attach:hover {
    background: var(--panel-2);
    border-color: color-mix(in srgb, var(--accent) 58%, var(--border));
    color: var(--accent);
    transform: translateY(-1px);
  }
}
.chat-attach:focus-visible {
  outline-color: var(--accent);
  border-color: var(--accent);
}
.chat-attach:active {
  transform: translateY(1px) scale(.98);
}
.chat-attach:disabled,
.chat-attach[aria-disabled="true"] {
  opacity: .5;
  cursor: not-allowed;
  transform: none;
}
.chat-attach[data-state="loading"] svg { opacity: .16; }
.chat-attach[data-state="loading"]::after {
  content: "";
  position: absolute;
  width: 16px;
  height: 16px;
  border: 2px solid color-mix(in srgb, var(--accent) 24%, transparent);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: chat-attach-spin .65s linear infinite;
}
.chat-attach[data-state="error"] {
  color: var(--up);
  border-color: color-mix(in srgb, var(--up) 65%, var(--border));
}
.chat-attach[data-state="success"] {
  color: var(--accent);
  border-color: color-mix(in srgb, var(--accent) 65%, var(--border));
}
@keyframes chat-attach-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .chat-attach,
  .chat-preview-remove,
  .chat-send,
  .chat-msg-img { transition: none; }
  .chat-attach[data-state="loading"]::after { animation: none; }
}

.chat-preview {
  order: -1;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding: 2px 0;
}
.chat-preview-item {
  position: relative;
  width: 64px;
  height: 64px;
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--bg-soft);
  box-shadow: 0 4px 14px color-mix(in srgb, var(--text) 8%, transparent);
}
.chat-preview-item img { display: block; width: 100%; height: 100%; object-fit: cover; }
.chat-preview-remove {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 1px solid color-mix(in srgb, var(--text) 14%, transparent);
  border-radius: 50%;
  background: color-mix(in srgb, var(--text) 82%, transparent);
  color: var(--bg);
  font-size: 17px;
  line-height: 1;
  display: grid;
  place-items: center;
  cursor: pointer;
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: background-color .15s ease, border-color .15s ease;
}
.chat-preview-remove::before {
  content: "";
  position: absolute;
  inset: -10px;
}
@media (hover: hover) {
  .chat-preview-remove:hover {
    background: var(--accent);
    border-color: var(--accent);
  }
}
.chat-preview-remove:focus-visible { outline-color: var(--accent); }
.chat-preview-remove:active { background: color-mix(in srgb, var(--accent) 78%, var(--text)); }

/* 已发送用户消息里的缩略图；原图由本机 IndexedDB 恢复。 */
.chat-msg-imgs { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.chat-msg-img {
  width: 64px;
  height: 64px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--border);
  cursor: zoom-in;
  transition: transform 0.15s ease, border-color 0.15s ease;
}
.chat-msg-img:hover,
.chat-msg-img:focus-visible {
  transform: scale(1.03);
  border-color: var(--accent);
}
.chat-msg-img:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.chat-input-row input,
.chat-input-row textarea {
  flex: 1;
  min-width: 0;   /* 允许 flex 收缩, 防止窄屏下被内容撑宽导致附件/发送按钮换行 */
  background: var(--bg-soft);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 12px;
  padding: 10px 14px;
  font-size: 13px;
  outline: none;
  transition: border-color 0.15s;
}

.chat-input-row textarea {
  resize: none;
  overflow-y: auto;
  line-height: 1.5;
  min-height: 44px;   /* 与附件/发送按钮共享一个触控高度 */
  max-height: 76px;   /* 两行上限, 超出内部滚动 */
  font-family: inherit;
}

.chat-input-row input:focus,
.chat-input-row textarea:focus { border-color: var(--accent); }

.chat-input-row .chat-send {
  flex: none;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 14px;
  display: grid;
  place-items: center;
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: transform .12s ease, background-color .16s ease, opacity .16s ease;
}
.chat-input-row .chat-send svg {
  display: block;
  width: 18px;
  height: 18px;
}
@media (hover: hover) {
  .chat-input-row .chat-send:not(:disabled):hover { transform: translateY(-1px); }
}
.chat-input-row .chat-send:focus-visible { outline-color: var(--accent); }
.chat-input-row .chat-send:active { transform: translateY(1px) scale(.98); }
.chat-input-row .chat-send:disabled {
  opacity: .5;
  cursor: not-allowed;
  transform: none;
}

/* AI 助手记忆保留提示 */

/* ---------- 弹窗 ---------- */
.modal-mask {
  position: fixed;
  inset: 0;
  background: rgba(5, 7, 12, 0.65);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
}

.modal {
  width: min(420px, calc(100vw - 40px));
  background: var(--panel);
  border: 1px solid var(--border-strong);
  border-radius: 16px;
  box-shadow: var(--shadow);
  overflow: hidden;
  animation: msg-in 0.18s ease;
}

/* 日K线弹窗: 加宽容器, 层级高于聊天放大弹窗(200) */
.modal-lg {
  width: min(980px, 94vw);
}

#kline-modal {
  z-index: 210;
}

/* 聊天页「? 帮助」弹窗必须压在全屏对话遮罩(200)之上 —— 它是从全屏对话里点开的,
   同层的话后开的反而在下, 藏起来就等于点了没反应(同 #kline-modal/#qr-modal 那条惯例)。
   只抬这一个弹窗, **不动 .modal-mask 的基础值 100**(那会连带抬高全部弹窗)。 */
#chat-help-modal {
  z-index: 219;
}

/* 聊天图片查看器: 覆盖 AI 对话全屏层，图片按视口等比完整显示。 */
#chat-image-modal { z-index: 230; }
.chat-image-full {
  display: block;
  width: auto;
  height: auto;
  max-width: min(94vw, 1440px);
  max-height: calc(100vh - 56px);
  max-height: calc(100dvh - 56px);
  object-fit: contain;
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.36);
  cursor: zoom-out;
}
.chat-image-close {
  position: fixed;
  top: max(12px, env(safe-area-inset-top, 0px));
  right: max(12px, env(safe-area-inset-right, 0px));
  z-index: 231;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--panel);
  border: 1px solid var(--border-strong);
  color: var(--text);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

#kline-canvas {
  width: 100%;
  height: 330px;
  display: block;
  border-radius: 8px;
  background: var(--chart-bg);
  cursor: grab;   /* 日K弹窗支持拖动平移 */
  touch-action: none;          /* 触摸手势完全交给 JS(长按/平移/捏合), 禁用浏览器默认滚动/缩放 */
  -webkit-touch-callout: none; /* 防 iOS 长按弹菜单 */
  user-select: none;           /* 防长按选中画布文本 */
}

#kline-canvas.kline-grabbing {
  cursor: grabbing;
}

/* 日K弹窗提示条(操作说明 + 可见日期区间) */
.kline-hint {
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 2px;
}

/* 日K弹窗表头信息条(悬停/默认显示最新一天 OHLC+涨跌+量, 同花顺式; 非浮窗, 不打断交互) */
.kline-info {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 10px;
  font-size: 12px;
  color: var(--muted);
  min-height: 18px;
}

.kline-info .ki-date {
  color: var(--text);
  font-weight: 600;
  margin-right: 2px;
}

.kline-info b {
  color: var(--text);
  font-weight: 500;
}

/* 涨跌额/幅随涨跌着色(复用全局 --up/--down) */
.kline-info b.price-up { color: var(--up); }
.kline-info b.price-down { color: var(--down); }

/* 日K弹窗均线显隐开关行(与提示条间距 6px, 开关高亮/置灰切换) */
.kline-ma-toggles {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
}

.kline-ma-label {
  font-size: 12px;
  color: var(--muted);
  margin-right: 2px;
}

.ma-toggle {
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: 12px;
  line-height: 1;
  padding: 4px 10px;
  border-radius: 12px;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}

.ma-toggle:hover { color: var(--text); }

.ma-toggle.on {
  color: var(--text);
  border-color: var(--accent);
  background: rgba(91, 140, 255, 0.12);
}

.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 18px 12px;
}

.modal-head h3 { font-size: 15px; }

.modal-close {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 15px;
  cursor: pointer;
}

.modal-close:hover { color: var(--text); }

.modal-body { padding: 4px 18px 8px; display: flex; flex-direction: column; gap: 12px; }

.modal-stock { font-size: 13px; color: var(--muted); }

.field { display: flex; flex-direction: column; gap: 6px; }
.field > span { font-size: 12px; color: var(--muted); }

.field select, .field input {
  background: var(--bg-soft);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 10px;
  padding: 9px 12px;
  font-size: 14px;
  outline: none;
}

.field select:focus, .field input:focus { border-color: var(--accent); }

/* 2026-09-15 需求: 只读字段(管理员用户配置里的飞书 App ID) —— 视觉弱化, 一眼看出不可改 */
.field input[readonly], .field input[readonly]:focus {
  background: var(--bg);
  color: var(--muted);
  border-style: dashed;
  cursor: not-allowed;
}

.field-row { display: flex; align-items: center; gap: 6px; }
.field-row input { flex: 1; min-width: 0; }
.field-row .btn-mini { margin-left: 0; white-space: nowrap; }
.field-hint { font-size: 12px; color: var(--muted); min-height: 14px; }

.radio-row { display: flex; gap: 14px; }

.radio {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-size: 13px;
}

.radio input { accent-color: var(--accent); }
.radio-label { color: var(--text); }

/* 步骤引导 / 字段说明 / 成功反馈(2026-09-14 邮箱绑定可用性优化) */
.step-tip {
  font-size: 12px; color: var(--muted); line-height: 1.8;
  background: var(--bg-soft); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 10px; margin-bottom: 8px;
}
.step-tip b { color: var(--text); font-weight: 600; }
/* 行内说明复用既有的 .field-hint(12px muted, 触发表单同款), 不另立规则 */
.form-ok {
  color: #48bb78;
  font-size: 12px;
  background: rgba(72, 187, 120, 0.08);
  border: 1px solid rgba(72, 187, 120, 0.3);
  border-radius: 10px;
  padding: 8px 12px;
}

.form-error {
  color: var(--up);
  font-size: 12px;
  background: rgba(255, 77, 94, 0.08);
  border: 1px solid rgba(255, 77, 94, 0.3);
  border-radius: 10px;
  padding: 8px 12px;
}

/* ---------- 触发条件弹窗(周期快捷选择 / 重复提醒 / 实时预检) ---------- */
.preset-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }

.preset-chip {
  font-size: 12px;
  color: var(--muted);
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 9px;
  cursor: pointer;
  font-variant-numeric: tabular-nums;
  transition: color 0.15s, border-color 0.15s;
}

.preset-chip:hover { color: var(--accent); border-color: var(--accent); }

.checkbox-field { gap: 4px; }

/* 实时预检条: 展示引擎口径的文案/对应价位/是否已满足(创建前就能看到结果) */
.trigger-preview {
  font-size: 12px;
  color: var(--text);
  background: rgba(91, 140, 255, 0.08);
  border: 1px solid rgba(91, 140, 255, 0.28);
  border-radius: 10px;
  padding: 8px 12px;
  line-height: 1.6;
}

.trigger-preview.warn {
  color: #ffb86c;
  background: rgba(255, 184, 108, 0.08);
  border-color: rgba(255, 184, 108, 0.3);
}

.modal-foot {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 6px 18px 16px;
}

/* 今日财经早报弹窗正文(Markdown 渲染, 长文可滚动) */
.news-content {
  max-height: 62vh;
  overflow-y: auto;
  line-height: 1.7;
  font-size: 14px;
}

.news-content h1, .news-content h2, .news-content h3, .news-content h4 {
  margin: 10px 0 6px;
  line-height: 1.35;
}
.news-content h1 { font-size: 18px; }
.news-content h2 { font-size: 16px; }
.news-content h3, .news-content h4 { font-size: 15px; }
.news-content p { margin: 6px 0; }
.news-content ul, .news-content ol { margin: 6px 0; padding-left: 22px; }
.news-content li { margin: 3px 0; line-height: 1.6; }
.news-content strong { font-weight: 700; }
.news-content code {
  background: rgba(127, 127, 127, 0.18);
  border-radius: 4px;
  padding: 1px 5px;
  font-size: 13px;
  font-family: ui-monospace, SFMono-Regular, Consolas, "Courier New", monospace;
}
.news-content pre {
  background: rgba(0, 0, 0, 0.25);
  border-radius: 8px;
  padding: 8px 10px;
  overflow-x: auto;
  margin: 6px 0;
}
.news-content pre code { background: none; padding: 0; }
.news-content a { color: var(--accent); text-decoration: underline; }

/* ---------- Claude Agent 方案卡片 ---------- */
.agent-card {
  align-self: flex-start;
  width: 96%;
  background: linear-gradient(180deg, rgba(91, 140, 255, 0.07), var(--panel-2));
  border: 1px solid rgba(91, 140, 255, 0.35);
  border-radius: 14px;
  padding: 12px 14px;
  animation: msg-in 0.18s ease;
}

.agent-head { font-size: 13px; font-weight: 600; color: var(--accent); margin-bottom: 8px; }

.agent-plan {
  font-family: ui-monospace, "Cascadia Code", "JetBrains Mono", Consolas, monospace;
  font-size: 12px;
  line-height: 1.6;
  color: var(--text);
  background: rgba(0, 0, 0, 0.25);
  border-radius: 10px;
  padding: 10px 12px;
  max-height: 260px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-word;
  margin-bottom: 8px;
}

.agent-status { font-size: 12px; color: var(--muted); margin-bottom: 8px; }
.agent-status.agent-done { color: var(--down); }
.agent-status.agent-failed { color: var(--up); }
.agent-status.agent-cancelled { color: var(--muted); text-decoration: line-through; }
/* 已超时取消但可按原方案继续: 同属"取消"但不是终点, 所以**不划删除线**(划掉会让
   旁边那颗「继续执行」按钮看起来自相矛盾), 用强调色把"还有一条路可走"说出来。 */
.agent-status.agent-revivable { color: var(--accent); }

.agent-actions { display: flex; gap: 10px; }

.btn-sm { padding: 7px 16px; font-size: 13px; }

/* ---------- Toast ---------- */
.toasts {
  position: fixed;
  bottom: 22px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 200;
}

.toast {
  background: var(--panel-2);
  border: 1px solid var(--border-strong);
  color: var(--text);
  border-radius: 12px;
  padding: 10px 18px;
  font-size: 13px;
  box-shadow: var(--shadow);
  animation: msg-in 0.2s ease;
}

.toast-error { border-color: rgba(255, 77, 94, 0.5); color: #ff8a95; }
.toast-ok { border-color: rgba(0, 196, 140, 0.5); }

/* ---------- 多用户: 账号信息与设置面板 ---------- */
.user-chip {
  font-size: 12px;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px 12px;
  white-space: nowrap;
}
.settings-btn {
  font-size: 12px;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 10px;
  min-height: 44px;
  padding: 0 12px;
  cursor: pointer;
  outline: 2px solid transparent;
  outline-offset: 2px;
}
@media (hover: hover) {
  .settings-btn:hover { color: var(--accent); border-color: var(--accent); }
}
.settings-btn:focus-visible { outline-color: var(--accent); }
.settings-btn:disabled { opacity: 0.5; cursor: default; }
.settings-btn:disabled:hover { color: var(--muted); border-color: var(--border); }
.settings-body { max-height: 62vh; overflow-y: auto; }
.settings-group { border-top: 1px solid var(--border); padding-top: 12px; }
.settings-group:first-child { border-top: none; }
.settings-title { font-size: 13px; font-weight: 600; color: var(--accent); margin-bottom: 4px; }

/* 飞书配置弹窗(2026-09-17 修正, BUGS #57): 弹窗自身限高 + 内容区自己滚 —— 与 #indicator-modal
   同款写法。修前统一用 .settings-body{max-height:62vh}, 私有配置那 5 个输入框 + 测试按钮 + 3 行
   说明就把首屏占满, 「生成绑定码」被挤到可视区之外、页面上又没有任何滚动提示, 用户以为根本没有
   这个入口(入口其实一直在, 只是要往下滚)。 */
#feishu-modal .modal {
  max-height: calc(100vh - 32px);
  max-height: calc(100dvh - 32px);
  display: flex;
  flex-direction: column;
}

#feishu-modal .modal-head, #feishu-modal .modal-foot { flex: none; }
#feishu-modal .settings-body {
  flex: 1 1 auto;
  min-height: 0;
  max-height: min(76vh, calc(100dvh - 160px));
}

/* 私有配置收成折叠项(2026-09-17): 原生 <details>, 不需要新 JS; 标题视觉沿用 .settings-title */
#feishu-modal summary.settings-title {
  cursor: pointer;
  list-style: none;      /* Firefox/标准写法隐藏原生三角 */
  user-select: none;
  margin-bottom: 0;
}

#feishu-modal summary.settings-title::-webkit-details-marker { display: none; }  /* WebKit 系 */
#feishu-modal summary.settings-title::before { content: "▸ "; color: var(--muted); }
#feishu-modal details[open] > summary.settings-title { margin-bottom: 4px; }
#feishu-modal details[open] > summary.settings-title::before { content: "▾ "; }

/* ---------- 工具类 ---------- */
.hidden { display: none !important; }

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: 4px; }
::-webkit-scrollbar-track { background: transparent; }

/* ---------- 工具栏 / 搜索 / 排序 ---------- */
.toolbar { display: flex; align-items: center; gap: 6px; margin-left: auto; flex-wrap: wrap; }
.stock-sort, .stock-search { background: var(--field-bg); border: 1px solid var(--border); color: var(--text); border-radius: 10px; padding: 0 10px; font-size: 12px; }
.stock-sort { min-height: 44px; }
.stock-sort:focus-visible, .stock-search:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.stock-search { flex: 1; min-width: 140px; }
.add-stock-bar { display: flex; gap: 8px; }
.add-stock-bar .stock-search { margin-left: auto; }

/* ---------- 行情明细行(今开/最高/最低/量) ---------- */
.card-oh-row { display: flex; gap: 12px; padding: 2px 14px 6px; font-size: 11px; color: var(--muted); }
.oh-item b { color: var(--text); font-weight: 500; margin-left: 3px; }

/* ---------- 卡片指标行(量比/换手/振幅/BIAS/RSI/MACD; 点击打开指标面板) ---------- */
.card-ind-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  padding: 2px 14px 6px;
  font-size: 11px;
  color: var(--muted);
  cursor: pointer;
}

.card-ind-row:hover { background: rgba(127, 127, 127, 0.06); }
.ind-item b {
  color: var(--text);
  font-weight: 500;
  margin-left: 3px;
  font-variant-numeric: tabular-nums;
}

/* ---------- 指标面板(📈 指标): 与日K弹窗(210)同级, 高于聊天放大弹窗(200) ---------- */
#indicator-modal { z-index: 215; }

/* 四段指标叠起来会比一屏高: 弹窗自身限高 + 内容区自己滚, 保证小屏也能看全(不裁切) */
#indicator-modal .modal {
  max-height: calc(100vh - 32px);
  max-height: calc(100dvh - 32px);
  display: flex;
  flex-direction: column;
}

#indicator-modal .modal-head { flex: none; }
#indicator-modal .modal-body { overflow-y: auto; min-height: 0; padding-bottom: 14px; }

/* 宽屏两列(四段并排, 长度约减半), 窄屏单列; 不做 auto-fit 是因为 980 宽下会排成三列,
   5 列宽表格会被挤到换行截断 */
.ind-grid { display: grid; grid-template-columns: 1fr; gap: 12px; align-items: start; }
@media (min-width: 860px) { .ind-grid { grid-template-columns: 1fr 1fr; } }

.ind-body { display: flex; flex-direction: column; gap: 12px; line-height: 1.6; }

.ind-loading, .ind-empty {
  font-size: 13px;
  color: var(--muted);
  padding: 18px 4px;
  text-align: center;
}

.ind-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
}

.ind-price {
  font-size: 22px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.ind-meta { font-size: 12px; color: var(--muted); }

.ind-sec {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 8px 12px 10px;
}

.ind-sec-title { font-size: 13px; color: var(--text); font-weight: 500; }
.ind-sec-hint { font-size: 11px; color: var(--muted); margin-top: 2px; }

.ind-table { margin-top: 6px; font-size: 12px; font-variant-numeric: tabular-nums; }

/* 等宽列: flex-basis 0 让每列严格等分, 各行内容长短不同也不会错列 */
.ind-row {
  display: flex;
  gap: 8px;
  align-items: baseline;
  padding: 3px 0;
  border-top: 1px solid rgba(127, 127, 127, 0.12);
}

.ind-row > * {
  flex: 1 1 0;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ind-row > .ind-k:first-child { flex: 1.15 1 0; }

.ind-row:first-child { border-top: none; }

.ind-head-row { color: var(--muted); font-size: 11px; }

.ind-k { color: var(--muted); }
.ind-v { color: var(--text); font-weight: 500; }
.ind-strong { color: var(--accent); }

.ind-note { font-size: 11px; color: var(--muted); line-height: 1.7; }

/* ---------- 空状态引导 ---------- */
.guide-title { font-size: 15px; color: var(--text); margin-bottom: 8px; }
.guide-step { font-size: 13px; color: var(--muted); line-height: 1.8; }

/* ---------- 帮助 / 触发集中视图 ---------- */
.help-content { line-height: 1.7; font-size: 13px; color: var(--text); }
.help-guide-link {
  display: inline-flex;
  align-items: center;
  min-height: 42px;
  padding: 9px 14px;
  border: 1px solid color-mix(in srgb, var(--accent) 40%, var(--border));
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
}
.help-guide-link:hover {
  border-color: var(--accent);
  filter: brightness(1.06);
}
.targets-table { display: flex; flex-direction: column; gap: 6px; }
.target-row { display: flex; justify-content: space-between; align-items: center; gap: 10px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; }
.target-row.done { opacity: 0.55; }
.target-info { font-size: 13px; }
.target-current { font-size: 12px; color: var(--muted); white-space: nowrap; }
/* 集中视图右侧「现价 + 操作区」: 操作区用 flex+wrap, 窄屏折行而非被裁掉(BUGS #70 教训) */
.target-right { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.target-actions { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
/* 操作区里的 .btn-mini 自带 margin-left:4px(为行内并排留距), flex+gap 下是重复间距 */
.target-actions .btn-mini { margin-left: 0; }

/* 「我的全部触发」弹窗(2026-10-03 需求 83): 与 #indicator-modal / #feishu-modal 同款的
   "弹窗自身限高 + 内容区自己滚"。基础 .modal 是 overflow:hidden 且**不限高**, 条目一多
   弹窗整体高过屏幕 ⇒ 超出的部分被 overflow:hidden 直接裁掉且滚不动(手机上底部的
   「编辑/删除」看得见摸不着)。这是 BUGS #44 同族的第二个现场 —— 修法照抄既有模式。
   双写 vh/dvh: 移动端地址栏收放时 vh 会跳, dvh 才精确(老浏览器不认识 dvh 则回退上一行)。 */
#targets-modal .modal {
  max-height: calc(100vh - 32px);
  max-height: calc(100dvh - 32px);
  display: flex;
  flex-direction: column;
}

#targets-modal .modal-head { flex: none; }
#targets-modal .modal-body { overflow-y: auto; min-height: 0; padding-bottom: 14px; }

/* 长备注不把左侧信息列撑破 94vw: .target-row 是 flex 行, 左列必须能收缩 */
#targets-modal .target-info { min-width: 0; }
/* 「我的触发」列表里点「编辑」要能盖在列表之上: #trigger-modal 在 index.html 中先于
   #targets-modal 出现, 二者同为 .modal-mask 的 z-index:100, 同层时后出现者在上 —— 不抬高
   这一条, 编辑弹窗会被列表盖住, 点下去像没反应(BUGS #57「入口存在 ≠ 看得见」同族)。
   取 218 高于 #indicator-modal(215) / #qr-modal(216) / #ai-task-output-modal(217)。 */
#trigger-modal { z-index: 218; }
.done-tag { color: #8a94a3; border: 1px solid var(--border); border-radius: 999px; padding: 0 8px; font-size: 11px; }
.pwd-reset-tag { color: #ffb86c; border: 1px solid rgba(255, 184, 108, 0.5); background: rgba(255, 184, 108, 0.08);
  border-radius: 999px; padding: 0 8px; font-size: 11px; margin-left: 4px; }
.muted { color: var(--muted); }
.small { font-size: 11px; }

/* ---------- 设置增强 ---------- */
.account-line { font-size: 13px; line-height: 1.9; color: var(--muted); }
.account-line b { color: var(--text); }
.field-help { display: inline-block; width: 14px; height: 14px; line-height: 14px; text-align: center;
  border-radius: 50%; border: 1px solid var(--border); color: var(--muted); font-size: 10px; margin-left: 4px; cursor: help; }
/* 点击「?」弹出的说明气泡(js showFieldHelpTip 生成) */
.field-help-tip {
  position: fixed;
  z-index: 500;
  max-width: 260px;
  padding: 8px 12px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  box-shadow: var(--shadow);
  pointer-events: none;
}
.settings-hint { font-size: 11px; color: var(--muted); margin-top: 8px; line-height: 1.6; }
.permissions-table-wrap {
  margin-top: 10px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: 10px;
}
.permissions-table {
  width: 100%;
  min-width: 820px;
  border-collapse: collapse;
  font-size: 12px;
}
.permissions-table th,
.permissions-table td {
  padding: 9px 10px;
  border-left: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  text-align: center;
  white-space: nowrap;
}
.permissions-table tr:last-child td { border-bottom: 0; }
.permissions-table th:first-child,
.permissions-table td:first-child {
  position: sticky;
  left: 0;
  z-index: 1;
  min-width: 116px;
  border-left: 0;
  background: var(--panel);
  color: var(--muted);
  text-align: left;
}
.permissions-table thead th {
  background: var(--panel-2);
  color: var(--text);
  font-weight: 600;
}
.permissions-table thead th:first-child { background: var(--panel-2); }
.permissions-table tbody td { color: var(--text); }
.perm-yes { color: var(--down); font-weight: 600; }
.perm-no { color: var(--muted); }
.permissions-notes {
  margin-top: 10px;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.7;
}
.permissions-notes div::before { content: "• "; }
/* 弹窗顶部的一条口径提醒(2026-09-25 需求 68 第 5 条: 「只能选择其中一种绑定机器人方式」)。
   与 .settings-hint 的区别是**语气**: hint 是可忽略的补充说明(灰色小字), warn 是必须知道的
   一条规则 —— 所以给琥珀色边框 + 浅底, 让它在弹窗顶部自成一格, 不会被当成又一段废话略过。
   配色沿用 .feishu-tag.warn(#ffb86c); 全站两处用到「提醒」这个语义: 弹窗顶部的二选一规则,
   与共享组标题下的「推荐用自己的私有机器人」(2026-09-25 第二轮从顶部挪过去的, 见 index.html)。 */
.settings-warn { font-size: 11.5px; line-height: 1.6; color: #ffb86c;
  margin: 4px 0 10px; padding: 6px 10px; border-radius: 6px;
  border: 1px solid rgba(255, 184, 108, 0.45); background: rgba(255, 184, 108, 0.08); }
/* 共享组标题下那条推荐: 它紧跟组标题, 上下留白比顶部的规则块更紧(默认的 4/10 会把标题与二维码
   之间撑出两段空档, 看起来像"标题配了两条互不相干的说明")。 */
#shared-reco { margin: 2px 0 8px; }
.settings-subtitle { font-size: 12px; font-weight: 600; color: var(--muted); margin-top: 14px; margin-bottom: 2px; }
.settings-subtitle:first-child { margin-top: 0; }
.admin-user-list { max-height: 52vh; overflow-y: auto; }
.users-admin-pager { display: flex; align-items: center; justify-content: center; gap: 6px;
  margin-top: 10px; flex-wrap: wrap; }
.users-admin-pager.hidden { display: none; }
.users-admin-pager .btn-mini { margin-left: 0; }
.users-admin-pager .btn-mini:disabled { opacity: 0.4; pointer-events: none; }
.users-admin-pager .btn-mini.active { color: var(--accent); border-color: var(--accent);
  background: rgba(80, 160, 255, 0.12); pointer-events: none; }
.users-admin-pager .pager-info { font-size: 11px; color: var(--muted); margin: 0 6px; white-space: nowrap; }
.admin-user-row { display: flex; justify-content: space-between; align-items: center; gap: 10px;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px; padding: 8px 12px; margin-bottom: 6px; }
.admin-user-row.disabled { opacity: 0.55; }
/* 2026-09-04 行动作收纳: 行内按钮删除后整行可点进详情(禁用用户行仍可点开以便重新启用) */
.admin-user-row.clickable { cursor: pointer; transition: border-color 0.15s, background 0.15s; }
.admin-user-row.clickable:hover { border-color: var(--accent); background: rgba(127, 127, 127, 0.06); }
.admin-user-info { font-size: 13px; min-width: 0; }
.admin-row-arrow { margin-left: auto; color: var(--muted); font-size: 14px; line-height: 1; flex: none; }
.admin-user-row:hover .admin-row-arrow { color: var(--accent); }
.btn-mini { font-size: 11px; padding: 3px 8px; margin-left: 4px; }
/* 用户配置列表排序工具栏(2026-09-04 三项改进): 排序下拉 + 升/降切换按钮 */
.users-admin-toolbar { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.users-admin-toolbar select { max-width: 200px; }
.users-admin-toolbar .btn-mini { margin-left: 0; }
/* 2026-09-04 用户详情页动作区(重置密码/禁用, 原行内按钮移入此处) */
.ud-actions { display: flex; align-items: center; gap: 8px; margin: 2px 0 8px; flex-wrap: wrap; }
.ud-actions .btn-mini { margin-left: 0; }
.ud-tog.ud-danger {
  color: #ff8a95;
  border: 1px solid rgba(255, 77, 94, 0.5);
  background: rgba(255, 77, 94, 0.12);
}
.ud-tog.ud-danger:hover { background: rgba(255, 77, 94, 0.22); color: #ff9aa6; }
.users-detail-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.users-detail-head b { font-size: 14px; }
/* 用户详情弹窗: 比默认弹窗略宽, 容纳统计卡片 */
#users-detail-modal .modal { width: min(520px, 94vw); }
.users-detail-grid { display: grid; grid-template-columns: 90px 1fr; gap: 3px 12px; font-size: 12px; line-height: 1.9; }
.users-detail-grid span { color: var(--muted); }
.users-detail-stats { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.users-detail-stats .stat { flex: 1 1 130px; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 10px; }
.users-detail-stats .stat span { display: block; font-size: 11px; color: var(--muted); margin-bottom: 2px; }
.users-detail-stats .stat b { font-size: 15px; }
.users-detail-stats .stat i { display: block; font-style: normal; font-size: 11px; color: var(--muted); margin-top: 2px; }
/* AI Router(2026-09 需求): 用户详情里的用量/虚拟 key/限额区块 */
.users-detail-router { margin-top: 12px; padding: 10px 12px; background: var(--field-bg);
  border: 1px solid var(--border); border-radius: 8px; }
.users-detail-router-head { font-size: 12px; font-weight: 600; color: var(--muted); margin-bottom: 8px; }
.router-key-row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; flex-wrap: wrap; }
.router-key-row code { background: var(--bg-soft); border: 1px solid var(--border); border-radius: 6px;
  padding: 3px 8px; font-size: 12px; word-break: break-all; }
.router-limit-edit { display: flex; align-items: center; gap: 6px; margin-top: 10px; flex-wrap: wrap; }
.limit-input { width: 90px; background: var(--bg-soft); border: 1px solid var(--border); color: var(--text);
  border-radius: 6px; padding: 4px 8px; font-size: 12px; }
.btn-danger { background: rgba(255, 77, 94, 0.12); border: 1px solid rgba(255, 77, 94, 0.5); color: #ff8a95;
  border-radius: 6px; padding: 7px 12px; font-size: 13px; cursor: pointer; }
.btn-danger:hover { background: rgba(255, 77, 94, 0.2); }

/* ---------- 用户类型(2026-09-04 分档)徽标与编辑器 ---------- */
.tier-tag { display: inline-block; padding: 0 6px; margin-left: 5px; border-radius: 4px;
  font-size: 11px; line-height: 18px; vertical-align: 1px; color: #fff; font-weight: 600; }
.tier-normal { background: #8a94a6; }
.tier-vip { background: #c9a227; }
.tier-svip { background: #9a4df0; }
.tier-admin { background: #d04949; }

/* ---------- 飞书机器人绑定状态徽标(2026-09-15: 管理员用户列表一眼看出谁绑了谁没绑) ---------- */
.feishu-tag { display: inline-block; padding: 0 8px; border-radius: 999px; font-size: 11px;
  line-height: 18px; vertical-align: 1px; }
.feishu-tag.ok { color: #3ecf8e; border: 1px solid rgba(62, 207, 142, 0.5); background: rgba(62, 207, 142, 0.08); }
.feishu-tag.warn { color: #ffb86c; border: 1px solid rgba(255, 184, 108, 0.5); background: rgba(255, 184, 108, 0.08); }
.feishu-tag.off { color: #8a94a3; border: 1px solid var(--border); }
.ud-tier-row { display: flex; align-items: center; gap: 10px; margin: 8px 0 4px; flex-wrap: wrap; }
.ud-tier-row select { max-width: 220px; }
#ud-peruser-group { margin-top: 4px; }
#users-detail-error, #admin-config-error { margin-top: 10px; }
.settings-body .users-detail-router { margin-top: 4px; }

/* ---------- 移动端适配 ---------- */
@media (max-width: 900px) {
  /* 移动端: AI 页聊天面板铺满可视区(顶栏+底部导航之间) */
  .tabpage#tab-ai { display: none; }
  .tabpage#tab-ai.active { display: block; }
  /* 2026-10-03 需求 78: 面板**正好占满**顶栏与底部导航之间。原 `-132px` 是按"上下各留 14px 空"配的
     (顶栏 ≈46px + .layout 上内边距 14px 之下的 14px 空 → 面板 100vh-132 → 下沿离导航还差 14px),
     手机上一眼看就是"上下各空一截"。新口径 = 顶栏 ≈46px + 底部导航 58px = 104px, 再用负外边距
     抵掉 .layout 的上下内边距(上 14px 全额抵掉; 下 76px 只抵掉比导航高的那 18px, 留 58px 给固定
     导航让位) ⇒ 「面板 + 顶栏 + 导航 + 内边距」正好 = 100vh: 既无留白, 也不出现外滚动条。 */
  .tabpage#tab-ai .chat-panel { height: calc(100vh - 104px); min-height: 0; border-radius: 14px;
                                margin: -14px 0 -18px; }
  .add-stock-bar { flex-wrap: wrap; }
  .stock-search { min-width: 100%; }
  .user-chip { display: none; }
  .card-chart { height: 140px; }
  /* 顶栏收纳: 设置/退出等已并入「我的」页; 使用说明与新闻胶囊同栏保留 */
  .updated, #users-admin-btn, #settings-btn, #logout-btn { display: none; }
  /* 移动端：允许顶栏与监控工具栏换行，所有触控目标保持 44px。 */
  #status-badge { display: none; }
  .topbar { padding: 10px 12px; flex-wrap: wrap; row-gap: 8px; white-space: normal; }
  .brand { flex: 1 1 180px; min-width: 0; }
  #tab-title { font-size: 16px; white-space: nowrap; }
  .topbar-right { flex: 1 1 300px; min-width: 0; justify-content: flex-end; overflow: visible; flex-wrap: wrap; gap: 8px; }
  .news-pill { font-size: 12px; padding: 0 12px; white-space: nowrap; }
  .section-head { flex-wrap: wrap; overflow: visible; }
  .section-head h2 { font-size: 14px; white-space: nowrap; }
  .count-pill { font-size: 12px; white-space: nowrap; }
  .toolbar { flex: 1 1 auto; min-width: 0; flex-wrap: wrap; overflow: visible; gap: 6px; justify-content: flex-start; margin-left: 0; }
  .toolbar .settings-btn, .toolbar .stock-sort { font-size: 12px; padding: 0 10px; white-space: nowrap; }
  .activation-steps { grid-template-columns: 1fr; }
  .activation-step { min-height: 64px; }

  /* 2026-10-03 需求 79: 窄屏点底部「AI 助手」默认全屏, 而全屏遮罩(z-index:200)原本必然盖住
     底部导航(z-index:30) ⇒ 那四个按钮就点不到了(= 把用户关在 AI 页里)。
     做法是**把遮罩底边上收一个导航的高度**(58px + 安全区), 导航条根本不在遮罩范围内。
     **为什么不去抬 nav 的 z-index**: 那会让底部导航浮在其它弹窗(用户列表/系统配置/二维码…)之上;
     收遮罩只影响"全屏对话"这一种状态, 与其它弹窗零交互。
     `.chat-modal{width/height:100%}` 相对遮罩的 padding box 解析, 于是自动变成"整屏减去导航高度"。 */
  body.chat-fullscreen .chat-modal-mask {
    inset: 0 0 calc(58px + env(safe-area-inset-bottom, 0px)) 0;
  }
  /* 已经在全屏, 头部这个「⛶ 全屏」入口(随 .chat-tools 一起搬进弹窗头)就无意义了; 只留 🗑 */
  body.chat-fullscreen #chat-max { display: none; }
}

/* ---------- 手机窄屏适配(≤560px) ---------- */
/* 为什么单列一档而不是并进 900px 那档: 下面这些都是"折行"规则, 在平板上会把本来一行放得下的
   工具栏拆成两行(布局退化); 手机上才是必需的。
   **顶栏在 2026-10-03(需求 78)被显式回退**: 2026-09-30 BUGS #70 为躲"横向溢出"把
   `.topbar-right` 折到了第二行, 但那多占一行、`justify-content:flex-end` 与标题又分列两端,
   用户要的是「主标题与三个胶囊(今日财经/收盘快照/使用说明)**同一行**、整体更紧凑」
   (与 static/ui_preview_v3.html 那版既定口径一致)。
   **为什么不能"把 flex-end + overflow-x 搬回来"就完事**: `flex-end` 是**不安全对齐** ——
   内容比容器宽时溢出发生在**行首(左侧)**, 而 `overflow-x:auto` 的滚动起点固定在左端、左侧
   滚不回来, 被推出屏幕的恰恰是排在最前面的那个入口(正是 #70 的现场)。
   所以这一档**靠收小尺寸来避免溢出**(字号/内边距/间距一起收, 让三胶囊在 360px 下也放得下),
   并**保留 `justify-content: flex-start`**; 只有极窄(≤320px)才退化为可横向滚动兜底。
   注意**不隐藏任何入口**(BUGS #57: 藏掉的按钮 = 用户眼里没这功能)。
   `.toolbar` / `.section-head` 的折行**不在本次回退范围** —— 它们与顶栏是两件事, 仍按 #70 口径。 */
@media (max-width: 560px) {
  /* 顶栏改为两行：标题一行，新闻/帮助按钮独立换行，避免 11px 小字与横向滚动。 */
  .topbar { padding: 10px 12px; flex-wrap: wrap; }
  .brand { min-width: 0; }                 /* 不加则 #tab-title 的省略号不生效 */
  .brand h1 { font-size: 14px; }
  #tab-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .topbar-right { flex: 1 0 100%; flex-wrap: wrap; justify-content: flex-start;
                  overflow: visible; margin-top: 0; gap: 8px; min-width: 0; }
  .news-pill { font-size: 12px; padding: 0 12px; }
  /* 监控清单标题行: 数量胶囊与工具栏(⏰ 定时AI / 🎯 我的触发 / 排序 / ⤢ 折叠)同处一行。
     2026-10-03 需求 81 起不再折行 —— 与顶栏(需求 78)同一口径: **靠收小尺寸买"同一行"**,
     而不是把"右对齐 + 横向滚动"那套搬回来(#70 的现场: 右对齐是不安全对齐, 溢出落在**行首**,
     而滚动起点固定在左端, 被推出屏幕的恰是排最前的「⏰ 定时AI」)。
     本档**不隐藏任何入口**(BUGS #57), 并显式 `overflow: visible` 覆盖 ≤900px 那档的 `hidden`,
     否则溢出部分直接被裁掉(不是藏, 是根本画不出来)。 */
  .section-head { flex-wrap: wrap; overflow: visible; row-gap: 8px; gap: 8px; }
  .toolbar { flex: 1 0 100%; flex-wrap: wrap; justify-content: flex-start;
             overflow: visible; margin-left: 0; gap: 6px; }
  .count-pill { font-size: 11px; padding: 2px 7px; }
  .toolbar .settings-btn, .toolbar .stock-sort { font-size: 12px; padding: 0 10px; }
  .toolbar .stock-sort { flex: 0 1 auto; min-width: 0; }
  .activation-card { padding: 12px; }
  .activation-head h2 { font-size: 14px; }
}

/* 极窄屏：继续换行，不产生页面级横向滚动。 */
@media (max-width: 320px) {
  .topbar-right, .toolbar { overflow: visible; }
  .activation-collapse { min-width: 44px; padding: 0 8px; }
}

/* 聊天折叠: 收起后只留标题栏(可点展开), 避免遮挡内容。
   2026-10-03 需求 84: 消息区外面包了一层 .chat-messages-wrap, 收起时要**连外壳一起**隐藏,
   否则外壳还在占位(内层 display:none 不影响外壳的 flex:1)。 */
.chat-panel.collapsed .chat-messages-wrap,
.chat-panel.collapsed .chat-examples,
.chat-panel.collapsed .chat-input-row { display: none; }
.chat-panel.collapsed .chat-collapse-btn { transform: rotate(180deg); }

/* ---------- 共享机器人二维码(2026-09-25 需求 68 追加) ---------- */
/* 共享机器人是**管理员建的应用**, 用户得先把它加进自己的飞书, 才能给它发绑定码 ——
   static/robot.png 就是这个"添加"入口, 此前只能靠管理员线下发截图。
   缩略图特意铺**白底**: 二维码必须白底黑字, 暗色主题下透明底会扫不出来。
   缩略图只占一行(200px), 大图交给 #qr-modal: 手机扫屏幕上的缩略图基本扫不动。 */
.qr-wrap { margin-top: 6px; }
.qr-thumb {
  display: block;
  width: 200px;
  height: auto;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #fff;
  cursor: zoom-in;
}
.qr-thumb:hover { border-color: var(--accent); }

/* 大图弹窗宽一点(默认 .modal 只有 420px, 二维码会被压得比实体还小), 且 z-index 必须压在
   #feishu-modal 之上 —— 它是从飞书弹窗里点开的, 藏在下层就等于点了没反应。 */
#qr-modal { z-index: 216; }
.qr-modal { width: min(760px, 94vw); }
.qr-full { display: block; width: 100%; height: auto; border-radius: 10px; background: #fff; }

/* ---------- 定时 AI 任务列表(2026-09-30 需求 74) ---------- */
.ai-task-list { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.ai-task-row { border: 1px solid var(--border); border-radius: 10px; padding: 8px 10px; }
/* 已暂停的任务整行压暗: 一眼看出"它现在不会跑"(只压暗不给 hidden —— 藏起来用户就找不到它了) */
.ai-task-row.off { opacity: 0.62; }
.ai-task-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* 时间用等宽数字: 多条任务纵向排列时 08:30 与 15:10 的冒号要对齐, 否则列表看着是歪的 */
.ai-task-time { font-weight: 600; font-variant-numeric: tabular-nums; }
.ai-task-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ai-task-tag { flex: none; font-size: 11px; padding: 1px 7px; border-radius: 9px;
  border: 1px solid var(--border); color: var(--muted); }
/* 「内容不适」(被金融限定闸门自动停用)的标签必须与中性灰**肉眼可分** —— 否则它和自己的
   「已暂停」长得一样, 用户看不出是哪条被系统停了(BUGS #57: 置灰/换色不做就前后一个样)。
   用红系而非琥珀: 徽标(.me-badge)本来就是琥珀色, 同色系会把"要紧"和"常规计数"混在一起。 */
.ai-task-tag.warn { border-color: rgba(255, 77, 94, 0.55); color: #ff8a95;
  background: rgba(255, 77, 94, 0.12); }
/* 行级"轻标识": 只染边框、且把压暗从 0.62 抬到 0.78 —— 0.62 会把上面那枚红标签一起洗淡,
   而这枚标签正是这一行唯一的"为什么被停"线索。 */
.ai-task-row.off-topic { border-color: rgba(255, 77, 94, 0.45); opacity: 0.78; }
/* 「我的」页入口徽标: 有内容不适的任务时也换成红系(不打开弹窗也要能看出"有东西要处理") */
.me-badge.warn { color: #ff8a95; background: rgba(255, 77, 94, 0.14);
  border-color: rgba(255, 77, 94, 0.45); }
.ai-task-prompt { font-size: 12px; color: var(--muted); margin-top: 4px; line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ai-task-meta { font-size: 11px; color: var(--muted); margin-top: 4px; }
.ai-task-acts { display: flex; gap: 6px; margin-top: 6px; }
/* .btn-mini 自带 margin-left:4px(为行内并排的按钮留距), 在 flex+gap 的按钮组里是重复间距 */
.ai-task-acts .btn-mini { margin-left: 0; }
#ai-task-form-hint { color: #ffc46b; }
/* 点「✎ 编辑」后表单组顶端要对齐滚动区上沿(2026-10-05 需求 74.7): .modal-body 的 padding-top
   只有 4px, 不给 scroll-margin 会让表单标题贴在最上沿、视觉上像被裁掉一截。
   **必须限定 #ai-task-modal 作用域**: .settings-group 是飞书配置/管理配置弹窗**共用**的类,
   裸写会波及它们。.settings-body{max-height:62vh} 一个字都不动(改高度会牵动 BUGS #70/#78 的窄屏版面)。 */
#ai-task-modal .settings-group { scroll-margin-top: 8px; }

/* ---------- 定时 AI 任务「最近一次输出」阅读层(2026-10-02 需求 74.5) ---------- */
/* z-index 必须压在宿主弹窗之上: 它是从 #ai-task-modal 里点开的, 同层的话后开的反而在下
   (同 #qr-modal 的注释 —— 光是"功能都在"不够, 用户得真看得见)。 */
#ai-task-output-modal { z-index: 217; }
/* 需求 88: 正文改由 marked 渲染成 HTML, 排版口径交给同源的 .msg-md(见上, 与 AI 聊天气泡一致),
   这里只管容器 —— 白空格模式、字号字色与可滚动的阅读区。
   **不要在这里再写 white-space: pre-wrap**: 它会把渲染出的 <p>/<li> 之间再叠一层换行, 行距异常;
   而且本条规则在表里排在 .msg-md 之后, 会盖掉后者为渲染结果设的 normal。 */
.ai-task-output-body {
  word-break: break-word; overflow-wrap: anywhere;
  font-size: 13px; line-height: 1.7; color: var(--text);
  background: rgba(255, 255, 255, 0.03); border: 1px solid var(--border);
  border-radius: 10px; padding: 10px 12px; margin: 8px 0 0;
  max-height: 52vh; overflow-y: auto;   /* 「滑动看全文」的载体: 正文区自身滚动 */
}

/* ---------- 网站备案号页脚(工信部要求: 首页底部居中, 链接至 beian.miit.gov.cn) ---------- */
/* 2026-10-25(需求 97 / BUGS #90): 用户最终口径 = 备案号放在**网页最下方**, 只有滚到
   最底部才看到 —— 不再钉在视口底部(那样会一直压住最后一屏内容, 手机上尤其碍事)。
   实现回到**普通文档流**: 页脚是 <main> 之后的最后一个块, 跟内容一起滚。移动端底部
   Tab 导航是 fixed 的 58px(含安全区), 用页脚自身的下内边距把备案号顶到导航上方 ——
   滚到底时依次是「页脚文字 → 58px 空白 → 导航栏」, 谁也不压谁。
   注意: 这里**不要**再加 position: fixed / transform, 那会退回 #88/#89 的老问题。 */
.beian-footer {
  text-align: center;
  padding: 10px 16px 70px;                                          /* 58 + 12, 旧内核兜底 */
  padding-bottom: calc(70px + env(safe-area-inset-bottom, 0px));
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
  border-top: 1px solid var(--border);
  background: transparent;
}
.beian-footer a { color: var(--muted); text-decoration: none; }
.beian-footer a:hover { color: var(--accent); text-decoration: underline; }

/* 桌面端没有底部 Tab 导航, 页脚就是正文最后一行 */
@media (min-width: 900px) {
  .beian-footer { padding: 16px; }
}
