/*
  **這一條必須放在最前面，而且必須是全域的。**
  瀏覽器內建樣式表的 `[hidden] { display: none }` 只是一條普通的 UA 規則，任何一條作者寫的
  `display` 宣告都會蓋掉它——本檔的 `.field { display: flex }` 就是一例。後果是
  `el('label', { class: 'field', hidden: true }, …)` 這種寫法（工作項 9 的備援碼欄位、
  工作項 10b 的六位數欄位、工作項 13、15 都用）**藏不掉標題文字**：使用者一打開登入畫面就同時
  看到「驗證器六位數」與「備援碼」兩組標題，只有其中一組下面有輸入框，看起來像壞掉的畫面。
  而 CI 會全綠——現有斷言驗的是 `<input>` 本身，UA 規則對它仍然有效。
  在這裡一次擋掉整個計畫後續所有同型錯誤，比在每個工作項各補一條 `.xxx[hidden]` 可靠。
*/
[hidden] { display: none !important; }

/* 設計權杖集中在這裡。改配色只改這一段。 */
:root {
  color-scheme: dark;

  --bg: #14161a;
  --surface: #1c1f26;
  --surface-raised: #242833;
  --line: #333947;
  --text: #e8eaef;
  --text-muted: #98a0b0;

  /* 六種嚴重度色帶（規格第九節「視覺設計決定」）。
     **exhausted 與 expired 必須是不同的顏色**：一個是等下一輪視窗，一個是這週不能用了。
     **idle 與 disabled 也必須不同色**（工作項 11 補上，P5-26d）：一個是「還沒開始跑」，
     一個是「我把它關掉了」，同色的話使用者分不出這兩件事。 */
  --state-running: #4c8bf5;
  --state-warning: #f0a02c;
  --state-expired: #e5484d;
  --state-exhausted: #2bb6c4;   /* 青色，規格指定 */
  --state-disabled: #4a5060;
  --state-idle: #6b7280;        /* 中性灰，與 --state-disabled 的深藍灰刻意不同 */

  /* 破壞性動作的警示色。**刻意與 --state-expired 同值但另立一個名字**：
     色帶的「已到期」與按鈕的「危險」是兩種語意，共用一個變數的話，
     哪天要調其中一個就會連帶改到另一個，而且改的人不會發現。 */
  --danger: #e5484d;

  --ok: #46a758;
  --radius: 10px;
  --gap: 12px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 16px/1.5 system-ui, -apple-system, "Noto Sans TC", sans-serif;
  /* 手機上不可以出現橫向捲動。 */
  overflow-x: hidden;
  padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}

#app { padding: var(--gap); padding-bottom: 96px; }

.screen[hidden] { display: none; }
.screen-title { font-size: 1.25rem; margin: 4px 0 var(--gap); }

/*
  標題列導覽（規格第九節「畫面間導覽」，決定 88）。主畫面：標題在左、`.screen-actions` 靠右（設定連結；
  計畫 6 的通知鈴鐺加在它左邊）。子畫面：`.nav-back` 在左、標題接在後面。
  `.nav-link` 的 min-height／min-width 44px 是觸控命中區的下限（NavigationTests 用 bounding box 釘住），
  不要為了排版把它縮小。三個無憑證畫面沒有 `.screen-header`，`.screen-title` 仍套上面那條的 margin。
*/
.screen-header { display: flex; align-items: center; gap: 8px; min-height: 44px; margin: 0 0 var(--gap); }
.screen-header .screen-title { margin: 0; min-width: 0; }
.screen-actions { display: flex; align-items: center; gap: 4px; margin-left: auto; }
.nav-link {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; min-width: 44px; padding: 0 8px;
  color: var(--text); text-decoration: none; white-space: nowrap;
  border-radius: var(--radius);
}
.nav-link:active { background: var(--surface); }
.nav-back { margin-left: -8px; color: var(--text-muted); }
.screen-actions .nav-link { margin-right: -8px; }
.screen-body { display: flex; flex-direction: column; gap: var(--gap); }

.muted { color: var(--text-muted); font-size: 0.875rem; }
.warn { color: var(--state-warning); }
.emphasis { color: var(--state-expired); font-weight: 600; }

/* ── 主畫面的清單與一列 ── */
/* 清單容器自己要給列與列之間留空：`.screen-body` 的 gap 只作用在它的直接子元素（#home-list 是一個），
   列是 #home-list 的子元素，沒有這條會一列貼著一列（2026-09-11 使用者人工驗收時指出）。 */
#home-list { display: flex; flex-direction: column; gap: 8px; }

.row {
  display: flex;
  align-items: stretch;
  gap: var(--gap);
  background: var(--surface);
  border-radius: var(--radius);
  overflow: hidden;
}

/* 狀態同時用「顏色」與「位置（最左緣、固定寬度）」雙重編碼，
   使用者不必讀文字內容，掃視色帶就能看出哪一列該注意（規格第九節）。 */
.row-band { flex: 0 0 6px; background: var(--state-disabled); }
.state-running   { background: var(--state-running); }
.state-warning   { background: var(--state-warning); }
.state-expired   { background: var(--state-expired); }
.state-exhausted { background: var(--state-exhausted); }
.state-disabled  { background: var(--state-disabled); }
/* **少了這一條，「待機中」會落回 .row-band 的預設值＝停用色**，而所有類別名的斷言照樣綠
   ——這正是工作項 11 補它的理由（P5-26d／P5-50）。 */
.state-idle      { background: var(--state-idle); }

.row-main { flex: 1 1 auto; min-width: 0; padding: 10px 0; display: flex; flex-direction: column; gap: 4px; }
.row-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 秒數從 9 跳到 10 時不可以讓畫面左右抖動（規格第九節「視覺設計決定」）。
   規格講的是**兩件事**：等寬字型「並」套用 tabular-nums。tabular-nums 只保證數字等寬，
   冒號、間隔與單位字仍會隨字型而浮動，所以字型本身也要指定；中文單位（「小時」「分」）
   會自然 fallback 到系統中文字型，不受這串影響。 */
.row-remaining {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  font-size: 1.125rem;
}

.row-progress { height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; }
.row-progress > i { display: block; height: 100%; background: var(--state-running); }
.row-weekly { font-size: 0.875rem; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.row-action { flex: 0 0 auto; display: flex; align-items: center; padding-right: 10px; }
/* 被推播深連結點進來的那一列（規格第九節第 4 點、決定 57）：外框畫在列的內側（負的 offset），
   不會把 .row 撐大、也不會被 overflow: hidden 裁掉。顏色沿用「進行中」的藍——它是「注意這一列」，
   不是一種新的嚴重度，不另立權杖。 */
.row-highlight { outline: 2px solid var(--state-running); outline-offset: -2px; }

/* ── 主畫面的空狀態 ── */
#home-empty { display: flex; flex-direction: column; gap: var(--gap); padding: 24px 0; text-align: center; }

/* ── 表單 ── */
.field { display: flex; flex-direction: column; gap: 4px; }
.field-label { font-size: 0.875rem; color: var(--text-muted); }
.field-hint { font-size: 0.75rem; color: var(--text-muted); }
.field input, .field select, .field textarea {
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--text);
  font: inherit;
  padding: 10px;
  width: 100%;
}

.stepper { display: flex; align-items: center; gap: 8px; }
.stepper input { text-align: center; font-variant-numeric: tabular-nums; }
.stepper button { min-width: 48px; min-height: 48px; }
/* 長按連續調整（決定 52）：按住時不可以跳出文字選取或系統選單，也不要 300 ms 的點擊延遲。 */
.stepper button { touch-action: manipulation; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }

/* ── 按鈕 ── */
.btn {
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  color: var(--text);
  font: inherit;
  min-height: 44px;
  padding: 10px 16px;
}
.btn-primary { background: var(--state-running); border-color: transparent; color: #fff; width: 100%; }
/* 破壞性動作：看得見、知道它存在，但不填滿背景、不搶注意力（規格第九節）。 */
.btn-danger { background: transparent; border-color: var(--danger); color: var(--danger); }
.btn-quiet { background: transparent; border-color: transparent; color: var(--text-muted); }

/* ── 提示列與狀態列 ── */
.banner {
  background: var(--state-running);
  color: #fff;
  padding: 10px var(--gap);
  text-align: center;
  cursor: pointer;
}
.banner[hidden] { display: none; }

.status-bar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  background: var(--surface);
  border-top: 1px solid var(--line);
  color: var(--text-muted);
  font-size: 0.8125rem;
  padding: 8px var(--gap);
  padding-bottom: calc(8px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* ── 底部彈出面板（項目編輯，第九個畫面） ── */
#sheet-host:empty { display: none; }
.sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  max-height: 88vh;
  overflow-y: auto;
  background: var(--surface);
  border-radius: var(--radius) var(--radius) 0 0;
  border-top: 1px solid var(--line);
  padding: var(--gap);
  padding-bottom: calc(var(--gap) + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: var(--gap);
  transform: translateY(100%);
  transition: transform 160ms ease-out;
}
.sheet-open { transform: translateY(0); }
/* 背景：蓋住整個主畫面，點它關閉面板（三個關閉入口之一，另兩個是關閉鈕與 Esc）。 */
.sheet-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); z-index: 10; }
/* 標題與關閉鈕同一列（P5-38）：關閉鈕跟著面板頂端走，永遠在單手可及的範圍內。 */
.sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.sheet-head h2 { margin: 0; font-size: 1.125rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sheet-close { flex: 0 0 auto; font-size: 1.25rem; line-height: 1; padding: 8px 12px; min-width: 44px; }
/* 解析預覽與超長警告緊貼在到期時間欄位下面，不要跟一般段落一樣留大段上下留白。 */
.sheet-preview { margin: 0; }
/* 勾選框那兩列：水平排、對齊；`.field` 是垂直排的，用在這裡會把框與字上下疊起來。 */
.field-check { display: flex; flex-direction: row; align-items: center; gap: 8px; min-height: 44px; }
.field-check input { width: auto; margin: 0; }
/* 刪除獨立成一列、與儲存按鈕拉開距離（規格第九節）。 */
.sheet-danger-row { margin-top: 24px; display: flex; justify-content: center; }
.sheet-danger-row:empty { display: none; }
/* 確認方塊由 js/ui/confirm.js 產生，工作項 16 共用同一份樣式——**不要在別處再定義一次**。 */
.sheet-confirm {
  position: absolute; inset: auto 0 0 0;
  background: var(--surface-raised); border-top: 1px solid var(--line);
  padding: var(--gap); display: flex; flex-direction: column; gap: 8px;
}
.sheet-confirm p { margin: 0; }

details > summary { cursor: pointer; padding: 8px 0; color: var(--text-muted); }

/* ── 設定畫面（工作項 15） ── */
/* 每一區：小標題＋內容，區與區之間由 .screen-body 的 gap 分隔；#settings-push 是計畫 6 的掛載點（定案五）。 */
.settings-section { display: flex; flex-direction: column; gap: 8px; }
.settings-section h2 { margin: 4px 0 0; font-size: 0.875rem; font-weight: 600; color: var(--text-muted); }
.settings-section p { margin: 0; }
/* 一列連結（已登入的裝置、配對桌面程式、通知授權引導）：整列可點、至少 48px 高（拇指目標），右緣「›」。 */
.settings-link {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  min-height: 48px; padding: 10px 12px;
  background: var(--surface); border-radius: var(--radius);
  color: var(--text); text-decoration: none;
}

@media (prefers-reduced-motion: reduce) {
  .sheet { transition: none; }
}

/* ── 已登入的裝置（工作項 16） ── */
/* 共用的確認方塊（js/ui/confirm.js）是 position: absolute，要疊在這個畫面底部就得有定位脈絡。 */
.devices-body { position: relative; }
.devices-body > p, .devices-section p { margin: 0; }
.devices-section { display: flex; flex-direction: column; gap: 8px; }
.devices-section h2, .devices-revoked > summary { margin: 4px 0 0; font-size: 0.875rem; font-weight: 600; color: var(--text-muted); }
.device-row {
  background: var(--surface); border-radius: var(--radius);
  padding: var(--gap); margin-bottom: 8px;
  display: flex; flex-direction: column; gap: 4px;
}
.device-name { font-weight: 600; }
.device-expiry.warn { font-weight: 600; }
.device-actions { display: flex; gap: 8px; margin-top: 4px; }
/* 已撤銷分區灰階呈現、預設收合（規格第九節）。 */
.devices-revoked { filter: grayscale(1); opacity: 0.75; }
.devices-revoked > summary { padding: 8px 0; }
#devices-message:empty { display: none; }
#devices-message { display: flex; align-items: center; gap: 8px; }

/* ── 配對桌面程式（工作項 17） ── */
.pair-advice { margin: 0; font-weight: 600; }
/* 網址與複合字串都是要被抄或被複製的東西：可換行、可選取，不要被截掉。 */
.pair-url, .pair-composite { display: block; word-break: break-all; user-select: all; -webkit-user-select: all; }
/* 配對碼：大字、等寬數字，讓人隔著桌子也讀得到。 */
.pair-code { font-size: 2rem; font-variant-numeric: tabular-nums; letter-spacing: 0.1em; text-align: center; margin: 0; }
.pair-code.expired { opacity: 0.5; text-decoration: line-through; }
.pair-result { display: flex; flex-direction: column; gap: 8px; background: var(--surface); border-radius: var(--radius); padding: var(--gap); }
.pair-result p { margin: 0; }
.pair-steps { margin: 0; padding-left: 1.25em; display: flex; flex-direction: column; gap: 6px; }
#pair-message:empty { display: none; }
#pair-message { margin: 0; }
