/* 由 GAS 版 mod_styles.html 移植；配色與版面維持一致 */
/*
   * 配色沿用既有營運中心的視覺：米色底、深藍頂列、橘色重點。
   * 刻意只做淺色一套——這是內部營運工具，與既有系統並排使用時
   * 顏色跟著使用者的系統偏好變反而不一致。
   */
  :root {
    --bg: #f1eee4;
    --surface: #ffffff;
    --surface-alt: #faf8f2;
    --topbar: #1b2b33;
    --dark-card: #22343c;
    --accent: #e8672c;
    --accent-hover: #cf551c;
    --ink: #17272e;
    --muted: #6d7c83;
    --line: #e4dfd2;
    --line-strong: #d3ccbb;
    --ok: #2f9e6a;
    --danger: #d64545;
    --radius: 14px;
  }

  * { box-sizing: border-box; }

  html, body { height: 100%; }
/*
   關掉雙指縮放。

   viewport 的 user-scalable=no 在 iOS Safari 的分頁裡會被忽略——Apple 為了
   無障礙刻意不理會它，只有從主畫面啟動的獨立模式才生效。所以要靠 touch-action
   才擋得住：允許單指平移，但不接受縮放手勢。

   為什麼要關：版面本來就是為手機設計的，不需要放大；而誤觸縮放之後
   畫面會卡在放大平移的狀態，頂列被切掉、看起來像壞掉，同仁不會自己縮回去。

   代價是視力不佳的使用者無法放大。系統字級設定仍然有效（我們沒有寫死
   px 以外的縮放行為），那是比較好的放大方式。
*/
html {
  touch-action: pan-x pan-y;
  -webkit-text-size-adjust: 100%;
}


  body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans TC",
                 "PingFang TC", "Microsoft JhengHei", sans-serif;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
  }

  .hidden { display: none !important; }

  /* ===== 頂列 ===== */

  /* 頂列與分頁列一起固定在畫面上方，捲動時不會消失。
     兩者包在同一個容器裡 sticky，避免分開計算偏移量——頂列在手機上
     會因為隱藏單位名稱而變矮，寫死的偏移量就會露出縫隙。 */
  .sticky-head {
    position: sticky;
    top: 0;
    z-index: 50;
  }

  /*
     頂列要讓開手機的狀態列。

     index.html 用了 viewport-fit=cover 加上 black-translucent，
     所以從主畫面啟動時網頁會延伸到瀏海／動態島底下——不補這段的話，
     頂列的文字與「設定」按鈕會被狀態列蓋住而按不到（實機回報過）。

     底部的分頁列早就處理了 safe-area，頂部一直漏掉。
  */
  .topbar {
    background: var(--topbar);
    color: #fff;
    padding: 14px 0;
    padding-top: calc(14px + env(safe-area-inset-top, 0px));
  }
  .topbar-inner {
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 20px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
  }
  .brand { display: flex; align-items: center; gap: 11px; min-width: 0; }
  /* 公司 logo。球體本身是淺灰白，深色頂列上直接放就有對比；
     淺色登入頁上靠中央黑紅的 KH 標誌辨識，不另外加底色。 */
  .brand-logo {
    width: 34px; height: 34px;
    flex: none;
    object-fit: contain;
    display: block;
  }
  .brand-name {
    font-size: 17px; font-weight: 700; letter-spacing: .3px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }

  .topbar-right { display: flex; align-items: center; gap: 10px; }
  .who { text-align: right; line-height: 1.35; min-width: 0; }
  .who-name { font-size: 14px; font-weight: 700; }
  .who-meta { font-size: 12px; color: #a8b6bc; }

  .chip {
    padding: 7px 15px;
    border: 1px solid rgba(255,255,255,.28);
    border-radius: 8px;
    background: transparent;
    color: #fff;
    font-size: 13.5px; font-weight: 600; font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
    transition: background .15s;
  }
  .chip:hover { background: rgba(255,255,255,.12); }
  .chip-active { background: #fff; color: var(--topbar); border-color: #fff; }

  /* ===== 身份切換 =====
     一個人同時管兩間店時才出現。做在「設定」左邊而不是收進設定裡：
     切錯身份看到的是另一間店的數字，那是每次進系統都要先確認一眼的東西，
     藏兩層底下等於沒有。 */
  .ident-wrap { position: relative; }
  .chip-ident {
    display: inline-flex; align-items: center; gap: 6px;
    max-width: 210px;
  }
  .ident-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .ident-caret { font-size: 10px; opacity: .75; flex: none; }
  /* 不是本職時整顆變成強調色——切過去之後畫面上若沒有痕跡，
     人會忘記自己現在戴的是哪一頂帽子。 */
  .chip-ident.is-alt {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
  }
  .chip-ident.is-alt:hover { background: var(--accent-hover); }

  .ident-menu {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    min-width: 260px;
    max-width: 84vw;
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: 10px;
    box-shadow: 0 12px 32px rgba(0,0,0,.22);
    padding: 6px;
    z-index: 90;
  }
  .ident-wrap.open .ident-menu { display: block; }

  .ident-menu-head {
    padding: 8px 10px 6px;
    font-size: 11.5px; font-weight: 700; letter-spacing: .06em;
    color: var(--muted);
  }
  .ident-item {
    display: block; width: 100%;
    padding: 9px 10px;
    border: 0; border-radius: 8px;
    background: transparent;
    text-align: left;
    font-family: inherit; font-size: 14px;
    color: var(--ink);
    cursor: pointer;
  }
  .ident-item:hover { background: var(--surface-alt); }
  .ident-item.on { background: var(--topbar); color: #fff; }
  .ident-item-sub { font-size: 12px; opacity: .7; margin-top: 2px; }
  .ident-item[disabled] { opacity: .6; cursor: default; }

  /* ===== 版面 ===== */

  .shell { max-width: 1180px; margin: 0 auto; padding: 18px 20px 60px; }

  /* 分頁列的底色要不透明，否則捲動時內容會從底下透出來 */
  .tabs-bar {
    background: var(--bg);
    border-bottom: 1px solid var(--line);
    padding: 12px 20px;
  }
  .tabs-bar .tabs { max-width: 1140px; margin: 0 auto; }

  /* ===== 分頁列 ===== */

  /* 群組化之後只剩四項，不再需要橫向捲——而且 overflow 會把展開的選單裁掉 */
  .tabs {
    display: flex;
    gap: 4px;
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 6px;
    overflow: visible;
  }

  .tab {
    padding: 9px 16px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--ink);
    font-size: 14.5px; font-weight: 600; font-family: inherit;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
    transition: background .15s, color .15s;
  }
  .tab:hover { background: var(--surface-alt); }
  .tab-active { background: var(--topbar); color: #fff; }
  .tab-active:hover { background: var(--topbar); }

  /* ===== 麵包屑與標題 ===== */

  .crumb {
    margin: 20px 0 0;
    font-size: 13px;
    color: var(--muted);
  }
  .crumb span + span::before { content: '›'; margin: 0 9px; color: var(--line-strong); }

  .eyebrow {
    margin: 22px 0 6px;
    font-size: 12.5px; font-weight: 700;
    letter-spacing: .16em;
    color: var(--accent);
    text-transform: uppercase;
  }
  h1.page-title {
    margin: 0 0 10px;
    font-size: 40px; font-weight: 800;
    letter-spacing: -.01em;
    line-height: 1.15;
  }
  .page-lead { margin: 0 0 26px; font-size: 15px; color: var(--muted); max-width: 62ch; }

  @media (max-width: 640px) {
    h1.page-title { font-size: 29px; }
    .who-meta { display: none; }
    /* 手機頂列只剩下 logo、名字、身份、設定，身份按鈕要讓出空間 */
    .chip-ident { max-width: 120px; padding: 7px 10px; }
    .ident-menu { min-width: 220px; }
    /* 手機螢幕矮，固定區塊要盡量薄，否則內容可視範圍被吃掉太多 */
    .topbar {
      padding: 9px 0;
      padding-top: calc(9px + env(safe-area-inset-top, 0px));
    }
    .topbar-inner { padding: 0 14px; }

    /*
       分頁列移到螢幕底部——單手拿手機時拇指構得到的是下緣，不是上緣。
       .tabs-bar 雖然是 sticky 容器的子元素，position:fixed 仍以視窗為基準
       （祖先沒有 transform／filter，不會產生新的包含區塊）。
       它脫離文件流之後，上方的 sticky-head 就只剩頂列。
    */
    .tabs-bar {
      position: fixed;
      left: 0; right: 0; bottom: 0;
      z-index: 60;
      /* 白底讓它與米色頁面分開，看起來像獨立的導覽列而不是頁面的一部分 */
      background: var(--surface);
      box-shadow: 0 -2px 12px rgba(23, 39, 46, .06);
      border-top: 1px solid var(--line);
      border-bottom: 0;
      /* iPhone 的home indicator 會蓋住最後幾像素 */
      padding: 6px 8px calc(6px + env(safe-area-inset-bottom, 0px));
    }
    .tabs-bar .tabs {
      border: 0;
      border-radius: 0;
      padding: 0;
      background: transparent;
      gap: 2px;
    }

    /*
       底部導覽平均分配寬度。

       .tabs 的直接子元素現在是 .tab-group 包裝（群組）與 .tab（首頁）兩種，
       只給 .tab 設 flex 的話，首頁會把剩餘空間全部吃掉、其他項目被擠到右邊。
       兩種都要設，而且群組裡的按鈕要撐滿群組。
    */
    .tabs > .tab,
    .tabs > .tab-group { flex: 1 1 0; min-width: 0; }

    /*
       期間限定的那幾個在手機上收成「檔期活動」一顆。

       底部那一排寬度就那麼多，新機預購已經佔一格，再加一個競賽就擠到
       看不清楚字。桌機沒有這個問題，維持各自一顆比多一層點擊好。
       用 CSS 切換而不是 JS 判斷寬度：那樣不必處理旋轉螢幕與拖曳視窗。
    */
    .only-wide { display: none !important; }
    /*
       特異性比底下那條 .only-narrow 高，所以不管兩條規則誰寫在前面都成立。
       只靠順序的話，哪天有人搬動這個區塊，手機上那顆按鈕就會消失。
    */
    .tabs > .tab-group.only-narrow { display: flex !important; }
    /* 手機才有的獨立按鈕（小嫻、或「更多」裡只剩的那一個）也一樣 */
    .tabs > .tab.only-narrow { display: flex !important; }
    .tab-group > .tab-parent { width: 100%; }

    /* 底部導覽只有文字辨識度差，改成圖示在上、文字在下 */
    .tab {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 3px;
      padding: 5px 6px;
      font-size: 11px;
      line-height: 1.2;
    }
    /* 群組按鈕在手機上也要走同一套直向排列，不能沿用桌機的橫向 */
    .tab-parent {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 3px;
    }
    .tab-parent > span:not(.tab-caret) {
      max-width: 100%;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .tab::before {
      content: attr(data-icon);
      font-size: 19px;
      line-height: 1;
    }
    .tab.tab-img::before { content: none; }
    .tab .tab-icon-wrap { display: block; font-size: 19px; line-height: 1; height: 19px; }
    .tab .tab-icon-wrap .tab-icon-img { width: 24px; height: 24px; margin: -2.5px 0; }
    /* 底部導覽的選取狀態用顏色，不用深色色塊——那在下緣會顯得很重 */
    .tab-active, .tab-active:hover { background: transparent; color: var(--accent); }
    .tab:hover { background: transparent; }

    /* 內容要留出底部導覽的高度，否則最後一列會被蓋住 */
    .shell { padding: 14px 14px calc(84px + env(safe-area-inset-bottom, 0px)); }
  }

  /* 桌機不需要那顆收合的按鈕——兩個入口各自一顆看得更清楚 */
  .only-narrow { display: none !important; }

  /* ===== 卡片 ===== */

  .card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 22px 24px;
  }
  .card + .card { margin-top: 16px; }

  /* 公告內容：長網址不能把整頁撐成可以左右拖 */
  .ann-body {
    margin-top: 10px; white-space: pre-wrap; line-height: 1.7;
    overflow-wrap: anywhere; word-break: break-word; min-width: 0;
  }
  .ann-link { color: var(--accent); text-decoration: underline; overflow-wrap: anywhere; }
  .link-preview { margin: 6px 0 10px; }
  .link-preview-card {
    display: flex; gap: 12px; align-items: stretch;
    border: 1px solid var(--line); border-radius: 10px; overflow: hidden;
    background: var(--surface-alt); color: inherit; text-decoration: none;
    max-width: 560px;
  }
  .link-preview-card:hover { border-color: var(--line-strong); }
  .link-preview-img { width: 96px; min-width: 96px; object-fit: cover; background: #eee; }
  .link-preview-text { padding: 10px 12px; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
  .link-preview-site { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .02em; }
  .link-preview-title { font-weight: 700; font-size: 14.5px; line-height: 1.4; }
  .link-preview-desc {
    font-size: 13px; color: var(--muted); line-height: 1.45;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  }
  .card-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 16px; flex-wrap: wrap;
  }
  .card h2 { margin: 0 0 3px; font-size: 17px; font-weight: 700; }
  /*
     .hint 是全站通用的次要說明，不該只在卡片裡才有樣式。

     原本只寫了 .card .hint，所以對話框、篩選列那些地方的 hint
     會吃到瀏覽器預設的 16px——比旁邊的正文還大，看起來像標題。
     實際被回報過（行程編輯的參加名單說明「太大」）。
  */
  .hint { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--muted); }

  .card-dark {
    background: var(--dark-card);
    border-color: var(--dark-card);
    color: #fff;
  }
  .card-dark h2 { color: #fff; }
  .card-dark .hint { color: #9fb0b7; }

  /* ===== 按鈕 ===== */

  .btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 9px;
    padding: 12px 20px;
    border: 1px solid var(--line-strong);
    border-radius: 10px;
    background: var(--surface);
    color: var(--ink);
    font-size: 15px; font-weight: 600; font-family: inherit;
    text-decoration: none; cursor: pointer;
    transition: background .15s, border-color .15s, opacity .15s;
    -webkit-tap-highlight-color: transparent;
  }
  .btn:hover { border-color: var(--muted); }

  /*
     停用中的按鈕要看得出來。

     原本只寫了 aria-disabled，但程式裡一律是設 button.disabled——兩者選不到
     同一個東西，結果是按下去按鈕確實鎖住了、外觀卻一點變化都沒有。
     使用者以為沒按到就一直按（簽核畫面實際被回報過）。
  */
  .btn:disabled,
  .btn[aria-disabled="true"] { opacity: .55; cursor: default; }
  .btn:disabled:hover { border-color: var(--line-strong); }
  .btn-primary:disabled:hover { background: var(--accent); border-color: var(--accent); }
  .btn-danger:disabled:hover { border-color: var(--line-strong); }

  /* 深色按鈕上的轉圈要用白色，不然幾乎看不見 */
  .btn-primary .spinner { border-color: rgba(255, 255, 255, .4); border-top-color: #fff; }
  .btn-danger .spinner { border-top-color: var(--danger); }
  /* 按鈕裡的轉圈比獨立使用時小一點，才不會把按鈕撐高 */
  .btn .spinner { width: 14px; height: 14px; }
  .btn-primary {
    background: var(--accent); border-color: var(--accent); color: #fff;
  }
  .btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
  .btn-block { display: flex; width: 100%; }
  .btn-block + .btn-block { margin-top: 12px; }
  .btn-sm { padding: 7px 14px; font-size: 13px; font-weight: 600; }
  .btn-danger { color: var(--danger); }
  .btn-danger:hover { border-color: var(--danger); }

  /* ===== 訊息 ===== */

  .msg {
    padding: 12px 15px;
    border-radius: 10px;
    border: 1px solid transparent;
    font-size: 13.5px;
    margin-bottom: 16px;
    white-space: pre-wrap;
  }
  .msg-error { background: #fdecec; border-color: #f4c9c9; color: #a62c2c; }
  .msg-ok    { background: #e8f6ee; border-color: #bfe4d0; color: #1d7a4f; }
  .msg-info  { background: var(--surface-alt); border-color: var(--line); color: var(--muted); }
  .msg-warn  { background: #fdf3e3; border-color: #f0dcb4; color: #96631a; }

  /* ===== 其他元件 ===== */

  .spinner {
    width: 16px; height: 16px;
    border: 2px solid var(--line-strong);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: spin .7s linear infinite;
    flex: none;
  }
  @keyframes spin { to { transform: rotate(360deg); } }

  .loading-row {
    display: flex; align-items: center; gap: 12px;
    color: var(--muted); font-size: 14px;
  }

  .kv {
    display: grid;
    grid-template-columns: 96px 1fr;
    gap: 10px 16px;
    font-size: 14px;
    margin: 0;
  }
  .kv dt { color: var(--muted); }
  .kv dd { margin: 0; font-weight: 600; }

  .device {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px;
    padding: 14px 0;
    border-top: 1px solid var(--line);
    font-size: 14px;
  }
  .device-name { font-weight: 700; }
  .device-meta { color: var(--muted); font-size: 12.5px; }

  .badge {
    display: inline-block;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 11.5px; font-weight: 700;
  }
  .badge-off { background: #eeeae0; color: var(--muted); }

  /* ===== 載入進度 ===== */

  .progress {
    padding: 18px 20px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
  }
  .progress-row { display: flex; align-items: center; gap: 12px; }
  .progress-text { font-size: 14px; color: var(--ink); flex: 1; }
  .progress-time {
    font-size: 13px; color: var(--muted);
    font-variant-numeric: tabular-nums;
  }
  .progress-hint { font-size: 12.5px; color: var(--muted); margin-top: 8px; }

  /* ===== 首頁功能格 ===== */

  /* 電腦一排六個、手機一排兩個。用 auto-fit 會依容器寬度自己決定數量，
     但那樣中間尺寸的螢幕會跑出三個、五個這種不規則的排法，
     所以直接指定欄數，只在斷點切換。 */
  .home-grid {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 14px;
  }
  @media (max-width: 1000px) { .home-grid { grid-template-columns: repeat(3, 1fr); } }
  @media (max-width: 640px)  { .home-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; } }

  .home-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 26px 12px;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--ink);
    font-family: inherit;
    text-decoration: none;
    cursor: pointer;
    transition: border-color .15s, transform .12s, box-shadow .15s;
    -webkit-tap-highlight-color: transparent;
  }
  .home-tile:hover {
    border-color: var(--accent);
    transform: translateY(-2px);
    box-shadow: 0 6px 18px rgba(23, 39, 46, .08);
  }
  .home-tile:active { transform: translateY(0); }
  .home-icon { font-size: 30px; line-height: 1; display: block; }
  /* 圖片圖示：跟 emoji 一樣大，桌機分頁列沒有圖示就不畫 */
  /* 稍微比 emoji 大一點：logo 是細線條的圖，同樣尺寸看起來會比色塊狀的 emoji 小 */
  .tab-icon-img { width: 1.25em; height: 1.25em; object-fit: contain; vertical-align: -0.2em; border-radius: 4px; }
  .home-icon .tab-icon-img { width: 1.35em; height: 1.35em; margin: -0.18em 0; }
  .tab .tab-icon-wrap { display: none; }
  .home-label { font-size: 14.5px; font-weight: 700; text-align: center; }

  .home-tile.is-disabled {
    opacity: .55;
    cursor: not-allowed;
    background: var(--surface-alt);
  }
  .home-tile.is-disabled:hover {
    border-color: var(--line);
    transform: none;
    box-shadow: none;
  }
  .home-note {
    font-size: 11.5px;
    color: var(--muted);
    text-align: center;
    margin-top: -4px;
  }

  @media (max-width: 640px) {
    .home-tile { padding: 22px 10px; }
    .home-icon { font-size: 26px; }
    .home-label { font-size: 13.5px; }
  }

  /* 點標誌回首頁 */
  #view-app .brand { cursor: pointer; }

  /* 篩選用的小晶片 */
  .chip-row { display: flex; flex-wrap: wrap; gap: 6px; }
  .filter-chip {
    padding: 6px 12px;
    border: 1px solid var(--line-strong);
    border-radius: 999px;
    background: var(--surface);
    color: var(--muted);
    font-size: 13px; font-weight: 600; font-family: inherit;
    cursor: pointer;
  }
  .filter-chip.on { background: var(--topbar); border-color: var(--topbar); color: #fff; }
  /* 第三種狀態要一眼分得出來，不能只是同一個顏色的深淺 */
  .filter-chip.on.alt { background: #8a5a10; border-color: #8a5a10; color: #fff; }

  /* 排序按鈕的箭頭固定佔一格寬度，沒選中時是空的——直接把箭頭接在文字後面，
     按鈕會在點下去的瞬間變寬，把後面的選項擠到下一行，整列跳一下 */
  .sort-chip { display: inline-flex; align-items: center; }
  .chip-mark {
    display: inline-block;
    width: 1em;
    text-align: center;
    font-size: 12px;
  }

  /* 可排序的表頭 */
  th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
  th.sortable:hover { color: var(--ink); }

  /* 表格裡當按鈕用的姓名欄 */
  .link-cell {
    border: 0; background: none; padding: 0;
    font: inherit; font-weight: 600;
    color: var(--ink); cursor: pointer; text-align: left;
  }
  .link-cell:hover { color: var(--accent); }

  /* 展開的明細列 */
  tr.detail-row td { background: var(--surface-alt); padding: 0; }
  .detail-box { padding: 16px 14px 20px; }
  .detail-title {
    font-size: 12px; font-weight: 700; color: var(--accent);
    letter-spacing: .08em; margin: 16px 0 6px;
  }
  .detail-box > .detail-title:first-child { margin-top: 0; }

  /* 安裝步驟 */
  ol.steps {
    margin: 16px 0 0;
    padding-left: 22px;
    font-size: 14px;
    line-height: 1.9;
  }
  ol.steps li::marker { color: var(--accent); font-weight: 700; }
  ol.steps .steps-warn { color: var(--danger); list-style: none; margin-left: -22px; margin-top: 8px; }

  /* 尚未開發的分頁 */
  .placeholder {
    border: 1px dashed var(--line-strong);
    border-radius: var(--radius);
    background: var(--surface-alt);
    padding: 40px 26px;
    text-align: center;
    color: var(--muted);
    font-size: 14px;
  }
  .placeholder strong { display: block; color: var(--ink); font-size: 16px; margin-bottom: 6px; }

  /* ===== 戰況：篩選列與數據 ===== */

  .filters {
    display: flex;
    align-items: flex-end;
    gap: 14px;
    flex-wrap: wrap;
    margin-bottom: 18px;
  }
  .field { display: flex; flex-direction: column; gap: 5px; }
  .field label { font-size: 12px; font-weight: 600; color: var(--muted); }
  /* textarea 原本完全沒樣式，用的是瀏覽器預設——外觀不一致，
     字級也小到會觸發 iOS 的自動放大 */
  /*
     核取方塊與單選鈕不吃這一組樣式。

     它們也是 <input>，套上 width:100% 與 min-height:40px 之後會變成
     一個 40px 的巨大圓圈，旁邊的文字被擠到一個字一行（實際發生過）。
     用 :not() 排除，比在每個地方加類別可靠。
  */
  .field select,
  .field input:not([type="checkbox"]):not([type="radio"]),
  .field textarea {
    width: 100%;
    max-width: 100%;
    padding: 9px 12px;
    border: 1px solid var(--line-strong);
    border-radius: 9px;
    background: var(--surface);
    color: var(--ink);
    font-size: 14px; font-family: inherit;
    line-height: 1.5;
    min-height: 40px;
  }
  .field textarea { resize: vertical; }

  /*
     iOS Safari 的日期／時間輸入框不吃 width: 100%。

     它們帶著 -webkit-appearance 的原生外觀，那個外觀有自己的固有寬度，
     min-width: 0 也壓不掉，於是在窄螢幕上直接撐破容器。桌機 Chrome 沒有
     這個行為，所以只在實機上才看得到。

     拿掉原生外觀才會回到一般的盒模型。點擊時仍然會叫出 iOS 的原生
     日曆與時間滾輪——被關掉的只有外框的樣式，不是選擇器本身。
  */
  input[type="date"], input[type="time"], input[type="datetime-local"] {
    -webkit-appearance: none;
    appearance: none;
    display: block;
    width: 100%;
    min-width: 0;
    max-width: 100%;
  }

  /* 拿掉原生外觀後，iOS 會讓內容靠上，要自己把它擺回垂直置中 */
  input[type="date"]::-webkit-date-and-time-value,
  input[type="time"]::-webkit-date-and-time-value {
    text-align: left;
    min-height: 22px;
  }

  /* 日曆圖示在 iOS 上會被 appearance:none 連帶影響，明確保留 */
  input[type="date"]::-webkit-calendar-picker-indicator,
  input[type="time"]::-webkit-calendar-picker-indicator {
    opacity: .55;
  }
  .field select:focus, .field input:focus, .field textarea:focus {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
  }

  .segmented { display: flex; gap: 3px; background: var(--surface); border: 1px solid var(--line-strong); border-radius: 9px; padding: 3px; }
  .segmented button {
    padding: 7px 15px; border: 0; border-radius: 7px;
    background: transparent; color: var(--ink);
    font-size: 13.5px; font-weight: 600; font-family: inherit; cursor: pointer;
  }
  .segmented button.on { background: var(--topbar); color: #fff; }

  /* 區塊切換用的 segmented 項目較多，手機上橫向捲而不是換行——
     換行會讓它變成兩三列，把畫面上緣佔掉一大塊 */
  .segmented.seg-wrap { overflow-x: auto; scrollbar-width: none; }
  .segmented.seg-wrap::-webkit-scrollbar { display: none; }
  .segmented.seg-wrap button { flex: 0 0 auto; white-space: nowrap; }

  .stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 14px;
    margin-bottom: 18px;
  }
  .stat {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 18px 20px;
  }
  .stat-label { font-size: 12.5px; color: var(--muted); font-weight: 600; }
  .stat-value { font-size: 30px; font-weight: 800; letter-spacing: -.02em; margin-top: 3px; line-height: 1.15; }
  .stat-value .unit { font-size: 14px; font-weight: 700; color: var(--muted); margin-right: 3px; }
  /* 值是一段文字而不是數字（例如「2 小時 30 分」），30px 會撐破卡片 */
  .stat-value.stat-text { font-size: 21px; }
  .stat-sub { font-size: 12.5px; color: var(--muted); margin-top: 4px; }
  .stat-hero { background: var(--dark-card); border-color: var(--dark-card); color: #fff; }
  .stat-hero .stat-label, .stat-hero .stat-sub { color: #9fb0b7; }
  .neg { color: var(--danger); }

  .table-wrap { overflow-x: auto; margin: 0 -4px; }
  table.data { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 460px; }
  table.data th, table.data td { padding: 10px 12px; text-align: right; white-space: nowrap; }
  table.data th:first-child, table.data td:first-child { text-align: left; white-space: normal; min-width: 140px; }
  table.data thead th {
    font-size: 12px; color: var(--muted); font-weight: 700;
    border-bottom: 1px solid var(--line-strong);
  }
  /*
     可點的表頭。使用者回饋「點上方按鈕排序不直覺」——表頭就在資料正上方，
     點它才是預期行為。排序方向用 ↕ ↓ ↑ 標在文字後面。
  */
  table.data th.sortable {
    cursor: pointer; user-select: none; -webkit-user-select: none;
  }
  table.data th.sortable:hover,
  table.data th.sortable:focus-visible { color: var(--text); }
  table.data th.sort-active { color: var(--text); }

  table.data tbody tr + tr td { border-top: 1px solid var(--line); }
  table.data tbody tr:hover { background: var(--surface-alt); }
  .num { font-variant-numeric: tabular-nums; }
  td.strong { font-weight: 700; }
  /* 在名單裡標出自己那一列 */
  tr.row-total td {
    background: var(--surface-alt);
    border-top: 2px solid var(--line-strong);
  }
  /* 離職的列淡化，但仍看得清楚——完全隱藏會讓人以為資料不見了 */
  tr.is-left td { color: var(--muted); }
  tr.is-left .link-cell { color: var(--muted); }
  tr.row-self td { background: #fdf3e3; }
  tr.row-self td:first-child { font-weight: 700; box-shadow: inset 3px 0 0 var(--accent); }

  /* 查詢中：內容變淡但留在原地，頂端跑一條進度條。
     整塊清空再重畫會讓畫面跳動，反而更像壞掉。 */
  .is-loading { opacity: .45; pointer-events: none; transition: opacity .15s; }

  .loading-bar {
    height: 3px;
    border-radius: 3px;
    background: var(--line);
    overflow: hidden;
    margin-bottom: 14px;
    position: relative;
  }
  .loading-bar::after {
    content: '';
    position: absolute;
    inset: 0;
    width: 40%;
    background: var(--accent);
    border-radius: 3px;
    animation: slide 1s ease-in-out infinite;
  }
  @keyframes slide {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(250%); }
  }

  /* 門市選擇對話框 */
  .picker-actions {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; margin-bottom: 12px;
  }
  .picker-count { font-size: 13.5px; font-weight: 600; color: var(--muted); }

  .picker-list {
    max-height: 46vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--surface);
  }
  /* 部門標題：本身就是「整組切換」的按鈕，用底色與縮排跟門市列分開 */
  .picker-group {
    display: flex; align-items: center; gap: 10px;
    width: 100%;
    padding: 10px 14px;
    border: 0;
    border-bottom: 1px solid var(--line);
    background: var(--surface-alt);
    color: var(--ink);
    font-size: 13.5px; font-family: inherit;
    text-align: left;
    cursor: pointer;
    position: sticky; top: 0; z-index: 1;
  }
  .picker-group:hover { background: #f1eee4; }
  .picker-group-name { font-weight: 700; flex: 1; }
  .picker-group-count { color: var(--muted); font-size: 12.5px; font-variant-numeric: tabular-nums; }
  /* 全選才填滿；部分選取顯示為半選狀態 */
  .picker-group.on .picker-check { background: var(--accent); border-color: var(--accent); }

  .picker-item {
    display: flex; align-items: center; gap: 10px;
    width: 100%;
    padding: 11px 14px 11px 30px;
    border: 0;
    border-bottom: 1px solid var(--line);
    background: transparent;
    color: var(--ink);
    font-size: 14px; font-family: inherit;
    text-align: left;
    cursor: pointer;
  }
  .picker-item:last-child { border-bottom: 0; }
  .picker-item:hover { background: var(--surface-alt); }
  .picker-item.on { font-weight: 700; }
  .picker-check {
    width: 20px; height: 20px;
    flex: none;
    display: flex; align-items: center; justify-content: center;
    border: 1px solid var(--line-strong);
    border-radius: 5px;
    font-size: 13px; line-height: 1;
    color: #fff;
  }
  .picker-item.on .picker-check { background: var(--accent); border-color: var(--accent); }

  /* ===== 設定對話框 ===== */

  /*
   * 用 position:fixed 覆蓋整個檢視區。開啟時同時鎖住 body 捲動，
   * 否則背景內容會跟著滑動，在手機上會很錯亂。
   */
  .modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: rgba(18, 30, 36, .55);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 32px 16px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    animation: modal-fade .15s ease-out;
  }
  @keyframes modal-fade { from { opacity: 0; } }

  .modal {
    width: 100%;
    max-width: 540px;
    background: var(--bg);
    border-radius: 16px;
    overflow: hidden;
    box-shadow: 0 26px 64px rgba(0, 0, 0, .34);
    animation: modal-rise .2s cubic-bezier(.2, .8, .3, 1);
  }
  @keyframes modal-rise { from { transform: translateY(14px); opacity: 0; } }

  .modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 17px 20px;
    background: var(--topbar);
    color: #fff;
  }
  .modal-title { font-size: 16.5px; font-weight: 700; }
  .modal-sub { font-size: 12.5px; color: #a8b6bc; margin-top: 1px; }

  .modal-close {
    width: 32px; height: 32px;
    flex: none;
    display: flex; align-items: center; justify-content: center;
    border: 1px solid rgba(255,255,255,.28);
    border-radius: 8px;
    background: transparent;
    color: #fff;
    font-size: 19px; line-height: 1; font-family: inherit;
    cursor: pointer;
    transition: background .15s;
  }
  .modal-close:hover { background: rgba(255,255,255,.14); }

  .modal-body { padding: 18px; }
  .modal-body .card { border-color: var(--line); }

  body.modal-open, body.reauth-open { overflow: hidden; }

  /* Session 過期時覆蓋在當前功能上，保留背景裡已填的內容。 */
  .reauth-backdrop {
    position: fixed;
    inset: 0;
    z-index: 220;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(18, 30, 36, .72);
    backdrop-filter: blur(3px);
  }
  .reauth-card {
    width: 100%;
    max-width: 390px;
    padding: 28px 24px 20px;
    border-radius: 18px;
    background: var(--bg);
    box-shadow: 0 26px 70px rgba(0, 0, 0, .38);
    text-align: center;
    animation: modal-rise .2s cubic-bezier(.2, .8, .3, 1);
  }
  .reauth-card .brand-logo { margin: 0 auto 10px; }
  .reauth-card h2 { margin: 0 0 8px; }
  .reauth-card .hint { margin: 0 0 18px; line-height: 1.65; }
  .reauth-card .msg { margin: 0 0 14px; text-align: left; }
  .reauth-cancel { margin-top: 14px; }

  @media (max-width: 640px) {
    .modal-backdrop { padding: 0; }
    .modal { max-width: none; min-height: 100%; border-radius: 0; }

    /*
       滿版的對話框同樣會頂到狀態列底下，關閉鈕就按不到了。
       補在標題列上，讓標題與關閉鈕整條往下移。
    */
    .modal-head {
      padding-top: calc(17px + env(safe-area-inset-top, 0px));
    }

    /* 底部的操作按鈕也要讓開 home indicator */
    .modal-body {
      padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px));
    }
  }

  /* ===== 登入頁 ===== */

  /* 登入頁沒有頂列，上緣要自己讓開狀態列 */
  .login-wrap {
    max-width: 430px;
    margin: 0 auto;
    padding: calc(56px + env(safe-area-inset-top, 0px)) 20px
             calc(40px + env(safe-area-inset-bottom, 0px));
  }
  .login-brand { text-align: center; margin-bottom: 26px; }
  .login-brand .brand-logo { width: 52px; height: 52px; margin: 0 auto 14px; }
  .login-brand h1 { margin: 0 0 4px; font-size: 23px; font-weight: 800; }
  .login-brand p { margin: 0; font-size: 13px; color: var(--muted); letter-spacing: .06em; }

  .divider {
    display: flex; align-items: center; gap: 12px;
    margin: 18px 0; color: var(--muted); font-size: 12.5px;
  }
  .divider::before, .divider::after {
    content: ''; flex: 1; height: 1px; background: var(--line);
  }

/* ===== 學習護照 ===== */

.section-label {
  margin: 20px 0 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .08em;
  color: var(--muted);
  text-transform: uppercase;
}
.section-label:first-child { margin-top: 4px; }

/*
 * 營業條款認證的考卷。
 *
 * 一題一塊，塊與塊之間看得出界線——條款題目通常很長，沒有分塊的話
 * 在手機上會變成一整片文字，讀的人分不出選項屬於哪一題。
 */
.cert-q {
  margin-top: 14px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-alt);
}
.cert-q .picker-list { background: var(--surface); }

/* 簽核意見的標題。沒有標題的話那一格看起來像是選填的備註 */
.apv-comment-label {
  display: block;
  margin-bottom: 4px;
  font-size: 12.5px; font-weight: 700;
  color: var(--muted);
}

/* 專案比對：同單品項與門號／IMEI */
/*
   專案銷售明細的欄寬。

   這張表大多是文字欄，預設的「靠右＋不換行」會把多出來的寬度平均塞給
   每一欄，門市與業務別中間就空出一大段。改成：文字欄靠左、寬度只夠內容，
   多出來的寬度全部給「實際賣出」——它是唯一會換行的那一欄，
   品項名稱可以很長（折抵品項會把兩個商品名接在一起）。
*/
/* 選擇器要寫成 table.data.ps-table：通用規則是 table.data td（0,1,2），
   只寫 .ps-table td（0,1,1）會輸給它，等於沒寫 */
table.data.ps-table th, table.data.ps-table td { text-align: left; width: 1%; white-space: nowrap; }
table.data.ps-table th:nth-child(5), table.data.ps-table td:nth-child(5),
table.data.ps-table th:nth-child(10), table.data.ps-table td:nth-child(10) { text-align: right; }
table.data.ps-table th:nth-child(8), table.data.ps-table td:nth-child(8) {
  width: auto; min-width: 260px; white-space: normal;
}
.ps-sold { font-size: 12.5px; line-height: 1.5; white-space: normal; word-break: break-word; }
.ps-mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px;
  letter-spacing: .02em;
}
.ps-dim { color: var(--muted); }

/* 點數獎金級距：一階一列，窄螢幕自動落成一欄 */
.pp-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.pp-row .field { margin: 0; }

/* ===== 競賽遊戲 ===== */

.ct-head {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 8px;
  margin-bottom: 14px;
}
.ct-period { font-size: 13.5px; color: var(--muted); font-weight: 700; }
.ct-left {
  padding: 3px 12px;
  border-radius: 999px;
  background: var(--surface-alt);
  font-size: 13px; font-weight: 800;
}
/* 剩三天以內轉紅：那是唯一需要被看到的狀態 */
.ct-left.is-hot { background: #fdeaea; color: #97231f; }

/* 自己的名次擺最上面：三十個人的表格裡找自己很花時間 */
.ct-me {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 18px;
  margin-bottom: 16px;
  border-radius: var(--radius);
  background: linear-gradient(135deg, var(--accent) 0%, var(--accent-dark, #1f4fd8) 100%);
  color: #fff;
}
.ct-me-rank { font-size: 20px; font-weight: 900; white-space: nowrap; }
.ct-me-main { flex: 1; min-width: 0; }
.ct-me-name { font-size: 15px; font-weight: 800; }
.ct-me .hint { color: rgba(255, 255, 255, .82); }
.ct-me-score { font-size: 26px; font-weight: 900; }

/*
 * 棋盤排成一條可以左右捲的路徑，不是大富翁那種方框。
 *
 * 方框在手機的直向畫面上中間那一大塊是空的，而格子被擠到只有指甲大。
 * 一條路徑每一格都還看得清楚上面站了誰，捲動也是手機上最自然的動作。
 */
.ct-board-wrap {
  margin-top: 12px;
  overflow-x: auto;
  padding-bottom: 8px;
}
.ct-board { display: flex; gap: 10px; min-width: min-content; }

.ct-cell {
  flex: 0 0 96px;
  min-height: 104px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface-alt);
  display: flex; flex-direction: column; gap: 4px;
}
.ct-cell-no { font-size: 12px; font-weight: 800; color: var(--muted); }
.ct-cell-note { font-size: 11px; line-height: 1.4; color: var(--muted); }
.ct-cell.is-start { background: #eef6ee; border-color: #cfe4cf; }
.ct-cell.is-goal { background: #fff6e5; border-color: #f0d9a8; }
.ct-cell.is-taken { border-color: var(--accent); }

/* 棋子。字只放得下兩三個，所以名字取最後兩個字 */
.ct-token {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--line-strong, var(--line));
  font-size: 11px; font-weight: 700;
  white-space: nowrap;
}
.ct-token.is-me { background: var(--accent); border-color: var(--accent); color: #fff; }

/* ===== 競賽設定 ===== */

.ctc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
}
.ctc-grid .field { margin: 0; }

.ctc-rule {
  margin-top: 12px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-alt);
}
.ctc-rule .field { margin-top: 8px; }

/*
 * 從 POS 抓來的選項清單。
 *
 * 小類有一兩百個，所以這一塊限高並自己捲——不限高的話對話框會長到
 * 看不完，而下面的儲存鈕永遠捲不到。
 */
.ctc-opts {
  margin-top: 6px;
  max-height: 190px;
  overflow-y: auto;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
}
.ctc-opt {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  color: var(--ink);
  font-size: 13.5px; font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.ctc-opt:last-child { border-bottom: 0; }
.ctc-opt:hover { background: var(--surface-alt); }
.ctc-opt-name { font-weight: 700; }
/* 賣過幾筆：一眼看得出哪些是主力 */
.ctc-opt-n {
  flex: none;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--surface-alt);
  font-size: 11.5px; font-weight: 700; color: var(--muted);
}
.ctc-opts .hint { padding: 9px 12px; }

/* ===== 初次載入的骨架 ===== */

/*
 * 一片空白加一行「載入中」沒有告訴使用者「等一下這裡會有東西」，
 * 看起來比較像壞掉。骨架先佔住位置，載完之後內容長在同一個地方，
 * 畫面不會整個跳一下。
 *
 * 骨架也套同一層模糊：一來跟背景更新看起來是同一件事，二來模糊之後
 * 沒有人會把那幾條灰色橫槓誤讀成真的資料。
 */
.skel-wrap { position: relative; min-height: 220px; }

/*
 * 骨架區只有兩百多像素高，遮罩那組 18vh 的上緣留白會把說明卡推到看不見的
 * 地方。這裡改成置中——同一個元件在不同高度的容器裡要各自對齊。
 */
.skel-wrap .veil { padding-top: 0; align-items: center; }

.skel {
  filter: blur(3px);
  opacity: .5;
  padding: 4px 2px;
}
.skel-row { display: flex; gap: 10px; margin-top: 14px; }

.skel-bar {
  height: 14px;
  border-radius: 7px;
  background: linear-gradient(90deg, var(--surface-alt) 0%, var(--line) 50%, var(--surface-alt) 100%);
  background-size: 200% 100%;
  animation: skel-sweep 1.4s ease-in-out infinite;
}
.skel-title { width: 38%; height: 20px; margin-bottom: 4px; }
.skel-wide { flex: 3; }
.skel-narrow { flex: 1; }

@keyframes skel-sweep {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/*
 * 會動的東西對某些人是不舒服的，系統設定說了就照做。
 * 骨架本身仍然在（那是版面資訊），只是不掃動。
 */
@media (prefers-reduced-motion: reduce) {
  .skel-bar { animation: none; }
}

/* ===== 背景更新與擱置的遮罩 ===== */

/*
 * 更新資料時不清空畫面，改成把它模糊起來。
 *
 * 清空重畫看起來像資料掉了，而且捲動位置、展開的那幾筆、剛設好的篩選
 * 全部歸零。模糊＋擋住操作的話，使用者看得到「還是原本那些東西，
 * 只是正在換新的」。
 */
/* 模糊的是內容，不是遮罩本身——所以模糊套在子層，遮罩疊在上面 */
.is-veiled { position: relative; }
.is-veiled > *:not(.veil) {
  filter: blur(3px);
  opacity: .55;
  transition: filter .18s ease, opacity .18s ease;
  /* 擋住操作：底下的資料正要被換掉，這半秒按下去可能落在等一下就不存在的那一筆 */
  pointer-events: none;
  user-select: none;
}

.veil {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  /* 內容很長時遮罩也很長，卡片要留在看得到的地方 */
  padding-top: 18vh;
}

.veil-card {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  justify-content: center;
  max-width: 92%;
  padding: 14px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: 0 6px 24px rgba(0, 0, 0, .12);
  /* 卡片本身要按得下去（尤其擱置時那顆更新鈕） */
  pointer-events: auto;
}
.veil-text { font-size: 14px; font-weight: 700; }

/*
   更新中：遮罩跟著內容捲動，卡片黏在視窗上。

   卡片原本貼在遮罩頂端，也就是那一頁的最上面。使用者離開前如果捲到頁面
   下半部，回來時整張卡片在畫面外——他看到的是整頁突然模糊、按不動，
   而且沒有任何說明。黏住之後捲到哪都看得到「資料更新中」。

   偏移量避開固定頂列（--head-h 由 JS 量實際高度寫入，見 syncHeadHeight）。
*/
.veil-busy { position: absolute; padding-top: 0; }
.veil-busy .veil-card {
  /*
     用 fixed 不用 sticky：sticky 只要祖先有一層 overflow 不是 visible 就會
     失效，而那種失效沒有任何徵兆——只是卡片又跑回畫面外。fixed 在這個專案
     裡已經驗證過（擱置的那張卡就是這樣做的）。
  */
  position: fixed;
  top: calc(var(--head-h, 0px) + 24px);
  left: 50%;
  transform: translateX(-50%);
  max-width: min(92vw, 420px);
}

/* 擱置的卡片黏在畫面上，長頁面捲到哪都看得到那顆按鈕 */
.veil-idle { position: fixed; inset: 0; align-items: center; padding-top: 0; }
.veil-idle .veil-card { flex-direction: column; text-align: center; }

@media (prefers-reduced-motion: reduce) {
  .is-veiled > *:not(.veil) { transition: none; }
}

/* ===== Mac mini 代理管理 ===== */

/*
 * 記錄用等寬字並保留原本的空白：那幾行是對齊過的（時間、交易代碼、狀態、
 * 耗時），用比例字型會全部歪掉，而歪掉之後就得逐行讀而不是掃過去。
 */
.mm-logs {
  margin-top: 12px;
  max-height: 420px;
  overflow: auto;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-alt);
}
.mm-log {
  padding: 6px 10px;
  border-bottom: 1px solid var(--line);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-all;
}
.mm-log:last-child { border-bottom: 0; }
.mm-log.is-bad  { background: #fdeaea; color: #97231f; font-weight: 700; }
.mm-log.is-warn { background: #fdf3e3; color: #96631a; }

/* 到機房要打的指令。可以直接選取複製，所以不換行擠在一起 */
.mm-code {
  margin: 10px 0 0;
  padding: 12px 14px;
  overflow-x: auto;
  border-radius: 10px;
  background: var(--surface-alt);
  border: 1px solid var(--line);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px; line-height: 1.7;
}

/* 目前使用中的版本號：這一頁最重要的一個值，要一眼看到 */
.mm-now {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px;
  margin-top: 12px;
}
.mm-now-k { font-size: 13px; color: var(--muted); }
.mm-now-v {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 20px; font-weight: 800;
  letter-spacing: .5px;
}

/* 一排並列的操作按鈕，窄螢幕自動換行 */
.btn-row { display: flex; flex-wrap: wrap; gap: 8px; }

/* 分區底下的子分類（主管專區 › 區主管）。比分區標題輕一級，
   看得出是同一區裡的一堆，而不是另一個分區 */
.section-sublabel {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 16px 0 8px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--muted);
}
.section-sublabel::after {
  content: '';
  flex: 1;
  border-top: 1px solid var(--line);
}

.course-list { margin-top: 4px; }

.course-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}
.course-item:last-child { border-bottom: 0; }
.course-item.is-cancelled { opacity: .55; }
.course-item.is-cancelled .course-name { text-decoration: line-through; }

.course-main { flex: 1; min-width: 0; }
.course-name { font-size: 14.5px; font-weight: 700; }
.course-meta { font-size: 12.5px; color: var(--muted); margin-top: 3px; }
.course-meta.warn { color: var(--danger); font-weight: 600; }

.status-pass { font-size: 13px; color: var(--ok); font-weight: 600; margin-top: 3px; }
.status-fail { font-size: 13px; color: var(--danger); font-weight: 600; margin-top: 3px; }

.pill {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
  vertical-align: middle;
}
.pill-ok     { background: #e4f5ec; color: #1e7a4f; }
.pill-danger { background: #fce8e8; color: #b13333; }
.pill-warn   { background: #fdf0dc; color: #96601a; }
.pill-muted  { background: var(--surface-alt); color: var(--muted); }

@media (max-width: 640px) {
  .course-item { flex-direction: column; align-items: stretch; gap: 10px; }
  .course-item .btn, .course-item .pill { align-self: flex-start; }
}

/* ===== 學習護照的大類選擇 ===== */

.module-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  margin-top: 4px;
}

.module-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 20px 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: border-color .15s, transform .15s, box-shadow .15s;
}
.module-card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(23, 39, 46, .08);
}
.module-card:active { transform: translateY(0); }

.module-icon { font-size: 28px; line-height: 1; flex-shrink: 0; }
.module-main { flex: 1; min-width: 0; }
.module-title { font-size: 15px; font-weight: 700; }
.module-stat { font-size: 12.5px; margin-top: 5px; line-height: 1.5; }
.module-stat.tone-todo { color: var(--danger); font-weight: 600; }
.module-stat.tone-done { color: var(--ok); font-weight: 600; }
.module-stat.tone-none { color: var(--muted); }

.module-arrow { font-size: 22px; color: var(--muted); flex-shrink: 0; }

@media (max-width: 900px) {
  .module-grid { grid-template-columns: 1fr; }
}

/* ===== 管理部專區：模組分組 =====

   一次十幾張卡片排成一片，找東西只能從頭讀到尾。分組後每一區都短到
   一眼看得完，標題那條細線負責把區塊切開——用線而不是用底色或方框，
   是因為卡片本身已經有邊框了，再加一層容器會變成框中框。
*/

.module-group + .module-group { margin-top: 26px; }

.module-group-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 10px;
}
/* 標題右邊補一條線拉到底，讓分組的範圍看得出來 */
.module-group-head::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--line);
}
.module-group-label {
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: .1em;
  color: var(--muted);
}

/* ===== 手機：表格改成一列一張卡片 =====

   大表格在手機上橫向捲是最難用的模式——滑到第五欄時已經忘了在看誰，
   標題列也早就捲出畫面外。這裡把每一列變成一張卡片，每個儲存格顯示成
   「欄位名稱　數值」，靠 JS 事後補上的 data-label 供應名稱。

   只在 .stacked 生效：沒套用的表格維持原本的橫向捲，不會因為漏改而壞掉。
*/
/*
   排序按鈕列只在手機上出現。

   桌機看得到表頭，直接點表頭排序；卡片模式（下面的 media query）會把
   整個 thead 藏起來，那裡沒有表頭可以點，所以窄螢幕才需要這排按鈕。
*/
.sort-bar { display: none; }

@media (max-width: 720px) {
  .sort-bar { display: block; }

  .table-wrap { overflow-x: visible; margin: 0; }

  table.data.stacked { min-width: 0; display: block; }
  table.data.stacked thead { display: none; }
  table.data.stacked tbody { display: block; }

  table.data.stacked tbody tr {
    display: block;
    border: 1px solid var(--line);
    border-radius: 12px;
    padding: 10px 14px;
    margin-bottom: 10px;
    background: var(--surface);
  }
  table.data.stacked tbody tr:hover { background: var(--surface); }
  table.data.stacked tbody tr + tr td { border-top: 0; }

  table.data.stacked td {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 14px;
    padding: 5px 0;
    text-align: right;
    white-space: normal;
    min-width: 0;
  }
  table.data.stacked td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    max-width: 55%;
    text-align: left;
    font-size: 12px;
    font-weight: 700;
    color: var(--muted);
  }
  /* 沒有欄位名稱就不要留出左邊那一欄的空間 */
  table.data.stacked td[data-label=""]::before { content: none; }

  /* 第一欄當卡片標題：整行、粗體、底下畫一條分隔 */
  table.data.stacked tbody td:first-child {
    display: block;
    text-align: left;
    font-size: 15px;
    font-weight: 700;
    padding: 2px 0 8px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--line);
  }
  table.data.stacked tbody td:first-child::before { content: none; }

  /* 次要欄位在手機上收起來，資訊量太大的表才用得到 */
  table.data.stacked .col-secondary { display: none; }

  /* 展開列不是資料列，維持整塊寬度 */
  table.data.stacked tbody tr.detail-row {
    border: 0;
    padding: 0;
    margin: -6px 0 10px;
    background: transparent;
  }
  table.data.stacked tbody tr.detail-row td {
    display: block;
    padding: 0;
    text-align: left;
  }
  table.data.stacked tbody tr.detail-row td::before { content: none; }

  table.data.stacked tbody tr.row-self { border-color: var(--accent); }
  table.data.stacked tbody tr.row-self td:first-child { box-shadow: none; }
  table.data.stacked tbody tr.row-total { background: var(--surface-alt); }
  table.data.stacked tbody tr.row-total td { background: transparent; border-top: 0; }
}

/* ===== 總務用品的數量輸入 ===== */

.qty-list { margin-bottom: 4px; }

.qty-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
}
.qty-row:last-child { border-bottom: 0; }

.qty-name { flex: 1; min-width: 0; font-size: 14px; }

/* 數量欄固定寬度：一整排右緣對齊才掃得快，而且手機上要夠大才點得到 */
.qty-input {
  flex: 0 0 78px;
  width: 78px;
  min-height: 40px;
  padding: 8px 10px;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: 15px;
  text-align: right;
}
.qty-input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

/* ===== 觸控裝置：表單字級一律 16px =====

   iOS Safari 在輸入框字級小於 16px 時，會在聚焦的瞬間自動放大整個頁面，
   而且離開輸入框之後不會縮回去——結果就是整頁卡在放大狀態、右側被切掉。

   正確的解法是把字級提到 16px，而不是在 viewport 加 maximum-scale=1。
   後者會連使用者自己想放大來看清楚都一併禁掉，那是無障礙的退步；
   而且 iOS 本來就會忽略 user-scalable=no。這裡只消除「非預期的自動放大」，
   使用者主動雙指縮放仍然正常。

   用 pointer: coarse 而不是螢幕寬度：會自動放大的是觸控裝置這個特性本身，
   跟視窗多寬無關——平板橫放一樣會中。
*/
@media (pointer: coarse) {
  .field select,
  .field input,
  .field textarea,
  .qty-input,
  input[type="text"],
  input[type="search"],
  input[type="number"],
  input[type="date"],
  input[type="email"],
  input[type="tel"],
  select,
  textarea {
    font-size: 16px;
  }
}

/* ===== 有新版本的提示 ===== */

.update-bar {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(18px + env(safe-area-inset-bottom, 0px));
  z-index: 200;               /* 要在對話框(100)與手機導覽列(60)之上 */
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: calc(100% - 28px);
  padding: 12px 16px;
  border-radius: 12px;
  background: var(--topbar);
  color: #fff;
  box-shadow: 0 8px 28px rgba(23, 39, 46, .28);
}

.update-text { font-size: 14px; font-weight: 600; }
.update-actions { display: flex; gap: 8px; flex-shrink: 0; }

/* 深色底上的按鈕要自己一套配色，沿用淺色的會看不見 */
.update-bar .btn {
  background: transparent;
  border-color: rgba(255, 255, 255, .35);
  color: #fff;
}
.update-bar .btn:hover { border-color: #fff; }
.update-bar .btn-primary {
  background: var(--accent);
  border-color: var(--accent);
}
.update-bar .btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }

@media (max-width: 640px) {
  /* 手機的導覽列固定在底部，提示要疊在它上面而不是蓋住它 */
  .update-bar {
    left: 14px;
    right: 14px;
    max-width: none;
    transform: none;
    bottom: calc(72px + env(safe-area-inset-bottom, 0px));
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }
  .update-actions { justify-content: flex-end; }
}

/* ===== 管理部專區的案件操作列 ===== */

.bo-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  flex-shrink: 0;
}
.bo-actions select,
.bo-actions input[type="text"] {
  min-height: 38px;
  padding: 7px 10px;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: 14px;
}
.bo-actions input[type="text"] { width: 110px; }

.bo-row .bo-error { flex-basis: 100%; margin-top: 8px; }

/* 反灰的模組卡片：滑過去不要有可點擊的錯覺 */
/*
   登入畫面的 Google 按鈕在生物辨識進行中先反灰。

   pointer-events: none 是重點：它是一個 <a>，光改顏色擋不住點擊，
   而這顆按下去就是一趟 OAuth 跳轉，中途攔不回來。
*/
.btn.is-disabled {
  opacity: .45;
  pointer-events: none;
  filter: grayscale(1);
}
.login-google-hint { margin: 8px 0 0; text-align: center; font-size: 12.5px; }

.module-card.is-disabled {
  opacity: .55;
  cursor: not-allowed;
  background: var(--surface-alt);
}
.module-card.is-disabled:hover {
  border-color: var(--line);
  transform: none;
  box-shadow: none;
}

@media (max-width: 640px) {
  /* 手機上操作列自己佔一整列，否則三個元件擠在右側都太窄 */
  .bo-actions { width: 100%; }
  .bo-actions select { flex: 1; }
  .bo-actions input[type="text"] { flex: 0 0 100px; width: 100px; }
}

/* ===== 我的專案 ===== */

.pm-card { margin-bottom: 14px; }

.pm-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
}
.pm-head h2 { margin: 0; }
.pm-head .pill { flex-shrink: 0; margin-top: 4px; }

.pm-report {
  margin-top: 14px;
  padding: 12px 14px;
  border-radius: 10px;
  background: var(--surface-alt);
  font-size: 13.5px;
}

.pm-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}

.placeholder-card {
  padding: 28px 20px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  text-align: center;
  color: var(--muted);
  font-size: 14px;
}

@media (max-width: 640px) {
  /* 標題與狀態在窄螢幕上並排會把標題擠成一直條 */
  .pm-head { flex-direction: column; gap: 8px; }
  .pm-head .pill { margin-top: 0; align-self: flex-start; }
  .pm-actions .btn { flex: 1 0 auto; }
}

/* ===== 學習護照人資端的必修／選修規則 ===== */

.hr-rule {
  margin-top: 12px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface-alt);
}

.hr-rule-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

/* 規則區裡的名單限高，否則一個部門幾十人就把對話框撐爆 */
.hr-rule .picker-list { max-height: 240px; overflow-y: auto; }

/* ===== 講座時間選擇 ===== */

/* 日期佔比較寬，起訖時間各半——時間欄位比日期短，等寬會留一堆空白 */
.hr-when {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 10px;
}

/*
   grid 項目的 min-width 預設是 auto，而原生的日期／時間輸入框有自己的
   最小寬度——欄位縮不到比它更窄，整個 grid 就撐破容器往右溢出。
   min-width: 0 才讓欄位真的能被壓縮。
*/
.hr-when .field { min-width: 0; }
.hr-when input { min-width: 0; width: 100%; max-width: 100%; }

.field-label-standalone {
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  margin-bottom: 5px;
}

/* 640px 與全站其他斷點一致；大螢幕手機與橫放也涵蓋得到 */
@media (max-width: 640px) {
  .hr-when { grid-template-columns: 1fr; }
}

/* ===== 人員評核分數調整 ===== */

.ee-item { align-items: flex-start; }

.ee-totals { display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0; }
.ee-total {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 54px;
  padding: 6px 8px;
  border-radius: 8px;
  background: var(--surface-alt);
}
.ee-total-label { font-size: 11px; color: var(--muted); font-weight: 600; }
.ee-total-value { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }

.ee-form {
  margin: 4px 0 18px;
  padding: 16px;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: var(--surface-alt);
}

.ee-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 10px;
}
/* 原生數字輸入框在窄欄位裡同樣會撐破容器 */
.ee-grid .field { min-width: 0; }
.ee-grid input { min-width: 0; width: 100%; }

/* 總分欄位標出來：它不是自動算的，是照填的值存 */
.ee-is-total label { color: var(--accent); }
.ee-is-total input { border-color: var(--accent); font-weight: 700; }

@media (max-width: 640px) {
  .ee-item { flex-direction: column; }
  .ee-totals { width: 100%; }
  .ee-total { flex: 1; }
  .ee-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ===== 分數調整 · 表格版（PC / 平板） =====

   27 欄的試算表式表格，沿用原管理中台的做法：表頭與左側四欄凍結，
   其餘橫向捲。批次微調需要一次看到很多人，展開式在大螢幕上反而難用。
*/

.ee-table-wrap {
  overflow: auto;
  max-height: calc(100vh - 260px);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  margin: 0;
}

/* 這張表不套卡片化：大螢幕才會出現，小螢幕走展開式 */
.ee-table { min-width: 1560px; font-size: 13px; border-collapse: separate; border-spacing: 0; }

.ee-table th, .ee-table td {
  padding: 5px 6px;
  white-space: nowrap;
  text-align: center;
  border-bottom: 1px solid var(--line);
  border-right: 1px solid var(--line);
}

/*
   表頭分兩層，用途不同所以配色也不同：

   第一層是模組分組，用色塊快速定位（跟原本的中台一樣）。
   第二層是欄位名稱，字小又多，深底白字在 12px 下很吃力——改成淺底深字，
   對比從 4:1 拉到 12:1 以上。

   凍結欄位的規則特異性比 thead 高，所以那四格必須明確指定顏色，
   否則會拿到 .ee-fixed 的白底配 thead 的白字，整個看不見。
*/
.ee-table thead th {
  position: sticky;
  top: 0;
  z-index: 20;
  font-weight: 700;
  border-bottom: 0;
}

/* 第一層：模組分組 */
.ee-table thead th.ee-grp {
  height: 30px;
  font-size: 13px;
  letter-spacing: .04em;
  color: #fff;
}
.ee-grp-sales   { background: #1565c0; }
.ee-grp-hr      { background: #bf360c; }
.ee-grp-ops     { background: #4a148c; }
.ee-grp-manager { background: #00695c; }

/* 第二層：欄位名稱——淺底深字才看得清楚 */
.ee-table thead tr:nth-child(2) th { top: 30px; }
.ee-table thead th.ee-sub {
  background: var(--surface-alt);
  color: var(--ink);
  font-size: 12px;
  border-bottom: 2px solid var(--line-strong);
}
/* 總分欄仍要跳出來，但用淺橘底深橘字而不是白字 */
.ee-table thead th.ee-sub-total {
  background: #fbe6d4;
  color: #a34608;
}

/* 左側四欄與最右的操作欄凍結。交叉處的層級要比一般表頭高。 */
.ee-table .ee-fixed { position: sticky; background: var(--surface); z-index: 10; }
.ee-table thead th.ee-fixed {
  z-index: 30;
  background: var(--topbar);
  color: #fff;
  font-size: 12px;
}
.ee-table .ee-f1 { left: 0; min-width: 62px; }
.ee-table .ee-f2 { left: 62px; min-width: 96px; text-align: left; }
.ee-table .ee-f3 { left: 158px; min-width: 84px; }
.ee-table .ee-f4 { left: 242px; min-width: 76px; border-right: 2px solid var(--topbar); }

.ee-name { font-weight: 700; }
.ee-store { font-size: 11px; color: var(--muted); }

.ee-grand {
  display: inline-block;
  min-width: 46px;
  padding: 3px 7px;
  border-radius: 999px;
  background: var(--topbar);
  color: #fff;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.ee-cell input {
  width: 70px;
  min-width: 0;
  padding: 4px 6px;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
  text-align: right;
}
.ee-cell input:disabled { background: var(--surface-alt); color: var(--muted); }
.ee-cell input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }
.ee-cell-total input { width: 74px; border-color: var(--accent); font-weight: 700; }

/* 評分說明是文字，要比數字欄寬 */
.ee-table tbody tr td:nth-last-child(3) input[type="text"] { width: 150px; text-align: left; }

.ee-table tbody tr:hover td { background: #fbf8f1; }
.ee-table tbody tr:hover .ee-fixed { background: #fbf8f1; }
.ee-table tbody tr.ee-dirty .ee-fixed { background: #fdf3e3; }
.ee-table tbody tr.ee-dirty td { background: #fefaf2; }

.ee-act { position: sticky; right: 0; background: var(--surface); z-index: 10; }
.ee-table thead th.ee-act-head {
  position: sticky;
  right: 0;
  z-index: 30;
  background: var(--topbar);
  color: #fff;
  font-size: 12px;
}
.ee-status { display: block; font-size: 10.5px; margin-top: 3px; color: var(--muted); }
.ee-status-ok { color: var(--ok); }
.ee-status-bad { color: var(--danger); white-space: normal; max-width: 180px; }

/* 表格版只在寬螢幕出現；窄螢幕由展開式接手，不必再做卡片化 */
@media (max-width: 767px) {
  .ee-table-wrap { display: none; }
}

/* ===== 可點兩下編輯的列 ===== */

/*
   點兩下沒有視覺提示就沒人會發現，所以整列要看起來可互動：
   游標變手指、滑過去換底色。標題文字也會寫明。
*/
tr.row-dblclick { cursor: pointer; }
tr.row-dblclick:hover td { background: #fbf8f1; }
tr.row-dblclick:active td { background: #f5efe2; }

/* 點兩下會選取整列文字，很干擾——只擋選取，不影響複製欄位裡的值 */
tr.row-dblclick td { user-select: none; }

/* ===== 分數匯入（限電腦） ===== */

.imp-card { padding: 0; overflow: hidden; }

.imp-card-head {
  padding: 12px 20px;
  color: #fff;
  font-size: 15px;
  font-weight: 700;
}

.imp-item { padding: 16px 20px; border-bottom: 1px solid var(--line); }
.imp-item:last-child { border-bottom: 0; }

.imp-item-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 6px;
}
.imp-item-title { font-size: 15px; font-weight: 700; }

.imp-row {
  display: grid;
  grid-template-columns: 130px 1fr 150px;
  gap: 12px;
  align-items: end;
  margin-top: 12px;
}
/* 原生的檔案與日期控制項在 grid 裡會撐破容器 */
.imp-row .field { min-width: 0; }
.imp-row input, .imp-row select { min-width: 0; max-width: 100%; }

/* 對不到員工的清單可能很長，限高避免把整頁推下去 */
.imp-errors {
  margin-top: 6px;
  max-height: 120px;
  overflow-y: auto;
  font-size: 12.5px;
  line-height: 1.7;
}

/* ===== 多檔上傳（APP 會員評分） ===== */

.imp-files {
  margin-top: 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}

.imp-file-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  background: var(--surface);
}
.imp-file-row:last-child { border-bottom: 0; }
.imp-file-row:nth-child(even) { background: var(--surface-alt); }

.imp-file-main { flex: 1; min-width: 0; }
.imp-file-label { font-size: 14px; font-weight: 700; }

.imp-file-pick { flex: 0 0 300px; min-width: 0; }
.imp-file-pick input[type="file"] { max-width: 100%; }
.imp-file-note { margin-top: 4px; word-break: break-all; }

/* ===== 人資考勤輸入 ===== */

.hri-wrap { max-height: calc(100vh - 340px); overflow: auto; }

.hri-table { min-width: 1080px; font-size: 13px; }
.hri-table th, .hri-table td { padding: 8px 10px; vertical-align: top; text-align: left; }
.hri-table thead th {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--surface-alt);
  color: var(--ink);
  border-bottom: 2px solid var(--line-strong);
}

.hri-name { white-space: nowrap; }
.hri-name .pill { margin-top: 4px; }

/* 已填的整列淺綠，跟原中台一樣一眼看得出誰還沒填 */
.hri-table tbody tr.hri-filled td { background: #f2f8f2; }
.hri-table tbody tr.ee-dirty td { background: #fefaf2; }

.hri-table input[type="number"] {
  width: 84px;
  min-width: 0;
  padding: 5px 7px;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
  text-align: right;
}
.hri-table input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

.hri-special { min-width: 280px; }
.hri-sp-line { display: flex; gap: 6px; margin-bottom: 5px; }
.hri-sp-reason {
  flex: 1;
  min-width: 0;
  padding: 5px 7px;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
}
.hri-table .hri-sp-score { width: 74px; flex: 0 0 74px; }

.hri-total { font-size: 15px; font-variant-numeric: tabular-nums; }

/* ===== 目標進度（精簡列） ===== */

.goal-strip {
  padding: 14px 18px;
  margin-bottom: 18px;
  border: 1px solid var(--line);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius);
  background: var(--surface);
}
.goal-strip.is-done { border-left-color: var(--ok); }
.goal-strip.is-behind { border-left-color: var(--danger); }

.goal-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.goal-title { font-size: 14.5px; font-weight: 700; }
.goal-sub { font-size: 12px; font-weight: 600; color: var(--muted); }

.goal-figs { display: flex; align-items: baseline; gap: 12px; flex-shrink: 0; }
.goal-pct { font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums; }
.goal-nums { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }

.goal-foot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  margin-top: 8px;
  flex-wrap: wrap;
}
.goal-verdict { font-size: 13px; font-weight: 600; }
.goal-strip.is-behind .goal-verdict { color: var(--danger); }
.goal-strip.is-done .goal-verdict { color: var(--ok); }
.goal-days { font-size: 12px; color: var(--muted); flex-shrink: 0; }

/*
   手機版：桌機的 flex-wrap 會讓標題、達成率、金額各自換行，變成五六列，
   完全失去「精簡一列」的意義。這裡改成不換行，達成率與金額上下疊在右側，
   次要資訊（度量名稱、天數、預估標籤）隱藏。
*/
@media (max-width: 640px) {
  .goal-strip { padding: 12px 14px; margin-bottom: 14px; }

  .goal-head { flex-wrap: nowrap; align-items: center; gap: 10px; }
  .goal-title {
    flex: 1;
    min-width: 0;
    font-size: 13.5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .goal-sub { display: none; }

  .goal-figs { flex-direction: column; align-items: flex-end; gap: 1px; flex-shrink: 0; }
  .goal-pct { font-size: 19px; line-height: 1.1; }
  .goal-nums { font-size: 11px; }

  .goal-foot { flex-wrap: nowrap; gap: 8px; margin-top: 6px; }
  .goal-verdict { font-size: 12px; line-height: 1.45; }
  .goal-days { display: none; }

  /* 「預估」那兩個字在窄螢幕會撞到上面那行，只留標記線 */
  .goal-pace::after { display: none; }
}

.goal-bar {
  position: relative;
  height: 14px;
  margin-top: 10px;
  border-radius: 999px;
  background: var(--surface-alt);
  border: 1px solid var(--line);
  overflow: visible;
}

.goal-fill {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--accent-hover));
  transition: width .4s cubic-bezier(.2, .8, .3, 1);
}
.goal-fill.is-done { background: linear-gradient(90deg, #34b37c, var(--ok)); }

/* 今天該做到哪：一條垂直標記，跟橘色的條子一比就知道落後還是超前。
   （標推估月底位置的話，月初那幾天線會跑到最右邊，看起來像快達標了） */
.goal-pace {
  position: absolute;
  top: -5px;
  bottom: -5px;
  width: 2px;
  background: var(--ink);
  opacity: .55;
}
.goal-pace::after {
  content: '今天';
  position: absolute;
  top: -15px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 10px;
  font-weight: 700;
  color: var(--muted);
  white-space: nowrap;
}

/* ===== 目標設定 ===== */

.tg-bar { display: flex; gap: 8px; flex-wrap: wrap; margin: 12px 0 14px; }

.tg-table .tg-prev { color: var(--muted); }
.tg-table tbody tr.tg-set td { background: #f6faf7; }

.tg-input {
  width: 120px;
  min-width: 0;
  padding: 6px 9px;
  border: 1px solid var(--line-strong);
  border-radius: 7px;
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: 14px;
  text-align: right;
}
.tg-input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

/* ===== 排除規則的解析預覽 ===== */

.tg-rules { margin-top: 10px; }
.tg-rules-title { font-size: 12px; font-weight: 700; color: var(--muted); margin-bottom: 5px; }

.tg-rule {
  font-size: 12.5px;
  padding: 4px 9px;
  margin-bottom: 4px;
  border-radius: 6px;
  background: var(--surface-alt);
  border-left: 3px solid var(--line-strong);
}
/* 限定小類的規則標出來，一眼看得出哪幾條是有範圍的 */
.tg-rule.is-scoped { border-left-color: var(--accent); }

.tg-import { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tg-import select {
  min-height: 34px;
  padding: 5px 9px;
  border: 1px solid var(--line-strong);
  border-radius: 7px;
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
}

/* ===== 配件認定設定的收合列 ===== */

.tg-cfg-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 20px;
}
.tg-cfg-title { font-size: 15px; font-weight: 700; }
.tg-cfg-bar .btn { flex-shrink: 0; }

.tg-cfg-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.tg-cfg-head h2 { margin: 0; }

@media (max-width: 640px) {
  .tg-cfg-bar { flex-direction: column; align-items: stretch; }
}

/* ===== 表頭置頂 =====

   往下捲時看不到欄位名稱，長表格就得一直往回滑。所有經過 labelCells()
   的表格（會帶 .stacked）都黏在固定頂列下方。

   偏移量用 --head-h，由 JS 量實際高度寫入——寫死會錯位：桌機是頂列＋分頁列，
   手機分頁列在底部所以只有頂列，而且頂列在手機上還會因為隱藏單位名稱而變矮。

   ee-table 與 hri-table 有自己的捲動容器，黏在容器頂端，不套這一段。
*/
/*
   兩個陷阱：

   1. .table-wrap 有 overflow-x: auto，瀏覽器會把另一軸也算成 auto——
      sticky 於是黏在那個容器而不是頁面。容器沒有高度限制就永遠不會捲，
      表頭等於完全沒作用。所以要給它一個高度上限，讓它自己捲。

   2. sticky 配 border-collapse: collapse 會讓表頭的框線消失、渲染錯亂。
      要改成 separate 並自己畫線。
*/
@media (min-width: 721px) {
  .table-wrap { max-height: calc(100vh - 230px); overflow: auto; }

  table.data.stacked { border-collapse: separate; border-spacing: 0; }
  table.data.stacked th,
  table.data.stacked td { border-bottom: 1px solid var(--line); }
  table.data.stacked tbody tr + tr td { border-top: 0; }

  table.data.stacked thead th {
    position: sticky;
    top: 0;
    z-index: 5;
    background: var(--surface-alt);
    border-bottom: 2px solid var(--line-strong);
  }
}

/* 「顯示更多」的展開鈕：低調一點，它不是主要動作 */
.btn-more {
  margin: 2px 0 18px;
  border-style: dashed;
  color: var(--muted);
  font-weight: 600;
}
.btn-more:hover { color: var(--ink); border-color: var(--muted); }

/* ===== 報名名單的批次操作 ===== */

.hr-batch {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 12px 0 6px;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--surface-alt);
  border: 1px solid var(--line);
}
.hr-batch select {
  min-height: 34px;
  padding: 5px 9px;
  border: 1px solid var(--line-strong);
  border-radius: 7px;
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
}
.hr-batch .hint { margin-left: auto; }

/* 勾選框要夠大才點得到，尤其在平板上 */
.hr-pick {
  width: 18px;
  height: 18px;
  margin-right: 12px;
  flex-shrink: 0;
  align-self: center;
}

@media (max-width: 640px) {
  .hr-batch .hint { margin-left: 0; width: 100%; }
}

/* ===== 首頁的門市天氣 ===== */

.wx {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 18px;
  margin-bottom: 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(135deg, #eef4f7, var(--surface));
}

.wx-icon { font-size: 34px; line-height: 1; flex-shrink: 0; }
.wx-main { flex: 1; min-width: 0; }
.wx-top { display: flex; align-items: baseline; gap: 10px; }
.wx-temp { font-size: 26px; font-weight: 800; font-variant-numeric: tabular-nums; }
.wx-desc { font-size: 14px; font-weight: 600; }
.wx-sub { font-size: 12.5px; color: var(--muted); margin-top: 2px; }

.wx-where { text-align: right; flex-shrink: 0; }
.wx-store { font-size: 13.5px; font-weight: 700; }
.wx-time { font-size: 11.5px; color: var(--muted); margin-top: 2px; }

/* 颱風只在真的有消息時出現，所以可以用比較強的顏色 */
.wx-typhoon {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 18px;
  margin: -8px 0 18px;
  border: 1px solid #f0c2c2;
  border-left: 4px solid var(--danger);
  border-radius: var(--radius);
  background: #fdf1f1;
}
.wx-typhoon-icon { font-size: 24px; line-height: 1; }
.wx-typhoon-name { font-size: 14px; font-weight: 700; color: #a32b2b; }
.wx-typhoon-sub { font-size: 12px; color: #8a4a4a; margin-top: 2px; }
.wx-typhoon-impact {
  font-size: 12.5px; font-weight: 700; color: #a32b2b; margin-top: 4px;
}

@media (max-width: 640px) {
  .wx { gap: 12px; padding: 12px 14px; }
  .wx-icon { font-size: 28px; }
  .wx-temp { font-size: 22px; }
  /* 地點擠到第三欄會把溫度壓扁，改成放在描述下方 */
  .wx-where { display: none; }
  .wx-sub::after { content: attr(data-where); }
}

/* ===== 載入佔位 =====

   天氣與目標是載入後才插進來的。不先佔住位置，下方的功能磚會被往下推——
   同仁剛好在那個時間差按下去就會點到別的功能。
*/
.skeleton {
  border-radius: var(--radius);
  background: linear-gradient(
    100deg,
    var(--surface-alt) 30%,
    #f6f3ec 45%,
    var(--surface-alt) 60%
  );
  background-size: 300% 100%;
  animation: skeleton-sweep 1.4s ease-in-out infinite;
  margin-bottom: 18px;
}

@keyframes skeleton-sweep {
  from { background-position: 100% 0; }
  to   { background-position: -60% 0; }
}

/* 會暈車的人不該被掃光效果干擾 */
@media (prefers-reduced-motion: reduce) {
  .skeleton { animation: none; }
}

/* ===== 分頁群組選單 ===== */

.tab-group { position: relative; }

.tab-parent { display: inline-flex; align-items: center; gap: 5px; }
.tab-caret { font-size: 10px; opacity: .6; transition: transform .15s; }
.tab-group.open .tab-caret { transform: rotate(180deg); }

/* 下拉選單裡的子分類小標 */
.tab-menu-sub {
  padding: 8px 12px 4px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .06em;
  color: var(--muted);
  border-top: 1px solid var(--line);
  margin-top: 4px;
}

.tab-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 60;
  min-width: 200px;
  /* 說明文字比標籤長，太窄會斷成很多行 */
  max-width: 280px;
  padding: 6px;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  background: var(--surface);
  box-shadow: 0 10px 30px rgba(23, 39, 46, .16);
  display: none;
}
.tab-group.open .tab-menu { display: block; }

/* 桌機滑過就展開。限定真的有游標的裝置——觸控螢幕的 hover 會黏住不放。 */
@media (hover: hover) and (pointer: fine) {
  .tab-group:hover .tab-menu { display: block; }

  /*
     按鈕與選單之間有 6px 視覺間隙，游標穿過那段時兩者都沒被 hover，
     選單會在還沒碰到選項前就消失。用一塊看不見的區塊把間隙補起來——
     間隙仍然看得到，但滑鼠移動的路徑是連續的。
  */
  .tab-menu::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: -10px;
    height: 10px;
  }
  /* 手機的選單往上開，橋接要墊在下方 */
  .tab-group.open .tab-menu::before { content: none; }
}

.tab-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 12px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--ink);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}
.tab-item:hover { background: var(--surface-alt); }
.tab-item.on { background: var(--surface-alt); color: var(--accent); }
.tab-item-icon { font-size: 16px; line-height: 1; flex-shrink: 0; }

/* 進不去的分頁：看得到但按不下去，底下寫明要什麼身分才進得來 */
.tab-item.is-locked { cursor: default; align-items: flex-start; }
.tab-item.is-locked:hover { background: transparent; }
.tab-item.is-locked .tab-item-icon,
.tab-item.is-locked .tab-item-text > span:first-child { opacity: .45; }

.tab-item-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tab-item-note {
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--muted);
  white-space: normal;
}

/* 整組都進不去的群組按鈕，以及進不去的獨立按鈕 */
.tab.is-dim { opacity: .45; cursor: default; }
.tab.is-dim:hover { border-color: transparent; }

@media (max-width: 640px) {
  /* 底部導覽的選單要往上開，往下開會跑到畫面外 */
  .tab-menu {
    top: auto;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%);
    min-width: 210px;
    max-height: 60vh;
    overflow-y: auto;
  }
  /* 最左與最右的群組貼邊開，不然會超出畫面 */
  .tab-group:first-of-type .tab-menu { left: 0; transform: none; }
  .tab-group:last-of-type .tab-menu { left: auto; right: 0; transform: none; }

  .tab-parent .tab-caret { display: none; }   /* 底部導覽的空間要留給文字 */
  .tab-item { padding: 11px 12px; font-size: 15px; }
}

/* ===== 設定裡的開關 ===== */

.pref-row {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}
.pref-row:last-of-type { border-bottom: 0; }

.pref-main { flex: 1; min-width: 0; }
.pref-label { font-size: 14.5px; font-weight: 700; margin-bottom: 3px; }

.pref-switch {
  position: relative;
  flex-shrink: 0;
  width: 50px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--line-strong);
  cursor: pointer;
  transition: background .18s;
}
.pref-switch.on { background: var(--accent); }
.pref-switch:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.pref-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
  transition: transform .18s;
}
.pref-switch.on .pref-knob { transform: translateX(20px); }

@media (prefers-reduced-motion: reduce) {
  .pref-switch, .pref-knob { transition: none; }
}

/* ===== 小嫻 ===== */

/*
   對話區自己捲動，輸入框固定在下方。
   讓整頁跟著長的話，對話一多輸入框就被推到畫面外，每問一句都要先捲到底。

   高度由 JS 實際量測（sizeChat）而不是用 vh 硬算：聊天框上方還有標題區，
   手機底部又有導覽列，把這些常數寫死在 CSS 裡只要版面一動就會失準。
   下面這個值只是 JS 還沒跑到之前的暫用值。
*/
.chat {
  display: flex;
  flex-direction: column;
  height: 60vh;
  min-height: 320px;
}

.chat-log {
  flex: 1;
  overflow-y: auto;
  padding: 4px 2px 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  /* iOS 慣性捲動，沒有的話捲起來很生硬 */
  -webkit-overflow-scrolling: touch;
}

/* 小嫻的自我介紹 */
.chat-hero {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 12px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--line);
}

.chat-hero-face {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  /* 原圖四角是白的，圓形裁切之後只留下黃圈內的部分 */
  object-fit: cover;
  flex-shrink: 0;
  background: var(--surface);
}

.chat-hero-name { font-size: 16px; font-weight: 800; letter-spacing: .02em; }
.chat-hero-desc { font-size: 13px; color: var(--muted); margin-top: 2px; }

.chat-row {
  display: flex;
  align-items: flex-end;
  gap: 8px;
}
.chat-row.chat-me { justify-content: flex-end; }

.chat-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  object-fit: cover;
  flex-shrink: 0;
  background: var(--surface);
}

.chat-bubble {
  max-width: min(72%, 560px);
  padding: 10px 14px;
  border-radius: 16px;
  font-size: 15px;
  line-height: 1.65;
  /* 長網址與沒有空白的長字串要斷行，不然會把泡泡撐出容器 */
  overflow-wrap: anywhere;
}

.chat-bot .chat-bubble {
  background: var(--surface-alt);
  border: 1px solid var(--line);
  border-bottom-left-radius: 5px;
}

.chat-me .chat-bubble {
  background: var(--accent);
  color: #fff;
  border-bottom-right-radius: 5px;
}

/* 正在輸入 */
.chat-typing { display: flex; gap: 5px; align-items: center; padding: 14px; }

.chat-typing span {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--muted);
  animation: chat-blink 1.3s infinite;
}
.chat-typing span:nth-child(2) { animation-delay: .18s; }
.chat-typing span:nth-child(3) { animation-delay: .36s; }

@keyframes chat-blink {
  0%, 60%, 100% { opacity: .28; }
  30%           { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .chat-typing span { animation: none; opacity: .55; }
}

.chat-suggest { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 2px; }

.chat-chip {
  padding: 7px 13px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font-size: 13.5px;
  cursor: pointer;
}
.chat-chip:hover { border-color: var(--accent); color: var(--accent); }

.chat-form {
  display: flex;
  gap: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}

.chat-input {
  flex: 1;
  min-width: 0;
  padding: 11px 14px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font-size: 15px;
}
.chat-input:focus { outline: none; border-color: var(--accent); }
.chat-input:disabled { opacity: .6; }

.chat-send {
  flex-shrink: 0;
  padding: 0 20px;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
}
.chat-send:disabled { opacity: .5; cursor: default; }

/* 手機：輸入框字級不能小於 16px，否則 iOS 會自動放大且不會還原 */
@media (pointer: coarse) {
  .chat-input { font-size: 16px; }
}

.chat-reset {
  flex-shrink: 0;
  width: 42px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--muted);
  font-size: 17px;
  cursor: pointer;
}
.chat-reset:hover { border-color: var(--accent); color: var(--accent); }
.chat-reset:disabled { opacity: .5; cursor: default; }

/* ===== 首頁的通知引導 ===== */

.notify-prompt {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 16px 18px;
  margin-bottom: 18px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface-alt);
}

.notify-prompt-icon { font-size: 24px; line-height: 1.2; flex-shrink: 0; }
.notify-prompt-main { flex: 1; min-width: 0; }
.notify-prompt-title { font-size: 15.5px; font-weight: 800; margin-bottom: 4px; }

.notify-prompt-actions {
  display: flex;
  gap: 8px;
  margin-top: 12px;
  flex-wrap: wrap;
}
.notify-prompt-actions .btn { padding: 8px 16px; font-size: 14px; }

/* ===== 目標進度排名 ===== */

.rank-card { margin-top: 18px; }
.rank-head { margin-bottom: 4px; }
.rank-section { margin-top: 18px; }
.rank-section:first-of-type { margin-top: 10px; }

.rank-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
}
.rank-row:last-child { border-bottom: 0; }

.rank-no {
  width: 22px;
  flex-shrink: 0;
  text-align: center;
  font-size: 14px;
  font-weight: 800;
  color: var(--muted);
}

.rank-who { flex: 1; min-width: 0; }
.rank-name { font-size: 14.5px; font-weight: 700; }
.rank-unit { font-size: 12.5px; color: var(--muted); margin-top: 1px; }

.rank-figs {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-end;
  flex-shrink: 0;
}

.rank-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--surface-alt);
  border: 1px solid var(--line);
  white-space: nowrap;
}
.rank-chip.is-behind {
  background: #fdeeee;
  border-color: #f2c9c9;
}

.rank-chip-label { font-size: 11.5px; color: var(--muted); }
.rank-chip-pct { font-size: 14px; font-weight: 800; }
.rank-chip.is-behind .rank-chip-pct { color: var(--danger); }

/* 首頁摘要 */

.home-rank { margin-bottom: 18px; }

.home-rank-top {
  display: flex;
  align-items: center;
  gap: 16px;
}

.home-rank-count {
  display: flex;
  align-items: baseline;
  gap: 3px;
  flex-shrink: 0;
  min-width: 66px;
}
.home-rank-num { font-size: 34px; font-weight: 800; line-height: 1; }
.home-rank-unit { font-size: 14px; color: var(--muted); }
.home-rank-count.is-behind .home-rank-num { color: var(--danger); }
.home-rank-count.is-ok .home-rank-num { color: var(--ok); }

.home-rank-say { flex: 1; min-width: 0; }
.home-rank-title { font-size: 15.5px; font-weight: 800; margin-bottom: 3px; }

.home-rank-lines {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}

.home-rank-line {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 0;
  font-size: 13.5px;
}
.home-rank-label { color: var(--muted); flex-shrink: 0; width: 76px; }
.home-rank-who { flex: 1; min-width: 0; font-weight: 700; }
.home-rank-unit2 { font-weight: 400; color: var(--muted); font-size: 12.5px; }
.home-rank-pct { font-weight: 800; flex-shrink: 0; }
.home-rank-pct.is-behind { color: var(--danger); }

/* 手機：名次列改成兩行，橫排會把百分比擠到看不見 */
@media (max-width: 520px) {
  .rank-row { flex-wrap: wrap; }
  .rank-figs { width: 100%; justify-content: flex-start; padding-left: 34px; }
  .home-rank-label { width: 68px; }
}

/* ===== 組織圖 ===== */

.org-bar {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: 14px;
}
.org-search { flex: 1; min-width: 160px; }
.org-dept { width: auto; min-width: 130px; }

.org-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 8px;
  border-bottom: 1px solid var(--line);
}
.org-row:hover { background: var(--surface-alt); }
.org-row.is-hit { background: #fff6e8; }

.org-main { flex: 1; min-width: 0; }
.org-name { font-size: 14.5px; font-weight: 700; }
.org-title { font-weight: 400; color: var(--muted); font-size: 13px; }
.org-left { color: var(--danger); font-size: 12.5px; }
.org-sub { font-size: 12.5px; color: var(--muted); margin-top: 2px; }

.org-fixed {
  padding: 9px 12px;
  background: var(--surface-alt);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 14px;
}

.org-problems { margin: 6px 0 0; padding-left: 20px; }
.org-problems li { margin: 3px 0; }

.confirm-actions { display: flex; gap: 8px; margin-top: 10px; }

/* 縮排由 JS 依螢幕寬度設定（見 paintOrgTree）——
   在這裡用 !important 蓋掉的話，整棵樹會被壓成一條直線，隸屬關係就看不出來了 */
@media (max-width: 520px) {
  .org-row .org-sub { font-size: 12px; }
}

/* 唯讀組織圖：不可點，也就不該有滑鼠變化 */
.org-row-view { cursor: default; }
.org-row-view:hover { background: transparent; }

.org-row-view.is-me { background: #fff6e8; }

.org-me-tag {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
  vertical-align: 1px;
}

/* 「找我自己」的閃爍：三次就停，不要一直閃 */
@keyframes org-flash {
  0%, 100% { background: #fff6e8; }
  50%      { background: #ffd9a8; }
}

.org-row-view.is-flash,
.org-person.is-flash {
  animation: org-flash .55s ease-in-out 3;
}

/* 關掉動畫效果的使用者改成停留一下的實心底色，仍然看得出是哪一列 */
@media (prefers-reduced-motion: reduce) {
  .org-row-view.is-flash,
  .org-person.is-flash { animation: none; background: #ffd9a8; }
}

/* ===== 組織圖：依門市 =====

   部門 › 門市 › 人。同仁反應的是「分不出哪幾個人是同一間店的」，
   所以門市那一層做成有邊框的卡片，而不是靠縮排——人一多，
   縮排幾格在畫面上幾乎看不出差別。 */

.org-dept-block { margin-bottom: 22px; }

.org-dept-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px;
  padding: 0 2px 8px;
  border-bottom: 2px solid var(--line-strong);
  margin-bottom: 10px;
}
.org-dept-name { font-size: 15px; font-weight: 800; }
.org-dept-count { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* 主管那一層：部門與門市之間。同仁心裡的分類是「那是誰管的」 */
.org-mgr { margin: 0 0 14px; }

.org-mgr-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px;
  padding: 6px 2px 6px 0;
}
.org-mgr-name { font-size: 14px; font-weight: 700; }
.org-mgr-count {
  flex: none;
  font-size: 12px; color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* 主管底下的門市往右縮一階，並用一條線串起來 */
.org-mgr-body {
  position: relative;
  padding-left: 16px;
}
.org-mgr-body::before {
  content: '';
  position: absolute;
  left: 3px; top: 0; bottom: 20px;
  border-left: 1px solid var(--line-strong);
}

.org-store {
  position: relative;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  margin-bottom: 8px;
  overflow: hidden;
}
/* 從那條直線接到卡片的橫枝 */
.org-store::before {
  content: '';
  position: absolute;
  left: -13px; top: 20px;
  width: 13px;
  border-top: 1px solid var(--line-strong);
}
.org-store.is-last { margin-bottom: 0; }
.org-store.is-open { border-color: var(--line-strong); }

.org-store-head {
  display: flex; align-items: center; gap: 10px;
  width: 100%;
  padding: 11px 13px;
  border: 0;
  background: transparent;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}
.org-store-head:hover { background: var(--surface-alt); }
.org-store.is-open .org-store-head { background: var(--surface-alt); }

.org-store-caret { color: var(--muted); font-size: 12px; flex: none; }
.org-store-main { flex: 1; min-width: 0; }
.org-store-name { font-size: 14.5px; font-weight: 700; }
/* 店長收合時也看得到——那是找店的人第一個要知道的 */
.org-store-boss {
  display: block;
  font-size: 12.5px; color: var(--muted);
  margin-top: 2px;
}
.org-store-count {
  flex: none;
  font-size: 12.5px; font-weight: 700; color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.org-store-body {
  padding: 4px 13px 10px 30px;
  border-top: 1px solid var(--line);
}

/* 樹枝：每個人左邊一條 ├，最後一個是 └。
   靠 CSS 畫而不是塞字元，字才選得起來、也不會被搜尋比對到 */
.org-person {
  position: relative;
  padding: 8px 4px 8px 18px;
}
.org-person::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  border-left: 1px solid var(--line-strong);
}
.org-person::after {
  content: '';
  position: absolute;
  left: 0; top: 18px;
  width: 12px;
  border-top: 1px solid var(--line-strong);
}
/* 最後一個人：直線只畫到自己那一橫為止，樹枝才收得起來 */
.org-person.is-last::before { bottom: auto; height: 18px; }

/* 姓名後面的標記（新人／已離職）。跟職稱之間留一點距離就好 */
.org-tag { margin-left: 6px; vertical-align: 1px; }

.org-person.is-me { background: #fff6e8; border-radius: 6px; }
/* 已離職卻還掛在圖上：看得到但淡化，人資才知道要更新 */
.org-person.is-left { opacity: .55; }

@media (max-width: 520px) {
  .org-store-body { padding-left: 20px; }
  .org-dept-block { margin-bottom: 16px; }
  /* 手機螢幕窄，樹枝的縮排要讓出來給內容 */
  .org-mgr-body { padding-left: 11px; }
  .org-store::before { left: -8px; width: 8px; }
}

/* ===== 簽核 ===== */

.apv-card { margin-bottom: 16px; }

.apv-head { display: flex; align-items: flex-start; gap: 12px; }
.apv-icon { font-size: 22px; flex-shrink: 0; line-height: 1.3; }
.apv-main { flex: 1; min-width: 0; }
.apv-title { font-size: 15px; font-weight: 800; }
.apv-sub { font-size: 12.5px; color: var(--muted); margin-top: 3px; }

/* 單子的內容區。卡片與細節視窗共用同一份內容（見 apvCardBody） */
.apv-detail { margin-top: 4px; }

.apv-caret { flex-shrink: 0; color: var(--muted); font-size: 13px; line-height: 1.6; }

.apv-status {
  flex-shrink: 0;
  padding: 3px 11px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 700;
  white-space: nowrap;
}

.apv-fields {
  margin: 14px 0;
  padding: 12px 14px;
  background: var(--surface-alt);
  border-radius: 10px;
}
.apv-field { display: flex; gap: 12px; padding: 3px 0; font-size: 13.5px; }
.apv-flabel { color: var(--muted); flex-shrink: 0; width: 82px; }
.apv-fvalue { flex: 1; min-width: 0; overflow-wrap: anywhere; }

.apv-steps { margin-top: 12px; }

.apv-step {
  display: flex;
  gap: 12px;
  padding: 9px 10px;
  border-left: 3px solid var(--line);
  margin-bottom: 6px;
}
/* 目前這一關要一眼看得出來，那是唯一需要有人動作的地方 */
.apv-step.is-now {
  border-left-color: var(--accent);
  background: #fff6e8;
}

.apv-step-no {
  flex-shrink: 0;
  width: 20px;
  font-weight: 800;
  color: var(--muted);
}
.apv-step-who { flex: 1; min-width: 0; }
.apv-step-one {
  display: flex;
  gap: 10px;
  align-items: baseline;
  flex-wrap: wrap;
  font-size: 13.5px;
  padding: 2px 0;
}
.apv-step-act { font-size: 12px; font-weight: 700; }
.apv-step-comment {
  width: 100%;
  font-size: 12.5px;
  color: var(--muted);
  padding-left: 2px;
}

.apv-skipped { margin-top: 8px; }

.apv-actions { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.apv-btns { display: flex; gap: 8px; margin-top: 10px; }
.apv-btns .btn { flex: 1; }

/* 完成／已核准。原本只在 .module-stat 底下有定義，簽核卡片上的「已核准」
   因此一直是沒有底色的白字——看起來像漏了樣式 */
.tone-done { background: #e8f6ee; color: #1d7a4f; }
.tone-wait { background: #fff1de; color: #8a5a10; }
/* 失敗。抓取紀錄那一欄需要一個「壞掉」的顏色，紅底才看得出來 */
.tone-off  { background: #fdeaea; color: #97231f; }
.tone-bad  { background: #fdeeee; color: var(--danger); }
/* 不適用（例如倉庫不列入稽核）。灰的，看得出「不是壞消息也不是好消息」 */
.tone-none { background: var(--surface-alt); color: var(--muted); }

/* ===== 簽核設定 ===== */

.apv-flow { margin-bottom: 16px; }

.apv-cfg-group { margin-bottom: 12px; }

.apv-cfg-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.apv-cfg-no { font-size: 15px; font-weight: 800; }
.apv-cfg-tools { display: flex; gap: 6px; }

.apv-cfg-item {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 8px;
}
.apv-cfg-label { flex: 1 1 40%; min-width: 0; }
.apv-cfg-kind { flex: 0 0 110px; }
.apv-cfg-value { flex: 1 1 40%; min-width: 0; }
.apv-cfg-value select { width: 100%; }

/* 手機：一列塞四個元件會全部擠成一團，改成堆疊 */
@media (max-width: 620px) {
  .apv-cfg-item { flex-wrap: wrap; }
  .apv-cfg-label { flex: 1 1 100%; }
  .apv-cfg-kind { flex: 0 0 auto; }
  .apv-cfg-value { flex: 1 1 auto; }
}

/* ===== 員工購買申請單 ===== */

/* 查到的商品。改成一張單多件之後，這一塊掛在每一列的 .item-info 底下 */
.pur-found {
  padding: 12px 14px;
  background: #f0f7f2;
  border: 1px solid #cfe6d8;
  border-radius: 10px;
}
.pur-found-name { font-size: 15px; font-weight: 800; }
.pur-found-sub { font-size: 13px; color: var(--muted); margin-top: 4px; }

.pur-money {
  margin-top: 16px;
  padding: 14px;
  background: var(--surface-alt);
  border-radius: 10px;
}
.pur-money-row {
  display: flex;
  justify-content: space-between;
  padding: 4px 0;
  font-size: 14px;
}
.pur-money-row.is-total {
  margin-top: 8px;
  padding-top: 10px;
  border-top: 1px solid var(--line-strong);
  font-size: 17px;
  font-weight: 800;
}

.pur-found-full {
  font-size: 12.5px;
  color: var(--muted);
  margin-top: 3px;
  overflow-wrap: anywhere;
}

.pur-branches { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }

.pur-branch {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid #cfe6d8;
  font-size: 12.5px;
}
.pur-branch-qty { font-weight: 800; }

.pur-nostock { margin-top: 10px; }

/* 載具格式不對。說明本來就在那一行，變色即可，不必另外跳一則錯誤 */
.hint.is-bad { color: var(--danger); font-weight: 600; }

/* 只有在途、沒有現貨的門市 */
.pur-branch.is-transit { border-color: var(--line-strong); opacity: .75; }

.pur-transit {
  font-size: 11px;
  color: var(--muted);
  padding: 0 4px;
  border-left: 1px solid var(--line);
}

/* ===== 從信件連結簽核 ===== */

/* 信件連結是獨立一頁，沒有頂列擋著，安全區域要自己讓開 */
.link-approval {
  min-height: 100vh;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: calc(32px + env(safe-area-inset-top, 0px)) 16px
           calc(32px + env(safe-area-inset-bottom, 0px));
  background: var(--bg);
}

.link-card { max-width: 520px; width: 100%; }

.link-icon { font-size: 34px; text-align: center; }
.link-card h2 { text-align: center; margin: 6px 0 4px; }
.link-sub { text-align: center; font-size: 13.5px; color: var(--muted); }
.link-id {
  text-align: center;
  font-size: 12.5px;
  color: var(--muted);
  margin-top: 2px;
}

.link-me {
  margin-top: 14px;
  padding: 10px 14px;
  background: #fff6e8;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 700;
}

/* ===== 商品列（攜出單與員購單共用） =====

   兩張單都是「一列一件：料號、數量、查到什麼」，所以樣式共用一份。
   原本叫 .tko-*，員購單改成可以填多件之後就不再只屬於攜出單了。 */

.item-row {
  padding: 10px 0;
  border-bottom: 1px solid var(--line);
}
.item-row:last-of-type { border-bottom: 0; }

.item-top { display: flex; gap: 8px; align-items: center; }
.item-code { flex: 1; min-width: 0; }
.item-qty { flex: 0 0 86px; }

.item-info { margin-top: 6px; min-height: 18px; }
.item-name { font-size: 13.5px; font-weight: 700; }
.item-nums { font-size: 12.5px; color: var(--muted); margin-left: 8px; }
.item-err { font-size: 12.5px; color: var(--danger); }

.item-table td.num, .item-table th:nth-child(n+2) { text-align: right; }
.item-table { margin-top: 12px; }

/* 手機：料號與數量並排會太擠 */
@media (max-width: 460px) {
  .item-top { flex-wrap: wrap; }
  .item-code { flex: 1 1 100%; }
  .item-qty { flex: 0 0 100px; }
  .item-nums { display: block; margin-left: 0; margin-top: 2px; }
}

/* ===== 財產用品請購單 ===== */

/* 系統自動帶入的申請人、單位、日期。不是輸入欄位，樣子也不該像 */
.asset-who {
  margin: 4px 0 16px;
  padding: 12px 14px;
  background: var(--surface-alt);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.asset-who-row { display: flex; gap: 10px; font-size: 13.5px; }
.asset-who-row + .asset-who-row { margin-top: 5px; }
.asset-who-label { flex: 0 0 72px; color: var(--muted); }
.asset-who-value { font-weight: 700; }

.asset-price { flex: 0 0 110px; }

.asset-spec-bar { display: flex; gap: 8px; align-items: flex-start; margin-top: 8px; }
.asset-spec-pick { flex: 0 0 130px; }
.asset-spec-wrap { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }

.asset-sub { margin-top: 6px; font-size: 13px; font-weight: 700; text-align: right; }

.asset-purpose { min-height: 110px; }

.asset-spec-link {
  display: inline-block;
  margin-top: 3px;
  font-size: 12.5px;
  font-weight: 700;
}

/* 導去別張表單的提示。按鈕與說明同一塊，不要讓人自己去找入口 */
.affairs-redirect { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }

/* ===== 首頁：行政人員的待辦 ===== */

.inbox-card { margin-bottom: 18px; border-left: 4px solid var(--accent); }
.inbox-clear { margin-bottom: 18px; }

.inbox-group + .inbox-group { margin-top: 6px; }

.inbox-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  width: 100%;
  padding: 11px 0 8px;
  border: 0; border-top: 1px solid var(--line);
  background: none; color: inherit; font: inherit;
  text-align: left; cursor: pointer;
}
.inbox-head:hover .inbox-label { color: var(--accent); }

.inbox-icon { font-size: 17px; flex: none; }
.inbox-label { font-weight: 700; font-size: 14.5px; }
.inbox-count { font-size: 13px; color: var(--muted); }
.inbox-count b { font-size: 16px; color: var(--ink); }

.inbox-note { font-size: 12.5px; color: var(--muted); }
.inbox-note.is-late { color: var(--danger); font-weight: 700; }

.inbox-arrow { margin-left: auto; color: var(--muted); font-size: 18px; flex: none; }

.inbox-items { padding-left: 27px; }
.inbox-item {
  display: flex; gap: 10px; align-items: baseline;
  font-size: 12.5px; color: var(--muted);
  padding: 2px 0;
}
.inbox-unit { flex: 0 0 88px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inbox-summary { flex: 1; min-width: 0; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.inbox-time { flex: none; font-size: 11.5px; }

@media (max-width: 560px) {
  .inbox-items { padding-left: 0; }
  .inbox-unit { flex: 0 0 auto; max-width: 40%; }
  /* 手機上時間換行只會把摘要擠掉，摘要比時間重要 */
  .inbox-time { display: none; }
}

/* ===== 總倉標籤申請（門市端） ===== */

.lb-list { margin-top: 6px; }
.lb-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}
.lb-row:last-child { border-bottom: 0; }
/* 已完成的淡化但不藏起來——店員要看得到「這張確實好了」 */
.lb-row.is-done { opacity: .68; }

.lb-main { flex: 1; min-width: 0; }
.lb-title { font-size: 14.5px; font-weight: 700; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.lb-sub { font-size: 12.5px; color: var(--muted); margin-top: 3px; }

.lb-side { flex-shrink: 0; text-align: right; }
.lb-handler { font-size: 11.5px; color: var(--muted); margin-top: 4px; }

/* ===== 標籤申請總覽（管理部） ===== */

.lbo-month { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.lbo-month-label { font-size: 17px; font-weight: 700; min-width: 130px; text-align: center; }

.lbo-charts { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-top: 22px; }
.lbo-chart {
  padding: 16px 18px;
  background: var(--surface-alt);
  border: 1px solid var(--line);
  border-radius: 10px;
}
.lbo-chart-title { font-weight: 700; font-size: 13.5px; margin-bottom: 12px; }

.lbo-bar-row { display: flex; align-items: center; gap: 10px; font-size: 12.5px; }
.lbo-bar-row + .lbo-bar-row { margin-top: 7px; }
.lbo-bar-name { flex: 0 0 88px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lbo-bar-track { flex: 1; height: 9px; background: var(--line); border-radius: 999px; overflow: hidden; }
.lbo-bar-fill { height: 100%; background: var(--accent); border-radius: 999px; }
.lbo-bar-num { flex: 0 0 32px; text-align: right; font-weight: 700; }

.lbo-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 12px; }
.lbo-card {
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-left: 4px solid var(--line-strong);
  border-radius: 10px;
  background: var(--surface);
}
/* 等越久越顯眼：一天以上是紅的，那才是要先處理的 */
.lbo-card.is-new  { border-left-color: #1d7a4f; }
.lbo-card.is-warn { border-left-color: #96631a; }
.lbo-card.is-late { border-left-color: var(--danger); }

.lbo-card-top { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.lbo-store { font-weight: 700; font-size: 14px; }
.lbo-age { font-size: 12px; color: var(--muted); flex-shrink: 0; }
.lbo-card.is-late .lbo-age { color: var(--danger); font-weight: 700; }
.lbo-what { font-size: 13.5px; font-weight: 600; margin: 6px 0 4px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }

@media (max-width: 720px) {
  .lbo-charts { grid-template-columns: 1fr; }
}

/* ===== 人資簽呈 ===== */

/* 簽呈是要讓人寫得下去的，格子太小會逼人寫成一句話 */
.memo-area { min-height: 120px; }

.memo-attach { margin: -4px 0 16px; display: flex; flex-direction: column; gap: 8px; }

.memo-files { display: flex; flex-direction: column; gap: 6px; }
.memo-file {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--surface-alt);
  font-size: 13px;
}
.memo-file-icon { flex: none; }
.memo-file-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.memo-file-size { color: var(--muted); font-size: 12.5px; }

/* 卡片上的附件：一個一顆，點了直接開 */
.apv-files { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0 4px; }
.apv-file {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 11px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  font-size: 13px; font-weight: 600;
  text-decoration: none;
  max-width: 100%;
}
.apv-file:hover { border-color: var(--accent); }
.apv-file span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 關卡條件：一列排完「金額小計　大於　5000　時才要簽」 */
.apv-cfg-cond {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin-top: 10px; padding-top: 10px;
  border-top: 1px dashed var(--line);
}
.apv-cfg-cond-rest { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.apv-cfg-cond-num { flex: 0 0 110px; }

@media (max-width: 460px) {
  .asset-price { flex: 0 0 100px; }
  .asset-spec-bar { flex-wrap: wrap; }
  .asset-spec-pick { flex: 1 1 100%; }
}

.apv-cfg-only {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 2px 0 10px 2px;
  font-size: 13px;
  color: var(--muted);
  cursor: pointer;
}
.apv-cfg-only input { width: 15px; height: 15px; }

/* ===== 可搜尋的人員選擇器 =====
   類別前綴用 psel- 而不是 picker-：門市篩選早就在用 .picker-list 與
   .picker-item，撞名的話那邊的清單會套到這裡的絕對定位而飛出對話框。
   實際發生過一次。 */

.psel { position: relative; }
.psel-input { width: 100%; }

.psel-list {
  position: absolute;
  z-index: 40;
  left: 0;
  right: 0;
  top: calc(100% + 4px);
  max-height: 260px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(23, 39, 46, .12);
}

.psel-item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 13px;
  cursor: pointer;
  border-bottom: 1px solid var(--line);
}
.psel-item:last-child { border-bottom: 0; }
.psel-item:hover { background: var(--surface-alt); }
.psel-item.on { background: #fff6e8; }

.psel-name { font-weight: 700; font-size: 14px; flex-shrink: 0; }
.psel-meta { font-size: 12.5px; color: var(--muted); }

.psel-empty { padding: 12px 13px; font-size: 13px; color: var(--muted); }

/* 手機的輸入框字級要 16px，否則 iOS 會自動放大 */
@media (pointer: coarse) {
  .psel-input { font-size: 16px; }
}

/* ===== 薪資異動單 ===== */

.sal-info {
  margin: -6px 0 14px;
  padding: 12px 14px;
  background: var(--surface-alt);
  border-radius: 10px;
}
.sal-info-row { display: flex; gap: 12px; padding: 3px 0; font-size: 13.5px; }
.sal-info-label { color: var(--muted); width: 76px; flex-shrink: 0; }

.sal-radios { display: flex; flex-wrap: wrap; gap: 10px 16px; }

.sal-radio {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 14px;
  cursor: pointer;
  /* 選項名稱不能斷行：「職等/職稱調整」被拆成一個字一行完全看不懂 */
  white-space: nowrap;
  padding: 6px 12px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
}
.sal-radio:has(input:checked) {
  border-color: var(--accent);
  background: #fff6e8;
}
.sal-radio input { width: 16px; height: 16px; min-height: 0; flex: none; }

.sal-grid { margin-top: 4px; }

.sal-row {
  display: grid;
  grid-template-columns: 108px 1fr 1fr;
  gap: 8px;
  align-items: center;
  margin-bottom: 6px;
}
.sal-label { font-size: 13.5px; color: var(--muted); }

.sal-head {
  font-size: 13px;
  font-weight: 800;
  color: var(--ink);
  padding-bottom: 4px;
}
.sal-head .sal-label { color: var(--ink); }

.sal-total { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line-strong); }
.sal-sum {
  padding: 9px 12px;
  background: var(--surface-alt);
  border-radius: 8px;
  font-weight: 800;
  text-align: right;
}

.sal-diff { margin-top: 12px; text-align: right; font-size: 15px; }
.sal-diff-num { font-weight: 800; font-size: 18px; }
.sal-diff-num.up { color: var(--ok); }
.sal-diff-num.down { color: var(--danger); }

/* 簽核卡上的對照表：有變動的列標出來，那才是要看的 */
.sal-table td.num, .sal-table th:nth-child(n+2) { text-align: right; }
.sal-table tr.sal-changed { background: #fff6e8; }
.sal-table tr.sal-changed td:first-child { font-weight: 700; }
.sal-table tr.sal-total-row { font-weight: 800; border-top: 2px solid var(--line-strong); }

/*
   手機：項目名稱自成一行，兩個輸入框並排。

   min-width: 0 是關鍵——grid 項目的預設最小寬度是內容寬度，
   輸入框有固有寬度，不壓掉的話兩欄會撐破螢幕（右邊那欄被切掉）。
*/
@media (max-width: 560px) {
  .sal-row {
    grid-template-columns: 1fr 1fr;
    gap: 6px;
  }
  .sal-row > * { min-width: 0; }
  .sal-label {
    grid-column: 1 / -1;
    margin-bottom: -2px;
    font-size: 13px;
  }
  /* 標題列在窄螢幕沒有意義：每一列自己都有項目名稱了 */
  .sal-head { display: none; }
  .sal-total { grid-template-columns: 1fr 1fr; }
}

/* 載入畫面的補充說明：等太久時才出現，平常不佔版面 */
.boot-note {
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  line-height: 1.6;
}

/* 目標設定：配件基準的標示（營業額／毛利逐人不同） */
.tg-basis {
  display: inline-block;
  margin-right: 6px;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--surface-alt);
  border: 1px solid var(--line);
  font-size: 11px;
  color: var(--muted);
  vertical-align: middle;
}
.tg-basis.is-gp {
  background: #fff1de;
  border-color: #e8c99a;
  color: #8a5a10;
  font-weight: 700;
}
/* 全品項營業額：那一欄根本不只算配件，要比毛利更顯眼 */
.tg-basis.is-all {
  background: #e8f0fe;
  border-color: #9db8e8;
  color: #1a4a8a;
  font-weight: 700;
}

/* ===== 配件改看毛利的門市選擇 ===== */

.gp-group { margin-bottom: 12px; }

.gp-dept {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 7px 12px;
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  background: var(--surface-alt);
  color: var(--ink);
  font-size: 13.5px;
  font-weight: 700;
  font-family: inherit;
  cursor: pointer;
  text-align: left;
}
.gp-dept.on { border-color: var(--accent); background: #fff1de; }
/* 部分勾選要與「全勾」明顯不同，否則會以為整個部門都設定好了 */
.gp-dept.partial { border-color: #e8c99a; background: #fffaf2; }

.gp-check {
  width: 16px;
  flex: none;
  text-align: center;
  color: var(--accent);
  font-weight: 800;
}
.gp-count { margin-left: auto; font-weight: 400; color: var(--muted); font-size: 12.5px; }

.gp-stores {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px 0 0 12px;
}


/* ===== 店內會議回報 ===== */

/* 整列就是開關；沒回報的那些不能展開（沒東西可看），所以是 disabled */
.mtg-row { padding: 0; }
.mtg-head {
  display: flex; align-items: center; gap: 12px;
  width: 100%; padding: 12px 0;
  border: 0; background: none; color: inherit; font: inherit;
  text-align: left; cursor: pointer;
}
.mtg-head:disabled { cursor: default; }
.mtg-head:not(:disabled):hover .lb-title { color: var(--accent); }

/* 未回報的用左側紅邊標出來——這一頁要回答的就是「誰還沒交」 */
.mtg-row.is-missing { box-shadow: inset 3px 0 0 var(--danger); padding-left: 12px; }

.mtg-detail {
  padding: 4px 0 14px 12px;
  border-left: 2px solid var(--line);
  margin: 0 0 6px 4px;
}
.mtg-item + .mtg-item { margin-top: 12px; }

/* ===== 下載區 ===== */

/* 麵包屑：每一層都可以點回去，最後一層是目前位置所以不能點 */
.dl-crumb {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
  margin-bottom: 14px;
}
.dl-crumb-item {
  border: 0; background: none; padding: 3px 6px; border-radius: 7px;
  font: inherit; font-size: 13.5px; font-weight: 600;
  color: var(--accent); cursor: pointer;
}
.dl-crumb-item:hover { background: var(--surface-alt); }
.dl-crumb-item.is-here { color: var(--ink); cursor: default; }
.dl-crumb-item.is-here:hover { background: none; }
.dl-crumb-sep { color: var(--muted); font-size: 13px; }

.dl-list { margin-top: 10px; }

.dl-row {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
  border-left: 0; border-right: 0; border-top: 0;
  background: none; color: inherit; font: inherit; text-align: left;
}
.dl-row:last-child { border-bottom: 0; }

/* 資料夾整列可點，檔案列不可點（按鈕在右邊）——手感要分得出來 */
.dl-folder { cursor: pointer; }
.dl-folder:hover .dl-name { color: var(--accent); }

.dl-icon { flex: none; font-size: 19px; line-height: 1.3; }

.dl-main { flex: 1; min-width: 0; }
.dl-name { font-size: 14px; font-weight: 600; overflow-wrap: anywhere; }
.dl-sub { font-size: 12.5px; color: var(--muted); margin-top: 2px; }

.dl-acts { flex: none; display: flex; gap: 6px; }
.dl-arrow { flex: none; color: var(--muted); font-size: 18px; }

.dl-note { margin-top: 14px; }

@media (max-width: 520px) {
  /* 手機上按鈕換到下一行，檔名才有完整寬度可以顯示 */
  .dl-row { flex-wrap: wrap; }
  .dl-main { flex: 1 1 100%; order: 1; }
  .dl-icon { order: 0; }
  .dl-acts { order: 2; margin-left: auto; margin-top: 8px; }
  .dl-arrow { order: 2; margin-left: auto; }
}

/* ===== 門市稽核 ===== */

.ad-type {
  margin-left: 8px; padding: 1px 8px; border-radius: 999px;
  background: var(--surface-alt); border: 1px solid var(--line);
  font-size: 11.5px; font-weight: 600; color: var(--muted);
}

.ad-row { gap: 10px; }
.ad-acts { flex: none; display: flex; gap: 6px; flex-wrap: wrap; }
.ad-badge {
  margin-left: 6px; padding: 1px 7px; border-radius: 999px;
  background: rgba(0, 0, 0, .08); font-size: 11.5px; font-weight: 700;
}
.ad-badge.is-done { background: #e8f6ee; color: #1d7a4f; }

/* ---- 打分表 ---- */

.ad-item {
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}
.ad-item:last-of-type { border-bottom: 0; }

/*
   標題一行、按鈕一行，固定直向。

   原本是橫向 flex 加 flex-wrap：標題短的時候按鈕擠得進右邊，標題長就被
   擠到下一行——同一頁裡按鈕一下在右邊一下在下面，稽核人員每一項都要
   重新找按鈕在哪。稽核回報過。

   直向排的代價是每一項高一點，但那些項目本來就要一項一項看，
   位置固定比省高度重要。
*/
.ad-item-head {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 8px;
}
.ad-item-name { font-size: 14.5px; font-weight: 700; line-height: 1.5; }
.ad-item-max { margin-left: 8px; font-size: 12px; font-weight: 600; color: var(--muted); }

/* 分數用按鈕：現場拿手機打，按一下比叫鍵盤打字快，也不會填出範圍外的值 */
.ad-scores { display: flex; gap: 6px; flex-wrap: wrap; }
.ad-score {
  min-width: 42px; padding: 7px 10px;
  border: 1px solid var(--line-strong); border-radius: 9px;
  background: var(--surface); color: var(--ink);
  font: inherit; font-size: 14px; font-weight: 700; cursor: pointer;
}
.ad-score:hover { border-color: var(--accent); }
.ad-score.on { background: var(--accent); border-color: var(--accent); color: #fff; }

/*
   符合／未符合兩選項。

   只有兩顆，按鈕可以做大一點——稽核是在門市現場拿手機單手操作的，
   目標大一點按起來準得多。選中時用綠／紅而不是統一的強調色：
   一整頁掃下來要能一眼看出哪幾項沒過。
*/
.ad-score-2 { min-width: 76px; padding: 9px 14px; font-size: 14.5px; }
.ad-score-2.is-ok.on {
  background: var(--ok); border-color: var(--ok); color: #fff;
}
.ad-score-2.is-no.on {
  background: var(--danger); border-color: var(--danger); color: #fff;
}

.ad-item-desc { font-size: 12.5px; color: var(--muted); line-height: 1.55; }
.ad-item-note { margin-top: 8px; font-size: 13px; }

.ad-total { margin-top: 16px; }

/* ---- 查詢 ---- */

.ad-total-badge {
  flex-shrink: 0; padding: 4px 12px; border-radius: 999px;
  font-size: 13.5px; font-weight: 800;
}

.ad-block + .ad-block { margin-top: 18px; }

.ad-view-item {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
}
.ad-view-item:last-child { border-bottom: 0; }
.ad-main { flex: 1; min-width: 0; }

/* 沒拿滿分的標出來——這一頁店長要看的就是「我掉在哪裡」 */
.ad-view-item.is-lost { box-shadow: inset 3px 0 0 var(--danger); padding-left: 11px; }
.ad-view-score { flex: none; font-size: 14px; font-weight: 800; }
.ad-view-score.is-lost { color: var(--danger); }

.ad-item-note-text { font-size: 12.5px; color: var(--danger); margin-top: 5px; }
.ad-note { margin-top: 14px; }

@media (max-width: 560px) {
  .ad-row { flex-wrap: wrap; }
  .ad-acts { flex: 1 1 100%; margin-top: 8px; }
}

/* ---- 稽核門市設定 ---- */

.ad-cfg-btn { margin-left: auto; }

.ad-cfg-count {
  font-size: 13px; color: var(--muted); font-weight: 600;
  padding-bottom: 10px; border-bottom: 1px solid var(--line);
}

.ad-cfg-row { gap: 10px; }
/* 關掉的淡化但不藏起來——設定頁要看得到全部，才知道自己關了哪些 */
.ad-cfg-row.is-off .lb-main { opacity: .5; }

.ad-cfg-acts { flex: none; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ad-cfg-type { flex: none; }
.ad-cfg-type button { padding: 6px 12px; font-size: 13px; }

.ad-unset {
  margin-left: 8px; padding: 1px 8px; border-radius: 999px;
  background: #fdf3e3; border: 1px solid #f0dcb4; color: #96631a;
  font-size: 11.5px; font-weight: 700;
}

@media (max-width: 560px) {
  .ad-cfg-row { flex-wrap: wrap; }
  .ad-cfg-acts { flex: 1 1 100%; margin-top: 8px; }
}

/* 不列入稽核的門市：一行帶過，不佔清單的位置 */
.ad-excluded {
  margin-top: 16px; padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: 12.5px; color: var(--muted);
}
.ad-excluded-label {
  display: inline-block; margin-right: 8px;
  padding: 1px 8px; border-radius: 999px;
  background: var(--surface-alt); border: 1px solid var(--line);
  font-weight: 700;
}

.ad-nonsales {
  margin-left: 8px; padding: 1px 8px; border-radius: 999px;
  background: var(--surface-alt); border: 1px solid var(--line);
  font-size: 11.5px; font-weight: 600; color: var(--muted);
}

/* ===== 各系統專案相關資訊 ===== */

.biz-card + .biz-card { margin-top: 14px; }

/*
   檢測標準：分類 → 可選項目。

   門市收機時是照著一項一項對的，所以分類要一眼看得到（左側粗體），
   選項排成一顆一顆的標籤而不是一長串文字——一長串在手機上會斷在
   奇怪的地方，而且掃視時很容易看漏中間那一項。
*/
.biz-spec { display: flex; flex-direction: column; gap: 14px; margin-top: 10px; }

.biz-spec-grp {
  padding-left: 11px;
  border-left: 3px solid var(--line-strong);
}
.biz-spec-name {
  font-size: 13.5px; font-weight: 700; color: var(--text);
  margin-bottom: 6px;
}
.biz-spec-rows { display: flex; flex-direction: column; gap: 6px; }

.biz-spec-row {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 10px;
}
.biz-spec-label {
  font-size: 12.5px; color: var(--muted); font-weight: 600;
  min-width: 104px;
}
.biz-spec-vals { display: flex; flex-wrap: wrap; gap: 6px; }

.biz-spec-val {
  display: inline-block;
  padding: 3px 9px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--surface-alt);
}

/* 窄螢幕：標籤自己一行，選項才有足夠寬度不被擠成一欄 */
@media (max-width: 520px) {
  .biz-spec-label { min-width: 100%; }
}

/* 說明區塊：規章文字，行距放寬一點才讀得下去 */
.biz-note { background: var(--surface-alt); }
.biz-line {
  margin: 0 0 8px;
  font-size: 13.5px;
  line-height: 1.75;
  color: var(--ink);
}
.biz-line:last-child { margin-bottom: 0; }

.biz-links { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; }

.biz-link {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 8px;
  border-radius: 9px;
  color: inherit; text-decoration: none;
  font-size: 14px; font-weight: 600;
}
.biz-link:hover { background: var(--surface-alt); }
.biz-link:hover .biz-link-name { color: var(--accent); }
.biz-link-icon { flex: none; font-size: 17px; }
.biz-link-name { flex: 1; min-width: 0; overflow-wrap: anywhere; }

/* ===== 名片申請 ===== */

.nc-row { gap: 10px; }
.nc-acts { flex: none; display: flex; align-items: center; gap: 6px; }
.nc-acts .input { width: auto; min-width: 110px; margin: 0; padding: 7px 10px; font-size: 13.5px; }

@media (max-width: 560px) {
  .nc-row { flex-wrap: wrap; }
  .nc-acts { flex: 1 1 100%; margin-top: 8px; }
  .nc-acts .input { flex: 1; }
}

/* 名片申請的附件：一個附件一塊，底下跟著它的用途 */
.nc-file {
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--surface-alt);
}
.nc-file + .nc-file { margin-top: 8px; }
.nc-file-top { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.nc-file-use { margin: 8px 0 0 !important; font-size: 13px; }

/* ===== iPhone 18 預購現況 ===== */

.po-bars { margin-bottom: 16px; }
.po-bar-name { flex: 0 0 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.po-bar-pct { flex: 0 0 38px; text-align: right; font-size: 11.5px; color: var(--muted); }

.po-filters {
  display: flex; flex-wrap: wrap; gap: 10px;
  padding-bottom: 14px; margin-bottom: 6px;
  border-bottom: 1px solid var(--line);
}
.po-filter { flex: 1 1 140px; min-width: 0; }
.po-filter label { display: block; font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.po-filter .input { width: 100%; margin: 0; padding: 8px 10px; font-size: 13.5px; }
.po-search { flex: 2 1 200px; }
/* 清除鈕跟著篩選器一起換行，寬度不要被拉開 */
.po-filter-clear { flex: 0 1 auto; }
.po-filter-clear .btn { white-space: nowrap; }

.po-detail { padding-top: 4px; }

/* 撥號與簡訊：門市看這一頁的目的就是打電話，中間不該再多一步複製貼上 */
.po-contact { display: flex; flex-wrap: wrap; gap: 8px; margin: 12px 0; }

/*
 * 處理這一筆：狀態、進度、服務人員、備註，一起改、一顆按鈕存。
 *
 * 原本是兩塊各自帶一顆儲存鍵，同仁分不清哪一顆存哪一些而漏存。
 */
.po-edit-box {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}

/* 三個下拉並排；窄螢幕自動落成一欄，欄位標題才不會被擠掉 */
.po-edit-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px;
}
.po-edit-box .field { margin: 0; }
.po-edit-box label {
  display: block;
  margin-bottom: 4px;
  font-size: 12.5px; font-weight: 700;
  color: var(--muted);
}
.po-edit-box .input { margin: 0; padding: 8px 10px; font-size: 13.5px; width: 100%; }
.po-edit-box > .field { margin-top: 10px; }
.po-edit-box > .btn { margin-top: 12px; }

@media (max-width: 560px) {
  .po-bar-name { flex: 0 0 96px; }
}

/* 各門市預購的名次 */
.po-rank {
  flex: none; width: 26px;
  font-size: 14px; font-weight: 800; color: var(--muted);
  text-align: center;
}
.po-rank.is-top { color: var(--accent); }
/* 一筆都沒有的店淡化但不藏起來——那正是要追的那幾間 */
.po-zero .lb-title, .po-zero .lb-sub { opacity: .55; }

/* ===== 行政疏失 ===== */

/* 篩選列：桌機一排，窄螢幕自己折行 */
.filter-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 10px 14px;
  margin-bottom: 12px;
}
.filter-row .field { margin: 0; }

.fa-item { border-top: 1px solid var(--line); }
.fa-item:first-of-type { border-top: 0; }

/*
   標題列點了展開。整列可點而不是只有小三角——手機上那個三角形
   要按得很準，而整列是最容易命中的目標。
*/
.fa-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 11px 4px; cursor: pointer;
}
.fa-head:hover { background: var(--surface-alt); }

.fa-head-main { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; min-width: 0; }
.fa-head-right { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }

.fa-date { font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.fa-code {
  font-size: 12px; font-weight: 700; color: var(--text);
  padding: 1px 7px; border: 1px solid var(--line); border-radius: 999px;
}
.fa-person { font-size: 14px; font-weight: 700; color: var(--text); }
.fa-store { font-size: 12.5px; color: var(--muted); }

.fa-amt {
  font-size: 14px; font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums;
}
/* 撤銷或異議中：金額變灰，但仍然看得到原本判多少 */
.fa-amt.is-zero { color: var(--muted); font-weight: 600; }

.fa-status {
  font-size: 11.5px; font-weight: 700;
  padding: 2px 8px; border-radius: 999px; white-space: nowrap;
}
.st-open { background: var(--surface-alt); color: var(--muted); }
/* 異議中用強調色而不是紅色：那不是錯誤，是「還沒定案」 */
.st-dispute { background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent); }
.st-closed { background: color-mix(in srgb, var(--ok) 14%, transparent); color: var(--ok); }
.st-void { background: var(--surface-alt); color: var(--muted); text-decoration: line-through; }

/*
   狀態類別是 'st-' 加上 faultStatusClass() 算出來的字尾，
   check_css_classes.py 掃不到這種動態組出來的名字，會回報成「CSS 定義了但沒用到」。
   四個都在用，不要刪。
*/

.fa-caret { font-size: 12px; color: var(--muted); width: 12px; text-align: center; }

.fa-body-detail {
  padding: 4px 4px 14px;
  border-left: 3px solid var(--line-strong);
  margin: 0 0 10px 4px;
  padding-left: 12px;
}

.fa-field { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-bottom: 7px; }
.fa-label { font-size: 12px; color: var(--muted); font-weight: 600; min-width: 68px; }
.fa-value { font-size: 13.5px; color: var(--ink); line-height: 1.65; flex: 1; min-width: 0; }

/* 異議原文：引用的樣子，讓裁決的人一眼分得出哪段是當事人說的 */
.fa-quote {
  background: var(--surface-alt);
  border-radius: 10px;
  padding: 11px 13px;
  margin: 10px 0;
  font-size: 13.5px;
  line-height: 1.7;
  color: var(--ink);
}
.fa-quote-head { font-size: 12px; font-weight: 700; color: var(--muted); margin-bottom: 5px; }

.fa-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }

.fa-filelist { display: flex; flex-direction: column; gap: 3px; margin-top: 6px; }
.fa-fileitem { font-size: 12.5px; color: var(--muted); }

@media (max-width: 520px) {
  /* 窄螢幕：狀態與金額移到第二行，標題列才不會擠成兩個字換一行 */
  .fa-head { flex-wrap: wrap; }
  .fa-head-right { width: 100%; justify-content: flex-start; }
  .fa-label { min-width: 100%; }
}

/* 疏失規範設定：一條一列，欄寬照內容長短分配 */
.fc-list { display: flex; flex-direction: column; gap: 6px; margin: 10px 0; }

.fc-row {
  display: grid;
  grid-template-columns: 140px 76px 1fr 110px 150px 32px;
  gap: 6px;
  align-items: center;
}
.fc-row input {
  padding: 7px 9px;
  font-size: 13px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  color: var(--ink);
  min-width: 0;
}
.fc-row input:disabled { background: var(--surface-alt); color: var(--muted); }
.fc-row input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

.fc-del {
  border: 0; background: transparent; cursor: pointer;
  color: var(--muted); font-size: 15px; padding: 4px;
  border-radius: 6px;
}
.fc-del:hover { background: var(--surface-alt); color: var(--danger); }

@media (max-width: 900px) {
  /*
     窄螢幕改成一條一張卡：六欄擠在手機上每一欄只剩幾十像素，
     條文那一欄根本看不到自己打了什麼。
  */
  .fc-row {
    grid-template-columns: 1fr 1fr;
    gap: 5px;
    padding: 9px;
    border: 1px solid var(--line);
    border-radius: 10px;
  }
  .fc-text { grid-column: 1 / -1; }
  .fc-note { grid-column: 1 / -1; }
  .fc-del { grid-column: 2; justify-self: end; }
}

/* 分期標記。清單上會有三筆看起來一樣的單，要一眼分得出是第幾期 */
.fa-part {
  font-size: 11.5px; font-weight: 700; color: var(--accent);
  padding: 1px 7px; border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  white-space: nowrap;
}

/* 異議 vs 金牌：兩條路差很多，做成兩張可點的卡而不是下拉選單 */
.fa-pick { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }

.fa-pick-opt {
  text-align: left;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--surface);
  cursor: pointer;
  font: inherit;
  color: inherit;
}
.fa-pick-opt:hover { border-color: var(--line-strong); }
.fa-pick-opt.is-on {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}
.fa-pick-title { font-size: 13.5px; font-weight: 700; color: var(--text); }
.fa-pick-desc { font-size: 12.5px; color: var(--muted); line-height: 1.6; margin-top: 3px; }

/* ===== 人員多選 ===== */

.pk { border: 1px solid var(--line); border-radius: 11px; overflow: hidden; }

.pk-search {
  width: 100%;
  padding: 10px 12px;
  border: 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
  background: var(--surface);
  color: var(--ink);
}
.pk-search:focus { outline: 2px solid var(--accent); outline-offset: -2px; }

/* 已選的人放在清單上方：捲到下面時仍然看得到自己選了誰 */
.pk-summary {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  padding: 9px 11px;
  background: var(--surface-alt);
  border-bottom: 1px solid var(--line);
  min-height: 40px;
}
.pk-none { font-size: 12.5px; color: var(--muted); }
.pk-count { font-size: 12.5px; font-weight: 700; color: var(--text); margin-right: 2px; }

.pk-chip {
  font: inherit; font-size: 12px;
  padding: 3px 9px;
  border: 1px solid var(--accent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  color: var(--accent);
  cursor: pointer;
}
.pk-chip:hover { background: color-mix(in srgb, var(--accent) 20%, transparent); }

.pk-clear {
  font: inherit; font-size: 12px;
  border: 0; background: transparent; color: var(--muted);
  cursor: pointer; text-decoration: underline;
  margin-left: auto;
}

/* 清單自己捲，不要把整頁推長——三百多人的話整頁會捲不完 */
.pk-list { max-height: 320px; overflow-y: auto; }

.pk-grp + .pk-grp { border-top: 1px solid var(--line); }

.pk-grp-head {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 11px;
  background: var(--surface-alt);
  position: sticky; top: 0;      /* 捲動時看得到現在在哪一間店 */
  z-index: 1;
}
.pk-grp-name { font-size: 12.5px; font-weight: 700; color: var(--text); }
.pk-grp-n { font-size: 11.5px; color: var(--muted); }
.pk-grp-all {
  font: inherit; font-size: 11.5px;
  margin-left: auto;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 2px 9px;
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
}
.pk-grp-all:hover { color: var(--text); border-color: var(--accent); }

.pk-row {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 11px;
  cursor: pointer;
  font-size: 13.5px;
}
.pk-row:hover { background: var(--surface-alt); }
.pk-row.is-on { background: color-mix(in srgb, var(--accent) 7%, transparent); }
.pk-row input { width: 16px; height: 16px; flex-shrink: 0; }

.pk-row-main { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; min-width: 0; }
.pk-name { color: var(--ink); }
.pk-meta { font-size: 11.5px; color: var(--muted); }

/* 必收的通知類型：看得出是開著的，但點不動 */
.pref-switch.is-locked { opacity: .55; cursor: not-allowed; }

/* 還在異議期限內的單：左側標一條，混在已結案的裡面才看得出來 */
.fa-item.is-urgent {
  border-left: 3px solid var(--accent);
  background: color-mix(in srgb, var(--accent) 4%, transparent);
}
.fa-item.is-urgent .fa-head { padding-left: 9px; }

.fa-due {
  font-size: 11.5px; font-weight: 700; color: var(--accent);
  white-space: nowrap;
}

/* ===== 首頁：下一個行程 ===== */

.nev {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  margin-bottom: 14px;
  cursor: pointer;
}
.nev:hover { border-color: var(--line-strong); }
.nev-icon { font-size: 22px; flex-shrink: 0; }
.nev-main { flex: 1; min-width: 0; }
.nev-title {
  font-size: 14.5px; font-weight: 700; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nev-meta { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.nev-loc { color: var(--muted); }

.nev-count {
  font-size: 13px; font-weight: 700; color: var(--muted);
  white-space: nowrap; flex-shrink: 0;
}
/* 一小時內的用強調色——那是「該準備了」而不是「還早」 */
.nev-count.is-soon { color: var(--accent); }

/* ===== 行事曆 ===== */

.cal-switch {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; padding: 12px 14px;
}
.cal-switch-label { font-size: 15px; font-weight: 700; color: var(--text); }

.cal-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 4px;
  cursor: pointer;
}
.cal-row + .cal-row { border-top: 1px solid var(--line); }
.cal-row:hover { background: var(--surface-alt); }

.cal-row-day {
  width: 44px; flex-shrink: 0; text-align: center;
  border-right: 1px solid var(--line);
}
.cal-row-d {
  font-size: 18px; font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums; line-height: 1.1;
}
.cal-row-w { font-size: 11px; color: var(--muted); }

.cal-row-main { flex: 1; min-width: 0; }
.cal-row-title { font-size: 14px; font-weight: 600; color: var(--ink); }
.cal-row-meta { font-size: 12.5px; color: var(--muted); margin-top: 2px; }

.cal-people, .cal-copied {
  font-size: 11.5px; color: var(--muted);
  padding: 2px 8px; border: 1px solid var(--line); border-radius: 999px;
  white-space: nowrap; flex-shrink: 0;
}

.cal-check { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.cal-check input { width: 16px; height: 16px; }

/* ===== 月曆格 ===== */

.mg {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  margin-top: 10px;
}

.mg-head {
  background: var(--surface-alt);
  padding: 7px 4px;
  text-align: center;
  font-size: 12px; font-weight: 700; color: var(--muted);
}
.mg-head.is-weekend { color: var(--accent); }

.mg-cell {
  background: var(--surface);
  min-height: 76px;
  padding: 4px 5px;
}
.mg-cell.is-blank { background: var(--surface-alt); }
.mg-cell.is-weekend { background: color-mix(in srgb, var(--surface-alt) 60%, var(--surface)); }
.mg-cell.is-today { background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }

.mg-day {
  font-size: 12px; font-weight: 700; color: var(--muted);
  font-variant-numeric: tabular-nums; margin-bottom: 3px;
}
.mg-cell.is-today .mg-day { color: var(--accent); }

.mg-ev {
  font-size: 11px; line-height: 1.35;
  padding: 3px 5px; margin-bottom: 2px;
  border-radius: 5px;
  background: var(--surface-alt);
  color: var(--ink);
  cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mg-ev:hover { background: var(--line); }
/* 指定我參加的用強調色，一眼分得出哪幾天要到 */
.mg-ev.is-mine {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent); font-weight: 600;
}

@media (max-width: 640px) {
  /*
     手機上格子只有五十幾像素寬，標題一個字都放不下。
     改成只顯示一個點，詳細內容看下面的清單。
  */
  .mg-cell { min-height: 52px; padding: 3px; }
  .mg-ev {
    font-size: 0;
    height: 5px; padding: 0; margin: 0 auto 3px;
    width: 60%; border-radius: 3px;
    background: var(--line-strong);
  }
  .mg-ev.is-mine { background: var(--accent); }
}

/* ===== 複製行程 ===== */

.cc-row {
  display: flex; align-items: center; gap: 9px;
  padding: 9px 4px;
}
.cc-row + .cc-row { border-top: 1px solid var(--line); }
.cc-row.is-done { opacity: .5; }
.cc-row input[type="checkbox"] { width: 16px; height: 16px; flex-shrink: 0; }

.cc-main { flex: 1; min-width: 0; }
.cc-title { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.cc-meta { font-size: 12px; color: var(--muted); margin-top: 2px; }

.cc-day {
  width: 58px; padding: 6px 8px;
  border: 1px solid var(--line); border-radius: 8px;
  font-size: 13px; text-align: center;
  background: var(--surface); color: var(--ink);
}
.cc-dayunit { font-size: 12px; color: var(--muted); }

/* 行程編輯的參加名單：說明與選單之間留一點距離 */
.cal-people-field { margin-top: 4px; }
.cal-people-field .hint { margin-bottom: 8px; }

/* ===== 行銷活動用品申請單 ===== */

/* 自動帶入的三項：看得到但不能改 */
.pm-auto {
  background: var(--surface-alt);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 14px;
}
.pm-auto-row { display: flex; gap: 12px; font-size: 13.5px; }
.pm-auto-row + .pm-auto-row { margin-top: 5px; }
.pm-auto-label { color: var(--muted); min-width: 64px; }
.pm-auto-value { color: var(--ink); font-weight: 600; }

/* 一份是什麼要講清楚——「申請 3 份」對不同品項意思差很多 */
.pm-unit {
  font-size: 13px; color: var(--muted);
  padding: 8px 11px;
  background: var(--surface-alt);
  border-radius: 8px;
  margin-bottom: 10px;
}

/* 門市現有庫存：這張單的重點，要顯眼 */
.pm-stock {
  margin-top: 10px;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 0 10px 10px 0;
  background: color-mix(in srgb, var(--accent) 5%, transparent);
}
.pm-stock.is-bad { border-left-color: var(--danger); background: #fef2f2; }
.pm-stock-head { font-size: 14px; font-weight: 700; color: var(--text); }

/* 其他活動的多筆輸入 */
.pm-row {
  display: grid;
  grid-template-columns: 1fr 110px 90px 32px;
  gap: 6px;
  margin-bottom: 6px;
}
.pm-row input {
  padding: 8px 10px; font-size: 13.5px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface); color: var(--ink);
  min-width: 0;
}
.pm-row input:focus { outline: 2px solid var(--accent); outline-offset: -1px; }

@media (max-width: 560px) {
  /* 窄螢幕：品名自己一行，成本與份數並排 */
  .pm-row { grid-template-columns: 1fr 1fr 32px; }
  .pm-name { grid-column: 1 / -1; }
}

/* 預計成本 */
.pm-total {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px 12px;
  margin: 14px 0;
  padding: 12px 14px;
  background: var(--surface-alt);
  border-radius: 10px;
}
.pm-total:empty { display: none; }
.pm-total-label { font-size: 13px; color: var(--muted); }
.pm-total-value {
  font-size: 20px; font-weight: 700; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.pm-total-detail { font-size: 12.5px; color: var(--muted); }
.pm-total-note {
  width: 100%; font-size: 12.5px; color: var(--accent); font-weight: 600;
}

/* 簽核卡片上的即時庫存 */
.pm-live {
  margin: 12px 0;
  padding: 11px 13px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 0 10px 10px 0;
  background: color-mix(in srgb, var(--accent) 5%, transparent);
}
.pm-live-head { font-size: 13px; font-weight: 700; color: var(--text); margin-bottom: 6px; }
.pm-live-body { min-height: 20px; }
.pm-live-total { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.pm-live-store { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.pm-live-item { font-size: 12.5px; color: var(--muted); }
.pm-live-qty {
  font-size: 18px; font-weight: 700; color: var(--accent);
  font-variant-numeric: tabular-nums; margin-left: auto;
}
.pm-live-line {
  display: flex; justify-content: space-between; gap: 10px;
  font-size: 12.5px; color: var(--muted); margin-top: 4px;
}
.pm-live-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.pm-live-num { font-variant-numeric: tabular-nums; }

/* ===== 預購碼協尋 ===== */

/*
   門市人員要照著念給客人聽，所以數字要大到隔著櫃台也看得清楚。
   一個人可能有多筆預購，每一筆各自一塊。
*/
.po-code-box {
  margin-bottom: 12px;
  padding: 16px;
  border: 2px dashed var(--accent);
  border-radius: 14px;
  background: rgba(255, 255, 255, .04);
  text-align: center;
}
.po-code-label { font-size: 13px; color: var(--muted); margin-bottom: 6px; }
.po-code-value {
  font-size: 40px; font-weight: 800; letter-spacing: .18em;
  color: var(--accent); line-height: 1.2;
  font-variant-numeric: tabular-nums;
  user-select: all;
}
.po-code-note { font-size: 12.5px; color: var(--muted); line-height: 1.6; margin-top: 8px; }

/* ===== 匯入進度 ===== */

/*
   上傳期間唯一會動的東西。轉檔那一段後端完全沒有回音，所以百分比是
   估的——重點不是準，是讓人看得出來「還在跑」而不是「掛了」。
*/
.imp-progress { margin: 14px 0; }
.imp-progress-head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 12px; margin-bottom: 6px;
}
.imp-progress-text { font-size: 13px; color: var(--muted); }
.imp-progress-pct {
  font-size: 13px; font-weight: 700; color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.imp-progress-bar {
  height: 8px; border-radius: 999px; overflow: hidden;
  background: rgba(255, 255, 255, .1);
}
.imp-progress-fill {
  height: 100%; width: 0;
  border-radius: 999px;
  background: var(--accent);
  transition: width .4s ease;
}

/* ===== 身份功能設定（管理部專區 → 設定）=====

   兩欄並排：左邊是「這個身份手上有什麼」，右邊是「還沒開放的」。
   拖拉與點一下都能把功能在兩欄之間搬動（見 app.js 的 rtBindDrag）。 */

.rt-roles {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin: 18px 0 6px;
}
.rt-role {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  padding: 9px 14px;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: var(--surface);
  font-family: inherit;
  cursor: pointer;
}
.rt-role:hover { border-color: var(--accent); }
.rt-role.on { background: var(--topbar); border-color: var(--topbar); color: #fff; }
.rt-role-name { font-size: 14px; font-weight: 700; }
.rt-role-n { font-size: 11.5px; opacity: .7; }

.rt-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin: 16px 0 18px;
  align-items: start;
}
@media (max-width: 820px) {
  .rt-cols { grid-template-columns: 1fr; }
}

.rt-col {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  /* 拖過來時整欄亮起來。沒有這個回饋的話，放手前完全不知道會掉在哪一邊 */
  transition: border-color .12s, background .12s;
}
.rt-col.is-over { border-color: var(--accent); background: #fff7f2; }
.rt-col-head {
  padding: 12px 14px 8px;
  border-bottom: 1px solid var(--line);
}
.rt-col-title { font-size: 14.5px; font-weight: 700; }
.rt-col-body { padding: 10px 14px 16px; min-height: 120px; }

.rt-group-label {
  margin: 12px 0 6px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .06em;
  color: var(--muted);
}
.rt-chips { display: flex; flex-wrap: wrap; gap: 7px; }

.rt-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 7px 12px;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  background: var(--surface-alt);
  font-size: 13.5px; font-weight: 600;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
}
.rt-chip:hover { border-color: var(--accent); }
.rt-chip.is-dragging { opacity: .35; }
.rt-chip.is-pinned {
  cursor: default;
  background: var(--surface);
  border-style: dashed;
  color: var(--muted);
}
.rt-chip.is-pinned:hover { border-color: var(--line-strong); }
.rt-lock { font-size: 11px; }

/* 颱風警報地區：縣市多，用可自動換行的選取磚。 */
.ta-tools { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 12px; }
.ta-region-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 8px;
  margin-bottom: 14px;
}
.ta-region {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px;
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  background: var(--surface);
  font-size: 13.5px; font-weight: 600;
  cursor: pointer;
}
.ta-region.on { border-color: var(--accent); background: #fff7f2; }
.ta-region input { accent-color: var(--accent); }

/* 跟著手指／游標走的那一份。pointer-events 一定要關掉，
   否則 elementFromPoint 只會抓到它自己，永遠判斷不出放在哪一欄。 */
.rt-ghost {
  position: fixed;
  transform: translate(-50%, -50%);
  pointer-events: none;
  z-index: 200;
  box-shadow: 0 8px 20px rgba(0,0,0,.24);
  background: #fff;
  opacity: .95;
}

.rt-empty { font-size: 13px; color: var(--muted); padding: 8px 0; }

.rt-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  margin: 4px 0 14px;
}

/* ===== 兼任身份編輯（員工資料庫 → 點開某個人）===== */

.alt-row {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface-alt);
  padding: 12px 14px 14px;
  margin: 12px 0;
}
.alt-row-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 10px;
}
.alt-row-title { font-size: 13.5px; font-weight: 700; }
.alt-row .field { margin-bottom: 10px; }

.alt-off {
  display: flex; align-items: center; gap: 8px;
  font-size: 13.5px;
  margin: 6px 0 2px;
  cursor: pointer;
}
.alt-off input { width: 16px; height: 16px; }

/* 兩個下拉留空白時會沿用本職，光看選單不容易當場算出結果，直接把結果寫出來 */
.alt-preview {
  margin-top: 10px;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--surface);
  border: 1px dashed var(--line-strong);
  font-size: 13px; font-weight: 600;
  color: var(--muted);
}

/* ===== 獎金手機設定 ===== */

/* 一段級距：「第 [1] 台起，每台 [500] 元　刪除」 */
.pb-tier {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin: 8px 0;
}
.pb-tier input {
  width: 96px;
  flex: none;
}
.pb-tier-lead { font-size: 13.5px; color: var(--muted); white-space: nowrap; }

/* 目標的對象：門市統一或某一位同仁 */
.pt-who {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 13px;
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  background: var(--surface);
  font-family: inherit; font-size: 13.5px; font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}
.pt-who:hover { border-color: var(--accent); }
.pt-who.on { background: var(--topbar); border-color: var(--topbar); color: #fff; }
/* 選中時裡面的「已設定」標籤要看得見，深底配淺綠會糊掉 */
.pt-who.on .pill { background: rgba(255,255,255,.22); color: #fff; }

/* 料號查詢：輸入框加一顆按鈕，手機上會自己換行 */
.pb-lookup { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 2px; }
.pb-lookup input { flex: 1 1 220px; min-width: 0; }
.pb-lookup .btn { flex: 0 0 auto; }


/* 達成率沒算到的部分：分子只算有設目標的人，差額要講出來 */
.goal-note {
  margin-top: 8px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

/* 獎金目標的對象清單：一間店一段，店名當小標 */
.pt-store-label {
  margin: 14px 0 6px;
  font-size: 12.5px; font-weight: 700; letter-spacing: .04em;
  color: var(--muted);
}
.pt-store-label:first-of-type { margin-top: 6px; }

/* ===== 簽核：我送出的／我簽過的 清單 ===== */

.apv-filter { padding-bottom: 14px; }

/* 整列可點，點了跳出那張單的完整內容 */
.apv-list table.data tbody tr.row-click { cursor: pointer; }
.apv-list table.data tbody tr.row-click:hover { background: var(--surface-alt); }

.apv-row-icon { margin-right: 6px; }

/* 更新後不再符合篩選的那一筆：留著並說明原因，
   靜靜消失會讓人以為更新失敗，靜靜留著又像篩選壞了 */
.po-filtered-note { margin: 0 0 8px; }

/* ===== 預購：服務人員 ===== */

/* 誰在跟這張單。收合時也看得到——「還沒有人接」是店長掃清單時在找的東西 */
.po-who {
  display: flex; align-items: center; gap: 6px;
  margin-top: 4px;
  font-size: 13px;
  font-weight: 700;
}
.po-who-tag {
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--surface-alt);
  color: var(--muted);
  font-size: 11.5px;
  font-weight: 700;
}
/* 客人指名的要看得出來：那是改動前要先想一下的單 */
.po-who-tag.is-customer { background: #fdf0dc; color: #96601a; }
.po-who-tag.is-none { background: #fce8e8; color: #b13333; }

.po-tools { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }

/* ===== 預購配貨 ===== */

/* 配貨以規格計數：機型一行、容量與顏色一行。顏色是配錯最常見的地方，粗體 */
.alloc-model { font-weight: 700; }
.alloc-spec { font-size: 13px; font-weight: 700; color: var(--accent); }

/* 總倉填數量的那一格：短一點，一列一格，負數是收回 */
.alloc-qty { width: 84px; padding: 8px 10px; text-align: right; font: inherit;
  border: 1px solid var(--line-strong); border-radius: 8px; }
table.data.alloc-grid th:first-child, table.data.alloc-grid td:first-child { min-width: 200px; }

.alloc-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.alloc-bar .field { margin: 0; min-width: 180px; }

/* 選中的那一列。配貨是「先選規格再選單子」，選了什麼要一直看得到 */
table.data tbody tr.row-on { background: #fff6e8; }
/* 門市配貨：跟選的規格對不上的預約單 */
table.data tbody tr.row-mismatch { background: #fdf1f1; }
/* 配貨中：整列變淡，等伺服器回來；配好：整列變綠，幾秒後收掉 */
table.data tbody tr.is-busy { opacity: .5; }
table.data tbody tr.row-done { background: #e4f5ec; transition: background .3s; }
.alloc-want-color { font-weight: 700; }
.alloc-diff { font-size: 12px; color: var(--danger); font-weight: 700; margin-top: 2px; }

/* 寶藏遠征：demo 原始背景與雙格寶箱素材。 */
.tr-world{color:#f8ecd0;padding:clamp(16px,3vw,36px);border-radius:24px;background:linear-gradient(180deg,#071217a6,#050e14f0),url('/assets/treasure/expedition-base.png') center top/cover;box-shadow:0 20px 60px #07141b33}
.tr-hero{text-align:center;padding:12px 0 24px}.tr-eyebrow{color:#eed294;font-size:11px;font-weight:800;letter-spacing:.18em}.tr-hero h2{color:#fff3ca;font-size:clamp(28px,4vw,46px);margin:12px 0;text-shadow:0 3px 20px #0009}.tr-hero p{color:#ded4bc;margin:10px 0}.tr-rule{font-size:clamp(14px,2vw,18px)}
.tr-stats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}.tr-stats>div{padding:18px 10px;border:1px solid #eaca8640;background:#081923b8;border-radius:14px;text-align:center}.tr-stats span{display:block;font-size:12px;color:#cec6b0}.tr-stats strong{display:block;color:#ffe8a4;font-size:clamp(20px,3vw,32px);margin-top:6px}
.tr-toolbar{display:flex;gap:12px;align-items:center;justify-content:space-between;margin:22px 0 16px;flex-wrap:wrap}.tr-world .btn{color:#f9eac6;border-color:#d4ad6266;background:#16282d}.tr-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(100px,1fr));gap:12px}
.tr-chest{position:relative;min-width:0;overflow:hidden;padding:12px 4px 10px;border:1px solid #ddb76c66;background:linear-gradient(145deg,#19333bed,#071820ed);border-radius:14px;color:#ffe5a6;cursor:pointer;transition:transform .2s,border-color .2s}.tr-chest:not(:disabled):hover{transform:translateY(-4px);border-color:#ffdb79;box-shadow:0 8px 20px #0005}.tr-chest:focus-visible{outline:3px solid #ffe39d;outline-offset:3px}.tr-chest:disabled{cursor:default}.tr-chest.is-claimed{opacity:.45;filter:grayscale(.5)}
.tr-number{position:absolute;top:7px;left:7px;z-index:1;padding:2px 7px;border-radius:20px;font-size:10px;background:#07111ac9}.tr-sprite{display:block;width:100%;aspect-ratio:1;background:url('/assets/treasure/treasure-chest-sprite.png') left center/200% 100% no-repeat;filter:drop-shadow(0 10px 10px #0007)}.tr-sprite.is-open{background-position:right center}.tr-chest-label{display:block;font-size:11px}
.tr-details,.tr-history{margin-top:24px;border-top:1px solid #e6c27840;padding-top:18px;line-height:1.8;overflow-wrap:anywhere}.tr-details summary{cursor:pointer;font-weight:700}.tr-details p,.tr-history p{font-size:13px;color:#ded4bc;margin:8px 0}.tr-history h3{color:#ffe5a6;font-size:16px}.tr-sync{margin-top:20px;font-size:11px;color:#c1b9a5}
.tr-opening{text-align:center;padding:16px;border-radius:18px;color:#ffebc1;background:radial-gradient(ellipse at 50% 40%,#645228,#071923 70%);overflow:hidden}.tr-opening>.tr-sprite{width:min(100%,320px);margin:auto;animation:tr-arrive .7s ease both}.tr-opening h2{font-size:22px;color:#ffebc1;overflow-wrap:anywhere}.tr-opening.is-revealed>.tr-sprite{animation:tr-unlock .9s ease both;filter:drop-shadow(0 0 30px #ffd36999)}.tr-opening.is-revealed h2{animation:tr-arrive .7s .4s both}
.tr-config{border:0;margin:0;padding:0;min-width:0}.tr-config:disabled{opacity:.75}.tr-reward-row{display:grid;grid-template-columns:minmax(0,1fr) 76px auto auto;gap:8px;align-items:center;margin-bottom:10px}.tr-reward-row input{min-width:0}
@keyframes tr-arrive{from{opacity:0;transform:translateY(40px) scale(.7)}to{opacity:1;transform:none}}@keyframes tr-unlock{0%{transform:scale(.9)}25%{transform:rotate(-4deg)}45%{transform:rotate(4deg) scale(1.05)}70%{transform:translateY(-12px) scale(1.1)}100%{transform:none}}
@media(max-width:600px){.tr-world{padding:14px;border-radius:16px;background-position:61% top}.tr-grid{grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}.tr-stats{gap:6px}.tr-stats>div{padding:12px 4px}.tr-reward-row{grid-template-columns:minmax(0,1fr) 62px auto}.tr-reward-row .btn{grid-column:1/-1;justify-self:end}.tr-opening{padding:10px}}
@media(prefers-reduced-motion:reduce){.tr-opening>.tr-sprite,.tr-opening.is-revealed>.tr-sprite,.tr-opening.is-revealed h2{animation:none}.tr-chest{transition:none}}
.tr-reward-row input{width:100%;min-height:44px;padding:10px 12px;border:1px solid #cdc9be;border-radius:10px;background:#fff;color:#1b2b33;font:inherit}

/* ===== 門市戰況：快速導覽列 =====

   一排按鈕黏在固定頂列底下，點了就捲到對應區塊。這一頁很長（目標、排名、
   數字、評論、明細），店長在手機上找「還沒回的評論」要滑好幾屏。

   偏移量用 --head-h：桌機是頂列＋分頁列，手機分頁列在底部所以只有頂列
   （見 syncHeadHeight）。祖先都沒有 overflow 不是 visible 的容器，sticky 才會動。
*/
.battle-nav {
  position: sticky;
  top: var(--head-h, 0px);
  z-index: 40;
  display: flex;
  gap: 6px;
  overflow-x: auto;
  scrollbar-width: none;
  padding: 8px 0 10px;
  margin: 0 0 8px;
  background: var(--bg);
  -webkit-overflow-scrolling: touch;
}
.battle-nav::-webkit-scrollbar { display: none; }
.battle-nav button {
  flex: 0 0 auto;
  padding: 7px 14px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font-size: 13px; font-weight: 600; font-family: inherit;
  white-space: nowrap;
  cursor: pointer;
}
.battle-nav button.on { background: var(--topbar); border-color: var(--topbar); color: #fff; }
/* 捲到定位時被導覽列與頂列蓋住的高度，由 JS 算；這裡只是保險 */
.battle-anchor { scroll-margin-top: calc(var(--head-h, 0px) + 56px); }

/* ===== 門市戰況：Google 評論 ===== */
.gr-card { margin-top: 18px; }
.gr-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.gr-head h2 { margin: 0; }
.gr-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.gr-table td.gr-hit { color: var(--ok); font-weight: 700; }
.gr-table td.gr-miss { color: var(--danger, #b13333); font-weight: 700; }

.gr-list { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 10px; }
.gr-item {
  border: 1px solid var(--line);
  border-left: 4px solid var(--accent);
  border-radius: var(--radius);
  background: var(--surface-alt);
  padding: 12px 14px;
}
.gr-item.gr-old { border-left-color: var(--line-strong); }
.gr-item-head { display: flex; justify-content: space-between; gap: 10px; flex-wrap: wrap; font-size: 13px; }
.gr-item-store { font-weight: 700; }
.gr-item-meta { color: var(--muted); }
.gr-stars { color: #d9930d; letter-spacing: 1px; }
.gr-stars.low { color: var(--danger, #b13333); }
.gr-item-text { margin: 8px 0 0; font-size: 14px; line-height: 1.55; white-space: pre-wrap; word-break: break-word; }
.gr-item-foot { margin-top: 8px; display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.gr-item-foot a { font-size: 13px; font-weight: 600; }

/* 總倉配貨：門市列可以展開看每一張單（分數高的在前） */
.link-btn {
  border: 0; background: transparent; padding: 0;
  color: var(--ink); font: inherit; font-weight: 600; cursor: pointer;
  text-align: left;
}
.link-btn:hover { color: var(--accent); }

/* ===== 門市排隊管理 ===== */
.queue-card { max-width: 980px; }
.queue-controls { display:flex; align-items:end; gap:12px; flex-wrap:wrap; }
.queue-controls .field { margin:0; min-width:190px; }
.queue-refresh { min-height:44px; }
.queue-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:14px; margin-top:18px; }
.queue-lane { border:1px solid var(--line); border-radius:12px; padding:15px; background:var(--surface-alt); }
.queue-lane h2,.queue-desk h2 { font-size:16px; margin:0 0 5px; }
.queue-pay { border-top:4px solid #e9a41a; }
.queue-biz { border-top:4px solid #3979b9; }
.queue-current { font-size:32px; line-height:1.15; font-weight:800; color:var(--topbar); font-variant-numeric:tabular-nums; margin:8px 0; }
.queue-row { color:var(--muted); font-size:14px; min-height:24px; }
.queue-call { width:100%; margin-top:12px; min-height:46px; }
.queue-desk { margin-top:16px; border-top:1px solid var(--line); padding-top:16px; }
.queue-desk-ticket { font-size:18px; font-weight:700; margin:5px 0; }
.queue-paused { margin:4px 0 10px; color:#a45a17; font-weight:600; }
.queue-actions { display:flex; flex-wrap:wrap; gap:8px; margin-top:12px; }
.queue-actions .btn { min-height:44px; }
.queue-sync { color:var(--muted); font-size:12px; margin:15px 0 0; }
@media(max-width:600px){
  .queue-controls { display:grid; grid-template-columns:1fr 1fr; gap:9px; }
  .queue-controls .field { min-width:0; }
  .queue-refresh { width:100%; }
  .queue-grid { grid-template-columns:1fr; gap:10px; }
  .queue-current { font-size:30px; }
  .queue-actions { display:grid; grid-template-columns:1fr 1fr; }
  .queue-actions .btn:last-child { grid-column:1/-1; }
}
.alloc-need-detail > td { background: var(--surface-alt); padding: 8px 10px 12px; }
.alloc-need-detail .table-wrap { margin: 0; }

/* ===== 頂列的通知鈕 ===== */
.chip-notify { position: relative; display: inline-flex; align-items: center; gap: 6px; }
.notify-badge {
  min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px;
  background: var(--accent); color: #fff; font-size: 12px; font-weight: 800; line-height: 20px; text-align: center;
}
.notify-badge.is-overdue { background: var(--danger); }
.notice-list { display: grid; gap: 10px; }
.notice-item { display: flex; gap: 12px; align-items: flex-start; padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
.notice-item.is-urgent { border-color: #e6c766; background: #fffbea; }
.notice-item.is-overdue { border-color: #f0b4b4; background: #fdf1f1; }
.notice-icon { font-size: 22px; line-height: 1; }
.notice-main { flex: 1; min-width: 0; }
.notice-title { font-weight: 700; }
.notice-sub { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.notice-item .btn { flex: none; align-self: center; }

/* 設定裡的切換身份：原本是頂列的下拉選單，搬進卡片後照一般清單排 */
.ident-menu-inline { display: block !important; position: static; min-width: 0; margin-top: 12px; box-shadow: none; }

/* 採購分析：規格欄固定、零用點表示，合計列加粗 */
table.data.alloc-demand-table th:first-child, table.data.alloc-demand-table td:first-child { min-width: 180px; position: sticky; left: 0; background: var(--surface); z-index: 2; }
table.data.alloc-demand-table td.alloc-zero { color: var(--line-strong); }
table.data.alloc-demand-table tr.alloc-demand-sum td { border-top: 2px solid var(--line-strong); font-weight: 700; }
.po-alloc { margin-right: 6px; }
.alloc-covered { color: #96601a; font-weight: 700; }

/* 管理部專區：專案比對，獨立服務與人工查核。 */
.pr-toolbar,.pr-tabs{display:flex;align-items:end;gap:10px;flex-wrap:wrap;margin:16px 0}
.pr-toolbar .field{margin:0;min-width:160px}.pr-toolbar .field .input{display:block;margin-top:5px}
.pr-filters{display:grid;grid-template-columns:repeat(4,minmax(140px,1fr));gap:12px;margin:18px 0}
.pr-filters .field{margin:0}.pr-filters label,.pr-review label{display:block;font-size:13px;color:var(--muted)}
.pr-filters .input,.pr-review .input{display:block;width:100%;margin-top:6px}
.pr-imports{font-size:13px;line-height:1.8}.pr-imports h3{margin:0 0 8px}
.pr-stats{grid-template-columns:repeat(3,minmax(0,1fr))}
/* Match the specificity of table.data so its nowrap rule cannot spill long plans across columns. */
table.data.pr-table{min-width:1200px}
table.data.pr-table td,table.data.pr-table th{text-align:left;vertical-align:top}
table.data.pr-table td{max-width:250px;white-space:normal;overflow-wrap:anywhere}
table.data.pr-table td:nth-child(4),table.data.pr-table td:nth-child(7){min-width:220px}
table.data.pr-table td:nth-child(2),table.data.pr-table td:nth-child(5),table.data.pr-table td:nth-child(6),table.data.pr-table td:nth-child(8){white-space:nowrap}
table.data.pr-table td[colspan]{max-width:none}
.pr-detail{text-align:left;padding:12px;background:var(--surface-alt)}
.pr-related{margin-top:16px}.pr-related>.card{margin:10px 0}
.pr-sources{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}.pr-sources .card{margin:0}
.pr-fields{display:grid;grid-template-columns:95px minmax(0,1fr);gap:6px;font-size:13px}.pr-fields dt{color:var(--muted)}.pr-fields dd{margin:0;overflow-wrap:anywhere;white-space:pre-wrap}
.pr-review{max-width:760px;margin-top:16px}.pr-review .field{margin-bottom:12px}.pr-review textarea{resize:vertical}
@media(max-width:800px){.pr-filters{grid-template-columns:repeat(2,minmax(0,1fr))}.pr-sources{grid-template-columns:1fr}.pr-stats{grid-template-columns:1fr}.pr-tabs .btn{flex:1 1 40%}}
@media(max-width:420px){.pr-filters{grid-template-columns:1fr}.pr-toolbar .field{width:100%}}
.pr-review .pr-rule{display:flex;align-items:flex-start;gap:8px;color:var(--ink);margin:10px 0}.pr-rule input{margin-top:3px;flex:none}.pr-rule+ .hint{margin-bottom:12px}
