/* ============================================================
   HHG Design System — tokens.css
   v1.18.0 (2026-08-29)
   ⚠️ 這一行是**庫的版本號**，跟著 GUIDELINE.md 的 Changelog 走，改本檔就要一起改。
      （v1.9.0–v1.13.1 期間它漏更新、停在 v1.8.0 停了五版，2026-08-17 補正。）
   Design foundation：主色 ink #1B1D22 為 HHG 官方定版＋橘 CTA；
   v1.17.0 新增三顆：--hit-min（觸控命中下限）、--ds-badge-h（badge 膠囊高）、--sp-48（間距階梯第十二階）。
   v1.16.0 觸控回饋：33 條 :hover 全數補上 :active（token 零變動，見 GUIDELINE Changelog）。
   v1.15.0 斷點由 3 階改 4 階（新增 992，原 --bp-lg 1200 更名為 --bp-xl）——見 GUIDELINE 原則 8。
   v1.14.0 起中性色與幾何採 warm（暖化中性色、圓角與控件高度各升一階），
   原本的 [data-theme="warm"] 主題層自此併入本檔成為預設，不再是可切換的主題。
   規範全文與使用時機見同資料夾 GUIDELINE.md。
   ============================================================ */
:root{
  /* ---- 色票：中性 ---- */
  --ground:#F8F7F7;          /* 頁面底（v1.14.0 warm 併入庫預設，原 #F7F8FA） */
  --surface:#FFFFFF;         /* 卡片/面板底 */
  /* 次表面（2026-08-11 v1.3.0 補）：比 --surface 深一階、但不到 --ground 的底。
     用於「白卡裡面還要再分一層」的地方：摺疊區標題列、側欄計數徽章、選單頁尾、中性小標籤。
     起因：權限申請 prototype 自己補了這個 hex，等於繞過原則 1「不自創灰色」——收進來讓它有名字。
     ⚠️ v1.14.0（2026-08-17）warm 併入庫預設：值改為 #F2F1F1。**與 --slate-bg 從此不再同值**
     （--slate-bg 隨 warm 保留現行 #F1F2F6 不變——狀態色照拍板維持既有值，見 GUIDELINE changelog）。
     原本「同值不同語意，分開留是為了改狀態色不連帶動版面層次」的理由，
     現在變成兩者本來就不同值，反而更乾淨地體現這個分家。 */
  --surface-2:#F2F1F1;
  --text:#2E2E31;            /* 主文 */
  --muted:#5C5C61;           /* 次要文字 */
  --faint:#6B6E7B;           /* 弱文字/輔助說明 */
  --disabled-fg:#B6B6B8;     /* 停用文字 */
  --disabled-fg-2:#CBCBCC;   /* 停用附註（如「（停用）」） */
  --line:#E9E8E8;            /* 一般框線/分隔線 */
  --line-strong:#C5C5C7;     /* 強框線（啟用中的卡） */
  --line-soft:#F1F0EF;       /* 弱分隔線（drawer header/footer） */
  --disabled-bg:#FAF9F9;     /* 停用卡底 */
  --field-bg:#F6F5F4;        /* 輸入框底 */
  --chip-bg:#F0EFEE;         /* 未選 chip 底 */

  /* ---- 色票：主色（ink，擔任 OMS navy 的角色） ---- */
  --ink:#1B1D22;
  --ink-hi:#3D404A;              /* ink 亮階（深色面上的選中底/次階層） */
  --ink-tint-05:rgba(27,29,34,.05);  /* tablist 底/搜尋框底/統計 chip 底 */
  --ink-tint-06:rgba(27,29,34,.06);  /* 疊層中階（2026-08-11 起表格列 hover 改吃 --hover-bg，本值目前無使用者，保留以維持 05/06/08 疊層階梯完整） */
  --ink-tint-08:rgba(27,29,34,.08);  /* badge 底 */

  /* ---- 色票：CTA 橘（稀有色：僅 CTA 與導覽選中系，不當控件選中色） ---- */
  --cta:#F08200;
  --cta-weak:#FF9D1B;
  /* 2026-08-10 新增：橘的「可讀文字階」。--cta #F08200 對白底只有 2.66:1（白底橙字明文禁用），
     所以橘一直只能做填色、無法出現在文字上。
     ⚠️ v1.14.0（2026-08-17）warm 併入庫預設，本值改用官方品牌橙深階 #C96A00
     （原 #A45D25 是 oklch(0.55 0.115 55) 算出來、通過 AA 的自製值，隨 warm 併入撤除）。
     官方深階實測**未達 AA**：對白卡 3.79:1、對暖底 3.53:1（4.5 門檻不到）——
     這是 warm 探索階段（themes.experimental.css）就記錄且已接受的已知限制，不是本次新問題。
     ⚠️ 用途嚴格限「caption 與小狀態提示」——連結、強調字、控件選中一律維持 ink（2026-08-10 使用者裁決），
     這個限制範圍正好把它擋在「必須達 AA 的內文字」用途之外。 */
  --cta-ink:#C96A00;
  --hover-bg:#FFFAF3;        /* 全站 hover 底（側欄導覽／表格列／選項列共用；2026-08-11 起表格列併入） */
  --nav-sel-bg:#FCF1DE;      /* 導覽選中底 */
  /* 橙 tint（2026-08-11 v1.3.0 補）：CTA 色的淺底，比 --nav-sel-bg 再深一階。
     用於中性說明條（.ds-alert-info）——「這段話要被看見，但它不是狀態」。
     ⚠️ 這一階只當**底色**，文字一律 --text；橘要出現在文字上只有 --cta-ink 一條路（原則 2）。
     同樣是把 prototype 自補的 hex 收進庫。深淺階梯：--hover-bg < --nav-sel-bg < --accent2-weak。 */
  --accent2-weak:#FFEECB;

  /* ---- 色票：狀態 ---- */
  --amber:#E0A100;  --amber-bg:#FDF3D6;
  --green:#1E9E62;  --green-bg:#E7F5EE;
  --red:#D8442B;    --red-bg:#FBEAE6;
  --slate:#565A66;  --slate-bg:#F1F2F6;
  --req-border:#F2D0C8;      /* 必填未填卡框（--red 淡化） */
  --req-star:#DB8A79;        /* 必填星號 */

  /* ---- 填色上的前景（2026-08-13 v1.8.0 新增）----
     在此之前 components.css 有 **18 處寫死 `#fff`**（primary 鈕／option 選中／seg／pill／
     checkbox 勾／分頁 current／popover 標題列／toast／spinner…）。淺色派看不出問題——
     --ink 一直是深色，白字當然可讀；但那是**巧合不是規則**，一旦主色變亮（深色模式、
     或任何把 --ink 調亮的主題）就是白字壓亮底，當場壞掉，而且主題層完全救不了
     （主題只能覆蓋 token，覆蓋不了寫死值）。
     每個填色各有自己的前景，不共用一顆：**它們的底色不同色相不同明度，將來不一定同時是白**。
     ⚠️ --on-cta 是這組裡最可能先分家的一顆：--cta #F08200 配白字只有 2.66:1，
        是公司明文禁用的組合（見 --cta-ink 的註解）。現在維持白是「照現況封存」，
        不是說它合格——真要修，改這一顆就全庫生效。
     ⚠️ 深底上的**文字階梯**與**疊層階梯**不在這裡。實測 `[data-shell="framed"]` 區塊
        （theme-lab.html:125-167）用了 8 種白 alpha：**文字只有兩階 .93／.52**，
        其餘 .06／.07／.08／.10／.12／.14 是面層與邊界。深色 KPI 卡 `.lab-kpi-dark`
        另用 .62／.55（文字）與 .18（面）。
        ⚠️ 別把 theme-lab 頁首切換器那組（.09／.72／.66／.10）算進來——那是實驗頁自己的
        chrome，不是產品元件。
        那是一整套「深底版中性色」，規格要等側欄升庫時拿實作對照著定
        （見 GUIDELINE backlog P1↑）。**不要現在憑空補**——那會重演 --fs-app 的老路：
        token 先於元件存在，然後被挪用到不對的地方。 */
  --on-ink:#FFFFFF;          /* --ink 底上的文字與符號 */
  --on-cta:#FFFFFF;          /* --cta 底（⚠️ 見上方對比說明） */
  --on-danger:#FFFFFF;       /* --red 底 */
  --on-green:#FFFFFF;        /* --green 底（toast 成功圖示） */

  /* ---- 深底中性色階梯（2026-08-13 v1.9.0 新增，使用者拍板 6 顆）----
     ⚠️ **不要拿 `--on-ink` 當深底文字色**。`--on-ink` 是純白，服務的是「小面積填色控件上的字」
     （primary 鈕、選中的 option）——那裡要純白才夠銳利。大面積深底上的文字用純白會過亮、
     邊緣起光暈，所以主文字是 93%。兩者是不同需求，共用一顆就會有一邊是錯的。

     值的來源＝`theme-lab.html` 的 `[data-shell="framed"]` 實測（125-167 行），不是發明的。
     實測有 8 個值，收斂成 6 顆的理由逐條寫在下面。

     ⚠️ **深色端的 alpha 必須比淺色端大**：淺色端是 --ink-tint-05/06/08，深色端要 06/10/14
     才看得出同樣的階差。同 warm 主題實測到的「暖底要 6%/7%/10% 而非 5%/6%/8%」——
     「淺底由主色透明度衍生」這條原則，前提是底夠中性；底一深，等比例的疊層就消失了。 */
  --on-dark:rgba(255,255,255,.93);          /* 深底主文字（品牌名、導覽選中項、帳號名） */
  --on-dark-2:rgba(255,255,255,.52);        /* 深底次要文字（副標、分組標題、未選導覽項） */
  --on-dark-tint-06:rgba(255,255,255,.06);  /* 最淺疊層：導覽 hover、深底上的輸入框底（實測 .06/.07 兩值，肉眼差 ΔL* 約 0.3，收成一階） */
  --on-dark-tint-10:rgba(255,255,255,.10);  /* 中階疊層：計數膠囊、kbd、icon 鈕 hover */
  --on-dark-tint-14:rgba(255,255,255,.14);  /* 強調面：頭像底（實測 .12/.14，收成一階取深者，頭像需要撐得住文字） */
  --on-dark-line:rgba(255,255,255,.08);     /* 深底上的分隔線與內嵌邊界 */

  /* ---- 白色當「材質」而非前景（2026-08-13 v1.8.0 新增）----
     這三個原本也是寫死值，但語意跟上面那組不同：它們不是「底色上的字」，
     而是元件自己的一個面。分開命名是為了不讓 --on-ink 被當成萬用白。
     ⚠️ 2026-08-17：本標頭原本寫在 --on-green 之後（第 94 行），但 v1.9.0 把「深底中性色階梯」
     整組插進標頭與它的三顆 token 之間，標頭從此被孤立、描述不到任何東西。
     機械解析 tokens.json 時它成了零顆 token 的空群組才被發現 —— 已搬到它該在的位置。
     教訓：插一組新 token 進既有區段時，要確認沒有把某個標頭與它的 token 拆開。 */
  --focus-halo:#FFFFFF;      /* 焦點環的間隙（讓 ink 環在深淺底都跳得出來）。深色主題下必須跟著底走，否則變亮環 */
  --switch-off:#D5D7DC;      /* switch 關閉軌道。⚠️ 這是全庫唯一的冷灰硬值，暖色主題下一眼看得出不屬於那一派（warm 實測） */
  --switch-thumb:#FFFFFF;    /* switch 滑塊。它是「浮在軌道上的旋鈕」，不是文字前景 */

  /* ---- 圓角階層（大→小；同類元件一律取同級） ----
     v1.14.0（2026-08-17）warm 併入庫預設，全階升一階（原值見 changelog）。
     ⚠️ **待觀察**：升階後 --r-fieldcard 與 --r-input 同為 14px，圓角階梯在此少一階
     （原本 10 vs 12 是相鄰兩級）。這是 warm 原值就有的重疊，不是本次改動製造的新問題，
     照拍板值進，尚未決定要不要分家——見 GUIDELINE 待觀察清單。 */
  --r-drawer:24px;           /* 抽屜/大型浮動面板 */
  --r-menu:20px;             /* 下拉選單容器、確認 modal */
  --r-card:18px;             /* 表格卡片/內容卡 */
  --r-input:14px;            /* 輸入框、popover */
  --r-fieldcard:14px;        /* 欄位卡片（⚠️ 與 --r-input 同值，見上方待觀察） */
  --r-btn:12px;              /* 按鈕、tabs 容器、搜尋框、分頁鈕、select trigger、menu option */
  --r-chip:10px;             /* pill 多選 chip、虛線加號鈕 */
  --r-tag:8px;               /* 小標籤 tag、tab、fx/mono badge */
  --r-check:4px;             /* checkbox */
  --r-full:999px;            /* switch 軌、頭像、full pill */

  /* ---- 間距階梯（2026-08-10 新增）----
     來源＝雙向實測，不是發明的：①本庫 components.css 現行 padding/gap 實際用值
     ②DesignMD (designmd.co) 淺色版全頁取樣的高頻值。兩邊交集＝下列階梯，主力是 8／12／20。
     ⚠️ 現行殘留三個階梯外的髒值（3px／5px／18px 各 1–3 處），改元件時順手收斂到最近一階。
     命名採「值即名」而非 sp-1/2/3：本庫幾何是硬規定、不做整體縮放，
     值即名可讓「同類元件取同級」一眼看出違規，也不會有對照表記錯的風險。 */
  --sp-2:2px;    /* 極貼合：tab 之間、icon 與計數 */
  --sp-4:4px;    /* 標籤與控件、badge 內縮 */
  --sp-6:6px;    /* 按鈕內 icon 與字、pill 內距 */
  --sp-8:8px;    /* 控件之間的預設間距（最常用） */
  --sp-10:10px;  /* 卡內小區塊 */
  --sp-12:12px;  /* 表格儲存格左右、卡片內距小號（最常用） */
  --sp-14:14px;  /* 按鈕左右內距 */
  --sp-16:16px;  /* 卡片內距 */
  --sp-20:20px;  /* 卡片內距大號、區塊之間 */
  --sp-24:24px;  /* 抽屜/面板內距 */
  --sp-32:32px;  /* 頁面區段之間 */
  /* 2026-08-28 v1.17.0 新增：階梯頂端原本停在 32，而 32 到「空狀態內距」那一階之間是空的，
     於是 .ds-empty 長出 46px＝上面那句「三個階梯外髒值」漏數的第四個。收斂到 48（+2px）。
     值即名的命名法不變。 */
  --sp-48:48px;  /* 空狀態內距、大留白區塊 */

  /* ---- 控件高度階層 ----
     v1.14.0（2026-08-17）warm 併入庫預設，全階升一階（原值見 changelog）。
     恆等式仍然成立：--h-tab + 2×--ds-tabs-pad ＝ --h-btn → 34 + 2×4 ＝ 42 ✓ */
  --h-input:48px;            /* 文字輸入 */
  --h-btn:42px;              /* 按鈕、搜尋框、分頁鈕、表格勾選命中盒 */
  --h-select:38px;           /* select/combobox trigger、卡內小輸入、虛線加號鈕 */
  --h-tab:34px;              /* tab（坐在 --ds-tabs-pad 的軌道裡） */
  --h-icon:34px;             /* icon 鈕（2026-08-11 v1.3.0 從 --h-tab 分家，見下方 coarse 段） */
  --h-seg:33px;              /* segmented chip */
  --h-chip:28px;             /* pill 多選 chip */
  --h-row:58px;              /* 表格列/表頭 */
  --h-bar:66px;              /* 抽屜 header/footer */
  --ds-tabs-pad:4px;         /* tabs 軌道內距。恆等式：--h-tab + 2×--ds-tabs-pad ＝ --h-btn（同列同高） */
  /* 2026-08-28 v1.17.0 新增（元件層 token，沿用 --ds-tabs-pad 的既有慣例）：
     狀態標籤膠囊的高度。收它的理由＝它是 .ds-badge 那條 `white-space:nowrap` 的**前提**
     （高度寫死，文字一換行就溢出膠囊，2026-08-12 實測踩過），而下游已手抄四份。
     ⚠️ **刻意不進 --h-* 家族**：那個家族帶一個隱含契約——「pointer:coarse 下放大到命中下限」。
        badge 不是控件、不是點擊目標，跟著放大只會撐爆表格列高。所以它用 --ds-* 前綴，
        並且**刻意不在下方 coarse 放大清單裡**。 */
  --ds-badge-h:22px;         /* 狀態標籤膠囊高（.ds-badge。非控件，不隨 coarse 放大） */

  /* ---- 命中盒（不是視覺尺寸階） ----
     契約：**這一顆只用於「這東西要被手指點到」的最小高度**，不是萬用 44。
     不要拿它當面板高度、間距或圖示直徑——`--fs-app` 的教訓是「token 先於元件存在就會被挪用」，
     這一顆反過來：元件早就在用了（六個無名的 44），只是沒有名字。
     來源＝WCAG 2.5.5／2.5.8 的觸控目標下限，也是下方 pointer:coarse 整段的立論基礎。
     庫內落點：.ds-option（base 就要 44，選單選項一律可點）、coarse 下的 .ds-link／
     .ds-checkbox／.ds-switch（高度由內容撐出來、token 管不到，只能在元件層補 min-height）、
     .ds-select-menu 的捲動上限（＝可見 7 列 × 這一顆，見 components.css 該處註解）。
     ⚠️ 它**不是**高度階梯的一階：不要拿它跟 --h-btn／--h-select 並列挑選。 */
  --hit-min:44px;            /* 觸控最小命中高度（WCAG 2.5.5／2.5.8） */

  /* ---- 應用外殼版面常數（2026-08-13 v1.9.0 新增）----
     216 不是折衷值，是**兩份獨立產品實作量出來的同一個數**（權限申請 #sidebar 與採購
     .sidebar 都是 216px）。theme-lab 的 236／248 是實驗頁自己的排版，不採計。
     framed 版面下加寬到 248：外殼有 12px 外距、側欄本身透明，216 在深框裡看起來會偏窄。 */
  --side-w:216px;            /* 側欄寬（桌機） */
  --side-w-framed:248px;     /* 深色外框版面下的側欄寬 */
  --side-w-drawer:240px;     /* ≤820 抽屜寬（實測值，比桌機略寬：抽屜是唯一導覽，不必為內容讓位） */

  /* 詳情頁輔助欄寬（2026-08-14 v1.13.0）。
     ⚠️ **證據強度比 --side-w 弱，要誠實**：216 有兩份獨立產品實作背書，292 只有權限申請
     一份活的實作（採購案的 .dbaux 是零 markup 使用的死樣式，且血緣是從採購複製到權限申請，
     不是各自長出來）。採用前建議對自己的內容量一次。 */
  --aux-w:292px;             /* 兩欄詳情版面的右側輔助欄 */

  /* 黏頂偏移（2026-08-14 v1.13.0）＝黏頂元素要讓開的高度＝它上方所有已 sticky 的東西。
     ⚠️ **預設 0，這是刻意的**：庫目前沒有頂欄元件（`.ds-appshell` 只有側欄與 main），
     所以「沒有東西擋著」才是庫的預設狀態；給非 0 預設會逼每個採用者先寫一次覆寫。
     ⚠️ **覆寫要掛在容器上，不要掛 :root**——同一支 app 在不同斷點會有不同值。
        權限申請就是實例：≤820 頂欄在文件流內（偏移 53／觸控 57），≥821 頂欄改 absolute
        退出文件流（偏移 0）。掛 :root 表達不出這件事。
          .ds-main{ --ds-sticky-top:calc(6px + var(--h-btn) + 6px + 1px); }
          @media (min-width:821px){ .ds-main{ --ds-sticky-top:0px; } }
     ⚠️ **它不是「頂欄高度」**，兩者是不同的東西：≥821 那個情境裡頂欄仍然有高度，但偏移是 0。
        不要把 min-height 與本 token 共用一顆。 */
  --ds-sticky-top:0px;

  /* ---- 字級階層 ---- */
  /* 2026-08-10 新增：頁標題自成一階。原本頁標題與 modal 標題共用 19px，
     頁面因此沒有錨點——19 vs 內文 14＝1.36× 落差，掃過去「什麼都差不多大」。
     參考基準：DesignMD 大標 36 vs 內文 16＝2.25×。這裡取 26/14＝1.86×，
     兼顧「內部工具不喧鬧」與「要有一個明確的視覺入口」。
     ⚠️ v1.14.0（2026-08-17）warm 併入庫預設：26→27px、字距 -.015em→-.008em（放鬆感，字距不收那麼緊）。 */
  --fs-page:27px;    --fw-page:700;   /* 頁標題（內容區的 h1） */
  --ls-page:-.008em;                  /* 大字收緊（warm 起收得比之前鬆） */
  --fs-title:19px;   --fw-title:700;   /* modal／抽屜標題 */
  --fs-panel:17.5px; --fw-panel:700;   /* 抽屜/面板標題 */
  /* 2026-08-12 v1.5.2 新增：app shell 這一階。
     起因＝theme-lab 的側欄（品牌名／導覽圖示）需要 16，而階梯上 14 與 17.5 之間是空的。
     為什麼不借現成的兩階：**14 撐不起 app 名**（跟導覽項目同級，掃過去沒有階層），
     **17.5 是「抽屜／面板標題」的語意**，借來當側欄品牌名會讓那一階的意思變模糊
     （同一個值同時代表兩種角色，就是階梯開始失效的起點）。
     ⚠️ **2026-08-13 更新：側欄已於 v1.9.0 進庫（`.ds-appshell`／`.ds-side`），這一階
     自此有了正式的元件歸屬，不再是「token 先於元件存在」的狀態。** 但用途仍限 app shell
     的品牌名與導覽，不要外借（外借就會變成第二個「沒有語意的中間值」）。 */
  --fs-app:16px;     --fw-app:700;     /* app shell：側欄品牌名、導覽圖示 */
  --fs-body:14px;                      /* 內文、輸入值 */
  --fs-section:13.5px; --fw-section:600; /* section 標題 */
  --fs-label:13px;   --fw-label:600;   /* 欄位 label、tab、按鈕 */
  --fs-sub:12px;                       /* 小 label、pill chip */
  --fs-hint:11.5px;                    /* hint、badge、副說明 */
  --fs-micro:11px;                     /* fx chip、nav 副標 */

  /* ---- 數字展示階（2026-08-14 v1.13.0 新增，使用者拍板）----
     ⚠️ **這一組是「大號數字」專用，不是第二套標題階**。
     為什麼不挪用標題階（曾經的選項）：這批系統的畫面上「大號數字」是一個獨立且反覆
     出現的角色（金額、件數、天數），把它綁在 --fs-page／--fs-panel／--fs-body 上，
     將來調整標題層次就會**連帶改到金額**——那是兩件無關的事，不該共用一顆。
     ⚠️ 它與 --fs-app 的差別（後者是「token 先於元件存在」的反例，見上）：
     這三階**一進來就同時服務兩個元件三個落點**（KPI 主數字／合計金額／inset 統計值），
     不是為單一元件開的後門。
     ⚠️ 用這一階的地方一律要配 `font-variant-numeric:tabular-nums`——大號數字會被
     逐列比較，比例字寬會讓小數點對不齊。庫內 .ds-mono 已含此宣告。 */
  --fs-num-lg:28px;  /* KPI 主數字 */
  --fs-num-md:18px;  /* 合計列金額、單據頭金額 */
  --fs-num-sm:15px;  /* 卡內 inset 統計值 */
  --ls-num:-.02em;   /* 大號數字收緊（比 --ls-page 的 -.008em 再緊：數字字面比中文窄，同樣字距看起來會鬆；
                        v1.14.0 warm 併入後 --ls-page 變鬆，兩者差距比之前更大，本值不隨之聯動——理由不變） */

  /* ---- 陰影 ----
     v1.14.0（2026-08-17）warm 併入庫預設：單層、大（「柔和」的陰影語彙）取代原本的多層小陰影。
     rgba 跟著 --ink #1B1D22 走（27,29,34），不是另一組色溫。 */
  --sh-card:0 6px 26px rgba(27,29,34,.10);                                   /* 內容卡 */
  --sh-pop:0 10px 28px rgba(27,29,34,.15),0 2px 8px rgba(27,29,34,.09);      /* popover */
  --sh-menu:0 14px 36px rgba(27,29,34,.17),0 3px 10px rgba(27,29,34,.10);    /* 下拉選單（白底靠陰影跳出） */
  --backdrop:rgba(27,29,34,.48);                                             /* modal/drawer 遮罩 */

  /* ---- 字體 ---- */
  --sans:-apple-system,BlinkMacSystemFont,"PingFang TC","Noto Sans TC","Microsoft JhengHei",sans-serif;
  --mono:ui-monospace,"SF Mono",Menlo,Consolas,monospace;

  /* ---- 動效 ---- */
  --t-fast:.12s ease;
  --t-med:.18s ease;

  /* ---- 疊層階梯（2026-08-11 新增）----
     原本 popover/select/drawer/modal 各自寫死 1000/1500/1800/1900/2000，專案端又另有一套
     15/20/25/30/40/50/60/70/100/200 → 兩套數字系統並存，誰蓋誰全靠巧合。
     規則：**只准用這七階，不准寫裸數字**。階與階之間留 100 給專案插自己的東西
     （例如專案的黏頂工具列可用 --z-sticky + 1，但不得跨到下一階）。 */
  --z-base:0;         /* 一般內容 */
  --z-sticky:100;     /* 黏頂工具列、表頭、批次操作列 */
  --z-nav:200;        /* 側欄、頂欄、行動版抽屜遮罩 */
  --z-popover:1000;   /* popover、tooltip、通知面板 */
  --z-select:1500;    /* select 展開選單（必須蓋過 popover：它常開在 popover 內） */
  --z-drawer:1800;    /* 抽屜與其遮罩（遮罩 1800／本體 1900） */
  --z-modal:2000;     /* modal／dialog */
  /* 第八階（2026-08-11 v1.3.0 新增）：toast 必須蓋過對話框。
     理由是硬的——對話框裡的動作失敗時會 toast 錯誤訊息（DS.confirm／DS.dialog 的 onConfirm 回 false
     那條路徑），toast 若與 modal 同階，就會被後掛上 body 的遮罩壓在底下＝使用者看不到失敗原因。 */
  --z-toast:2100;

  /* ---- 斷點（2026-08-11 新增；2026-08-24 v1.15.0 由 3 階改 4 階）----
     ⚠️ CSS 的 @media 不吃 custom property（`@media (max-width:var(--bp-md))` 無效），
     所以這裡是**規範用的常數表**，不是可引用的變數——寫 media query 時照抄數字。
     只准用這四個斷點，不要再發明 900／1199 之類的中間值。
     --bp-sm:640px   手機（主管手機審核＝既定主情境）：側欄改抽屜、動作列釘視窗底
     --bp-md:820px   小筆電／分割視窗：仍走抽屜、副標收起、鈴鐺搬回頂欄
     --bp-lg:992px   窄桌機／大平板：兩欄詳情與四欄表頭排得下，但還不到三欄並排
     --bp-xl:1200px  桌機：三欄／並排版面才展開

     🔴 **2026-08-24 v1.15.0：--bp-lg 的值由 1200 改成 992，1200 移到新的 --bp-xl。**
        不是加一顆而已，是**改名＋改值**。原因：走 Tailwind 之後 token 名會直接變成
        variant 名（--bp-lg → `lg:`），而開發端既有的 `lg:` 期望 992；若我們讓
        --bp-lg 留在 1200，他們既有的 `lg:` 會靜靜變成 1200 才觸發 ⇒ 992–1200
        這段版面無聲壞掉。改名時實測庫內對 --bp-lg 的引用＝0（1200 從未出現在任何
        @media，庫內 @media 全寫死 640／820），兩個下游 prototype 也只用 --bp-md。
     ⚠️ 992 這一階目前**在庫內零使用者**——它是為下游而存在的常數，不要以為漏改。
        （值同時放在這裡當文件，實際 media query 請寫死數字） */
  --bp-sm:640px;
  --bp-md:820px;
  --bp-lg:992px;
  --bp-xl:1200px;
}

/* ============================================================
   觸控裝置：放大控件高度（2026-08-11 v1.3.0 拍板）
   ============================================================
   **決定觸控目標大小的是「輸入裝置」，不是「螢幕寬度」。**
   用 max-width 當代理指標兩種情況都會判錯：
     ・1024px 的 iPad ＝手指，卻被判成桌機 → 目標太小
     ・拉窄到 700px 的桌機視窗 ＝滑鼠，卻被判成手機 → 整排控件無謂變胖
   因為全庫所有元件的高度都吃這幾個 token，**改 token 即全庫生效**，
   採用專案一行都不用寫——「不准覆寫 ds- class」那條規矩因此得以維持完整
   （在此之前，44px 觸控放大只能寫在專案的 @media(max-width:820) 裡覆寫 ds- class）。

   用 `pointer` 不用 `any-pointer`：
     pointer     ＝**主要**輸入裝置的精度 → 純滑鼠桌機接了觸控螢幕仍是 fine，不會被放大
     any-pointer ＝任一輸入裝置 → 只要插著觸控螢幕就全部放大，誤傷面太大
   ⚠️ 已知副作用（可接受，登記於此）：二合一筆電切到平板模式、部分 Android 桌面版瀏覽器
     會回報 coarse，於是在鍵鼠情境下也拿到放大版。判斷是**放大不會壞，只是密度低一點**——
     反過來（觸控裝置拿到 36px 目標）才是真的點不到。故接受誤判往「大」的方向。

   逐項判斷（不是無腦全放大）：
   ⚠️ v1.14.0（2026-08-17）warm 併入庫預設後，下列「base → coarse」的 base 端數字已更新
   （coarse 端的放大目標值不變，放大邏輯與取捨理由也不變）：
     --h-input 48 ／ --h-row 58 ／ --h-bar 66 ── **不動**，本來就 ≥44
     --h-btn   42 → 44  按鈕/搜尋框/分頁鈕/表格勾選命中盒：主要點擊目標，補到 44
     --h-select 38 → 44  select・combobox trigger、卡內小輸入、虛線加號鈕：同上
                         （副作用：coarse 下 -sm 與 -md 同高，兩者在觸控上本來就沒有區分的意義）
     --h-icon  34 → 44  icon 鈕：只有一個圖示、沒有文字幫忙擴大命中區，最需要補
     --h-tab   34 → 40  tab：**不是 44**。它坐在軌道裡，軌道外高必須等於 --h-btn(44)，
                         所以 tab(40)＋軌道內距(2×2)＝44。命中盒實際 40，仍遠高於
                         WCAG 2.5.8 的 24×24 下限；把 tab 拉到 44 會讓軌道變 52，
                         與同列的按鈕/搜尋框差 8px＝違反「同列同高」（原則 4）。
     --ds-tabs-pad 4 → 2 上面那條恆等式的另一半。
     --h-seg   33 → 40  segmented 是真的單選控件（不是裝飾 chip），33 在手指下太薄。
     --h-chip  28 → 32  pill 多選 chip：**刻意不到 44**。chips 是密集並排的，全部 44
                         會把一組 8 個 chip 撐成兩三排、反而更難掃；32 是在
                         「看得出是一組 chip」與「點得到」之間的取捨（≥24 下限）。

   ⚠️ **下面那三顆 44 就是 `--hit-min`（v1.17.0 新增），改一起改。**
      這裡刻意**保留字面值、不寫 `var(--hit-min)`**，理由是下游相容：
      `tokens.json` 的 `pointerCoarse` 區塊是原樣搬字串（`build-tokens.mjs` 的 `parseFlat`），
      寫成 `var()` 之後下游拿到的會是字串 `"var(--hit-min)"`——Chakra theme 這類會對值做
      運算的產生器會當場壞掉，而且是無聲的。所以這一段的契約是「值必須是純數字＋px」，
      並由產生器的出廠檢查 C 強制（`^\d+(px)?$`）。
   ============================================================ */
@media (pointer: coarse){
  :root{
    --h-btn:44px;
    --h-select:44px;
    --h-icon:44px;
    --h-tab:40px;
    --ds-tabs-pad:2px;
    --h-seg:40px;
    --h-chip:32px;
  }
}
