/* =====================================================================
   RiskDeck · 园艺账本「玻璃展柜」设计语言(自 CBRO 监控台 v2 移植)
   设计令牌与签名元素原样搬运;布局适配现有 SPA(展柜深绿侧边栏 + 多视图)。
   结构:F 字体 → 0 令牌 → 1 基底 → 2 布局(侧边栏/顶栏) → 3 chips 与 pill
        → 4 控件 → 5 面板解剖与卡片 → 6 KPI → 7 图表容器与骨架 → 8 表格
        → 9 徽章 → 10 toast → 11 表单与账户卡 → 12 空态/杂项 → 13 状态页
        → 14 玻璃与流光(@supports 渐进增强) → 15 动效与可达性 → 16 响应式
   ===================================================================== */

/* ---------- F. 自托管字体(零 CDN;url 相对 /static/styles.css) ---------- */
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 500 700;
  font-display: swap;
  src: url(vendor/fonts/Fraunces-500-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(vendor/fonts/IBMPlexMono-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(vendor/fonts/IBMPlexMono-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(vendor/fonts/IBMPlexMono-600-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* IBM Plex Sans 为可变字体(wght 100-700),单文件声明 400-600 区间即可
   (评审缺陷9:此前 400/500/600 三条规则指向三个字节相同的副本,浪费 ~91KB) */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400 600;
  font-stretch: 100%;
  font-display: swap;
  src: url(vendor/fonts/IBMPlexSans-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- 0. 设计令牌(单一来源,自参照 §0 原样搬运) ---------- */
:root{
  /* 纸面三层 */
  --paper-0:#f7f6f0;            /* 页面底 */
  --paper-1:#fcfbf7;            /* 卡片 / 面板 */
  --paper-2:#efeee5;            /* 内嵌(输入框、轨道、表头悬停) */

  /* 墨色四档 */
  --ink-900:#1f2b26;            /* 标题与数据主体 */
  --ink-700:#415047;            /* 正文 */
  --ink-500:#5c6b62;            /* 说明 */
  --ink-400:#8a988e;            /* 眉头 / 占位 / 轴标 */

  /* 方向轴:多 / 正 / 正相关 = 韭葱绿;空 / 负 / 负相关 = 陶土 */
  --direction-long:#2f6b4f;
  --direction-long-deep:#1e4a36;
  --direction-long-soft:#e4efe8;
  --direction-short:#b8593f;
  --direction-short-deep:#8f3f2c;
  --direction-short-soft:#f6e3dc;

  /* 健康轴:正常 / 注意 / 异常(与方向轴永不混用) */
  --status-ok:#2e8757;          --status-ok-soft:#e2f0e7;
  --status-warn:#a87b2f;        --status-warn-soft:#f4ebd7;
  --status-bad:#b02a30;         --status-bad-soft:#f8dfde;

  /* 展柜(整页唯一允许「重」的元素 —— 本应用用作左侧边栏) */
  --vitrine:#16322a;
  --vitrine-deep:#0f241e;
  --vitrine-line:rgba(247,246,240,.16);
  --vitrine-text:#eef0e8;

  /* 玻璃材质(iOS 系感):重模糊 + 高饱和透光 + 顶缘高光 + 柔影 */
  --glass-blur-bar:36px;
  --glass-blur-panel:26px;
  --glass-blur-soft:18px;
  --glass-saturation:1.8;
  --glass-fill-panel:rgba(252,251,247,.58);
  --glass-fill-card:rgba(252,251,247,.46);
  --glass-fill-bar:rgba(247,246,240,.42);
  --glass-fill-popover:rgba(252,251,247,.64);
  --glass-rim:rgba(255,255,255,.62);
  --glass-edge:rgba(255,255,255,.40);
  --glass-shadow:0 12px 32px rgba(22,50,42,.10), 0 2px 8px rgba(22,50,42,.06);

  /* 细线 */
  --line-1:#d9d5c7;             /* 结构细线 */
  --line-0:#e8e6da;             /* 内部更轻的细线 / 方格纸 */

  /* 空间节奏(4px 基数) */
  --space-1:4px; --space-2:8px; --space-3:12px; --space-4:16px;
  --space-5:24px; --space-6:32px; --space-7:48px;

  /* 时间节奏(单一缓动族) */
  --easing-calm:cubic-bezier(.22,1,.36,1);
  --duration-fast:160ms; --duration-base:260ms; --duration-slow:480ms;

  /* 海拔三级 */
  --shadow-rest:0 1px 2px rgba(31,43,38,.05);
  --shadow-raise:0 10px 28px -18px rgba(31,43,38,.30), 0 1px 2px rgba(31,43,38,.05);
  --shadow-overlay:0 18px 44px -20px rgba(31,43,38,.45);

  /* 字体三役 */
  --font-display:"Fraunces","Songti SC","SimSun",Georgia,serif;
  --font-interface:"IBM Plex Sans",-apple-system,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;
  --font-data:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;

  /* 字号阶 */
  --text-eyebrow:10.5px; --text-caption:12px; --text-body:13px;
  --text-subhead:15px;   --text-title:18px;   --text-display:26px;

  /* 圆角刻度 */
  --radius-1:6px; --radius-2:10px; --radius-3:14px;

  /* 布局 */
  --sidebar-w:208px;
}

/* ---------- 1. 基底 ---------- */
*,*::before,*::after{box-sizing:border-box}
html{background:var(--paper-0)}
body{
  margin:0; min-height:100vh;
  color:var(--ink-700);
  font-family:var(--font-interface);
  font-size:var(--text-body); line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4,p{margin:0}

/* 方格纸覆层:盖在流体之上、内容之下 */
body::after{
  content:""; position:fixed; inset:0; z-index:0; pointer-events:none;
  background-image:
    repeating-linear-gradient(to right, var(--line-0) 0 1px, transparent 1px 24px),
    repeating-linear-gradient(to bottom, var(--line-0) 0 1px, transparent 1px 24px);
  opacity:.55;
}
#fluid_background_canvas{
  position:fixed; inset:0; z-index:0; width:100%; height:100%;
  pointer-events:none;
}
.watermark{
  position:fixed; right:18px; bottom:14px; z-index:0; width:120px;
  opacity:.06; pointer-events:none; filter:grayscale(35%);
}
#app,#toasts,#progressbar{position:relative; z-index:1}

::selection{background:var(--direction-long-soft)}
a{color:var(--direction-long); text-decoration:none}
a:hover{text-decoration:underline}
kbd{
  font-family:var(--font-data); font-size:11px; padding:1px 5px;
  border:1px solid var(--line-1); border-bottom-width:2px;
  border-radius:4px; background:var(--paper-1); color:var(--ink-700);
}

/* 文字语义工具类:
   pos/neg = 方向轴(多绿 / 空陶土);ok/warn/bad = 健康轴;dim = 弱化 */
.pos{color:var(--direction-long)}  .neg{color:var(--direction-short)}
.ok{color:var(--status-ok)}        .warn{color:var(--status-warn)}
.bad{color:var(--status-bad)}      .dim{color:var(--ink-400)}
.muted{color:var(--ink-500)}       .gold{color:var(--status-warn)}
.small{font-size:var(--text-caption)}
.tiny{font-size:11px}
.right{text-align:right} .center{text-align:center} .left{text-align:left}
.mono{font-family:var(--font-data)}
.hidden{display:none !important}
.num{font-family:var(--font-data); font-variant-numeric:tabular-nums}
.spacer{flex:1}

:focus-visible{outline:2px solid var(--direction-long); outline-offset:2px; border-radius:2px}

/* 细滚动条(信息密度面板里大量滚动区) */
*{scrollbar-width:thin; scrollbar-color:var(--line-1) transparent}
*::-webkit-scrollbar{width:8px; height:8px}
*::-webkit-scrollbar-thumb{background:var(--line-1); border-radius:8px}
*::-webkit-scrollbar-track{background:transparent}

/* ---------- 2. 布局:展柜深绿侧边栏 + 玻璃顶栏 ---------- */
#app{display:flex; min-height:100vh}

/* 侧边栏 = 全页唯一深色重物(展柜纪律) */
#sidebar{
  width:var(--sidebar-w); flex:0 0 var(--sidebar-w);
  display:flex; flex-direction:column;
  position:sticky; top:0; height:100vh;
  background:
    radial-gradient(120% 60% at 50% 0%, rgba(76,138,104,.18), transparent 60%),
    linear-gradient(180deg, var(--vitrine), var(--vitrine-deep));
  border-right:1px solid var(--vitrine-deep);
  box-shadow:inset -1px 0 0 rgba(247,246,240,.06);
  color:var(--vitrine-text);
}
.brand{
  display:flex; align-items:center; gap:var(--space-3);
  padding:18px 16px 16px;
  border-bottom:1px solid var(--vitrine-line);
}
.brand img{width:34px; height:34px; border-radius:8px; flex:none}
.brand-word{
  font-family:var(--font-display); font-weight:600; font-size:19px;
  letter-spacing:.04em; color:var(--vitrine-text); line-height:1.05;
}
.brand-word small{
  display:block; font-family:var(--font-interface); font-weight:500;
  font-size:var(--text-eyebrow); letter-spacing:.14em;
  color:rgba(238,240,232,.55); text-transform:uppercase; margin-top:2px;
}
#nav{flex:1; padding:12px 10px; display:flex; flex-direction:column; gap:2px}
#nav a,.sidebar-bottom a{
  display:flex; align-items:center; gap:10px;
  padding:9px 12px; border-radius:var(--radius-1);
  color:rgba(238,240,232,.72); font-size:13px; font-weight:500;
  text-decoration:none;
  transition:background var(--duration-fast) var(--easing-calm),
             color var(--duration-fast) var(--easing-calm),
             box-shadow var(--duration-fast) var(--easing-calm);
}
#nav a:hover,.sidebar-bottom a:hover{
  background:rgba(247,246,240,.08); color:var(--vitrine-text); text-decoration:none;
}
#nav a.active,.sidebar-bottom a.active{
  background:rgba(228,239,232,.14);
  color:#fff;
  box-shadow:inset 3px 0 0 var(--direction-long-soft);
}
.ico{width:16px; height:16px; flex:0 0 16px}
.sidebar-bottom{padding:10px; border-top:1px solid var(--vitrine-line)}

#main{flex:1; min-width:0; display:flex; flex-direction:column}

/* 顶栏 → 玻璃细栏(基础实底,玻璃在 §14 渐进增强) */
#topbar{
  position:sticky; top:0; z-index:30;
  display:flex; align-items:center; justify-content:space-between;
  gap:var(--space-4); flex-wrap:wrap;
  min-height:52px; padding:var(--space-2) var(--space-5);
  background:rgba(252,251,247,.84);
  backdrop-filter:blur(10px) saturate(1.1);
  -webkit-backdrop-filter:blur(10px) saturate(1.1);
  border-bottom:1px solid var(--line-1);
}
.topbar-right{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap}
.poll-label{color:var(--ink-400); font-size:var(--text-caption)}
#clock{
  font-family:var(--font-data); font-size:var(--text-caption);
  color:var(--ink-500); white-space:nowrap;
}
#last-update{font-family:var(--font-data); white-space:nowrap}

/* 顶栏刷新发丝进度线:
   #progressbar = 现行 app.js 使用的请求指示(fixed 顶缘发丝);
   #refresh_progress_track/bar = Wave-2 轮询倒计时接线位。 */
#progressbar{
  position:fixed; top:0; left:0; right:0; height:2px;
  z-index:40; pointer-events:none;
  opacity:0; transition:opacity var(--duration-base) var(--easing-calm);
}
#progressbar.active{opacity:1}
#progressbar .bar{
  height:100%; width:40%;
  background:linear-gradient(90deg, transparent, var(--direction-long), var(--direction-long-deep), transparent);
  animation:progress_slide 1.1s linear infinite;
}
@keyframes progress_slide{
  0%{transform:translateX(-100%)}
  100%{transform:translateX(350%)}
}
#refresh_progress_track{
  position:absolute; left:0; right:0; bottom:-1px; height:2px;
  background:transparent; pointer-events:none;
}
#refresh_progress_bar{
  display:block; height:100%; width:0;
  background:linear-gradient(to right, var(--direction-long), var(--direction-long-deep));
  opacity:.85;
}

/* ---------- 3. chips(账户多选)与 pill(状态徽章) ---------- */
.chips{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap; min-height:28px}
.chip{
  display:inline-flex; align-items:center; gap:6px;
  padding:4px 10px; border:1px solid var(--line-1); border-radius:999px;
  background:var(--paper-1); box-shadow:var(--shadow-rest);
  font-family:var(--font-data); font-size:11.5px; color:var(--ink-500);
  white-space:nowrap; cursor:pointer; user-select:none;
  transition:border-color var(--duration-fast) var(--easing-calm),
             color var(--duration-fast) var(--easing-calm),
             background var(--duration-fast) var(--easing-calm);
}
.chip:hover{border-color:var(--direction-long); color:var(--ink-900)}
.chip.on{
  background:var(--direction-long-soft); border-color:var(--direction-long);
  color:var(--direction-long-deep); font-weight:500;
}
.chip .chip-dot,.chip .dot,.chip-dot{
  width:7px; height:7px; border-radius:50%; flex:none; background:var(--ink-400);
}
.chip-all{border-style:dashed; background:transparent}
.chips-empty{color:var(--ink-500); font-size:12.5px}
.dot.ok,.chip-dot.ok{background:var(--status-ok)}
.dot.warn,.chip-dot.warn{background:var(--status-warn)}
.dot.bad,.chip-dot.bad{background:var(--status-bad)}

.pill{
  display:inline-flex; align-items:center; gap:6px;
  padding:4px 10px; border:1px solid var(--line-1); border-radius:999px;
  background:var(--paper-1); box-shadow:var(--shadow-rest);
  font-family:var(--font-data); font-size:11.5px; color:var(--ink-700);
  font-variant-numeric:tabular-nums; white-space:nowrap;
}
.pill .dot{width:7px; height:7px; border-radius:50%; background:var(--ink-400); flex:none}
.pill.ok{border-color:var(--status-ok); background:var(--status-ok-soft); color:var(--status-ok)}
.pill.ok .dot{background:var(--status-ok)}
.pill.warn{border-color:var(--status-warn); background:var(--status-warn-soft); color:#7c5a20}
.pill.warn .dot{background:var(--status-warn)}

/* agepill:数据年龄胶囊(Wave-2 接线位) */
.agepill{
  display:inline-block; min-width:52px; text-align:center;
  font-family:var(--font-data); font-size:11.5px; font-weight:500;
  border-radius:999px; padding:2px 8px;
}
.agepill.ok{background:var(--status-ok-soft); color:var(--status-ok)}
.agepill.warn{background:var(--status-warn-soft); color:#7c5a20}
.agepill.bad{background:var(--status-bad-soft); color:var(--status-bad)}

/* ---------- 4. 控件(ghost 按钮 / 分段切换 / 输入框 一种形态) ---------- */
.ghost-button,.segmented button,.btn,.range-btn{
  appearance:none; -webkit-appearance:none;
  display:inline-flex; align-items:center; gap:6px;
  font-family:var(--font-interface); font-size:var(--text-caption); font-weight:500;
  color:var(--ink-700); background:var(--paper-1);
  border:1px solid var(--line-1); border-radius:var(--radius-1);
  padding:5px 11px; cursor:pointer; line-height:1.3;
  transition:background var(--duration-fast) var(--easing-calm),
             border-color var(--duration-fast) var(--easing-calm),
             color var(--duration-fast) var(--easing-calm);
}
.ghost-button:hover,.segmented button:hover,.btn:hover{
  border-color:var(--direction-long); color:var(--direction-long-deep);
}
.ghost-button.selected{
  background:var(--direction-long-soft); border-color:var(--direction-long);
  color:var(--direction-long-deep);
}
.ghost-button.paused{
  background:var(--status-warn-soft); border-color:var(--status-warn); color:#7c5a20;
}
select.ghost-button{padding-right:8px}
.segmented{display:inline-flex; border-radius:var(--radius-1); overflow:hidden; border:1px solid var(--line-1)}
.segmented button{border:0; border-radius:0; background:var(--paper-1)}
.segmented button + button{border-left:1px solid var(--line-1)}
.segmented button.selected{
  background:var(--direction-long-soft); color:var(--direction-long-deep); font-weight:600;
}

/* 既有 .btn 家族 → ghost 形态映射 */
.btn:active{transform:scale(.97)}
.btn:disabled{opacity:.5; cursor:not-allowed}
.btn-primary{
  background:var(--direction-long); border-color:var(--direction-long-deep); color:var(--paper-1);
}
.btn-primary:hover{background:var(--direction-long-deep); color:var(--paper-1)}
.btn-danger{background:transparent; border-color:var(--status-bad); color:var(--status-bad)}
.btn-danger:hover{background:var(--status-bad-soft); border-color:var(--status-bad); color:var(--status-bad)}
.btn-ghost{background:transparent}
.btn-sm{padding:3px 10px; font-size:11.5px}
.btn .ico{width:13px; height:13px}
.btn.spinning .ico{animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}

/* 原生输入控件 → text-input 形态 */
.text-input,
select,input[type="text"],input[type="password"],input[type="number"],input[type="date"]{
  font-family:var(--font-data); font-size:var(--text-caption); color:var(--ink-900);
  background:var(--paper-2); border:1px solid var(--line-1); border-radius:var(--radius-1);
  padding:5px 10px;
  transition:border-color var(--duration-fast) var(--easing-calm),
             box-shadow var(--duration-fast) var(--easing-calm),
             background var(--duration-fast) var(--easing-calm);
}
.text-input{min-width:190px}
.text-input::placeholder,input::placeholder{color:var(--ink-400)}
.text-input:focus,select:focus,input:focus{
  outline:none; background:var(--paper-1);
  border-color:var(--direction-long); box-shadow:0 0 0 3px var(--direction-long-soft);
}
input[type="range"]{accent-color:var(--direction-long); background:transparent; border:none; padding:0}
input[type="range"]:focus{box-shadow:none}

.spinner{
  display:inline-block; width:13px; height:13px;
  border:2px solid rgba(31,43,38,.18); border-top-color:currentColor;
  border-radius:50%; animation:spin .7s linear infinite;
  vertical-align:-2px;
}

/* ---------- 5. 面板解剖(眉头 + 标题 + 说明 + 操作区 + 裁切角) ---------- */
#view-root{
  flex:1; width:100%; max-width:1640px; margin:0 auto;
  padding:var(--space-5) var(--space-5) var(--space-7);
}
.page-head{
  display:flex; align-items:baseline; gap:var(--space-3); flex-wrap:wrap;
  margin-bottom:var(--space-4);
}
.page-head h2{
  font-family:var(--font-display); font-weight:600; font-size:22px;
  color:var(--direction-long-deep); line-height:1.15;
}
.page-head .spacer{flex:1}

/* 网格布局 */
.grid{display:grid; gap:var(--space-4); margin-bottom:var(--space-4)}
.grid-2{display:grid; gap:var(--space-4); margin-bottom:var(--space-4); grid-template-columns:repeat(auto-fit,minmax(430px,1fr))}
.grid-3{display:grid; gap:var(--space-4); margin-bottom:var(--space-4); grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}

/* panel(Wave-2 视图重构采用)与 card(现行区块)共享纸面材质与裁切角 */
.panel,.card{
  position:relative; background:var(--paper-1);
  border:1px solid var(--line-1); border-radius:var(--radius-3);
  box-shadow:var(--shadow-rest);
  animation:panel_enter var(--duration-slow) var(--easing-calm) both;
}
.panel{padding:var(--space-5)}
.panel::before,.panel::after,
.card::before,.card::after{content:""; position:absolute; width:14px; height:14px; pointer-events:none}
.panel::before,.card::before{
  top:-5px; left:-5px;
  border-top:1.5px solid var(--direction-long); border-left:1.5px solid var(--direction-long);
  border-top-left-radius:8px;
}
.panel::after,.card::after{
  bottom:-5px; right:-5px;
  border-bottom:1.5px solid var(--direction-long); border-right:1.5px solid var(--direction-long);
  border-bottom-right-radius:8px;
}
@keyframes panel_enter{from{opacity:0; transform:translateY(10px)} to{opacity:1; transform:none}}

.panel-header{
  display:flex; align-items:flex-end; justify-content:space-between;
  gap:var(--space-4); flex-wrap:wrap; margin-bottom:var(--space-4);
}
.panel-heading-group{min-width:240px}
.panel-eyebrow{
  margin:0 0 3px; font-size:var(--text-eyebrow); font-weight:600;
  letter-spacing:.16em; text-transform:uppercase; color:var(--ink-400);
}
.panel-title{
  margin:0; font-family:var(--font-display); font-weight:600;
  font-size:var(--text-title); color:var(--direction-long-deep); line-height:1.15;
}
.panel-subtitle{margin:4px 0 0; font-size:var(--text-caption); color:var(--ink-500)}
.panel-actions{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap}
.panel-footnote{
  margin-top:var(--space-3); font-size:11.5px; color:var(--ink-400); line-height:1.7;
}
.panel-footnote.at-top{margin:0 0 var(--space-3)}

/* 现行 card 解剖:card-head ≈ panel-header,card-body 为内容区 */
.card-head{
  display:flex; align-items:center; gap:var(--space-3); flex-wrap:wrap;
  padding:var(--space-4) var(--space-4) var(--space-3);
  border-bottom:1px solid var(--line-0);
}
.card-head h3{
  font-family:var(--font-display); font-weight:600; font-size:16px;
  color:var(--direction-long-deep); line-height:1.2;
}
.card-sub{font-size:11.5px; color:var(--ink-500)}
.card-head .spacer{flex:1}
.card-body{padding:var(--space-4)}
.card-body.tight{padding:var(--space-2) var(--space-2)}
.card.full{grid-column:1 / -1}
.panel.full{grid-column:1 / -1}

/* ---------- 6. KPI 卡:Fraunces 大数字 + 大写小标签 ---------- */
.kpi-grid{
  display:grid; gap:var(--space-3); margin-bottom:var(--space-4);
  grid-template-columns:repeat(auto-fit,minmax(168px,1fr));
}
.kpi{
  background:var(--paper-1); border:1px solid var(--line-1);
  border-radius:var(--radius-2); box-shadow:var(--shadow-rest);
  padding:var(--space-3) var(--space-4) var(--space-2);
  transition:transform var(--duration-fast) var(--easing-calm),
             box-shadow var(--duration-fast) var(--easing-calm);
}
.kpi:hover{transform:translateY(-1px); box-shadow:var(--shadow-raise)}
.kpi-label{
  font-size:var(--text-eyebrow); font-weight:600; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-400);
  margin-bottom:3px; display:flex; align-items:center; gap:6px;
}
.kpi-value{
  font-family:var(--font-display); font-weight:600; font-size:var(--text-display);
  color:var(--ink-900); line-height:1.1; font-variant-numeric:tabular-nums;
  border-radius:4px;
}
.kpi-value.pos{color:var(--direction-long)} .kpi-value.neg{color:var(--direction-short)}
.kpi-value.ok{color:var(--status-ok)} .kpi-value.warn{color:var(--status-warn)}
.kpi-value.bad{color:var(--status-bad)}
.kpi-sub{font-size:11px; color:var(--ink-500); margin-top:2px; font-variant-numeric:tabular-nums}
.kpi-value.flash{animation:value_flash .7s var(--easing-calm)}
@keyframes value_flash{
  0%{background:var(--direction-long-soft)}
  100%{background:transparent}
}

/* ---------- 7. 图表容器与骨架 ---------- */
.chart{width:100%}
.chart-sm{height:240px}
.chart-md{height:300px}
.chart-lg{height:360px}
.chart-xl{height:430px}
.chart:empty{
  background:linear-gradient(100deg, var(--paper-2) 40%, var(--paper-1) 50%, var(--paper-2) 60%);
  background-size:200% 100%;
  animation:shimmer 1.4s infinite;
  border-radius:var(--radius-1);
}
.skeleton{
  border-radius:var(--radius-1);
  background:linear-gradient(100deg, var(--paper-2) 40%, var(--paper-1) 50%, var(--paper-2) 60%);
  background-size:200% 100%;
  animation:shimmer 1.4s infinite;
}
@keyframes shimmer{0%{background-position:130% 0} 100%{background-position:-70% 0}}
.skel-lines .skeleton{margin-bottom:var(--space-2)}

/* chart-box(Wave-2 图表分格接线位) */
.chart-grid{display:grid; grid-template-columns:1fr 1fr; gap:var(--space-4)}
.chart-box{
  background:var(--paper-2); border:1px solid var(--line-0);
  border-radius:var(--radius-2); padding:var(--space-3) var(--space-4) var(--space-4);
  overflow:hidden;
}
.chart-box-label{
  font-size:var(--text-eyebrow); font-weight:600; letter-spacing:.12em;
  text-transform:uppercase; color:var(--ink-400); margin-bottom:var(--space-3);
}
.chart-footnote{padding-top:var(--space-1); font-size:11px; color:var(--ink-400)}
.chart-wide{grid-column:1 / -1; position:relative; margin-top:var(--space-2)}

/* ---------- 8. 表格(账页 ledger 形态) ---------- */
.table-wrap{overflow-x:auto}
.scroll-y{max-height:380px; overflow-y:auto}
.tbl{width:100%; border-collapse:separate; border-spacing:0; font-size:12.5px; white-space:nowrap}
.tbl th{
  position:sticky; top:0; z-index:2; background:var(--paper-1);
  padding:8px 10px; text-align:right; white-space:nowrap;
  font-size:var(--text-eyebrow); font-weight:600; letter-spacing:.10em;
  text-transform:uppercase; color:var(--ink-400);
  border-bottom:1px solid var(--line-1);
  cursor:pointer; user-select:none;
}
.tbl th:hover{color:var(--direction-long)}
.tbl th.left,.tbl td.left{text-align:left}
.tbl th.center,.tbl td.center{text-align:center}
.tbl td{
  text-align:right; padding:7px 10px;
  border-bottom:1px solid var(--line-0);
  font-family:var(--font-data); font-variant-numeric:tabular-nums;
  color:var(--ink-900); font-size:12px;
}
.tbl tbody tr{transition:background var(--duration-fast) var(--easing-calm)}
.tbl tbody tr:hover{background:var(--paper-2)}
.tbl tbody tr:last-child td{border-bottom:none}

/* ledger-table(Wave-2 采用的参照原名) */
.table-scroll{max-height:620px; overflow:auto; border:1px solid var(--line-0); border-radius:var(--radius-1)}
.ledger-table{width:100%; border-collapse:separate; border-spacing:0; font-size:12.5px}
.ledger-table th{
  position:sticky; top:0; z-index:2; background:var(--paper-1);
  padding:8px 10px; text-align:left; white-space:nowrap;
  font-size:var(--text-eyebrow); font-weight:600; letter-spacing:.10em;
  text-transform:uppercase; color:var(--ink-400);
  border-bottom:1px solid var(--line-1);
}
.ledger-table th.numeric{text-align:right}
th.sortable{cursor:pointer; user-select:none}
th.sortable:hover{color:var(--direction-long)}
th .arrow{color:var(--direction-long)}
.ledger-table td{
  padding:7px 10px; border-bottom:1px solid var(--line-0);
  vertical-align:middle; white-space:nowrap;
}
.ledger-table td.num{font-family:var(--font-data); font-variant-numeric:tabular-nums; text-align:right}
tr.datarow{cursor:pointer; transition:background var(--duration-fast) var(--easing-calm)}
tr.datarow:hover{background:var(--paper-2)}
.row-ok{box-shadow:inset 3px 0 0 var(--status-ok)}
.row-warn{box-shadow:inset 3px 0 0 var(--status-warn)}
.row-bad{box-shadow:inset 3px 0 0 var(--status-bad)}
tr.flash{animation:row_flash var(--duration-base) var(--easing-calm)}
@keyframes row_flash{0%{background:var(--direction-long-soft)} 100%{background:transparent}}

.gran{
  display:inline-block; font-family:var(--font-data); font-size:11px;
  background:var(--paper-2); border:1px solid var(--line-0);
  border-radius:999px; padding:1px 8px; color:var(--ink-500);
}

/* lsbar:多空条(左空右多,中缝细线;流光见 §14) */
.lsbar{
  position:relative; display:inline-block; vertical-align:middle;
  width:64px; height:6px; margin-left:8px;
  background:var(--paper-2); border-radius:3px; overflow:hidden;
}
.lsbar::before{content:""; position:absolute; left:50%; top:0; bottom:0; width:1px; background:var(--line-1)}
.lsbar i{position:absolute; top:0; bottom:0; max-width:50%}
.lsbar .l{left:50%; background:var(--direction-long); border-radius:0 3px 3px 0}
.lsbar .s{right:50%; background:var(--direction-short); border-radius:3px 0 0 3px}

/* ---------- 9. 徽章(方向轴 / 健康轴 / 中性) ---------- */
.badge{
  display:inline-block; padding:1px 8px; border-radius:999px;
  font-size:11px; font-weight:600; line-height:1.6;
  border:1px solid transparent; font-family:var(--font-data);
}
.badge-long {color:var(--direction-long-deep); background:var(--direction-long-soft); border-color:var(--direction-long)}
.badge-short{color:var(--direction-short-deep); background:var(--direction-short-soft); border-color:var(--direction-short)}
.badge-ok   {color:var(--status-ok); background:var(--status-ok-soft); border-color:var(--status-ok)}
.badge-warn {color:#7c5a20; background:var(--status-warn-soft); border-color:var(--status-warn)}
.badge-danger{color:var(--status-bad); background:var(--status-bad-soft); border-color:var(--status-bad)}
.badge-pm   {color:var(--vitrine-text); background:var(--vitrine); border-color:var(--vitrine-deep)}
.badge-std  {color:var(--ink-700); background:var(--paper-2); border-color:var(--line-1)}
.badge-dim  {color:var(--ink-500); background:var(--paper-2); border-color:var(--line-0)}
.warn-liq{color:var(--status-bad); font-weight:700}

/* ---------- 10. toast(纸面卡片,左缘按健康轴着色) ---------- */
#toasts{
  position:fixed; right:18px; bottom:18px; z-index:2000;
  display:flex; flex-direction:column; gap:var(--space-2); max-width:380px;
}
.toast{
  display:flex; align-items:center; gap:10px;
  background:var(--paper-1); border:1px solid var(--line-1);
  border-left:3px solid var(--ink-400);
  border-radius:var(--radius-2); padding:10px 14px;
  font-size:var(--text-body); color:var(--ink-700);
  box-shadow:var(--shadow-overlay);
  animation:toast_in var(--duration-base) var(--easing-calm);
}
.toast.error{border-left-color:var(--status-bad)}
.toast.ok{border-left-color:var(--status-ok)}
.toast.out{opacity:0; transform:translateX(20px); transition:all var(--duration-base) var(--easing-calm)}
.toast button{
  background:transparent; border:1px solid var(--line-1); border-radius:5px;
  color:var(--direction-long); font-size:var(--text-caption); padding:2px 9px;
  cursor:pointer; flex:0 0 auto; font-family:var(--font-interface);
}
.toast button:hover{background:var(--direction-long-soft); border-color:var(--direction-long)}
.toast .toast-x{border:none; color:var(--ink-400); font-size:14px; padding:0 4px}
@keyframes toast_in{from{opacity:0; transform:translateY(10px)} to{opacity:1; transform:none}}

/* ---------- 11. 表单与账户卡 ---------- */
.acc-form{display:flex; flex-direction:column; gap:var(--space-3)}
.form-row{display:flex; flex-direction:column; gap:5px}
.form-row > label{
  font-size:var(--text-eyebrow); font-weight:600; letter-spacing:.08em;
  text-transform:uppercase; color:var(--ink-400);
}
.form-row input{width:100%; padding:7px 11px}
.form-actions{display:flex; align-items:center; gap:var(--space-3); flex-wrap:wrap}
.form-msg{font-size:12.5px; color:var(--ink-500)}
.form-msg.ok{color:var(--status-ok)}
.form-msg.err{color:var(--status-bad)}

.type-cards{display:grid; grid-template-columns:1fr 1fr; gap:var(--space-2)}
.type-card{position:relative; cursor:pointer}
.type-card input{position:absolute; opacity:0}
.type-card > div{
  border:1px solid var(--line-1); border-radius:var(--radius-1);
  background:var(--paper-2); padding:10px 13px;
  display:flex; flex-direction:column; gap:2px;
  transition:border-color var(--duration-fast) var(--easing-calm),
             background var(--duration-fast) var(--easing-calm);
}
.type-card > div b{font-size:var(--text-body); color:var(--ink-900)}
.type-card > div span{font-size:11px; color:var(--ink-500); font-family:var(--font-data)}
.type-card input:checked + div{
  border-color:var(--direction-long);
  background:var(--direction-long-soft);
  box-shadow:0 0 0 1px var(--direction-long) inset;
}
.type-card:hover > div{border-color:var(--direction-long)}

.acc-card{
  background:var(--paper-1); border:1px solid var(--line-1); border-radius:var(--radius-2);
  box-shadow:var(--shadow-rest);
  padding:15px 17px; display:flex; flex-direction:column; gap:9px;
  transition:transform var(--duration-fast) var(--easing-calm),
             box-shadow var(--duration-fast) var(--easing-calm);
}
.acc-card:hover{transform:translateY(-1px); box-shadow:var(--shadow-raise)}
.acc-card-head{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap}
.acc-card-head b{font-family:var(--font-display); font-weight:600; font-size:15px; color:var(--ink-900)}
.acc-dot{width:10px; height:10px; border-radius:50%; flex:0 0 10px}
.acc-kv{display:flex; align-items:center; justify-content:space-between; gap:10px; font-size:12.5px}
.acc-kv .k{color:var(--ink-500)}
.acc-kv .v{font-variant-numeric:tabular-nums}
.acc-kv .v.mono{font-family:var(--font-data); font-size:12px}
.acc-weight-edit{display:flex; align-items:center; gap:6px}
.acc-weight-edit input{width:72px; padding:3px 8px; font-size:12px}
.acc-actions{display:flex; gap:var(--space-2); margin-top:2px}
.acc-confirm{
  background:var(--status-bad-soft); border:1px solid var(--status-bad); border-radius:var(--radius-1);
  padding:10px 12px; display:flex; flex-direction:column; gap:var(--space-2); font-size:12.5px;
  color:var(--ink-700);
}
.acc-confirm input{padding:4px 9px; font-size:12.5px}
.acc-confirm .row{display:flex; gap:var(--space-2)}

/* ---------- 12. 空态 / 引导页 / 杂项 ---------- */
.empty-hero{
  max-width:720px; margin:6vh auto 0; text-align:center;
  display:flex; flex-direction:column; gap:18px; align-items:center;
}
.empty-hero .big-ico{
  width:74px; height:74px; border-radius:20px;
  background:var(--direction-long-soft);
  border:1px solid var(--line-1); box-shadow:var(--shadow-rest);
  display:flex; align-items:center; justify-content:center;
  font-size:34px;
}
.empty-hero h2{
  font-family:var(--font-display); font-weight:600; font-size:24px;
  color:var(--direction-long-deep);
}
.empty-hero p{color:var(--ink-500); max-width:540px}
.empty-steps{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr));
  gap:var(--space-3); width:100%; text-align:left;
}
.empty-step{
  background:var(--paper-1); border:1px solid var(--line-1); border-radius:var(--radius-2);
  box-shadow:var(--shadow-rest); padding:13px 15px;
}
.empty-step .n{
  display:inline-flex; width:22px; height:22px; border-radius:50%;
  background:var(--direction-long-soft); color:var(--direction-long-deep);
  align-items:center; justify-content:center;
  font-family:var(--font-data); font-size:12px; font-weight:700;
  margin-bottom:7px;
}
.empty-step b{display:block; font-size:var(--text-body); color:var(--ink-900); margin-bottom:3px}
.empty-step span{font-size:var(--text-caption); color:var(--ink-500)}
.empty-form-card{width:100%; max-width:560px; text-align:left}

.hint-box{
  border:1px dashed var(--line-1); border-radius:var(--radius-2);
  background:var(--paper-1);
  padding:26px; text-align:center; color:var(--ink-500); font-size:var(--text-body);
}

.sec-tips{display:flex; flex-direction:column; gap:9px; font-size:12.5px; color:var(--ink-500); margin:0; padding:0}
.sec-tips li{margin-left:18px}
.sec-tips b{color:var(--ink-900)}

/* movers 列表(方向条底色由 JS 内联,流光见 §14) */
.mover{
  display:grid; grid-template-columns:130px 1fr 72px; gap:10px;
  align-items:center; padding:5px 2px; font-size:12.5px;
  border-bottom:1px solid var(--line-0);
}
.mover:last-child{border-bottom:none}
.mover-sym{display:flex; align-items:center; gap:7px; overflow:hidden}
.mover-sym b{font-family:var(--font-data); color:var(--ink-900)}
.mover-bar{height:6px; background:var(--paper-2); border-radius:3px; overflow:hidden}
.mover-bar > span{display:block; height:100%; border-radius:3px; transition:width var(--duration-slow) var(--easing-calm)}
.mover .pct{text-align:right; font-family:var(--font-data); font-variant-numeric:tabular-nums; font-weight:600}

/* 账户风险状态行 */
.mmr-row{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:8px 2px; border-bottom:1px solid var(--line-0); font-size:12.5px;
}
.mmr-row:last-child{border-bottom:none}
.mmr-row b{min-width:110px; color:var(--ink-900)}
.mmr-row .spacer{flex:1}

/* 键值对 */
.kv-list{display:flex; flex-direction:column}
.kv{
  display:flex; justify-content:space-between; gap:14px;
  padding:6px 2px; font-size:12.5px; border-bottom:1px solid var(--line-0);
}
.kv:last-child{border-bottom:none}
.kv .k{color:var(--ink-500)}
.kv .v{font-family:var(--font-data); font-variant-numeric:tabular-nums; text-align:right; color:var(--ink-900)}

/* details 折叠 */
details.fold > summary{
  cursor:pointer; list-style:none; user-select:none;
  display:flex; align-items:center; gap:var(--space-2);
  font-size:var(--text-eyebrow); font-weight:600; letter-spacing:.1em;
  text-transform:uppercase; color:var(--ink-400);
}
details.fold > summary::-webkit-details-marker{display:none}
details.fold > summary::before{
  content:"▸"; color:var(--ink-400);
  transition:transform var(--duration-fast) var(--easing-calm);
}
details.fold[open] > summary::before{transform:rotate(90deg)}
details.fold > summary:hover{color:var(--direction-long)}
details.fold .fold-body{padding-top:var(--space-3)}

/* 业绩控制区:range 按钮组 → 分段切换形态 */
.perf-controls{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
.range-group{
  display:inline-flex; border:1px solid var(--line-1);
  border-radius:var(--radius-1); overflow:hidden;
}
.range-btn{border:0; border-radius:0; border-right:1px solid var(--line-1)}
.range-btn:last-child{border-right:none}
.range-btn.on{
  background:var(--direction-long-soft); color:var(--direction-long-deep); font-weight:600;
}
.custom-range{display:inline-flex; align-items:center; gap:6px}

/* 权重滑条 */
.weight-row{
  display:grid; grid-template-columns:150px 1fr 130px; gap:var(--space-3);
  align-items:center; padding:7px 2px; font-size:12.5px;
}
.weight-row .wname{display:flex; align-items:center; gap:7px; overflow:hidden; white-space:nowrap}
.weight-row .wname b{color:var(--ink-900)}
.weight-row .wval{text-align:right; font-family:var(--font-data); font-variant-numeric:tabular-nums; color:var(--ink-500)}
.weight-row .wval b{color:var(--ink-900)}

/* meta 徽章行 */
.meta-row{display:flex; align-items:center; gap:var(--space-2); flex-wrap:wrap; margin-bottom:var(--space-4)}

/* ---------- 13. 状态页 ---------- */
.stat-big{
  font-family:var(--font-display); font-weight:600; font-size:28px;
  color:var(--ink-900); font-variant-numeric:tabular-nums;
}
.stat-big small{font-size:var(--text-body); color:var(--ink-500); font-weight:400; font-family:var(--font-interface)}
.meter{
  height:7px; background:var(--paper-2); border-radius:4px; overflow:hidden;
  border:1px solid var(--line-0); margin-top:6px;
}
.meter > span{
  display:block; height:100%; border-radius:4px;
  background:var(--status-ok);
  transition:width var(--duration-slow) var(--easing-calm);
}

/* ---------- 14. 玻璃与流光(@supports 渐进增强) ----------
 * 毛玻璃:仅在浏览器支持 backdrop-filter 时启用,card/panel/kpi/topbar
 *   变为半透明磨砂,让背后的流体丝绸隐约透出;
 *   滚动遮罩面(粘性表头)保持完全不透明,纪律不破。
 * 总开关:顶栏「✦ 特效」→ body.effects-reduced 时本节全部回退为静态实底。 */
@supports ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))){
  body:not(.effects-reduced) .panel,
  body:not(.effects-reduced) .card{
    background:var(--glass-fill-panel);
    backdrop-filter:blur(var(--glass-blur-panel)) saturate(var(--glass-saturation)) brightness(1.06);
    -webkit-backdrop-filter:blur(var(--glass-blur-panel)) saturate(var(--glass-saturation)) brightness(1.06);
    border-color:var(--glass-edge);
    box-shadow:inset 0 1px 0 var(--glass-rim),
               inset 0 0 0 1px rgba(255,255,255,.16),
               var(--glass-shadow);
  }
  body:not(.effects-reduced) .kpi,
  body:not(.effects-reduced) .acc-card,
  body:not(.effects-reduced) .empty-step{
    background:var(--glass-fill-card);
    backdrop-filter:blur(var(--glass-blur-soft)) saturate(var(--glass-saturation)) brightness(1.06);
    -webkit-backdrop-filter:blur(var(--glass-blur-soft)) saturate(var(--glass-saturation)) brightness(1.06);
    border-color:var(--glass-edge);
    box-shadow:inset 0 1px 0 var(--glass-rim), 0 4px 14px rgba(22,50,42,.07);
  }
  body:not(.effects-reduced) #topbar{
    background:var(--glass-fill-bar);
    backdrop-filter:blur(var(--glass-blur-bar)) saturate(var(--glass-saturation)) brightness(1.08);
    -webkit-backdrop-filter:blur(var(--glass-blur-bar)) saturate(var(--glass-saturation)) brightness(1.08);
    border-bottom-color:var(--glass-edge);
    box-shadow:inset 0 1px 0 var(--glass-rim), 0 1px 0 rgba(22,50,42,.05);
  }
  body:not(.effects-reduced) .toast{
    background:var(--glass-fill-popover);
    backdrop-filter:blur(var(--glass-blur-soft)) saturate(var(--glass-saturation)) brightness(1.05);
    -webkit-backdrop-filter:blur(var(--glass-blur-soft)) saturate(var(--glass-saturation)) brightness(1.05);
    border-color:var(--glass-edge);
    box-shadow:inset 0 1px 0 var(--glass-rim), 0 10px 28px rgba(22,50,42,.14);
  }
}

/* 方向条流光:多头向右、空头向左的缓慢光泽(仅装点,不承载语义) */
@keyframes direction_flow_sheen{
  from{background-position:-160% 0}
  to{background-position:260% 0}
}
body:not(.effects-reduced) .lsbar i.l,
body:not(.effects-reduced) .mover-bar > span,
body:not(.effects-reduced) .meter > span{
  background-image:linear-gradient(105deg,
    transparent 36%, rgba(255,255,255,.42) 50%, transparent 64%);
  background-size:220% 100%; background-repeat:no-repeat;
  animation:direction_flow_sheen 2.6s linear infinite;
}
body:not(.effects-reduced) .lsbar i.s{
  background-image:linear-gradient(105deg,
    transparent 36%, rgba(255,255,255,.42) 50%, transparent 64%);
  background-size:220% 100%; background-repeat:no-repeat;
  animation:direction_flow_sheen 2.9s linear infinite reverse;
}

/* 特效总开关关闭:流体画布隐藏(玻璃与流光已由 :not() 选择器回退) */
body.effects-reduced #fluid_background_canvas{display:none}
body.effects-reduced .watermark{opacity:.5}

/* ---------- 15. 动效与可达性 ---------- */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation:none !important; transition:none !important}
  #progressbar .bar,#refresh_progress_bar{display:none}
}
@media (prefers-reduced-transparency: reduce){
  .panel,.card,.kpi,.acc-card,.empty-step,#topbar,.toast{
    background:var(--paper-1) !important;
    backdrop-filter:none !important;
    -webkit-backdrop-filter:none !important;
  }
}

/* ---------- 16. 响应式(保留现有侧边栏坍缩意图) ---------- */
@media (max-width:1180px){
  .chart-grid{grid-template-columns:1fr}
  .kpi-grid{grid-template-columns:repeat(auto-fit,minmax(138px,1fr))}
}
@media (max-width:1100px){
  .grid-2{grid-template-columns:1fr}
}
@media (max-width:900px){
  :root{--sidebar-w:60px}
  .brand{justify-content:center; padding:14px 0}
  .brand-word,#nav a span,.sidebar-bottom a span{display:none}
  #nav a,.sidebar-bottom a{justify-content:center; padding:11px 0}
  #nav a.active,.sidebar-bottom a.active{box-shadow:inset 2px 0 0 var(--direction-long-soft)}
  #view-root{padding:var(--space-3)}
  .mover{grid-template-columns:110px 1fr 64px}
  .weight-row{grid-template-columns:110px 1fr 110px}
}
@media (max-width:780px){
  #topbar{padding:var(--space-2) var(--space-3)}
  #clock,#last-update{display:none}
  .panel{padding:var(--space-4)}
  .card-head,.card-body{padding-left:var(--space-3); padding-right:var(--space-3)}
}
