/*
Theme Name: 銷波快 Marketblock
Theme URI: https://marketblock.cc/
Author: ClassOn 雙捷數位有限公司
Author URI: https://classon.com.tw/
Description: 銷波快行銷電台官方主題。Block Theme，一頁一 block 架構，設計 token 取自 homepage-v8-blue 設計正本。
Requires at least: 6.7
Tested up to: 7.1
Requires PHP: 8.0
Version: 1.0.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: marketblock
Tags: blog, news, one-column, block-patterns, full-site-editing
*/

/* ⚠️ 本檔由 automation-scripts/build-theme-css.py 從設計正本
      marketblock-proposals/homepage-v8-blue.html 的 `@site` 標記區產生。
      **不要直接編輯**——下次重跑會被覆蓋。
      要改共用樣式請改設計正本的 @site 區，然後重跑這支腳本
      與 build-*.py（那些產生 228 個靜態頁，吃的是同一份來源）。 */

/* ═══ 自架字型 ═══
   2026-08-12 從 Google Fonts CDN 改為自架。三個理由：
   ① 不對第三方發請求（Google Fonts 會拿到讀者 IP）
   ② 可依品牌語料子集化——CDN 版切成 105 個 unicode-range 分片，
      光前 40 片就 1,981 KB；自架子集化後三個檔合計 636 KB
   ③ 可變字型單檔涵蓋全字重，不必為 400/500/700/900 各載一個檔

   中文用 Source Han Sans TW（思源黑體）。這不是換字——
   實測 Google Fonts 的 Noto Sans TC 內部版權欄寫的是
   「(c) 2014-2021 Adobe, with Reserved Font Name 'Source'」，
   兩者本來就是同一套字，只是發行名不同。

   拉丁字改用 Source Sans 3：與思源黑體同屬 Source 家族，
   拉丁字形同源設計，混排時筆畫粗細與字面率一致。
   （原本考慮的 Calibri 是微軟專有字型，不允許 webfont 嵌入，
     且 macOS/Linux/Android 都沒有，會靜默 fallback。）

   unicode-range 讓拉丁字先載入 54 KB 就能顯示，
   中文那 556 KB 只在頁面真的有中文字時才下載。 */
@font-face {
  font-family: 'Source Sans 3'; font-style: normal;
  font-weight: 200 900;                 /* 可變字重 */
  font-display: swap;
  src: url('assets/fonts/SourceSans3-var.woff2') format('woff2-variations');
  unicode-range: U+0000-00FF, U+0100-017F, U+2000-206F, U+20AC, U+2122, U+2190-2193, U+25A0-25FF;
}
@font-face {
  font-family: 'Source Han Sans TW'; font-style: normal;
  font-weight: 250 900;
  font-display: swap;
  src: url('assets/fonts/shs-tw-var.woff2') format('woff2-variations');
  unicode-range: U+2E80-9FFF, U+3000-303F, U+FF00-FFEF, U+F900-FAFF;
}
/* 秋空黑體 MN（ChiuKong Gothic M）— display 專用，只含標題字集
   SIL OFL 1.1｜github.com/ChiuMing-Neko/ChiuKongGothic v.1.300（2022-10-09）

   ★ **只有 900 一個字重，這是實測後刪減的結果**（2026-08-30）。
     原本子集了 700 與 900 兩個（各約 254KB）。實地量五個頁型的 h1，
     發現**全部都是 weight 900**——套用範圍是 `h1/.ax-title/.scol .ch/.who-name`，
     那四個角色本來就都是 900。700 那份從頭到尾**沒有任何頁面載入過**，
     `document.fonts.check('700 …')` 回 false 就是證據。
     ⚠️ 教訓：子集化的字重要照**實際渲染值**決定，不是照 DB 的規格清單抄。
       DB 寫 500/700/900 是字型家族**提供**的字重，不等於站上**用到**的字重。

   unicode-range 只含 CJK：拉丁與數字仍走 Source Sans 3，不重複下載。 */
@font-face {
  font-family: 'ChiuKong Gothic M'; font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url('assets/fonts/ckg-mn-900.woff2') format('woff2');
  unicode-range: U+2E80-9FFF, U+3000-303F, U+FF00-FFEF, U+F900-FAFF;
}
@font-face {
  font-family: 'Geist Mono'; font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('assets/fonts/GeistMono-var.woff2') format('woff2-variations');
  unicode-range: U+0020-007E, U+00B7, U+2014, U+2190-2193, U+00B0, U+2025;
}

/* ===== TOKENS — 方向 D：純白深藍 =====
   比值全部實算（automation-scripts/check-design.py 可複驗），不是估的。
   底色階梯只有三階，而且 --bg-2 整頁只出現在訂閱區與頁尾：
   中段一路 bg-0/bg-1 交替純粹是分段，「打破交替」本身就是抵達訊號。 */
:root {
  /* 底色 */
  --bg-0: #ffffff;    /* 主底：純白 */
  --bg-1: #f4f7fa;    /* 次底：極淺冷灰 */
  --bg-2: #e7eef6;    /* 三底：淺藍灰——保留給視覺高峰 */
  --line-c: #d3dde8;  /* 邊線 */

  /* 文字（比值對 --bg-0 純白）*/
  --ink:    #111c2b;   /* 主文   17.15:1 */
  --text:   #22303f;   /* 正文   13.44:1 */
  --body:   #31404f;   /* 內文   10.62:1 */
  --muted:  #465565;   /* 次要    7.64:1 */
  --sub:    #5a6877;   /* 補充    5.70:1 */
  --meta:   #5f6d7c;   /* 日期/來源 5.30:1（B3 專用）*/
  --faint:  #5f6d7c;   /* 同 meta：不另設更弱的階，避免不小心用到不合格的灰 */
  --fg:     #111c2b;

  /* 重點色：深藍 */
  --blue:      #14476b;  /* 主重點  9.80:1 白底／8.38:1 在 bg-2 上，正文用也安全 */
  --blue-mid:  #1d5c8f;  /* hover、次級  7.05:1 */
  --blue-soft: #2e7292;  /* 品牌既有藍：裝飾線、細緻強調  5.33:1 */
  --blue-wash: rgba(20,71,107,.08);  /* 背景染色 */

  /* 線條 */
  --line:  rgba(0,0,0,.08);
  --line-m: rgba(0,0,0,.12);

  /* 字型 */
  --sans: 'Source Sans 3', 'Source Han Sans TW', system-ui, sans-serif;
  --mono: 'Geist Mono', ui-monospace, monospace;
  /* ★ display 字族（2026-08-30）：秋空黑體 MN，只用在中文標題。
     · DB `typography_system.pairing_logic`：「display≠body 字族製造層級對比」
     · 為什麼需要它：層級對比若只能靠字級，就得把標題放大，而 DB
       `scale.gravity_center` 明寫「**不吼，用語言的重量而非字級的大小**」。
       字族承擔一部分對比之後，字級就不必扛全部。
     ⚠️ 上游是 Source Han Sans v2.004，與 body 的思源黑體**同源**——
       所以這是「同骨架的風格對比」（印刷體筆形 vs 現代黑體），不是真正的跨族，
       對比會比預期弱。這一點在決定時已知並接受。
     ⚠️ 只子集了 h1/h2/h3 出現過的 1,703 字。**日更會長出新字**，
       子集沒有的字會 fallback 回思源黑體＝同一行混兩套字型。
       日更管線要加「新字偵測」，或定期重跑 _fonts-eval/_subset_mn.py。
     ⚠️ **只上 900 一個字重**（實測發現 700 沒有任何頁面用到，見 @font-face 的說明）。
       500/700 那兩層留給思源黑體，讓層級同時靠字重與字族拉開。 */
  --display: 'ChiuKong Gothic M', 'Source Han Sans TW', var(--sans);
  /* 流動容器：跟著螢幕寬度長，不再固定 1200。
     1920px 螢幕上原本左右各空 360px（37.5% 畫面沒用到）。
     92vw 讓兩側維持 4% 的呼吸。
     ★ 2026-08-30：上限 1560 → **1160**。
       理由不是「窄比較好看」，是閱讀欄收到 640px 之後，
       1560 的容器讓置中的閱讀欄兩側各空 460px，看起來像沒做完。
       1160 讓 640 閱讀欄與容器比約 0.55，置中時站得住。
       ⚠️ 不直接照抄 DB `spatial_personality` 的 960-1080——
         那一段沒有做 v1.3 遷移（仍寫「深色」「丹寧黃」），是 v1.2 的規格。
       ⚠️ **容器層改動要在上線前一次做完**：習慣由情境線索觸發，
         版面位置一旦被讀者的程序記憶記住，之後每改一次都在扣習慣
         （Fournier 2022 情境穩定性 d=1.33；Garaialde 2020 習慣被打斷績效優勢完全消失）。 */
  --wrap: min(1160px, 92vw);

  /* 閱讀欄：720px → 720/16 = 45字/行，符合 B4 下限 */
  /* 640px ÷ 16px = 40 全形字/行 —— WCAG 1.4.8「40 if CJK」與 W3C JLREQ 的橫組上限。
     ⚠️ 原本是 720px，註解寫「B4：45-75 字/行」＝45 字，但那個 45-75 是
        Bringhurst 給**拉丁字符**的 CPL 被誤套到全形字上，整段都在上限之上。 */
  --read-col: min(640px, 92vw);
}

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box }
html { scroll-behavior: smooth }
body {
  background: var(--bg-0);
  color: var(--text);
  font-family: var(--sans);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden; font-size: 16px}
.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 40px; position: relative }
a { color: inherit; text-decoration: none }
.mono { font-family: var(--mono) }

/* ===== ANIMATIONS ===== */
.reveal { opacity: 1; transform: none }
.reveal.js-anim { opacity: 0; transform: translateY(16px); transition: opacity .6s ease, transform .6s ease }
.reveal.js-anim.in { opacity: 1; transform: none }

@keyframes breathe { 0%,100% { opacity: .45 } 50% { opacity: .9 } }
@keyframes eq { 0%,100% { height: 28% } 50% { height: 100% } }
@keyframes strikein { from { transform: scaleX(0) } to { transform: scaleX(1) } }

/* 左側細豎導軌（鋼藍色，取代深色版的金光導軌）*/
.rail {
  position: fixed;
  left: max(20px, calc((100vw - var(--wrap)) / 2 + 24px));
  top: 0; bottom: 0; width: 1px;
  background: repeating-linear-gradient(180deg, rgba(20,71,107,.35) 0 3px, transparent 3px 16px);
  z-index: 3; pointer-events: none;
  animation: breathe 5s ease-in-out infinite;
}
@media (max-width: 980px) { .rail { display: none } }

/* ===== NAV =====
   版面一律用 class 定位，不用裸元素選擇器。原因：內頁的頁內導覽區塊
   （延伸術語、回到主題軸）語意上也是 nav 元素，裸的 nav 選擇器會把它們
   一起變成固定在頂端的橫條，直接蓋掉真正的站台導覽——實測發生過。
   footer 同理，所以是 .site-footer 不是 footer。
   註：本段刻意不寫尖括號版的標籤名。產生器用正規式從本檔抽區塊，
   註解裡出現假標籤會讓它從這裡開始抓，把整段 CSS 灌進每一頁。 */
.site-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  backdrop-filter: blur(10px);
  background: rgba(255,255,255,.88);
  border-bottom: 1px solid var(--line-c);
}
.site-header .wrap { position: relative; display: flex; align-items: center; justify-content: space-between; height: 64px }
/* ═══ 品牌 lockup ═══
   .mb-mark 是消波塊標記，描圖自品牌既有橫式 logo（automation-scripts/trace-logo.py）。
   吃 currentColor，所以深底淺底共用同一份路徑。
   內部稜線 .mb-facet 在 20px 以下關掉——細節糊掉只會變髒。 */
.brand { display: inline-flex; align-items: center; gap: .62em;
         font-weight: 900; letter-spacing: .04em; font-size: 17px; color: var(--ink) }
.brand .mk { color: var(--blue) }
/* 標記用主重點藍：品牌既有 logo 本來就是藍的，這個色盤下不需要再改成單色。
   稜線是白色描邊，在深藍實心上讀得出三個面。 */
.mb-mark { width: 1.72em; height: 1.72em; flex: none; color: var(--blue) }
.mb-mark svg { display: block; width: 100%; height: 100% }
@media (max-width: 480px) { .mb-mark .mb-facet { display: none } }
.navlinks { display: flex; align-items: center; gap: 26px; font-size: 14px; color: var(--muted) }
.navlinks > a:hover { color: var(--ink) }
.has-sub { position: relative; cursor: default }
.has-sub > span { display: inline-flex; align-items: center; gap: 4px }
.has-sub > span::after { content: "▾"; font-size: 10px; color: var(--sub) }
.has-sub .sub {
  position: absolute; top: calc(100% + 10px); left: 50%;
  transform: translateX(-50%) translateY(6px);
  background: var(--bg-0);
  border: 1px solid var(--line-c);
  border-radius: 10px; padding: 10px; display: flex; gap: 4px;
  opacity: 0; visibility: hidden; transition: .2s;
  box-shadow: 0 8px 32px rgba(0,0,0,.10);
}
.has-sub:hover .sub { opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0) }
.has-sub .sub a { padding: 10px 16px; border-radius: 7px; text-align: center; transition: background .2s }
.has-sub .sub a:hover { background: var(--blue-wash) }
.has-sub .sub .ch { display: block; font-size: 20px; font-weight: 900; color: var(--blue); line-height: 1 }
.has-sub .sub .en { display: block; font-family: var(--mono); font-size: 9px; letter-spacing: .1em; color: var(--sub); margin-top: 5px }
.nav-cta {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--blue); color: #ffffff;
  padding: 8px 16px; border-radius: 7px;
  font-weight: 700; font-size: 13px;
  transition: transform .2s;
}
.nav-cta:hover { transform: translateY(-1px) }




/* ═══ 手機導覽 ═══
   原本 760px 以下直接 `.navlinks { display:none }`，等於手機使用者沒有導覽——
   那不是響應式，是把功能砍掉。改成漢堡開合的抽屜。
   用 aria-expanded / aria-controls 讓螢幕閱讀器知道狀態，
   按鈕本身是 <button> 不是 <div>，鍵盤 Tab 得到、Enter/Space 可觸發。 */
.nav-toggle {
  display: none; background: none; border: 0; cursor: pointer;
  width: 44px; height: 44px;                 /* 44px 是觸控目標下限 */
  padding: 10px; margin-right: -10px;
  flex-direction: column; justify-content: space-between;
}
.nav-toggle-bar {
  display: block; height: 2px; width: 100%; background: var(--ink);
  border-radius: 2px; transition: transform .25s ease, opacity .2s ease;
}
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) { transform: translateY(9px) rotate(45deg) }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) { opacity: 0 }
.nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) { transform: translateY(-9px) rotate(-45deg) }

@media (max-width: 760px) {
  .nav-toggle { display: flex }
  .navlinks {
    display: block;                          /* 不再 none —— 改用高度收合 */
    position: absolute; left: 0; right: 0; top: 100%;
    background: rgba(255,255,255,.98);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--line-c);
    padding: 0 20px;
    max-height: 0; overflow: hidden;
    transition: max-height .3s ease, padding .3s ease;
    box-shadow: 0 12px 28px rgba(0,0,0,.08);
  }
  .navlinks[data-open="true"] { max-height: 80vh; overflow-y: auto; padding: 8px 20px 20px }
  .navlinks > a, .has-sub > span {
    display: block; padding: 14px 0; font-size: 16px;
    border-bottom: 1px solid var(--line-c);
  }
  /* 手機不做 hover 下拉，五軸直接攤開 */
  .has-sub .sub {
    position: static; transform: none; opacity: 1; visibility: visible;
    box-shadow: none; border: 0; padding: 8px 0 12px;
    /* 五軸在窄螢幕會溢出（實測 390px 時第五個「堤」被切掉），
       改成自動換行：容得下就排一列，容不下就折行。 */
    display: grid; grid-template-columns: repeat(auto-fit, minmax(58px, 1fr)); gap: 4px;
    background: transparent;
  }
  .has-sub > span::after { content: "" }
  .has-sub .sub .ch { font-size: 17px }
  .has-sub .sub .en { font-size: 7px; letter-spacing: .06em }
  .has-sub .sub a { padding: 8px 4px }
  .nav-cta { display: block; text-align: center; margin: 14px 0 4px; padding: 13px 16px }
}

/* ═══ 影像帶 ═══
   白底站要有 v6 那種攝影份量，靠的不是「每頁都鋪照片」，
   而是在白色之間插入全幅的深色影像帶——雜誌式的中斷，重量來自對比。
   只用在首頁；內頁維持輕。 */
.mb-band { margin: 0; width: 100%; overflow: hidden; line-height: 0; position: relative }
.mb-band img { width: 100%; height: clamp(150px, 22vw, 230px); object-fit: cover; display: block }
/* 淺色帶不需要白色羽化去救硬切——它本來就跟白底同一個明度家族。
   只在下緣做極短的淡出，把影像接進下一段的 bg-1。 */
.mb-band::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, transparent 78%, rgba(244,247,250,.85) 100%);
}
@media (prefers-reduced-motion: no-preference) {
  .mb-band img { transition: transform 1.2s ease }
}

/* ===== 分節線 ===== */
.section-rule { width: 100%; height: 1px; background: var(--line-c); display: block; border: none; margin: 0 }
.accent-seam {
  width: 100%; height: 1px; display: block; border: none; margin: 0;
  background: linear-gradient(90deg, transparent 0%, rgba(20,71,107,.4) 20%, rgba(20,71,107,.55) 50%, rgba(20,71,107,.4) 80%, transparent 100%);
}

/* ===== 共用 mag-label =====
   ⚠️⚠️ **這個元件自帶 margin-bottom，拿去當「行內標籤」用時外距會跟著來。**
   它本來是**區塊標題**（標題在上、內容在下，所以需要下外距）。
   已知踩過一次：`.na-meta` 把它當行內標籤，那個 18px 外距讓它比同一行的日期高 9px
   —— 因為 `align-items: center` 對齊的是**外距框**不是內容框（20.4+18=38.4，置中後內容被推到頂端）。
   修法是在該情境覆寫 `margin-bottom: 0`（見 build-template-pages.py 的 .na-meta .mag-label）。

   ★ 為什麼不把外距移到父層 gap（2026-08-31 盤點後的決定）：
     全站實測 **847 次使用、829 次（98%）是標準區塊標題**，那個外距是對的。
     移到父層等於要在 829 個正確的呼叫點補回間距，為了修一個已經修好的案例。
     「元件不該自帶外距」（Max Stoiber / Kyle Shevlin）在原則上成立，
     但**這個元件的證據不支持重構**——1 個反例 vs 829 個正例。
     ⚠️ 若之後行內用法**超過 3 處**，就該做成 `.mag-label--inline` 變體，
       讓行內情境明確 opt-in，而不是每次靠情境覆寫。那時再回來改。 */
.mag-label { display: flex; align-items: center; gap: 10px; margin-bottom: 18px }
/* 這是區塊標題（h2），視覺上刻意做成小標籤——語意與外觀分離：
   語意上它必須是 h2（文件大綱、螢幕閱讀器、SEO），外觀上它是等寬小字。 */
.mag-label-text { font-family: var(--mono); font-size: 12px; font-weight: 500; letter-spacing: .36em; color: var(--blue); text-transform: uppercase }
.mag-label-text::before { content: "▪ " }
.mag-label-rule { flex: 1; height: 1px; background: var(--line-c); max-width: 180px }

/* ===== 共用頁首標題（.ax-title / .ax-desc） =====
   首頁自己不用這兩條，放這裡是因為它們被軸頁、podcast 列表、單集頁、
   早期單集封存至少四處使用。原本各自抄一份，結果：
   ① 早期單集封存那份根本沒抄到，H1 掉回主題預設 50.4px/w700
      （全站級距裡沒有這個值，而 measure-design.js 只量 p/li 讀不到）
   ② 抄過的兩份已經漂移——.ax-desc 上限一邊 17px 一邊 18px。
   ★ 被三個以上的 block 用到就該進共用層，不該手抄（design.md §3）。 */
.ax-title { font-size: clamp(21px,3vw,36px); font-weight: 900; color: var(--ink); line-height: 1.35 }

/* ★ display 字族的套用範圍（2026-08-30）。
   只給「大到看得出筆形」的標題：h1 級、五軸展示字、人名。
   ⚠️ **不套 h2/h3**：21px 以下筆形差異肉眼幾乎看不出來，
     卻要付一次字型切換的代價（FOUT 與額外解碼）。
     DB 的 `pairing_logic` 要的是**層級對比**，對比在最大的那一層就成立，
     不需要每一層都換字族。
   ⚠️ 裸 `h1` 選擇器（0,0,1）刻意用低特異性：各產生器的
     `.na-h1`/`.st-h1`/`.gl-h1`… 只設 font-size 與 font-weight，
     不設 font-family，所以不會衝突，也不必逐檔改 10 支產生器。 */
h1, .ax-title, .scol .ch, .who-name { font-family: var(--display) }
.ax-desc { font-size: clamp(14px,1.4vw,17px); color: var(--body); margin-top: 12px; max-width: 40em }
/* 以下 8 條原本寫在下方「全幅意境首屏」與「CTA 列」區段裡，
   但 about／axis／podcast 等內頁的 hero 與按鈕都會用到，
   因此原樣搬到全站層。宣告內容未變，也沒有其他規則覆寫它們。 */
.hero-photo { position: absolute; inset: 0; z-index: 0 }
.hero-photo img { width: 100%; height: 100%; object-fit: cover; display: block }
/* 只做「白霧」不做「黑幕」：底部淡出到白，讓深色字有安定的落腳處，
   同時把影像下緣接進下一段的白底，接縫消失。 */
.hero-photo::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(255,255,255,.10) 0%, rgba(255,255,255,.34) 46%,
                              rgba(255,255,255,.80) 82%, #ffffff 100%);
}
/* 晨光紋理：極淺冷灰對角漸層，取代照片 */
.hero-bg {
  position: absolute; inset: 0; z-index: 0;
  background:
    radial-gradient(ellipse 70% 55% at 80% 30%, rgba(46,114,146,.07), transparent 65%),
    radial-gradient(ellipse 40% 40% at 15% 80%, rgba(20,71,107,.04), transparent 60%),
    linear-gradient(160deg, var(--bg-1) 0%, #eef3f9 50%, var(--bg-2) 100%);
}
/* ⚠️ inline-flex 一定要配 align-items / justify-content。
   少了它們，flex 容器預設 justify-content: flex-start——但按鈕平常會縮到
   內容寬度，flex-start 看起來剛好等於置中，所以這個缺陷一直沒被發現。
   一旦按鈕被拉寬（表單裡與輸入框並排、或外層給了 width），文字就會靠左。
   是在訂閱表單上才顯出來的，但問題一直在共用層，不是那一頁的。 */
.btn {
  padding: 12px 22px; font-weight: 700; font-size: 16px;
  display: inline-flex; align-items: center; justify-content: center;
  gap: 7px; border-radius: 6px; transition: transform .2s;
}
.btn-primary { background: var(--blue); color: #ffffff }
.btn-ghost {
  border: 1px solid var(--line-c); color: var(--muted);
  background: transparent;
}
.btn:hover { transform: translateY(-2px) }
/* ===== FOOTER ===== */
/* 與 subscribe 同底色（讓頁尾整塊成為高峰的重量），靠一條明確的分隔線劃界 */
.site-footer { background: var(--bg-2); border-top: 1px solid rgba(20,71,107,.22) }
.foot-cta { border-bottom: 1px solid var(--line-c); padding: 44px 0 }
.foot-cta .wrap { display: flex; align-items: center; justify-content: space-between; gap: 30px; flex-wrap: wrap }
/* ⚠️ 2026-08-28：這一列有**三個**子元素，不是兩個——`.say`、`.foot-form`，
      以及訂閱後才有字的狀態訊息 `.mb-sub-msg`。
      `space-between` 是在三者之間分配，於是 1440px 實測：
      `.say` 在 436px 結束、表單 742px 才開始，中間空了 306px，
      而 `.mb-sub-msg` 被擠成貼在右邊緣的**零寬欄**。
      畫面上看起來是「文字在左、表單浮在中間、右邊一大塊空白」。
      更糟的是它是潛伏的：訊息平常沒字，等真的訂閱成功才會塞進零寬容器。
   ★ 修法：狀態訊息強制換行佔滿整列（它本來就該在表單底下），
      `.say` 給可伸縮基準，表單才會靠右對齊。 */
.foot-cta .say { flex: 1 1 320px; min-width: 0 }
.foot-cta .mb-sub-msg { flex: 1 0 100%; margin-top: 4px }
/* 下限 20px：藍色字在 bg-2 上是 8.38:1（暖色版是 3.95:1，換深藍後餘裕大增），必須穩穩落在 WCAG「大字」(≥18.66px 粗體) 這側 */
.foot-cta h3 { font-size: clamp(20px, 2.2vw, 26px); font-weight: 900; color: var(--ink) }
.foot-cta h3 .g { color: var(--blue) }
.foot-cta p { color: var(--muted); font-size: 16px; margin-top: 6px; line-height: 1.72 }
.foot-form { display: flex; gap: 10px; flex: 0 0 auto }
.foot-form input {
  background: var(--bg-0); border: 1px solid var(--line-c);
  border-radius: 7px; padding: 12px 16px;
  color: var(--text); font-family: var(--sans); font-size: 14px;
  min-width: 220px; outline: none;
}
.foot-form input::placeholder { color: var(--sub) }
.foot-form input:focus { border-color: rgba(20,71,107,.5) }
/* 同 .sub-form：outline:none 之後要自己補回鍵盤焦點環，
   單靠邊框換色不足以當焦點指示。頁尾表單每一頁都有，所以這條影響全站。 */
.foot-form input:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; border-color: var(--blue) }
.foot-form button {
  background: var(--blue); color: #ffffff; border: none;
  border-radius: 7px; padding: 0 18px; font-weight: 700; font-size: 14px;
  cursor: pointer; font-family: var(--sans);
}
.foot-main {
  /* SC-ICG 2026-09-12：原本是 padding: 52px 0 40px，shorthand 會把 .wrap 的
     左右 40px 一起歸零，導致 footer 主區塊比頁面其他內容往左凸出 40px。
     改用 padding-block 只設上下，保留 .wrap 的水平內距。 */
  padding-block: 52px 40px;
  display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.1fr; gap: 40px;
}
.fcol h4 {
  font-family: var(--mono); font-size: 12px; letter-spacing: .2em;
  color: var(--sub); text-transform: uppercase; margin-bottom: 16px;
}
.fcol a { display: block; color: var(--muted); font-size: 14px; padding: 5px 0; line-height: 1.5 }
.fcol a:hover { color: var(--blue) }
/* 必須是 flex：.mb-mark 若留在 display:inline，寬高設定不生效，SVG 會撐到預設尺寸 */
.foot-brand .fb-logo { display: inline-flex; align-items: center; gap: .62em;
                       font-weight: 900; font-size: 17px; margin-bottom: 10px; color: var(--ink) }
.foot-brand .fb-logo .mk { color: var(--blue) }
/* 13px 不在全站音階（12/14/16/18）上，收到 14px。 */
.foot-brand p { color: var(--sub); font-size: 14px; line-height: 1.65; margin-bottom: 16px }
.foot-social { display: flex; flex-wrap: wrap; gap: 7px }
.foot-social a {
  font-family: var(--mono); font-size: 12px; letter-spacing: .04em;
  color: var(--muted); border: 1px solid var(--line-c);
  border-radius: 20px; padding: 5px 10px;
}
.foot-social a:hover { color: var(--blue); border-color: rgba(20,71,107,.4) }
.fcol .glos a::before { content: "› "; color: var(--blue) }
.fcol .glos a.all { color: var(--ink); font-weight: 700 }
.fcol .glos a.all::before { content: "" }
.foot-legal { border-top: 1px solid var(--line-c); padding: 20px 0 }
.foot-legal .wrap {
  display: flex; justify-content: space-between; align-items: center;
  flex-wrap: wrap; gap: 10px;
  font-family: var(--mono); font-size: 12px; color: var(--sub); letter-spacing: .03em;
}
.foot-legal .lk { display: flex; gap: 16px }
.foot-legal .lk a:hover { color: var(--muted) }

/* ===== RWD ===== */
@media (max-width: 960px) {
  .sgrid { grid-template-columns: repeat(3, 1fr) }
  .who-grid { grid-template-columns: 1fr; gap: 36px }
  .portrait-card { max-width: 320px }
  .portrait-coords { display: none }
  .foot-main { grid-template-columns: 1fr 1fr }
  .foot-cta .wrap { flex-direction: column; align-items: flex-start }
  /* ★★ flex-basis 量的是**主軸**：row 時是寬度、column 時是高度。
     桌機那條 `.foot-cta .say { flex: 1 1 320px }` 是為了不讓文字欄塌陷（＝最小寬度），
     但這裡把方向翻成 column 之後，同一個 320px 變成**最小高度**——
     實測 .say 內容只有 64px 卻被撐成 320px，多出 250px 的死白，
     畫面上是「標題和訂閱框中間空一大塊」。
     ⚠️ 這種錯 L1 閘門抓不到：字級、對比、行長全部正常，壞的是空間。
     只有實際看畫面或量元素高度才會發現。 */
  .foot-cta .say { flex: 0 0 auto }
}
@media (max-width: 760px) {
  .wrap { padding: 0 20px }
  .sgrid { grid-template-columns: 1fr; border-left: none }
  .scol { border-right: none; border-top: 1px solid var(--line-c) }
  .ep { grid-template-columns: 70px 1fr 36px }
  .foot-main { grid-template-columns: 1fr }
  .foot-form input { min-width: 0; flex: 1 }
  .news-item { grid-template-columns: 76px 1fr; }
  .news-src { display: none }
  .who-grid { grid-template-columns: 1fr }
}

/* ═══ 訂閱表單的共用件（首頁 / 頁尾 / 訂閱頁三處共用）═══ */

/* 蜜罐。⚠️ 不能用 display:none 或 visibility:hidden——
   部分機器人會跳過明顯隱藏的欄位，密碼管理器反而可能去填它。
   移出畫面才是對真人不可見、對解析 HTML 的機器人可見。
   配合 aria-hidden 與 tabindex=-1，螢幕閱讀器與鍵盤都碰不到。 */
.mb-sub-hp-wrap {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden;
}

/* 狀態訊息。原本先佔住高度，理由是「從無到有會把下方內容往下推，
   使用者按下訂閱的瞬間畫面跳一下，那正是最需要穩定感的時刻」。
   ⚠️ 2026-08-29 推翻該決定，改成空的時候收合。把成本攤開來看：
     空白被看到＝每篇文章每次載入 100%（實測手機版佔 36.6px，
     訂閱鈕下方明顯比上方空一截，上 26px 下 63px）；
     位移會發生＝只有真的按下訂閱的人，不到 1%，而且發生在視線下方。
   ★ 另外 CLS **不計入使用者互動後 500ms 內的位移**，
     這個跳動本來就不會被扣分——為它預留的是一個不會被計分的問題。
   要回退的話把 :empty 那條刪掉即可。 */
.mb-sub-msg {
  min-height: 1.9em; margin-top: 10px;
  font-size: 14px; line-height: 1.7; color: var(--body);
}
.mb-sub-msg:empty { min-height: 0; margin-top: 0 }
.mb-sub-msg[data-state="invalid"],
.mb-sub-msg[data-state="error"],
.mb-sub-msg[data-state="rate_limited"],
.mb-sub-msg[data-state="unconfigured"] { color: var(--sub) }
.mb-sub-msg[data-state="ok"],
.mb-sub-msg[data-state="already"] { color: var(--ink); font-weight: 700 }

.mb-subscribe button[disabled] { opacity: .55; cursor: default }
/* ═══ 主題 chips ═══
   沿用 .news-src 既有的 chip 語彙（mono / 1px line-c / 小字距），只放大成可點擊尺寸。
   用 wrap 不用橫向捲動：捲動會把選項藏在畫面外，而這頁的情緒目標是「穩定的方向感」，
   藏起來的方向感不算方向感。

   ⚠️ 放在全站層而不是 #daily-briefing 段落裡：hub 頁與 /news/ 列表也要用同一組 chip。
      放段落層的話 site_css() 抽不到，內頁會拿到孤兒的手機覆寫卻沒有基礎規則——
      畫面不會報錯，只會長得不對。
   ⚠️ 必須排在本區 @media 之前：同權重下後者勝，順序反了手機覆寫就永遠不生效。 */
/* 下外距 26→18：同樣是還首屏預算給清單，見 .briefing-header 的說明。 */
.topic-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: -6px 0 18px }
/* ★ 2026-08-29：11px → 12px，標記層的硬底線。原本 11px 夾在 .news-src 的 10
   與 .news-date 的 12 之間，三級只差 1.09-1.10×，讀者分辨不出是三種東西。 */
/* ★ border-radius 999px → 4px（2026-08-30）。
   DB `component_vocabulary.avoids` 明列「**漂浮藥丸標籤**」，
   而 `form.gravity_center` 是「直線為主……用微圓角（4-8px）軟化邊緣」。
   DB 的原則寫得很好：「**選元件＝問世界，不問潮流**」——
   藥丸標籤是別的世界的詞彙，不是破曉海岸這個世界的。
   ⚠️ 這一項純屬品牌詞彙，外部研究對圓角形狀無任何實證。品牌有最終權威。 */
.topic-chip {
  font-family: var(--mono); font-size: 12px; letter-spacing: .06em;
  color: var(--sub); border: 1px solid var(--line-c); border-radius: 4px;
  padding: 5px 12px; white-space: nowrap;
  transition: color .15s, border-color .15s, background .15s;
}
.topic-chip:hover { color: var(--blue); border-color: rgba(20,71,107,.4); background: var(--bg-1) }
.topic-chip[aria-current="page"] { color: #fff; background: var(--blue); border-color: var(--blue) }

/* ═══ 手機版 footer 壓縮 ═══
   實測手機上 footer 高 1,208px、佔全頁 17.3%，24 個連結四欄直向堆疊。
   頁尾不是內容，是索引——它不該吃掉六分之一的捲動距離。
   改成兩欄並排（高度砍半），並壓縮上下留白與行距。 */
@media (max-width: 760px) {
  .foot-main { grid-template-columns: 1fr 1fr; gap: 22px 18px; padding: 34px 0 26px }
  .foot-brand { grid-column: 1 / -1 }          /* 品牌區仍佔滿一整列 */
  /* ★ 手機的覆寫比桌機更小，是全站最容易被漏掉的一層：
     桌機看起來已經修好，手機還留著 10px／11px／13px。
     ⚠️ 改字級時 @media 區塊要一起看，它會**蓋掉**上面剛調好的值。 */
  .fcol h4 { margin-bottom: 10px; font-size: 12px }
  .fcol a { padding: 6px 0; font-size: 14px }
  .foot-brand p { font-size: 14px; margin-bottom: 12px }
  .foot-social { gap: 6px }
  .foot-social a { padding: 5px 9px; font-size: 12px }
  .foot-cta { padding: 26px 0 }
  .foot-legal { padding: 14px 0; font-size: 12px }
  .foot-legal .wrap { flex-direction: column; align-items: flex-start; gap: 8px }
  /* 第三欄（知識資源）在兩欄格線裡會落單成第三列。
     讓它橫跨整列並把連結改成橫排標籤，五個詞收進兩行而不是五行。 */
  .foot-main .fcol:last-child { grid-column: 1 / -1 }
  .foot-main .fcol:last-child > a {
    display: inline-block; padding: 5px 10px; margin: 0 6px 6px 0;
    border: 1px solid var(--line-c); border-radius: 999px; font-size: 12px;
  }

  /* 9 個 chip 在 360px 會排到三列，壓掉播報清單的位置。收緊到兩列。 */
  .topic-chips { gap: 6px; margin-bottom: 20px }
  .topic-chip { font-size: 10px; padding: 4px 10px; letter-spacing: .04em }
}
