/* 捐款管理系統 視覺系統(票 01 定案)
 *
 * 方向：一本攤開的帳冊。米白底(入口站與其他庭芳系統同色)、深墨字、數字用等寬數字排齊；
 * 庭芳桃紅只用在「要你動手」的地方(主要按鈕、目前分頁、焦點)，數字與圖表不用桃紅，免得跟按鈕搶。
 * 圖表用四個資料色(--data-1 到 --data-4，藍綠為主、淺藍綠是去年同期、金色是定期定額、橄欖綠備用)。
 * 狀態色各司其職不混用：
 *   完成      綠(--ok)
 *   待處理    琥珀(--warn，ATM 未付、收據未寄這類等人動手的)
 *   失敗      紅(--late，扣款失敗、同步失敗)
 *   停用      灰(--off)
 * 手機優先：單欄、大觸控區(最小 44px)、整頁照常捲動(iPhone Safari 不做整頁 fixed 版面)；底部分頁列 fixed bottom 加安全區。
 * 720px 以上電腦版內容置中、最寬 1080px；主選單回到頂欄。
 *
 * token 分四組：顏色、字級、間距、圓角與陰影。元件只准用 token，不寫死數值。
 * 介面對齊鐵律：同一列的輸入框、下拉、日期、按鈕一律 --ctl-h 高，單行控制項拿掉原生外觀(下拉箭頭自己畫)，勾選框自己畫。
 */
:root {
  /* 一、顏色：底與字 */
  --bg: #F7F7F3; --surface: #FFFFFF; --surface-2: #F0F0EA; --surface-3: #E7E7DF;
  --ink: #26302D; --ink-2: #44504B; --muted: #6B7571; --ph: #9DA49F;
  --line: #E2E4DD; --line-2: #CFD3CB;
  /* 品牌：庭芳桃紅。主按鈕用院徽亮桃紅，白字粗體(對比 4.5:1 以上)；連結與目前分頁用深一階 */
  --brand: #E4007F; --primary: #C8006F; --primary-hover: #A8005D; --primary-soft: #FCE8F2; --on-primary: #FFFFFF;
  --btn-bg: #E4007F; --btn-bg-hover: #C8006F; --on-btn: #FFFFFF; --btn-weight: 800;
  --btn-shadow: 0 1px 2px rgba(0, 0, 0, .14), 0 6px 16px rgba(228, 0, 127, .32);
  --btn-line: #A9B0A7;
  /* 狀態 */
  --ok: #1D6B45; --ok-soft: #E5F3EB;
  --warn: #9A5800; --warn-soft: #FFF4DF; --warn-line: #F1D9A6;
  --late: #B42318; --late-soft: #FDECEA; --late-line: #F4C7C2;
  --off: #6B7571; --off-soft: #ECEDE9;
  --focus: rgba(200, 0, 111, .24);
  /* 資料色(圖表)：不用品牌桃紅 */
  --data-1: #2E6E8E; --data-2: #9CC2D3; --data-3: #B98A2E; --data-4: #6E8B5B;
  /* 下拉箭頭(自己畫，顏色跟 --muted) */
  --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236B7571' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  /* 二、字級(手機基準 16px，不小於 13px) */
  --font: "PingFang TC", "Noto Sans TC", "Microsoft JhengHei", system-ui, -apple-system, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --fs-xs: 13px; --fs-sm: 14px; --fs-md: 16px; --fs-lg: 18px; --fs-xl: 21px; --fs-2xl: 26px; --fs-num: 30px;
  /* 三、間距：4 的倍數；控制項高度(輸入框、下拉、日期、按鈕同一列同高) */
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 20px; --s6: 24px; --s7: 32px; --s8: 48px;
  --ctl-h: 44px; --ctl-h-sm: 36px;
  /* 四、圓角與陰影 */
  --r-sm: 8px; --r-md: 12px; --r-lg: 16px; --r-pill: 999px;
  --shadow-1: 0 1px 2px rgba(38, 48, 45, .05), 0 2px 10px rgba(38, 48, 45, .04);
  --shadow-2: 0 2px 4px rgba(38, 48, 45, .06), 0 10px 28px rgba(38, 48, 45, .08);
  --shadow-3: 0 18px 50px rgba(38, 48, 45, .22);
  --wrap: 1080px;
  color-scheme: light;
}
/* 深色：跟著系統(prefers-color-scheme)，也可以用 data-theme 強制。登入頁(gate-mode)不跟著走，見下方。 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #151817; --surface: #1D2120; --surface-2: #242928; --surface-3: #2C3230;
    --ink: #ECEFEC; --ink-2: #CBD1CD; --muted: #98A29D; --ph: #6C7571;
    --line: #2C3230; --line-2: #3A413E;
    --brand: #FF4DA6; --primary: #FF5CAD; --primary-hover: #FF85C1; --primary-soft: #3A1B2B; --on-primary: #1B0912;
    --btn-bg: #FF5CAD; --btn-bg-hover: #FF85C1; --on-btn: #1B0912; --btn-shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 6px 18px rgba(255, 92, 173, .28);
    --btn-line: #5A635F;
    --ok: #6FD19A; --ok-soft: #16301F;
    --warn: #F4B860; --warn-soft: #372A12; --warn-line: #54401C;
    --late: #FF8A7E; --late-soft: #3A1B18; --late-line: #5B2A25;
    --off: #98A29D; --off-soft: #262B29;
    --focus: rgba(255, 92, 173, .32);
    --data-1: #6FB3D2; --data-2: #3F6475; --data-3: #E0B55A; --data-4: #9DBB86;
    --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2398A29D' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    --shadow-1: 0 1px 2px rgba(0, 0, 0, .3); --shadow-2: 0 8px 24px rgba(0, 0, 0, .35); --shadow-3: 0 18px 50px rgba(0, 0, 0, .55);
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --bg: #151817; --surface: #1D2120; --surface-2: #242928; --surface-3: #2C3230;
  --ink: #ECEFEC; --ink-2: #CBD1CD; --muted: #98A29D; --ph: #6C7571;
  --line: #2C3230; --line-2: #3A413E;
  --brand: #FF4DA6; --primary: #FF5CAD; --primary-hover: #FF85C1; --primary-soft: #3A1B2B; --on-primary: #1B0912;
  --btn-bg: #FF5CAD; --btn-bg-hover: #FF85C1; --on-btn: #1B0912; --btn-shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 6px 18px rgba(255, 92, 173, .28);
  --btn-line: #5A635F;
  --ok: #6FD19A; --ok-soft: #16301F;
  --warn: #F4B860; --warn-soft: #372A12; --warn-line: #54401C;
  --late: #FF8A7E; --late-soft: #3A1B18; --late-line: #5B2A25;
  --off: #98A29D; --off-soft: #262B29;
  --focus: rgba(255, 92, 173, .32);
  --data-1: #6FB3D2; --data-2: #3F6475; --data-3: #E0B55A; --data-4: #9DBB86;
  --select-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2398A29D' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .3); --shadow-2: 0 8px 24px rgba(0, 0, 0, .35); --shadow-3: 0 18px 50px rgba(0, 0, 0, .55);
  color-scheme: dark;
}

/* ── 基礎 ── */
* { box-sizing: border-box; margin: 0; padding: 0; }
/* [hidden] 的預設權重最低，任何自己寫的 display 都蓋得過它，所以要 !important */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
body { font-family: var(--font); font-size: var(--fs-md); line-height: 1.6; color: var(--ink); background: var(--bg);
       min-height: 100vh; -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }
a.btn:hover { text-decoration: none; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
.num, .mono { font-variant-numeric: tabular-nums; }
.mono { font-family: var(--mono); }
.muted { color: var(--muted); }
.view { max-width: var(--wrap); margin: 0 auto;
        padding: var(--s4) max(var(--s4), env(safe-area-inset-right)) calc(var(--s8) + env(safe-area-inset-bottom)) max(var(--s4), env(safe-area-inset-left)); }

/* ── 頂欄：sticky 黏在上方；整頁照常捲動、不用 fixed，iPhone Safari 的工具列才不會蓋住內容 ── */
.top { position: sticky; top: 0; z-index: 30; background: color-mix(in srgb, var(--bg) 88%, var(--surface)); border-bottom: 1px solid var(--line);
       backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
/* 模擬資料模式(票 20)：頂欄最上面一條紅底白字，跟頂欄一起黏住，捲到哪裡都看得到 */
.mock-banner { display: block; padding: 6px max(var(--s4), env(safe-area-inset-right)) 6px max(var(--s4), env(safe-area-inset-left));
               background: #B42318; color: #FFFFFF; font-size: var(--fs-sm); font-weight: 800; line-height: 22px; text-align: center; }  /* 深色模式也用這個深紅：白字對比夠 */
.mock-banner[hidden] { display: none; }
.top-in { max-width: var(--wrap); margin: 0 auto; height: 60px; display: flex; align-items: center; gap: var(--s5);
          padding: 0 max(var(--s4), env(safe-area-inset-right)) 0 max(var(--s4), env(safe-area-inset-left)); }
.brand { display: flex; align-items: center; gap: 10px; color: var(--ink); font-weight: 800; font-size: var(--fs-lg);
         letter-spacing: .02em; min-width: 0; flex: none; }
.brand img { width: 32px; height: 32px; border-radius: 50%; flex: none; display: block; }
/* 頂欄：點院徽回系統入口 apps.tinfun.org.tw、點系統名稱回本系統首頁 (跨系統鐵律，2026-10-14 Jacky 定) */
.brand a { display: flex; align-items: center; min-width: 0; color: inherit; text-decoration: none; }
.brand a:hover { text-decoration: none; }
.brand span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* 電腦主選單(照公文收文系統)：目前那一頁白底桃紅字 */
.nav { display: flex; align-items: center; gap: 2px; min-width: 0; }
.nav a { display: inline-flex; align-items: center; height: 40px; padding: 0 14px; border-radius: var(--r-pill);
         color: var(--ink-2); font-weight: 700; font-size: var(--fs-sm); white-space: nowrap; }
.nav a:hover { background: var(--surface-2); color: var(--ink); text-decoration: none; }
.nav a[aria-current="page"] { background: var(--surface); color: var(--primary); box-shadow: var(--shadow-1); }
/* 右邊：電腦是一排文字連結「名字｜管理｜臉或指紋綁定｜登出」，手機是名字按鈕加選單。
   斷點 720px 跟其他庭芳系統同一個數字；app.js 的 寬螢幕() 也用 720px。 */
.me { margin-left: auto; position: relative; flex: none; }
.me-links { display: flex; align-items: center; gap: var(--s4); font-size: var(--fs-sm); white-space: nowrap; }
.me-links b { color: var(--ink); }
.me-links a, .me-links button { color: var(--ink-2); text-decoration: underline; text-underline-offset: 3px; background: none; border: 0;
                                padding: 4px 0; font: inherit; cursor: pointer; }
.me-links a:hover, .me-links button:hover { color: var(--primary); }
.me-links a[aria-current="page"] { color: var(--primary); font-weight: 700; }
.me-btn { display: flex; align-items: center; height: 40px; padding: 0 14px; border: 1px solid var(--line-2);
          background: var(--surface); border-radius: var(--r-pill); cursor: pointer; font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2);
          max-width: 10em; }
.me-btn span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.me-btn:hover { border-color: var(--primary); }
.menu { position: absolute; right: 0; top: calc(100% + 8px); z-index: 40; min-width: 200px; background: var(--surface);
        border: 1px solid var(--line); border-radius: var(--r-md); box-shadow: var(--shadow-2); padding: 6px; }
.menu button, .menu a { display: block; width: 100%; text-align: left; border: 0; background: none; cursor: pointer;
                        padding: 12px; border-radius: var(--r-sm); color: var(--ink); font-size: var(--fs-md); }
.menu button:hover, .menu a:hover { background: var(--surface-2); text-decoration: none; }
@media (min-width: 720px) { .me-btn, .menu { display: none !important; } }
/* 手機不出現「管理」(跨系統既定規則)：管理連結只在電腦那一排裡，手機整排藏起來；主選單收進底部分頁列 */
@media (max-width: 719px) { .me-links { display: none; } .nav { display: none; } .brand { font-size: var(--fs-md); } .top-in { gap: var(--s3); } }

/* ── 底部分頁列(手機，照公文收文系統)：fixed bottom:0 加安全區，整頁照常捲動；頁面底部多留 padding 給它 ── */
.tabbar { position: fixed; left: 0; right: 0; bottom: 0; z-index: 30; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
          background: color-mix(in srgb, var(--surface) 94%, var(--bg)); border-top: 1px solid var(--line);
          backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
          padding: 6px max(var(--s2), env(safe-area-inset-right)) calc(6px + env(safe-area-inset-bottom)) max(var(--s2), env(safe-area-inset-left)); }
.tabbar a { display: grid; justify-items: center; align-content: center; gap: 2px; min-height: 48px; padding: 4px 0 2px;
            color: var(--muted); font-size: 12px; font-weight: 700; border-radius: var(--r-md); text-decoration: none; }
.tabbar a:hover { text-decoration: none; }
.tabbar svg { width: 24px; height: 24px; }
.tabbar a[aria-current="page"] { color: var(--primary); }
@media (min-width: 720px) { .tabbar { display: none !important; } }
@media (max-width: 719px) {
  body.has-tabbar .view { padding-bottom: calc(var(--s8) + 64px + env(safe-area-inset-bottom)); }
  body.has-tabbar .toast { bottom: calc(76px + env(safe-area-inset-bottom)); }
}

/* ── 按鈕：同一列跟輸入框、下拉同高(--ctl-h)。主按鈕院徽亮桃紅；次要 .ghost 白底框線；破壞性 .danger 紅底 ── */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: var(--ctl-h); padding: 0 20px;
       border: 0; border-radius: var(--r-pill); cursor: pointer; font-weight: var(--btn-weight); font-size: var(--fs-md); line-height: 1; white-space: nowrap;
       background: var(--btn-bg); color: var(--on-btn); transition: background .15s, transform .06s, box-shadow .15s, border-color .15s;
       box-shadow: var(--btn-shadow); vertical-align: middle; }
.btn:hover { background: var(--btn-bg-hover); }
.btn:active { transform: scale(.97); }
.btn:disabled { opacity: .45; cursor: default; box-shadow: none; transform: none; }
.btn.ghost { background: var(--surface); color: var(--ink); border: 1.5px solid var(--btn-line); font-weight: 700; box-shadow: 0 1px 2px rgba(38, 48, 45, .08); }
.btn.ghost:hover { border-color: var(--btn-bg); background: var(--primary-soft); }
.btn.danger { background: var(--late); color: #FFFFFF; box-shadow: 0 1px 2px rgba(0, 0, 0, .14); }
.btn.danger:hover { background: color-mix(in srgb, var(--late) 85%, #000); }
.btn.small { height: var(--ctl-h-sm); padding: 0 14px; font-size: var(--fs-sm); }
.btn.block { width: 100%; }
.btn svg { width: 20px; height: 20px; flex: none; }
.actions { display: flex; gap: var(--s2); margin-top: var(--s5); }
.actions .btn { flex: 1; }

/* ── 輸入(單行)：寫死高度、拿掉原生外觀。Safari 的下拉不吃最小高度、日期框會自己長高，所以一律 height 加 appearance: none ── */
.field { display: block; }
.field + .field { margin-top: var(--s4); }
.field > span { display: block; font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2); margin-bottom: 6px; }
.ctl {
  display: block; width: 100%; height: var(--ctl-h); margin: 0; padding: 0 14px; background-color: var(--surface); border: 1px solid var(--line-2);
  border-radius: var(--r-md); outline: none; font-size: var(--fs-md); line-height: normal; color: var(--ink);
  -webkit-appearance: none; appearance: none; transition: border-color .15s, box-shadow .15s; }
.ctl:focus { border-color: var(--primary); box-shadow: 0 0 0 4px var(--focus); }
.ctl::placeholder { color: var(--ph); }
select.ctl { padding-right: 40px; background-image: var(--select-arrow); background-repeat: no-repeat; background-position: right 12px center; background-size: 18px 18px; cursor: pointer; }
/* Safari 的日期框：拿掉原生外觀後內部那一格仍會撐高、置中，固定成跟其他欄位一樣 */
input[type=date].ctl { display: flex; align-items: center; }
input[type=date].ctl::-webkit-date-and-time-value { text-align: left; margin: 0; }
input[type=date].ctl::-webkit-datetime-edit { padding: 0; line-height: 1; }
input[type=date].ctl::-webkit-calendar-picker-indicator { margin: 0; opacity: .6; cursor: pointer; }
textarea.ctl { height: auto; min-height: 96px; padding: 10px 14px; line-height: 1.6; resize: vertical; }
/* 勾選框：自己畫(20px 方框，勾是 SVG)，跟文字同一條中線 */
.check { display: inline-flex; align-items: center; gap: 10px; min-height: var(--ctl-h); cursor: pointer; font-size: var(--fs-md); color: var(--ink); user-select: none; line-height: 1.3; }
.check input { flex: none; width: 20px; height: 20px; margin: 0; border: 1.5px solid var(--btn-line); border-radius: 6px; background: var(--surface) center / 14px 14px no-repeat;
               -webkit-appearance: none; appearance: none; cursor: pointer; transition: background-color .15s, border-color .15s; }
.check input:checked { background-color: var(--primary); border-color: var(--primary);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12.5 4.5 4.5L19 7.5'/%3E%3C/svg%3E"); }
.check input:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
/* 同一列的控制項(篩選列、查詢列)：底部切齊，每個控制項同高 */
.ctl-row { display: flex; align-items: flex-end; gap: var(--s3); flex-wrap: wrap; }
.ctl-row .field { flex: 0 1 200px; }
.ctl-row .field + .field { margin-top: 0; }
.ctl-row .btn, .ctl-row .check { flex: none; }
@media (max-width: 719px) { .ctl-row .field { flex: 1 1 100%; } }

/* ── 卡片、標籤、提示條 ── */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-1); padding: var(--s5); }
.chip { display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 10px; border-radius: var(--r-pill);
        font-size: var(--fs-xs); font-weight: 700; white-space: nowrap; background: var(--surface-2); color: var(--ink-2); }
.chip.ok { background: var(--ok-soft); color: var(--ok); }
.chip.warn { background: var(--warn-soft); color: var(--warn); }
.chip.late { background: var(--late-soft); color: var(--late); }
.chip.off { background: var(--off-soft); color: var(--off); }
.chip.brand { background: var(--primary-soft); color: var(--primary); }
.banner { display: flex; gap: var(--s3); align-items: flex-start; padding: var(--s3) var(--s4); border-radius: var(--r-md);
          font-size: var(--fs-sm); background: var(--surface-2); color: var(--ink-2); }
.banner.warn { background: var(--warn-soft); color: var(--warn); }
.banner.late { background: var(--late-soft); color: var(--late); }
.banner.ok { background: var(--ok-soft); color: var(--ok); }
.banner svg { width: 20px; height: 20px; flex: none; margin-top: 1px; }

/* ── 數字卡(總覽用)：標題、大數字(等寬數字)、跟去年同期比 ── */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--s3); }
.kpi { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-1); padding: var(--s4) var(--s5); }
.kpi .k-label { font-size: var(--fs-sm); font-weight: 700; color: var(--muted); }
.kpi .k-num { font-size: var(--fs-num); font-weight: 800; line-height: 1.25; margin-top: 2px; font-variant-numeric: tabular-nums; letter-spacing: .01em; }
.kpi .k-num small { font-size: var(--fs-md); font-weight: 700; color: var(--muted); margin-right: 4px; }
.kpi .k-sub { font-size: var(--fs-xs); color: var(--muted); margin-top: 4px; }
.kpi .up { color: var(--ok); font-weight: 700; } .kpi .down { color: var(--late); font-weight: 700; }
.kpi-note { color: var(--muted); font-size: var(--fs-xs); margin-top: var(--s3); line-height: 1.6; }

/* ── 總覽完整版(票 04) ──
 * 由上到下：要處理的事(看明細以上，要動手的放最上面)、本月與今年兩張數字卡(含跟去年同期比)、趨勢圖與用途拆開(電腦並排、手機上下)。
 * 增減：多是綠、少是紅、持平與去年沒有是灰；顏色之外一定有字(多、少)與箭頭，色弱也分得出來。 */
.k-cmp { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; margin-top: var(--s3); font-size: var(--fs-sm); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.k-range { font-size: var(--fs-xs); color: var(--muted); margin-top: 4px; }
.delta { display: inline-flex; align-items: center; gap: 3px; height: 26px; padding: 0 10px; border-radius: var(--r-pill); font-size: var(--fs-xs);
         font-weight: 800; white-space: nowrap; background: var(--off-soft); color: var(--off); font-variant-numeric: tabular-nums; }
.delta svg { width: 14px; height: 14px; flex: none; }
.delta.up, .kpi .delta.up { background: var(--ok-soft); color: var(--ok); }
.delta.down, .kpi .delta.down { background: var(--late-soft); color: var(--late); }
/* 要處理的事：一整條可以點的卡片，沒有未處理是綠、有就是琥珀 */
.todo-strip { display: flex; align-items: center; gap: var(--s3); padding: var(--s3) var(--s4); margin-bottom: var(--s3); color: var(--ink);
              background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-1); transition: border-color .15s; }
.todo-strip:hover { text-decoration: none; border-color: var(--primary); }
.todo-strip .ts-icon { flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: var(--ok-soft); color: var(--ok); }
.todo-strip.has .ts-icon { background: var(--warn-soft); color: var(--warn); }
.todo-strip .ts-icon svg { width: 22px; height: 22px; }
.todo-strip .ts-text { flex: 1; min-width: 0; display: grid; line-height: 1.4; }
.todo-strip .ts-text b { font-size: var(--fs-md); }
.todo-strip .ts-text span { font-size: var(--fs-sm); color: var(--muted); }
.todo-strip .ts-num { flex: none; display: inline-flex; align-items: baseline; gap: 2px; font-variant-numeric: tabular-nums; }
.todo-strip .ts-num b { font-size: var(--fs-xl); font-weight: 800; line-height: 1; }
.todo-strip.has .ts-num b { color: var(--warn); }
.todo-strip .ts-num small { font-size: var(--fs-xs); color: var(--muted); font-weight: 700; }
.todo-strip .ts-go { flex: none; display: grid; place-items: center; color: var(--muted); }
.todo-strip .ts-go svg { width: 20px; height: 20px; }
.todo-strip .ts-text .ts-note { font-size: var(--fs-xs); }
/* 總覽最上面：要處理的事與到期提醒兩張(電腦並排、同高，手機上下排)；到期提醒有人時用品牌色 */
.ov-strips { display: grid; gap: var(--s3); margin-bottom: var(--s3); }
.ov-strips .todo-strip { margin-bottom: 0; }
@media (min-width: 720px) { .ov-strips { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.todo-strip.rn-strip.has .ts-icon { background: var(--primary-soft); color: var(--primary); }
.todo-strip.rn-strip.has .ts-num b { color: var(--primary); }
/* 趨勢與用途：電腦並排(趨勢寬)，手機上下 */
.ov-grid { display: grid; gap: var(--s3); margin-top: var(--s3); align-items: start; }
@media (min-width: 960px) { .ov-grid { grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); } }
.card-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--s2) var(--s3); min-height: 36px; }
.card-head h2 { font-size: var(--fs-lg); line-height: 1.3; font-weight: 800; }
.legend { display: flex; align-items: center; gap: var(--s3); font-size: var(--fs-xs); color: var(--muted); }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.sw { display: inline-block; width: 12px; height: 12px; border-radius: 3px; flex: none; }
.sw.now { background: var(--data-1); } .sw.ly { background: var(--data-2); }
/* 讀數：預設是本月，滑過或點一下長條就換成那個月 */
.readout { margin: var(--s3) 0 var(--s2); min-height: 92px; }
.readout .ro-title { display: flex; align-items: center; gap: var(--s2); font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2); }
.readout .ro-main { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px var(--s3); margin-top: 2px; }
.readout .ro-num { font-size: var(--fs-2xl); font-weight: 800; line-height: 1.25; font-variant-numeric: tabular-nums; }
.readout .ro-num small { font-size: var(--fs-sm); font-weight: 700; color: var(--muted); margin-right: 4px; }
.readout .ro-count { font-size: var(--fs-sm); color: var(--muted); font-variant-numeric: tabular-nums; }
.readout .ro-cmp { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; margin-top: 4px; font-size: var(--fs-sm); color: var(--muted); font-variant-numeric: tabular-nums; min-height: 26px; }
/* 趨勢圖(SVG)：顏色全部走這裡的 class，深色模式跟著 token 換 */
.trend { -webkit-user-select: none; user-select: none; }
.trend-svg { display: block; width: 100%; height: auto; overflow: visible; touch-action: manipulation; }
.trend text { font-family: var(--font); font-size: 11px; fill: var(--muted); font-variant-numeric: tabular-nums; }
.trend .gridline { stroke: var(--line); stroke-width: 1; }
.trend .gridline.base { stroke: var(--line-2); }
.trend .band { fill: var(--surface-2); opacity: 0; transition: opacity .12s; }
.trend .col:hover .band { opacity: .6; }
.trend .col.on .band { opacity: 1; }
.trend .ghost { fill: var(--data-2); opacity: .75; }
.trend .bar { fill: var(--data-1); }
.trend .bar.partial { fill: url(#partialStripe); stroke: var(--data-1); stroke-width: 1.2; }
.trend .stripe-bg { fill: var(--data-1); opacity: .22; }
.trend .stripe-fg { fill: var(--data-1); }
.trend .mlab { fill: var(--ink-2); font-weight: 600; }
.trend .col.on .mlab { fill: var(--ink); font-weight: 800; }
.trend .ylab { font-size: 10px; }
.trend .vlab { fill: var(--ink); font-size: 12px; font-weight: 800; opacity: 0; }
.trend .col.on .vlab { opacity: 1; }
.trend .hit { fill: transparent; cursor: pointer; }
.trend .col { outline: none; }
.trend .col:focus-visible .band { opacity: 1; stroke: var(--primary); stroke-width: 2; }
/* 本月與今年切換：一組膠囊按鈕(同高 36px)，按下去的是白底 */
.seg { display: inline-flex; align-items: center; gap: 2px; height: var(--ctl-h-sm); padding: 3px; border-radius: var(--r-pill); background: var(--surface-2); flex: none; }
.seg button { height: 30px; padding: 0 14px; border: 0; border-radius: var(--r-pill); background: transparent; color: var(--muted);
              font-size: var(--fs-sm); font-weight: 700; line-height: 1; cursor: pointer; -webkit-appearance: none; appearance: none; }
.seg button[aria-pressed="true"] { background: var(--surface); color: var(--ink); box-shadow: var(--shadow-1); }
.seg button:hover { color: var(--ink); }
/* 依捐款用途：一條百分比長條加清單；前四名各一個資料色，其餘併成「其他」(灰) */
.stack { display: flex; gap: 2px; height: 14px; margin: var(--s4) 0 var(--s2); border-radius: var(--r-pill); overflow: hidden; background: var(--surface-2); }
.stack i { display: block; height: 100%; min-width: 3px; }
.stack .c1, .sw.c1 { background: var(--data-1); } .stack .c2, .sw.c2 { background: var(--data-2); }
.stack .c3, .sw.c3 { background: var(--data-3); } .stack .c4, .sw.c4 { background: var(--data-4); }
.stack .c0, .sw.c0 { background: var(--off); }
.type-list { list-style: none; }
.type-list li { display: grid; grid-template-columns: 12px minmax(0, 1fr) auto 3.8em; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.type-list .t-name { min-width: 0; display: grid; line-height: 1.4; }
.type-list .t-name b { font-size: var(--fs-sm); font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.type-list .t-name small { font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.type-list .t-amt { font-size: var(--fs-sm); font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.type-list .t-pct { font-size: var(--fs-xs); color: var(--muted); text-align: right; font-variant-numeric: tabular-nums; }
.type-total { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s3); padding-top: var(--s3); font-size: var(--fs-sm); font-weight: 800; font-variant-numeric: tabular-nums; }
.type-total small { font-weight: 400; color: var(--muted); }
.type-empty { color: var(--muted); font-size: var(--fs-sm); text-align: center; padding: var(--s6) 0; }

/* ── 頁首(每一頁的標題列) ── */
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s3); margin-bottom: var(--s4); }
.page-head h1 { font-size: var(--fs-2xl); line-height: 1.25; letter-spacing: .01em; }
.page-head p { color: var(--muted); font-size: var(--fs-sm); margin-top: 4px; }
.page-head .sync { display: inline-flex; align-items: center; gap: 6px; }
.page-head .sync svg { width: 15px; height: 15px; }
/* 標題在左、最後更新在最右邊，同一列、同中線(2026-10-25 Jacky 改)；手機窄到放不下時最後更新換到下一行靠右 */
.page-head.ph-row { align-items: center; flex-wrap: wrap; row-gap: 2px; margin-bottom: 0; }
.page-head.ph-row .sync { margin: 0 0 0 auto; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ── 固定頁首(2026-10-25 Jacky 改)：總覽、募款專案、要處理、到期提醒、報表的標題列捲動時黏在頂欄下面 ──
 * 整頁照常捲動(iPhone Safari 慣例)，只有這一塊 sticky；top 是 app.js 量好的頂欄高度(含模擬資料橫幅)。
 * 往上蓋掉 .view 的上邊距(margin-top 負值、padding-top 補回)：沒捲動時位置跟以前一樣，而且一開始就貼著頂欄，捲動時不會跳。
 * 不透明底色左右延伸到整個畫面寬(box-shadow 加 clip-path，不會造成橫向捲動)；黏住後下緣多一條細線，報表的分頁底線本身就是那條線。 */
html { scroll-padding-top: calc(var(--top-h, 61px) + var(--head-h, 0px) + 8px); }
.sticky-head { position: sticky; top: var(--top-h, 61px); z-index: 20; background: var(--bg);
               margin: calc(-1 * var(--s4)) 0 var(--s1); padding: var(--s4) 0 var(--s3);
               box-shadow: 0 0 0 100vmax var(--bg); clip-path: inset(0 -100vmax); }
.sticky-head.is-stuck { box-shadow: 0 0 0 100vmax var(--bg), 0 1px 0 100vmax var(--line); clip-path: inset(0 -100vmax -1px); }
.sticky-head > .pj-summary { margin: var(--s3) 0 0; }
.sticky-head + .section-title { margin-top: var(--s3); }
.sticky-head:has(> .adm-tabs) { padding-bottom: 0; margin-bottom: var(--s4); }
.sticky-head:has(> .adm-tabs).is-stuck { box-shadow: 0 0 0 100vmax var(--bg); clip-path: inset(0 -100vmax); }
.sticky-head > .adm-tabs { margin: var(--s3) 0 0; }

/* ── 空狀態 ── */
.empty { display: grid; justify-items: center; text-align: center; gap: var(--s2); padding: var(--s8) var(--s5);
         background: var(--surface); border: 1px dashed var(--line-2); border-radius: var(--r-lg); }
.empty .art { width: 96px; height: 96px; margin-bottom: var(--s2); }
.empty h2 { font-size: var(--fs-xl); line-height: 1.35; }
.empty p { color: var(--muted); font-size: var(--fs-sm); max-width: 30em; line-height: 1.7; }
.empty .btn { margin-top: var(--s3); }

/* ── 登入頁 ──
   版面、文字、配色逐項照人事帳號系統示範站 demo.tinfun.org.tw(Jacky 指定的各系統登入範本)，只有系統名稱不同。
   示範站只有亮色，所以登入頁不跟著深色模式走：html.gate-mode 時整組色票換成示範站的(app.js 的 門口() 掛上、畫外框() 拿掉)。
   選擇器多掛一個 :root 是為了壓過上面深色模式那條 :root:not([data-theme="light"])。 */
html.gate-mode:root {
  --bg: #F7F7F3; --surface: #FFFFFF; --ink: #303735; --ink-2: #303735; --muted: #66706D; --ph: #929996;
  --primary: #E4007F; --primary-hover: #B10063; --primary-soft: #FDEEF6; --on-primary: #FFFFFF;
  --btn-bg: #E4007F; --btn-bg-hover: #B10063; --on-btn: #FFFFFF; --btn-weight: 700;
  --btn-shadow: 0 1px 2px rgba(0, 0, 0, .08), 0 4px 12px color-mix(in srgb, #E4007F 22%, transparent); --btn-line: #D9DED9;
  --line: #E0E4DF; --line-2: #D9DED9; --focus: rgba(228, 0, 127, .12);
  --ok: #1B5E33; --late: #A32C15; --off: #66706D; --off-soft: #ECEDE9;
  color-scheme: light;
}
html.gate-mode body { line-height: 1.7; }
/* 上方留白刻意小(示範站：logo 上面不要空太多)，不做垂直置中 */
.gate { max-width: 26rem; margin: 0 auto; padding: 1.5rem 1.25rem 2.5rem; text-align: center; }
html.gate-mode .view { padding-top: 0; }
.gate .logo { width: 88px; height: 88px; border-radius: 50%; object-fit: cover; display: block; margin: 0 auto .7rem;
              box-shadow: 0 6px 18px rgba(48, 55, 53, .16); }
.gate h1 { font-size: 1.45rem; margin-bottom: .25rem; line-height: 1.7; }
/* 卡片寬度跟著裡面那條 200px 直欄走(--欄寬 只寫這裡一處，標籤、輸入框、兩顆按鈕、忘記登入碼都切齊它) */
.gate .card { --欄寬: 200px; max-width: 16rem; margin: 0 auto; padding: 1.5rem 1.4rem; text-align: left; border-radius: 16px;
              box-shadow: 0 1px 2px rgba(48, 55, 53, .05), 0 8px 24px rgba(48, 55, 53, .06); }
.gate .field { width: var(--欄寬); margin: 0 auto 1.1rem; }
.gate .field + .field { margin-top: 0; }
.gate .field > span { font-weight: 600; font-size: .9rem; margin-bottom: .4rem; color: var(--muted); }
.gate input { display: block; width: 100%; font: inherit; color: var(--ink); background: var(--surface); font-size: 1rem; line-height: 1.7;
              border: 1.5px solid var(--line-2); border-radius: 10px; padding: .55em .75em; outline: none; -webkit-appearance: none; appearance: none; }
.gate input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--focus); }
.gate input::placeholder { color: var(--ph); }
/* 四位數字碼：固定寬置中、四個點的 placeholder；左邊多 12px 補 letter-spacing 在最後一字後面多的那格 */
.gate #code { font-size: 28px; letter-spacing: 12px; text-align: center; padding: 10px 0 10px 12px; border-width: 2px; border-radius: 12px; line-height: normal; }
/* 登入那一列：左半「登入」、右半臉或指紋的圖示鈕，兩顆同色同高；忘記登入碼是右下角一行底線文字 */
.gate .btn { height: auto; line-height: inherit; font-weight: 600; box-shadow: 0 2px 8px rgba(177, 0, 99, .22); }
.gate .login-actions { display: flex; gap: .6rem; width: var(--欄寬); margin: 0 auto; }
.gate .login-actions .btn { flex: 1 1 0; font-size: 1.05rem; padding: .85em 0; }
.gate .login-actions .btn svg { width: 30px; height: 30px; }
.gate #passkey { padding: 0; }
.gate #passkey[aria-busy="true"] { opacity: .45; }
.gate .forgot { width: var(--欄寬); margin: 1rem auto 0; text-align: right; font-size: .875rem; }
.gate .forgot a { color: var(--muted); text-decoration: underline; text-underline-offset: 3px; }
/* 登入頁的彈窗照示範站：置中、上緣色帶就是語氣(綠＝成功、紅＝失敗)，一顆「關閉」 */
html.gate-mode .modal-bg { background: rgba(48, 55, 53, .45); align-items: center; padding: 1.25rem; }
.modal.gate-modal { max-width: 19rem; padding: 1.5rem 1.4rem; text-align: center; border-radius: 16px; border-top: 5px solid var(--line);
                    box-shadow: 0 12px 40px rgba(48, 55, 53, .28); }
.modal.gate-modal.ok { border-top-color: var(--ok); }
.modal.gate-modal.no { border-top-color: var(--late); }
.modal.gate-modal .modal-msg { font-size: 1rem; line-height: 1.75; margin-bottom: 1.25rem; word-break: break-word; }
.modal.gate-modal .btn { height: auto; font-size: 1.05rem; padding: .85em 1.6em; }

/* ── 彈窗、提示、載入 ── */
.modal-bg { position: fixed; inset: 0; z-index: 50; background: rgba(20, 23, 22, .45); display: grid; place-items: center; padding: var(--s4); }
.modal { width: 100%; max-width: 420px; background: var(--surface); border-radius: var(--r-lg); box-shadow: var(--shadow-3); padding: var(--s6) var(--s5) var(--s5);
         max-height: calc(100vh - 32px); max-height: calc(100dvh - 32px); overflow-y: auto; overscroll-behavior: contain; }
.modal p { font-size: var(--fs-md); line-height: 1.7; }
@media (max-width: 480px) { html:not(.gate-mode) .modal-bg { align-items: end; padding: 0; }
  .modal:not(.gate-modal) { max-width: none; border-radius: var(--r-lg) var(--r-lg) 0 0; padding-bottom: calc(var(--s5) + env(safe-area-inset-bottom)); } }
.toast { position: fixed; left: 50%; bottom: calc(24px + env(safe-area-inset-bottom)); transform: translateX(-50%); z-index: 60;
         background: var(--ink); color: var(--bg); padding: 12px 20px; border-radius: var(--r-pill); font-size: var(--fs-sm);
         font-weight: 700; box-shadow: var(--shadow-3); max-width: calc(100vw - 32px); }
.loading { display: grid; place-items: center; min-height: 160px; }
.spinner { width: 28px; height: 28px; border-radius: 50%; border: 3px solid var(--line); border-top-color: var(--primary); animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation-duration: 2s !important; } }

/* ── 管理頁(電腦版，720px 以上；票 05、09、11 填內容) ── */
@media (max-width: 719.98px) { .pc-only { display: none !important; } }
@media (min-width: 720px) { .mobile-only { display: none !important; } }

/* 彈窗共用的標題與說明(票 05 起) */
.modal-title { font-size: var(--fs-xl); line-height: 1.35; margin-bottom: var(--s3); }
.modal .modal-sub { color: var(--muted); font-size: var(--fs-sm); line-height: 1.7; margin: var(--s3) 0 0; }
.modal .banner { margin-top: var(--s3); }
.hint { font-size: var(--fs-xs); color: var(--muted); line-height: 1.7; margin-top: var(--s3); }

/* 管理頁的區塊分頁：一排底線分頁，之後的票加區塊就多一格(設定、查看與匯出紀錄) */
.adm-tabs { display: flex; gap: var(--s1); border-bottom: 1px solid var(--line); margin-bottom: var(--s4); }
.adm-tabs a { display: inline-flex; align-items: center; height: 42px; padding: 0 var(--s4); margin-bottom: -1px; color: var(--muted);
              font-weight: 700; font-size: var(--fs-sm); border-bottom: 3px solid transparent; }
.adm-tabs a:hover { color: var(--ink); text-decoration: none; }
.adm-tabs a[aria-current="page"] { color: var(--primary); border-bottom-color: var(--primary); }
/* 分頁多到一排放不下(報表到票 09 有五格)：不換行、整排左右滑，頁面本身不會橫向捲動 */
/* 底線改用 inset 陰影畫：overflow 會裁掉往下凸 1px 的目前分頁底線 */
.adm-tabs { overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; border-bottom: 0; box-shadow: inset 0 -1px 0 var(--line); }
.adm-tabs a { margin-bottom: 0; }
.adm-tabs::-webkit-scrollbar { display: none; }
.adm-tabs a { flex: none; white-space: nowrap; }

/* ── 人員與權限(票 05) ──
 * 一張卡片列成員：每列「同仁｜角色(三選一膠囊)｜發簡訊、收摘要信兩個勾選｜移除」，四欄同一條中線；
 * 角色膠囊與移除鈕同高(36px，--ctl-h-sm)，勾選框 20px 跟文字同中線。720px 寬也排得下一列。 */
.mem-card, .log-card { margin-bottom: var(--s4); }
.role-legend { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr); gap: var(--s3) var(--s6);
               margin: var(--s3) 0 var(--s5); padding: var(--s3) var(--s4); background: var(--surface-2); border-radius: var(--r-md);
               font-size: var(--fs-xs); color: var(--ink-2); line-height: 1.5; }
.role-legend h3 { font-size: var(--fs-xs); font-weight: 800; color: var(--muted); letter-spacing: .04em; margin-bottom: 6px; }
.role-legend ul { list-style: none; display: grid; gap: 6px; }
.role-legend li { display: grid; grid-template-columns: 5.2em minmax(0, 1fr); align-items: center; gap: var(--s2); min-height: 24px; }
.role-legend .chip { justify-self: start; }
.role-legend b { font-weight: 800; color: var(--ink); }
.chip.role-viewer { background: var(--surface); color: var(--ink-2); box-shadow: inset 0 0 0 1px var(--line-2); }
.chip.role-detail { background: color-mix(in srgb, var(--data-1) 16%, var(--surface)); color: var(--data-1); }
.chip.role-admin { background: var(--primary-soft); color: var(--primary); }
.mem-grid { display: grid; grid-template-columns: minmax(140px, 1fr) auto auto auto; column-gap: var(--s4); }
.mem-head, .mem-list, .mem-row { grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; align-items: center; }
.mem-head { font-size: var(--fs-xs); font-weight: 700; color: var(--muted); padding-bottom: 6px; border-bottom: 1px solid var(--line); }
.mem-list { list-style: none; }
.mem-row { min-height: 64px; padding: 10px 0; border-bottom: 1px solid var(--line); }
.mem-row.adding { opacity: .6; pointer-events: none; }
.mem-who { display: flex; align-items: center; gap: var(--s3); min-width: 0; }
.mem-who > div { display: grid; min-width: 0; line-height: 1.4; }
.mem-who b { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; font-size: var(--fs-md); }
.mem-who small { font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ava { flex: none; display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%;
       background: var(--primary-soft); color: var(--primary); font-weight: 800; font-size: var(--fs-sm); }
.role-seg button { padding: 0 12px; }
.role-seg button[data-role="admin"][aria-pressed="true"] { color: var(--primary); }
.role-seg button[data-role="detail"][aria-pressed="true"] { color: var(--data-1); }
.mem-flags { display: flex; align-items: center; gap: var(--s4); }
.mem-flags .check { min-height: var(--ctl-h-sm); font-size: var(--fs-sm); }
.check.off { color: var(--muted); cursor: default; }
.check input:disabled { opacity: .45; cursor: default; }
.add-big { margin-top: var(--s4); }
.add-big svg { width: 18px; height: 18px; }

/* 修改紀錄：一張表，時間｜誰改的｜同仁｜改了什麼 */
.log-note { font-size: var(--fs-xs); }
.log-table { width: 100%; border-collapse: collapse; margin-top: var(--s3); font-size: var(--fs-sm); }
.log-table th { text-align: left; font-size: var(--fs-xs); font-weight: 700; color: var(--muted); padding: 6px var(--s2); border-bottom: 1px solid var(--line); }
.log-table td { padding: var(--s2); border-bottom: 1px solid var(--line); vertical-align: middle; line-height: 1.5; }
.log-table td:first-child { width: 10em; white-space: nowrap; color: var(--muted); }
.log-table td:nth-child(2), .log-table td:nth-child(3) { white-space: nowrap; }
.lg-what svg { width: 14px; height: 14px; vertical-align: -2px; color: var(--muted); }
#logMore { margin-top: var(--s3); }

/* 從在職名冊加人的窗：搜尋、可勾清單(已在名單上的停用並標角色)、加入為哪個角色 */
.modal.pick-modal { max-width: 560px; }
.roster-list { margin-top: var(--s3); max-height: 44vh; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--r-md); }
.check.pick-row { display: flex; width: 100%; gap: var(--s3); padding: 4px var(--s3); border-bottom: 1px solid var(--line); }
.check.pick-row:last-child { border-bottom: 0; }
.check.pick-row:hover { background: var(--surface-2); }
.check.pick-row.taken { cursor: default; color: var(--muted); }
.pick-row .who { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: var(--s2); }
.pick-row .who small { font-size: var(--fs-xs); color: var(--muted); }
.pick-none { margin-top: var(--s3); font-size: var(--fs-sm); }
.pick-role { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s2) var(--s3); margin-top: var(--s4); }
.pick-role > span { font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2); }
.pick-role small { flex-basis: 100%; font-size: var(--fs-xs); color: var(--muted); }
.byid-field { margin-top: var(--s4); }

/* ── 樣式頁(#/style)：視覺系統的樣張，截圖自查與對齊量測用 ── */
.section-title { font-size: var(--fs-sm); font-weight: 800; color: var(--muted); letter-spacing: .08em; margin: var(--s7) 0 var(--s3); }
.section-title:first-of-type { margin-top: var(--s4); }
.swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); gap: var(--s2); }
.swatch { border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; background: var(--surface); font-size: var(--fs-xs); }
.swatch i { display: block; height: 44px; }
.swatch b, .swatch span { display: block; padding: 0 10px; }
.swatch b { padding-top: 6px; } .swatch span { color: var(--muted); padding-bottom: 8px; }
.row { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: center; }
.type-sample { display: grid; gap: var(--s2); }
.type-sample > div { display: grid; grid-template-columns: 6em 1fr; gap: var(--s3); align-items: baseline; padding: var(--s2) 0; border-bottom: 1px dashed var(--line); }
.type-sample code { font-family: var(--mono); font-size: var(--fs-xs); color: var(--muted); }
.space-sample { display: flex; align-items: flex-end; gap: var(--s3); flex-wrap: wrap; }
.space-sample > div { display: grid; justify-items: center; gap: 4px; font-size: var(--fs-xs); color: var(--muted); font-family: var(--mono); }
.space-sample i { display: block; background: var(--primary-soft); border: 1px solid var(--primary); border-radius: 2px; }
.radius-sample { display: flex; gap: var(--s3); flex-wrap: wrap; }
.radius-sample > div { display: grid; justify-items: center; gap: 6px; font-size: var(--fs-xs); color: var(--muted); font-family: var(--mono); }
.radius-sample i { display: block; width: 72px; height: 56px; background: var(--surface); border: 1px solid var(--line); }
.bars { display: flex; align-items: flex-end; gap: 6px; height: 120px; padding-top: var(--s2); }
.bars i { flex: 1; border-radius: 4px 4px 0 0; }

/* ── 募款專案進度(票 06)：一張募款專案一張卡，電腦兩三欄、手機一欄 ──
 * 卡片由上到下：名稱與狀態、期間、達成率大數字與「已募／目標」、進度條、還差多少、三格小數字(捐款人數、筆數、最近一筆)。
 * 進度條用資料色(不用桃紅，桃紅只給要動手的地方)；達成目標換成綠色並寫「已達成目標」，顏色之外一定有字。 */
.pj-summary { display: flex; flex-wrap: wrap; gap: var(--s2); margin: calc(var(--s2) * -1) 0 0; }
.pj-summary span { display: inline-flex; align-items: baseline; gap: 4px; height: 30px; padding: 0 12px; border-radius: var(--r-pill);
                   background: var(--surface-2); color: var(--ink-2); font-size: var(--fs-sm); line-height: 30px; }
.pj-summary b { font-size: var(--fs-md); color: var(--ink); font-variant-numeric: tabular-nums; }
.pj-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--s3); }
@media (max-width: 719px) { .pj-grid { grid-template-columns: minmax(0, 1fr); } }
.pj-card { display: flex; flex-direction: column; gap: var(--s2); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
           box-shadow: var(--shadow-1); padding: var(--s4) var(--s5); min-width: 0; }
.pj-card.is-ended { background: color-mix(in srgb, var(--surface) 70%, var(--bg)); box-shadow: none; }
.pj-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); min-height: 28px; }
.pj-head h3 { font-size: var(--fs-lg); line-height: 1.35; font-weight: 800; min-width: 0; overflow-wrap: anywhere; }
.pj-head .chip { flex: none; }
.pj-when { font-size: var(--fs-xs); color: var(--muted); margin-top: -4px; }
.pj-main { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s1); }
.pj-rate { display: inline-flex; align-items: baseline; gap: 2px; font-variant-numeric: tabular-nums; line-height: 1; }
.pj-rate b { font-size: 40px; font-weight: 800; letter-spacing: -.01em; }
.pj-rate small { font-size: var(--fs-lg); font-weight: 800; color: var(--muted); }
.pj-vs { display: grid; justify-items: end; gap: 2px; font-size: var(--fs-sm); color: var(--muted); font-variant-numeric: tabular-nums; text-align: right; line-height: 1.4; }
.pj-vs b { color: var(--ink); font-weight: 800; }
.pj-amt { font-size: var(--fs-num); font-weight: 800; line-height: 1.2; font-variant-numeric: tabular-nums; }
.pj-amt small { font-size: var(--fs-md); font-weight: 700; color: var(--muted); margin-right: 4px; }
.meter { height: 12px; border-radius: var(--r-pill); background: var(--surface-2); overflow: hidden; }
.meter i { display: block; height: 100%; min-width: 4px; border-radius: var(--r-pill); background: var(--data-1); }
.meter.done i { background: var(--ok); }
.pj-gap { display: flex; align-items: center; gap: 6px; font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2); font-variant-numeric: tabular-nums; min-height: 22px; }
.pj-gap.done { color: var(--ok); }
.pj-gap svg { width: 18px; height: 18px; flex: none; }
.pj-also, .pj-nogoal { font-size: var(--fs-xs); color: var(--muted); }
.pj-meta { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s2); margin-top: auto; padding-top: var(--s3); border-top: 1px solid var(--line); }
.pj-meta div { min-width: 0; }
.pj-meta dt { font-size: var(--fs-xs); color: var(--muted); }
.pj-meta dd { font-size: var(--fs-sm); font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ── 報表(票 06 起)：分頁沿用管理頁的 .adm-tabs ──
 * 捐款用途統計：期間切換(本月、今年、自訂)在卡片標題列；自訂打開一排日期(起日、迄日、查詢同高 --ctl-h)。
 * 電腦是七欄的表：用途、兩條比較長條(深色這段期間、淺色去年同期)、金額、佔比、筆數、去年同期、增減。
 * 手機收成每個用途三行：名稱與金額、長條、小字(筆數、佔比、去年同期)與增減。 */
.pu-custom { margin-top: var(--s4); padding: var(--s4); border-radius: var(--r-md); background: var(--surface-2); }
.pu-custom .field { flex: 0 1 190px; min-width: 0; }
.pu-custom input[type=date].ctl { min-width: 0; }
@media (max-width: 719px) {
  /* 手機：起日與迄日並排各半，查詢鈕自己一列滿寬 */
  .pu-custom { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .pu-custom .btn { grid-column: 1 / -1; }
}
#purposeBody { transition: opacity .15s; }
#purposeBody.is-loading { opacity: .45; pointer-events: none; }
.pu-range { display: grid; gap: 2px; margin-top: var(--s4); font-size: var(--fs-sm); color: var(--muted); line-height: 1.5; }
.pu-range b { color: var(--ink); font-size: var(--fs-md); font-weight: 800; }
.pu-note { margin-top: var(--s3); }
.pu-total { display: flex; align-items: flex-end; justify-content: space-between; flex-wrap: wrap; gap: var(--s2) var(--s5); margin-top: var(--s3);
            padding-bottom: var(--s4); border-bottom: 1px solid var(--line); }
.pu-total .k-label { font-size: var(--fs-sm); font-weight: 700; color: var(--muted); }
.pu-total .k-num { font-size: var(--fs-num); font-weight: 800; line-height: 1.25; font-variant-numeric: tabular-nums; }
.pu-total .k-num small { font-size: var(--fs-md); font-weight: 700; color: var(--muted); margin-right: 4px; }
.pu-total .k-sub { font-size: var(--fs-xs); color: var(--muted); }
.pu-total .k-cmp { margin-top: 0; }
.pu-legend { margin: var(--s4) 0 var(--s1); }
/* 欄寬用 px 不用 em：表頭字比較小，用 em 會讓表頭與內容的欄位對不齊 */
.pu-row { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(0, 1.5fr) 124px 64px 68px 124px 92px; align-items: center; gap: var(--s3);
          padding: 12px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.pu-headrow { padding: 8px 0; font-size: var(--fs-xs); font-weight: 700; color: var(--muted); }
.pu-headrow .r, .pu-amt, .pu-share, .pu-cnt, .pu-last { text-align: right; white-space: nowrap; }
.pu-name { min-width: 0; }
.pu-name b { display: block; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pu-amt { font-weight: 800; }
.pu-share, .pu-cnt, .pu-last { color: var(--ink-2); }
.pu-delta { display: flex; justify-content: flex-end; }
.pu-bars { display: grid; gap: 3px; }
.pu-bars i { display: block; border-radius: var(--r-pill); }
.pu-bars i:not([style*="width:0.0%"]) { min-width: 3px; }
.pu-bars .now { height: 10px; background: var(--data-1); }
.pu-bars .ly { height: 6px; background: var(--data-2); }
.pu-meta { display: none; }
.pu-sum { border-bottom: 0; font-weight: 800; }
.pu-sum .pu-name b { font-weight: 800; }
@media (max-width: 719px) {
  .pu-headrow { display: none; }
  .pu-row { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name amt" "bars bars" "meta delta"; gap: 6px var(--s3); }
  .pu-name { grid-area: name; } .pu-amt { grid-area: amt; } .pu-bars { grid-area: bars; } .pu-delta { grid-area: delta; }
  .pu-meta { grid-area: meta; display: grid; min-width: 0; font-size: var(--fs-xs); color: var(--muted); line-height: 1.5; }
  .pu-meta span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .pu-share, .pu-cnt, .pu-last { display: none; }
  .pu-sum .pu-bars { display: none; }
  .pu-sum { grid-template-areas: "name amt" "meta delta"; }
}

/* ── 定期定額(票 07)：報表的一個區塊 ──
 * 由上到下：四張數字卡(有效人數、每月預估入帳、本月新增、本月取消)、近 12 個月進出圖與「每月預估入帳怎麼算」(電腦並排、手機上下)、
 * 有效定期定額名單(看明細以上，按了才讀)。進出圖：新增往上(資料色 1)、取消往下(資料色 3)、期滿疊在取消下面(灰)、圓點是淨增減。 */
.kpi .k-num small.u { margin: 0 0 0 4px; }
@media (min-width: 960px) { .rc-kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 720px) and (max-width: 959.98px) { .rc-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 719px) {
  /* 手機：有效人數與每月預估各佔一整列，本月新增與取消並排 */
  .rc-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rc-kpis #rcActive, .rc-kpis #rcMonthly { grid-column: 1 / -1; }
  .rc-kpis #rcNew, .rc-kpis #rcCancel { padding: var(--s3) var(--s4); }
  .rc-kpis #rcNew .k-num, .rc-kpis #rcCancel .k-num { font-size: var(--fs-2xl); }
}
.rc-grid { display: grid; gap: var(--s3); margin-top: var(--s3); align-items: start; }
@media (min-width: 960px) { .rc-grid { grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); } }
.sw.rc-new { background: var(--data-1); } .sw.rc-cancel { background: var(--data-3); } .sw.rc-done { background: var(--off); opacity: .7; }
.sw.rc-net { background: var(--surface); border: 2px solid var(--ink); border-radius: 50%; width: 10px; height: 10px; }
.trend .rc-up { fill: var(--data-1); }
.trend .rc-up.partial { opacity: .7; }
.trend .rc-dn { fill: var(--data-3); }
.trend .rc-dn2 { fill: var(--off); opacity: .7; }
.trend .rc-dot { fill: var(--surface); stroke: var(--ink); stroke-width: 2; pointer-events: none; }
.readout .rc-ro span { display: inline-flex; align-items: center; gap: 6px; }
/* 每月預估入帳怎麼算：一種扣款頻率一列(名稱與張數、換算方式、換算後每月)，最下面合計 */
.rc-freq { list-style: none; margin-top: var(--s2); }
.rc-freq li { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 4px var(--s3); padding: 10px 0; border-bottom: 1px solid var(--line); }
.rc-freq .rf-name { min-width: 0; display: grid; line-height: 1.4; }
.rc-freq .rf-name b { font-size: var(--fs-sm); font-weight: 700; }
.rc-freq .rf-name small { font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.rc-freq .rf-name small.rf-how { color: var(--ink-2); }
.rc-freq .rf-amt { display: grid; font-size: var(--fs-sm); font-weight: 800; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; line-height: 1.4; }
.rc-freq .rf-amt small { font-size: var(--fs-xs); font-weight: 400; color: var(--muted); }
/* 有效定期定額名單 */
.rc-list { margin-top: var(--s3); }
.rc-list .card-head { flex-wrap: nowrap; }
.rc-sub { font-size: var(--fs-xs); color: var(--muted); margin-top: 2px; }
.rc-tools { margin-top: var(--s4); padding: var(--s4); border-radius: var(--r-md); background: var(--surface-2); }
.rc-tools .rc-search { flex: 0 1 260px; }
.rc-tools .rc-sortf { flex: 0 1 240px; }
.rc-count { display: flex; align-items: center; height: var(--ctl-h); margin-left: auto; font-size: var(--fs-sm); color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.rc-table { margin-top: var(--s2); }
.rc-row { display: grid; grid-template-columns: minmax(0, 1.5fr) 132px 80px 104px 112px minmax(0, 1fr); align-items: center; gap: var(--s3);
          padding: 10px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.rc-headrow { padding: 8px 0; font-size: var(--fs-xs); font-weight: 700; color: var(--muted); }
.rc-headrow .r, .rc-amt, .rc-paid, .rc-total { text-align: right; white-space: nowrap; }
.rc-name, .rc-amt, .rc-total { min-width: 0; display: grid; line-height: 1.4; }
.rc-name b { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rc-name small, .rc-amt small, .rc-total small { font-size: var(--fs-xs); color: var(--muted); font-weight: 400; }
.rc-amt { font-weight: 800; }
.rc-next { white-space: nowrap; font-variant-numeric: tabular-nums; }
.rc-next { display: grid; line-height: 1.4; }
.rc-next small { font-size: var(--fs-xs); color: var(--muted); }
.rc-next.past { color: var(--late); }
.rc-state { display: flex; flex-wrap: wrap; gap: 4px; }
.rc-meta { display: none; }
.rc-row .num { font-variant-numeric: tabular-nums; }
@media (max-width: 719px) {
  .rc-count { margin-left: 0; height: auto; }
  .rc-headrow { display: none; }
  .rc-row { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name amt" "meta state"; gap: 4px var(--s3); }
  .rc-name { grid-area: name; } .rc-amt { grid-area: amt; } .rc-state { grid-area: state; justify-content: flex-end; }
  .rc-meta { grid-area: meta; display: block; min-width: 0; font-size: var(--fs-xs); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .rc-paid, .rc-total, .rc-next { display: none; }
}

/* ── 捐款人動態(票 08)：報表的一個區塊 ──
 * 由上到下：四張數字卡(新、持續、回流、流失)、去年到今年(兩條對齊的橫條)與近幾年圖(電腦並排、手機上下)、各年人數表、
 * 捐款人名單(看明細以上，按了才讀；年度、找姓名、排序同一列，四類用膠囊切換)。
 * 四類各一個顏色，圖、色塊、膠囊都用同一組：持續(資料色 1)、回流(資料色 3)、新(資料色 4)、流失(紅，去年有捐今年還沒捐)。 */
.sw.df-continuing, .df-fl-bar .df-continuing { background: var(--data-1); }
.sw.df-returning, .df-fl-bar .df-returning { background: var(--data-3); }
.sw.df-new, .df-fl-bar .df-new { background: var(--data-4); }
.sw.df-lapsed, .df-fl-bar .df-lapsed { background: var(--late); opacity: .8; }
.trend .df-continuing { fill: var(--data-1); }
.trend .df-returning { fill: var(--data-3); }
.trend .df-new { fill: var(--data-4); }
.trend .df-lapsed { fill: var(--late); opacity: .8; }
.trend .col.partial .df-continuing, .trend .col.partial .df-returning, .trend .col.partial .df-new { opacity: .7; }
@media (min-width: 960px) { .df-kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 720px) and (max-width: 959.98px) { .df-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 719px) {
  /* 手機：兩張一列，字小一號 */
  .df-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .df-kpis .kpi { padding: var(--s3) var(--s4); }
  .df-kpis .k-num { font-size: var(--fs-2xl); }
}
.df-kpi .k-label { display: flex; align-items: center; gap: 6px; }
.df-kpi .k-cmp { color: var(--muted); font-size: var(--fs-xs); margin-top: var(--s2); }
.df-grid { display: grid; gap: var(--s3); margin-top: var(--s3); align-items: start; }
@media (min-width: 960px) { .df-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); } }

/* 去年到今年：左邊是年份與人數，右邊是橫條(持續對齊在最左邊) */
.df-flow { display: grid; gap: var(--s3); margin-top: var(--s4); }
.df-fl-row { display: grid; grid-template-columns: 64px minmax(0, 1fr); align-items: center; gap: var(--s3); }
.df-fl-lab { display: grid; line-height: 1.3; }
.df-fl-lab b { font-size: var(--fs-sm); font-weight: 800; }
.df-fl-lab small { font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.df-fl-bar { display: flex; gap: 2px; height: 24px; border-radius: var(--r-sm); overflow: hidden; }
.df-fl-bar i { display: block; height: 100%; min-width: 3px; }
.df-fl-sum { margin-top: var(--s4); font-size: var(--fs-sm); color: var(--ink-2); line-height: 1.6; }
.df-fl-sum b { color: var(--ink); font-variant-numeric: tabular-nums; }
.df-fl-list { list-style: none; margin-top: var(--s2); }
.df-fl-list li { display: grid; grid-template-columns: 12px minmax(0, 1fr) auto; align-items: center; gap: 10px; padding: 9px 0; border-bottom: 1px solid var(--line); }
.df-fl-list li:last-child { border-bottom: 0; }
.df-fl-name { min-width: 0; display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 var(--s2); line-height: 1.4; }
.df-fl-name b { font-size: var(--fs-sm); font-weight: 700; }
.df-fl-name small { font-size: var(--fs-xs); color: var(--muted); }
.df-fl-num { font-size: var(--fs-sm); font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }
.df-fl-num small { font-size: var(--fs-xs); font-weight: 400; color: var(--muted); margin-left: 2px; }
.readout .ro-num small.u { margin: 0 0 0 4px; }

/* 各年人數：年度、捐款人、新、持續、回流、流失；新的年份在上面 */
.df-years { margin-top: var(--s3); }
.df-table { margin-top: var(--s2); }
.df-yrow { display: grid; grid-template-columns: minmax(0, 1.3fr) repeat(5, minmax(0, 1fr)); align-items: center; gap: var(--s2);
           padding: 10px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.df-yrow:last-child { border-bottom: 0; }
.df-headrow { padding: 8px 0; font-size: var(--fs-xs); font-weight: 700; color: var(--muted); }
.df-headrow span { display: flex; align-items: center; gap: 5px; }
.df-headrow .r { justify-content: flex-end; }
.df-yrow .r { text-align: right; }
.df-yrow .num { font-variant-numeric: tabular-nums; color: var(--ink-2); }
.df-yrow .df-strong { color: var(--ink); font-weight: 800; }
.df-y { display: flex; align-items: baseline; flex-wrap: wrap; gap: 0 var(--s2); min-width: 0; }
.df-y b { font-weight: 800; font-variant-numeric: tabular-nums; }
.df-y small { font-size: var(--fs-xs); color: var(--muted); }
@media (max-width: 719px) {
  /* 手機：年份下面那行小字(到幾月幾日、資料起點)換到第二行，數字對齊年份那一行(第一條基線) */
  .df-yrow { grid-template-columns: minmax(0, 1.25fr) repeat(5, minmax(0, 1fr)); align-items: baseline; gap: 6px; font-size: var(--fs-xs); }
  .df-headrow .sw { display: none; }
  .df-y { display: grid; }
  .df-y small { font-size: 11px; line-height: 1.4; }
}

/* 捐款人名單：工具列沿用定期定額的 .rc-tools(年度、找姓名、排序同高 --ctl-h)，下面四類膠囊、類別說明、名單 */
.df-tools .df-yearf { flex: 0 1 180px; }
.df-kinds { display: flex; width: max-content; max-width: 100%; margin-top: var(--s3); }
.df-kinds button { display: inline-flex; align-items: center; gap: 6px; }
.df-kinds .df-n { font-variant-numeric: tabular-nums; color: var(--muted); font-weight: 700; }
.df-kinds button[aria-pressed="true"] .df-n { color: var(--ink); }
.df-kinds button { white-space: nowrap; }
@media (max-width: 719px) {
  /* 手機：年度、找姓名、排序各佔一整列；四類膠囊平分整列，拿掉色塊才放得下「持續 124」 */
  .df-tools .field { flex: 1 1 100%; }
  .df-kinds { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); width: 100%; }
  .df-kinds button { justify-content: center; padding: 0 4px; gap: 4px; min-width: 0; }
  .df-kinds .sw { display: none; }
}
.df-kind-say { display: flex; align-items: center; gap: 6px; margin-top: var(--s3); font-size: var(--fs-sm); color: var(--ink-2); }
#dfListArea { transition: opacity .15s; }
#dfListArea.is-loading { opacity: .45; pointer-events: none; }
.df-list { margin-top: var(--s1); }
.df-lrow { display: grid; grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr)); align-items: center; gap: var(--s3);
           padding: 10px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.df-lrow .r { text-align: right; }
.df-name { min-width: 0; }
.df-name b { display: block; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.df-c1, .df-c2, .df-c3 { display: grid; line-height: 1.4; white-space: nowrap; font-variant-numeric: tabular-nums; }
.df-c1 small, .df-c2 small, .df-c3 small { font-size: var(--fs-xs); color: var(--muted); }
.df-main, .df-meta { display: none; }
@media (max-width: 719px) {
  .df-list .df-headrow { display: none; }
  .df-lrow { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name main" "meta meta"; gap: 2px var(--s3); }
  .df-name { grid-area: name; }
  .df-main { grid-area: main; display: block; font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }
  .df-meta { grid-area: meta; display: block; min-width: 0; font-size: var(--fs-xs); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .df-c1, .df-c2, .df-c3 { display: none; }
}

/* ── 報表的期間選擇(票 09 起，大額捐款人與付款管道共用) ──
 * 一張工具卡：標題與期間切換(同一列)，按「自訂」才出現日期列(沿用 .pu-custom：起日、迄日、查詢同高 --ctl-h)。
 * 下面是內容(期間範圍、數字卡、表)，換期間時整塊淡掉，畫好再亮回來。 */
.rp-body { transition: opacity .15s; }
.rp-body.is-loading { opacity: .45; pointer-events: none; }
.rp-range { margin: var(--s4) 0 var(--s2); }

/* ── 大額捐款人(票 09) ──
 * 由上到下：期間範圍、目前的兩個門檻(管理者在電腦上多一個「調整門檻」連結)、兩張數字卡(累計大額、單筆大額)、
 * 看明細以上才有兩張名單卡：累計前幾名(右上角下拉選前 20、50、100 名，只重畫)、單筆大額捐款(依金額由大到小)。 */
.bg-th { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s2); margin-bottom: var(--s3); }
.bg-th-link { display: inline-flex; align-items: center; height: 24px; font-size: var(--fs-sm); font-weight: 700; margin-left: var(--s1); }
.bg-kpis, .pm-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.bg-sub span { display: block; }
.bg-topn { display: flex; align-items: center; gap: var(--s2); flex: none; }
.bg-topn > span { margin: 0; white-space: nowrap; }
.bg-topn .ctl { width: 132px; }
/* 累計前幾名：名次｜捐款人｜累計金額｜筆數｜最大一筆｜最近一次 */
.bt-table, .bg-table { margin-top: var(--s2); }
.bt-row { display: grid; grid-template-columns: 48px minmax(0, 1.6fr) 132px 72px 124px 108px; align-items: center; gap: var(--s3);
          padding: 10px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.bt-headrow, .bg-headrow, .pm-headrow { padding: 8px 0; font-size: var(--fs-xs); font-weight: 700; color: var(--muted); }
.bt-headrow .r, .bt-rank, .bt-amt, .bt-cnt, .bt-max { text-align: right; white-space: nowrap; }
.bt-rank { color: var(--muted); font-weight: 700; padding-right: var(--s1); }
.bt-name, .bg-name { min-width: 0; display: flex; align-items: center; gap: 6px; }
.bt-name b, .bg-name b { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.bg-name .chip { flex: none; }
.bt-amt, .bg-amt { font-weight: 800; }
.bt-cnt, .bt-max { color: var(--ink-2); }
.bt-last, .bg-date { white-space: nowrap; font-variant-numeric: tabular-nums; }
.bt-meta, .bg-meta { display: none; }
/* 單筆大額捐款：收款日期｜捐款人｜金額｜捐款用途｜募款專案｜付款方式 */
.bg-row { display: grid; grid-template-columns: 96px minmax(0, 1.3fr) 120px minmax(0, 1fr) minmax(0, 1fr) minmax(0, .9fr); align-items: center; gap: var(--s3);
          padding: 10px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.bg-headrow .r, .bg-amt { text-align: right; white-space: nowrap; }
.bg-purpose, .bg-project, .bg-method { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-2); }
@media (max-width: 719px) {
  .bg-kpis .kpi { padding: var(--s3) var(--s4); }
  .bg-kpis .k-num { font-size: var(--fs-2xl); }
  .bt-headrow, .bg-headrow { display: none; }
  .bt-row { grid-template-columns: 28px minmax(0, 1fr) auto; grid-template-areas: "rank name amt" "rank meta meta"; gap: 2px var(--s2); }
  .bt-rank { grid-area: rank; align-self: start; padding-right: 0; line-height: 1.6; }
  .bt-name { grid-area: name; } .bt-amt { grid-area: amt; }
  .bt-meta { grid-area: meta; display: block; min-width: 0; font-size: var(--fs-xs); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .bt-cnt, .bt-max, .bt-last { display: none; }
  .bg-row { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name amt" "meta meta"; gap: 2px var(--s3); }
  .bg-name { grid-area: name; } .bg-amt { grid-area: amt; }
  .bg-meta { grid-area: meta; display: block; min-width: 0; font-size: var(--fs-xs); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .bg-date, .bg-purpose, .bg-project, .bg-method { display: none; }
  #bigTopCard .card-head { flex-wrap: wrap; }
  #bigTopCard .bg-topn { width: 100%; }
  #bigTopCard .bg-topn .ctl { flex: 1; width: auto; }
}

/* ── 付款管道(票 09) ──
 * 兩張數字卡(期間合計、金流手續費總額)，下面一張表：付款方式｜金額比例長條｜金額｜佔比｜筆數｜筆數佔比｜手續費｜手續費率，最後一列合計。
 * 960px 以下拿掉長條與筆數佔比；手機收成每種付款方式兩行(名稱與金額、小字)加一條長條。 */
.pm-card { margin-top: var(--s3); }
.pm-table { margin-top: var(--s2); }
.pm-row { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1.2fr) 124px 64px 76px 72px 112px 72px; align-items: center; gap: var(--s3);
          padding: 10px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.pm-headrow .r, .pm-amt, .pm-share, .pm-cnt, .pm-cshare, .pm-fee, .pm-rate { text-align: right; white-space: nowrap; }
.pm-name { min-width: 0; }
.pm-name b { display: block; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pm-amt { font-weight: 800; }
.pm-share, .pm-cnt, .pm-cshare, .pm-fee, .pm-rate { color: var(--ink-2); }
.pm-bar { display: block; height: 10px; border-radius: var(--r-pill); background: var(--surface-2); overflow: hidden; }
.pm-bar i { display: block; height: 100%; border-radius: var(--r-pill); background: var(--data-1); }
.pm-sum { border-bottom: 0; font-weight: 800; }
.pm-sum .pm-bar { background: none; }
.pm-meta { display: none; }
@media (min-width: 720px) and (max-width: 959.98px) {
  .pm-row { grid-template-columns: minmax(0, 1fr) 116px 60px 72px 104px 64px; }
  .pm-bar, .pm-cshare, .pm-headrow .h-bar, .pm-headrow .h-cshare { display: none; }
}
@media (max-width: 719px) {
  .pm-kpis { grid-template-columns: minmax(0, 1fr); }
  .pm-headrow { display: none; }
  .pm-row { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name amt" "bar bar" "meta meta"; gap: 6px var(--s3); }
  .pm-name { grid-area: name; } .pm-amt { grid-area: amt; } .pm-bar { grid-area: bar; height: 8px; }
  .pm-meta { grid-area: meta; display: grid; min-width: 0; font-size: var(--fs-xs); color: var(--muted); line-height: 1.5; }
  .pm-meta span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .pm-share, .pm-cnt, .pm-cshare, .pm-fee, .pm-rate { display: none; }
  .pm-sum { grid-template-areas: "name amt" "meta meta"; }
  .pm-sum .pm-bar { display: none; }
}

/* ── 設定(票 09，管理頁的一個區塊) ──
 * 一個群組一張卡；每一項一列：左邊名稱、說明、預設值與誰改的，右邊輸入框(280px)；多行文字整列。
 * 名稱第一行跟輸入框同一條中線(上方留 10px)；卡片底下一排「狀態文字｜還原｜儲存」，兩顆按鈕同高(--ctl-h)。
 * 金額框左邊帶 NT$、整數框右邊帶單位，字放在框裡面(絕對定位)，框本身仍是 --ctl-h 高。 */
.st-card { margin-bottom: var(--s4); }
.st-mock .card-head { justify-content: flex-start; flex-wrap: nowrap; }
.st-mock .chip { flex: none; }
.st-mock .rc-sub { margin-top: var(--s1); }
.st-form { margin-top: var(--s2); }
.st-item { display: grid; grid-template-columns: minmax(0, 1fr) 280px; gap: var(--s2) var(--s6); align-items: start; padding: var(--s4) 0; border-bottom: 1px solid var(--line); }
.st-item.wide { grid-template-columns: minmax(0, 1fr); }
.st-label { display: grid; gap: 2px; min-width: 0; padding-top: 10px; line-height: 1.5; }
.st-label label { font-weight: 800; font-size: var(--fs-md); line-height: 24px; }
.st-label small { font-size: var(--fs-xs); color: var(--ink-2); }
.st-label small.st-meta { color: var(--muted); }
.st-ctl { min-width: 0; }
.st-err { margin-top: 6px; font-size: var(--fs-xs); color: var(--late); }
.ctl[aria-invalid="true"] { border-color: var(--late); }
.ctl-affix { position: relative; }
.ctl-affix .pre, .ctl-affix .post { position: absolute; top: 0; bottom: 0; display: flex; align-items: center; font-size: var(--fs-sm); font-weight: 700; color: var(--muted); pointer-events: none; }
.ctl-affix .pre { left: 14px; }
.ctl-affix .post { right: 14px; }
.ctl-affix .ctl { text-align: right; font-variant-numeric: tabular-nums; }
.ctl-affix.has-pre .ctl { padding-left: 52px; }
.ctl-affix.has-post .ctl { padding-right: 48px; }
.st-foot { display: flex; align-items: center; justify-content: flex-end; gap: var(--s2); padding-top: var(--s4); }
.st-status { margin-right: auto; font-size: var(--fs-sm); color: var(--muted); }

/* ── 要處理的事(票 10，手機底部分頁列的「要處理」) ──
 * 手機優先：上面四個類型方塊(手機兩兩一排、電腦一排四個)，點一下只看那一種；下面一件一張卡(電腦 960px 以上兩欄)。
 * 每種一個識別色(--k)：扣款失敗紅、未付款琥珀、收據未寄金、感謝未做藍綠；卡片左邊一條色帶、類型膠囊同色。
 * 卡片下面先一排聯絡方式膠囊，再一列「已處理」(手機整列滿寬、電腦靠右)；手機 44px(大觸控區)、電腦 36px。
 * 已處理的卡片淡一階，預設收在「已處理 N 件」底下，展開看誰、何時、備註與處理紀錄。 */
.k-recur_failed { --k: var(--late); }
.k-unpaid { --k: var(--warn); }
.k-receipt { --k: var(--data-3); }
.k-thankyou { --k: var(--data-1); }
.sw.k-recur_failed, .sw.k-unpaid, .sw.k-receipt, .sw.k-thankyou { background: var(--k); }
.td-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s2); margin-bottom: var(--s4); }
@media (min-width: 720px) { .td-tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s3); } }
.td-tile { position: relative; overflow: hidden; display: grid; gap: 2px; justify-items: start; text-align: left; padding: var(--s3) var(--s4) var(--s3) calc(var(--s4) + 2px);
           background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-1); cursor: pointer;
           font: inherit; color: var(--ink); -webkit-appearance: none; appearance: none; transition: border-color .15s, box-shadow .15s; }
.td-tile::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--k); }
.td-tile:hover { border-color: var(--line-2); }
.td-tile[aria-pressed="true"] { border-color: var(--primary); box-shadow: 0 0 0 3px var(--focus); }
.td-tile .tt-name { font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2); line-height: 1.35; }
.td-tile .tt-num { font-size: var(--fs-2xl); font-weight: 800; line-height: 1.2; font-variant-numeric: tabular-nums; color: var(--k); }
.td-tile .tt-num small { font-size: var(--fs-sm); font-weight: 700; color: var(--muted); margin-left: 3px; }
.td-tile.zero .tt-num { color: var(--muted); }
.td-tile .tt-sub { font-size: var(--fs-xs); color: var(--muted); }
.td-tools { margin-bottom: var(--s2); }
.td-tools .td-search { flex: 0 1 320px; }
.td-count { display: flex; align-items: center; height: var(--ctl-h); font-size: var(--fs-sm); color: var(--muted); font-variant-numeric: tabular-nums; }
@media (max-width: 719px) { .td-count { height: auto; } }
.td-sec { display: flex; align-items: center; gap: var(--s2); margin: var(--s5) 0 var(--s3); font-size: var(--fs-md); font-weight: 800; line-height: 1.4; }
.td-sec small { font-size: var(--fs-sm); font-weight: 700; color: var(--muted); font-variant-numeric: tabular-nums; }
.td-list { display: grid; gap: var(--s3); }
@media (min-width: 960px) { .td-list { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; } }
.td-card { position: relative; overflow: hidden; display: grid; gap: var(--s2); min-width: 0; padding: var(--s4) var(--s4) var(--s4) calc(var(--s4) + 4px);
           background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-1); }
.td-card::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--k); }
.td-card.done { background: color-mix(in srgb, var(--surface) 55%, var(--bg)); box-shadow: none; }
.td-card.done::before { opacity: .45; }
.td-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s2); }
.chip.td-kind { background: color-mix(in srgb, var(--k) 14%, var(--surface)); color: var(--k); }
.td-when { font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; line-height: 24px; }
.td-when.late { color: var(--late); font-weight: 700; }
.td-who { display: flex; align-items: center; justify-content: space-between; gap: var(--s3); min-width: 0; }
.td-who b { min-width: 0; font-size: var(--fs-lg); font-weight: 800; line-height: 1.35; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.td-card.done .td-who b { color: var(--ink-2); }
.td-amt { flex: none; font-weight: 800; white-space: nowrap; }
.td-amt small { margin-left: 4px; font-size: var(--fs-xs); font-weight: 700; color: var(--muted); }
.td-desc { font-size: var(--fs-sm); color: var(--ink-2); line-height: 1.65; }
.td-flags { display: flex; flex-wrap: wrap; gap: 6px; }
.td-foot { display: grid; gap: var(--s2); margin-top: var(--s1); }
.td-contact { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); flex: 1 1 auto; min-width: 0; }
.td-c { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; height: var(--ctl-h); padding: 0 14px; border-radius: var(--r-pill);
        background: var(--surface-2); color: var(--ink); font-size: var(--fs-sm); font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.td-c span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.td-c svg { width: 18px; height: 18px; flex: none; color: var(--primary); }
a.td-c:hover { text-decoration: none; background: var(--primary-soft); }
.td-c.off { background: transparent; border: 1px dashed var(--line-2); color: var(--muted); font-weight: 400; }
.td-c.off svg { color: var(--muted); }
.td-c.none { background: transparent; color: var(--muted); font-weight: 400; padding: 0; }
.td-done { justify-self: end; }
.td-done svg { width: 18px; height: 18px; }
@media (max-width: 719px) { .td-done { justify-self: stretch; } .td-c { flex: 1 1 auto; } .td-c.none { flex: none; } }
@media (min-width: 720px) { .td-c, .td-foot .btn, .td-rec-foot .btn { height: var(--ctl-h-sm); } .td-foot .btn, .td-rec-foot .btn { padding: 0 16px; font-size: var(--fs-sm); } }
.td-record { display: grid; gap: var(--s2); margin-top: var(--s1); padding-top: var(--s3); border-top: 1px solid var(--line); }
.td-rec-main { display: flex; align-items: center; gap: var(--s2); font-size: var(--fs-sm); line-height: 1.5; color: var(--ok); }
.td-rec-main svg { width: 18px; height: 18px; flex: none; }
.td-rec-main span { color: var(--ink-2); font-variant-numeric: tabular-nums; }
.td-rec-main b { color: var(--ink); }
.td-note { padding: var(--s2) var(--s3); border-radius: var(--r-sm); background: var(--surface-2); font-size: var(--fs-sm); line-height: 1.6; overflow-wrap: anywhere; }
.td-hist summary { cursor: pointer; font-size: var(--fs-xs); color: var(--muted); }
.td-hist ol { list-style: none; display: grid; gap: 4px; margin-top: var(--s2); font-size: var(--fs-xs); color: var(--ink-2); line-height: 1.5; }
.td-rec-foot { display: flex; justify-content: flex-end; }
.td-more { display: flex; align-items: center; justify-content: center; gap: var(--s2); width: 100%; height: var(--ctl-h); margin-top: var(--s5); padding: 0 var(--s4);
           border: 1px dashed var(--line-2); border-radius: var(--r-md); background: transparent; color: var(--ink-2); font: inherit; font-size: var(--fs-sm); font-weight: 700;
           line-height: 1; cursor: pointer; -webkit-appearance: none; appearance: none; }
.td-more:hover { border-color: var(--primary); color: var(--ink); }
.td-more svg { width: 18px; height: 18px; flex: none; transition: transform .15s; }
.td-more[aria-expanded="true"] svg { transform: rotate(90deg); }
.td-done-list { margin-top: var(--s3); }
/* 更早的(設定天數以前)：每一種下面一條虛線按鈕，點了才讀；展開的卡片標「更早的」 */
.td-more.td-older { margin-top: var(--s3); flex-wrap: wrap; column-gap: var(--s2); row-gap: 0; height: auto; min-height: var(--ctl-h); padding: 6px var(--s4); line-height: 1.35; }
.td-more.td-older small { font-size: var(--fs-xs); font-weight: 600; color: var(--muted); }
.td-more.td-older:disabled { cursor: progress; opacity: .7; }
.td-older-list { margin-top: var(--s3); }
.td-sec-none { margin: 0; }
.td-tags { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.chip.td-old { background: var(--surface-2); color: var(--ink-2); }
/* 標記視窗：常用備註膠囊(36px)、備註框、字數 */
.td-quick { display: flex; flex-wrap: wrap; gap: var(--s2); margin: var(--s4) 0 var(--s3); }
.td-q { height: var(--ctl-h-sm); padding: 0 14px; border: 1px solid var(--line-2); border-radius: var(--r-pill); background: var(--surface); color: var(--ink);
        font: inherit; font-size: var(--fs-sm); font-weight: 700; line-height: 1; cursor: pointer; -webkit-appearance: none; appearance: none; }
.td-q:hover, .td-q[aria-pressed="true"] { border-color: var(--primary); background: var(--primary-soft); color: var(--primary); }
.td-note-count { margin-top: 4px; text-align: right; font-size: var(--fs-xs) !important; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ── 捐款查詢、捐款人明細、查看與匯出紀錄(票 11) ──
 * 名單上的捐款人姓名(電腦版)是連到明細頁的連結：字色照舊，滑過才變桃紅加底線，名單看起來不會一整片連結色。
 * 查詢條件卡：快速期間膠囊在標題列；起日、迄日、捐款人一排，四個下拉一排(電腦四欄，手機兩欄)，全部 --ctl-h 同高；按鈕靠右。
 * 結果：日期｜捐款人｜金額｜用途｜募款專案｜付款方式｜狀態，手機收成兩行；下面一排上一頁、頁數、下一頁。 */
.dn-link { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: inherit; }
.dn-link b { color: var(--ink); }
.dn-link:hover { text-decoration: none; }
.dn-link:hover b { color: var(--primary); text-decoration: underline; text-underline-offset: 3px; }
.td-who .dn-link { flex: 0 1 auto; }
.sq-form .card-head { margin-bottom: var(--s3); }
.sq-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s3); align-items: end; }
.sq-grid .field + .field { margin-top: 0; }
.sq-grid .sq-who { grid-column: span 2; }
.sq-grid .ctl { min-width: 0; }
.sq-actions { display: flex; align-items: center; justify-content: flex-end; gap: var(--s3); margin-top: var(--s4); }
.sq-err { margin-right: auto; color: var(--late); font-size: var(--fs-sm); font-weight: 700; }
.sq-result { margin-top: var(--s3); }
.sq-result .card-head { flex-wrap: nowrap; }
.sq-result .card-head .btn svg { width: 18px; height: 18px; }
#sqBody.is-loading { opacity: .5; pointer-events: none; transition: opacity .15s; }
.sq-table { margin-top: var(--s2); }
.sq-row { display: grid; grid-template-columns: 96px minmax(0, 1.3fr) 112px minmax(0, 1fr) minmax(0, 1fr) minmax(0, .8fr) 76px; align-items: center; gap: var(--s3);
          padding: 10px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.sq-headrow { padding: 8px 0; font-size: var(--fs-xs); font-weight: 700; color: var(--muted); }
.sq-headrow .r, .sq-amt { text-align: right; white-space: nowrap; }
.sq-amt { font-weight: 800; }
.sq-date { white-space: nowrap; font-variant-numeric: tabular-nums; }
.sq-name { min-width: 0; display: flex; align-items: center; gap: 6px; }
.sq-name > b { min-width: 0; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sq-name .dn-link b { font-weight: 700; }
.sq-name .chip { flex: none; }
.sq-purpose, .sq-project, .sq-method { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-2); }
.sq-state { display: flex; }
.sq-meta { display: none; }
.sq-pager { display: flex; align-items: center; justify-content: center; gap: var(--s3); margin-top: var(--s4); font-size: var(--fs-sm); color: var(--muted); }
@media (max-width: 719px) {
  .sq-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .sq-grid .sq-who { grid-column: 1 / -1; }
  .sq-form .card-head { flex-wrap: wrap; }
  .sq-actions { flex-wrap: wrap; }
  .sq-actions .btn { flex: 1 1 0; }
  .sq-err { flex: 1 1 100%; }
  .sq-headrow { display: none; }
  .sq-row { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name amt" "meta state"; gap: 4px var(--s3); }
  .sq-name { grid-area: name; } .sq-amt { grid-area: amt; } .sq-state { grid-area: state; justify-content: flex-end; }
  .sq-meta { grid-area: meta; display: block; min-width: 0; font-size: var(--fs-xs); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .sq-date, .sq-purpose, .sq-project, .sq-method { display: none; }
  .sq-pager { flex-wrap: wrap; }
  .sq-pager span { order: -1; flex: 1 1 100%; text-align: center; }
}
/* 捐款人明細：回上一頁、頁首(姓名、編號與類型膠囊)、三張數字卡、基本資料與聯絡方式(電腦並排)、定期定額、捐款、處理紀錄、提醒簡訊 */
.dn-back { margin-bottom: var(--s3); }
.dn-back .btn svg { width: 16px; height: 16px; transform: rotate(180deg); }
.dn-head h1 { overflow-wrap: anywhere; }
.dn-sub { display: flex !important; align-items: center; flex-wrap: wrap; gap: 6px var(--s2); margin-top: 6px !important; }
.dn-banner { margin-bottom: var(--s3); }
.dn-kpis .k-num small { margin-right: 4px; }
.dn-kpis .dn-dates { font-size: var(--fs-xl); line-height: 1.6; }
.dn-grid { display: grid; gap: var(--s3); margin-top: var(--s3); align-items: start; }
@media (min-width: 960px) { .dn-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.dn-dl { margin-top: var(--s2); }
.dn-dl-row { display: grid; grid-template-columns: 7.5em minmax(0, 1fr); align-items: center; gap: var(--s3); min-height: 44px; padding: 6px 0;
             border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.dn-dl-row dt { color: var(--muted); font-weight: 700; }
.dn-dl-row dd { min-width: 0; overflow-wrap: anywhere; }
.dn-id { display: inline-flex; align-items: center; gap: var(--s3); }
.dn-id .num { font-size: var(--fs-md); letter-spacing: .06em; }
.dn-id .dn-full { color: var(--primary); font-weight: 800; }
.dn-contact { list-style: none; margin-top: var(--s2); }
.dn-contact li { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; align-items: center; gap: var(--s3); min-height: 44px; padding: 6px 0;
                 border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.dn-c-ic { display: grid; place-items: center; color: var(--muted); }
.dn-c-ic svg { width: 18px; height: 18px; }
.dn-c-v { min-width: 0; overflow-wrap: anywhere; font-weight: 700; }
.dn-c-t { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-size: var(--fs-xs); white-space: nowrap; }
.dn-h3 { margin-top: var(--s4); font-size: var(--fs-sm); font-weight: 800; color: var(--ink-2); }
.dn-flags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--s2); }
.dn-flags .chip svg { width: 14px; height: 14px; flex: none; }
.dn-sec { margin-top: var(--s3); }
.dr-table, .dg-table { margin-top: var(--s2); }
.dr-row { display: grid; grid-template-columns: 112px 132px 80px 112px minmax(0, 1.2fr) minmax(0, 1fr); align-items: center; gap: var(--s3);
          padding: 10px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.dr-headrow, .dg-headrow { padding: 8px 0; font-size: var(--fs-xs); font-weight: 700; color: var(--muted); }
.dr-headrow .r, .dr-amt, .dr-paid, .dr-total { text-align: right; white-space: nowrap; }
.dr-start, .dr-amt, .dr-total, .dr-next, .dg-date { display: grid; line-height: 1.4; min-width: 0; }
.dr-start small, .dr-amt small, .dr-total small, .dr-next small, .dg-date small { font-size: var(--fs-xs); color: var(--muted); font-weight: 400; }
.dr-amt { font-weight: 800; }
.dr-state { display: flex; flex-wrap: wrap; gap: 4px; }
.dg-row { display: grid; grid-template-columns: 96px 112px minmax(0, 1fr) minmax(0, 1fr) minmax(0, .8fr) minmax(0, 1.1fr) 76px; align-items: center; gap: var(--s3);
          padding: 10px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.dg-headrow .r, .dg-amt { text-align: right; white-space: nowrap; }
.dg-amt { font-weight: 800; }
.dg-purpose, .dg-project, .dg-method, .dg-rc { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--ink-2); }
.dg-rc { font-size: var(--fs-xs); }
.dg-state { display: flex; }
.dg-meta { display: none; }
.dn-log td small.dn-sum { display: block; font-size: var(--fs-xs); color: var(--muted); }
@media (max-width: 719px) {
  .dr-headrow, .dg-headrow { display: none; }
  .dr-row { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "amt state" "start next"; gap: 4px var(--s3); }
  .dr-amt { grid-area: amt; text-align: left; } .dr-state { grid-area: state; justify-content: flex-end; }
  .dr-start { grid-area: start; } .dr-next { grid-area: next; text-align: right; }
  .dr-paid, .dr-total { display: none; }
  .dg-row { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "amt state" "meta meta"; gap: 4px var(--s3); }
  .dg-amt { grid-area: amt; text-align: left; } .dg-state { grid-area: state; justify-content: flex-end; }
  .dg-meta { grid-area: meta; display: block; min-width: 0; font-size: var(--fs-xs); color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .dg-date, .dg-purpose, .dg-project, .dg-method, .dg-rc { display: none; }
  .dn-log td:nth-child(2) { white-space: normal; }
}
/* 查看與匯出紀錄(管理頁區塊) */
#arExport { margin-top: var(--s3); }
.ar-table th.r, .ar-table td.r { text-align: right; }
.ar-table td.r { white-space: nowrap; }
.ar-table td .dn-link { display: inline-block; max-width: 16em; vertical-align: middle; }
.ar-cond { color: var(--ink-2); }
.lg-more { margin-top: var(--s3); }

/* ── 到期提醒(票 12，手機底部分頁列的「到期提醒」) ──
 * 上面兩個方塊切換兩份名單(手機也兩個並排，同高)：期數快扣完金色、信用卡快到期藍綠。資料來源沒有卡片到期日時方塊寫「資料來源不支援」。
 * 勾選列(有發簡訊權限才有)：全選、已勾幾位、發送鈕同一列同中線(電腦 44px)；手機發送鈕換到下一列滿寬。
 * 票 13：發送總開關未開時勾選列下面一行說明；提醒過的卡片多一行簡訊狀態膠囊；預覽窗與捐款人明細的簡訊紀錄在本節最後。
 * 一張定期定額一張卡(沿用要處理的事的卡片)：勾選框、姓名、金額同一條中線；不能發簡訊那一區色帶灰色、勾選框不能勾，改給電話與 Email。 */
.k-installments { --k: var(--data-3); }
.k-card { --k: var(--data-1); }
.sw.rn-ok { background: var(--ok); }
.sw.rn-off { background: var(--off); }
.rn-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s2); margin-bottom: var(--s4); }
@media (min-width: 720px) { .rn-tiles { grid-template-columns: repeat(2, minmax(0, 300px)); gap: var(--s3); } }
.td-tile .tt-na { font-size: var(--fs-md); color: var(--muted); }
.rn-tools { margin-bottom: var(--s3); }
.rn-tools .rn-search { flex: 0 1 320px; }
.rn-count { display: flex; align-items: center; height: var(--ctl-h); font-size: var(--fs-sm); color: var(--muted); font-variant-numeric: tabular-nums; }
@media (max-width: 719px) { .rn-count { height: auto; } }
.rn-bar { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s2) var(--s4); padding: var(--s2) var(--s4); margin-bottom: var(--s2);
          background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-1); }
.rn-bar .check { font-size: var(--fs-sm); font-weight: 700; }
.rn-picked { display: inline-flex; align-items: center; height: var(--ctl-h); font-size: var(--fs-sm); color: var(--muted); font-variant-numeric: tabular-nums; }
.rn-picked b { margin: 0 3px; color: var(--ink); }
.rn-send { margin-left: auto; }
.rn-switch { flex-basis: 100%; display: flex; align-items: flex-start; gap: 6px; margin: calc(-1 * var(--s1)) 0 var(--s1);
             font-size: var(--fs-xs); line-height: 1.6; color: var(--warn); font-weight: 700; }
.rn-switch svg { width: 16px; height: 16px; flex: none; margin-top: 1.5px; }
@media (max-width: 719px) {
  .rn-bar { padding: var(--s1) var(--s3) var(--s3); }
  .rn-send { flex: 1 1 100%; margin-left: 0; }
  .rn-switch { margin: 0; }
}
.rn-sec-note { margin: calc(-1 * var(--s2)) 0 var(--s3); font-size: var(--fs-xs); color: var(--muted); line-height: 1.6; }
.rn-card.blocked { --k: var(--off); }
.rn-card.picked { border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); background: color-mix(in srgb, var(--primary-soft) 50%, var(--surface)); }
.rn-who { display: flex; align-items: center; gap: var(--s3); min-width: 0; }
.rn-name { flex: 1 1 auto; min-width: 0; }
.rn-name b { display: block; font-size: var(--fs-lg); font-weight: 800; line-height: 1.35; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rn-card.blocked .rn-name b { color: var(--ink-2); }
.check.rn-check { flex: none; min-height: var(--ctl-h-sm); }
@media (max-width: 719px) { .check.rn-check { min-height: var(--ctl-h); padding-right: var(--s1); } }
.rn-line { font-size: var(--fs-sm); color: var(--ink-2); line-height: 1.6; font-variant-numeric: tabular-nums; }
.rn-line b { color: var(--ink); }
.rn-line .late { color: var(--late); font-weight: 700; }
.rn-line .dot { color: var(--muted); }
.rn-seg { display: inline-block; }
.rn-next { font-size: var(--fs-xs); color: var(--muted); line-height: 1.5; font-variant-numeric: tabular-nums; }
.rn-next.late { color: var(--late); }
.rn-card .chip svg { width: 13px; height: 13px; flex: none; }
.rn-mobile { display: inline-flex; align-items: center; gap: 6px; height: 24px; font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.rn-mobile svg { width: 16px; height: 16px; flex: none; color: var(--muted); }
.rn-adjust { margin-top: var(--s2); font-size: var(--fs-sm); }

/* ── 到期提醒簡訊(票 13) ──
 * 卡片：提醒過的多一行，簡訊狀態膠囊(待發、已領藍綠，已發、已送達綠，失敗、未送達紅，查不到黃)與說明同一條中線；勾選框不能勾。
 * 預覽窗：最上面一行合計(幾位、幾則)，超過 70 字的有黃色說明條；每個人一塊：姓名、手機、字數與則數膠囊同一條中線，下面是實際內文。
 * 捐款人明細：收過的提醒一則一塊(時間、哪一種到期、狀態、字數則數同一條中線；內文；發到哪支、誰按的)。 */
.rn-sent { display: flex; align-items: center; flex-wrap: wrap; gap: 4px var(--s2); min-height: 24px; }
.rn-sent .chip { font-weight: 700; }
.rn-sent-t { font-size: var(--fs-xs); color: var(--muted); line-height: 1.5; }
.rn-card.reminded:not(.blocked) { --k: color-mix(in srgb, var(--ok) 70%, var(--line)); }
.chip svg { flex: none; }
.chip.brand svg, .chip.ok svg, .chip.late svg, .chip.warn svg { width: 13px; height: 13px; }
.modal.sm-modal { max-width: 600px; max-height: calc(100dvh - 2 * var(--s4)); display: flex; flex-direction: column; }
.sm-modal .sm-list { overflow-y: auto; overscroll-behavior: contain; min-height: 0; flex: 1 1 auto; }
.sm-sum { font-size: var(--fs-md); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.sm-sum b { color: var(--ink); margin: 0 2px; }
.sm-list { list-style: none; margin: var(--s3) 0 0; padding: 0; display: grid; gap: var(--s2); }
.sm-item { padding: var(--s3); border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface-2); }
.sm-item.long { border-color: color-mix(in srgb, var(--warn) 45%, var(--line)); }
.sm-head { display: flex; align-items: center; flex-wrap: wrap; gap: 4px var(--s2); min-height: 24px; }
.sm-name { font-size: var(--fs-md); font-weight: 800; line-height: 24px; }
.sm-to { display: inline-flex; align-items: center; gap: 4px; height: 24px; font-size: var(--fs-sm); color: var(--ink-2); }
.sm-to svg { width: 14px; height: 14px; flex: none; color: var(--muted); }
.sm-n { margin-left: auto; font-variant-numeric: tabular-nums; }
.sm-body { margin-top: var(--s2); font-size: var(--fs-sm); line-height: 1.75; color: var(--ink); white-space: pre-wrap; word-break: break-word; overflow-wrap: anywhere; }
.ds-list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); }
.ds-item { padding: var(--s3) 0; border-top: 1px solid var(--line); }
.ds-item:first-child { border-top: 0; padding-top: 0; }
.ds-head { display: flex; align-items: center; flex-wrap: wrap; gap: 4px var(--s2); min-height: 24px; }
.ds-at { font-size: var(--fs-sm); font-weight: 700; color: var(--ink-2); line-height: 24px; }
.ds-n { margin-left: auto; font-size: var(--fs-xs); color: var(--muted); line-height: 24px; }
.ds-item .sm-body { max-width: 46em; }
.ds-meta { margin-top: var(--s1); font-size: var(--fs-xs); color: var(--muted); line-height: 1.6; }
/* 手機：狀態說明自己一行(膠囊在上)；簡訊紀錄的時間自己一行，種類、狀態、字數在第二行同一條中線 */
@media (max-width: 719px) {
  .rn-sent-t { flex-basis: 100%; }
  .ds-at { flex-basis: 100%; }
}
.dn-sec .ds-list { margin-top: var(--s2); }

/* ── 自動發送與續捐率(票 14) ──
 * 到期提醒頁：方塊上面一行「自動發送已開啟(綠)／沒有開啟(灰)」膠囊與說明同一條中線(手機說明換到膠囊下一行)。
 * 續捐率：三張數字卡(續捐率、收到提醒、還在觀察)，下面一張表：到期情況｜續捐比例長條｜續捐率｜收到提醒｜續捐｜沒有續捐｜還在觀察，最後一列合計。
 * 960px 以下拿掉長條；手機收成每一列兩行(名稱與續捐率、長條、小字)。 */
.rn-auto { display: flex; align-items: flex-start; gap: 4px var(--s2); min-height: 24px; margin-bottom: var(--s3); }
.rn-auto .chip { flex: none; }
.rn-auto .chip { font-weight: 700; }
.rn-auto .chip svg { width: 13px; height: 13px; flex: none; }
.rn-auto-t { flex: 1 1 auto; min-width: 0; font-size: var(--fs-sm); color: var(--muted); line-height: 24px; }
.rn-auto-t a { margin-left: var(--s2); white-space: nowrap; }
.rn-adjust { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4); }
.rr-kpis { margin-top: var(--s3); }
.rr-na { font-size: var(--fs-lg); color: var(--muted); font-weight: 700; }
.rr-table { margin-top: var(--s2); }
.rr-row { display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1.3fr) 96px 88px 72px 88px 88px; align-items: center; gap: var(--s3);
          padding: 10px 0; border-bottom: 1px solid var(--line); font-size: var(--fs-sm); }
.rr-headrow { padding: 8px 0; color: var(--muted); font-size: var(--fs-xs); font-weight: 700; }
.rr-headrow .r, .rr-rate, .rr-n { text-align: right; white-space: nowrap; }
.rr-name { min-width: 0; }
.rr-name b { display: block; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rr-rate { font-weight: 800; }
.rr-rate .rr-na { font-size: var(--fs-sm); }
.rr-n { color: var(--ink-2); }
.rr-bar { display: block; height: 10px; border-radius: var(--r-pill); background: var(--surface-2); overflow: hidden; }
.rr-bar i { display: block; height: 100%; border-radius: var(--r-pill); background: var(--ok); }
.rr-sum { border-bottom: 0; font-weight: 800; }
.rr-meta { display: none; }
@media (min-width: 720px) and (max-width: 959.98px) {
  .rr-row { grid-template-columns: minmax(0, 1fr) 88px 80px 64px 80px 80px; }
  .rr-bar, .rr-headrow .h-bar { display: none; }
}
@media (max-width: 719px) {
  .rn-auto { flex-wrap: wrap; }
  .rn-auto-t { flex-basis: 100%; line-height: 1.6; }
  .rr-kpis { grid-template-columns: minmax(0, 1fr); }
  .rr-headrow { display: none; }
  .rr-row { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name rate" "bar bar" "meta meta"; gap: 6px var(--s3); }
  .rr-name { grid-area: name; } .rr-rate { grid-area: rate; } .rr-bar { grid-area: bar; height: 8px; }
  .rr-meta { grid-area: meta; display: block; min-width: 0; font-size: var(--fs-xs); color: var(--muted); line-height: 1.5; font-weight: 400; }
  .rr-n { display: none; }
}

/* ── 年度報表(票 15) ──
 * 一張工具卡：標題、年度下拉與「下載 PDF」(同一列、同高 --ctl-h)；下面是那一年的內容：
 * 三張數字卡(捐款總額跟前一年比、捐款人數、定期定額人數變化)、每月捐款圖、依捐款用途與募款專案(電腦並排)、捐款人動態與定期定額(電腦並排)。
 * 「下載 PDF」打開的列印版是後端產的獨立頁面(src/annualreport.js)，樣式在那裡，不在這裡。 */
.ar-ctl { display: flex; align-items: center; gap: var(--s2); }
.ar-yearf { display: block; width: 168px; }
.ar-kpis { margin-top: var(--s3); }
@media (min-width: 960px) { .ar-kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.ar-month { margin-top: var(--s3); }
.ar-grid { display: grid; gap: var(--s3); margin-top: var(--s3); align-items: start; }
@media (min-width: 960px) { .ar-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.stack .cn, .sw.cn { background: var(--surface-3); box-shadow: inset 0 0 0 1px var(--line-2); }
.ar-active { margin-top: var(--s3); font-size: var(--fs-sm); color: var(--ink-2); }
.ar-active b { color: var(--ink); font-variant-numeric: tabular-nums; }
#arPdf[aria-disabled="true"] { opacity: .45; pointer-events: none; box-shadow: none; }
/* 只給螢幕閱讀器的標籤(年度下拉的「年度」) */
.sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
@media (max-width: 719px) {
  /* 手機：年度下拉與下載 PDF 並排佔滿一列 */
  .ar-bar .card-head > h2 { flex: 1 1 100%; }
  .ar-ctl { flex: 1 1 100%; }
  .ar-yearf { flex: 1 1 auto; width: auto; min-width: 0; }
}
