/* 主題:一個主題 = 一塊 token — #259,#392 擴成五塊。
 *
 * 使用者原話 2026-08-25:「我想支援多種色彩主題,目前先3種,要考慮以後的主題擴充
 * 性。目前的 UI code 可能需要 refactor。」#392 是那句「以後」到的那一天:D-F102 定
 * 下**五個主題**(淺色 / 深色 / 低飽和深色 / 可愛 / Organic),而 #241 那四顆可選的
 * 主題色跟著退役 —— 一個主題自己就是一整組配色,再讓使用者從裡面挑一顆主色,等於
 * 讓兩個作者同時決定同一格。
 *
 * ## 這一支裝什麼、不裝什麼
 *
 * 裝的是**值**:顏色、陰影、圓角、字型堆疊。每一個主題在這裡各佔一塊,而那一塊
 * 是那個主題的全部 —— 讀 Organic 長什麼樣不必翻七支 views/*.css。
 *
 * 不裝規則。「圓角 16px 的是卡片」住在 style.css,「這台裝置現在選的是哪個主題」
 * 住在 prefs.js。這一支一條選擇器都不認得 `.card`。
 *
 * **#392 之後它是全站唯一一個寫得出色碼的地方。** 在這裡以外的每一支樣式表與每
 * 一支 JS(`web/` 底下,vendor 除外)裡出現任何 hex / rgb / hsl 字面值都紅
 * (`test_web.NoColourLiteral
 * OutsideTheTokenLayer`,例外逐條列在那一支裡)—— 少了那條線,「換一個主題」永遠
 * 只換得動一部分畫面,而剩下的那一部分沒有人數得出來。
 *
 * ## 七個選擇器,六條路
 *
 *   html                                   不隨主題變的常數(相機層,見底下)
 *   :root                                  沒有 data-theme(第一次開、或選「跟系統」)
 *   @media (prefers-color-scheme: dark)    ↑ 的暗色那一半 —— **「跟系統」走的仍然是它**
 *   html[data-theme="light"]               鎖淺色
 *   html[data-theme="dark"]                鎖深色
 *   html[data-theme="dark-muted"]          鎖低飽和深色 — #392
 *   html[data-theme="cute"]                鎖可愛 — #392
 *   html[data-theme="organic"]             鎖 Organic
 *
 * `auto` **沒有自己的規則,而那是刻意的**:它的意思正是「沒有人鎖」,所以它落回
 * `:root` 加那句 media query。「跟系統」的深色那一半是 **`dark`** 而不是
 * `dark-muted`(D-F102):低飽和深色是一個要自己挑的東西,不是深色的新預設。
 *
 * 特異度:`html[data-theme=…]` 是 (0,1,1),壓得過 media 裡那個 `:root` 的
 * (0,1,0)(`@media` 不加特異度)。所以在深色系統上鎖淺色是淺的,在淺色系統上鎖
 * 深色是深的 —— 這正是「顯式主題」這四個字的全部內容。
 *
 * **淺色那一份只寫一次**(`:root` 與 `html[data-theme="light"]` 共用同一個選擇器
 * 清單:清單裡每一支各自算特異度,所以 (0,1,0) 與 (0,1,1) 兩個身分都在)。深色那
 * 一份**寫了兩次**,而那是 CSS 的限制不是選擇:media 裡的 `:root` 與 media 外的
 * `html[data-theme="dark"]` 隔著一個 `@media` 邊界,共用不了同一組宣告。兩份會漂
 * 移,所以 test_web 的 EveryThemeBlockDefinesTheWholeContract 逐字比對它們。
 *
 * ## 載入順序
 *
 * index.html:style.css → **themes.css** → prefs.css。中間那一格是 token 的定義,
 * 兩邊是讀它的人:style.css 的元件讀形狀與顏色,prefs.css 只剩字級與 ＋ 鈕的左右
 * (#392 之後它一格顏色都不碰了 —— 挑主色那四條規則跟著 `--ac-*` 一起退役)。
 *
 * ## 值從哪裡來
 *
 * 五塊的值由 #391 的設計產物算出來(OKLCH 上定錨、WCAG 對比逐對驗過),而**這裡
 * 是它們在產品裡的唯一一份**:設計那邊的表是推導紀錄,不是執行期讀得到的東西。
 * 對比與色差兩條線由 test_web 的 EveryThemeMeetsContrast 與
 * TheBalanceLinesStayApartInEveryTheme 守著,而它們讀的正是這一支檔案。
 *
 * ── 契約清單開始 ──────────────────────────────────────────────
 *   新主題要定義的就是底下這些,一格都不能少(缺一格 = 那個主題在某一塊畫面上
 *   會靜靜地掉回別的主題的值,而畫面不會說話)。
 *
 *   面與字
 *     --bg          頁面底色(html 與 body 都畫,D-F90)
 *     --card        卡片、彈出的紙的底色
 *     --chip        藥丸鈕、收合面、長條槽的底
 *     --line        分隔線與框線
 *     --ink         主要文字
 *     --dim         次要文字、標籤、分隔用的小字
 *     --nav         底部導覽列的底色(多數主題與卡片同色,Organic 刻意差一階)
 *
 *   品牌
 *     --accent        主色:主要動作的實心底、「現在在這一頁」、正向的數字
 *     --on-accent     實心 accent 上面那些字與描邊(#392 之前全站寫死 18 個 #fff,
 *                     而深色主題的亮綠底上白字只有 2.2:1)
 *     --accent-soft   主色的淡底:選中的 chip、圖例
 *     --ring          鍵盤焦點框
 *     --accent-grad-a 主鈕 / FAB 漸層的起點(不做漸層的主題兩格同值)
 *     --accent-grad-b 漸層終點
 *
 *   記帳種類(一筆帳是支出、收入、退款還是轉帳 —— log.css 的 `.tag.*`)
 *     --kind-expense --kind-income --kind-refund --kind-transfer
 *     --kind-expense-soft --kind-income-soft --kind-refund-soft --kind-transfer-soft
 *
 *   帳本種類(多人分帳 / 共同帳戶 / 集資 / 個人記帳 —— 帳本籤與帳本清單)
 *     --ledger-split --ledger-pool --ledger-capital --ledger-personal
 *     --ledger-split-soft --ledger-pool-soft --ledger-capital-soft --ledger-personal-soft
 *
 *   狀態
 *     --ok --warn --danger        成功 / 警告 / 錯誤與刪除
 *     --ok-soft --warn-soft --danger-soft
 *     --on-warn                   警告色實心底上的字(未讀徽章)
 *
 *     **`--warn` 與 `--danger` 在 #392 之前是同一格。** 「差額還掛著」與「這一顆
 *     按下去帳本就沒了」共用一個顏色,而使用者要分辨的正是那兩件事。
 *
 *   圖表
 *     --chart-1 --chart-2 --chart-3   圓餅的六段 / 成員色塊(第六格同時是
 *     --chart-4 --chart-5 --chart-6   圓餅上的「其他」)
 *     --chart-cash            戶頭餘額那條線
 *     --chart-settled         帳面餘額那條線
 *     --chart-paid            各人墊付那幾條長條
 *     --chart-grid            格線與軸線
 *
 *     **成員色與圖表序列色是同一組** — #392。`fmt.js` 以前自己拿著五個 hex,三個
 *     主題共用同一份(深色不變、Organic 也不變),而同一個人在首頁的色塊與報表
 *     圓餅上本來就該是同一個顏色。
 *
 *     `--chart-cash` / `--chart-settled` 是 #182 首頁那張圖上的兩條餘額線,而那一
 *     票留下一句要守的話:「戶頭裡有多少錢」「都平之後剩多少」跟「花掉多少錢」疊
 *     在同一張圖上,三者不能同色。**新主題要接下的是這句承諾,不只是兩個色碼**
 *     (TheBalanceLinesStayApartInEveryTheme 量的是 OKLab 距離,不是對比)。
 *
 *   系統
 *     --statusbar        Android 狀態列 / iOS 瀏海底下透出來的那一片(= 頁面底色)
 *     --manifest-theme   manifest 的 theme_color 與 background_color(同上)
 *
 *   形狀
 *     --radius-s    輸入框、小方鈕
 *     --radius-m    主要動作鈕、方形的容器
 *     --radius-l    卡片、彈出的紙
 *     --radius-pill 藥丸
 *     --border-w    卡與 chip 的框線粗細(可愛主題是 2px,其餘 1px)
 *
 *   陰影與幕
 *     --shadow      卡片、彈出的紙
 *     --shadow-fab  浮在畫面上的那顆 ＋ 鈕(它離頁面更遠,所以是另一階)
 *     --scrim       彈出的紙底下那一層幕(#392 之前四處各寫一個 rgba,而其中一處
 *                   的值與另外三處不同 —— 沒有人是故意的)
 *
 *   底紋
 *     --bg-deco     頁面底色之上那一層裝飾(`body::before`)。多數主題是 `none`;
 *                   可愛與 Organic 各有一組很淡的漸層。
 *
 *   字型
 *     --font-body     內文
 *     --font-heading  app 名、卡片標題(h3)、那個大數字(.big)
 * ── 契約清單結束 ──────────────────────────────────────────────
 *
 * **不在契約裡的,與為什麼。**
 *
 *   `border-radius: 50%`(頭像圓點、未讀徽章)與 `0 8px 8px 0`(左邊那條色帶的
 *   端點)是**幾何**不是主題:一個圓換了主題還是圓,而那條色帶的方角那一側貼著
 *   卡緣,圓起來就露出底色。
 *
 *   **相機層那一組(`--cam-*`)不在契約裡,而它們在底下那塊 `html {}` 上。** 那
 *   一層蓋著相機的畫面,而相機的畫面不隨主題變:白字與半透明黑站在鏡頭拍到的東
 *   西上面,五個主題都是同一組值。收成 token 是為了讓「靜態掃描:token 層以外零
 *   色碼」那條線成立,不是為了讓它跟著主題走 —— 所以它不進契約,新主題也不必替
 *   它填一格。
 *
 *   **契約裡有幾格今天還沒有讀者**,而那是刻意的:`--kind-expense` / `--kind-refund`
 *   / `--kind-transfer` 那一組與 `--ledger-split` / `--ledger-capital` /
 *   `--ledger-personal` 那一組是 #392 新開的能力(「一筆帳是哪一種」「一本帳是哪
 *   一種」在畫面上要一眼看得出來),而畫出它們是版面的改動不是顏色的改動 ——
 *   #392 的檔案範圍是「把既有的硬編碼顏色換成 token」,不是替每一顆籤重新排版。
 *   **不先定義它們的代價比較大**:下一張票要畫那幾顆籤的時候,五個主題各要重解一
 *   次 20 個顏色,而那正是這一票在做的事。`--accent-soft` 同理(選中的 chip 今天
 *   走的是 `--card` 加一圈 accent 邊)。
 *
 *   web/auth.css 與 web/api.js 裡的圓角**沒有跟著換**:#259 的檔案範圍是
 *   style.css / views/*.css,#392 只補了那兩支的顏色。登入閘與 toast 的 12px 因此
 *   仍然是寫死的 —— 下一個人會看到這一句。 */

/* ------------------------------------------------------------ vendored 字型

   三個家族 — #392(D-F102)。**宣告是全域的,而用得到哪一個由主題決定**:
   `@font-face` 宣告的是「這個名字對到哪一個檔」,不是「誰要用它」;瀏覽器在沒有
   人叫得到那個 family 的時候一個 byte 都不會去拿(#260 在沙盒 Chromium 上實測
   過:鎖淺色開一次 → `/vendor/fonts/` 零個請求)。分成幾塊寫、或搬進第四支樣式
   表,換來的只是一組要跟著主題開關的宣告。

     Plus Jakarta Sans  淺色 / 深色 / 低飽和深色的標題與內文;Organic 的內文
     Nunito             可愛的標題與內文
     Fraunces           Organic 的標題(變數軸 opsz / wght / SOFT / WONK)

   **`font-display: swap`**:三支加起來 183 KB,而它們是從自己的伺服器拿的(同一
   個 origin、無 CDN)—— swap 的意思是「先用系統字畫,拿到了再換」,而那正是這個
   app 在慢速網路上該有的行為:先看得到字。

   **`unicode-range` 限 latin,而那是「鎖一個主題只下載一族」的保證**:三個宣告的
   範圍逐字相同,而瀏覽器只會去拿「畫面上真的有字落在這個範圍、且真的有人叫得到
   這個 family」的那一份。中文一個字形都沒有 —— 這不是漏掉,是這三套字本來就沒有
   中文,所以 `--font-body` / `--font-heading` 的堆疊在它們後面接的是系統那一串
   (`-apple-system, "SF Pro Text", "Noto Sans TC", system-ui`),而落回去的粒度是
   **字元**不是整段(font fallback 就是這樣運作的)。

   **不 preload**:哪一族是關鍵取決於使用者鎖了哪一個主題,而 preload 猜錯就是白
   下載一份 120 KB 的 Fraunces 給一個鎖了淺色的人。

   來源與雜湊(vendored 的東西沒有 lockfile,這份紀錄就是「它沒有被人動過」的全部
   證據,同 ARCHITECTURE §4.6 對 uPlot / jsQR / zxing 立的規矩;由
   test_web.TheThemeFontsAreVendored 釘著):

     plus-jakarta-sans-latin-var.woff2   27,348 bytes
       https://fonts.gstatic.com/s/plusjakartasans/v12/LDIoaomQNQcsA88c7O9yZ4KMCoOg4Ko20yw.woff2
       sha256 153fc85b70298beeb1d61a5f723331649e7f23bb77302a66e61cb3e2fbdb5e79
     nunito-latin-var.woff2              39,128 bytes
       https://fonts.gstatic.com/s/nunito/v32/XRXV3I6Li01BKofINeaB.woff2
       sha256 ba344451eab25b217a165363b1982048a5e5830a0daf36577973955a04cac793
     fraunces-latin-var.woff2           120,788 bytes
       https://fonts.gstatic.com/s/fraunces/v38/6NUI8FyLNQOQZAnv9bYEvCeYdG9Ea92uemAO8Uik.woff2
       sha256 e79165432c3e1e01aff1ea4d394dec633c13ec70f09e92432ae77aa6e1aa7328

   三支都是 SIL Open Font License 1.1,授權全文與檔案放在一起(vendor/fonts/OFL-*.txt)
   —— OFL 要求散布時附上授權,而「附」的意思是它得跟著檔案走,不是寫在某一份文件裡。

   **#260 的 Figtree 與 Caprasimo 在這一票退休**:Organic 換了一整組配色與字型
   (D-F102),而留著兩個沒有人叫得到的 `@font-face` 等於留兩個沒有人會發現壞掉的
   檔案。 */
@font-face {
  font-family: "Plus Jakarta Sans";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("vendor/fonts/plus-jakarta-sans-latin-var.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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Nunito";
  font-style: normal;
  font-weight: 200 1000;
  font-display: swap;
  src: url("vendor/fonts/nunito-latin-var.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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("vendor/fonts/fraunces-latin-var.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+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* --------------------------------------------------- 不隨主題變的常數(相機層)

   拍照與掃 QR 那一層蓋著**相機拍到的畫面**,而那個畫面不隨主題變:白字與半透明
   黑站在鏡頭前面的東西上,五個主題都是同一組值。#392 之前這一層在 views/add.css
   裡是 19 個各自為政的 rgba / #fff,收成八格是為了讓「token 層以外零色碼」那條
   靜態線成立 —— 不是為了讓它跟著主題走。

   **選擇器是 `html` 而不是 `:root`**,而那是兩件事:`:root` 是淺色那一塊的身分
   (test_web 的 theme_blocks() 靠它認人),而這裡要的是一塊「不是任何主題」的常
   數。特異度 (0,0,1) 比每一塊主題都低,所以哪一天有主題真的要換掉相機層的白,
   它自己那一塊蓋得過來。 */
html {
  --cam-bg: rgba(0, 0, 0, .82);
  --cam-bg-solid: rgba(0, 0, 0, .92);
  --cam-ink: #FFFFFF;
  --cam-line: rgba(255, 255, 255, .5);
  --cam-line-strong: rgba(255, 255, 255, .85);
  --cam-fill: rgba(255, 255, 255, .28);
  --cam-fill-strong: rgba(255, 255, 255, .55);
  --cam-chip: rgba(0, 0, 0, .45);
  --cam-ring: rgba(0, 0, 0, .35);
  --cam-black: #000000;
  /* `mask-image` 的漸層只讀 alpha,任何不透明的顏色畫出來都一樣 —— 它是一個
     **遮罩**不是一個顏色(log.css 那幾條把一排籤的兩端淡出去的規則)。收成一格
     是為了讓「token 層以外零色碼」那條線不必為它開例外。 */
  --mask-ink: #000000;
}


/* ------------------------------------------------------------------- 淺色

   預設的那一個 —— 沒有人鎖主題、而系統也不是深色時看到的就是它。綠色主色沿用
   #241 以來的身分(這個 app 的正向數字一直是綠的),而 #392 把它從 #2f6f4f 推到
   #047857:同一個色族,對卡片 5.48:1(舊的 5.20),而它同時是 `--kind-income` ——
   「收入」與「主色」在這個 app 裡本來就是同一件事的兩個名字。 */
/* **設定頁那一格色卡也掛在同一份選擇器清單上** — #392。那六格畫的是
   `var(--bg)` / `var(--card)` / `var(--accent)`(views/account.css 的
   `.ac-theme .ac-chip`),而這一句把那一格裡的三個 token 換成它代表的那個主題的
   —— **色卡印出來的必定就是按下去會得到的東西**,沒有第二個作者。#241 的四顆色票
   (`.ac-sw[data-accent=…]`)當年立的就是這條規矩,而它跟著那四顆一起退役之後,
   這裡是它的新家。 */
:root,
html[data-theme="light"],
.ac-theme[data-theme="light"] {
  /* 面與字 */
  --bg: #F8FAFC; --card: #FFFFFF; --chip: #EEF3F1; --line: #DCE4E0;
  --ink: #0F172A; --dim: #5B6472; --nav: #FFFFFF;
  /* 品牌 */
  --accent: #047857; --on-accent: #FFFFFF; --accent-soft: #D6F3E6; --ring: #047857;
  --accent-grad-a: #047857; --accent-grad-b: #047857;
  /* 記帳種類 */
  --kind-expense: #B15158; --kind-income: #047857; --kind-refund: #0369A1; --kind-transfer: #6D28D9;
  --kind-expense-soft: #FFF3F2; --kind-income-soft: #D6F3E6; --kind-refund-soft: #DBEFFB; --kind-transfer-soft: #EAE2FB;
  /* 帳本種類 */
  --ledger-split: #1D4ED8; --ledger-pool: #0F766E; --ledger-capital: #B45309; --ledger-personal: #BE185D;
  --ledger-split-soft: #DCE7FD; --ledger-pool-soft: #D2F0EC; --ledger-capital-soft: #FFF3E3; --ledger-personal-soft: #FBDDEA;
  /* 狀態 */
  --ok: #15803D; --warn: #B45309; --danger: #B91C1C; --ok-soft: #E3FAE9;
  --warn-soft: #FFF3E3; --danger-soft: #FDE2E2; --on-warn: #FFFFFF;
  /* 圖表 */
  --chart-1: #2563EB; --chart-2: #059669; --chart-3: #D97706; --chart-4: #7C3AED;
  --chart-5: #DB2777; --chart-6: #0891B2; --chart-cash: #1D4ED8; --chart-settled: #7E22CE;
  --chart-paid: #3B82F6; --chart-grid: #DCE4E0;
  /* 系統 */
  --statusbar: #F8FAFC; --manifest-theme: #F8FAFC;
  /* 形狀 */
  --radius-s: 10px; --radius-m: 12px; --radius-l: 16px;
  --radius-pill: 999px; --border-w: 1px;
  /* 陰影與幕 */
  --shadow: 0 1px 2px rgba(15,23,42,.05), 0 8px 24px rgba(15,23,42,.05);
  --shadow-fab: 0 2px 6px rgba(15,23,42,.18), 0 10px 24px rgba(15,23,42,.14);
  --scrim: rgba(15,23,42,.5);
  /* 底紋 */
  --bg-deco: none;
  /* 字型 */
  --font-body: "Plus Jakarta Sans", -apple-system, "SF Pro Text", "Noto Sans TC", system-ui, sans-serif;
  --font-heading: "Plus Jakarta Sans", -apple-system, "SF Pro Text", "Noto Sans TC", system-ui, sans-serif;
}

/* ------------------------------------------------- 深色,跟著系統走(auto)

   **與底下 `html[data-theme="dark"]` 逐字相同,而那是 `@media` 邊界的限制不是選
   擇**(檔頭「五個選擇器」那一段)。兩份會漂移,所以
   EveryThemeBlockDefinesTheWholeContract.test_the_two_dark_blocks_are_word_for_word
   逐字比對它們。

   **「跟系統」的深色是 `dark` 不是 `dark-muted`** — D-F102。低飽和深色是一個要自
   己去挑的東西:它把語意色的彩度砍掉一半以上,而那是一個口味,不是「深色」的更
   好的預設。 */
@media (prefers-color-scheme: dark) {
  :root {
    /* 面與字 */
    --bg: #0F172A; --card: #1A2236; --chip: #26314A; --line: #334059;
    --ink: #F1F5F9; --dim: #9AA7BA; --nav: #1A2236;
    /* 品牌 */
    --accent: #34D399; --on-accent: #052E16; --accent-soft: #123B31; --ring: #34D399;
    --accent-grad-a: #34D399; --accent-grad-b: #34D399;
    /* 記帳種類 */
    --kind-expense: #C87C81; --kind-income: #34D399; --kind-refund: #38BDF8; --kind-transfer: #A78BFA;
    --kind-expense-soft: #3C2224; --kind-income-soft: #123B31; --kind-refund-soft: #12344A; --kind-transfer-soft: #2E2A52;
    /* 帳本種類 */
    --ledger-split: #60A5FA; --ledger-pool: #2DD4BF; --ledger-capital: #FBBF24; --ledger-personal: #F472B6;
    --ledger-split-soft: #1E3050; --ledger-pool-soft: #123D3C; --ledger-capital-soft: #3F3220; --ledger-personal-soft: #44223A;
    /* 狀態 */
    --ok: #4ADE80; --warn: #FBBF24; --danger: #F87171; --ok-soft: #143D2A;
    --warn-soft: #3F3220; --danger-soft: #3E2030; --on-warn: #0F172A;
    /* 圖表 */
    --chart-1: #3B82F6; --chart-2: #059669; --chart-3: #D97706; --chart-4: #8B5CF6;
    --chart-5: #EC4899; --chart-6: #0891B2; --chart-cash: #93C5FD; --chart-settled: #DDADEC;
    --chart-paid: #2563EB; --chart-grid: #334059;
    /* 系統 */
    --statusbar: #0F172A; --manifest-theme: #0F172A;
    /* 形狀 */
    --radius-s: 10px; --radius-m: 12px; --radius-l: 16px;
    --radius-pill: 999px; --border-w: 1px;
    /* 陰影與幕 */
    --shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.3);
    --shadow-fab: 0 2px 6px rgba(0,0,0,.4), 0 10px 24px rgba(0,0,0,.35);
    --scrim: rgba(2,6,23,.6);
    /* 底紋 */
    --bg-deco: none;
    /* 字型 */
    --font-body: "Plus Jakarta Sans", -apple-system, "SF Pro Text", "Noto Sans TC", system-ui, sans-serif;
    --font-heading: "Plus Jakarta Sans", -apple-system, "SF Pro Text", "Noto Sans TC", system-ui, sans-serif;
  }
}

/* ------------------------------------------------------------ 深色,鎖定的 */
html[data-theme="dark"],
.ac-theme[data-theme="dark"] {
  /* 面與字 */
  --bg: #0F172A; --card: #1A2236; --chip: #26314A; --line: #334059;
  --ink: #F1F5F9; --dim: #9AA7BA; --nav: #1A2236;
  /* 品牌 */
  --accent: #34D399; --on-accent: #052E16; --accent-soft: #123B31; --ring: #34D399;
  --accent-grad-a: #34D399; --accent-grad-b: #34D399;
  /* 記帳種類 */
  --kind-expense: #C87C81; --kind-income: #34D399; --kind-refund: #38BDF8; --kind-transfer: #A78BFA;
  --kind-expense-soft: #3C2224; --kind-income-soft: #123B31; --kind-refund-soft: #12344A; --kind-transfer-soft: #2E2A52;
  /* 帳本種類 */
  --ledger-split: #60A5FA; --ledger-pool: #2DD4BF; --ledger-capital: #FBBF24; --ledger-personal: #F472B6;
  --ledger-split-soft: #1E3050; --ledger-pool-soft: #123D3C; --ledger-capital-soft: #3F3220; --ledger-personal-soft: #44223A;
  /* 狀態 */
  --ok: #4ADE80; --warn: #FBBF24; --danger: #F87171; --ok-soft: #143D2A;
  --warn-soft: #3F3220; --danger-soft: #3E2030; --on-warn: #0F172A;
  /* 圖表 */
  --chart-1: #3B82F6; --chart-2: #059669; --chart-3: #D97706; --chart-4: #8B5CF6;
  --chart-5: #EC4899; --chart-6: #0891B2; --chart-cash: #93C5FD; --chart-settled: #DDADEC;
  --chart-paid: #2563EB; --chart-grid: #334059;
  /* 系統 */
  --statusbar: #0F172A; --manifest-theme: #0F172A;
  /* 形狀 */
  --radius-s: 10px; --radius-m: 12px; --radius-l: 16px;
  --radius-pill: 999px; --border-w: 1px;
  /* 陰影與幕 */
  --shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.3);
  --shadow-fab: 0 2px 6px rgba(0,0,0,.4), 0 10px 24px rgba(0,0,0,.35);
  --scrim: rgba(2,6,23,.6);
  /* 底紋 */
  --bg-deco: none;
  /* 字型 */
  --font-body: "Plus Jakarta Sans", -apple-system, "SF Pro Text", "Noto Sans TC", system-ui, sans-serif;
  --font-heading: "Plus Jakarta Sans", -apple-system, "SF Pro Text", "Noto Sans TC", system-ui, sans-serif;
}

/* -------------------------------------------------------------- 低飽和深色

   D-F102 新增的第四個 — #392。**它與「深色」的差別是一句話能講完的**:底色從帶
   藍的 #0F172A 換成石墨灰 oklch(0.215 0.006 260),而語意色的彩度砍掉一半以上
   (深色那一份是 C 0.15–0.17,這一份是 C 0.07–0.09)。

   要的是「晚上看很久也不刺眼」,而刺眼的來源是**彩度**不是亮度 —— 深色主題那顆
   #34D399 的綠在 OLED 上是一塊會發光的東西。所以這一塊不是「把深色調暗一點」:
   每一格都是重新在 OKLCH 上定錨、再往上找到剛好過對比線的那一階。

   代價寫在這裡:低彩度的六個圖表色彼此更難分,所以 `--chart-*` 那六格是靠**明度**
   拉開的(TheBalanceLinesStayApartInEveryTheme 量的 OKLab 距離,五塊都要過
   0.10)—— 不是靠色相。 */
html[data-theme="dark-muted"],
.ac-theme[data-theme="dark-muted"] {
  /* 面與字 */
  --bg: #181A1C; --card: #232527; --chip: #2F3033; --line: #3B3D40;
  --ink: #E6E8EA; --dim: #A2A5AA; --nav: #232527;
  /* 品牌 */
  --accent: #66A382; --on-accent: #181A1C; --accent-soft: #1D3227; --ring: #66A382;
  --accent-grad-a: #66A382; --accent-grad-b: #66A382;
  /* 記帳種類 */
  --kind-expense: #C98481; --kind-income: #66A382; --kind-refund: #6A9DBA; --kind-transfer: #A08EC3;
  --kind-expense-soft: #3E2726; --kind-income-soft: #1D3227; --kind-refund-soft: #1B303D; --kind-transfer-soft: #322B3F;
  /* 帳本種類 */
  --ledger-split: #7599C7; --ledger-pool: #5DA29D; --ledger-capital: #B88F56; --ledger-personal: #BE86A5;
  --ledger-split-soft: #222F40; --ledger-pool-soft: #163231; --ledger-capital-soft: #382C1A; --ledger-personal-soft: #3D2834;
  /* 狀態 */
  --ok: #6AA376; --warn: #B88F56; --danger: #E46689; --ok-soft: #203224;
  --warn-soft: #382C1A; --danger-soft: #382224; --on-warn: #181A1C;
  /* 圖表 */
  --chart-1: #658FC2; --chart-2: #517F4C; --chart-3: #986C28; --chart-4: #7F6BA4;
  --chart-5: #A6616D; --chart-6: #2F7D90; --chart-cash: #4E8BAB; --chart-settled: #9976A4;
  --chart-paid: #5477A3; --chart-grid: #3B3D40;
  /* 系統 */
  --statusbar: #181A1C; --manifest-theme: #181A1C;
  /* 形狀 */
  --radius-s: 10px; --radius-m: 12px; --radius-l: 16px;
  --radius-pill: 999px; --border-w: 1px;
  /* 陰影與幕 */
  --shadow: 0 1px 2px rgba(0,0,0,.35), 0 8px 24px rgba(0,0,0,.25);
  --shadow-fab: 0 2px 6px rgba(0,0,0,.4), 0 10px 24px rgba(0,0,0,.3);
  --scrim: rgba(0,0,0,.6);
  /* 底紋 */
  --bg-deco: none;
  /* 字型 */
  --font-body: "Plus Jakarta Sans", -apple-system, "SF Pro Text", "Noto Sans TC", system-ui, sans-serif;
  --font-heading: "Plus Jakarta Sans", -apple-system, "SF Pro Text", "Noto Sans TC", system-ui, sans-serif;
}

/* ------------------------------------------------------------------ 可愛

   D-F102 新增的第五個 — #392。紫色主色、圓角一路放大到 28px、框線 2px、陰影帶一
   道 inset 的「黏土」立體感(ui-ux-pro-max 的 Claymorphism (Mobile)),而字型換成
   Nunito —— 圓體與圓角是同一句話的兩半。

   **它是唯一一個 `--accent-grad-a` 與 `--accent-grad-b` 不同值的主題**:主鈕與 FAB
   在它底下是一道紫色漸層。其餘四個主題兩格同值,所以那道 `linear-gradient` 在它們
   身上畫出來的就是一塊實心 —— 讀取端因此只有一份寫法。

   `--bg-deco` 在它底下是三顆很淡的徑向漸層(粉 / 紫 / 琥珀),畫在 `body::before`
   上。那是這個主題的性格,不是裝飾用的雜訊:它是唯一讓「可愛」在**空白處**也講得
   出話的東西。 */
html[data-theme="cute"],
.ac-theme[data-theme="cute"] {
  /* 面與字 */
  --bg: #F4F1FA; --card: #FFFFFF; --chip: #ECE6F8; --line: #DDD3F1;
  --ink: #332F3A; --dim: #635F69; --nav: #FFFFFF;
  /* 品牌 */
  --accent: #7C3AED; --on-accent: #FFFFFF; --accent-soft: #EDE4FF; --ring: #A78BFA;
  --accent-grad-a: #8B5CF6; --accent-grad-b: #6D28D9;
  /* 記帳種類 */
  --kind-expense: #B15154; --kind-income: #077A54; --kind-refund: #0B72AD; --kind-transfer: #7C3AED;
  --kind-expense-soft: #FFF2F1; --kind-income-soft: #E0F7EC; --kind-refund-soft: #E2F1FB; --kind-transfer-soft: #EFE8FF;
  /* 帳本種類 */
  --ledger-split: #2359D6; --ledger-pool: #0C7A72; --ledger-capital: #B8500A; --ledger-personal: #B21EC4;
  --ledger-split-soft: #E6EDFE; --ledger-pool-soft: #DDF5F2; --ledger-capital-soft: #FFF1E4; --ledger-personal-soft: #FBE6FC;
  /* 狀態 */
  --ok: #077A54; --warn: #A84C08; --danger: #C21F66; --ok-soft: #E0F7EC;
  --warn-soft: #FFEEDD; --danger-soft: #FFE8F1; --on-warn: #FFFFFF;
  /* 圖表 */
  --chart-1: #8B5CF6; --chart-2: #DB2777; --chart-3: #3B82F6; --chart-4: #BD8000;
  --chart-5: #059669; --chart-6: #EA580C; --chart-cash: #2F6BE8; --chart-settled: #C026D3;
  --chart-paid: #8B5CF6; --chart-grid: #DDD3F1;
  /* 系統 */
  --statusbar: #F4F1FA; --manifest-theme: #F4F1FA;
  /* 形狀 */
  --radius-s: 14px; --radius-m: 20px; --radius-l: 28px;
  --radius-pill: 999px; --border-w: 2px;
  /* 陰影與幕 */
  --shadow: inset 0 -3px 0 rgba(124,58,237,.10), 0 6px 0 rgba(124,58,237,.06), 0 12px 28px rgba(124,58,237,.12);
  --shadow-fab: 0 6px 0 rgba(91,33,182,.55), 0 14px 28px rgba(124,58,237,.35);
  --scrim: rgba(51,47,58,.45);
  /* 底紋 */
  --bg-deco: radial-gradient(circle at 12% 6%, rgba(219,39,119,.16), transparent 28%), radial-gradient(circle at 92% 28%, rgba(124,58,237,.16), transparent 30%), radial-gradient(circle at 18% 88%, rgba(251,191,36,.18), transparent 28%);
  /* 字型 */
  --font-body: "Nunito", -apple-system, "SF Pro Text", "Noto Sans TC", system-ui, sans-serif;
  --font-heading: "Nunito", -apple-system, "SF Pro Text", "Noto Sans TC", system-ui, sans-serif;
}

/* ---------------------------------------------------------------- Organic

   使用者裁示 2026-08-25 的第三個主題,而 **D-F102 把它整組換掉了** — #392。#260
   那一版是奶油沙 + 陶土 + 鼠尾草,#391 重新設計成「竹影苔茶」:竹漿宣紙的暖白底
   oklch(0.961 0.010 94)、松煙墨的 ink、抹茶綠的主色 oklch(0.48 0.09 152)、茶園色
   的圖表。字型從 Caprasimo + Figtree 換成 **Fraunces + Plus Jakarta Sans**:標題
   是一支帶 SOFT 軸的襯線,內文回到與其餘主題同一支無襯線 —— 舊那一版標題與內文
   都是自己的字,而那讓每一頁的內文在五個主題之間換來換去。

   **名字仍然是「Organic」** — D-F102(使用者裁示):設定頁上那一格印的就是這四個
   字母,不譯成中文。舊使用者存的 `tabby.theme=organic` 因此原樣沿用,他打開來看
   到的是新的這一組(prefs.js 的遷移那一段寫著為什麼不另發通知)。

   `--nav` 刻意比 `--card` 深一階(#F1EFE6 對 #FCFAF6):底部那條導覽列在暖白的紙
   上要看得出是另一塊面,而一條 1px 的線在這個色域裡不夠。

   標題那一支 Fraunces 的變數軸由底下 `html[data-theme="organic"]` 的
   `font-variation-settings` 給(SOFT 50 / opsz 36)—— 那是這一支字「軟」起來的地
   方,而不設定的話拿到的是它的 default instance(SOFT 0,一支很硬的襯線)。 */
html[data-theme="organic"],
.ac-theme[data-theme="organic"] {
  /* 面與字 */
  --bg: #F4F2EB; --card: #FCFAF6; --chip: #EAE6DB; --line: #DBD6C6;
  --ink: #1E231E; --dim: #586555; --nav: #F1EFE6;
  /* 品牌 */
  --accent: #306C43; --on-accent: #FFFFFF; --accent-soft: #D2E2CF; --ring: #306C43;
  --accent-grad-a: #306C43; --accent-grad-b: #306C43;
  /* 記帳種類 */
  --kind-expense: #A84F45; --kind-income: #3A754C; --kind-refund: #367187; --kind-transfer: #806543;
  --kind-expense-soft: #FFE8E4; --kind-income-soft: #DAF1DF; --kind-refund-soft: #D4F1FD; --kind-transfer-soft: #FCEAD4;
  /* 帳本種類 */
  --ledger-split: #316F97; --ledger-pool: #30746C; --ledger-capital: #915F21; --ledger-personal: #985476;
  --ledger-split-soft: #D8F0FF; --ledger-pool-soft: #D2F3ED; --ledger-capital-soft: #FDE9D4; --ledger-personal-soft: #FFE6F2;
  /* 狀態 */
  --ok: #39754D; --warn: #935E24; --danger: #B7184C; --ok-soft: #D9F1DF;
  --warn-soft: #FEE9D5; --danger-soft: #F8D0D5; --on-warn: #FFFFFF;
  /* 圖表 */
  --chart-1: #247E6B; --chart-2: #6E9162; --chart-3: #AB7E54; --chart-4: #568FA7;
  --chart-5: #A85B68; --chart-6: #A381A0; --chart-cash: #468097; --chart-settled: #8F7451;
  --chart-paid: #6E9162; --chart-grid: #DBD6C6;
  /* 系統 */
  --statusbar: #F4F2EB; --manifest-theme: #F4F2EB;
  /* 形狀 */
  --radius-s: 10px; --radius-m: 14px; --radius-l: 20px;
  --radius-pill: 999px; --border-w: 1px;
  /* 陰影與幕 */
  --shadow: 0 1px 2px rgba(35,45,30,.05), 0 8px 24px rgba(35,45,30,.06);
  --shadow-fab: 0 3px 10px rgba(35,88,53,.25), 0 10px 24px rgba(35,45,30,.12);
  --scrim: rgba(28,33,28,.5);
  /* 底紋 */
  --bg-deco: radial-gradient(ellipse at 12% 0%, rgba(90,120,70,.10), transparent 42%), radial-gradient(ellipse at 100% 90%, rgba(170,140,80,.10), transparent 40%);
  /* 字型 */
  --font-body: "Plus Jakarta Sans", -apple-system, "SF Pro Text", "Noto Sans TC", system-ui, sans-serif;
  --font-heading: "Fraunces", -apple-system, "SF Pro Text", "Noto Sans TC", system-ui, sans-serif;
}

/* Fraunces 的變數軸 — #392。**它不是 token**:`font-variation-settings` 是規則不
   是值,而它只對一支字型有意義。放在這裡而不是 style.css,理由與 `@font-face`
   相同 —— 換掉 Organic 那支字的人只要讀這一支檔案。

   `.brand` 是左上角那個 app 名,`h3` 是卡片標題,`.big` 是首頁那個大數字 ——
   `--font-heading` 的三個讀者(style.css),逐字對上。 */
html[data-theme="organic"] .brand,
html[data-theme="organic"] h3,
html[data-theme="organic"] .big {
  font-variation-settings: "SOFT" 50, "opsz" 36;
}
