/* chatime-a11y：無障礙樣式。此檔會逐層擴充，目前僅放可用來驗證掛載成功的標記。 */
:root {
	--chatime-a11y-loaded: 1;
}

/* 2.4.7 Focus Visible：全站一致的焦點外框。
   用 outline 而非 box-shadow，因為 outline 不受 overflow:hidden 裁切。
   偏移 2px 讓外框不貼著元素邊緣，在深色與淺色底上都看得見。 */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
	outline: 3px solid #111;
	outline-offset: 2px;
	border-radius: 2px;
}

/* 深色底（紫色頁首、部分飲品 tint）上改用白框，確保 3:1 對比。
   2026-09-07 用真實飲品頁（premium-boba-milk-tea）核對過，發現 brief 原本的選擇器
   `.brxe-section[class*="drink-tint-"] :where(...):focus-visible` 範圍抓太大、會出真的
   問題，不是只有「class 對不對」的層次：
   - `.drink-hero.drink-tint-<色名>` 這個 <section> 本身的 background-color 其實是白色；
     tint 色是靠 `.drink-hero::before` 這個裝飾用偽元素（搭配 mask 做出波浪形狀）疊出來的，
     只蓋住左側圖片那一塊，不是整個 section。
   - section 裡唯一真正可聚焦的元素「View allergen info」按鈕，量出來的背景是白色（在
     `.drink-hero__media`〈圖片容器〉右邊、波浪覆蓋不到的地方），不是疊在 tint 色上面。
   - 照 brief 原始選擇器套用後實測：這顆按鈕的焦點外框會被強制設成白色，白底上疊白框——
     等於沒有焦點外框，這正是 2.4.7 要防的問題，等於因為這條規則本身把它做壞了。
   因此原版把範圍收窄到只有 `.drink-hero__media` 內的可聚焦元素才給白框；但那個容器裡
   從頭到尾只有一張 <img>，沒有真的可聚焦元素，這條規則從未套用到任何東西過——不是
   「預留給未來」，是死碼，2026-09-08 全站複驗時移除（見下方，跟頁首白框改成有條件是
   同一次編輯、同一個原因：兩條規則其實是同一份原始規則被拆開後留下的兩半）。

   2026-09-08（收尾複驗，四個結案項之一）：這裡的 `header` 白框原本是全站無條件套用，
   前提是「頁首背景一律夠深」。這個前提在六個淺色 tint（leaf/arctic-water/dew/goldfish/
   flamingo/peacock）的飲品頁上不成立——Task 5b 已經測過這六個 tint 底色不夠深，深到連
   4.5:1 的文字都過不了，才把頁首文字/圖示改成 `#1A1A1A`；但同一次改動漏了這裡的焦點框，
   當時仍是白色，於是同一份樣式表對同一塊背景同時斷言「文字要深」跟「外框要白」兩件互斥
   的事。實測（用 Task 5b 已記錄的七色底色，套 WCAG 相對亮度公式反推，不是憑印象）：

     tint          白框對比   #111 外框對比
     leaf          2.27       8.32
     arctic-water  2.26       8.37
     dew           2.65       7.12
     goldfish      2.76       6.85
     flamingo      3.03       6.24
     peacock       3.45       5.47（唯一過 3:1 的 tint）
     berry         7.91       （白字已合格，未受影響，維持不動）
     非飲品頁固定紫 `#5C2D91`  9.38  （頁首白框的原始前提，仍然成立）

   前五個 tint（leaf/arctic-water/dew/goldfish/flamingo）白框不合格（2.26–3.03），
   35/63 支飲品頁受影響，每一個頁首可聚焦元素都中；peacock（3.45）跟 berry（7.91）本來
   就過關，不需要也不該跟著動——把它們也改深框只是多做不必要的視覺改動，不是修 bug。
   Reviewer 建議「把 header 整條從白框選擇器移掉」如果照字面做，會連非飲品頁（固定紫
   `#5C2D91`，前提仍成立、白框本來就合格）一起改回黑框，量出來 `#111` 對這個紫色只有
   一般水準（未在此重算，但明顯是拿掉一個原本沒問題的白框，製造新的視覺回歸）——所以
   這裡不是整條移掉 `header`，而是沿用 Task 5b 已經在用、且已知穩定的
   `body:has(.drink-hero:is(...))` 技巧，只在「有這五個失敗 tint 之一」時關掉白框，讓它
   退回全站預設的黑框 `#111`（前五個 tint 量到 6.24–8.37，全部遠超 3:1）；peacock、
   berry、以及所有非飲品頁的頁首則完全不受這條規則影響，維持原本已合格的白框。 */
header :where(a, button, [tabindex]):focus-visible {
	outline-color: #fff;
}
body:has(.drink-hero:is(.drink-tint-leaf, .drink-tint-arctic-water, .drink-tint-dew, .drink-tint-goldfish, .drink-tint-flamingo)) header :where(a, button, [tabindex]):focus-visible {
	outline-color: #111;
}

/* 2.4.11 Focus Not Obscured：這裡刻意不放 scroll-margin-top。
   2026-09-07 fix round 1：brief 原本要求桌機 169px、手機 121px（來自重建計畫對頁首的
   既定設計），部署後我方與 reviewer 各自獨立實測（含清除 LiteSpeed 快取排除舊快取
   誤判）都確認：目前線上版本沒有任何固定或 sticky 的頁首元素——捲動後頁首跟著頁面
   一起捲走；全頁唯一的 fixed 定位元素是手機選單抽屜展開時的關閉按鈕，不是頁首。
   也就是說這條規則要防的情境（固定頁首擋住剛聚焦或錨點跳轉到的元素）現在不存在，
   套用後唯一的可見效果是每次 Tab 停在畫面邊緣、或錨點跳轉時，該元素上方憑空多出
   169px／121px 的留白——這是在修一個不存在的問題，而且會製造新的、看得到的副作用。
   已依 owner 裁示移除。2.4.11 的通過與否改成在最終驗證階段對當時的真實頁面實測
   確認，不是靠這種預先假設的規則。若之後真的做出固定疊層頁首，屆時再用實測到的
   頁首高度加回這條規則。 */

/* 2.5.8 Target Size (Minimum)：互動元素至少 24×24 CSS 像素。
   只補尺寸不改視覺：用 min-width/min-height 加置中，圖示本身大小不變。
   2026-09-07 實測盤點（桌機 1440px／手機 390px，首頁＋門市頁＋飲品頁＋飲品列表頁）：
   - 主選單連結（nav a）在兩種 viewport 下實際曝光的那個變體都已經是 24px 高，本來就不算
     違規，這裡的規則對它是保險，不是修正。
   - 真正低於 24×24 的是頁首與頁尾的社群圖示連結：`.bricks-link-wrapper`（桌機頁首約
     21×31、頁尾約 35-40×16；手機頁尾約 21-24×16），下面這條規則對得上、修得到。
   - brief 原本另外列的 `.brxe-icon a` 選不到任何東西：`.brxe-icon` 是圖示 <i> 本身的
     class，不是包住連結的容器（結構其實是反過來的 `<a class="bricks-link-wrapper">
     <i class="...brxe-icon"></i></a>`），已移除這個選不到東西的選擇器，改由
     `.bricks-link-wrapper` 涵蓋同一批圖示連結。
   - 跳過導覽連結（.skip-link）平時是 clip 成 1×1 的視覺隱藏樣式（focus 時才變成
     183×37），不是真的可點擊目標，不算違規，這裡不處理。
   - 門市頁的「Use my location」按鈕、Leaflet 地圖版權連結、飲品列表頁窄螢幕下的分類
     篩選標籤（drink-cat）量到的高度也低於 24px，但這些元素屬於 Task 11（地圖鍵盤操作）
     與 Task 12（飲品篩選）的檔案範圍，這裡不動，避免跟後續任務的實作互相踩線。
   - 手機版頁首的漢堡選單按鈕（.bricks-mobile-menu-toggle，「Open mobile menu」）量到
     32×16，高度也不足 24px，但它的鍵盤操作與焦點管理是 Task 8 的範圍（同一顆按鈕），
     這裡同樣不動，避免搶在那個任務的鍵盤／焦點邏輯定案前先改了它的框大小。
     以上四項（Task 11／12／8 各自的元素）都已記錄在 Task 4 報告裡供追蹤。
   2026-09-07 fix round 1（reviewer 發現）：原本還列了 `.brxe-pagination span`。實測
   `.brxe-pagination` 底下所有 `<span>`（目前頁碼指示 `.page-numbers.current`、
   省略號 `.page-numbers.dots`、裝飾用的上/下一頁停用占位符
   `.drink-pager__nav--prev/next`、「of N」文字 `.drink-pager__total`）全部
   `tabIndex === -1`、沒有 `onclick`、沒有 `role`、`cursor: auto`——沒有一個是真正
   互動元素，2.5.8 的「互動元素」範圍不包含它們。原本能「安全」只是巧合：省略號那個
   span 剛好被另一支跟本次改動無關的分頁腳本用 inline style 設成 `display:none`，
   不是這條規則的功勞，也不該依賴一支自己管不到的腳本來保證安全。已移除
   `.brxe-pagination span`，只留下真正可聚焦、可點擊的 `<a>`（頁碼連結、上一頁／
   下一頁連結）。 */
.bricks-link-wrapper,
nav a,
.brxe-pagination a {
	min-width: 24px;
	min-height: 24px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
}

/* 2.5.8 Target Size (Minimum)：手機選單漢堡鈕（.bricks-mobile-menu-toggle，
   「Open/Close mobile menu」），Task 4 記錄、保留給 Task 8（本任務）處理的
   第四個目標尺寸違規。2026-09-07 實測（390px）：32×16，高度不足 24px。
   這裡刻意不沿用上面 `.bricks-link-wrapper` 那條 min-width/min-height 做法：
   這顆按鈕所在的 `#brxe-nagwri`／`#brxe-egyrxy` 是靠子元素高度自動撐開的
   flex 容器（實測其餘手足節點——手機選單面板與遮罩——都是 position:fixed，
   已脫離文件流，完全不參與這個自動撐開的高度計算，容器高度目前就是這顆按鈕
   自己的高度）；若直接把按鈕 min-height 設成 24px，會把這顆按鈕、連帶整個
   容器與頁首那一列的版面高度從 16px 撐大到 24px——這是看得見的版面尺寸變更，
   不是「只補尺寸不改視覺」，牴觸本次任務「不得改變一般使用者看到的畫面」的
   前提，也還沒經過個別核准。
   改用絕對定位的 `::after` 純擴大可點擊／觸控命中範圍：`position:absolute`
   已脫離文件流，不會撐大任何父層或位移任何手足元素，內容留空、不上背景／
   邊框，視覺上不存在——這是 WCAG 2.5.8 Understanding 文件本身列出的合規
   做法（invisible target expansion），不是變通。四邊各加 4px：32×16 →
   40×24，剛好達到 24×24 下限，且按鈕本身已是 `position: relative`（Bricks
   原生樣式），`::after` 的絕對定位以它為基準，不需要額外宣告。已實測確認
   `::after` 目前未被站台其他樣式使用（`content: none`），也已實測擴大後的
   命中範圍點擊仍會觸發開關（見 task-8-report.md）。 */
.bricks-mobile-menu-toggle::after {
	content: '';
	position: absolute;
	inset: -4px;
}

/* 2.4.7／2.1.1：門市頁地圖容器現在可聚焦（tabindex 由 Leaflet keyboard:true 原生
   給、stores.js 的 accessibleMap() 又顯式宣告一次），理論上已經吃得到上面
   `:where(...,[tabindex]):focus-visible` 那條全站規則——實測也確實吃得到（焦點
   外框顏色/寬度都對），但那條規則用了 :where()，特異度是 0，跟 Leaflet 自己
   `.leaflet-container { outline-offset: 1px }`（一般規則，特異度是一個 class）
   在 outline-offset 這個屬性上打平，目前 leaflet.css 排在 a11y.css 之後，
   於是 offset 被 Leaflet 的 1px 蓋掉（外框本身看得到，2.4.7 不受影響，只是
   offset 差 1px）。這裡用比 :where() 高的特異度顯式宣告一次，不依賴兩份樣式表
   之後的載入順序不會變。 */
.leaflet-container:focus-visible {
	outline: 3px solid #111;
	outline-offset: 2px;
}

/* 2.5.8 Target Size (Minimum)：門市頁地圖右下角的 Leaflet 版權連結，Task 4
   記錄、保留給本任務處理的目標尺寸違規（另一項門市定位鈕屬於別的任務範圍，
   這裡不動）。2026-09-07 實測（1440px 桌機，/stores/ 頁，真瀏覽器量測）：
   `.leaflet-control-attribution a` 量到 51.375×14，高度不足 24px 下限、寬度已
   足夠，只差 10px 高。這顆連結貼在地圖右下角，旁邊沒有多餘版面可以讓
   min-height 撐大視覺尺寸而不移動任何東西（父層 `.leaflet-control-attribution`
   本身也只有 61.375×16.8，一樣不夠），跟手機漢堡鈕（見上面 fix round 1 那段）
   同一個理由，改用絕對定位的 `::after` 純擴大可點擊／觸控命中範圍：連結原本是
   `position:static`，這裡把它設成 `position:relative`（沒有 top/left 偏移，
   不會移動連結本身），讓 `::after` 以連結自己（不是父層）為定位基準，四邊各
   加 5px（14+10=24，剛好達到下限），內容留空、不上背景／邊框，視覺上不存在。
   父層 `overflow` 實測是 `visible`，擴大範圍不會被裁掉；擴大後的命中範圍會蓋到
   地圖本身的一小塊邊角，但那個角落本來就被這條半透明版權列蓋住，不影響一般
   拖曳／點擊地圖的操作。 */
.leaflet-control-attribution a {
	position: relative;
}
.leaflet-control-attribution a::after {
	content: '';
	position: absolute;
	inset: -5px;
}

/* 1.4.11 Non-text Contrast：Leaflet 縮放按鈕（+/−）之間、以及外圈的邊界。
   兩個來源都不合格：(1) 兩顆按鈕中間的分隔線 `.leaflet-bar a { border-bottom:
   1px solid #ccc }`，對白底量到約 1.6:1；(2) 桌機（無觸控）情形下外層
   `.leaflet-control-zoom` 只靠 `box-shadow: 0 1px 5px rgba(0,0,0,.65)` 做邊界，
   模糊漸層量不出可靠的 3:1（觸控裝置會多一條 `border: 2px solid rgba(0,0,0,.2)`，
   等效於對白底 #ccc 灰，一樣不到 3:1）。兩個來源都是「按鈕本身的邊」，所以直接在
   `.leaflet-control-zoom-in`／`-out` 兩顆按鈕上各補一圈實心邊框，蓋掉原本的分隔線
   與外層那圈不可靠的陰影／半透明邊，顏色選 #595959——對白底量到約 5.5:1、對地圖
   預設底色 #ddd 量到更高，兩者都過 3:1。只動邊框顏色，不動按鈕文字色（+/− 原本
   就是黑字，對白底已經合格，不需要也不該動）、不動按鈕尺寸與版面位置，維持跟
   原本一樣的按鈕外觀與操作。
   fix round（部署後實測抓到）：第一版選擇器 `.leaflet-control-zoom a` 對
   `border-bottom` 這個子屬性跟 Leaflet 自己的 `.leaflet-bar a` 特異度打平
   （都是一個 class＋一個元素），leaflet.css 排在 a11y.css 之後印出，「後印的贏」，
   實測結果是三邊變 #595959、底邊仍是原本的 #ccc——比完全沒改還糟（看起來像沒套
   齊全的錯誤，而不是刻意的設計）。這裡把選擇器疊上容器實際同時具備的兩個
   class（`leaflet-control-zoom leaflet-bar leaflet-control`，實測過的真實
   class 清單），特異度變兩個 class＋一個元素，不靠印出順序就贏，不需要
   `!important`。
   fix round 1（reviewer 用放大截圖抓到，第一版報告誤寫成「只換了顏色」）：
   兩顆按鈕上下緊貼、中間沒有間隔，`border: 1px solid #595959` 對兩顆按鈕都是
   四邊全上——於是「+」的底邊與「−」的頂邊疊在一起，分隔線從原本的 1px 變成
   兩條相鄰的 1px 疊成一條約 2px 粗的深色帶，比外圈其餘三邊粗一倍，是沒注意到
   的第二個視覺改動，第一版報告只講了顏色、沒講粗細，是誤述不是省略。
   修法：分隔線只給其中一顆按鈕的那一邊，不要兩邊都給。這裡讓「−」（`:last-child`，
   下面那顆）拿掉自己的頂邊，分隔線只剩「+」（上面那顆）的底邊在，粗細就是
   單一的 1px，跟外圈其餘三邊一致；「−」原本就有的 `:last-child { border-bottom:
   none }`（Leaflet 自己的規則，維持不動，見上一輪）沒有被這裡動到，外圈最下面
   那段曲線一樣是靠 box-shadow 表示邊界。 */
.leaflet-control-zoom.leaflet-bar a {
	border: 1px solid #595959;
}
.leaflet-control-zoom.leaflet-bar a:last-child {
	border-top: none;
}

/* 2.5.8 Target Size (Minimum)：門市頁「Use my location」按鈕（`#store-use-location`
   `.store-search__geo`）。Task 4 當初量到 133×20 記在清單裡，但派工時寫「屬於其他任務」
   之後從未實際指派給任何任務——兩邊都以為對方會做，結果沒人做，是控制者的分派錯誤
   （task-12 複審發現、記在 progress.md），併入本任務補做，獨立於表單那組修正之外驗收。
   2026-09-07 重新實測（1440/1024/768/390/320 五種寬度，novamira-chatime-com 開發機
   覆寫，/stores/ 頁，真瀏覽器量測 getBoundingClientRect）：五種寬度量到的尺寸完全一致，
   都是 133.25×20——記錄的數字是對的，不是像同一份原始清單裡「飲品分類篩選膠囊」那項
   （其實是 96×96 的滿版延展連結，Task 12 複審已更正）那種量測錯誤。
   寬度 133px 已遠超過 24px 下限，只差高度 4px。這顆按鈕 `position: static`，是
   `.brxe-container` 底下第三個、也是最後一個直接子節點（前兩個是頁面標題 h1 與門市搜尋欄
   `.store-search__field`），上緣與搜尋欄之間有 20-24px 空隙（依寬度而定，320px 最窄時
   仍有 20px），下緣與下一個 section（地圖／門市清單所在區塊）之間有約 180px 空隙——五種
   寬度都一樣寬裕，用不可見的擴大命中範圍（`::after`，WCAG 2.5.8 Understanding 文件本身
   列出的合規做法）往上下各加 2px（20+2+2=24），不會摸到搜尋欄或地圖，不需要另外判斷
   viewport。實測過這顆按鈕目前沒有用到 `::after`（`content: none`），父層
   `.brxe-container` 的 `overflow` 是 `visible`，擴大範圍不會被裁掉，也不會被裁掉去蓋到
   搜尋欄或地圖。按鈕本身已知會保持它現在的 `display: flex`，這裡只加
   `position: relative` 讓 `::after` 以按鈕自己（不是父層）為定位基準，不改變任何看得見
   的排版（沒有 top/left 偏移）。 */
.store-search__geo {
	position: relative;
}
.store-search__geo::after {
	content: '';
	position: absolute;
	top: -2px;
	bottom: -2px;
	left: 0;
	right: 0;
}

/* 只給螢幕閱讀器的文字：不能用 display:none，那樣讀不到。 */
.chatime-a11y-sr-only {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

/* 1.4.3 Contrast (Minimum)：owner 2026-09-07 逐項核准的六項色彩對比修正
   （task-5-report.md 量測、task-5b 施作）。「近黑色」統一用 #1A1A1A——這不是
   隨手挑的，是 owner 核准清單裡每一個比值（leaf 7.67／arctic-water 7.71／
   dew 6.56／goldfish 6.31／flamingo 5.75／peacock 5.04／按鈕 5.50／
   淺紫區塊 4.92／粉紅橫幅另用色卡的洋紅，不用近黑）算出來就是用 #1A1A1A 當
   前景色反推的，逐一核對過完全吻合（不是 a11y.css 別處拿來做 focus 外框的
   #111——那是另一個用途、另一個值，兩者刻意不共用）。 */

/* 項目 1＋2：飲品內頁頁首導覽文字與圖示，疊在 tint 色塊上。
   頁首（<header>）不是 .drink-hero 的子元素——它是絕對定位、z-index 999 疊在
   hero 上面的手足元素，tint class 掛在 .drink-hero 這個 <section> 上，頁首
   本身拿不到那個 class。純 CSS 選不到「看手足元素的 class 決定自己樣式」，
   所以這裡用 :has()（現行 Chromium/Firefox/Safari 皆支援）在共同祖先 body
   上判斷「頁面裡有沒有這六種 tint 之一」，回頭改頁首的文字與圖示顏色。
   七色只挑六色（leaf/arctic-water/dew/goldfish/flamingo/peacock），故意排除
   berry——berry 白字對比已經 7.91，本來就合格，不需要也不該被這條規則動到；
   非飲品頁（首頁/門市/加盟等）沒有 .drink-hero，:has() 一律不成立，頁首維持
   原本的白字，不受影響。
   四個 Font Awesome <i class="brxe-icon"> 與四個行內 <svg>（頁首「Follow us」
   社群圖示，桌機版用 <i>、手機選單抽屜版用 <svg>，兩套都在 <header> 裡、都
   可調色）跟文字用同一個 :has() 條件、同時變色，符合 owner 追加的規則：
   「文字變深，圖示要跟著變深」。
   桌機導覽連結的顏色來自 Bricks 用元素 ID 產生的規則
   （`#brxe-nagwri .bricks-nav-menu > li > a { color: var(--light) }`），
   FA 圖示的顏色也是逐一用 ID 設的（如 `#brxe-humais { color: var(--light) }`）
   ——兩者都是 ID 選擇器，優先權比這裡的 class/偽類選擇器高，一般寫法蓋不過去，
   這裡用 !important 是必要手段，不是隨手加的（手機選單裡的連結與 svg 靠
   繼承拿色、優先權低，其實不需要 !important 也會生效，但跟桌機那組合併寫在
   同一個宣告區塊，統一用 !important 比較好維護、不會有時漏蓋）。
   實測過：真的用真實飲品頁（brown-sugar-boba-milk 等）逐一核對六個 tint
   對應的實際 class（`.drink-hero.drink-tint-<name>`），不是憑文件描述硬套。 */
body:has(.drink-hero:is(.drink-tint-leaf, .drink-tint-arctic-water, .drink-tint-dew, .drink-tint-goldfish, .drink-tint-flamingo, .drink-tint-peacock)) header nav a,
body:has(.drink-hero:is(.drink-tint-leaf, .drink-tint-arctic-water, .drink-tint-dew, .drink-tint-goldfish, .drink-tint-flamingo, .drink-tint-peacock)) header i.brxe-icon,
body:has(.drink-hero:is(.drink-tint-leaf, .drink-tint-arctic-water, .drink-tint-dew, .drink-tint-goldfish, .drink-tint-flamingo, .drink-tint-peacock)) header svg {
	color: #1A1A1A !important;
}

/* 項目 3（2026-09-08，嘗試過一版 CSS 換圖、已還原，理由寫在這裡留痕跡）：
   頁首 logo 的白色圓形背板，維持完全不動、繼續依賴客戶自己的檔案，不由本
   掛件接手。

   客戶目前線上的 logo 檔（無條件用在全站每一頁：首頁、七種飲品 tint、
   門市、加盟……單一 `<img>`，沒有任何依 tint 切換的邏輯——`.css-filter`
   這個 class 名稱看起來像色彩濾鏡，實測 `getComputedStyle(img).filter` 是
   `none`、目前載入的樣式表也沒有任何規則命中這個 class，是留下的空 class，
   不影響任何東西）本來就已經是「白色圓形背板 + 深紫 wordmark + 綠色葉子」
   這個樣子，直接下載這顆檔案解碼比對過，也跟這個專案較早留下的 tint 頁首
   截圖核對過：wordmark 對白底 11.04:1、對 tint 直接量測也有 4.89:1，白色
   圓形本身對淺色 tint 只有 2.26–3.45:1——這些都是客戶自己一直以來的既有
   樣子，不是本任務造出來的新現象。

   曾經試過的作法與為什麼撤回：本掛件一度新增了一顆自己的圓形背板檔＋
   `content: url()` CSS 規則，把六個問題 tint（leaf/arctic-water/dew/
   goldfish/flamingo/peacock）換成本掛件自己出的版本，讓這個呈現方式变成
   「我方 remediation 明確保證」而非「客戶檔案剛好長這樣」。這個立意沒有
   錯，但**這一版的畫法用了跟客戶原始檔案不同的圓心、半徑，把 wordmark
   縮小套進一個新的圓（縮放比例約 0.52）**——外層 `<img>` 的框（101×92／
   64×58.3px）量起來沒有變，但框裡的商標本身明顯變小、四周多出一圈留白，
   葉子原本伸出圓外的尾端也被裁掉；reviewer 用像素直接量桌機版 arctic-water
   頁首，wordmark 的可視範圍從 57×49 縮到 29×26，面積剩不到四分之一，肉眼
   可辨。這是沒人要求、也沒被發現的可見變更——早先只驗證了外層 `<img>` 的
   box 尺寸沒變、只用截圖粗看「看起來差不多」，沒有真的疊圖比對 wordmark
   本身的像素範圍，才會漏掉。已完整撤回：新畫的圓形背板檔已刪除、CSS 規則
   已移除，六個 tint 的頁首無條件退回客戶自己原本的檔案，跟其餘 tint／
   非飲品頁完全一致，不再有兩種不同的 logo 呈現同時存在於站上。

   這也改變了 1.4.11 這條準則能立足的論點：客戶自己的品牌資產是「這個低
   對比呈現是品牌規範規定」這一類判斷裡站得住腳的立場；換成本掛件自己選
   的幾何形狀，反而會讓「這是品牌規範、非我方作者選擇」這個立場站不住腳。
   完整論證見交付報告與 criteria.json 的 1.4.11 備註。 */

/* 項目 4：白字印在品牌綠 #00A664 上量到 3.16，需要 4.5。底色（品牌綠）完全
   不動，只把文字改成近黑，量到 5.50。
   fix round 1（2026-09-07，reviewer 抓到）：owner 核准的「31 個節點」是
   ~/ops/a11y/chatime/baseline/1.4.3-pairs-before.json 裡 fg=#ffffff／
   bg=#00a664 這一組 merge 後的精確計數，不是估計值，逐一核對後是四種元素：
     - 10 個 `.bricks-background-primary`（Bricks 按鈕，本檔案原本只蓋到這批）
     - 1 個 franchise 表單的 `<span class="text">Submit</span>`——它自己沒有
       color 規則，是繼承父層 `<button class="bricks-button
       bricks-background-primary">` 的顏色，父層被下面這條規則蓋到之後它就
       跟著變深，不用另外寫選擇器，已用 computed style 核對過
       （span 量到 `rgb(26, 26, 26)`）。
     - 1 個 `/stores/` 頁的 `.store-search__go`（「Go」按鈕）——**第一版漏掉**。
     - 19 個 `/stores/` 頁的 `.store-card__btn`（「Get directions」連結）——
       **第一版漏掉**，是這組裡數量最大的一塊。
   後兩者（20 個節點）跟 Bricks 按鈕是同一組前景/背景色對、同一個量測比值
   （3.16→改後 5.50），只是用門市元件自己的 class 實作，不是 Bricks 產生的
   `.bricks-background-primary`——選擇器只寫了後者，等於這 20 個節點完全沒被
   蓋到，卻在第一版報告裡被誤判成「不在核准清單內」。這裡把它們一起補上，
   不是新的核准範圍，是同一個核准項目裡本來就該蓋到的部分。 */
.bricks-background-primary {
	/* 這個 !important 是「蓋過另一支樣式表自己的顏色選擇」，不是隨手保險，
	   寫清楚蓋的是誰、為什麼、什麼時候可以拿掉：
	   - 蓋的是誰：Core Framework 的 `.btn { color: #fff }`
	     （`core_framework.css`，跟 `.bricks-background-primary` 同樣掛在這顆
	     按鈕上、同樣是 class 選擇器、優先權打平）。
	   - 為什麼非蓋不可：Core Framework 的樣式表在 wp_head 裡排在 a11y.css
	     **之後**印出（enqueue 順序：Bricks → a11y.css → core-framework），
	     優先權打平時「後印的贏」，Core Framework 會贏回去——部署後量過，
	     沒有 !important 這條規則量出來仍是白字，不是理論推演。
	   - 這代表：如果 Core Framework 未來自己為了無障礙把 `.btn` 的顏色改掉
	     （不管改成什麼），這條 !important 一樣會蓋過去、變成看不出來為什麼
	     按鈕顏色「應該」由 Core Framework 決定卻沒有生效——這是這條規則會
	     一直安靜擋著、需要記錄的副作用。
	   - 什麼時候可以拿掉：a11y.css 改成排在 core-framework **之後**印出
	     （調整 `00-bootstrap.php` 的 enqueue 依賴/優先權），或 Core Framework
	     自己把 `.btn` 的顏色改到 ≥4.5:1，兩者任一發生，這裡就不再需要
	     !important，屆時要回來刪掉、不要留著當保險。 */
	color: #1A1A1A !important;
}

/* 上面兩個門市元件的顏色規則，找到的來源是 Bricks 針對這個頁面產生的行內
   `<style>`（`bricks-frontend-inline-inline-css`，在 wp_head 裡排在 a11y.css
   之前），不是 Core Framework，這兩個元素身上也沒有 `.btn` class——所以這裡
   不需要 !important，一般的 class 選擇器＋較晚印出就足以蓋過去，部署後也是
   照這個方式量過確認生效才寫成不加 !important。 */
.store-search__go,
.store-card__btn {
	color: #1A1A1A;
}

/* fix round 2（2026-09-07，reviewer 抓到）：`.store-card__btn:hover` 本來就有
   `background: #00925A; color: #fff;`（同一份行內樣式，跟預設狀態的白字/綠底
   是同一套設計——hover 時底色加深一點當作互動回饋），這條規則是
   `.class:hover`（一個 class＋一個偽類），優先權比上面單純的 `.store-card__btn`
   高，不管印出順序都會贏，所以 hover 時文字被蓋回白色，變成「平常是深色字、
   一滑過去又跳回白字」的閃爍，而且白字對 hover 後的 `#00925A` 只有 3.99，
   一樣不合格——比 axe 定期掃描抓得到的問題更隱蔽：靜態掃描不會觸發 hover，
   這個問題在這個專案至今所有的 scan/assert 證據裡都不會出現，是 reviewer 直接
   讀 CSS 層疊關係找到的，不是量出來的。
   底色的加深（`#00925A`）不在 owner 核准範圍內，這裡不動；能動的是文字顏色，
   所以走文字這條路——同一顆按鈕、同一個核准項目，不需要另外核准。
   **這裡刻意沒有沿用 `#1A1A1A`**：算過 `#1A1A1A` 對 hover 後的 `#00925A`
   只有 4.36，還是不到 4.5（原因是 `#00925A` 比預設的 `#00A664` 更暗，對深色
   文字反而更不利，跟對白字更有利的方向相反）。改用純黑 `#000000`，對
   `#00925A` 量到 5.26，才真的過。跟 `.store-card__btn` 預設狀態用同一個
   `!important` 判斷邏輯：這條也是 `.class:hover` 對 `.class:hover`，優先權打平，
   靠印出順序（a11y.css 排在這份行內樣式之後）就贏，不需要 `!important`。
   `.store-search__go` 沒有對應的 `:hover` 規則（查過同一份行內樣式表，
   查無 `.store-search__go:hover`），維持原本只在預設狀態變色即可，沒有這個
   問題。 */
.store-card__btn:hover {
	color: #000000;
}

/* 項目 5：淺紫區塊（背景 #B296C8）的白字標題／說明文字，量到 2.59，改用
   owner 色卡的深紫 #500778，量到 4.92。
   這個背景色目前只出現在三個地方，且各自是 Bricks 用元素 ID 產生樣式、同一顆
   ID 在共用範本裡在多頁一致出現，逐一核對過：
     - 首頁「Get your fix」區塊：#brxe-adsofv
     - about-us「Contact Us」區塊：#brxe-ljzcue
     - 飲品內頁共用範本「Mix-ins」區塊：#brxe-daftbw（同一個 ID 在所有飲品頁
       上都一樣，因為飲品頁共用同一份範本，不是每支飲品各自的 ID）
   故意不用「.has-shape」這種共用 class 去掃全站：首頁另外還有一個「Trending
   drinks this week」區塊也是 `.brxe-section.has-shape`，但背景是另一個深紫
   #500778、文字本來就是合格的 #5C2D91，不在 owner 核准清單裡、也沒有對比問題
   ——如果用 class 去掃會連它一起改到，等於動了一個沒核准、也沒壞掉的東西。
   同一個理由，首頁「飲品分類」那排色塊（.drink-cat，13px 粗體白字疊在同樣的
   #B296C8 上）這裡也沒有動：它們用 `bricks-lazy-hidden` 延後渲染，這次全站
   掃描沒掃到它們（不在 owner 核准的 8+2 個節點、3 個頁面範圍內），是另一個
   之後要排的違規，不屬於這次核准清單，寫在這裡留痕跡，不要順手改掉。 */
#brxe-adsofv :is(h1, h2, h3, h4, h5, h6, p),
#brxe-ljzcue :is(h1, h2, h3, h4, h5, h6, p),
#brxe-daftbw :is(h1, h2, h3, h4, h5, h6, p) {
	color: #500778;
}

/* 項目 6：每頁都有的粉紅橫幅「JOIN THE PAR-TEA」，文字 #F16776 印在頁面底色
   #F0EAF4 上（footer/section/container 全部透明，實際看到的底色來自 <html>
   的背景色，量測與 owner 核准的數字都是照這個真正生效的底色算的），量到
   2.56，改用 owner 色卡的洋紅 #B61F7E，量到 5.10。這個標題的元素 ID
   （#brxe-xpmdjn）在頁尾範本裡全站共用、逐頁核對過一致，用 ID 選最精準，不會
   誤傷其他標題。 */
#brxe-xpmdjn {
	color: #B61F7E;
}

/* 2.2.2 Pause, Stop, Hide：Franchise hero 背景影片的暫停/播放按鈕。
   按鈕的 DOM 節點是 a11y.js 從 wp_footer 搬進 hero section 內部的（見該檔
   說明），這裡的 position:absolute 是相對於那個 section。
   hero section（Bricks 設定 `_position` 已核對過是 "relative"，2026-09-07
   實查 `_bricks_page_content_2`）本身就有 position:relative，理論上不需要
   再補；下面這條規則是保險，用 Bricks 自己在「有背景影片的 section」上
   一律加的 `has-bg-video` class 兜底，不寫死目前這個 section 的元素 ID——
   這個專案已經因為 Bricks 重新編輯會換元素 ID、抄舊 ID 撲空好幾次
   （task-14 之前的教訓），用穩定的 class 比較不會在下次改版後失效。

   bottom 偏移量 48px（不是原本試的 16px）：實測發現 hero 底部的波浪分隔
   （`.bricks-shape-divider`，Bricks 設定 height 40px）在按鈕所在的水平範圍
   內，波峰最高處比它自己宣告的 40px 還再往上探一截——用真實螢幕截圖逐像素
   掃描量出來的，不是照 40px 這個設定值去推算：桌機 1440px 寬時，按鈕正下方
   到頁面淺色底色（--bg-body）之間，波浪最高處量到只剩 9px 的間隙（bottom:16px
   時量到按鈕邊框幾乎貼著波浪，某些 x 位置甚至重疊）。16px 會讓按鈕的白色
   邊框在底邊這一段緊貼淺色底色，白框對淺色底只有 1.18:1，遠低於 1.4.11
   非文字對比要求的 3:1。48px 讓按鈕整體留在波浪最高點之上，量測見
   task-14-report.md。 */
section.has-bg-video {
	position: relative;
}

.chatime-a11y-video-toggle {
	position: absolute;
	right: 16px;
	bottom: 48px;
	z-index: 20;
	min-width: 24px;
	min-height: 24px;
	padding: 8px 14px;
	background: #1a1a1a;
	color: #fff;
	border: 1px solid #fff;
	border-radius: 4px;
	font-size: 14px;
	line-height: 1.4;
	cursor: pointer;
}
.chatime-a11y-video-toggle:focus-visible {
	outline: 3px solid #fff;
	outline-offset: 2px;
}

/* 2026-09-09 owner 裁示 block-until-consent：Franchise hero 背景影片的「同意才
   播放」按鈕（45-video-consent-gate.php／a11y.js 的同意閘門模組）。

   位置刻意跟暫停鈕（上面 `.chatime-a11y-video-toggle`）分開處理，不是共用同一顆：
   這顆按鈕要在影片還沒開始播放前就先讓人看到、按下去，暫停鈕要在影片開始播放後
   才有意義，兩者不會同時存在——但兩者都必須是 `section.has-bg-video` 的手足元素
   （不能是 `.bricks-background-video-wrapper` 的子元素）：wrapper 是
   `position:absolute;z-index:-1!important`，會建立自己的疊層情境，裡面的子元素
   不管給多高的 z-index，都逃不出這個情境，會被 section 自己的 `::after` 深色遮罩
   （`rgba(0,0,0,.6)`，跟 wrapper 同一個疊層層級、DOM 順序在後）蓋住變暗——白字
   按鈕疊上這層遮罩會變成灰階，對比大幅下降。放在 section 裡（wrapper 外面）、
   z-index 給得比遮罩高，才能維持這裡量到的對比（見 youtube-consent-report.md）。

   位置用 top/left 百分比置中，不是固定像素：實測桌機（1440×900）與手機
   （390×844）兩種斷點下，hero 的 heading 都是從 padding-top:360px 開始、往下
   延伸到 hero 總高度再往上留 220px（`#brxe-wwiyjl` 的 Bricks 設定值，兩種斷點
   共用同一組像素值，不隨斷點變動），所以「heading 底部到 wave 分隔線安全區之間」
   這個可用範圍在兩種斷點下的比例接近（量出來都落在 hero 高度的 75%–80% 之間）——
   用百分比而不是固定像素，斷點之間才不會需要各自調一次數字。實際成品截圖見
   youtube-consent-report.md，桌機/手機都有驗過沒有跟 heading 或 wave 重疊。 */
.chatime-video-gate__play {
	position: absolute;
	left: 50%;
	top: 78%;
	transform: translate(-50%, -50%);
	z-index: 20;
	display: flex;
	align-items: center;
	gap: 10px;
	min-height: 24px;
	padding: 12px 22px;
	background: #1a1a1a;
	color: #fff;
	border: 1px solid #fff;
	border-radius: 6px;
	font-size: 16px;
	font-weight: 700;
	line-height: 1.4;
	white-space: nowrap;
	cursor: pointer;
}
.chatime-video-gate__play:focus-visible {
	outline: 3px solid #fff;
	outline-offset: 2px;
}
.chatime-video-gate__play-icon {
	display: inline-block;
	width: 0;
	height: 0;
	border-style: solid;
	border-width: 8px 0 8px 14px;
	border-color: transparent transparent transparent currentColor;
	flex: none;
}

/* Task 16b defect 2（1.4.3）：門市內頁「Get directions」連結（class
   `store-detail__cta`，`brxe-text-link` 元件），白字印在品牌綠 #00A664 上
   實測 3.16:1，19/24 現存門市中（其餘 5 個是「Coming Soon」門市，頁面上
   沒有地址、這顆連結本身不會渲染）。

   這是 T5b 已核准的同一組配色、同一個修法（底色不動，文字改近黑）——但
   T5b 當時只框到 `.bricks-background-primary`／`.store-search__go`／
   `.store-card__btn` 這幾個既有清單，`store-detail__cta` 是自訂
   `text-link` 元件、視覺上長得一樣，技術實作沒有落在那份清單框定的任何一個
   選擇器裡，所以完全沒被那次的規則蓋到（詳見
   ~/ops/a11y/chatime/evidence/task16/task16-new-defects.md 缺陷 2）。
   approval 覆蓋的是「這個顏色決定」本身，不是當時量到的節點數，這裡是同一個
   已核准決定延伸到一個先前漏掉的元件，不需要另外核准（brief 原文）。

   實測（真實門市頁 chatime-bel-air，getComputedStyle，非套公式推算）：
   預設態 color: rgb(255,255,255) / background-color: rgb(0,166,100)
   （#00A664）→ 3.16:1；hover 態 background-color: rgb(0,146,90)
   （#00925A，跟 .store-card__btn:hover 是同一個 hover 加深規則、同一個
   來源——Bricks 為這個元件生成的行內 <style>，`href: null`，printed 在
   a11y.css 之前，class 選擇器優先權打平時「後印的贏」）→ 3.99:1。查過
   整份文件所有 <style> 表裡選擇器含 "store-detail__cta" 的規則，只有這
   兩條（預設＋:hover），沒有 :focus／:active／:visited 專屬規則，不需要
   額外覆蓋分支。

   跟 .store-card__btn 完全同一組底色（#00A664 預設／#00925A hover），近黑
   #1A1A1A 對 #00A664 量到 5.50（合格），但對 hover 後的 #00925A 只有
   4.36（不合格——#00925A 比 #00A664 暗，對深色文字反而更不利），這裡直接
   沿用 fix round 2 已經驗證過的解法：hover 態用純黑 #000000（對 #00925A
   量到 5.26），不是再猜一次同一個坑。跟 .store-card__btn 一樣，兩條都是
   `.class`／`.class:hover` 對 Bricks 行內 `<style>` 的同優先權選擇器，靠
   a11y.css 印出順序較晚就贏，不需要 !important——部署後有重新量測確認生效
   （見 task-16b-report.md），不是照搬理論。 */
.store-detail__cta {
	color: #1A1A1A;
}
.store-detail__cta:hover {
	color: #000000;
}

/* Task 16b defect 3（1.4.10 Reflow）：320 CSS px 寬度下的橫向捲動。

   franchise／about-us 兩頁「The Chatime Difference」／同款 4 欄特色卡片
   網格（Bricks 節點 `xaiqsi`／`rqtlia`，兩頁各自複製貼上的獨立節點，不是
   同一個共用元件，因此各自需要一條規則）：`_gridTemplateColumns` 只有
   桌機「1fr 1fr 1fr 1fr」與 mobile_portrait「1fr 1fr」兩層；卡片內圖片
   固定 `_width:160` 沒有再往下的響應式覆蓋。

   fix round 1（2026-09-08，reviewer 掃 12 個寬度抓到）：**第一版判斷是錯的。**
   第一版只在 320／340／359／360px 四個點量過，跳過 360 直接跳到 768，
   誤判「360px 以上完全乾淨」——跟這個任務存在的理由是同一種錯（稀疏樣本），
   只是把稀疏樣本從「哪些網址」搬到「哪些寬度」。reviewer 用 Playwright 對
   320–768px 每 8px 連續量測抓到：mobile_portrait 這個 Bricks 內建斷點的
   實際媒體查詢是 `(max-width: 478px)`（直接讀頁面 CSSOM 對照
   `#brxe-xaiqsi` 的規則核對出來的真實值，不是猜的），2 欄版面只在
   ≤478px 生效；478px 以上、直到內容本身自然放得下 4 欄為止（實測
   scrollWidth 在 480px 撐到 722px，隨寬度緩慢增加，728px 才自然轉乾淨），
   中間完全沒有任何斷點縮到 2 欄，退回桌機版 4 欄 × 160px 圖片，480–720px
   這整段全部橫向捲動（例如 568px，iPhone SE 橫向，落在這個壞掉的區間內）。
   本輪修正前重新逐 8px（320 到 768）複測兩頁，結果跟 reviewer 完全吻合。

   修法：把 2 欄規則的斷點從「只有 ≤359px 單欄」擴大成兩層——
   ≤767px 維持（或退回）2 欄，≤359px 才進一步收成單欄（跟第一版理由
   相同：2 欄 × 160px 圖片在低於 360px 時連 2 欄都放不下）。767px 不是
   隨手選的數字：直接讀同一頁 CSSOM，站上既有的 `#brxe-44c6ea`
   （這個網格的父容器）本來就有一條 Bricks 原生產生的
   `@media (max-width: 767px) { flex-wrap: nowrap; }` 規則——這是 Bricks
   自己的 mobile_landscape 斷點，767px 這個值是「站台自己已經在用的斷點」，
   不是另外發明的門檻。用這個值等於是把 2 欄／4 欄的切換點，從「完全沒有
   斷點、內容自己看撐不撐得下」改成「跟站上其他地方一致的響應式斷點」，
   是在修一個 Bricks 兩層斷點之間漏掉的空隙，不是在設計一個新版面。

   量測（真實頁面，Playwright resize + scrollWidth，320 到 768 逐 8px 連續量，
   不是挑點）：
     320–359px → 收成單欄，320px 下 scrollWidth 320px（無捲動）
     360–767px → 2 欄，480px／600px 下 scrollWidth 皆等於 clientWidth（無捲動）
     768px（含）以上 → 完全不受這兩條規則影響（大於 767px 條件不成立），
       跟修正前後 scrollWidth 逐一比對於 768／1024／1440px 完全相同
   479–767px 這段是真正的「一般使用者會用到的寬度」（小尺寸手機橫向、
   小型平板直向），跟第一版誤判的「只影響 320–359 幾乎沒人用的寬度」不同——
   這裡確實會改變這個寬度區間目前看到的畫面（現況是橫向捲動）。
   之所以不因此送 owner 核准：現況（橫向捲動）本身就是壞的、不是設計出來的
   結果，且新的 2 欄版面就是**這個網格自己在再窄一點的 mobile_portrait
   斷點已經在用的版面**（同一個 `_gridTemplateColumns:mobile_portrait`
   設定值），這裡只是把它套用的範圍往上補到跟站上另一個既有斷點
   （767px）銜接，是補齊斷點間的空隙、不是設計一個新版面。已依要求在
   480px／600px 對 franchise／about-us 兩頁拍修正前後截圖
   （`~/ops/a11y/chatime/evidence/task16b/screenshots/`），供 owner 用肉眼
   核對、如果不同意可以推翻。 */
@media (max-width: 767px) {
	#brxe-xaiqsi,
	#brxe-rqtlia {
		grid-template-columns: 1fr 1fr !important;
	}
}
@media (max-width: 359px) {
	#brxe-xaiqsi,
	#brxe-rqtlia {
		grid-template-columns: 1fr !important;
	}
}

/* Task 16b defect 3（1.4.10 Reflow）：privacy 頁內文用一整串全形破折號
   （`———————————————————————————————`，最長 31 字元不含空白）當視覺分隔線
   （Bricks 節點 `jfmlrb`），沒有任何空格可以換行，瀏覽器只能把它當一個不可
   斷開的「字」，逼頁面撐寬到 423px（實測 scrollWidth，320px 視窗下）。

   這不是二維版面才有意義的內容（不是地圖、不是資料表），是真實可讀文字被
   推出視窗，1.4.10 沒有例外條款可用。

   修法：`overflow-wrap: anywhere`，只允許瀏覽器在真的沒有其他斷點可用、
   即將溢位時才在字元邊界換行，不影響任何本來就能正常斷行的文字。這條規則
   在任何寬度下對「一行本來就放得下」的內容零視覺影響——分隔線在 360px 以上
   本來就完整印在一行內（實測 768px／1440px 加這條規則前後 scrollWidth
   逐一比對完全相同，見 task-16b-report.md），只有在窄到放不下的寬度
   （≤359px，同上一條的量測）才會真的斷成兩行；一般使用者在任何真實裝置
   寬度上看到的分隔線樣式不變，同樣不落在需要另外核准的「改變一般寬度下
   畫面」那類情況。範圍只鎖定這一個文字區塊（`#brxe-jfmlrb` 底下的
   `<p>`），不影響 privacy 頁或站上其他段落文字的換行行為。 */
#brxe-jfmlrb p {
	overflow-wrap: anywhere;
}

/* Task 16b defect 3 fix round 1（1.4.10 Reflow）：另一個橫向捲動來源，
   **不是** privacy 頁的內容，是全站共用的頁尾（跟 Task 7 修過的
   `<h2>JOIN THE PAR-TEA</h2>` 同一個頁尾範本 post 78）。

   reviewer 在 privacy 頁 480px 抓到「一個無關的既有元素」造成捲動；實查
   定位到是頁尾「JOIN THE PAR-TEA」標題與社群圖示這一排（class
   `footer-social`），480–576px 這段寬度裡標題文字＋4 個圖示的固定寬度加總
   超過版面可用寬度，`flex-wrap: nowrap`＋預設 `min-width: auto` 讓瀏覽器
   選擇讓圖示溢出而不是換行或縮小——跟 franchise/about-us 那個網格是同一種
   「flex/grid 沒有留退路」的成因。

   因為頁尾是全站共用範本，這不只是 privacy 頁的問題：實測改之前对首頁／
   `/terms/`／門市內頁／飲品內頁分別在 520px 量都得到一模一樣的
   `scrollWidth: 567`（跟 privacy 頁完全相同的數字），證實這是**全站** 97
   頁在 480–576px 這段寬度共有的缺陷，只是先前兩輪的量測都沒有測過這個
   寬度區間（第一輪只測 320px，這裡的第二輪本來也只針對 franchise/about-us/
   privacy 三頁）——跟本任務的起源是同一種坑：只是這次是「哪個寬度」的
   稀疏樣本，不是「哪個網址」。因為根因在共用頁尾，修一條規則就對全站生效，
   不需要也不應該逐頁單獨修。

   修法：`.footer-social { flex-wrap: wrap; }`——圖示原本擠不下時允許換到
   第二行，不再溢出版面。跟前面兩個網格斷點的修法是同一個判斷：現況
   （橫向捲動）本身是壞的，換行是「原本就該有、只是沒設」的退路，不是新
   設計。量測過視覺影響範圍：768px／1024px／1440px 這排圖示的容器高度加
   規則前後完全不變（單行，未觸發換行），確認一般桌機／平板寬度不受影響；
   480–600px 這段容器高度從 ~97px 變成 ~215px（圖示確實換成兩行）——這是
   這條修正在該寬度區間**唯一**會看到的畫面變化，已依要求在 480px／600px
   對 franchise／about-us 兩頁的截圖裡一併涵蓋頁尾範圍
   （`~/ops/a11y/chatime/evidence/task16b/screenshots/`）。不用
   `!important`：`.footer-social` 是唯一設定 `flex-wrap` 的規則來源，沒有
   優先權更高的規則需要蓋過。 */
.footer-social {
	flex-wrap: wrap;
}

/* 2026-09-09（門市地圖視覺行為補齊，owner 交辦）：圖釘上方的永久店名標籤。
   數值逐項對照 ~/ops/a11y/chatime/evidence/au-map-behaviour.md 對原站
   （chatime.com.au/stores/）的真瀏覽器實測——背景 #5C2D91（跟圖釘同一個紫）、
   白字、700、9px、line-height 12.6px、內距 2px 5px 1px、圓角 2px、對比
   9.38:1（遠高於 4.5:1，不是這裡的問題）。
   HTML 結構在 stores.js 的 pinHtml()/pinLabelHtml()：這個 <span> 是 Leaflet
   divIcon 容器（`.leaflet-marker-icon`，本身就是 44×55、`position:absolute`）
   的子節點，這裡的 absolute 定位是相對於那個容器，不需要另外包一層 wrapper。
   `bottom: 100%` 讓標籤貼著容器上緣（也就是圖釘正上方），不管標籤自己多高都
   一樣貼齊；`left: 50% + transform: translateX(-50%)` 做水平置中，不看標籤
   自己的寬度（店名長短不一）。
   `white-space: normal` + `max-width`：原站也是 white-space:normal（會隨店名
   長度換行），這裡加 max-width 是因為我方 24 家店裡有幾家店名偏長（例如
   "Chatime University Mall"），完全不限制寬度會讓標籤變成一條長方形橫幅，
   在門市密集的城市（東岸幾顆圖釘只差幾十像素）互相蓋住的機率更高；
   130px 是實測「常見店名兩行內排得下、不會變成三行」抓出來的值。
   `pointer-events: none` 不是必要（標籤是圖釘 click handler 所在容器的子
   節點，點在標籤上一樣會透過事件冒泡觸發 marker 的 click），這裡加上是為了
   避免標籤在視覺上蓋住相鄰圖釘時，滑鼠意外命中的是標籤而不是它視覺上看起來
   要點的那顆圖釘本體——保險，不是修正一個已知會出錯的行為。 */
.store-marker__label {
	position: absolute;
	bottom: 100%;
	left: 50%;
	transform: translateX(-50%);
	margin-bottom: 3px;
	max-width: 130px;
	padding: 2px 5px 1px;
	border-radius: 2px;
	background: #5C2D91;
	color: #fff;
	font-weight: 700;
	font-size: 9px;
	line-height: 12.6px;
	text-align: center;
	white-space: normal;
	pointer-events: none;
}

/* 2026-09-09：「縮放要能回得去」的重置按鈕（stores.js 的 addResetControl()，
   原站沒有這個、是本任務要求補的）。用真正的 <button>，鍵盤 Tab／Enter／
   Space 都是原生行為，聚焦時已經吃得到全站的 `:focus-visible` 外框規則
   （本檔案最上方，對這個淺灰底地圖量到的對比遠超過 3:1，不需要另外覆寫
   outline 顏色）。
   `min-height` 確保 2.5.8 的 24px 下限。
   fix round（部署後實測抓到，Important）：原本以為按鈕預設的 `hidden` 屬性
   （stores.js 設定）不需要另外處理——`hidden` 是瀏覽器原生行為，UA 樣式表有
   `[hidden] { display: none }`。但這個假設是錯的：`[hidden]` 屬性選擇器跟下面
   `.store-map-reset` 這個 class 選擇器特異度打平（都是 0-1-0），a11y.css 又排在
   UA 樣式表之後載入，「後印的贏」，於是這條規則自己的 `display: inline-flex`
   蓋掉了 UA 的 `display: none`——實測（門市列表頁一次都還沒點過任何圖釘）
   `getComputedStyle` 量到 `display: flex`、`offsetWidth/Height` 皆為正、
   `hasAttribute('hidden')` 也確實是 true，三者合起來證實按鈕在頁面剛載入、
   根本還沒有任何店可以「返回」的時候就已經看得到、點得到——這正是本任務
   「重置按鈕只在選了某家店之後才出現」這個設計意圖被自己的樣式表蓋掉的
   defect，不是理論上的風險。跟 `.chatime-consent-checkbox` 的 `min-width`
   同一種「特異度打平、後印的贏」坑，修法一致：把 `[hidden]` 的情況獨立寫一條
   更具體的規則（class + 屬性選擇器，特異度 0-2-0，蓋過上面單純的 class
   選擇器），不需要 `!important`。 */
.store-map-reset {
	position: absolute;
	top: 10px;
	right: 10px;
	z-index: 1000;
	display: inline-flex;
	align-items: center;
	min-height: 24px;
	padding: 6px 14px;
	border: 1px solid #5C2D91;
	border-radius: 4px;
	background: #fff;
	color: #5C2D91;
	font-size: 13px;
	font-weight: 700;
	line-height: 1.2;
	cursor: pointer;
}
.store-map-reset[hidden] {
	display: none;
}
.store-map-reset:hover {
	background: #f3ecf9;
}

/* 2026-09-09（Franchise 表單 Disclaimer checkbox，owner 交辦）：owner 核准的
   做法是「維持一顆真正的 checkbox，換一個自訂 label，連結放在 label 裡面」
   （見 a11y.js 對應模組的完整說明）——這裡只負責視覺，不影響底層仍是原生
   `<input type="checkbox">` 這件事。
   `.chatime-consent-row`：這顆 checkbox 所在的 `<li>`（Bricks 原生就是
   `display:flex; align-items:baseline`）。checkbox 放大到 24px 之後
   `baseline` 對齊會讓 checkbox 跟第一行文字的視覺基準線對不齊，這裡改成
   `flex-start`，只影響對齊方式，不影響原本 8px 的 `gap`（不覆寫、原樣繼承）。
   `.chatime-consent-checkbox`：原本 13×13、瀏覽器預設外觀，這裡只放大到
   24×24（2.5.8 下限，也是「看起來更講究」的一部分）並用 `accent-color` 上
   品牌紫——不是隱藏原生控制項、疊一顆假的上去（owner 明確不要那樣做），是
   同一顆原生 checkbox 本身變大、變色，鍵盤／表單驗證／輔助科技吃到的仍然是
   同一個元素。
   `.chatime-consent-label a`：這個表單的全站 <a> 預設是 `text-decoration:
   none`（實測 footer 連結核對過），而這個連結文字顏色跟外圍免責聲明文字
   同樣是 #5C2D91、也一樣是 700——只換顏色或粗細都做不到「不只靠顏色分辨」，
   這裡明確加回底線，讓連結不需要靠顏色（1.4.1）也看得出是連結，也讓視覺上
   看起來比一整段純文字更講究。焦點樣式沿用全站 `:focus-visible` 規則（連結
   本身就在 `:where(a, ...)` 選擇器範圍內），沒有另外覆寫。 */
.chatime-consent-row {
	align-items: flex-start !important;
}
/* fix round（部署後實測抓到）：只加 `width: 24px` 時，`height` 套用了、`width`
   沒有——就算改成 `width: 24px !important`，`getComputedStyle` 量到的仍然是原生
   13px，`r.style.getPropertyPriority('width')` 也核對過確實是 `"important"`，
   代表贏了 cascade 優先權，問題不在特異度／`!important`，是「用哪個值」這一層。
   用二分法逐一在真實頁面對這顆 checkbox 疊加 inline `!important` 屬性實測
   （見 map-and-form-report.md 的除錯記錄）：只有補上 `min-width: 24px` 才讓
   `offsetWidth` 真的變成 24；同樣疊加 `flex-shrink:0`／`flex-basis`／
   `box-sizing`／`transform`／`zoom`／`aspect-ratio`／`display:inline-block`
   都沒有單獨解決。判定：某條我方沒能在 `document.styleSheets`（含遞迴 @media/
   @supports）列舉到的規則把 `max-width` 釘在一個小於 24px 的值（懷疑是走
   @import 或瀏覽器內部把原生 checkbox 外觀相關的最大尺寸鎖住），
   `width` 被那個 `max-width` 夾住；CSS 對 min/max/width 三者衝突時 min-width
   優先於 max-width（規格行為），所以把 min-width 也頂到 24px 能繞過去，不需要
   先確定 max-width 那條規則實際的來源與數值。
   height 沒有這個問題（同一輪測試中，只給 `height: 24px` 就直接生效），這裡
   對稱地也給 height 補一個不會有副作用的 min-height，純粹一致性與保險，不是
   因為 height 也重現了同一個 bug。 */
.chatime-consent-checkbox {
	width: 24px !important;
	min-width: 24px !important;
	height: 24px;
	min-height: 24px;
	margin: 0;
	accent-color: #5C2D91;
	cursor: pointer;
}
.chatime-consent-label {
	cursor: pointer;
}
.chatime-consent-label a {
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 2px;
}
.chatime-consent-label a:hover {
	text-decoration-thickness: 2px;
}

/* 2026-09-09（Privacy Policy 標題層級修正，owner 交辦）：page id 3 的政策內文
   （`_bricks_page_content_2`，元素 jfmlrb／urxjyn）過去用 Word 貼上的殘骸標記
   （單一項目 `<ol>`/`<ul>`、`<p><b>…</b></p>`）冒充標題，鍵盤／標題導覽在這頁
   只看得到一個項目。內容已改成真正的 `<h2>`–`<h4>`，見
   docs/chatime-handover-database-changes.md 第 2 項。

   這裡只處理「換上真標題之後，畫面看起來不能壞掉」：全站 Theme Style 對
   h2/h3/h4 的預設字級是 64px/56px/48px、字重 900/900/700（給首頁大標題用
   的），這份政策內文原本全部是跟本文一樣大小的一般文字（PART A/B/C 與
   Scope of This Policy / ADDITIONAL INFORMATION 那幾則本來就用行內 `<b>`
   加粗，其餘則是不加粗的純文字），套用全站預設字級會讓整頁變成一堆超大
   標題、版面高度暴增，讀起來不再是同一份文件。

   做法：只在這個政策內容容器（`#brxe-llmwlu`，即 `_bricks_page_content_2`
   裡的 `llmwlu` 區塊，urxjyn 前言＋jfmlrb 政策全文都在它底下）裡，把
   h2/h3/h4 字級收回跟本文一致（1em）、行高比照本文（1.7 ≈ 27.2px/16px），
   只留字重差異做最小限度的視覺分層：h2（Scope/PART A/PART B/PART C/
   ADDITIONAL INFORMATION）與 h3 用 700、h4 用 600，比原本全部同一字重多了
   一點層次，但不到「看起來像另一份設計」的程度。標題原本靠 `<ol>`/`<ol
   start="N">` 自動編號顯示的「1.」「2.」……這個編號本來就不是文字內容
   本身（innerText 不含它），且原始編號在殘骸標記下本來就不連貫（多處各自
   獨立的 `<ol>` 沒有 start 屬性、各自從 1 開始），不是刻意設計的章節序號，
   這裡不用 CSS counter 重建它，改用真標題結構本身（h2>h3>h4 巢狀層級）
   取代原本靠編號暗示的層次。
   `#brxe-llmwlu` 是 Bricks 產生的元素 ID，只在有人用 Bricks 編輯器重建這個
   區塊結構時才會變——目前是能拿到的最貼近「只選中這塊內容、不影響其他
   共用區塊（例如頁尾 JOIN THE PAR-TEA 那個 h2）」的選擇器。 */
#brxe-llmwlu h2,
#brxe-llmwlu h3,
#brxe-llmwlu h4 {
	font-size: 1em;
	line-height: 1.7;
	margin: 0;
}
#brxe-llmwlu h2,
#brxe-llmwlu h3 {
	font-weight: 700;
}
#brxe-llmwlu h4 {
	font-weight: 600;
}

/* 2.4.4／4.1.2：同意橫幅裡的空連結（2026-09-09 修）

   實查：同意管理外掛在橫幅底部渲染一個「Cookie 政策」連結槽位
   `<a class="cmplz-link cookie-statement" href="/privacy/"></a>`。本站沒有獨立的
   Cookie 政策文件，這個槽位就渲染成**完全沒有文字**的連結。它的 `display` 是
   `inline`（不是 none）、尺寸 0×0，所以看不見卻仍然留在無障礙樹裡——螢幕閱讀器
   會唸出一個沒有名稱的連結，axe 判為 `link-name` / serious，全站每一頁都有。
   它旁邊那個看得見的「Privacy Policy」連結指向同一個網址，所以這個槽位沒有任何
   資訊價值。

   為什麼用 `:empty` 而不是直接 `display:none`：這個規則只在連結真的沒有內容時
   生效。日後若在外掛裡設定了 Cookie 政策文件、槽位長出文字，這條規則就自動
   失效，不會把一個有意義的連結藏起來。

   為什麼修在樣式層而不是 PHP：這個節點是外掛前端 JS 在執行期插進橫幅的，
   伺服器端的輸出過濾看不到它。 */
a.cmplz-link.cookie-statement:empty {
	display: none;
}
