/* ── 视觉 token：真源在 shared/tianqiong_core/visual_tokens.py（架构 §12.11）──
   变量由 app.js 从 GET /api/v1/visual-tokens 取到后写入（documentElement.style.setProperty）。
   ★ 这里【故意不保留兜底值】—— 保留就是第三份副本（真源改了它不变，且没人会红）。 */
:root {
  /* ── 端侧命名值（架构 §12.11 的 ①/② 类：**不进真源**，但「不共享 ≠ 可以裸写」）──
     规则体里只许用 var(--…)；下面这些是它们**唯一合法的定义位置**。
     ★ 同值不同语义的下场：e.g. --th-bg 与 --row-hover-bg 现在同值，
       但按语义分开命名 —— 否则将来一个要变、另一个被锁住。 */
  --nav-active-bg: #EEF3FF;
  --field-bg: #fff;              /* ★ 不读真源：它是 **Web 自己的白**（控件面），与 card 语义无关；
                                    且读真源会把 Web 自己的白也拴在端点可用性上（fetch 失败 ⇒ 连它也丢） */
  --on-primary: #fff;            /* ★ 不读真源：**经裁定它不等 card** ——
                                    若 primary 换浅黄/浅绿，这里必须变【深色】（否则白字看不见），
                                    而 card 仍是白 ⇒ 耦合会让换肤出错对比度 ⇒ 它持有自己的字面量 */
  --btn-secondary-bg: #fff;      /* ★ 不读真源：同 --field-bg（Web 自己的白面） */
  --th-bg: #FAFBFC;
  --row-hover-bg: #FAFBFC;
  --badge-ok-bg: #E7F6EC;
  --badge-warn-bg: #FEF3E2;
  --badge-bad-bg: #FDECEC;
  --badge-info-bg: #EAF0FE;
  --msg-error-bg: #FDECEC;
  --msg-success-bg: #E7F6EC;
  --code-bg: #0F172A;
  --code-fg: #D6E2FF;
}


* { box-sizing: border-box; }

/* ── S5：液体玻璃（Web 独有能力）+ 彩色流沙（canvas）──────────────────
   ★ 数值**全部**来自真源（端点下发成变量）⇒ 这里**没有任何裸数值**（有断言钉住；见
     `tests/test_visual_tokens_s5.py` 与 `tests/test_s5_visual_web.py`）。
   ★ 性能意识（客户要"更好"）：模糊半径取 12px，并用**更高的填充不透明度**换回"玻璃感"
     —— 模糊的代价随半径上升，而玻璃只用在**有界**的少数面板上（`.glass`），**不给整页**。
   ★ Qt 端**不模拟**模糊（没有该能力）⇒ 走真源里的 `qt_fallback`（blur_px=0，见 §12.11.5）。
     "能力没有就不假装有"是同一条原则，两端一致。 */

.glass {
  position: relative;
  background: rgb(255 255 255 / var(--glass-fill-alpha));
  backdrop-filter: blur(var(--glass-blur-px)) saturate(140%);
  -webkit-backdrop-filter: blur(var(--glass-blur-px)) saturate(140%);
  border: var(--glass-stroke-px) solid rgb(255 255 255 / var(--glass-stroke-alpha));
  box-shadow: 0 6px 24px rgb(15 23 42 / 0.06);
}

/* 不支持 `backdrop-filter`（老浏览器 / GPU 合成被关）⇒ **提高不透明度**兜住可读性，
   而**不**去假装模糊 —— 与 Qt 端同一条原则。 */
@supports not (backdrop-filter: blur(1px)) {
  .glass { background: rgb(255 255 255 / 0.94); }
}

/* 内容层：压在流沙之上，保证文字可读 */
.glass > .glass-content { position: relative; z-index: 1; }

/* 彩色流沙：铺在玻璃面板内侧的装饰层（不拦交互；尺寸=父容器） */
canvas.sand {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0.55;
}

/* 尊重系统"减少动态效果"：直接不显示（同时也是省电开关） */
@media (prefers-reduced-motion: reduce) {
  canvas.sand { display: none; }
}

body {
  margin: 0;
  font-family: "Microsoft YaHei UI", "PingFang SC", system-ui, sans-serif;
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
  line-height: 1.6;
}

.hidden { display: none !important; }

/* ---------- 登录 ---------- */
.login-wrap {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.login-card {
  width: 360px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 32px;
}
.login-card h1 { margin: 0 0 4px; font-size: 22px; font-weight: 500; }
.login-card .slogan { color: var(--muted); margin: 0 0 24px; font-size: 13px; }

/* ---------- 布局 ---------- */
.topbar {
  height: 56px;
  background: var(--card);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  padding: 0 24px;
  position: sticky;
  top: 0;
  z-index: 10;
}
.brand { font-size: 17px; font-weight: 500; }
.brand .sub { color: var(--muted); font-size: 12px; margin-left: 6px; }
.spacer { flex: 1; }
.user-box { color: var(--muted); font-size: 13px; }

.layout { display: flex; min-height: calc(100vh - 56px); }
.sidebar {
  width: 180px;
  background: var(--card);
  border-right: 1px solid var(--border);
  padding: 16px 0;
}
.sidebar a {
  display: block;
  padding: 10px 24px;
  color: var(--text);
  text-decoration: none;
  font-size: 14px;
}
.sidebar a:hover { background: var(--bg); }
.sidebar a.active { color: var(--primary); background: var(--nav-active-bg); border-right: 3px solid var(--primary); }

.content { flex: 1; padding: 24px; overflow-x: auto; }

/* ---------- 组件 ---------- */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  margin-bottom: 20px;
}
.card h2 { margin: 0 0 16px; font-size: 15px; font-weight: 500; }

.grid-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 20px; }
.stat {
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 16px;
}
.stat .label { color: var(--muted); font-size: 12px; }
.stat .value { font-size: 24px; font-weight: 500; margin-top: 4px; }

label { display: block; margin-bottom: 4px; font-size: 13px; color: var(--muted); }
input, select, textarea {
  width: 100%; padding: 8px 10px; margin-bottom: 12px;
  border: 1px solid var(--border); border-radius: 8px;
  font-size: 14px; font-family: inherit; background: var(--field-bg); color: var(--text);
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--primary); }

button {
  padding: 8px 16px; border: none; border-radius: 8px;
  background: var(--primary); color: var(--on-primary); cursor: pointer;
  font-size: 14px; font-family: inherit;
}
button:hover { opacity: 0.9; }
button.secondary { background: var(--btn-secondary-bg); color: var(--text); border: 1px solid var(--border); }
button.danger { background: var(--danger); }
button:disabled { opacity: 0.5; cursor: not-allowed; }

table { width: 100%; border-collapse: collapse; font-size: 13px; }
th, td { padding: 10px 12px; text-align: left; border-bottom: 1px solid var(--border); }
th { color: var(--muted); font-weight: 500; background: var(--th-bg); }
tbody tr:hover { background: var(--row-hover-bg); }

.badge { display: inline-block; padding: 2px 8px; border-radius: 6px; font-size: 12px; }
.badge.ok { background: var(--badge-ok-bg); color: var(--success); }
.badge.warn { background: var(--badge-warn-bg); color: var(--warning); }
.badge.bad { background: var(--badge-bad-bg); color: var(--danger); }
.badge.info { background: var(--badge-info-bg); color: var(--primary); }

.msg { padding: 10px 14px; border-radius: 8px; margin-bottom: 16px; font-size: 13px; }
.msg.error { background: var(--msg-error-bg); color: var(--danger); }
.msg.success { background: var(--msg-success-bg); color: var(--success); }

.row-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.toolbar { display: flex; gap: 8px; align-items: flex-end; margin-bottom: 16px; flex-wrap: wrap; }
.toolbar > div { min-width: 140px; }
.toolbar input, .toolbar select { margin-bottom: 0; }

pre.keys-box {
  background: var(--code-bg); color: var(--code-fg); padding: 16px; border-radius: 8px;
  max-height: 260px; overflow: auto; font-size: 12px; line-height: 1.8;
  font-family: Consolas, monospace;
}
.muted { color: var(--muted); font-size: 12px; }
