/* SSI Sync — 海圖紙暖底 · 深海墨藍字 · 青綠行動色
   顏色分工：青綠=可操作 / 苔綠=已驗證 / 琥珀=需處理 / 磚紅=破壞性 / 藍=Garmin 來源標籤 */
:root{
  --bg:#efece4; --surf:#fbfaf6; --surf2:#f4f1e9; --surf3:#e8e3d8;
  --ink:#122430; --ink2:#4a5c66;
  /* --ink3 是最淡的那一階（提示、次要說明、狀態標籤）。原本 #7d8b92 對
     背景只有 2.97:1,遠低於 WCAG AA 的 4.5:1 —— 這是全站最普遍的可讀性問題,
     axe 在設定頁一次就抓到 15 處。現在的值對 bg/surf/surf2/surf3 四個底色
     都 >= 4.5,質感沒變,只是真的看得見了。 */
  --ink3:#5a676c;
  --line:#ddd6c9; --line2:#cbc2b2;
  --gar:#1c5c99; --gar-s:#e3ecf6;
  --ssi:#0b7a82; --ssi-b:#0d949e; --ssi-s:#dcefef;
  /* 青綠「字」壓在青綠底（--ssi-s）上時要更深：--ssi 本身只有 4.28:1。
     在一般底色上用 --ssi 是夠的,所以只有這個組合需要另一個值。 */
  --ssi-ink:#096167;
  /* 服務名稱（Garmin / SSI 這兩個標題）的文字色。兩邊共用同一個值 ——
     分成兩個顏色時,即使把對比配平了,藍與青綠並排還是看得出不一致。
     刻意和 --gar/--ssi 分開:那兩個還要當按鈕底色與焦點環,不能為了標題就動它們。
     也刻意不用青綠 —— 這個配色裡青綠代表「可操作」,標題用它會像可以點。 */
  --brand-t:#1c5c99;
  --btn-fg:#ffffff;
  --ok:#4c7a2e; --ok-s:#e7efd9;
  --warn:#a5701a; --warn-s:#f8ead1;
  /* 淡底上的文字專用：--ok / --warn 本身對 -s 底只有 4.3 與 3.58，達不到 AA 的 4.5。
     它們同時也是邊框與圓點的顏色，直接調深會動到那些地方，所以另外開一組。 */
  --ok-ink:#3a5f25;    /* 對 --ok-s 為 6.24，對備份晶片的底 6.24→5.20 */
  --warn-ink:#734e0f;  /* 對 --warn-s 為 6.26，對 .cb-jump 的 hover 底仍有 4.91 */
  --crit:#a84234; --crit-s:#f8e4e0;
  --tag-fg:#fff;   /* 潛水類型徽章的字。淺色主題的 --crit/--gar 是深色，白字 6:1 以上 */
  --sh:0 1px 2px rgba(18,36,48,.06),0 10px 26px -14px rgba(18,36,48,.2);
  --sh-lg:0 2px 6px rgba(18,36,48,.07),0 24px 48px -20px rgba(18,36,48,.28);
  --r:14px; --rs:10px;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
  --bg:#08151b; --surf:#102229; --surf2:#152b33; --surf3:#1c3740;
  --ink:#ece6da; --ink2:#a6b3b6; --ink3:#909da2;   /* 同上：原值在卡片上只有 4.27 */
  --line:#22383f; --line2:#2f4750;
  --gar:#6aa9e2; --gar-s:#10273c; --ssi:#2ab5bd; --ssi-b:#4fd3da; --ssi-s:#0a3035;
  --ssi-ink:#2ab5bd;   /* 深色主題下 --ssi 對 --ssi-s 已經有 5.68:1 */
  --brand-t:#6aa9e2;
  --btn-fg:#04222a;
  --ok:#93c364; --ok-s:#1a2814; --warn:#dfa951; --warn-s:#2c2413;
  --ok-ink:#93c364; --warn-ink:#dfa951;   /* 深色下已是 7.54 / 7.26，不必另調 */
  --crit:#e08476; --crit-s:#2f1a16;
  /* 深色主題把 --crit/--gar 提亮成「給深底用的前景色」，拿來當徽章底
     時白字只有 2.5:1。字改成深色，對 #e08476 是 6.5、對 #6aa9e2 是 7.1。 */
  --tag-fg:#14191a;
  --sh:0 1px 2px rgba(0,0,0,.4),0 12px 30px -16px rgba(0,0,0,.75);
  --sh-lg:0 2px 8px rgba(0,0,0,.45),0 28px 56px -24px rgba(0,0,0,.85);
}}
:root[data-theme="dark"]{
  --bg:#08151b; --surf:#102229; --surf2:#152b33; --surf3:#1c3740;
  --ink:#ece6da; --ink2:#a6b3b6; --ink3:#909da2;   /* 同上：原值在卡片上只有 4.27 */
  --line:#22383f; --line2:#2f4750;
  --gar:#6aa9e2; --gar-s:#10273c; --ssi:#2ab5bd; --ssi-b:#4fd3da; --ssi-s:#0a3035;
  --ssi-ink:#2ab5bd;   /* 深色主題下 --ssi 對 --ssi-s 已經有 5.68:1 */
  --brand-t:#6aa9e2;
  --btn-fg:#04222a;
  --ok:#93c364; --ok-s:#1a2814; --warn:#dfa951; --warn-s:#2c2413;
  --ok-ink:#93c364; --warn-ink:#dfa951;   /* 深色下已是 7.54 / 7.26，不必另調 */
  --crit:#e08476; --crit-s:#2f1a16;
  /* 深色主題把 --crit/--gar 提亮成「給深底用的前景色」，拿來當徽章底
     時白字只有 2.5:1。字改成深色，對 #e08476 是 6.5、對 #6aa9e2 是 7.1。 */
  --tag-fg:#14191a;
  --sh:0 1px 2px rgba(0,0,0,.4),0 12px 30px -16px rgba(0,0,0,.75);
  --sh-lg:0 2px 8px rgba(0,0,0,.45),0 28px 56px -24px rgba(0,0,0,.85);
}


/* ── IBM Plex Mono（自架）────────────────────────────────────
 *
 * 為什麼不用 Google Fonts 的 CSS：那張表是非同步載入的（media="print"
 * 再切回 all），所以 @font-face 是在首次繪製**之後**才出現 —— 字型一到位，
 * 每一處 .mono 的寬度就變一次，整頁重排。桌機的 CLS 0.124 幾乎全部來自
 * 這一下（PSI 把 0.118 記在 footer 上，原因寫著「Web font loaded」）。
 *
 * 自架之後 @font-face 和這個檔案一起到（styles.css 本來就是 render-blocking），
 * 搭配 font-display:optional：字型在首次繪製前就緒才會被採用，否則這一次
 * 就用系統等寬字，**不換、不跳**。順帶少掉兩個第三方網域與兩次 preconnect。
 *
 * 只收 latin 子集：介面的中文由系統字型負責，這個字型只用在數字、代碼、
 * 潛水編號那些地方。三個字重共約 45 KB，但瀏覽器只會抓真的用到的那幾個。
 *
 * 授權：IBM Plex 是 OFL-1.1，授權條款放在 fonts/OFL.txt。
 */
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:400;
  font-display:optional;
  src:url("/static/fonts/ibm-plex-mono-400-latin.woff2?v=08949f72") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,
    U+FEFF,U+FFFD;}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:600;
  font-display:optional;
  src:url("/static/fonts/ibm-plex-mono-600-latin.woff2?v=0d1f0b8d") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,
    U+FEFF,U+FFFD;}
@font-face{font-family:"IBM Plex Mono";font-style:normal;font-weight:700;
  font-display:optional;
  src:url("/static/fonts/ibm-plex-mono-700-latin.woff2?v=4f84d86c") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,
    U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,
    U+FEFF,U+FFFD;}

*{box-sizing:border-box}
/* hidden 屬性一定要贏。
 *
 * 瀏覽器預設樣式裡的 [hidden]{display:none} 優先度**最低**，所以只要那個元素
 * 的 class 自己設了 display（.callout 是 flex、.dlg-form 是 block），
 * `el.hidden = true` 就完全沒有作用 —— 程式以為收起來了，畫面上一直看得見。
 *
 * 這個站上真的發生過兩次（登入頁的分享提示、挑欄位的搜尋框），所以在這裡
 * 一次擋掉，而不是每次都補一條 .xxx[hidden]。 */
[hidden]{display:none!important}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
/* 中文不載網路字型，用裝置本來就有的那套。
 *
 * 之前第一順位是 Noto Sans TC（Google Fonts）。實測：光首頁就要 872 KB
 * —— 12 個中文切片 772 KB 加上 100 KB 的 CSS，是我們自己所有檔案（91 KB）
 * 的十倍。潛水員多半是上岸後用手機行動網路開這個站，那個代價不值得。
 *
 * 而且各家系統本來就有好的繁中字型：Android 是 Noto Sans CJK TC（跟
 * Noto Sans TC 同一套字，長得一模一樣）、Apple 是蘋方、Windows 是微軟
 * 正黑。順序照裝置排，最後才交給 system-ui。
 *
 * 英數與數字仍用 IBM Plex Mono（只有拉丁字母，整包約 30 KB）—— 日誌的
 * 編號、深度、時間都靠它對齊。 */
body{margin:0;background:var(--bg);color:var(--ink);
  font-family:"PingFang TC","Microsoft JhengHei","Noto Sans CJK TC",
    "Noto Sans TC",system-ui,sans-serif;
  line-height:1.65;font-size:15px;-webkit-font-smoothing:antialiased}
.mono,.num{font-family:"IBM Plex Mono",ui-monospace,monospace;font-variant-numeric:tabular-nums}
button{font-family:inherit;cursor:pointer}
/* 16px 是 iOS Safari 的門檻：小於它，一聚焦就會自動放大整頁 */
input,select,textarea{font-family:inherit;font-size:16px}
a{color:var(--ssi-b);text-decoration:none}
a:hover{text-decoration:underline}
:focus-visible{outline:2px solid var(--ssi-b);outline-offset:2px;border-radius:6px}
/* ── 獨立頁面（隱私權說明、404）──────────────────────────
   這兩頁不在 SPA 裡,是各自有網址的靜態頁 —— 搜尋引擎才索引得到,
   也才連結得出去。共用同一份 styles.css,外觀不會分岔。 */
.doc{max-width:720px;margin:0 auto;color:var(--ink2);font-size:14.5px;line-height:1.9}
.doc h1{margin-bottom:4px}
/* 語言切換：中／英兩個網址互指。不是導覽的一部分,所以低調一點 */
.doc-lang{font-weight:700}
.doc h2{font-size:1.1rem;font-weight:800;color:var(--ink);margin:34px 0 8px}
.doc p{margin:0 0 10px}
.doc b{color:var(--ink);font-weight:700}
.doc-lede{background:var(--surf);border:1px solid var(--line);border-radius:var(--r);
  padding:16px 18px;margin:0 0 8px!important}
.doc-note{background:var(--warn-s);border:1px solid color-mix(in srgb,var(--warn) 38%,transparent);
  border-radius:var(--rs);padding:12px 15px;font-size:13.5px;margin-top:12px!important}
.doc-list,.doc-steps{margin:8px 0 10px;padding-left:1.35em}
.doc-list li,.doc-steps li{margin-bottom:8px}
.doc-steps li::marker{font-family:"IBM Plex Mono",monospace;font-weight:700;color:var(--ssi)}
.doc-table{width:100%;border-collapse:collapse;margin:10px 0 4px;font-size:13.5px}
.doc-table th,.doc-table td{text-align:left;padding:9px 11px;border-bottom:1px solid var(--line);
  vertical-align:top}
.doc-table th{color:var(--ink);font-weight:700;border-bottom:1px solid var(--line2)}
.doc-contact{margin-top:34px;padding-top:18px;border-top:1px solid var(--line)}
/* 段落裡的行內連結一定要有底線：只靠顏色區分,色覺障礙的人看不出那是連結
   （WCAG 的 link-in-text-block）。--ssi-ink 是深一階的青綠,對比才夠。 */
/* 教學頁的截圖。寫死 width/height（HTML 屬性）讓瀏覽器先留好位置,
   圖載入時版面才不會被推來推去（CLS）。 */
.doc-fig{margin:16px 0 18px}
.doc-fig img{width:100%;height:auto;display:block;border:1px solid var(--line);
  border-radius:var(--rs);background:var(--surf)}
.doc-fig figcaption{margin-top:8px;font-size:12.5px;color:var(--ink3)}

.doc a{color:var(--ssi-ink);text-decoration:underline;text-underline-offset:3px;
  text-decoration-thickness:1px}
.doc a:hover{text-decoration-thickness:2px}
/* 表格在窄螢幕不硬擠,讓它自己捲 */
@media(max-width:640px){
  .doc-table{display:block;overflow-x:auto;white-space:nowrap}
  .doc-table td,.doc-table th{white-space:normal;min-width:7.5em}
}
.notfound-code{font-family:"IBM Plex Mono",monospace;font-weight:700;font-size:64px;
  color:var(--ink3);letter-spacing:.06em;line-height:1;margin-bottom:10px}

/* 跳到主要內容。平常看不到,鍵盤 Tab 到它才出現 —— 只用 display:none 的話
   螢幕閱讀器也讀不到,所以是移出畫面而不是隱藏。 */
.skiplink{position:absolute;left:8px;top:-60px;z-index:1000;
  background:var(--surf);color:var(--ink);border:1px solid var(--ssi);
  padding:10px 16px;border-radius:9px;font-weight:700;font-size:13.5px;
  text-decoration:none;box-shadow:var(--sh);transition:top .15s}
.skiplink:focus{top:8px;outline:2px solid var(--ssi);outline-offset:2px}
/* <main> 加了 tabindex="-1" 才接得住跳過連結的焦點,但它是整塊內容 ——
   聚焦時畫一圈外框很怪,所以只收掉外框,不收掉聚焦本身。 */
main:focus{outline:none}

/* 設定頁的卡片標題是 h2（層級要接在頁面 h1 之後,不能跳到 h3），
   但視覺上維持原本 h3 的大小 —— 標題層級是給螢幕閱讀器的結構,不是字級。 */
h2.cardtitle{font-size:1.02rem;font-weight:700;margin:0 0 4px;letter-spacing:0}

.hidden{display:none!important}
/* 登入頁在 app.js 接手之前就先畫出來。
     沒有 JS          搜尋引擎與 AI 爬蟲多半不執行 JS，靠這條才看得到內容
     有 JS、還沒登入過 第一次繪製就有東西，不必等 app.js（少掉幾秒空白與
                      一次把頁尾推下去的位移）
     有 JS、上次登入過 .wasin 成立，維持隱藏 —— 他要看的是總覽，先閃一次
                      登入頁更糟
   .routed 由 show() 在第一次切分頁時掛上，從那之後分頁完全由 show() 控制。 */
html:not(.js) #pageAuth.hidden,
html.js:not(.wasin):not(.routed) #pageAuth.hidden{display:block!important}
.wrap{max-width:940px;margin:0 auto;padding:0 20px}

/* ── 頂列 ── */
.bar{position:sticky;top:0;z-index:40;background:color-mix(in srgb,var(--bg) 88%,transparent);
  backdrop-filter:blur(10px);border-bottom:1px solid var(--line)}
.bar .in{display:flex;align-items:center;gap:12px;height:58px}
.logo{display:flex;align-items:center;gap:9px;font-weight:900;font-size:15.5px}
.logo i{width:11px;height:11px;border-radius:50%;font-style:normal;
  background:linear-gradient(135deg,var(--gar),var(--ssi-b));box-shadow:0 0 0 3px var(--ssi-s)}
.barnav{margin-left:auto;display:flex;align-items:center;gap:8px}
.navlink{font-size:13px;color:var(--ink2);padding:6px 10px;border-radius:7px;background:none;border:none}
.navlink:hover{background:var(--surf2);color:var(--ink)}
.navlink.on{background:var(--ssi-s);color:var(--ssi-ink);font-weight:700}
.who{font-size:12.5px;color:var(--ink3);font-family:"IBM Plex Mono",monospace}
.tgl{border:1px solid var(--line2);background:var(--surf);color:var(--ink2);
  min-width:32px;height:32px;padding:0 8px;border-radius:8px;font-size:14px;line-height:1}
/* 語言鈕放的是語言代碼（ZH／EN），字比 ◐ 寬；用 min-width 讓它自己長 */
#tgLang{font-size:12px;font-weight:700;letter-spacing:.04em}
.tgl:hover{color:var(--ink);border-color:var(--ssi)}

/* ── App 風格底部導覽（浮動膠囊 + 中間大圓 FAB） ── */
.tabbar{position:fixed;left:0;right:0;bottom:0;z-index:45;display:flex;justify-content:center;
  pointer-events:none;padding:0 14px calc(12px + env(safe-area-inset-bottom,0px))}
.tabinner{pointer-events:auto;display:flex;align-items:center;justify-content:space-between;
  width:100%;max-width:460px;height:60px;padding:0 8px;
  background:color-mix(in srgb,var(--surf) 90%,transparent);
  -webkit-backdrop-filter:saturate(1.5) blur(14px);backdrop-filter:saturate(1.5) blur(14px);
  border:1px solid var(--line);border-radius:22px;
  box-shadow:0 12px 34px -10px rgba(0,0,0,.32),0 3px 10px -3px rgba(0,0,0,.18)}
.tabitem{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  height:60px;min-width:0;background:none;border:none;cursor:pointer;
  color:var(--ink3);font-size:10.5px;font-weight:600;transition:color .15s}
.tabitem svg{width:23px;height:23px;transition:stroke-width .15s}
.tabitem span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tabitem:hover{color:var(--ink2)}
.tabitem.on{color:var(--ssi)}
.tabitem.on svg{stroke-width:2.2}
/* 中間大圓：凸起、品牌漸層、外圈用底色做出「穿過膠囊」的缺口感 */
.tabfab{flex:0 0 auto;position:relative;transform:translateY(-16px);
  width:58px;height:58px;border-radius:50%;border:none;cursor:pointer;
  display:flex;align-items:center;justify-content:center;color:#fff;
  background:linear-gradient(135deg,var(--gar),var(--ssi-b));
  box-shadow:0 10px 22px -5px color-mix(in srgb,var(--ssi) 60%,transparent),0 0 0 5px var(--bg);
  transition:transform .12s,box-shadow .15s}
.tabfab .fabicon{width:26px;height:26px;stroke-width:2}
.tabfab:hover{box-shadow:0 12px 26px -5px color-mix(in srgb,var(--ssi) 70%,transparent),0 0 0 5px var(--bg)}
.tabfab:active{transform:translateY(-16px) scale(.93)}
.tabfab.on{box-shadow:0 0 0 3px var(--ssi-s),0 10px 22px -5px color-mix(in srgb,var(--ssi) 60%,transparent),0 0 0 5px var(--bg)}
/* 電腦版維持頂列連結導覽，不顯示底部 tab bar */
/* 平板以下(含手機)用底部 tab bar;桌機(>1024)才隱藏它、改用頂列連結 */
@media(min-width:1025px){.tabbar{display:none}}

/* ── 通用 ── */
/* .ptitle 是各分頁的標題。看起來、讀起來都是 h1，但在文件大綱裡不是 ——
   原因見 app.js 的 PTITLE。 */
h1,.ptitle{font-size:clamp(1.7rem,4vw,2.3rem);font-weight:900;letter-spacing:-.02em;
  margin:0 0 6px;text-wrap:balance}
h2{font-size:1.28rem;font-weight:800;margin:0 0 4px;letter-spacing:-.01em}
h3{font-size:1.02rem;font-weight:700;margin:0 0 4px}
.sub{color:var(--ink2);margin:0 0 22px;max-width:60ch}
.page{padding:26px 0 80px}
.card{background:var(--surf);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--sh)}
.pad{padding:22px}
.stack{display:flex;flex-direction:column;gap:16px}
.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.spacer{flex:1}

.btn{border:none;border-radius:10px;padding:12px 20px;font-weight:700;font-size:14.5px;
  background:var(--ssi);color:var(--btn-fg);transition:.15s;
  box-shadow:0 2px 10px -3px color-mix(in srgb,var(--ssi) 60%,transparent)}
.btn:hover:not(:disabled){background:var(--ssi-b)}
.btn.ghost{background:transparent;color:var(--ink2);border:1px solid var(--line2);box-shadow:none}
.btn.ghost:hover:not(:disabled){background:var(--surf2);color:var(--ink)}
.btn.danger{background:transparent;color:var(--crit);box-shadow:none;
  border:1px solid color-mix(in srgb,var(--crit) 42%,var(--line2))}
.btn.danger:hover:not(:disabled){background:var(--crit-s);border-color:var(--crit)}
.btn.block{width:100%}
.btn.sm{padding:8px 14px;font-size:13px;border-radius:8px}
/* 獨立頁面用 <a> 當按鈕（那是導覽,不是動作）—— 補上 button 預設就有的幾項 */
a.btn{display:inline-block;text-decoration:none;text-align:center}
/* 停用：不靠 opacity 壓亮度 —— 深色底上 45% 的青綠仍然像一顆可以按的按鈕,
   淡掉多少完全取決於後面是什麼顏色。改成明確換成「無作用色」(灰面 + 淡字),
   兩個主題看起來一致。不動 border:兩個描邊變體只換顏色,尺寸才不會跳。 */
.btn:disabled{cursor:not-allowed;box-shadow:none;background:var(--surf3);color:var(--ink3)}
.btn.ghost:disabled,.btn.danger:disabled{
  background:transparent;color:var(--ink3);border-color:var(--line)}

label.fld{display:block;margin-bottom:14px}
label.fld .lb{display:block;font-size:12.5px;font-weight:700;color:var(--ink2);margin-bottom:5px}
input[type=text],input[type=email],input[type=password]{
  width:100%;padding:11px 13px;border:1px solid var(--line2);border-radius:9px;
  background:var(--surf);color:var(--ink)}
input[type=number],select{
  padding:10px 12px;border:1px solid var(--line2);border-radius:9px;
  background:var(--surf);color:var(--ink)}
/* 語言清單會愈來愈長,給它一個下限寬度,選項才不會被擠成一小格 */
#langSelect{min-width:180px}
input:focus,select:focus{border-color:var(--ssi);outline:none;box-shadow:0 0 0 3px var(--ssi-s)}
.hint{font-size:12px;color:var(--ink3);margin-top:5px}
/* 欄位級的錯誤提示。:empty 才不會在沒有錯誤時撐出一行空白 */
.hint.err{color:var(--crit);font-weight:600}
.hint.err:empty{display:none}
input.bad,input.bad:focus{border-color:var(--crit);box-shadow:0 0 0 3px var(--crit-s)}
.checkline{display:flex;gap:9px;align-items:flex-start;font-size:13px;color:var(--ink2)}
.checkline input{margin-top:3px;accent-color:var(--ssi)}

.msg{padding:11px 14px;border-radius:9px;font-size:13.2px;margin-bottom:14px;border:1px solid}
.msg.err{background:var(--crit-s);border-color:color-mix(in srgb,var(--crit) 40%,transparent);color:var(--ink)}
.msg.ok{background:var(--ok-s);border-color:color-mix(in srgb,var(--ok) 38%,transparent);color:var(--ink)}

.callout{border-radius:var(--rs);padding:14px 16px;border:1px solid;display:flex;gap:12px;align-items:flex-start}
.callout .ic{font-family:"IBM Plex Mono",monospace;font-weight:700;flex:0 0 auto;font-size:12px;padding-top:2px}
.callout.w{background:var(--warn-s);border-color:color-mix(in srgb,var(--warn) 40%,transparent)}
.callout.w .ic{color:var(--warn)}
.callout.o{background:var(--ok-s);border-color:color-mix(in srgb,var(--ok) 38%,transparent)}
.callout.o .ic{color:var(--ok)}
.callout.c{background:var(--crit-s);border-color:color-mix(in srgb,var(--crit) 42%,transparent)}
.callout.c .ic{color:var(--crit)}
.callout h4{margin:0 0 3px;font-size:13.8px}
.callout p{margin:0;font-size:12.8px;color:var(--ink2)}

/* ── 登入頁 ── */
/* 表單欄位窄一點好讀,標題區寬一點才不會把中文詞從中間折斷 —— 兩個不同的寬度 */
.authwrap{max-width:430px;margin:0 auto}
.authhead{max-width:600px;margin:56px auto 24px;text-align:center}
.authhead .flow{display:flex;align-items:center;justify-content:center;gap:12px;margin-top:18px}
.srcbox{border:1px solid var(--line2);border-radius:11px;padding:11px 18px;background:var(--surf2)}
.srcbox .nm{font-weight:800;font-size:14px;color:var(--brand-t)}
.srcbox .sm{font-size:11px;color:var(--ink3);font-family:"IBM Plex Mono",monospace}
/* ── 登入卡片下方的說明 ────────────────────────────────────
   第一次來的人需要它,回訪的人不該被它擋住 —— 所以放在表單下方。
   這也是搜尋引擎與 AI 爬蟲唯一讀得到的內容,不能只存在於 JS 裡。 */
.lander{margin-top:40px;padding-top:32px;border-top:1px solid var(--line);
  color:var(--ink2);font-size:14px;line-height:1.85}
.lander h2{font-size:15.5px;font-weight:800;color:var(--ink);margin:30px 0 8px;line-height:1.5}
.lander h2:first-child{margin-top:0}
.lander p{margin:0}
.lander b{color:var(--ink);font-weight:700}
.lander-steps{margin:10px 0 0;padding-left:1.3em}
.lander-steps li{margin-bottom:9px;padding-left:2px}
.lander-steps li::marker{font-family:"IBM Plex Mono",monospace;font-weight:700;color:var(--ssi)}
/* 安全性那組用打勾而不是項目符號：這幾條是「我們保證做到的事」 */
.lander-list{margin:10px 0 0;padding-left:0;list-style:none}
.lander-list li{position:relative;padding-left:1.6em;margin-bottom:9px}
.lander-list li::before{content:"✓";position:absolute;left:0;top:0;
  color:var(--ok);font-weight:700}
.noscript{margin-top:16px}
.lander-more{margin-top:26px!important;padding-top:18px;border-top:1px solid var(--line)}
/* 這幾個連結在頁面底色（--bg）上，--ssi 只有 4.31 ——
   --ssi-ink 就是為了「文字放在淺底上」而存在的那一個（6.09） */
.lander-more a{color:var(--ssi-ink);font-weight:600;text-decoration:none}
.lander-more a:hover{text-decoration:underline}

/* ── 全站頁尾 ──────────────────────────────────────────────
 *
 * 教學、常見問題、隱私權原本只寫在未登入的招攬區塊裡（#pageAuth）,
 * 一登入整段就被藏起來 —— 已經在用的人反而找不到說明,也看不到聯絡方式。
 * 頁尾放在所有分頁之外,登入與否都在。
 *
 * 窄螢幕的底部 tab bar 是 position:fixed,會蓋住頁尾,所以這裡自己空出
 * 它的高度（.page 的那份 padding 只作用在分頁裡,管不到頁尾）。 */
.sitefoot{border-top:1px solid var(--line);margin-top:48px;padding:22px 0 26px;
  font-size:13px;color:var(--ink3)}
.sitefoot .wrap{display:flex;flex-wrap:wrap;align-items:center;gap:10px 20px}
.sitefoot nav{display:flex;flex-wrap:wrap;gap:10px 18px}
.sitefoot a{color:var(--ssi-ink);font-weight:600;text-decoration:none}
.sitefoot a:hover{text-decoration:underline}
.sitefoot .foot-contact{margin:0;margin-left:auto}
@media(max-width:1024px){
  .sitefoot{padding-bottom:calc(96px + env(safe-area-inset-bottom,0px))}
  /* 窄螢幕擠在同一行會斷得很難看,連結與聯絡方式各自成行 */
  .sitefoot .foot-contact{margin-left:0}
}

.tabs{display:flex;gap:4px;background:var(--surf2);padding:4px;border-radius:10px;margin-bottom:20px}
.tabs button{flex:1;border:none;background:none;padding:9px;border-radius:7px;font-size:13.5px;
  font-weight:700;color:var(--ink3)}
.tabs button.on{background:var(--surf);color:var(--ink);box-shadow:var(--sh)}

/* ── 連結狀態卡 ── */
.conngrid{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}
@media(max-width:720px){.conngrid{grid-template-columns:1fr}}
.conn{background:var(--surf);border:1px solid var(--line);border-radius:var(--r);
  padding:20px;box-shadow:var(--sh);display:flex;flex-direction:column;gap:4px}
/* 已連結。持續存在的部分很淡：右上角一層苔綠微光,讓卡片看起來是「亮著」的。 */
.conn.linked{
  border-color:color-mix(in srgb,var(--ok) 40%,var(--line));
  background:
    radial-gradient(130% 100% at 100% 0%,
      color-mix(in srgb,var(--ok) 10%,transparent), transparent 62%),
    var(--surf)}

/* 剛連上的一次性小獎勵：卡片泛一圈光、「已連結」輕輕浮上來。
   只播一次（class 由 renderConnections 依前後狀態決定）。
   下面那個狀態點的漣漪是另一回事 —— 它在已連結期間一直跑。
   偏好減少動態時,檔頭那條全域規則會把這裡的動畫整組關掉。 */
.conn.just-linked{animation:connLit .9s ease-out}
@keyframes connLit{
  0%,100%{box-shadow:var(--sh)}
  38%{box-shadow:var(--sh),0 0 0 4px color-mix(in srgb,var(--ok) 24%,transparent)}
}
/* 已連結期間,狀態點持續輕輕擴散 —— 像在呼吸,告訴你這條線是活的。
   後面 45% 的週期留白,所以是「一下、停一下」而不是連續閃,
   放在視野邊角才不會一直搶注意力。 */
.conn.linked .dot.on::after{
  content:"";position:absolute;inset:0;border-radius:50%;
  animation:dotPing 2.6s ease-out infinite}
@keyframes dotPing{
  0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--ok) 55%,transparent)}
  55%,100%{box-shadow:0 0 0 12px transparent}
}
.conn.just-linked .state.on{animation:stateRise .5s .1s backwards ease-out}
@keyframes stateRise{from{opacity:0;transform:translateY(-4px)}}
.conn .top{display:flex;align-items:center;gap:10px}
.conn .nm{font-weight:800;font-size:16px;color:var(--brand-t)}
.dot{width:9px;height:9px;border-radius:50%;background:var(--ink3);flex:0 0 auto;position:relative}
.dot.on{background:var(--ok);box-shadow:0 0 0 3px color-mix(in srgb,var(--ok) 22%,transparent)}
.dot.err{background:var(--crit);box-shadow:0 0 0 3px color-mix(in srgb,var(--crit) 22%,transparent)}
.conn .state{font-size:12.5px;font-family:"IBM Plex Mono",monospace;color:var(--ink3);margin-left:auto}
.conn .state.on{color:var(--ok)}
.conn .acct{font-size:13px;color:var(--ink2);word-break:break-all}
.conn .meta{font-size:11.5px;color:var(--ink3);font-family:"IBM Plex Mono",monospace}
.conn .acts{margin-top:auto;padding-top:14px;display:flex;gap:8px}

/* ── 步驟列 ── */
.rail{display:flex;align-items:center;padding:18px 0 22px;overflow-x:auto}
.rstep{display:flex;align-items:center;gap:9px;flex:0 0 auto;padding-right:14px}
.rstep .n{width:25px;height:25px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  font-family:"IBM Plex Mono",monospace;font-size:12px;font-weight:600;
  border:1.5px solid var(--line2);color:var(--ink3);background:var(--surf);flex:0 0 auto}
.rstep .t{font-size:12.5px;color:var(--ink3);font-weight:600;white-space:nowrap}
.rstep.done .n{background:var(--ok);border-color:var(--ok);color:var(--btn-fg)}
.rstep.done .t{color:var(--ink2)}
.rstep.now .n{background:var(--ssi);border-color:var(--ssi);color:var(--btn-fg);
  box-shadow:0 0 0 4px var(--ssi-s)}
.rstep.now .t{color:var(--ink);font-weight:700}
.rline{flex:1 1 20px;min-width:14px;height:1.5px;background:var(--line2);margin-right:14px}
.rline.fill{background:var(--ok)}

/* ── console ── */
.console{background:var(--surf2);border:1px solid var(--line);border-radius:var(--rs);
  padding:14px 16px;font-family:"IBM Plex Mono",monospace;font-size:12.5px;line-height:2;min-height:130px}
/* 進度訊息可能含長網址／端點，必須換行而不是撐破版面 */
.cl{display:flex;gap:9px;align-items:baseline;flex-wrap:wrap}
.cl .tx,.cl .ep{overflow-wrap:anywhere;min-width:0}
.cl .st{flex:0 0 auto;width:14px;color:var(--warn)}
.cl.ok .st{color:var(--ok)}
.cl .tx{color:var(--ink)}
.cl .ep{color:var(--ink3);font-size:11.5px}
@keyframes bl{50%{opacity:.25}}
.blink{animation:bl 1.1s infinite}

/* ── 統計 ── */
.statgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:18px 0}
@media(max-width:640px){.statgrid{grid-template-columns:repeat(2,1fr)}}
.stat{background:var(--surf);border:1px solid var(--line);border-radius:var(--rs);padding:14px}
.stat .v{font-family:"IBM Plex Mono",monospace;font-size:25px;font-weight:700;line-height:1;
  font-variant-numeric:tabular-nums}
.stat .k{font-size:11.5px;color:var(--ink3);margin-top:6px;font-weight:600}
.stat.hi{border-color:color-mix(in srgb,var(--ssi) 50%,var(--line));background:var(--ssi-s)}
.stat.hi .v{color:var(--ssi-ink)}
.stat.mut .v{color:var(--ink3)}

/* ── 潛水卡 ── */
.dlist{display:flex;flex-direction:column;gap:14px}
.dive{background:var(--surf);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--sh);overflow:hidden;transition:.15s}
.dive.off{opacity:.5}
.dive.need{border-color:color-mix(in srgb,var(--warn) 55%,var(--line))}
.dhead{display:flex;gap:14px;padding:16px 18px;align-items:flex-start}
.chk{appearance:none;width:20px;height:20px;border:1.5px solid var(--line2);border-radius:6px;
  background:var(--surf);flex:0 0 auto;margin-top:2px;position:relative;transition:.12s}
.chk:checked{background:var(--ssi);border-color:var(--ssi)}
.chk:checked::after{content:"✓";position:absolute;inset:0;display:flex;align-items:center;
  justify-content:center;color:var(--btn-fg);font-size:13px;font-weight:700}
.dmain{flex:1;min-width:0}
.dtop{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.dno{font-family:"IBM Plex Mono",monospace;font-size:12px;font-weight:700;color:var(--ssi-ink);
  background:var(--ssi-s);padding:2px 8px;border-radius:6px}
.dwhen{font-weight:700;font-size:15px;font-family:"IBM Plex Mono",monospace;font-variant-numeric:tabular-nums}
.dsite{color:var(--ink2);font-size:13.5px}
.dstats{display:flex;gap:18px;margin-top:9px;flex-wrap:wrap}
.ds{display:flex;align-items:baseline;gap:5px}
.ds .dv{font-family:"IBM Plex Mono",monospace;font-weight:700;font-size:15px;font-variant-numeric:tabular-nums}
.ds .dk{font-size:11px;color:var(--ink3)}
.badges{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px}
.bdg{font-family:"IBM Plex Mono",monospace;font-size:11px;font-weight:600;padding:3px 8px;
  border-radius:6px;white-space:nowrap}
.bdg.ok{background:var(--ok-s);color:var(--ok-ink)}
.bdg.w{background:var(--warn-s);color:var(--warn-ink)}
.bdg.n{background:var(--surf3);color:var(--ink3)}
.bdg.s{background:var(--ssi-s);color:var(--ssi-ink)}
.dtoggle{background:none;border:none;color:var(--ssi);font-size:12.5px;font-weight:600;
  padding:0;margin-top:11px;display:inline-flex;align-items:center;gap:5px}
.dtoggle:hover{text-decoration:underline}
.dbody{border-top:1px solid var(--line);background:var(--surf2);padding:16px 18px}
.fldwrap{overflow-x:auto}
table.flds{border-collapse:collapse;width:100%;font-size:13px;min-width:430px}
table.flds th{text-align:left;font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink3);padding:0 12px 7px 0;font-weight:600;white-space:nowrap}
table.flds td{padding:5px 12px 5px 0;border-top:1px solid var(--line);vertical-align:top}
table.flds td.f{font-family:"IBM Plex Mono",monospace;font-size:11.5px;color:var(--ink3);white-space:nowrap}
table.flds td.v{font-family:"IBM Plex Mono",monospace;font-weight:600;
  font-variant-numeric:tabular-nums;white-space:nowrap}
table.flds tr.empty td.v{color:var(--ink3);font-weight:400}
.src{font-size:10.5px;padding:1.5px 7px;border-radius:5px;font-family:"IBM Plex Mono",monospace;
  font-weight:600;white-space:nowrap}
.src.garmin{background:var(--gar-s);color:var(--gar)}
.src.calc{background:var(--surf3);color:var(--ink3)}
.src.none{background:var(--warn-s);color:var(--warn)}
.src.match,.src.lookup{background:var(--ssi-s);color:var(--ssi-ink)}

/* 已經有潛點時收成一行。一次同步十幾筆時，每張卡片都攤開一排按鈕
   會把真正需要你處理的那幾筆淹掉。 */
.picked{margin-top:12px;display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  background:var(--surf2);border:1px solid var(--line);border-radius:var(--rs);
  padding:9px 13px;font-size:13px}
.picked .pk-l{color:var(--ink3);font-size:12.5px}
.picked .pk-v{color:var(--ink);font-weight:700}
.picked .btn{margin-left:auto}
.pick .ph{display:flex;align-items:center;gap:10px}
.pick .pk-close{margin-left:auto;font-weight:400}

/* 選好之後要退成中性色 —— 選擇器現在一直都在,維持琥珀（=需處理）會讓
   已經處理好的那筆看起來還有問題。 */
.pick.done{background:var(--surf2);border-color:var(--line)}
.pick.done .ph{color:var(--ink2)}
.pick{margin-top:12px;background:var(--warn-s);border-radius:var(--rs);padding:13px 15px;
  border:1px solid color-mix(in srgb,var(--warn) 40%,transparent)}
.pick .ph{font-weight:700;font-size:13.5px;margin-bottom:3px}
.pick .pd{font-size:12.5px;color:var(--ink2)}
.opts{display:flex;gap:7px;flex-wrap:wrap;margin-top:10px}
.opt{border:1px solid var(--line2);background:var(--surf);border-radius:8px;padding:7px 12px;
  font-size:12.5px;color:var(--ink);transition:.12s}
.opt:hover{border-color:var(--ssi)}
.opt.sel{background:var(--ssi);border-color:var(--ssi);color:var(--btn-fg);font-weight:600}
/* 選項裡的「潛過 N 次」。本來寫成 inline 的 opacity:.6 —— opacity 會把文字和
   背景混起來，對比度變成算不出來的數字（實測 4.21，低於 AA 的 4.5）。
   改用量過的 --ink2（6.67）。選中時整顆變深色底，就跟著用按鈕的前景色。 */
.opt .sub{color:var(--ink2)}
.opt.sel .sub{color:var(--btn-fg);opacity:.85}

/* ── 備份保證卡 ── */
.bkcard{display:flex;gap:14px;align-items:flex-start;padding:16px 18px;background:var(--ok-s);
  border:1px solid color-mix(in srgb,var(--ok) 34%,transparent);border-radius:var(--r)}
.bkicon{width:32px;height:32px;border-radius:9px;background:var(--ok);color:var(--btn-fg);
  flex:0 0 auto;display:flex;align-items:center;justify-content:center;font-size:16px;font-weight:700}
.bkt{font-weight:800;font-size:14.5px}
.bkd{font-size:12.8px;color:var(--ink2);margin-top:3px;line-height:1.65}
.bkrow{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px}
.bkchip{font-family:"IBM Plex Mono",monospace;font-size:11px;font-weight:600;padding:3px 9px;
  border-radius:6px;background:color-mix(in srgb,var(--ok) 15%,transparent);color:var(--ok-ink)}

/* ── 確認列 ── */
.confirmbar{position:sticky;bottom:0;margin-top:18px;
  background:color-mix(in srgb,var(--surf) 94%,transparent);backdrop-filter:blur(10px);
  border:1px solid var(--line);border-radius:var(--r);padding:15px 18px;box-shadow:var(--sh-lg);
  display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.cbtext{flex:1;min-width:180px}
.cbtext .big{font-weight:800;font-size:15px}
.cbtext .sm{font-size:12.5px;color:var(--ink2);margin-top:1px}
/* 擋住送出的條件（還沒選潛點／還沒給密碼）。灰字看起來像附註,
   使用者會只看到送出鈕是灰的卻不知道為什麼 —— 琥珀=需處理。 */
.cb-jump{
  display:inline-flex;align-items:center;gap:7px;margin-top:5px;
  padding:4px 10px;border-radius:8px;font-size:12.5px;font-weight:700;
  color:var(--warn-ink);background:var(--warn-s);font-family:inherit;
  border:1px solid color-mix(in srgb,var(--warn) 42%,transparent)}
.cb-jump::before{
  content:"!";font-family:"IBM Plex Mono",ui-monospace,monospace;font-weight:700}
.cb-jump:hover{background:color-mix(in srgb,var(--warn) 22%,var(--warn-s))}
.cb-jump:focus-visible{outline:2px solid var(--warn);outline-offset:2px}

/* 跳過去之後閃一下 —— 畫面上有好幾張卡片,只捲過去看不出是哪一張 */
.dive.flash,#pwGate.flash{animation:jumpFlash 1.1s ease-out}
@keyframes jumpFlash{
  0%,100%{box-shadow:0 0 0 0 transparent}
  22%{box-shadow:0 0 0 4px color-mix(in srgb,var(--warn) 45%,transparent)}
}

/* ── 進度 ── */
.syncrow{display:flex;align-items:center;gap:13px;padding:13px 0;border-bottom:1px solid var(--line)}
.syncrow:last-child{border-bottom:none}
.sicon{width:26px;height:26px;border-radius:50%;flex:0 0 auto;display:flex;align-items:center;
  justify-content:center;font-size:13px;font-weight:700;background:var(--surf3);color:var(--ink3);
  font-family:"IBM Plex Mono",monospace}
.syncrow.run .sicon{background:var(--warn-s);color:var(--warn)}
.syncrow.done .sicon{background:var(--ok);color:var(--btn-fg)}
.syncrow.failed .sicon{background:var(--crit);color:var(--btn-fg)}
.sinfo{flex:1;min-width:0}
.sname{font-weight:700;font-size:14px;font-family:"IBM Plex Mono",monospace}
.sstep{font-size:12px;color:var(--ink2);margin-top:1px}
.bkstep{border-bottom:1px solid var(--line);padding-bottom:13px;margin-bottom:4px}
.bkstep .sicon{background:var(--ok-s);color:var(--ok)}
.bkstep.done .sicon{background:var(--ok);color:var(--btn-fg)}

/* ── 結果 ── */
.rmark{width:54px;height:54px;border-radius:50%;background:var(--ok);color:var(--btn-fg);
  display:flex;align-items:center;justify-content:center;font-size:27px;margin:0 auto 14px;
  box-shadow:0 0 0 8px var(--ok-s)}
.rmark.bad{background:var(--crit);box-shadow:0 0 0 8px var(--crit-s)}
.ritem{display:flex;align-items:center;gap:12px;background:var(--surf);border:1px solid var(--line);
  border-radius:var(--rs);padding:12px 15px}
.ritem .rno{font-family:"IBM Plex Mono",monospace;font-size:12px;font-weight:700;color:var(--ssi);
  background:var(--ssi-s);padding:2px 8px;border-radius:6px;flex:0 0 auto}
.ritem .rwhen{font-family:"IBM Plex Mono",monospace;font-weight:600;font-size:13.5px}
.ritem .rsite{color:var(--ink2);font-size:13px;flex:1;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.ritem .rver{font-size:11px;font-family:"IBM Plex Mono",monospace;font-weight:600;color:var(--ok);
  background:var(--ok-s);padding:3px 9px;border-radius:6px;flex:0 0 auto}
.rp{display:flex;align-items:center;gap:13px;padding:14px 16px;background:var(--surf);
  border:1px solid var(--line);border-left:3px solid var(--ok);border-radius:var(--rs)}
.rp .rpi{font-size:17px;color:var(--ok);flex:0 0 auto}
.rp .rpt{font-weight:700;font-size:13.6px}
.rp .rpd{font-size:12.4px;color:var(--ink2);margin-top:1px}
.rp .rpid{font-family:"IBM Plex Mono",monospace;font-size:11.5px;color:var(--ink3)}

/* ── 歷史 ── */
.hrow{display:flex;align-items:center;gap:12px;padding:13px 16px;background:var(--surf);
  border:1px solid var(--line);border-radius:var(--rs)}
.hrow .hs{font-family:"IBM Plex Mono",monospace;font-size:11px;font-weight:600;padding:3px 9px;
  border-radius:6px;flex:0 0 auto}
.hs.done{background:var(--ok-s);color:var(--ok)}
.hs.failed{background:var(--crit-s);color:var(--crit)}
.hs.other{background:var(--surf3);color:var(--ink3)}
.hrow .ht{font-family:"IBM Plex Mono",monospace;font-size:13px}
.hrow .hd{color:var(--ink2);font-size:13px;flex:1;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}

.empty-state{text-align:center;padding:44px 24px;color:var(--ink2)}
.empty-state .big{font-size:40px;margin-bottom:8px;opacity:.5}

/* ═══════════════════════════════════════════════════════════════
   響應式
   斷點：900 平板 / 640 大手機 / 430 小手機
   原則：內容永遠不橫向溢出；寬表格自己捲動；觸控目標夠大。
   ═══════════════════════════════════════════════════════════════ */

/* 長 email、潛點名不可撐破版面 */
.who,.conn .acct,.ritem .rsite,.hrow .hd,.dsite{overflow-wrap:anywhere}

@media (max-width:900px){
  .wrap{padding:0 16px}
  .page{padding:20px 0 72px}
  .pad{padding:18px}
}

@media (max-width:640px){
  body{font-size:14.5px}
  .wrap{padding:0 14px}
  .pad{padding:16px}
  .page{padding:16px 0 calc(96px + env(safe-area-inset-bottom,0px))}

  /* 頂列：手機上只放「導覽」。
     英文的 Overview / History / Settings / Sign out 比中文的 總覽/紀錄/設定/登出
     寬非常多，四個連結加兩顆切換鈕在 414px 就會溢出。
     主題與登出移到設定頁（它們本來就是設定，不是導覽）；
     語言鈕留著 —— i18n 的入口藏起來等於沒做。 */
  .bar .in{height:54px;gap:8px}
  .who{display:none}
  .barnav{gap:4px}
  .navlink{padding:9px 7px;font-size:13px}
  /* 頂列：登入之後的四個頁面連結已經搬到底部 tab bar（見檔尾的 .pagelink），
     所以這裡空間很夠，主題鈕留著 —— 公開內容頁與未登入的登入頁沒有設定頁
     可去，藏起來等於整個功能消失。
     登出仍然收在設定頁：它本來就是設定，不是導覽。 */
  #btnLogout{display:none}
  .tgl{min-width:38px;height:38px;padding:0 9px}
  .logo{flex:0 0 auto;white-space:nowrap}

  /* 步驟列：不捲動。只留「目前步驟」的文字，其餘剩編號圈 —— 五步剛好塞得下 */
  .rail{padding:14px 0 18px;overflow:visible}
  .rstep{padding-right:0;gap:0}
  .rstep:not(.now) .t{display:none}
  .rstep.now{gap:8px;padding-right:2px}
  .rstep.now .t{font-size:12.5px;white-space:nowrap}
  .rline{flex:1 1 auto;min-width:6px;margin:0 6px}

  /* 登入頁 */
  .authhead{margin-top:26px}
  .authhead .flow{gap:8px}
  .srcbox{padding:9px 14px}

  /* 潛水卡：統計改為兩欄網格，避免擠成一長條 */
  .dhead{padding:14px;gap:11px}
  .dstats{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px 14px}
  .dbody{padding:14px}
  .dtop{gap:7px}
  .dwhen{font-size:14.5px}

  /* 確認列：文字一行、按鈕平分一列 */
  .confirmbar{padding:13px 14px;gap:10px}
  .cbtext{flex:1 0 100%;min-width:0}
  .confirmbar .btn{flex:1}

  /* 歷史／結果列：允許換行，狀態標籤獨立一行 */
  .hrow,.ritem{flex-wrap:wrap;gap:8px 10px;padding:12px 14px}
  .hrow .hd,.ritem .rsite{flex:1 0 100%;white-space:normal;text-overflow:clip}
  .ritem .rver{margin-left:auto}

  /* 欄位表：手機上改成堆疊，不要左右捲 ——
     這是「確認要寫入什麼」的畫面，最重要的資訊不該藏在橫向捲軸後面。
        欄位名稱 ─────────── 將寫入的值
        odin_user_log_xxx ── 來源             */
  .fldwrap{overflow-x:visible}
  table.flds{min-width:0;display:block}
  table.flds thead{display:none}
  table.flds tbody{display:block}
  table.flds tr{display:grid;grid-template-columns:1fr auto;column-gap:10px;row-gap:1px;
    padding:9px 0;border-top:1px solid var(--line);align-items:baseline}
  table.flds tr:first-child{border-top:none;padding-top:0}
  table.flds td{display:block;padding:0;border:none;white-space:normal}
  /* td.f / td.v 在桌面版是 nowrap，而 `table.flds td.f` 的選擇器比上面那條
     `table.flds td` 更精確 —— 不明確覆寫的話，手機版會繼續 nowrap，
     像 odin_user_log_pressure_start_bar 這種長欄位名就撐破堆疊格線。 */
  table.flds td.f,table.flds td.v{white-space:normal;overflow-wrap:anywhere}
  table.flds td:nth-child(1){grid-area:1/1;font-weight:600}
  table.flds td:nth-child(3){grid-area:1/2;text-align:right}
  table.flds td:nth-child(2){grid-area:2/1;font-size:10.5px;overflow-wrap:anywhere}
  table.flds td:nth-child(4){grid-area:2/2;text-align:right}

  /* 進度列 */
  .syncrow{gap:11px}
  .bkcard{padding:14px;gap:11px}

  /* 備份／還原點 */
  .rp{padding:12px 14px;gap:11px}
}

@media (max-width:430px){
  /* 英文的標籤比中文長得多（「可自行填寫」5 字 vs "Fillable"）。
     在最窄的螢幕上，寧可讓標籤折成兩行，也不要被 .dive 的 overflow:hidden 切掉。 */
  .bdg,.bkchip{white-space:normal}
  .rstep .n{width:22px;height:22px;font-size:11px}
  .rstep.now .n{box-shadow:0 0 0 3px var(--ssi-s)}
  .rstep.now .t{font-size:12px}
  .rline{min-width:4px;margin:0 4px}
  /* 英文導覽（Overview / Logbook / History / Settings）在 375–412px 會把
     頂列推到 394px 寬 —— 剛好是 iPhone SE／12／13 這些最常見的寬度。
     .logo 是 flex:0 0 auto 不肯讓位，所以要從間距這邊省出來。 */
  .logo{font-size:14.5px}
  .navlink{padding:8px 3px;font-size:12.5px}
  .bar .in{gap:4px}
  .barnav{gap:2px}
  .statgrid{gap:9px}
  .stat{padding:12px}
  .stat .v{font-size:22px}
  .dstats{grid-template-columns:repeat(2,minmax(0,1fr))}
  .btn{padding:12px 16px}
  .authhead .flow{flex-direction:column;gap:6px}
  .authhead .flow>div[style]{transform:rotate(90deg)}
  .opts{gap:6px}
  .opt{padding:9px 11px}
}

/* 最窄的螢幕（≤360px）：每一個像素都該留給導覽，字樣收掉只留圓點標記。
   英文的 Overview / History / Settings 就佔掉一半寬度 —— 中文不會有這個問題，
   但樣式不分語言，所以以較寬的那個（英文）為準。 */
@media (max-width:360px){
  .logotext{display:none}
  .navlink{padding:8px 4px;font-size:12px}
}

/* 觸控裝置：把細小的文字按鈕撐到可點的高度 */
@media (hover:none) and (pointer:coarse){
  .navlink,.dtoggle,.opt{min-height:40px;display:inline-flex;align-items:center}
  .chk{width:24px;height:24px}
  .btn.sm{padding:10px 14px}
}

/* 很矮的視窗（手機橫放）：確認列不要黏住吃掉半個畫面 */
@media (max-height:480px){
  .confirmbar{position:static}
}

/* 使用者可自行填寫的欄位（氣瓶壓力／容量／配重） */
.fldin{width:88px;padding:5px 8px;border:1px solid var(--line2);border-radius:7px;
  background:var(--surf);color:var(--ink);font-family:"IBM Plex Mono",monospace;
  font-size:13px;text-align:right;font-variant-numeric:tabular-nums;
  -moz-appearance:textfield;appearance:textfield}
.fldin::-webkit-outer-spin-button,.fldin::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.fldin:focus{border-color:var(--ssi);outline:none;box-shadow:0 0 0 3px var(--ssi-s)}
.fldin.bad{border-color:var(--crit);box-shadow:0 0 0 3px var(--crit-s)}
.unit{font-size:11px;color:var(--ink3);margin-left:5px;font-family:"IBM Plex Mono",monospace}
.src.manual{background:var(--ok-s);color:var(--ok)}
@media (max-width:640px){ .fldin{width:76px} }

/* ══════════ 潛水日誌（SSI 風格）══════════ */
/* 日誌頁上方的動作列（「檢查新潛水」）。.sub 的下緣留白由它接手 */
.lb-actions{margin:-10px 0 18px}
/* 待續接同步的入口。沒有的時候是空的 —— :empty 才不會留下一段空白 */
.lb-resume{margin:0 0 18px}
.lb-resume:empty{display:none}
/* ── 載入中的骨架 ──────────────────────────────────────────
   形狀和真正的列一致，資料到了不會整個版面跳一下。
   微光從左掃到右；偏好減少動態時（檔頭的全域規則）動畫會被關掉，
   骨架仍然是靜態的灰塊，不影響理解。 */
.sk-note{display:flex;align-items:center;gap:9px;color:var(--ink2)}
.sk-dots{display:inline-flex;gap:4px}
.sk-dots i{width:6px;height:6px;border-radius:50%;background:var(--ssi);
  animation:skDot 1.1s ease-in-out infinite}
.sk-dots i:nth-child(2){animation-delay:.15s}
.sk-dots i:nth-child(3){animation-delay:.3s}
@keyframes skDot{0%,60%,100%{opacity:.25;transform:translateY(0)}
  30%{opacity:1;transform:translateY(-3px)}}

.lb-row.sk{cursor:default;pointer-events:none}
/* 骨架不設任何高度 —— 高度來自和真實列同一組字級與行距。
   只換掉顏色（文字透明、底色變灰），版面就完全一致。 */
.lb-row.sk .lb-tag{background:var(--surf3);color:transparent;
  position:relative;overflow:hidden}
.sk-b{border-radius:7px;background:var(--surf3);color:transparent;
  position:relative;overflow:hidden}
.sk-b::after,.lb-row.sk .lb-tag::after{content:"";position:absolute;inset:0;
  transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,
    color-mix(in srgb,var(--surf) 85%,transparent),transparent);
  animation:skShine 1.4s ease-in-out infinite}
@keyframes skShine{to{transform:translateX(100%)}}
.lb-row.sk .lb-site{width:42%}
.lb-row.sk .lb-meta{width:62%}
.lb-row.sk .lb-stat{width:54px}
/* 每一列的寬度錯開一點，看起來才像真的資料而不是排版線稿 */
.lb-row.sk:nth-child(2n) .lb-site{width:34%}
.lb-row.sk:nth-child(3n) .lb-site{width:52%}
.lb-row.sk:nth-child(2n) .lb-meta{width:54%}
.lb-row.sk:nth-child(3n) .lb-meta{width:70%}

/* 清單／地圖切換 */
.lb-views{display:inline-flex;gap:4px;background:var(--surf2);padding:4px;
  border-radius:10px;margin:0 0 14px}
.lb-view{border:none;background:none;border-radius:7px;padding:7px 16px;
  font-size:13px;font-weight:600;color:var(--ink2);font-family:inherit}
.lb-view.on{background:var(--surf);color:var(--ink);box-shadow:var(--sh)}
.lb-view:focus-visible{outline:2px solid var(--ssi);outline-offset:1px}

/* 潛水地圖。陸地輪廓是本地資產（Natural Earth 110m, CC0），
   不載入任何圖磚 —— 使用者的座標不會離開這個站。 */
/* 地圖比清單需要更多空間。清單的 940px 是為了閱讀寬度，地圖沒有這個限制，
   所以讓它往兩側各撐開一些（撐不開時 max-width 會自動收回來）。 */
.lb-map{position:relative;background:var(--surf);border:1px solid var(--line);
  border-radius:var(--r);padding:10px;overflow:hidden;
  width:min(1280px, calc(100vw - 40px));margin-left:50%;transform:translateX(-50%)}
/* touch-action:pan-y —— 單指垂直滑動讓給頁面捲動。
   設成 none 的話，手指落在地圖上整頁就捲不動了（地圖比視窗還高）。 */
.lb-map svg{display:block;width:100%;height:auto;touch-action:pan-y;cursor:grab}
.lb-map svg:active{cursor:grabbing}

/* 縮放控制。壓在地圖右下角,不佔額外的垂直空間。
   地圖比一般視窗還高,放在上緣的話「捲到看得見清單」時控制鈕就在畫面外了 ——
   兩者都放在下緣,才會同時看得到。清單的右邊留出這一欄的寬度。 */
.lb-mapctl{position:absolute;right:18px;bottom:18px;display:flex;flex-direction:column;gap:4px}
.lb-mapctl button{width:34px;height:34px;border-radius:9px;font-size:17px;line-height:1;
  background:color-mix(in srgb,var(--surf) 92%,transparent);backdrop-filter:blur(6px);
  border:1px solid var(--line2);color:var(--ink);font-family:inherit;box-shadow:var(--sh)}
.lb-mapctl button:hover{border-color:var(--ssi);color:var(--ssi-ink)}
.lb-mapctl button:focus-visible{outline:2px solid var(--ssi);outline-offset:2px}
.lb-map .mp circle{fill:color-mix(in srgb,var(--ssi) 55%,transparent);
  stroke:var(--ssi-b);stroke-width:2;vector-effect:non-scaling-stroke;
  cursor:pointer;transition:.15s}
.lb-map .mp:hover circle{fill:var(--ssi)}
.lb-map .mp:focus{outline:none}
.lb-map .mp:focus-visible circle{stroke:var(--warn);stroke-width:4}
/* 已經點開的那一顆。清單在地圖下面，這顆點是兩者之間唯一的連結，要看得出來 */
.lb-map .mp.on circle{fill:var(--ssi);stroke:var(--brand-t);stroke-width:3.5}
/* ── 換頁轉場（清單 ⇄ 潛水詳情）─────────────────────────
   直接抽換 innerHTML 是硬切的，看不出剛剛發生了什麼。
   加一點方向感：進去時從右邊淡入，回來時從左邊 —— 和使用者
   心裡的「往裡走／退回來」對得起來。

   只讓 #lbBody 參與轉場（給它 view-transition-name），
   頂上的導覽列就不會跟著滑動。 */
#lbBody{view-transition-name:lbbody}
/* ⚠ view-transition-name 會建立一個堆疊脈絡。全螢幕的覆蓋層是 #lbBody 的
   子孫，脈絡一旦成立，它的 z-index:70 就只在 #lbBody 內部比大小，
   贏不過外面 z-index:40 的頂列 —— 右上角的關閉鈕會被頂列蓋住點不到。
   全螢幕和換頁轉場不會同時發生，所以那時候直接關掉它。 */
body.mapfull #lbBody{view-transition-name:none}
::view-transition-old(lbbody){animation:vtOut .16s ease both}
::view-transition-new(lbbody){animation:vtIn .24s cubic-bezier(.2,.8,.3,1) both}
html[data-vt="back"] ::view-transition-new(lbbody){animation-name:vtInBack}
html[data-vt="back"] ::view-transition-old(lbbody){animation-name:vtOutBack}
@keyframes vtOut{to{opacity:0;transform:translateX(-14px)}}
@keyframes vtIn{from{opacity:0;transform:translateX(18px)}}
@keyframes vtOutBack{to{opacity:0;transform:translateX(14px)}}
@keyframes vtInBack{from{opacity:0;transform:translateX(-18px)}}
/* 沒有 View Transitions 的瀏覽器（例如 Firefox）的退路 */
.vt-in{animation:vtIn .24s cubic-bezier(.2,.8,.3,1) both}
.vt-back{animation:vtInBack .24s cubic-bezier(.2,.8,.3,1) both}
@media (prefers-reduced-motion:reduce){
  .vt-in,.vt-back{animation:none}
  ::view-transition-old(lbbody),::view-transition-new(lbbody){animation:none}
}

/* ── 全螢幕 ──────────────────────────────────────────────
   自己的覆蓋層,不是只靠原生的 Fullscreen API —— iOS Safari 的
   requestFullscreen 只支援 <video>,沒有這層 iPhone 上就等於沒功能。

   ⚠ transform 一定要歸零：有 transform 的祖先會讓 position:fixed
   退化成相對於它定位,覆蓋層就蓋不滿整個視窗。 */
.lb-map.full{position:fixed;inset:0;z-index:70;
  width:100%;max-width:none;margin:0;transform:none;
  border:0;border-radius:0;padding:0;background:var(--bg);
  display:flex;align-items:center;justify-content:center}
.lb-map.full svg{width:100%;height:auto;max-height:100%}
/* 覆蓋層打開時底下不該還能捲 —— 在地圖上滑動時背景跟著動會很混亂 */
body.mapfull{overflow:hidden}
/* 控制鈕與清單避開瀏海與底部的手勢列 */
.lb-map.full .lb-mapctl{right:calc(18px + env(safe-area-inset-right,0px));
  bottom:calc(18px + env(safe-area-inset-bottom,0px))}
.lb-map.full .lb-pickwrap{left:calc(14px + env(safe-area-inset-left,0px));
  right:calc(66px + env(safe-area-inset-right,0px));
  bottom:calc(14px + env(safe-area-inset-bottom,0px))}
/* 離開鈕。覆蓋層模式下沒有瀏覽器的離開提示,只靠 Esc 的話用觸控的人出不來 */
.lb-mapclose{position:absolute;z-index:2;
  top:calc(16px + env(safe-area-inset-top,0px));
  right:calc(18px + env(safe-area-inset-right,0px));
  width:42px;height:42px;border-radius:50%;font-size:16px;line-height:1;
  background:color-mix(in srgb,var(--surf) 92%,transparent);backdrop-filter:blur(6px);
  border:1px solid var(--line2);color:var(--ink);font-family:inherit;box-shadow:var(--sh)}
.lb-mapclose:hover{border-color:var(--ssi);color:var(--ssi-ink)}
.lb-mapclose:focus-visible{outline:2px solid var(--ssi);outline-offset:2px}
.lb-mapctl .mzf[aria-pressed="true"]{border-color:var(--ssi);color:var(--ssi-ink)}
@media (max-width:720px){
  .lb-map.full .lb-pickwrap{left:calc(8px + env(safe-area-inset-left,0px));
    right:calc(62px + env(safe-area-inset-right,0px));
    bottom:calc(8px + env(safe-area-inset-bottom,0px))}
}

/* 手勢提示。浮在地圖中央,做了「會被讓給頁面」的手勢時出現一下下 */
.lb-maphint{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) scale(.96);
  padding:10px 18px;border-radius:999px;font-size:13.5px;font-weight:600;
  background:color-mix(in srgb,var(--ink) 86%,transparent);color:var(--surf);
  box-shadow:0 6px 24px -6px rgba(0,0,0,.4);white-space:nowrap;max-width:calc(100% - 32px);
  opacity:0;pointer-events:none;transition:opacity .18s,transform .18s}
.lb-maphint.on{opacity:1;transform:translate(-50%,-50%) scale(1)}
@media (prefers-reduced-motion:reduce){.lb-maphint{transition:opacity .18s}}
/* 圖磚的資料來源標示。ODbL 要求要標，而全螢幕時外面那行說明看不到，
   所以它必須疊在地圖裡面。壓在左下角，不擋右下角的縮放控制。 */
.lb-mapattr{position:absolute;z-index:1;
  left:calc(8px + env(safe-area-inset-left,0px));
  bottom:calc(6px + env(safe-area-inset-bottom,0px));
  padding:2px 7px;border-radius:5px;font-size:10.5px;line-height:1.5;
  color:var(--ink2);background:color-mix(in srgb,var(--surf) 78%,transparent);
  -webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);pointer-events:none}
/* 圖磚模式下不要抗鋸齒模糊（放大時寧可像素化也不要糊成一片） */
.lb-map svg.tiled image{image-rendering:auto}
.lb-map svg.drawn>path{fill:var(--surf3);stroke:var(--line2);stroke-width:1.2;
  vector-effect:non-scaling-stroke}
.lb-map-note{margin-top:10px;text-align:center}
.lb-map-credit{font-size:11.5px;color:var(--ink3)}

/* 點開一顆點之後列出的潛水。
   疊在地圖底部而不是另外接一張卡片在下面 —— 它講的是「這顆點裡有什麼」,
   和那顆點是同一件事,分成兩塊會讓人以為是兩個區域。
   列本身完全沿用清單頁的 .lb-row,看到的是同一個東西。 */
/* 高度收在地圖的 46%：清單要看得到幾筆，但地圖不能被蓋掉 ——
   蓋住了就失去「這幾筆在這裡」的意義，那才是把它疊上來的理由。 */
.lb-pickwrap{position:absolute;left:14px;right:66px;bottom:14px;height:46%;
  display:flex;pointer-events:none}
.lb-pickwrap:empty{display:none}
.lb-pick{flex:1;min-height:0;display:flex;flex-direction:column;pointer-events:auto;
  background:color-mix(in srgb,var(--surf) 93%,transparent);backdrop-filter:blur(12px);
  border:1px solid var(--line2);border-radius:var(--r);box-shadow:0 8px 32px -8px rgba(0,0,0,.28);
  padding:14px 16px 0;animation:pickUp .22s cubic-bezier(.2,.8,.3,1)}
@keyframes pickUp{from{opacity:0;transform:translateY(12px)}}
@media (prefers-reduced-motion:reduce){.lb-pick{animation:none}}
.lb-pick-head{display:flex;align-items:center;gap:12px;flex:none}
.lb-pick-head h2{margin:0;font-size:15.5px;flex:1;min-width:0}
.lb-pick-head h2:focus-visible{outline:2px solid var(--ssi);outline-offset:3px;border-radius:4px}
.lb-pick-head button{margin-left:auto;flex:none}
.lb-pick .hint{margin:2px 0 10px;flex:none}
/* 清單自己捲,卡片本身不長高 —— 不然一顆點有五十筆就把地圖整個吃掉 */
.lb-pick .lb-list{overflow-y:auto;min-height:0;padding-bottom:14px}
/* flex 項目在限高的容器裡預設會被壓縮。不擋下來的話,五十筆會各自縮成
   一條線（實測整份清單變成一疊橫線）—— 列的高度必須是列自己的事。 */
.lb-pick .lb-row{flex:none}
.lb-pick .lb-more{margin:4px 0 0}
/* 疊在地圖上時列不用再自己帶陰影,卡片已經有了 */
.lb-pick .lb-row{box-shadow:none}

/* 只給螢幕閱讀器的補充說明 */
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);
  clip-path:inset(50%);white-space:nowrap}
/* 「在 Google 地圖上檢視」。放在標題列右側,用圖釘 icon ——
   它講的是「這一筆潛水在哪裡」,和左邊的潛點名稱是同一件事。 */
.lb-maplink{margin-left:auto;display:inline-flex;align-items:center;gap:7px;
  padding:8px 14px;border-radius:999px;text-decoration:none;white-space:nowrap;
  background:var(--surf2);border:1px solid var(--line2);
  color:var(--ink2);font-size:12.5px;font-weight:600;transition:.15s}
.lb-maplink:hover{border-color:var(--ssi);color:var(--ink);background:var(--surf)}
.lb-maplink:focus-visible{outline:2px solid var(--ssi);outline-offset:2px}
.lb-maplink .pin{width:15px;height:15px;flex:0 0 auto;fill:var(--ssi-ink)}
.lb-maplink .pin circle{fill:var(--surf2)}
.lb-maplink:hover .pin circle{fill:var(--surf)}
@media(max-width:520px){
  /* 窄螢幕只留圖釘,文字收起來（title 與 sr 仍讀得到） */
  .lb-maplink{padding:9px;gap:0}
  .lb-maplink .lbl{position:absolute;width:1px;height:1px;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap}
}

/* 日誌清單的搜尋。資料在前端,所以是即時過濾,不打 API */
.lb-search{display:flex;align-items:center;gap:12px;margin:0 0 14px;flex-wrap:wrap}
.lb-search input{flex:1;min-width:200px;padding:10px 13px;border:1px solid var(--line2);
  border-radius:9px;background:var(--surf);color:var(--ink)}
.lb-search input:focus{border-color:var(--ssi);outline:none;box-shadow:0 0 0 3px var(--ssi-s)}
.lb-found{font-size:12.5px;color:var(--ink3);white-space:nowrap}
.lb-more{margin-top:14px;text-align:center}

.lb-offline{margin:0 0 12px;padding:9px 13px;border-radius:var(--rs);
  background:var(--warn-s);color:var(--warn);font-size:13px;font-weight:600;
  border:1px solid color-mix(in srgb,var(--warn) 30%,transparent)}
.lb-list{display:flex;flex-direction:column;gap:10px}
/* button 只從 line 69 繼承到 font-family，字級與行距仍是瀏覽器預設的
   13.33px/normal —— 沒設的話 .lb-site（主要資訊）只比 .lb-meta（次要）
   大 0.8px，階層等於沒有，骨架（div）也永遠對不上這個高度。 */
.lb-row{font-size:inherit;line-height:inherit;
  display:flex;align-items:stretch;gap:14px;width:100%;text-align:left;cursor:pointer;
  background:var(--surf);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--sh);padding:0;overflow:hidden;transition:border-color .15s,transform .05s}
.lb-row:hover{border-color:var(--line2)}
.lb-row:active{transform:scale(.995)}
.lb-tag{display:flex;flex-direction:column;justify-content:center;align-items:center;
  min-width:88px;padding:12px 8px;color:var(--tag-fg);font-weight:700}
.lb-tag.scuba{background:var(--crit)}
.lb-tag.free{background:var(--gar)}
.lb-kind{font-size:15px;letter-spacing:.3px}
.lb-num{font-family:"IBM Plex Mono",monospace;font-size:13px;opacity:.9;margin-top:2px}
.lb-mid{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;gap:3px;padding:10px 0}
.lb-site{font-weight:600;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lb-meta{font-size:12.5px;color:var(--ink3)}
.lb-right{display:flex;flex-direction:column;justify-content:center;align-items:flex-end;gap:3px;
  padding:10px 14px 10px 0;white-space:nowrap}
.lb-stat{font-family:"IBM Plex Mono",monospace;font-size:13px;color:var(--ink2)}
.lb-shield{color:var(--ok);font-size:15px;margin-top:2px}
/* 沒認證的列也要留這個位置,否則兩種列高度不一樣 */
.lb-shield.off{visibility:hidden}
.lb-head{display:flex;align-items:center;gap:14px;margin:14px 0 18px}
.lb-head .lb-tag{border-radius:12px;min-width:80px}
.lb-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;margin-bottom:8px}
.lb-bigstat{background:var(--surf2);border:1px solid var(--line);border-radius:var(--r);padding:14px 16px}
.lb-bigstat .l{display:block;font-size:12px;color:var(--ink3);margin-bottom:4px}
.lb-bigstat .v{font-size:26px;font-weight:700;color:var(--ink);line-height:1}
.lb-bigstat .v em{font-size:14px;font-weight:500;color:var(--ink3);font-style:normal}
/* ── 潛水比較 ─────────────────────────────────────────────
   一筆潛水有近四百個欄位,真正有意義的是「哪裡不一樣」,
   所以預設只列出有差異的那些,相同的收起來。 */
.cmp-bar{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin:16px 0 10px;
  background:var(--surf2);border:1px solid var(--line);border-radius:var(--rs);padding:10px 14px}
.cmp-pick{display:flex;align-items:center;gap:9px}
.cmp-pick .cl{font-size:12.5px;color:var(--ink2);white-space:nowrap}
.cmp-pick select{max-width:min(340px,58vw)}
.cmp-bar .btn{margin-left:auto}

/* 兩筆的識別。B 欄用青綠,和下面每一列的 B 值對得起來 */
/* 兩邊各是哪一筆 —— 整張比較表的欄位抬頭。
 *
 * 字級：原本 12.5px 比欄位標籤還小，而它才是「左邊這欄是誰的」的唯一線索。
 *
 * 格線：跟著 .cs 走（同樣的欄寬、padding，尾端也補一格差值欄的寬度），
 * 抬頭才會剛好落在它所說明的那一欄上面。原本是 1fr 1fr 又沒有 padding，
 * 左邊那個飄在「最大深度」那一欄的上方，指的卻是右邊的數字。 */
.cmp-head{display:grid;grid-template-columns:1fr 1fr 1fr auto;gap:12px;
  padding:0 14px;margin-bottom:8px;font-size:14.5px;font-weight:700;line-height:1.35}
.cmp-head .ca{grid-column:2;color:var(--ink2)}
.cmp-head .cb{grid-column:3;color:var(--ssi-ink)}
.cmp-head::after{content:"";min-width:3.5em}   /* 對齊 .cs .d 的差值欄 */
/* 詳情頁的「✔ 已認證」。本來是 inline 的 var(--ok)，在頁面底色上只有 4.31 */
.lb-head .vfy{color:var(--ok-ink)}

.cmp-stats{display:flex;flex-direction:column;gap:2px;margin-bottom:8px}
.cs{display:grid;grid-template-columns:1fr 1fr 1fr auto;gap:12px;align-items:baseline;
  background:var(--surf2);border:1px solid var(--line);border-radius:var(--rs);padding:11px 14px}
.cs .l{font-size:12px;color:var(--ink3);display:flex;align-items:center;gap:6px}
.cs .a,.cs .b{font-size:19px;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums}
.cs .b{color:var(--ssi-ink)}
.cs em{font-size:12px;font-weight:500;color:var(--ink3);font-style:normal}
.cs .d{font-family:"IBM Plex Mono",monospace;font-size:12.5px;font-weight:700;
  color:var(--warn-ink);text-align:right;min-width:3.5em}
.cs .d.same{color:var(--ink3);font-weight:400}

/* 比較模式的欄位列：標籤 + 兩個值 */
/* 最後一欄留給釘選鈕。少了它，第四個子元素會被擠到下一行，
   每一列變成兩倍高 —— 而且那顆鈕會落在標籤的正下方，看起來像屬於別人。 */
.fieldrow.cmp{display:grid;grid-template-columns:minmax(7em,1.1fr) 1fr 1fr auto;
  gap:12px;align-items:baseline}
.fieldrow.cmp .fv{text-align:left}
.fieldrow.cmp .fv:last-child{color:var(--ssi-ink)}
.fieldrow.cmp.diff{background:color-mix(in srgb,var(--warn) 9%,transparent);
  margin:0 -8px;padding-left:8px;padding-right:8px;border-radius:6px}
.fieldrow .dlt{font-family:"IBM Plex Mono",monospace;font-size:11.5px;font-weight:700;
  color:var(--warn-ink);font-style:normal;margin-left:4px}

@media (max-width:720px){
  /* 手機上地圖改直式（見 app.js 的 mapAspect），清單佔六成才列得下幾筆。
     右邊留 62px 給縮放控制,不然兩者會貼在一起。 */
  .lb-pickwrap{left:8px;right:62px;bottom:8px;height:60%}
  .lb-pick{padding:12px 12px 0}
  .lb-pick .lb-tag{min-width:64px}
  /* 空間只夠放兩三列,說明行讓出來 —— 標題已經寫了「72 次潛水」 */
  .lb-pick .hint{display:none}
}

/* 窄螢幕：三欄擠不下,標籤自己一行 */
@media(max-width:560px){
  .cs{grid-template-columns:1fr auto;row-gap:4px}
  .cs .l{grid-column:1/-1}
  .cs .d{grid-column:2}
  .fieldrow.cmp{grid-template-columns:1fr 1fr auto}
  .fieldrow.cmp .fl{grid-column:1/-1}
  /* 窄螢幕的 .cs 是 1fr auto：兩個數值分別貼齊左右兩端。抬頭跟著貼齊，
     右邊那個要靠右 —— 放在正中間的話，它指的是右邊那一欄卻長得像在指中間。 */
  .cmp-head{grid-template-columns:1fr auto;padding:0 14px;font-size:13px}
  .cmp-head .ca{grid-column:1}
  .cmp-head .cb{grid-column:2;text-align:right}
  .cmp-head::after{content:none}
}

.lb-groups{display:flex;flex-direction:column;gap:16px;margin-top:16px}
.lb-group{background:var(--surf);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--sh);padding:6px 18px 14px}
.lb-group h2{font-size:13px;text-transform:uppercase;letter-spacing:.6px;color:var(--ssi);
  margin:14px 0 6px;padding-bottom:8px;border-bottom:1px solid var(--line)}
.fieldrow{display:flex;justify-content:space-between;gap:16px;padding:7px 0;
  border-bottom:1px dashed var(--line);font-size:14px}
.fieldrow:last-child{border-bottom:0}
.fl{color:var(--ink2)}
.fl.mono{font-family:"IBM Plex Mono",monospace;font-size:12px;color:var(--ink3)}
.fv{color:var(--ink);font-weight:600;text-align:right;word-break:break-word}
.fv.empty{color:var(--ink3);font-weight:400}
@media(max-width:520px){.lb-tag,.lb-head .lb-tag{min-width:66px}.lb-kind{font-size:13px}}

/* 手機與平板:頂列不放頁面連結(改用底部 tab bar),內容底部留白避開浮動列。
   放檔尾確保 padding-bottom 蓋過前面各斷點設的 shorthand padding。 */
@media(max-width:1024px){
  .pagelink{display:none}
  .page{padding-bottom:calc(96px + env(safe-area-inset-bottom,0px))}
}

/* ── 分享一筆潛水 ──────────────────────────────────────────
 *
 * 排在檔尾：它要蓋過前面各斷點對 .row / .card 設的 shorthand。 */

/* 詳細頁標題下方那一排動作。分享、匯入、比較都在這裡 —— 和欄位之間
   隔一條線，讓「這是可以做的事」和「這是資料」在視覺上分開。 */
.share-actions{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:14px 0 4px}

/* 匯入前先改：一列一欄，標籤在左、輸入框在右。窄螢幕改成上下 ——
   並排時輸入框會被擠到剩幾個字寬，改一個潛點名稱要橫向捲。 */
.fieldrow.ed{display:grid;grid-template-columns:minmax(7em,1fr) minmax(0,1.4fr);
  gap:10px 16px;align-items:center;padding:9px 0}
.fieldrow.ed .fl{line-height:1.35}
.edin{width:100%;padding:8px 11px;border:1px solid var(--line2);border-radius:8px;
  background:var(--bg);color:var(--ink);font-size:15px;min-width:0}
textarea.edin{resize:vertical;line-height:1.5}
/* 可複選的欄位（特殊潛水可以同時是船潛＋沉船）用一排勾選框，不用
   <select multiple>：後者在桌機要按著 Ctrl 才取消得掉一項，在手機上更是
   看不出「可以多選」。點一下就切換，這件事不該需要先知道要按哪個鍵。 */
.edchecks{display:flex;flex-wrap:wrap;gap:6px 8px;min-width:0}
.edchk{display:inline-flex;align-items:center;gap:6px;padding:6px 10px;
  border:1px solid var(--line2);border-radius:999px;background:var(--bg);
  font-size:13.5px;line-height:1.3;cursor:pointer}
.edchk input{margin:0;accent-color:var(--ssi)}
.edchk:has(input:checked){border-color:var(--ssi);background:var(--ssi-s);font-weight:600}
.edchk:focus-within{outline:2px solid var(--ssi);outline-offset:1px}

/* 改不動的欄位：畫成純文字加一句交代，不留一個可以亂打的框 */
.fieldrow.ed.ro .fv{text-align:left;font-weight:600}
.ed-ro{display:block;margin-top:3px;font-weight:400}
/* 「這一筆沒有 GPS，要用潛點的座標嗎」 */
.ed-gps{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:10px 0 0}
.edin:focus{border-color:var(--ssi);outline:none;box-shadow:0 0 0 3px var(--ssi-s)}
.ed-fixed{margin:10px 2px 0}
.ed-only{margin:6px 2px 14px}
/* 「新增欄位」——每一張分類卡片底下各一顆。整行寬、虛線框：它是一個
   「這一類還可以再加東西」的位置，不是一顆和「確認匯入」同級的動作鍵。 */
.ed-add{display:flex;width:100%;justify-content:center;align-items:center;gap:8px;
  margin-top:12px;padding:8px 12px;border-style:dashed;font-size:13.5px;font-weight:600}
.ed-add .plus{font-size:16px;line-height:1}
/* 這一筆一欄都沒記到的分類：只剩標題和那顆按鈕，別留一段空白 */
.lb-group.empty h2,.lb-group.empty h3{margin-bottom:0}
.lb-group.empty .ed-add{margin-top:10px}
/* 挑欄位的清單。視窗高度有限，讓清單自己捲，搜尋框和取消鍵永遠看得到。 */
#fldSearch{width:100%;box-sizing:border-box;padding:11px 13px;
  border:1px solid var(--line2);border-radius:9px;background:var(--surf);color:var(--ink)}
.fld-list{max-height:min(46vh,340px);overflow:auto;margin:12px -4px 0;padding:0 4px}
/* 搜尋框收起來時清單就直接接在標題底下 */
#fldForm[hidden]+.fld-list{margin-top:10px}
.fld-item{display:block;width:100%;text-align:left;padding:9px 10px;border:0;
  border-radius:8px;background:transparent;color:var(--ink);font-size:14.5px;
  cursor:pointer}
.fld-item:hover,.fld-item:focus-visible{background:var(--ssi-s);outline:none}
.fld-item .fl{color:inherit}
.fld-none{margin:14px 2px}
/* 幾十個欄位，動作列黏在底部才按得到。手機有底部 tab bar，往上讓開它。 */
.ed-bar{position:sticky;bottom:0;z-index:4;display:flex;flex-wrap:wrap;
  align-items:center;gap:10px;margin-top:14px;padding:12px 0;
  background:linear-gradient(to bottom,transparent,var(--bg) 22%);}
.ed-bar .ed-count{margin-right:auto;font-size:12.5px;color:var(--ink3)}
.ed-bar .ed-count.on{color:var(--ssi);font-weight:700}
#impEdited{margin:2px 0 0;font-size:12.5px;color:var(--ssi);font-weight:700}
@media(max-width:560px){
  .fieldrow.ed{grid-template-columns:1fr;gap:5px}
  .ed-bar{bottom:calc(72px + env(safe-area-inset-bottom,0px))}
  .ed-bar .btn{flex:1}
  .ed-bar .ed-count{flex:1 0 100%;margin:0 0 2px}
}

.share-box{margin:14px 0 4px}
.share-code-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.share-code-row .l{font-size:12.5px;color:var(--ink3)}
/* 分享碼要看得清楚、抄得動：等寬、字距拉開、字級比內文大一截。
   使用者會對著螢幕念給朋友聽，或用手機拍下來。 */
.share-code{font-family:"IBM Plex Mono",ui-monospace,monospace;font-weight:700;
  font-size:19px;letter-spacing:.14em;color:var(--ssi-ink);
  background:var(--ssi-s);border-radius:8px;padding:5px 11px;user-select:all}
.share-code.sm{font-size:13px;letter-spacing:.08em;padding:2px 7px}
.share-copy{margin-top:12px;gap:8px}
.share-note{margin:12px 0 0}

.share-rules{margin:8px 0 0}

/* 「某某分享的潛水紀錄」。接在日期那一行下面，講的是來源不是數據。 */
.detail-note{margin:6px 0 0;color:var(--ssi-ink);font-weight:600}
/* 分享頁沒有左邊那塊徽章，標題就從最左邊開始 */
.lb-head.notag{gap:0}

.share-row{gap:10px;flex-wrap:wrap}
.share-row-main{display:flex;flex-direction:column;gap:1px;margin-right:auto;min-width:0}
.share-row-main b{font-size:14px}

@media(max-width:560px){
  .share-actions .btn{flex:1 1 auto}
  .share-row{align-items:flex-start}
}

/* ── 彈出視窗（原生 <dialog>）─────────────────────────────
 *
 * 只做外觀。焦點困在裡面、Esc 關閉、背景不能操作，都由瀏覽器負責 ——
 * 自己刻那三件事幾乎一定會做得更差。 */
.dlg{border:0;padding:0;background:transparent;max-width:min(440px,calc(100vw - 32px));width:100%}
.dlg::backdrop{background:color-mix(in srgb,#000 46%,transparent);backdrop-filter:blur(2px)}
.dlg > *{background:var(--surf)}
.dlg{border-radius:16px;box-shadow:0 18px 50px rgba(0,0,0,.28);overflow:hidden;
  background:var(--surf);border:1px solid var(--line2);color:var(--ink);padding:22px 22px 20px}
.dlg h2{font-size:1.15rem;font-weight:800;margin:0 0 4px;letter-spacing:-.01em}
.dlg .sub{margin:0 0 16px}
.dlg-form{display:block}
/* 分享碼是一串要抄進來的字：等寬、字距拉開、字級大一點，
   打錯一個字元就進不去，不該讓人瞇著眼睛對。 */
#shCode{width:100%;box-sizing:border-box;font-family:"IBM Plex Mono",ui-monospace,monospace;
  font-size:17px;letter-spacing:.14em;text-transform:uppercase;text-align:center}
.dlg .msg{margin:10px 0 0}
/* 對話框裡的輸入框：和表單裡的一樣寬、一樣高，不要因為換了容器就變一種樣子 */
.dlg-form input[type=email],.dlg-form input[type=text],.dlg-form input[type=password]{
  width:100%;box-sizing:border-box}
.dlg-form .fld{margin-bottom:0}
/* 主要動作撐開、取消只佔自己的寬度 —— 兩顆等寬會讓「取消」看起來和
   「寄出」一樣重要，但它們不是同一個層級的選擇 */
.dlg-actions{margin-top:18px;gap:10px;align-items:center}
.dlg-actions .btn{flex:1 1 auto}
.dlg-actions .btn.ghost{flex:0 0 auto}
@media(max-width:420px){
  .dlg-actions{flex-direction:column-reverse;align-items:stretch}
  .dlg-actions .btn{width:100%}
}

/* 「忘記密碼？」。它是一條路，不是一個動作 —— 畫成按鈕會和「登入」搶注意力，
   所以用連結的樣子。但仍然是 <button>（沒有網址可以去），
   而原生按鈕不設樣式就會長成作業系統那顆灰色方框。 */
/* Turnstile 的 widget（在自己的視窗裡，按下功能按鈕之後才出現）。
   置中：它是一塊固定 300px 寬的第三方方塊。
   撐住高度：widget 是非同步畫進來的，不先佔位的話視窗會在它到位的瞬間
   往下長一截 —— 而使用者的滑鼠已經停在那個位置上了。 */
.ts-box{display:flex;justify-content:center;align-items:center;
  min-height:70px;margin:16px 0 4px}
/* 窄螢幕上那個 300px 的 iframe 會頂出去，縮一點讓它待在視窗裡 */
@media(max-width:360px){
  .ts-box{transform:scale(.92);transform-origin:top center}
}

.authlink{margin:12px 0 0;text-align:center}
.authlink button{background:none;border:0;padding:8px 6px;font:inherit;
  font-size:13px;color:var(--ssi-ink);cursor:pointer;border-radius:8px;
  text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:color-mix(in srgb,var(--ssi) 40%,transparent)}
.authlink button:hover{color:var(--ssi);text-decoration-color:currentColor}
.authlink button:focus-visible{outline:2px solid var(--ssi);outline-offset:1px}
@media (prefers-reduced-motion:no-preference){
  .dlg[open]{animation:dlgIn .16s ease-out}
  @keyframes dlgIn{from{opacity:0;transform:translateY(6px) scale(.98)}}
}

/* ── 釘選欄位 ──────────────────────────────────────────── */

/* 比較模式下每一列右邊的釘選鈕。
 *
 * **一直看得到**。先前平常是透明的、滑鼠移過去才浮現 —— 手機沒有 hover，
 * 等於整個功能不存在；就算在電腦上，也要先把游標亂晃一遍才會發現。
 *
 * 做成看得出是按鈕的形狀（有外框），而不是一個飄在旁邊的小圖示；
 * 尺寸拉到 32px，手指按得到。 */
.fieldrow .pin{width:32px;height:32px;display:inline-flex;align-items:center;
  justify-content:center;padding:0;margin:0 0 0 6px;flex:0 0 auto;
  background:var(--surf);border:1px solid var(--line2);border-radius:9px;
  color:var(--ink3);cursor:pointer;transition:background .12s,border-color .12s,color .12s}
.fieldrow .pin svg{width:15px;height:15px;fill:currentColor}
.fieldrow .pin:hover{border-color:var(--ssi);color:var(--ssi-ink)}
.fieldrow .pin:focus-visible{outline:2px solid var(--ssi);outline-offset:2px}
/* 已釘選的要一眼認得出來，不只是顏色深一點 */
.fieldrow .pin.on{background:var(--ssi-s);border-color:var(--ssi);color:var(--ssi-ink)}

/* 抓握處：抓著它上下拖。
 *
 * touch-action:none 只設在這一顆上 —— 整塊都設的話，手機上「手指放到這一列
 * 就捲不動頁面」。 */
.cs .grip{width:28px;height:28px;display:inline-flex;align-items:center;
  justify-content:center;padding:0;flex:0 0 auto;background:none;border:0;
  border-radius:7px;color:var(--ink3);cursor:grab;touch-action:none}
.cs .grip svg{width:14px;height:14px;fill:currentColor}
.cs .grip:hover{background:var(--surf3);color:var(--ink)}
.cs .grip:focus-visible{outline:2px solid var(--ssi);outline-offset:1px}
.cs .grip:active{cursor:grabbing}

/* 拖曳中的那一列：浮起來跟著手指。
 *
 * pointer-events:none 是必要的，不是裝飾：elementFromPoint 要拿到它
 * 「底下」那一列，才知道現在拖到哪裡了。
 *
 * 位移由 JS 每次 pointermove 設 transform，所以這裡**不能**加 transition
 * —— 加了就會慢半拍地追手指，看起來像卡住。 */
.cs.dragging{pointer-events:none;position:relative;z-index:3;
  border-color:var(--ssi);background:var(--surf);
  box-shadow:0 10px 26px rgba(0,0,0,.22);transform-origin:center}
/* 拖曳期間不要選到文字，也讓其餘幾列滑順地讓位 */
.dragging-list{user-select:none;-webkit-user-select:none}
.dragging-list .cs:not(.dragging){transition:transform .14s ease,opacity .14s}
.dragging-list .cs:not(.dragging){opacity:.72}

/* 取消釘選。
 *
 * **一直看得到**，和右邊那顆釘選鈕一樣 —— 只在 hover 時出現的話，手機上
 * 等於沒有辦法取消。做成同樣的按鈕形狀、同樣的觸控尺寸，一眼就知道是一對
 * 可以按的東西。 */
.pinctl{width:28px;height:28px;display:inline-flex;align-items:center;
  justify-content:center;padding:0;font-size:12px;line-height:1;
  color:var(--ink3);cursor:pointer;font-family:inherit;flex:0 0 auto;
  margin-left:auto;background:var(--surf);border:1px solid var(--line2);
  border-radius:8px;transition:background .12s,border-color .12s,color .12s}
.pinctl:hover{background:var(--crit-s);border-color:var(--crit);color:var(--crit)}
.pinctl:focus-visible{outline:2px solid var(--ssi);outline-offset:2px}

/* 還沒釘任何欄位時的說明。那塊區域空著沒有理由 */
.pin-empty{margin:16px 0 8px}

/* 已過期的分享：留在清單上但不搶眼 —— 看得到才知道為什麼朋友說連結壞了 */
.share-row.off{opacity:.62}
