/*
 * LapseWatch 網站的設計系統。
 *
 * ── 方向：誠實的儀表 ─────────────────────────────────
 *
 * 這是一個關於**錢**與**信任**的產品：它要你把訂閱清單交給它，
 * 而它的賣點是「我們不綁住你」。所以視覺上不能耍花招，
 * 但也不能像沒做完——**平淡和華麗一樣傷信任**。
 *
 * 三個決定：
 *
 * 1. **暖白紙感而不是純白**（#FBFAF7）。純白配黑字是每一個未經設計的
 *    網頁的樣子；暖一點點就會讀起來像有人排過版。
 * 2. **墨綠為錨、琥珀為警**。琥珀只用在「快到期」這一個語意上——
 *    一個顏色只做一件事，使用者才學得會它的意思。
 * 3. **數字用等寬**。這是錢的產品，金額要能上下對齊；
 *    比例字型下的 NT$1,180 和 NT$998 對不齊，看起來就不像帳。
 *
 * ── 字型 ─────────────────────────────────────────────
 *
 * ⚠️ **刻意不載入中文網頁字型。** 一套繁體中文字型是 5–10MB，
 * 而這個站最重要的資產是 18 篇要被搜尋引擎收錄的教學頁——
 * 為了字型讓每一頁多等兩秒，換來的是跳出率。
 * 層次改用**字重、字級、留白**做，那才是真正產生層次的東西。
 * 系統字型堆疊照台灣使用者的實際環境排（蘋方 → 微軟正黑）。
 */

:root {
  color-scheme: light;

  /* ── 顏色 ── */
  --bg: #fbfaf7;
  --surface: #ffffff;
  --surface-sunk: #f2f1ec;
  --text: #14181a;
  --muted: #5c6663;
  --line: #e2e1da;
  --line-strong: #cfcec4;

  --accent: #186050;
  --accent-ink: #ffffff;
  --accent-soft: #e8f0ed;

  /* 琥珀＝時間快到了。這個顏色在這個站只有這一個意思 */
  --warn: #a8560a;
  --warn-soft: #fbf0e3;

  --danger: #a52016;
  --danger-soft: #fbeae8;

  /* ── 間距 ── 4 的倍數，不要臨時湊數字 */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;
  --s7: 48px;
  --s8: 72px;

  --radius: 10px;
  --radius-lg: 16px;

  --font: 'PingFang TC', 'Microsoft JhengHei', 'Noto Sans TC', system-ui,
    -apple-system, 'Segoe UI', sans-serif;
  /*
    ⚠️ 英文頁要用拉丁字優先的堆疊。

    上面那組是中文優先的，而中文字型裡的彎引號與撇號是**全形**——
    英文頁的 "That's it" 會變成 "That' s it"，中間空一格。
    那不是排版風格，是看起來像壞掉。
  */
  --font-latin: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue',
    Arial, sans-serif;
  /* 金額專用。tabular 讓數字等寬，上下才對得齊 */
  --font-num: ui-monospace, 'SF Mono', 'Cascadia Mono', 'Roboto Mono', monospace;

  --shadow-sm: 0 1px 2px rgba(20, 24, 26, 0.04);
  --shadow: 0 4px 16px -6px rgba(20, 24, 26, 0.12);
}

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;

    --bg: #14171a;
    --surface: #1b1f22;
    --surface-sunk: #101315;
    --text: #e8ebe9;
    --muted: #98a29e;
    --line: #2c3235;
    --line-strong: #3c4448;

    /* 品牌綠在深色底上對比不足，要調亮而不是直接沿用 */
    --accent: #52b394;
    --accent-ink: #06231c;
    --accent-soft: #17302a;

    --warn: #e8a35c;
    --warn-soft: #2e2113;

    --danger: #f08a80;
    --danger-soft: #2f1a18;

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow: 0 4px 16px -6px rgba(0, 0, 0, 0.5);
  }
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  /*
    ⚠️ 用 `clip` 不是 `hidden`。
    頁首與頁尾用 `100vw` + 負邊距做滿版，而 `100vw` 含捲軸寬度，
    不擋的話桌機上會多出一條橫向捲軸。
    但 `overflow: hidden` 會建立一個捲動容器，**裡面的 `position: sticky`
    就全部失效**——試算頁的總額列、政策頁的側欄目錄都靠它。
    `clip` 不建立捲動容器，兩件事都成立。
  */
  overflow-x: clip;
  padding: 0 var(--s5) var(--s6);
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.8;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/*
  ⚠️ **頁尾要被推到視窗底部**，短頁面才不會讓它浮在半空中。
  登入頁、支援頁、退款頁的內容都不到一個螢幕高，而頁尾停在內容正下方
  的話，下面會空出一大塊——看起來像頁面還沒載完。

  用 flex + `margin-top: auto`，不是 `position: fixed`：
  固定定位的頁尾在長頁面上會一直擋住內容。
*/
.wrap {
  max-width: 760px;
  margin: 0 auto;
  min-height: calc(100vh - var(--s6));
  display: flex;
  flex-direction: column;
}

/*
  ⚠️ `margin-top: auto` 只在內容比視窗**短**的時候有作用（把頁尾推到底）。
  長頁面上 auto 等於 0，於是 `footer.site` 自己的 `margin-top: var(--s8)`
  被這一條蓋掉、又沒有東西補上——頁尾那條分隔線就貼在最後一段文字下面 12px。

  用 padding 補**沒有用**：分隔線是 `border-top`，畫在盒子的上緣，
  padding 只會把頁尾的文字往下推，線還是貼著。距離只能來自外面，
  所以改成讓前一個元素長出下邊距。
*/
.wrap > footer.site {
  margin-top: auto;
  /* 線改由裡面的第一段來畫，見下面那條 */
  border-top: 0;
  padding-top: 0;
  /* 和頁首一樣脫離 `.wrap`，否則底下那條線也會每頁一個寬度 */
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  padding-inline: max(var(--s5), calc(50vw - 500px));
}
/*
  ⚠️ 距離放在**頁尾裡面**，不是放在前一個元素上。

  第一版寫的是 `.wrap > *:has(+ footer.site) { margin-bottom }`，
  但方案頁的頁尾前面是一個 `hidden` 的狀態列——選到的是那個看不見的元素，
  margin 加在 `display: none` 的東西上等於沒加。而「頁尾前面那個是不是隱藏的」
  會隨每一頁不同，用選擇器去追永遠追不完。
*/
.wrap > footer.site > :first-child {
  margin-top: var(--s7);
  padding-top: var(--s5);
  border-top: 1px solid var(--line);
}

/*
 * ⚠️ flex 容器的子元素**不會摺疊 margin**。
 *
 * 一般排版下，段落的 24px 下邊距和標題的 48px 上邊距會摺疊成 48px；
 * 變成 flex 之後兩個相加變 72px，而前一個元素是什麼決定了相加多少——
 * 於是每個 h2 上方的空白變成 48 / 60 / 72 三種，節奏就散了。
 *
 * 把「緊接在標題前面」的那個元素的下邊距歸零，
 * 空白就固定等於標題自己的上邊距，和摺疊時的結果一致。
 */
.wrap > *:has(+ h2),
.wrap > *:has(+ h1) {
  margin-bottom: 0;
}
/*
  ⚠️ 麵包屑是例外。
  上面那條把它的下邊距也歸零，於是教學內頁的「取消教學 / 工具與雲端 / Adobe」
  直接貼在 h1 上——看起來像標題多了一行小字，而不是一條導覽路徑。
*/
.wrap > .crumb:has(+ h1) {
  margin-bottom: var(--s3);
}

/* 教學頁與政策頁是長文，窄一點更好讀；計算機需要寬一點放欄位 */
.wrap-wide {
  max-width: 940px;
}

/*
  政策長文：目錄 220 + 間距 48 + 內文 ~680。
  **內文的行長沒有變**——變寬是為了在旁邊擺一欄目錄，不是為了讓文字更長。
  一行超過 760 就開始難讀，而這三頁本來就是最不想讓人讀不下去的三頁。
*/
.wrap-doc {
  max-width: 1000px;
}

a {
  color: var(--accent);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ── 頁首 ─────────────────────────────────────────── */

/*
  ⚠️ **導覽列不能跟著 `.wrap` 的寬度走。**

  版心有三種：760（教學內頁）、940（首頁、試算、教學索引、方案）、
  1000（政策長文）。導覽列原本是 `.wrap` 的子元素，於是它的左右邊界
  每換一頁就動一次——LOGO 和帳號選單在畫面上左右滑，
  而那是**每一次換頁都會看到**的東西。

  作法是讓它整條滿版、內容自己置中在 1000。負邊距用 `50% - 50vw` 跳出
  `.wrap` 的限制，`padding-inline` 再把內容收回中間那 1000 裡。
  底線因此橫跨整個視窗——那本來就是頁首該有的樣子。
*/
header.site {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s4);
  padding: var(--s5) max(var(--s5), calc(50vw - 500px));
  margin-bottom: var(--s6);
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
  width: 100vw;
  margin-inline: calc(50% - 50vw);
}

/*
  ⚠️ **`[hidden]` 要用 `!important`，這不是偷懶。**

  UA 樣式表的 `[hidden] { display: none }` 特異性是 0-1-0，而任何
  `.something { display: flex }` 也是 0-1-0——後者贏在順序。
  結果是 JS 明明把 `hidden` 設好了，東西還留在畫面上。

  這個站已經踩過三次：`.svc`（搜尋濾掉的卡片沒消失）、
  `.svc-row`（同上）、`.btn`（登入鈕和帳號選單同時出現）。
  每次都是加一條 `.那個類別[hidden]` 補起來——**但補不完**，
  下一個設了 display 又會被 JS 開關的類別還是會中。

  一條全域規則把整類問題結束掉。

*/
[hidden] {
  display: none !important;
}

/* ── 品牌與帳號選單 ───────────────────────────────── */

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--s3);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
  text-decoration: none;
}

.brand-mark {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
}

/*
  ⚠️ **目前在哪一頁要看得出來。**

  `aria-current="page"` 本來就有設（apply-nav.mjs 會標），
  但一直沒有任何樣式吃它——於是它只對讀螢幕的人有用，
  用眼睛看的人完全不知道自己在哪。

  用底線而不是變色：導覽列裡已經有一顆有底色的「方案與價格」，
  那個獨佔性是刻意的，再多一個會互相搶。
*/
header.site nav > a[aria-current='page'] {
  color: var(--text);
  font-weight: 600;
  border-bottom: 2px solid var(--accent);
  padding-bottom: 2px;
  text-decoration: none;
}

/*
  ⚠️ 方案與價格是導覽列裡唯一有底色的一項。
  其他三項是「你可以去做的事」，這一項是「要付錢的地方」——
  在一排長得一樣的純文字連結裡，它跟旁邊搶不到任何注意力。
*/
.nav-cta {
  padding: 7px 14px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
  border-bottom: 0;
}

.nav-cta:hover,
.nav-cta[aria-current='page'] {
  background: var(--accent);
  color: var(--accent-ink);
  border-bottom: 0;
}

/*
  語言切換。刻意做得不顯眼——中文是預設，英文頁只是給
  從 Chrome 商店英文頁面進來的人一個落點。
*/
.nav-lang {
  font-size: 13px;
}

.acct {
  position: relative;
  display: flex;
  align-items: center;
}

.acct .btn-sm {
  padding: 7px 16px;
  font-size: 14px;
}

/* 下拉用原生 `<details>`：不需要 JS 就能開合，鍵盤本來就能操作 */
.acct summary {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: 5px 10px 5px 5px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  cursor: pointer;
  list-style: none;
  font-size: 14px;
  color: var(--text);
}

.acct summary::-webkit-details-marker {
  display: none;
}

.acct summary:hover {
  border-color: var(--line-strong);
}

.acct .avatar {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 13px;
  font-weight: 700;
}

.acct .acct-email {
  max-width: 12ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.acct .caret {
  font-size: 11px;
  color: var(--muted);
}

.acct-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 20;
  min-width: 190px;
  display: grid;
  padding: var(--s2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
}

.acct-menu a,
.acct-menu button {
  padding: 9px var(--s3);
  border: 0;
  border-radius: 6px;
  background: none;
  font: inherit;
  font-size: 14px;
  text-align: left;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
}

.acct-menu a:hover,
.acct-menu button:hover {
  background: var(--surface-sunk);
}

/* 登出和上面三個是不同性質的動作，中間要有一條線 */
.acct-menu button {
  margin-top: var(--s2);
  padding-top: var(--s3);
  border-top: 1px solid var(--line);
  border-radius: 0;
  color: var(--danger);
}

@media (max-width: 560px) {
  /* 手機上名字讓位，只留頭像與箭頭 */
  .acct .acct-email {
    display: none;
  }
}

/*
  ⚠️ 用 flex + gap，不是 `nav a { margin-left }`。
  margin 只套用在 `<a>` 上，而「我的訂閱」那一頁的導覽列最後是一顆
  `<button>`（登出）——用 margin 的話它會直接黏在前一個連結上。
*/
header.site nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s1) var(--s4);
}

/*
  ⚠️ **手機上的點擊目標至少要 44px 高。**

  原本這裡是 `padding: 4px 0`，算出來每個連結只有 34px——
  低於 Apple 的 44 與 Google 的 48。導覽列是全站每一頁都有的東西，
  點不準的話使用者每一頁都在點錯。

  桌機上維持原本的緊湊間距（滑鼠準得多，而且 48px 高的一排連結
  會讓頁首變得很笨重），用 hover 能力當分界而不是螢幕寬度——
  平板橫著拿時寬度像桌機，但手指還是手指。
*/
nav a {
  font-size: 14px;
  color: var(--muted);
  text-decoration: none;
  padding: var(--s1) 0;
  border-bottom: 1px solid transparent;
}


nav a:hover {
  color: var(--text);
  border-bottom-color: var(--accent);
}

/* ── 文字 ─────────────────────────────────────────── */

h1 {
  font-size: clamp(28px, 4.4vw, 38px);
  line-height: 1.3;
  letter-spacing: -0.02em;
  margin: 0 0 var(--s4);
  text-wrap: balance;
}

h2 {
  font-size: 21px;
  line-height: 1.45;
  letter-spacing: -0.01em;
  margin: var(--s7) 0 var(--s3);
}

h3 {
  font-size: 16px;
  line-height: 1.5;
  margin: 0 0 var(--s2);
}

p,
li {
  margin: 0 0 var(--s3);
}

/*
 * ⚠️ 長字串一定要能斷行。
 *
 * 教學頁的步驟是從 `guides.data.json` 來的，而那些步驟常常包含網址
 * （例如「開啟 play.google.com/store/account/subscriptions」）。
 * 一個沒有空格的長字串在手機寬度下撐開整個版面，
 * 整頁就變成可以左右拖動的——而使用者只會覺得這個網站做壞了。
 *
 * 用 `break-word` 不是 `anywhere`：前者只在「這個字單獨一行也放不下」時才斷，
 * 一般的中英文混排不受影響。
 */
p,
li,
td,
summary,
.answer,
.direct .url {
  overflow-wrap: break-word;
}

.lede {
  font-size: 18px;
  line-height: 1.75;
  color: var(--muted);
  margin-bottom: var(--s5);
  text-wrap: pretty;
}

.muted {
  color: var(--muted);
  font-size: 14px;
}

/* 金額。等寬 + tabular，上下才對得齊 */
.num {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}

/* ── 卡片 ─────────────────────────────────────────── */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s4) var(--s5);
  margin: 0 0 var(--s3);
  box-shadow: var(--shadow-sm);
}

.card h3 {
  font-size: 16px;
}

.card p:last-child {
  margin-bottom: 0;
}

/* 可點的卡片（教學頁索引）。整塊都是熱區，不是只有標題那一行 */
a.card {
  display: block;
  color: inherit;
  text-decoration: none;
  transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}

a.card:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
  box-shadow: var(--shadow);
}

a.card h3 {
  color: var(--accent);
}

/*
  ⚠️ callout 是「停下來讀這一句」，不是裝飾。
  用得太多就沒有人會停——一頁最多一到兩個。
*/
.callout {
  border-left: 3px solid var(--accent);
  background: var(--accent-soft);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: var(--s3) var(--s5);
  margin: var(--s5) 0;
}

.callout p:last-child {
  margin-bottom: 0;
}

/*
  ⚠️ 整圈綠框，比一般 callout 重一級。
  「一鍵取消 + 30 天退款」是這個產品的誠信證明——一個做「防止被扣款」
  的工具，自己的訂閱好不好取消就是它值不值得信任的證據。
  那句話不能長得跟旁邊的補充說明一樣。
*/
.callout-strong {
  border: 1px solid var(--accent);
  border-left-width: 3px;
  border-radius: var(--radius);
  padding: var(--s4) var(--s5);
}

.callout-warn {
  border-left-color: var(--warn);
  background: var(--warn-soft);
}

/* ── 表格 ─────────────────────────────────────────── */

table {
  width: 100%;
  border-collapse: collapse;
  margin: var(--s4) 0 var(--s5);
  font-size: 15px;
}

/*
  寬表格的橫向捲動容器。

  ⚠️ **捲動要發生在表格自己身上，不是整個頁面。**
  沒有這一層的話，手機上一張三欄的表格會把 body 撐寬，
  於是整頁都能左右拖——包含導覽列和頁尾。那看起來就像版面壞了。

  `margin` 抵銷掉 table 自己的上下邊界，避免包一層就多出一段空白。
*/
/*
  「我的訂閱」的分頁列。

  ⚠️ 用底線標示目前這一頁，不是整顆變色的膠囊。
  這一列有四項，四顆膠囊會和導覽列的「方案與價格」搶注意力——
  而那顆是全站唯一有底色的東西，那個獨佔性是刻意的。
*/
.tabs {
  display: flex;
  gap: var(--s1);
  margin: var(--s6) 0 var(--s5);
  border-bottom: 1px solid var(--line);
  /* 手機上四項放不下時可以橫向捲，不要擠成兩行 */
  overflow-x: auto;
  overscroll-behavior-x: contain;
}

.tabs button {
  flex: 0 0 auto;
  padding: var(--s3) var(--s4);
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  background: none;
  color: var(--muted);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}

.tabs button:hover {
  color: var(--text);
}

.tabs button[aria-selected='true'] {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

/*
  ⚠️ 面板的第一個元素不要再帶上邊距。

  h2 自己有 48px 的上邊距，而分頁列下面已經有 24px——
  兩個加起來讓內容和分頁之間空出一大塊，看起來像載入失敗。
*/
[role='tabpanel'] > :first-child {
  margin-top: 0;
}

/*
  帳號分頁裡的三塊。
  每一塊回答一個問題，中間要有明顯的距離——
  原本它們是同一列上的四顆按鈕，看起來像雜物櫃。
*/
.stack {
  display: grid;
  gap: var(--s6);
}

.stack h3 {
  margin: 0 0 var(--s2);
}

/*
  共享清單在表格裡的分隔列。

  ⚠️ 共享來的訂閱**一定要看得出來是誰的**。
  和自己的混在一起的話，使用者會以為那是自己記的，
  然後在自己的帳單上找不到那一筆。
*/
.shared-head {
  padding-top: var(--s4);
  color: var(--muted);
  font-size: 13px;
  font-weight: 600;
}

.shared-row td:first-child {
  padding-left: var(--s4);
}

/*
  邀請連結的輸入框。
  用 input 而不是 <code>：使用者要能一次全選複製，
  而長網址在 <code> 裡只能手動拖曳。
*/
.share-link {
  width: 100%;
  margin: var(--s2) 0;
  padding: var(--s2) var(--s3);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-num);
  font-size: 13px;
}

/* 年度回顧卡片上的那個大數字 */
.review-num {
  margin: var(--s2) 0 var(--s1);
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: 26px;
  font-weight: 700;
  line-height: 1.2;
  /* 金額可能很長（多幣別會並排），窄螢幕上要能斷行而不是撐破卡片 */
  overflow-wrap: anywhere;
}

.scroll {
  overflow-x: auto;
  margin: var(--s4) 0 var(--s5);
  /* 捲到邊界時不要把捲動傳給整頁 */
  overscroll-behavior-x: contain;
}

.scroll > table {
  margin: 0;
  /* 欄位太窄會擠成兩三行；寧可捲動也不要疊字 */
  min-width: 32rem;
}

th,
td {
  text-align: left;
  padding: var(--s3) var(--s3);
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

th {
  font-size: 13px;
  color: var(--muted);
  font-weight: 600;
  border-bottom-color: var(--line-strong);
}

tr:last-child td {
  border-bottom: 0;
}

/* ── 按鈕 ─────────────────────────────────────────── */

/*
  ⚠️ 這一段曾經整個不存在，而 `class="btn"` 用在 20 個頁面上——
  包含每一篇教學頁的「用 LINE 提醒我」。所有按鈕都是瀏覽器的預設灰方塊，
  而沒有任何測試會抓到：HTML 合法、連結會動、tsc 和 eslint 都不看 CSS。

  `<a>` 和 `<button>` 共用同一組類別：教學頁的 CTA 是連結、表單送出是按鈕，
  但使用者眼中它們是同一個東西。
*/
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  padding: 11px 20px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.1s ease;
}

.btn:hover {
  background: var(--surface-sunk);
  border-color: var(--muted);
}

.btn:active {
  transform: translateY(1px);
}

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

.btn-primary:hover {
  background: color-mix(in srgb, var(--accent) 86%, var(--text));
  border-color: color-mix(in srgb, var(--accent) 86%, var(--text));
}

.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
}

.btn:disabled:hover {
  background: var(--accent);
  border-color: var(--accent);
}

/* 連結型按鈕的文字色不能被 a{color} 蓋掉 */
a.btn-primary,
a.btn-primary:hover {
  color: var(--accent-ink);
}

.btn-block {
  width: 100%;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  margin: var(--s4) 0;
}

/* ── 頁尾 ─────────────────────────────────────────── */

footer.site {
  margin-top: var(--s8);
  padding-top: var(--s5);
  border-top: 1px solid var(--line);
  font-size: 13px;
  color: var(--muted);
}

footer.site a {
  color: var(--muted);
}

footer.site a:hover {
  color: var(--accent);
}

/* ── 首頁的英雄區 ─────────────────────────────────── */

.hero {
  padding: var(--s6) 0 var(--s7);
}

.hero h1 {
  font-size: clamp(32px, 5.5vw, 46px);
}

.hero .lede {
  max-width: 34em;
  font-size: 19px;
}

/* 三個一組的重點。首頁與方案頁共用 */
.grid-3 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--s3);
  margin: var(--s4) 0 var(--s5);
}

.grid-3 .card {
  margin: 0;
}

/* 步驟。數字要看得出是順序，不是項目符號 */
.steps {
  list-style: none;
  counter-reset: step;
  padding: 0;
  margin: var(--s4) 0 var(--s5);
  display: grid;
  gap: var(--s3);
}

/*
  ⚠️ **不要用 grid 排這個。**
  `grid-template-columns: 30px 1fr` 會把 li 的**每一個子元素**當成 grid 項目，
  所以內文裡只要出現一個 `<strong>`，它就會被丟進第二列的 30px 欄位——
  整句話變成一個字一行垂直排下來。內文有幾個行內元素是寫文案的人決定的，
  版面不能依賴那個數字。

  改成 padding 留位子 + 絕對定位的圓圈，內文就照正常的行內流排版。
*/
.steps li {
  counter-increment: step;
  position: relative;
  padding-left: 42px;
  min-height: 30px;
  margin: 0;
  /*
    ⚠️ **grid 項目的 `min-width` 預設是 `auto`，意思是「不准縮到比內容還窄」。**

    教學頁的步驟裡常常有一整串網址（play.google.com/store/account/subscriptions），
    那是一個斷不開的字，於是這一列的 min-content 寬度就等於那串網址的長度——
    li 直接比 ol 寬出去，整頁在手機上可以左右拖。

    `overflow-wrap: break-word` 擋不住這個：它管的是「排版時要不要斷字」，
    但 min-width: auto 是在**算容器寬度**的階段就已經把 li 撐開了。
    兩個都要有。
  */
  min-width: 0;
}

.steps li::before {
  content: counter(step);
  position: absolute;
  left: 0;
  top: 0.15em;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  font-family: var(--font-num);
  font-size: 14px;
  font-weight: 700;
}

/* ── 三種用法的對照表 ─────────────────────────────── */

.tiers {
  width: 100%;
  border-collapse: collapse;
  margin: var(--s4) 0;
  font-size: 15px;
}

.tiers th,
.tiers td {
  text-align: left;
  padding: var(--s3);
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.tiers th {
  font-size: 13px;
  color: var(--muted);
}

.tiers tr:last-child td {
  border-bottom: 0;
}

@media (max-width: 560px) {
  .tiers,
  .tiers tbody,
  .tiers tr,
  .tiers td {
    display: block;
  }
  .tiers thead {
    display: none;
  }
  .tiers tr {
    border-bottom: 1px solid var(--line);
    padding: var(--s2) 0;
  }
  .tiers td {
    border: 0;
    padding: var(--s1) 0;
  }
  .tiers td:first-child {
    font-weight: 700;
  }
}

/* ── 表單 ─────────────────────────────────────────── */

input,
select,
textarea {
  font: inherit;
  font-size: 15px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  padding: 10px 12px;
}

input:focus,
select:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}

input::placeholder {
  color: var(--muted);
  opacity: 0.7;
}

.field {
  display: grid;
  gap: var(--s2);
}

.field > span {
  font-size: 13px;
  font-weight: 600;
}

/* ── 標籤 ─────────────────────────────────────────── */

.tag {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 600;
  background: var(--surface-sunk);
  color: var(--muted);
}

.tag-accent {
  background: var(--accent-soft);
  color: var(--accent);
}

.tag-warn {
  background: var(--warn-soft);
  color: var(--warn);
}

/* ── 方案卡 ───────────────────────────────────────── */

/*
  ⚠️ **不要用表格讓人決定要不要付錢。**
  表格是拿來比較細節的，但決定「要不要買」是先看價格與一句話，
  細節是之後才查的。原本這一頁一進去就是兩張表，
  沒有價格的視覺重量、也沒有任何可以按的東西。
*/
.plans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--s4);
  margin: var(--s5) 0 var(--s6);
}

.plan {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
  padding: var(--s5);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

.plan-featured {
  border-color: var(--accent);
  box-shadow: var(--shadow);
}

.plan h3 {
  margin: 0;
  font-size: 15px;
  color: var(--muted);
  font-weight: 600;
}

.plan .price {
  display: flex;
  align-items: baseline;
  gap: var(--s2);
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
}

.plan .price small {
  font-family: var(--font);
  font-size: 14px;
  font-weight: 500;
  color: var(--muted);
  letter-spacing: 0;
}

.plan ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  /*
    ⚠️ 用 `start` 對齊，不要讓列被拉開。

    `flex: 1` 是為了把按鈕推到卡片底部、讓三張卡的按鈕齊平。
    但 grid 預設會把多出來的高度平均分給每一列——項目少的那張卡
    （月繳只有三項）就變成三行等距散開，看起來像漏排版。
    改成 start 之後，多出來的空間統一留在清單下方。
  */
  align-content: start;
  gap: var(--s2);
  font-size: 14px;
}

/*
  ⚠️ 把按鈕推到底部的工作交給最後一個 ul，不是每一個。

  付費卡現在有兩組清單（都包含／各自的特色），如果每一個 ul 都
  `flex: 1`，多餘的高度會被平分成兩塊空白夾在中間。
*/
.plan > ul:last-of-type {
  flex: 1;
}

.plan ul li {
  margin: 0;
  padding-left: 22px;
  position: relative;
  line-height: 1.65;
}

.plan ul li::before {
  content: '✓';
  position: absolute;
  left: 0;
  color: var(--accent);
  font-weight: 700;
}

.plan ul li.no::before {
  content: '—';
  color: var(--muted);
}

.plan ul li.no {
  color: var(--muted);
}

/* ── 常見問題 ─────────────────────────────────────── */

/*
  ⚠️ FAQ 用 `<details>`，不是一長串 h3 + p。
  攤開來的十個問答是一面文字牆——使用者要找的是**他那一個**問題，
  而在牆裡找一行字比捲動十個標題慢得多。
  收合起來一眼掃得完，而且不需要任何 JavaScript。
*/
.faq {
  display: grid;
  gap: var(--s2);
  margin: var(--s4) 0 var(--s6);
}

.faq details {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  overflow: hidden;
}

.faq details[open] {
  border-color: var(--line-strong);
}

.faq summary {
  padding: var(--s3) var(--s5);
  font-weight: 600;
  font-size: 15px;
  cursor: pointer;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s3);
}

.faq summary::-webkit-details-marker {
  display: none;
}

.faq summary::after {
  content: '+';
  font-family: var(--font-num);
  font-size: 18px;
  color: var(--accent);
  flex-shrink: 0;
}

.faq details[open] summary::after {
  content: '−';
}

.faq summary:hover {
  background: var(--surface-sunk);
}

.faq .answer {
  padding: 0 var(--s5) var(--s4);
  color: var(--muted);
  font-size: 15px;
}

.faq .answer p:last-child {
  margin-bottom: 0;
}

/* ── 教學頁的直達網址 ─────────────────────────────── */

/*
  ⚠️ 這是整頁的重點，**不能只是一行普通連結**。
  使用者搜尋「Netflix 怎麼取消」落在這裡，他要的就是這個網址；
  找不到的話他會回去按上一頁，那一頁的功夫就白費了。
*/
.direct {
  display: grid;
  gap: var(--s3);
  padding: var(--s5);
  margin: var(--s5) 0 var(--s6);
  border: 1px solid var(--accent);
  border-radius: var(--radius-lg);
  background: var(--accent-soft);
}

.direct .label {
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
  margin: 0;
}

.direct .url {
  font-family: var(--font-num);
  font-size: 14px;
  word-break: break-all;
  color: var(--muted);
  margin: 0;
}

/*
  沒有直達網址的版本。
  用中性色而不是綠色：綠色在這個站的意思是「這裡有東西可以按」，
  而這一塊恰恰是在說「沒有東西可以按」。
*/
.direct-none {
  border-color: var(--line-strong);
  background: var(--surface-sunk);
}

.direct-none .label {
  color: var(--muted);
}

/*
  會賠錢的那種陷阱。
  用 --warn（琥珀）不是 --danger（紅）：紅色在這個站的意思是「刪除／出錯」，
  而這裡是「小心，這一條會讓你付出代價」——那正是琥珀在這個站的語意。
*/
.card-warn {
  border-color: var(--warn);
  background: var(--warn-soft);
}

.card-warn .card-flag {
  margin: 0 0 var(--s2);
  font-size: 13px;
  font-weight: 700;
  color: var(--warn);
}

.card-warn p:last-child {
  margin-bottom: 0;
}

.direct-none p:last-child {
  margin-bottom: 0;
}

/* ── 政策頁的目錄 ─────────────────────────────────── */

.toc {
  padding: var(--s4) var(--s5);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  margin: var(--s5) 0;
}

.toc p {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  margin: 0 0 var(--s2);
}

.toc ol {
  margin: 0;
  padding-left: 1.4em;
  columns: 2;
  column-gap: var(--s5);
  font-size: 14px;
}

.toc li {
  margin: 0 0 var(--s1);
  break-inside: avoid;
}

@media (max-width: 560px) {
  .toc ol {
    columns: 1;
  }
}

@media (max-width: 560px) {
  body {
    padding: 0 var(--s4) var(--s7);
  }
  h2 {
    margin-top: var(--s6);
  }
}

/* ============================================================
   LapseWatch 改版 — 新增樣式
   接在 website/style.css 現有區塊之後。
   全部只用既有變數，深色模式自動成立，verify:styles 會過。
   ============================================================ */

/* ── 首屏 ───────────────────────────────────────────── */
.hero-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: var(--s7);
  align-items: center;
  padding: var(--s7) 0 var(--s6);
}
@media (max-width: 860px) {
  .hero-split { grid-template-columns: 1fr; }
}

/*
  ⚠️ **`<figure>` 的預設左右邊距是 40px。**
  首屏右欄只有 380px 寬，扣掉 80px 之後截圖剩 300px——手機畫面裡的
  字就變得讀不到了，而那張圖存在的唯一理由就是讓人看懂「傳一句話就記好了」
  長什麼樣子。這是瀏覽器預設樣式，不歸零就永遠在那裡。
*/
.hero-split figure {
  margin: 0;
  display: grid;
  gap: var(--s3);
}

/* 兩段 padding 疊在一起，首屏上方會空掉 100px 以上 */
.hero.hero-split {
  padding-top: var(--s5);
}

/* 截圖固定比例裁切，切掉 LINE 畫面下方的空白與輸入列 */
.hero-shot {
  display: block;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 0.7;
  background: var(--surface);
  box-shadow: var(--shadow);
}
.hero-shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  display: block;
}

.eyebrow {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  background: var(--accent-soft);
  color: var(--accent);
}

.trust-strip {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s5);
  padding: var(--s4) 0;
  border-top: 1px solid var(--line);
  font-size: 14px;
  color: var(--muted);
}
.trust-strip strong { color: var(--accent); }

/* ── 搜尋與篩選（教學索引、計算機共用） ─────────────── */
.picker {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: 13px 18px;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}
.picker input {
  border: 0;
  padding: 0;
  background: none;
  flex: 1;
  font-size: 16px;
}
.picker input:focus { box-shadow: none; }
.picker:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  /*
    ⚠️ 沒有這一行的話，分類鈕會**直接貼在搜尋框下緣**（實測 0px）。
    兩個東西中間沒有距離，讀起來就是同一個元件——
    使用者看到的是「一個下面長了一排按鈕的搜尋框」，
    而它們其實是兩種獨立的篩選方式。
  */
  margin-top: var(--s4);
}
.chip {
  padding: 7px 14px;
  border-radius: 999px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}
.chip[aria-pressed='true'] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}
@media (max-width: 560px) {
  /* 手機加大觸控區 */
  .chip { padding: 9px 14px; }
}

/* ── 服務網格（教學索引） ───────────────────────────── */
/*
  ⚠️ **組與組之間原本空掉快 90px。**
  六組疊起來，整頁 2,290px 裡有超過五分之一是分組之間的空白，
  而每一組本身只有一到三列卡片。捲起來的感覺是「東西很少但頁面很長」。

  `.svc-grid` 的下邊距與下一個 `h2` 的上邊距是兩份，這裡把區塊自己
  當成間距的來源（`section + section`），只留一份。
*/
.svc-grid {
  display: grid;
  gap: var(--s2);
  margin: 0;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
/*
  ⚠️ 用 `section` 自己的上邊距，不要用 `section + section`。
  只給相鄰的那些的話，**第一組會直接貼在篩選鈕下面**——
  而分類標題貼著篩選鈕，看起來像那個標題是篩選鈕的一部分。
*/
section[data-cat] { margin-top: var(--s6); }
/* 同理，最後一組後面的那行小字也要有距離，否則它會貼在卡片下緣 */
section[data-cat] + p { margin-top: var(--s5); }
section[data-cat] > h2 { margin: 0 0 var(--s3); font-size: 19px; }
section[data-cat] > p.muted { margin: 0 0 var(--s3); font-size: 14px; }

.svc {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
  min-height: 62px;
  padding: 11px var(--s4);
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.15s ease, background 0.15s ease;
}
/*
  ⚠️ 卡片要看得出是連結。
  原本整張卡唯一的線索是標題是綠色的，而 hover 只有邊框變色 +
  上移一個像素——那個位移小到看不出來，反而讓整排卡片在滑過去時輕微抖動。
  改成整張卡換底色，並讓標題長出一個箭頭。
*/
.svc:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.svc h3 {
  font-size: 15px;
  color: var(--accent);
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--s2);
}
.svc h3::after {
  content: '→';
  margin-left: auto;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.svc:hover h3::after { opacity: 1; }
.svc p {
  font-size: 13px;
  line-height: 1.55;
  color: var(--muted);
  margin: 0;
}
/* 有 indexWarn 的服務 */
.svc-costly { border-color: var(--warn); }

/* ── 教學內頁 ───────────────────────────────────────── */
.crumb {
  font-size: 14px;
  color: var(--muted);
  margin: 0 0 var(--s3);
}
.meta {
  display: flex;
  align-items: center;
  gap: var(--s3);
  flex-wrap: wrap;
  margin: 0 0 var(--s6);
}
.meta-verified {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 11px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  background: var(--accent-soft);
  color: var(--accent);
}

/* 直達面板是全頁最重要的東西，按鈕要比一般 .btn 大一號 */
.direct .btn-primary {
  font-size: 17px;
  padding: 16px 28px;
}
.direct .after {
  margin: var(--s4) 0 0;
  padding-top: var(--s3);
  border-top: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
  font-size: 14px;
}

/* severity: 'high' 的陷阱。琥珀＝再不注意就會有代價 */
.gotcha-costly {
  border: 1px solid var(--warn);
  border-left: 4px solid var(--warn);
  border-radius: var(--radius);
  background: var(--warn-soft);
  padding: var(--s4) var(--s5);
  margin: 0 0 var(--s5);
}
.gotcha-costly .tag {
  background: var(--warn);
  color: var(--warn-soft);
  font-weight: 700;
  margin-bottom: var(--s2);
}

/* ── 計算機 ─────────────────────────────────────────── */
/*
  試算頁的服務列表。**兩欄的列，不是膠囊。**

  ⚠️ 我做過一次膠囊版，理由是「38 個方框太空、整頁三個半螢幕」。
  那個判斷的前提是錯的：空的原因不是列表形式，是我自己把
  分類標題做成 h2、把列做得又高又深、還讓空的總額列永遠佔著 90px。
  三個都修掉之後，兩欄的列比膠囊好——**名稱對齊，掃得比較快**，
  而且勾選前後是同一個東西在原地變化，不是換一種形狀。
*/
.svc-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s2);
  margin: 0;
}
@media (max-width: 640px) {
  .svc-grid-2 { grid-template-columns: 1fr; }
}

.svc-row {
  display: flex;
  align-items: center;
  gap: var(--s3);
  padding: 9px var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  /* 沒勾的是「還沒選的東西」，不該和選好的一樣重 */
  color: var(--muted);
  cursor: pointer;
  font-size: 14px;
  transition: border-color 0.15s ease, color 0.15s ease;
}
.svc-row:hover { border-color: var(--line-strong); color: var(--text); }

/*
  ⚠️ **勾選後排到該組最上面，用 `order` 不要動 DOM。**

  搬動節點會讓正在輸入的金額欄失去焦點——使用者打到一半，
  游標突然不見了。`order` 只影響版面，焦點完全不受影響。
*/
.svc-row.on {
  order: -1;
  grid-column: 1 / -1;
  padding: 11px var(--s4);
  border-color: var(--accent);
  border-width: 1.5px;
  color: var(--text);
  box-shadow: var(--shadow-sm);
  flex-wrap: wrap;
}

/*
  勾選框。瀏覽器預設的那顆在 macOS 與 Windows 上長得完全不同，
  而它是這一頁唯一重複 38 次的元件——不統一的話整頁的質感由作業系統決定。
*/
.svc-row input[type='checkbox'] {
  appearance: none;
  width: 18px;
  height: 18px;
  margin: 0;
  flex-shrink: 0;
  border: 1.5px solid var(--line-strong);
  border-radius: 5px;
  background: var(--bg);
  cursor: pointer;
  position: relative;
}
.svc-row input[type='checkbox']:checked {
  background: var(--accent);
  border-color: var(--accent);
}
.svc-row input[type='checkbox']:checked::after {
  content: '';
  position: absolute;
  left: 5px;
  top: 1px;
  width: 4px;
  height: 9px;
  border: solid var(--accent-ink);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.svc-row input[type='checkbox']:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.svc-row .pick {
  display: flex;
  align-items: center;
  gap: var(--s3);
  flex: 1;
  min-width: 120px;
  cursor: pointer;
}
.svc-row .name { font-weight: 500; }
.svc-row.on .name { font-weight: 600; font-size: 15px; }

/*
  ⚠️ **分段揭露：沒勾的列不顯示金額欄與週期。**
  38 個服務同時攤開就是 114 個控制項，而使用者真正要填的大概四個。
  這兩塊一直在 DOM 裡（不是動態產生的），所以勾選之後焦點可以立刻
  落到金額欄，而取消勾選時填過的數字也還留著。
*/
.svc-row:not(.on) .amount,
.svc-row:not(.on) .cycle {
  display: none;
}

.svc-row .amount {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: 8px var(--s3);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
}
/* 幣別符號由 JS 依瀏覽器地區填入，寬度固定住才不會在 NT$ 與 $ 之間左右跳 */
.svc-row .amount .symbol {
  font-size: 13px;
  color: var(--muted);
  min-width: 2.2em;
  text-align: right;
}
.svc-row .amount input {
  width: 5em;
  border: 0;
  padding: 0;
  background: none;
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: 17px;
  font-weight: 700;
}
.svc-row .amount input:focus { box-shadow: none; }
/*
  ⚠️ 拿掉 number input 的上下箭頭。
  那兩個箭頭一次加減 1 元——沒有人會用它把金額從 0 按到 380，
  而它們佔掉金額欄右邊的空間、還讓每一列的右緣長得不一樣寬。
*/
.svc-row .amount input::-webkit-outer-spin-button,
.svc-row .amount input::-webkit-inner-spin-button {
  appearance: none;
  margin: 0;
}
.svc-row .amount input { appearance: textfield; }

/* 週期用 radio 做的分段控制，不是 select——兩個選項不值得一個下拉選單 */
.cycle {
  display: inline-flex;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
}
.cycle input { position: absolute; opacity: 0; pointer-events: none; }
.cycle label {
  padding: 8px 16px;
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
}
.cycle input:checked + label {
  background: var(--accent);
  color: var(--accent-ink);
}
.cycle input:focus-visible + label {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/*
  總額列是這一頁唯一的產出，值得整條底色。
  原本只有一條 2px 綠線，在 3568px 的頁面上沒有人看得到。
*/
/*
  ⚠️ **總額列是浮在內容上面的，不是接在內容後面的。**

  它 sticky 在視窗底部，所以捲動時**一定**會蓋住後面的東西——
  原本它整條貼著視窗下緣、沒有圓角也沒有陰影，看起來就是
  「最後一列服務被切掉一半」，而不是「有一塊東西浮在上面」。

  內縮 + 圓角 + 陰影之後，被蓋住的那一列從底下透出來，
  使用者一眼就知道那是遮住不是壞掉。
*/
.totals {
  position: sticky;
  bottom: var(--s4);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s5);
  flex-wrap: wrap;
  background: var(--accent);
  color: var(--accent-ink);
  padding: var(--s4) var(--s5) calc(var(--s4) + env(safe-area-inset-bottom));
  /*
    ⚠️ 上邊距是給**停下來之後**用的。
    捲到底時 sticky 元素會回到它在文件流裡的位置，而那裡緊接著最後一列
    服務——中間沒有任何距離，看起來還是黏在一起。
    黏住的時候（捲動中）邊距不影響位置，所以只有靜止那一刻看得到它。
  */
  margin: var(--s6) 0 0;
  border-radius: var(--radius-lg);
  box-shadow: 0 10px 30px -10px rgba(20, 24, 26, 0.45);
}
.totals p { margin: 0; }
.totals .year {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: 36px;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
}
.totals .month {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.totals .btn {
  background: var(--surface);
  border-color: var(--surface);
  color: var(--accent);
}
@media (max-width: 560px) {
  .totals .year { font-size: 28px; }
}

/* ── 方案卡 ─────────────────────────────────────────── */
/* 卡片等高，特性清單撐開，按鈕才會齊平 */
.plans { align-items: stretch; }
.plan { position: relative; }
.plan-badge {
  position: absolute;
  top: -11px;
  left: var(--s5);
}
.plan .price s {
  font-family: var(--font-num);
  color: var(--muted);
}

/* ── 儀表板（我的訂閱） ─────────────────────────────── */
.overview {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4);
  margin: 0 0 var(--s6);
  align-items: stretch;
}
/* 主要金額吃掉剩下的空間，但不能被側卡壓到看不清楚 */
.overview > .spend { flex: 1 1 300px; }
.overview > .card { flex: 1 1 280px; }

/*
  ⚠️ **三張卡並排在這一頁是排不下的。**

  這一頁的容器是 760px，而年度金額那張至少要 300（52px 的數字），
  兩張側卡各 280——加起來 892。硬排的結果是第三張掉到第二列
  並被拉成整列寬，看起來像另一個區塊而不是同一組數字。實際量出來才發現。

  所以有第三張時改成上下兩層：年度金額獨佔一列（它本來就是主角），
  下面兩張小卡對半分。層級反而更清楚了。

  用 JS 加 class 而不是 `:has()`：這一頁沒有其他地方需要 `:has()`，
  而 hasSaved 那個判斷 JS 本來就算好了。
*/
.overview.has-saved > .spend { flex: 1 1 100%; }
@media (max-width: 760px) {
  /* 窄螢幕一張一列。並排的 300px 卡在手機上會把字擠成兩三行 */
  .overview > .spend,
  .overview > .card { flex: 1 1 100%; }
}

.spend {
  padding: var(--s5) var(--s6);
  border: 1px solid var(--accent);
  border-radius: var(--radius-lg);
  background: var(--accent-soft);
}
.spend .label {
  font-size: 14px;
  font-weight: 600;
  color: var(--accent);
  margin: 0 0 var(--s1);
}
.spend .amount {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: 52px;
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.05;
  margin: 0 0 var(--s1);
}
@media (max-width: 560px) {
  .spend .amount { font-size: 40px; }
}

/* 唯一需要立刻行動的資訊 */
.due-next {
  border-color: var(--warn);
  background: var(--warn-soft);
}
.due-next .label { color: var(--warn); }

/* 金額靠右等寬：一欄數字沒有對齊的話，「這幾筆哪一筆最貴」要一個一個讀 */
.subs .num {
  text-align: right;
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.subs td { vertical-align: middle; }
/*
  ⚠️ **不要在 `<td>` 上設 `display: flex`。**
  那會讓它不再是表格儲存格——它不跟著整列拉高，於是它的下框線
  比同一列其他三格高幾個像素，整張表看起來像有一條錯位的直線。
*/
.subs .row-actions { text-align: right; white-space: nowrap; }
.subs .row-actions .link-btn + .link-btn { margin-left: var(--s3); }

/*
  「媽媽 在付」。

  ⚠️ 共享清單上這一行是最重要的一句話——真正會被扣款的常常不是
  清單的擁有者。做得比服務名稱小但不要太灰：他要一眼掃到「這筆是誰的」，
  而不是去找。
*/
.payer {
  display: inline-block;
  margin-top: 2px;
  font-size: 12px;
  color: var(--text);
  background: var(--surface-sunk);
  border-radius: 999px;
  padding: 1px 8px;
}

/*
  「下一則提醒 8/12 09:00　LINE」。

  ⚠️ 刻意做小、做灰：它是**確認用**的資訊，不是這一列的主角。
  和到期日一樣大的話，兩個日期會並排在同一格裡互相打架，
  而使用者真正要看的是「什麼時候扣款」。
*/
.next-remind {
  display: inline-block;
  margin-top: 2px;
  font-size: 12px;
  color: var(--muted);
  font-family: var(--font-num);
}
/* 排不到提醒是一個「產品可能沒在運作」的狀態，不能和正常的長一樣 */
.next-remind.none {
  color: var(--warn);
  font-family: var(--font);
}

/*
  共享清單上「提醒我」那一格。

  ⚠️ 勾選框放大到 18px 並留出 44px 的可點範圍：
  這是整個共享分頁**唯一一個決定使用者收不收得到提醒**的控制項，
  而在手機上點不到的開關等於沒有這個功能。
  和上面同一個理由，不要在 `<td>` 上設 flex。
*/
.row-remind { text-align: center; }
.remind-toggle {
  width: 18px;
  height: 18px;
  margin: var(--s2) var(--s3);
  cursor: pointer;
  accent-color: var(--accent);
}
.remind-toggle:disabled { cursor: progress; }
.days {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-family: var(--font-num);
  font-size: 12px;
  font-weight: 700;
  background: var(--surface-sunk);
  color: var(--muted);
}
.days.soon {
  background: var(--warn-soft);
  color: var(--warn);
}
/*
  ⚠️ 已過期不能和「還有 3 天」同色。
  琥珀的意思是「還來得及，但要處理了」；已過期的意思是
  **錢已經扣走了**——那是完全不同的一件事，而使用者需要一眼分得出來。
*/
.days.over {
  background: var(--danger-soft);
  color: var(--danger);
}

/*
  ⚠️ 多幣別時要降字級。
  52px 的「$9,228 + US$240」在桌機上就會折成兩行，把整張卡撐高、
  跟旁邊的琥珀卡對不齊。多一種幣別就多一行，字級跟著往下走一階。
*/
.spend .amount.two { font-size: 38px; }
.spend .amount.many { font-size: 30px; }
.spend .amount span { display: block; }

/* ── 政策長文 ───────────────────────────────────────── */
.doc {
  display: grid;
  grid-template-columns: 220px minmax(0, 1fr);
  gap: var(--s7);
  align-items: start;
}
.doc-toc {
  position: sticky;
  top: var(--s5);
  font-size: 14px;
}

/*
  ⚠️ **連結要包一層才排得起來。**
  目錄是 `<details>`（手機要收起來），而 `display: grid` 設在 `<details>`
  上面對它的內容沒有作用——內容在瀏覽器自己的內部盒子裡，不是它的 grid 項目。
  結果 13 條連結會像一段普通文字一樣連續折行，看起來像沒有樣式。
*/
.doc-toc-list {
  display: grid;
  gap: 2px;
  border-left: 1px solid var(--line);
}

/*
  桌機不需要那顆展開鈕：旁邊有空間，目錄一直開著就好。
  手機才需要它——13 節攤開就是整整一個螢幕。
*/
.doc-toc summary {
  padding: 10px var(--s4);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
  font-weight: 600;
  cursor: pointer;
  margin-bottom: var(--s3);
}
@media (min-width: 861px) {
  .doc-toc summary { display: none; }
}

.doc-toc a {
  padding: 6px var(--s3);
  color: var(--muted);
  text-decoration: none;
}
.doc-toc a:hover { color: var(--text); }
.doc-toc a[aria-current='true'] {
  border-left: 2px solid var(--accent);
  margin-left: -1px;
  color: var(--accent);
  font-weight: 600;
}
.sec-head {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  padding-top: var(--s5);
  border-top: 1px solid var(--line-strong);
}
.sec-head h2 { margin: 0; }
.sec-head .n {
  font-family: var(--font-num);
  font-size: 14px;
  font-weight: 700;
  color: var(--accent);
}
/* 一句話版本：比一般 callout 重一級 */
.callout.summary p:last-child {
  font-size: 19px;
  line-height: 1.7;
}
.callout.summary .label {
  font-size: 14px;
  font-weight: 700;
  color: var(--accent);
  margin: 0 0 var(--s2);
}
/*
  ⚠️ 860px 以下一定要退回 static，
  否則側欄會蓋住內文。這個不會被測試抓到，只會在截圖裡看到。
*/
@media (max-width: 860px) {
  .doc { grid-template-columns: 1fr; }
  .doc-toc { position: static; }
}


/* 產品截圖。外框讓它看起來是「一張畫面」，不是一塊貼上來的圖 */
.shot {
  margin: var(--s5) 0 var(--s6);
}
.shot img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
}
.shot figcaption {
  margin-top: var(--s3);
  font-size: 13px;
}

/* 教學內頁結尾的那一段。和上面的陷阱卡拉開距離，讓它讀起來是「另一件事」 */
.next {
  margin-top: var(--s7);
  margin-bottom: var(--s5);
}

/* ── 狀態訊息與文字按鈕 ─────────────────────────────── */

/*
  ⚠️ **這一段是補回來的，不是新增的。**

  `subscriptions.html` 裡有一行註解寫著「`.msg` 與 `.link-btn` 已經搬到 style.css，
  方案頁也要用」——但那次搬移只刪掉了舊的定義，沒有貼上新的。
  於是註解本身變成了唯一的證據，而它說的是假話。

  實際結果：登入的錯誤訊息、付款失敗的訊息全部是無樣式的段落，
  紅色警告和成功訊息長得一模一樣；登出、下載 CSV／JSON、
  每一列的編輯與移除全部是瀏覽器預設的灰方塊按鈕。
  這正是 `.btn` 那個 bug 的第二次發生，而這次是被
  `verify:styles` 新增的網站類別檢查抓到的。
*/

.msg {
  margin: var(--s3) 0 0;
  padding: 10px 14px;
  border-radius: var(--radius);
  font-size: 14px;
  line-height: 1.6;
  background: var(--surface-sunk);
  color: var(--muted);
}
.msg.ok {
  background: var(--accent-soft);
  color: var(--accent);
}
.msg.err {
  background: var(--danger-soft);
  color: var(--danger);
}

/* 次要動作。看得出可以點，但不跟主按鈕搶 */
.link-btn {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--accent);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.link-btn:hover {
  text-decoration-thickness: 2px;
}

/*
  ⚠️ **破壞性動作要看得出來不一樣。**
  「移除」和「編輯」原本是兩顆完全相同的按鈕，而其中一顆會刪掉資料。
*/
.link-btn.danger {
  color: var(--danger);
}

/* 付費卡裡的小標題：「兩個付費方案都包含」／「月繳的特色」 */
.plan-shared-title {
  margin: var(--s3) 0 0;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--muted);
}

/* 「這兩項只涵蓋伺服器上的訂閱」那一句 */
.plan-scope {
  margin: 0;
  font-size: 12px;
  line-height: 1.6;
}

/*
  英文頁（/en/）用拉丁字優先的字型堆疊。
  用 `html[lang='en']` 而不是加一個類別：語言本來就寫在 <html> 上，
  而漏加類別的那一頁不會有任何跡象。
*/
html[lang='en'] body {
  font-family: var(--font-latin);
}

/* ── 首頁的迷你試算 ─────────────────────────────────
   ⚠️ 這是首屏唯一不用離站就體驗得到價值的東西。
   使用者的第一個問題不是「要不要裝」，是「我到底花了多少」——
   那個數字自己會說服人。
*/
.mini-calc {
  margin-top: var(--s5);
  padding: var(--s4);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.mini-title {
  margin: 0 0 var(--s3);
  font-size: 14px;
  font-weight: 600;
  color: var(--muted);
}

.mini-grid {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}

/*
  用膠囊而不是一列一列：五個選項排成五列會佔掉整個首屏，
  而這個東西要在標題下面、不能把 CTA 推出畫面。
*/
.mini-pick {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  border: 1px solid var(--line);
  border-radius: 999px;
  cursor: pointer;
  font-size: 14px;
  line-height: 1.4;
  /* 觸控裝置上整顆都要按得到 */
  min-height: 40px;
}

.mini-pick:hover {
  border-color: var(--line-strong);
}

/* 勾選之後整顆變色，不是只有小方塊——一眼看得出選了哪幾個 */
.mini-pick:has(input:checked) {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
}

.mini-pick input {
  /* 方塊本身藏起來，整顆膠囊就是它的點擊區 */
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.mini-name {
  white-space: nowrap;
}

.mini-price {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

.mini-pick:has(input:checked) .mini-price {
  color: inherit;
}

.mini-out {
  margin: var(--s4) 0 0;
  font-size: 15px;
  /*
    ⚠️ 固定高度。沒有這個的話，勾第一個時整塊會往下推一行，
    下面的 CTA 跟著跳——而使用者的手指正要往那裡按。
  */
  min-height: 44px;
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  flex-wrap: wrap;
}

.mini-zero {
  color: var(--muted);
}

.mini-total {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: 30px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--accent);
}

.mini-sub {
  font-size: 13px;
  color: var(--muted);
}

.mini-act {
  margin: var(--s3) 0 0;
}

.mini-more {
  margin: var(--s2) 0 0;
  font-size: 13px;
}

/* ════════════════════════════════════════════════════
   觸控裝置的點擊目標

   ⚠️ **這一段必須放在檔案最後面。**

   它是覆寫，而媒體查詢**不增加權重**——同權重下後面的贏。
   第一版把它放在檔案中段，於是 `.link-btn { padding: 0 }`（第 2000 多行）
   把裡面的 `padding-inline` 蓋掉了：高度變成 44、寬度還是 26。
   看起來修好了，實際上只修好一半。

   ⚠️ **只在 `hover: none` 下生效。** 用滑鼠的裝置維持緊湊版面——
   44px 一排的導覽列會讓頁首變得很笨重，而滑鼠本來就準。
   用有沒有 hover 判斷而不是螢幕寬度：平板橫著拿的寬度像桌機，
   但手指還是手指。

   每一條都是 `npm run audit` 實測量出來不夠的，不是照規範抄的。
   ════════════════════════════════════════════════════ */

@media (hover: none) {
  header.site nav > a,
  header.site .brand,
  .acct summary,
  .acct .btn-sm {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    /*
      ⚠️ 也要有最小寬度。「中文」只有兩個字 ＝ 28px 寬，
      高度撐到 44 之後仍然是一個很細的長條。
    */
    min-width: 44px;
    justify-content: center;
  }

  /*
    清單列上的「編輯／已取消／刪除」原本是 26×23，三顆並排——
    而**刪除是破壞性的**，旁邊 3px 就是「已取消」。
    手機上點錯的代價是刪掉一筆訂閱。
  */
  .link-btn {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding-inline: var(--s3);
  }

  /* 有了內距之後要能換行，不然窄螢幕上會把表格撐開 */
  .row-actions {
    flex-wrap: wrap;
  }

  /*
    ⚠️ 核取方塊不放大。它們包在 <label> 裡，整列都可以點，
    而把方塊本身撐到 44px 會讓那一排清單變得很鬆散。
  */
  input:not([type='checkbox']):not([type='radio']),
  select,
  textarea {
    min-height: 44px;
  }

  .doc-toc a {
    display: flex;
    align-items: center;
    min-height: 44px;
  }

  /*
    麵包屑上的連結（27 篇教學頁每一頁都有一個）原本 28px 高。
    它是使用者回到索引的主要路徑——在手機上點不準的話，
    他會改按瀏覽器的上一頁，然後那個回不到索引。

    用內距撐開而不是放大字：字體大小是版面節奏的一部分，
    而點擊區不必看得見。
  */
  .crumb a {
    display: inline-block;
    padding-block: var(--s2);
  }
}

/*
  「已經省下」卡。

  ⚠️ **不要給它自己的底色。**
  這個站的底色已經有兩個明確的意思：accent（綠）是主要金額那張大卡，
  琥珀是「時間快到了」。再上一個色，三張卡就全是重點，
  而顏色一旦到處都是就不再代表任何事。

  它靠**數字用 accent 色**和旁邊那張琥珀卡分開，同時保持在
  年度總額之下——那張才是這一頁的主角，這張是佐證。
*/
.saved strong {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--accent);
}

/*
  取消教學頁的「一年少付多少」。

  ⚠️ 金額要等寬對齊。這是一份用來**互相比較**的清單
  （「我用的是哪一個方案、退掉值多少」），數字沒有對齊的話
  要一個一個讀才知道哪個大。
*/
.worth {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--s3);
  font-variant-numeric: tabular-nums;
}
.worth li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s2) var(--s4);
  padding: var(--s2) 0;
  border-bottom: 1px solid var(--line);
}
.worth .per {
  color: var(--muted);
}
/*
  ⚠️ 一年的金額靠右、加重。
  這份清單存在的理由就是拿來比大小的（「我退掉的是哪一個、值多少」），
  散在行中間的話要一個一個讀。
*/
.worth .year {
  margin-left: auto;
  font-weight: 700;
}
.worth li:last-child {
  border-bottom: 0;
}

/* 回顧卡的下載列 */
.share-card-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s3);
  margin-top: var(--s5);
}

/*
  送不出去的提醒。

  ⚠️ 用 danger 不是 warn。琥珀的意思是「還來得及，但要處理了」，
  而這一段的意思是**已經有東西沒送到**——那是已經發生的事，
  和「快到期了」完全不同一個等級。
*/
.alert-fail {
  border: 1px solid var(--danger);
  border-left-width: 3px;
  border-radius: var(--radius);
  background: var(--danger-soft);
  padding: var(--s4) var(--s5);
  margin: 0 0 var(--s5);
}
.alert-fail strong {
  color: var(--danger);
}
.alert-fail ul {
  margin: var(--s2) 0;
  padding-left: 1.2em;
}
.alert-fail li {
  padding: 2px 0;
}
.alert-fail p:last-child {
  margin-bottom: 0;
}

/* 「貼上多筆」與「新增訂閱」並排 */
.sec-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}

.import-label textarea {
  width: 100%;
  font-family: var(--font-num), monospace;
  font-size: 15px;
  line-height: 1.6;
  padding: var(--s3);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: inherit;
  resize: vertical;
}

#import-result ul {
  margin: var(--s2) 0 var(--s4);
  padding-left: 1.2em;
}
#import-result li {
  padding: 2px 0;
}
#import-bad-box li {
  color: var(--danger);
}

/*
  只給螢幕閱讀器看的標籤。

  ⚠️ 不要用 `display: none` 或 `visibility: hidden`——
  那兩個會讓螢幕閱讀器也讀不到，等於這個標籤根本不存在。
*/
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/*
  設定頁的勾選框。

  ⚠️ 整行都要可以點（label 包住 input），不是只有那個小方框。
  在手機上點一個 16px 的方框是這一頁最容易點不到的東西。
*/
.check {
  display: flex;
  align-items: flex-start;
  gap: var(--s3);
  padding: var(--s3) 0;
  cursor: pointer;
}
.check input {
  margin-top: 3px;
  flex: none;
}


/*
  第三方登入的按鈕。

  ⚠️ **刻意做小，而且排在 email 之後。**

  一開始是滿版按鈕放在最上面，結果整張登入卡的第一眼變成
  「用 Google 登入」——而這個產品的第一句話是「不需要註冊、不需要登入」。
  把別人的品牌放在最顯眼的位置，等於用它來背書我們自己的登入。

  ⚠️ 也不用品牌色。這一頁不是在賣 Google，而且兩顆品牌色按鈕會互相打架。
*/
.oauth-buttons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s3);
}

.btn-oauth {
  /* 不是 block：兩顆並排時各自只佔自己需要的寬度 */
  padding: 8px 16px;
  font-size: 14px;
  font-weight: 500;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--text);
}
.btn-oauth:hover { border-color: var(--text); background: var(--surface-sunk); }

.oauth-note {
  margin-top: var(--s3);
  font-size: 12px;
  text-align: center;
  line-height: 1.7;
}

/* 「或」中間那條線 */
.oauth-or {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin: var(--s4) 0 var(--s3);
  color: var(--muted);
  font-size: 12px;
}
.oauth-or::before,
.oauth-or::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--line);
}
