/* ==========================================================================
   台灣航線全覽 — 視覺系統
   配色與 skyfaring.net 一致（Tailwind slate + sky）。方向是財經資料刊物的數據頁：
   克制、數字優先、髮絲線分隔，不做卡片陰影與漸層。

   只允許兩套刻度：
     字級  --fs-12 13 15 18 24 32 48
     間距  --sp-8 16 24 32 48 64 96
   強調色只有一個：sky（淺色 #0284c7、深色 #38bdf8）。正負變化用同色相深淺 ＋ 正負號。
   深色模式：系統偏好為預設，:root[data-theme] 可手動覆寫。
   ========================================================================== */

:root {
  /* ---- 字級刻度（只有這七級）---- */
  --fs-12: 12px;
  --fs-13: 13px;
  --fs-15: 15px;
  --fs-18: 18px;
  --fs-24: 24px;
  --fs-32: 32px;
  --fs-48: 48px;

  /* ---- 間距刻度（8 的倍數）---- */
  --sp-8: 8px;
  --sp-16: 16px;
  --sp-24: 24px;
  --sp-32: 32px;
  --sp-48: 48px;
  --sp-64: 64px;
  --sp-96: 96px;

  /* ---- 版面 ---- */
  --w-text: 880px;
  --w-wide: 1040px;
  --row-h: 44px;          /* 表格列高，同時是觸控區最小高度 */
  --tap: 44px;            /* 觸控目標最小高度 */
  --hero-h: 240px;
  --radius-0: 0;          /* 預設不用圓角 */
  --radius-2: 2px;        /* 極小圓角，只用在色塊 */
  --radius-full: 50%;     /* 只有導覽列的圓形站徽用 */
  --hair: 1px;            /* 髮絲線 */
  --line-strong: 1.5px;   /* 折線 */
  --chart-min: 560px;     /* 圖表在手機上的最小可讀寬度，超過就橫向捲動 */

  /* ---- 色票（slate + sky，淺色）---- */
  --paper: #f8fafc;      /* slate-50 背景 */
  --surface: #ffffff;    /* 表格底 */
  --paper-2: #f8fafc;    /* hover 列 */
  --ink: #0f172a;        /* slate-900 主文字 */
  --ink-2: #475569;      /* slate-600 次要文字 */
  --ink-3: #64748b;      /* slate-500 標籤、單位 */
  --ink-4: #94a3b8;      /* slate-400 弱化文字 */
  --rule: #e2e8f0;       /* slate-200 髮絲線 */
  --rule-2: #e2e8f0;
  --accent: #0284c7;     /* sky-600 連結與強調 */
  --accent-2: #0369a1;   /* sky-700 */
  --accent-soft: #f0f9ff;/* sky-50 強調淡底 */
  --thead-rule: #7dd3fc; /* sky-300 表頭底線 */
  --delta-up: var(--accent);
  --delta-down: color-mix(in srgb, var(--accent) 45%, var(--ink-3));
  --chart-bar: color-mix(in srgb, var(--ink) 15%, transparent);
  --hero-bg: #0f172a;
  --hero-bg-2: #1e3a5f;
  --hero-scrim: color-mix(in srgb, #0f172a 40%, transparent);
  color-scheme: light;
}

/* 系統偏好為預設 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #0f172a;      /* slate-900 */
    --surface: #1e293b;    /* slate-800 */
    --paper-2: #1e293b;
    --ink: #f1f5f9;        /* slate-100 */
    --ink-2: #cbd5e1;      /* slate-300 */
    --ink-3: #94a3b8;      /* slate-400 */
    --ink-4: #64748b;      /* slate-500 */
    --rule: #334155;       /* slate-700 */
    --rule-2: #334155;
    --accent: #38bdf8;     /* sky-400 */
    --accent-2: #7dd3fc;   /* sky-300 */
    --accent-soft: #1e293b;
    --thead-rule: #0369a1; /* sky-700 */
    --delta-up: var(--accent);
    --delta-down: color-mix(in srgb, var(--accent) 45%, var(--ink-3));
    --chart-bar: color-mix(in srgb, var(--ink) 15%, transparent);
    color-scheme: dark;
  }
}

/* 手動覆寫：導覽列的月亮／太陽鈕寫 data-theme */
:root[data-theme="dark"] {
  --paper: #0f172a;
  --surface: #1e293b;
  --paper-2: #1e293b;
  --ink: #f1f5f9;
  --ink-2: #cbd5e1;
  --ink-3: #94a3b8;
  --ink-4: #64748b;
  --rule: #334155;
  --rule-2: #334155;
  --accent: #38bdf8;
  --accent-2: #7dd3fc;
  --accent-soft: #1e293b;
  --thead-rule: #0369a1;
  --delta-up: var(--accent);
  --delta-down: color-mix(in srgb, var(--accent) 45%, var(--ink-3));
  --chart-bar: color-mix(in srgb, var(--ink) 15%, transparent);
  color-scheme: dark;
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }
html, body { overflow-x: clip; }   /* 寬表格與圖表各自在容器內捲，整頁不橫向捲 */

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", system-ui, sans-serif;
  font-size: var(--fs-15);
  line-height: 1.5;
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

.wrap { width: 100%; max-width: var(--w-text); margin: 0 auto; padding: 0 var(--sp-24); }
.wrap-wide { max-width: var(--w-wide); }

/* ---------- 連結：文字底線，不做按鈕 ---------- */
a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: var(--rule);
}
a:hover { color: var(--accent); text-decoration-color: currentColor; }
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--ink); color: var(--paper);
  padding: var(--sp-8) var(--sp-16); z-index: 20; text-decoration: none;
}
.skip:focus { left: 0; }
.vh {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* ---------- 標題：襯線 ---------- */
h1, h2, h3, h4 {
  font-family: inherit;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-wrap: balance;          /* 不支援的瀏覽器就照一般換行 */
}
p, li, figcaption { text-wrap: pretty; }
/* 數字與單位絕不分家 */
.nw { white-space: nowrap; }
h1 { font-size: var(--fs-32); line-height: 1.25; margin: 0 0 var(--sp-16); }
h2 { font-size: var(--fs-24); line-height: 1.3; margin: var(--sp-48) 0 var(--sp-16); }
h3 { font-size: var(--fs-18); line-height: 1.4; margin: var(--sp-32) 0 var(--sp-8); }
p { margin: 0 0 var(--sp-16); max-width: 68ch; }

/* 眉標：小字、字距放開 */
.eyebrow {
  font-family: "Noto Sans TC", sans-serif;
  font-size: var(--fs-12);
  letter-spacing: 0.04em;
  color: var(--ink-3);
  margin: 0 0 var(--sp-8);
  text-transform: none;
}
.eyebrow a { text-decoration-color: transparent; }
.standfirst {
  font-size: var(--fs-18); line-height: 1.5; color: var(--ink-2);
  margin-bottom: var(--sp-24); text-wrap: pretty; max-width: 60ch;
}
.note { font-size: var(--fs-13); color: var(--ink-3); margin: var(--sp-8) 0 var(--sp-16); }
.muted { color: var(--ink-3); }
.tnum { font-variant-numeric: tabular-nums; }

/* ---------- 頁首 ---------- */
.site-head { border-bottom: 1px solid var(--rule); }
.head-inner {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--sp-8) var(--sp-24);
  padding-top: var(--sp-16); padding-bottom: var(--sp-16);
}
.brand {
  font-weight: 700; font-size: var(--fs-18); text-decoration: none;
  letter-spacing: -0.01em; display: inline-flex; align-items: center;
  gap: var(--sp-8); white-space: nowrap; flex: 0 0 auto;
}
.brandmark {   /* 左邊的圓形小圖示，跟 skyfaring 同構 */
  width: 32px; height: 32px; flex: 0 0 32px; border-radius: 50%;
  background: var(--accent); color: #ffffff;
  display: inline-flex; align-items: center; justify-content: center;
}
.brandmark .ico { color: currentColor; }
.site-head nav { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-16); }
.site-head nav a {
  font-size: var(--fs-13); color: var(--ink-2);
  text-decoration: none; display: inline-flex; align-items: center; gap: var(--sp-8);
}
.site-head nav a:hover { color: var(--accent); }
.ico { flex: 0 0 auto; color: var(--ink-3); vertical-align: -0.18em; }
a:hover > .ico, button:hover > .ico { color: inherit; }

/* 「我是…」下拉：原生 details，沒有 JS 也能開 */
.rolemenu { position: relative; }
.rolemenu > summary {
  list-style: none; cursor: pointer; font-size: var(--fs-13); color: var(--ink-2);
  display: inline-flex; align-items: center; gap: var(--sp-8);
}
.rolemenu > summary::-webkit-details-marker { display: none; }
.rolemenu > summary:hover { color: var(--accent); }
.rolemenu[open] > summary { color: var(--accent); }
.rolemenu ul {
  position: absolute; z-index: 10; right: 0; top: calc(100% + var(--sp-8));
  margin: 0; padding: var(--sp-8) 0; list-style: none; min-width: 210px;
  background: var(--surface); border: 1px solid var(--rule);
}
.rolemenu li a {
  display: flex; align-items: center; gap: var(--sp-8);
  padding: var(--sp-8) var(--sp-16); font-size: var(--fs-13);
}
.rolemenu li a:hover { background: var(--accent-soft); color: var(--accent); }

/* ---------- 麵包屑 ---------- */
.crumbs {
  font-size: var(--fs-12); color: var(--ink-3);
  padding-top: var(--sp-16); letter-spacing: 0.04em;
}
.crumbs a { text-decoration-color: transparent; }
.crumbs a:hover { text-decoration-color: currentColor; }
.crumbs span[aria-hidden] { margin: 0 var(--sp-8); }

/* `.wrap { padding: 0 24px }` 是 shorthand 且權重比 `main` 高，v1～v4 的
   `main { padding-top: … }` 其實從來沒有生效過（實測 computed 是 0px），
   首頁角色區才會整個貼在 hero 底邊上（使用者 2026-09-16 回報的 A 項）。
   選擇器補成 main.wrap 才蓋得過去。上緣的留白由各區塊自己負責，
   這裡只把內容與頁尾之間該有的空白補回來。 */
main.wrap { padding-bottom: var(--sp-32); }

/* ---------- 數字列：髮絲線分隔的四欄，不是卡片 ---------- */
.stats {
  list-style: none; margin: var(--sp-24) 0 var(--sp-32); padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--ink);
}
.stats > li {
  padding: var(--sp-16) var(--sp-16) var(--sp-16) 0;
  border-bottom: 1px solid var(--rule);
}
.stats > li + li { border-left: 1px solid var(--rule-2); padding-left: var(--sp-16); }
.stat-h { display: flex; align-items: center; gap: var(--sp-8); margin-bottom: var(--sp-8); }
.stat-k {
  font-size: var(--fs-12); letter-spacing: 0.04em; color: var(--ink-3);
}
.stat-v {
  display: block;
  font-size: var(--fs-48);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}
/* 七位數以上的座位供給（6,251,667）在 48px 下寬 260px，超過欄寬會壓到隔壁欄的
   數字上。降一階到 32px，刻度仍然只用 12/13/15/18/24/32/48。*/
.stat-v-sm { font-size: var(--fs-32); }
.stat-s {
  display: block; margin-top: var(--sp-8);
  font-size: var(--fs-12); letter-spacing: 0.04em; color: var(--ink-3);
}
.stat-lead .stat-v { font-size: var(--fs-48); }
.stat-lead .stat-v-sm { font-size: var(--fs-32); }

/* ---------- 表格 ---------- */
/* 表格在窄螢幕上一定會溢出（欄位就是這麼多）。v1 只有一條 1px 硬邊，看不出
   還有內容；v2 用 mask 做右側漸隱，並把「橫向捲動」四個字畫在容器右上角，
   兩者都只在真的溢出時才出現（.is-scrollable 由 site.js 標記）。 */
.tablewrap {
  position: relative;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  margin: var(--sp-16) 0 var(--sp-32);
  background: var(--surface);
  border-top: 1px solid var(--rule);
}
.tablewrap.is-scrollable {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent 100%);
          mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent 100%);
}
/* 捲到最右邊就不用再淡出了 */
.tablewrap.is-scrollable.at-end {
  -webkit-mask-image: none; mask-image: none;
}
.scrollhint {
  display: none; font-size: var(--fs-12); letter-spacing: 0.04em;
  color: var(--ink-3); text-align: right; margin: 0 0 var(--sp-16);
}
.is-scrollable + .scrollhint, .scrollhint.on { display: block; }
/* 圖表：捲動的是 .chartscroll，figcaption 留在外面不跟著淡出也不跟著捲 */
.chartscroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.chartscroll.is-scrollable {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent 100%);
          mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent 100%);
}
.chartscroll.is-scrollable.at-end {
  -webkit-mask-image: none; mask-image: none;
}

table.data {
  width: 100%; border-collapse: collapse;
  font-size: var(--fs-13); min-width: 640px;
}
table.data caption {
  text-align: left; font-size: var(--fs-12); letter-spacing: 0.04em;
  color: var(--ink-3); padding-bottom: var(--sp-8);
}
table.data thead th {
  font-weight: 500;
  font-size: var(--fs-12); letter-spacing: 0.08em; color: var(--ink-3);
  text-align: left; white-space: nowrap;
  padding: var(--sp-8) var(--sp-16) var(--sp-8) 0;
  border-bottom: 1px solid var(--thead-rule);
  background: transparent;
}
table.data tbody th, table.data tbody td, table.data tfoot th, table.data tfoot td {
  height: var(--row-h);
  padding: 0 var(--sp-16) 0 0;
  border-bottom: 1px solid var(--rule-2);
  text-align: left; white-space: nowrap; vertical-align: middle;
}
table.data tbody th[scope="row"] { font-weight: 400; }
table.data tbody tr:hover { background: var(--accent-soft); }
table.data .num { text-align: right; font-variant-numeric: tabular-nums; }
table.data .key { color: var(--accent); font-weight: 500; }
table.data tfoot th, table.data tfoot td {
  /* 比髮絲線重一階就夠，深色下用 --ink 會在深底上畫一條刺眼的亮白線 */
  border-top: 1px solid var(--ink-3); border-bottom: none;
  font-weight: 500; color: var(--ink);
}
table.data td .sub { display: block; font-size: var(--fs-12); color: var(--ink-3); }
table.data a { text-decoration-color: transparent; }
table.data tr:hover a { text-decoration-color: var(--rule); }

table.sortable thead th[data-sort] { cursor: pointer; }
table.sortable thead th[data-sort]:hover { color: var(--accent); }
table.sortable thead th[data-sort]::after { content: "↕"; margin-left: var(--sp-8); opacity: .35; }
table.sortable thead th[aria-sort="ascending"]::after { content: "↑"; opacity: 1; }
table.sortable thead th[aria-sort="descending"]::after { content: "↓"; opacity: 1; }

.iata { font-size: var(--fs-12); color: var(--ink-3); margin-left: var(--sp-8); letter-spacing: 0.04em; }
.tag {
  font-size: var(--fs-12); letter-spacing: 0.04em; color: var(--ink-3);
  margin-left: var(--sp-8); padding-left: var(--sp-8); border-left: 1px solid var(--rule);
}
.up { color: var(--delta-up); }
.down { color: var(--delta-down); }

/* 展開第二層資訊（入境／出境拆分） */
details.more {
  border-top: 1px solid var(--rule-2); margin: 0 0 var(--sp-32);
}
details.more > summary {
  cursor: pointer; list-style: none; padding: var(--sp-16) 0;
  font-size: var(--fs-13); color: var(--ink-2);
  display: flex; align-items: center; gap: var(--sp-8);
}
details.more > summary::-webkit-details-marker { display: none; }
details.more > summary::before { content: "＋"; color: var(--ink-3); }
details.more[open] > summary::before { content: "−"; }
details.more > summary:hover { color: var(--accent); }
details.more .tablewrap { margin-top: 0; }

/* ---------- 清單 ---------- */
.linklist, .changelist, .ranklist {
  list-style: none; margin: var(--sp-16) 0 var(--sp-32); padding: 0;
  border-top: 1px solid var(--rule);
}
.linklist > li, .changelist > li, .ranklist > li {
  padding: var(--sp-8) 0; border-bottom: 1px solid var(--rule-2);
  display: flex; gap: var(--sp-16); align-items: baseline;
}
.ranklist .rank-n {
  flex: 0 0 76px; text-align: right; font-variant-numeric: tabular-nums;
  font-size: var(--fs-18); font-weight: 600;
}
.ranklist .rank-b { flex: 1 1 auto; }
.ranklist .rank-b .muted, .linklist .muted, .changelist .muted {
  display: block; font-size: var(--fs-12); color: var(--ink-3); letter-spacing: 0.04em;
}
.changelist .mark {
  flex: 0 0 auto; font-size: var(--fs-12); letter-spacing: 0.04em; color: var(--ink-3);
}
.chips { list-style: none; display: flex; flex-wrap: wrap; gap: var(--sp-8) var(--sp-16); padding: 0; margin: var(--sp-16) 0 var(--sp-32); }
.chips li { font-size: var(--fs-13); }
.deflist { margin: 0 0 var(--sp-24); padding-left: var(--sp-16); }
.deflist li { margin-bottom: var(--sp-8); max-width: 68ch; }

/* ---------- 圖表 ---------- */
figure.chartbox { margin: var(--sp-16) 0 var(--sp-32); }
.chart { display: block; width: 100%; height: auto; min-width: 420px; }
.chart-h { min-width: 340px; }
.chart .grid { stroke: var(--rule-2); stroke-width: 1; }
.chart .axis { stroke: var(--rule); stroke-width: 1; }
.chart .ax { fill: var(--ink-3); font-size: var(--fs-12); letter-spacing: 0.04em; }
.chart .ax-r { fill: var(--accent); }
.chart .ax-lab { fill: var(--ink-2); font-size: var(--fs-13); }
.chart .ax-val { fill: var(--ink-3); font-size: var(--fs-12); }
.chart .bar { fill: var(--chart-bar); }
.chart .line { fill: none; stroke: var(--accent); stroke-width: 1.5; stroke-linejoin: round; }
.chart .dot { fill: var(--accent); }
.chart .val { font-size: var(--fs-13); font-weight: 600; }
.chart .val-bar { fill: var(--ink-2); }
.chart .val-line { fill: var(--accent); }
figure.chartbox figcaption {
  font-size: var(--fs-12); color: var(--ink-3); letter-spacing: 0.04em;
  padding-top: var(--sp-8); border-top: 1px solid var(--rule-2);
}
.legend { display: inline-flex; gap: var(--sp-16); margin-left: var(--sp-16); }
.legend span { display: inline-flex; align-items: center; gap: var(--sp-8); }
/* 圖例色塊。一定要限定在 .legend 底下：表格的 td.key 也叫 key */
.legend .key { width: 10px; height: 2px; display: inline-block; }
.legend .key-bar { background: var(--ink); opacity: .3; height: 8px; }
.legend .key-line { background: var(--accent); }

/* ---------- 搜尋（縮小） ---------- */
.searchbox { margin: 0 0 var(--sp-8); }
.searchbox input[type="search"] {
  width: 100%; max-width: 440px; font: inherit; font-size: var(--fs-15);
  padding: var(--sp-8) 0; color: var(--ink); background: transparent;
  border: none; border-bottom: 1px solid var(--ink);
}
.searchbox input:focus { outline: none; border-bottom-color: var(--accent); }
.results {
  list-style: none; margin: var(--sp-8) 0 var(--sp-24); padding: 0;
  max-width: 440px; border-top: 1px solid var(--rule);
}
.results li { border-bottom: 1px solid var(--rule-2); }
.results a {
  display: flex; justify-content: space-between; gap: var(--sp-16);
  align-items: baseline; padding: var(--sp-8) 0; text-decoration: none;
}
.results a:hover { color: var(--accent); background: var(--accent-soft); }
.results .r-n { font-size: var(--fs-13); }
.results .r-s { font-size: var(--fs-12); color: var(--ink-3); }
.results .r-t { font-size: var(--fs-12); color: var(--ink-3); letter-spacing: 0.04em; flex: 0 0 auto; }

/* ---------- 角色選擇（唯一的按鈕樣式） ---------- */
/* 角色選擇：髮絲線分隔的四欄，不是四張帶框的卡片（DESIGN_SPEC 規則 4）。
   結構與 .stats／.entries 同構：上緣一條墨線、欄間 1px 分隔線、沒有外框。 */
.roles {
  list-style: none; margin: var(--sp-24) 0 var(--sp-32); padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--ink); gap: 0;
}
.roles > li { border-bottom: 1px solid var(--rule); }
.roles > li:nth-child(even) { border-left: 1px solid var(--rule-2); }
.rolebtn {
  display: block; width: 100%; height: 100%; text-align: left; text-decoration: none;
  background: transparent; color: inherit; font: inherit;
  border: 0; padding: var(--sp-16) var(--sp-16) var(--sp-16) 0; cursor: pointer;
}
.roles > li:nth-child(even) .rolebtn { padding-left: var(--sp-16); }
.rolebtn:hover, .rolebtn:focus-visible { background: var(--accent-soft); }
.rolebtn:hover .rolebtn-t, .rolebtn:hover .ico { color: var(--accent); }
.rolebtn-t {
  display: flex; align-items: center; gap: var(--sp-8);
  font-weight: 700; font-size: var(--fs-18); text-wrap: balance;
}
.rolebtn-s {
  display: block; margin-top: var(--sp-8); font-size: var(--fs-13);
  color: var(--ink-3); text-wrap: pretty;
}

.rolebar {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--sp-16); border-bottom: 1px solid var(--rule);
  padding-bottom: var(--sp-8); margin-bottom: var(--sp-24);
}
.rolebar .now { font-size: var(--fs-13); color: var(--ink-2); display: inline-flex; align-items: center; gap: var(--sp-8); }
.rolebar .swap { font-size: var(--fs-12); letter-spacing: 0.04em; }

/* 角色入口卡（髮絲線格，不是卡片堆疊） */
.entries {
  list-style: none; margin: var(--sp-16) 0 var(--sp-32); padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--ink);
}
.entries > li { border-bottom: 1px solid var(--rule); }
.entries > li:nth-child(even) { border-left: 1px solid var(--rule-2); }
.entries a {
  display: block; padding: var(--sp-16) var(--sp-16) var(--sp-16) 0; text-decoration: none; height: 100%;
}
.entries > li:nth-child(even) a { padding-left: var(--sp-16); }
.entries a:hover { background: var(--accent-soft); }
.entries .e-h { display: flex; align-items: center; gap: var(--sp-8); font-size: var(--fs-12); letter-spacing: 0.04em; color: var(--ink-3); }
.entries .e-v { display: block; font-size: var(--fs-24); font-weight: 600; line-height: 1.15; margin: var(--sp-8) 0; font-variant-numeric: tabular-nums; }
.entries .e-s { display: block; font-size: var(--fs-13); color: var(--ink-2); }

/* ---------- 文章 ---------- */
.artlist { list-style: none; margin: var(--sp-16) 0 var(--sp-32); padding: 0; border-top: 1px solid var(--ink); }
.artlist > li { border-bottom: 1px solid var(--rule); padding: var(--sp-16) 0; }
.artlist h3 { margin: 0 0 var(--sp-8); font-size: var(--fs-18); max-width: 34em; }
.artlist h3 a { text-decoration-color: transparent; }
.artlist h3 a:hover { text-decoration-color: currentColor; }
.artmeta { font-size: var(--fs-12); letter-spacing: 0.04em; color: var(--ink-3); display: flex; align-items: center; gap: var(--sp-8); margin-bottom: var(--sp-8); }
.artlist p { margin: 0; font-size: var(--fs-13); color: var(--ink-2); }

.prose { max-width: 68ch; }
.prose h2 { font-size: var(--fs-24); margin: var(--sp-48) 0 var(--sp-16); }
.prose h3 { font-size: var(--fs-18); }
.prose p { margin-bottom: var(--sp-16); }
.prose ul, .prose ol { padding-left: var(--sp-16); margin: 0 0 var(--sp-16); }
.prose li { margin-bottom: var(--sp-8); }
.prose table { border-collapse: collapse; width: 100%; font-size: var(--fs-13); margin: var(--sp-16) 0 var(--sp-32); }
.prose th, .prose td { padding: var(--sp-8) var(--sp-16) var(--sp-8) 0; border-bottom: 1px solid var(--rule-2); text-align: left; }
.prose th { font-size: var(--fs-12); letter-spacing: 0.08em; color: var(--ink-3); font-weight: 500; border-bottom-color: var(--rule); }
.prose td:not(:first-child), .prose th:not(:first-child) { text-align: right; }
.prose hr { border: none; border-top: 1px solid var(--rule); margin: var(--sp-32) 0; }
.prose hr + p { font-size: var(--fs-12); color: var(--ink-3); }

.artnav { display: flex; justify-content: space-between; gap: var(--sp-24); border-top: 1px solid var(--rule); padding-top: var(--sp-16); font-size: var(--fs-13); }

/* ---------- 逐月變動史 ---------- */
.changes-month { border-top: 1px solid var(--rule); padding: var(--sp-16) 0; }
.changes-month h3 { margin: 0 0 var(--sp-8); font-size: var(--fs-18); }
.changes-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--sp-32); font-size: var(--fs-13); }
.changes-grid > div > :first-child { margin-top: 0; }
.changes-grid dt { font-size: var(--fs-12); letter-spacing: 0.04em; color: var(--ink-3); }
.changes-grid dd { margin: 0 0 var(--sp-8); }

/* ---------- 提示條 ---------- */
.notice {
  background: var(--accent-soft);
  border-left: 2px solid var(--accent); padding: var(--sp-8) var(--sp-16);
  font-size: var(--fs-13); color: var(--ink-2); margin: 0 0 var(--sp-24);
}
.formula {
  border-left: 2px solid var(--ink); padding: var(--sp-8) var(--sp-16);
  font-size: var(--fs-15); margin: 0 0 var(--sp-24);
}

/* ---------- 頁尾 ---------- */
.site-foot {
  border-top: 1px solid var(--rule); padding: var(--sp-24) 0 var(--sp-48);
  font-size: var(--fs-12); color: var(--ink-3); letter-spacing: 0.04em;
}
.site-foot p { margin: 0 0 var(--sp-8); max-width: none; }

/* ---------- 斷點 ---------- */
@media (min-width: 720px) {
  .stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .stats.stats-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .stats.stats-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stats > li + li { border-left: 1px solid var(--rule-2); }
  .roles { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .roles > li + li { border-left: 1px solid var(--rule-2); }
  .roles > li .rolebtn, .roles > li:nth-child(even) .rolebtn { padding-left: var(--sp-16); }
  .roles > li:first-child .rolebtn { padding-left: 0; }
  .entries { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .entries > li + li { border-left: 1px solid var(--rule-2); }
  .entries > li a, .entries > li:nth-child(even) a { padding-left: var(--sp-16); }
  .entries > li:first-child a { padding-left: 0; }
  .changes-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  h1 { font-size: var(--fs-48); }
}

@media (max-width: 719px) {
  .wrap { padding: 0 var(--sp-16); }
  h1 { font-size: var(--fs-24); line-height: 1.3; }

  /* 導覽擠成兩行不好按：改成可橫向捲動的一列，每個連結 44px 觸控區 */
  .head-inner { flex-wrap: nowrap; align-items: center; }
  .site-head nav {
    flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    gap: var(--sp-16); margin-left: auto; padding-bottom: 2px;
  }
  .site-head nav > * { flex: 0 0 auto; }
  .site-head nav a, .rolemenu > summary {
    min-height: var(--tap); display: inline-flex; align-items: center;
  }
  .themetoggle { width: var(--tap); height: var(--tap); }
  .rolebtn { min-height: var(--tap); }
  .entries a { min-height: var(--tap); }
  table.sortable thead th { min-height: var(--tap); }
  h2 { font-size: var(--fs-18); margin-top: var(--sp-32); }
  .standfirst { font-size: var(--fs-15); }
  .stat-v, .stat-lead .stat-v { font-size: var(--fs-24); }
  .stats > li:nth-child(odd) { border-left: none; padding-left: 0; }
  .rolemenu ul { right: auto; left: 0; }
}

@media print {
  .site-head, .site-foot, .search, .roles, .rolebar { display: none; }
  .tablewrap { overflow: visible; }
}


/* ---------- 主題切換鈕 ---------- */
.themetoggle {
  background: transparent; border: 1px solid var(--rule); color: var(--ink-2);
  width: 32px; height: 32px; padding: 0; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.themetoggle:hover { color: var(--accent); border-color: var(--accent); }
.themetoggle .ico { color: currentColor; }
.themetoggle .i-sun { display: none; }
:root[data-theme="dark"] .themetoggle .i-sun { display: block; }
:root[data-theme="dark"] .themetoggle .i-moon { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .themetoggle .i-sun { display: block; }
  :root:not([data-theme="light"]) .themetoggle .i-moon { display: none; }
}

/* ---------- 首頁 hero：深藍底 ＋ 壓暗的真實照片 ---------- */
.hero {
  position: relative; background: var(--hero-bg); color: #f1f5f9;
  border-bottom: 1px solid var(--rule); overflow: hidden;
}
.hero::before {   /* 沒有照片時的底：極淡明暗，不是彩色 */
  content: ""; position: absolute; inset: 0; background: var(--hero-bg-2); opacity: .45;
}
.hero-img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: .55;
}
.hero-scrim { position: absolute; inset: 0; background: var(--hero-scrim); }
/* hero 收矮一階：v1 的 64/48 讓 1280×900 的第一屏完全看不到數字列
   （DESIGN_SPEC 規則 3 數字優先）。 */
.hero-inner { position: relative; padding-top: var(--sp-48); padding-bottom: var(--sp-32); }
.hero .eyebrow {
  color: #38bdf8; letter-spacing: 0.12em; text-transform: uppercase;
  margin-bottom: var(--sp-16);
}
.hero h1 { color: #ffffff; margin-bottom: var(--sp-16); }
.hero .standfirst { color: #cbd5e1; margin-bottom: 0; }
.hero .credit { color: #94a3b8; margin: var(--sp-16) 0 0; }

/* ---------- 內頁小圖（H1 上方的 240px 帶狀圖） ---------- */
.pagephoto {
  position: relative; height: var(--hero-h); margin: var(--sp-24) 0 var(--sp-24);
  background: var(--hero-bg); overflow: hidden;
}
.pagephoto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pagephoto .hero-scrim { position: absolute; inset: 0; background: var(--hero-scrim); }
.pagephoto .eyebrow {
  position: absolute; left: var(--sp-16); bottom: var(--sp-16); right: var(--sp-16);
  color: #e2e8f0; margin: 0; letter-spacing: 0.12em; text-transform: uppercase;
}
.credit {
  font-size: var(--fs-12); color: var(--ink-3); letter-spacing: 0.04em;
  margin: calc(var(--sp-24) * -1) 0 var(--sp-24);
}
.credit a { color: inherit; }

@media (max-width: 719px) {
  :root { --hero-h: 180px; }
  .hero-inner { padding-top: var(--sp-32); padding-bottom: var(--sp-32); }
}

/* ==========================================================================
   資料圖像化：全部是 build 時畫好的內嵌 SVG。
   只有 sky 一個強調色，次要用墨色透明度；深色模式靠 currentColor 與 color-mix 自動翻轉。
   ========================================================================== */

/* sky 色階：市佔條與熱圖共用（深色模式整組反轉明暗） */
:root {
  --sky-1: #075985; --sky-2: #0369a1; --sky-3: #0284c7; --sky-4: #0ea5e9;
  --sky-5: #38bdf8; --sky-6: #7dd3fc; --sky-7: #bae6fd; --sky-8: #e0f2fe;
  --heat-0: #f0f9ff; --heat-1: #e0f2fe; --heat-2: #bae6fd; --heat-3: #7dd3fc;
  --heat-4: #38bdf8; --heat-5: #0284c7; --heat-6: #075985;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --sky-1: #bae6fd; --sky-2: #7dd3fc; --sky-3: #38bdf8; --sky-4: #0ea5e9;
    --sky-5: #0284c7; --sky-6: #0369a1; --sky-7: #075985; --sky-8: #0c4a6e;
    --heat-0: #13293b; --heat-1: #17415c; --heat-2: #0c4a6e; --heat-3: #0369a1;
    --heat-4: #0284c7; --heat-5: #38bdf8; --heat-6: #7dd3fc;
  }
}
:root[data-theme="dark"] {
  --sky-1: #bae6fd; --sky-2: #7dd3fc; --sky-3: #38bdf8; --sky-4: #0ea5e9;
  --sky-5: #0284c7; --sky-6: #0369a1; --sky-7: #075985; --sky-8: #0c4a6e;
  --heat-0: #13293b; --heat-1: #17415c; --heat-2: #0c4a6e; --heat-3: #0369a1;
  --heat-4: #0284c7; --heat-5: #38bdf8; --heat-6: #7dd3fc;
}

/* 圖內共用小字 */
.chart .c-title { fill: var(--ink-2); font-size: var(--fs-12); font-weight: 500; letter-spacing: 0.04em; }
.chart .c-note  { fill: var(--ink-3); font-size: var(--fs-12); letter-spacing: 0.04em; }
.chart .c-lab   { fill: var(--ink-3); font-size: var(--fs-12); }
.chart .c-val   { fill: var(--ink-2); font-size: var(--fs-12); font-variant-numeric: tabular-nums; }

/* 1. 航線地圖 */
.chart-map { min-width: var(--chart-min); }
.chart-map .c-land { fill: color-mix(in srgb, var(--ink) 9%, transparent); stroke: none; }
.chart-map .c-grat { stroke: var(--rule); stroke-width: 1; }
.chart-map .c-geo  { fill: var(--ink-4); font-size: var(--fs-12); opacity: .75; }
.chart-map .c-arc  { fill: none; stroke: var(--accent); stroke-linecap: round; }
.chart-map .c-arc1 { stroke-width: .8; opacity: .35; }
.chart-map .c-arc2 { stroke-width: 1.4; opacity: .55; }
.chart-map .c-arc3 { stroke-width: 2.2; opacity: .8; }
.chart-map .c-dot  { fill: var(--accent); }
.chart-map .c-origin { fill: var(--ink); }
.chart-map .c-olab { fill: var(--ink); font-size: var(--fs-12); font-weight: 500; }

/* 2. 市佔堆疊條 */
.chart-share { min-width: 440px; }
.chart-share .seg.s1 { fill: var(--sky-1); } .chart-share .seg.s2 { fill: var(--sky-2); }
.chart-share .seg.s3 { fill: var(--sky-3); } .chart-share .seg.s4 { fill: var(--sky-4); }
.chart-share .seg.s5 { fill: var(--sky-5); } .chart-share .seg.s6 { fill: var(--sky-6); }
.chart-share .seg.s7 { fill: var(--sky-7); } .chart-share .seg.s8 { fill: var(--sky-8); }

/* 3. 季節性熱圖 */
.chart-heat { min-width: var(--chart-min); }
.chart-heat .hc.h0 { fill: var(--heat-0); } .chart-heat .hc.h1 { fill: var(--heat-1); }
.chart-heat .hc.h2 { fill: var(--heat-2); } .chart-heat .hc.h3 { fill: var(--heat-3); }
.chart-heat .hc.h4 { fill: var(--heat-4); } .chart-heat .hc.h5 { fill: var(--heat-5); }
.chart-heat .hc.h6 { fill: var(--heat-6); }
.chart-heat .hc.h-na { fill: color-mix(in srgb, var(--ink) 5%, transparent); }
.chart-heat .hv { fill: var(--ink-2); font-size: var(--fs-12); font-variant-numeric: tabular-nums; }
.chart-heat .hv.hv-dark { fill: #f8fafc; }
:root[data-theme="dark"] .chart-heat .hv.hv-dark { fill: #0f172a; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .chart-heat .hv.hv-dark { fill: #0f172a; }
}

/* 4. 表格內的走勢小圖 */
.spark { display: block; overflow: visible; }
.spark-line { fill: none; stroke: var(--accent); stroke-width: 1.25; vector-effect: non-scaling-stroke; }
.spark-dot { fill: var(--accent); }
td.sparkcell { width: 104px; padding-right: var(--sp-8); }

/* 5. YoY 變化條 */
.yb { display: inline-block; vertical-align: middle; }
.yb-axis { stroke: var(--rule); stroke-width: 1; }
.yb-up { fill: var(--accent); }
.yb-down { fill: color-mix(in srgb, var(--ink) 40%, transparent); }
.ybcell { white-space: nowrap; }
.ybcell .ybnum { margin-left: var(--sp-8); font-variant-numeric: tabular-nums; }

/* 6. 水平長條排行 */
.chart-hbar { min-width: 440px; }
.chart-hbar .hbar { fill: var(--accent); opacity: .85; }
.chart-hbar .c-lab-r { fill: var(--ink-2); }

/* 7. 多條折線 */
.chart-multi { min-width: 340px; }
.chart-multi .ml { fill: none; stroke-width: 1.6; stroke-linejoin: round; }
.chart-multi .ml1 { stroke: var(--sky-2); } .chart-multi .ml2 { stroke: var(--sky-3); }
.chart-multi .ml3 { stroke: var(--sky-5); } .chart-multi .ml4 { stroke: var(--ink-4); }
.chart-multi .mld.ml1 { fill: var(--sky-2); stroke: none; }
.chart-multi .mld.ml2 { fill: var(--sky-3); stroke: none; }
.chart-multi .mld.ml3 { fill: var(--sky-5); stroke: none; }
.chart-multi .mld.ml4 { fill: var(--ink-4); stroke: none; }
.chart-multi .mlt { font-size: var(--fs-12); font-weight: 500; stroke: none; }
.chart-multi .mlt.ml1 { fill: var(--sky-2); } .chart-multi .mlt.ml2 { fill: var(--sky-3); }
.chart-multi .mlt.ml3 { fill: var(--sky-5); } .chart-multi .mlt.ml4 { fill: var(--ink-4); }

/* H1 下方的副標：數字都放這裡，標題本身只留實體詞 */
.subtitle {
  font-size: var(--fs-13); color: var(--ink-2); letter-spacing: 0.04em;
  margin: 0 0 var(--sp-16); font-variant-numeric: tabular-nums;
  text-wrap: pretty;
}
.hero .subtitle { color: #cbd5e1; }

/* 標題的第二層：數字摘要都放這裡，主標本身不帶冒號 */
.hmeta {
  font-size: var(--fs-13); color: var(--ink-3); letter-spacing: 0.04em;
  margin: calc(var(--sp-8) * -1) 0 var(--sp-16);
  font-variant-numeric: tabular-nums;
}
h3 + .hmeta { margin-top: 0; }

/* 表頭縮寫：底線提示，滑過看全名 */
abbr[title] { text-decoration: underline dotted; text-underline-offset: 3px; cursor: help; }

/* ==========================================================================
   手機版最後覆寫：確保觸控區 ≥ --tap（放在檔案最後，避免被後面的規則蓋掉）
   ========================================================================== */
@media (max-width: 719px) {
  .themetoggle { width: var(--tap); height: var(--tap); }
  .site-head nav a, .rolemenu > summary { min-height: var(--tap); }
  /* table cell 的 min-height 無效，要用 height */
  table.sortable thead th { height: var(--tap); }
  .rolebtn { min-height: var(--tap); }
  .results a, .rolemenu li a { min-height: var(--tap); align-items: center; }
}

/* ==========================================================================
   v2 追加：REVIEW 修正（放在檔案最後，蓋掉前面的同名規則）
   ========================================================================== */

/* ---------- 孤字與拆詞（DESIGN_SPEC 規則 2）----------
   中文沒有詞界，balance／pretty 只能幫標題挑比較平均的斷點，擋不住
   「每／週」「331,515 個／座位」這種拆法。真正綁住的是 build 時包的
   <span class="nw">（見 build.py 的 nowrap()），這裡補齊所有標題與短句。 */
h1, h2, h3, h4, .rolebtn-t, .e-h, .stat-k, .artlist h3, .lede {
  text-wrap: balance;
}
.lede, .standfirst, .subtitle, .hmeta, .note, .muted, .e-s, .rolebtn-s,
p, li, dd, figcaption, caption {
  text-wrap: pretty;
}
/* 短句（12 個全形字以內）整句不斷行，最常見的孤字來源 */
.stat-k, .stat-s, .e-h, .crumbs span[aria-current] { overflow-wrap: break-word; }

/* ---------- 圖表：市佔堆疊條的段內文字 ---------- */
.chart-share { min-width: 420px; }
.chart-share .seg-t, .chart-share .seg-t-rev {
  font-size: var(--fs-12); font-weight: 500; letter-spacing: 0.02em;
}
.chart-share .seg-t { fill: var(--ink); }
.chart-share .seg-t-rev { fill: #f8fafc; }       /* 前四階是深底，文字反白 */
.chart-share .seg-p { font-variant-numeric: tabular-nums; font-weight: 600; }
/* 深色模式整組色階翻轉，前四階變成亮底，文字要改回深色 */
:root[data-theme="dark"] .chart-share .seg-t-rev { fill: #0f172a; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .chart-share .seg-t-rev { fill: #0f172a; }
}

/* ---------- 圖表：熱圖 ---------- */
/* 圖例移到圖下方之後不必再留右側空間，最小寬度跟著降，手機上 12 個月塞得進去 */
.chart-heat { min-width: 480px; }
/* v4 第 5 項：手機上改成顯示格內數字。SVG 在 375 下是 480÷620＝0.774 倍，
   所以 viewBox 內寫 15px 才等於畫面上的 11px（DESIGN_SPEC 規則 9 的唯一例外，
   使用者 2026-09-16 指定）。月份標籤同時改成每隔一個顯示，才空得出位置。 */
@media (max-width: 719px) {
  .chart-heat .hv { display: block; font-size: 15px; }
  .chart-heat .c-lab { font-size: 15px; }
  .chart-heat .c-lab.m-alt { display: none; }
}

/* ---------- 圖表：走勢圖的年份界線與年份標籤 ---------- */
.chart .yearline { stroke: var(--rule-2); stroke-dasharray: 2 4; }
.chart .ax-y { fill: var(--ink-2); font-weight: 500; }

/* ---------- 圖表：表格內小圖的基準線 ---------- */
.spark-base {
  stroke: var(--rule); stroke-width: 1; vector-effect: non-scaling-stroke;
}

/* ---------- 圖表：地圖 ---------- */
/* 世界地圖需要寬度才讀得懂；區域地圖（單一航線）縮得進手機就不要強迫捲動 */
.chart-map { min-width: var(--chart-min); }
.chart-map.chart-map-near { min-width: 300px; }
.chart-map .c-olab {
  paint-order: stroke; stroke: var(--paper); stroke-width: 3px;
  stroke-linejoin: round;
}
.chart-map .c-geo {
  paint-order: stroke; stroke: var(--paper); stroke-width: 2.5px;
  stroke-linejoin: round; opacity: .9;
}

/* ---------- 首頁：本月變化兩欄 ---------- */
/* 沒有停飛時只剩一欄，不要留一半空白（REVIEW C3） */
.changes-grid.one-col { grid-template-columns: minmax(0, 1fr); }

/* ---------- 角色入口：選了角色之後的四個入口一定要有數字 ---------- */
.entries .e-v:empty { display: none; }

/* ---------- 排行清單：加上比例條 ---------- */
.ranklist .rank-bar {
  display: block; height: 3px; margin-top: var(--sp-8);
  background: var(--chart-bar); max-width: 260px;
}
.ranklist .rank-bar > i { display: block; height: 100%; background: var(--accent); }

/* ---------- 兩欄清單之間補一條髮絲線（REVIEW C12）---------- */
@media (min-width: 720px) {
  .changes-grid.ruled > div + div {
    border-left: 1px solid var(--rule-2); padding-left: var(--sp-32);
  }
}

/* ---------- 逐月變動史：分年折疊（REVIEW A2）---------- */
.yearnav {
  list-style: none; display: flex; flex-wrap: wrap; gap: var(--sp-8) var(--sp-16);
  padding: 0; margin: var(--sp-16) 0 var(--sp-32);
  border-top: 1px solid var(--rule); padding-top: var(--sp-16);
}
.yearnav a { font-size: var(--fs-13); }
details.yearblock { border-top: 1px solid var(--rule); }
details.yearblock > summary {
  cursor: pointer; list-style: none; padding: var(--sp-16) 0;
  font-size: var(--fs-18); font-weight: 700;
  display: flex; align-items: center; gap: var(--sp-8); min-height: var(--tap);
}
details.yearblock > summary::-webkit-details-marker { display: none; }
details.yearblock > summary::before { content: "＋"; color: var(--ink-3); font-weight: 400; }
details.yearblock[open] > summary::before { content: "−"; }
details.yearblock > summary:hover { color: var(--accent); }
details.yearblock > summary .muted {
  font-size: var(--fs-12); font-weight: 400; letter-spacing: 0.04em;
}

/* ==========================================================================
   v3 追加：從圖到答案、橫向比較、機場頁資訊架構
   ========================================================================== */

/* ---------- 自動生成的一句話結論 ----------
   不是提示框、不是卡片：左邊一條 2px 強調色直線，字級比內文大一階。
   出現在航線頁的季節性圖上方、機場頁與國家頁的數字列下方。 */
.takeaway {
  font-size: var(--fs-18); line-height: 1.5; color: var(--ink);
  border-left: 2px solid var(--accent);
  padding: 0 0 0 var(--sp-16);
  margin: 0 0 var(--sp-24); max-width: 60ch; text-wrap: pretty;
}
h2 + .takeaway, .hmeta + .takeaway { margin-top: var(--sp-16); }

/* ---------- 數字列的橫向比較（自己一行，不跟 sub 擠） ---------- */
.stat-r {
  display: block; margin-top: var(--sp-8);
  font-size: var(--fs-12); letter-spacing: 0.04em; color: var(--accent);
  font-variant-numeric: tabular-nums;
}

/* ---------- 表格首欄的迷你長條：不看數字也掃得出高低 ---------- */
.minibar {
  display: block; height: 4px; margin-top: var(--sp-8);
  width: 120px; max-width: 100%;
  background: var(--chart-bar);
}
.minibar > i { display: block; height: 100%; background: var(--accent); opacity: .85; }


/* ---------- 逐月載客率中位數（季節性文章的主圖） ---------- */
.chart-month { min-width: 420px; }
.chart-month .bar { fill: var(--chart-bar); }
.chart-month .bar.hot { fill: var(--accent); opacity: .85; }
.chart-month .bar.cold { fill: color-mix(in srgb, var(--accent) 35%, transparent); }
.chart-month .baseline {
  stroke: var(--ink-3); stroke-width: 1; stroke-dasharray: 3 3;
}

/* ---------- 文章行長 ≤ 38 個全形字 ----------
   68ch 在中文是 45 字上下，一行太長讀起來會掉行。字級 15px，36em ＝ 36 字。 */
/* 只有文字欄要收窄，圖與表照樣用整個內容寬度（收窄整個 .prose 會把
   航線地圖擠成一小塊）。 */
.prose { max-width: none; }
.prose p, .prose li, .prose h2, .prose h3, .prose dl { max-width: 36em; }
.prose figure.chartbox figcaption { max-width: 36em; }

/* ==========================================================================
   v4 追加：整區收合、三種新圖表、手機熱圖
   ========================================================================== */

/* ---------- 整區收合（機場頁的區域、國家頁的出發機場、航空公司頁的航線組）----
   摘要列本身就是一行資料：名稱在左、四個數字在右、下面一條迷你長條。
   預設全部收起，所以桃園機場頁收合狀態只有八行。 */
.regions { margin: 0 0 var(--sp-32); border-top: 1px solid var(--rule); }
details.regionblock { border-bottom: 1px solid var(--rule-2); }
details.regionblock > summary {
  cursor: pointer; list-style: none;
  display: grid;
  /* 名稱用自己的寬度，數字欄吃掉剩下的並靠右；反過來寫的話
     「台北直飛東北亞」在窄螢幕會被壓成一字一行 */
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "name meta" "bar bar";
  align-items: baseline; column-gap: var(--sp-16);
  padding: var(--sp-16) 0 var(--sp-8);
  min-height: var(--tap);
}
details.regionblock > summary::-webkit-details-marker { display: none; }
details.regionblock > summary:hover .gs-n { color: var(--accent); }
.gs-n {
  grid-area: name; font-size: var(--fs-18); font-weight: 700; color: var(--ink);
  display: flex; align-items: baseline; gap: var(--sp-8); white-space: nowrap;
}
.gs-n::before { content: "＋"; color: var(--ink-3); font-weight: 400; font-size: var(--fs-15); }
details.regionblock[open] > summary .gs-n::before { content: "−"; }
.gs-m {
  grid-area: meta; display: flex; flex-wrap: wrap; justify-content: flex-end;
  gap: var(--sp-8) var(--sp-16);
  font-size: var(--fs-13); color: var(--ink-3);
}
.gs-c b { font-weight: 500; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.gs-bar {
  grid-area: bar; display: block; height: 3px; margin-top: var(--sp-8);
  background: var(--chart-bar);
}
.gs-bar > i { display: block; height: 100%; background: var(--accent); opacity: .85; }
details.regionblock[open] > summary { padding-bottom: var(--sp-16); }
details.regionblock .tablewrap { margin-top: 0; }
details.regionblock > .note { margin-top: var(--sp-8); }

/* 「全部展開／全部收合」：由 site.js 取消 hidden 才出現 */
.expandall { margin: 0 0 var(--sp-8); text-align: right; }
.linkbtn {
  background: transparent; border: 0; padding: var(--sp-8) 0;
  font: inherit; font-size: var(--fs-13); color: var(--ink-2);
  border-bottom: 1px solid var(--rule); cursor: pointer; min-height: var(--tap);
}
.linkbtn:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* ---------- 左右發散的水平長條（/changes/ 增減班、角色頁座位 YoY）---------- */
.chart-div { min-width: 480px; }
.chart-div .hbar.hb-up { fill: var(--accent); opacity: .85; }
.chart-div .hbar.hb-down { fill: color-mix(in srgb, var(--ink) 38%, transparent); }
.chart-div .zeroline { stroke: var(--rule); stroke-width: 1; }
.chart-div .c-lab-r { fill: var(--ink-2); }
.chart-div .c-val.v-up { fill: var(--accent); }
.chart-div .c-val.v-down { fill: var(--ink-2); }

/* ---------- 上下發散的逐月長條（/changes/ 新開與停飛）---------- */
.chart-ud { min-width: var(--chart-min); }
.chart-ud .bar.ud-up { fill: var(--accent); opacity: .85; }
.chart-ud .bar.ud-down { fill: color-mix(in srgb, var(--ink) 38%, transparent); }
.chart-ud .zeroline { stroke: var(--ink-4); stroke-width: 1; }
.chart-ud .c-lab-y { fill: var(--ink-2); }
.chart-ud .ud-t { fill: var(--accent); }

/* ---------- 直方圖（角色頁載客率分佈）---------- */
.chart-hist { min-width: 480px; }
.chart-hist .bar { fill: var(--chart-bar); }
.chart-hist .baseline { stroke: var(--accent); stroke-width: 1; stroke-dasharray: 3 3; }
.chart-hist .c-note { fill: var(--accent); }

/* ---------- 手機（覆寫在最後）---------- */
@media (max-width: 719px) {
  /* 導覽列橫向捲動時右側要看得出還有東西，且主題切換鈕不能被推出畫面 */
  .site-head nav {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
            mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
  }
  .head-inner { gap: var(--sp-8); }
  .themetoggle { flex: 0 0 var(--tap); }

  /* 數字列兩欄（規則 9）。大數字在手機上再降一階避免撞線 */
  .stat-v, .stat-lead .stat-v { font-size: var(--fs-24); }
  .stat-v-sm, .stat-lead .stat-v-sm { font-size: var(--fs-18); }

  /* hero 與內頁帶狀圖在手機高度 180px（使用者指定） */
  :root { --hero-h: 180px; }
  .hero-inner { padding-top: var(--sp-24); padding-bottom: var(--sp-24); }
  .hero h1 { font-size: var(--fs-24); }
  .hero .standfirst { font-size: var(--fs-15); margin-bottom: 0; }

  /* 觸控目標 ≥ 44px */
  .rolebtn { min-height: 88px; }
  .entries a { min-height: var(--tap); }
  .yearnav a { min-height: var(--tap); display: inline-flex; align-items: center; }
  .artlist h3 a, .linklist a, .changelist a, .ranklist a {
    display: inline-block; min-height: var(--tap); line-height: 1.6;
  }

  /* 文章內文的圖一律縮進容器，不要撐開整個 document（REVIEW A3） */
  .prose .chart { min-width: 0; }
  .prose table { display: block; overflow-x: auto; }

  /* 兩欄清單在手機是上下堆疊，間距固定 32px（刻度） */
  .changes-grid { gap: var(--sp-32); }

  /* v3：結論句在手機降一階，跟內文同級但保留左邊那條線 */
  .takeaway { font-size: var(--fs-15); padding-left: var(--sp-8); }
  .minibar { width: 84px; }

  /* v4：區域摘要列在 375 排不下一行，改成名稱一行、數字一行、長條一行 */
  details.regionblock > summary {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "name" "meta" "bar";
    row-gap: var(--sp-8);
  }
  .gs-n { white-space: normal; }
  .gs-m { justify-content: flex-start; }

  /* DESIGN_SPEC 規則 9：手機字級不小於 13px。
     v1／v2 全站的小字（眉標、數字列標籤、麵包屑、表頭、圖說、頁尾）都是 12px，
     在 375 上偏小。手機把 --fs-12 整個提到 13px，刻度沒有變多。
     圖內的文字例外：SVG 是固定 viewBox，放大 1px 兩個月份標籤就會疊在一起。 */
  :root { --fs-12: 13px; }
  .chart { --fs-12: 12px; }
}

/* ==========================================================================
   v5 追加（使用者 2026-09-16 第二輪）
   A 角色區與 hero 的留白、B 逐月收合與手機熱圖、C 地圖畫線、D 進場動畫
   放在檔案最後，蓋得過前面的同名規則。
   ========================================================================== */

/* ---------- A. 首頁：hero 底邊與下方第一個區塊的留白 ----------
   使用者回報選了角色之後「旅遊業」那行幾乎貼著 hero 的深色底邊。
   桌機 48px、手機 32px，兩個值都在間距刻度上。選角色前的 #rolepick 一併處理，
   它本來也是貼著的。 */
#rolepick, .rolepanel { padding-top: var(--sp-48); }

/* 角色名那行 → 髮絲線 → 數字，三段間距重新對到刻度上：
   文字到線 16px、線到入口卡 24px（原本是 8px 與塌陷後的 24px）。 */
.rolepanel .rolebar {
  padding-bottom: var(--sp-16);
  margin-bottom: var(--sp-24);
}
.rolepanel .entries { margin-top: 0; }

@media (max-width: 719px) {
  #rolepick, .rolepanel { padding-top: var(--sp-32); }
}

/* ---------- B1. 逐月變動史：一個月一個 <details> ----------
   摘要列比區域摘要再緊一階（一行 44px），24 個月收起來才壓得住頁高。 */
details.monthblock { border-bottom: 1px solid var(--rule-2); }
details.monthblock > summary {
  cursor: pointer; list-style: none;
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  align-items: baseline; column-gap: var(--sp-16);
  padding: var(--sp-8) 0; min-height: var(--tap);
}
details.monthblock > summary::-webkit-details-marker { display: none; }
details.monthblock > summary:hover .mb-n { color: var(--accent); }
.mb-n {
  font-size: var(--fs-15); font-weight: 700; color: var(--ink);
  white-space: nowrap;
  display: flex; align-items: baseline; gap: var(--sp-8);
}
.mb-n::before { content: "＋"; color: var(--ink-3); font-weight: 400; }
details.monthblock[open] > summary .mb-n::before { content: "−"; }
.mb-m {
  display: flex; flex-wrap: wrap; justify-content: flex-end;
  gap: 0 var(--sp-16); font-size: var(--fs-13); color: var(--ink-3);
}
.mb-c b { font-weight: 500; color: var(--ink-2); font-variant-numeric: tabular-nums; }
details.monthblock > .changes-grid { padding: 0 0 var(--sp-16); margin: 0; }
details.monthblock > .changes-grid > div > :first-child { margin-top: 0; }

/* 更早的每一年：收起來的那 16 行也壓緊一階 */
details.yearblock > summary { padding: var(--sp-8) 0; }

/* ---------- B2. 角色頁的「再看 N 條」與「每一欄是什麼」 ---------- */
details.morelist { margin: 0 0 var(--sp-16); }
details.morelist > summary {
  cursor: pointer; list-style: none; font-size: var(--fs-13); color: var(--ink-2);
  border-bottom: 1px solid var(--rule); padding: var(--sp-8) 0;
  min-height: var(--tap); display: flex; align-items: center; gap: var(--sp-8);
}
details.morelist > summary::-webkit-details-marker { display: none; }
details.morelist > summary::before { content: "＋"; color: var(--ink-3); }
details.morelist[open] > summary::before { content: "−"; }
details.morelist > summary:hover { color: var(--accent); }

/* ---------- B3. 手機熱圖：轉置版（月份直向、年份橫向、近 8 年）----------
   桌機用原本那張，手機換成轉置版，兩張都在 HTML 裡，只切換顯示。
   viewBox 寬 320 在 375 上渲染成 343px，格內 11px 的字變成 11.8px。 */
.chart-heat-m { display: none; }
.chart-heat-m .hc.h0 { fill: var(--heat-0); } .chart-heat-m .hc.h1 { fill: var(--heat-1); }
.chart-heat-m .hc.h2 { fill: var(--heat-2); } .chart-heat-m .hc.h3 { fill: var(--heat-3); }
.chart-heat-m .hc.h4 { fill: var(--heat-4); } .chart-heat-m .hc.h5 { fill: var(--heat-5); }
.chart-heat-m .hc.h6 { fill: var(--heat-6); }
.chart-heat-m .hc.h-na { fill: color-mix(in srgb, var(--ink) 5%, transparent); }
.chart-heat-m .hv {
  fill: var(--ink-2); font-size: 11px; font-variant-numeric: tabular-nums;
}
.chart-heat-m .hv.hv-dark { fill: #f8fafc; }
.chart-heat-m .c-lab { fill: var(--ink-3); font-size: 11px; }
:root[data-theme="dark"] .chart-heat-m .hv.hv-dark { fill: #0f172a; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .chart-heat-m .hv.hv-dark { fill: #0f172a; }
}

@media (max-width: 719px) {
  .chart-heat { display: none; }
  .chart-heat-m { display: block; min-width: 0; width: 100%; }
}

/* ---------- B4. 國家頁的機場 × 航點矩陣 ---------- */
table.matrix td.mx-0 { color: var(--ink-4); }
table.matrix th[scope="row"] { min-width: 150px; }

/* ==========================================================================
   C／D 進場動畫
   規則：全部走 CSS transition（沒有動畫函式庫），只動 transform、opacity 與
   stroke-dashoffset，這三個不觸發重排，所以不會產生 CLS；元素的尺寸在
   HTML 就佔好了。`js-anim` 由 <head> 的小腳本在 paint 前決定，
   prefers-reduced-motion: reduce 或沒有 IntersectionObserver 時整組不生效。
   ========================================================================== */

/* ---------- C. 地圖畫線 ----------
   每條弧線帶 pathLength="100"（長度正規化）與 --d 延遲；SVG 本身是畫完的狀態，
   下面這兩條規則只在 js-anim 時把它倒回去再放出來。 */
.js-anim .chart-map .c-arc { stroke-dasharray: 100; stroke-dashoffset: 100; }
.js-anim .chart-map.anim-in .c-arc {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset var(--map-dur, 1200ms) ease-out var(--d, 0ms);
}
/* 終點的小圓點與航點名在線畫到之後才淡入 */
.js-anim .chart-map .c-dot, .js-anim .chart-map .c-dlab { opacity: 0; }
.js-anim .chart-map.anim-in .c-dot, .js-anim .chart-map.anim-in .c-dlab {
  opacity: 1;
  transition: opacity 300ms ease-out var(--dd, 0ms);
}

/* 航點名：跟出發機場同一種樣式，加白邊才不會被陸地色吃掉 */
.chart-map .c-dlab {
  fill: var(--ink-2); font-size: var(--fs-12); font-weight: 500;
  paint-order: stroke; stroke: var(--paper); stroke-width: 3px;
  stroke-linejoin: round;
}

/* ---------- D. 長條進場：0 長到目標寬 ----------
   用 scaleX 不用 width：transform 不觸發重排，量到的 CLS 才會是 0。 */
.js-anim .minibar > i, .js-anim .rank-bar > i, .js-anim .gs-bar > i,
.js-anim .chart-share .seg {
  transform: scaleX(0);
  transform-origin: left center;
  transform-box: fill-box;          /* SVG 的 rect 要用自己的框當原點 */
}
.js-anim .anim-in.minibar > i, .js-anim .anim-in.rank-bar > i,
.js-anim .anim-in.gs-bar > i, .js-anim .chart-share.anim-in .seg {
  transform: scaleX(1);
  transition: transform 600ms ease-out var(--d, 0ms);
}
/* 市佔條的段內文字等長條長到位再出現 */
.js-anim .chart-share .seg-t, .js-anim .chart-share .seg-t-rev { opacity: 0; }
.js-anim .chart-share.anim-in .seg-t, .js-anim .chart-share.anim-in .seg-t-rev {
  opacity: 1; transition: opacity 300ms ease-out 500ms;
}

/* ---------- D. 大數字：JS 從 0 跑到目標值 ----------
   HTML 內本來就是最終值，沒有 JS 或要求減少動態時直接顯示，不需要任何樣式。
   tabular-nums 已經在 .stat-v 上，跑動時字寬不會跳。 */
.stat-v { font-variant-numeric: tabular-nums; }

/* 使用者在系統層要求減少動態時，整組動畫不存在（雙保險，head 腳本已擋一次） */
@media (prefers-reduced-motion: reduce) {
  .js-anim .chart-map .c-arc { stroke-dasharray: none; stroke-dashoffset: 0; }
  .js-anim .chart-map .c-dot, .js-anim .chart-map .c-dlab { opacity: 1; }
  .js-anim .minibar > i, .js-anim .rank-bar > i, .js-anim .gs-bar > i,
  .js-anim .chart-share .seg { transform: none; }
  .js-anim .chart-share .seg-t, .js-anim .chart-share .seg-t-rev { opacity: 1; }
  * { transition-duration: 0.001ms !important; }
}

/* 「全部展開」是 <p>，會吃到 `p { max-width: 68ch }`，text-align: right 於是
   只靠到 540px 的地方而不是內容右緣（v4 就有，v5 順手修掉）。 */
.expandall { max-width: none; }
