/*
 * 一天聽一點 — Design Tokens（SSOT）
 *
 * ════════════════════════════════════════════════════════════════════
 * 這是全站視覺的唯一來源。顏色、字級、間距、圓角、陰影、層級一律定義在此，
 * 其他 CSS 一律 hsl(var(--x)) / var(--x) 引用。
 * 客戶要調色時改這一支，19 頁同步生效。
 * ════════════════════════════════════════════════════════════════════
 *
 * 【分層】兩層 + 選擇性第三層
 *
 *   Layer 1  Primitive   --slate-500: 225 2% 49%      「這是什麼顏色」
 *   Layer 2  Semantic    --border: var(--slate-200)   「這個顏色代表什麼意義」
 *   Layer 3  Component   只在元件真的偏離語意層時才建（目前只有 Footer 反白）
 *
 *   元件請用「語意層」，不要直接用 Primitive —— 那樣改配色時會漏改。
 *   唯一例外是需要色階微調的場合（例如 hover 要比底色深一階）。
 *
 * 【寫法】HSL 分量 + hsl(var(--x))
 *   值寫成 `225 2% 49%` 而非 `#7C7D80`，使用時 hsl(var(--slate-500))。
 *   這樣才能用 hsl(var(--slate-500) / .5) 調透明度。
 *   命名沿用 shadcn（與公司 merp／後台公版同一套，內部溝通零成本）。
 *
 * 【色階怎麼來的】
 *   由 .agent/design/generate-ramps.php 產生。客戶色票僅供參考（要的是
 *   「低飽和、差不多這種調性」而非指定色值），所以重新調色一定會發生：
 *   改該腳本的三個錨點 → 重跑 → 貼回本檔的 Primitive 區塊。
 *   腳本會同時驗證所有「底色×文字」組合的 WCAG 對比，不合規直接標出來。
 *
 * 【⚠️ 這組色票的陷阱】
 *   參考色票的四個色裡**只有黑色能當內文**：
 *     BLACK 21.00 ✓｜SLATE #7C7D80 4.12 ✗（差 4.5）｜AERIAL 1.74 ✗｜NUDE 1.26 ✗
 *   次要文字必須用 slate-600（5.59），比參考色僅深 3%、視覺幾乎無差別但合規。
 *   **不要因為「看起來夠深」就把 slate-500 拿去當內文。**
 *
 * 【關於「禁寫死 hex」】
 *   中央廚房準則 H 有這條，但原文四處全部位於 .ck-flow-* 步驟條章節內，
 *   稽核方式也寫明是 grep「該區塊」—— 它是元件級規範，不是全站鐵律。
 *   本專案仍全站執行這個紀律（好實務），但這是我們自己的加嚴，非準則 H 的要求。
 */

:root {

    /* ══════════════════════════════════════════════════════════════
       Layer 1 — Primitive
       ══════════════════════════════════════════════════════════════ */

    /* ── 色階 ──────────────────────────────────────────────────
       由 .agent/design/generate-ramps.php 產生，勿手改。
       ★ = 客戶參考色所在的階 */

    /* ⚠️ 保留小數：整數化會讓 HSL→RGB 來回轉換產生 1-3 的色差，
       使錨點色與註解標示的 hex 對不上（實測 #7C7D80 會渲染成 #7A7C7F）。 */

    /* slate — 中性軸：文字、邊框、表面 */
    --slate-50:      240 6.67% 97.06%;    /* #F7F7F8 */
    --slate-100:     180 3.23% 93.92%;    /* #EFF0F0 */
    --slate-200:     210 3.03% 87.06%;    /* #DDDEDF */
    --slate-300:     220 2.56% 77.06%;    /* #C3C4C6 */
    --slate-400:     225 2.13% 63.14%;    /* #9FA0A3 */
    --slate-500:     225 1.59% 49.41%;    /* #7C7D80 ★參考色 — 對比 4.12，不可當內文 */
    --slate-600:     216 2.39% 40.98%;    /* #66686B — 最淺的合法內文色 5.59 */
    --slate-700:     225 2.38% 32.94%;    /* #525356 */
    --slate-800:     210 1.64% 23.92%;    /* #3C3D3E */
    --slate-900:     240 1.41% 13.92%;    /* #232324 */

    /* aerial — 強調軸：互動、focus、冷色表面 */
    --aerial-50:     210 37.5% 96.86%;    /* #F4F7FA */
    --aerial-100:    210 40% 94.12%;      /* #EAF0F6 */
    --aerial-200:    208.8 40.98% 88.04%; /* #D4E1ED */
    --aerial-300:    209.3 39.82% 77.84%; /* #B0C7DD ★參考色 */
    --aerial-400:    209.5 39.88% 68.04%; /* #8DAECE */
    --aerial-500:    208.9 39.71% 59.02%; /* #6D98C0 */
    --aerial-600:    209.4 40% 47.06%;    /* #4879A8 */
    --aerial-700:    209.2 40.21% 38.04%; /* #3A6288 */
    --aerial-800:    209.5 39.86% 28.04%; /* #2B4864 */
    --aerial-900:    208.3 39.13% 18.04%; /* #1C2F40 */

    /* nude — 暖色軸：溫暖表面、標籤 */
    --nude-50:       33.3 60% 97.06%;     /* #FCF8F3 */
    --nude-100:      35.3 54.84% 93.92%;  /* #F8F1E7 */
    --nude-200:      33.5 56.67% 88.24%;  /* #F2E3D0 ★參考色 */
    --nude-300:      33.1 56.86% 80%;     /* #E9CFAF */
    --nude-400:      32.9 57.06% 68.04%;  /* #DCB27F */
    --nude-500:      32.8 57.14% 56.08%;  /* #CF954F */
    --nude-600:      33 57.21% 44.9%;     /* #B47931 */
    --nude-700:      33.1 57.38% 35.88%;  /* #906127 */
    --nude-800:      32.8 56.39% 26.08%;  /* #68461D */
    --nude-900:      32.6 56.1% 16.08%;   /* #402B12 */

    /* ember — 高飽和軸：唯一一個「敢跳出來」的顏色（2026-07-30 新增）
     *
     * 【為什麼要多這一軸】
     * 原本三軸（slate 中性／aerial 冷／nude 暖）飽和度都壓得很低，這是品牌
     * 規格「設計降低至 15%」的直接結果，也是對的。但因此**沒有任何一個顏色
     * 能表達「你正在動它」** —— 進入鈕 hover 只能靠底色從 88% 白變成 100% 白，
     * 那在照片上幾乎看不出來。使用者指定補一個深橘。
     *
     * 【為什麼是這個橘】
     * 色相取 20–22°，是 nude 軸（33°）往紅移一點：同屬暖色家族，並排不打架，
     * 但飽和度拉到 75–82%（nude 是 57%），一眼就知道它是另一個層級的東西。
     *
     * ⚠️ **只給互動狀態用**（hover／目前選中），不要拿去當區塊底色或裝飾。
     *    它是全站唯一的高飽和色，用在第二個地方就不再是「這裡可以動」的訊號了。
     *
     * ⚠️ 這一軸**不是** generate-ramps.php 產生的（那支只吃三個客戶錨點色）。
     *    要調色請直接改這四行，並重驗下面註記的對比值。
     */
    --ember-100:     22 80% 95%;          /* #FCF0E8 極淺底 — 配主要文字 14.03 ✓ */
    --ember-200:     22 75% 86%;          /* #F6D4C1 有顏色的分界線 */
    --ember-600:     20 82% 43%;          /* #C85014 主色 — 配白 4.55 ✓ 過 AA */
    --ember-700:     20 84% 35%;          /* #A4400E 再深一階 — 配白 6.33 ✓ */

    /* 絕對值 */
    --white:         0 0% 100%;
    --black:         0 0% 0%;

    /* ── 字級 ──────────────────────────────────────────────────
       盤點時全站有 20 個相異字級，光是 .68–.95rem 的小字區就塞了 12 個，
       多數相差不到 0.03rem（肉眼不可辨）。收斂為 7 階。
       ⚠️ Bootstrap 的 .small（全站 52 次）與 .fs-* 也在管字級，
          下方 Bootstrap 對接區有覆寫，避免變成第三套並存的系統。 */
    --text-2xs:      0.68rem;   /* pill、斷點提示 */
    --text-xs:       0.75rem;   /* 麵包屑、圖說 */
    --text-sm:       0.8rem;    /* 按鈕、表單標籤、footer 連結（全站最常用）*/
    --text-base:     0.875rem;  /* 輔助說明 */
    --text-md:       1rem;      /* 內文 */
    --text-lg:       1.15rem;   /* section 標題 */
    --text-xl:       1.5rem;    /* LOGO */
    --text-2xl:      2rem;      /* 頁面主標 */

    /* ── 字重 ──────────────────────────────────────────────────
       Google Fonts 載入 300/400/500/700（900 未使用，已從 main.php 移除）*/
    --weight-light:  300;       /* LOGO、banner 大標 — 本站的優雅感來源 */
    --weight-normal: 400;
    --weight-medium: 500;
    --weight-bold:   700;

    /* ── 字距 ──────────────────────────────────────────────────
       本站大量使用寬字距，是視覺識別的一部分。原有 8 個值收斂為 5。
       （.04em→.05em、.14em→.12em、.2em→.18em 吸附）*/
    --tracking-tight: 0.02em;   /* section 標註 */
    --tracking:       0.05em;   /* 按鈕、麵包屑 */
    --tracking-wide:  0.12em;   /* LOGO */
    --tracking-wider: 0.18em;   /* 主導覽（uppercase）、頁面主標 */
    --tracking-widest:0.32em;   /* LOGO 桌機 — 全站最寬 */

    /* ── 行高 ──────────────────────────────────────────────── */
    --leading-none:    1;       /* 導覽對齊用 */
    --leading-tight:   1.3;
    --leading-normal:  1.6;
    --leading-relaxed: 1.9;     /* 內文段落（原有 1.9 與 2 幾乎不可辨，收斂為一）*/

    /* ── 字體 ──────────────────────────────────────────────────
       客戶方品牌提案第 3 頁凱宇本人的回饋：「文字風格希望以『日常』為主軸，
       避免使用過度粗、用力的字體，接近無印良品風格」，第二版封面大標即採明體。
       故標題走明體、內文維持黑體 —— 中文明體在螢幕小字下辨識度明顯較差，
       全站明體會傷可讀性，這也是該提案封面只有大標與副標兩層文字的原因。
       規格見 .agent/design/brand-spec.md。 */
    --font-body:    "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", sans-serif;
    --font-display: "Noto Serif TC", "Songti TC", "PMingLiU", serif;

    /* 英文手寫體。與 signature 的毛筆「一天聽一點」同屬手寫筆意，
       用在只有英文的小標（目前是格子版主視覺的標籤）。
       ⚠️ 手寫體不要配 text-transform:uppercase 或寬字距 —— 那會把連筆拆散，
          看起來像把手寫字硬排成印刷字。維持原樣的大小寫與正常字距。
       ⚠️ 只給英文用。中文沒有對應的字符，會直接掉回後面的備援字體。 */
    --font-script:  "Caveat", "Segoe Script", "Bradley Hand", cursive;

    /* 中文手寫感。
       ⚠️ **目前沒有任何地方在用**：它是為「主視覺格子在英文標籤下加一行中文」
          加的，同日下午使用者看過實品後決定只留英文。token 與下面這段結論
          留著備查（處置方式同 _vtabs.php、_rule_stroke.php）。
       ⚠️ **站上沒有載入任何繁中手寫網頁字型**，只有 Noto Sans TC / Noto Serif TC /
          Caveat 三支（見 layouts/main.php 的 Google Fonts 那一行）。
          --font-script 的備援 `cursive` 對中文的解析各平台不同（macOS 可能給
          楷體、Windows 會掉回正黑），那正是本專案當初拒用 emoji 的同一個理由
          —— 跨平台繪製不一致，所以**不能靠 cursive 撞運氣**。
       這裡改列**系統楷體**：楷體是系統字型裡最接近手寫筆意的一支，
       兩大平台都內建（macOS：Kaiti TC / BiauKai；Windows：標楷體 DFKai-SB），
       零新依賴、零載入成本，最後退回品牌明體。
       ⚠️ 要真正的手寫體必須另外載一支 CJK webfont（例如霞鶩文楷 TC），
          那是新依賴 —— 依全域守則第 4 條要先做來源／授權／維護狀態掃描，
          而且 CJK 字檔動輒數 MB，得先確認載入成本。**不要順手加上去。** */
    --font-kai:     "Kaiti TC", "BiauKai", "DFKai-SB", "KaiTi", "楷體", var(--font-display);

    /* ── Signature 品牌印記 ────────────────────────────────────
       品牌規格明訂「Signature 尺寸固定、位置可變動」，故尺寸定為 token，
       位置留給呼叫端用 Bootstrap utility 排。
       比例 897:187 為素材墨跡實際長寬比，改素材時要一起改。 */
    --signature-ratio: 897 / 187;
    --signature-w-sm:  7rem;      /* footer */
    --signature-w-md:  9.5rem;    /* header — 與原文字 LOGO 視覺寬度相當 */
    --signature-w-lg:  12rem;     /* 疊加於圖片 */

    /* ── 間距 ──────────────────────────────────────────────────
       ⚠️ 刻意對齊 Bootstrap 的 4px scale。
       全站約 260 處在用 mb-3 / p-4 / gap-2 等原生 utility（準則 5 要求優先用
       框架原生 class），若自立一套 scale，token 與 utility 會各走各的。
       原本手寫的 19 個刻度（.12/.35/.55/1.2/1.4/2.2rem…）向這裡吸附。 */
    --space-1:  0.25rem;   /* = Bootstrap 1 */
    --space-2:  0.5rem;    /* = Bootstrap 2 */
    --space-3:  1rem;      /* = Bootstrap 3 */
    --space-4:  1.5rem;    /* = Bootstrap 4 */
    --space-5:  3rem;      /* = Bootstrap 5 */
    --space-6:  4rem;      /* Bootstrap 沒有，補 */
    --space-7:  6rem;      /* Bootstrap 沒有，補 */

    /* ── 版面 ──────────────────────────────────────────────────
       --gutter-x 是全站水平留白的單一來源。盤點時這個值以 3.5rem/1.3rem
       的形式在 wireframe.css 重複出現 8 次，是最高價值的 token 化目標。 */
    --container-max:  1440px;
    --gutter-x:       3.5rem;   /* section 左右留白 */
    /* section 上下留白。2026-07-31 由 3rem 拉到 6rem。
     *
     * 【為什麼要加倍】使用者回報「滾一下就看到下一個區塊，很擁擠」。實測：
     * 視窗高 886 時三個區塊分別只有 592 / 542 / 678，**每一區都比一個螢幕矮**，
     * 所以永遠同時看得到兩區；而相鄰兩區「內容到內容」的空白只有 72px
     * （下 48 ＋ 上 48 − 疊合 24）。滿版色帶會換底色，72px 撐不住那個轉換。
     * 拉到 6rem 之後空白變 168px，區塊高度也接近一個視窗。
     *
     * ⚠️ 這個 token 同時是 footer 的上下內距（style.css 的 .site-footer）
     *    與全站內頁 section 的留白 —— 改它是整站一起變，這是刻意的，
     *    首頁與內頁的節奏不該不一樣。
     * ⚠️ 加留白解決的是「區塊之間太擠」，**不會**讓區塊本身變得比一個視窗高
     *    （那要靠內容量）。想再更寬鬆就往上調這三個值，不要去改 .site-slab
     *    的疊合量 —— 那 24px 是圓角半徑，兩者必須相等。
     */
    --section-y:      6rem;     /* section 上下留白 */
    --header-y:       1.6rem;   /* header 上下留白 */

    /* ── 圓角 ──────────────────────────────────────────────────
     * 【2026-07-30 整組上調一階】原本 2/4/8 偏「印刷、無圓角」的紙感。
     * 本專案要與同事那版（細線條＋直角）做出區隔，方向定為「稍微數位化」，
     * 圓角是最省成本的一支槓桿 —— 改這四行，全站跟上。
     *
     * ⚠️ 巢狀時外層用 --radius-lg、內層用 --radius，**不要兩層都給 lg**。
     *    幾何上內圓角應等於外圓角減內距；卡片內距是 space-3（16px）、
     *    外圓角 16px，內層再給 16px 會看起來鼓出來。降一階最接近正確。
     */
    --radius-sm:   4px;
    --radius:      8px;
    --radius-lg:   16px;
    /* 區塊級圓角（2026-07-31 新增）：滿版區塊互相疊合時的上緣圓角，
       見 style.css 的 .site-slab。
       ⚠️ **不屬於上面那條卡片巢狀尺度**（外層 lg、內層 radius）。它是「整個
          區塊」的半徑，不會有東西巢在它裡面又要再降一階 —— 別把它拿去當
          卡片外框，那會比 --radius-lg 大一截、跟其他卡片對不起來。
       24px 是實測值：滿版寬度下 --radius-lg 的 16px 幾乎看不出弧度。 */
    --radius-xl:   24px;
    --radius-pill: 999px;
    --radius-full: 50%;     /* 圓形：進入鈕、浮動社群鈕、步驟圈 */

    /* ── 邊框 ────────────────────────────────────────────────── */
    --border-width:       1px;
    --border-width-thick: 3px;   /* 引言左框 */

    /* ── 陰影 ──────────────────────────────────────────────────
       原有 4 個值的高度階梯（2/8/12px）是合理的，但 alpha 用了
       .12/.14/.16 三個近似值且無理由，統一為 .14。
       陰影色用 slate 而非純黑，與低飽和色票較搭。 */
    --shadow-sm: 0 2px 8px hsl(var(--slate-900) / 0.14);
    --shadow-md: 0 8px 16px hsl(var(--slate-900) / 0.14);
    --shadow-lg: 0 12px 22px hsl(var(--slate-900) / 0.14);

    /* ── 層級 ──────────────────────────────────────────────────
       原本 30/40/50/1050 散落硬編碼。這裡建立有文件的階梯，
       並刻意避開 Bootstrap 元件用的 1000–1080 區間。 */
    --z-base:     1;
    --z-sticky:   30;    /* sticky header */
    --z-dropdown: 40;    /* 手機導覽浮層 */
    --z-overlay:  50;    /* 開發用斷點提示 */
    --z-float:    900;   /* 右下浮動社群鈕（低於 Bootstrap modal 1055）*/

    /* ── 動態 ──────────────────────────────────────────────────
       原本只有單一 --transition，拆成 duration + easing 才能個別調整 */
    --duration-fast: 120ms;
    --duration:      200ms;
    --duration-slow: 320ms;
    --ease:          cubic-bezier(0.2, 0, 0, 1);
    --transition:    var(--duration) var(--ease);
    /* 手繪分隔筆觸「畫出來」的時間。比其他動態長一個量級是刻意的 ——
       它模擬的是一筆書寫，200ms 會變成「閃現」而不是「落筆」。
       放進 token 而非硬編在元件裡，是為了讓下方 reduced-motion 區塊
       能一併歸零（該區塊是全站關閉動態的唯一開關）。 */
    --duration-draw:   1100ms;

    /* ── 玻璃鈕（2026-08-03，使用者指定：全站按鈕統一成 header 漢堡鈕那種質感）──
     *
     * 【先講清楚那顆漢堡鈕到底是什麼】實測它自己 `backdrop-filter: none` ——
     * 模糊在 header 那一層（.is-glass 的 blur(16px)）。它本體只有兩件事：
     *   background: rgba(255,255,255,.10)   半透明白
     *   border:     rgba(255,255,255,.28)   白細邊
     * 好看的前提是**底下比它暗**。
     *
     * 【所以統一的是「構造」不是「顏色」】半透明填色 ＋ 1px 細描邊 ＋ 背景模糊，
     * 顏色一律走這組 token，深底與淺底各自有一份。白玻璃直接抄到淺底上會整顆
     * 消失（10% 白疊在紙色 250,244,237 上是 251,245,238，肉眼分不出來）。
     *
     * 【下面每個 alpha 都是回推出來的，不是挑好看的】WCAG 1.4.11 要求非文字的
     * 邊界 3:1。改版前 .site-btn 的描邊（--slate-500）對色帶實測 **3.77:1**，
     * 玻璃版不能掉下來：
     *   --glass-line .55 疊在色帶(250,244,237)上 ＝ 132 灰 ≈ 改版前的 124 灰，
     *   等重量、不是變淡。
     *   深底那份維持 .28 —— 白/.28 疊在純黑 header 上實測正好 3.0:1，
     *   再淡就不合格了。
     */
    --glass-blur:       blur(10px) saturate(1.15);

    /* 淺色表面（紙面色帶、白卡）：把鈕提亮一階（沿用改版前 --card-soft
       「比色帶淺一階，鈕自然浮得出來」的方向），描邊走深色。 */
    --glass-fill:       hsl(var(--white) / .55);
    --glass-line:       hsl(var(--foreground) / .55);
    /* hover：填色壓深一階、描邊到底。方向與改版前（card-soft → nude-100）相同，
       不要反過來做成「提亮」—— 那會讓全站的 hover 方向一夕之間相反。 */
    --glass-fill-hover: hsl(var(--foreground) / .08);
    --glass-line-hover: hsl(var(--foreground) / .95);

    /* 壓在照片上（六處進入圓鈕）：深色玻璃 ＋ 白圖示。
     * ⚠️ **不能用白玻璃。** 選圖標準是「柔和色調、留白足夠」，近白照片是常態
     *    不是例外，實測最亮處 (238,239,238)，白玻璃疊上去 240 ＝ 沒有鈕。
     * ⚠️ .50 是**下限回推**，不是挑的：白箭頭要在最亮的照片上過 3:1，
     *    alpha 至少 .44。實測 .50 → 近白照片 3.52:1、服務專區淺面板 3.21:1、
     *    暗部照片 17:1。**調低就會有地方不合格。**
     */
    --glass-media-fill: hsl(var(--black) / .50);
    --glass-media-line: hsl(var(--white) / .45);
    --glass-media-fg:   hsl(var(--white));


    /* ══════════════════════════════════════════════════════════════
       Layer 2 — Semantic（元件請用這層）
       命名沿用 shadcn，與公司 merp／後台公版一致。
       ══════════════════════════════════════════════════════════════ */

    /* 表面與文字
     *
     * 【底＝純白、無框卡＝暖白】（2026-07-30 定案）
     * 曾短暫把兩者對調（底暖白、卡純白），實測後改回這個方向。
     *
     * ⚠️ --background 與 --card 同為純白，所以**無框卡不能用 --card** ——
     *    同色會完全看不見輪廓。無框卡請用 --card-soft（見下）。
     *    有框卡（.site-card 家族）用 --card 沒問題，它靠 border 分界。
     */
    --background:          var(--white);
    --foreground:          var(--slate-900);   /* 主要文字 15.70 */
    --muted:               var(--slate-50);    /* 次要區塊底 */
    --muted-foreground:    var(--slate-600);   /* 次要文字 5.59 — 最淺的合法內文色 */
    --card:                var(--white);       /* 有框卡 */
    --card-foreground:     var(--slate-900);
    /* 無框卡的底色。取 nude 軸最淺的一階：與純白有可辨的差異，又不至於
       變成一塊色塊 —— 品牌規格「設計降低至 15%」不允許用飽和底色圈出卡片。
       走暖色而非 --muted 的冷灰，是為了搭配知識素材本身的暖色調。 */
    --card-soft:           var(--nude-50);     /* #FCF8F3 暖白 */
    /* 清單裡「目前這一項」的淺底（服務專區用）。比 --card-soft 深一階，
       落差 1.06 —— 與首頁三個色帶的階距同一個尺度，看得出被選中又不跳。
       ⚠️ 曾用過 --accent-soft（淡橘），使用者反映太深，橘色現在只留給
          進度線與圓鈕 hover。不要改回有彩色。
       配主要文字 14.0 ✓ */
    --surface-selected:    var(--nude-100);    /* #F8F1E7 */

    /* 線 */
    --border:              var(--slate-200);   /* 分隔線、卡片邊框 */
    --input:               var(--slate-300);   /* 表單框線 */

    /* 主要動作 */
    --primary:             var(--black);       /* 主要按鈕底 */
    --primary-foreground:  var(--white);       /* 21.00 */

    /* 強調與互動 */
    --accent:              var(--aerial-100);  /* hover 底、標籤底 */
    --accent-foreground:   var(--aerial-800);  /* 9.49 */

    /* 高飽和互動（2026-07-30 新增，取自 ember 軸）
       用途嚴格限定在「使用者正在動的那個東西」：
         --accent-strong  進入鈕 hover 的實心底（配白箭頭 4.55 ✓）
         --accent-soft    服務專區當前項目的淺底（配主要文字 14.03 ✓）
         --border-accent  服務專區面板的有色分界線（取代原本的整片底色）
       ⚠️ 不要把 --accent-strong 拿去當大面積底色，理由見 ember 軸註解。 */
    --accent-strong:            var(--ember-600);
    --accent-strong-hover:      var(--ember-700);
    --accent-strong-foreground: var(--white);
    --accent-soft:              var(--ember-100);
    --border-accent:            var(--ember-200);
    --ring:                var(--aerial-600);  /* focus 外框 4.59 */
    --link:                var(--aerial-700);  /* 內文連結 6.40 */
    --link-hover:          var(--aerial-800);

    /* 區塊底色（區塊分色用） */
    --surface-warm:        var(--nude-50);     /* 服務專區 */
    --surface-cool:        var(--aerial-50);   /* 知識專區 */

    /*
     * 首頁的「逐階加深」階梯（2026-07-31 新增）。
     * 往下捲時每一區比上一區暖一點、深一點，銜接就不會有突兀的邊界。
     * 實測相鄰兩階的落差只有 1.06 / 1.06 / 1.12 —— 看得出分區，但不會刺眼。
     *
     * 這是在試過「一塊深色區」之後的結論：純黑與鄰區的落差是 19.9 與 21.0，
     * 換成暖棕（nude-800）也還有 8.0，使用者判定仍然太深。改成整條都留在
     * 淺色帶、只做微幅遞進。
     *
     * 【2026-07-31 二次收斂：步距再減半】
     * 第一版是 nude-50 / nude-100 / nude-200，落差 1.06 / 1.06 / 1.12，
     * 使用者仍嫌大。改成整條收在 nude-50 ~ nude-100 之間：
     *   白 → 第一階 1.057（這一階固定，因為主視覺就坐在頁面白底上）
     *   第一階 → 第二階 1.033
     *   第二階 → 第三階 1.027
     *
     * ⚠️ **不要再加深**。整體調性一旦壓過 nude-100，就不再是「淡淡的變化」，
     *    而且卡片（--card-soft ＝ nude-50）會開始浮不出底色。
     * ⚠️ 反過來也不要再更淡：實測步距壓到 1.02 以下就幾乎看不出分區了，
     *    等於白做。要調請只動 --surface-warm-2 的亮度。
     * ⚠️ 第一階刻意就是 --surface-warm 本人，不另立 token —— 服務專區原本
     *    用的就是它，避免同一個顏色有兩個名字。
     */
    /*
     * ⚠️ 這一階是**手寫的中間值，不是 generate-ramps.php 產生的**。
     *    nude 軸只有 50 / 100 / 200，50 與 100 之間沒有階，而這裡需要。
     *    色相與飽和度取兩端的中間（34 / 57%），只有亮度是新的。
     *    日後若重跑 generate-ramps.php，這一行不會被覆蓋，但要記得回頭核對
     *    它是否仍落在 nude-50 與 nude-100 之間。
     */
    --surface-warm-2:      34 57% 95.46%;      /* #FAF4ED 實體課程 */
    --surface-warm-3:      var(--nude-100);    /* #F8F1E7 知識專區 */

    /* 標籤 */
    --pill:                var(--nude-100);
    --pill-foreground:     var(--slate-800);   /* 9.71 */
    --tag:                 var(--aerial-100);
    --tag-foreground:      var(--aerial-800);  /* 8.26 */

    /* 語意色（表單驗證、提示）
       ⚠️ 這三個尚未納入色階系統，仍是通用值。
          若之後表單要做完整的錯誤/成功狀態，應比照上面的方式展開色階並驗對比。 */
    --success:             142 71% 35%;
    --warning:             38 92% 40%;
    --danger:              0 84% 45%;
}


/*
 * ══════════════════════════════════════════════════════════════════
 * Bootstrap 對接
 *
 * Bootstrap 5.3 自己就用 CSS 變數驅動（--bs-*）。覆寫它的變數，
 * 讓原生 utility（.small / .text-muted / .border / .rounded…）
 * 直接吃我們的 token，避免產生第三套並存的系統。
 * ══════════════════════════════════════════════════════════════════
 */
:root {
    --bs-body-bg:          hsl(var(--background));
    --bs-body-color:       hsl(var(--foreground));
    --bs-body-font-family: var(--font-body);
    --bs-body-line-height: var(--leading-normal);

    --bs-secondary-color:  hsl(var(--muted-foreground));   /* .text-muted */
    --bs-border-color:     hsl(var(--border));             /* .border */
    --bs-border-radius:    var(--radius);
    --bs-link-color:       hsl(var(--link));
    --bs-link-hover-color: hsl(var(--link-hover));
    --bs-emphasis-color:   hsl(var(--foreground));
}


/*
 * ══════════════════════════════════════════════════════════════════
 * 多版設計稿
 *
 * 一份設計稿 = 一組 token 覆寫。B 版只覆寫「與 A 版有差異」的變數。
 * 啟用：<html data-theme="b">，或網址加 ?theme=b（白名單過濾，見 layouts/main.php）
 * 客戶定案後把沒選中的那組刪掉，不留死碼。
 *
 * ⚠️ 覆寫請下在 Layer 1（錨點色階）或 Layer 2（語意層），不要改元件。
 *    改色階 = 整體調性換掉；改語意層 = 只換某個角色的用色。
 * ══════════════════════════════════════════════════════════════════
 */
[data-theme="b"] {
    /* 範例：換成更暖的調性
    --aerial-300: 25 45% 78%;
    --surface-cool: var(--nude-50);
    */
}


/*
 * ══════════════════════════════════════════════════════════════════
 * 響應式
 *
 * 間距類 token 在窄幅收斂，各元件不必各自寫 media query。
 * ⚠️ 斷點一律用 Bootstrap 的 .98 寫法。
 *    先前 wireframe.css 用 991px、tokens.css 用 991.98px，
 *    中間有 0.98px 的縫隙（在該寬度下兩邊規則都不套用）。
 * ══════════════════════════════════════════════════════════════════
 */
@media (max-width: 991.98px) {
    :root {
        --gutter-x:  1.5rem;
        /* 跟著桌機的 3→6rem 等比放大（2026-07-31）。窄幅本來就單欄、
           每一區都遠比視窗高，不需要跟桌機一樣多的留白，所以只到 4rem
           而不是 6rem —— 全照桌機放會讓手機版整頁長度暴增。 */
        --section-y: 4rem;
        --header-y:  1rem;
        --text-2xl:  1.5rem;   /* 頁面主標在手機縮一級 */
        --text-xl:   1.15rem;  /* LOGO */
    }
}

@media (max-width: 575.98px) {
    :root {
        --gutter-x:  1.3rem;
        --section-y: 2.5rem;
    }
}

/* 尊重使用者的減少動態偏好 */
@media (prefers-reduced-motion: reduce) {
    :root {
        --duration-fast: 0ms;
        --duration:      0ms;
        --duration-slow: 0ms;
        --duration-draw: 0ms;
    }
}
