/* ============================================================
   tokens.css —— 全站唯一 :root。三层：primitive -> brand -> semantic。
   组件 CSS 只许引用 semantic 层（U2 规则由 tests/test_ui_standard.py 检查）。

   出处：docs/中台信息架构与UI标准.md §3.2
   状态：新增文件，暂无页面引用，加载后零视觉变化（落地路线 P1）
   规则：本文件是全站唯一的 :root 声明。styles.css 与 shared/common.css
         现有的三处 :root 在 P2 收敛后删除，删除前保留「旧名兼容段」。
   ============================================================ */

/* 层序声明：必须在所有样式之前。旧文件靠首尾包裹进入 legacy 层（P3）
   2026-10-17 改成一串空层块（和 `@layer reset, legacy, …;` 一句完全等价，层序照第一次出现排）：
   Chromium/Edge 100 有个 bug——同一张表里既有逗号那种 @layer 声明句、又有 @media，表被第二次加载（首页里嵌的
   /home 等小页面也引 tokens.css）时从缓存复制样式表会死循环，整页卡死、点哪都没反应（办公室一台 Edge 100 登录后就这样）。
   别改回逗号写法。 */
@layer reset{} @layer legacy{} @layer base{} @layer components{} @layer shell{} @layer page{}

/* ---------- 第 1 层 primitive：原始阶梯，只被第 2/3 层引用 ---------- */
:root{
  /* 品牌绿 10 级 */
  --g-50:#EEF6F1;  --g-100:#D8EDE1; --g-200:#B3DAC5; --g-300:#86C2A3; --g-400:#52A47E;
  --g-500:#2B8761; --g-600:#166447; --g-700:#10553C; --g-800:#0C4230; --g-900:#0A3325;

  /* 中性 13 级（--g-600 与 --n-950 是唯二延续下来的品牌资产） */
  --n-0:#FFFFFF;   --n-25:#F7F9F8;  --n-50:#EEF1EF;  --n-100:#E3E8E5; --n-200:#DCE2DF;
  --n-300:#C3CCC7; --n-400:#7E8D86; --n-500:#5E6E66; --n-600:#4A5A53; --n-700:#35423C;
  --n-800:#22302A; --n-900:#1B2621; --n-950:#15241F;

  /* 状态三色。红色补 800/900 两级：Button danger 有 hover/active 态却无 token（评审 M7） */
  --a-50:#FCF4E2;  --a-200:#E3CE9B; --a-600:#9A6A14; --a-700:#7A5310;  /* 琥珀 */
  --r-50:#FCEEEB;  --r-200:#E8C3B9; --r-600:#B5493A; --r-700:#9E4130;
  --r-800:#8A3829; --r-900:#75301F;                                    /* 红 */
  --b-50:#EAF2FB;  --b-200:#BBD3E8; --b-600:#1F6FA8; --b-700:#1A5F90;  /* 蓝 */
  --v-50:#F3EFFA;  --v-200:#D5C9EA; --v-600:#6B4FA0; --v-700:#57408A;  /* 紫 */

  /* 深色区域专用阶梯 */
  --d-bg:#15241F;        --d-sunken:#0F1B17;        --d-hover:#1E3029;   --d-selected:#1A4634;
  --d-border:#2C3F38;    --d-border-strong:#3A5048; --d-control:#5A7268;
  --d-text:#FFFFFF;      --d-text-2:#AFC2B9;        --d-text-3:#8FA69C;
  --d-accent:#6FD0A0;    --d-accent-hover:#8ADCB4;
}

/* ---------- 第 2 层 brand：换品牌 / 接第二个租户只改这一段 ---------- */
:root{
  --brand-fg:          var(--g-600);
  --brand-fg-hover:    var(--g-700);
  --brand-fg-active:   var(--g-800);
  --brand-soft-bg:     var(--g-50);
  --brand-soft-fg:     var(--g-700);
  --brand-soft-border: var(--g-200);
  --brand-dark-bg:     var(--d-bg);
  --brand-dark-accent: var(--d-accent);
}
/* 多租户示例（今天不启用，字段位先留）：
   [data-brand="itop"]{ --brand-fg:#0F5C8C; --brand-soft-bg:#EAF2FB; } */

/* ---------- 第 3 层 semantic：组件 CSS 只许用这一层 ---------- */
:root{
  /* 面 */
  --canvas:           var(--n-50);    /* #EEF1EF 页面地 */
  --surface:          var(--n-0);     /* #FFFFFF 卡片/面板/表格/弹窗/输入框 */
  --surface-sunken:   var(--n-50);    /* #EEF1EF 表头/只读区/禁用控件 */
  --surface-hover:    var(--n-25);    /* #F7F9F8 行 hover / ghost hover */
  --surface-selected: var(--brand-soft-bg); /* #EEF6F1 选中行/当前导航底 */
  /* 浮层优先靠阴影+边框区分，不靠色差；深色区阴影不可见，故在深色段改用色差重绑（评审 M6） */
  --surface-raised:   var(--n-0);

  /* 描边 */
  --border:         var(--n-200);  /* #DCE2DF 卡片边框/分隔线 */
  --border-subtle:  var(--n-100);  /* #E3E8E5 表格行间线（比容器边框弱一档，50 行不发灰） */
  --border-strong:  var(--n-300);  /* #C3CCC7 需要被看见的分隔 */
  --border-control: var(--n-400);  /* #7E8D86 input/select/checkbox 边界，3.48:1 ✓ */

  /* 文字 —— 对比度为实算值，由 test_contrast 复核 */
  --text-primary:     var(--n-900);  /* #1B2621 on #fff = 15.60:1 */
  --text-secondary:   var(--n-600);  /* #4A5A53 on #fff =  7.30:1 */
  --text-muted:       var(--n-500);  /* #5E6E66 on #fff = 5.39:1 / on #EEF1EF = 4.74:1 */
  --text-placeholder: var(--n-500);  /* placeholder 是文字，必须 4.5:1，禁止用 --n-400 */
  --text-disabled:    var(--n-400);  /* 仅禁用态，豁免 4.5:1 */
  --text-on-accent:   var(--n-0);    /* #fff on #166447 = 7.12:1 */

  /* 强调 */
  --accent:             var(--brand-fg);
  --accent-hover:       var(--brand-fg-hover);
  --accent-active:      var(--brand-fg-active);
  --accent-soft-bg:     var(--brand-soft-bg);
  --accent-soft-fg:     var(--brand-soft-fg);
  --accent-soft-border: var(--brand-soft-border);
  --focus-ring:         var(--g-700);  /* 全站唯一焦点色，用法固定 2px solid + 2px offset */

  /* 语义状态：五色 × 三件套 */
  --success-fg:var(--g-700); --success-bg:var(--g-50); --success-border:var(--g-200);
  --warning-fg:var(--a-700); --warning-bg:var(--a-50); --warning-border:var(--a-200);
  --danger-fg: var(--r-700); --danger-bg: var(--r-50); --danger-border: var(--r-200);
  --danger-solid:var(--r-700);              /* 白字在实心上 6.46:1 */
  --danger-solid-hover:var(--r-800);
  --danger-solid-active:var(--r-900);
  --info-fg:   var(--b-700); --info-bg:   var(--b-50); --info-border:   var(--b-200);
  --neutral-fg:var(--n-600); --neutral-bg:var(--n-50); --neutral-border:var(--n-200);

  /* 遮罩：全站唯一值，不带 backdrop-filter */
  --overlay: rgba(16, 26, 22, .55);

  /* 骨架屏两色（规范钦点 skeleton 为默认加载态，缺它第一个组件就卡住） */
  --skeleton-base:  var(--n-50);
  --skeleton-sheen: var(--n-25);

  /* 头像 */
  --avatar-bg: var(--g-100);
  --avatar-fg: var(--g-700);   /* #10553C on #D8EDE1 = 6.99:1 */

  /* 文本选中 */
  --selection-bg: var(--g-100);
  --selection-fg: var(--text-primary);

  /* 荧光笔道（产品表「特点」里的关键参数，10-23）：比搜索 <mark>（--warning-bg 整块）更黄、只画字的下半截；--fluo-line 是打印时的下划线 */
  --fluo-bg: #FBE7A1; --fluo-line: #E5C45A;

  /* 消息气泡（组件 #16）。--bubble-mine 是全站唯一允许保留旧值的颜色：
     微信语义的一部分，一线靠它一眼分辨「这条是我发的」，改色会被误读成发送失败 */
  --bubble-mine: #95ec69;

  /* 图表（禁止裸色值的必然配套） */
  --chart-1:#166447; --chart-2:#1F6FA8; --chart-3:#B5493A; --chart-4:#7A5AA6;
  --chart-5:#9A6A14; --chart-6:#2F8F8F; --chart-7:#A0507E; --chart-8:#5E6E66;
  --chart-seq-1:#D8EDE1; --chart-seq-2:#86C2A3; --chart-seq-3:#2B8761;
  --chart-seq-4:#10553C; --chart-seq-5:#0A3325;
  --chart-positive:#2B8761; --chart-negative:#B5493A;
  --chart-axis:var(--n-300); --chart-grid:var(--n-100); --chart-zero:var(--n-400);
}

/* ---------- 深色区域：同名重绑，组件 CSS 一行不改 ---------- */
[data-surface="dark"]{
  --canvas:           var(--d-bg);
  --surface:          var(--d-bg);
  --surface-sunken:   var(--d-sunken);
  --surface-hover:    var(--d-hover);
  --surface-selected: var(--d-selected);
  --surface-raised:   var(--d-hover);   /* 深色区阴影不可见，改用色差（评审 M6 的取舍） */
  --border:           var(--d-border);
  --border-subtle:    var(--d-border);
  --border-strong:    var(--d-border-strong);
  --border-control:   var(--d-control);  /* #5A7268 on #15241F = 3.10:1 ✓ */
  --text-primary:     var(--d-text);     /* 16.10:1 */
  --text-secondary:   var(--d-text-2);   /*  8.62:1 */
  --text-muted:       var(--d-text-3);   /*  6.21:1 */
  --text-placeholder: var(--d-text-3);
  --text-disabled:    var(--d-control);
  --text-on-accent:   var(--d-bg);       /* #15241F on #6FD0A0 = 8.59:1 */
  --accent:           var(--brand-dark-accent);
  --accent-hover:     var(--d-accent-hover);
  --accent-soft-bg:   var(--d-selected);
  --focus-ring:       var(--brand-dark-accent);
  --avatar-bg:        var(--d-selected);
  --avatar-fg:        var(--d-text);
  --skeleton-base:    var(--d-hover);
  --skeleton-sheen:   var(--d-border);
  --bubble-mine:      var(--d-selected);
  /* 不重绑滚动条，深色侧栏会出现亮色滚动条（评审 M7） */
  scrollbar-color: var(--d-control) var(--d-bg);
}
/* 禁止组合（写成断言，不靠人记）：
   --text-muted(#8FA69C) 不得出现在 --surface-selected(#1A4634) 上 —— 实算 4.11:1，不达标。
   该组合只允许 --text-secondary（5.71:1）或 --text-primary（10.66:1）。 */

/* ---------- 排版 ---------- */
:root{
  /* 不引 Inter：全站从未交付过它，而旧 CSS 用了 6 个变量字体专用字重。
     代价是不同员工机字形略有差异；收益是字重层级在所有机器上都成立。 */
  --font-sans: system-ui, -apple-system, "Segoe UI", "PingFang SC",
               "Microsoft YaHei", "Hiragino Sans GB", sans-serif;
  --font-mono: ui-monospace, "SF Mono", Consolas, "Liberation Mono", monospace;

  /* 字号/行高成对定义，禁止单独改其一。最小 12px —— 删除全部 10/10.5/11/11.5/12.5/13.5px */
  --fs-xs:12px;  --lh-xs:18px;
  --fs-sm:13px;  --lh-sm:20px;    /* 正文基准 */
  --fs-md:14px;  --lh-md:22px;
  --fs-lg:16px;  --lh-lg:24px;
  --fs-xl:20px;  --lh-xl:28px;
  --fs-2xl:26px; --lh-2xl:34px;
  --fs-metric:30px; --lh-metric:36px;  /* 仅指标卡数字，配 font-variant-numeric:tabular-nums */
  --lh-prose:1.7;                      /* 唯一例外，只许用在 .prose 多行段落 */

  /* 字重 4 档。删除 550/560/620/650/750/760 */
  --fw-regular:400; --fw-medium:500; --fw-semibold:600; --fw-bold:700;
}

/* ---------- 间距 / 圆角 / 阴影 / 描边 / 图标 ---------- */
:root{
  /* 4px 基数，8 级 */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px;
  --sp-5:20px; --sp-6:24px; --sp-8:32px; --sp-12:48px;

  /* 圆角 3 级 + 胶囊 */
  --radius-sm:6px;     /* 按钮/输入/select/checkbox/小标签 */
  --radius-md:10px;    /* 卡片/面板/表格容器/模态/抽屉/下拉面板 */
  --radius-lg:14px;    /* 仅全屏级容器：登录卡、空态大图标底 */
  --radius-full:999px; /* 状态点/头像/pill 筛选。禁止再写 99px */
  --radius-bubble:4px 12px 12px 12px; /* 对方气泡；自己气泡水平镜像（组件 #16） */

  /* 阴影 3 级 */
  --shadow-1:0 1px 2px rgba(20,35,29,.08);
  --shadow-2:0 6px 16px rgba(20,35,29,.12);
  --shadow-3:0 16px 40px rgba(20,35,29,.20);

  --bw-hair:1px;       /* 所有分隔与边框 */
  --bw-focus:2px;      /* 焦点环 */
  --bw-indicator:3px;  /* 当前项指示条、tab 下划线、row-tone 竖条 */

  /* 图标尺寸档（规范多处点名像素却无 token，评审 M7） */
  --icon-sm:16px;   /* 弹层关闭键、输入框前后缀 */
  --icon-md:20px;   /* 按钮内图标、表格行操作 */
  --icon-rail:24px; /* 一级图标栏 */
  --icon-lg:32px;   /* EmptyState panel 变体 */
  --icon-xl:48px;   /* EmptyState page 变体 */
}

/* ---------- 控件尺度与密度轴 ---------- */
:root{
  --ctl-h-sm:32px; --ctl-h-lg:44px;
  --ctl-h:36px;    /* 默认控件高 */
  --row-h:40px;    /* 表格/列表行高 */
  --cell-px:12px;  /* 单元格左右内边距 */
}
/* 密度是一个标量，不是某个组件的变体。列表页模板默认 compact。
   compact 下 sm 同步降到 28px，否则 md 与 sm 拉平、三档退化成两档（评审 M5）。 */
[data-density="compact"]{ --ctl-h:32px; --ctl-h-sm:28px; --row-h:32px; --cell-px:10px; }

/* ---------- 层级 ---------- */
:root{
  --z-base:0; --z-sticky:100; --z-nav:200; --z-dropdown:300;
  --z-popover:400; --z-modal:500; --z-toast:600;
  /* 原生 <dialog> 走浏览器 top layer，不使用 --z-modal */
}

/* ---------- 动效 ---------- */
:root{
  --dur-fast:120ms;  /* hover / focus / 变色 */
  --dur-base:180ms;  /* 展开 / 淡入 / Toast */
  --dur-slow:260ms;  /* 抽屉 / 模态入场 */
  --ease: cubic-bezier(.2,0,0,1);
}
@media (prefers-reduced-motion: reduce){
  :root{ --dur-fast:0ms; --dur-base:0ms; --dur-slow:0ms; }
}

/* ---------- 宽度与容器 ---------- */
:root{
  --w-rail:72px;        /* 一级图标栏 */
  --w-nav-panel:208px;  /* 二级面板，自带 overflow-y:auto */
  --topbar-h:56px;
  --page-max:1440px;    /* 内容区最大宽 */
  --prose-max:68ch;     /* 正文段落最大宽 */
  --form-max:560px;
  --modal-sm:420px; --modal-md:560px; --modal-lg:760px;
  --drawer-sm:360px; --drawer-md:480px; --drawer-lg:640px;
}

/* ---------- 断点（CSS 不支持在 @media 里用变量，此处为唯一权威声明，脚本按它做白名单）
   宽度：640 / 900 / 1280 / 1600
   高度：860（唯一的高度断点，专治 1366x768）
   ---------------------------------------------------------- */

/* ============================================================
   旧名兼容段（P2 起为生效状态：全部指向语义 token）
   作用：17 个 legacy CSS 里对旧变量名的引用继续工作，值来自新色板。
   旧 :root 已全部删除（styles.css×2 / shared/common.css / ui-polish.css）。
   legacy 文件在 P3-P5 迁移中逐个消亡后，本段随之删除。
   - --canvas 不在此段：语义层已定义同名 token，这里再写会遮蔽它。
   - --wx-mine 指向 --bubble-mine（全站唯一保留旧值的颜色，微信语义）。
   - --control-border 指向 --border-control：输入框边界从 1.3:1 提到 3.48:1，
     是 P2 刻意的可见变化，不是回归。
   机器检查：tests/test_ui_standard.py::test_compat_covers_legacy_names
   ============================================================ */
:root{
  --ink:        var(--text-primary);
  --ink-2:      var(--text-secondary);
  --muted:      var(--text-muted);
  --line:       var(--border-subtle);
  --line-strong:var(--border);
  --card:       var(--surface);
  --sidebar:    var(--d-bg);
  --green:      var(--accent);
  --green-2:    var(--g-500);
  --green-soft: var(--accent-soft-bg);
  --mint:       var(--focus-ring);      /* 旧用法即焦点环，并入统一焦点色 */
  --amber:      var(--a-600);
  --coral:      var(--danger-fg);
  --blue:       var(--b-600);
  --shadow:     var(--shadow-1);        /* 旧 40px 大模糊让每张卡发灰，收敛为 1 级 */
  --wx-bg:      var(--canvas);
  --wx-mine:    var(--bubble-mine);
  --control-height:40px;                /* 尺度类保持旧值，P3 由 ui.css 的 --ctl-h 接管 */
  --control-radius:8px;
  --control-border:var(--border-control);
  --selection-border:var(--border);
}

/* ============================================================
   飞书监控页专用段（/feishu）
   出处：app/static/feishu/feishu.css 原本自带一份 :root，用户要求该页视觉
   与飞书桌面端一致（员工零学习成本），所以色值刻意不取本文件的语义 token。
   但 :root 只能有一个家（test_single_root），裸色值也只允许出现在本文件
   （test_no_bare_hex），因此把定义搬到这里、用法留在那边。
   **这些值是飞书的品牌色，不要"收敛"成 --accent / --text-primary 之类，
   一改那页就不像飞书了。** /feishu 页下线时整段删除。
   机器检查：tests/test_ui_standard.py::test_single_root / test_no_bare_hex
   ============================================================ */
:root{
  --fs-blue:         #3370ff;   /* 飞书主蓝：链接、@、选中强调 */
  --fs-blue-bg:      #e1eaff;   /* 蓝色淡底：选中会话、机器人标签 */
  --fs-blue-bg-soft: #f0f4ff;   /* 更淡的蓝底：详情页高亮块 */
  --fs-text:         #1f2329;   /* 正文 */
  --fs-text-2:       #646a73;   /* 次要文字 */
  --fs-text-3:       #8f959e;   /* 时间、弱提示 */
  --fs-border:       #dee0e3;   /* 分割线 */
  --fs-border-light: #eff0f1;
  --fs-bg:           #ffffff;
  --fs-bubble:       #f2f3f5;   /* 消息气泡灰 */
  --fs-bubble-hover: #ebedf0;   /* 带引用的气泡 hover */
  --fs-hover:        #f2f3f5;
  --fs-hint-bg:      #fdf6e3;   /* 顶部提示条底色 */
  --fs-quote-bar:    #bbbfc4;   /* 引用行左侧竖线 */
  --fs-green:        #2ea121;
  --fs-green-bg:     #e8f7ee;   /* 任务号标签底色 */
  --fs-danger:       #f54a45;
}

/* ============================================================
   数据表的「选项色板」（/table 的下拉、成员、关联字段上色）
   出处：用户 2026-09-24 要求「下拉、人员选择这些类型像简道云一样带颜色」。
   **简道云的真配色拿不到**——开放接口 widget/list 只返回 name/label/type，
   既没有选项清单也没有颜色（实测）。所以这里是我们自己的一套 8 档软色板，
   由取值稳定哈希取档（static/shared/fields.js 的 optionTone），
   保证同一个取值在表格、行详情、筛选标签里颜色一致。
   一律浅底深字：深底当标签底色会看不清字（2026-09-21 那次反馈的同款坑）。
   机器检查：tests/test_ui_standard.py（裸色值与 :root 只允许出现在本文件）
   ============================================================ */
:root{
  --tag-0-bg:var(--g-50);   --tag-0-fg:var(--g-700);
  --tag-1-bg:var(--b-50);   --tag-1-fg:var(--b-700);
  --tag-2-bg:var(--a-50);   --tag-2-fg:var(--a-700);
  --tag-3-bg:var(--r-50);   --tag-3-fg:var(--r-700);
  --tag-4-bg:var(--v-50);   --tag-4-fg:var(--v-700);   /* 紫，复用已有阶梯 */
  --tag-5-bg:#E4F3F2;       --tag-5-fg:#1F6B66;   /* 青 */
  --tag-6-bg:#F7EDF3;       --tag-6-fg:#8A3B6B;   /* 品红 */
  --tag-7-bg:var(--n-100);  --tag-7-fg:var(--n-700);
  /* 成员与关联不参与哈希，各自固定一档，一眼能和「选项」区分开 */
  --tag-person-bg:#E9F0FA;  --tag-person-fg:#2A5A8C;
  --tag-link-bg:#F1EFE9;    --tag-link-fg:#6B5A33;
}
