/* ==============================================================================
   胡sir牌阳澄湖大闸蟹 · 苏州数字化智慧农业与生产监控全景大屏
   设计系统 v3「瑞士排版 · 湖金索引」（Design Tokens → 画布 → 指挥栏 → 章节 → 组件 → 双主题 → 响应式）
   v3 设计语言（相对 v2「曜石指挥甲板」的重设计要点，均不触碰 screen.js 渲染契约）：
     1. 瑞士国际主义排版：去卡片盒子——面板底/圆角/阴影全部废除，内容以发丝横线分节、
        栏间以竖向发丝线分隔（报纸栅格），画布即唯一表面；
     2. 黑白灰 + 单一湖金强调：金色只出现在「章节索引号 / 选中塘口描边 / 关键强调」，
        其余一律单色阶；语义绿仅保留在 JS 既有语义标签（资质徽章）；
     3. 数字即英雄：KPI 数值 36px/800（≤1920 视口降 30px 防截断）、塘口检视 20px/800，全部 tabular-nums；
     4. 章节索引制：01–07 金色序号 + 章节题 + 发丝下划线（编辑刊物目录式导航）；
     5. 不对称指挥栏：品牌居左、主标题紧随其后左对齐（弃居中），栏底 2px 实线为海报式粗规线；
     6. 直角几何：控件/节点零圆角，时间轴节点改方章（完成态 = 实色方 + 反色对勾）；
     7. ECharts 数据墨水保留 JS 既有三族色（图表是数据不是装饰），CSS 装饰层严格单色。
   契约守护（勿破坏，均有测试锁定，且为两轮独立审查沉淀的防护规则，v3 必须继承）：
     - .theme-toggle 单图标按钮与 :root[data-theme='dark'] 图标显隐两条规则的精确字符串；
     - :root:not([data-theme]) 无 JS 兜底（否则夜间画面配太阳图标）；
     - 主题色四处定义点同步：HTML 静态 meta / HTML 内联脚本 / screen.js updateMetaThemeColor / CSS --bg；
     - 日间方章完成态由基座 .step-node.completed 消费 token 自动反转，
       禁止再引入 .step-node 浅底特判（会与基座产生特异性竞争，见 §12）；塘口 focus-visible 日/夜双保底；
     - 批次卡 focus 焦点环用 outline-offset 负值内嵌（ink overflow 不进滚动区域，正偏移会被裁切）；
     - .mini-batch-no 须为 block + min-width:0（flex item 缺省 min-width:auto 拒收缩，ellipsis 失效）；
     - .iot-cell-val 溢出三件套；.timeline-empty 跨列；轨道段左端 16px 补偿 10px 列间隙；
     - KPI 第 2 列 1.4fr 加宽（公母比双数值）+ 各断点 .kpi-value.sm 字号显式回补；
     - 980 档 KPI 偶数格分隔线须同特异性 (0,2,0) 显式回补（1720 档 3n+1 规则会残留命中）。
   ============================================================================== */

/* ------------------------------ 1. Design Tokens（夜间缺省） ------------------------------ */
:root {
    color-scheme: dark;

    /* 画布与墨色（瑞士双色阶 + 中间灰阶） */
    --bg: #0b0d11;
    --fg: #f4f4f1;
    --fg-2: #b4b8c0;
    --fg-3: #7c818c;

    /* 规线体系（v3 的全部「结构」都在线上） */
    --rule: rgba(244, 244, 241, 0.16);
    --rule-soft: rgba(244, 244, 241, 0.08);
    --rule-strong: rgba(244, 244, 241, 0.85);

    /* 单一强调色：湖金（与 screen.js CHART_THEMES.dark 的 tempColor/maleColor 同源 #e0a84f） */
    --gold: #e0a84f;
    --gold-dim: rgba(224, 168, 79, 0.55);

    /* 语义色（仅 JS 既有语义消费：资质徽章文字） */
    --ok: #3fd6a4;

    /* 字体 */
    --font-stack: -apple-system, "SF Pro Text", "Segoe UI", Roboto, "PingFang SC",
        "HarmonyOS Sans SC", "Microsoft YaHei", sans-serif;

    --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ------------------------------ 2. 画布与全局 ------------------------------ */
* { margin: 0; padding: 0; box-sizing: border-box; }

html, body { height: 100%; }

body {
    font-family: var(--font-stack);
    color: var(--fg);
    background: var(--bg);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    -webkit-font-smoothing: antialiased;
    -webkit-tap-highlight-color: transparent;
    overflow-x: hidden;
}

::selection { background: var(--gold); color: var(--bg); }

.ic {
    width: 1em;
    height: 1em;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
    flex: none;
}
.ic-xs { width: 13px; height: 13px; }
.ic-lg { width: 20px; height: 20px; }

/* ------------------------------ 3. 指挥栏（不对称 + 海报粗规线） ------------------------------ */
.screen-header {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 0;
    padding: 16px 28px 14px;
    border-bottom: 2px solid var(--rule-strong);
    background: var(--bg);
    position: sticky;
    top: 0;
    z-index: 50;
}

.header-brand {
    display: flex;
    align-items: center;
    gap: 11px;
    min-width: 0;
    padding-right: 24px;
}

/* 品牌徽记：金色竖条（瑞士几何标记，替代 v2 渐变圆角章） */
.brand-emblem {
    width: 14px;
    height: 38px;
    border-radius: 0;
    display: grid;
    place-items: center;
    color: var(--bg);
    background: var(--gold);
    border: 0;
    box-shadow: none;
    flex: none;
}
.brand-emblem .ic { width: 15px; height: 15px; }

.brand-text h1 {
    font-size: 17px;
    font-weight: 800;
    letter-spacing: 0.05em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.brand-text p {
    font-size: 11px;
    color: var(--fg-3);
    margin-top: 3px;
    letter-spacing: 0.04em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.header-center-title {
    text-align: left;
    min-width: 0;
    border-left: 1px solid var(--rule);
    padding-left: 24px;
}

.header-kicker {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 10px;
    font-weight: 650;
    letter-spacing: 0.32em;
    text-transform: uppercase;
    color: var(--fg-3);
    margin-bottom: 5px;
}
.header-kicker .ic { color: var(--gold); }

/* 主标题：纯色重字重（弃渐变字，日间白底不可见问题即天然消除） */
.main-screen-title {
    font-size: 21px;
    font-weight: 800;
    letter-spacing: 0.06em;
    color: var(--fg);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.header-controls {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 10px;
    min-width: 0;
    flex-wrap: wrap;
    padding-left: 24px;
}

/* 信息件：直角线框，瑞士器械件 */
.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 30px;
    padding: 0 10px;
    border-radius: 0;
    border: 1px solid var(--rule);
    background: transparent;
    font-size: 11.5px;
    color: var(--fg-2);
    white-space: nowrap;
}
.chip .ic { color: var(--gold); }
.chip-region b { color: var(--fg); font-size: 12px; letter-spacing: 0.14em; }
.chip-region { border-color: var(--gold-dim); }

.live-clock {
    font-size: 17px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.03em;
    color: var(--fg);
    padding: 0 6px;
    /* 盒宽由 screen.js 按最宽数字形态实测锁死（tnum 失效环境兜底），居中让残余秒差对称消散 */
    text-align: center;
}

.connection-status {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 26px;
    padding: 0 10px;
    border-radius: 0;
    font-size: 11px;
    color: var(--fg-3);
    border: 1px solid var(--rule-soft);
    background: transparent;
    white-space: nowrap;
    /* 盒宽由 screen.js 锁死为最宽状态文案，居中避免「正在更新」等窄文案右侧留大空档 */
    justify-content: center;
}
/* 状态件前置呼吸点：JS 不区分成败挂类，故只作「活动指示」用中性色，
   不用绿色暗示健康——失败态文案「更新失败，保留上次画面」由文字自述 */
.connection-status::before {
    content: "";
    width: 5px;
    height: 5px;
    background: var(--fg-3);
    animation: statusPulse 2.4s ease-in-out infinite;
    flex: none;
}

@keyframes statusPulse {
    0%, 100% { opacity: 0.4; }
    50% { opacity: 1; }
}

.nav-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    height: 30px;
    padding: 0 13px;
    border-radius: 0;
    border: 1px solid var(--rule-strong);
    background: transparent;
    color: var(--fg);
    font-size: 11.5px;
    font-weight: 650;
    letter-spacing: 0.08em;
    text-decoration: none;
    white-space: nowrap;
    transition: background 0.18s var(--ease), color 0.18s var(--ease), border-color 0.18s var(--ease);
}
.nav-btn:hover { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.nav-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.nav-btn-accent { border-color: var(--gold); color: var(--gold); }
.nav-btn-accent:hover { background: var(--gold); color: var(--bg); }
.nav-btn .ic { color: currentColor; }

/* ------------------------------ 4. 主栅格（报纸栏式竖规线） ------------------------------ */
.screen-main {
    flex: 1;
    display: grid;
    grid-template-columns: 344px minmax(0, 1fr) 358px;
    gap: 0;
    align-items: start;
    padding: 0 28px 8px;
    max-width: 2200px;
    width: 100%;
    margin: 0 auto;
}

.screen-column { display: flex; flex-direction: column; gap: 30px; min-width: 0; padding-top: 24px; }

/* 栏间竖向发丝线（报纸分栏） */
.screen-column + .screen-column { border-left: 1px solid var(--rule-soft); }
.screen-column-center { padding-left: 26px; padding-right: 26px; }
.screen-column-left { padding-right: 26px; }
.screen-column-right { padding-left: 26px; }

/* 章节 = 开放式内容 + 发丝结构线；盒状底/圆角/阴影全部废除 */
.card {
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: 0;
    transition: none;
}

.card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding-bottom: 9px;
    margin-bottom: 16px;
    border-bottom: 1px solid var(--rule);
}

.card-title { display: flex; align-items: baseline; gap: 9px; min-width: 0; }

/* v2 的图标色块在 v3 退场（DOM 保留，纯 CSS 隐藏，可随时回滚） */
.title-icon { display: none; }

/* 章节索引号：湖金等宽数字，瑞士目录式导航 */
.sec-idx {
    font-style: normal;
    font-size: 11px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.12em;
    color: var(--gold);
    flex: none;
}

.card-title h2 {
    font-size: 13px;
    font-weight: 750;
    letter-spacing: 0.08em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tag {
    display: inline-flex;
    align-items: center;
    height: 20px;
    padding: 0;
    border-radius: 0;
    font-size: 10.5px;
    color: var(--fg-3);
    border: 0;
    border-bottom: 1px solid var(--rule-soft);
    background: transparent;
    white-space: nowrap;
    flex: none;
    /* 超长 source_label 防破版：inline-flex 下 overflow 为硬裁（无省略号），保底不溢出栏外 */
    max-width: 55%;
    overflow: hidden;
}

.card-foot-note {
    margin-top: 10px;
    text-align: left;
    font-size: 10.5px;
    color: var(--fg-3);
    letter-spacing: 0.04em;
}

/* ------------------------------ 5. KPI 排版台（数字即英雄） ------------------------------ */
/* 开放式数据表：顶部 2px 粗规线定界，竖向发丝分栏，无底无影 */
.center-kpi-grid {
    display: grid;
    grid-template-columns: 1fr 1.4fr repeat(4, minmax(0, 1fr));
    background: transparent;
    border: 0;
    border-top: 2px solid var(--rule-strong);
    border-radius: 0;
    box-shadow: none;
    overflow: visible;
}

.kpi-card {
    background: transparent;
    border: 0;
    border-left: 1px solid var(--rule-soft);
    border-radius: 0;
    box-shadow: none;
    padding: 14px 16px 12px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    transition: none;
}
.kpi-card:first-child { border-left: 0; padding-left: 0; }

.kpi-head { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }

.kpi-kicker {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: var(--fg-3);
}

.kpi-title { font-size: 11.5px; font-weight: 550; color: var(--fg-2); letter-spacing: 0.02em; }

.kpi-value {
    font-size: 36px;
    font-weight: 800;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
    color: var(--fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.kpi-value-sm { font-size: 24px; letter-spacing: -0.01em; color: var(--gold); }
/* v3 单色纪律：数值层不用绿/彩字；公母比是唯一金色数值——「关键强调」的显式例外 */
.kpi-green { color: var(--fg); }
.kpi-amber { color: var(--fg); }

.kpi-note {
    margin-top: 9px;
    font-size: 10.5px;
    color: var(--fg-3);
    letter-spacing: 0.03em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ------------------------------ 6. 时序轨道（方章节点 · 单色） ------------------------------ */
.timeline-card { padding-bottom: 4px; }

.timeline-empty {
    grid-column: 1 / -1;
    padding: 26px 0 22px;
    text-align: center;
    font-size: 12px;
    color: var(--fg-3);
}

.data-source-note {
    font-size: 11.5px;
    color: var(--fg-3);
    margin: -4px 0 16px;
    letter-spacing: 0.02em;
}

.timeline-bar {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
    position: relative;
}

.timeline-step {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 8px;
    padding-top: 4px;
    min-width: 0;
}

/* 方章节点：待执行 = 镂空线框；完成态 = 实色方章 + 反色对勾（无渐变无辉光） */
.step-node {
    width: 36px;
    height: 36px;
    border-radius: 0;
    display: grid;
    place-items: center;
    font-size: 13px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    color: var(--fg-3);
    background: transparent;
    border: 1px solid var(--rule-strong);
    position: relative;
    z-index: 1;
    transition: none;
}

/* 轨道段：1px 发丝线；完成段由 :has() 加粗为 2px 实线（旧浏览器优雅降级为发丝线）。
   左端 16px = 半格宽 50% + 列间隙 10px − 方章避让 26px，保证左右对称避让 */
.timeline-step::before {
    content: "";
    position: absolute;
    top: 22px;
    left: calc(-50% + 16px);
    right: calc(50% + 16px);
    height: 1px;
    background: var(--rule);
}
.timeline-step:first-child::before { display: none; }

.timeline-step:has(.step-node.completed)::before {
    height: 2px;
    top: 21.5px;
    background: var(--rule-strong);
}

.step-node.completed {
    color: var(--bg);
    background: var(--fg);
    border-color: var(--fg);
    box-shadow: none;
}

.step-time {
    font-size: 10.5px;
    font-variant-numeric: tabular-nums;
    color: var(--fg-3);
    letter-spacing: 0.08em;
}

.step-name { font-size: 12.5px; font-weight: 650; color: var(--fg); letter-spacing: 0.04em; }

/* ------------------------------ 7. 中下双节（配比 + 物流） ------------------------------ */
.center-bottom-grid {
    display: grid;
    grid-template-columns: 300px minmax(0, 1fr);
    gap: 30px;
}

/* 画布宽度直接驱动 ECharts 几何（radius 为 min(w,h) 百分比、外部标签受画布位图裁切）：
   268px = v2 实证基线（300px 列 − 卡片左右内边距 32px），标签呈现与已验收的 v2 完全一致 */
.ratio-chart { height: 212px; max-width: 268px; }
.flow-chart { height: 164px; }

.sf-guarantee-row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    border-top: 1px solid var(--rule-soft);
    margin-top: 12px;
    padding-top: 12px;
}

.sf-metric { text-align: left; }
.sf-metric + .sf-metric { border-left: 1px solid var(--rule-soft); padding-left: 18px; }

.sf-metric-label { font-size: 10.5px; color: var(--fg-3); letter-spacing: 0.04em; }

.sf-metric-val {
    margin-top: 5px;
    font-size: 20px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    color: var(--fg);
}

/* ------------------------------ 8. 塘口主图与检视面板（规格单） ------------------------------ */
.pond-atlas-stage { display: flex; flex-direction: column; gap: 14px; }

/* 分区页签（A/B/C 区塘口）：居中排布 + 通栏发丝底线，active = 金字 + 金色 2px 底线 */
.pond-zone-tabs {
    display: flex;
    flex-wrap: wrap;            /* 区数增多时换行，不溢出栏宽 */
    justify-content: center;
    gap: 4px 22px;
    border-bottom: 1px solid var(--rule);
    margin-bottom: 12px;
}
/* 首帧未取数或塘口清空时不画空发丝线 */
.pond-zone-tabs:empty { display: none; }

.pond-tab {
    appearance: none;
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    padding: 5px 2px 7px;
    margin-bottom: -1px;
    font-family: var(--font-stack);
    font-size: 11.5px;
    font-weight: 650;
    letter-spacing: 0.1em;
    color: var(--fg-3);
    cursor: pointer;
    transition: color 0.16s var(--ease), border-color 0.16s var(--ease);
}
.pond-tab:hover { color: var(--fg-2); }
.pond-tab:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
.pond-tab.is-active { color: var(--gold); border-bottom-color: var(--gold); }

.pond-map-frame {
    border: 1px solid var(--rule);
    border-radius: 0;
    overflow: hidden;
    box-shadow: none;
}

.pond-map { display: block; width: 100%; height: auto; }

.atlas-meta text {
    font-size: 9px;
    fill: var(--gold);
    font-family: var(--font-stack);
}

/* 夜间水体：单色浅墨平涂（弃渐变）。不挂主题前缀 = 同时覆盖「无 data-theme 的无 JS 兜底态」，
   否则该态会回落到 HTML 内置 v2 蓝渐变，破坏单色纪律；日间由 §12 更高特异性覆写为纸蓝灰 */
#pondWater stop:nth-child(1) { stop-color: #181c25; }
#pondWater stop:nth-child(2) { stop-color: #151920; }
#pondWater stop:nth-child(3) { stop-color: #12151c; }
#reedDike rect { fill: #0b0d11; }
#reedDike path { stroke: rgba(244, 244, 241, 0.10); }

.pond-node { cursor: pointer; outline: none; }
/* rx:0 覆写 JS 注入的 rx=12 圆角矩形，对齐 v3 直角几何（SVG2 几何属性，旧浏览器优雅降级保留圆角） */
.pond-node .pond-body {
    rx: 0;
    fill: url(#pondWater);
    stroke: var(--rule);
    stroke-width: 1;
    transition: stroke 0.16s var(--ease), stroke-width 0.16s var(--ease);
}
.pond-node:hover .pond-body,
.pond-node:focus-visible .pond-body { stroke: var(--fg-2); }

/* 选中态：单一金色粗描边（全图唯一金色线，湖金纪律） */
.pond-node.is-active .pond-body {
    stroke: var(--gold);
    stroke-width: 2;
    filter: none;
}

/* 键盘焦点保底指示：is-active 的金描边在源序上压过 hover 变色（选中态身份优先），
   focus-visible 以「浅墨+加粗描边」保底，保证键盘焦点在任何节点（含已选中）都可感知 */
.pond-node:focus-visible .pond-body {
    stroke: var(--fg-2);
    stroke-width: 2;
}

.pond-sheen { fill: none; }

.pond-id {
    font-size: 19px;
    font-weight: 800;
    fill: var(--fg);
    text-anchor: middle;
    font-family: var(--font-stack);
    letter-spacing: 0.05em;
}
.pond-zone {
    font-size: 12px;
    fill: var(--fg-2);
    text-anchor: middle;
    font-family: var(--font-stack);
    letter-spacing: 0.04em;
}
/* 塘口数值：单色阶（金色纪律：只给选中描边与索引号） */
.pond-metric {
    font-size: 13px;
    fill: var(--fg-2);
    text-anchor: middle;
    font-variant-numeric: tabular-nums;
    font-family: var(--font-stack);
}

/* 密铺档位字号（档位类由 screen.js paintPondMap 按行数挂到 svg 根）：
   compact（10-18 口，4-6 行）压字号保「编号+区位」两行；mini（≥19 口，≥7 行）只留编号单行。
   viewBox 480 实测渲染约 1:1（2026-09-19 由塘口 rect 屏显 156px/内部 153px 实测），
   字号上限以单元格宽约束：区位名截断 10 字 × 12px ≈ 132px < 153px 格宽 */
.pond-map--compact .pond-id { font-size: 12px; }
.pond-map--compact .pond-zone { font-size: 10px; }
.pond-map--mini .pond-id { font-size: 12px; letter-spacing: 0.03em; }

/* 塘口检视面板（规格单：发丝行规线 + 20px 英雄数值，无底色） */
.pond-inspector {
    border: 0;
    border-top: 1px solid var(--rule);
    border-radius: 0;
    background: transparent;
    padding: 12px 0 0;
}

.pond-inspector-kicker {
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.3em;
    text-transform: uppercase;
    color: var(--gold);
}

.pond-inspector-title {
    margin-top: 5px;
    font-size: 17px;
    font-weight: 800;
    color: var(--fg);
    letter-spacing: 0.03em;
}

.pond-inspector-metrics {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0;
    margin-top: 12px;
    border-top: 1px solid var(--rule-soft);
}
.pond-inspector-metrics div:last-child { grid-column: 1 / -1; }
/* 规格单行：每格底部发丝线，行距靠 padding（末行以容器下缘视觉收口由 note 分隔） */
.pond-inspector-metrics div { padding: 8px 0 7px; border-bottom: 1px solid var(--rule-soft); }

.pond-inspector-metrics dt { font-size: 10px; color: var(--fg-3); letter-spacing: 0.1em; }
.pond-inspector-metrics dd {
    font-size: 20px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
    color: var(--fg);
    margin-top: 3px;
}

.pond-data-note {
    margin-top: 10px;
    padding-top: 0;
    border-top: 0;
    font-size: 10.5px;
    color: var(--fg-3);
    letter-spacing: 0.03em;
}

/* ------------------------------ 9. 水质四联指标（发丝十字分格） ------------------------------ */
.iot-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    border: 0;
    border-radius: 0;
    background: transparent;
    overflow: visible;
}

.iot-cell {
    border: 0;
    border-radius: 0;
    background: transparent;
    padding: 11px 13px;
    min-width: 0;
}
/* 发丝十字分格：奇数格右缘、前两格下缘 */
.iot-cell:nth-child(odd) { border-right: 1px solid var(--rule-soft); }
.iot-cell:nth-child(-n+2) { border-bottom: 1px solid var(--rule-soft); }

.iot-cell-label {
    font-size: 10px;
    color: var(--fg-3);
    letter-spacing: 0.1em;
}

.iot-cell-val {
    margin-top: 5px;
    font-size: 24px;
    font-weight: 800;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.01em;
    color: var(--fg);
    /* 与 .kpi-value 同等溢出防护：数值容器恒为单行，异常长值省略号兜底不撑破分格 */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.iot-cell-unit {
    margin-left: 4px;
    font-size: 10.5px;
    font-weight: 500;
    color: var(--fg-3);
}

.env-chart { height: 176px; margin-top: 14px; }

/* ------------------------------ 10. 批次流水、资质公示与说明（清单式） ------------------------------ */
.batch-scroll-wrap {
    max-height: 392px;
    overflow-y: auto;
    padding-right: 2px;
    scrollbar-width: thin;
    scrollbar-color: rgba(124, 129, 140, 0.4) transparent;
}
.batch-scroll-wrap::-webkit-scrollbar { width: 5px; }
.batch-scroll-wrap::-webkit-scrollbar-thumb { background: rgba(124, 129, 140, 0.4); border-radius: 0; }

.batch-feed-list { display: flex; flex-direction: column; }
/* 空态收敛：JS 对空批次/空资质是 textContent 直写容器（text 节点继承此处），
   子组件均有显式样式不受影响——零 JS 改动让空态文字与 .timeline-empty 同层级 */
.batch-feed-list,
#certListWrap { font-size: 12px; color: var(--fg-3); padding: 6px 0; }

/* 清单式批次行：无卡片盒，行间发丝线，hover 金色编号 */
.batch-card-mini {
    border: 0;
    border-bottom: 1px solid var(--rule-soft);
    border-radius: 0;
    background: transparent;
    padding: 10px 2px;
    cursor: pointer;
    transition: none;
}
/* hover 反馈 = 编号转金（清单式的克制反馈；边线/底色 hover 在 v3 全透明基座上无从谈起） */
.batch-card-mini:hover .mini-batch-no { color: var(--gold); }
/* 焦点环必须内嵌（offset 负值）：outline 属 ink overflow 不进滚动区域，
   正偏移会被 .batch-scroll-wrap(overflow:auto，左/上 padding 为 0) 裁到不可见 */
.batch-card-mini:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }

.mini-row-1 { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; }

/* text-overflow 仅对块容器行内内容生效：inline-flex 下批次号溢出会被硬裁无省略号，
   故用 block 容器；徽标图标以 CSS 隐藏（清单式去装饰，DOM 由 JS 注入不可删）；
   min-width:0 必须保留——本元素是 .mini-row-1 的 flex item，缺省 min-width:auto 会拒收缩 */
.mini-batch-no {
    display: block;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 12.5px;
    font-weight: 750;
    color: var(--fg);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.03em;
}
.mini-batch-no .ic { display: none; }

.mini-tag {
    font-size: 9.5px;
    padding: 2px 7px;
    border-radius: 0;
    color: var(--fg-2);
    background: transparent;
    border: 1px solid var(--rule);
    white-space: nowrap;
    flex: none;
    letter-spacing: 0.06em;
    /* 超长 status 防破版（同 .tag） */
    max-width: 60%;
    overflow: hidden;
}

.mini-row-2 {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 5px;
    font-size: 10.5px;
    color: var(--fg-3);
    font-variant-numeric: tabular-nums;
}

@keyframes rise {
    from { opacity: 0; transform: translateY(4px); }
    to { opacity: 1; transform: none; }
}

.batch-card-mini,
.cert-slide-box { animation: rise 0.3s var(--ease) backwards; }

/* 资质公示（同为清单式） */
#certListWrap { display: flex; flex-direction: column; }

.cert-slide-box {
    border: 0;
    border-bottom: 1px solid var(--rule-soft);
    border-radius: 0;
    background: transparent;
    padding: 10px 2px;
}

.cert-badge-tag {
    display: inline-block;
    font-size: 9.5px;
    font-weight: 650;
    letter-spacing: 0.1em;
    padding: 1px 6px;
    border-radius: 0;
    color: var(--ok);
    background: transparent;
    border: 1px solid var(--rule);
}

.cert-title { margin-top: 6px; font-size: 12.5px; font-weight: 700; color: var(--fg); letter-spacing: 0.03em; }
.cert-meta { margin-top: 3px; font-size: 10.5px; color: var(--fg-3); font-variant-numeric: tabular-nums; }

/* 说明框：瑞士线框体，无色底 */
.service-note-box {
    display: flex;
    gap: 8px;
    align-items: flex-start;
    margin-top: 14px;
    border: 1px solid var(--rule);
    background: transparent;
    border-radius: 0;
    padding: 10px 12px;
    font-size: 11px;
    line-height: 1.65;
    color: var(--fg-2);
}
.service-note-box .ic { color: var(--gold); margin-top: 2px; }
.service-note-box b { color: var(--fg); }

/* ------------------------------ 11. 底部状态栏 ------------------------------ */
.screen-footer {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 12px;
    padding: 13px 24px 15px;
    font-size: 10.5px;
    color: var(--fg-3);
    letter-spacing: 0.05em;
    border-top: 1px solid var(--rule-soft);
}

.footer-sep { width: 1px; height: 10px; background: var(--rule); }

/* ------------------------------ 12. 日间主题（纸白 · 油墨） ------------------------------ */
/* 瑞士纸面：暖白纸底 + 近黑油墨；token 整体反转，组件规则只消费 token */
:root[data-theme='light'] {
    color-scheme: light;

    --bg: #fafaf7;
    --fg: #14151a;
    --fg-2: #454852;
    --fg-3: #676a73;
    --rule: rgba(20, 21, 26, 0.18);
    --rule-soft: rgba(20, 21, 26, 0.09);
    --rule-strong: rgba(20, 21, 26, 0.85);
    --gold: #8a6114;
    --gold-dim: rgba(138, 97, 20, 0.75);
    --ok: #0a7a6c;
}

/* 画布即纸面（纯平，无光斑无点阵）：基座 body/.screen-header 直接消费 var(--bg)，
   随本 token 块自动反转，无需日间特判；theme-color 四处同步点的 CSS 侧即此 --bg */

/* 方章完成态由基座 .step-node.completed(0,2,0) 直接生效：其消费的 --fg/--bg token 随主题
   自动反转，日间无需 (0,4,0) 特判（此处曾有的特判与 :root[data-theme='light'] .step-node
   纸底规则配对，v3.0.1 审查确认冗余后一并删除）；:has() 轨道段同理消费 --rule-strong */

/* 塘口水色：日间浅纸蓝灰单色平涂（SVG 渐变 stop 的 stop-color 可被 CSS 覆盖） */
:root[data-theme='light'] #pondWater stop:nth-child(1) { stop-color: #eef1f5; }
:root[data-theme='light'] #pondWater stop:nth-child(2) { stop-color: #e9edf2; }
:root[data-theme='light'] #pondWater stop:nth-child(3) { stop-color: #e4e9ee; }
:root[data-theme='light'] #reedDike rect { fill: var(--bg); }
:root[data-theme='light'] #reedDike path { stroke: rgba(20, 21, 26, 0.10); }
:root[data-theme='light'] .pond-node .pond-body { stroke: rgba(20, 21, 26, 0.26); }
/* 日间空闲描边特异性(0,4,0)会压过基座 hover/focus-visible(0,3,0)，必须显式补回：
   塘口节点 outline:none，focus-visible 描边是键盘焦点的唯一指示 */
:root[data-theme='light'] .pond-node:hover .pond-body,
:root[data-theme='light'] .pond-node:focus-visible .pond-body { stroke: var(--fg-2); }
:root[data-theme='light'] .pond-node.is-active .pond-body {
    stroke: var(--gold);
}
/* 与夜间同构：日间 is-active(0,5,0) 同样压过 focus 变色，focus-visible 需显式保底 */
:root[data-theme='light'] .pond-node:focus-visible .pond-body {
    stroke: var(--fg-2);
    stroke-width: 2;
}

/* 日间 SVG 金字与指北针箭头：--gold 已随主题反转为压深值 #8a6114（纸底实算 5.28:1 达 AA）。
   polygon 是 HTML 内联 fill="#e0a84f" 的三角箭头，若漏覆写会在纸底上色裂成亮橙（v2 回归教训） */
:root[data-theme='light'] .atlas-meta text { fill: var(--gold); }
:root[data-theme='light'] .atlas-meta polygon { fill: var(--gold); }

:root[data-theme='light'] .batch-scroll-wrap { scrollbar-color: rgba(20, 21, 26, 0.3) transparent; }
:root[data-theme='light'] .batch-scroll-wrap::-webkit-scrollbar-thumb { background: rgba(20, 21, 26, 0.3); }

/* ------------------------------ 13. 主题切换控件与过渡 ------------------------------ */
/* 单图标切换按钮：日间显示太阳、夜间显示月亮，点击在日/夜间翻转（图标显隐由 data-theme 驱动） */
.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 30px;
    padding: 0;
    border: 1px solid var(--rule-strong);
    border-radius: 0;
    background: transparent;
    color: var(--fg-2);
    cursor: pointer;
    transition: color 0.18s var(--ease), border-color 0.18s var(--ease);
}
.theme-toggle:hover { color: var(--fg); border-color: var(--gold); }
.theme-toggle:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* 图标跟随主题：日间太阳 / 夜间月亮（两枚 SVG 并存，按 data-theme 切换显隐） */
.theme-toggle .theme-ic-dark { display: none; }
/* 无 JS 时 html 无 data-theme 属性：token 已按夜间缺省渲染，月亮图标须同步兜底，
   否则出现「夜间画面+太阳图标」矛盾（追加规则，不改动下方被测试锁定的两条精确子串） */
:root:not([data-theme]) .theme-toggle .theme-ic-dark { display: block; }
:root:not([data-theme]) .theme-toggle .theme-ic-light { display: none; }
:root[data-theme='dark'] .theme-toggle .theme-ic-dark { display: block; }
:root[data-theme='dark'] .theme-toggle .theme-ic-light { display: none; }

/* 主题切换瞬间的柔和过渡（由 JS 仅在切换时挂载，避免常驻开销） */
html.theme-transition,
html.theme-transition *,
html.theme-transition *::before,
html.theme-transition *::after {
    transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease,
        fill 0.3s ease, stroke 0.3s ease, box-shadow 0.3s ease !important;
}

/* 减弱动效偏好下，过渡类同样被压制（选择器与 .theme-transition 同特异性，确保可覆盖） */
@media (prefers-reduced-motion: reduce) {
    html.theme-transition,
    html.theme-transition *,
    html.theme-transition *::before,
    html.theme-transition *::after {
        transition: none !important;
    }
}

/* ------------------------------ 14. 响应式与可达性 ------------------------------ */
@media (max-width: 1920px) {
    /* 1721–1920 常见宽度防截断：36px 的「8,973.4 / 95.67%」在该区间 1fr 格内会触发省略号。
       30px/21px 经 1730px 实测验证（该宽度是 6.4fr 分格的最窄工况） */
    .kpi-value { font-size: 30px; }
    .kpi-value.kpi-value-sm { font-size: 21px; }
}

@media (max-width: 1720px) {
    .screen-main { grid-template-columns: 318px minmax(0, 1fr) 336px; padding: 0 16px 6px; }
    /* KPI 排版台降为 3×2：第二行补上缘分隔，行首格去左缘 */
    .center-kpi-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .kpi-card:nth-child(3n+1) { border-left: 0; }
    .kpi-card:nth-child(n+4) { border-top: 1px solid var(--rule-soft); }
    .kpi-value { font-size: 31px; }
    /* 双数值卡（公母比）不参与同幅放大：媒体查询内 .kpi-value(0,1,0) 源序靠后会压过
       基座的 .kpi-value-sm(0,1,0)，须用 (0,2,0) 显式保住「次级数值」层级，
       同时保住 §5 排版台第 2 列 1.4fr 加宽的设计依据（按双数值定制） */
    .kpi-value.kpi-value-sm { font-size: 22px; }
    .ratio-chart { height: 200px; }
}

@media (max-width: 1380px) {
    .screen-header { grid-template-columns: auto 1fr; }
    .header-center-title { display: none; }
    .screen-main { grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr); }
    /* (0,2,0) 与基座 .screen-column + .screen-column 同特异性、源序靠后获胜：
       裸 .screen-column-right(0,1,0) 压不掉基座竖规线，981-1380 全宽行会拖幽灵竖线 */
    .screen-column.screen-column-right {
        grid-column: 1 / -1;
        border-left: 0;
        padding-left: 0;
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 30px;
        align-items: start;
    }
    /* 3 等分格下公母比 15 字形（22px 需 ~198px > 格内 ~182px）会触发省略号 */
    .kpi-value.kpi-value-sm { font-size: 19px; }
}

@media (max-width: 980px) {
    .screen-header { grid-template-columns: 1fr; justify-items: start; row-gap: 12px; }
    .header-controls { justify-content: flex-start; padding-left: 0; }
    .screen-main { grid-template-columns: minmax(0, 1fr); }
    /* 三栏纵向堆叠后解除报纸竖规线，否则中栏左缘拖一条全高「幽灵竖线」 */
    .screen-column + .screen-column { border-left: 0; }
    .screen-column-left { padding-right: 0; }
    .screen-column-center { padding-left: 0; padding-right: 0; }
    /* 1380 档已升为 (0,2,0)，裸 (0,1,0) 会被其 repeat(2) 压掉，窄屏无法收回单列；
       「断点选择器升级必须成对」——本规则与 1380 档 .screen-column.screen-column-right 同步维护 */
    .screen-column.screen-column-right { grid-template-columns: minmax(0, 1fr); }
    /* KPI 降为 2 列：清空 3 列断言再按 2 列补线。
       注意 1720 档的 .kpi-card:nth-child(3n+1)(0,2,0) 在 ≤980 时仍命中第 4 格，
       特异性高于下方 .kpi-card(0,1,0) 的整体重置，必须用同特异性(0,2,0)的偶数格规则显式回补，
       否则 2 列布局下第 2 行行尾格（第 4 格）缺失竖向发丝分隔线 */
    .center-kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .kpi-card { border-left: 1px solid var(--rule-soft); border-top: 0; }
    .kpi-card:nth-child(2n+1) { border-left: 0; }
    .kpi-card:nth-child(2n) { border-left: 1px solid var(--rule-soft); }
    .kpi-card:nth-child(n+3) { border-top: 1px solid var(--rule-soft); }
    .kpi-value { font-size: 28px; }
    .kpi-value.kpi-value-sm { font-size: 21px; }
    .center-bottom-grid { grid-template-columns: minmax(0, 1fr); }
    .timeline-bar { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 18px; }
    .timeline-step:nth-child(3)::before { display: none; }
}

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