/* 打卡頁專用樣式。

   原本內嵌在 index.html 裡（21KB）。HTML 是「現在哪一版」的唯一入口，
   只快取 60 秒，也就是每次冷開都要重新下載一遍。抽成獨立檔之後網址帶
   內容指紋、標成 immutable——沒改東西的日子裡一個請求都不會發。

   ⚠ 必須排在 style.css 之後載入：這裡有覆寫共用樣式的規則。 */

  /* ── 現場地圖 ──
     字壓在地圖上，靠一層由上而下加深的半透明遮罩撐可讀性——不是把地圖蓋掉。
     遮罩落在文字位置約 .33，地圖透得出三分之二，跟當初選定的模擬圖一致。
     能做到這麼淡的關鍵是次要文字改用 --map-fg-2：淺色的 --sub(#666) 在這個濃度只有
     4.3:1，是它一路逼著遮罩加深的。
     地圖自己的路名止於 46%（map.js 的 TEXT_FLOOR），不會透到字底下。
     調整版面或色票後務必重跑 scripts/test-map-contrast.mjs，別靠肉眼——
     地圖會動，看一張截圖說「還行」是不算數的。 */
  .hero { padding: 0; overflow: hidden; }
  /* ---- 地圖高度跟著螢幕高度走 ----
     原本寫死 320px。在 375×667 上那是整頁的 48%，把底下五顆捷徑鈕推出第一屏
     （實測要捲 117px；360×640 要捲 144px）。
     改成 min(38vh, 320px)：高螢幕維持原樣，矮螢幕自動收——
     地圖是輔助資訊（讓人確認「我站的位置對不對」），不該把要按的東西擠掉。
     下限 210px：再矮就看不出自己在圈內還是圈外，那它就失去意義了。 */
  .mapband { position: relative; height: clamp(200px, 35vh, 320px); }
  .mapband canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
  .mapband .veil {
    position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(180deg,
      var(--map-scrim-top) 0%, transparent 26%,
      transparent 44%, var(--map-scrim-1) 56%,
      var(--map-scrim-2) 72%, var(--panel) 100%);
  }
  .mapband .over { position: absolute; left: 0; right: 0; bottom: 12px; padding: 0 16px; }
  /* 問候與日期同一行；日期不再吊在時鐘右下角當下標 */
  .mapband .greet {
    display: flex; align-items: baseline; gap: 8px;
    font-size: .84rem; color: var(--map-fg-2); margin-bottom: 5px; text-shadow: var(--map-text-shadow);
  }
  .clock {
    font-size: 3.4rem; font-weight: 200; letter-spacing: -.02em; line-height: 1;
    color: var(--head); font-variant-numeric: tabular-nums; text-shadow: var(--map-text-shadow);
    transition: font-size .3s, opacity .3s;
  }
  /* 收班之後把時鐘縮下來。
     那個一直在跳的數字，在「還沒打卡」時是有用的（跟班表對照，判斷來不來得及）；
     一旦今天結束了，它就不再回答任何問題——而它仍然是整個畫面上最大的東西，
     把「我今天打了什麼」壓到下面去。收班後改由那份紀錄當主角。 */
  .hero.done .clock { font-size: 1.6rem; opacity: .55; font-weight: 300; }
  .hero.done .greet { font-size: .95rem; color: var(--head); font-weight: 600; }
  /* 定位狀態膠囊（.locbar）搬到 style.css：後台的打卡頁預覽也要用同一顆。
     各自定義一份的話，預覽看起來會跟同仁真正看到的不一樣——
     而那正是預覽最不該發生的事。 */
  /* 地圖以下的內容區：卡片本身已無 padding，這裡補回來 */
  .hero .below { padding: 14px 16px 16px; }
  /* ---- 這一頁以「一屏裝得下」為目標 ----
     其他頁面是捲著看的，這一頁不是：主按鈕與底下五顆捷徑都要一眼看得到、
     不必滑動。矮螢幕上把外距收一階，換到的空間正好是那五顆鈕。
     只在矮螢幕收，高螢幕維持原本比較寬鬆的呼吸感。 */
  @media (max-height: 720px) {
    body { padding: 10px 12px; }
    .hero.card { margin-bottom: 8px; }
    .hero .below { padding: 10px 14px 12px; }
    .shortcuts > a, .shortcuts > span { padding: 7px 2px; }
  }
  /* 重疊圍欄的地點選擇 */
  .site-pick { margin-top: 8px; text-align: left; }
  .site-pick.hide { display: none; }
  .site-pick .sp-hint { font-size: .74rem; color: var(--muted); margin-bottom: 5px; }
  .site-pick .sp-row { display: flex; gap: 6px; flex-wrap: wrap; }
  .site-pick button {
    flex: 1; min-width: 40%; margin: 0; padding: 8px 6px; font-size: .84rem; border-radius: 10px;
    background: var(--panel2); border: 1px solid var(--line); color: var(--muted);
  }
  .site-pick button.on { border-color: var(--green); color: var(--green); background: rgba(47, 212, 143, .1); }
  .site-pick button small { display: block; font-size: .68rem; opacity: .8; }
  /* 「目前狀態」那一列已移除：地圖上的點、定位膠囊、今日打卡摘要
     已經把「我在哪、從幾點起」講完了，再列一次只是把畫面塞滿。 */
  /* 班制／工時一行帶過，下面接細進度條——取代原本分散的三、四行提示 */
  /* 班制那一行：「公司班　08:30 – 17:30」。
     原本用 --muted（最淡的那階），深色底上幾乎看不見——而它是判斷遲到的依據，
     不是可有可無的裝飾。改用 --sub（次要但讀得到），時間再重一階。 */
  .statline { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin: 2px 2px 7px; font-size: .82rem; color: var(--sub); }
  .statline #statRight { color: var(--text); font-variant-numeric: tabular-nums; }
  .statline .worked { font-weight: 600; color: var(--sub); }
  .statline .late { font-weight: 600; color: var(--red); }
  /* ---- 狀態條 ----
     班制、今天幾點上的班、已經工作多久——這三件事原本散在三個地方：
     班制在 statline 左邊、上班時間要自己從今日歷程的第一行看、
     已工作多久只在問候語裡出現一次。三格並排之後，它們是同一組事實，
     而且欄位固定，人第二次進來就知道要看哪一格。 */
  .statbar { display: flex; gap: 2px; background: var(--line-strong); border-radius: 10px;
    overflow: hidden; margin: 0 0 4px; }
  /* 三格的內容一格是數字（08:27）、一格是中文（公司班），而數字沒有下伸部、
     字身也比漢字矮——同一個行高裡，數字的視覺重心會比漢字高一點點，
     三格並排就看得出中間那格「浮起來」。
     解法是不靠行高排版：每一格與每一行都用 flex 置中，行高固定成 1，
     那條基線的差異就不會再被半行距放大。 */
  .statbar > div {
    flex: 1; background: var(--panel2); padding: 8px 4px; text-align: center;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  }
  .statbar b {
    display: flex; align-items: center; justify-content: center;
    height: 1.15em; line-height: 1; white-space: nowrap;
    color: var(--head); font-size: .95rem; font-weight: 800; font-variant-numeric: tabular-nums;
  }
  .statbar b.late { color: var(--red); }
  /* 「已工作」是這一列真正要看的數字（另外兩格是脈絡），給它顏色 */
  .statbar b.lead { color: var(--green); }
  .statbar span {
    display: flex; align-items: center; justify-content: center;
    height: 1.15em; line-height: 1; white-space: nowrap;
    font-size: .64rem; letter-spacing: .04em;
    color: var(--muted); font-variant-numeric: tabular-nums;
  }
  .statbar.hide { display: none; }
  /* 一行擺得下四段東西（標籤／時段／案件／取消鈕）的關鍵是「誰可以被截斷」：
     標籤與時段是這一列的意義所在，不能折行；案件名稱是輔助，太長就切掉；
     取消鈕是動作，永遠要看得到。手機 375px 下就是靠這個分配活下來的。 */
  .otplan {
    display: flex; align-items: center; gap: 8px; margin: 0 0 6px;
    font-size: .78rem; color: var(--violet-ink, var(--violet));
    background: rgba(167, 139, 250, .12); border: 1px solid rgba(167, 139, 250, .3);
    border-radius: 9px; padding: 6px 10px; white-space: nowrap;
  }
  .otplan.hide { display: none; }
  .otplan b { color: var(--head); font-weight: 600; }
  .otplan .case {
    flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
    font-size: .74rem; color: var(--muted);
  }
  .otplan .x {
    flex: none; width: auto; padding: 4px 10px; font-size: .74rem; border-radius: 7px;
    background: transparent; color: var(--sub); border: 1px solid var(--line-strong);
  }
  /* 細線而不是一個有底有框的元件——它只是輔助刻度，不該自成一塊 */
  .bar { height: 3px; border-radius: 2px; background: var(--line); overflow: hidden; }
  .bar.hide { display: none; }
  .bar .fill { height: 100%; background: var(--green); border-radius: 2px; width: 0; transition: width .5s; }
  /* ---- 打卡頁的按鈕走「實心高對比」----
     這一頁有一半的使用場景在工地與戶外：太陽底下，漸層看不出來、光暈等於不存在、
     藥丸形狀的邊界在強光下也糊掉。所以主按鈕改成實心色塊、圓角收到 12px、
     字再大一級並加字距——遠看是一塊顏色，近看才是字，兩種距離都認得出來。
     其他頁（簽核、紀錄、表單）維持原本的比例，那些頁多半在室內或車上看。 */
  .bigbtn {
    width: 100%; text-align: center; padding: 21px 14px;
    font-size: 1.42rem; font-weight: 800; letter-spacing: .06em;
    border-radius: 12px; margin-top: 12px;
  }
  .bigbtn.in { background: var(--btn-in-bg); color: var(--btn-text); box-shadow: var(--glow-green-box); }
  /* 上班鈕底下那個「08:30 制」是**班制**，不是會被記下來的時間。
     原本只寫「08:30」，而按鈕上的一個時間最直覺的讀法就是「按下去會記這個時間」——
     實際記的是當下。加一個「制」字，並且刻意做得比主標小、比它淡，
     讓它讀起來像註記而不是一個值。 */
  .bigbtn.in small, .bigbtn.mv small {
    display: block; font-size: .62em; font-weight: 500; opacity: .75; margin-top: 2px;
  }
  .bigbtn.out { background: var(--btn-out-bg); color: var(--btn-text); box-shadow: var(--glow-orange-box); }
  /* 第三種主按鈕：移動類（外出／回公司／抵達工地）。
     上班時段裡最常按的就是這顆，所以它該站在主位；但它不是「上班」也不是「下班」那種
     一天一次的承諾，用中性藍跟那兩顆分開，按錯的代價一眼就看得出不一樣。 */
  /* 移動類不是實心色塊：它跟「上班／下班」不同量級（一天按好幾次、按錯代價小）。
     粗一點的外框在強光下仍然咬得住邊界，但不會跟主色搶。 */
  .bigbtn.move {
    background: var(--btn-move-bg); color: var(--btn-move-fg);
    border: 2px solid var(--btn-move-line); box-shadow: none;
  }
  .bigbtn small { display: block; font-size: .72rem; font-weight: 500; opacity: .85; margin-top: 3px; }
  #today .src { font-style: normal; font-size: .68rem; color: var(--muted); border: 1px solid var(--line);
    border-radius: 8px; padding: 1px 6px; margin-left: 6px; white-space: nowrap; }
  .alldone { text-align: center; margin-top: 12px; padding: 12px; border-radius: 10px; background: rgba(47, 212, 143, .1); border: 1px solid rgba(47, 212, 143, .3); color: var(--green); font-weight: 700; }
  .moves { margin-top: 9px; }
  .mv-h { font-size: .75rem; color: var(--muted); margin: 8px 0 4px; text-align: left; }
  .mv-row { display: flex; gap: 8px; flex-wrap: wrap; }
  .mv-row button { border: 2px solid var(--line-strong); background: transparent; color: var(--text); }
  /* flex-basis 必須歸零：基礎樣式的 button{width:100%} 會讓每顆的基準寬度都是滿版，
     配上 flex-wrap 就變成一顆一行（原本只有一顆時看不出來，加第二顆才爆出來）。 */
  .mv-row button {
    flex: 1 1 0; min-width: 28%; width: auto;
    background: transparent; color: var(--sub); padding: 10px 6px; font-size: .86rem;
    border: 1px solid var(--line);
  }
  /* 展開清單不是打卡動作，不給框——避免跟旁邊會寫紀錄的按鈕看起來同級 */
  .mv-row button.more { border-color: transparent; color: var(--blue); }
  /* 今日歷程：預設收合，點標題列展開。 */
  .timeline { margin: 2px 0 4px; }
  /* ⚠ 選擇器要指到「資料列」本身，不能寫 .timeline div——
     那會連外層的 .tl-body 一起套上 flex 與框線，整段塌成一列。 */
  .timeline .tl-body > div:not(.tl-more) {
    display: flex; align-items: center; gap: 9px; padding: 6px 0; font-size: .86rem;
  }
  .timeline .tl-body > div + div { border-top: 1px solid var(--line); }

  /* 收合時的那一列：左邊「今日 N 筆」，右邊摘要，最右邊箭頭。
     摘要寫的是「幾點上班 → 最後一筆是什麼」——那是這一段最常被看的兩件事，
     看得到就不必展開。 */
  .tl-h {
    display: flex; align-items: center; gap: 8px; width: 100%;
    padding: 9px 11px; margin: 0; cursor: pointer;
    font: inherit; color: var(--sub); text-align: left;
    background: var(--panel2); border: 1px solid var(--line); border-radius: 9px;
  }
  .tl-h:hover { border-color: var(--line-strong); }
  .tl-h .tl-n { flex: none; font-size: .8rem; color: var(--muted); }
  .tl-h .tl-sum {
    flex: 0 1 auto; min-width: 0; font-size: .82rem; color: var(--head);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-variant-numeric: tabular-nums;
  }
  /* ---- 「可以點」由形狀表達，不是再寫一句字 ----
     原本這裡有一句「（點擊展開）」，跟旁邊的箭頭在講同一件事，
     而一列裡真正有資訊的是「今日 N 筆」與那句摘要。
     改成整列有淡底與邊框——它看起來就是一顆可以按的東西，箭頭補足方向。 */
  .tl-h .tl-chev { flex: none; color: var(--muted); transition: transform .15s; margin-left: auto; }
  .tl-h.open .tl-chev { transform: rotate(90deg); }
  .tl-h.open .tl-sum { color: var(--muted); }
  .timeline b { font-weight: 600; color: var(--head); font-variant-numeric: tabular-nums; }
  .timeline span:last-of-type { color: var(--sub); flex: 1; min-width: 0; }
  .timeline .dot-in, .timeline .dot-move, .timeline .dot-out { font-size: .62rem; flex: none; }
  .timeline .dot-in { color: var(--green); }
  .timeline .dot-move { color: var(--cyan); }
  .timeline .dot-out { color: var(--orange); }
  .timeline .door { font-style: normal; font-size: .68rem; color: var(--muted); margin-left: 6px;
    border: 1px solid var(--line); border-radius: 6px; padding: 1px 5px; }
  .tl-more { font-size: .78rem; padding: 4px 0 6px; }
  .tl-more a { color: var(--blue); }
  .timeline .rv { width: auto; flex: none; padding: 2px 8px; font-size: .72rem; margin-left: 6px; background: rgba(255, 122, 122, .1); color: var(--red); border: 1px solid rgba(255, 122, 122, .35); border-radius: 8px; }
  /* 預設隱藏用 .hide（不要在 #adhocBox 直接寫 display:none——
     JS 用 style.display='' 清行內樣式時會退回 CSS 的 none，輸入框永遠出不來）*/
  #adhocBox { margin-top: 10px; text-align: left; }
  #adhocBox.hide { display: none; }
  #adhocBox label { display: block; font-size: .78rem; color: var(--orange); margin-bottom: 4px; }
  /* 當日臨時地點：今天填過的自填地點，一鍵重用免再打字（個人限定、隔日失效） */
  #adhocRecent { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
  #adhocRecent.hide { display: none; }
  #adhocRecent .lbl { font-size: .72rem; color: var(--muted, #999); }
  #adhocRecent button { width: auto; flex: none; padding: 4px 10px; font-size: .78rem; border-radius: 14px;
    background: rgba(230, 92, 0, .1); color: var(--orange); border: 1px solid rgba(230, 92, 0, .4); }
  /* 上班鈕的班別時間（工地 08:00／外出 08:30，按哪顆就是哪個班） */
  .bigbtn small { display: block; font-size: .72rem; font-weight: 400; opacity: .85; margin-top: 2px; }
  /* 五顆一排、不換行。
     窄螢幕（375px）扣掉間距每格只剩約 62px，四個字剛好放得下——
     所以字級與左右內距都要收，寧可小一點也不要折成兩排。 */
  /* ---- 欄數要跟著字體大小走 ----
     原本寫死 repeat(5, 1fr)。1fr 的最小尺寸預設是 min-content，而每一格都
     white-space: nowrap，所以字一放大格子就撐開——五格硬擠在一行，整列衝出畫面。
     有人把手機系統字體調到 200%，這一排就跑到 499px（畫面只有 360px），
     最右邊那兩顆完全按不到。
     改成 auto-fit + em：em 會跟著字體放大，字大就自動變成三欄、四欄，
     排下來變兩行——醜一點，但每一顆都按得到。 */
  .shortcuts {
    display: grid; gap: 6px; font-size: .72rem;
    grid-template-columns: repeat(auto-fit, minmax(4.6em, 1fr));
  }
  /* ⚠ 一定要用 `>`：不加的話 .shortcuts span 會連按鈕**裡面**那個
     <span class="ico">🏗</span> 一起套上 padding: 9px 2px——圖示因此多了 18px 高，
     每顆鈕變成 80px、整列 80px，而那五顆正是被擠出第一屏的東西。
     這個選擇器原本就寫錯，只是沒有人把它跟「要滑動才看得到」連在一起。 */
  .shortcuts > a, .shortcuts > span {
    display: block; text-align: center; background: var(--panel); border-radius: 12px;
    padding: 9px 2px; text-decoration: none; color: var(--sub); font-size: 1em;
    border: 1px solid var(--line);
    white-space: nowrap;          /* 寧可縮字，也不要「人員／動態」拆成兩行 */
    letter-spacing: -.02em;
    min-width: 0;                 /* 沒有它，長字仍然會把格子撐出去 */
  }
  /* ⚠ emoji 的字框比字大得多：font-size 16.8px 的 🏗 在 line-height:normal 下
     實測佔 42px 高，於是每顆捷徑鈕變成 80px、整列 80px——而那五顆是每天要按的，
     卻因此被擠出第一屏。給它一個明確的行高，字沒有變小，高度少掉 23px。 */
  /* 圖示是行內 SVG（見 app.js 的 ICONS）。給死尺寸而不是跟著字級走：
     這一列的高度就是靠它固定的，emoji 時代那 42px 的行高問題不能回來。 */
  .shortcuts .ico {
    display: block; margin: 0 auto 3px; width: 22px; height: 22px; opacity: .75;
  }
  .shortcuts .ico svg { width: 100%; height: 100%; display: block; }
  /* 再窄一點的機型（iPhone SE 這類 320px）：字再收一階 */
  @media (max-width: 350px) {
    .shortcuts { gap: 4px; font-size: .66rem; }
    .shortcuts > a, .shortcuts > span { padding: 8px 1px; }
  }
  .shortcuts > span { opacity: .4; }
  /* 深淺色切換已移到「其他功能 → 深／淺色模式」，各頁不再各放一顆開關 */
  /* 跳板模式（見 <head>）：只留一個轉圈，其餘打卡頁專屬的東西都不要出現 */
  [data-springboard] #locShortcuts,
  [data-springboard] #locSkip,
  [data-springboard] #locRetryRow,
  [data-springboard] #locStatus { display: none !important; }
  [data-springboard] .loc-btn { font-size: .9rem; }
  .loc-wrap { min-height: 80vh; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px; }
  .loc-ring { width: 156px; height: 156px; border-radius: 50%; display: flex; align-items: center; justify-content: center; position: relative; }
  .loc-ring::before {
    content: ''; position: absolute; inset: 0; border-radius: 50%;
    border: 3px solid var(--line);
    pointer-events: none; /* 動畫圈不可攔截點擊，否則按鈕按不到 */
  }
  .loc-ring.locating::before { border-top-color: var(--cyan); border-right-color: var(--cyan); animation: spin 1s linear infinite; }
  .loc-ring.ok::before { border-color: var(--green); }
  .loc-ring.fail::before { border-color: var(--red); }
  @keyframes spin { to { transform: rotate(360deg); } }
  .loc-btn {
    width: 122px; height: 122px; border-radius: 50%;
    font-size: 1.25rem; font-weight: 700; letter-spacing: 2px;
    background: var(--panel2); border: 1px solid var(--line); color: var(--cyan);
    display: flex; align-items: center; justify-content: center; padding: 0;
    position: relative; z-index: 1;
  }
  .loc-ring.locating .loc-btn { animation: pulse 1.3s ease-in-out infinite; }
  .loc-ring.ok .loc-btn { color: var(--green); }
  .loc-ring.fail .loc-btn { color: var(--red); }
  @keyframes pulse { 50% { transform: scale(.93); } }
  /* 診斷標記：字很小、顏色很淡。它是給回報問題時用的，不該搶走說明文字的注意力。 */
  .loc-status .diag { display: block; font-size: .68rem; opacity: .45; margin-top: 3px; }
  .loc-status { color: var(--sub); font-size: .95rem; text-align: center; padding: 0 24px; line-height: 1.6; }
  .loc-skip { color: var(--blue); font-size: .85rem; }
  /* 定位成功轉場：打勾放大淡出 → 主頁淡入 */
  .loc-wrap.exit { animation: locExit .22s ease forwards; }
  @keyframes locExit { to { transform: scale(1.7); opacity: 0; } }
  #main.fadein { animation: mainIn .26s ease; }
  @keyframes mainIn { from { opacity: 0; transform: translateY(12px); } }

  /* 長按按鈕說明：頂部浮出卡片（放手即消失），pointer-events:none 不擋操作 */
  #pressTip {
    position: fixed; left: 14px; right: 14px; top: 14px; z-index: 90; display: none;
    background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
    padding: 12px 14px; box-shadow: 0 8px 24px rgba(0, 0, 0, .45);
    pointer-events: none; font-size: .88rem; line-height: 1.6; color: var(--sub);
    animation: fadeIn .15s;
  }
  #pressTip b { color: var(--head); display: block; margin-bottom: 2px; }
  [data-pt] { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }

