/* Standalone MI-OS token file (pages that <link> it; /book retired 2026-10-13, D-121).
   Mirrors ~/luxe-kit/styles/tokens.css (SoT). Until 2026-09-29 build_book_ledger.py
   regenerated it from the old SPA's inline block; that extraction is gone — edit here,
   in step with luxe-kit. /app <link>s this file too (inline copy and demo.src.html
   retired 2026-10-05; see RETIREMENT_INVENTORY §F token copies). */
/* tokens:begin — 併回 repo 時改用 styles/tokens.css */
:root{

  /* 色彩收斂 2026-08-12（個股頁改版 W1 / D4）：--accent／--accent-wash／--metal 逐字
     抄自 ~/luxe-kit/styles/tokens.css。/app 先前用的深藍強調色與亮金金屬色是 kit
     前一個世代的值，已與其餘三個 App drift；kit 才是 SoT。 */
  --paper:#F6F3EC;
  --paper-2:#ECE8DD;
  --paper-3:#E7E2D6;
  --ink:#191712;
  --hair:rgba(25,23,18,.12);
  --accent:#16555f;
  --metal:#9c7c42;
  --alert:#8C2F23;
  --wash:rgba(25,23,18,.05);
  --glass:rgba(246,243,236,.72);
  --glass-strong:rgba(246,243,236,.82);
  --scrim:rgba(25,23,18,.32);
  --shadow:0 14px 34px rgba(25,23,18,.16);
  --ink-80:rgba(25,23,18,.80);
  --ink-60:rgba(25,23,18,.60);
  --ink-45:rgba(25,23,18,.45);
  --ink-40:rgba(25,23,18,.40);
  --ink-30:rgba(25,23,18,.30);
  --ink-25:rgba(25,23,18,.25);
  --accent-wash:rgba(22,85,95,.08);
  --accent-hair:rgba(22,85,95,.34);
  --alert-wash:rgba(140,47,35,.08);
  --r-card:22px;
  --r-pill:999px;
  --r-sheet:30px;
  --t-fast:.3s;
  --t-base:.5s;
  /* 圖表序列色（luxe-kit tokens.css 的鏡像；SoT 在 kit）。專供圖表繪圖區，非 UI 色。
     以 dataviz validate_palette.js 對 --paper 驗過：L-band / C≥0.10 / 對比≥3:1 /
     最差相鄰 CVD ΔE 15.4。改值前重跑 validator，並同步 luxe-kit。 */
  --chart-1:#2f6fae; --chart-2:#128a5f; --chart-3:#b07d1c; --chart-4:#3f7a2a;
  --chart-5:#4a3aa7; --chart-6:#c2506f; --chart-7:#c1521f;
  --serif-tc:"Noto Serif TC",serif;
  --latin:var(--sans); /* 2026-09-18 拍板:數字改走內文黑體(luxe-kit DESIGN-SYSTEM §2) */
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang TC","Noto Sans TC","Microsoft JhengHei",sans-serif;
  --tk-kicker:.28em;
  --tk-caps:.26em;
  --tk-label:.12em;
  --tk-title:.04em;
  --ease:cubic-bezier(.22,1,.36,1);
  --spring:cubic-bezier(.32,.72,0,1);
}
/* tokens:end */
/* luxe-fs-scale:start — 由 luxe-kit 產生,勿就地改。
   canonical:luxe-kit/styles/tokens.css。要改階梯就改 canonical,再跑 node scripts/sync-kit.mjs。
   五個站各有一份手抄階梯 = 五份會各自漂移的字級 SoT,那正是階梯要防的事。 */
:root {
  /* ---- type scale ------------------------------------------------------
     One ladder. Every font-size in a product resolves to a rung — no literal
     px in component CSS, no literal px in inline styles, none in JS templates.
     A product without a named ladder drifts downward: each new component is
     authored one notch smaller than the last, and nobody notices until the
     whole app reads at 11px. That is exactly what happened to 羅盤.

     CJK needs more optical size than Latin at the same nominal px: fuller
     glyph box, denser strokes, no ascenders to carry the eye. 13px Latin body
     reads fine; 13px 繁體 does not. --fs-base is the body size, and the floor
     is --fs-micro, which is only ever a tracked Latin kicker or a tab label.
     Web steps the whole ladder up (see the min-width:900 block below): a
     1440px working column is read from ~70cm, a phone from ~35cm. */
  /* 2026-09-27 使用者拍板:字級改連續。每一階在斷點上的值 = 原階梯值(360/900/1600/1900),
     中間用 clamp(本階, 截距+斜率vw, 下一階) 線性插值,不再在 900/1600/1900 突跳;<360 停在手機值、≥1900 停在終點。
     版型斷點不變,只有字級連續。改數字請改表(各 media 區塊的端點),斜率/截距照 (y-x)/(b-a) 重算。 */
  --fs-micro:  clamp(10.5px, 10.167px + 0.093vw, 11px);   /* tracked Latin kicker, tab label. nothing else. */
  --fs-caps:   clamp(12px, 11.667px + 0.093vw, 12.5px);     /* CJK micro-label, section kicker */
  --fs-xs:     clamp(13px, 12.667px + 0.093vw, 13.5px);     /* caption, meta, badge */
  --fs-sm:     clamp(14px, 13.333px + 0.185vw, 15px);     /* secondary body, chip, sub-label */
  --fs-md:     clamp(15px, 14.333px + 0.185vw, 16px);     /* button, list meta, dense body */
  --fs-base:   clamp(16px, 15.333px + 0.185vw, 17px);     /* THE body size. prose, item names. NOT inputs: a field's text = its label (--fs-caps); phone 16px floor = luxe-pickers sealFontFloor. */
  --fs-lg:     clamp(17.5px, 16.5px + 0.278vw, 19px);   /* card title, item name with weight */
  --fs-xl:     clamp(19.5px, 18.5px + 0.278vw, 21px);   /* sheet title, sub-head */
  --fs-2xl:    clamp(22px, 20px + 0.556vw, 25px);     /* screen sub-display */
  --fs-3xl:    clamp(26px, 23.333px + 0.741vw, 30px);     /* numeral display, keypad */
  --fs-title:  clamp(34px, 28.667px + 1.481vw, 42px);     /* screen title */
  --fs-amount: clamp(56px, 42.667px + 3.704vw, 76px);     /* the one big number per screen */
  /* 2026-07-30: --t-hero 原本只定義在下面的 min-width:900 區塊裡,於是手機版
     `font-size:var(--t-hero)` 解不出值、**整條宣告被丟掉** → hero 掉回繼承的 15px。
     五個站都讀 var(--t-hero) 且都沒給 fallback,實際受害的是兩個:
       天樞(.hero h1/.stat n)、璇璣(h1.display/.score-hero .big)—— 無條件讀,手機版整個 hero 平掉。
       羅盤/萬試通自己的 tokens.css 早就有一份 base --t-hero:64px(手抄的),所以逃過;
       衡只在 @media(min-width:1220px) 裡讀,那個寬度本來就有值,也逃過。
     「同一個 token 有兩份定義,其中一份剛好補到 canonical 的洞」不是安全,是巧合 ——
     canonical 缺一個 rung,是不是壞掉完全取決於各站有沒有留舊的手抄本。
     這正是這道階梯要防的失敗模式(字級靜默往下漂),只是漏在階梯自己身上。
     教訓寫進閘門:fs-scale 的任何字級 rung 都必須在 base :root 有值,
     web 區塊只能「調大」,不能是某個 rung 的唯一定義。 */
  --t-hero:    clamp(64px, 48px + 4.444vw, 88px);     /* hero. 360→900 連續長到 88px,之後固定 */
  /* ---- spacing scale(2026-09-14 使用者拍板新增)------------------------
     新寫的 margin / padding / gap 取一階,不寫字面 px。--pad-page 是頁面留白、隨斷點跳階,不併進來。
     住在這個區塊是為了搭 sync-kit 既有的 fan-out,不是因為它屬於字級。
     既有頁面與黃金範例尚未遷移(常用 6/10/14/18/22 會吸附 2px),另排一波在 430/1440 對截圖。 */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-8: 32px;
  --sp-12: 48px;
  --sp-16: 64px;
  --sp-24: 96px;
}
/* 密集版階梯(2026-10-16 RF-220 使用者拍板):工作型 CRM 用,一屏要放下清單與明細,字級比展示型小一截。
   宿主在 <html> 寫 data-fs-ladder="dense" 啟用;值 = 天樞 DEMO e8b11d5 視覺契約逐值(46 個寬度實測)。
   跳階不連續是刻意的:契約量的是 899/1220/1599 這類交界寬度,改連續等於改驗收稿,要改先登錄契約裁決。
   沒列的 rung(--fs-3xl / --fs-title)沿用上面的標準階。 */
:root[data-fs-ladder="dense"] {
  --fs-micro: 10.5px; --fs-caps: 12px; --fs-xs: 13px; --fs-sm: 14px; --fs-md: 15px;
  --fs-base: 16px; --fs-lg: 17.5px; --fs-xl: 19.5px; --fs-2xl: 22px;
  --fs-amount: 38px; --t-hero: 32px;
}
@media (min-width: 900px) {
  :root {
    --fs-micro:  11px;
    --fs-caps:   clamp(12.5px, 11.857px + 0.071vw, 13px);
    --fs-xs:     clamp(13.5px, 12.857px + 0.071vw, 14px);
    --fs-sm:     clamp(15px, 14.357px + 0.071vw, 15.5px);
    --fs-md:     clamp(16px, 14.714px + 0.143vw, 17px);
    --fs-base:   clamp(17px, 15.714px + 0.143vw, 18px);
    --fs-lg:     clamp(19px, 17.714px + 0.143vw, 20px);
    --fs-xl:     clamp(21px, 18.429px + 0.286vw, 23px);
    --fs-2xl:    clamp(25px, 18.571px + 0.714vw, 30px);
    --fs-3xl:    clamp(30px, 24.857px + 0.571vw, 34px);
    --fs-title:  clamp(42px, 34.286px + 0.857vw, 48px);
    --fs-amount: clamp(76px, 50.286px + 2.857vw, 96px);
    --t-hero: 88px;
    --pad-page: 64px;
  }
}
/* 大螢幕兩階(2026-09-02,天樞 luxe DEMO 提案回寫):≥1600 / ≥1900 再各升一階。
   27 吋螢幕看到 900 階 = 76px 大數 + 手機階的留白 = 手機放大,不是網頁版。
   終點 = 黃金稿 luopan-luxe-v3 的 hero 88 / 大數 132:--t-hero 在 900 階就已到頂,
   兩階只推 --fs-amount 與正文;殼層(rail / context 欄寬、sheet 寬、留白)同斷點
   一起放大,規格在 docs/DESIGN-SYSTEM.md §斷點。閘門 fs-scale-web-only-rung 不變:
   每個 rung 仍在 base :root 有值,這裡只准調大。 */
@media (min-width: 1600px) {
  :root {
    --fs-micro:  clamp(11px, 8.333px + 0.167vw, 11.5px);
    --fs-caps:   clamp(13px, 10.333px + 0.167vw, 13.5px);
    --fs-xs:     clamp(14px, 8.667px + 0.333vw, 15px);
    --fs-sm:     clamp(15.5px, 12.833px + 0.167vw, 16px);
    --fs-md:     clamp(17px, 11.667px + 0.333vw, 18px);
    --fs-base:   clamp(18px, 12.667px + 0.333vw, 19px);
    --fs-lg:     clamp(20px, 14.667px + 0.333vw, 21px);
    --fs-xl:     clamp(23px, 12.333px + 0.667vw, 25px);
    --fs-2xl:    clamp(30px, 8.667px + 1.333vw, 34px);
    --fs-3xl:    clamp(34px, 12.667px + 1.333vw, 38px);
    --fs-title:  clamp(48px, 16px + 2vw, 54px);
    --fs-amount: clamp(96px, -96px + 12vw, 132px);
    --t-hero: 88px;
    --pad-page: 80px;
  }
}
@media (min-width: 1900px) {
  :root {
    --fs-micro:  11.5px;
    --fs-caps:   13.5px;
    --fs-xs:     15px;
    --fs-sm:     16px;
    --fs-md:     18px;
    --fs-base:   19px;
    --fs-lg:     21px;
    --fs-xl:     25px;
    --fs-2xl:    34px;
    --fs-3xl:    38px;
    --fs-title:  54px;
    --fs-amount: 132px;
    --t-hero: 88px;
    --pad-page: 96px;
  }
}
/* 密集版的三個跳階(選擇器比 :root 具體,與上面標準階的先後無關;三段之間依寬度遞增)。 */
@media (min-width: 900px) {
  :root[data-fs-ladder="dense"] { --fs-caps: 12.5px; --fs-sm: 14.5px; --fs-md: 15.5px; --fs-base: 16.5px; --fs-lg: 18px; --fs-xl: 20px; --fs-2xl: 24px; --fs-amount: 48px; --t-hero: 40px; }
}
@media (min-width: 1600px) {
  :root[data-fs-ladder="dense"] { --fs-micro: 11px; --fs-caps: 12.5px; --fs-xs: 13.5px; --fs-sm: 15px; --fs-md: 16px; --fs-base: 18px; --fs-lg: 19px; --fs-xl: 22px; --fs-2xl: 26px; --fs-amount: 56px; --t-hero: 46px; }
}
@media (min-width: 1900px) {
  :root[data-fs-ladder="dense"] { --fs-micro: 11.5px; --fs-caps: 13px; --fs-xs: 14px; --fs-sm: 15.5px; --fs-md: 17px; --fs-base: 19px; --fs-lg: 20px; --fs-xl: 23px; --fs-2xl: 28px; --fs-amount: 64px; --t-hero: 52px; }
}
/* luxe-fs-scale:end */
/* tables:begin — 全站投行表格的唯一正本(2026-10-28 使用者 #8 拍板 Q1-Q7;規格
   docs/architecture/VIZ_TABLE_SPEC_RCA.md「Tables」)。頁面以 <body class="luxe-tables"> 選用;
   :where() 讓特異度等同裸 table/th/td,模組 CSS 照舊可以覆寫,但只准覆寫寬度與內距 ——
   置中由 scripts/lint_viz_geometry.py 的 tc 計數只減不增。
   文字欄靠左、數字欄靠右走等寬數字;表頭與欄同向。表頭底一條墨線、資料列髮絲線、
   tr.tot = 小計(墨線＋加重)、tr.tot.g = 合計(雙線);列由產表程式標記,CSS 不猜。
   不做斑馬紋。負數由 td() 轉成 (1,234),右括號掛在欄外(.cp 零寬)讓數字對齊。 */
:where(.luxe-tables) table{border-collapse:collapse;width:100%;font-size:var(--fs-sm)}
/* 窄表(<=3 欄)不撐滿:投行表的欄寬跟著內容走,兩欄 k/v 被拉到滿寬會讓數字離標籤半個版面遠。 */
:where(.luxe-tables) table:not(:has(tr>:nth-child(4))){width:auto;min-width:min(100%,24rem)}
:where(.luxe-tables) th{font-weight:400;font-size:var(--fs-caps);color:var(--ink-60);text-align:right;vertical-align:bottom;padding:var(--sp-3);border-bottom:1px solid var(--ink);white-space:nowrap}
:where(.luxe-tables) td{padding:var(--sp-3);border-top:1px solid var(--hair);text-align:right;font-family:var(--latin);font-variant-numeric:lining-nums tabular-nums;white-space:nowrap}
:where(.luxe-tables tbody tr:first-child) td{border-top:0}
:where(.luxe-tables) :is(th,td):first-child,:where(.luxe-tables) :is(th,td).l{text-align:left}
:where(.luxe-tables) td.l,:where(.luxe-tables) td .nm{font-family:var(--sans)}
:where(.luxe-tables) td .nm{display:block}
:where(.luxe-tables) td .tk{font-size:var(--fs-xs);color:var(--ink-45)}
:where(.luxe-tables) td .cp{display:inline-block;width:0}
:where(.luxe-tables) tbody tr{cursor:pointer}
:where(.luxe-tables) tbody tr:hover td{background:var(--wash)}
:where(.luxe-tables) tr.tot td{font-weight:500;border-top:1px solid var(--ink)}
:where(.luxe-tables) tr.tot.g td{border-top:3px double var(--ink)}
:where(.luxe-tables) .tblwrap{border:1px solid var(--hair);border-radius:var(--r-card);background:var(--paper)}
/* tables:end */
