@charset "UTF-8";

/* @import 必須排在所有規則之前，這是 CSS 規範的硬性要求 */
@import url("tokens.css");

/* ==========================================================================
   翼王智慧會計雲 — 應用樣式表（前台與管理端共用本檔）
   Gate v2 U-1，2026-09-16
   ==========================================================================

   【本檔在誰之後載入】
   兩端的 index.php 都先載 css/bootstrap.min.css 再載本檔，所以在「選擇器
   分量相同」時本檔一定贏。這是刻意的策略：全站 40 幾支 PHP 已經滿是
   Bootstrap 的 class（btn／btn-primary／alert／table／form-control），
   與其把它們一支一支改寫成自訂 class（diff 巨大、每一次改動都是一次回歸風險），
   不如把 Bootstrap 的 CSS 變數（--bs-*）接到設計 token 上——
   改一處，全站 40 幾支檔案同時換上新設計，而且完全不動 PHP。
   這也是後續 U-2～U-5 能安心改版面的前提：視覺已經統一，那幾個 gate 只要專心處理結構。

   【為什麼不改用 Bootstrap 的 SCSS 重新編譯】
   本機沒有 Node/SCSS 工具鏈（實測 npm 不在 PATH），而且編譯產物要進版控，
   日後任何人要改一個顏色都得先裝工具鏈。用 CSS 變數覆寫是零工具鏈的做法。

   【檔案結構】
     1. 基礎（body、連結、標題、金額字體）
     2. Bootstrap 變數橋接（按鈕／表單／表格／提示訊息／導覽列）
     3. 焦點可見性（WCAG 2.4.7，既有優點，本檔強化而非取代）
     4. 版面骨架（頁首／導覽／麵包屑／內容／頁尾／代操提示列）
     5. 共用元件（提示訊息、空狀態、卡片、載入中、確認對話、權限不足）
     6. 語意化 class（取代原本散在 PHP 裡的內嵌 style）
     7. 響應式與列印
   ========================================================================== */


/* ==========================================================================
   1. 基礎
   ========================================================================== */

html {
    /* 錨點跳轉（例如「跳至主要內容」）時不要被固定頁首遮住 */
    scroll-padding-top: var(--sp-6);
}

body {
    background: var(--bg);
    color: var(--ink);
    font-family: var(--ff-sans);
    font-size: var(--fs-body);
    line-height: var(--lh-body);
}

a {
    color: var(--brand);
    text-decoration: none;
}

a:hover {
    color: var(--brand-hover);
    text-decoration: underline;   /* 不只靠顏色區分連結（WCAG 1.4.1 不以顏色為唯一手段）*/
}

h1, h2, h3, h4, h5, h6 {
    color: var(--ink);
    letter-spacing: -0.01em;
    line-height: var(--lh-tight);
}

h1 { font-size: var(--fs-page); font-weight: 700; }
h2 { font-size: 1.5rem;        font-weight: 700; }
h3 { font-size: var(--fs-sect); font-weight: 700; }
h4 { font-size: 1.0625rem;     font-weight: 700; }
h5, h6 { font-size: var(--fs-item); font-weight: 500; }

/**
 * 金額字體（設計稿：「金額一律等寬數字（tabular-nums），讓每一位數在欄內垂直對齊
 * ——這是會計報表能不能用眼睛掃出差異的關鍵。」）
 *
 * .num 是設計稿定義的 class 名稱，沿用。
 * 本系統的金額目前多半直接寫在 <td class='text-end'> 裡沒有包 .num，
 * 所以下面再補一條：表格中靠右對齊的儲存格一律套等寬數字——
 * 會計報表的右對齊欄位就是金額欄，這個推論在本系統成立（U-4 會再逐頁確認）。
 */
.num,
.table td.text-end,
.table th.text-end {
    font-family: var(--ff-num);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
}


/* ==========================================================================
   2. Bootstrap 變數橋接
   ========================================================================== */

:root {
    /* 全域 */
    --bs-body-bg:          var(--bg);
    --bs-body-color:       var(--ink);
    --bs-body-font-family: var(--ff-sans);
    --bs-body-font-size:   var(--fs-body);
    --bs-body-line-height: var(--lh-body);
    /* U-6b（2026-09-17）：由 var(--line)（1.35:1）改為 var(--line-interactive)（3.92:1）。
       Bootstrap 把這個變數當成「元件」的預設框線色，本專案實際吃到它的只有
       .form-check-input（勾選框／單選鈕，76 處）——.table／.form-control／.form-select／
       .table-responsive／.ew-card／.dropdown-menu 在本檔都已各自明寫框線色，不受影響；
       .img-thumbnail／.input-group-text／.nav-tabs／.accordion／.pagination／.list-group／
       .modal／.border* 這些 Bootstrap 元件全站零使用（已逐一 grep 確認）。
       也就是說裝飾性框線的視覺完全不變，變的只有那個真正需要 3:1 的控制項邊界。 */
    --bs-border-color:     var(--line-interactive);
    --bs-border-radius:    var(--r);
    --bs-border-radius-sm: var(--r);
    --bs-border-radius-lg: var(--r);
    --bs-link-color:       var(--brand);
    --bs-link-hover-color: var(--brand-hover);
    --bs-secondary-color:  var(--ink-2);
    --bs-tertiary-color:   var(--ink-3);
    --bs-emphasis-color:   var(--ink);
    --bs-heading-color:    var(--ink);
}

/* ---------- 按鈕階層（設計稿：主要／次要／危險／停用，最小高度 44px）---------- */

.btn {
    --bs-btn-padding-x: var(--btn-px);
    --bs-btn-padding-y: 0;
    --bs-btn-font-size: var(--fs-body);
    --bs-btn-font-weight: 500;
    --bs-btn-border-radius: var(--r);
    --bs-btn-line-height: var(--lh-tight);

    /* 觸控目標：設計稿「手機上按不到的按鈕等於沒有按鈕」。
       用 min-height + inline-flex 置中，而不是固定 height——
       文字放大 200% 時按鈕才會跟著長高而不是把字切掉（WCAG 1.4.4）。 */
    min-height: var(--tap);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
}

/* 表格操作欄裡的小按鈕沿用 Bootstrap 的 btn-sm，但觸控目標不縮水 */
.btn-sm {
    --bs-btn-padding-x: var(--sp-3);
    --bs-btn-font-size: var(--fs-label);
}

/* 主要動作：實心主色 + 白字（前台 6.00:1／管理端 5.59:1） */
.btn-primary {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--brand);
    --bs-btn-border-color: var(--brand);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--brand-hover);
    --bs-btn-hover-border-color: var(--brand-hover);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--brand-hover);
    --bs-btn-active-border-color: var(--brand-hover);
    --bs-btn-disabled-color: var(--ink-3);
    --bs-btn-disabled-bg: var(--line-2);
    --bs-btn-disabled-border-color: var(--line);
}

/**
 * 主要動作的外框版（U-1 第二輪修正，2026-09-16）
 *
 * 【為什麼補這一條：它是本 gate 造成的對比度回歸】
 * 第一輪的 Bootstrap→token 橋接是「憑印象列變體」，處理了 .btn-outline-secondary
 * 與 .btn-outline-danger，**唯獨漏了 .btn-outline-primary**。
 * 漏掉的後果不只是「沒接到 token」，而是一個真正的無障礙回歸：
 *   這顆按鈕沿用 Bootstrap 原廠的 primary 藍 #0d6efd，改版前它疊在純白 #ffffff 上
 *   剛好是 4.50:1（貼著門檻過關）；U-1 把頁面底色由白改成 --bg（#F9FAFC）之後
 *   就掉到 4.31:1，未達 4.5:1。按鈕的 HTML 一個字都沒改，壞掉的是它所在的配色環境。
 *   在管理端還會多一個問題：它顯示成藍色，而不是管理端該有的綠色。
 *
 * 接到 --brand 之後：前台 --brand 對 --surface 6.00:1、對 --bg 5.74:1；
 * 管理端透過 Manager/css/app.css 的主色覆寫自動變綠，--admin 對 --surface 5.59:1、
 * 對 --bg 5.36:1。四種組合都在門檻之上，不再貼邊。
 *
 * 【根因不是漏一行，是「列舉的來源錯了」】
 * 正確的做法是拿「程式碼裡實際用到的變體」當清單，而不是憑印象。
 * 實測全站（排除 _0old／tcpdf／vendor／securimage）用到的變體與處數：
 *   btn-primary 52、btn-sm 23、btn-default 16、btn-secondary 10、btn-success 9、
 *   btn-danger 7、btn-warning 4、btn-outline-primary 2、btn-outline-danger 2、btn-link 2
 * 本輪依這份清單把三個沒接到的一次補齊（outline-primary、warning、default），
 * 日後新增變體時請重跑一次上面那道 grep。
 */
.btn-outline-primary {
    --bs-btn-color: var(--brand);
    --bs-btn-bg: var(--surface);
    --bs-btn-border-color: var(--brand);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--brand);
    --bs-btn-hover-border-color: var(--brand);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--brand-hover);
    --bs-btn-active-border-color: var(--brand-hover);
    --bs-btn-disabled-color: var(--ink-3);
    --bs-btn-disabled-bg: var(--line-2);
    --bs-btn-disabled-border-color: var(--line);
}

/**
 * 次要動作：白底 + 框線（設計稿的「取消」）
 *
 * U-1 第二輪追加兩個變體到同一組：
 *   .btn-warning —— 全站只用在 4 顆「清除」（type=reset）。Bootstrap 原廠的黃色
 *     不在設計系統裡，而「清除」在語意上是次要動作、不是警告；接到次要樣式
 *     才符合設計稿的按鈕階層。對比由 #000 on #ffc107 變成 --ink on --surface（16.03:1）。
 *   .btn-default —— 這是 Bootstrap 3 的 class，Bootstrap 5 根本沒有定義它，
 *     所以全站 16 顆「回上一頁」按鈕目前是「沒有底色也沒有框線」的裸按鈕，
 *     看起來不像按鈕。接到次要樣式之後它們才有可辨識的邊界（1.4.11）。
 *     這兩項都不改 HTML，只是讓既有的 class 名稱指到正確的樣式。
 */
.btn-secondary,
.btn-outline-secondary,
.btn-light,
.btn-dark,
.btn-warning,
.btn-default {
    --bs-btn-color: var(--ink);
    --bs-btn-bg: var(--surface);
    /* U-6b（2026-09-17）：由 var(--line) 改為 var(--line-interactive)。
       這一組按鈕的填色是 --surface（白），周圍多半也是白，比值 1:1；
       「這是一顆可按的控制項」這件事完全靠這條框線傳達，所以它適用 1.4.11 的 3:1。
       原本指到標示為裝飾用途的 --line 只有 1.35:1（對白）／1.29:1（對頁面底色）／
       1.18:1（對代操提示列的琥珀底），改後分別是 3.92／3.76／3.44:1。
       停用狀態的框線（下面那行 disabled-border-color）刻意維持 --line 不動：
       1.4.11 明文豁免 inactive 元件，把它一起調深會讓「不能按」的訊息消失。 */
    --bs-btn-border-color: var(--line-interactive);
    --bs-btn-hover-color: var(--ink);
    --bs-btn-hover-bg: var(--line-2);
    --bs-btn-hover-border-color: var(--ink-3);
    --bs-btn-active-color: var(--ink);
    --bs-btn-active-bg: var(--line-2);
    --bs-btn-active-border-color: var(--ink-3);
    --bs-btn-disabled-color: var(--ink-3);
    --bs-btn-disabled-bg: var(--line-2);
    --bs-btn-disabled-border-color: var(--line);
}

/* 破壞性動作：白底 + 危險色框線與文字（設計稿的「刪除」）。
   不做成實心紅：實心紅在列表裡每一列都出現時會變成視覺噪音，
   而且會把「刪除」看起來像主要動作。 */
.btn-danger,
.btn-outline-danger {
    --bs-btn-color: var(--danger);
    --bs-btn-bg: var(--surface);
    --bs-btn-border-color: var(--danger);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--danger);
    --bs-btn-hover-border-color: var(--danger);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--danger);
    --bs-btn-active-border-color: var(--danger);
}

/* 正向完成（列印、匯出）：既有程式用 btn-success，接到設計的「已完成」色 */
.btn-success {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--ok);
    --bs-btn-border-color: var(--ok);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: var(--ok-hover);
    --bs-btn-hover-border-color: var(--ok-hover);
    --bs-btn-active-color: #fff;
    --bs-btn-active-bg: var(--ok-hover);
    --bs-btn-active-border-color: var(--ok-hover);
}

/* 停用（設計稿的「已結帳」）：灰底灰字、游標明示不可點 */
.btn:disabled,
.btn.disabled {
    cursor: not-allowed;
    opacity: 1;              /* 不用半透明：半透明會讓對比度不可預測 */
}

/* 連結型按鈕（表格內的文字操作） */
.btn-link {
    --bs-btn-color: var(--brand);
    --bs-btn-hover-color: var(--brand-hover);
}

/* ---------- 表單欄位 ---------- */

.form-label,
.col-form-label {
    font-size: var(--fs-label);
    font-weight: 500;
    color: var(--ink);
    margin-bottom: var(--sp-1);
}

.form-control,
.form-select {
    font-family: inherit;
    font-size: var(--fs-input);
    min-height: var(--tap);
    padding: var(--sp-2) var(--sp-3);
    color: var(--ink);
    background-color: var(--surface);
    border-radius: var(--r);

    /**
     * 【與設計稿的唯一一處刻意差異，請 verifier 注意】
     * 設計稿的輸入框框線是 var(--line)，實測它對白底只有 1.35:1。
     * WCAG 2.1 的 1.4.11 非文字對比要求「識別 UI 元件所需的視覺資訊」達 3:1，
     * 輸入框的邊界正是這種資訊——看不到框線就不知道哪裡可以打字。
     * 這裡改用同一套 token 裡的 --ink-3（對白底 5.05:1），沒有新增任何顏色。
     * 改前的 Bootstrap 預設 #dee2e6 是 1.29:1，所以這是改善不是回歸。
     */
    border: 1px solid var(--ink-3);
}

.form-control::placeholder {
    color: var(--ink-3);        /* 5.05:1，達一般文字門檻 */
    opacity: 1;                 /* Firefox 預設會再壓透明度，關掉才守得住對比 */
}

.form-control:focus,
.form-select:focus {
    border-color: var(--brand);
    box-shadow: 0 0 0 var(--sp-1) var(--focus-ring);
}

/* 金額輸入一律靠右 + 等寬數字 */
.form-control.num,
input[type="number"].form-control {
    text-align: right;
}

/* 錯誤狀態（設計稿：危險色框線 + 危險色淡底 + 以 aria-describedby 綁定的說明） */
.form-control.is-invalid,
.form-select.is-invalid,
.ew-field--error .form-control,
.ew-field--error .form-select {
    border-color: var(--danger);
    background-color: var(--danger-soft);
}

.invalid-feedback,
.ew-field__error {
    display: block;
    font-size: var(--fs-note);
    color: var(--danger);
    margin-top: var(--sp-1);
}

/* 欄位說明文字 */
.form-text,
.ew-field__hint {
    display: block;
    font-size: var(--fs-note);
    color: var(--ink-2);        /* 7.43:1 */
    margin-top: var(--sp-1);
    line-height: var(--lh-body);
}

/* 一組「標籤 + 欄位 + 說明／錯誤」的垂直堆疊（設計稿的表單欄位範例） */
.ew-field {
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    margin-bottom: var(--sp-4);
}

/* ---------- 資料表格 ---------- */

.table {
    --bs-table-color: var(--ink);
    --bs-table-bg: var(--surface);
    --bs-table-border-color: var(--line);
    --bs-table-striped-color: var(--ink);
    --bs-table-striped-bg: var(--line-2);
    --bs-table-hover-color: var(--ink);
    --bs-table-hover-bg: var(--brand-soft);
    font-size: var(--fs-label);
    vertical-align: middle;
}

.table > thead th,
.table > thead td {
    background: var(--line-2);
    color: var(--ink-2);        /* 對 --line-2 實測 6.43:1，達一般文字門檻 */
    font-weight: 500;
}

/**
 * 表頭不換行——只在「有橫向捲動容器」的表格裡才套用（U-1 第二輪，實測修正）
 *
 * 設計稿的表頭是 white-space: nowrap，理由很實際：「傳票編號」在 44px 的欄位裡
 * 會被擠成一字一行（v1 已量測過的問題）。但 nowrap 只有在表格可以橫向捲動時才安全；
 * 套在沒有捲動容器的表格上，內容撐不下就會變成整頁水平溢出。
 * 實測：會計科目表管理（Act=8200）那張 10 欄的表格沒有 .table-responsive，
 * 文字放大 200% 時整頁 scrollWidth 由 1280 變成 1281px。
 * 因此把 nowrap 限縮在 .table-responsive 內；其餘表格維持可換行。
 * （U-4／U-5 會把報表與設定頁的寬表格逐一放進 .table-responsive，屆時自動套上。）
 */
.table-responsive > .table > thead th,
.table-responsive > .table > thead td {
    white-space: nowrap;
}

/**
 * 儲存格內距（U-1 第二輪，實測修正）
 *
 * 設計稿的表格欄距是 14px，但設計稿的表格一律放在橫向捲動容器裡；
 * 本系統目前還有幾張寬表格是裸的 <table>（會計科目表管理 10 欄、資產負債表的版面表格等，
 * 要到 U-4／U-5 才會逐一放進捲動容器）。在那些表格上把欄距從 Bootstrap 的 8px 加寬到 12px，
 * 等於每一欄多 8px，10 欄就是 80px——實測會讓「文字放大 200%」時的水平溢出由 0px 變成 1px，
 * 320px 寬時原本就溢出的報表再多溢出約 19px。那是本 gate 造成的回歸，不能留。
 *
 * 所以：沒有捲動容器的表格維持 8px（與改版前相同，零回歸）；
 *       已經放進 .table-responsive 的表格才用較寬鬆的 12px（溢出由容器吸收）。
 * U-4／U-5 把寬表格逐一包進捲動容器之後，設計稿的密度就會自然套用上去。
 */
.table > :not(caption) > * > * {
    padding: var(--sp-2) var(--sp-2);
}

.table-responsive > .table > :not(caption) > * > * {
    padding: var(--sp-2) var(--sp-3);
}

/* 橫向捲動容器：v1 已定案「寬報表一律不做卡片化」，
   改用 table-responsive + min-width，借貸左右比對與列印版才會一致。 */
.table-responsive {
    border: 1px solid var(--line);
    border-radius: var(--r);
    background: var(--surface);
}

.table-responsive > .table {
    margin-bottom: 0;
}

/* ---------- 提示訊息（Bootstrap alert 接到設計的四種語意）---------- */

.alert {
    --bs-alert-border-radius: var(--r);
    font-size: var(--fs-label);
    line-height: var(--lh-body);
    padding: var(--sp-3) var(--sp-4);
    border: 1px solid transparent;
    border-left-width: 3px;     /* 設計稿：左側 3px 語意色實線 */
}

.alert-danger {
    --bs-alert-color: var(--ink);
    --bs-alert-bg: var(--danger-soft);
    --bs-alert-border-color: var(--danger);
    --bs-alert-link-color: var(--danger);
    border-left-color: var(--danger);
}

.alert-warning {
    --bs-alert-color: var(--ink);
    --bs-alert-bg: var(--warn-soft);
    --bs-alert-border-color: var(--warn);
    --bs-alert-link-color: var(--warn-icon);
    border-left-color: var(--warn);
}

.alert-success {
    --bs-alert-color: var(--ink);
    --bs-alert-bg: var(--admin-soft);
    --bs-alert-border-color: var(--ok);
    --bs-alert-link-color: var(--ok);
    border-left-color: var(--ok);
}

.alert-info,
.alert-primary,
.alert-secondary,
.alert-light,
.alert-dark {
    --bs-alert-color: var(--ink);
    --bs-alert-bg: var(--brand-soft);
    --bs-alert-border-color: var(--brand);
    --bs-alert-link-color: var(--brand);
    border-left-color: var(--brand);
}

/* alert 內的圖示不要被文字擠壓 */
.alert .bi {
    flex-shrink: 0;
    color: inherit;
}

/* ---------- Bootstrap 文字語意色（既有 PHP 用得到的幾個）---------- */

.text-danger  { color: var(--danger) !important; }   /* 6.04:1，取代原本 14 處 color:red 的 4.00:1 */
.text-success { color: var(--ok) !important; }
.text-warning { color: var(--warn-icon) !important; } /* 警示文字用深一階的 --warn-icon，才守得住 4.5:1 */
.text-muted,
.text-secondary { color: var(--ink-2) !important; }

/* ---------- 導覽列 ---------- */

.navbar {
    --bs-navbar-color: var(--ink-2);
    --bs-navbar-hover-color: var(--brand);
    --bs-navbar-active-color: var(--brand);
    --bs-navbar-brand-color: var(--ink);
    --bs-navbar-brand-hover-color: var(--ink);
    --bs-navbar-padding-y: 0;
    padding-left: 0;
    padding-right: 0;
    background: var(--surface) !important;   /* 蓋掉既有 markup 的 bg-body-tertiary */
}

.navbar .nav-link,
.navbar .dropdown-toggle {
    font-size: var(--fs-body);
    /* 設計稿的分頁式導覽：目前位置以主色底線標示。
       min-height 44px 讓手機上每個選單項目都是合格的觸控目標。 */
    min-height: var(--tap);
    display: flex;
    align-items: center;
    padding: 0 var(--sp-3);
    border-bottom: 2px solid transparent;
}

.navbar .nav-link.active,
.navbar .nav-link[aria-current="page"] {
    color: var(--brand);
    font-weight: 500;
    border-bottom-color: var(--brand);
}

.dropdown-menu {
    --bs-dropdown-border-color: var(--line);
    --bs-dropdown-border-radius: var(--r);
    --bs-dropdown-link-color: var(--ink);
    --bs-dropdown-link-hover-bg: var(--brand-soft);
    --bs-dropdown-link-hover-color: var(--brand);
    --bs-dropdown-link-active-bg: var(--brand-soft);
    --bs-dropdown-link-active-color: var(--brand);
    --bs-dropdown-font-size: var(--fs-body);
}

.dropdown-item {
    min-height: var(--tap);
    display: flex;
    align-items: center;
}

.dropdown-item.active,
.dropdown-item[aria-current="page"] {
    font-weight: 500;
}

/**
 * 行動版導覽的漢堡鈕（Gate v2 U-3 順手修）
 *
 * Bootstrap 的 .navbar-toggler 實測是 56×40px，高度差 4px 沒到 44px 的觸控目標下限。
 * 它是手機上「唯一」能打開選單的控制項，按不準就等於整個導覽不可用。
 * 只加 min-height，寬度與內距都不動，所以不會影響任何頁面的水平尺寸
 * （U-1／U-2 的 320px 零溢出基準不受影響，改後已重新實測）。
 */
.navbar-toggler {
    min-height: var(--tap);
}


/* ==========================================================================
   3. 焦點可見性（WCAG 2.4.7）
   ==========================================================================

   這一項在改版前已經通過（Bootstrap 預設的 box-shadow 焦點環），屬「不可回歸」，
   所以本檔只加強、不移除。

   設計稿的焦點示範是 outline: 3px solid oklch(0.50 0.13 250 / 0.35)。
   實測那個半透明色疊在白底上只有約 1.4:1，單獨使用不符合 1.4.11（焦點指示需 3:1），
   所以這裡做成兩層：
     內層 3px 實心主色 outline —— 對白底 6.00:1，這是真正保證看得見的那一層；
     外層 6px 半透明光暈 box-shadow —— 重現設計稿的視覺。
   選擇器同時列出 .btn / .form-control 等 Bootstrap 類別，
   是因為 Bootstrap 自己的 .btn:focus-visible 分量是 (0,2,0)，
   只寫 :focus-visible（(0,1,0)）會被它蓋掉。
   ========================================================================== */

:focus-visible,
.btn:focus-visible,
.btn-check:focus-visible + .btn,
.nav-link:focus-visible,
.dropdown-item:focus-visible,
.navbar-toggler:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible,
.page-link:focus-visible {
    outline: 3px solid var(--brand);
    outline-offset: 2px;
    box-shadow: 0 0 0 6px var(--focus-ring);
}

/* 輸入框取得焦點時同時保留上面 .form-control:focus 的邊框變化，兩者不衝突 */
.form-control:focus-visible,
.form-select:focus-visible {
    border-color: var(--brand);
}


/* ==========================================================================
   4. 版面骨架
   ==========================================================================
   對應設計稿 Dashboard／Journal 兩張畫板的頁首：
   品牌標記 → 分隔線 → 目前客戶（名稱 + 統編） → 彈性留白 → 使用者 → 登出。
   ========================================================================== */

.ew-header {
    background: var(--surface);
    border-bottom: 1px solid var(--line);
}

.ew-header__inner {
    display: flex;
    align-items: center;
    flex-wrap: wrap;            /* 手機上自動換行，不擠壓、不溢出 */
    gap: var(--sp-3) var(--sp-5);
    padding: var(--sp-2) var(--sp-4);
    min-height: 60px;           /* 設計稿 60px；用 min-height，文字放大時才長得開 */
}

.ew-header__brand {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    color: var(--ink);
    font-size: var(--fs-input);
    font-weight: 700;
    letter-spacing: -0.01em;
}

.ew-header__brand:hover {
    color: var(--ink);
    text-decoration: none;
}

/* 品牌標記：主色圓角方塊 + 白色帳簿圖示，兩端只差主色 */
.ew-header__mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 26px;
    height: 26px;
    border-radius: 5px;
    background: var(--brand);
    color: #fff;
    font-size: 15px;
    line-height: 1;
}

.ew-header__divider {
    width: 1px;
    height: 22px;
    background: var(--line);
    flex-shrink: 0;
}

.ew-header__company {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;               /* 讓長公司名可以被 flex 壓縮而不是撐破版面 */
}

.ew-header__company-name {
    font-size: var(--fs-body);
    font-weight: 500;
}

.ew-header__company-meta {
    font-size: var(--fs-micro);
    color: var(--ink-3);
}

.ew-header__spacer {
    flex-grow: 1;
}

.ew-header__user {
    font-size: var(--fs-label);
    color: var(--ink-2);
}

/* 導覽列所在的那一條（在頁首底下、與頁首同一張白底） */
.ew-nav {
    background: var(--surface);
    border-bottom: 1px solid var(--line);
    padding: 0 var(--sp-4);
}

/**
 * 看得見的頁面標題（Gate v2 U-2）
 *
 * h1 的字級／字重已由基礎樣式給（--fs-page / 700），這裡只處理下方留白。
 * U-1 的 h1 全站都是 visually-hidden（因為每支功能檔自己有 h3，同一句話會出現兩次）；
 * 儀表板是第一個沒有 h3 的頁面，所以它的 h1 改成看得見的。
 * U-3／U-4／U-5 把各功能檔的 h3 收掉時，那些頁面也會改用這個 class。
 */
.ew-page__title {
    margin: 0 0 var(--sp-4);
}

/* 麵包屑：設計稿是 12px、--ink-3、以「/」分隔的一行小字，壓在頁面標題上方 */
.ew-crumb {
    font-size: var(--fs-note);
    color: var(--ink-3);
    margin-bottom: var(--sp-1);
}

.ew-crumb ol {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-1);
    margin: 0;
    padding: 0;
}

.ew-crumb li + li::before {
    content: "/";
    margin-right: var(--sp-1);
    color: var(--line);
}

.ew-crumb a {
    color: var(--ink-3);
}

.ew-crumb a:hover {
    color: var(--brand);
}

/**
 * 內容容器
 *
 * 左右留白為什麼寫成 max(...)（U-1 第二輪，實測修正）：
 *   本容器取代的是原本的 .container-fluid，而它底下各功能檔輸出的 Bootstrap .row
 *   帶有負的左右外距（-0.5 × --bs-gutter-x），本來是靠 container 的同值 padding 抵銷的。
 *   若這裡寫死 16px，使用者把文字放大到 200%（root 32px）時 gutter 會變成 48px、
 *   負外距變成 -24px，16px 的 padding 抵不掉，整頁就會水平溢出 8px——
 *   這一點是 Playwright 實測抓到的（放大前 0px、放大後 8px）。
 *   max() 讓留白至少等於半個 gutter：一般字級時取設計稿的 16px，
 *   文字放大時自動長到 24px，兩種情況都不會溢出。
 */
.ew-page {
    padding: var(--sp-5) max(var(--sp-4), calc(0.5 * var(--bs-gutter-x, 1.5rem))) var(--sp-7);
}

/* 頁尾 */
.ew-footer {
    border-top: 1px solid var(--line);
    background: var(--surface);
    padding: var(--sp-4);
    font-size: var(--fs-note);
    color: var(--ink-3);
}

/**
 * 事務所代操提示列
 *
 * 改版前這只是 Bootstrap 的 alert-warning 一行文字，和頁面其他提示長得一樣，
 * 使用者分不出「我現在是以事務所身分在別人的帳上操作」。
 * 改成整條橫幅：警告色底、上下各一條實線、左側粗色條，視覺上明確與頁首分離。
 */
.ew-acting {
    background: var(--warn-soft);
    border-top: 1px solid var(--warn);
    border-bottom: 1px solid var(--warn);
    border-left: 4px solid var(--warn);
    padding: var(--sp-2) var(--sp-4);
}

.ew-acting__inner {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--sp-2) var(--sp-3);
    font-size: var(--fs-label);
    line-height: var(--lh-body);
}

.ew-acting__icon {
    color: var(--warn-icon);    /* 對 --warn-soft 4.93:1 */
    flex-shrink: 0;
}

.ew-acting__spacer {
    flex-grow: 1;
}


/* ==========================================================================
   5. 共用元件
   ========================================================================== */

/* ---------- 卡片 ---------- */
.ew-card {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r);
    padding: var(--sp-4) var(--sp-5);
}

/**
 * 區段小標（設計稿：13px / 700 / 字距 0.06em / --ink-3，例「需要處理」「本月收支」）
 *
 * .ew-card__title 與 .ew-sect__title 共用同一條規則：兩者在設計稿裡是同一個字級樣式，
 * 分成兩個名稱只是因為一個掛在卡片裡、一個掛在區段標題上（U-2 儀表板用後者）。
 * 寫成同一條而不是複製一份，是為了「改字級時不會只改到一半」。
 */
.ew-card__title,
.ew-sect__title {
    font-size: var(--fs-note);
    font-weight: 700;
    letter-spacing: 0.06em;
    color: var(--ink-3);
    margin: 0 0 var(--sp-2);
}

/* ---------- 提示訊息（不依賴 Bootstrap 的版本）---------- */
.ew-alert {
    display: flex;
    align-items: flex-start;
    gap: var(--sp-2);
    padding: var(--sp-3) var(--sp-4);
    border-radius: var(--r);
    border-left: 3px solid var(--brand);
    background: var(--brand-soft);
    font-size: var(--fs-label);
    line-height: var(--lh-body);
    color: var(--ink);
}

.ew-alert__icon { flex-shrink: 0; color: var(--brand); }
.ew-alert strong { font-weight: 500; }

.ew-alert--danger { background: var(--danger-soft); border-left-color: var(--danger); }
.ew-alert--danger .ew-alert__icon { color: var(--danger); }

.ew-alert--warn   { background: var(--warn-soft); border-left-color: var(--warn); }
.ew-alert--warn .ew-alert__icon { color: var(--warn-icon); }

.ew-alert--ok     { background: var(--admin-soft); border-left-color: var(--ok); }
.ew-alert--ok .ew-alert__icon { color: var(--ok); }

/* ---------- 空狀態（設計稿：虛線框、置中、圖示 + 標題 + 說明 + 主要動作）---------- */
.ew-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--sp-7) var(--sp-4);
    background: var(--surface);
    border: 1px dashed var(--line);
    border-radius: var(--r);
}

.ew-empty__inner {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-2);
    text-align: center;
    max-width: 42ch;
}

.ew-empty__icon  { color: var(--ink-3); font-size: 2rem; line-height: 1; }
.ew-empty__title { font-size: var(--fs-input); font-weight: 500; }
.ew-empty__desc  { font-size: var(--fs-label); color: var(--ink-2); line-height: var(--lh-loose); }

/* ---------- 載入中 ----------
   用純 CSS 的旋轉圈，不引進任何套件。
   prefers-reduced-motion 時改成靜態（WCAG 2.3.3 動畫可關閉）。 */
.ew-spinner {
    display: inline-block;
    width: 1.25em;
    height: 1.25em;
    vertical-align: -0.2em;
    border: 2px solid var(--line);
    border-top-color: var(--brand);
    border-radius: 50%;
    animation: ew-spin 0.8s linear infinite;
}

@keyframes ew-spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    .ew-spinner { animation: none; border-top-color: var(--line); }
    * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* ---------- 確認對話 ----------
   用平台原生的 <dialog>（showModal() 自帶焦點陷阱、Esc 關閉、aria-modal），
   不自製 modal 也不動用 Bootstrap 的 JS Modal。 */
.ew-dialog {
    border: 1px solid var(--line);
    border-radius: var(--r);
    background: var(--surface);
    color: var(--ink);
    padding: var(--sp-5);
    max-width: 32rem;
    font-size: var(--fs-label);
}

.ew-dialog::backdrop { background: var(--scrim); }
.ew-dialog__title   { font-size: var(--fs-item); font-weight: 700; margin: 0 0 var(--sp-2); }
.ew-dialog__actions { display: flex; justify-content: flex-end; gap: var(--sp-2); margin-top: var(--sp-5); }

/* ---------- 權限不足 ----------
   取代原本 25 處的 <p style='text-align:center; color:red;'>。
   原本那個 color:red 對白底只有 4.00:1（未達 4.5:1），
   換成 --danger 之後是 6.04:1。上方留白由本 class 提供，
   所以呼叫端那四個 <br> 也一併刪掉。 */
.ew-denied {
    margin: var(--sp-7) auto;
    max-width: 42ch;
    text-align: center;
    font-size: var(--fs-item);
    color: var(--danger);
}


/* ==========================================================================
   6. 語意化 class（取代原本散在 PHP 裡的內嵌 style）
   ==========================================================================
   每一條都標明它取代了哪一處，方便日後追溯。
   ========================================================================== */

/* 頁首 h1 旁的公司名稱小字（原 index.php 的 style='font-size: 0.6em; '） */
.ew-title-sub {
    font-size: 0.6em;
    font-weight: 400;
    color: var(--ink-2);
}

/* 日記簿列表：9 個欄位低於 720px 會被擠成一字一行（原 NJournal.php 的 min-width:720px） */
.ew-table-journal { min-width: 720px; }

/* 傳票明細分錄表（原 NJournalEdit.php 的 min-width:640px）。
   U-3 已把這個值與借／貸欄寬一起搬到下方 6c 段（金額欄改固定寬度，min-width 提高到 780px），
   這裡不再重複定義，避免同一個屬性有兩個真相來源。 */

/* 傳票基本資料表的標題欄寬（原 NJournalEdit.php 的 th style='width:20%'） */
.ew-th-label { width: 20%; }

/* 科目匯入預覽表：6 欄平均分配（原 NsubjectImport.php 的 6 處 th style='min-width: 16%;'）。
   改成由表格自己的 class 統一控制 th，一個 class 取代 6 處內嵌樣式。 */
.ew-table-import th { min-width: 16%; }


/* ---------- 報表表格（Gate v2 U-4，20260917）----------
 *
 * v1 已定案「寬報表一律不做卡片化」：會計報表的價值就在借貸左右對照，
 * 拆成一張一張卡片之後對不起來，而且與 pdf41x0.php 的列印版長得不一樣。
 * 所以這裡的做法一律是「.table-responsive 橫向捲動容器 + 表格自己的 min-width」：
 * 表格維持原本的欄列結構，放不下的部分由容器的捲軸吸收，整頁永遠不溢出。
 *
 * min-width 的值是量出來的，不是猜的，而且判準不是「內容不折行」而是
 * **「375px 的手機上，金額欄必須看得見」**——這是第一版做錯、看了實機截圖才改的：
 * 第一版取 480px、代號欄 7em、金額欄 9em，結果 375px 時整個金額欄被推到捲動區之外，
 * 使用者打開資產負債表看到的是一整排沒有數字的科目名稱。報表沒有數字就不是報表。
 * 現在的值：三欄的報表（4140 資產負債表、4150 損益表、4160 試算表）取 340px，
 * 代號欄 6em（放得下 8 位數的科目代號）、金額欄 8em（放得下 3,924,602.00），
 * 375px 的手機（內容區約 343px）三欄全部在視窗內、一個字都不必橫捲，
 * 太長的科目名稱自己折成兩行——報表寧可名稱折行，也不能把金額推到看不見的地方；
 * 320px 時仍然會有約 52px 要橫捲，那是這個寬度的物理極限（代號 + 金額本身就要 210px）。
 * 四欄的 4110 會計項目表多一個「借貸」欄，取 420px；
 * 六欄的總分類帳（ajaxGetSubjectAccounting.php）取 540px——它六欄在手機上一定要捲
 * （編號 + 日期 + 三個金額欄本身就要 400px 以上，摘要再怎麼折行也塞不進 343px），
 * 欄序與 pdf4130.php 一致、不在本 gate 改動；能做的是把數字欄壓到 6em、
 * 讓「借方」在 375px 就進得了視窗，使用者看得出右邊還有欄位。
 *
 * 為什麼 min-width 不設更大：min-width 設得愈大，捲軸出現得愈早、金額欄被推出去得愈快。
 * 在 1280px 桌機上這幾張表都遠寬於 min-width，這個值只在窄螢幕才生效。
 */
.ew-table-report      { min-width: 340px; }
.ew-table-report--w4  { min-width: 420px; }
.ew-table-ledger      { min-width: 540px; }

/* 損益表最下面那一列淨額：三組「名稱 + 金額」共六格，比明細表更擠 */
.ew-table-report-net  { min-width: 460px; }

/* 報表的代號欄與金額欄改用固定寬度（取代原本 <th width='20%'> 這類 HTML 屬性）。
   百分比欄寬在「表格有 min-width、容器會橫向捲動」的情況下會與 min-width 互相打架：
   百分比是相對於表格的實際寬度算的，而表格寬度又由內容決定，於是欄寬會隨資料筆數浮動。
   固定寬度讓同一份報表在不同客戶、不同期間看起來一致，也讓金額欄的右對齊真的對得齊。 */
.ew-col-code   { width: 6em; }
.ew-col-amount { width: 8em; }

/* 總分類帳（六欄）的欄寬：摘要欄不給寬度，讓它吸收剩下的空間並自行折行 */
.ew-col-no    { width: 4.5em; }
.ew-col-date  { width: 6em; }
.ew-col-money { width: 6em; }


/* --------------------------------------------------------------------------
 * 管理與設定畫面的寬表格（Gate v2 U-5，20260917）
 *
 * 判準與上面那組報表完全相同，也是量出來的、不是猜的：
 * 「在 320px 把表格放進 .table-responsive 之後，整頁水平溢出必須是 0，
 *   而且第一個資料欄（代號／名稱）要完整看得見」——U-4 的陷阱第 20 條：
 * 只看「整頁溢出 0」會通過一個把所有有用欄位都推到捲動區外的畫面。
 *
 * 這六個值只在窄螢幕生效；1280px 桌機上這幾張表都遠寬於 min-width。
 * -------------------------------------------------------------------------- */

/* 會計科目表（範本 Act=1100 與客戶 Act=8200，同一組 10 欄）：
   代號 + 名稱 + 借貸 + 啟用 + 五個報表分類 + 功能。
   五個分類欄的表頭是「資產負債表 借」這種 6 個中文字的詞，
   低於這個寬度就會被壓成一行一字、整張表變成一面文字牆。 */
.ew-table-subject  { min-width: 780px; }

/* 使用單位列表（Act=8100）：名稱 + 統編 + 電話 + 地址 + 功能（功能欄有 4 個操作） */
.ew-table-company  { min-width: 660px; }

/* 使用者列表（Act=8110）：權限 + 姓名 + 部門 + 職稱 + 帳號 + 電話 + 功能 */
.ew-table-employee { min-width: 680px; }

/* 營業稅：統一發票清單（Act=5200，10 欄）與帳稅勾稽（Act=5210）的逐張比對、沒有入帳兩張表（8 欄）。
   375px 時表格被壓到容器寬，金額與「結果」欄每格斷成好幾行、一列高到 200px 以上（G5-2b 截圖量到）；
   給 min-width 讓它在容器裡橫向捲動，列高回到一兩行（量測：勾稽兩張表 860px 時 59～61px，與 1280px 相同）。
   發票清單多了「傳票」與兩顆按鈕的「功能」欄，860～940px 時按鈕上下疊成 105px，1000px 起回到 61px，另給修飾 class。 */
.ew-table-vat       { min-width: 860px; }
.ew-table-vat--list { min-width: 1000px; }

/* 401 工作底稿（Act=5220，G5-2c）：銷項、零稅率、稅額計算三張表 560px 時列高 38px（與 1280px 相同）；
   進項表 7 欄、第一欄是長的憑證名稱，800px 時「進項總金額」那列 204px、900px 79px、1000px 59px（兩行），取 1000px。 */
.ew-table-vat401       { min-width: 560px; }
.ew-table-vat401--wide { min-width: 1000px; }

/* 記帳士客戶指派（Act=9110）：記帳士 + 使用單位 + 指派時間 + 狀態 + 功能。
   「使用單位」欄的內容是「名稱（統編）」，本身就要 20 個中文字寬。 */
.ew-table-assign   { min-width: 620px; }

/* 多客戶結帳總覽矩陣（Act=9210 未帶 CK）：使用單位 + 12 個月 + 未結帳 + 功能。
   12 個月份格每格至少要放得下一個符號（28px）＋格線，
   加上左邊的單位名稱欄與右邊兩欄，760px 是不讓月份格被壓到看不出顏色的下限。 */
.ew-table-fpmatrix { min-width: 760px; }
.ew-table-fpmatrix > thead > tr > th,
.ew-table-fpmatrix > tbody > tr > td { padding-left: 4px; padding-right: 4px; }
.ew-table-fpmatrix td .ew-cell { min-width: 28px; }

/**
 * 「未到期」格的虛線框加深（Gate v2 U-5b，20260917：已移到下面的基礎規則）
 *
 * U-5 原本只把這個覆寫掛在 .ew-table-fpmatrix 與 .ew-legend--fp 底下，
 * 理由是「不動已驗收的前台儀表板外觀」。但 U-5 的 verifier 實測證明，
 * 前台儀表板吃的正是基礎規則，那裡的框線仍然是 --line 的 1.29:1
 * ——低於 WCAG 2.1 的 1.4.11（非文字對比 3:1），使用者看到的是一塊看不出邊界的空白。
 * 所以本 gate 把 --ink-3（對頁面底色實測 4.86:1）改寫進基礎規則，
 * 前台與管理端一次達標，這兩行覆寫也就成了同色的贅句，一併刪除。
 * 基礎規則見本檔的 .ew-cell--future。
 */

/* 會計期間結帳的期間清單（Act=9210 帶 CK）：8 欄，其中「操作」欄在反結帳時
   會出現一個輸入框 + 一顆按鈕，是整張表最寬的一格。 */
.ew-table-period   { min-width: 860px; }

/* 矩陣最左邊的「使用單位」欄：不給下限的話，12 個月份格會把它壓到 77px（實測），
   「社團法人東台灣幼兒教保專業促進協會」會變成一行兩個字的細長條。 */
.ew-table-fpmatrix > tbody > tr > th { min-width: 150px; }

/**
 * 管理端傳票編輯（Act=2102）的分錄表格
 *
 * 【為什麼不共用前台的 .ew-table-voucher】前台在 U-3 把那個 class 做成
 * 「768px 以下變成一列一張卡片」的手機版（display:block、tbody>tr 變 flex 卡片，
 * 並依賴 .ew-vrow／.ew-vcell--in／.ew-side／.ew-vlabel 那一整套標記與借貸切換 JS）。
 * 管理端這一頁是事務所自己記帳的 legacy 畫面、限負責人使用，沒有那一套標記；
 * 直接掛上去的實測結果是**表頭列被當成一張卡片**印出「代號 項目名稱／摘要／借／貸」
 * 四行字（375px 實機截圖確認）。所以這裡用自己的 class，只要一個 min-width，
 * 窄螢幕就是單純的橫向捲動——與管理端其他表格一致。
 * 值 640px = 科目欄 + 摘要欄 + 兩個金額欄 + 刪除鈕的最小可用寬度。
 */
.ew-table-mgrvoucher { min-width: 640px; }


/* ==========================================================================
   6b. 儀表板（Gate v2 U-2，20260917）
   ==========================================================================
   對應設計稿 docs/design/Dashboard.dc.html（前台）與 ClosingMatrix.dc.html 的
   狀態格語彙（管理端）。兩端共用本段，差別只有主色（由 token 自動切換）。

   本段沒有新增任何顏色：用到的每一個值都來自 css/tokens.css。
   ========================================================================== */

/* 儀表板的區段之間用一致的垂直節奏（設計稿 22px≈--sp-5） */
.ew-dash {
    display: flex;
    flex-direction: column;
    gap: var(--sp-5);
}

.ew-dash__sect {
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
}

/* 區段標題那一行：標題靠左、補充說明或「更多 →」連結靠右 */
.ew-dash__head {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--sp-1) var(--sp-3);
}

.ew-dash__head .ew-sect__title { margin-bottom: 0; }

.ew-dash__head-note {
    font-size: var(--fs-label);
    color: var(--ink-3);
}

.ew-dash__head-link {
    margin-left: auto;
    font-size: var(--fs-label);
    font-weight: 500;
    white-space: nowrap;
}

/**
 * 主要／次要兩欄（設計稿：1.35fr 1fr）
 * 992px 以下改成單欄堆疊——兩欄各自都有表格與 12 格的月份格，
 * 擠在平板寬度會讓兩邊都不好讀。
 */
.ew-dash__cols {
    display: grid;
    grid-template-columns: 1.35fr 1fr;
    gap: var(--sp-5);
    align-items: start;
}

/**
 * min-width: 0 是這一段唯一不能省的一行（實測抓到的真 bug）
 *
 * grid 項目的預設 min-width 是 auto，也就是「不得小於自己內容的 min-content」。
 * 左欄裡是「最近異動」表格，而 U-1 的規則讓 .table-responsive 裡的表頭 white-space: nowrap
 * （為了不讓「傳票編號」被擠成一字一行）。於是那張表的 min-content 等於五個表頭的寬度總和，
 * 一路往上把 grid 欄撐開——即使表格自己有橫向捲軸也一樣，因為 overflow 不會改變
 * 一個 block 盒的 intrinsic 尺寸，它只決定溢出之後怎麼呈現。
 * 實測（2026-09-17，Playwright）：沒有這一行時，前台總覽在 320px 寬水平溢出 17px、
 * 文字放大 200% 時溢出 232px；加上之後兩者都是 0，表格改由自己的捲軸吸收。
 */
.ew-dash__cols > * {
    min-width: 0;
}

@media (max-width: 991.98px) {
    .ew-dash__cols { grid-template-columns: 1fr; }
}

/* ---------- 數字卡（本月收入／支出／淨額／資產總額）---------- */

/**
 * 卡片列用 auto-fit + minmax 而不是固定 4 欄：
 * 桌機是 4 欄、平板自動變 2 欄、手機自動變 1 欄，不必寫三組斷點，
 * 而且在 320px 也絕不會因為「硬排 4 欄」而水平溢出（minmax 的下限會先收斂）。
 * 最小寬度 190px 是量出來的：本系統的金額最長是 13 個字元（含千分位與小數），
 * 以 --fs-stat 的字級量起來約 172px，加左右內距後需要 190px 才不會換行。
 */
.ew-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: var(--sp-3);
}

.ew-stat {
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r);
    padding: var(--sp-4) var(--sp-4);
    min-width: 0;               /* 讓長金額可以被 grid 壓縮而不是撐破欄寬 */
}

.ew-stat__label {
    font-size: var(--fs-label);
    color: var(--ink-2);        /* 7.43:1 */
}

/**
 * 金額本體。設計稿是 26px；這裡寫 1.625rem（＝16px 基準的 26px），
 * 使用者把瀏覽器字級調大時會跟著放大（WCAG 1.4.4）。
 * 字型走 --ff-num（tabular-nums），數字在多張卡片之間才對得齊。
 */
.ew-stat__value {
    font-family: var(--ff-num);
    font-variant-numeric: tabular-nums;
    font-feature-settings: "tnum" 1;
    font-size: 1.625rem;
    font-weight: 500;
    letter-spacing: -0.01em;
    line-height: var(--lh-tight);
    overflow-wrap: anywhere;    /* 極長的金額寧可折行，也不要撐出水平捲軸 */
}

/* 淨額（本期損益／本期餘絀）：正數用「已完成」綠、負數用危險色。
   兩者都不是唯一的區分手段——數字本身帶負號，不以顏色為唯一資訊（WCAG 1.4.1）。 */
.ew-stat__value--ok     { color: var(--ok); }        /* 白底 5.22:1，26px 屬大型文字 */
.ew-stat__value--danger { color: var(--danger); }    /* 白底 6.04:1 */

/* .ew-meta 是同一個樣式的通用名稱：表格列裡的「統編 · 組織類型」小字也用它。
   共用一條規則而不是複製一份，字級要改時不會只改到一半。 */
.ew-stat__note,
.ew-meta {
    font-size: var(--fs-note);
    color: var(--ink-3);        /* 5.05:1 */
}

/* 淨額卡片用「已完成」色描邊，在四張卡片中一眼看出哪一張是結論（設計稿的作法） */
.ew-stat--net { border-color: var(--ok); }

/* ---------- 需要處理（提示列右側的動作）---------- */

.ew-alert__body {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.ew-alert__title { font-weight: 500; }

.ew-alert__meta {
    font-size: var(--fs-label);
    color: var(--ink-2);
}

/* 提示列右側的動作（連結或小表單）。align-self: center 讓它與多行文字垂直置中；
   flex-shrink: 0 避免它被長文字擠壓成兩行。 */
.ew-alert__action {
    align-self: center;
    flex-shrink: 0;
    white-space: nowrap;
}

/* ---------- 結帳進度格 ---------- */

/**
 * 12 個月一排 6 格（設計稿）。用 grid 的等分欄，
 * 每一格的高度固定 34px（設計稿），寬度由欄寬決定——
 * 320px 時每格約 40px，仍看得清楚符號。
 */
.ew-months {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: var(--sp-2);
}

.ew-months__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--sp-1);
    min-width: 0;
}

/**
 * 月份標籤刻意「不」寫 white-space: nowrap。
 * 320px + 文字放大 200% 時，「10月」在 22px 字級下約 48px 寬，會超過該欄的可用寬度；
 * nowrap 的話它會直接把整頁撐出水平捲軸（U-2 硬驗收條件要求 320px 溢出為 0）。
 * 讓它在極端情況下折成兩行，是唯一不需要犧牲字級的作法。
 */
.ew-months__label {
    font-family: var(--ff-num);
    font-size: var(--fs-micro);
    color: var(--ink-3);        /* 5.05:1 */
    text-align: center;
}

/* 有事情要處理的月份（未結帳、不平衡）把月份字加重，不只靠格子的顏色 */
.ew-months__item--todo .ew-months__label {
    color: var(--ink-2);
    font-weight: 500;
}

/**
 * 狀態格本體
 *
 * 【每一種狀態都有「看得見的符號」，不只有顏色】
 *   已結帳 ✓ ／ 不平衡 ! ／ 未結帳 未 ／ 無分錄 — ／ 本月（空白＋實線框）／ 未到期（空白＋虛線框）
 * 這是設計稿明寫的要求（「色盲與單色視覺使用者都分得出來」）。
 * 另外每一格都帶一段視覺隱藏的完整狀態文字（年月＋狀態名稱）給報讀軟體。
 *
 * 前台的格子是純資訊（<span>），管理端之後若要做成可點擊的按鈕（U-5 的多客戶結帳總覽），
 * 沿用同一組 class 即可——.ew-cell 已經有 44px 的最小觸控高度預留。
 */
.ew-cell {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 34px;
    border-radius: var(--r);
    font-size: var(--fs-note);
    font-weight: 700;
    line-height: 1;
    border: 1px solid transparent;
}

/* 可點擊版本（button）：觸控目標放大到 44px，並沿用全站的焦點指示 */
button.ew-cell {
    min-height: var(--tap);
    font-family: inherit;
    cursor: pointer;
}

.ew-cell--ok     { background: var(--ok);        border-color: var(--ok);     color: #fff; }             /* 白字對 --ok 5.22:1 */
.ew-cell--bad    { background: var(--danger);    border-color: var(--danger); color: #fff; }             /* 白字對 --danger 6.04:1 */
.ew-cell--warn   { background: var(--warn-soft); border-color: var(--warn);   color: var(--warn-icon); } /* --warn-icon 對 --warn-soft 4.93:1 */
.ew-cell--none   { background: var(--line-2);    border-color: var(--ink-3);  color: var(--ink-2); }     /* 無分錄：框線對本格底色 --line-2 實測 4.39:1（U-5c 由 --line 的 1.17:1 改上來）；--ink-2 對 --line-2 6.43:1 */
.ew-cell--now    { background: var(--surface);   border-color: var(--ink-3); }                           /* 本月：實線框，框線對白底 5.05:1 */
.ew-cell--future { background: var(--bg);        border: 1px dashed var(--ink-3); }                      /* 未到期：虛線框，框線對頁面底色 4.86:1（U-5b 由 --line 的 1.29:1 改上來） */

/* ---------- 圖例 ---------- */

.ew-legend {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2) var(--sp-4);
    margin-top: var(--sp-4);
    padding-top: var(--sp-3);
    border-top: 1px solid var(--line);
}

.ew-legend__item {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    font-size: var(--fs-note);
    color: var(--ink-2);        /* 7.43:1 */
}

/* 圖例色塊沿用 .ew-cell 的配色，只是縮小成 15×15；符號也一起顯示，與格子完全對應 */
.ew-legend .ew-cell {
    width: 15px;
    min-width: 15px;
    min-height: 15px;
    font-size: 9px;
    border-radius: 2px;
}

/* ---------- 空狀態的動作列 ---------- */

.ew-empty__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--sp-2);
    margin-top: var(--sp-2);
}


/* ==========================================================================
   6c. 記帳核心畫面（Gate v2 U-3，20260917）
   ==========================================================================
   對應設計稿 docs/design/Journal.dc.html（日記簿）、VoucherDesktop.dc.html（桌機傳票）
   與 VoucherMobile.dc.html（手機傳票）。

   本段沒有新增任何顏色，用到的值全部來自 css/tokens.css。

   【這一段要解決的核心問題】
   傳票編輯頁的借／貸是兩個並排的輸入框。U-1 把明細表包進 .table-responsive 之後，
   整頁不再水平溢出，但代價是：375px 寬時兩個金額欄整個被推到捲動容器外面，
   使用者必須先把表格往左撥才看得到金額欄，而且撥到之後每個欄位的可輸入寬度
   只有 44.8px（實測，見 gate 報告 §4.1）。會計系統最常按的兩個欄位變成最難按的。

   解法（設計稿 VoucherMobile 的作法）：**一筆分錄只會是借方或貸方，不會兩邊都有值**，
   所以手機版不並排兩個框，改成「借／貸切換 + 單一金額欄」。金額欄因此可以吃掉
   整個卡片寬度、字級放大到 1.375rem（22px）。桌機版維持表格形式不變。

   【為什麼不是兩套 HTML】
   兩套 HTML 就是兩套 name 屬性、兩份要維護的欄位清單，而且「存檔行為必須逐欄相同」
   這條要求會立刻變成兩倍的驗證成本。這裡只出一套 HTML：手機版顯示的那個金額欄
   **就是** name=in01[] 或 name=out01[] 的那個輸入框本體，只是用 CSS 把另一邊藏起來、
   把表格列改成卡片。送出的表單欄位與改版前逐欄相同，伺服器端一個字都不用改。
   ========================================================================== */

/* ---------- 共用：欄位格線（搜尋卡片與傳票表頭共用）---------- */

/**
 * 欄位格線用 auto-fit + minmax，不寫死欄數：
 * 1280px 排成一列、768px 自動收成 3～4 欄、375px 以下收成 1 欄。
 *
 * 最小寬度 140px 是算出來的，不是猜的：日記簿搜尋列有 6 個欄位、其中兩個寬欄各佔 2 格，
 * 合計 8 格。auto-fit 能排幾格的公式是「N × min + (N−1) × gap ≤ 可用寬度」；
 * 1280px 視窗的內容區約 1240px，min 取 150px 時 8×150+7×12 = 1284 > 1240，只排得下 7 格，
 * 於是「金額上限」會被單獨擠到第二行、和「金額下限」拆開（實測截圖確認）。
 * 取 140px 時 8×140+7×12 = 1204 ≤ 1240，剛好一行排得完。
 * 140px 仍然放得下 type=date 的輸入框（扣掉左右內距 24px 後 116px，實測日期加日曆圖示約 105px）。
 */
.ew-fieldgrid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: var(--sp-3);
}

/**
 * min-width: 0 是這一段不能省的一行（與 U-2 在 .ew-dash__cols 踩到的是同一個坑）
 *
 * grid 項目的預設最小尺寸是 auto，也就是「不得小於自己內容的 min-content」，
 * 而 <input type=date> 的 min-content 是由它顯示的日期字串加上日曆圖示決定的——
 * 文字放大 200% 時（root 32px、--fs-input 變成 30px）實測是 283px，
 * 而 320px 螢幕扣掉頁面與卡片的內距只剩 222px 可用。於是 1fr 的軌道被日期欄
 * 由內往外撐開，整頁水平溢出 12px（實測，本 gate 第一版）。
 * 兩層都要寫：外層讓軌道可以縮，內層讓輸入框本身可以縮到軌道寬度。
 * 代價是極端情況下日期欄的內容會被裁切一點點，但那遠優於整頁出現水平捲軸。
 */
.ew-fieldgrid > * { min-width: 0; }

.ew-fieldgrid .form-control,
.ew-fieldgrid .form-select { min-width: 0; }

/* 文字類的搜尋欄位（科目、摘要關鍵字）給兩倍寬度，長關鍵字才看得完 */
.ew-fieldgrid .ew-fieldgrid__wide { grid-column: span 2; }

@media (max-width: 575.98px) {
    /* 手機一律單欄：span 2 在單欄 grid 裡會產生一個空欄位，必須收回 */
    .ew-fieldgrid { grid-template-columns: 1fr; }
    .ew-fieldgrid .ew-fieldgrid__wide { grid-column: span 1; }
}

/* 篩選卡片裡的欄位不要再帶 .ew-field 的下方外距（間距由 grid 的 gap 提供） */
.ew-fieldgrid .ew-field { margin-bottom: 0; }

/**
 * 只有一兩個欄位的篩選列（例：列印傳票只要一個「傳票編號」）用 auto-fill 而不是 auto-fit。
 * 兩者唯一的差別就在這裡：auto-fit 會把沒有項目的軌道收掉，剩下那一個欄位於是被
 * 1fr 拉成整個卡片那麼寬——一個只放幾位數的編號欄橫跨 1200px，看起來像壞掉。
 * auto-fill 保留空軌道，欄位維持一個正常的欄寬。
 */
.ew-fieldgrid--fill {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
}

/**
 * 搜尋卡片在大螢幕固定 8 欄
 *
 * auto-fit 算出來的欄數會隨可用寬度的零頭浮動（1280px 視窗實際只排得下 7 欄），
 * 結果是「金額下限」留在第一行、「金額上限」被擠到第二行——一對上下限被拆開，
 * 使用者要在兩行之間找它的另一半。日記簿搜尋列剛好是 8 格（兩個寬欄各 2 格），
 * 所以在夠寬的螢幕直接指定 8 欄，一行排完、成對的欄位不會被拆散。
 * 門檻取 1200px 是因為再窄下去每一欄會小於 130px，type=date 的日曆圖示會被裁到。
 * 只作用在 .ew-search 內：傳票表頭用的是同一個 .ew-fieldgrid，但它只有 3 個欄位，
 * 固定 8 欄會讓它右邊空掉一半。
 */
@media (min-width: 1200px) {
    .ew-search .ew-fieldgrid { grid-template-columns: repeat(8, minmax(0, 1fr)); }
}

.ew-search__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--sp-2);
    margin-top: var(--sp-3);
}

/* 查詢結果摘要那一行（共 N 張傳票、借貸合計、平衡與否） */
.ew-result {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-1) var(--sp-4);
    margin: var(--sp-4) 0 var(--sp-2);
    font-size: var(--fs-label);
    color: var(--ink-2);        /* 7.43:1 */
}

.ew-result__v {
    color: var(--ink);
    font-weight: 500;
}

/* 平衡／不平衡的狀態字：顏色之外一定同時有文字與圖示，不以顏色為唯一手段（WCAG 1.4.1） */
.ew-result__ok  { display: inline-flex; align-items: center; gap: var(--sp-1); color: var(--ok); }
.ew-result__bad { display: inline-flex; align-items: center; gap: var(--sp-1); color: var(--danger); }

/* ---------- 日記簿列表 ---------- */

/* 同一張傳票的第一列畫一條較重的上框線，視覺上把分錄分群
   （設計稿用的是 rowspan 合併，本系統維持「每列都是一筆分錄」的既有結構，
     改用框線分群，資料結構與改版前相同，搜尋結果的逐列比對才做得到）。 */
.ew-table-journal > tbody > tr.ew-jrow--first > td {
    border-top: 2px solid var(--ink-3);
}

/* 操作欄的小按鈕：btn-sm 的內距算出來只有 42px 寬，補到 44px 才是合格的觸控目標 */
.ew-table-journal .btn-sm,
.ew-table-journal .btn-sm.btn {
    min-width: var(--tap);
}

/* 合計列 */
.ew-table-journal > tfoot > tr > td {
    border-top: 2px solid var(--ink-3);
    font-weight: 500;
    background: var(--surface);
}

/* ---------- 傳票編輯：桌機（表格形式，設計稿 VoucherDesktop）---------- */

/**
 * 金額欄改用固定寬度而不是百分比（U-3）
 *
 * 改版前是 th style='width:15%'（U-1 收成 .ew-th-amount）。百分比的問題是：
 * 表格在 768px 只有 736px 可用時，15% = 110px，扣掉儲存格內距 24px、輸入框內距 24px
 * 與框線 2px，實際可輸入寬度只剩 52.9px（實測）。硬驗收條件要求 ≥ 72px。
 * 改成固定 150px 之後，同樣的算法得到 150 − 24 − 24 − 2 = 100px。
 * 表格的 min-width 同步由 640px 提高到 780px（5 欄的合理最小值），
 * 多出來的寬度由 .table-responsive 的橫向捲軸吸收，整頁不會溢出。
 */
.ew-table-voucher { min-width: 780px; }

.ew-table-voucher th.ew-th-amount,
.ew-table-voucher td.ew-vcell--in,
.ew-table-voucher td.ew-vcell--out {
    width: 150px;
}

/* 操作欄固定 72px：一顆 44px 的刪除鈕加左右內距 */
.ew-table-voucher th.ew-th-act,
.ew-table-voucher td.ew-vcell--act {
    width: 72px;
    text-align: center;
}

/* 借貸方向切換在桌機不出現——桌機同時看得到借、貸兩欄，不需要切換 */
.ew-side { display: none; }

/**
 * 欄位標籤（.ew-vlabel）
 *
 * 桌機：視覺隱藏（欄位語意由表頭提供），但報讀軟體仍念得到「第 N 列 借方金額」。
 * 手機：卡片模式沒有表頭，同一個元素改成看得見的標籤（見下方 media query）。
 * 用同一個元素而不是輸出兩份，避免「改了一份忘了另一份」。
 *
 * 這裡不用 Bootstrap 的 .visually-hidden：那個 class 帶 !important，
 * 手機版就再也覆寫不回來了。
 */
.ew-vlabel {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* 「第 N 列」這一段在任何寬度都只給報讀軟體聽，不佔畫面 */
.ew-vlabel__n {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* 卡片左上角的列號徽章（只在手機出現） */
.ew-vrow__no { display: none; }

/* ---------- 傳票編輯：手機（卡片 + 借貸切換，設計稿 VoucherMobile）---------- */

@media (max-width: 767.98px) {

    /**
     * 取消明細表的橫向捲動容器
     *
     * 手機版已經不是表格了（每一列變成一張卡片，欄位上下堆疊），寬度一定放得下，
     * 留著捲動容器只會多一層框線與一條永遠用不到的捲軸。
     * overflow 改回 visible 的同時必須把 tabindex 產生的焦點框也一併處理——
     * 容器不再捲動時，tabindex="0" 會變成一個「按了什麼都不會發生」的焦點站，
     * 所以 PHP 端在手機版仍保留 tabindex（HTML 不隨寬度改變），
     * 這是可接受的：它仍然是 role="region"，報讀軟體會念出「傳票明細分錄」。
     */
    .ew-voucher-scroll {
        border: 0;
        background: transparent;
        overflow: visible;
    }

    .ew-table-voucher {
        display: block;
        min-width: 0;
        margin-bottom: 0;
    }

    /* 表頭與桌機用的合計列在卡片模式沒有位置——合計改由下方的狀態列呈現 */
    .ew-table-voucher > thead,
    .ew-table-voucher > tfoot { display: none; }

    .ew-table-voucher > tbody { display: block; }

    /* 一列分錄 = 一張卡片 */
    .ew-table-voucher > tbody > tr {
        display: flex;
        flex-direction: column;
        gap: var(--sp-3);
        background: var(--surface);
        border: 1px solid var(--line);
        border-radius: var(--r);
        padding: var(--sp-3);
        margin-bottom: var(--sp-3);
    }

    /**
     * 儲存格變成區塊
     * 選擇器要壓得過 U-1 的 `.table-responsive > .table > :not(caption) > * > *`（分量 0,2,1），
     * 所以這裡寫到 tbody > tr > td 這一層（分量 0,2,3）。
     */
    .table-responsive > .ew-table-voucher > tbody > tr > td,
    .ew-table-voucher > tbody > tr > td {
        display: flex;
        flex-direction: column;
        gap: var(--sp-1);
        width: auto;
        border: 0;
        padding: 0;
    }

    /* 卡片頂端那一條：左邊列號徽章、右邊刪除鈕 */
    .table-responsive > .ew-table-voucher > tbody > tr > td.ew-vcell--act,
    .ew-table-voucher > tbody > tr > td.ew-vcell--act {
        order: -1;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        width: auto;
    }

    .ew-vrow__no {
        display: inline-flex;
        align-items: center;
        font-family: var(--ff-num);
        font-size: var(--fs-note);
        font-weight: 500;
        color: var(--ink-2);        /* 對 --line-2 6.43:1 */
        background: var(--line-2);
        border-radius: 3px;
        padding: 2px 7px;
    }

    /* 欄位標籤在卡片模式變成看得見的小標（設計稿 12px / 500 / --ink-2） */
    .ew-vlabel {
        position: static;
        width: auto;
        height: auto;
        margin: 0;
        overflow: visible;
        clip-path: none;
        font-size: var(--fs-note);
        font-weight: 500;
        color: var(--ink-2);        /* 7.43:1 */
    }

    /* ---- 借／貸切換 ---- */

    .ew-side {
        display: flex;
        flex-direction: column;
        gap: var(--sp-1);
    }

    .ew-side__lbl {
        font-size: var(--fs-note);
        font-weight: 500;
        color: var(--ink-2);
    }

    /* 兩顆等寬的按鈕連成一個分段控制項 */
    .ew-side__btns {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        border: 1px solid var(--ink-3);     /* 1.4.11：框線要看得見，5.05:1 */
        border-radius: var(--r);
        overflow: hidden;
    }

    .ew-side__btn {
        font: inherit;
        font-size: var(--fs-input);
        font-weight: 500;
        min-height: var(--tap);
        border: 0;
        background: var(--surface);
        color: var(--ink-2);                /* 未選取：7.43:1 */
        cursor: pointer;
    }

    .ew-side__btn + .ew-side__btn {
        border-left: 1px solid var(--ink-3);
    }

    /* 已選取：主色實底 + 白字（前台 6.00:1／管理端 5.59:1）。
       aria-pressed 同時是樣式鉤子與無障礙狀態，兩者不會各說各話。 */
    .ew-side__btn[aria-pressed="true"] {
        background: var(--brand);
        color: #fff;
    }

    /* 焦點指示沿用全站規則（第 3 節），但按鈕在分段控制項內部，
       outline-offset 要往內收才不會被 overflow:hidden 裁掉 */
    .ew-side__btn:focus-visible {
        outline: 3px solid var(--brand);
        outline-offset: -3px;
        box-shadow: none;
    }

    /**
     * 只顯示「目前這一邊」的金額欄
     *
     * data-side 由 PHP 依既有資料算出（in01>0 且 out01=0 → debit，反之 credit），
     * 之後由切換鈕維護。第三種值 both 是給「同一列借貸都有值」的歷史資料用的：
     * 那種資料兩欄都要顯示出來，否則使用者看不到其中一邊卻仍然會被送出去。
     */
    .ew-vrow[data-side="debit"]  > td.ew-vcell--out { display: none; }
    .ew-vrow[data-side="credit"] > td.ew-vcell--in > .ew-amt { display: none; }

    /* 金額欄吃掉整個卡片寬度，字級放大到 22px（設計稿）。
       min-height 56px 大於觸控目標下限，是因為它是本頁按最多次的欄位。 */
    .ew-amt__input.form-control {
        width: 100%;
        font-size: 1.375rem;
        min-height: 56px;
    }

    /* 刪除鈕在卡片模式是圖示按鈕，維持 44×44 */
    .ew-vrow__remove.btn { min-width: var(--tap); }
}

/* ---------- 傳票狀態列（即時借貸合計與差額，兩種寬度都出現）---------- */

.ew-vstatus {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-3);
    margin-top: var(--sp-4);
    padding: var(--sp-3) var(--sp-4);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r);
}

/* 三個數字（借方合計／貸方合計／差額）等分，320px 也不會擠在一起 */
.ew-vstatus__nums {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--sp-3);
    flex: 1 1 260px;
    min-width: 0;
}

.ew-vstatus__cell {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.ew-vstatus__k {
    font-size: var(--fs-note);
    color: var(--ink-3);        /* 5.05:1 */
}

.ew-vstatus__v {
    font-family: var(--ff-num);
    font-variant-numeric: tabular-nums;
    font-size: var(--fs-input);
    font-weight: 500;
    overflow-wrap: anywhere;    /* 極長金額折行，不撐出水平捲軸 */
}

/* 差額不為 0 時轉成危險色；數字本身仍然帶正負號，顏色不是唯一手段 */
.ew-vstatus__v--bad { color: var(--danger); font-weight: 700; }

/* 狀態訊息條（平衡／不平衡／尚未輸入） */
.ew-vstatus__bar {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    flex: 1 1 220px;
    min-width: 0;
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--r);
    background: var(--line-2);
    color: var(--ink-2);        /* 對 --line-2 6.43:1 */
    font-size: var(--fs-label);
    font-weight: 500;
}

.ew-vstatus__bar--ok  { background: var(--admin-soft); color: var(--ok-hover); }   /* --ok-hover 對 --admin-soft 7.2:1 */
.ew-vstatus__bar--bad { background: var(--danger-soft); color: var(--danger); }    /* --danger 對 --danger-soft 5.6:1 */

.ew-vstatus__act {
    display: flex;
    gap: var(--sp-2);
    margin-left: auto;
}

@media (max-width: 575.98px) {
    /* 手機：儲存鈕獨占一行且撐滿，是本頁最後一個動作，不該被擠成小按鈕 */
    .ew-vstatus__act { width: 100%; margin-left: 0; }
    .ew-vstatus__act .btn { flex: 1 1 auto; }
}

/* ---------- 期初餘額開帳（Act=9220，Gate v2 G3-2）---------- */

/**
 * 合計列黏在視窗底部。
 *
 * 為什麼只有這一頁需要：期初開帳的表單一次列出該單位「全部啟用中的科目」
 * （四家客戶實測各 54 個，資料表裡最多 226 個），使用者捲到一半時看不到
 * 借貸差額就等於看不到自己還差多少——而差額不為 0 時儲存鈕是停用的。
 * 只加一個修飾子，.ew-vstatus 的基礎樣式（含底色與內距）原封不動重用。
 *
 * 框線改用 --line-interactive（對頁面底色 3.92:1，達 WCAG 1.4.11 的 3:1）：
 * 它浮在內容上方，邊界要看得出來才知道下面還有被遮住的內容；
 * 基礎樣式的 --line（1.35:1）是給「跟著內容捲動」的版本用的。
 *
 * 螢幕高度很小時（橫放的手機、或文字放大到 200% 的筆電）改回一般定位：
 * 這條列本身約 90px 高，在 480px 的可視高度裡黏在底部會吃掉五分之一畫面。
 */
.ew-vstatus--sticky {
    position: sticky;
    bottom: 0;
    z-index: 3;
    border-color: var(--line-interactive);
}

@media (max-height: 480px) {
    .ew-vstatus--sticky { position: static; }
}

/**
 * 期初餘額輸入表：四欄（代號／名稱／借方期初／貸方期初）。
 *
 * min-width 的判準與第 6d 段那六張表相同——不是「內容不折行」，而是
 * 「兩個金額輸入框在橫向捲動時仍然完整可見」。620px 是量出來的：
 * 代號 6em + 名稱可壓縮 + 兩個 10em 的金額欄，再加表格內距。
 *
 * 金額欄為什麼要比報表的 8em 再寬：那邊欄位裡是一段文字，這邊是輸入框，
 * 輸入框有自己的左右內距。1280px 實機截圖實測 8em 時「100000.00」
 * 只看得到「100000.」——使用者看不完自己剛打進去的數字。
 */
.ew-table-opening { min-width: 620px; }

.ew-table-opening .ew-col-amount { width: 10em; }

/* 主層標題列（流動資產、業務收入…）：與資料列區分開來，但不是新顏色 */
.ew-obsect__master > th {
    background: var(--line-2);
    color: var(--ink-2);        /* 對 --line-2 實測 6.43:1 */
    font-weight: 700;
}

/* details/summary：原生展開收合，不需要任何 JS 與 aria 屬性 */
.ew-obsect {
    margin-bottom: var(--sp-4);
}

.ew-obsect__summary {
    cursor: pointer;
    padding: var(--sp-3) var(--sp-2);
    font-weight: 500;
}

.ew-obsect__title {
    font-size: var(--fs-sect);
    font-weight: 700;
    margin-right: var(--sp-3);
}

/* 焦點指示沿用全站規則（第 3 節）；summary 預設不是 :focus-visible 的目標之一，
   所以這裡明寫一次，鍵盤使用者 Tab 到區塊標題時才看得到自己在哪裡 */
.ew-obsect__summary:focus-visible {
    outline: 3px solid var(--brand);
    outline-offset: 2px;
}

/* ---------- 傳票列印預覽（Act=4120）---------- */

/* 預覽區模擬一張紙：白底、細框、置中的抬頭 */
.ew-preview {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r);
    padding: var(--sp-5) var(--sp-4);
}

.ew-preview__title {
    text-align: center;
    font-size: var(--fs-sect);
    font-weight: 700;
    margin: 0 0 var(--sp-1);
}

.ew-preview__meta {
    text-align: center;
    font-size: var(--fs-label);
    color: var(--ink-2);
    margin: 0 0 var(--sp-4);
}

/* 簽核欄（負責人／主管／會計） */
.ew-sign {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--sp-3);
    margin-top: var(--sp-5);
    padding-top: var(--sp-4);
    border-top: 1px solid var(--line);
    font-size: var(--fs-label);
    color: var(--ink-2);
    text-align: center;
}

/* 傳票明細表在 720px 以下靠容器捲動（欄位少，門檻比日記簿低） */
.ew-table-preview { min-width: 520px; }

.ew-table-preview > tfoot > tr > td {
    border-top: 2px solid var(--ink-3);
    font-weight: 500;
}


/* ==========================================================================
   7. 響應式與列印
   ========================================================================== */

/* 手機：頁首改為左右兩段可換行，內容區留白縮小但仍保有可讀邊界 */
@media (max-width: 575.98px) {

    /* 按鈕內距縮到 12px（＝Bootstrap 原本的值）：320px 寬的畫面上，
       設計稿的 20px 內距會讓日期篩選列的「篩選」按鈕寬過它所在的 col-3，
       整頁因此水平溢出 10px（實測）。高度仍然是 44px，觸控目標不縮水。 */
    .btn { --bs-btn-padding-x: var(--sp-3); }

    .ew-header__inner { gap: var(--sp-2) var(--sp-3); padding: var(--sp-2) var(--sp-3); }
    .ew-header__divider { display: none; }
    .ew-nav  { padding: 0 var(--sp-2); }
    .ew-page { padding: var(--sp-4) max(var(--sp-3), calc(0.5 * var(--bs-gutter-x, 1.5rem))) var(--sp-6); }
    .ew-acting { padding: var(--sp-2) var(--sp-3); }

    /* 儀表板（U-2）：手機上區段間距縮小一階，一個畫面塞得下比較多資訊 */
    .ew-dash      { gap: var(--sp-4); }
    .ew-dash__cols { gap: var(--sp-4); }
    .ew-stat      { padding: var(--sp-3); }

    /* 提示列的動作按鈕改成獨占一行：320px 時它與說明文字並排，會把說明擠成
       一行三、四個字的細長條（實測截圖確認）。整頁不會溢出，但很難讀。 */
    .ew-alert { flex-wrap: wrap; }
    .ew-alert__action { width: 100%; margin-top: var(--sp-2); }

    /* 結帳進度格在手機改成一排 4 格（3 列）。
       維持 6 格的話，320px 加上文字放大 200% 時月份標籤會擠不下——
       改成 4 格之後每格約 68px，22px 的「10月」放得進去。 */
    .ew-months { grid-template-columns: repeat(4, minmax(0, 1fr)); }

    /* 手機上導覽列展開時是垂直清單，底線指示改成左側色條比較合理 */
    .navbar-collapse .nav-link {
        border-bottom-color: transparent;
        border-left: 3px solid transparent;
        padding-left: var(--sp-2);
    }
    .navbar-collapse .nav-link.active,
    .navbar-collapse .nav-link[aria-current="page"] {
        border-left-color: var(--brand);
    }
}

/* 列印：頁首、導覽、頁尾、按鈕不印；表格以框線為主，不印底色 */
@media print {

    .ew-header,
    .ew-nav,
    .ew-footer,
    .ew-acting,
    .btn,
    .visually-hidden-focusable { display: none !important; }

    body { background: #fff; font-size: 11pt; }

    .table-responsive { border: 0; overflow: visible !important; }

    /* Gate v2 U-4：報表的借貸兩邊在紙上一律並排。
       螢幕上是 col-lg-6（992px 以下堆疊），但 A4 直式的可用寬度只有約 794px，
       照 col-lg-6 的斷點走就會在紙上變成上下兩張表——與 pdf41x0.php 的版面不一致。
       會計報表的借貸左右比對就是它的用途，所以列印時強制回到兩欄。 */
    .ew-report-grid > [class*="col-"] {
        flex: 0 0 50%;
        max-width: 50%;
    }
    .ew-table-journal,
    .ew-table-voucher,
    .ew-table-preview,
    /* Gate v2 U-4：報表的 min-width 只是螢幕上「不要被壓扁」的下限，
       印在紙上時版面寬度由紙張決定，留著 min-width 會讓最後一欄被切到紙外。 */
    .ew-table-report,
    .ew-table-report--w4,
    .ew-table-report-net,
    .ew-table-vat,                /* Gate v2 G5-2b：營業稅清單與帳稅勾稽 */
    .ew-table-vat--list,
    .ew-table-vat401,             /* Gate v2 G5-2c：401 工作底稿 */
    .ew-table-vat401--wide,
    .ew-table-ledger { min-width: 0; }

    /* 列印傳票（Gate v2 U-3）：只印那張傳票本身。
       查詢表單、狀態列、搜尋卡片都是螢幕上的操作介面，紙上沒有意義。 */
    .ew-search,
    .ew-vstatus,
    .ew-result,
    .ew-crumb { display: none !important; }

    .ew-preview { border: 0; padding: 0; }
}
