/* 自选跟踪 / 我的持仓 两页共用的样式（同一份，避免改一处漏一处）
 * 源自 index.html 的内联 <style>，逐字搬出；改样式只改这里，两页同时生效。 */
    :root {
      --bg: #f4f6f9;
      --card: #ffffff;
      --ink: #1c2333;
      --muted: #8a94a6;
      --line: #eceff4;
      --up: #d64545;
      --down: #1a9c6b;
      --flat: #8a94a6;
      --brand: #10284b;
      --accent: #2b6cb0;
      /* 宽屏（平板/桌面）内容列的宽度上限。手机视口 ≤ 430，永远不生效；改列宽只改这一个值。 */
      --shell-w: 480px;
      /* 安全区（状态栏/刘海/手势条）。**必须同时读 env() 和 --safe-area-inset-***，取较大者：
         Android 上 Capacitor 的 SystemBars 插件（capacitor.config.json 里 insetsHandling:"css"）
         会把真实状态栏高度写进 documentElement 的 --safe-area-inset-top；而 WebView < 140 时
         env(safe-area-inset-*) 取不到值（Chromium 已知 bug），那种情况下插件改用「给 WebView 加
         原生 padding」来让开，注入的变量是 0。两边取 max 在三种分支下都对：
           · WebView ≥140（插件让 WebView 通到屏幕边缘）→ env 和 var 都是真值 → 取真值（顶栏避开状态栏）
           · WebView <140（插件用原生 padding 让开）   → 两者都是 0  → 不加多余留白（不会双倍留白）
           · 普通浏览器（没有插件）                    → var 是 0，用 env 给的值
         ⚠️ 只写 env() 会让新安卓机（WebView≥140）顶栏被状态栏盖住；只写 var() 则网页端失效。
         这正是「有的安卓机正常、有的重叠」的原因 —— 取决于该机 WebView 走哪条分支。 */
      --sat: max(env(safe-area-inset-top, 0px), var(--safe-area-inset-top, 0px));
      --sab: max(env(safe-area-inset-bottom, 0px), var(--safe-area-inset-bottom, 0px));
    }
    * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
    /* 全站字号按屏宽自适应：430px = iPhone Pro Max 的 CSS 宽（设计基准），430 及以上取到上限、
       与原字号逐值相同；窄屏按比例缩 —— 同一段文字在 360 宽的安卓上占屏比例才跟苹果一致，
       否则小屏上字相对更大、卡片折行（实测「支撑」行内容 297px，360 屏只有 285px 可用）。
       各字号的 vw 系数 = 字号 ÷ 430 × 100，向上取整到 4 位小数（保证 430 宽上能吃满上限）。
       根字号也必须缩放：没写 font-size、靠继承的元素（如 .hs-empty）否则固定 16px。 */
    html, body { margin: 0; padding: 0; background: var(--bg); color: var(--ink); font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", sans-serif; font-size: clamp(12.8px, 3.721vw, 16px); }
    /* 底部 .add-bar 是 fixed 的，必须按它的真实高度预留，否则最后一段内容（持仓的「历史成交」）
       会被永久遮住、怎么划都划不上来。高度不是常量：两行 vs 一行、iPhone 安全区（本来就写在
       .add-bar 的 padding 里）、系统字体缩放都会改它，所以由 shell.js 量出来写进 --bar-h，
       这里只管加余量。旧写法是硬编码 90px，比 iPhone 上的实际高度（89 + 安全区）小，故被遮。 */
    body { padding-bottom: calc(var(--bar-h, 104px) + 14px); }

    /* ===== 宽屏（平板 / 桌面浏览器）居中列 =====
       字号在 430px 视口宽就撞上 clamp 上限、不再变大，但布局是 width:100% / flex:1 + space-between，
       会继续拉伸：实测 1649px 窗口下一张卡片内部「同行最大空白」有 888px、档位按钮从 71px 拉成 384px
       （字还是 10px），看着全是空洞。这里把内容收进一个居中列，两侧留出页面底色。
       ⚠️ 只处理「页面本体」（header / main / 底部栏 / 返回顶部）；K线弹窗、买卖·资金·备份面板
       是独立的全屏浮层（position:fixed 且各自 width:100%），不受这里影响，要收窄需单独改。 */
    main { max-width: var(--shell-w); margin-left: auto; margin-right: auto; }

    header {
      position: sticky; top: 0; z-index: 10;
      background: var(--brand); color: #fff;
      padding: 16px 16px calc(10px + var(--sat));
      padding-top: calc(16px + var(--sat));
      /* 宽屏：深色条保持通宽（顶栏该有的样子），只把里面的内容推去和下面的列对齐。
         手机端 max() 取到 16px，与原来逐像素相同。 */
      padding-left: max(16px, calc((100% - var(--shell-w)) / 2 + 16px));
      padding-right: max(16px, calc((100% - var(--shell-w)) / 2 + 16px));
      display: flex; align-items: center; justify-content: space-between;
      box-shadow: 0 2px 10px rgba(16,40,75,.15);
    }
    header h1 { font-size: clamp(15.2px, 4.4187vw, 19px); margin: 0; font-weight: 700; letter-spacing: .5px; }
    header .sub { font-size: clamp(9.6px, 2.7907vw, 12px); opacity: .75; margin-top: 2px; }
    .header-actions { display: flex; gap: 8px; }
    .header-actions button {
      background: rgba(255,255,255,.14); color: #fff; border: none;
      border-radius: 20px; padding: 7px 13px; font-size: clamp(10.4px, 3.0233vw, 13px); cursor: pointer;
    }
    .header-actions button:active { background: rgba(255,255,255,.28); }

    /* 统计条 */
    /* 四格金额在 375px 下放不下：原来 .num 是固定 22px、格子是 flex:1（=1 1 auto，缩不到内容
       宽度以下），持仓那四格内容共 366px + 间距，把整行撑到 422px（横向溢出 47px）且第 4 格
       的「+¥16,734」换行成两行。改成等宽可收缩 + 字号随视口缩放，保证单行不换行。 */
    .stats {
      display: flex; gap: 8px; padding: 12px 8px;
      background: var(--card); margin: 12px 10px 0; border-radius: 14px;
      box-shadow: 0 1px 4px rgba(16,40,75,.05);
    }
    .stat-box { flex: 1 1 0; min-width: 0; text-align: center; }
    .stat-box .num { font-size: clamp(13px, 3.9vw, 20px); font-weight: 700; white-space: nowrap; }
    .stat-box .lbl { font-size: clamp(10px, 3vw, 12px); color: var(--muted); margin-top: 2px; white-space: nowrap; }
    /* 现金为负（漏记入金）的提示色，与 .panel-echo.warn 同一套 */
    .stat-box .num.warn { color: #c0700c; }
    .stat-box .lbl.warn { color: #c0700c; font-weight: 600; }

    .section-title {
      display: flex; align-items: center; gap: 8px;
      padding: 18px 16px 10px; font-size: clamp(11.2px, 3.2559vw, 14px); font-weight: 600; color: var(--muted);
    }
    .section-title .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex: 0 0 auto; }

    /* 自选列表 */
    .list { padding: 0 12px; }
    .card {
      background: var(--card); border-radius: 14px; padding: 13px 14px;
      margin-bottom: 10px; box-shadow: 0 1px 4px rgba(16,40,75,.05);
    }
    .card-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
    /* 左侧要挤下 名称 + 代码 + 「持N股」 + 删除「×」四样；name 可以压缩，现价不能（别被顶掉） */
    .card-name { display: flex; align-items: center; gap: 8px; min-width: 0; }
    .card-head .price { flex: 0 0 auto; }
    .card-name .name { font-size: clamp(13.6px, 3.9535vw, 17px); font-weight: 700; }
    .card-name .code { font-size: clamp(9.6px, 2.7907vw, 12px); color: var(--muted); }
    .card-head .price { font-size: clamp(16px, 4.6512vw, 20px); font-weight: 700; font-variant-numeric: tabular-nums; }
    .card-bar { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
    .chg-pill { font-size: clamp(11.2px, 3.2559vw, 14px); font-weight: 600; min-width: 76px; text-align: center; padding: 5px 0; border-radius: 8px; color: #fff; }
    .chg-detail { flex: 1; font-size: clamp(9.6px, 2.7907vw, 12px); color: var(--muted); line-height: 1.65; }
    .chg-detail .add { display: block; }
    .chg-detail .today { display: block; }
    /* 加入信息高亮行 */
    .join-line {
      display: inline-flex; align-items: center; gap: 5px;
      background: #eef4fb; color: var(--accent); font-size: clamp(9.6px, 2.7907vw, 12px); font-weight: 600;
      padding: 5px 10px; border-radius: 8px; margin-bottom: 8px;
    }
    .join-line .jlabel { color: var(--muted); font-weight: 500; }
    .join-line .jprice { color: var(--ink); font-weight: 700; font-variant-numeric: tabular-nums; }
    .join-line .jtime { font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink); }
    .join-line .jsession { color: #fff; font-weight: 700; font-size: clamp(8.8px, 2.5582vw, 11px); padding: 1px 6px; border-radius: 6px; background: var(--accent); }
    .join-line .jsession.pm { background: #e08214; }

    /* ATR 动态止盈/止损建议行 */
    .atr-line {
      display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 10px;
      font-size: clamp(9.6px, 2.7907vw, 12px); line-height: 1.5; padding: 8px 10px; margin-bottom: 4px;
      border-radius: 8px; background: #f7f9fc;
      border-left: 3px solid var(--muted); color: var(--muted);
      font-variant-numeric: tabular-nums;
    }
    .atr-line .atr-state { font-weight: 700; }
    .atr-line .atr-txt { }
    .atr-line .atr-txt b { color: var(--ink); font-weight: 700; }
    .atr-line .atr-txt i { font-style: normal; font-weight: 600; }
    .atr-line .atr-hint { margin-left: auto; color: #b6bdca; font-size: clamp(8.8px, 2.5582vw, 11px); }
    .atr-line.hold { border-left-color: var(--muted); }
    .atr-line.hold .atr-state { color: var(--muted); }
    .atr-line.near { border-left-color: var(--accent); background: #f0f6fc; }
    .atr-line.near .atr-state { color: var(--accent); }
    .atr-line.take { border-left-color: var(--up); background: #f9d7d7; }
    .atr-line.take .atr-state { color: var(--up); font-weight: 700; }
    .atr-line.stop { border-left-color: var(--down); background: #d3efdd; }
    .atr-line.stop .atr-state { color: var(--down); font-weight: 700; }
    /* 止损线已抬到成本之上 = 实际锁盈（显示为「移动止盈」）：橙色，避免被读成亏损防线。需在 .stop 之后声明以覆盖其绿色 */
    .atr-line.locked { border-left-color: #e08214; background: #fdf3e5; }
    .atr-line.locked .atr-state { color: #c0700c; font-weight: 700; }
    .atr-line .atr-lock { font-style: normal; font-weight: 700; font-size: clamp(8.8px, 2.5582vw, 11px); color: #c0700c; background: #fbe6c8; padding: 1px 5px; border-radius: 6px; }

    /* 支撑/压力带行（自选视图用，持仓视图仍用上面的 .atr-line）——版式与 .atr-line 一致，只换语义配色。
       A股惯例色：支撑用绿(--down)、压力用红(--up)，与K线弹窗里的参考线同色。 */
    .zone-line {
      display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 10px;
      font-size: clamp(9.6px, 2.7907vw, 12px); line-height: 1.5; padding: 8px 10px; margin-bottom: 4px;
      border-radius: 8px; background: #f7f9fc;
      border-left: 3px solid var(--muted); color: var(--muted);
      font-variant-numeric: tabular-nums;
    }
    .zone-line .zone-txt { display: inline-flex; align-items: baseline; flex-wrap: wrap; gap: 5px; }
    .zone-line .zk { font-weight: 700; }
    .zone-line .zone-txt b { color: var(--ink); font-weight: 700; }
    .zone-line .zone-txt i { font-style: normal; font-weight: 600; }
    .zone-line .zone-txt.sup .zk { color: var(--down); }
    .zone-line .zone-txt.res .zk { color: var(--up); }
    .zone-line .ztouch { color: #8a94a6; font-size: clamp(8.8px, 2.5582vw, 11px); }
    .zone-line .zdist { color: var(--accent); }
    /* 跌破/突破：转橙，与持仓页「止损抬过成本改叫移动止盈」用同一个提示色 */
    .zone-line .zone-txt.broke .zk, .zone-line .zone-txt.broke b { color: #c0700c; }
    .zone-line .zstate { color: #c0700c; font-weight: 700; }
    .zone-line .zone-txt.none, .zone-line .zone-txt.none .zk { color: #b6bdca; font-weight: 600; }
    /* 「无带」时补的近端参考位（近期高低点）：比上面那句灰一点、小一号 —— 它是未经验证的单点极值 */
    .zone-line .znear { color: #9aa4b2; font-size: clamp(8.8px, 2.5582vw, 11px); }
    /* 角色互转说明（由压力转来／由支撑转来）：是**解释出处**，不是警告，所以用灰的辅助色，
       别用 .zstate 那个橙色 —— 橙色在这条线上专指「跌破/突破」。 */
    .zone-line .zflip { color: #8a94a6; font-size: clamp(8.8px, 2.5582vw, 11px); }
    .zone-line .zone-hint { margin-left: auto; color: #b6bdca; font-size: clamp(8.8px, 2.5582vw, 11px); }
    /* 止盈止损档位总开关（全局一处，宽松→极保守） */
    .atr-control { display: flex; align-items: center; gap: 10px; margin: 12px 12px 0; }
    .atr-control .ac-lbl { flex: none; font-size: clamp(9.6px, 2.7907vw, 12px); color: #8a94a6; white-space: nowrap; }
    .atr-control .atr-preset { flex: 1; margin: 0; }
    .atr-preset { display: flex; gap: 6px; flex-wrap: wrap; }
    .atr-preset button {
      flex: 1; min-width: 0; padding: 4px 2px; font-size: clamp(8px, 2.3256vw, 10px); line-height: 1.2;
      color: #8a94a6; background: #f2f5fa; border: 1px solid #e2e8f0;
      border-radius: 10px; cursor: pointer; white-space: nowrap; font-variant-numeric: tabular-nums;
    }
    .atr-preset button.on { background: #2b6cb0; border-color: #2b6cb0; color: #fff; font-weight: 700; }
    .card-bar .chg-pill { white-space: nowrap; }

    .del-btn {
      background: none; border: none; color: #c4cad4; font-size: clamp(16px, 4.6512vw, 20px); line-height: 1;
      cursor: pointer; padding: 6px 4px;
    }
    /* 已删除自选（历史折叠区，弱化样式；点开详情不受影响） */
    .history-section { margin: 14px 12px 8px; }
    .hs-head {
      display: flex; align-items: center; gap: 8px; padding: 8px 10px;
      background: #f4f6fa; border: 1px solid #e6ebf1; border-radius: 8px; cursor: pointer;
      color: #6a7486; font-size: clamp(10.4px, 3.0233vw, 13px); font-weight: 600;
    }
    .hs-lbl { flex: none; }
    .hs-count { background: #e2e7ee; color: #8a94a6; border-radius: 9px; padding: 1px 7px; font-size: clamp(8.8px, 2.5582vw, 11px); }
    .hs-arrow { margin-left: auto; color: #a6afbc; font-size: clamp(9.6px, 2.7907vw, 12px); transition: transform .2s; }
    .history-section.open .hs-arrow { transform: rotate(180deg); }
    .hs-body { display: none; margin-top: 6px; }
    .history-section.open .hs-body { display: block; }
    .hcard .hs-empty { color: #b6bdca; font-size: clamp(9.6px, 2.7907vw, 12px); text-align: center; padding: 16px 0; }
    .hcard {
      background: #fbfcfe; border: 1px solid #edf1f6; border-radius: 10px;
      padding: 10px 12px; margin-bottom: 8px; cursor: pointer;
    }
    .hcard-head { display: flex; align-items: baseline; gap: 6px; }
    .hcard-head .name { font-weight: 600; color: #4a5568; font-size: clamp(11.2px, 3.2559vw, 14px); }
    .hcard-head .code { color: #a6afbc; font-size: clamp(9.6px, 2.7907vw, 12px); }
    .hcard .hjoin { color: #a6afbc; font-size: clamp(8.8px, 2.5582vw, 11px); margin-top: 3px; }
    .hcard .hbar {
      display: flex; flex-wrap: wrap; gap: 8px 14px; margin-top: 6px;
      font-size: clamp(9.6px, 2.7907vw, 12px); color: #4a5568; font-variant-numeric: tabular-nums;
    }
    .hcard .hbar b { font-weight: 600; }
    .hcard .hchg.up { color: var(--up); }
    .hcard .hchg.down { color: var(--down); }
    .del-btn:active { color: var(--up); }
    .up { color: var(--up); } .down { color: var(--down); } .flat { color: var(--flat); }

    .empty {
      text-align: center; color: var(--muted); padding: 50px 20px; line-height: 1.8; font-size: clamp(11.2px, 3.2559vw, 14px);
    }
    .empty .big { font-size: clamp(33.6px, 9.7675vw, 42px); display: block; margin-bottom: 12px; opacity: .5; }

    /* 底部添加栏 */
    .add-bar {
      position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
      /* 宽屏：同为 fixed，用 max-width + margin:auto 收进上面那条居中列（手机上不生效） */
      max-width: var(--shell-w); margin-left: auto; margin-right: auto;
      background: var(--card); border-top: 1px solid var(--line);
      padding: 10px 12px calc(10px + var(--sab));
      display: flex; gap: 8px; box-shadow: 0 -2px 10px rgba(16,40,75,.06);
    }
    .add-bar input {
      flex: 1; min-width: 0; border: 1px solid var(--line); border-radius: 10px;
      padding: 12px 14px; font-size: clamp(12.8px, 3.721vw, 16px); outline: none; background: #f8fafc;
    }
    .add-bar input:focus { border-color: var(--accent); }
    .add-bar .go {
      background: var(--accent); color: #fff; border: none; border-radius: 10px;
      padding: 0 16px; font-size: clamp(12px, 3.4884vw, 15px); font-weight: 600; cursor: pointer; white-space: nowrap;
    }
    .add-bar .go:active { opacity: .85; }

    /* 返回顶部 */
    .totop {
      /* 宽屏：贴到居中列的右沿（fixed 的百分比按视口算），而不是窗口最右边 */
      position: fixed; right: max(12px, calc((100% - var(--shell-w)) / 2 + 12px));
      bottom: calc(var(--bar-h, 104px) + 24px); z-index: 15;
      width: 42px; height: 42px; border-radius: 50%; background: rgba(16,40,75,.86); color: #fff;
      display: none; align-items: center; justify-content: center; font-size: clamp(16px, 4.6512vw, 20px); cursor: pointer;
    }

    .toast {
      position: fixed; left: 50%; bottom: 120px; transform: translateX(-50%); z-index: 40;
      background: rgba(0,0,0,.82); color: #fff; padding: 10px 18px; border-radius: 22px;
      font-size: clamp(11.2px, 3.2559vw, 14px); opacity: 0; transition: opacity .25s; pointer-events: none; text-align: center; max-width: 82%;
    }
    .toast.show { opacity: 1; }

    .loading {
      position: fixed; inset: 0; z-index: 50; background: var(--bg);
      display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 14px;
      font-size: clamp(11.2px, 3.2559vw, 14px); color: var(--muted);
    }
    .spinner { width: 34px; height: 34px; border: 3px solid var(--line); border-top-color: var(--accent); border-radius: 50%; animation: spin 1s linear infinite; }
    @keyframes spin { to { transform: rotate(360deg); } }

    /* ===== 行情详情弹窗 ===== */
    .modal-mask {
      position: fixed; inset: 0; z-index: 60; background: rgba(0,0,0,.5);
      display: none; align-items: flex-end; justify-content: center;
    }
    .modal-mask.show { display: flex; }
    .modal {
      /* 78vh → 88vh：K线弹窗上方本来空着一大截背景，加高后把多出来的高度全给主图（见 detail.js 的 grid）。
         ⚠️ 只影响「只显示日K线」这一种情形；分时（含同框）走 .modal.tall = 90vh，不受影响。 */
      width: 100%; height: 88vh; background: var(--card);
      border-radius: 18px 18px 0 0; overflow: hidden;
      display: flex; flex-direction: column;
      animation: slideUp .22s ease;
    }
    /* 「同框」= K线在上 + 历史分时在下，两张图共显示时把窗口拉高，避免分时被压扁/裁掉 */
    .modal.tall { height: 90vh; }
    @keyframes slideUp { from { transform: translateY(40%); opacity: .4; } to { transform: translateY(0); opacity: 1; } }

    .modal-head {
      padding: 14px 16px 10px; border-bottom: 1px solid var(--line);
      display: flex; align-items: flex-start; justify-content: space-between;
    }
    .modal-head .mname { font-size: clamp(15.2px, 4.4187vw, 19px); font-weight: 700; }
    .modal-head .mcode { font-size: clamp(9.6px, 2.7907vw, 12px); color: var(--muted); margin-left: 6px; }
    .modal-head .mprice { font-size: clamp(17.6px, 5.1163vw, 22px); font-weight: 700; font-variant-numeric: tabular-nums; }
    .modal-head .chgline { font-size: clamp(9.6px, 2.7907vw, 12px); color: var(--muted); margin-top: 2px; }
    .modal-close {
      background: #f0f2f6; border: none; color: #6b7586; font-size: clamp(16px, 4.6512vw, 20px); line-height: 1;
      width: 34px; height: 34px; border-radius: 50%; cursor: pointer; flex: 0 0 auto;
    }
    .modal-close:active { background: #e2e6ee; }

    .modal-tabs {
      display: flex; gap: 4px; padding: 10px 12px 0;
    }
    .modal-tabs button {
      flex: 1; padding: 9px 0; border: none; background: #f0f2f6; color: var(--muted);
      font-size: clamp(11.2px, 3.2559vw, 14px); border-radius: 9px; cursor: pointer; font-weight: 500;
    }
    .modal-tabs button.active { background: var(--brand); color: #fff; }
    /* 分时图刻度切换（全天/实时时间刻度 + 10%/自动涨跌幅坐标），仅在分时tab显示 */
    .minute-toolbar { display: flex; gap: 6px; padding: 8px 12px 0; }
    .minute-toolbar.hidden { display: none; }
    .mt-btn {
      border: 1px solid var(--line); background: #f0f2f6; color: #6b7586; font-size: clamp(8.8px, 2.5582vw, 11px);
      border-radius: 5px; padding: 3px 10px; cursor: pointer; line-height: 1.5;
    }
    .mt-btn:active { background: #e2e6ee; }
    /* K线多周期选择（日/周/月/年）——放在标题栏里，小字号 */
    .kline-periods { display: flex; gap: 4px; margin-top: 7px; }
    .kline-periods.hidden { display: none; }
    .kline-periods button {
      padding: 2px 9px; border: 1px solid var(--line); background: #f0f2f6; color: var(--muted);
      font-size: clamp(8.8px, 2.5582vw, 11px); border-radius: 5px; cursor: pointer; line-height: 1.5;
    }
    .kline-periods button.on { background: var(--brand); color: #fff; border-color: var(--brand); }

    .modal-body { flex: 1; overflow: hidden; position: relative; min-height: 320px; display: flex; flex-direction: column; }
    .modal-body.tall { min-height: 620px; }
    .chart-wrap { flex: 1 1 0; min-height: 0; width: 100%; position: relative; }
    .minute-panel { display: none; flex: 0 0 56%; min-height: 320px; border-top: 1px solid var(--line); background: var(--card); flex-direction: column; }
    .minute-panel.show { display: flex; }
    .minute-panel .chart-wrap { flex: 1 1 0; min-height: 0; }
    .minute-head { display: flex; align-items: center; gap: 8px; padding: 4px 12px; border-bottom: 1px solid var(--line); font-size: clamp(9.6px, 2.7907vw, 12px); color: var(--muted); background: #fafbfd; }
    .minute-head .minute-title { font-weight: 600; color: var(--text); }
    .minute-head .minute-date { flex: 1; text-align: right; color: var(--muted); font-variant-numeric: tabular-nums; }
    .minute-close { border: none; background: #f0f2f6; color: #6b7586; font-size: clamp(9.6px, 2.7907vw, 12px); border-radius: 6px; padding: 3px 10px; cursor: pointer; }
    .minute-close:active { background: #e2e6ee; }
    .modal-tip {
      position: absolute; inset: 0; display: none; flex-direction: column;
      align-items: center; justify-content: center; gap: 12px; color: var(--muted); font-size: clamp(11.2px, 3.2559vw, 14px);
      background: var(--card);
    }
    .modal-tip.show { display: flex; }

    .modal-foot {
      padding: 8px 16px calc(10px + var(--sab));
      font-size: clamp(9.6px, 2.7907vw, 12px); color: var(--muted); text-align: center; border-top: 1px solid var(--line);
    }
    /* K线价轴日期徽章（可点击）：悬停到某根K线时出现在价轴线上，近5日显示「查看当日分时图」可点开下方同框分时 */
    .day-badge {
      position: absolute; left: 0; top: 0; width: 100%; height: 36px;
      z-index: 30; display: none; pointer-events: none;
    }
    /* 点柱子只弹出红色按钮；「整条顶带」都是可点击区域——手机上手指有一点点偏移也不会落到别的K线上重新选择。 */
    .day-badge.recent { pointer-events: auto; cursor: pointer; }
    .badge-btn {
      position: absolute; left: 0; top: 0; transform: translateX(-50%);
      background: #d64545; color: #fff; border-radius: 4px;
      padding: 8px 14px; min-height: 20px; font-size: clamp(9.6px, 2.7907vw, 12px); font-weight: 600;
      line-height: 1.5; white-space: nowrap;
      font-variant-numeric: tabular-nums; box-shadow: 0 1px 3px rgba(0,0,0,.18);
      pointer-events: none; /* 交给父级顶带统一接收，保证整带都能点开 */
    }

    /* ===== 卡片内操作按钮（自选页「买入」/ 持仓页「加仓」「卖出」） ===== */
    .act-btn {
      border: 1px solid #dbe3ee; background: #f4f7fc; color: var(--accent);
      font-size: clamp(9.6px, 2.7907vw, 12px); font-weight: 600; border-radius: 14px; padding: 5px 12px;
      cursor: pointer; line-height: 1.4; white-space: nowrap;
    }
    .act-btn:active { background: #e7eefa; }
    .act-btn.sell { background: #fdf1ee; border-color: #f3d8d1; color: #c0562f; }
    .act-btn.sell:active { background: #f9e4de; }
    /* 只放动作按钮（自选页：未持有 = 买入一个；已持有 = 加仓 + 卖出。持仓页 = 加仓 + 卖出）。
       原来这里还塞着「持N股」和删除「×」，把中间那列涨跌明细挤成了 3 行；两者都挪到卡片
       顶部（代码后面）之后，操作区只剩动作、回到一行。 */
    .act-bar {
      display: grid; grid-template-columns: auto auto; gap: 4px 8px;
      margin-left: auto; align-items: center; justify-items: center;
    }
    /* 自选页改用这个：按钮**另起一行**靠右，不再跟涨跌明细抢宽度。
       因为「加仓 + 卖出」两个两字按钮比原来的「买入 + ×」宽一大截，并排时中间那列只剩
       ~137px，放不下「加入后 +2.66%（18.82 → 19.32）」需要的 ~200px → 两行明细双双折行、
       卡片反而更高（实测 242 → 264）。让按钮独占一行后明细拿到整宽，两行都回到 1 行。 */
    .act-bar.solo { display: flex; justify-content: flex-end; gap: 8px; margin: 8px 0 0; }
    .hold-chip {
      font-size: clamp(8.8px, 2.5582vw, 11px); font-weight: 600; color: var(--down); background: #eaf6f1;
      border-radius: 12px; padding: 4px 9px; white-space: nowrap; font-variant-numeric: tabular-nums;
    }

    /* ===== 历史成交流水行 ===== */
    .ledger-list { padding: 0 12px; }
    .ledger-row {
      background: var(--card); border-radius: 12px; padding: 9px 12px; margin-bottom: 7px;
      box-shadow: 0 1px 3px rgba(16,40,75,.04);
    }
    .lr-top { display: flex; align-items: baseline; gap: 7px; }
    .lr-top .lr-side { font-size: clamp(8.8px, 2.5582vw, 11px); font-weight: 700; border-radius: 5px; padding: 1px 6px; }
    .lr-top .lr-side.buy { background: #fdeeee; color: var(--up); }
    .lr-top .lr-side.sell { background: #eaf6f1; color: var(--down); }
    .lr-top .lr-name { font-size: clamp(11.2px, 3.2559vw, 14px); font-weight: 600; }
    .lr-top .lr-code { font-size: clamp(8.8px, 2.5582vw, 11px); color: #a6afbc; }
    .lr-top .lr-date { margin-left: auto; font-size: clamp(8.8px, 2.5582vw, 11px); color: var(--muted); font-variant-numeric: tabular-nums; }
    .lr-top .lr-del {
      background: none; border: none; color: #c4cad4; font-size: clamp(14.4px, 4.1861vw, 18px); line-height: 1;
      padding: 0 2px; cursor: pointer; flex: 0 0 auto;
    }
    .lr-del:active { color: var(--up); }
    .lr-mid {
      display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 5px;
      font-size: clamp(9.6px, 2.7907vw, 12px); color: #4a5568; font-variant-numeric: tabular-nums;
    }
    .lr-mid .k { color: #a6afbc; }
    .lr-fee { font-size: clamp(8.8px, 2.5582vw, 11px); color: #b0b8c4; margin-top: 3px; font-variant-numeric: tabular-nums; }

    /* ===== 分段切换（曲线视图） ===== */
    .view-switch { display: flex; gap: 4px; }
    .view-switch button {
      padding: 2px 10px; border: 1px solid var(--line); background: #f0f2f6; color: var(--muted);
      font-size: clamp(8.8px, 2.5582vw, 11px); border-radius: 5px; cursor: pointer; line-height: 1.5;
    }
    .view-switch button.on { background: var(--brand); color: #fff; border-color: var(--brand); }

    /* ===== 交易弹层（买入 / 卖出 / 资金，动态挂 body，不受列表重渲染影响） ===== */
    .panel-mask {
      position: fixed; inset: 0; z-index: 70; background: rgba(0,0,0,.5);
      display: flex; align-items: flex-end; justify-content: center;
    }
    .panel {
      width: 100%; max-height: 90vh; overflow-y: auto; background: var(--card);
      border-radius: 18px 18px 0 0; padding-bottom: calc(12px + var(--sab));
      animation: slideUp .22s ease;
    }
    .panel-head { display: flex; align-items: center; padding: 15px 16px 8px; }
    .panel-title { font-size: clamp(13.6px, 3.9535vw, 17px); font-weight: 700; }
    .panel-x {
      margin-left: auto; background: #f0f2f6; border: none; color: #6b7586; font-size: clamp(14.4px, 4.1861vw, 18px);
      line-height: 1; width: 30px; height: 30px; border-radius: 50%; cursor: pointer;
    }
    .panel-sub { padding: 0 16px 10px; font-size: clamp(8.8px, 2.5582vw, 11px); color: var(--muted); line-height: 1.6; }
    .panel-body { padding: 0 16px; }
    .panel-field { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-top: 1px solid var(--line); }
    .panel-field .pf-lbl { flex: 0 0 74px; font-size: clamp(10.4px, 3.0233vw, 13px); color: var(--muted); }
    .panel-field input, .panel-field select {
      flex: 1; min-width: 0; border: 1px solid var(--line); border-radius: 9px;
      padding: 10px 12px; font-size: clamp(12.8px, 3.721vw, 16px); outline: none; background: #f8fafc; color: var(--ink);
    }
    .panel-field input:focus, .panel-field select:focus { border-color: var(--accent); }
    .panel-readonly {
      display: flex; align-items: baseline; gap: 8px; padding: 4px 0 9px;
      font-size: clamp(12px, 3.4884vw, 15px); font-weight: 700;
    }
    .panel-readonly span { font-size: clamp(9.6px, 2.7907vw, 12px); color: var(--muted); font-weight: 500; }
    .panel-readonly .pf-held { margin-left: auto; font-variant-numeric: tabular-nums; }
    .panel-echo {
      margin: 10px 16px 0; padding: 9px 11px; border-radius: 9px; background: #f6f9fd;
      font-size: clamp(9.6px, 2.7907vw, 12px); color: #4a5568; line-height: 1.7; font-variant-numeric: tabular-nums;
    }
    .panel-echo:empty { display: none; }
    .panel-echo.warn { background: #fdf3e5; color: #c0700c; }
    .panel-echo .pe-warn { color: #c0700c; }
    .panel-list { margin: 12px 16px 0; }
    .panel-list-head { font-size: clamp(9.6px, 2.7907vw, 12px); color: var(--muted); padding-bottom: 6px; }
    .panel-row {
      display: flex; align-items: center; gap: 8px; padding: 7px 0; border-top: 1px solid var(--line);
      font-size: clamp(9.6px, 2.7907vw, 12px); font-variant-numeric: tabular-nums;
    }
    .panel-row .pr-date { color: var(--muted); }
    .panel-row .pr-side { font-weight: 600; }
    .panel-row .pr-amt { margin-left: auto; font-weight: 600; }
    .panel-row .pr-del {
      background: none; border: none; color: #c4cad4; font-size: clamp(13.6px, 3.9535vw, 17px); line-height: 1;
      padding: 0 2px; cursor: pointer;
    }
    .panel-row .pr-del:active { color: var(--up); }
    .panel-foot { display: flex; gap: 10px; padding: 14px 16px 4px; }
    .panel-foot button {
      flex: 1; border: none; border-radius: 11px; padding: 13px 0; font-size: clamp(12px, 3.4884vw, 15px);
      font-weight: 600; cursor: pointer;
    }
    .panel-cancel { background: #f0f2f6; color: #6b7586; }
    .panel-ok { background: var(--accent); color: #fff; }
    .panel-ok:disabled { opacity: .45; cursor: not-allowed; }

    /* ===== 单页双视图（自选 / 持仓合并，见 js/shell.js）=====
     * 两个视图启动时都已渲染好，切换只切 display。
     * 不要改用 visibility:hidden / height:0 —— #holdPnlChart 需要真实盒尺寸，
     * 隐藏态高度为 0 时 ECharts init 会得到 0×0 空白画布。 */
    .view { display: none; }
    .view.active { display: block; }

    /* header 左侧的分段控件：header 底色就是 var(--brand)，
     * 默认 .view-switch 是「浅灰底 + 品牌色高亮」，在品牌色背景上选中态完全看不出来。
     * 这里换成「未选 = 半透明白 / 选中 = 实心白反色」，与右侧刷新按钮同一套语言。 */
    header { flex-wrap: wrap; row-gap: 6px; }
    header .view-switch { gap: 6px; }
    header .view-switch button {
      border: 1px solid transparent; background: rgba(255,255,255,.14); color: #fff;
      font-size: clamp(10.4px, 3.0233vw, 13px); font-weight: 600; padding: 6px 15px; border-radius: 16px;
    }
    header .view-switch button:active { background: rgba(255,255,255,.28); }
    header .view-switch button.on { background: #fff; color: var(--brand); border-color: #fff; }
    header .view-switch button.on:active { background: #eef2f8; }
    /* 副标题文案随视图切换且较长，独占一行铺满，免得和左右控件挤一起被截断 */
    header .sub { flex: 1 1 100%; order: 9; margin-top: 0; }

    /* 视图标题行右侧的动作按钮（自选「清空」/ 持仓「资金」），与「历史成交」的 hs-mini 同款 */
    .section-title .title-btn {
      margin-left: auto; border: 1px solid var(--line); background: #fff; color: #6a7486;
      font-size: clamp(8.8px, 2.5582vw, 11px); font-weight: 500; border-radius: 6px; padding: 3px 10px;
      cursor: pointer; line-height: 1.5;
    }
    .section-title .title-btn:active { background: #eef1f6; }

    /* ===== 持仓视图（原 holdings.html 内联 <style> 整段下沉，只把 #pnlChart 改成 #holdPnlChart）===== */
    .pnl-card { background: var(--card); border-radius: 14px; margin: 12px 12px 0; padding: 10px 8px 4px; box-shadow: 0 1px 4px rgba(16,40,75,.05); }
    .pnl-head { display: flex; align-items: center; gap: 8px; padding: 0 6px 4px; }
    .pnl-title { font-size: clamp(10.4px, 3.0233vw, 13px); font-weight: 600; color: var(--muted); }
    .pnl-now { font-size: clamp(12px, 3.4884vw, 15px); font-weight: 700; font-variant-numeric: tabular-nums; }
    .pnl-now .pct { font-size: clamp(9.6px, 2.7907vw, 12px); margin-left: 4px; }
    .pnl-now .dim { font-size: clamp(9.6px, 2.7907vw, 12px); color: var(--muted); font-weight: 500; margin-left: 4px; }
    .pnl-bar { display: flex; align-items: center; gap: 8px; padding: 0 6px 6px; }
    .pnl-range { margin-left: auto; display: flex; gap: 4px; }
    .pnl-range button {
      padding: 2px 9px; border: 1px solid var(--line); background: #f0f2f6; color: var(--muted);
      font-size: clamp(8.8px, 2.5582vw, 11px); border-radius: 5px; cursor: pointer; line-height: 1.5;
    }
    .pnl-range button.on { background: var(--brand); color: #fff; border-color: var(--brand); }
    #holdPnlChart { width: 100%; height: 190px; }
    .pnl-foot { padding: 2px 6px 6px; font-size: clamp(8.8px, 2.5582vw, 11px); color: #b6bdca; line-height: 1.6; }

    /* 持仓卡片：买入信息行 + 金额行 */
    .hold-line {
      display: inline-flex; align-items: center; flex-wrap: wrap; gap: 5px;
      background: #eef4fb; color: var(--accent); font-size: clamp(9.6px, 2.7907vw, 12px); font-weight: 600;
      padding: 5px 10px; border-radius: 8px; margin-bottom: 8px;
      font-variant-numeric: tabular-nums;
    }
    .hold-line .jlabel { color: var(--muted); font-weight: 500; }
    .hold-line .jprice { color: var(--ink); font-weight: 700; }
    .money-grid {
      display: flex; flex-wrap: wrap; gap: 4px 12px; margin: 2px 0 6px;
      font-size: clamp(9.6px, 2.7907vw, 12px); color: var(--muted); font-variant-numeric: tabular-nums;
    }
    .money-grid b { font-weight: 700; font-size: clamp(10.4px, 3.0233vw, 13px); }
    .money-grid .k { color: #a6afbc; }
    .atr-extra { font-size: clamp(8.8px, 2.5582vw, 11px); color: #a6afbc; }
    .adj-warn {
      font-size: clamp(8.8px, 2.5582vw, 11px); color: #c0700c; background: #fdf3e5; border-radius: 8px;
      padding: 5px 9px; margin-bottom: 6px; line-height: 1.5;
    }
    /* 底部买入栏：代码 + 金额 + 按钮（一行）
       原来三格写 46%+32%+20% + 两个 8px 间距 = 超过 100%，必定折行：第二行只剩「买入」一个
       按钮，而按钮没有兄弟撑高（flex 默认 stretch 靠同排最高的兄弟），实测只剩 21px 高，
       既难点又不整齐，还把底栏撑到 89px 高。改回一行；输入框字号跟自选页一致（16px 也是
       iOS 上「小于 16px 的输入框聚焦会整页缩放」的临界值）。 */
    .add-bar.hold { flex-wrap: nowrap; }
    .add-bar.hold .c-code { flex: 1 1 150px; }   /* 要放得下 placeholder「6 位代码或中文」(≈137px) */
    .add-bar.hold .c-amt { flex: 1 1 120px; }    /* 「金额（元）」(≈108px) */
    .add-bar.hold .go { flex: 0 0 auto; }
    .stat-box .lbl.up, .stat-box .lbl.down { font-weight: 600; }
    /* 备份/恢复面板：整块 JSON 的文本域。不给 .panel-field 用（那是 flex 单行布局），
       自己占满一整块；user-select:text 是给安卓长按「全选/复制/粘贴」用的（备份失败时的兜底路径）。 */
    .bk-json {
      display: block; width: 100%; height: 150px; padding: 9px 10px; margin-top: 8px;
      font: 12px/1.55 ui-monospace, Menlo, Consolas, monospace;
      color: var(--ink); background: #f8fafc;
      border: 1px solid var(--line); border-radius: 9px;
      resize: none; overflow: auto; outline: none; word-break: break-all;
      -webkit-user-select: text; user-select: text;
    }
    .bk-json:focus { border-color: var(--accent); }
    .hs-mini {
      border: 1px solid var(--line); background: #fff; color: #6a7486; font-size: clamp(8.8px, 2.5582vw, 11px);
      border-radius: 6px; padding: 2px 8px; cursor: pointer; line-height: 1.5;
    }
    .hs-mini:active { background: #eef1f6; }
