/* LEDCALL OPS — 运营控台
 *
 * 2026-09-05 重做。之前是"往旧样式里塞新 tab", 结果 18 个 tab 平铺在一行,
 * 中文被压成竖排。设计参照 docs/decisions/ops-console.md 的三层结构。
 *
 * ⚠️ **所有既有类名一个都不能改。** 13 个老页面 (concerts / ops_spots /
 * video_assets / users / …) 直接引用 .kpi-card / .pill / .data-table / .field /
 * .track / .modal 这些名字, 改名就是静默崩一片。这里只换视觉, 不换契约。
 *
 * 两条中文排版规则, 跟本仓 App 侧一致:
 *   - 中文**不加 letter-spacing**。字距是给拉丁大写小标签用的, 加在中文上只会散。
 *   - 数字一律 tabular-nums, 列对齐才读得下去。
 *
 * 不引 webfont: 服务器在国内, Google Fonts 会拖慢甚至加载失败。丝印标签的性格
 * 靠字号 + 字距 + 大写做, 系统 sans 够用。
 */

:root {
  /* 蓝调深灰的设备面板色, 不是纯黑 —— 纯黑上任何边框都要么看不见要么发脏 */
  --bg: #12141a;
  --bg-alt: #191c25;
  --bg-deep: #0e1015;
  --line: #262b37;
  --line-hi: #333a4a;

  --ink: #e9ecf3;
  /* ⚠️ 这个变量以前**不存在**, 而 .kpi-value / .data-table td 一直在引用它 ——
   * 于是那些数字的颜色是继承来的, 不是设计的。补上。 */
  --ink-hi: #ffffff;
  --ink-lo: #8a93a6;

  /* accent = 灯牌粉。这是应援本身的颜色, 也是 App 里 newProgram chip 的颜色 */
  --pink: #ff3d8b;
  --pink-dim: #7a1f44;
  /* 语义色跟 accent 分开 —— 不然"高亮"和"出事了"长得一样 */
  --crit: #ff4d5e;
  --amber: #f2a93b;
  --lime: #3dd68c;
  --cyan: #4cc9f0;
  --violet: #8a5cff;

  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  --r: 6px;
  --rail-w: 178px;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB",
    "Microsoft YaHei", "Helvetica Neue", sans-serif;
  font-size: 13.5px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* 拉丁丝印小标签。中文标题**不要**用这个 */
.silk {
  font-size: 10px; font-weight: 600; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--ink-lo);
}
.num, .kpi-value, td.n, th.n { font-variant-numeric: tabular-nums; }

button {
  background: transparent;
  border: 1px solid var(--line-hi);
  color: var(--ink-lo);
  padding: 5px 12px;
  border-radius: var(--r);
  cursor: pointer;
  font-size: 12.5px;
  font-family: inherit;
  transition: border-color .12s, color .12s, background .12s;
}
button:hover { border-color: var(--ink-lo); color: var(--ink); }
button:disabled { opacity: 0.35; cursor: not-allowed; }
button:focus-visible { outline: 2px solid var(--pink); outline-offset: 1px; }
button.primary { border-color: var(--pink-dim); color: #ff8fbb; background: #2a1220; }
button.primary:hover { border-color: var(--pink); color: #ffb8d4; }
button.danger { border-color: #5c2229; color: var(--crit); }
button.danger:hover { background: #2b1519; color: var(--crit); }
button.lime { border-color: #22553d; color: var(--lime); }
button.lime:hover { background: #132a21; color: var(--lime); }
button.amber { border-color: #5a431a; color: var(--amber); }
button.amber:hover { background: #2a2213; color: var(--amber); }

input, textarea, select {
  background: var(--bg-deep);
  border: 1px solid var(--line);
  color: var(--ink);
  padding: 6px 9px;
  border-radius: var(--r);
  font-size: 12.5px;
  font-family: inherit;
  width: 100%;
}
textarea { font-family: var(--mono); resize: vertical; }
/*
 * 勾选框得从上面那条 width:100% 里摘出来。
 *
 * 被拉成整行宽的 checkbox 不会变大 —— 它还是那个小方块, 只是**居中飘在一条
 * 空白带里**, 跟自己的文字上下分家。看起来像"页面排版崩了", 而 DOM 结构完全正确
 * (2026-09-20 社群配置表单实拍)。radio 同理, 一起摘。
 */
input[type="checkbox"], input[type="radio"] {
  width: auto;
  margin: 0;
  vertical-align: middle;
}
/* 勾选框那一行: 框和字并排, 字不再是灰色小标签 (它是选项文本不是字段名) */
.field-check { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.field-check span { font-size: 12.5px; color: var(--ink); }
input:focus, textarea:focus, select:focus { outline: none; border-color: var(--pink); }
input[type="datetime-local"] { font-family: var(--mono); font-size: 11.5px; }

label { display: block; font-size: 11.5px; color: var(--ink-lo); margin-bottom: 4px; }
a { color: var(--pink); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ── shell: 左 rail + 主区 ───────────────────────────────────────────
 * 顶部平铺装不下 18 个 tab —— 中文会被压成竖排 (2026-09-05 截图)。
 * 竖向 rail 天然能分组, 而"分组"正是这次重排的全部意义: 当班 / 主线 / 底层。 */
.shell { display: grid; grid-template-columns: var(--rail-w) 1fr; min-height: 100vh; }

.rail {
  background: var(--bg-alt);
  border-right: 1px solid var(--line);
  position: sticky; top: 0; align-self: start;
  max-height: 100vh; overflow-y: auto;
  padding-bottom: 20px;
  display: flex; flex-direction: column;
}
.rail .brand {
  font-weight: 700; letter-spacing: 0.16em; color: var(--pink);
  font-size: 12px; padding: 16px 14px 4px;
}
.rail-grp { padding: 14px 14px 5px; }
.nav { display: flex; flex-direction: column; gap: 1px; padding: 0 8px; }
.nav .tab {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; border-radius: var(--r);
  color: var(--ink-lo); font-size: 13px; cursor: pointer;
  border-left: 2px solid transparent;
  white-space: nowrap;
}
.nav .tab:hover { background: #1f2331; color: var(--ink); }
.nav .tab.active { background: #1f2331; color: var(--ink); border-left-color: var(--pink); }
.nav .tab .badge {
  margin-left: auto; font-family: var(--mono); font-size: 10px;
  padding: 0 5px; border-radius: 8px; background: var(--crit); color: #fff;
  font-variant-numeric: tabular-nums;
}
.nav .tab .badge.soft { background: var(--line-hi); color: var(--ink-lo); }
.rail-foot {
  margin-top: auto; padding: 14px; border-top: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 8px; align-items: flex-start;
}
.rail-foot .me { color: var(--ink-lo); font-size: 11px; word-break: break-all; }

.main { min-width: 0; }
.container { max-width: 1180px; margin: 0; padding: 22px 26px 60px; }

/* 旧的横向 topbar 保留定义 —— 万一还有别的地方渲染它, 不至于裸奔 */
.topbar { display: flex; align-items: center; gap: 18px; padding: 0 24px; height: 52px;
  background: var(--bg-alt); border-bottom: 1px solid var(--line); }
.topbar .brand { font-weight: 700; letter-spacing: .16em; color: var(--pink); font-size: 14px; }
.topbar .tabs { display: flex; gap: 4px; flex: 1; flex-wrap: wrap; }
.topbar .me { color: var(--ink-lo); font-size: 12px; }

/* login */
.login { display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 24px; }
.login-card {
  background: var(--bg-alt); border: 1px solid var(--line);
  border-radius: 10px; padding: 30px; width: 340px;
}
.login-card h1 { margin: 0 0 22px; font-size: 15px; letter-spacing: 0.16em; color: var(--pink); }
.login-card .field { margin-bottom: 13px; }
.login-card button { width: 100%; padding: 9px; }
.login-card .err { color: var(--crit); font-size: 12px; margin-top: 12px; }

/* ── 区块 ──────────────────────────────────────────────────────────── */
.sec { margin-bottom: 26px; }
.sec-hd { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.sec-hd .rule { flex: 1; height: 1px; background: var(--line); }

/* 页头。中文标题不加字距 */
.page-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.page-head h2 { margin: 0; font-size: 18px; letter-spacing: 0; color: var(--ink); flex: 1; font-weight: 600; }
.page-head .filter { display: flex; gap: 8px; align-items: center; }
.page-head .filter select, .page-head .filter input { width: auto; min-width: 110px; }
h3 { font-size: 13px; font-weight: 600; letter-spacing: 0; margin: 22px 0 10px; color: var(--ink); }

/* ── 表 ───────────────────────────────────────────────────────────── */
table {
  width: 100%; border-collapse: collapse;
  background: var(--bg-alt); border: 1px solid var(--line);
  border-radius: var(--r); overflow: hidden;
}
th, td { padding: 7px 12px; text-align: left; border-bottom: 1px solid #21252f; font-size: 12.5px; vertical-align: middle; }
th {
  color: var(--ink-lo); font-weight: 600; letter-spacing: 0.1em;
  font-size: 10px; text-transform: uppercase; background: #14171f; white-space: nowrap;
}
tbody tr:hover { background: #1d212b; }
tbody tr:last-child td { border-bottom: none; }
td .actions { display: flex; gap: 6px; flex-wrap: wrap; }
td.n, th.n { text-align: right; font-family: var(--mono); }
.tw { overflow-x: auto; }

/* ── 状态 pill ─────────────────────────────────────────────────────── */
.pill {
  padding: 1.5px 7px; border-radius: 9px; font-size: 11px; letter-spacing: 0;
  border: 1px solid; display: inline-block; line-height: 1.5; white-space: nowrap;
}
.pill.upcoming  { color: var(--cyan);   border-color: #1d4a5c; background: #12262e; }
.pill.live      { color: var(--lime);   border-color: #22553d; background: #132a21; }
.pill.ended     { color: var(--ink-lo); border-color: var(--line); }
.pill.cancelled { color: var(--crit);   border-color: #5c2229; background: #2b1519; }
.pill.pending   { color: var(--amber);  border-color: #5a431a; background: #2a2213; }
.pill.approved  { color: var(--lime);   border-color: #22553d; background: #132a21; }
.pill.rejected  { color: var(--crit);   border-color: #5c2229; background: #2b1519; }
.pill.active    { color: var(--lime);   border-color: #22553d; background: #132a21; }
.pill.closed    { color: var(--ink-lo); border-color: var(--line); }
.pill.published { color: var(--lime);   border-color: #22553d; background: #132a21; }
.pill.draft     { color: var(--amber);  border-color: #5a431a; background: #2a2213; }
.pill.archived  { color: var(--ink-lo); border-color: var(--line); }

/* 数据源徽记 —— 值班台/排期页的承重信息: 这块数现在到底存不存在。
 * a=有 · b=数据存了但后台以前读不到 · c=还没有数据源 */
.src {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .02em;
  padding: 1px 5px; border-radius: 3px; border: 1px solid; white-space: nowrap;
  margin-left: 6px; vertical-align: middle;
}
.src.a { color: var(--lime);   border-color: #22553d; background: #132a21; }
.src.b { color: var(--amber);  border-color: #5a431a; background: #2a2213; }
.src.c { color: var(--ink-lo); border-color: var(--line); border-style: dashed; }
.legend {
  display: flex; gap: 12px; flex-wrap: wrap; align-items: center;
  padding: 9px 13px; font-size: 11.5px; color: var(--ink-lo);
  border-top: 1px solid #21252f;
}
.hint {
  font-size: 11.5px; color: var(--ink-lo); padding: 9px 13px; line-height: 1.65;
  border-top: 1px solid #21252f;
}
.hint:first-child { border-top: none; }

/* ── modal ─────────────────────────────────────────────────────────── */
.modal-bg { position: fixed; inset: 0; background: rgba(0,0,0,0.72);
  display: flex; align-items: center; justify-content: center; padding: 24px; z-index: 100; }
.modal { background: var(--bg-alt); border: 1px solid var(--line-hi);
  border-radius: 10px; width: 100%; max-width: 720px; max-height: 90vh;
  display: flex; flex-direction: column; }
.modal-head { padding: 14px 18px; border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 12px; }
.modal-head h3 { margin: 0; font-size: 14px; letter-spacing: 0; color: var(--ink); flex: 1; }
.modal-body { padding: 18px; overflow-y: auto; }
.modal-foot { padding: 12px 18px; border-top: 1px solid var(--line);
  display: flex; gap: 10px; justify-content: flex-end; }
.field { margin-bottom: 13px; }
.field-row { display: flex; gap: 13px; }
.field-row .field { flex: 1; }

/* ── tracks 编辑器 ─────────────────────────────────────────────────── */
.tracks { display: flex; flex-direction: column; gap: 10px; }
.track { border: 1px solid var(--line); border-radius: var(--r); padding: 10px; background: var(--bg-deep); }
.track-head { display: flex; gap: 8px; margin-bottom: 8px; align-items: center; }
.track-head input { flex: 1; }
.track textarea { min-height: 100px; }
.track-add { border: 1px dashed var(--line-hi); border-radius: var(--r);
  padding: 12px; text-align: center; color: var(--ink-lo); cursor: pointer; }
.track-add:hover { border-color: var(--pink); color: #ff8fbb; }

/* ── 图 ────────────────────────────────────────────────────────────── */
.img-thumb { width: 52px; height: 38px; object-fit: cover; border-radius: 4px;
  border: 1px solid var(--line); background: var(--bg-deep); cursor: pointer; }
.img-full { max-width: 90vw; max-height: 80vh; display: block; }

.empty { text-align: center; color: var(--ink-lo); padding: 36px; font-size: 13px;
  border: 1px dashed var(--line); border-radius: var(--r); }
.muted { color: var(--ink-lo); }
.err { color: var(--crit); font-size: 12px; }
.ok { color: var(--lime); font-size: 12px; }

.toast {
  position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%);
  background: var(--bg-alt); border: 1px solid var(--lime); color: var(--lime);
  padding: 9px 16px; border-radius: var(--r); z-index: 200; font-size: 12.5px;
}
.toast.err { border-color: var(--crit); color: var(--crit); }

/* ── KPI 卡 ────────────────────────────────────────────────────────── */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(186px, 1fr)); gap: 10px; }
.kpi-card {
  background: var(--bg-alt); border: 1px solid var(--line);
  border-radius: var(--r); padding: 12px 13px 13px;
}
.kpi-label {
  color: var(--ink-lo); font-size: 11.5px; letter-spacing: 0;
  margin-bottom: 4px; display: flex; align-items: center; flex-wrap: wrap;
}
.kpi-value {
  color: var(--ink-hi); font-family: var(--mono);
  font-size: 25px; font-weight: 700; line-height: 1.15; letter-spacing: -0.02em;
  margin-bottom: 2px; word-break: break-all;
}
.kpi-sub { color: var(--ink-lo); font-size: 11px; line-height: 1.5; }
.kpi-tag { margin-top: 8px; font-size: 11.5px; letter-spacing: 0; font-weight: 600; }
/* 没有数据源的格子: 虚线 + 压暗, 跟"真的是 0"区分开 */
.kpi-card.void { border-style: dashed; border-color: #333a4a; background: transparent; }
.kpi-card.void .kpi-value { color: #4a5265; }

/* ── data-table (旧页面用) ─────────────────────────────────────────── */
.data-table {
  width: 100%; border-collapse: collapse; background: var(--bg-alt);
  border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; font-size: 12px;
}
.data-table th {
  background: #14171f; color: var(--ink-lo); text-align: left; padding: 7px 10px;
  letter-spacing: 0.1em; text-transform: uppercase; font-size: 10px;
  border-bottom: 1px solid var(--line);
}
.data-table td { padding: 7px 10px; border-bottom: 1px solid #21252f; color: var(--ink); }
.data-table tr:hover td { background: #1d212b; }
.data-table code {
  font-family: var(--mono); letter-spacing: .08em;
  background: #12262e; color: var(--cyan); padding: 2px 6px; border-radius: 3px;
}

@media (max-width: 860px) {
  .shell { grid-template-columns: 1fr; }
  .rail { position: static; max-height: none; border-right: none;
    border-bottom: 1px solid var(--line); }
  .nav { flex-direction: row; flex-wrap: wrap; }
  .nav .tab { width: auto; }
  .rail-foot { flex-direction: row; align-items: center; margin-top: 0; }
  .container { padding: 16px 14px 48px; }
}
@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* ── 崩溃 ──────────────────────────────────────────────────────────
 * 一条事件要一眼看出三件事: 哪儿炸的 (堆栈) · 之前干了什么 (面包屑) · 什么机器。
 * 所以不再倒原始 JSON, 那个降级成一个按钮。 */
.crash-detail {
  border: 1px solid var(--line); border-radius: var(--r);
  background: var(--bg-alt); padding: 14px 16px; margin-top: 16px;
}
.crash-ttl { font-size: 14px; font-weight: 600; color: var(--ink); margin-bottom: 3px; }
.crash-ttl .type { color: var(--pink); }
.crash-meta {
  color: var(--ink-lo); font-size: 11px; font-family: var(--mono);
  margin-bottom: 14px; word-break: break-all;
}
.crash-frames { font-family: var(--mono); font-size: 11.5px; line-height: 1.5; }
/* inApp = 我们自己的代码, 给底色顶出来; 框架/第三方帧压暗, 一屏里先看亮的那几行。 */
.crash-frames .fr { display: flex; gap: 12px; padding: 3px 8px; border-radius: 4px; }
.crash-frames .fr.app { background: rgba(255,255,255,.035); }
.crash-frames .fr.ext { opacity: .45; }
.crash-frames .fn { color: var(--ink); flex: 0 0 190px; }
.crash-frames .loc { color: var(--ink-lo); word-break: break-all; }
.crash-crumbs { font-family: var(--mono); font-size: 11px; line-height: 1.9; color: var(--ink-lo); }
/* 处理状态区: 打开一条崩溃, 第一眼要回答"这条处理过没有"。 */
.crash-triage {
  border: 1px solid var(--line); border-radius: 6px;
  padding: 10px 12px; margin: 10px 0 4px;
  background: rgba(255,255,255,.02);
}
.crash-triage .field-row { margin-bottom: 8px; align-items: center; flex-wrap: wrap; gap: 8px; }
.crash-triage .field-row:last-of-type { margin-bottom: 0; }
.crash-notes {
  font-family: var(--mono); font-size: 11px; line-height: 1.9;
  color: var(--ink-lo); margin-top: 8px;
}
.crash-notes .cat { color: var(--cyan); }
.crash-crumbs .cat { color: var(--cyan); }
.crash-raw {
  font-family: var(--mono); font-size: 11px; line-height: 1.6;
  max-height: 420px; overflow: auto; white-space: pre-wrap; word-break: break-all;
  color: var(--ink-lo); background: var(--bg-deep);
  border: 1px solid var(--line); border-radius: var(--r);
  padding: 10px; margin-top: 10px;
}
