/* ─────────────────────────────────────────────────────────────
 * 界面语言 · Token
 *
 * 唯一的调色方式：**语义名**。任何地方写死颜色都是违规
 * （判据：换一套色，应该只改这一个文件）。
 *
 * 两套主题共用**同一组语义名** —— 是"同一份 token 的两个值"，
 * 不是两套 token：
 *   theme-console  事务（亮）：管理台 —— 读与决定，长扫表格
 *   theme-canvas   内容（暗）：创作台 —— 看内容，暗底不抢画面
 *
 * 详见《界面语言 v1》。
 * ───────────────────────────────────────────────────────────── */

/* ── 复位：`hidden` 必须真的隐藏 ──────────────────────────────────────────
 *
 * 为什么需要这一条（2026-09-18 实测踩到）：
 *   HTML 的 `hidden` 属性靠**UA 样式表的 `display:none`** 生效，
 *   而元素**自己的 `display` 优先级更高** —— 于是
 *     <div hidden style="display:flex">   ⇒  **仍然显示**
 *   组织管理的两个弹窗（邀请 / API key）都这么写 ⇒ **每次加载都盖在整页上**，
 *   而且内容还是空的（它们的 JS 在 `hidden=false` 时才填）。
 *
 * 这是一条**正确的全局规则**：`hidden` 的意思就是隐藏，任何地方都不该例外。
 * 加在 tokens.css（三个台共享）⇒ 一次修好全部，并防住以后同样的写法。
 */
/* ── 复位：`box-sizing` ────────────────────────────────────────────────────
 *
 * 为什么需要这一条（2026-09-19 实测踩到）：
 *   三个台各自在自己的 `<style>` 里写了 `*{box-sizing:border-box}`（web 9 处、
 *   其余各 1 处），**而 tokens.css 里 0 处** —— 于是凡是"只加载 tokens.css"的
 *   页面就拿不到它。
 *
 *   唯一这样做的页面是 **identity 的 OIDC 登录页**（HTML 内联在
 *   identity/identity/src/routes.rs 的 login_form_html 里，只 `<link>` 了 tokens.css）。
 *   实测：`.ui-input` 写 `style="width:100%"`，容器 360px，
 *     360 + padding 16 + border 2 = **378px** ⇒ 比容器宽 18px
 *     ⇒ 输入框的右边缘比 label 和按钮**多出 18px，三者对不齐**。
 *   而创作台同一个 `.ui-input` 量到 326 = 326，完全对齐 —— 差别只在这一条。
 *
 * 这是**设计系统该有的复位**，不是某一个页面的补丁：
 *   `width:100%` 的含义就应该是"占满容器"，而不是"占满容器再溢出 padding 与边框"。
 * 放在 tokens.css（三个台 + 登录页共享）⇒ 一处修好全部，并防住以后同样的写法。
 */
*, *::before, *::after { box-sizing: border-box; }

[hidden] { display: none !important; }

/* ── 复位：`<body>` 的默认外边距 ──────────────────────────────────────────
 * 为什么需要这一条（2026-09-30 实测踩到）：
 *   本文件既有的 `.ui-body{margin:0}` 是挂在 **`<html>`** 上的，
 *   而浏览器默认的那 8px 外边距在 **`<body>`** 上 —— 两者不是一个元素。
 *   后果（在管理后台量到的实数）：整页的 header 落在 (8, 8)、宽 1496 而不是 1512；
 *   左导航与内容**整体右移下移 8px**，右边与下边各留一道不该有的缝。
 *   创作台此前自己在 `shell.css` 里补了 `html, body { margin: 0 }` 才没中招 ——
 *   这正是「同一条纪律在三处各写一遍」的代价：写了两处，漏了一处。
 *   放在共享层 ⇒ 一处修好三台 + 登录页，且以后新加的面自动继承。
 */
body { margin: 0; }

/* ══════════════════════════════════════════════════════════════════════
 * 外观（scheme）· 浅色 / 深色 —— 与「面」正交的第二个维度（2026-09-22）
 *
 * 此前"明暗"被绑死在「面」上（.theme-console 亮 / .theme-canvas 暗；09-19 又按
 * 所有者要求把三台与画布统一成一族全暗）⇒ 用户对这一层**没有选择**。
 * 但这是两个正交的维度，混在一起就表达不了"管理台也想用亮色"：
 *   面（surface）  = theme-canvas / theme-console —— 产品结构，用户不切
 *   外观（scheme） = light / dark —— **用户可切**，落在 <html data-scheme>
 *
 * 写法：两条规则，**每个值只写一次**：
 *   :root, :root[data-scheme="light"]                         ← 浅色（默认/兜底）
 *   :root[data-scheme="dark"], .theme-canvas, .theme-console   ← 深色（面的默认）
 * 深色那条写在后面 ⇒「有面 class、没 data-scheme」时按面的默认（深色），
 * **与改动前逐像素一致**；一旦 <html> 显式标了 data-scheme，
 * 它（特异性 0,2,0）就压过面 class（0,1,0），切换生效。
 *
 * 浅色不是新设计的一套配色：就是本文件原本为亮底写的那套暖白值
 * （#f7f6f3 暖白 / #22201d 暖黑 / #7d5f2c 深金）—— 被 09-19 的全暗覆盖埋掉了，
 * 这里把它请回来。**换外观 = 换这一层，不动任何一处组件样式。**
 * ══════════════════════════════════════════════════════════════════════ */
:root, :root[data-scheme="light"] {
  /* color-scheme：让原生控件（number 箭头/select 面板/滚动条…）跟随浅色。一处真相。 */
  color-scheme: light;

  /* ── 语义色（每义一色，不得混用）──────────────────────────────────
   * ★★ 2026-09-27 视觉语言收口：浅色主题从「暖纸 + 暖棕」**整体转为小云雀语言** ——
   *   冷中性浅底 + 白卡片 + **单一紫强调**；界面去饱和，**内容（封面/成片）才是彩色**。
   *   像素取证（小云雀首页，2938×1610）：
   *   · 界面里**唯一的彩色**是右上角一枚紫 #9d73ff（hue≈240）；
   *   · 青蓝/红粉/暖黄等高饱和像素**全部只出现在 y>1040 的底部封面缩略图** = 内容，非界面；
   *   · 页面底冷浅灰 #f2f2f4，顶部一抹极淡紫雾 #eae0fe。
   *   纪律（沿用 2026-09-19）：**只换色相、不改视觉重量** —— 底仍近白、正文仍近黑、
   *   各对比度档位（正文≥4.5 · 控件边界≥3 · 主按钮≥4.5）一律不变。 */
  --accent: #6d5ae6;        /* 品牌主行动 = 紫（与 --agent 统一：一屏只有一种强调色）*/
  --accent-ink: #ffffff;
  --danger: #b8322a;        /* 破坏性：移除/撤销/停用。不用于"取消" */
  --warn: #8f6512;          /* 需要注意：缺口/未定价/余额将尽 */
  --ok: #0f7a4e;            /* 已完成/通过：绿是**状态色**，不与品牌紫混用 */

  /* ── 中性（冷调排版与结构）──────────────────────────────── */
  --bg: #f5f5f7;            /* 页面底（冷浅灰；与原暖底同明度）*/
  --card: #ffffff;          /* 卡片/表面 */
  --ink: #1f2023;           /* 正文（冷近黑）*/
  --muted: #5f6368;         /* 次要：时间/归属/说明，≥4.5:1 */
  --line: #e4e5e9;          /* 装饰行线/容器描边 */
  --line-strong: #898d96;   /* 控件边界：输入框/按钮，≥3:1 */
  --chip: #eef0f3;          /* 状态标签底 */
  --chip-ink: #585d66;

  /* ── 状态色的淡底与描边（同一语义成对出现；冷调）────────────── */
  --warn-bg: #fbf3df;   --warn-line: #e8d6a0;
  --ok-bg: #e6f5ed;     --ok-line: #aedcc6;
  --danger-bg: #fcebea; --danger-line: #f0c1bc;
  /* 主色悬停淡底/线 = 紫（与 AI 表面统一，hover 不再出现暖雾）*/
  --accent-bg: #f1eefd;  --accent-line: #d9d2f8;

  /* ── 状态色 · 补齐（2026-10-08）────────────────────────────────────
   * 此前只有 ok / warn / danger 三支，于是同一件事在不同页面长得不一样：
   *   「排队 / 已受理」借一个**孤立且没人用**的 --blue（还没配底与线）；
   *   「失败」借 danger；「停用 / 草稿」借中性灰。
   * 状态是**语义**：一义一色，且**每支必须成对给出 bg / line**
   *   —— 不给，用到淡底的地方就会各自发明一个（画布那边已经发明了 60 多处写死色）。
   * ⚠️ `--blue` 正名为 `--info`（一物一名；实测 `--blue` 全仓 0 处引用），
   *   且**顺手修掉它的对比度**：原值 `#2f7fb0` 在浅色里只有 3.86（**<4.5，不达标**），
   *   现取 `#226289`（底上 5.82 / 白卡 6.61 / 页底 6.07）——与 ok/warn/danger 同一明度档。
   *   为什么不用"排队"当名字：「排队」只是它的一种场景，充值待处理、审核中、上传中都是它。 */
  --info: #226289;   --info-bg: #e8f2f8;   --info-line: #b7d4e4;

  /* ── 类型色 · 一条色相环（2026-10-08 新增）────────────────────────
   * 与状态色**分族**，回答的是另一个问题：
   *   状态色（--ok/--warn/--danger/--info/--agent）＝ **它怎么样了**（高彩度，信号）
   *   类型色（--kind-N）                        ＝ **它是哪一类**（低彩度，墨色）
   * 纪律（不这样做就会变成"整页花掉"）：
   *   ① **只用在标记位**：图标底、左 3px 条、小圆点、chip 文字 —— 面积小；
   *   ② **不许铺大面积底色**（卡面/面板一律走中性灰阶）；
   *   ③ **不许表达层级/重要性**（那仍归字重 + 明度 + 缩进 —— 《卡片视觉语言》§五）；
   *   ④ **同屏里类型色与状态色不出现在同一个零件上**（红点＝失败 还是＝图片？不许有歧义）。
   * 每台自己声明"哪一类映射到哪一号"，**只声明一次**（见《配色语汇》§四的映射表）。 */
  --kind-1: #44518f; --kind-1-bg: #eaecf7;
  --kind-2: #1f6b7a; --kind-2-bg: #e4f1f4;
  --kind-3: #3d7350; --kind-3-bg: #e7f1ea;
  --kind-4: #7b6a2e; --kind-4-bg: #f3efe0;
  --kind-5: #8a5a35; --kind-5-bg: #f5ece4;
  --kind-6: #6f4a63; --kind-6-bg: #f2eaf0;

  /* ── AI 助手身份色 = 品牌紫（与 accent 统一）────────────────── */
  --agent: #6d5ae6;
  --agent-bright: #5b48d6;
  --agent-soft: #7a68ea;
  --agent-faint: #b9aef5;
  --agent-bg: #f1eefd;
  --agent-line: rgba(109, 90, 230, .28);

  /* ── 表面第三档 / 弱文字 / 卡内弱分隔线（冷）────────────────── */
  --panel3: #e7e8ec;                 /* 悬停/嵌套表面 */
  --dim: #8b8f96;                    /* 正文级以下弱文字 */
  --label: #5d6168;                  /* 微标签（10.5px），≥4.5:1 */
  --line-soft: rgba(0, 0, 0, .055);  /* 卡内弱分隔线 */

  /* ── 叠色三档：亮底靠"压暗"分层（黑叠，冷底通用）────────────── */
  --raise-1: rgba(0, 0, 0, .02);
  --raise-2: rgba(0, 0, 0, .04);
  --raise-3: rgba(0, 0, 0, .06);

  /* ── 遮罩：弹层压暗背后 ──────────────────────────────────── */
  --scrim: rgba(20, 20, 28, .45);
  /* ── 点阵底（`CanvasHub` 的 `.cv-dots`）· 静态点的**基线不透明度** ────────
   * 为什么它必须住在明暗层（2026-10-08 业主实测抓到）：
   *   此前这个基线在代码里**写死 0.16**，于是**它只对浅色成立** ——
   *   浅色下 `--ink`(#1f2023) 在 .16 上是清晰的浅灰点；暗色下 `--ink`(#e6e6e6)
   *   同样 .16 落在近黑底里几乎看不见。同一份点阵，两副面孔。
   * ⇒ 明暗各一个值。改点阵的强弱**只改这里**，不必再动 CanvasHub 的 JS。 */
  --dots-a: .16;

  /* ── 悬停"升起"（亮底靠阴影表达浮起）──────────────────────── */
  --shadow-lift: 0 6px 20px rgba(0, 0, 0, .13);
  --lift-surface: #ffffff;
  --lift-line: #d9dbdf;

  /* 表面边框悬停档（比 --line 深一档）*/
  --line-hover: #d2d4d9;

  /* 「运行中 / info」冷蓝 */
}

/* ── 常量：与明暗无关（排版 / 间距 / 圆角 / 动效）────────────────
 * 这一层放这儿：它们不随 scheme 变，也不随面变。 */
:root {
  /* ── 排版 ──────────────────────────────────────────── */
  /* ⚠️ **中文字形必须显式列全平台**（Lark Design 是唯一把中文当第一公民的那家）。
     此前只有苹方(macOS) + 微软雅黑(Windows) ⇒ **Linux/Android 会落到 system-ui，
     而那里可能没有中文字形** ⇒ 整片界面变成方框。加上 Noto Sans SC（Android/多数
     Linux 发行版的中文默认）作为第三顺位，四个平台才都有中文字。 */
  --font: -apple-system, "PingFang SC", "Microsoft YaHei", "Noto Sans SC",
          "Source Han Sans SC", system-ui, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;
  /* **字号只有五档**（多一档就多一次犹豫，结果是九个近似值） */
  /* ── 规范字号阶（9 档）────────────────────────────────────────────
     ✅ 2026-09-22 对齐竞品（小云雀 xyq.jianying.com，实测）：**小字号段本来就对得上**
     （它 10/11/12/13/14 与我们 2xs/micro/small/body/md 逐档相同），差的是**大字号段** ——
     它有 34px 的页面主标题与 39px 的 hero，而我们最大只到 26px 且**从未使用**（使用次数 0），
     于是整个界面的字高都挤在 11–14px 之间 ⇒ 观感"不够大气"。
     这一轮把上面四档放大，**小字号段一动不改**（正文密度是工作台的命，动它会把表格与列表挤坏）。

     命名纪律：**按语义命名，不按尺寸命名** —— `--fs-2xl` 回答不了
     "这里该用哪一档"；`--fs-title` 可以。所以没有 xs/sm/lg 这套尺寸名。

     取整纪律：**相邻档至少差 1px**。差 0.5px（12 / 12.5）在 10–16 区间
     人眼无法稳定分辨，只会让作者在两档之间随意挑，最终又长出新值。 */
  --fs-2xs:     10px;  /* 角标：数字徽标、极小标记（**不放正文**） */
  --fs-micro:   11px;  /* 标注：chip·kicker（**不放正文**） */
  --fs-small:   12px;  /* 佐证：时间·归属·说明 */
  --fs-body:    13px;  /* **默认**：正文·表格·表单 */
  --fs-md:      14px;  /* 正文强调：表格小标题·次级标题 */
  --fs-title:   18px;  /* 区块/页面标题（16→18：与小云雀同段） */
  --fs-xl:      22px;  /* 大区块标题（19→22） */
  --fs-display: 28px;  /* 一个数：每屏至多一处（22→28） */
  --fs-hero:    34px;  /* 主视觉：空态标题·封面标题（26→34，对齐小云雀的页面主标题） */
  --lh: 1.6;           /* 正文（中文比英文宽一档） */
  --lh-tight: 1.25;    /* 标题（**单行**）：中文单行用紧的没问题 */
  /* 多行中文的紧凑档（Lark Design 的中文本地化要点：中文行距需求高于拉丁）。
     名字取创作台已有的叫法，避免同一个概念出现两种名字。 */
  --lh-snug: 1.45;
  /* **字重只有三档**，且必须落在系统字体真正有的值上（不许 650/700 —— 会被合成或取整，
     同一份 CSS 在不同机器上字重不同） */
  --fw-normal: 400;
  --fw-medium: 500;
  --fw-strong: 600;

  /* ── 间距 / 圆角 / 阴影 ─────────────────────────────── */
  /* **4 的倍数**；奇数一律不许（对齐会变成巧合） */
  --sp-1: 4px;    /* 同组内：文字与图标 */
  --sp-2: 8px;
  --sp-3: 12px;   /* 组与组 */
  --sp-4: 16px;
  --sp-5: 24px;   /* 区块之间 */
  --sp-6: 32px;
  --r-sm: 6px;    /* 内联小件：标签、徽章、表格单元格 */
  --r-md: 10px;   /* 控件：按钮、输入框、下拉 */
  --r-lg: 16px;   /* 容器：卡片、面板、浮层（2026-09-22 上提——它此前只被创作台私藏在
                     页面 :root 里，其余三面拿不到；尺寸同时对齐竞品卡片的 16px） */
  --r-pill: 999px;/* 胶囊：分段控件、状态点、提交键 */
  --shadow: 0 1px 2px rgba(0, 0, 0, .04);

  /* ── 控件高度：**只有三档**（2026-09-30 立）────────────────────────────
   * 为什么需要它（三台实测的按钮高度）：
   *   创作台 [28,45,81,29,24,34,27,31] · 管理台 [24,47,31] · 运营台 [24,40,37,48,87,29]
   * —— 同一个产品里「按钮」这个物件有八九种高度。根因：高度是 `font-size + padding`
   *   **推出来的**，而每一处的字号都不一样 ⇒ 推出来自然各不相同。
   *   控件尺寸必须是**声明的**，不是算出来的（同 Material 的 touch-target 纪律）。
   * 三档：sm = 行内/表格里的动作 · md = 默认 · lg = 表单里的主操作。
   * ⚠️ 只是**下限**（min-height）—— 高的那个（如整块可点区域）不被压低。 */
  /* ── 骨架：左栏宽（2026-09-30 立）────────────────────────────────────
   * 三台实测分别是 **248 / 220 / 220** —— 同一个产品里"导航占多宽"有三个答案，
   * 而它是最影响"这是不是同一个产品"的一个数。收成一处定义，三台共用。 */
  --rail-w: 240px;

  --ctl-sm: 26px;
  --ctl-md: 32px;
  --ctl-lg: 40px;

  /* ── 版面：内容栏的最大宽度（2026-09-30 立）────────────────────────
   * 为什么需要它：三台的内容面此前都**拉满可用宽度** —— 一张 1264px 宽的卡里
   * 只装三行字，右半边全是空的（实测：管理后台「概况」三行，标签在 356、值在 818）。
   * 给一个上限并左对齐，页面才有"栏"的感觉；表格型页面自己放宽（它们真的宽）。
   * 一处定义，三台共用 —— 不各写一个。 */
  --page-w: 1120px;

  /* ── 动效 / 层级（elevation）───────────────────────────────────
   * ⚠️ 这五个 token 原先因一处补丁错位落在 `[hidden]` 选择器里（2026-09-20 修正）——
   *    它们于是只对**隐藏元素**存在 ⇒ 凡是用到"悬停升起"的地方全部静默失效：
   *    `--dur / --ease` 拿不到值 ⇒ 过渡变成 `unset`（瞬间跳变，没有动效）；
   *    `--lift-surface / --lift-line` 拿不到值 ⇒ `background` 变透明、描边不出现。
   *    动效与层级和间距/圆角是同一类东西：**全局常量，只能住在 `:root`**。 */
  /* 时长与曲线也是一处定义（Material：动效必须有含义，一条 durations 常量表
     比在每个组件里各写一个 0.15s 更能保证含义一致）。 */
  --dur: 150ms;
  --ease: cubic-bezier(.2, 0, 0, 1);   /* Material 的标准缓出 */
}
/* ⚠️ `--shadow-lift` / `--lift-surface` / `--lift-line` 三个**不在这一层**
   （2026-09-22 移入明暗层）：暗底上阴影几乎看不见、靠"表面提亮 + 描边提亮"分层，
   亮底上则相反。它们本来就是明暗的函数，放在"与明暗无关"的常量层是错位。 */

/* ── 外观 · 深色 —— **面的默认**；也是 <html data-scheme="dark"> 的显式深色 ──
 *
 * ⚠️ **三个后台与画布共用同一族暗色**（2026-09-19 按所有者要求改）。
   此前后台是暖白底 + 深绿主色 —— 那是"企业后台"的谱系，与画布的
   （#0a0a0a 近黑 + #c4b08a 暖金）像两个产品。

   2026-09-22：`.theme-console` 与 `.theme-canvas` **合并为同一条规则**。
   两者此前的差异只是 4 处同色相不同明度的状态色 + `--line-strong`，而
   管理台的 `--line-strong: #3a3a42` **本身就违规** —— 该值对卡片 #1a1a1e
   的对比度约 1.7:1，而本文件自己的约定是"控件边界必须 ≥3:1（WCAG 1.4.11）"。
   合并取达标的那支（#6b6b74）。同一个产品不该有两种红、两种琥珀。

   对比度已逐项核对（暗底上）：
     ink 16.43 · muted 7.5 · accent 9.36 · ok 11.36 · warn 11.86 · danger 7.16
   （--line 1.39 —— 它是装饰性描边，按本文件既有约定无 3:1 要求） */
:root[data-scheme="dark"], .theme-canvas, .theme-console {
  /* color-scheme：原生件（滚动条/select 面板/number 箭头）跟随深色。一处真相。 */
  color-scheme: dark;

  /* ── 小云雀深色语言（2026-09-27 像素取证，2938×1596）──────────────────
   * 实测面阶（**不用纯黑**，层级靠小步提亮）：
   *   页面底 #111111 → 左栏 #161616 → 图标容器 #1c1c1c → 顶部 pill #242424；
   * 文字：正文 #d8d8d8，强调/标题 #f8f8f8；
   * 紫更克制：顶部一枚暗紫底 #5a428a，亮紫 #9c72fc 只作小点缀；
   * 高饱和的青蓝/红粉/暖黄仍只出现在封面缩略图 = 内容，非界面。
   * 语言归纳：深灰底 + 小步面阶 + 高亮中性文字 + **克制的紫** + 内容才是彩色。
   * 纪律：只换色相/面阶，不改对比度档位（正文≥4.5 · 控件边界≥3 · 主按钮≥4.5）。 */
  --accent: #9c72fc;        /* 品牌主行动 = 亮紫（深色下比浅色主题更克制）*/
  --accent-ink: #15101f;
  --danger: #f05349;        /* 破坏性 */
  --warn: #e0b341;          /* 需要注意 */
  --ok: #48c774;            /* 已完成/通过：状态色 */

  /* ── 中性（冷调深灰）──────────────────────────────────── */
  --bg: #111111;            /* 页面底（非纯黑）*/
  --card: #181818;          /* 卡片/表面（底 → card → panel3 小步提亮）*/
  --ink: #e6e6e6;           /* 正文 */
  --muted: #a6a6a6;         /* 次要：时间/归属/说明，≥4.5:1 */
  --line: #262626;          /* 装饰行线/容器描边 */
  --line-strong: #6c6c6c;   /* 控件边界，≥3:1 */
  --chip: #242424;          /* 状态标签底 */
  --chip-ink: #d8d8d8;

  /* ── 状态色淡底/描边（成对；暗底）────────────────────────── */
  --warn-bg: #2a2210;   --warn-line: #4a3c16;
  --ok-bg: #10261a;     --ok-line: #1c422b;
  --danger-bg: #2a1414; --danger-line: #4a2020;
  --accent-bg: #241a3d;  --accent-line: #4a3578;

  /* ── 状态色 · 补齐 / 类型色 · 色相环（2026-10-08，与浅色同一组语义名）── */
  --info: #5b9ac9;   --info-bg: #10222e;   --info-line: #1d3d51;
  --kind-1: #8f9bd8; --kind-1-bg: #1a1d2b;
  --kind-2: #6fb8c6; --kind-2-bg: #131f22;
  --kind-3: #7fb98d; --kind-3-bg: #141f18;
  --kind-4: #c4b071; --kind-4-bg: #211d13;
  --kind-5: #c39572; --kind-5-bg: #221a14;
  --kind-6: #b98fae; --kind-6-bg: #1f1720;

  /* ── 表面第三档 / 弱文字 / 卡内弱分隔线 ──────────────────── */
  --panel3: #242424;                 /* 悬停/嵌套表面/pill */
  --dim: #8c8c8c;                    /* 正文级以下弱文字 */
  --label: #a0a0a0;                  /* 微标签 */
  --line-soft: rgba(255, 255, 255, .06);

  /* ── 叠色三档：暗底靠"提亮"分层 ─────────────────────────── */
  --raise-1: rgba(255, 255, 255, .02);
  --raise-2: rgba(255, 255, 255, .045);
  --raise-3: rgba(255, 255, 255, .08);

  /* 表面边框悬停档 */
  --line-hover: #343434;

  /* 「运行中 / info」冷蓝 */

  /* 遮罩：暗底要厚 */
  --scrim: rgba(0, 0, 0, .70);
  /* ── 点阵底（`CanvasHub` 的 `.cv-dots`）· 静态点的**基线不透明度** ────────
   * 为什么它必须住在明暗层（2026-10-08 业主实测抓到）：
   *   此前这个基线在代码里**写死 0.16**，于是**它只对浅色成立** ——
   *   浅色下 `--ink`(#1f2023) 在 .16 上是清晰的浅灰点；暗色下 `--ink`(#e6e6e6)
   *   同样 .16 落在近黑底里几乎看不见。同一份点阵，两副面孔。
   * ⇒ 明暗各一个值。改点阵的强弱**只改这里**，不必再动 CanvasHub 的 JS。 */
  --dots-a: .30;

  /* 悬停"升起"：暗底靠表面提亮 + 描边提亮 */
  --shadow-lift: 0 6px 20px rgba(0, 0, 0, .40);
  --lift-surface: #232323;
  --lift-line: #3a3a3a;

  /* ── AI 身份色 = 克制的紫 ─────────────────────────────────
   * 亮紫 #9c72fc 用于标签/图标/「问 AI」；暗紫底 #241a3d 用于 AI 表面。
   * 与 --accent 统一为同一支紫：深色下品牌色即 AI 色，但面积小、不喧宾夺主。 */
  --agent: #9c72fc;
  --agent-bright: #b79bff;
  --agent-soft: #a98efd;
  --agent-faint: #c9b6ff;
  --agent-bg: #241a3d;
  --agent-line: rgba(156, 114, 252, .38);
}

/* ── 密度 ────────────────────────────────────────────────── *
 * 管理台默认「平衡」；表格页可切「紧凑」。 */
.density-compact { --sp-2: 6px; --sp-3: 10px; --sp-4: 14px; --fs-body: 12px; }
.density-cozy    { --sp-2: 12px; --sp-3: 18px; --sp-4: 26px; }

/* ── 基础元素（三个界面共用同一套写法）─────────────────────── */
.ui-body {
  margin: 0;
  font: var(--fs-body) / var(--lh) var(--font);
  background: var(--bg);
  color: var(--ink);
}
.ui-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--sp-4);
  box-shadow: var(--shadow);
}
.ui-title { font-size: var(--fs-title); font-weight: 600; margin: 0; }
.ui-display { font-size: var(--fs-display); font-weight: 600; font-variant-numeric: tabular-nums; }
.ui-muted { color: var(--muted); }
/* **数字**：等宽 + 右对齐 + 单位紧跟 —— 见《界面语言 §3.4》 */
.ui-num { font-variant-numeric: tabular-nums; }

.ui-chip {
  background: var(--chip);
  color: var(--chip-ink);
  border-radius: var(--r-pill);
  padding: 2px 9px;
  font-size: var(--fs-small);
}
.ui-btn {
  font: inherit;
  padding: var(--sp-1) var(--sp-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--card);
  color: var(--ink);
  cursor: pointer;
  /* 高度**声明**成默认档，并按文字垂直居中 —— 不再由字号推出来。 */
  min-height: var(--ctl-md);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* **主操作**：每屏至多一个 */
.ui-btn--primary { background: var(--accent); color: var(--accent-ink); border-color: var(--accent); }
/* **破坏性**：动词 + 宾语，不是"确定" */
.ui-btn--danger { color: var(--danger); }
/* ★ 2026-09-30：**按钮要有悬浮反馈**。
   实测（`CSS.forcePseudoState` 强制 :hover + 读计算样式前后差异）：`.ui-btn` 在 hover 下
   **一个属性都不变** —— 而它是**全产品共用**的按钮，创作台的「发布本层 / 生成本镜头 / 让 AI 优化」
   都是它 ⇒ 全产品的按钮都少了这层反馈（管理台的 `.act`、运营台的 `.mini` 也各有各的版本，
   那次是补齐；这里是补上**共用件**本身）。
   ⚠️ 必须写在 `--primary / --danger` **之后**：本仓的层叠按**书写顺序**裁决
      （实测：`:hover` 的优先级本高于变体类，但写在变体之前**不生效**，移到之后才生效 ——
       同 manage.css 里那条同源注记）。
   ⚠️ 强调色实心按钮**不换底色**（换成浮层色会读成"主操作被我按掉了"），只提亮一档。 */
.ui-btn:hover { background: var(--raise-2); border-color: var(--line-strong); }
.ui-btn--primary:hover { background: var(--accent); border-color: var(--accent); filter: brightness(1.10); }
.ui-btn--danger:hover { color: var(--danger); border-color: var(--danger); }
/* ═══ 禁用态：**必须看得出来** ═══════════════════════════════════════════
 * ★ 2026-09-30 普查发现：**管理台与运营台一条 `:disabled` 样式都没有**，
 *   而管理台代码里**确实在运行时禁用按钮**（审核通过/拒绝、邀请签发 —— 就是为了防连点/防重复提交）。
 *   于是那些按钮禁用后**看起来和能点的一模一样**，用户点下去没反应
 *   ⇒ 又变成"按了没反应"，而这次的原因**不是没接处理器，是没接样式**。
 *   三台都在用 `disabled` 表达状态（共 30 余处），就该有一个统一的样子。
 *
 * 取值**沿用创作台既有的 `.seg-add:disabled`**（`opacity:.45` + `not-allowed`），不另立一套。
 *
 * ⚠️ 为什么写成 `:disabled:not(:enabled)` 这种看着啰嗦的写法（实测踩过）：
 *   第一版写的是 `button:disabled`（优先级 0,1,1），而各台自带 `button.act { cursor: pointer }`
 *   也是 **0,1,1** —— 优先级相同，**而各台的 CSS 在 tokens.css 之后加载** ⇒ 它赢 ⇒
 *   实测「opacity 生效了、光标还是 pointer」：**半透明了，但鼠标移上去仍是个手**，反而更迷惑。
 *   多一个 `:not(:enabled)` 把优先级提到 0,2,1，才压得住。 */
button:disabled:not(:enabled),
input:disabled:not(:enabled),
select:disabled:not(:enabled),
textarea:disabled:not(:enabled),
.ui-btn:disabled:not(:enabled) {
  opacity: .45;
  cursor: not-allowed;
}
/* ═══ 键盘焦点：全产品一套 ═══════════════════════════════════════════════
 * ★ 2026-09-30：实测三台的焦点现状（`CSS.forcePseudoState` 强制 `:focus-visible` + 读计算样式）：
 *   · 三台的可聚焦元素**都有**焦点指示，但走的是**浏览器默认蓝框**（`outline: auto` + rgb(153,200,255)）
 *     ⇒ 与本站主色（紫）不是一套；且三台各写各的：创作台只给部分输入框写了环、
 *       运营台那条 `button:focus-visible{border-color:var(--acc)}` **被更高优先级的
 *       `#app.shell .nav button`（ID 选择器）盖掉**、管理台一条都没写。
 *   · 键盘用户**看得见**（这点没坏），但"看得见的是什么"三台不一致，也不是设计过的。
 * ⇒ 在**共用令牌层**落一条：主色焦点环 + 2px 外扩。
 *   外扩 2px 是有意的：强调色实心按钮（`.ui-btn--primary`）本身就是紫底，
 *   环必须落在按钮**外面**才分得清。
 * ⚠️ 别把它写成 `:focus`：`:focus-visible` 只在**键盘导航**时出现，鼠标点按钮不会多出一圈环。 */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.ui-input {
  font: inherit;
  /* ★ 2026-09-30：内边距 `var(--sp-1) var(--sp-2)`（4px 8px）→ `var(--sp-2) var(--sp-3)`（8px 12px）。
     原因：普查发现输入框这个**最基础的控件**四处不同规格 ——
     设计系统 4px 8px · 创作台 8px 12px · 管理台 6px 8px（还写死）· 运营台 8px 10px（右写死）。
     取**多数值**（创作台/运营台都是 8px 纵内边距）并全部走令牌 —— 这样**密度档位**
     （`.density-compact { --sp-2:6px; --sp-3:10px }`）对输入框才真正生效。
     另外：写死的 px 本身就让密度切换失效，这是原来的隐性问题。 */
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  background: var(--card);
  color: var(--ink);
}
.ui-table { width: 100%; border-collapse: collapse; }
.ui-table th, .ui-table td {
  text-align: left;
  padding: var(--sp-2) var(--sp-2);
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-body);
}
.ui-table th { color: var(--muted); font-weight: 500; }
.ui-table tr:last-child td { border-bottom: 0; }
/* 数字列右对齐（§3.4）*/
.ui-table .ui-num { text-align: right; }

/* **空态**：必须回答"为什么空 + 怎么开始"（§4.3）*/
.ui-empty { color: var(--muted); padding: var(--sp-4); text-align: center; }
/* **错误**：必须给出下一步（§4.3）*/
.ui-err { color: var(--danger); font-size: var(--fs-small); min-height: 20px; }
.ui-hint { color: var(--muted); font-size: var(--fs-small); }
