/* ==========================================================================
   Surglasses 官網 —— 主樣式表
   風格：深色科技感 + 品牌綠 (#7BAF31) 點綴
   說明：本檔案不引用任何外部資源（無 Google Fonts、無 CDN），
         好處是載入快、無隱私外洩、CSP 可以設得非常嚴格。
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. 設計變數（改這裡就能全站換色 / 換間距）
   -------------------------------------------------------------------------- */
:root {
  /* 品牌色 —— 取自 Logo_Surglasses-Green.png 實際像素 */
  --brand: #7baf31;
  --brand-bright: #9ad449;
  --brand-dim: #5b8424;
  --brand-glow: rgba(123, 175, 49, 0.35);

  /* 點綴色（青藍）—— 取自 AI Table 機身上「ASCLEPIUS Ai」標誌的實際像素。
     全站是「綠為主、藍為輔」的兩色系統，分界是一條可以直接套用的規則：

       綠 = 可以互動的東西 + 大面積
            按鈕、文字連結、表單控制項、導覽的目前狀態、
            CTA 區塊、大數字（stat / metric）、hero 背景。
       藍 = 不能點的小裝飾
            小標籤（eyebrow）、打勾與圖示、細線、光暈、hover 邊框、
            小標記（office/location/新聞標籤）。

     這樣分的用意：綠色永遠等於「這裡可以按」，訪客不必重新學；
     藍色只是點綴，不承擔任何操作語意。頁首字標是綠的，也因此
     和按鈕保持一致，不會出現 logo 跟主色打架的問題。

     對比實測（對四種底色 --bg / --bg-raised / --surface / --surface-2）：
     #5ecdff 為 10.97 / 10.34 / 9.73 / 8.85，對應的綠 #9ad449 是
     11.19 / 10.54 / 9.93 / 9.03 —— 每一個都在 AAA，差距不到 0.2。 */
  --accent: #00a8f0;
  --accent-bright: #5ecdff;
  --accent-glow: rgba(0, 168, 240, 0.35);

  /* 深色底層（帶一點綠調的近黑，比純黑更有質感） */
  --bg: #080b0a;
  --bg-raised: #0e1412;
  --surface: #131b18;
  --surface-2: #1a2420;

  /* 文字。括號內是在 --bg 上的實測對比度（WCAG AA 需 4.5:1，AAA 需 7:1）。
     --text-faint 原本是 #6b7671，只有 4.19:1 未達 AA —— 它用在頁尾版權與
     法律連結這種小字上，更需要對比，所以調亮到剛好合格的最小值。 */
  --text: #e9efea;       /* 16.9:1  AAA */
  --text-muted: #9ca7a1; /*  8.0:1  AAA */
  --text-faint: #7b857f; /*  4.9:1  AA（在最淺的 --surface 上仍有 4.6:1） */

  --line: rgba(255, 255, 255, 0.09);
  --line-strong: rgba(255, 255, 255, 0.16);

  /* 表單欄位填錯時的提示色。刻意選偏橘的紅：純紅在深綠底上會偏暗，
     而且和品牌綠是互補色，撞在一起很刺眼。 */
  --danger: #ef8a6d;     /* 8.0:1  AAA（在最淺的 --surface-2 上仍有 6.5:1） */

  /* 排版 */
  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI Variable Display",
    "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans TC",
    "Microsoft JhengHei", sans-serif;

  /* 版面
     容器寬度用 rem 而不是 px，是為了配合下方的 4K 設定：
     只要調整 html 的 font-size，整個版面（字級、間距、圓角、容器寬）
     就會等比放大，不需要逐項調整。 */
  --container: 77.5rem;
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --section-y: clamp(4.5rem, 9vw, 8.5rem);

  --radius: 14px;
  --radius-lg: 22px;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --------------------------------------------------------------------------
   2. 重置與基礎
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* sticky header 高度，避免錨點跳轉時標題被遮住 */
  scroll-padding-top: 6rem;
  /* 告訴瀏覽器本站是深色的。表單的核取方塊、下拉選單展開後的清單、
     捲軸這些由作業系統畫的元件，CSS 管不到，只有這個屬性能讓它們跟著變深色。 */
  color-scheme: dark;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.0625rem);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

p {
  margin: 0;
}

/* blockquote 的瀏覽器預設值是 margin: 1em 40px，
   左右那 40px 會讓推薦卡片比它的格線欄位窄一截（而且會被誤認為間距沒對齊）。
   figure 預設也有左右邊距，同樣要清掉。 */
blockquote,
figure,
dl,
dd {
  margin: 0;
}

/* fieldset 的瀏覽器預設值有邊框、內距和左右邊距，
   放進表單的格線裡會比隔壁欄位窄一截，而且多出一圈灰框。 */
fieldset {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

legend {
  padding: 0;
}

img,
video,
picture {
  display: block;
  max-width: 100%;
  height: auto;
}

a {
  color: inherit;
  text-decoration: none;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

/* 鍵盤操作時才顯示外框，滑鼠點擊不顯示 —— 兼顧美觀與無障礙 */
:focus-visible {
  outline: 2px solid var(--brand-bright);
  outline-offset: 3px;
  border-radius: 4px;
}

/* 螢幕閱讀器專用文字 */
.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;
}

/* 跳到主內容（鍵盤使用者按 Tab 第一個看到的連結） */
.skip-link {
  position: fixed;
  top: 0.75rem;
  left: 0.75rem;
  z-index: 200;
  padding: 0.7rem 1.1rem;
  background: var(--brand);
  color: #06120a;
  font-weight: 700;
  border-radius: 8px;
  transform: translateY(-200%);
  transition: transform 0.2s var(--ease);
}

.skip-link:focus {
  transform: translateY(0);
}

/* --------------------------------------------------------------------------
   3. 版面容器
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  position: relative;
  padding-block: var(--section-y);
}

.section--tight {
  padding-block: clamp(3rem, 6vw, 5rem);
}

.section--raised {
  background: var(--bg-raised);
}

/* 區塊之間的細分隔線 */
.section--edge {
  border-top: 1px solid var(--line);
}

/* --------------------------------------------------------------------------
   4. 文字元件
   -------------------------------------------------------------------------- */

/* 小標籤（區塊上方的綠色小字） */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin-bottom: 1.1rem;
  color: var(--accent-bright);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.eyebrow::before {
  content: "";
  width: 1.75rem;
  height: 1px;
  background: currentColor;
  opacity: 0.7;
}

.eyebrow--plain::before {
  display: none;
}

/* 標題樣式必須自己帶字重與行高，不能依賴 h1~h4 標籤。
   原因是有些地方為了語意正確（例如每頁只能有一個 h1）會把標題
   寫成 <p class="h-display">，若字重只定義在 h1 選擇器上，
   那些地方就會掉回一般字重。 */
.h-display,
.h1,
.h2,
.h3 {
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.025em;
  text-wrap: balance;
}

.h-display {
  font-size: clamp(2.5rem, 1.4rem + 5vw, 5.25rem);
  letter-spacing: -0.04em;
}

.h1 {
  font-size: clamp(2.1rem, 1.5rem + 2.6vw, 3.5rem);
}

.h2 {
  font-size: clamp(1.75rem, 1.35rem + 1.7vw, 2.6rem);
}

.h3 {
  font-size: clamp(1.2rem, 1.08rem + 0.5vw, 1.45rem);
  letter-spacing: -0.015em;
}

.lead {
  max-width: 62ch;
  color: var(--text-muted);
  font-size: clamp(1.0625rem, 1rem + 0.35vw, 1.25rem);
  line-height: 1.65;
}

.body-muted {
  color: var(--text-muted);
}

.text-brand {
  color: var(--brand-bright);
}

/* 區塊標題群組 */
.section-head {
  max-width: 52rem;
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}

.section-head--center {
  margin-inline: auto;
  text-align: center;
}

.section-head p {
  margin-top: 1.1rem;
}

/* --------------------------------------------------------------------------
   5. 按鈕
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.95rem 1.75rem;
  /* 圓角。原本是 999px 的全膠囊型，量出來的按鈕高度約 56px，
     等於實際圓角 28px；使用者要求全站按鈕的倒角減少 10~15px，
     所以改成 14px（正好也是全站的 --radius，和卡片一致）。 */
  border-radius: 14px;
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
  transition: transform 0.2s var(--ease), background-color 0.2s var(--ease),
    border-color 0.2s var(--ease), box-shadow 0.2s var(--ease), color 0.2s var(--ease);
}

.btn:hover {
  transform: translateY(-2px);
}

.btn:active {
  transform: translateY(0);
}

.btn--primary {
  background: var(--brand);
  color: #06120a;
  box-shadow: 0 10px 30px -12px var(--brand-glow);
}

.btn--primary:hover {
  background: var(--brand-bright);
  box-shadow: 0 16px 40px -12px var(--brand-glow);
}

.btn--ghost {
  border: 1px solid var(--line-strong);
  color: var(--text);
  backdrop-filter: blur(6px);
}

.btn--ghost:hover {
  border-color: var(--brand);
  background: rgba(123, 175, 49, 0.1);
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
}

/* 內文段落後方的按鈕列，需要多一點上方留白。
   註：這些原本是寫成 inline style 的，但 .htaccess 的 CSP 會封鎖
   inline style 屬性（style-src-attr 回退到 style-src），因此改成 class。 */
.btn-row--spaced {
  margin-top: 2rem;
}

/* 置中的單行連結 */
.text-center {
  text-align: center;
}

.mt-lg {
  margin-top: 2.25rem;
}

/* 用 h2 的語意但不要 h2 的視覺重量（獎項區的說明文字） */
.h-subtle {
  font-weight: 600;
}

/* 文字型連結（帶箭頭） */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--brand-bright);
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.link-arrow svg {
  transition: transform 0.25s var(--ease);
}

.link-arrow:hover svg {
  transform: translateX(4px);
}

/* --------------------------------------------------------------------------
   6. 頁首 / 導覽
   -------------------------------------------------------------------------- */
.header {
  position: sticky;
  top: 0;
  z-index: 100;
  transition: background-color 0.3s var(--ease), border-color 0.3s var(--ease),
    backdrop-filter 0.3s var(--ease);
  border-bottom: 1px solid transparent;
}

/* 選單展開時,後方整頁蓋一層遮罩:選單在最上層,後方內容不可點擊(點遮罩會關閉選單)。
   遮罩是 .header 的偽元素(固定、鋪滿視窗、墊在頁首內容之下),所以不需要多一個 DOM 節點。
   選單用 hover 或點擊展開,兩種狀態都要涵蓋。 */
.header::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: rgba(2, 4, 3, 0.62);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.2s var(--ease), visibility 0.2s;
}

.header:has(.nav__item--menu:hover .nav__menu)::after,
.header:has(.nav__trigger[aria-expanded="true"])::after,
.header:has(.nav.is-open)::after {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* 在頁面最上方時，頁首後面是正在播放的首屏影片。
   影片內容一直在變，導覽文字很容易被亮的畫面吃掉，
   所以鋪一層由上往下淡出的暗色漸層。

   刻意讓它比頁首本身高（bottom: -2.5rem），漸層才會延伸到頁首下緣之外，
   看起來是「畫面頂端自然變暗」而不是「有一條深色橫帶」。 */
.header::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: -2.5rem;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    rgba(8, 11, 10, 0.78) 0%,
    rgba(8, 11, 10, 0.55) 45%,
    rgba(8, 11, 10, 0.22) 74%,
    transparent 100%
  );
  transition: opacity 0.35s var(--ease);
}

/* 捲動後改用實心毛玻璃，漸層就不需要了（兩個疊在一起會過暗） */
.header.is-stuck::before {
  opacity: 0;
}

.header.is-stuck {
  background: rgba(8, 11, 10, 0.82);
  backdrop-filter: blur(16px) saturate(160%);
  border-bottom-color: var(--line);
}

.header__inner {
  display: flex;
  align-items: center;
  gap: 1.5rem;
  min-height: 4.75rem;
}

/* 橫式字標：以寬度控制大小，比控制高度更好對齊 */
.header__logo img {
  width: clamp(9rem, 13vw, 11.5rem);
  height: auto;
}

.nav {
  margin-left: auto;
}

.nav__list {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}

.nav__link {
  display: inline-block;
  padding: 0.55rem 0.85rem;
  border-radius: 8px;
  color: var(--text-muted);
  font-size: 0.9rem;
  font-weight: 600;
  transition: color 0.2s var(--ease), background-color 0.2s var(--ease);
}

.nav__link:hover,
.nav__link[aria-current="page"] {
  color: var(--text);
  background: rgba(255, 255, 255, 0.06);
}


/* --------------------------------------------------------------------------
   6b. 下拉選單

   觸發元素用 <button> 而不是 <a>：它不會連到任何地方，只是展開選單。
   用 <a href="#"> 會讓鍵盤與螢幕閱讀器使用者以為那是一個連結。
   總覽頁另外放在選單裡的第一項（Overview）。
   -------------------------------------------------------------------------- */
.nav__item {
  position: relative;
}

.nav__trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}

.nav__chevron {
  flex-shrink: 0;
  opacity: 0.55;
  transition: transform 0.25s var(--ease), opacity 0.2s var(--ease);
}

.nav__item--menu:hover .nav__chevron,
.nav__trigger[aria-expanded="true"] .nav__chevron {
  opacity: 1;
}

.nav__trigger[aria-expanded="true"] .nav__chevron {
  transform: rotate(180deg);
}

.nav__menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 10;
  min-width: 15rem;
  padding: 0.45rem;
  /* 與觸發按鈕之間留一點距離，但用 margin 會產生滑鼠移動時的斷層，
     所以改用 border-top 撐開一段透明區域當「橋」，游標移過去不會關閉 */
  border-top: 0.55rem solid transparent;
  background-clip: padding-box;
  background-color: rgba(14, 20, 18, 0.97);
  backdrop-filter: blur(16px) saturate(160%);
  border-radius: var(--radius);
  box-shadow: 0 18px 40px -18px rgba(0, 0, 0, 0.85);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-0.4rem);
  transition: opacity 0.22s var(--ease), transform 0.22s var(--ease),
    visibility 0.22s;
}

/* 選單本體加一圈細框。因為 border-top 已經被拿去當「橋」，
   這裡用 outline 補其餘三邊，才不會影響上方的透明區域。 */
.nav__menu::before {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid var(--line-strong);
  border-radius: inherit;
  pointer-events: none;
}

.nav__item--menu:hover .nav__menu,
.nav__item--menu:focus-within .nav__menu,
.nav__trigger[aria-expanded="true"] + .nav__menu {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.nav__menu a {
  display: block;
  padding: 0.6rem 0.85rem;
  border-radius: 9px;
  color: var(--text-muted);
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.35;
  white-space: nowrap;
  transition: color 0.18s var(--ease), background-color 0.18s var(--ease);
}

.nav__menu a:hover,
.nav__menu a:focus-visible {
  color: var(--text);
  background: rgba(123, 175, 49, 0.14);
}

.nav__menu a[aria-current="page"] {
  color: var(--brand-bright);
  background: rgba(123, 175, 49, 0.1);
}

/* 目前這一頁所屬的分類：觸發按鈕也要看得出來是「所在位置」。
   data-current 是 tools/sync-shell.py 自動標上去的。 */
.nav__trigger[data-current="true"] {
  color: var(--text);
}

.nav__trigger[data-current="true"]::after {
  content: "";
  position: absolute;
  left: 0.85rem;
  right: 0.85rem;
  bottom: 0.15rem;
  height: 2px;
  border-radius: 2px;
  background: var(--accent-bright);
}

.nav__trigger {
  position: relative;
}

/* 選單第一項是總覽頁，用一條分隔線和其餘子頁區隔。
   （這是給「一欄式」下拉選單用的。目前四個選單都是 §6c 的大選單，
   所以這條規則現在沒有作用；留著是為了將來再加一個單純的下拉選單。）

   :not(.nav__mega) 不是防禦性寫法，是修一個實際的錯：大選單裡有好幾個
   「自己是第一個 <a>」的連結 —— 每欄的 Learn、每個章節清單的第一項 ——
   這條規則會把它們全部改成 --text 並加粗，於是 Learn 是白的、Demo 是綠的，
   四個章節清單的第一行也比其他行亮。0-2-1 比元件自己的 0-2-0 高，
   在元件那邊逐條加特異性只會沒完沒了，所以在來源這裡限定範圍。 */
.nav__menu:not(.nav__mega) a:first-child {
  margin-bottom: 0.3rem;
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--line);
  border-radius: 9px 9px 0 0;
  color: var(--text);
  font-weight: 600;
}

/* --------------------------------------------------------------------------
   6c. 大選單（Medical Devices / Medical Education）

   使用者 2026-08-24 選定的樣式，來源是設計稿 website surglass.pdf：
   面板橫跨整個頁首寬度，每個產品一欄 —— 大圖、產品名、一句說明、
   Learn / Demo，下面接該產品的章節連結，欄與欄之間一條細分隔線。

   刻意「只加不改」：§6b 的下拉選單一行都沒動，這裡只是替同一組
   .nav__item--menu / .nav__trigger / .nav__menu 換一種內容排法。
   所以 main.js 的點擊開合、Esc 關閉、方向鍵、手機展開全部照舊生效，
   一行 JS 都不用改。

   Company / Connect 沒有產品可以放，用 .mega__inner--lists（純連結欄，
   置中），對應設計稿裡的 About Us 那一版。

   三件量過、不要重新推導的事：
     1. 圖片舞台用固定高度 9.5rem，不是 aspect-ratio。第一欄和最後一欄
        沒有左右內距（要對齊 .container 的邊），欄寬因此和中間兩欄不同，
        用 aspect-ratio 會讓舞台高度跟著欄寬跑，四個產品名就差了 17px。
     2. 各欄用 subgrid 對齊四列。說明文字有的一行有的兩行，不對齊的話
        Learn / Demo 和章節連結會各自高低不一。不支援 subgrid 的舊瀏覽器
        只是回到各欄自行排列，不會壞掉。
     3. Learn / Demo 的底線是必要的，不是裝飾：--brand-bright 對旁邊的
        --text-muted 只有 1.41:1，只靠顏色不合 WCAG 1.4.1。面板底色
        （#0b100e）上量到 --text 16.44:1、--text-muted 7.72:1、
        --text-faint 5.03:1、--brand-bright 10.86:1，全部過 AA。

   選單圖片一律用 assets/img/nav-*.webp（480 寬，見 build-assets.py 的
   NAV_THUMBS）。頁首每一頁都帶著，直接引用原檔是七張共 1,033 KB，
   縮圖版是 200 KB，而舞台最寬也只有 428px（4K）。
   -------------------------------------------------------------------------- */
@media (min-width: 62rem) {

  /* 面板要跨滿整個頁首寬度，定位基準必須是 .header 而不是那一顆選單項目，
     所以把 .nav__item 的 position: relative 拿掉（.header 本身是 sticky，
     已經是定位基準，不用另外加東西）。 */
  .nav__item--mega {
    position: static;
  }

  .nav__mega {
    left: 0;
    right: 0;
    min-width: 0;
    padding: 0;
    border-radius: 0;
    /* 面板往上移，貼近選單按鈕（使用者 2026-08-24 指定：整塊往上移，寬度不動）。
       §6b 的 top: 100% 對齊的是「頁首下緣」＝ 76px，而按鈕下緣在 59.03px ——
       中間那 17px 是游標會掉出去、選單被關掉的那一段。

       **上限是「Contact Us」**，不是選單按鈕：那顆按鈕比選單按鈕高 4px，下緣在
       61.08px（3.818rem）。第一版寫 1.125rem（面板上緣 58px）確實貼齊了選單按鈕，
       但那顆綠色按鈕的下緣就被面板疊上去了，使用者回報「太貼了，Contact Us 的
       綠色會被壓到」。所以現在取 0.875rem：
         面板上緣 = 4.75rem − 0.875rem = 3.875rem
         Contact Us 下緣 = (4.75rem + 2.886rem) ÷ 2 = 3.818rem
       面板上緣落在它下面 0.057rem（16px 時 0.9px、21px 時 1.2px），兩者不重疊，
       所以也不需要再幫那顆按鈕加 z-index。
       剩下的 3px 縫由 .nav__trigger::before 補（見下面），那塊補丁只有 4px 高、
       完全留在頁首裡面，不會像先前 24px 的版本壓到產品頁的子導覽。 */
    top: calc(100% - 0.875rem);
    /* 完全不透明(執行長 2026-11-09:後方頁面內容不可透出),並加上下緣細線與陰影 */
    background-color: #0b100e;
    backdrop-filter: none;
    box-shadow: 0 26px 60px -12px rgba(0, 0, 0, 0.95);
    /* ★ 這一行是修一個看得見的缺陷，不要拿掉（使用者 2026-08-24 回報）。
       §6b 用「8px 透明的 border-top」當滑鼠的橋，讓游標從按鈕移到選單的途中
       不會離開 .nav__item--menu 而把選單關掉。窄選單時那 8px 只有 15rem 寬、
       壓在頁面上看不出來；改成全寬面板之後它變成一條橫跨整個畫面的透明帶，
       而 backdrop-filter 是作用在 border box 上（不是 padding box），
       所以那 8px 會把後面的首屏影片模糊＋提高飽和度 —— 實測就是一條毛玻璃縫，
       首屏畫面亮的時候特別明顯。
       §6b 的 background-clip: padding-box 正是把背景裁掉、讓那條帶子透明的原因。
       改成 border-box 之後背景會塗滿整個 border box，帶子變成面板自己的顏色，
       縫消失，而「橋」還在（那 8px 仍然屬於這個元素，滑鼠事件照舊）。 */
    background-clip: border-box;
  }

  /* 按鈕下緣 59.03px 到面板上緣 62px 之間還有 3px。游標慢慢移過那 3px 時
     .nav__item--menu:hover 會不成立，選單就關掉了，所以用按鈕自己的 ::before
     把它接起來：它是 li 的子孫，游標在上面 hover 仍然成立，而且完全看不見。

     0.25rem = 4px，蓋過 3px 的縫還多 1px；底部落在 63px，離頁首下緣（77px）
     還有 14px —— 這一點很重要：先前有一版寫 1.5rem（24px），底部跑到 83px，
     把九支產品頁子導覽三個連結的上緣 6px 蓋掉了（子導覽上緣就在 77px）。
     這一版沒有那個問題，寬度也只有按鈕本身（加寬會和隔壁按鈕的那塊重疊，
     變成移到邊界時換隔壁的選單打開）。 */
  .nav__item--mega .nav__trigger::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    height: 0.25rem;
  }

  /* 「使用者主動點第二次收起來」的狀態，必須蓋過 :hover ——
     點完之後游標還在按鈕上，光把 aria-expanded 改掉沒有用（見 main.js §2b）。
     這裡 0-3-1 比 §6b 那條 :hover 規則的 0-2-1 高，所以贏得過。
     旗標只活到游標離開這顆選單為止，所以 hover 展開的行為不會被永久關掉。 */
  .nav__item--menu.is-collapsed:hover .nav__menu,
  .nav__item--menu.is-collapsed:focus-within .nav__menu {
    opacity: 0;
    visibility: hidden;
    transform: translateY(-0.4rem);
  }

  /* §6b 的 ::before 是四邊細框；全寬面板只需要下緣一條線 */
  .nav__mega::before {
    border: 0;
    border-bottom: 1px solid var(--line-strong);
    border-radius: 0;
  }

  .nav__mega a {
    padding: 0;
    border-radius: 0;
    white-space: normal;
  }

  /* §6b 的 a[aria-current="page"] 會鋪一層綠色底。整張產品卡（含圖片舞台）
     被鋪滿會很突兀，改成只把產品名變綠。 */
  .nav__mega a[aria-current="page"] {
    background: none;
  }

  .nav__mega a[aria-current="page"] .mega__name {
    color: var(--brand-bright);
  }

  .mega__inner {
    padding: 2.25rem 0 2.5rem;
  }

  /* 面板最上面一行：分類名稱 + 總覽頁連結 */
  .mega__top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 1.75rem;
    margin-bottom: 1.75rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--line);
  }

  /* 這一行和下面的格線各自帶留白，相鄰時會加倍 */
  .mega__top + .mega__inner {
    padding-top: 0;
  }

  .mega__top-label {
    color: var(--text-faint);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
  }

  .nav__mega .mega__all {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--brand-bright);
    font-size: 0.875rem;
    font-weight: 600;
  }

  .nav__mega .mega__all:hover,
  .nav__mega .mega__all:focus-visible {
    background: none;
    text-decoration: underline;
    text-underline-offset: 3px;
  }

  /* 產品牆 */
  .mega__inner--wall {
    display: grid;
    gap: 0;
    grid-template-rows: auto auto auto auto;
  }

  .mega__inner--wall.mega--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .mega__inner--wall.mega--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

  /* 三個產品 + 一塊純連結區（Medical Education 的 Institutions / Applications） */
  .mega__inner--wall.mega--3-lists {
    grid-template-columns: repeat(3, minmax(0, 1fr)) 1.4fr;
  }

  .mega__col {
    padding: 0 1.6rem;
  }

  .mega__col + .mega__col {
    border-left: 1px solid var(--line);
  }

  .mega__col:first-child { padding-left: 0; }
  .mega__col:last-child  { padding-right: 0; }

  /* 各欄對齊母格線的四列（圖＋名稱／說明／Learn-Demo／章節連結） */
  .mega__inner--wall .mega__col {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
    align-content: start;
  }

  /* 純連結那一欄不吃 subgrid：它自己是兩組並排，列數不一樣 */
  .mega__inner--wall .mega__col--lists {
    grid-template-rows: none;
  }

  /* 產品都是黑色機身，直接放在近黑背景上會消失，
     所以和 .split__media--stage 一樣給一點光暈。 */
  .mega__shot {
    display: block;
    height: 9.5rem;
    margin-bottom: 0.9rem;
    padding: 0.5rem;
    border-radius: var(--radius);
    background:
      radial-gradient(60% 70% at 50% 62%, rgba(0, 168, 240, 0.14), transparent 70%),
      var(--surface);
    transition: background-color 0.2s var(--ease);
  }

  .mega__shot img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
  }

  .nav__mega .mega__product {
    display: block;
  }

  .mega__name {
    display: block;
    color: var(--text);
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1.35;
    transition: color 0.18s var(--ease);
  }

  .nav__mega .mega__product:hover .mega__name,
  .nav__mega .mega__product:focus-visible .mega__name {
    color: var(--brand-bright);
  }

  .nav__mega .mega__product:hover .mega__shot {
    background:
      radial-gradient(60% 70% at 50% 62%, rgba(0, 168, 240, 0.2), transparent 70%),
      var(--surface-2);
  }

  .nav__mega .mega__product:hover,
  .nav__mega .mega__product:focus-visible {
    background: none;
  }

  .mega__note {
    margin: 0.35rem 0 0;
    color: var(--text-muted);
    font-size: 0.8125rem;
    line-height: 1.5;
  }

  .mega__cues {
    display: flex;
    gap: 1.1rem;
    margin: 0.85rem 0 1.1rem;
  }

  .nav__mega .mega__cue {
    color: var(--brand-bright);
    font-size: 0.8125rem;
    font-weight: 600;
    text-decoration: underline;
    text-decoration-color: rgba(154, 212, 73, 0.45);
    text-underline-offset: 3px;
  }

  .nav__mega .mega__cue:hover,
  .nav__mega .mega__cue:focus-visible {
    background: none;
    text-decoration-color: currentColor;
  }

  .mega__label {
    margin: 0 0 0.5rem;
    color: var(--text-faint);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
  }

  .nav__mega .mega__links a {
    display: block;
    padding: 0.38rem 0;
    color: var(--text-muted);
    font-size: 0.875rem;
    font-weight: 500;
    line-height: 1.35;
  }

  .nav__mega .mega__links a:hover,
  .nav__mega .mega__links a:focus-visible {
    color: var(--text);
    background: none;
    text-decoration: underline;
    text-underline-offset: 3px;
  }

  /* 產品牆右側那一塊純連結區（兩組並排） */
  .mega__col--lists {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.75rem;
    align-content: start;
  }

  /* 沒有產品圖的選單（Company / Connect）。
     內容置中 —— 這兩顆按鈕在頁首偏右，連結靠左會看起來和按鈕斷開。 */
  .mega__inner--lists {
    display: flex;
    justify-content: center;
    gap: 4.5rem;
  }

  .mega__inner--lists .mega__group {
    min-width: 12rem;
  }
}

/* 手機版的大選單。
   §21 是全站的手機版區塊，但大選單的規則放在元件自己這裡比較好維護
   （和 .dotnav 的做法一樣）。面板退回 §6b 原本的展開式清單：
   圖片、說明、Learn / Demo 全部收起來，只留可以點的文字。

   也刻意不列每個產品的章節連結 —— 四個產品 × 四個章節，實測展開後
   995px，要滑很久；收掉後 341px，和原本的選單一樣長。章節在頁面裡
   本來就找得到。Company / Connect 的連結不受影響（那才是它們的內容）。 */
@media (max-width: 61.9375rem) {
  .mega__shot,
  .mega__note,
  .mega__cues,
  .mega__top-label {
    display: none;
  }

  .mega__inner,
  .mega__col--lists {
    display: block;
    padding: 0;
    border: 0;
  }

  .mega__top {
    margin-bottom: 0.25rem;
  }

  .mega__inner--wall .mega__col:not(.mega__col--lists) > .mega__links {
    display: none;
  }

  .nav__mega .mega__name,
  .nav__mega .mega__all {
    display: block;
    padding: 0.7rem 0.75rem;
    color: var(--text);
    font-size: 0.9375rem;
    font-weight: 600;
  }

  .nav__mega a[aria-current="page"] .mega__name {
    color: var(--brand-bright);
  }

  .mega__label {
    margin: 0.6rem 0 0.1rem;
    padding: 0 0.75rem;
    color: var(--text-faint);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
  }

  .nav__mega .mega__links a {
    display: block;
    padding: 0.6rem 0.75rem 0.6rem 1.5rem;
    color: var(--text-muted);
    font-size: 0.9375rem;
  }
}

.header__cta {
  padding: 0.7rem 1.35rem;
  font-size: 0.875rem;
}

/* 漢堡按鈕（只在手機顯示） */
.nav-toggle {
  display: none;
  margin-left: auto;
  width: 2.75rem;
  height: 2.75rem;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
}

.nav-toggle__bars,
.nav-toggle__bars::before,
.nav-toggle__bars::after {
  display: block;
  width: 1.1rem;
  height: 2px;
  background: var(--text);
  transition: transform 0.25s var(--ease), opacity 0.2s var(--ease);
}

/* 這一段的 position / will-change 都是修 bug 用的，不是排版用的。
   使用者實機回報：手機上三槓變成 X 的時候，X 左邊會多出兩個小白點，
   而且「捲動一陣子之後才會消失」。

   關鍵線索是使用者補充的第二句：**只有先捲動過頁面才會發生，一載入就按不會**。
   捲動會讓 .header 加上 .is-stuck，而 .is-stuck 才有
   backdrop-filter: blur(16px) saturate(160%)。也就是說毛玻璃那一層是前提 ——
   iOS Safari 在毛玻璃圖層上方做小面積的 transform 動畫時，重繪範圍會算少一塊，
   動畫中間某一格的舊畫面就留在上面沒被擦掉，要等別的事件觸發整片重繪才消失。
   （這也解釋了為什麼「多滑一下就好了」。）

   兩道修法，兩件不同的事：

   1) 讓按鈕自己成為一個合成層（下面 §21 的 transform: translateZ(0)），
      動畫就不必去動頁首那層毛玻璃。**不可以改成在 .header 上加 transform** ——
      手機版的 .nav 是 position: fixed 且是 .header 的子孫，頁首一有 transform
      就會變成它的容器，整個選單面板會定位錯掉。

   2) 把虛擬元素的定位參考對象固定住。展開時 .nav-toggle__bars 會拿到
      transform，而一個元素只要有 transform 就成為子孫絕對定位的 containing
      block —— 收合／展開之間，兩個虛擬元素的參考對象會在動畫頭尾各換一次
      （收合時參考 .nav-toggle，展開時參考這條線本身）。兩種算法在這裡剛好
      落在同一個位置，所以畫面上看不出來，但那正是「重繪範圍算不準」的溫床。
      固定成 relative、並把 left/top 寫死（不要依賴 flex 容器的 static
      position 自動置中），兩個狀態就完全一致。

   改完的畫面和改之前逐像素相同（用 SVG foreignObject 把兩版規則各畫一次、
   放大 8 倍比對，收合與展開兩種狀態都是 0 個像素有差）。 */
.nav-toggle__bars {
  position: relative;
  will-change: transform;
}

.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  will-change: transform, opacity;
}

.nav-toggle__bars::before {
  transform: translateY(-6px);
}

.nav-toggle__bars::after {
  transform: translateY(6px);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars {
  transform: rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before {
  opacity: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after {
  transform: rotate(-90deg);
}

/* --------------------------------------------------------------------------
   7. Hero 首屏
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  /* 減去頁首高度，讓首屏剛好一個視窗高 */
  min-height: min(92vh, 62rem);
  display: flex;
  align-items: center;
  margin-top: -4.75rem;
  padding-top: 4.75rem;
  overflow: hidden;
  isolation: isolate;
}

.hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
}

/* 首屏每一張背景：只有淡入淡出，沒有縮放。

   ★ 不要把 transform / scale 加回這一層。

   原本這裡有一個「緩慢拉遠」的效果（scale(1.06) -> scale(1)，8 秒）。
   使用者回報背景影片在播放時會抖動，而且抖動的範圍正好是縮放進行中
   ——「漸遠效果結束後就不會抖了」。原因是縮放比例每一幀都在變，
   影片畫面也每一幀都在變，所以一張 1920x1080 的影片畫面每一幀都得
   按新的比例重新合成一次，和影片解碼互相搶資源。

   在移除之前先試過三個比較保守的做法，都沒有解決抖動：
     1. 把 will-change 放到正在動的那一層（原本錯放在裡面的 <video> 上）。
     2. 讓已經看不見的那幾張不要再跑 8 秒的反向縮放動畫，
        把同時在動的圖層數從 2～3 層降到 1 層。
     3. 把 brightness/saturate 濾鏡烙進影片檔案，不在瀏覽器即時套。
        ——「這一項保留」，見下面的 .hero__video。它本身是正確的最佳化
        （少掉每一幀一次濾鏡運算），只是不足以消除抖動。
   最後由使用者決定直接移除縮放效果（2026-08-27）。

   靜止時的構圖沒有變：原本動畫的終點就是 scale(1)，也就是現在的狀態，
   只有動畫「起點」的那 6% 放大消失了。 */
.hero__slide-bg {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1.2s var(--ease);
}

.hero__slide-bg.is-active {
  opacity: 1;
}

.hero__slide-bg img,
.hero__slide-bg video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* 首屏背景影片 */
.hero__video {
  display: block;

  /* 這裡刻意「沒有」兩樣東西，兩者都是為了消除實測到的卡頓，不要加回來：

     1. 沒有 filter。素材偏暗，以前是用
            filter: brightness(1.22) saturate(1.08)
        在瀏覽器裡即時提亮。影片每一幀都在變，所以這個濾鏡每一幀都要重算
        一次，永遠無法重複利用。2026-08-27 起改成在轉檔時就烙進影片與
        封面圖（tools/build-video.py 的 brighten 旗標與 CSS_FILTER_MATRIX），
        顏色實測與舊做法相同（平均差 0.451/255、最大 4/255）。
        要改亮度請改那邊並重轉，不要在這裡加 filter。

     2. 沒有 will-change。<video> 本身沒有動畫，而 will-change 也不會影響
        影片解碼是否用 GPU —— 舊註解寫「影片解碼交給 GPU」是誤解。
        放在這裡只會讓三個 <video> 各自常駐一個合成圖層，白白佔資源。

     注意 <video> 一定要有 muted 屬性，否則瀏覽器會封鎖自動播放
     （有聲音的影片不准自動播，這是所有瀏覽器的共同政策）。 */
}

/* 疊在背景圖上的漸層，確保文字永遠讀得清楚 */
/* 背景影片本身就是暗的（夜間地球平均亮度只有 40/255），
   所以遮罩不能整片壓黑，否則畫面等於全黑。
   做法是只在左側文字所在的區域壓暗（確保文字對比度），
   右側幾乎放清，讓影片內容看得見。 */
.hero__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
      100deg,
      rgba(8, 11, 10, 0.9) 0%,
      rgba(8, 11, 10, 0.72) 30%,
      rgba(8, 11, 10, 0.22) 58%,
      rgba(8, 11, 10, 0.05) 78%,
      rgba(8, 11, 10, 0.3) 100%
    ),
    linear-gradient(to top, var(--bg) 0%, transparent 24%);
}

.hero__inner {
  position: relative;
  width: 100%;
  padding-block: clamp(4rem, 10vh, 7rem);
}

.hero__slides {
  display: grid;
}

.hero__slide {
  grid-area: 1 / 1;
  max-width: 54rem;
  opacity: 0;
  visibility: hidden;
  transform: translateY(1.5rem);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease),
    visibility 0.7s;
}

.hero__slide.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.hero__title {
  margin-bottom: 1.5rem;
}

.hero__title span {
  display: block;
}

/* 第二行用綠色，做出層次 */
.hero__title span + span {
  color: var(--brand-bright);
}

.hero__sub {
  max-width: 44ch;
  margin-bottom: 2.25rem;
  color: rgba(233, 239, 234, 0.86);
  font-size: clamp(1.0625rem, 1rem + 0.4vw, 1.3125rem);
}

/* Hero 分頁指示器 */
.hero__dots {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: clamp(2.5rem, 6vh, 4rem);
}

.hero__dot {
  position: relative;
  width: 2.75rem;
  height: 3px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.22);
  overflow: hidden;
  transition: background-color 0.3s var(--ease);
}

.hero__dot::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--brand-bright);
  transform: scaleX(0);
  transform-origin: left;
}

/* 進度條的時間由 JS 依「該張背景影片的長度」算出後寫進 --dwell，
   所以進度條走完的瞬間就是換頁的瞬間，兩者不可能不同步。
   7s 只是影片還沒載入時的備用值。 */
.hero__dot.is-active::after {
  animation: dot-fill var(--dwell, 7s) linear forwards;
}

@keyframes dot-fill {
  to {
    transform: scaleX(1);
  }
}

/* 首屏底部的向下捲動提示 */
.hero__scroll {
  position: absolute;
  bottom: 1.75rem;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  color: var(--text-faint);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.hero__scroll span:last-child {
  width: 1px;
  height: 2.25rem;
  background: linear-gradient(to bottom, var(--brand-bright), transparent);
  animation: scroll-hint 2.4s var(--ease) infinite;
}

@keyframes scroll-hint {
  0%,
  100% {
    opacity: 0.25;
    transform: scaleY(0.4);
    transform-origin: top;
  }
  50% {
    opacity: 1;
    transform: scaleY(1);
    transform-origin: top;
  }
}

/* --------------------------------------------------------------------------
   7b. 內頁首屏
        首頁的 .hero 是整個視窗高、帶背景影片的版本，內頁不需要那麼重。
        這裡是給 contact / about / 產品頁共用的輕量版：只有標題、說明與按鈕，
        背景用左上角一團品牌綠光暈接到頁面底色，做出和首頁一致的調性。
   -------------------------------------------------------------------------- */
.page-hero {
  position: relative;
  padding-top: clamp(3.5rem, 8vw, 6.5rem);
  padding-bottom: clamp(3rem, 7vw, 5.5rem);
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(ellipse 75% 90% at 10% 0%, rgba(123, 175, 49, 0.15), transparent 62%),
    linear-gradient(180deg, var(--bg-raised), var(--bg));
  overflow: hidden;
}

.page-hero__inner {
  position: relative;
}

/* 標題本身收窄就好，不能把 .container 收窄 ——
   .container 有 margin-inline: auto，一旦給它 max-width，
   整段內容會變成置中，就對不上底下區塊的左邊界了。 */
.page-hero__title {
  max-width: 20ch;
  margin-bottom: 1.5rem;
}

/* 內頁 hero 的配圖（選用 —— 加上 .page-hero--media 才會出現）。
   純文字的 hero 仍然是預設，沒有合適素材的頁面什麼都不用改。

   圖片用絕對定位掛在 .page-hero 上（它本來就有 position: relative
   和 overflow: hidden），才能突破 .container 的寬度限制、一路出血到
   視窗右緣。DOM 順序上圖片放在 .page-hero__inner 前面，
   兩者都是定位元素，後畫的文字自然蓋在上面，不必動 z-index。

   左緣用 mask 淡出，圖片才會「融進」背景，而不是貼上去的一塊矩形；
   淡出範圍給到 55%，是為了確保就算文字排到圖片區域的左半邊，
   那裡的圖片也已經幾乎全透明 —— 文字永遠不會壓在有內容的畫面上，
   所以不需要為對比度另外加暗色遮罩。 */
.page-hero__media {
  display: none;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 46%;
}

.page-hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.9;
}

/* 窄螢幕不顯示配圖。內頁 hero 要維持精簡 ——
   在 390px 手機上把 3:2 的圖疊上去，標題和按鈕會被整個推出畫面外。
   用 display: none 而不是 visibility，圖片才不會進入視埠；
   配上 loading="lazy"，手機上這張圖根本不會被下載。 */
@media (min-width: 64rem) {
  .page-hero--media .page-hero__media {
    display: block;
    -webkit-mask-image: linear-gradient(to right, transparent, #000 55%);
    mask-image: linear-gradient(to right, transparent, #000 55%);
  }

  /* 收窄的是裡面的文字，不是 .container ——
     .container 有 margin-inline: auto，一給它 max-width 整段就會置中，
     左邊界就對不上底下的區塊了（和上面 .page-hero__title 同一個理由）。 */
  .page-hero--media .lead {
    max-width: min(40ch, var(--hero-text-max));
  }

  /* 首屏的法規說明等小字也要收窄,不可延伸到右側配圖上(1024 到 1440 寬度都不壓圖)。
     以視窗寬度為上限:配圖從 54% 處開始,文字欄最寬到 54vw 減去左側留白。 */
  .page-hero--media {
    --hero-text-max: calc(54vw - max(2.5rem, (100vw - 71.5rem) / 2) - 2rem);
  }
  .page-hero--media .body-muted {
    max-width: min(46ch, var(--hero-text-max));
    margin-top: 1rem;
  }

  /* 標題與小標也收窄(長標題、長小標在 1024 到 1280 寬度會延伸到配圖上) */
  .page-hero--media .page-hero__title {
    max-width: min(20ch, var(--hero-text-max));
  }
  .page-hero--media .eyebrow {
    max-width: var(--hero-text-max);
  }

  /* 從右到左的語言(阿拉伯文):文字靠右,配圖改放左側,淡出方向相反,避免文字壓在圖上 */
  html[dir="rtl"] .page-hero--media .page-hero__media {
    right: auto;
    left: 0;
    -webkit-mask-image: linear-gradient(to left, transparent, #000 55%);
    mask-image: linear-gradient(to left, transparent, #000 55%);
  }
}

/* --------------------------------------------------------------------------
   8. 產品雙欄（解剖桌 / AR 導航）
   -------------------------------------------------------------------------- */
.split {
  display: grid;
  gap: clamp(2.5rem, 6vw, 5rem);
  align-items: center;
  grid-template-columns: 1fr;
}

@media (min-width: 62rem) {
  .split {
    grid-template-columns: 1fr 1fr;
  }

  /* 交錯排版：偶數區塊圖片放左邊 */
  .split--reverse .split__media {
    order: -1;
  }
}

.split__media {
  position: relative;
}

/* 圖片後方的綠色光暈，讓透明背景的產品圖浮起來 */
.split__media::before {
  content: "";
  position: absolute;
  inset: 8% 4%;
  z-index: -1;
  background: radial-gradient(circle at 50% 50%, var(--accent-glow), transparent 68%);
  filter: blur(48px);
}

.split__media img,
.split__media video {
  width: 100%;
  border-radius: var(--radius-lg);
}

/* 「展示台」：解剖桌與 AR 眼鏡的機身是黑色的，直接放在近黑背景上會看不見。
   這裡用一層較亮的橢圓漸層當背景，讓深色產品有對比可以浮出來。 */
.split__media--stage {
  padding: clamp(1rem, 2.5vw, 2rem);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background:
    radial-gradient(ellipse 62% 55% at 50% 58%, rgba(0, 168, 240, 0.18), transparent 72%),
    radial-gradient(ellipse 95% 85% at 50% 42%, rgba(255, 255, 255, 0.085), transparent 70%),
    linear-gradient(165deg, var(--surface-2), var(--bg-raised) 70%);
  overflow: hidden;
}

/* 展示台不需要外層那圈額外光暈，會疊得太亮 */
.split__media--stage::before {
  display: none;
}

/* 產品圖本身不裁圓角（透明背景，裁了也看不出來） */
.split__media--stage img,
.split__media--stage video {
  border-radius: 0;
}

/* 台面上的一道地平線，暗示產品「站」在平面上 */
.split__media--stage::after {
  content: "";
  position: absolute;
  left: 12%;
  right: 12%;
  bottom: 16%;
  height: 1px;
  background: linear-gradient(
    to right,
    transparent,
    rgba(0, 168, 240, 0.35),
    transparent
  );
}

/* .split__media--portrait 曾經存在，是給 who-we-are.html 的創辦人大頭照用的
   （把人像收窄到 26rem，免得白底棚拍照在近黑背景上變成一大塊亮面）。
   使用者的指示是「任何頁面都不要放老闆的介紹」，那一區整個拿掉了，
   類別也就跟著刪掉，不留沒人用的樣式。
   日後真的又要在雙欄裡放人像照時，記得：這是 grid 項目，
   只寫 max-width + margin-inline: auto 會讓它不再撐滿欄位，寬度改由內容決定，
   而裡面的 img 是 width: 100% —— 兩者互相依賴，實測會量到 0px 寬。
   一定要同時寫 width: 100%。 */

/* .theme-asclepius 已經移除。它原本把小標、打勾和展示台光暈染成青藍，
   但那個藍現在是全站的點綴色（見 :root 的 --accent），所以這個類別
   變成什麼都不做。類別名稱也一併從 HTML 拿掉了，免得下一個人以為
   加上它會有效果。要再做「單一產品專屬配色」的話，請另外開一個
   新類別覆寫 --accent，不要復活這個名字。 */

.split__body > * + * {
  margin-top: 1.35rem;
}

/* 產品標題可點擊連到產品頁 */
.split__title {
  transition: color 0.2s var(--ease);
}

a.split__title:hover,
a:hover > .split__title {
  color: var(--brand-bright);
}

/* --------------------------------------------------------------------------
   9. 特色清單（打勾項目）
   -------------------------------------------------------------------------- */
.check-list {
  display: grid;
  gap: 0.85rem;
  margin-top: 1.75rem !important;
}

.check-list li {
  display: grid;
  grid-template-columns: 1.4rem 1fr;
  gap: 0.85rem;
  align-items: start;
  color: var(--text-muted);
  font-size: 0.9688rem;
  line-height: 1.55;
}

.check-list svg {
  width: 1.4rem;
  height: 1.4rem;
  margin-top: 0.1rem;
  color: var(--accent-bright);
  flex-shrink: 0;
}

/* 名稱標籤列（AI Table 的八個軟體模組）。
   這八個是一份「附了什麼」的清單，不是八個賣點 ——
   用 .check-list 排會佔掉半頁高度，還會讓每一項看起來份量相同。
   壓成一排藥丸標籤，一眼就數得出有八個。 */
.tag-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.tag {
  padding: 0.45rem 0.85rem;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  color: var(--text);
  font-size: 0.8125rem;
  font-weight: 600;
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   10. 卡片網格（Why choose / Impact 明細）
   -------------------------------------------------------------------------- */
/* 15rem 這個下限是算過的：1240px 容器扣掉留白與間距後，
   剛好讓 4 張卡片能並排一行（用 17rem 會被擠成 3+1，很不平衡）。 */
.card-grid {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

/* 六張一組的卡片牆（聯絡頁的洽詢分類）。
   不能用上面的 auto-fit —— 螢幕一寬它就自動塞成 5 欄，
   第 6 張落單掛在下一列。固定 3 欄才會永遠是整齊的 3+3。
   窄螢幕仍交給 auto-fit 處理，自然退成 2 欄再退成 1 欄。 */
.card-grid--trio {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
}

@media (min-width: 62rem) {
  .card-grid--trio {
    grid-template-columns: repeat(3, 1fr);
  }
}

.card {
  position: relative;
  padding: clamp(1.5rem, 3vw, 2.1rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color 0.3s var(--ease), transform 0.3s var(--ease),
    background-color 0.3s var(--ease);
}

.card:hover {
  transform: translateY(-4px);
  border-color: rgba(0, 168, 240, 0.4);
  background: var(--surface-2);
}

/* 卡片頂端的綠色細線，hover 時展開 */
.card::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 2px;
  background: linear-gradient(to right, var(--accent), transparent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.4s var(--ease);
}

.card:hover::after {
  transform: scaleX(1);
}

.card__icon {
  display: grid;
  place-items: center;
  width: 2.9rem;
  height: 2.9rem;
  margin-bottom: 1.25rem;
  background: rgba(0, 168, 240, 0.12);
  border: 1px solid rgba(0, 168, 240, 0.24);
  border-radius: 11px;
  color: var(--accent-bright);
}

.card__icon svg {
  width: 1.4rem;
  height: 1.4rem;
}

/* 用編號代替圖示（AI Table 的八項教材亮點）。
   這八項沒有專屬圖示，臨時挑八個意思沾不上邊的圖示比數字更難讀，
   而且來源文案本來就是編號的 01–08。方框沿用 .card__icon，只換內容。
   tabular-nums 讓每張卡的數字寬度一致，編號才會對齊成一直排。 */
.card__icon--num {
  font-size: 0.9375rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.card h3 {
  margin-bottom: 0.6rem;
}

.card p {
  color: var(--text-muted);
  font-size: 0.9375rem;
  line-height: 1.6;
}

/* 整張卡片就是連結時（例如聯絡頁的洽詢分類），
   底部補一行帶箭頭的提示。用 margin-top: auto 把它壓到底，
   這樣同一列卡片的箭頭會對齊，不會因為說明長短不一而高低錯落。 */
a.card {
  display: flex;
  flex-direction: column;
}

a.card .card__cue {
  align-self: flex-start;
  margin-top: auto;
  padding-top: 1.25rem;
}

a.card:hover .card__cue svg {
  transform: translateX(4px);
}

/* 產品照佔滿卡片上緣（醫材總覽頁的四個產品）。
   總覽頁的第一件事是讓人看到硬體長什麼樣，純圖示的卡片不夠。
   用負邊界把圖片推到卡片邊緣（負值必須和 .card 的 padding 一致，
   否則左右會露出一條底色）。

   固定 3/2 的舞台是為了把比例差很多的產品圖統一高度：
   實測四張分別是 1.15 / 1.22 / 1.60 / 1.85，
   用 cover 會把台車和眼鏡裁掉，所以用 contain，
   留白處由舞台的綠色光暈接住，看起來像同一組拍攝。 */
.card__media {
  margin: calc(clamp(1.5rem, 3vw, 2.1rem) * -1);
  margin-bottom: clamp(1.4rem, 2.6vw, 1.8rem);
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(ellipse 58% 62% at 50% 60%, rgba(0, 168, 240, 0.12), transparent 70%),
    var(--surface-2);
}

.card__media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* 內縮版的舞台（AI Table 的 Models 兩張機型圖）。
   .card__media 是固定 3/2 的框，object-fit: contain 會「用比較緊的那一邊」貼滿：
   實測框是 560x373（1.50），兩張機型圖是 1600x1270（1.26）與 1600x1121（1.43），
   兩張都比框窄，所以是靠高度撐滿 —— 圖片上下緣剛好壓在框線上，
   上緣還會撞到 .card::after 那條綠線，看起來像排版擠爆了。
   給框加內距把畫面往內縮，機身才不會頂到邊；padding 吃掉的空間由舞台的
   光暈接住，和 .split__media--stage 本來就有 padding 是同一套做法。

   沒有直接改 .card__media，是因為「比框窄」不等於「看起來會頂到」——
   要看圖自己上緣有沒有透明留白。2026-08-16 使用者回報醫材總覽頁 #lineup 的
   Caduceus S-Navigation 圖頂到框上緣，實測那四張：
   ar-nav 1.22（alpha bbox 從 y=47/982 才開始，可見內容距框上緣 17.8px，不用改）、
   caduceus-s-ar-green-navigation-cart-1 1.148（bbox 就是整張 1600x1394，
   可見內容距框上緣 0px —— 正是這一張），foresee-x 1.60 與 ooopds 1.85 靠寬度撐滿。
   所以只有那一張加了 --inset（加完距上緣 20px，和同一列的 17.8px 對得齊）。
   判斷方式：比例 < 1.5 先量 alpha bbox，真的貼到 y=0 才要加。 */
.card__media--inset {
  padding: clamp(0.75rem, 1.6vw, 1.25rem);
}

/* 照片版的舞台（教育總覽頁的 Institutions / Applications）。
   contain 是為了去背的產品圖而設的：留白由光暈接住，看起來像刻意的。
   但真實照片是滿版矩形，contain 會在上下或左右留下黑邊 ——
   實測這兩張是 1.90 與 1.33，同一列並排時黑邊寬度差很多，像是排版出錯。
   照片改用 cover 裁切填滿，兩張才會等高等寬。 */
.card__media--cover img {
  object-fit: cover;
}

/* 淺色底板版的舞台（events.php 的展會宣傳圖）。
   那 27 張圖是主辦單位的海報與 logo 拼成的宣傳稿，底色都是淺色、
   而且圖裡就印著展會名稱與日期的深色文字 —— 直接放在深色舞台上，
   圖的白底會變成一塊硬邦邦的方形亮塊，邊界看起來像沒去背。
   放在淺色底板上就成了「一張裱框的印刷品」，這也是首頁獎項跑馬燈
   （.marquee__item）對含深色文字的標誌採用的同一套做法 ——
   什麼樣的素材該配哪一種底，CLAUDE.md 第 11 節有記錄。

   框改成 4/3 而不是沿用 .card__media 的 3/2，是量過的：
   27 張的比例是 19 張 1.00、其餘 0.92 / 1.25 / 1.30 / 1.57。
   對 3/2（1.50）的框來說，那 19 張正方形左右各要空掉 12.5% 的框寬。
   換成 4/3（1.333）之後在 1280px 實測（含 padding）：
   正方形左右各 14%、1.25 是 3%、1.30 是 3%、1.57 上下各 6%、
   0.92 那張左右各 17% —— 那一張是唯一的直式圖，也是最差的情況。
   contain 而不是 cover：這些圖的字都在中間偏下，裁掉就讀不到展會名稱。
   padding 也順便解決了 .card__media--inset 那個問題：圖片離框上緣 16px，
   不會頂到 .card::after 那條 2px 的細線。 */
.card__media--plate {
  aspect-ratio: 4 / 3;
  padding: clamp(0.6rem, 1.4vw, 1rem);
  background: rgba(255, 255, 255, 0.9);
  border-bottom: 1px solid rgba(255, 255, 255, 0.16);
}

.card:hover .card__media--plate {
  background: #fff;
}

/* 兩欄的卡片牆（總覽頁的產品卡）。
   產品照需要寬度，四張擠成一排每張只剩不到 300px，硬體就看不清楚了。
   和 --trio 同理不能用 auto-fit：螢幕一寬會自動塞成 3 欄，第 4 張落單。 */
.card-grid--pair {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
}

@media (min-width: 62rem) {
  .card-grid--pair {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* 八張一組的卡片牆（AI Table 的教材亮點）。
   和 --trio / --pair 同理不能用預設的 auto-fit：4K 時根字級變大、
   容器變寬，15rem 的下限會排成 5 欄，第 6、7、8 張落單成 5+3。
   八張要永遠是偶數欄才不會有孤兒，所以只允許 1 / 2 / 4 欄：
     < 40rem  → 1 欄（min(100%) 撐開）
     ≥ 40rem  → 2 欄 × 4 列
     ≥ 75rem  → 4 欄 × 2 列
   4 欄的門檻拉到 75rem 而不是其他區塊用的 62rem：在 992px 上
   一張卡只剩約 213px 寬，扣掉 .card 的內距後正文只有 150px，
   短句也會斷成四五行。1200px 起才夠。 */
.card-grid--quad {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}

@media (min-width: 40rem) {
  .card-grid--quad {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 75rem) {
  .card-grid--quad {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* --------------------------------------------------------------------------
   10b. 影片牆（See it in action）
        每支影片捲進畫面才開始播、捲出畫面就暫停，
        避免同時解碼多支影片拖慢頁面、也省筆電電力。
   -------------------------------------------------------------------------- */
.video-grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
}

.video-card {
  margin: 0;
  display: flex;
  flex-direction: column;
}

.video-card__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
  transition: border-color 0.3s var(--ease), transform 0.3s var(--ease);
}

.video-card:hover .video-card__frame {
  border-color: rgba(0, 168, 240, 0.42);
  transform: translateY(-3px);
}

.video-card__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-card__caption {
  padding-top: 1.25rem;
}

.video-card__caption h3 {
  margin-bottom: 0.5rem;
}

.video-card__caption p {
  color: var(--text-muted);
  font-size: 0.9375rem;
  line-height: 1.6;
}


/* --------------------------------------------------------------------------
   10c. 完整影片播放器
        22MB 的影片不會自動下載 —— preload="none" 讓瀏覽器只顯示封面圖，
        訪客按下播放鍵才開始傳輸。
   -------------------------------------------------------------------------- */
.film {
  position: relative;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: #000;
  overflow: hidden;
}

.film__video {
  width: 100%;
  height: 100%;
  display: block;
}

/* 覆蓋在封面圖上的播放按鈕 */
.film__play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.25rem;
  background: linear-gradient(
    to top,
    rgba(8, 11, 10, 0.7),
    rgba(8, 11, 10, 0.25) 55%,
    rgba(8, 11, 10, 0.5)
  );
  transition: opacity 0.4s var(--ease), visibility 0.4s;
}

.film__play:hover .film__play-icon {
  transform: scale(1.08);
  background: var(--brand-bright);
}

.film.is-playing .film__play {
  opacity: 0;
  visibility: hidden;
}

.film__play-icon {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: clamp(3.5rem, 6vw, 5rem);
  height: clamp(3.5rem, 6vw, 5rem);
  background: var(--brand);
  color: #06120a;
  border-radius: 50%;
  box-shadow: 0 14px 40px -10px var(--brand-glow);
  transition: transform 0.3s var(--ease), background-color 0.3s var(--ease);
}

.film__play-icon svg {
  width: 42%;
  height: 42%;
  margin-left: 8%;
}

.film__play-text {
  text-align: left;
}

.film__play-title {
  display: block;
  font-size: clamp(1.0625rem, 1rem + 0.5vw, 1.375rem);
  font-weight: 700;
  letter-spacing: -0.015em;
}

.film__play-meta {
  display: block;
  margin-top: 0.2rem;
  color: var(--text-muted);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

@media (max-width: 30rem) {
  /* 手機版空間不夠，只留播放圖示 */
  .film__play-text {
    display: none;
  }
}


/* --------------------------------------------------------------------------
   10d. 規格比較表（解剖桌四種機型、以及產品頁的「我們 vs 別人」比較表）
        四款機型、七項規格。拆成四張卡片會逼訪客上下捲動來回比對，
        而「哪一台適合我的教室」正是這一段唯一要回答的問題 ——
        能橫向對照的表格才是對的形式，來源文件本身也是一張表。

        窄螢幕不把表格擠成一欄：欄位一窄，每一格都會斷成三四行，
        反而更難讀。改成整張表在自己的容器裡橫向捲動，
        頁面本身仍然不會出現水平捲軸（min-width 只作用在 <table> 上）。
        捲動容器要能用鍵盤操作，所以 HTML 那邊帶 tabindex="0" 與
        role="region"；:focus-visible 的外框由 §1 的全域規則接手。
   -------------------------------------------------------------------------- */
.spec-scroll {
  overflow-x: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.spec-table {
  width: 100%;
  /* 46rem = 一欄規格名 + 四欄機型的下限。再窄的話「3840 x 1080」
     這種值會被拆行，四欄就對不齊了。 */
  min-width: 46rem;
  border-collapse: collapse;
  text-align: left;
  font-size: 0.9375rem;
}

.spec-table th,
.spec-table td {
  padding: 0.85rem clamp(0.75rem, 1.4vw, 1.15rem);
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.spec-table thead th {
  border-bottom: 1px solid var(--line-strong);
  color: var(--text);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

/* 左欄是規格名稱（列標題），用 --text-muted 壓下去，
   讓視線先落在四欄機型的數值上。 */
.spec-table tbody th {
  width: 20%;
  color: var(--text-muted);
  font-weight: 600;
}

.spec-table td {
  color: var(--text-muted);
  line-height: 1.55;
}

.spec-table tbody tr:last-child th,
.spec-table tbody tr:last-child td {
  border-bottom: 0;
}

/* 比較表裡「我們自己這一欄」。
   這種表永遠是「本公司 vs 別人 vs 傳統做法」，如果整張表都是同一種灰白，
   訪客得自己逐格比對才知道哪一欄比較好 —— 我們的優勢等於沒有被講出來。
   .spec-own 加在該欄的每一格（含表頭）上：整欄染成品牌綠、墊一層極淡的
   底色，表頭上緣再加一條 2px 綠線當旗標。

   為什麼要底色，不能只改文字顏色：表格在窄螢幕會橫向捲動。有底色時整欄
   會被讀成「一整欄」；只改文字顏色的話，捲到一半就散成不相干的幾格。

   為什麼是綠不是藍：§1 的規則是「綠 = 主色 + 大面積 + 大數字」，
   .stat__value 用的就是同一個 --brand-bright。藍是不能點的小裝飾，
   扛不起「這一欄是重點」這個語意。
   實測對比：#9ad449 疊在這層底色上仍是 9.9:1（AAA）。

   之後 caduceus-s / foresee-x / ooopds 的比較表同理 —— 在自家那一欄的
   每一格加上這個類別就好，不必再寫新的 CSS。 */
.spec-table .spec-own {
  color: var(--brand-bright);
  font-weight: 600;
  background: rgba(123, 175, 49, 0.07);
}

.spec-table thead .spec-own {
  color: var(--brand-bright);
  /* 用 inset shadow 而不是 border-top，否則會多佔 2px 把整張表往下推 */
  box-shadow: inset 0 2px 0 var(--brand);
}

/* 表格裡的連結（award-quality.html 的第一欄是產品名稱，點了跳到該產品頁）。
   全站的 a 是 color: inherit、text-decoration: none —— 樣式一律由所在的元件決定，
   所以不特別指定的話，表格裡的連結會和旁邊的純文字長得一模一樣，看不出可以點。
   綠色＝可互動（§4 的綠藍規則），另外保留一條淡下劃線：
   只靠顏色區分連結不符合 WCAG 1.4.1，而綠與旁邊的灰字對比不到 3:1。 */
.spec-table a {
  color: var(--brand-bright);
  text-decoration: underline;
  text-decoration-color: rgba(154, 212, 73, 0.45);
  text-underline-offset: 3px;
}

.spec-table a:hover,
.spec-table a:focus-visible {
  text-decoration-color: currentColor;
}

/* 表格底下的補充說明（例如 43" 只含兩套軟體） */
.spec-note {
  margin-top: 1rem;
  color: var(--text-faint);
  font-size: 0.875rem;
  line-height: 1.6;
}


/* --------------------------------------------------------------------------
   10e. 年份輪播（公司沿革 —— who-we-are.html 的 Our Evolution）
   -------------------------------------------------------------------------- */
/* 一次只顯示一年，用上方的年份軌道、左右箭頭或自動換頁切換。
   做法和首頁 Hero 完全一樣（同一格 grid 疊在一起、切 .is-active 淡入淡出），
   所以兩者的節奏看起來是同一套設計。

   為什麼不做成十一段直接攤開的年表：那樣捲下去是一長條灰，
   而且 2019 / 2020 / 2021 三句「進軍某洲」句型一模一樣，連著讀特別呆板。
   一次一年就沒有這個問題，日後美編給了每一年的照片也放得進去。

   軌道刻意保留全部十一個年份：一次只看一年會失去整體感，
   年份列就是那條「整條年表的縮圖」，同時兼任分頁指示器。

   沒有 JavaScript 時：軌道與箭頭根本不會被建立（由 JS 產生），
   .is-ready 也不會加上，十一段沿革就是十一段直接攤開的文字 ——
   內容不會消失，搜尋引擎也讀得到。 */
.yearline {
  --yearline-dwell: 7.5s;
}

/* --- 年份軌道 ---------------------------------------------------------- */
/* 窄螢幕塞不下十一個年份，和 .subnav__list 用同一招：
   單行橫向捲動、藏起捲軸，目前選到的那一年由 JS 捲進可視範圍。 */
.yearline__rail {
  display: flex;
  gap: 0.25rem;
  margin-bottom: clamp(1.75rem, 3.5vw, 2.5rem);
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}

.yearline__rail::-webkit-scrollbar {
  display: none;
}

.yearline__year {
  position: relative;
  flex: none;
  padding: 0.55rem 0.85rem 0.75rem;
  color: var(--text-muted);
  font-size: 0.9375rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  scroll-snap-align: start;
  transition: color 0.25s var(--ease);
}

.yearline__year:hover {
  color: var(--text);
}

/* 目前這一年。顏色用品牌綠 —— 這是可點擊的導覽狀態，
   照 §1 的分色規則屬於綠色那一邊（和 .subnav__link 同理）。 */
.yearline__year[aria-selected="true"] {
  color: var(--brand-bright);
}

/* 年份底下的進度條。自動換頁時從左長到右，走完就換下一年 ——
   時間由 --yearline-dwell 控制，和 JS 的計時器讀同一個值，不可能不同步。 */
.yearline__year::after {
  content: "";
  position: absolute;
  left: 0.85rem;
  right: 0.85rem;
  bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: var(--brand-bright);
  transform: scaleX(0);
  transform-origin: left;
}

/* 停在某一年不動時（使用者接手、滑鼠停在上面、或系統要求減少動態），
   進度條顯示成整條實心，讀起來是「你在這裡」而不是「還在跑」。 */
.yearline__year[aria-selected="true"]::after {
  transform: scaleX(1);
}

/* 只有真的在自動換頁時才跑動畫。沿用首頁 Hero 的 dot-fill。
   先移除再重加 .is-active 是 JS 做的，動畫才會每次從頭播。 */
.yearline.is-playing .yearline__year.is-active::after {
  transform: scaleX(0);
  animation: dot-fill var(--yearline-dwell) linear forwards;
}

/* --- 內容區 ------------------------------------------------------------ */
/* .is-ready 之前（沒有 JS，或 JS 還沒跑到）維持一般的區塊流，
   十一段依序往下排；之後才疊成同一格做淡入淡出。 */
.yearline__slide + .yearline__slide {
  margin-top: clamp(2rem, 4vw, 3rem);
}

.yearline.is-ready .yearline__stage {
  display: grid;
}

.yearline.is-ready .yearline__slide {
  grid-area: 1 / 1;
  margin-top: 0;
  opacity: 0;
  /* visibility 一起切換，非目前這一年才不會被 Tab 鍵和螢幕閱讀器讀到 */
  visibility: hidden;
  transform: translateY(1.25rem);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease),
    visibility 0.6s;
}

.yearline.is-ready .yearline__slide.is-active {
  opacity: 1;
  visibility: visible;
  transform: none;
}

.yearline__slide {
  display: grid;
  gap: clamp(1rem, 2.5vw, 2rem);
  align-items: start;
}

/* 巨大的年份數字。沒有照片的時候它就是這一頁的視覺重量 ——
   純文字的輪播每一頁只有標題加一段字，左邊沒有東西撐著會顯得空。
   照 §1 的規則：夠大的元素用品牌綠（和 .stat__value 同一類）。 */
.yearline__num {
  color: var(--brand-bright);
  font-size: clamp(2.75rem, 6vw, 4.25rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.02em;
}

.yearline__title {
  margin-bottom: 0.85rem;
  font-size: clamp(1.25rem, 1.1rem + 0.6vw, 1.625rem);
  font-weight: 700;
  line-height: 1.3;
}

/* 62ch 和 .lead 用同一個上限：右欄是 1fr，4K 時會寬到一行放一百多個字。 */
.yearline__text p {
  max-width: 62ch;
  color: var(--text-muted);
}

.yearline__text p + p {
  margin-top: 0.75rem;
}

/* 每一年的配圖（選用）。目前十一頁都還沒有照片 —— 已向美編團隊提出。
   照片來了就在該張 .yearline__slide 加上 --media 並塞一個 .yearline__media，
   不需要改任何其他東西。 */
.yearline__media img {
  width: 100%;
  border-radius: var(--radius);
}

/* --- 左右箭頭與頁碼 ---------------------------------------------------- */
.yearline__controls {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}

.yearline__nav {
  display: grid;
  place-items: center;
  width: 2.75rem;
  height: 2.75rem;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  color: var(--text-muted);
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease),
    background-color 0.2s var(--ease);
}

.yearline__nav:hover {
  color: var(--brand-bright);
  border-color: var(--brand);
  background: rgba(123, 175, 49, 0.1);
}

.yearline__nav svg {
  width: 1.15rem;
  height: 1.15rem;
}

/* 頁碼靠左，把三顆按鈕推到最右邊。
   按鈕靠右是使用者的要求：右手拿手機時右側才按得到。 */
.yearline__count {
  margin-right: auto;
  color: var(--text-faint);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.1em;
}

/* 播放／暫停鈕：兩個圖示都在按鈕裡，這裡決定顯示哪一個。
   看的是 .is-paused（使用者的意圖）而不是 .is-playing（計時器現在有沒有在跑）——
   滑鼠只是停在上面時計時器會暫停，但圖示不該因此變成播放，
   因為移開就會自己恢復，圖示會和實際行為不一致。 */
.yearline__icon--play {
  display: none;
}

.yearline.is-paused .yearline__icon--play {
  display: block;
}

.yearline.is-paused .yearline__icon--pause {
  display: none;
}

/* 停住的時候按鈕本身也要看得出來是「等你按播放」，而不是一顆普通按鈕 */
.yearline.is-paused .yearline__toggle {
  color: var(--brand-bright);
  border-color: var(--brand);
}

/* 夠寬時年份和文字並排。10rem 是量過的：4.25rem 的字級下
   「2012」四個數字約 9.4rem 寬，10rem 剛好不會被擠到換行。 */
@media (min-width: 48rem) {
  .yearline__slide {
    grid-template-columns: minmax(0, 10rem) minmax(0, 1fr);
    column-gap: clamp(1.5rem, 3vw, 2.75rem);
  }

  /* 配圖在這個寬度還是自己佔一整列，文字才有足夠的行長 */
  .yearline__media {
    grid-column: 1 / -1;
  }
}

/* 再寬一點才讓配圖獨立成第三欄。門檻拉到 75rem 的理由和 .card-grid--quad
   一樣：更窄的時候三欄會把中間的文字壓到剩下一百多 px。 */
@media (min-width: 75rem) {
  .yearline__slide--media {
    grid-template-columns: minmax(0, 10rem) minmax(0, 1fr) minmax(0, 20rem);
  }

  .yearline__slide--media .yearline__media {
    grid-column: auto;
  }
}


/* --------------------------------------------------------------------------
   11. 客戶推薦
   -------------------------------------------------------------------------- */
.quote-grid {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
}

.quote {
  display: flex;
  flex-direction: column;
  padding: clamp(1.75rem, 3vw, 2.35rem);
  background: linear-gradient(160deg, var(--surface), var(--bg-raised));
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

/* 引號和底下的醫師署名刻意留在品牌綠，不跟著改成點綴藍。
   推薦序是首頁的信任背書，署名（某某醫師）是這一段最重的一句話，
   用主色才壓得住；引號跟著署名走，同一張卡片裡才不會兩種顏色打架。 */
.quote__mark {
  margin-bottom: 0.75rem;
  color: var(--brand);
  font-size: 3rem;
  font-weight: 700;
  line-height: 0.6;
}

.quote__text {
  flex: 1;
  font-size: clamp(1.0625rem, 1rem + 0.35vw, 1.1875rem);
  font-weight: 500;
  line-height: 1.55;
  letter-spacing: -0.01em;
}

.quote__author {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
  color: var(--brand-bright);
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

/* --------------------------------------------------------------------------
   12. Impact 分頁切換
   -------------------------------------------------------------------------- */
.tabs {
  display: inline-flex;
  gap: 0.25rem;
  padding: 0.3rem;
  margin-bottom: clamp(2rem, 4vw, 3rem);
  background: var(--surface);
  border: 1px solid var(--line);
  /* 同 .btn，倒角從膠囊型改小。外框比按鈕本身多了 0.3rem 的內距，
     所以外框 14px、裡面的按鈕 10px，兩圈圓弧才會是同心的。 */
  border-radius: 14px;
}

.tab {
  padding: 0.7rem 1.4rem;
  border-radius: 10px;
  color: var(--text-muted);
  font-size: 0.9rem;
  font-weight: 700;
  transition: color 0.2s var(--ease), background-color 0.2s var(--ease);
}

.tab:hover {
  color: var(--text);
}

.tab[aria-selected="true"] {
  background: var(--brand);
  color: #06120a;
}

.tab-panel[hidden] {
  display: none;
}

/* 統計數字（Impact 內） */
.metric {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.metric__value {
  color: var(--brand-bright);
  font-size: clamp(2.25rem, 1.6rem + 2.4vw, 3.5rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.04em;
  font-variant-numeric: tabular-nums;
}

.metric__label {
  font-size: 0.9375rem;
  font-weight: 700;
}

.metric__note {
  margin-top: 0.5rem;
  color: var(--text-muted);
  font-size: 0.9063rem;
  line-height: 1.55;
}

/* --------------------------------------------------------------------------
   13. 數字統計區
   -------------------------------------------------------------------------- */
.stats {
  display: grid;
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
}

.stat {
  padding: clamp(1.75rem, 3.5vw, 2.75rem) clamp(1.25rem, 2.5vw, 2rem);
  background: var(--bg-raised);
  text-align: center;
}

.stat__value {
  display: block;
  color: var(--brand-bright);
  font-size: clamp(2.25rem, 1.5rem + 2.6vw, 3.25rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.045em;
  font-variant-numeric: tabular-nums;
}

.stat__label {
  display: block;
  margin-top: 0.75rem;
  color: var(--text-muted);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   14. 獎項跑馬燈
   -------------------------------------------------------------------------- */
.marquee {
  position: relative;
  overflow: hidden;
  /* 左右淡出，讓跑馬燈不會硬切邊 */
  mask-image: linear-gradient(
    to right,
    transparent,
    #000 8%,
    #000 92%,
    transparent
  );
}

/* 間距刻意用 .marquee__item 的 margin-inline-end，不用 gap。
   gap 只出現在項目「之間」（n 個項目 n-1 條），所以整條軌道是 n*w + (n-1)*g，
   位移 50% 會落在 n/2*w + (n-1)/2*g —— 比「完整一組」少了半個間距，
   每繞一圈就跳 10px（1280px 實測）。改成 margin 之後整條是 n*(w+g)，
   50% 正好等於一組含其後間距，接軌才真的無縫。 */
.marquee__track {
  display: flex;
  width: max-content;
  padding-block: 0.5rem;
  /* 77s 而不是原本的 38s：軌道從兩組變四組、寬度變 2.025 倍，
     時間跟著等比放大才會維持原本的速度（實測 20.9 px/s）。 */
  animation: marquee 77s linear infinite;
}

.marquee:hover .marquee__track {
  animation-play-state: paused;
}

@keyframes marquee {
  to {
    /* 軌道內容重複兩次，位移 50% 即為無縫接軌 */
    transform: translateX(-50%);
  }
}

/* 獎項徽章保留原本的品牌配色（認證標誌要能被認出來），
   但部分徽章含深色文字，直接放深底會看不見，
   因此每個都放在淺色底板上 —— 深色網站呈現認證標誌的標準做法。 */
.marquee__item {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  margin-inline-end: 1.25rem;   /* 取代 .marquee__track 的 gap —— 理由見上面 */
  width: clamp(7rem, 11vw, 9.5rem);
  aspect-ratio: 1;
  padding: clamp(0.85rem, 1.6vw, 1.35rem);
  background: rgba(255, 255, 255, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--radius);
  opacity: 0.8;
  transition: opacity 0.3s var(--ease), background-color 0.3s var(--ease),
    transform 0.3s var(--ease);
}

.marquee__item:hover,
a.marquee__item:focus-visible {
  opacity: 1;
  background: #fff;
  transform: translateY(-3px);
}

.marquee__item img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/* --------------------------------------------------------------------------
   14b. 獎項陳列牆（award-quality.html 的十二座獎座）
   -------------------------------------------------------------------------- */
/* 素材夾裡那十二個檔案不是 logo，是「實體獎座與獎狀的去背照片」——
   金屬獎座、玻璃獎座、木框獎狀，全部拍在白底再去背。
   所以這裡刻意不用上面那塊白色底板（.marquee__item）：
   實測把它們合成在白底上，白色與透明玻璃的獎座（經濟日報優勝、COMPUTEX 獎牌）
   邊緣會整片消失；直接放在近黑的 --bg 上，金、銀、玻璃反而全部跳出來。
   跑馬燈那五個是「含深色文字的 logo」，情況正好相反，兩者不能共用同一種底。

   為什麼不用 .card-grid--quad + .card：
   --quad 在 40rem 以下是單欄，十二張直式獎座一張一個螢幕，手機要捲十二個畫面。
   這裡固定 2 / 3 / 4 / 6 欄 —— 十二可以被這四個數字整除，所以任何寬度都不會有孤兒卡片
   （和 --trio / --quad 當初挑欄數的理由相同）。 */
.award-grid {
  display: grid;
  gap: clamp(0.85rem, 1.8vw, 1.4rem);
  grid-template-columns: repeat(2, 1fr);
}

@media (min-width: 48rem) {
  .award-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 62rem) {
  .award-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

@media (min-width: 100rem) {
  .award-grid {
    grid-template-columns: repeat(6, 1fr);
  }
}

.award {
  display: flex;
  flex-direction: column;
}

/* 直式的舞台。獎座本身是立的（實測比例 0.41 ~ 1.44，十二個裡有七個高於寬），
   放進 .card__media 那個 3/2 橫框裡，最高的那座只會剩下 57px 寬。
   3/4 的框對「最高」與「最寬」兩端都還撐得住。
   內距和光暈的做法沿用 .card__media--inset / .split__media--stage。 */
/* 注意：這裡不能用 display: grid + place-items: center。
   grid item 在 place-items: center 之下不會被拉伸，img 的 height: 100%
   解不出框的高度，實測會長到 187x456（框只有 187x250），再被 overflow: hidden
   裁掉 —— 看起來就是「圖被切掉」。.card__media 是預設的 block 排版，照它做就對了。 */
.award__stage {
  aspect-ratio: 3 / 4;
  margin-bottom: 0.9rem;
  padding: clamp(0.6rem, 1.2vw, 1rem);
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background:
    radial-gradient(ellipse 60% 55% at 50% 62%, rgba(0, 168, 240, 0.12), transparent 70%),
    var(--surface);
}

.award__stage img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.award__year {
  color: var(--accent-bright);
  font-size: 0.75rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* 這條要自己帶 font-weight / line-height：獎項名稱會折到兩三行，
   靠 h1,h2,h3,h4 那組選擇器的 line-height: 1.1 會擠在一起（規則 §2.2）。 */
.award__name {
  margin-top: 0.3rem;
  color: var(--text);
  font-size: 0.9688rem;
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: normal;
}

.award__note {
  margin-top: 0.4rem;
  color: var(--text-muted);
  font-size: 0.875rem;
  line-height: 1.55;
}

/* --------------------------------------------------------------------------
   15. 全球據點
   -------------------------------------------------------------------------- */
.location-grid {
  display: grid;
  gap: 1.25rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
}

.location {
  display: flex;
  flex-direction: column;
  padding: clamp(1.75rem, 3.5vw, 2.6rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: border-color 0.3s var(--ease);
}

.location:hover {
  border-color: rgba(0, 168, 240, 0.4);
}

.location__kind {
  color: var(--accent-bright);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.location__place {
  margin: 0.75rem 0 1rem;
}

.location p {
  flex: 1;
  color: var(--text-muted);
  font-size: 0.9375rem;
  line-height: 1.65;
}

.location__links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin-top: 1.75rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}

/* --------------------------------------------------------------------------
   16. 結尾行動呼籲
   -------------------------------------------------------------------------- */
.cta {
  position: relative;
  padding: clamp(2.75rem, 6vw, 5rem);
  border: 1px solid rgba(123, 175, 49, 0.28);
  border-radius: var(--radius-lg);
  background: radial-gradient(
      ellipse 80% 120% at 50% 0%,
      rgba(123, 175, 49, 0.16),
      transparent 70%
    ),
    var(--bg-raised);
  text-align: center;
  overflow: hidden;
}

.cta .lead {
  margin-inline: auto;
  margin-top: 1.25rem;
}

.cta .btn-row {
  justify-content: center;
  margin-top: 2.25rem;
}

/* --------------------------------------------------------------------------
   16b. 聯絡表單
        表單左、輔助說明右。窄螢幕自動疊成一欄。
   -------------------------------------------------------------------------- */
.contact-layout {
  display: grid;
  gap: clamp(1.5rem, 3.5vw, 3rem);
  align-items: start;
  grid-template-columns: 1fr;
}

@media (min-width: 62rem) {
  .contact-layout {
    grid-template-columns: minmax(0, 1.65fr) minmax(0, 1fr);
  }
}

.form {
  padding: clamp(1.5rem, 3.5vw, 2.75rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
}

/* 15rem 下限的用意和 .card-grid 相同：
   容器夠寬時兩欄並排，窄了就自動退成一欄，不必寫斷點。 */
.form__grid {
  display: grid;
  gap: 1.15rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

.field {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  /* grid 項目預設 min-width: auto，長字串會把欄位撐爆版面 */
  min-width: 0;
}

.field--full {
  grid-column: 1 / -1;
}

.field > label {
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* 必填星號。星號本身對螢幕閱讀器沒有意義（欄位已有 required），
   所以在 HTML 裡標了 aria-hidden，這裡只負責顏色。 */
.field__req {
  color: var(--accent-bright);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 0.85rem 1rem;
  font: inherit;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg-raised);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  transition: border-color 0.2s var(--ease), background-color 0.2s var(--ease);
}

.field input::placeholder,
.field textarea::placeholder {
  color: var(--text-faint);
  /* Firefox 預設會把 placeholder 再調淡一次，對比度會掉到 AA 以下 */
  opacity: 1;
}

/* 只換邊框顏色，不換底色。
   底色若換成較亮的 --surface-2，placeholder（--text-faint）的對比度會掉到
   4.18:1，低於 AA 的 4.5:1 —— 而 placeholder 正是在「已聚焦但還沒打字」
   的這一刻最需要被讀到。維持 --bg-raised 則有 4.88:1。 */
.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--brand);
}

/* :user-invalid 只在「使用者實際填過又離開」後才成立，
   不像 :invalid 會讓還沒填的必填欄位一進頁面就全部標紅。 */
.field input:user-invalid,
.field select:user-invalid,
.field textarea:user-invalid {
  border-color: var(--danger);
}

.field textarea {
  min-height: 9.5rem;
  line-height: 1.6;
  resize: vertical;
}

/* 下拉選單：關掉系統外觀，換成自己的箭頭，
   否則 Windows 上會出現一顆亮灰色的按鈕，在深色版面很突兀。
   箭頭是內嵌的 SVG（data: URI），不算外部資源，CSP 的 img-src 已允許 data:。 */
.field select {
  padding-right: 2.75rem;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239ca7a1' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 1rem center;
  background-size: 1.05rem;
  cursor: pointer;
  appearance: none;
}

/* 展開後的選項清單是作業系統畫的，網頁樣式管不到；
   color-scheme 是唯一能讓它跟著深色主題走的方式。 */
.field select option {
  background: var(--surface-2);
  color: var(--text);
}

.field__hint {
  color: var(--text-faint);
  font-size: 0.8125rem;
  line-height: 1.5;
}

/* 複選題（想了解哪些產品）。
   刻意用核取方塊而不是 <select multiple> —— 多選下拉要按住 Ctrl 點選，
   多數人不知道有這回事，手機上更是幾乎無法操作。 */
.choices {
  grid-column: 1 / -1;
  /* fieldset 不設成 flex/grid：部分瀏覽器會讓 legend 跑掉位置 */
  display: block;
}

.choices legend {
  margin-bottom: 0.7rem;
  color: var(--text-muted);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.choices__grid {
  display: grid;
  gap: 0.6rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
}

.choices__hint {
  display: block;
  margin-top: 0.7rem;
}

/* 整塊都可以點（<label> 包住 input），點擊範圍比只有小方框大得多 */
.choice {
  display: grid;
  grid-template-columns: 1.05rem 1fr;
  gap: 0.7rem;
  align-items: start;
  padding: 0.7rem 0.9rem;
  background: var(--bg-raised);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  color: var(--text-muted);
  font-size: 0.875rem;
  line-height: 1.45;
  cursor: pointer;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease),
    background-color 0.2s var(--ease);
}

.choice:hover {
  border-color: var(--brand);
  color: var(--text);
}

.choice input {
  width: 1.05rem;
  height: 1.05rem;
  margin: 0.1rem 0 0;
  accent-color: var(--brand);
}

/* 勾選後整塊變綠，一眼就看得出選了哪幾項。
   :has() 不支援的舊瀏覽器只是少了這個高亮，功能完全不受影響。 */
.choice:has(input:checked) {
  border-color: var(--brand);
  background: rgba(123, 175, 49, 0.09);
  color: var(--text);
}

.form__consent {
  display: grid;
  grid-template-columns: 1.15rem 1fr;
  gap: 0.85rem;
  align-items: start;
  margin-top: 1.6rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--line);
  color: var(--text-muted);
  font-size: 0.875rem;
  line-height: 1.6;
}

.form__consent input {
  width: 1.15rem;
  height: 1.15rem;
  margin: 0.22rem 0 0;
  accent-color: var(--brand);
}

.form__consent a {
  color: var(--brand-bright);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Cloudflare Turnstile 那個框（2026-08-31）。
   ★ 只有 margin，沒有寬高，也沒有碰它裡面的任何東西 —— 那個框是 Cloudflare 用
     iframe 畫的，我們的樣式本來就進不去，硬設寬高只會讓它被裁掉。
     它自己的寬度約 300px、高約 65px，比表單窄，所以靠左放就好。
   ★ JavaScript 關掉時裡面是 <noscript> 的一段說明文字，這個 margin 一樣適用。 */
.form__check {
  /* 這個值改過兩次，兩次都是使用者看實際畫面之後決定的，不要憑推理改回去：
     1.75rem（貼在同意勾選下面）→ 他說兩個打勾框黏在一起；
     3.2rem（移到訊息欄下面）→ 他說這樣有點醜。
     現在是「放回同意條款之後、只留一點點間隔」，也就是 2.5rem。
     2.5rem 比欄位間距（1.15rem）大一倍有餘，讀得出是獨立的一塊；
     又明顯小於 .form__consent 另起一組用的 3.2rem，所以它會和同意條款、
     送出鍵讀成同一組 —— 那正是他要的樣子。 */
  margin-top: 2.5rem;

  /* ★ overflow-x 不是防呆，是必要的 —— 那個框是 Cloudflare 用 iframe 畫的，
     **固定 300px 寬**，我們的樣式進不去也改不了它。實測 390px 螢幕上表單的
     內容寬度剛好也是 300px（一點餘裕都沒有），所以再窄一點的機器
     （360px 的 Android 很常見）就會被它撐出橫向捲動，整頁歪掉。
     做法沿用站上處理同一類問題的既有模式：讓它在自己的框裡捲，不要推整頁
     （見 CLAUDE.md §5 的 .spec-scroll）。內容放得下時不會出現捲軸，
     所以桌機與 390px 都完全不受影響。
     ★ 刻意不用 transform: scale() 縮小它 —— 那會動到一個做人機驗證的第三方
       元件，而它本來就在偵測「自己有沒有被動手腳」，不值得冒那個險。 */
  overflow-x: auto;
}

.form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.5rem;
  margin-top: 1.75rem;
}

.form__note {
  color: var(--text-faint);
  font-size: 0.8125rem;
}

/* 送出後按鈕會被 JS 停用，避免連點兩下寄出兩封信 */
.form__submit[disabled] {
  opacity: 0.55;
  cursor: progress;
  transform: none;
}

/* 蜜罐欄位：擋自動填表的機器人。
   刻意不用 display:none —— 有些機器人會略過被隱藏的欄位，
   移到畫面外反而抓得到。tabindex="-1" 確保鍵盤使用者不會 Tab 進來。 */
.hp-field {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* 表單旁的補充說明 */
.contact-aside {
  display: grid;
  gap: 1.25rem;
}

.contact-aside__card {
  padding: clamp(1.5rem, 3vw, 2rem);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

.contact-aside__card h3 {
  margin-bottom: 0.85rem;
}

.contact-aside__card p {
  color: var(--text-muted);
  font-size: 0.9375rem;
  line-height: 1.65;
}

.contact-aside__card p + p {
  margin-top: 0.9rem;
}

.contact-aside__card a {
  color: var(--brand-bright);
}

.contact-aside__card a:hover {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* 「請勿填入病患資料」那張要看得出是警語，但不必做成紅色驚嚇框 */
.contact-aside__card--note {
  border-color: rgba(239, 138, 109, 0.35);
  background: linear-gradient(160deg, rgba(239, 138, 109, 0.07), var(--surface) 60%);
}

/* --------------------------------------------------------------------------
   16c. 據點資訊卡（照片 + 電話 / 傳真 / 地址）
   -------------------------------------------------------------------------- */
.office-grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
}

.office {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color 0.3s var(--ease);
}

.office:hover {
  border-color: rgba(0, 168, 240, 0.4);
}

.office__photo {
  aspect-ratio: 16 / 9;
  background: var(--surface-2);
}

.office__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.office__body {
  padding: clamp(1.5rem, 3vw, 2.25rem);
}

.office__kind {
  color: var(--accent-bright);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.office__name {
  margin: 0.75rem 0 1.5rem;
}

.office__rows {
  display: grid;
  gap: 0.9rem;
}

.office__row {
  display: grid;
  grid-template-columns: 5.5rem 1fr;
  gap: 0.25rem 1rem;
  align-items: start;
}

.office__row dt {
  padding-top: 0.15rem;
  color: var(--text-faint);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.office__row dd {
  color: var(--text-muted);
  font-size: 0.9375rem;
  line-height: 1.6;
}

.office__row a {
  color: var(--text);
}

.office__row a:hover {
  color: var(--brand-bright);
}

/* 手機上 5.5rem 的標籤欄會把地址擠成一行兩三個字，改成上下排 */
@media (max-width: 30rem) {
  .office__row {
    grid-template-columns: 1fr;
  }
}

/* --------------------------------------------------------------------------
   17. 頁尾
   -------------------------------------------------------------------------- */
.footer {
  padding-top: clamp(3.5rem, 7vw, 5.5rem);
  border-top: 1px solid var(--line);
  background: var(--bg-raised);
}

.footer__top {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem);
  padding-bottom: clamp(2.5rem, 5vw, 3.5rem);
  grid-template-columns: 1fr;
}

@media (min-width: 55rem) {
  .footer__top {
    grid-template-columns: minmax(14rem, 1fr) 2.4fr;
  }
}

.footer__brand img {
  width: 10.5rem;
  height: auto;
  margin-bottom: 1.5rem;
}

.footer__tagline {
  max-width: 26ch;
  color: var(--text-muted);
  font-size: 0.9375rem;
  line-height: 1.6;
}

.footer__social {
  display: flex;
  gap: 0.6rem;
  margin-top: 1.75rem;
}

.footer__social a {
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  color: var(--text-muted);
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease),
    background-color 0.2s var(--ease);
}

.footer__social a:hover {
  color: var(--brand-bright);
  border-color: var(--brand);
  background: rgba(123, 175, 49, 0.1);
}

.footer__social svg {
  width: 1.15rem;
  height: 1.15rem;
}

.footer__cols {
  display: grid;
  gap: clamp(1.75rem, 4vw, 2.5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 10rem), 1fr));
}

.footer__col h3 {
  margin-bottom: 1.1rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text);
}

.footer__col li + li {
  margin-top: 0.7rem;
}

.footer__col a {
  color: var(--text-muted);
  font-size: 0.9063rem;
  transition: color 0.2s var(--ease);
}

.footer__col a:hover {
  color: var(--brand-bright);
}

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1.75rem;
  border-top: 1px solid var(--line);
  color: var(--text-faint);
  font-size: 0.8125rem;
}

.footer__legal {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
}

.footer__legal a:hover {
  color: var(--text-muted);
}

/* --------------------------------------------------------------------------
   18. 左側點點導覽（參考 Medtronic）
   -------------------------------------------------------------------------- */
.dotnav {
  position: fixed;
  top: 50%;
  left: clamp(0.75rem, 1.6vw, 1.5rem);
  z-index: 90;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.4s var(--ease), visibility 0.4s;
}

.dotnav.is-visible {
  opacity: 1;
  visibility: visible;
}

.dotnav__item {
  position: relative;
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
}

.dotnav__item::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.28);
  transition: transform 0.3s var(--ease), background-color 0.3s var(--ease);
}

.dotnav__item:hover::before {
  background: rgba(255, 255, 255, 0.6);
  transform: scale(1.25);
}

.dotnav__item[aria-current="true"]::before {
  background: var(--accent-bright);
  transform: scale(1.5);
  box-shadow: 0 0 0 4px rgba(0, 168, 240, 0.16);
}

/* 滑過時跳出的區塊名稱 */
.dotnav__label {
  position: absolute;
  left: calc(100% + 0.6rem);
  padding: 0.4rem 0.7rem;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 7px;
  color: var(--text);
  font-size: 0.75rem;
  font-weight: 600;
  white-space: nowrap;
  opacity: 0;
  transform: translateX(-0.4rem);
  pointer-events: none;
  transition: opacity 0.25s var(--ease), transform 0.25s var(--ease);
}

.dotnav__item:hover .dotnav__label,
.dotnav__item:focus-visible .dotnav__label {
  opacity: 1;
  transform: none;
}

/* 空間不足就隱藏，免得壓到內容 */
@media (max-width: 87.5rem) {
  .dotnav {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   18b. 產品頁的區塊子導覽（橫式、貼在頁首下方）
   -------------------------------------------------------------------------- */
/* 為什麼產品頁不用上面的點點導覽：點點要滑過去才看得到區塊名稱。
   首頁的區塊名稱訪客大致猜得到（hero / 產品 / 見證 / 數字），
   但產品頁的區塊是「AI Assistant」「Software」「Models」這種
   非看到名稱不知道有什麼的內容，藏在 hover 後面等於沒有。
   所以產品頁改成一條橫的、名稱直接寫出來的子導覽。

   top 用算式而不是量出來的高度：.header__inner 的 min-height 就是 4.75rem，
   而頁首沒有任何會撐高它的內容（字標寬 11.5rem、比例 900:136，
   算出來只有 1.74rem 高），捲動後的 .is-stuck 也不改高度。
   要再加上 1px，因為 .header 有一條 border-bottom（實測整體高 77px、
   4.75rem 是 76px）—— 少了這 1px，子導覽的上緣會被頁首壓掉一條。
   單位是 rem，所以 4K 放大根字級時會一起跟著放大。

   z-index 80 夾在頁首（100）和內容之間：手機版展開的選單是
   .header 的子元素，會蓋在子導覽上面，不會互相穿插。 */
.subnav {
  position: sticky;
  top: calc(4.75rem + 1px);
  z-index: 80;
  background: rgba(8, 11, 10, 0.9);
  backdrop-filter: blur(14px) saturate(150%);
  border-bottom: 1px solid var(--line);
}

/* 手機上區塊名稱一定塞不進一行 —— 換行成兩三排會把內容整個往下推，
   而且捲動時高度還會變。改成單行橫向捲動：永遠只佔一行高度。
   隱藏捲軸是為了不讓一條灰槓橫在頁面上緣；
   兩端各留一點 padding，才看得出來右邊還有東西可以滑。 */
.subnav__list {
  display: flex;
  gap: 0.25rem;
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}

.subnav__list::-webkit-scrollbar {
  display: none;
}

.subnav__link {
  display: block;
  padding: 0.9rem 0.8rem;
  border-bottom: 2px solid transparent;
  color: var(--text-muted);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  white-space: nowrap;
  scroll-snap-align: start;
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}

.subnav__link:hover {
  color: var(--text);
}

/* 目前所在的區塊。顏色維持品牌綠 —— 子導覽是導覽狀態，
   照 :root 的分色規則屬於「可互動」那一邊，不用點綴藍。 */
.subnav__link[aria-current="true"] {
  color: var(--brand-bright);
  border-bottom-color: var(--brand-bright);
}

/* 點連結跳到區塊時，讓區塊標題停在頁首 + 子導覽的下方，
   而不是被這兩條吸頂的橫條蓋住。

   這裡要改的是 §2 已經有的 html { scroll-padding-top: 6rem }（只算了頁首），
   不是另外在區塊上加 scroll-margin-top —— 那兩個屬性會相加。
   實測加上去的結果是 96px + 148px = 244px，區塊被推到離頁首一百多 px 的地方。

   scroll-padding-top 只能下在真正在捲動的元素（html）上，所以 .subnav-page
   要掛在 <html> 而不是 <main>。
   量出來頁首 77px、子導覽 54px，共 131px；這裡是 148px，
   多出來的十幾 px 是刻意留的空隙，標題才不會緊貼橫條。 */
html.subnav-page {
  scroll-padding-top: calc(4.75rem + 3.5rem + 1rem);
}

/* --------------------------------------------------------------------------
   19. 進場動畫（捲到才淡入）
   -------------------------------------------------------------------------- */
.reveal {
  opacity: 0;
  transform: translateY(1.75rem);
  transition: opacity 0.8s var(--ease), transform 0.8s var(--ease);
}

.reveal.is-in {
  opacity: 1;
  transform: none;
}

/* 同一組元素依序進場 */
.reveal[data-delay="1"] { transition-delay: 0.08s; }
.reveal[data-delay="2"] { transition-delay: 0.16s; }
.reveal[data-delay="3"] { transition-delay: 0.24s; }
.reveal[data-delay="4"] { transition-delay: 0.32s; }

/* --------------------------------------------------------------------------
   20. 新聞與展會（news.php / news-article.php / events.php）
   -------------------------------------------------------------------------- */
/* .news-card__meta（日期列）、.news-card__tag（小標籤）與 .news-card h3
   （小一號的標題）這三條規則，展會卡片也在用 —— 兩邊是同一種版式，
   只是資料不同。events-lib.php 的卡片同時掛 news-card 與 event-card
   兩個 class：前者拿這裡的共用規則，後者只負責展會多出來的地點那一行。
   class 名字裡的 news 是歷史遺留（新聞先做），不代表只有新聞能用；
   複製一份 .event-card__meta 出來只會在改一邊忘一邊時長歪。 */

/* 換頁後程式會把焦點移到這個區塊，讓螢幕閱讀器讀出新內容。
   它是 tabindex="-1"，永遠不會被 Tab 鍵選到，只可能是程式移進來的，
   所以拿掉外框不會影響鍵盤操作 —— 留著反而會在整個區塊外圍
   閃出一圈框線，看起來像壞掉。
   #past 是 events.php 的「已結束」區塊，翻頁方式和 #latest 一樣。 */
#latest:focus,
#past:focus {
  outline: none;
}

/* 分類切換列。是真的連結，不是 JavaScript 分頁 ——
   每個分類都有自己的網址，可以分享也能被搜尋引擎收錄。 */
.news-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: 2.25rem;
}

.news-filter__link {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.6rem 1.1rem;
  color: var(--text-muted);
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;          /* 同 .btn，倒角從膠囊型改小 */
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease),
    background-color 0.25s var(--ease);
}

.news-filter__link:hover {
  color: var(--text);
  border-color: var(--line-strong);
  background: var(--surface-2);
}

/* 目前所在的分類。用 aria-current 當選擇器而不是另外加 class，
   狀態就只有一個來源，不會發生「看起來選中但螢幕閱讀器沒說」的情況。 */
.news-filter__link[aria-current="true"] {
  color: var(--bg);
  background: var(--brand);
  border-color: var(--brand);
}

.news-filter__count {
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
  opacity: 0.75;
}

.news-filter__link[aria-current="true"] .news-filter__count {
  opacity: 0.85;
}

/* 卡片上方的日期列。
   選擇器一定要寫成 .card .news-card__meta —— 這個元素是 .card 裡面的 <p>，
   而 .card p 已經指定了顏色與字級（權重 0-1-1）。單寫 .news-card__meta
   （0-1-0）會被壓過去，日期就會變得和摘要一樣大、一樣顏色，
   看不出來那是附註資訊。（量測過：實際渲染出來是 --text-muted 而不是 --text-faint。） */
.card .news-card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  margin-bottom: 0.75rem;
  /* 不用 --text-faint。它對 --bg 是 4.9:1，但卡片底色是比較亮的 --surface，
     量出來只剩 4.60:1 —— 過得了 AA 但離本站的 AAA 標準還差得遠，
     而這裡是 13px 的全大寫小字，最不該省對比的地方。
     改用 --text-muted（7.06:1），層次交給字級、全大寫與字距去做。 */
  color: var(--text-muted);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.news-card__tag {
  padding: 0.15rem 0.55rem;
  color: var(--accent-bright);
  background: rgba(0, 168, 240, 0.12);
  border-radius: 999px;
  letter-spacing: 0.04em;
}

/* 新聞卡片的標題比一般卡片小一號 —— 新聞標題本來就長，
   用 .h3 的尺寸會讓一張卡片被標題佔滿，摘要反而被擠掉。
   展會名稱一樣長（"The 33rd China (Guangzhou) International Health
   Industry Expo 2025"），所以展會卡片也掛 news-card 沿用這一條。 */
.news-card h3 {
  font-size: clamp(1.0625rem, 1.6vw, 1.1875rem);
  line-height: 1.3;
}

/* 展會卡片的地點那一行（events.php）。
   選擇器要寫成 .card .event-card__where —— 和上面 .news-card__meta 同一個
   道理，.card p 已經指定了 --text-muted（權重 0-1-1），單寫 class 會被壓過去。
   這一行用 --text 而不是 --text-muted：地點和日期一樣是讀者真正在找的資訊，
   不是附註。實測 #e9efea 在 .card 的 --surface 底色上是 15.03:1（AAA）。 */
.card .event-card__where {
  color: var(--text);
  font-weight: 500;
}

/* 上一頁 / 下一頁 */
.pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 2.5rem;
  padding-top: 1.75rem;
  border-top: 1px solid var(--line);
}

/* 已經在第一頁（或最後一頁）時，按鈕不會消失而是變成灰字。
   兩顆按鈕的位置固定，翻頁時「較舊」不會忽然跳到左邊。

   刻意不加 opacity —— 可以按的那一顆是 .btn--ghost（有外框），
   這一顆沒有外框，光是這樣就分得出來了。再壓透明度只會讓對比
   從 4.88:1 掉到 2:1 上下，變成看得到卻讀不清楚的字。 */
.pager__step--off {
  padding: 0.8rem 1.4rem;
  color: var(--text-faint);
  font-size: 0.9375rem;
  font-weight: 600;
}

.pager__count {
  color: var(--text-muted);
  font-size: 0.9375rem;
  text-align: center;
}

.pager__total {
  display: block;
  margin-top: 0.2rem;
  color: var(--text-faint);
  font-size: 0.8125rem;
}

/* --- 文章頁 ------------------------------------------------------------- */

/* 新聞標題可能很長，比一般內頁標題再放寬一些才不會斷得太碎 */
.article__title {
  max-width: 26ch;
}

.article__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  color: var(--text-muted);
  font-size: 0.9375rem;
}

.article__source {
  color: var(--text-faint);
}

.article__figure {
  margin-bottom: 2.5rem;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}

.article__figure img {
  display: block;
  width: 100%;
  height: auto;
}

/* 內文欄寬。65ch 左右是長篇文字最好讀的行長 ——
   在 4K 螢幕上讓文字橫跨整個容器，眼睛換行時會找不到下一行。 */
.article__body {
  max-width: 65ch;
  color: var(--text-muted);
  font-size: 1.0625rem;
  line-height: 1.75;
}

.article__body > * + * {
  margin-top: 1.25rem;
}

.article__body h2 {
  margin-top: 2.5rem;
  color: var(--text);
}

/* 段落裡的小標題（2026-08-28 加，第一個用的是 privacy.html 的 #cookies）。
   為什麼是 h3 而不是跟著上面用 h2：每一節本來就有一個 .section-head 的 h2，
   節內的小標題是它的下一層，寫成 h2 會變成同級的兄弟，螢幕閱讀器就讀不出
   從屬關係了。而 main.css 沒有針對 h3 元素的通用規則（見 CLAUDE.md §2 規則 2），
   所以字級與粗細要在這裡寫明，不能靠繼承。 */
.article__body h3 {
  margin-top: 2rem;
  color: var(--text);
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.5;
}

.article__body ul {
  padding-left: 1.25rem;
  list-style: disc;
}

.article__body li + li {
  margin-top: 0.5rem;
}

.article__body blockquote {
  padding-left: 1.25rem;
  color: var(--text);
  font-size: 1.125rem;
  border-left: 2px solid var(--accent);
}

/* 內文裡的連結。和 §10d 的 .spec-table a 是同一個問題、同一個解法：
   全站的 a 是 color: inherit、text-decoration: none，所以段落中間的連結會和
   旁邊的字長得一模一樣。綠色＝可互動（§4），下劃線是必要的不是裝飾 ——
   #9ad449 對周圍的 #9ca7a1 只有 1.41:1，只靠顏色分辨不符合 WCAG 1.4.1。

   新聞文章的內文是逐段轉義的純文字、產生不出 <a>，所以這條規則實際上是給
   法律頁（privacy.html 等）用的 —— 那幾頁大量重用 .article__body 排長文。 */
.article__body a {
  color: var(--brand-bright);
  text-decoration: underline;
  text-decoration-color: rgba(154, 212, 73, 0.45);
  text-underline-offset: 3px;
}

.article__body a:hover,
.article__body a:focus-visible {
  text-decoration-color: currentColor;
}

.article__origin {
  max-width: 65ch;
  margin-top: 2rem;
}

/* 上一篇 / 下一篇 */
.article__nav {
  display: grid;
  gap: 1rem;
  max-width: 65ch;
  margin-top: 3rem;
  padding-top: 2rem;
  border-top: 1px solid var(--line);
}

.article__nav-link {
  display: block;
  padding: 1.1rem 1.25rem;
  color: var(--text);
  text-decoration: none;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: border-color 0.25s var(--ease), background-color 0.25s var(--ease);
}

.article__nav-link:hover {
  border-color: rgba(0, 168, 240, 0.4);
  background: var(--surface-2);
}

.article__nav-dir {
  display: block;
  margin-bottom: 0.35rem;
  color: var(--accent-bright);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.article__nav-title {
  display: block;
  font-size: 0.9375rem;
  line-height: 1.45;
}

.article__nav-link--next {
  text-align: right;
}

.article__back {
  margin-top: 2.5rem;
}

@media (min-width: 48rem) {
  .article__nav {
    grid-template-columns: 1fr 1fr;
  }

  /* 只有一則時（第一篇或最後一篇）讓它靠自己那一側，
     不要一張卡片獨自佔滿整行 */
  .article__nav-link--next:only-child {
    grid-column: 2;
  }
}

/* --------------------------------------------------------------------------
   20b. 純文字法律頁的置中排版（privacy / terms / accessibility）

        這三頁刻意不放任何圖片（使用者決定，2026-08-20）。頁面其他地方
        的靠左排版是為了跟右側的配圖對齊，沒有圖的時候就只剩一邊空白：
        量過 3840px 下容器 1974px、內文欄 782px，右側空掉 1192px。改成置中。

        「置中」的定義：把欄位（.section-head、.article__body）置中，標題與
        導言的文字也置中，但 .article__body 裡的 <p> 與 <ul> 仍然靠左 ——
        置中的長段落每一行的起點都不一樣，讀到行尾換行時找不到下一行的
        左邊界。這三頁每一段都是十幾行的法律文字，段落本身不能置中。

        採的是 <html class="legal-page">，和 .subnav-page 同一個做法，所以選擇器
        是 0-2-1，穩穩蓋過前面 .section-head 等 0-1-0 的規則。三頁的形狀本來
        就要一致（CLAUDE.md §5），新增法律頁時這個 class 也要跟上。
   -------------------------------------------------------------------------- */

/* 光暈原本在左上角 10%，是配合靠左的標題；標題置中了就要跟著移到正上方。 */
html.legal-page .page-hero {
  background:
    radial-gradient(ellipse 75% 90% at 50% 0%, rgba(123, 175, 49, 0.15), transparent 62%),
    linear-gradient(180deg, var(--bg-raised), var(--bg));
  text-align: center;
}

html.legal-page .page-hero__title {
  max-width: 24ch;
  margin-inline: auto;
}

/* .lead 自己有 max-width: 62ch 但沒有 auto 邊距，不加這一條會卡在左邊。 */
html.legal-page .page-hero .lead,
html.legal-page .section-head .lead {
  margin-inline: auto;
}

/* 標題群組收窄到和內文欄差不多寬，兩欄才會同心：
   52rem 的預設值在 4K 上是 1092px，比 782px 的內文欄寬一大截。 */
html.legal-page .section-head {
  max-width: 40rem;
  margin-inline: auto;
  text-align: center;
}

html.legal-page .article__body {
  margin-inline: auto;
}

html.legal-page .btn-row {
  justify-content: center;
}

/* --------------------------------------------------------------------------
   20c. Cookie 同意橫幅（Google Ads 轉換追蹤用）
   -------------------------------------------------------------------------- */
/* 這一條橫幅是「同意之前一個位元組都不送給 Google」那個做法的門面 ——
   在訪客按下 Accept 之前，main.js §13 不會載入任何 Google 的程式。
   所以它不是裝飾，是唯一讓追蹤開始的開關。

   三件事刻意這樣做，不要「順手改掉」：

   1. 整塊是 JavaScript 建出來的（main.js §13），HTML 裡沒有它。
      這樣 26 頁一個字都不用改，而且 JS 關掉時它不出現 —— 那也是對的，
      因為追蹤本身就是 JS，JS 關掉時根本沒有東西需要同意。
   2. 它插在 .skip-link 後面、頁首前面，所以鍵盤的 Tab 順序是
      跳過導覽 → 同意橫幅 → 頁首。視覺上在畫面下緣，順序上在最前面，
      這是同意介面該有的位置。
   3. **兩顆按鈕大小一樣、都是一下就完成。** 拒絕不可以比接受難按，
      否則就是 GDPR 明文禁止的暗黑模式。要改樣式的話這一條要守住。 */
.consent {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  /* 頁首是 100、左側點點是 90、skip-link 是 200。
     夾在中間，蓋得住內容但蓋不住 skip-link。 */
  z-index: 150;
  background: var(--surface);
  border-top: 1px solid var(--line-strong);
  box-shadow: 0 -18px 40px rgba(0, 0, 0, 0.45);
  animation: consent-in 0.35s var(--ease) both;
}

@keyframes consent-in {
  from { transform: translateY(100%); }
  to   { transform: none; }
}

.consent__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.25rem 2rem;
  padding-block: 1.25rem;
}

.consent__body {
  flex: 1 1 22rem;
  min-width: 0;
}

.consent__title {
  margin: 0 0 0.35rem;
  font-weight: 700;
  color: var(--text);
}

.consent__text {
  margin: 0;
  /* 這一塊的對比實際量過（不是沿用別處的數字 —— --text-muted 在 --bg 上是
     7.96、--bg-raised 上是 7.50，在 --surface 上又不一樣）：
       標題 --text          15.03:1  AAA
       內文 --text-muted     7.06:1  AAA
       連結 --brand-bright   9.93:1  AAA */
  color: var(--text-muted);
  font-size: 0.95rem;
  line-height: 1.65;
  max-width: 68ch;
}

/* 站上全域 a { color: inherit; text-decoration: none }，所以這裡的連結
   和 .article__body a / .spec-table a 一樣要自己上色**並且**加底線 ——
   綠色壓在周圍的灰字上只有 1.41:1，光靠顏色會違反 WCAG 1.4.1。 */
.consent__text a {
  color: var(--brand-bright);
  text-decoration: underline;
  text-decoration-color: rgba(154, 212, 73, 0.45);
  text-underline-offset: 0.2em;
}

.consent__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  flex-shrink: 0;
}

/* 兩顆按鈕等寬 —— 見上面第 3 點。.btn 本身已經是 55.9 / 57.9px 高，
   遠超過 44px 的最小點擊區域。 */
.consent__btn {
  min-width: 9rem;
  justify-content: center;
}

@media (max-width: 47.9375rem) {
  .consent__actions {
    width: 100%;
  }

  .consent__btn {
    flex: 1 1 0;
    min-width: 0;
  }
}

/* --------------------------------------------------------------------------
   21. 手機版
   -------------------------------------------------------------------------- */
@media (max-width: 61.9375rem) {
  .nav-toggle {
    display: inline-flex;
    position: relative;
    /* 自己一個合成層：三槓變 X 的動畫才不會去重畫頁首的毛玻璃，
       否則 iOS Safari 會在毛玻璃上留下殘影（見上面 .nav-toggle__bars 的註解）。
       放在按鈕上而不是放在 .header 上，理由也寫在那裡。
       translateZ(0) + backface-visibility 是 Safari 上最老牌、最可靠的
       「請把這一塊獨立成一層」寫法；-webkit- 前綴是給 iOS 15.4 之前的版本。 */
    transform: translateZ(0);
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
  }

  .nav {
    position: fixed;
    inset: 4.75rem 0 auto;
    max-height: calc(100dvh - 4.75rem);
    margin: 0;
    padding: 1rem var(--gutter) 2rem;
    background: #080b0a;
    border-bottom: 1px solid var(--line-strong);
    box-shadow: 0 24px 48px -16px rgba(0, 0, 0, 0.9);
    overflow-y: auto;
    transform: translateY(-0.75rem);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.25s var(--ease), transform 0.25s var(--ease),
      visibility 0.25s;
  }

  .nav.is-open {
    opacity: 1;
    visibility: visible;
    transform: none;
  }

  .nav__list {
    flex-direction: column;
    align-items: stretch;
    gap: 0.15rem;
  }

  .nav__link {
    padding: 0.85rem 0.75rem;
    font-size: 1rem;
  }

  /* 手機上沒有滑鼠可以 hover，下拉選單改成點擊展開的清單。
     絕對定位在窄螢幕會超出畫面，所以改回一般文件流。 */
  .nav__trigger {
    width: 100%;
    justify-content: space-between;
  }

  /* 收合用 display:none 而不是高度動畫。
     高度動畫要嘛需要固定高度、要嘛需要多包一層容器；
     手機上的展開清單直接顯示/隱藏就夠好，也不會有算錯高度的風險。 */
  .nav__menu {
    position: static;
    display: none;
    min-width: 0;
    padding: 0.2rem 0 0.5rem 0.85rem;
    border-top: 0;
    background: none;
    backdrop-filter: none;
    border-radius: 0;
    box-shadow: none;
    opacity: 1;
    visibility: visible;
    transform: none;
    transition: none;
  }

  .nav__menu::before {
    display: none;
  }

  /* 手機沒有滑鼠，只認 aria-expanded，不要被 hover / focus-within 影響 */
  .nav__item--menu:hover .nav__menu,
  .nav__item--menu:focus-within .nav__menu {
    display: none;
  }

  .nav__trigger[aria-expanded="true"] + .nav__menu,
  .nav__item--menu:hover .nav__trigger[aria-expanded="true"] + .nav__menu,
  .nav__item--menu:focus-within .nav__trigger[aria-expanded="true"] + .nav__menu {
    display: block;
  }

  .nav__menu a {
    padding: 0.7rem 0.75rem;
    font-size: 0.9375rem;
    white-space: normal;
  }

  .header__cta {
    display: none;
  }

  /* 手機版把 CTA 放進展開的選單裡 */
  .nav__cta {
    margin-top: 1rem;
  }

  .nav__cta .btn {
    width: 100%;
  }

  .hero {
    min-height: auto;
  }

  .hero__scroll {
    display: none;
  }

  /* 手機版畫面窄，背景圖被裁得很滿，容易和標題打在一起。
     這裡把遮罩加重，並在文字所在的中段壓得更暗，確保標題永遠讀得清楚。 */
  .hero__scrim {
    background: linear-gradient(
      to bottom,
      rgba(8, 11, 10, 0.9) 0%,
      rgba(8, 11, 10, 0.88) 45%,
      rgba(8, 11, 10, 0.8) 72%,
      var(--bg) 100%
    );
  }
}

@media (min-width: 62rem) {
  .nav__cta {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   21b. 大螢幕與 4K
        在 4K（3840px）螢幕上，一個固定 1240px 的版面只佔畫面 1/3，
        內容會顯得又小又空。

        做法是放大 html 的 font-size。因為全站的字級、間距、圓角、
        容器寬度都是用 rem 定義的，改這一個數值就會等比放大整個版面，
        不需要為每個元件寫一套大螢幕樣式。
        （預設瀏覽器是 16px；下面每一階都同時把容器再放寬一些。）
   -------------------------------------------------------------------------- */
@media (min-width: 112.5rem) {
  /* 約 1800px 起 —— 大尺寸筆電與 2K 螢幕 */
  html {
    font-size: 17px;
  }

  :root {
    --container: 82rem;
  }
}

@media (min-width: 150rem) {
  /* 約 2400px 起 —— 2.5K / 寬螢幕 */
  html {
    font-size: 19px;
  }

  :root {
    --container: 88rem;
  }
}

@media (min-width: 200rem) {
  /* 約 3200px 起 —— 4K */
  html {
    font-size: 21px;
  }

  :root {
    --container: 94rem;
  }
}

/* 大螢幕上首屏不要無限拉高，否則標題會離頁首太遠 */
@media (min-width: 112.5rem) {
  .hero {
    min-height: min(88vh, 66rem);
  }
}

/* --------------------------------------------------------------------------
   21b. 多角度展示元件 .angle-viewer(public/assets/js/angle-viewer.js)
   版面比例固定 16:9(與原本的 960x540 動畫一致),不影響周圍版面。
   沒有 JavaScript 時只顯示第一張。
   -------------------------------------------------------------------------- */
.angle-viewer {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  touch-action: pan-y;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
}
.angle-viewer.is-dragging { cursor: grabbing; }
.angle-viewer:focus-visible { outline: 2px solid var(--accent, #00a8f0); outline-offset: 4px; }
.angle-viewer__frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  -webkit-user-drag: none;
}
.angle-viewer:not(.is-ready) .angle-viewer__frame:not(:first-of-type) { display: none; }
.angle-viewer.is-ready .angle-viewer__frame {
  opacity: 0;
  transition: opacity 0.9s ease;
}
.angle-viewer.is-ready .angle-viewer__frame.is-active { opacity: 1; }
.angle-viewer.is-spin .angle-viewer__frame { transition: none; }
.angle-viewer__dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.15rem;
  display: flex;
  justify-content: center;
  gap: 0.15rem;
}
.angle-viewer__dot {
  position: relative;
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}
.angle-viewer__dot::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0.55rem;
  height: 0.55rem;
  margin: -0.275rem 0 0 -0.275rem;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.35);
  transition: background 0.3s ease, transform 0.3s ease;
}
.angle-viewer__dot.is-active::before { background: var(--accent, #00a8f0); transform: scale(1.3); }
.angle-viewer__dot:focus-visible { outline: 2px solid var(--accent, #00a8f0); outline-offset: 0; border-radius: 50%; }
.angle-viewer__status { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* --------------------------------------------------------------------------
   22. 尊重「減少動態效果」的系統設定（無障礙必要項）
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .reveal {
    opacity: 1;
    transform: none;
  }

  .marquee__track {
    animation: none;
  }
}

/* 列印時去掉深色背景，省墨水 */
@media print {
  body {
    background: #fff;
    color: #000;
  }

  .header,
  .dotnav,
  .hero__media,
  .hero__scrim {
    display: none;
  }
}

/* ==========================================================================
   多語系與表單新增(語言切換選單、語言提示條、草稿提示、表單成功/錯誤訊息、RTL)
   只用既有的設計變數,不新增顏色或字型。
   ========================================================================== */
.lang-switch { position: relative; margin-inline-start: auto; margin-inline-end: 0.75rem; font-size: 0.875rem; }
.lang-switch summary { display: inline-flex; align-items: center; gap: 0.4rem; cursor: pointer; list-style: none; padding: 0.45rem 0.65rem; border: 1px solid var(--line-strong); border-radius: 999px; color: var(--text); }
.lang-switch summary::-webkit-details-marker { display: none; }
.lang-switch summary:hover, .lang-switch[open] summary { border-color: var(--brand); color: var(--brand-bright); }
.lang-switch ul { position: absolute; inset-inline-end: 0; top: calc(100% + 0.4rem); z-index: 60; margin: 0; padding: 0.4rem; list-style: none; min-width: 11rem; background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--radius); }
.lang-switch a { display: block; padding: 0.45rem 0.7rem; border-radius: 8px; color: var(--text); text-decoration: none; }
.lang-switch a:hover, .lang-switch a:focus-visible { background: var(--surface-2); color: var(--brand-bright); }
.lang-switch a[aria-current="true"] { color: var(--brand-bright); font-weight: 600; }

.lang-banner { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 0.75rem 1rem; padding: 0.7rem var(--gutter); background: var(--surface-2); border-bottom: 1px solid var(--line-strong); color: var(--text); font-size: 0.9375rem; }
.lang-banner[hidden] { display: none; }
.lang-banner__go { padding: 0.4rem 1rem; }
.lang-banner__stay { background: none; border: 0; padding: 0.4rem 0.6rem; color: var(--text-muted); text-decoration: underline; cursor: pointer; font: inherit; }
.lang-banner__stay:hover { color: var(--text); }

.draft-notice { padding: 0.45rem var(--gutter); text-align: center; font-size: 0.8125rem; color: var(--text-muted); background: var(--bg-raised); border-bottom: 1px dashed var(--line-strong); }

.contact-main { min-width: 0; }
.form__success { padding: 2rem; border: 1px solid var(--brand); border-radius: var(--radius-lg); background: var(--surface); }
.form__success[hidden] { display: none; }
.form__error { margin: 0 0 1rem; color: var(--danger); }
.form__error[hidden] { display: none; }
.turnstile { margin: 0 0 1rem; min-height: 0; }
.footer__address { margin-top: 0.75rem; font-size: 0.875rem; color: var(--text-muted); }
.footer__pro-note { margin: 1.5rem 0 0; padding-top: 1rem; border-top: 1px solid var(--line); font-size: 0.875rem; color: var(--text-muted); }
/* 非英文頁的頁尾一行:「本頁為翻譯版本,以英文版為準」(取代頁首的草稿橫幅) */
.footer__translation-note { margin: 1rem 0 0; font-size: 0.875rem; color: var(--text-muted); }

/* 阿拉伯文由右至左:字型加上常見阿拉伯文字型,圖示箭頭翻轉 */
html[dir="rtl"] body { font-family: var(--font), "Segoe UI", Tahoma, "Noto Sans Arabic", sans-serif; }
html[dir="rtl"] .link-arrow svg, html[dir="rtl"] .btn svg { transform: scaleX(-1); }
html[lang^="th"] body { font-family: var(--font), "Noto Sans Thai", "Leelawadee UI", Tahoma, sans-serif; }
/* 聯絡頁側欄段落內的電話連結:要有底線,不能只靠顏色區分(無障礙頁的承諾;Lighthouse link-in-text-block) */
.contact-aside__card p a { text-decoration: underline; text-underline-offset: 2px; }
