/* 這台裝置的偏好長什麼樣 — #241。web/prefs.js 寫 `<html>` 上那三個屬性,這裡寫
   「屬性長這樣的時候畫面差在哪」。
 *
 * **為什麼是自己一個檔案。** style.css 在 Batch 0 之後凍結(ARCHITECTURE §4.3),
 * 而這幾段做的又不是一支 view 的事:它們重定的是全站的 token 與兩塊 shell chrome
 * (nav 上緣那顆 FAB、整份版面的縮放)。放進 views/*.css 會讓「為什麼我的按鈕在
 * 左邊」的答案躲在某一頁的樣式表裡;放進 style.css 則是動那個凍結。第三條路是這
 * 一份:一個檔案,裝的正好是「使用者調得動的那幾樣」。
 *
 * **它在 index.html 排在 style.css 與 themes.css 後面。** #392 之前那個位置是被
 * 特異度逼出來的(挑主色那四條規則與主題塊同為 (0,1,1),要靠後到才贏);那四條
 * 跟著 `--ac-*` 一起退役之後,順序剩下的意義是「覆寫排在被覆寫的後面」這條讀起
 * 來就對的規矩 —— 而 `zoom` 與 `.fab` 的左右一格 token 都不重定。
 *
 * ------------------------------------------------------------ 一、主題色(已退役)
 *
 * **這一段在 #392(D-F102)整段刪掉了。** 它以前有四條規則,把 `<html>` 上的
 * `data-accent` 挑到的那一顆 `--ac-*` 接到 `--accent` 上,外加一條「Organic 自帶
 * 配色所以色票挑不動」的守門規則。
 *
 * 退役的理由是那條守門規則自己講出來的:一個主題如果自帶一整組配色,那麼「讓使用
 * 者再挑一顆主色」就是第二個作者 —— 而 #392 之後**每一個**主題都自帶一整組配色。
 * 留著那四條的代價不是多四行 CSS,是每加一個主題就要再驗一次「四顆色票在這塊底色
 * 上都讀得出來」(#241 的 ThePresetAccentsAreLegibleInEveryTheme 正是那條線),而
 * 五個主題 × 四顆 = 二十組沒有人真的看過的配色。
 *
 * 舊使用者存著的 `tabby.accent` 由 prefs.js 的 dropRetiredPrefs() 清掉,`<html>` 上那顆
 * `data-accent` 一併移除 —— 少了那一半,屬性會留在文件上而沒有任何規則讀它。
 */

/* ------------------------------------------------------------ 二、字體大小

   **走 `zoom`,而那是查過現場之後的選擇。** 這個 app 的字級從頭到尾是 px 寫死的
   (`body` 15px、`.big` 38px、`.label` 12.5px、`nav button` 11.5px…),root
   font-size 沒有任何一條規則讀 —— 換句話說 rem 那根槓桿在這裡是斷的。三條路:

     改成 calc(var(--fscale))  要動的是 style.css 與七支 views/*.css 裡幾十條既有
                              規則,而 style.css 正是凍結的那一支。漏掉一條的症狀
                              是「大」的時候某一格字沒跟著大,而那要一格一格看。
     只放大 body 那一級        `.big`、`.label`、nav 的字都不動 —— 使用者說「字太
                              小」時看的多半正是那幾格。半套比不做更糟。
     zoom 在 <html> 上        一條規則,整份版面等比例放大,比例關係一格都不會跑掉
                              (padding、圓角、圖、日曆格一起走)。

   選第三條。**它的代價要說清楚:放大的不只是字,是整個畫面** —— 和瀏覽器自己的
   頁面縮放同一種東西,所以設定頁上那一行說明就是這麼寫的。

   ⚠️ **2026-09-08(#360)加註,上面一段的選擇一個字不改,但它今天不是唯一的一
   段了。** 上面那三條路各自的評價都還對,漏掉的是第四件事:**`zoom` 在 Firefox
   126 以前根本不存在**。所以在 Firefox 100–125 上,上面那條「一條規則」等於零條
   規則 —— 設定頁那一排點得下去、`data-fsize` 掛得上去、值也存得起來,而畫面一動
   都不動。#353 的相容性掃描把它記成一個 known gap(`test_compat.CSS_KNOWN_GAPS`),
   這一票要把它關掉。

   **關掉它的辦法不是換掉 `zoom`,是給 `zoom` 一條退路,而那條退路要先有槓桿。**
   換掉 `zoom` 的兩條路都試過紙上作業,兩條都不成立:

     transform: scale()   `nav` 與 `.fab` 是 `position: fixed`,而一個帶
                          `transform` 的祖先會變成它們的包含塊 —— 那兩樣東西會
                          從「貼著視口」變成「貼著文件」,往下捲一頁就飛走了。
                          把捲動搬到 `body` 上可以繞過去,代價是 nav.js 的
                          `onScroll()`(收 FAB 的那一支)與手機上網址列的收合
                          全部改寫。這不是相容性修補,是換一套捲動模型。
     全站 px → rem        1499 個 px 裡只有 190 個是字級,其餘是 padding、圓角、
                          邊框、陰影。全換掉才等價於 `zoom`,而那是把整個視覺層
                          重寫一遍(含凍結的 style.css),再重驗一次 320/390 ×
                          五主題矩陣。這一票扛不起,也不該由一張掃描票扛。

   **所以做的是第三件事:把 190 條字級規則換成 rem,把 `zoom` 留著。** root
   font-size 由下面那條 `html { font-size: 16px }` 釘在 16(瀏覽器預設就是 16,所以
   今天的畫面一個像素都不動;釘住它是為了讓 `Npx → N/16 rem` 這條換算**與使用者
   的瀏覽器字級設定無關** —— 不釘的話這一票會順手改掉一件沒有人要求的事)。

   換算是機械的,而且每一個值都除得盡:`13px → .8125rem`、`12.5px → .78125rem`、
   `10.5px → .65625rem`。**「漏掉一條」那個症狀由測試接手**,不再靠一格一格看:
   `test_compat.TheCssFeaturesAreSupportedOrWaived.test_the_zoom_waiver_still_has
   _its_fallback` 掃過每一支 CSS,只要還有一條 `font-size: …px` 就是紅的。

   有了槓桿,退路只要兩行(下面那個 `@supports not (zoom: 1)`):有 `zoom` 的引擎
   (Chrome / Safari / Samsung / Firefox 126+,也就是這個 app 真正的使用者所在的
   每一台 iPhone)照舊整份版面等比例縮放;沒有 `zoom` 的 Firefox 100–125 拿到的是
   **每一個字級一起縮放,間距與圓角不動**。

   **這是降級不是等價,而降級的方向要說清楚**:那些機器上「大」拿到的是大一號的
   字塞進原尺寸的格子,不是放大的整頁。它落在 `CSS_WAIVERS` 的判準上(「不支援的
   人看到什麼」= 字變大了,間距沒跟著),不再是「一個安靜失效的設定」。

   **量出來的風險有兩個,兩個都在 390×844 上實測過**(playwright/Chromium,#241;
   數字寫在票的回報裡):

     `--navh` 由 nav.js 的 sizeNav() 用 offsetHeight 量,而量到的是**縮放前**的
     版面值(三檔量出來都是 `68px`);它被 `.fab` 的
     `bottom: calc(var(--navh) + 16px)` 讀進去的時候仍然在縮放的座標系裡 —— 兩邊
     同一個座標系,所以那道縫在三檔下都是 16 個縮放後的 px(螢幕上 nav 頂與 FAB
     底的距離:小 14.6、標準 16.3、大 18.9)。nav 自己 61 / 67.8 / 77.7,整條橫
     滿 390,三檔都沒有橫向捲動(`documentElement.scrollWidth` 恆為 390)。

     `.pick-list` 的 `max-height: 52vh` **不跟著縮放算**:computed 值三檔都是
     438.88px(52% × 844),而它畫在縮放的座標系裡,所以大檔時螢幕上是 505px。
     紙是貼著底部往上長的,505 + 紙頭 + nav 仍然離視窗頂很遠。

   兩檔的倍率:小 0.9、大 1.15。標準那一檔**沒有規則** —— 它就是「沒有人縮放」,
   `zoom: 1` 寫出來會多一個合成層。

   **大檔會讓設定頁那排色票折成兩行**(實測第四顆掉到第二列)。那是 `.ac-sws` 的
   `flex-wrap` 在做它該做的事,不是版面壞掉 —— 一排鈕折行仍然是一排鈕。 */
/* **倍率同時寫成一個 token** — D-F99(#370)。`zoom` 縮放的是整個座標系,而
   **視口單位不跟著縮**:`86vw` 在 `zoom: 1.15` 底下算出來仍然是 86% × 視口寬的
   CSS px,再被縮放乘 1.15 —— 螢幕上看到的是 **98.9vw**。實測(Chrome 152、
   360×740、大字級):快速切換那張下拉紙的 `max-width: 86vw` 因此量到 356px 寬,
   而它靠右對齊在 341.6,左緣落在 **-14.4** —— 紙的左邊掉出螢幕外面。

   讀它的人要自己除回去(`calc(86vw / var(--zoom, 1))`,見 style.css 的
   `.pick[data-drop] .pick-sheet`)。**標準檔沒有規則,所以也沒有這一格** ——
   `var(--zoom, 1)` 的退路就是它,而 `zoom: 1` 寫出來會多一個合成層(上面那一段
   的原話)。 */
/* **rem 的那個 1 是這裡定的** — #360。瀏覽器預設就是 16px,所以這一行今天是個
   no-op;它寫出來是為了讓上面那條換算(`Npx → N/16 rem`)不依賴使用者改過的瀏覽
   器字級 —— 少了它,把字級規則換成 rem 這件事會順手把「跟著瀏覽器字級走」也一起
   改了,而那是另一張票該問的問題(這個 app 從第一天就是 px 寫死的)。 */
html { font-size: 16px; }

html[data-fsize="small"] { zoom: .9; --zoom: .9; }
html[data-fsize="large"] { zoom: 1.15; --zoom: 1.15; }

/* Firefox 100–125 的退路 — #360。上面那兩條在那些引擎上是零條規則(`zoom` 到
   Firefox 126 才有),而 `@supports` 問的正是那件事本身,不是版本號:認得
   `zoom` 的引擎跳過這一塊,不認得的才進來。

   **這一塊與上面兩條互斥,所以不會疊乘。** 有 `zoom` 的地方 root 停在 16px,
   rem 因此是原尺寸;沒有 `zoom` 的地方 `zoom` 那兩條本來就不存在,縮放全由這裡
   的 root font-size 一個人做。少了 `@supports` 這層門,Chrome 上會是
   1.15 × 1.15 = **1.32**。

   倍率與上面逐字相同(16 × .9 = 14.4、16 × 1.15 = 18.4),而寫成絕對的 px 不是
   百分比:百分比的分母是使用者的瀏覽器字級,而上面那條 `html { font-size: 16px }`
   的整個用意就是不讓那個數字進來。

   **`--zoom` 那顆 token 在這裡刻意不設。** 它的用途是「把 `zoom` 沒縮到的視口單
   位除回去」(D-F99),而這條路上 `zoom` 一次都沒發生 —— `86vw` 就是 86vw,
   `var(--zoom, 1)` 的那個 1 正是對的答案。 */
@supports not (zoom: 1) {
  html[data-fsize="small"] { font-size: 14.4px; }
  html[data-fsize="large"] { font-size: 18.4px; }
}

/* ------------------------------------------------------- 三、＋鈕的位置

   使用者裁示 2026-08-24:「一般:+的按鈕位置(左 右)」。預設是右下(#201 的原
   話:「右下角、控制 bar 之上的懸浮圓形 + 號」),所以只有「左」需要一條規則。

   **只動左右,一個字都不碰它的隱藏行為。** 往下滑收起來走的是 `.fab.away` 的
   `transform: translateY(96px) scale(.9)` 與 opacity(nav.js 的 onScroll()),兩者
   都與水平位置無關 —— 這也正是這一票沒有動到 nav.js 的原因:那顆鈕停在哪一邊是
   版面,不是行為。

   **`right: auto` 今天不是必要的,寫著是為了明天。** 實測(390):只加 `left: 16px`
   那顆鈕照樣停在左邊、寬度仍然是 56 —— 因為 `.fab` 同時寫了 `width: 56px`,
   over-constrained 的 left/right/width 在 LTR 下被丟掉的是 `right`。把那個寬度拿掉
   的那一天(改成內距撐開、或換一顆更大的鈕),同一組規則量出來的是一顆 **358px 寬**
   的橢圓橫在畫面底部。一行 `right: auto` 讓那件事不會發生,而它現在是免費的。

   特異度 (0,2,1) 壓得過 `.fab` 的 (0,1,0)。左邊那一顆收起來的樣子也實測過:
   `transform: matrix(.9, 0, 0, .9, 0, 96)`、`opacity: 0`、`pointer-events: none`
   —— 和右邊逐字相同。 */
html[data-fab="left"] .fab { right: auto; left: 16px; }
/* 左邊那一顆也跟著內容欄收 — #289(QA F19)。算式與 style.css 那一條逐字對稱
   (那裡寫著為什麼是 552 與 50%),只是換一邊;`right: auto` 已經由上面那條給
   了,這裡只再推 `left` 一格。少了它,「＋ 鈕放左邊」的人在 768 寬上拿到的是
   內容欄左緣外面 52px 的一顆鈕 —— 和這張票要修的是同一個病,只是鏡像。 */
@media (min-width: 552px) {
  html[data-fab="left"] .fab { left: calc(50% - 244px); }
}
