/* =========================================================================
   TradeTool 设计令牌 —— 依《前端唯一真源 v2.0》§三 重建（2026-07-22）

   双层结构。**组件层与模板只许引用语义层**；引用 --_raw-* 或字面 hex/px 即 bug
   （scripts/css-lint.sh 执法）。

   ✅ Step 2 已拆除「过渡桥」：旧令牌名（--color-* / --bg-* / --text-* / --border-* /
   --shadow-* / --control-* / --leading-* / 琥珀族 / 品牌中间色阶）全部删除，
   组件层 99 处引用已归入本文件的语义层。**本文件即 v2 §三 的全部，没有第二套。**
   ========================================================================= */

/* —— vendored 字体（无 CDN，woff2 入库）——
   Inter（拉丁/数字）+ Noto Sans SC（中文，子集化 400/500/600）。
   放 tokens.css 而非 app.css：Django admin 也加载它，前后台字体一致。 */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/inter-latin-wght-normal.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+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Noto Sans SC";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/noto-sans-sc-400.woff2") format("woff2");
  unicode-range: U+2E80-9FFF, U+3000-303F, U+FF00-FFEF, U+FE30-FE4F;
}
@font-face {
  font-family: "Noto Sans SC";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/noto-sans-sc-500.woff2") format("woff2");
  unicode-range: U+2E80-9FFF, U+3000-303F, U+FF00-FFEF, U+FE30-FE4F;
}
@font-face {
  font-family: "Noto Sans SC";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/noto-sans-sc-600.woff2") format("woff2");
  unicode-range: U+2E80-9FFF, U+3000-303F, U+FF00-FFEF, U+FE30-FE4F;
}
/* 700：2026-08-03 A9 新增的一档。**必须有这条 @font-face，否则 700 是哑的**——
   body 上钉了 `font-synthesis-weight: none`（禁伪粗），声明缺失时 700 会静默落回 600，
   而"没变粗"和"变粗了一点点"肉眼分不出（同 L-16 那一类静默失效）。 */
@font-face {
  font-family: "Noto Sans SC";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/noto-sans-sc-700.woff2") format("woff2");
  unicode-range: U+2E80-9FFF, U+3000-303F, U+FF00-FFEF, U+FE30-FE4F;
}

:root {
  /* ============ 原始层（组件禁引） ============ */
  /* 中性阶（全档）＝slate 冷灰。2026-08-03 A9 复核后**保留**：
     新参照物（Linear/Stripe/Cursor）用的正是冷灰，换暖灰会往旧参照物 Shopify 那一侧走。 */
  --_raw-n0:#ffffff;  --_raw-n25:#fcfdfe; --_raw-n50:#f8fafc;
  --_raw-n100:#f1f5f9;--_raw-n200:#e2e8f0;--_raw-n300:#cbd5e1;
  --_raw-n400:#94a3b8;--_raw-n500:#64748b;--_raw-n600:#475569;
  --_raw-n700:#334155;--_raw-n800:#1e293b;--_raw-n900:#0f172a;
  /* 品牌阶（2026-08-16 修宪：靛蓝 #4f46e5 → **深青** #0e7490 一族；改品牌色仍只改本组）
     换的理由：靛蓝是 AI 产品用得最滥的那支色、「AI 味」的头号来源；深青带航海与
     国际贸易的联想，在同类软件里没被用滥。一套界面 × A 深青 / B 深海蓝两套色样张，
     老板 2026-08-16 深夜看图选定 A（四代沿革见 docs/修宪记录.md）。
     ⚠️ 换色必须同步 static/img/favicon.svg 与 static/brand/logo.svg 里写死的色值
     （SVG 引不到 CSS 变量）。 */
  --_raw-brand-50:#ecfeff; --_raw-brand-100:#cffafe; --_raw-brand-500:#0891b2;
  --_raw-brand-600:#0e7490; --_raw-brand-700:#155e75;
  /* 语义三族（文字色 / 浅底 / 描边） */
  --_raw-green:#067647;  --_raw-green-bg:#ecfdf3;  --_raw-green-line:#abefc6;
  --_raw-orange:#b54708; --_raw-orange-bg:#fffaeb; --_raw-orange-line:#fedf89;
  --_raw-red:#b42318;    --_raw-red-bg:#fef3f2;    --_raw-red-line:#fecdca;
  /* 危险确认态（2026-08-16 修宪，铁律③）：暗砖红，跟语义红分色值分形态——
     同一屏一颗等确认的删除钮和一枚「退信」红徽章不许长得一样。批②接到按钮上。 */
  --_raw-brick:#7f1d1d; --_raw-brick-bg:#fdf2f2;
  /* 数据色阶（2026-08-16 修宪，铁律②）：品牌色系浅→深 5 档，只进数据部位
     （漏斗量感条、战报格、分布条形、匹配分小条），深浅只表「多少」；
     禁入按钮、文字语义与状态徽章。 */
  --_raw-data-1:#ccfbf1; --_raw-data-2:#7dd3c8; --_raw-data-3:#2db5a5;
  --_raw-data-4:#0e8b80; --_raw-data-5:#0f5e63;
  /* 身份底色族（2026-08-16 修宪，铁律②）：按大洲固定映射，只垫客户身份件的
     首字母块；每洲一对（底色 + 字色）。不用哈希随机取色——相邻撞色会造假规律。 */
  --_raw-id-eu:#e7ecf6;   --_raw-id-eu-ink:#38507a;
  --_raw-id-asia:#f3ecdf; --_raw-id-asia-ink:#7a5c2e;
  --_raw-id-me:#f0e8e0;   --_raw-id-me-ink:#7d5a3c;
  --_raw-id-am:#e6f0e8;   --_raw-id-am-ink:#3d6a4a;
  --_raw-id-af:#f4e9e4;   --_raw-id-af-ink:#7d4a38;
  --_raw-id-oc:#e5eef2;   --_raw-id-oc-ink:#3a6273;

  /* ============ 语义层（唯一合法入口） ============ */
  /* 表面（2026-08-03 A9：整体各压深一档，让白卡片真的"浮"起来）
     此前 page=n50 / card=白 / sunken=n25——**三档挤在最亮的那一端**，
     卡片边界几乎只靠那 1px 细边撑着，卡内下沉区（n25 vs 白）更是肉眼分不出，
     于是整页读起来是一张平铺的白纸。这是老板说"太冷淡单调"的结构性来源之一。 */
  --surface-page:   var(--_raw-n100);  /* 画布：压深一档，卡片才有浮起来的余地 */
  --surface-card:   var(--_raw-n0);
  /* 卡面顶光渐变的终点（2026-08-04 C 套修宪）：卡面自上而下 白→n25 一档之内，
     **只表达深度、不表达含义**。正文功能区只许这一种渐变，其余渐变仍限未登录门面。 */
  --surface-card-lift: var(--_raw-n25);
  --surface-sunken: var(--_raw-n50);   /* 卡内下沉区、表格行 hover（n25→n50，真的看得见了） */
  /* 卡内操作台那条灰（F-6.17 第 8 条，2026-08-23）：**必须比 sunken 深一档**——
     n50 的台画过一版，实测与卡面对比度 1.01:1，正是"等于没画"那种（2026-08-22 采证原话）。
     指向已有原始值 n100，不引新原始值。 */
  --surface-deck:   var(--_raw-n100);
  --surface-hover:  var(--_raw-n100);  /* 控件 hover、tonal 按钮底（落在白卡上，仍可辨） */
  --surface-pressed:var(--_raw-n200);
  /* 文字 */
  --ink-strong: var(--_raw-n900);
  --ink-body:   var(--_raw-n800);
  /* **n500 → n600（2026-08-03 A9）**：两个理由，各自都足够。
     ① 画布压到 n100 后，n500 的灰字在页面底上只有 4.34:1，**掉出 WCAG AA**（此前 4.55:1 也只是刚过）；
     ② 发白的次级文字本身就是"冷淡"的一大来源——全站元信息都是这一档。
     n600 在新画布上 6.9:1、在白卡上 7.6:1，两处都宽裕。 */
  --ink-muted:  var(--_raw-n600);
  --ink-inverse:#ffffff;
  /* 描边（岗位见 S7） */
  --line-input: var(--_raw-n300);   /* 可输入控件默认边 */
  --line-row:   var(--_raw-n100);   /* 表格/列表行分隔 */
  --line-strong:var(--_raw-n800);   /* 深描边按钮档专用 */
  --line-card:  var(--_raw-n200);   /* 卡片/壳层轮廓（描边第四岗位，2026-07-29 修宪新增） */
  /* 含义色（S2 五色表） */
  /* 主动作色（2026-08-16 铁律③：主按钮上色）：近黑退出主动作岗位、只留给正文墨色
     与慎重档描边；主动作＝品牌色实心。跟 --meaning-interactive 同值不同职——
     一个管"这里最该做的那件事"，一个管"可交互与选中"。 */
  --meaning-action:      var(--_raw-brand-600);
  --meaning-action-hover:var(--_raw-brand-700);
  --meaning-interactive:      var(--_raw-brand-600);  /* 品牌=可交互/选中 */
  --meaning-interactive-hover:var(--_raw-brand-700);
  --meaning-interactive-bg:   var(--_raw-brand-50);
  --meaning-interactive-line: var(--_raw-brand-100);
  /* 展示级数字的墨色（2026-08-18 铁律②「展示级数字染品牌深档」的语义入口，批 3 建）：
     只给铁律④里用 tabular-nums 的那一档数字——漏斗段计数、战报数字、作业台队列数。
     **正文里的数字不染**，还是墨色。跟 --meaning-interactive-hover 同值不同职：
     一个是"鼠标压上去的那一刻"，一个是常驻的展示墨色，混用会让改色时改错一处。 */
  --ink-display: var(--_raw-brand-700);
  --meaning-positive: var(--_raw-green);  --meaning-positive-bg: var(--_raw-green-bg);  --meaning-positive-line: var(--_raw-green-line);
  --meaning-caution:  var(--_raw-orange); --meaning-caution-bg:  var(--_raw-orange-bg); --meaning-caution-line:  var(--_raw-orange-line);
  --meaning-negative: var(--_raw-red);    --meaning-negative-bg: var(--_raw-red-bg);    --meaning-negative-line: var(--_raw-red-line);
  /* 危险确认态（铁律③，批②接到按钮上） */
  --confirm-danger: var(--_raw-brick); --confirm-danger-bg: var(--_raw-brick-bg);
  /* 数据色阶与身份底色的语义入口（组件层只许引这两族，不许引 --_raw-*；
     用途边界见铁律②：数据色阶只进数据部位，身份底色只垫身份件首字母块） */
  --data-1: var(--_raw-data-1); --data-2: var(--_raw-data-2); --data-3: var(--_raw-data-3);
  --data-4: var(--_raw-data-4); --data-5: var(--_raw-data-5);
  --ident-eu-bg: var(--_raw-id-eu);     --ident-eu-ink: var(--_raw-id-eu-ink);
  --ident-asia-bg: var(--_raw-id-asia); --ident-asia-ink: var(--_raw-id-asia-ink);
  --ident-me-bg: var(--_raw-id-me);     --ident-me-ink: var(--_raw-id-me-ink);
  --ident-am-bg: var(--_raw-id-am);     --ident-am-ink: var(--_raw-id-am-ink);
  --ident-af-bg: var(--_raw-id-af);     --ident-af-ink: var(--_raw-id-af-ink);
  --ident-oc-bg: var(--_raw-id-oc);     --ident-oc-ink: var(--_raw-id-oc-ink);
  /* 下沉输入底（2026-08-17 批④拆混装第一刀：输入框改下沉灰底无边框、聚焦转白底＋品牌色环，
     跟按钮彻底分形——形状对照表「输入框」行，2026-08-16 随 A 深青样张拍板。
     与 --surface-hover 同值不同职：一个是输入框的常驻底，一个是控件悬停的瞬时底。 */
  --surface-field: var(--_raw-n100);
  /* 反色浮层（批量选择条这类吸底深色件，形状对照表「容器类」行）：
     深底 n900＋反白正文＋反色弱墨。身份是浮层不是含义色，不进五色表。 */
  --surface-inverse:  var(--_raw-n900);
  --ink-inverse-muted: var(--_raw-n400);
  /* 复选框定值（形状对照表「复选框」行：16px · 圆角 4 · 选中品牌实底白勾，
     2026-08-16 随样张拍板）。不是控件高档位（那是 --ctl-* 的地盘），是方形小件的边长。 */
  --check-size: 16px;
  --radius-check: 4px;
  /* 状态族（推导规则见 §四） */
  --state-disabled-bg:  var(--_raw-n100);
  --state-disabled-ink: var(--_raw-n400);
  --state-focus-outline: 2px solid var(--_raw-brand-600);  /* 配 outline-offset:2px */
  --line-input-focus:   var(--_raw-brand-600);
  --line-input-error:   var(--_raw-red);
  /* 字体栈（真源）。--font-stack-* 供 app.tailwind.css 的 @theme 桥引用：
     Tailwind 产物会把 --font-sans 重新发到 :root 且加载顺序在本文件之后，
     桥若写 `--font-sans: var(--font-sans)` 就是自引用循环＝变量作废——
     这正是 2026-08-01 前"Inter+Noto Sans SC 从未上过屏"的根因（守卫检查③钉着）。
     --font-sans/--font-mono 本体也在此定义：Django admin 只加载本文件不加载 app.css，
     admin-tweaks.css 的 var(--font-sans) 靠这两行才有值。 */
  --font-stack-sans: "Inter", "Noto Sans SC", system-ui, "Segoe UI", "Microsoft YaHei", sans-serif;
  --font-stack-mono: ui-monospace, "Cascadia Mono", Consolas, monospace;
  --font-sans: var(--font-stack-sans);
  --font-mono: var(--font-stack-mono);
  /* 字号角色（五档封闭，12px 全站地板，无例外）
     **2026-08-03 A9 拉开阶距**（老板：「字号 加粗不加粗这方面你可以大胆些，现在页面太冷淡单调了」）。
     旧阶 30/20/15/14/12 的病灶是 **section 15 与 body 14 只差 1px**——分区标题和正文
     肉眼几乎一样重，层级全靠字重硬撑，于是整页读起来是平的。
     新阶只把上三档拉开，**body 14 与 meta 12 一个都不动**：动了就掉密度，
     而密度是这个工具的核心（理念③密而齐）。 */
  /* 40 **只给展示级数字**（首页战报、漏斗段计数、统计格、队列数、登录门面那句）。
     2026-08-19 起**逐条卡公司名不再用它**——老板两次点观感（「字号太多太乱」
     「跟其他地方比很割裂」），而公司名不是数字，它当时还比页面标题 28 更大。已降到 --font-title。 */
  --font-display: 40px;  /* 展示级数字（30→36→40；2026-08-18 界面第二期修宪，铁律④） */
  --font-title:   28px;  /* 页面 h1（20→24→28；同上，2026-08-18 随气质定稿改） */
  --font-section: 17px;  /* 卡片/分区标题（15→17，与正文拉开 3px 而不是 1px） */
  --font-body:    14px;  /* 正文=body 基准（不动） */
  --font-meta:    12px;  /* 元信息、键位提示、表头（全站地板，不动） */
  /* 字重（**2026-08-03 A9：600 封顶放开到 700**）
     旧的「加粗一律 600」并不是设计判断，是子集化当初只做了 400/500/600 三档、
     700 没有真字形，于是把"没做"写成了"不该做"。现已补出 noto-sans-sc-700.woff2
     （582KB，四档合计 2.25MB，仍在 2.5MB 红线内），700 是**真字形不是伪粗**。
     分工：700 给标题（display/title/section），600 给卡内小标题与强调，正文一律 400。 */
  --weight-normal:400; --weight-medium:500; --weight-semibold:600; --weight-bold:700;
  /* 层次（2026-08-16 修宪，铁律⑤）：常驻两档 + 悬停抬升一档。
     elev-card 双层——近处 1px 描出卡缘、远处一层大而淡的落影给出浮起感（2026-08-04 C 套定型，
     本轮按样张微调轻了一点）；elev-lift 只随卡片 hover 抬升 1px 出现、不常驻——
     全站 175 张卡零 hover 那次诊断的解药之一。 */
  --elev-card:    0 1px 2px rgba(15,23,42,.04), 0 10px 28px -16px rgba(15,23,42,.14);
  --elev-lift:    0 2px 4px rgba(15,23,42,.05), 0 16px 40px -18px rgba(15,23,42,.20);
  --elev-overlay: 0 10px 28px -8px rgba(15,23,42,.18);
  /* 控件（2026-08-17 修宪随批④：常规 40→34、小 32→28，形状对照表 2026-08-16 随样张拍板；
     48 仅登录与移动主按钮、nav 36、芯片 28 不动。同日 --ctl-sm 与 --chip-h 同值属巧合不属合并：
     一个是控件档、一个是芯片档，角色不同，不许因此删掉其中一个。 */
  --ctl-lg:48px; --ctl-md:34px; --ctl-nav:36px; --ctl-sm:28px; --chip-h:28px;
  /* 卡片圆角 8→10px（2026-08-16 随形状对照表定，PRD §3.1 视觉基调行同批已改）：
     样张里主卡＝圆角 10 + 双层影 + 悬停抬升，老板看图选定；控件仍是 6px 不动。
     （2026-08-03 A9 曾把 10 收到 8，本轮按拍板的样张回到 10——不是复辟旧值，
     是配着新的阴影与 hover 一整套定的。） */
  --radius-ctl:6px; --radius-card:10px; --radius-pill:9999px;
  /* 动效。两档管两类事：--dur＝控件状态过渡与小浮层出场；--dur-slow＝大件出场
     （批量选择条这类从页底浮出的整条，150ms 会闪、220ms 才看得出"从哪来"）。
     全站动效只取这两档（150–250ms 带内），别再回组件里写字面毫秒数。 */
  --dur:150ms; --dur-slow:220ms; --ease:cubic-bezier(.22,.8,.32,1);
  /* 布局骨架 */
  /* --content-max 2026-08-18 由 1320 改 1600：老板在 2560 宽屏上看图拍板，
     原话「宽度上限为1600 就用这个」。配套见 --action-row-max。 */
  /* --detail-max 2026-08-22 新开一档（界面第二期批 11，台账 L-37）：
     详情页既不是要横向比对的宽页、也不是一件事一屏的窄流页。
     1120 是唯一一档让属性表排 3 列、空率又最低的（实测客户详情：
     736 排 2 列空 7%、960 排 2 列空 15%、1120 排 3 列空 6%、1600 排 4 列空 10%）。
     🔴 站内信详情不走这一档，它跟全部消息那一页是一对、留在 --flow-max（PRD F-24.15）。 */
  --sidebar-w:244px; --topbar-h:60px; --content-max:1600px; --detail-max:1120px; --flow-max:720px;
  /* 正文一行最长 40em（铁律⑫）。原先只有 `p { max-width: 40em }` 一条硬编码，
     dd 与 .prewrap 一个都没盖住——优秀开发信详情那封原信实测一行 1518px。
     2026-08-22 提成令牌，谁要收口引它，别各写各的（台账 L-38）。 */
  --read-max:40em;
  /* 主动作那一排不跟着页宽拉长：比选时「不设上限」那档把主按钮拉成 1000px 的长条，
     按钮再宽也不好按。封在 760。 */
  --action-row-max:760px;
  /* 专注模式左队列的两档宽（2026-08-19 老板拍板，原话「队列收成 76px 窄条，
     只留头像和状态点，悬停展开」）。76 是他给的数，262 是六版比选样张实测的展开宽。
     收起态让"看资料那一列"从 553 宽到 834（1280 实测），这正是他选 C 版的理由。 */
  --rail-w:88px; --rail-w-open:262px;
  /* 输入宽度档（L-31）：数字与短文本输入不许撑满一行。满宽=默认不落档；
     数字档由组件层 input[type="number"] 兜底，短文本档模板标 .input-sm。
     🔴 中档 2026-08-23 新增（界面第二期批 12，PRD F-13.14）：署名页「公司地址」
     那串字实测要 384px，短档 320 装不下、尾巴被截掉；而撑满一行是本条明令不许的。
     两个坏选择之间补的这一档，模板标 .input-md。**加档要有实测，别凭感觉加第四档。** */
  --field-w-num:10rem; --field-w-sm:20rem; --field-w-md:28rem;

  /* 间距（4px 基）。space-14/16/20 已按删除名单移除（零引用）。 */
  --space-1:0.25rem; --space-2:0.5rem;  --space-3:0.75rem; --space-4:1rem;
  --space-5:1.25rem; --space-6:1.5rem;  --space-8:2rem;
  --space-10:2.5rem; --space-12:3rem;

  /* 字距：只用在纯拉丁与数字上（S15：负字距仅限拉丁数字）。
     v2 §三 未列本族，但它不是颜色也不是字号档，作为原始尺度保留。 */
  --tracking-tight:-0.02em; --tracking-snug:-0.01em; --tracking-normal:0;
}
