
/* ══════════════════════════════════════════════════════════════
   兼容别名层 —— 全部指向下方「Design Tokens v2」真源。
   规则：此处只做别名（var 转发），禁止定义任何新色值。
   新增颜色一律在 1073 行起的真源里加，否则会出现两套相互打架的色板。
   ══════════════════════════════════════════════════════════════ */
:root{
  --panel:var(--card);--panel2:var(--card-soft);--border:var(--line);--line2:var(--line-strong);
  --txt:var(--ink);--txt2:var(--ink2);
  --down:var(--dn);
  --accent:var(--mint);--acc:var(--mint);--acc-deep:var(--mint-deep);--acc-soft:var(--mint-soft);
  --warn:var(--amber);--warn-soft:var(--amber-soft);--danger:var(--up);
  --serif:"PingFang SC","Microsoft YaHei",system-ui,sans-serif;
  --sans:"PingFang SC","Microsoft YaHei",-apple-system,BlinkMacSystemFont,sans-serif;
  --num:"DIN-PRO Numbers","DIN Pro","DIN Alternate",Roboto,"Helvetica Neue",Arial,sans-serif;
  --mono:"DIN-PRO Numbers",ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;
  --r-tag:6px;--r-control:8px;--r-inner:10px;--r-surface:14px;--r-region:14px;--r-modal:14px;
  --r-md:14px;--r-lg:18px;--r-xl:22px;
  --shadow-sm:0 1px 2px rgba(17,20,18,.05),0 2px 8px -2px rgba(17,20,18,.05);
  --shadow-md:0 1px 2px rgba(17,20,18,.05),0 16px 40px -24px rgba(17,20,18,.18);
  --shadow:var(--shadow-md);
  /* 全局间距：4px 基础网格。页面安全边距独立成 token，任何页面级内容不得越过。 */
  --sp-1:4px;--sp-2:8px;--sp-3:12px;--sp-4:16px;--sp-5:24px;--sp-6:32px;--sp-7:48px;
  --page-gutter:var(--sp-6);
}
*{box-sizing:border-box;margin:0;padding:0}
/* 全局滚动条统一样式：暗色细滚动条，透明轨道 + 半透明圆角滑块，hover 加深；横向纵向一致 */
::-webkit-scrollbar{width:7px;height:7px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:rgba(255,255,255,.12);border-radius:4px}
::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.24)}
::-webkit-scrollbar-corner{background:transparent}
*{scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.14) transparent}
body{background:var(--bg);color:var(--txt);font:12.5px/1.45 "PingFang SC","Microsoft YaHei",sans-serif;padding:var(--sp-3) var(--sp-4) calc(var(--sp-5) + var(--sp-3));font-variant-numeric:tabular-nums}
::selection{background:rgba(77,159,255,.35)}
:focus-visible{outline:2px solid var(--accent);outline-offset:1px}
h1{font-size:16px;font-weight:700}
/* 刊头不带下分隔线（26-09-14 用户要求）：与页脚同理——顶栏自身已有磨砂底与吸顶阴影层次，
   再压一条横线是多余的"重线"。注意这条线在两层各写了一次（此处的基础层 + 主题层 .top 里那条
   带 !important 的），只删一处另一处会顶上来。padding/margin 一律不动，删线不影响文字位置。 */
.top{display:flex;align-items:center;justify-content:center;gap:var(--sp-3);flex-wrap:wrap;padding:var(--sp-1) 0 var(--sp-2);margin-bottom:var(--sp-2)}
.top h1{font-size:15.5px;font-weight:700;letter-spacing:.5px;display:flex;align-items:center;gap:7px}
.top h1 .logo{width:16px;height:16px;display:inline-block;vertical-align:-2px;color:var(--mint);flex:none}
/* 状态是信息标签，不是操作按钮：全端使用方角标签，避免桌面胶囊 / 手机方角的语义跳变。 */
.pill{padding:2px 10px;border-radius:var(--r-tag);font-size:11px;border:1px solid var(--border);background:var(--panel)}
.pill.live{color:#7fe3a0;border-color:#2c5e43;background:#12281c}
.pill.wait{color:var(--warn);border-color:#5e4c22;background:#282112}
.pill.off{color:var(--sub)}
.right{margin-left:auto;display:flex;gap:var(--sp-2);align-items:center;color:var(--sub);font-size:12px}
/* 全局按钮：实心蓝底统一白字；状态不只靠透明度，保证深色背景与移动端均清晰。 */
button{cursor:pointer;border:none;background:#111412;color:#fff;border-radius:var(--r-control);padding:var(--sp-2) var(--sp-4);font-size:12px;font-weight:600;line-height:1.5;min-height:32px;white-space:nowrap;transition:background-color .15s,transform .1s,filter .15s,opacity .15s}
button:hover{background:var(--ink);opacity:1;transform:translateY(-1px)}
button:active{background:var(--ink2);transform:translateY(1px);opacity:1}
button:focus-visible{outline:2px solid #fff;outline-offset:2px}
button:disabled{background:var(--disabled-bg);color:var(--sub);opacity:1;cursor:not-allowed;transform:none}
.up{color:var(--up)} .down{color:var(--down)} .warn{color:var(--warn)} .danger{color:var(--danger)} .dim{color:var(--sub)} .acc{color:var(--accent)}
/* 统一注释规范：所有备注/说明统一为 .fn，置于卡片底部，虚线上分隔 */
/* 10.5px + 最暗的 --sub 是"最小 + 最暗"的组合，长段说明文字阅读吃力，统一提到 11px */
.fn{color:var(--sub);font-size:11px;line-height:1.6;margin-top:10px;padding-top:7px;border-top:1px dashed rgba(255,255,255,.09)}
/* 轨道最小值必须是 0（minmax(0,…)）：默认 1fr 的轨道最小值是 auto=内容最小宽度，
   而 .envcell .el 是 nowrap 长标签，几列最小宽之和会顶破卡片宽度、整块溢出到卡片外 */
.envgrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:0 14px;min-width:0}
.envcell{padding:1.5px 0;min-width:0}
.envcell .el{color:var(--sub);font-size:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.35}
.envcell .ev{font-size:11.5px;font-weight:600;line-height:1.35;overflow-wrap:anywhere}
.market-index-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:7px;margin:2px 0 7px}
.market-index{min-width:0;padding:5px 7px 6px;border:1px solid var(--border);border-radius:8px;background:var(--panel2)}
.market-index-name{display:block;color:var(--sub);font-size:10.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.market-index-price{font-size:15px;font-weight:700;line-height:1.25;margin-top:1px}
.market-index-meta{display:flex;gap:5px;align-items:baseline;font-size:10.5px;white-space:nowrap}
.market-index-meta .amount{font-weight:600}
.market-breadth{display:flex;gap:10px;align-items:baseline;flex-wrap:wrap;padding-top:5px;border-top:1px solid var(--line);font-size:11px}
.market-breadth b{font-size:12px;color:var(--txt)}
@media (max-width:640px){.envgrid{grid-template-columns:repeat(2,minmax(0,1fr))}.market-index-grid{gap:5px}.market-index{padding-left:5px;padding-right:5px}.market-index-price{font-size:14px}.market-index-meta{font-size:10px;gap:3px}}
@media (max-width:420px){.market-index-grid{grid-template-columns:minmax(0,1fr)}.market-index{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);column-gap:8px;align-items:center}.market-index-name{grid-column:1 / -1}}
/* 环境卡改「上下两段」后两段各占满整宽（26-09-14）：段内卡片列数不跟着加，
   指数卡会从 ~227px 被拉到 ~449px、海外卡从 144px 拉到 336px，内容全挤在左侧。
   这里按"卡片宽度维持原样"反算列数。
   关键：海外两组用 auto-fill 而不是 auto-fit。auto-fit 会把没内容的轨道塌掉，
   亚太只有 3 张就会被摊到 441px、而美股 9 张仍是 139px，同一块区域里卡片宽差 3 倍；
   auto-fill 保留空轨道，两组共用同一套 139px 列宽、上下列位对齐，只有行尾留空。
   手机档（≤640）不在此范围，完全沿用既有的 2 列设计。 */
@media (min-width:641px){
  /* 指数卡 5 张：目标 ≥190px，1512 宽下正好 5 张一行（264px），与改前的 227px 同量级 */
  .market-index-grid{grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
  /* 海外两组共用 ≥133px：1512 宽下 9 列 × 139px，与改版前 144px 同一量级，
     仍是"标签上、数值下"两行形态；窄一档自动折成 7+2 / 6+3，行尾留空属正常网格表现。 */
  .envgrid-us,.envgrid-ap{grid-template-columns:repeat(auto-fill,minmax(133px,1fr))}
}

/* 环境卡现在排在结论区最上方：手机端若内部栅格退化成单列，整块会高达 ~760px，   用户要滚一整屏才看到结论，故小屏仍保留 2 列（标签截断有 title 兜底） */
/* 结论区标题行已在 26-09-14 整体下线（模板里已无该元素），下列 .zone-head 规则当前没有实例。
   保留不删的理由：用户的指令是"这一行不展示"，不含"清理相关样式"；且这些规则跨基础层与 6 个断点，
   全部剔除属于范围外改动。若日后确认不再恢复标题行，可连同主题层（约 1286~1289、1867、1960）一并清掉。 */
.zone-head{display:flex;align-items:baseline;gap:10px;margin-bottom:6px;flex-wrap:wrap}
.zone-head b{font-size:13.5px}
.zone-head .sub{color:var(--sub);font-size:10.5px;line-height:1.6;min-width:220px}
.banner{border-radius:var(--r-surface);padding:var(--sp-2) var(--sp-3);margin-bottom:var(--sp-2);font-weight:600;display:none;border:1px solid;font-size:12.5px}
.banner.bad{display:block;color:var(--danger);border-color:#5e2a2a;background:#241214}
.banner.warn{display:block;color:var(--warn);border-color:#5e4c22;background:#282112}
.banner.good{display:block;color:#7fe3a0;border-color:#2c5e43;background:#12281c}
.module-state{margin:4px 0 7px;padding:5px 7px;border:1px solid rgba(221,170,70,.45);border-radius:4px;color:var(--warn);background:rgba(80,58,18,.24);font-size:11px;line-height:1.45}
.module-note{margin-top:7px;color:var(--sub);font-size:10.5px;line-height:1.45}
table{width:100%;border-collapse:separate;border-spacing:0;background:var(--panel);border-radius:10px;overflow:hidden}
th,td{padding:3.5px 8px;text-align:right;white-space:nowrap;border-bottom:1px solid var(--line);font-size:12px}
/* 表头层级：原与正文仅差 0.5px 字号、只靠灰色区分，层次几乎消失；且 var(--line) 这条分隔线
   在 --panel2 背景上几乎看不出来，表头与数据之间没有视觉分界。加粗 + 提色 + 提亮分隔线。
   走查（20轮）修正：原为两条 th 规则，第二条（sticky 定位那条）的 color:var(--sub) 把第一条的
   color:var(--txt) 覆盖掉了 —— 字重和分隔线提上去了，颜色却还停在 --sub，"提亮表头"只落地三分之二，
   注释与实现长期不符。合并为一条，颜色取介于 --sub 与 --txt 之间的 #b6c2d1：
   比正文暗、比旧表头亮，层次出来了又不抢数据行的注意力。 */
th{font-weight:600;color:#b6c2d1;background:var(--panel2);border-bottom:1px solid rgba(255,255,255,.15);cursor:pointer;user-select:none;position:sticky;top:0}
th:hover{color:var(--accent)}
td.l,th.l{text-align:left}
td.c,th.c{text-align:center}
tr:hover td{background:var(--hover-bg)}
.tag{display:inline-block;padding:0 6px;border-radius:4px;font-size:11px;background:var(--panel2);border:1px solid var(--border);color:var(--sub);margin-left:6px}
.tag.x{color:var(--danger);border-color:#5e2a2a}
.tag.t{color:var(--accent);border-color:rgba(255,180,71,.45);background:rgba(255,180,71,.08);font-weight:600}
/* 表格卡高度按「可见行数」标定，不写死总高：改 --tbl-rows 即可调整默认展示行数。
   实测（26-09-14 无头，481~1920 九档）：数据行 55px（≥835px）/ 59px（481~834px 触控放大档）；
   非数据行 = 上下边框 2 + 卡内汇总条 + 表头，随汇总条是否折行在 80.4~101.7px 间变。
   所以这两个值默认只是兜底，真实值由 renderTable 每次渲染按实测回填（窗口换档后自动重量）。
   12 行 = 12×行高 + 非数据行高（桌面档即 742.5px，刚好 12 行整行可见、不露第 13 行残边）。
   行高/表头/汇总条内边距变动后无需改这里，JS 会跟着走；只有【行数】需要人工改 --tbl-rows。 */
.tblwrap{--tbl-rows:12;--tbl-row-h:55px;--tbl-chrome-h:82.5px;max-height:calc(var(--tbl-rows)*var(--tbl-row-h) + var(--tbl-chrome-h));overflow:auto;border:1px solid var(--border);border-radius:10px}
.bar{display:flex;gap:var(--sp-2);align-items:center;flex-wrap:wrap;margin:var(--sp-2) 0}
input{background:var(--panel2);border:1px solid var(--border);color:var(--txt);border-radius:var(--r-control);padding:5px 10px;font-size:12.5px;width:220px;outline:none;transition:border-color .15s}
input:focus{border-color:var(--accent)}
input::placeholder{color:var(--sub)}
#searchBox{position:relative}
/* 搜索建议与同步面板都是同级浮层，统一圆角、描边和阴影。 */
#sug{position:absolute;top:36px;left:0;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-surface);z-index:9;min-width:260px;display:none;overflow:hidden;box-shadow:0 8px 24px rgba(0,0,0,.45)}
#syncPanel{position:absolute;top:calc(100% + 6px);right:0;left:auto;background:var(--panel2);border:1px solid var(--border);border-radius:var(--r-surface);z-index:12;padding:10px;width:min(302px,calc(100vw - 20px));box-shadow:0 10px 30px rgba(0,0,0,.5)}
#syncPanel .sr{display:flex;gap:8px;align-items:center;margin-bottom:8px}
#syncPanel input{width:100%;flex:1}
#syncPanel .st{font-size:11.5px;color:var(--sub);line-height:1.65;margin-bottom:8px}
#syncPanel .st b{color:var(--txt);font-weight:600}
#syncPanel .sync-health{display:flex;align-items:flex-start;gap:7px;padding:7px 8px;border-radius:7px;border:1px solid var(--border);background:rgba(255,255,255,.035);margin-bottom:8px}
#syncPanel .sync-dot{width:7px;height:7px;border-radius:50%;margin-top:5px;background:var(--sub);flex:0 0 auto}
#syncPanel .sync-health.ok .sync-dot{background:#62d78b}
#syncPanel .sync-health.pending .sync-dot{background:var(--warn)}
#syncPanel .sync-health.fail .sync-dot{background:var(--danger)}
#syncPanel .sync-health.conflict{border-color:rgba(255,176,32,.52);background:rgba(255,176,32,.08)}
#syncPanel .sync-health.conflict .sync-dot{background:var(--warn)}
#syncPanel .sync-health .sync-copy{min-width:0;line-height:1.5}
#syncPanel .sync-health b{display:block;color:var(--txt);font-size:11.5px}
#syncPanel .sync-health span{display:block;color:var(--sub);font-size:10.5px;margin-top:1px}
#syncPanel .sbtns{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:8px}
#syncPanel .sbtns button{font-size:12px;padding:4px 10px}
#syncPanel .sbtns button.ghost{background:var(--disabled-bg);color:var(--sub)}
/* 取回安全网（第29轮）：这一行只在「存在取回前留底」时才出现，平时完全不占版面。
   用琥珀色（与冲突态同色）提示这是一条待处理的、有时效的回退通道，而不是常驻功能。 */
#syncPanel .sync-undo{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin:0 0 8px;padding:6px 8px;border:1px solid rgba(255,176,32,.34);border-radius:7px;background:rgba(255,176,32,.07);font-size:10.5px;color:var(--sub);line-height:1.55}
#syncPanel .sync-undo span{flex:1 1 auto;min-width:0}
#syncPanel .sync-undo b{color:var(--txt);font-weight:600}
#syncPanel .sync-undo button{font-size:11px;padding:3px 8px}
#syncPanel .sync-undo button.ghost{background:var(--disabled-bg);color:var(--sub)}
@media (max-width:640px){#syncPanel{left:0;right:auto;width:min(302px,calc(100vw - 20px))}}
#sug div{padding:7px 12px;cursor:pointer;display:flex;justify-content:space-between;transition:background-color .12s}
#sug div:hover{background:#232c3a}
.del{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;min-width:32px;min-height:32px;cursor:pointer;color:var(--sub);border:0;background:transparent;border-radius:6px;padding:0 8px;transition:color .12s,background-color .12s}
.del:hover{color:var(--danger);background:rgba(255,107,107,.10)}
/* 内容是「文本 + <b>数字</b> + 文本 + …」的连续一句话。用 flex 会让每个文本片段和每个 <b>
   都成为独立 flex item，彼此插入 16px 间隙，整句被拆得七零八落。改回常规块级内联流。 */
.summary{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-surface);padding:var(--sp-2) var(--sp-3);margin-bottom:var(--sp-2);font-size:12px;line-height:1.9}
.summary b{font-size:14px;margin:0 3px}
/* 页脚说明按主题分行，避免规则、数据源与存储提示混成一整段。
   页脚不带任何分隔线（26-09-14 用户要求）：上方股票表卡片自带描边，再压一条线就是多余的"重线"。
   两处都要清干净——基础规则里的虚线描边 + 主题层里带 !important 的实线，只删一处另一处就会顶上来。
   间距不变（margin-top 20 + padding-top 12），文字位置与去掉线之前完全一致，只是线没了。 */
.foot{color:var(--sub);font-size:11px;margin-top:var(--sp-4);line-height:1.7;padding-top:var(--sp-2);max-width:1180px}
.foot-line+.foot-line{margin-top:3px}
.foot-line b{color:var(--txt);font-weight:600}
.sort-arrow{font-size:10px;color:var(--accent)}
th.sort-active{color:var(--accent)}
th.sort-active .sort-arrow{color:var(--accent)}
/* 结论区只负责分组，不再充当外层卡片：避免 zone → zcard → 子卡形成三层套娃。 */
.zone{margin:var(--sp-4) 0 var(--sp-3);border:0;border-radius:0;background:transparent;padding:0}
/* 标题与紧随其后的主卡用留白区分，避免标题底线与卡片上边框形成双线。 */
.zone-head{padding:0;margin-bottom:var(--sp-2);border:0}
.qtag{display:inline-block;font-size:10.5px;color:#0d1117;background:var(--accent);border-radius:var(--r-tag);padding:0 5px;font-weight:700;margin-right:5px}
.cgrid3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--sp-2)}
@media (max-width:1099px){.cgrid3{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:640px){.cgrid3{grid-template-columns:minmax(0,1fr)}}
.zcard{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-surface);padding:var(--sp-2) var(--sp-3);min-height:80px;transition:border-color .15s}
.r2top{margin:0 0 var(--sp-2)}
.r2picks{display:grid;gap:var(--sp-2);margin-top:var(--sp-2)}
/* 列数跟随实际入选数：2 只时不再空出 1/3 宽；1 只时限宽避免拉满整行 */
.r2picks.pick-n1{grid-template-columns:minmax(0,1fr);max-width:760px}
.r2picks.pick-n2{grid-template-columns:repeat(2,minmax(0,1fr))}
.r2picks.pick-n3{grid-template-columns:repeat(3,minmax(0,1fr))}
.r2picks .r2pick{margin-top:0}
/* TOP3 固定一行三列：桌面/平板均保持三席并列，窄屏再切回单列保证可读性。 */
@media (max-width:640px){.r2picks.pick-n1,.r2picks.pick-n2,.r2picks.pick-n3,#reboundCard>.zlist{grid-template-columns:minmax(0,1fr)}#reboundCard>.zlist{gap:8px;margin-top:8px}#reboundCard>.zlist>.zitem{padding:9px 0 11px}.r2picks.pick-n1{max-width:none}}
.zcard:hover{border-color:#39445c}
.zcard h4{font-size:12.5px;font-weight:600;margin-bottom:6px;color:var(--txt)}
.span3{grid-column:span 3}
@media (max-width:1099px){.span3{grid-column:span 2}}
@media (max-width:640px){.span3{grid-column:1}}
.zcard.hot{border-color:#3d5a8a;padding:11px 12px;background:linear-gradient(180deg,#19222f,#161b22)}
.zcard.hot:hover{border-color:#4d7ab8}
.zcard.hot h4{margin-bottom:7px;border-bottom:none;padding-bottom:0}
.zcard.hot .bigname{padding:3px 0}
.zcard.hot .pricebox{margin:8px 0;gap:8px}
.zcard.hot .pricebox .kv2{padding:3px 9px}
.zcard.hot .reason{margin-top:7px;line-height:1.65}
.zlist{columns:2;column-gap:14px}
/* 强势股榜单：前十名按 Z 字形（逐行左→右）排列，不沿用多列自上而下排版。 */
#mainlineCard .mainline-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));column-gap:14px;row-gap:0}
#mainlineCard .mainline-list .zitem{break-inside:auto;border-bottom:0 !important}
/* Q6a/Q6b 行尾「主榜判定」：说明这只票在 Q2 里被怎么处理（位次/淘汰原因原样引用主榜名单与候补池）。
   颜色只承载"主榜把它归到哪一层"，不是买卖语义：formal＝主榜打分卡内、irreversible＝当日不可逆淘汰、
   next/missing＝待复核、none＝本轮没有二轮记录。标上任何一档都不代表放行，放行只看 Q2 推荐位与价位口径。
   2026-10-10 起 Q6b 也挂同一份判定，选择器必须两张卡都覆盖 —— 只写 #mainlineCard 的话，Q6b 那行
   会退化成无字号、无颜色的裸文字（由 tests/ui-row-contract.test.mjs 的「⑦ 互指五态样式」双向核对）。 */
#mainlineCard .ml-vd,#reboundCard .ml-vd{font-size:11px;line-height:1.45;color:var(--sub);margin-top:1px;overflow-wrap:anywhere}
#mainlineCard .ml-vd.formal,#reboundCard .ml-vd.formal{color:var(--accent)}
#mainlineCard .ml-vd.irreversible,#reboundCard .ml-vd.irreversible{color:var(--warn)}
#mainlineCard .ml-vd.none,#reboundCard .ml-vd.none{opacity:.78}
/* Q6a⇄Q2 互指的五态配色口径（2026-10-10 复核 F21）：
   formal（已在主榜打分）走强调色、irreversible（今日不可逆淘汰）走预警色、none（未出分）压暗；
   next（等下一交易日窗口）与 missing（数据缺失待复核）刻意沿用上面 .ml-vd 的基线中性灰 ——
   它们只是"主榜已经怎么处理它"的事实说明，不代表放行也不代表淘汰，给它上色就会被读成态度。
   这里**不写** `.ml-vd.next{color:var(--sub)}` 这种重述默认值的声明（同一天刚删过两条这类声明）。
   双向核对由 tests/ui-row-contract.test.mjs 的「⑦ 互指五态样式」负责：新增一个状态既没上色、
   也没进下面这份中性名单，就必须红。BA-MLVD-NEUTRAL: next,missing */
@media (max-width:640px){#mainlineCard .ml-vd,#reboundCard .ml-vd{font-size:11.5px}}
@media (max-width:420px){.zlist{columns:1}}
@media (max-width:640px){#mainlineCard .mainline-list{grid-template-columns:minmax(0,1fr)}}
@media (max-width:560px){#avoidCard .zlist,#declineCard .zlist{columns:1}}
.zitem{break-inside:avoid;display:block;padding:4px 0;border-bottom:1px solid rgba(255,255,255,.05)}
/* Request H（26-09-08）：结论区三列卡（Q3/Q4/Q5）紧凑化 + 策略验证闭环可折叠；不改动任何文案 */
.cgrid3 .zcard{padding:7px 9px}
.cgrid3 .zcard h4{font-size:12px;margin-bottom:5px}
.cgrid3 .zlist{column-gap:10px}
.cgrid3 .zitem{padding:3px 0}
.cgrid3 .zitem .zr1{font-size:12px;line-height:1.34}
.cgrid3 .zitem .zrr{font-size:11px;line-height:1.4}
.cgrid3 .q3t{font-size:11px}
.cgrid3 .q3t td,.cgrid3 .q3t th{padding:2px 4px}
#reviewCard .rv-caret{float:right;margin:2px 0 0 8px;font-size:12px;line-height:1;color:var(--sub);cursor:pointer;transition:transform .15s;user-select:none}
#reviewCard.collapsed .rv-caret{transform:rotate(-90deg)}
#reviewCard.collapsed .rv-body{display:none}
.zitem:last-child{border-bottom:none}
.zitem .zr1{display:flex;gap:6px;font-size:12px;align-items:baseline;flex-wrap:nowrap}
.zitem .zr1 b{max-width:128px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.zitem .zr1 .zpct{margin-left:auto;white-space:nowrap;font-weight:600}
.zitem .zrr{color:var(--sub);font-size:11px;margin-top:2px;line-height:1.5}
.zitem .zr1 .dp{color:var(--sub);font-size:11px;background:rgba(255,255,255,.06);padding:0 6px;border-radius:4px;white-space:nowrap}
/* 逆势反弹独立赛道（路线 B）渲染 */
.rebound{border-left:3px solid var(--warn,var(--amber))}
.rebound h4 .sub{font-weight:400;font-size:11px;color:var(--sub);margin-left:6px}
.rblist{display:flex;flex-direction:column;gap:8px;margin-top:4px}
.rbrow{background:rgba(255,255,255,.03);border:1px solid var(--border);border-radius:8px;padding:6px 8px}
.rbr1{display:flex;gap:6px;align-items:baseline;flex-wrap:nowrap;font-size:13px}
.rbname{max-width:110px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rbcode{color:var(--sub);font-size:11px}
.rbprice{margin-left:auto;font-weight:600;font-variant-numeric:tabular-nums}
.rbr2{display:flex;flex-wrap:wrap;gap:6px;margin-top:5px}
.gchip{display:inline-flex;align-items:center;gap:4px;font-size:11px;padding:1px 7px;border-radius:10px;border:1px solid transparent;line-height:1.6}
.gchip i{width:7px;height:7px;border-radius:50%;display:inline-block;background:currentColor}
.gchip.g-ok{color:#3fb950;background:rgba(63,185,80,.12);border-color:rgba(63,185,80,.35)}
.gchip.g-bad{color:#f0626a;background:rgba(240,98,106,.12);border-color:rgba(240,98,106,.35)}
.gchip.g-na{color:var(--sub);background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.12)}
.rbcaps{margin-top:5px;font-size:11px;color:var(--amber);font-weight:600}
/* 逆势反弹策略组并入 Q2 卡（26-09-07）：作为 Q2 卡内独立子区块，与顺势赛道同卡展示 */
.r2rebound{margin-top:var(--sp-4);padding-top:var(--sp-3);border-top:1px dashed #2a313c}
/* Q6b 展示反弹评分前十名：实际容器是 #reboundCard，桌面两列、手机单列。 */
#reboundCard>.zlist{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 22px;margin-top:12px}
#reboundCard>.zlist>.zitem{min-width:0;margin:0;padding:11px 0 13px;border-bottom:1px solid var(--line)}
.r2rebound-h{display:flex;align-items:baseline;gap:6px;margin-bottom:8px}
.r2rebound-h .qtag{background:var(--warn,var(--amber));color:#1a1206}
.r2rebound-h .sub{font-weight:400;font-size:11px;color:var(--sub);margin-left:2px}
/* Q6b 逆势反弹策略组：复用 .zlist/.zitem 排版（与 Q4 避雷清单同形），以下为赛道内专属评估样式 */
/* Q6b 以反弹评分辅助排序，核心决策信息聚焦目标、止损、赔率和未通过的安全闸。
   回撤/振幅/子板块涨跌仅用于引擎筛选，不在逐票卡片重复占位。 */
.rb-rank{display:inline-block;min-width:18px;text-align:center;color:var(--sub);font-weight:700;margin-right:2px}
.rb-score{margin-left:4px;padding:1px 6px;border-radius:5px;border:1px solid var(--line);background:var(--panel2);color:var(--sub);font-size:10.5px;font-weight:700;white-space:nowrap}
.rb-score.acc{color:var(--accent);border-color:var(--accent)}
.rb-score.dim{color:var(--sub)}
.rb-eval{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto;gap:6px 8px;align-items:stretch;margin-top:6px}
.rb-decision{min-width:0;padding:6px 8px;border-radius:7px;background:var(--panel2);border:1px solid var(--line);line-height:1.25}
.rb-decision span{display:block;color:var(--sub);font-size:10px}
.rb-decision b{display:inline-block;margin-top:2px;color:var(--txt);font-size:12px;font-weight:700;white-space:nowrap}
.rb-decision em{margin-left:3px;font-size:10.5px;font-style:normal;font-weight:700;white-space:nowrap}
.rb-decision.rb-stop{border-left:2px solid var(--down)}
.rb-decision.rb-target{border-left:2px solid var(--accent)}
.rb-rr{display:flex;flex-direction:column;justify-content:center;min-width:52px;padding:6px 7px;border-radius:7px;background:var(--panel2);border:1px solid var(--line);text-align:center}
.rb-rr span{color:var(--sub);font-size:10px}.rb-rr b{margin-top:2px;color:var(--txt);font-size:12px;font-weight:700;white-space:nowrap}
.rb-gates{display:inline-flex;flex-wrap:wrap;gap:5px;margin-top:1px;grid-column:1/-1}
.r2-num{font-variant-numeric:tabular-nums;font-weight:700;font-size:12.5px} /* 数值加粗放大，一眼扫到关键数字 */
.rbdraw{color:var(--amber);font-weight:700;font-size:12.5px} /* 回撤深度=反弹空间，warn色+加粗突出 */
/* Q3 首轮筛选表：复用 .r2t 全部样式，仅微调内边距使六列更舒展 */
.q3t th,.q3t td{padding:6px 8px;font-size:11.5px}
.q3t td:nth-child(2){text-align:left;white-space:nowrap;max-width:180px}
.rbnote{margin-top:8px;font-size:11px;color:var(--sub);line-height:1.65;padding:4px 0}
.rbmore{margin-top:6px;font-size:11px;color:var(--amber);font-weight:600;letter-spacing:.2px} /* "共N只"提示用 warn 色区分 */
.envfull{margin-bottom:var(--sp-2)}
/* 市场阶段标签：方角、panel2 底、细边（站点规范：胶囊+亮描边会被认成按钮）。
   五档用不同色相 + ▼◆▲ 符号双通道区分，刻意不用纯红/纯绿——那对颜色已归涨跌幅 */
.phase{float:right;font-size:12.5px;font-weight:700;border-radius:4px;border:1px solid rgba(255,255,255,.28);background:var(--panel2);color:var(--sub);padding:2px 10px;letter-spacing:.3px}
.phase.p-crash{color:#ff9db3;border-color:rgba(224,122,144,.55);background:rgba(224,122,144,.20)}
.phase.p-bear{color:#9cc0f0;border-color:rgba(127,163,216,.52);background:rgba(127,163,216,.18)}
.phase.p-flat{color:#dfe6f0;border-color:rgba(168,178,194,.50);background:rgba(168,178,194,.16)}
.phase.p-bull{color:#6fdccb;border-color:rgba(84,184,168,.52);background:rgba(84,184,168,.18)}
.phase.p-mania{color:#cbb5ff;border-color:rgba(179,156,245,.55);background:rgba(179,156,245,.20)}
@media (max-width:640px){.phase{float:none;display:inline-block;margin-left:6px;vertical-align:2px}}
/* 判定依据/口径合并进环境卡默认展示（原为 phaseTag 的 hover title）；底部细线与三列内容分隔 */
.phase-detail{margin:0 0 7px;padding-bottom:6px;border-bottom:1px solid var(--line);font-size:11px;color:var(--sub);line-height:1.7}
.phase-detail b{color:var(--txt);font-weight:600}
.q1-state{border-radius:10px;padding:6px 12px;margin:0 0 8px;font-weight:600;display:block;border:1px solid;font-size:12.5px;line-height:1.45}
.q1-state.good{color:#7fe3a0;border-color:#2c5e43;background:#12281c}
.q1-state.bad{color:var(--danger);border-color:#5e2a2a;background:#241214}
/* 环境卡由「左右两栏」改为「上下两段」（26-09-14 老板指令）：上=条款结论+指数卡+市场广度，
   下=跨市场联动（海外指数）。原先是 1.1fr:1fr 两栏 + .envsec+.envsec 的一条左竖线分隔；
   现在任何宽度都是单列，分隔线相应改成顶边横线（见下方 .envsec+.envsec）。
   两段各占满整宽后，段内的卡片列数必须跟着加，否则指数卡会被横向拉成两倍宽、内容挤在左侧 ——
   见 .market-index-grid / .envgrp .envgrid 的 ≥641px 规则。 */
.envfull .envcols{grid-template-columns:minmax(0,1fr)}
/* Q2 未通过硬筛：按总分排名后以网格逐行左→右排列，避免多列从上到下填充打乱名次（Z 字形）。
   Q6 被剔除清单维持原有分栏，不与 Q2 排名逻辑混用。 */
.r2fail .r2fail-list{display:grid;grid-template-columns:minmax(0,1fr);column-gap:10px;row-gap:8px;margin-top:9px}
.r2fail .r2fail-list .zitem{break-inside:auto;border-bottom:0 !important}
/* 26-10-10 列数收口（老板指令：一行只放 3 只）：每条未通过项带「实际/阈值/差距/数据截至」四个数，
   原先 ≥1100px 升 4 列、≥1400px 升 6 列，一只票被压成 4~5 行、日期还从连字符处断成
   "数据截至 2026-" + "10-09"，同行各只票长短不一。现在桌面三列封顶，卡片样式见覆盖层第 13 节。
   断点由小到大书写（媒体查询不加特异性，靠书写顺序覆盖）：手机单列 → 平板两列 → 桌面三列。 */
@media (min-width:641px){.r2fail .r2fail-list{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (min-width:1001px){.r2fail .r2fail-list{grid-template-columns:repeat(3,minmax(0,1fr))}}
/* M6 淘汰个股：桌面端固定六列分栏，不设展开/收起，全部个股默认呈现。 */
@media (min-width:641px){#excludedCard .zlist{columns:6}}
.r2wrap{overflow-x:auto;margin:6px 0;padding-bottom:5px;scrollbar-gutter:stable;border-radius:10px}
/* overflow 必须是 visible：全局 table{overflow:hidden} 会让表格自己变成滚动容器，
   于是 th{sticky;top:0} 与首两列的 left 吸附全部相对这个从不滚动的盒子计算 → 静默失效。
   圆角裁切改由滚动容器 .r2wrap/.tblwrap 负责（overflow:auto 本身即可裁切） */
/* 表格铺满卡片宽度（V44 曾改 width:auto 按内容收紧，实测过密后按用户要求退回）；
   overflow 必须 visible，否则表格自身成为滚动容器会吞掉 sticky 表头/首列 */
.r2t{width:100%;border-collapse:separate;border-spacing:0;font-size:11.5px;overflow:visible}
#tbl{overflow:visible}
.r2t th,.r2t td{padding:4px 7px;text-align:center;border-bottom:1px solid var(--line);white-space:nowrap}
.r2t th{color:var(--sub);font-weight:600;cursor:default}
.r2t th:hover{color:var(--sub)}
.r2t th:nth-child(2),.r2t td:nth-child(2){border-right:1px solid rgba(255,255,255,.08)}
/* 固定前两列（#序号 + 名称），横向滚动时保持可见 */
.r2t th:nth-child(1),.r2t td:nth-child(1){position:sticky;left:0;z-index:3;width:34px;min-width:34px;max-width:34px;background:var(--panel2)}
.r2t th:nth-child(2),.r2t td:nth-child(2){position:sticky;left:34px;z-index:3;background:var(--panel2)}
.r2t td:nth-child(1){background:var(--panel);z-index:2}
.r2t td:nth-child(2){background:var(--panel);z-index:2;text-align:left;white-space:normal;max-width:170px;border-right:1px solid rgba(255,255,255,.08)}
/* Q2/Q3 状态列（第 4 列）：允许换行 + 上下限。实测依据（真实 <style> + 与生产同形的 17 列表，
   Chrome/CDP 在 1440/1024/768 三档量几何，2026-10-10）：
   · 单枚「主线观察」标签在 nowrap 下给本列 +62~70px，三枚标签时 1440 档列宽 228.5px；
   · 表格是 auto 布局，只要有一行带标签，整列（也就是每一行）都被撑宽 —— 1024 档整表横向溢出
     从 50.1px 涨到 112.1px，用户要往右多滚一列才看到总分。
   · 改成可换行但**不给下限**会把行高撑坏：自动布局把可换行的列压到最小内容宽（768 档实测列宽
     39px、行高 166.4px），所以 min-width 与 max-width 必须成对出现。
   · 加下限后（本行的 118/124）：1440 列宽 167.7、1024 溢出 52.1（比 nowrap 的 112.1 反而更小）、
     768 溢出 216.3（比 nowrap 的 272.3 小）；带两枚以上标签的行行高 40.9~43.9px，
     仍低于卡片高度标定用的 --tbl-row-h:55px，不会把卡高撑歪。
   机制与上一行的名称列同形（white-space:normal + max-width），不是新造的一套。 */
.r2t td:nth-child(4){white-space:normal;min-width:118px;max-width:124px}
.r2wrap tr:hover td:nth-child(1),.r2wrap tr:hover td:nth-child(2){background:var(--hover-bg)}
.r2harsh{color:var(--danger);border:1px solid #5e2a2a;background:#241214;border-radius:6px;padding:6px 10px;margin:6px 0;font-size:12px}
/* Q2：标题参数独立成 meta 行，淘汰名单与评分表格分离，避免大表格拥挤 */
.r2meta{color:var(--sub);font-size:11px;line-height:1.7;margin:2px 0 6px}
.r2meta .mi{display:block}
.r2meta b{color:var(--txt);font-weight:600}
.r2fail{margin-top:8px}
.r2fail-t{color:var(--sub);font-size:11px;margin-bottom:2px}
.r2fail .zrr{font-size:11px;line-height:1.5}
.r2fail .zitem{padding:3.5px 0}
/* 环境卡：上下两段（条款+广度 / 跨市场），26-09-14 由左右两栏改来；两段之间用顶边横线分隔。
   原先两栏时用左竖线 + 18px 左内边距做分隔，那两个值在这里一并去掉——留着会在下段左侧画出一条悬空竖线。 */
.envcols{display:grid;grid-template-columns:minmax(0,1fr);gap:0}
.envsec{padding:0;min-width:0}
.envsec+.envsec{border-top:1px solid var(--line);margin-top:10px;padding-top:10px}
.envsec-t{color:var(--sub);font-size:10.5px;font-weight:600;margin-bottom:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 手机上段间距收窄（与原两栏时代的手机档保持一致，只保留间距差异；
   原 ≤1099px 那条"退回两列"的媒体查询已删除——上下两段现在是所有宽度的唯一形态） */
@media (max-width:640px){
  .envsec+.envsec{margin-top:6px;padding-top:4px}
}
.envgrp+.envgrp{margin-top:4px}
.envgrp-t{color:var(--sub);font-size:10.5px;font-weight:600;margin-bottom:1px}
.envgrp .envgrid{gap:0 12px}
.r2pick{border:1px solid var(--border);border-radius:var(--r-inner);padding:8px 10px;margin-top:8px;background:var(--panel2)}
/* 标题行 flex+gap：原先行内元素无间距，名称/代码/价格粘连成"德福科技301151197.59"（走查#1 修复） */
.r2pick .zr1{display:flex;align-items:baseline;gap:6px;flex-wrap:wrap}
.r2pick .zr1 .medal{flex:0 0 auto}
/* TOP3 方案卡不做大面积彩色区分（站点规范：除涨跌幅外一律中性），名次由统一奖杯图标 + 数字表达；保留 m1/m2/m3 作为样式钩子 */
.medal{font-size:15px;margin-right:4px}
.n1{color:#ffd75e}.n2{color:#d9dfe6}.n3{color:#e8a15c}
/* 决策卡排版：名称放大、状态标签右置、现价独占一行放大 —— 核心结论一眼可读 */
.r2pick .zr1 b{font-size:14px}
.r2-tags{margin-left:auto;display:inline-flex;gap:5px;flex-wrap:wrap;justify-content:flex-end}
.r2pick .tag.tm{font-size:11.5px;padding:0 7px;font-weight:600}
.r2pick .tag.st,.r2pick .tag.sc{color:var(--sub)}
.r2pick .tag.wt{color:var(--warn);border-color:rgba(224,174,106,.4)}
.p-line{display:flex;align-items:baseline;gap:8px;margin:3px 0 5px}
.p-line .pl-lab{color:var(--sub);font-size:11px}
.p-line .p-now{font-size:16px;font-weight:700;letter-spacing:.3px}
.pricebox .kv-buy{border-color:rgba(77,159,255,.5);background:rgba(77,159,255,.10)}
.pricebox .kv-buy b{color:var(--mint-deep);font-size:13px;letter-spacing:.3px}
.pricebox .kv-sub{color:var(--sub);font-size:10.5px;margin-left:5px}
.reason.strong{color:var(--txt)}
.fn2{color:var(--sub);font-size:10.5px;line-height:1.6;margin-top:3px;opacity:.92}
.r2pick .zrr{margin-top:3px;line-height:1.6}
/* TOP3 决策摘要：首屏只保留身份、结论、三项判断、支持/风险与一张辅助图表 */
/* TOP3 本身是 Q2 内唯一一层子卡；其内部结论改为平面强调条，不再继续套卡。 */
.r2-summary{margin:var(--sp-2) 0;padding:var(--sp-2) 0 var(--sp-2) var(--sp-3);border-left:3px solid var(--accent);border-top:0;border-right:0;border-bottom:0;background:transparent;border-radius:0}
.r2-summary .sum-lab{color:var(--sub);font-size:10.5px;margin-bottom:2px}
.r2-summary .sum-text{color:var(--txt);font-size:13px;font-weight:600;line-height:1.55}
.r2-summary.sum-strong{border-left-color:var(--up)}
.r2-summary.sum-weak{border-left-color:var(--down)}
.r2-summary.sum-risk{border-left-color:var(--danger)}
.r2-summary.sum-watch{border-left-color:var(--warn)}
.r2-judges{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:0;margin:0 0 var(--sp-3);border-bottom:1px solid rgba(255,255,255,.09)}
.r2-judge{min-width:0;padding:4px 8px 8px;background:transparent;border:0;border-radius:0}
.r2-judge+.r2-judge{border-left:1px solid rgba(255,255,255,.09)}
.r2-judge span{display:block;color:var(--sub);font-size:10px;white-space:nowrap}
.r2-judge b{display:block;margin-top:2px;color:var(--txt);font-size:13px;line-height:1.2}
.r2-judge b.up{color:var(--up)}.r2-judge b.down{color:var(--down)}.r2-judge b.warn{color:var(--warn)}.r2-judge b.danger{color:var(--danger)}
.r2-evidence{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:var(--sp-3);margin:0 0 var(--sp-2)}
.r2-evidence>div{min-width:0;padding:var(--sp-2) 0 0;border-top:1px solid rgba(255,255,255,.09)}
.r2-evidence h5{margin:0 0 3px;color:var(--sub);font-size:10.5px;font-weight:600}
.r2-evidence ul{list-style:none;padding:0;margin:0}.r2-evidence li{font-size:11px;line-height:1.55;color:var(--txt);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.r2-evidence li::before{content:"·";color:var(--accent);margin-right:4px}
.r2-detail{margin-top:var(--sp-3);border-top:1px dashed rgba(255,255,255,.12);padding-top:var(--sp-2)}
.r2-detail>summary{cursor:pointer;color:var(--accent);font-size:11px;list-style:none;user-select:none;outline:none}
.r2-detail>summary::-webkit-details-marker{display:none}
.r2-detail>summary::before{content:"＋";display:inline-block;margin-right:4px;color:var(--sub)}
.r2-detail[open]>summary::before{content:"−"}
@media(max-width:560px){.r2-judges{gap:0}.r2-judge{padding:5px 6px 8px}.r2-judge b{font-size:12px}.r2-evidence{gap:6px}.r2-evidence li{font-size:11px}}
/* Q3 卡内双列：用多列而非 grid —— 排名列表按"列优先"流动，1~4 在左列、5~8 在右列，
   正符合从上到下的名次阅读顺序（grid 行优先会变成 1,2 / 3,4，名次要横向读） */
.q3list{columns:2;column-gap:16px;column-rule:1px solid rgba(255,255,255,.06)}
.q3row{padding:5px 0;border-bottom:1px solid var(--line);break-inside:avoid}
.q3row:last-child{border-bottom:none}
.q3l1{display:flex;align-items:baseline;gap:6px}
.q3rank{color:var(--accent);font-weight:700;min-width:15px;font-size:12.5px}
.q3name{font-size:12.5px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.q3code{font-size:11px;white-space:nowrap}
.q3score{margin-left:auto;font-weight:700;font-size:12.5px;white-space:nowrap;padding-left:4px}
.q3l2{display:flex;gap:10px;margin-top:1px;font-size:12px;padding-left:21px}
.q3price{color:var(--txt)}
/* 手机版保持双列：字号收紧规则放在文件后段的 ≤480px 块中（源码顺序覆盖上面的 14px 基线） */
.envfull h4{margin-bottom:3px}
.zcard .empty{color:var(--sub);font-size:12px;padding:6px 0}
.bigname{font-size:16px;font-weight:700}
.pricebox{display:flex;gap:6px;flex-wrap:wrap;margin:3px 0;font-size:12px}
.pricebox .kv2{background:transparent;border:0;border-left:1px solid var(--border);border-radius:0;padding:2px 10px;transition:border-color .15s}
.pricebox .kv2:hover{border-left-color:var(--accent);background:transparent}
.pricebox .kv2 span{color:var(--sub);margin-right:5px}
.reason{color:var(--sub);font-size:11.5px;line-height:1.5;margin-top:1px}
/* 二级指标固定 6 项：栅格 6 → 3 → 2，每一档都能整除，永不留孤立半行。
   （26-10-09：原先 6/4/2 是为 12 张卡配的，现在只剩 6 张，4 列会排成 4+2 的参差两行，改成 3 列。
   26-10-10 手机档实测截图：6 张竖排一列把卡片拉到 2500px 高，两列每格 ~180px 装得下
   "+3% / -4%" 这种双值读数，故手机保留 2 列，不再降到 1 列。） */
.rv-stats{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:var(--sp-2);padding:var(--sp-1) 0 var(--sp-3);font-size:12px}
@media (max-width:1099px){.rv-stats{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:640px){.rv-stats{grid-template-columns:repeat(2,minmax(0,1fr))}}
.rv-m{display:flex;flex-direction:column;align-items:flex-start;gap:3px;padding:8px 10px;background:var(--panel2);border:1px solid var(--border);border-radius:6px}
.rv-m span{color:var(--sub);font-size:11px;line-height:1.25}
.rv-m b{font-size:14px;font-weight:700}
.rv-sec{margin:16px 0 8px;font-size:12px;font-weight:700;display:flex;align-items:baseline;gap:6px;color:var(--txt)}
.rv-sec .dim{font-weight:400}
/* 逐笔明细：桌面两列、窄屏单列。原先固定 6 列把每张样本卡压到 ~200px，
   说明行里的"绿灯/走势/最高最低"全挤成竖排；两列才有足够宽度读完一行说明。 */
.rv-rows{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin-top:2px;max-height:340px;overflow-y:auto;padding-top:2px}
@media (max-width:899px){.rv-rows{grid-template-columns:minmax(0,1fr)}}
/* 一行笔目定成三列网格：徽章 | 名称＋日期 | 收益，说明独占整行。
   原先是纵向 flex 五个 span 叠五层，名称和收益被拉开、扫读时找不到对应关系。 */
.rv-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto;column-gap:8px;row-gap:3px;align-items:baseline;padding:8px 10px;border:1px solid rgba(255,255,255,.08);border-radius:6px;font-size:12px;transition:background-color .12s;background:rgba(255,255,255,.02)}
.rv-row:hover{background:rgba(255,255,255,.05)}
.rv-row .rv-out{grid-column:1;grid-row:1 / span 2;align-self:start;white-space:nowrap}
.rv-row .rv-name{grid-column:2;grid-row:1;min-width:0;overflow-wrap:anywhere}
.rv-row .rv-ret{grid-column:3;grid-row:1;justify-self:end;white-space:nowrap;font-weight:700}
.rv-row .rv-date{grid-column:2;grid-row:2;justify-self:start}
.rv-row .rv-ext{grid-column:1 / -1;grid-row:3;line-height:1.5;overflow-wrap:anywhere}
.rv-fn{background:transparent;border-radius:0;padding:12px 0 0;margin-top:16px;border-top:1px dashed rgba(255,255,255,.12)}
.rv-titles{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin:2px 0 0}
.rv-titles .rv-sec{margin:0}
/* 统计表整行通栏、每张一张软底卡：两张并排时 11 列的归因表在半宽里被压得读不下去。 */
.rv-tables{display:grid;grid-template-columns:minmax(0,1fr);gap:12px;align-items:start;margin:0 0 10px}
.rv-table-block{min-width:0}
.rv-table-block>.rv-sec{margin:2px 0 4px !important}
.rv-how{color:var(--sub);font-size:11px;line-height:1.55;margin:0 0 8px}
/* 横滑提示：桌面通栏放得下全部列，不必提示；只在窄屏出现一句，避免桌面上留一行废话 */
.rv-scroll-hint{display:none;color:var(--dim);font-size:11px;margin:0 0 6px}
@media (max-width:1099px){.rv-scroll-hint{display:block}}
.rv-tables .cal-tbl{margin:0}
/* 统计表在窄列/触屏上保留完整字段，通过自身横滚承载，不裁切也不强压列宽。 */
@media (max-width:1240px){.rv-tables{min-width:0}.rv-tables .cal-scroll{min-width:0;overflow-x:auto;-webkit-overflow-scrolling:touch}.rv-tables .cal-tbl{min-width:420px}}
.rv-titles:has(> :nth-child(2):last-child){grid-template-columns:repeat(2,minmax(0,1fr))}
.rv-titles:has(> :only-child){grid-template-columns:minmax(0,1fr)}
/* ===== Q7·Q8 合并面板：三级信息层级 =====
   导语 .rv-lede＝这组数字是怎么算出来的（始终在，全卡口径的唯一出处）
   一级 .rv-kpi＝每轮必看的 4 个结果指标（最大字号、实心底、结果色）——栅格同为 4，一行排满不留孤卡
   二级 .rv-stats＝执行与风险 6 项（栅格见上方）
   三级 .rv-mini＝样本规模与统计范围，降级为一条虚线文字条，不再做成一排卡片跟上面两层抢视线 */
.rv-lede{font-size:12px;line-height:1.6;color:var(--sub);padding:2px 0 10px}
.rv-lede b{color:var(--txt);font-weight:600}
.rv-kpi{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--sp-2);padding:var(--sp-1) 0 var(--sp-2)}
@media (max-width:1099px){.rv-kpi{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:420px){.rv-kpi{grid-template-columns:minmax(0,1fr)}}
.rv-kpi .rv-m{padding:10px 12px;border-color:rgba(255,255,255,.16);background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.015))}
.rv-kpi .rv-m span{font-size:11px}
.rv-kpi .rv-m b{font-size:19px;line-height:1.25}
/* 同一指标有服务端/本机两个口径时，主值取服务端（样本全、跨设备），本机值做弱化对照。
   注意选择器权重：.rv-m span 是 (0,1,1)，单写 .rv-sub (0,1,0) 会被它盖掉字号与颜色，
   必须带 .rv-m 前缀提到 (0,2,0) 才生效。 */
.rv-m .rv-sub{display:block;color:var(--sub);font-size:10.5px;font-weight:400;line-height:1.3;margin-top:1px}
.rv-mini{display:flex;flex-wrap:wrap;gap:3px 16px;padding:8px 10px;margin:0 0 var(--sp-3);font-size:11px;line-height:1.55;color:var(--dim);border:1px dashed var(--border);border-radius:6px}
.rv-mini span{color:var(--dim)}
.rv-mini b{color:var(--txt);font-weight:600}
/* 逐笔明细区：与上方统计表之间用实线分块，标题行带来源标签 */
.rv-details{border-top:1px solid rgba(255,255,255,.12);padding-top:var(--sp-2);margin-top:var(--sp-3)}
/* 全样本对照（C 双视图）：与头条"仅推荐"口径并排，视觉上弱一级、用虚线边框区分 */
/* 验证卡内的对照、情景、实验室均改为平面分区；只保留内部指标卡这一层。 */
/* 来源标签：本机快照 vs 服务端样本，明细与分区用它区分，避免两个口径互相冒充。
   描边标签＝服务端（权威口径）；.rv-lv 纯灰字＝本机（补充对照），两者强度有意拉开。 */
.rv-src{display:inline-block;font-size:10px;line-height:1.6;padding:0 4px;border-radius:3px;border:1px solid var(--border);color:var(--sub);margin-left:5px;vertical-align:1px;font-weight:400}
.rv-m span>.rv-src,.rv-sec>.rv-src{font-size:10px}
.rv-lv{font-size:11px;color:var(--sub);font-weight:400;margin-left:5px}
.rv-fallback{color:var(--sub);font-size:11.5px;line-height:1.6;padding:6px 0 2px}
.rv-fallback b{color:var(--txt);font-weight:600}
.cal-tbl{width:100%;border-collapse:collapse;font-size:12px;margin:2px 0 10px}
.cal-tbl th{text-align:left;padding:6px 10px;border-bottom:1px solid rgba(255,255,255,.1);color:var(--sub);font-weight:400}
.cal-tbl td{padding:6px 10px;border-bottom:1px solid rgba(255,255,255,.04);vertical-align:baseline}
.cal-tbl th:not(:first-child),.cal-tbl td:not(:first-child){text-align:right}
.cal-tbl tbody tr:hover{background:rgba(255,255,255,.02)}
.rv-scenario{margin:var(--sp-4) 0 var(--sp-3);padding-top:var(--sp-3);border:0;border-top:1px solid rgba(255,255,255,.12);border-radius:0;background:transparent;overflow:visible}
.rv-scenario summary,.rv-scenario .rv-flat-title{cursor:default;padding:0 0 8px;color:var(--txt);font-size:12px;font-weight:700;list-style-position:inside}
.rv-scenario summary::marker{color:var(--sub)}
.rv-scenario-note{padding:0 0 10px;color:var(--sub);font-size:11px;line-height:1.5}
.rv-scenario-table{width:100%;border-collapse:collapse;table-layout:fixed;font-size:11px}
.rv-scenario-table th,.rv-scenario-table td{padding:var(--sp-2) var(--sp-1);border-bottom:1px solid rgba(255,255,255,.06);text-align:right;white-space:nowrap}
.rv-scenario-table tbody tr:last-child td{border-bottom:0}
.rv-scenario-table th:first-child,.rv-scenario-table td:first-child{text-align:left;width:25%}
.rv-scenario-table th{color:var(--sub);font-weight:400}
.rv-scenario-table .dim{font-size:10px}
.rv-scenario-detail{padding:var(--sp-3) 0 var(--sp-1);border-top:0}
.rv-scenario-detail h5{margin:10px 0 5px;color:var(--sub);font-size:11px;font-weight:600}
.rv-scenario-detail-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:0;border-bottom:1px solid rgba(255,255,255,.08)}
.rv-scenario-detail-grid span{padding:6px 8px 8px;border-radius:0;background:transparent;font-size:10px;color:var(--sub)}
.rv-scenario-detail-grid span+span{border-left:1px solid rgba(255,255,255,.08)}
.rv-scenario-detail-grid b{display:block;color:var(--txt);font-size:11px;margin-top:2px}
.rv-scenario-recent{display:grid;gap:3px;color:var(--sub);font-size:10px}
.rv-scenario-empty{padding:10px;color:var(--sub);font-size:11px}
.p2-lab{margin:var(--sp-4) 0 var(--sp-3);padding-top:var(--sp-3);border:0;border-top:1px solid rgba(255,255,255,.14);border-radius:0;background:transparent;overflow:visible}
.p2-lab>summary,.p2-lab>.rv-flat-title{cursor:default;padding:0 0 9px;color:var(--txt);font-size:12px;font-weight:700;list-style-position:inside}
.p2-actions{display:inline-flex;gap:6px;float:right;margin-top:-2px}.p2-actions button{padding:2px 8px;min-height:24px;font-size:10px}
.p2-body{padding:0 0 var(--sp-1)}.p2-note{color:var(--sub);font-size:11px;line-height:1.5;margin-bottom:var(--sp-3)}
.p2-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-4) var(--sp-3)}.p2-module{min-width:0;border-top:0;padding-top:0}.p2-module:nth-child(n+3){border-top:1px solid rgba(255,255,255,.08);padding-top:var(--sp-3)}.p2-module.wide{grid-column:1/-1}.p2-module h5{font-size:11px;margin:0 0 var(--sp-2);color:var(--txt)}
.p2-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch}.p2-table{width:100%;min-width:430px;border-collapse:collapse;font-size:10.5px}.p2-table th,.p2-table td{padding:5px 6px;border-bottom:1px solid rgba(255,255,255,.05);text-align:right;white-space:nowrap}.p2-table th:first-child,.p2-table td:first-child{text-align:left}.p2-table th{color:var(--sub);font-weight:400}
@media (max-width:700px){.p2-grid{grid-template-columns:minmax(0,1fr)}.p2-module:nth-child(n+2){border-top:1px solid rgba(255,255,255,.08);padding-top:var(--sp-3)}}
@media (max-width:480px){
  .rv-scenario-table{font-size:10px}.rv-scenario-table th,.rv-scenario-table td{padding:6px 3px}
  .rv-scenario-detail-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .rv-scenario-detail-grid span:nth-child(odd){border-left:0}
  .p2-actions{float:none;display:flex;margin:8px 0 0 18px}.p2-lab>summary,.p2-lab>.rv-flat-title{padding-bottom:8px}.p2-body{padding:0}
  /* 验证卡表格：手机端改为横向滚动，不再强压列宽；单元格禁止文字重叠，过宽显示省略号 */
  .p2-table{width:auto;min-width:max-content;border-collapse:collapse;font-size:10px}
  .p2-table th,.p2-table td{padding:var(--sp-1) var(--sp-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .rv-tables .cal-tbl{min-width:max-content;font-size:10.5px}
  .rv-tables .cal-tbl th,.rv-tables .cal-tbl td{padding:5px 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  /* 间距统一：卡片间距、分区留白、列表行距保持一致，避免忽大忽小 */
  .rv-kpi{gap:var(--sp-2);padding:var(--sp-1) 0 var(--sp-2)}
  .rv-stats{gap:var(--sp-2);padding:var(--sp-1) 0 var(--sp-3)}
  .rv-mini{gap:3px 12px;padding:7px 9px;margin:0 0 var(--sp-3);font-size:11.5px}
  .rv-m{gap:var(--sp-1)}
  .rv-sec{margin:var(--sp-4) 0 var(--sp-2)}
  .rv-scenario,.p2-lab{margin:var(--sp-4) 0 var(--sp-3);padding-top:var(--sp-3)}
  .rv-fallback{padding:7px 0 3px}
  /* Q7/Q8 头部：标题占满第一行，操作按钮换到第二行并放大点击区 */
  #reviewCard h4{display:flex;flex-wrap:wrap;gap:4px 8px;align-items:center}
  #reviewCard h4 .rv-head-actions{position:static;float:none;width:100%;justify-content:flex-start;margin:4px 0 0}
  #reviewCard h4 .rv-head-actions .snap-btn{flex:1 1 auto;min-height:42px;font-size:12px}
  /* Q1 判定/口径更疏朗 */
  .phase-detail{line-height:1.7;gap:6px;display:flex;flex-direction:column}
  .phase-detail b{font-weight:600;color:var(--txt)}
  .q1-state{padding:8px 12px;margin-bottom:10px}
  /* 指数卡：价格与涨跌右对齐 */
  .market-index{padding:7px 9px;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:8px;row-gap:2px}
  .market-index-name{grid-column:1 / -1}
  .market-index-price{grid-column:1 / 2}
  .market-index-meta{grid-column:2 / 3;justify-content:flex-end}
  /* 复盘逐笔：名字、日期、收益、标签在同一行对齐 */
  .rv-row{gap:4px 10px;align-items:center}
  .rv-row .rv-ret{flex:1 1 auto;text-align:right}
  .rv-row .rv-date{white-space:nowrap}
  /* 顶部栏：来源标签与刷新按钮加大间距和点击区 */
  .top .right{gap:8px}
  #srcPill{display:inline-flex;align-items:center;min-height:36px;padding:5px 10px}
  #refreshBtn{min-height:36px;padding:6px 12px}
}
.cal-tbl .pos{color:#4ade80}
.cal-tbl .neg{color:#f87171}
.pos{color:#4ade80} .neg{color:#f87171}
.rv-row .rv-out{font-size:11px;font-weight:700;min-width:52px}
.rv-row .rv-out.w{color:var(--up)}
.rv-row .rv-out.s{color:var(--down)}
.rv-row .rv-out.h{color:var(--sub)}
.rv-row .rv-out.u{color:var(--accent)}
.snap-btn{padding:1px 8px;font-size:10.5px;border-radius:4px;line-height:1.7}
.rv-row .rv-name{font-weight:600}
.rv-row .rv-date{color:var(--sub);font-size:11px}
.rv-row .rv-ret{font-weight:700;white-space:nowrap;text-align:left}
.rv-row .rv-ext{color:var(--sub);font-size:11px;white-space:normal;min-width:0;text-align:left}
.zrow{display:flex;gap:8px;padding:2px 0;border-bottom:1px solid var(--line);font-size:12px;align-items:baseline;flex-wrap:wrap}
.zrow:last-child{border-bottom:none}
.zrow .idx{color:var(--accent);font-weight:700;min-width:13px}
.zrow .rr{color:var(--sub);font-size:11px;width:100%}
.batch-btn{display:inline-flex;align-items:center;gap:5px}
.ocr-modal{position:fixed;inset:0;background:rgba(8,10,14,.75);display:flex;align-items:center;justify-content:center;z-index:100;visibility:hidden;opacity:0;transition:opacity .18s,visibility .18s}
.ocr-modal.show{visibility:visible;opacity:1}
.ocr-box{background:var(--panel);border:1px solid var(--border);border-radius:var(--r-region);width:min(680px,94vw);max-height:84vh;display:flex;flex-direction:column}
/* 识别结果双列：117 只时单列要滚很久；列优先排布，行不被劈开。手机端仍单列（弹窗本就占满视口） */
.ocr-cols{columns:2;column-gap:22px}
.ocr-cols .ocr-row{break-inside:avoid}
@media (max-width:640px){.ocr-cols{columns:1}}
.ocr-head{display:flex;align-items:center;gap:8px;padding:10px 14px;border-bottom:1px solid var(--border)}
.ocr-head b{flex:1;font-size:13.5px}
.ocr-close{cursor:pointer;color:var(--sub);font-size:16px;padding:0 4px}
.ocr-close:hover{color:var(--txt)}
.ocr-body{padding:10px 14px;overflow:auto;flex:1}
.ocr-tag{margin-bottom:6px;font-size:12px;color:var(--sub)}
/* 补零改写提示：出现在预览弹窗正文、"确认添加"按钮之前，必须比一般说明更显眼 */
.ocr-pad{margin:0 0 8px;padding:6px 8px;border:1px solid var(--warn);border-radius:6px;background:rgba(255,176,32,.10);font-size:12px;line-height:1.5;color:var(--warn)}
.ocr-row{display:flex;align-items:center;gap:8px;padding:4px 0;border-bottom:1px solid rgba(255,255,255,.05);font-size:12.5px}
.ocr-row:last-child{border-bottom:none}
.ocr-row .nm{font-weight:600}
.ocr-row.skip{opacity:.55}
.ocr-foot{display:flex;align-items:center;gap:12px;padding:10px 14px;border-top:1px solid var(--border)}
.ocr-foot .msg{flex:1;font-size:12px;color:var(--sub)}
.toast{position:fixed;bottom:24px;left:50%;transform:translateX(-50%) translateY(10px);max-width:calc(100vw - 24px);overflow-wrap:anywhere;background:#1e2634;border:1px solid var(--border);color:var(--txt);border-radius:var(--r-inner);padding:8px 16px;font-size:12.5px;z-index:120;opacity:0;transition:opacity .25s,transform .25s;pointer-events:none;box-shadow:0 8px 24px rgba(0,0,0,.4)}
.watch-panel{position:fixed;right:var(--page-gutter);top:calc(var(--page-gutter) + 52px);z-index:110;width:min(380px,calc(100vw - (var(--page-gutter) * 2)));max-height:min(560px,calc(100dvh - 100px));overflow:auto;padding:14px;border:1px solid var(--line);border-radius:var(--r-lg);background:var(--card);box-shadow:0 16px 40px rgba(0,0,0,.32)}
.watch-panel[hidden]{display:none}.watch-head{display:flex;align-items:center;gap:8px;margin-bottom:10px}.watch-head b{font-size:14px}.watch-head span{color:var(--sub);font-size:11px}.watch-head button{margin-left:auto}.watch-subhead{display:flex;align-items:center;justify-content:space-between;gap:8px;margin:14px 0 4px;padding-top:10px;border-top:1px solid var(--hairline);font-size:12px}.watch-subhead b{font-size:12px}.watch-subhead span{font-size:11px;color:var(--sub)}.watch-empty{padding:14px 0;color:var(--sub);font-size:12px;line-height:1.7}.watch-alert,.watch-item,.watch-history{padding:10px 0;border-top:1px solid var(--hairline);font-size:12px}.watch-alert:first-of-type,.watch-item:first-of-type{border-top:0}.watch-alert b,.watch-item b,.watch-history b{display:block;font-size:12.5px}.watch-alert small,.watch-item small,.watch-history small{display:block;color:var(--sub);margin-top:3px;line-height:1.55}.watch-status{display:inline-flex;margin-left:5px;padding:1px 6px;border:1px solid var(--line);border-radius:99px;color:var(--sub);font-size:10.5px;font-weight:600;vertical-align:1px}.watch-status.pending{color:#a65400;border-color:rgba(166,84,0,.35);background:rgba(166,84,0,.07)}.watch-status.ok{color:#176d4a;border-color:rgba(23,109,74,.3);background:rgba(23,109,74,.06)}.watch-status.muted{color:var(--sub)}.watch-actions{display:flex;flex-wrap:wrap;gap:6px;margin-top:7px}.watch-actions button{font-size:11px;padding:4px 8px;min-height:26px}.watch-actions .watch-primary{color:#fff;background:var(--ink);border-color:var(--ink)}.watch-actions .watch-danger{color:#b33a3a}.watch-detail{margin-top:7px;padding:7px 8px;border-left:2px solid var(--line);background:var(--panel2);color:var(--sub);font-size:11px;line-height:1.65}.watch-note{margin-top:10px;padding:8px 9px;border-radius:var(--r-inner);background:var(--panel2);color:var(--sub);font-size:11px;line-height:1.65}.ba-watch{margin-left:6px}.ba-watch.is-watched{color:var(--accent)}
@media (max-width:640px){.watch-panel{top:8px;right:8px;width:calc(100vw - 16px);max-height:calc(100dvh - 16px);padding:12px}.watch-actions button{min-height:34px;padding:6px 10px}.watch-head{position:sticky;top:-12px;padding:10px 0 8px;background:var(--card);z-index:1}}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
#ocrFile{display:none}
.ocr-progress{display:inline-flex;align-items:center;gap:6px;margin:0 0 0 8px;width:130px}
.ocr-progress .bar{flex:1;height:5px;background:var(--panel2);border-radius:3px;overflow:hidden}
.ocr-progress .bar i{display:block;height:100%;width:0;background:var(--accent);transition:width .2s}
.ocr-progress .pct{color:var(--sub);font-size:11px;min-width:34px;text-align:right}

/* ===== 中屏(641-900px 平板/小窗)细节 ===== */
@media (max-width:900px) and (min-width:641px){
  th,td{padding:3px 6px;font-size:11.5px}
  .r2t th,.r2t td{padding:3.5px 5px}
  .zone-head .sub{min-width:0}
}
/* ===== 手机版专用（≤480px 纵向阅读） ===== */
@media (max-width:480px){
  html,body{max-width:100%;overflow-x:hidden}
  body{padding:var(--sp-2) var(--sp-3) var(--sp-5);font-size:12px}
  /* 顶部栏紧凑 */
  .top{justify-content:flex-start;gap:var(--sp-2);padding:var(--sp-1) 0 var(--sp-2);margin-bottom:var(--sp-2)}
  .top h1{font-size:14px}
  .right{gap:6px;font-size:11px}
  .pill{padding:2px 8px;font-size:10.5px}
  /* 主表精简列：只保留代码、名称、分析、最新价、涨跌幅。
     5 列在 320px 仍不应被硬压缩，保留容器内横滚以保证名称、价格和操作按钮可读。 */
  #tbl{min-width:360px;font-size:11.5px}
  .tblwrap{-webkit-overflow-scrolling:touch}
  #tbl th:nth-child(n+6),#tbl td:nth-child(n+6){display:none}
  #tbl th,#tbl td{padding:3px 4px}
  #tbl th:nth-child(2),#tbl td:nth-child(2){max-width:72px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .tblwrap{max-height:58vh}
  /* 搜索与工具条全宽 */
  .bar{gap:var(--sp-2);margin:var(--sp-2) 0}
  #searchBox{width:100%}
  .bar input{width:100%;padding:6px 10px;min-height:32px}
  #sug{min-width:calc(100vw - 20px)}
  .bar .batch-btn,.bar button{padding:6px 10px;min-height:32px}
  /* 触控目标放大 */
  button{padding:6px 12px;min-height:32px}
  .del{padding:0 8px}
  /* 结论区紧凑但不拥挤：卡片内边距略放大，分区上下留白一致 */
  .zone{padding:0;margin:var(--sp-4) 0 var(--sp-3)}
  .zone-head{padding:0;margin-bottom:var(--sp-2)}
  .zcard{padding:var(--sp-3)}
  .zcard.hot{padding:10px}
  .zone-head .sub{min-width:0}
  /* Q2 表格：手机稍缩字号仍横滚(sticky前2列保可见) */
  .r2t{font-size:11px}
  .r2t th,.r2t td{padding:3.5px 4px}
  .r2t td:nth-child(2){max-width:110px}
  /* 复盘行：窄屏刻意不走基础层的三列网格，回到横向换行。
     注意基础规则是 **grid**（26-10-10 由"纵向 flex 五个 span 叠五层"改成 徽章|名称+日期|收益
     三列网格），旧注释写的"基础规则是 column，必须显式改回 row"已经过期，别再照着它改。
     为什么窄屏仍用 flex：480px 下"名称"那一列按 minmax(0,1fr) 会被收益列挤到两三个字，
     换行反而能读；这条口径由 tests/render-unified.test.mjs 的几何断言负责（.rv-row 不溢出）。 */
  .rv-row{display:flex;flex-direction:row;flex-wrap:wrap;align-items:center;gap:4px 8px;padding:7px 8px}
  .rv-ext{min-width:0;margin-left:0;text-align:left;width:100%}
  /* 环境卡值字号 */
  .envcell .ev{font-size:11px}
  /* 汇总/说明条 */
  .summary{padding:4px 10px;gap:8px 14px;font-size:11.5px}
  .foot{font-size:10px}
  .banner{padding:5px 10px;font-size:12px}
  .fn{font-size:10px}
  /* pricebox 胶囊更紧凑 */
  .pricebox .kv2{padding:3px 8px;font-size:11.5px}
  /* 筛选汇总 b 略小 */
  .summary b{font-size:13px}
}
/* ===== 手机版字号整体上调（≤480px，第5轮：原 12px 基线长时间盯盘费眼） ===== */
@media (max-width:480px){
  body{font-size:13.5px}
  .top h1{font-size:16px}
  /* 状态标签跨端均为方角；手机端只调整字号与内边距，不改变组件语义。 */
  .pill{font-size:12px;padding:2px 9px;border-radius:var(--r-tag)}
  .right{font-size:12.5px;margin-left:0;width:100%;justify-content:flex-end;gap:8px;align-items:center}
  #cd{color:var(--sub);font-size:11.5px}
  #refreshBtn{background:#111412;border:1px solid rgba(255,255,255,.18);color:#fff;font-weight:600;border-radius:var(--r-control);padding:var(--sp-1) var(--sp-3)}
  #refreshBtn:hover{background:var(--ink)}
  #refreshBtn:active{background:var(--ink2)}
  #refreshBtn:disabled{background:var(--disabled-bg);color:var(--sub)}
  .banner{font-size:13.5px;padding:6px 11px}
  .zone-head b{font-size:14.5px}
  .zone-head .sub{font-size:12px}
  .zcard h4{font-size:14px;margin-bottom:7px}
  .qtag{font-size:12px}
  .bigname{font-size:18px}
  .kv2{font-size:13.5px}
  .pricebox .kv2{padding:4px 9px}
  .reason{font-size:13.5px;line-height:1.7}
  /* 主表与打分卡表 */
  #tbl{font-size:13px}
  #tbl th,#tbl td{padding:5px 6px}
  #tbl th:nth-child(2),#tbl td:nth-child(2){max-width:96px}
  .zpct{font-size:13.5px}
  .r2t{font-size:12.5px}
  .r2t th,.r2t td{padding:5px 6px}
  .r2t td:nth-child(2){max-width:132px}
  /* 时机标签手机端无需额外覆写：基础 .r2t .tm 已是最优值。
     ⚠ 历史坑记录：曾有一版把 .r2t .tm 写在**基础规则之前**的媒体查询里，媒体查询本身不增加
     特异性，于是那条覆写永远不生效。现在本块位于基础规则之后，若要覆写 .r2t .tm 是有效的；
     这里选择不覆写是出于显示效果判断，不是"写了也没用"。改动本块前先确认目标选择器在哪定义。 */
  .r2meta{font-size:12px;line-height:1.75}
  .r2harsh{font-size:13.5px}
  .r2fail-t{font-size:12.5px}
  .r2pick .zrr{font-size:13px;line-height:1.75}
  .medal{font-size:17px}
  .tag{font-size:12px;padding:1px 7px}
  /* 列表类（避雷/下跌/剔除/首轮） */
  .zr1{font-size:13.5px}
  .zrr{font-size:13px;line-height:1.7}
  .dp{font-size:13px}
  .q3name{font-size:14px}
  .q3code,.q3score,.q3price{font-size:13px}
  /* 环境卡与汇总 */
  .envsec-t{font-size:12.5px}
  .phase-detail{font-size:12px}
  .envcell{font-size:13.5px}
  .envcell .ev{font-size:13px}
  .summary{font-size:13px}
  .summary b{font-size:14.5px}
  .fn{font-size:11.5px;line-height:1.75}
  .foot{font-size:11.5px}
  .rv-row{font-size:13.5px}
}
/* ===== 验证看板三表格：桌面端横排 3 列，窄屏/手机自动堆叠 ===== */
@media (max-width:1099px){
  .rv-titles,.rv-tables{grid-template-columns:minmax(0,1fr)}
}
/* ===== Q3 卡内双列（手机版）：保持两列 + 收紧字号，避免互相挤压 ===== */
@media (max-width:480px){
  .q3list{columns:2;column-gap:9px;column-rule:1px solid rgba(255,255,255,.07)}
  .q3row{padding:4px 0}
  .q3l1{gap:4px}
  .q3rank{font-size:11.5px;min-width:11px}
  .q3name{font-size:11.5px}
  .q3code{font-size:10px}
  .q3score{font-size:11.5px;padding-left:2px}
  .q3l2{gap:6px;padding-left:15px;margin-top:0}
  .q3price,.q3l2 span{font-size:11px}
}
/* ===== 手机 Q2 打分卡：横滚大表 → 竖排卡片（≤480px）===== */
@media (max-width:480px){
  .r2wrap{overflow:visible}
  .r2t{min-width:0}
  .r2t,.r2t tbody,.r2t tr,.r2t td{display:block;width:100%;box-sizing:border-box}
  .r2t thead{display:none}
  /* 覆盖桌面 sticky 与前两列固定宽度，否则卡片被撑到 980px、数值溢出屏外 */
  .r2t th:nth-child(1),.r2t td:nth-child(1),.r2t th:nth-child(2),.r2t td:nth-child(2){position:static;left:auto;width:auto;min-width:0;max-width:none;background:none}
  /* 手机列表位于 Q2 主卡内，行项不再做第二层卡片：用大间距与上下分割线承载层级。 */
  .r2t tr{border:0;border-top:1px solid var(--border);border-radius:0;margin:10px 0 0;padding:10px 0 2px;background:transparent}
  .r2t tr:last-child{padding-bottom:var(--sp-3)}
  .r2t td{display:flex;align-items:baseline;justify-content:flex-start;gap:10px;padding:3px 0;border:none;position:static;background:none;max-width:none;white-space:normal;text-align:left}
  /* 名称格作为卡片标题（覆盖桌面的灰底与限宽） */
  .r2t td:nth-child(2){justify-content:flex-start;flex-wrap:wrap;font-size:14px;font-weight:700;padding-bottom:var(--sp-1);border-bottom:0;margin-bottom:var(--sp-1);background:none;max-width:none}
  .r2t td:nth-child(2)::before{display:none}
  /* 分析按钮也改为左对齐（与整体排版一致） */
  .r2t td.ba-cell{justify-content:flex-start;padding-top:6px}
  /* 状态列在卡片模式只在有标签时出现（无标签的行由 r2-st-empty 隐藏） */
  .r2t td.r2-st-empty{display:none}
  .r2t td.ba-cell::before{display:none}
  /* 各列标签：字段名由行模板的 td[data-label] 提供；固定宽度让数值起始位置对齐 */
  /* 标签宽 5.5em → 6.8em：最长列名「今日上榜次数」是 6 个汉字（6em），原宽度装不下会撑开，
     把该行数值整体右推，导致卡片模式下各行的数值起点参差不齐。 */
  .r2t td::before{content:attr(data-label);color:var(--sub);font-size:11.5px;text-align:left;flex:0 0 6.8em}
  .r2t td b{font-size:14px}
  /* 奖牌去外框放大，避免局促 */
  .r2t .tag.t{border:none;background:none;padding:0;margin-left:6px;font-size:17px;vertical-align:-2px}
}
/* ===== 买入分析（BA）===== */
.ba-cell{text-align:right;white-space:nowrap}
.r2t .ba-cell{text-align:center}
/* 主池表分析列已移到名称右侧：表头居中后单元格也要居中，否则按钮与表头错开约半格 */
#tbl .ba-cell{text-align:center}
.ba-cell .ba-btn{margin-left:0}
/* 分析按钮：与全局按钮同色系，略小一号以适配表格单元格 */
.ba-btn{display:inline-flex;align-items:center;gap:var(--sp-1);padding:var(--sp-1) var(--sp-3);border-radius:var(--r-control);font-size:11.5px;color:#fff;background:#111412;border:none;cursor:pointer;margin-left:var(--sp-2);vertical-align:middle;white-space:nowrap;line-height:1.45;font-weight:600;min-height:26px}
.ba-btn:hover{background:#000;opacity:1;transform:translateY(-1px)}
.ba-btn:active{background:var(--ink2);transform:translateY(1px)}
.ba-btn:disabled,.ba-btn.ba-busy,.ba-btn.ba-limited{background:var(--disabled-bg);color:var(--sub);opacity:1;pointer-events:none;transform:none}
.ba-modal{position:fixed;inset:0;background:rgba(10,10,24,.60);backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;z-index:200;animation:baIn .15s ease-out}
@keyframes baIn{from{opacity:0}to{opacity:1}}
.ba-card{width:min(92vw,1080px);max-height:88vh;overflow-y:auto;border-radius:var(--r-modal);border:1px solid rgba(255,255,255,.10);background:#1e1e36;display:flex;flex-direction:column;animation:baIn2 .15s ease-out}
@keyframes baIn2{from{opacity:0;transform:scale(.98)}to{opacity:1;transform:scale(1)}}
.ba-head{display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid rgba(255,255,255,.08);flex-wrap:wrap}
.ba-head .ba-stock{font-size:15px;font-weight:700}
.ba-badge{font-size:11px;padding:1px 8px;border-radius:999px;background:rgba(14,124,74,.14);color:var(--mint-deep)}
.ba-head .ba-spacer{flex:1}
.ba-head button{font-size:12px;padding:3px 10px;border-radius:6px;border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.05);color:inherit;cursor:pointer}
.ba-head button:hover{background:rgba(255,255,255,.1)}
.peer-compare{margin:10px 0;padding:10px;border:1px solid var(--border);border-radius:10px;background:var(--panel2)}
.peer-compare h3{font-size:13px;margin-bottom:6px}.peer-compare .peer-scroll{overflow-x:auto}.peer-compare table{min-width:620px}.peer-compare td,.peer-compare th{font-size:11px;padding:5px 7px}.peer-compare .peer-target{background:rgba(77,159,255,.10)}
.ba-meta{font-size:11px;color:rgba(255,255,255,.65);padding:8px 14px 0;line-height:1.6}
.ba-meta-top{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:5px}
.ba-meta-name{font-size:13px;font-weight:600;color:rgba(255,255,255,.85)}
.ba-meta-last{font-size:22px;font-weight:700;color:#fff;letter-spacing:.3px;font-variant-numeric:tabular-nums lining-nums}
.ba-meta-chg{font-size:14px;font-weight:600;font-variant-numeric:tabular-nums lining-nums}
.ba-meta-chg.up{color:#e8533f}
.ba-meta-chg.down{color:#2ea66b}
.ba-meta-sub{font-size:11px;color:rgba(255,255,255,.55);line-height:1.6}
.ba-meta-sub b{font-weight:600;color:rgba(255,255,255,.78)}
/* .ba-profile 已废弃（10:15 产品决策：点击分析默认空仓视角，不再展示身份选择；原 select/input 控件已移除） */

.ba-concl{position:sticky;top:0;z-index:2;background:#1e1e36;border-bottom:1px solid rgba(255,255,255,.08);padding:8px 14px}
.ba-concl table{width:100%;border-collapse:collapse;font-size:12px}
.ba-concl td,.ba-concl th{padding:4px 6px;border:1px solid rgba(255,255,255,.08);text-align:left}
.ba-concl th{color:rgba(255,255,255,.6);font-weight:600}
.ba-concl .ba-hl{color:var(--mint-deep);font-weight:700}
.ba-progress{height:2px;background:rgba(255,255,255,.06)}
.ba-progress i{display:block;height:100%;width:0;background:var(--mint-deep);transition:width .3s}
.ba-body{padding:var(--sp-2) var(--sp-4) var(--sp-3)}
/* 弹窗外壳已是卡片，正文分区改用留白和横线，避免 ba-card → ba-sec → 内容卡。 */
.ba-sec{border:0;border-top:1px solid rgba(255,255,255,.10);border-radius:0;margin:var(--sp-3) 0 0;padding-top:var(--sp-1);overflow:visible}
.ba-body>.ba-sec:first-child{border-top:0;margin-top:0;padding-top:0}
.ba-sec-head{display:flex;align-items:center;gap:var(--sp-2);padding:var(--sp-3) 0 var(--sp-2);cursor:pointer;font-size:14px;font-weight:600;background:transparent;user-select:none}
.ba-sec-head .ba-cnt{margin-left:auto;font-size:11px;color:rgba(255,255,255,.45)}
.ba-sec-head .ba-arr{transition:transform .15s;color:rgba(255,255,255,.5)}
.ba-sec[data-open="1"] .ba-arr{transform:rotate(180deg)}
.ba-sec-body{display:none;padding:0 0 var(--sp-3);font-size:13px;line-height:1.85;word-break:break-word}
.ba-sec-body p{margin:7px 0 0}
.ba-sec[data-open="1"] .ba-sec-body{display:block}
.ba-sec-body table{border-collapse:collapse;width:100%;margin:6px 0;font-size:12.5px}
.ba-sec-body th,.ba-sec-body td{border:1px solid rgba(255,255,255,.10);padding:4px 8px;text-align:left}
.ba-sec-body tr:nth-child(even){background:rgba(255,255,255,.03)}
.ba-sec-body code{background:rgba(255,255,255,.08);padding:0 4px;border-radius:4px;font-size:12px}
.ba-sec-body ul,.ba-sec-body ol{margin:4px 0;padding-left:20px}
.ba-sec-body h3,.ba-sec-body h4{font-size:13.5px;margin:15px 0 6px;color:#9ec1ff;font-weight:600}
.ba-strategy-hook{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin:var(--sp-3) 0 var(--sp-4)}
.ba-strategy-hook>div{min-width:0;padding:11px 12px;border:1px solid rgba(74,158,255,.28);border-radius:10px;background:rgba(74,158,255,.07);overflow-wrap:anywhere}
.ba-strategy-hook>div+div{border-left:1px solid rgba(74,158,255,.28)}
.ba-strategy-hook b{display:block;color:#9ec1ff;font-size:11px;margin-bottom:5px;font-weight:600;letter-spacing:.3px}
.ba-strategy-hook span{font-size:12px;line-height:1.6;color:rgba(255,255,255,.82)}
.ba-toolbar{position:static;z-index:auto;background:transparent;border:0;padding:0;display:flex;gap:8px;justify-content:flex-end}
.ba-toolbar button{font-size:12px;padding:var(--sp-1) var(--sp-3);border-radius:var(--r-inner);border:1px solid rgba(255,255,255,.18);background:transparent;color:rgba(255,255,255,.8);cursor:pointer}
.ba-toolbar button:hover{background:rgba(255,255,255,.08)}.ba-toolbar button:active{background:rgba(255,255,255,.14)}.ba-toolbar button:disabled{background:rgba(255,255,255,.05);color:rgba(255,255,255,.4);cursor:not-allowed}
.ba-empty{color:rgba(255,255,255,.45);padding:24px;text-align:center;font-size:13px}
.ba-disclaimer{font-size:11px;color:rgba(255,255,255,.5);padding:var(--sp-2) var(--sp-4);border-top:0;line-height:1.6}

/* ===== 打分卡表（r2t）窄屏专项：把「分析」按钮也钉住 =====
   下限 481px 是必需的：≤480px 走前面的「竖排卡片」模式，而本块的 nth-child 特异性更高、
   源码顺序又在其后，一旦写成 max-width:640px 就会在手机上把卡片模式重新拉成横滚表。 */
@media (max-width:640px) and (min-width:481px){
  .r2wrap{position:relative}
  /* 列宽必须固定，sticky 的 left 偏移才能算准（列1=34px，列2=118px → 列3 钉在 152px） */
  .r2t th:nth-child(2),.r2t td:nth-child(2){width:118px;min-width:118px;max-width:118px}
  .r2t th:nth-child(3),.r2t td:nth-child(3){position:sticky;left:152px;background:var(--panel2)}
  .r2t td:nth-child(3){background:var(--panel);z-index:2}
  .r2t th:nth-child(3){z-index:3}
  .r2wrap tr:hover td:nth-child(3){background:var(--hover-bg)}
  /* 右向投影：提示表格仍可继续横向滚动，避免被误认为列被截断 */
  .r2t th:nth-child(3),.r2t td:nth-child(3){box-shadow:7px 0 9px -7px rgba(0,0,0,.55)}
  .r2t th:nth-child(2),.r2t td:nth-child(2){border-right:1px solid rgba(255,255,255,.14)}
}
.ba-dec{display:block;border:1px solid rgba(14,124,74,.45);border-left:3px solid var(--mint-deep,#0e7c4a);background:rgba(14,124,74,.10);border-radius:10px;padding:10px 12px}
.ba-dec-head{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-bottom:9px}
.ba-cmd{font-size:12px;font-weight:600;color:rgba(255,255,255,.6);display:flex;align-items:baseline;gap:6px}
.ba-cmd b{font-size:18px;color:var(--mint-deep);letter-spacing:.5px}
.ba-lock{font-size:11px;font-weight:400;color:rgba(255,255,255,.45);border:1px solid rgba(255,255,255,.14);border-radius:999px;padding:1px 7px}
.ba-odds{font-size:12px;color:rgba(255,255,255,.72);border:1px solid rgba(255,255,255,.22);border-radius:6px;padding:3px 10px;cursor:help;white-space:nowrap}
.ba-chips{display:flex;gap:6px;flex-wrap:wrap;flex:1 1 100%;margin-top:2px}
.ba-chips .kv2{display:flex;align-items:baseline;gap:8px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.10);border-radius:8px;padding:4px 10px;font-size:13px}
.ba-chips .kv2 span{color:rgba(255,255,255,.55);white-space:nowrap}
.ba-chips .kv2 b{color:#fff;font-size:13.5px}
.ba-chips .kv2.ba-kv-hl b{color:var(--mint-deep)}
/* 买入区间时效标签：今日可触发=accent；下一交易日/日内难触发=中性灰（不用红绿，语义归涨跌幅） */
.ba-chips .kv-when{align-self:center;font-size:11px;padding:2px 7px;border-radius:4px;white-space:nowrap}
.ba-chips .kv-when.tdy{color:var(--mint-deep);border:1px solid rgba(14,124,74,.4);background:rgba(74,159,255,.10)}
.ba-chips .kv-when.nx{color:rgba(255,255,255,.6);border:1px solid rgba(255,255,255,.16);background:rgba(255,255,255,.04)}
/* BA 用户批准驾驶舱：风险、倒计时、执行价位与数据源健康一屏收敛 */
.ba-cockpit{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1.4fr) minmax(0,1fr);gap:7px;margin:0 0 8px}
.ba-cockpit-card{min-width:0;padding:7px 9px;border:1px solid rgba(255,255,255,.12);border-radius:8px;background:rgba(255,255,255,.035)}
.ba-cockpit-label{font-size:10.5px;color:rgba(255,255,255,.55);margin-bottom:4px}
.ba-cockpit-main{display:flex;align-items:center;gap:7px;font-weight:600;line-height:1.4}
.ba-risk-dot{width:9px;height:9px;border-radius:50%;background:#62d78b;box-shadow:0 0 7px currentColor;flex:0 0 auto}
.ba-risk-dot.yellow{background:#ffb020;color:#ffb020}.ba-risk-dot.red{background:#f0626a;color:#f0626a}
.ba-exec-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:5px}
.ba-exec-grid span{display:block;color:rgba(255,255,255,.5);font-size:10px}.ba-exec-grid b{display:block;color:#fff;font-size:12px;margin-top:1px;white-space:normal;overflow-wrap:anywhere}
.ba-source-health{display:flex;flex-wrap:wrap;gap:4px}.ba-source{font-size:10.5px;padding:2px 5px;border-radius:4px;border:1px solid rgba(255,255,255,.12);color:#62d78b}.ba-source.partial{color:#ffb020}.ba-source.unavailable{color:#f0626a}
@media (max-width:640px){.ba-cockpit{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.ba-cockpit-card:last-child{grid-column:1/-1}.ba-exec-grid b{font-size:11.5px}}
.ba-state-line{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:6px;margin-bottom:7px}.ba-state-item{padding:6px 8px;border:1px solid rgba(255,255,255,.12);border-radius:7px;background:rgba(255,255,255,.035);min-width:0}.ba-state-item span{display:block;font-size:10px;color:rgba(255,255,255,.52)}.ba-state-item b{display:block;margin-top:2px;font-size:12px;overflow-wrap:anywhere}.ba-state-item.blocked b{color:#f8a0a5}.ba-state-item.ready b{color:#62d78b}.ba-evidence-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:7px;margin-top:7px}.ba-evidence{padding:7px 9px;border:1px solid rgba(255,255,255,.1);border-radius:7px;background:rgba(255,255,255,.025)}.ba-evidence b{font-size:11px}.ba-evidence ul{margin:4px 0 0;padding-left:17px;font-size:11px;line-height:1.55}.ba-price-path{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:0;margin:8px 0 2px;position:relative}.ba-price-path:before{content:"";position:absolute;left:8%;right:8%;top:9px;height:2px;background:rgba(255,255,255,.18)}.ba-price-node{position:relative;text-align:center;font-size:10px;color:rgba(255,255,255,.55)}.ba-price-node i{display:block;width:10px;height:10px;margin:5px auto 4px;border-radius:50%;background:#8994a5;border:2px solid #1e1e36;position:relative;z-index:1}.ba-price-node.entry i{background:#5aa9ff}.ba-price-node.target i{background:#62d78b}.ba-price-node.stop i{background:#f0626a}.ba-full-view{position:fixed;inset:0;z-index:260;background:var(--bg,#151525);overflow:auto;padding:18px}.ba-full-shell{width:min(1080px,100%);margin:0 auto}.ba-full-head{position:sticky;top:0;z-index:3;display:flex;align-items:center;gap:10px;padding:10px 0;background:var(--bg,#151525);border-bottom:1px solid var(--border)}.ba-full-head h2{font-size:17px;margin:0}.ba-full-head .ba-spacer{flex:1}.ba-full-summary,.ba-full-body,.ba-full-review,.ba-full-peer{margin-top:10px;padding:12px;border:1px solid var(--border);border-radius:10px;background:var(--panel,#1e1e36);max-width:100%;overflow-wrap:anywhere}.ba-full-body table,.ba-full-peer table{width:100%;max-width:100%}.ba-version-change{font-size:12px;line-height:1.6;color:rgba(255,255,255,.72)}
@media(max-width:640px){.ba-state-line{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}.ba-evidence-grid{grid-template-columns:minmax(0,1fr)}.ba-full-view{padding:0}.ba-full-shell{width:100%}.ba-full-head{padding:calc(8px + env(safe-area-inset-top)) 10px 8px}.ba-full-summary,.ba-full-body,.ba-full-review,.ba-full-peer{margin:8px 10px;padding:10px;overflow-x:hidden}.ba-full-body table,.ba-full-peer table{display:block;overflow-wrap:anywhere;table-layout:fixed}.ba-full-body td,.ba-full-body th,.ba-full-peer td,.ba-full-peer th{white-space:normal;word-break:break-word}}

.r2t td.r2-tgt{min-width:84px;padding:3px 7px}
.r2t .tg-main{font-size:13.5px;font-weight:700;line-height:1.3}
.r2t .tg-sub{font-size:11px;color:var(--sub);line-height:1.3}
/* 上榜次数副行：主数字=进入前三次数，小字=累计在榜轮数/今日轮数 */
.r2t td.t3c{min-width:66px}
.r2legend{margin:4px 0 2px;padding:5px 9px;font-size:11px;line-height:1.6;color:var(--sub);background:rgba(128,128,128,.08);border-left:3px solid rgba(128,128,128,.35);border-radius:0 8px 8px 0}
.r2legend b{font-weight:600}
/* 手机端覆写必须放在基础规则之后：媒体查询不增加特异性，写在前面会被上面的基础规则直接覆盖
   （此前误放进前方的 @media(max-width:480px) 块，导致手机端适配完全没生效） */
@media (max-width:480px){
  /* 手机端目标列只调字号：卡片模式下 td 已是 flex + width:100%，
     旧横滚设计的固定宽度与左右内距会把卡片内对齐撑歪 */
  .r2t td.r2-tgt{min-width:0;padding:3px 0}
  .r2t .tg-main{font-size:13px}
  .r2t .tg-sub{font-size:10.5px;white-space:nowrap}
}
/* 目标达到后用静态彩虹色强调“已经兑现”，替代原来的置灰；无动画，避免闪烁干扰盯盘。 */
.r2t .tg-main.tg-reached,.r2t .tg-done{opacity:1;background:linear-gradient(90deg,#ff6b6b 0%,#ffb020 26%,#f3dc64 48%,#62d78b 70%,#5aa9ff 100%);-webkit-background-clip:text;background-clip:text;color:transparent!important;font-weight:800}
.r2t .tg-done{display:inline-block}
/* 时机标签：复用 .tag 视觉语言。原 999px 圆角+亮描边+主文本色与分析按钮 .ba-btn 同形，被误认为可点按钮 */
.r2t .tm{margin-left:0;padding:0 5px;font-size:11px;white-space:nowrap}
/* 时机分类色：蓝=可立即执行 / 琥珀=等回踩 / 紫=等突破。不用红绿，避免与涨跌幅语义撞车 */
.tm-now{color:#5aa9ff;background:rgba(90,169,255,.13);border-color:rgba(90,169,255,.38)}
.tm-dip{color:#e0ae6a;background:rgba(224,174,106,.11);border-color:rgba(224,174,106,.34)}
.tm-brk{color:#b39cf5;background:rgba(179,156,245,.11);border-color:rgba(179,156,245,.34)}
/* 行情列五态标签（方案 §3 配色）：蓝=前期/红=中期/橙=后期/灰=横盘/绿=下跌。
   此列的绿=「走下坡」风险语义，与涨跌幅列的红涨绿跌方向一致，与「时机」列的蓝/琥珀/紫不混用 */
.r2t .ws{margin-left:0;padding:0 5px;font-size:11px;white-space:nowrap}
.r2t .ws-early{color:#5aa9ff;background:rgba(90,169,255,.13);border-color:rgba(90,169,255,.38)}
.r2t .ws-mid{color:#ff6b6b;background:rgba(255,107,107,.13);border-color:rgba(255,107,107,.38)}
.r2t .ws-late{color:#f0932b;background:rgba(240,147,43,.14);border-color:rgba(240,147,43,.40)}
.r2t .ws-flat{color:#9aa7b8;background:rgba(154,167,184,.10);border-color:rgba(154,167,184,.30)}
.r2t .ws-down{color:#35c46f;background:rgba(53,196,111,.12);border-color:rgba(53,196,111,.36)}
@media (max-width:480px){
  /* 手机端收紧行情标签：必须排在上面基础规则之后（媒体查询不加特异性，与时机标签同理） */
  .r2t .ws{font-size:10.5px;padding:0 4px}
}
@media (max-width:480px){
  /* 手机端收紧时机标签：必须排在上面这条基础规则之后，否则媒体查询不加特异性会被覆盖 */
  .r2t .tm{font-size:10.5px;padding:0 4px}
}
/* ===== 买入分析弹窗 · 手机/小平板专项适配（≤640px） ===== */
@media (max-width:640px){
  /* 弹窗全屏化：居中浮窗在手机上四周留缝、圆角浪费空间，改为占满视口 */
  .ba-modal{align-items:stretch;justify-content:stretch;padding:0}
  /* 全屏弹窗去圆角是有意的：避免移动端出现无效留白，属于弹窗层级例外。 */
  .ba-card{width:100vw;max-width:none;height:100vh;height:100dvh;max-height:100dvh;border-radius:0;border-left:none;border-right:none;border-top:none}
  /* 头部与底部工具条避开刘海/小白条安全区 */
  .ba-head{padding:calc(8px + env(safe-area-inset-top)) 12px 8px;gap:6px}
  .ba-head .ba-stock{font-size:16px;font-weight:700}
  .ba-head button{padding:6px 11px;min-height:36px;font-size:13.5px}
  .ba-badge{font-size:12.5px;padding:2px 9px}
  .ba-spacer{flex:1 1 auto}
  .ba-meta{font-size:13px;padding:8px 12px 0;line-height:1.75}
  /* 结论区改为静态：六列表若仍 sticky 会长期占掉小屏近半高度 */
  .ba-concl{position:static;padding:10px 12px}
  .ba-dec{gap:8px}
  .ba-cmd{width:100%;font-size:12.5px}
  .ba-cmd b{font-size:16px}
  .ba-chips{gap:6px}
  .ba-chips .kv2{flex:1 1 calc(50% - 6px);justify-content:space-between;padding:6px 9px}
  .ba-chips .kv2 b{font-size:14px}
  .ba-body{padding:var(--sp-1) var(--sp-3) var(--sp-4);-webkit-overflow-scrolling:touch}
  .ba-sec{margin:var(--sp-4) 0 0;padding-top:var(--sp-1)}
  .ba-body>.ba-sec:first-child{margin-top:0;padding-top:0}
  .ba-sec-head{padding:var(--sp-3) 0 var(--sp-2);font-size:15.5px;gap:var(--sp-2)}
  .ba-sec-head .ba-cnt{font-size:12px}
  .ba-sec-body{padding:0 0 var(--sp-3);font-size:14.5px;line-height:1.85}
  .ba-sec-body h3,.ba-sec-body h4{font-size:15px;margin:10px 0 5px}
  .ba-strategy-hook{grid-template-columns:minmax(0,1fr);width:100%;max-width:100%;margin:var(--sp-3) 0 var(--sp-4)}
  .ba-strategy-hook>div{width:auto;max-width:100%;padding:10px 0}
  .ba-strategy-hook>div+div{border-left:0;border-top:1px solid rgba(74,158,255,.18)}
  .ba-sec-body ul,.ba-sec-body ol{padding-left:18px}
  .ba-sec-body li{margin:3px 0}
  .ba-toolbar{padding:0;gap:6px;justify-content:flex-end;align-items:center}
  .ba-toolbar button{flex:0 1 auto;min-height:36px;font-size:13px;padding:6px 9px}
  .ba-disclaimer{font-size:12.5px;line-height:1.7;padding:8px 12px calc(10px + env(safe-area-inset-bottom))}
  /* 有表头标签的表格 → 「字段名 + 值」卡片，彻底免横向滚动 */
  .ba-concl table,.ba-sec-body table{font-size:14px}
  .ba-concl table thead,.ba-sec-body table thead{display:none}
  .ba-concl table tbody,.ba-sec-body table tbody{display:block}
  .ba-concl table tr{display:flex;flex-wrap:wrap;gap:0 14px;border:1px solid rgba(255,255,255,.14);border-radius:10px;padding:8px 10px;margin:6px 0;background:rgba(255,255,255,.04)}
  .ba-sec-body table tr{display:block;border:0;border-top:1px solid rgba(255,255,255,.12);border-radius:0;padding:8px 0 2px;margin:8px 0 0;background:transparent}
  .ba-sec-body table tr:last-child{padding-bottom:var(--sp-2)}
  .ba-sec-body table tr:nth-child(even){background:transparent}
  .ba-concl table td{flex:1 1 calc(50% - 14px);display:flex;justify-content:flex-start;align-items:baseline;gap:10px;border:none;border-bottom:1px dashed rgba(255,255,255,.10);padding:5px 0;text-align:left;font-size:14.5px}
  .ba-sec-body table td{display:flex;justify-content:flex-start;align-items:baseline;gap:12px;border:none;border-bottom:1px dashed rgba(255,255,255,.08);padding:5px 0;text-align:left;font-size:14px}
  .ba-concl table tr>td:last-child,.ba-sec-body table tr>td:last-child{border-bottom:none}
  /* 每行已由顶部分割线区分，内部字段不再重复画虚线。 */
  .ba-sec-body table td{border-bottom:0}
  /* 同上：BA 弹窗表格里「次日上涨概率」等 6 字标签也需要 6.8em */
  .ba-concl table td::before,.ba-sec-body table td::before{content:attr(data-label);flex:0 0 6.8em;color:rgba(255,255,255,.55);font-size:13px;font-weight:600;text-align:left}
  .ba-concl table td:not([data-label]),.ba-sec-body table td:not([data-label]){justify-content:flex-start;text-align:left}
  .ba-concl table td:not([data-label])::before,.ba-sec-body table td:not([data-label])::before{content:none}
  /* 无表头可标注的表退回横向滚动，不强行拆行 */
  .ba-sec-body table.no-lab,.ba-concl table.no-lab{display:block;overflow-x:auto}
}
/* 分析按钮手机尺寸（须位于 .ba-btn 基础规则之后才能生效） */
@media (max-width:480px){
  .ba-btn{font-size:13px;padding:5px 12px;min-height:36px}
  .ba-cell .ba-btn{margin-left:0}
  .del{min-width:40px;min-height:40px}
  #syncPanel .sbtns button{min-height:36px}
}
/* ===== 全局对齐收口：桌面 / 平板 / 手机使用同一阅读规则 =====
   文本与列表从左读；数字按列右对齐；操作区贴右；卡片内字段名与值从同一左边线起。
   只处理展示层，不改变表格列语义、筛选规则或接口。 */
.top{justify-content:flex-start}
.top .right{margin-left:auto}
.zitem .zr1,.ocr-row{min-width:0}
.zitem .zr1 b,.ocr-row .nm{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.r2pick .zr1,.q3l1,.ocr-head,.ocr-foot{min-width:0}
.ocr-foot{flex-wrap:wrap}
.ocr-foot .msg{min-width:0;overflow-wrap:anywhere}
@media (max-width:640px){
  /* 顶部与工具条：身份/状态从左，操作留在右侧；空间不足才自然换行。 */
  .top{justify-content:flex-start;align-items:center;flex-wrap:wrap;gap:var(--sp-2)}
  .top .right{margin-left:0;width:100%;max-width:100%;min-width:0;justify-content:flex-start;flex-wrap:wrap;gap:var(--sp-2)}
  .bar>span[style*="margin-left:auto"]{margin-left:0!important;width:100%;justify-content:flex-start!important;flex-wrap:wrap}
  /* 列表与 OCR：姓名可缩，数值和操作不被挤出。 */
  .zitem .zr1{gap:5px}
  .zitem .zr1 b{flex:1 1 auto;max-width:none}
  .zitem .zr1 .zpct{margin-left:auto;flex:0 0 auto}
  .ocr-row .nm{flex:1 1 auto}
  .ocr-foot{align-items:flex-start}
  .ocr-foot button{margin-left:auto}
  /* Q1、Q2、验证卡：标题与状态左对齐；明细卡统一以左边线开始。 */
  .phase-detail,.q1-state,.r2meta,.rv-fallback,.rv-fn{text-align:left}
  .rv-sec{justify-content:flex-start}
  /* 底部操作条：搜索+批量按钮+云同步/导出/导入/恢复默认不再挤在一行 */
  .bar{flex-wrap:wrap;gap:var(--sp-2);align-items:center}
  #searchBox{order:0;width:100%}
  #batchBtn{order:1}
  #poolMeta{order:2;margin-left:auto;text-align:right;flex:1 1 auto}
  .bar>span[style*="margin-left:auto"]{order:3!important;width:100%!important;display:grid!important;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
  .bar>span[style*="margin-left:auto"] button{width:100%;min-height:44px}
}
@media (max-width:640px){
  /* 高频触控入口统一不小于 40px：搜索、同步、快照和单股分析不会因屏幕变窄而难以点击。 */
  .bar button,.snap-btn,.ba-btn,#syncPanel .sbtns button{min-height:40px}
  .ocr-close{min-width:40px;min-height:40px;display:inline-flex;align-items:center;justify-content:center}
  .toast{bottom:calc(16px + env(safe-area-inset-bottom))}
}
@media (max-width:480px){
  /* 手机顶部：右侧工具组不再被 margin-left:auto 推到第二行最右（留一大段空白），
     改为占满整行、左对齐，与标题/状态标签在同一阅读线上。 */
  .top .right{margin-left:0;width:100%;max-width:100%;justify-content:flex-start;flex-wrap:wrap;gap:var(--sp-2)}
  .top .right #cd{display:none}
  /* OCR 底栏：提示独占一行，确认按钮固定靠右，避免与提示文字互相挤压。 */
  .ocr-foot .msg{flex:1 0 100%}
  .ocr-foot button{margin-left:auto}
  /* 主表转窄列、Q2/BA 转字段卡后均按「字段左 / 数值左」阅读，避免左右混用。 */
  .r2t td,.ba-concl table td,.ba-sec-body table td{justify-content:flex-start;text-align:left}
  .r2t td::before,.ba-concl table td::before,.ba-sec-body table td::before{text-align:left}
}

/* ===== 决策前置卡（26-09-05 新增）：环境闸门 · 策略实测成绩 · 持仓诊断 ===== */
/* 位置刻意放在第一屏、所有个股建议之前：先知道"今天能不能做"和"这套策略历史上赚不赚钱"，
   再看推荐哪只票——顺序反了，再准的选股也会被错的环境吃掉。 */
.gate-head{display:flex;align-items:center;gap:8px;margin-bottom:var(--sp-2)}
.gate-head h4{margin:0;min-width:0}
/* 环境提示收进卡片右上角，避免用整行横幅挤占首屏。 */
.gatebar{display:flex;align-items:center;gap:5px;min-width:0;max-width:56%;margin-left:auto;border-radius:5px;padding:3px 7px;border:1px solid var(--border);background:var(--panel2)}
.gatebar.go{background:rgba(46,204,143,.10);border-color:rgba(46,204,143,.35)}
.gatebar.care{background:rgba(255,176,32,.10);border-color:rgba(255,176,32,.35)}
.gatebar.stop{background:rgba(255,107,107,.12);border-color:rgba(255,107,107,.40)}
.gatebar .gl{font-size:11.5px;font-weight:700;white-space:nowrap}
.gatebar.go .gl{color:var(--down)}
.gatebar.care .gl{color:var(--warn)}
.gatebar.stop .gl{color:var(--danger)}
/* 环境判定理由：走查修复（2026-09-23 实测 768px）——原来是单行 nowrap + 省略号，
   "涨跌比、跌停家数、上证涨跌幅缺失，无法确认环境…" 被截成一读就断的半句话，而它正是
   "为什么今天不给结论"的唯一说明。改成最多两行、超出再截，窄屏另起一行铺满。
   完整文本一直在父级 title 里，但触屏没有 hover，不能把可读性全押在悬停上。 */
.gatebar .gw{min-width:0;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;white-space:normal;word-break:break-word;font-size:10.5px;color:var(--sub);line-height:1.35}
.gategrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--sp-2);margin:var(--sp-2) 0}
/* ≤640 不再把理由整条 display:none：过去它一旦被隐藏，下面那条 `.gatebar .gw{width:100%}`
   就成了永远不生效的死规则（两个断点块各写一遍、后者被前者吃掉），读代码的人会以为窄屏是铺满显示的。
   现在改为换行铺满 + 最多两行，标签与理由各占其位。 */
@media (max-width:640px){.gate-head{align-items:flex-start}.gatebar{max-width:100%;flex-wrap:wrap;padding:3px 5px}.gatebar .gw{font-size:10.5px}.gatebar .gl{font-size:11px}}
.gm{background:var(--panel2);border:1px solid var(--border);border-radius:8px;padding:8px 10px}
.gm span{display:block;font-size:11px;color:var(--sub)}
.gm b{font-size:19px;font-weight:700}
.gm.neg b{color:var(--up)}
.gm.pos b{color:var(--down)}
.gatenote{font-size:11.5px;color:var(--sub);line-height:1.65;margin-top:6px}
.gatenote.warn{color:var(--warn)}
.holdform{display:flex;gap:var(--sp-2);flex-wrap:wrap;align-items:center;margin-top:var(--sp-3);padding-top:var(--sp-3);border-top:0}
.holdform input{width:116px;background:var(--panel2);border:1px solid var(--border);border-radius:6px;color:var(--txt);padding:6px 9px;font-size:13px}
.holdform button{background:var(--panel2);border:1px solid var(--border);border-radius:6px;color:var(--txt);padding:6px 12px;font-size:13px;cursor:pointer}
.holdform button:hover{border-color:var(--accent);color:var(--accent)}
/* 持仓诊断：代码/名称输入联想 */
.holdCodeWrap{position:relative;flex:0 0 auto}
.holdCodeWrap input{width:150px!important}
.holdSuggest{display:none;position:absolute;top:100%;left:0;z-index:50;background:var(--panel2);border:1px solid var(--border);border-radius:6px;max-height:200px;overflow-y:auto;min-width:200px;box-shadow:0 4px 12px rgba(0,0,0,.15)}
.hsItem{padding:6px 10px;font-size:13px;color:var(--txt);cursor:pointer;display:flex;justify-content:space-between;align-items:center}
.hsItem:hover{background:var(--panel1)}
.hsItem .hsCode{font-size:11px;color:var(--sub);font-family:monospace}
.holdout{margin-top:9px}
.holdverdict{font-size:17px;font-weight:700;margin-bottom:3px}
.holdverdict.v-stop{color:var(--danger)}
.holdverdict.v-reduce{color:var(--warn)}
.holdverdict.v-hold{color:var(--down)}
.holdverdict.v-add{color:var(--accent)}
.holdladder{list-style:none;padding:0;margin:6px 0}
.holdladder li{font-size:12.5px;padding:5px 0;border-bottom:1px solid var(--border);line-height:1.65}
.holdladder li:last-child{border-bottom:0}
/* 价位地图 / 风险打勾 / 概率推导（TOP3 卡内） */
/* P2 决策辅助块（概率校准/追高提示/目标可达性/风险体检）：紧凑单行式，减少纵向占用 */
.decblk{margin-top:6px;padding-top:5px;border-top:1px dashed rgba(255,255,255,.12)}
.decblk-t{font-size:11px;color:var(--sub);margin-bottom:2px;letter-spacing:.2px;font-weight:600}
.gatenote{font-size:11px;color:var(--sub);line-height:1.55;margin-top:3px} /* 紧凑行高 */
.gatenote.warn{color:var(--warn)}
.lvrow{display:flex;gap:4px;flex-wrap:wrap;margin-bottom:2px}
.lvchip{font-size:10.5px;padding:1px 6px;border-radius:4px;background:var(--panel2);border:1px solid var(--border);white-space:nowrap}
.lvchip.sup{border-color:rgba(46,204,143,.40)}
.lvchip.res{border-color:rgba(255,82,82,.40)}
.lvchip i{font-style:normal;color:var(--sub);font-size:9.5px;margin-left:3px}
.chkrow{display:flex;gap:4px;flex-wrap:wrap}
/* 纵向筹码分布：纵轴=价格，横向柱=该价格档位的筹码占比；红=获利盘，绿=套牢盘 */
.chipwrap{margin-top:4px}
.chipdist{display:grid;grid-template-columns:42px minmax(0,1fr);gap:6px;margin:4px 0 5px;min-height:132px}
.chipprices{display:flex;flex-direction:column;justify-content:space-between;align-items:flex-end;color:var(--sub);font-size:9.5px;line-height:1}
.chipplot{display:flex;flex-direction:column;justify-content:space-between;min-width:0;border-left:1px solid rgba(255,255,255,.18);padding:1px 0}
.chiprow{position:relative;display:flex;align-items:center;gap:4px;height:4px;min-width:0}
.chiprow::before{content:"";position:absolute;left:0;right:0;border-top:1px solid rgba(255,255,255,.035)}
.chiprow.is-zone{background:rgba(255,255,255,.045)}
.chiprow.is-current::before{border-top-color:rgba(255,82,82,.82)}
.chiprow.is-avg::before{border-top-color:rgba(255,255,255,.55)}
.chipbar{position:relative;z-index:1;height:3px;min-width:1px;border-radius:0 2px 2px 0;background:rgba(255,255,255,.22)}
.chipbar.win{background:rgba(255,82,82,.62)}
.chipbar.lose{background:rgba(46,204,143,.62)}
.chipmark{position:absolute;right:2px;z-index:2;font-size:9px;line-height:11px;white-space:nowrap;transform:translateY(-5px);padding:0 3px;border-radius:2px;background:var(--panel);font-weight:600}
.chipmark.current{color:var(--danger)}
.chipmark.avg{color:var(--sub)}
.chiplegend{display:flex;justify-content:space-between;align-items:center;font-size:9.5px;color:var(--sub);margin-top:2px}
.chiplegend .up{color:var(--danger)}.chiplegend .down{color:var(--down)}
.chipkv{display:flex;gap:6px;flex-wrap:wrap;margin-top:3px}
.chipkv span{font-size:10.5px;padding:1px 6px;border-radius:4px;background:var(--panel2);border:1px solid var(--border);white-space:nowrap;color:var(--sub)}
.chipkv b{color:var(--txt)}
.chipkv .warn{border-color:rgba(255,82,82,.45);color:#ff6b6b}
.chk{font-size:10.5px;padding:1px 6px;border-radius:4px;border:1px solid var(--border);background:var(--panel2);color:var(--sub);white-space:nowrap}
.chk.hit{border-color:rgba(255,107,107,.45);color:var(--danger);background:rgba(255,107,107,.08)}
.chk.safe{border-color:rgba(46,204,143,.30);color:var(--down)}
.chk.na{opacity:.60}
.probwhy{margin-top:5px;font-size:11px;color:var(--sub);line-height:1.75}
.probwhy details>summary{cursor:pointer;color:var(--accent);outline:none;list-style:none;user-select:none}
.probwhy details>summary::-webkit-details-marker{display:none}
.probwhy .pwi{display:flex;justify-content:space-between;gap:8px;padding:1px 0}
.probwhy .pwi b{font-weight:600}
.probwhy .pwi.plus b{color:var(--up)}
.probwhy .pwi.minus b{color:var(--down)}
@media(max-width:640px){
  .gategrid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .gatebar .gw{margin-left:0;width:100%}
  .holdform input{width:104px}
}
