/* ══════════════════════════════════════════════════════════════════════════════
   AWE theme.css — 全站樣式單一源（UX2 切片 1）
   ══════════════════════════════════════════════════════════════════════════════
   來源：design-demo.php ／ design-demo-pending.php 的 394 行共用 CSS（兩檔逐字相同，
   R3 定稿＝標準答案）＋ 待入倉專屬層中屬於「全站共用元件」的部分，抽成本檔。
   自本檔起：
     ①  Token 層（--awe-*）＝所有數值只在 §1 出現一次；
     ②  元件層只准 var()，不准再寫字面值；
     ③  _layout.php／login.php／兩頁 demo／styleguide.php 全部吃這一份，禁第二份 copy。
   樣式看板（living styleguide）＝ styleguide.php，吃真 token＋真元件、所見即真相。

   解掉的盤點 ID（AWE-design-sweep-r1.md）：
     DS-01 02 03 04 05 06 07 08 11 19 29 45 47 48 49 57 59 70 78 80 89 92（T 類 22 條）
     DS-D1 D2 D3 D4（token 缺階）＋ DS-D8（CSS 重複兩份）
   拍板③（2026-08-11 papalu）：統計帶可點性規則入 token 層 → 見 §7「可點 vs 不可點」。
   ══════════════════════════════════════════════════════════════════════════════ */


/* ══════════════════════════════════════════════════════════════════════════════
   §1  C 層 — AWE Theme Tokens（單一張表）
   ══════════════════════════════════════════════════════════════════════════════ */
:root{
  /* ── 1.1 字型棧（DS-02；zh-Hant 優先。Tabler 預設的 Inter 不含中文，會 fallback 到系統雜牌字） */
  --awe-font-sans: system-ui, -apple-system, "Segoe UI", "PingFang TC", "Noto Sans TC",
                   "Microsoft JhengHei", "Helvetica Neue", Arial, sans-serif;
  --awe-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
                   "Noto Sans Mono", monospace;

  /* ── 1.2 字階表（size / line-height / weight）─ 後台密度，但層次要拉得開 */
  --awe-fs-display: 26px;  --awe-lh-display: 32px;  --awe-fw-display: 600;  /* 統計卡數值 */
  --awe-fs-title:   20px;  --awe-lh-title:   28px;  --awe-fw-title:   600;  /* 頁標題 */
  --awe-fs-section: 15px;  --awe-lh-section: 22px;  --awe-fw-section: 600;  /* 區塊／卡片標題 */
  --awe-fs-body:    14px;  --awe-lh-body:    22px;  --awe-fw-body:    400;  /* 內文／表格內容 */
  --awe-fs-label:   13px;  --awe-lh-label:   20px;  --awe-fw-label:   600;  /* 表頭／表單標籤 */
  --awe-fs-caption: 12px;  --awe-lh-caption: 18px;  --awe-fw-caption: 500;  /* 註記／pretitle */
  /* DS-D1：徽章階。原本 11px/16px 以字面值散在 8 個元件（badge-cat／badge-flag／badge-state／
     badge-day／rc-fact dt／wh-card small／cell-code／cell-sub），token 表最小卻只到 caption 12px。 */
  --awe-fs-badge:   11px;  --awe-lh-badge:   16px;  --awe-fw-badge:   500;
  /* 最小階：表頭單位小字（件）與倉別快捷鍵角標。比徽章再小一階，只承載附註不承載資訊主體。 */
  --awe-fs-micro:   10px;  --awe-lh-micro:   13px;
  /* DS-D4：統計數值的兩個離階尺寸收進字階表。
     display-lg＝該頁主角（看板的「可售」）；display-sm＝次級分段帶（各倉存量）。 */
  --awe-fs-display-lg: 30px; --awe-lh-display-lg: 36px;
  --awe-fs-display-sm: 20px; --awe-lh-display-sm: 26px;
  /* 動作前要對的數字（入倉 modal 的排程／已入倉／剩餘三 tile） */
  --awe-fs-fact:    18px;  --awe-lh-fact:    24px;
  /* DS-D3：分段帶專用行高。原本 line-height:18px 字面重複在 band-cap／section-label／
     section-hint／day-sep 四處。 */
  --awe-lh-band:    18px;

  /* ── 1.3 色票（品牌紅紀律：每頁一顆主 CTA ＋ active 態；其餘中性；danger 分離） */
  --awe-brand:       #E51D52;
  --awe-brand-ink:   #C21543;
  --awe-brand-soft:  rgba(229, 29, 82, .08);
  --awe-brand-line:  rgba(229, 29, 82, .32);
  --awe-brand-tint:  rgba(229, 29, 82, .14);          /* 選中態的圖示底 */
  --awe-danger:      #D63939;              /* 破壞性動作／負庫存專用，與品牌紅分工 */
  --awe-danger-soft: rgba(214, 57, 57, .07);
  --awe-danger-tint: rgba(214, 57, 57, .12);
  --awe-danger-line: rgba(214, 57, 57, .28);
  --awe-warn:        #B26A00;              /* partial／琥珀語意 */
  --awe-warn-soft:   rgba(247, 168, 37, .14);
  --awe-warn-line:   rgba(247, 168, 37, .4);
  --awe-ok:          #2A7F4F;              /* done／綠語意 */
  --awe-ok-soft:     rgba(47, 179, 68, .12);
  --awe-ok-line:     rgba(47, 179, 68, .35);
  --awe-ok-dot:      #2FB344;              /* 資料時效綠點 */
  --awe-ink-1:  #182433;   /* 主文 */
  --awe-ink-2:  #667382;   /* 次文／表頭 */
  --awe-ink-3:  #A0AAB5;   /* 弱化：零值、佔位 */
  --awe-line:      #E7EAEF;
  --awe-surface:   #FFFFFF;
  --awe-surface-2: #F7F9FC;
  --awe-canvas:    #F3F5F9;                /* DS-03 */

  /* ── 1.4 圓角節奏（DS-04／DS-05） */
  --awe-radius-card:    10px;
  --awe-radius-control:  6px;
  --awe-radius-sm:       4px;   /* 控件內的內層元素（seg-tab 內軌、縮圖框） */
  --awe-radius-xs:       3px;   /* 角標（倉別快捷鍵） */
  --awe-radius-pill:    999px;

  /* ── 1.5 陰影兩階（1＝靜置卡片；2＝浮起／選單／hover） */
  --awe-shadow-1: 0 1px 2px rgba(24, 36, 51, .04), 0 1px 3px rgba(24, 36, 51, .05);
  --awe-shadow-2: 0 6px 16px rgba(24, 36, 51, .09), 0 2px 6px rgba(24, 36, 51, .04);
  /* sticky 動作列的「往上浮」陰影：與 shadow-2 同族但方向朝上（DS-78） */
  --awe-shadow-up: 0 -6px 16px rgba(24, 36, 51, .07), 0 -2px 6px rgba(24, 36, 51, .04);

  /* ── 1.6 密度（後台工作介面：舒適但不鬆散）
     後台的「舒適」不等於「鬆」——螢幕高度是有限資源，上方每多留 40px，表格就少看兩列。
     這一組值是「一屏能看到多少列」與「不擁擠」之間的取捨點。 */
  --awe-row-h:     38px;     /* 表格資料列高（含 1px 底線）＝「一屏看得到幾列」的唯一旋鈕 */
  --awe-row-y:     .3125rem; /* 表格列上下最小內距（內容換行時的呼吸；單行列高由 --awe-row-h 定） */
  --awe-cell-x:    .625rem;  /* 表格欄左右內距 */
  --awe-card-pad:  1.25rem;  /* 卡片內距（＝表格貼卡緣的第一／最後一欄內距） */
  --awe-seg-y:     .5rem;    /* 統計帶分段上下內距 */
  --awe-seg-h:     5rem;     /* 統計帶分段最小高（80px）＝可點／不可點段共用的同一格線，
                                拍板⑥：分段高度不准隨「有沒有圖示／是不是 band-sm」浮動 */
  --awe-gap:       1rem;     /* 區塊間距 */
  --awe-page-y:    .625rem;  /* 頁面上下呼吸 */

  /* ── 1.7 控件高度
     control-h    ＝ 篩選列所有控件（搜尋框／下拉／switch）共用同一個高度
     control-h-sm ＝ DS-D2：緊湊控件（seg-tab／chip／列操作鈕）。原本 28px 字面重複三處，
                     同時也是 WCAG 2.5.8 觸擊目標的本站取值。 */
  --awe-control-h:    38px;
  --awe-control-h-sm: 28px;
  --awe-control-h-lg: 46px;  /* modal 主數量欄（DS-47） */

  /* ── 1.8 圖示（inline SVG data URI；不引第三個外部依賴）
     下拉 chevron 與側欄／使用者選單同一支 Tabler chevron-down（DS-19），色走 ink-3。 */
  --awe-icon-chevron-down: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23A0AAB5' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6l6 -6'/%3E%3C/svg%3E");
  /* 可點分段的右上小箭頭（拍板③）。用 mask 上色，故顏色跟著 currentColor 走。 */
  --awe-icon-arrow-ur: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M17 7l-10 10'/%3E%3Cpath d='M8 7l9 0l0 9'/%3E%3C/svg%3E");
}

/* ── 1.9 相容別名 ────────────────────────────────────────────────────────────
   `--tctf` / `--tctf-soft` 是舊 _layout.php 定義的品牌色變數，正式頁仍有 inline style
   直接引用（例：balances.php 的合計卡 border-color:var(--tctf)）。本片不動 markup，
   故保留別名並指回 token，等它們的 markup 在後續切片退場後再刪。 */
:root{
  --tctf:      var(--awe-brand);
  --tctf-soft: var(--awe-brand-soft);
}


/* ══════════════════════════════════════════════════════════════════════════════
   §2  C → A 橋接層：把 token 灌回 Tabler 自己的變數名（DS-01）
   ══════════════════════════════════════════════════════════════════════════════
   這是「A＋C」的接點——Tabler 全套元件（btn / card / table / dropdown / form…）
   不用逐一貼補丁就會自動說我們的設計語言。 */
:root{
  --tblr-font-sans-serif: var(--awe-font-sans);
  --tblr-font-monospace:  var(--awe-font-mono);
  --tblr-body-font-size:  var(--awe-fs-body);
  --tblr-body-line-height: var(--awe-lh-body);
  --tblr-body-color: var(--awe-ink-1);
  --tblr-secondary:  var(--awe-ink-2);
  --tblr-font-size-h2: var(--awe-fs-title);
  --tblr-line-height-h2: var(--awe-lh-title);

  --tblr-primary: var(--awe-brand);
  --tblr-primary-rgb: 229, 29, 82;
  --tblr-primary-darken: #C21543;
  --tblr-primary-lt: #FDEAEF;
  --tblr-primary-lt-rgb: 253, 234, 239;
  --tblr-link-color: var(--awe-brand);
  --tblr-link-color-rgb: 229, 29, 82;
  --tblr-link-hover-color: var(--awe-brand-ink);
  --tblr-link-hover-color-rgb: 194, 21, 67;

  --tblr-border-radius: var(--awe-radius-control);
  /* DS-05 續｜Tabler 的 -sm／-lg 尺寸修飾詞不是讀 --tblr-border-radius，而是各自的
     --tblr-border-radius-sm(2px)／-lg。`.form-control-sm`／`.btn-sm` 因此仍是 2px 直角感，
     只覆蓋主 token 修不到（實測 .form-control 仍取回 2px）。控件圓角是一個節奏，
     不因為控件變小就換一種，故三顆一起指回 --awe-radius-control。 */
  --tblr-border-radius-sm: var(--awe-radius-control);
  --tblr-border-radius-lg: var(--awe-radius-control);
  --tblr-border-color: var(--awe-line);
  --tblr-border-color-translucent: var(--awe-line);
  --tblr-card-border-radius: var(--awe-radius-card);
  --tblr-card-box-shadow: var(--awe-shadow-1);
  --tblr-bg-surface: var(--awe-surface);
  --tblr-bg-surface-secondary: var(--awe-surface-2);
  --tblr-page-padding-y: var(--awe-page-y);

}
/* DS-19｜下拉 chevron 換成與側欄／使用者選單同一支圖（色走 ink-3）。
   陷阱：Tabler 把 --tblr-form-select-bg-img 直接宣告在 `.form-select{}` 規則裡，
   而不是在 :root。元素自己身上的 custom property 一定贏過從 :root 繼承下來的那份，
   所以只改 :root 完全沒效果（實測仍取回 Tabler 的 viewBox 0 0 16 16 原圖）。
   要在同一層（.form-select）覆蓋，靠後載入的順序取勝。 */
.form-select{ --tblr-form-select-bg-img: var(--awe-icon-chevron-down); }
body{ background: var(--awe-canvas); }
/* Tabler 把表單 focus 的 border-color 硬寫成 Tabler 藍（不走 token），光暈卻讀 primary-rgb
   -> 聚焦會變「藍框＋紅光暈」。邊框拉回同一顆 primary，focus 只剩一個色相。 */
.form-control:focus,.form-select:focus,.form-check-input:focus{
  border-color: rgba(var(--tblr-primary-rgb), .5);
}
/* P2-19 配套：篩選頁籤／分組 chip／盤差原因 chip 一律走 outline-secondary + .active。
   Tabler 的 .btn 基底把 --tblr-btn-active-border-color 綁在 --tblr-primary 上，token 換成
   品牌紅之後「選取中」會多出一圈紅框（看起來像警示）-> 拉回 secondary，紅色仍然稀缺。 */
.btn-outline-secondary.active{ --tblr-btn-active-border-color: var(--tblr-secondary); }
/* ── 拍板④（2026-08-11 papalu 眼驗）｜文字連結全站不用底線（含 hover）─────────
   修訂 DS-29：原規格是「表內連結 ink-1，hover 轉品牌紅＋加底線」。眼驗結論是底線本身
   就是噪音——一屏 40 列，滑鼠掃過去每一列都閃一條線，而且分頁 segmented 這種「看起來
   是控件、實作是 <a>」的元件被畫上底線後直接讀成壞掉。新規則：**hover 只變色，不加
   底線**；可點性靠色彩、hover 換底、游標與（統計帶的）箭頭去講，不靠底線。
   為什麼要寫在這裡：Tabler(Bootstrap reboot) 有 `a:hover{text-decoration:underline}`
   (0,1,1)，比 `.seg-tab{text-decoration:none}`(0,1,0) 高一階 → 元件層自己寫 none 擋不住，
   一定要在同層（`a:hover`）用後載入順序取勝。`.breadcrumb a:hover`(0,2,1) 與
   `.btn-link:hover`(0,2,0) 比 `a:hover` 高一階，各自點名，否則會單獨漏網。
   （Tabler 全庫掃過只有這四條會畫底線，第五條 `abbr[title]` 不是連結、刻意保留。） */
a,a:hover,a:focus,
.breadcrumb a:hover,
.btn-link:hover,.btn-link:focus-visible{ text-decoration: none; }


/* ══════════════════════════════════════════════════════════════════════════════
   §3  A 層 — 側欄（DS-11）
   ══════════════════════════════════════════════════════════════════════════════ */
.navbar-vertical{ background: var(--awe-surface); border-right: 1px solid var(--awe-line); }
.navbar-brand-image{ height: 2.4rem; }
.navbar-vertical .navbar-brand{ padding: .875rem 1rem !important; justify-content: flex-start !important; }
/* 品牌文案＝拍板名「TCTF 進銷存系統」，沿用 _layout.php 的兩行排法（TCTF ／ 進銷存系統）。 */
.sb-brand-text{ font-size: var(--awe-fs-section); line-height: 1.2; font-weight: var(--awe-fw-section);
  color: var(--awe-ink-1); }
.sb-brand-text .sb-brand-line{ display: block; }
.navbar-vertical .navbar-nav{ padding: .25rem .625rem .5rem; gap: 2px; }
.navbar-vertical .navbar-nav .nav-link{
  position: relative;
  border-radius: var(--awe-radius-control);
  font-size: var(--awe-fs-body); line-height: var(--awe-lh-body); color: var(--awe-ink-2);
  transition: background-color .12s ease, color .12s ease;
}
.navbar-vertical .navbar-nav .nav-link:hover{ background: var(--awe-surface-2); color: var(--awe-ink-1); }
.navbar-vertical .navbar-nav .nav-link.active{
  background: var(--awe-brand-soft); color: var(--awe-brand); font-weight: 600;
}
/* DS-11｜active 的左側品牌色指示條：稀缺的紅只用在「你在這裡」與主 CTA */
.navbar-vertical .navbar-nav .nav-link.active::before{
  content: ""; position: absolute; left: 0; top: 20%; bottom: 20%;
  width: 3px; border-radius: 0 3px 3px 0; background: var(--awe-brand);
}
.navbar-vertical .navbar-nav .nav-link .nav-link-icon{ color: inherit; opacity: .85; }
.navbar-vertical .navbar-nav .nav-link.active .nav-link-icon{ opacity: 1; }
/* Tabler 有一條「橫向 navbar 圖示鈕角標」規則（position:absolute）會誤套到直立側欄，
   把 badge 抽離文流釘在右上角。收回 flex 流、靠 margin-left:auto 收在同一列右端。 */
.navbar-vertical .navbar-nav .nav-link > .badge{
  position: static; transform: none; flex: none; margin-left: auto;
  font-size: var(--awe-fs-badge); font-weight: 600;
}
.badge.bg-tctf,.badge.bg-tctf-solid{ background: var(--awe-brand); color: #fff; }
.badge.badge-frozen{ background: transparent; color: var(--awe-ink-2); border: 1px solid var(--awe-line);
  font-weight: 500; }


/* ══════════════════════════════════════════════════════════════════════════════
   §4  資料時效狀態 ＋ 使用者選單 ＋ 下拉
   ══════════════════════════════════════════════════════════════════════════════ */
.awe-stamp{ display: inline-flex; align-items: center; gap: .5rem;
  font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption); color: var(--awe-ink-2); }
.awe-stamp .status-dot{ --tblr-status-color: var(--awe-ok-dot); }
.awe-user{ display: flex; align-items: center; gap: .5rem; padding: .25rem .375rem;
  border-radius: var(--awe-radius-control); }
.awe-user:hover{ background: var(--awe-surface-2); }
.awe-user .avatar{ background: var(--awe-brand); color: #fff; font-weight: 600; }
.awe-user-name{ font-size: var(--awe-fs-body); line-height: 1.15; font-weight: 600; color: var(--awe-ink-1); }
.awe-user-role{ font-size: var(--awe-fs-caption); line-height: 1.3; color: var(--awe-ink-2); margin-top: 2px; }
.awe-user .icon-chevron{ width: 1rem; height: 1rem; color: var(--awe-ink-3); }
.dropdown-menu{ box-shadow: var(--awe-shadow-2); border-color: var(--awe-line);
  border-radius: var(--awe-radius-control); }
/* Tabler 的 .dropdown-header 寫死 text-transform:uppercase → 帳號名與中文角色都被大寫掉
   （papalu（管理者）會變成 PAPALU（管理者））。帳號大小寫是資料，不該被樣式改寫。 */
.dropdown-header{ text-transform: none; letter-spacing: 0; font-size: var(--awe-fs-caption);
  color: var(--awe-ink-2); }
.dropdown-item{ font-size: var(--awe-fs-body); display: flex; align-items: center; gap: .5rem; }
.dropdown-item .icon{ width: 1rem; height: 1rem; color: var(--awe-ink-2); }


/* ══════════════════════════════════════════════════════════════════════════════
   §5  page-header
   ══════════════════════════════════════════════════════════════════════════════ */
.page-pretitle{ font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption);
  font-weight: var(--awe-fw-caption); letter-spacing: .06em; color: var(--awe-ink-3);
  text-transform: none; margin-bottom: 2px; }
.page-title{ font-size: var(--awe-fs-title); line-height: var(--awe-lh-title);
  font-weight: var(--awe-fw-title); color: var(--awe-ink-1); letter-spacing: -.01em; }
.page-subtitle{ font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption);
  color: var(--awe-ink-2); margin-top: .25rem; }
.page-header .btn{ border-radius: var(--awe-radius-control); }
.page-header .btn-primary{ box-shadow: 0 1px 2px rgba(229, 29, 82, .28); }
/* page-header 右側收納區：資料時效 → 動作鈕 → （分隔）使用者選單，同一列由左而右。
   排序照「這批資料多新 → 我要對它做什麼 → 我是誰」的閱讀順序；帳號依慣例收在最右。 */
.ph-utility{ display: flex; align-items: center; justify-content: flex-end;
  gap: .75rem; flex-wrap: wrap; }
.ph-sep{ width: 1px; align-self: stretch; margin: .25rem 0; background: var(--awe-line); }


/* ══════════════════════════════════════════════════════════════════════════════
   §6  卡片與區塊標題（DS-04／DS-57／DS-70／DS-80）
   ══════════════════════════════════════════════════════════════════════════════ */
.card{ border-radius: var(--awe-radius-card); border: 1px solid var(--awe-line);
  box-shadow: var(--awe-shadow-1); background: var(--awe-surface); }
/* DS-57／DS-80｜Tabler 的 .card-title 是 16px/500 ＝ 與內文同權重、層級講不清楚。
   DS-70｜Tabler 的 .h5/h5 是 .75rem(12px) ＝ 比 14px 內文還小，層級倒置（import 的
   「近期匯入批次」實測 12px）。兩者一起拉回同一階 section 15px/600。 */
.card-title,.h5,h5{
  font-size: var(--awe-fs-section); line-height: var(--awe-lh-section);
  font-weight: var(--awe-fw-section); color: var(--awe-ink-1);
}
.card-header .card-title{ margin: 0; }
.section-label{ font-size: var(--awe-fs-label); line-height: var(--awe-lh-label);
  font-weight: var(--awe-fw-label); color: var(--awe-ink-2); display: flex; align-items: center; gap: .375rem; }
.section-label .icon{ width: 1rem; height: 1rem; color: var(--awe-ink-3); }
.section-hint{ font-size: var(--awe-fs-caption); color: var(--awe-ink-3); }


/* ══════════════════════════════════════════════════════════════════════════════
   §7  統計帶（KPI band）
   ══════════════════════════════════════════════════════════════════════════════
   兩條帶：帶 1＝總量（品項數／可售／在手總量／負庫存），帶 2＝各倉存量。
   刻意做成「一張卡內以分隔線切段」，而不是 N 張等寬小卡：
   等寬小卡讓 7 個數字視覺同權重（現行版的主要問題），分段帶才有主從。 */
.band{ overflow: hidden; }
/* ── 拍板⑥（2026-08-11 papalu 眼驗）｜分段高度是一條格線，不是內容算出來的副產品 ──
   問題：可點段（有 .stat-ico 32px）算出來 80px、不可點段（band-sm、無圖示）算出來 63px，
   兩張帶並排時高度差 17px，讀起來像其中一張沒做完。而且窄寬度下可點段內容一換行就
   竄到 116px，落差更大。可點性應該只由「箭頭／hover」講（拍板③），高度不該一起變成
   第二個訊號——那會讓人以為高度也有意義。
   解法：min-height 鎖在同一顆 token，內容用 flex 垂直置中撐在格線裡；內容變高時仍可
   自然長高（min-height 是地板不是天花板），但地板全站同一條。 */
.seg{ position: relative; padding: var(--awe-seg-y) var(--awe-card-pad);
  min-height: var(--awe-seg-h);
  display: flex; flex-direction: column; justify-content: center;
  border-right: 1px solid var(--awe-line); border-bottom: 1px solid var(--awe-line); }
/* 兩層階梯（總量／各倉）收進同一張卡，用一條分隔線分層而不是分成兩張卡。 */
.band-cap{ display: flex; align-items: baseline; gap: .5rem; line-height: var(--awe-lh-band);
  padding: .125rem var(--awe-card-pad); background: var(--awe-surface-2);
  border-top: 1px solid var(--awe-line); border-bottom: 1px solid var(--awe-line); }
.band-cap .section-label{ font-size: var(--awe-fs-caption); line-height: var(--awe-lh-band); }
.band-cap .section-label .icon{ width: .875rem; height: .875rem; }
.band-cap .section-hint{ line-height: var(--awe-lh-band); }
.stat-label{ font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption);
  font-weight: var(--awe-fw-caption); letter-spacing: .04em; color: var(--awe-ink-2); }
/* 拍板⑦（2026-08-11 papalu 眼驗）｜數值與單位是一個詞，不准被拆行。
   症狀：分段一窄（實測 1200px 下 col-4＝150px）就把「1,284 件」的「件」擠到第二行，
   看起來像多了一列空資料，也把同一排分段的高度一起撐開。
   為什麼是 word-break:keep-all 而不是 white-space:nowrap：
     斷點發生在「數字→漢字」這個 UAX#14 的隱性換行機會上，keep-all 正是用來關掉它的；
     nowrap 則是把**整串**的換行機會全關掉——複合數值（demo-pending 的
     「19筆 ／10-500（件）」）在 375px 下就會直接溢出分隔線（實測溢出 41px）。
     keep-all 只黏住「數值＋單位」這個詞，兩個詞之間的空白仍可換行 → 窄寬度優雅換行、
     每個詞自身永不拆開。實測 375／576／768／992／1200／1440 六檔皆 0 溢出且單位不離行。 */
.stat-value{ font-size: var(--awe-fs-display); line-height: var(--awe-lh-display);
  font-weight: var(--awe-fw-display); color: var(--awe-ink-1);
  font-variant-numeric: tabular-nums; letter-spacing: -.02em; margin-top: .125rem;
  word-break: keep-all; }
.band-sm .stat-value{ font-size: var(--awe-fs-display-sm); line-height: var(--awe-lh-display-sm); }
.stat-unit{ font-size: var(--awe-fs-caption); font-weight: 500; color: var(--awe-ink-3); margin-left: .25rem; }
.stat-ico{ width: 2rem; height: 2rem; border-radius: var(--awe-radius-control);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--awe-surface-2); color: var(--awe-ink-2); flex: none; }
.stat-ico .icon{ width: 1.125rem; height: 1.125rem; }
/* 「可售」＝這頁的主角，靠字級與品牌色圖示拉出主從，不靠放大卡片（FN3 定案 2 起；
   一頁只給一顆 .stat-primary——兩顆並排就等於沒有主角） */
.stat-primary .stat-ico{ background: var(--awe-brand-soft); color: var(--awe-brand); }
.stat-primary .stat-value{ font-size: var(--awe-fs-display-lg); line-height: var(--awe-lh-display-lg); }
.stat-danger{ background: var(--awe-danger-soft); }
.stat-danger .stat-label,.stat-danger .stat-value{ color: var(--awe-danger); }
.stat-danger .stat-ico{ background: var(--awe-danger-tint); color: var(--awe-danger); }

/* ── 拍板③（2026-08-11 papalu）｜統計帶可點性規則入 token 層 ─────────────────
   問題（DS-D6）：demo-bal 的首段是可點下鑽、demo-pending 的首段是死 seg，版位與外觀
   完全相同、行為卻不同，使用者無從分辨。
   規則：
     ①「可點」＝ .stat-drill：有 hover 態（換底）＋ 右上一顆小箭頭（affordance 常駐、
        低調 ink-3；hover／選中才轉品牌色）。選中用品牌色 inset ring，不是填滿——
        飽和紅留給 CTA。
     ② 「不可點」＝ 純 .seg：無 hover 態、無箭頭、游標不變。
   兩者的差別因此是「有沒有那顆箭頭」這一個可以一眼看到的訊號，而不是要靠試點。 */
.stat-drill{ position: relative; cursor: pointer;
  transition: background-color .14s ease, box-shadow .14s ease; }
.stat-drill::after{
  content: ""; position: absolute; top: .5rem; right: .5rem;
  width: .875rem; height: .875rem; background-color: var(--awe-ink-3);
  -webkit-mask-image: var(--awe-icon-arrow-ur); mask-image: var(--awe-icon-arrow-ur);
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  opacity: .55; transition: opacity .14s ease, background-color .14s ease;
  pointer-events: none;
}
.stat-drill:hover{ background: var(--awe-surface-2); }
.stat-drill:hover::after{ opacity: 1; background-color: var(--awe-brand); }
.stat-drill:focus-visible{ outline: none; box-shadow: inset 0 0 0 2px var(--awe-brand); }
.stat-drill.on{ background: var(--awe-brand-soft); box-shadow: inset 0 0 0 1px var(--awe-brand); }
.stat-drill.on::after{ opacity: 1; background-color: var(--awe-brand); }
.stat-drill.on .stat-label{ color: var(--awe-brand); }
.stat-drill.on .stat-ico{ background: var(--awe-brand-tint); color: var(--awe-brand); }
.stat-danger.stat-drill.on{ background: var(--awe-danger-tint); box-shadow: inset 0 0 0 1px var(--awe-danger); }
.stat-danger.stat-drill::after{ background-color: var(--awe-danger); }
.stat-danger.stat-drill:hover::after,
.stat-danger.stat-drill.on::after{ background-color: var(--awe-danger); }
/* 負庫存卡（正式頁 balances 的 .card-neg）：與 .stat-danger 同一組語意，走 token 不寫死色 */
.card-neg{ border: 1px solid var(--awe-danger); background: var(--awe-danger-soft); }


/* ══════════════════════════════════════════════════════════════════════════════
   §8  全 0 空狀態引導
   ══════════════════════════════════════════════════════════════════════════════
   語氣是「下一步怎麼做」而不是警告：中性底、中性字，兩個出口做成連結。 */
.zero-hint{ display: flex; gap: .75rem; align-items: flex-start;
  padding: .875rem var(--awe-card-pad); border: 1px solid var(--awe-line);
  border-radius: var(--awe-radius-card); background: var(--awe-surface);
  box-shadow: var(--awe-shadow-1); }
.zero-hint > .icon{ width: 1.25rem; height: 1.25rem; flex: none; color: var(--awe-ink-3); margin-top: 1px; }
.zero-hint-title{ font-size: var(--awe-fs-label); line-height: var(--awe-lh-label);
  font-weight: var(--awe-fw-label); color: var(--awe-ink-1); }
.zero-hint-body{ font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption);
  color: var(--awe-ink-2); margin-top: .125rem; }
.zero-hint-body a{ color: var(--awe-brand); text-decoration: none; font-weight: 600; }
/* 拍板④：hover 只加深顏色，不加底線（見 §2 全站規則） */
.zero-hint-body a:hover{ color: var(--awe-brand-ink); text-decoration: none; }


/* ══════════════════════════════════════════════════════════════════════════════
   §9  篩選列（filter bar）與控件（DS-05／DS-19）
   ══════════════════════════════════════════════════════════════════════════════
   一條有節奏的列：所有控件共用 --awe-control-h 同高、同圓角、同 focus 態、同間距，
   垂直置中對齊成一條線。篩選列是每天要碰幾十次的工作面，控件長得不齊會一直被讀成
   「這頁沒做完」。 */
/* ── 拍板 A（2026-08-12 papalu 准）｜`.toolbar` 負外距歸零：全站 +7px 幾何缺陷的根治 ──
   症狀：`_layout.php::filter_bar()` 產出的 `.toolbar` 與 Tabler core 自帶的
   `.toolbar{ margin: 0 -.5rem }` **class 撞名**；本節原本只覆寫 padding／flex，margin 沒收，
   於是 Tabler 的 -8px 一直贏 → 篩選列外緣比所在 `.card` 左右各寬出 7px（-8 ＋ 卡片 1px 邊框）。
   底色透明時肉眼看不出來，但幾何是錯的；切片 5 給 chipbar 上灰底才把同一個根因顯影
   （BLOCK-5-1，當時只治了 .tabbar／.chipbar 兩條、本體列為待拍板）。
   ⚠ 兩頁 demo 的 filter bar 自己也帶 `.toolbar`，一樣是 +7 —— 這一條同時修正標準答案本身
   （design bar 位移，前後值記錄於 AWE-slice6a-implement-report.md §2）。 */
.toolbar{ margin-left: 0; margin-right: 0;
  padding: .375rem var(--awe-card-pad); border-bottom: 1px solid var(--awe-line);
  display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.toolbar .form-control,.toolbar .form-select{
  height: var(--awe-control-h); min-height: var(--awe-control-h);
  font-size: var(--awe-fs-body); line-height: 1.25;
  border-radius: var(--awe-radius-control); border: 1px solid var(--awe-line);
  background-color: var(--awe-surface); color: var(--awe-ink-1);
  box-shadow: none; transition: border-color .12s ease, box-shadow .12s ease; }
.toolbar .form-control::placeholder{ color: var(--awe-ink-3); }
.toolbar .form-control:hover,.toolbar .form-select:hover{ border-color: var(--awe-ink-3); }
.toolbar .form-control:focus,.toolbar .form-select:focus{
  border-color: var(--awe-brand); box-shadow: 0 0 0 3px var(--awe-brand-soft); }

/* 搜尋框：左放大鏡、右清除鈕（有字才出現）。padding 預留兩側圖示位，字不會壓到圖示上。
   min-width:0 / width:100% 是給 WebKit 的：input 有自帶的 intrinsic 寬度，
   不歸零的話 Safari 的 flex item 不肯縮到 flex-basis，篩選列會被撐爆換行。 */
.filter-search{ position: relative; flex: 0 0 260px; max-width: 260px; min-width: 0; }
.filter-search .form-control{ width: 100%; min-width: 0; }
.filter-search .form-control{ padding-left: 2.125rem; padding-right: 2.125rem; }
.filter-search .input-icon-addon{ width: 2.125rem; height: var(--awe-control-h);
  color: var(--awe-ink-3); pointer-events: none; }
.filter-search .input-icon-addon .icon{ width: 1rem; height: 1rem; }
.filter-clear{ position: absolute; right: .3125rem; top: 50%; transform: translateY(-50%);
  width: 1.5rem; height: 1.5rem; padding: 0; border: 0; background: transparent;
  border-radius: var(--awe-radius-pill); color: var(--awe-ink-3); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; }
.filter-clear .icon{ width: .875rem; height: .875rem; }
.filter-clear:hover{ background: var(--awe-surface-2); color: var(--awe-ink-1); }
.filter-clear:focus-visible{ outline: none; box-shadow: 0 0 0 2px var(--awe-brand-line); }

/* DS-19｜類別下拉：關掉原生外觀，chevron 換成與側欄／使用者選單同一支圖（顏色走 ink-3）。
   全站層的替換已由 §2 覆蓋 --tblr-form-select-bg-img 完成；這裡只再收一次位置與內距。 */
.filter-select{ flex: 0 0 168px; max-width: 168px; min-width: 0; }
.filter-select .form-select{ width: 100%; min-width: 0; }
.toolbar .form-select{ appearance: none; -webkit-appearance: none; padding: 0 2rem 0 .75rem;
  background-image: var(--awe-icon-chevron-down);
  background-repeat: no-repeat; background-position: right .625rem center; background-size: 16px 16px; }
.toolbar .form-control{ padding-top: 0; padding-bottom: 0; }

/* UX2 切片 3｜同列的按鈕收進「緊湊控件」那一階（--awe-control-h-sm 28px），不是 38px。
   兩件事各自成立：
   ① DS-17 講的是**表單控件**（搜尋框／下拉）要 38px，按鈕不在其中；
   ② 兩階並存本來就是標準答案——demo 的 `.tabbar` 就是 seg-tabs(28px) 與
      filter-search(38px) 同一列靠中線對齊，不是硬拉成同一高。
   現況 btn-sm 量到 **20px**，比 28px 那一階還矮、不屬於任何一階，這才是要收的缺口。
   字級與左右內距都留在原本 btn-sm 的值（12px／.5rem），只有高度升到 28px。
   （pending 兩組 btn-group、products 的「類別管理」、product_edit 的分組鈕都在此列；
   它們的**形**分別由切片 5／6b（seg-tabs＋chip）與切片 7（DS-39 位置）處理。） */
.toolbar .btn{ height: var(--awe-control-h-sm); min-height: var(--awe-control-h-sm);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: var(--awe-fs-caption); padding: 0 .5rem; }

/* UX2 切片 3 fix-r1｜⚠ 按鈕群**不得驅動整頁捲軸**（BLOCK-1 的根治）。
   `.btn-group` 是 nowrap 的 inline-flex，min-content 寬＝所有鈕相加，放在窄容器裡不會縮、
   只會把 document.scrollWidth 一路撐出去。product_edit 的「異動紀錄」分頁在 col-lg-4 窄欄
   （992px 下內寬僅 221px），7 顆分組鈕**基準就已經 256px、放不下**（基準本身 992 溢出 32px）；
   升到 28px 階後 312px，把溢出帶擴大到整個 992～1200px 窄欄帶。
   幾何上「調字級／內距」只能挪動失效的門檻、不能消除它——7 顆鈕在 221px 裡怎麼算都排不完。
   所以改成允許換行：群一旦放不下就往下折，寬度永遠 ≤ 容器，整頁溢出結構性歸零
   （連基準既有的 21～32px 一併收掉），且不必藏任何一顆鈕（優於水平捲動的隱藏內容）。
   換行後的形＝「被折行的一條緞帶」：群的頭尾收圓角、相鄰鈕維持共邊直角（Bootstrap 的
   -1px 共邊在圓角下會露出缺口，所以內部維持直角才乾淨），列間留 2px 讓折行看得出來。 */
.toolbar .btn-group{ flex-wrap: wrap; row-gap: 2px; }
.toolbar .btn-group .btn{ border-radius: 0; }
.toolbar .btn-group > :first-child,
.toolbar .btn-group > :first-child .btn{ border-start-start-radius: var(--awe-radius-control);
  border-end-start-radius: var(--awe-radius-control); }
.toolbar .btn-group > :last-child,
.toolbar .btn-group > :last-child .btn{ border-start-end-radius: var(--awe-radius-control);
  border-end-end-radius: var(--awe-radius-control); }

/* 卡片內嵌用的篩選列（product_edit 的「異動紀錄」分頁）：同一條 .toolbar 的節奏，
   但沒有卡片邊界可以貼，所以收掉左右內距與下緣線，免得在分頁內容裡多畫一條假邊界。 */
.toolbar-flush{ padding-left: 0; padding-right: 0; border-bottom: 0; }

/* 「只看有現貨」switch：撐到同高才與左邊兩個控件對得齊；整塊可點。 */
.filter-switch{ display: inline-flex; align-items: center; gap: .5rem;
  height: var(--awe-control-h); margin: 0; padding: 0 .375rem 0 0;
  font-size: var(--awe-fs-body); color: var(--awe-ink-1); cursor: pointer; }
.filter-switch .form-check-input{ float: none; margin: 0; flex: none; cursor: pointer; }
.filter-switch .form-check-input:checked{ background-color: var(--awe-brand); border-color: var(--awe-brand); }
.filter-switch .form-check-input:focus{ box-shadow: 0 0 0 3px var(--awe-brand-soft); }
.filter-switch .form-check-label{ cursor: pointer; }
/* chip 類（共 N 筆／負庫存 N）不撐滿控件高，但用同一條中線對齊 */
.toolbar .count-pill,.toolbar .neg-pill{ align-self: center; }
/* 負庫存計數徽章：N>0 才出現、點一下＝只看負庫存品項。 */
.neg-pill{ display: inline-flex; align-items: center; gap: .25rem; cursor: pointer;
  font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption); font-weight: 600;
  color: var(--awe-danger); background: var(--awe-danger-soft);
  border: 1px solid var(--awe-danger-line); border-radius: var(--awe-radius-pill);
  padding: .125rem .5rem; transition: background-color .14s ease, color .14s ease; }
.neg-pill .icon{ width: .875rem; height: .875rem; }
.neg-pill:hover{ background: var(--awe-danger-tint); }
.neg-pill:focus-visible{ outline: none; box-shadow: 0 0 0 2px rgba(214, 57, 57, .35); }
.neg-pill.on{ background: var(--awe-danger); border-color: var(--awe-danger); color: #fff; }
.count-pill{ font-size: var(--awe-fs-caption); font-weight: 600; color: var(--awe-ink-2);
  background: var(--awe-surface-2); border: 1px solid var(--awe-line);
  border-radius: var(--awe-radius-pill); padding: .125rem .5rem; }
.scope-note{ display: flex; gap: .375rem; align-items: flex-start;
  padding: .5rem var(--awe-card-pad); border-bottom: 1px solid var(--awe-line);
  background: var(--awe-brand-soft); color: var(--awe-ink-1);
  font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption); }
.scope-note .icon{ width: 1rem; height: 1rem; flex: none; color: var(--awe-brand); margin-top: 1px; }


/* ══════════════════════════════════════════════════════════════════════════════
   §10  表格（DS-06／DS-07／DS-08／DS-29／DS-45）
   ══════════════════════════════════════════════════════════════════════════════ */
/* 表格內捲吃滿「剩餘視高」：真正的高度由頁尾 fitTable() 每次量測後寫成 inline max-height。
   這裡只是 JS 未跑前的保底值。 */
.table-sticky{ max-height: calc(100vh - 20rem); min-height: 15rem; overflow: auto; }
.table{ --tblr-table-bg: var(--awe-surface); margin-bottom: 0; }
/* DS-07｜表頭 surface-2 底：sticky 時與資料列同色就看不出表頭黏住。
   sticky 定位只掛在真的有捲動容器的 .table-sticky 上（頁面本身捲動時把表頭釘在視窗頂端
   會蓋住內容）——外觀（底色／字階／內距）則全站表頭一致。 */
.table thead th{
  background: var(--awe-surface-2);
  text-transform: none;                     /* 專有名詞（Pinkoi 倉）不該被大寫掉 */
  font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption);
  font-weight: var(--awe-fw-label); letter-spacing: .03em; color: var(--awe-ink-2);
  padding: .375rem var(--awe-cell-x); white-space: nowrap;
  border-bottom: 1px solid var(--awe-line);
}
.table-sticky thead th{ position: sticky; top: 0; z-index: 3; }
/* 數量欄表頭做成兩行：倉名（主）＋（件）（單位小字）。 */
.table thead th .th-txt{ display: inline-block; vertical-align: middle; }
.th-main{ display: block; }
.th-unit{ display: block; font-size: var(--awe-fs-micro); line-height: var(--awe-lh-micro);
  font-weight: 500; color: var(--awe-ink-3); letter-spacing: 0; }
/* DS-06｜列高與欄內距走 token 而不是各處硬寫：td 的 height 在表格模型裡是「最小高度」，
   所以單行列＝--awe-row-h、內容換行的列仍會自己長高（padding 保留呼吸）。 */
.table tbody td{ padding: var(--awe-row-y) var(--awe-cell-x);
  height: var(--awe-row-h);
  font-size: var(--awe-fs-body); line-height: var(--awe-lh-body); vertical-align: middle;
  border-bottom-color: var(--awe-line); }
.table tbody tr:hover > td{ background: var(--awe-surface-2); }
.table tfoot td{ position: sticky; bottom: 0; z-index: 3; background: var(--awe-surface-2);
  font-size: var(--awe-fs-body); font-weight: 700; color: var(--awe-ink-1);
  padding: .4375rem var(--awe-cell-x); box-shadow: inset 0 1px 0 var(--awe-line); }
/* DS-06 續｜card-table 的首／末欄要與卡片內容左右緣對齊。Tabler 把它寫死成 1.25rem，
   拉回 token 之後「卡緣 20px｜中間各欄 10px｜卡緣 20px」＝左右對稱、且與卡片內距同源。 */
.card-table tr td:first-child,.card-table tr th:first-child{ padding-left: var(--awe-card-pad); }
.card-table tr td:last-child,.card-table tr th:last-child{ padding-right: var(--awe-card-pad); }
.tnum,.table .text-end{ font-variant-numeric: tabular-nums; }
.cell-code{ font-family: var(--awe-font-mono); font-size: var(--awe-fs-badge);
  color: var(--awe-ink-2); letter-spacing: -.01em; }
/* DS-29（2026-08-11 拍板④修訂）｜表內品名連結：Tabler 讓 <a> 直接吃 --tblr-link-color
   ＝ 品牌紅，一屏 40 列品名就是 40 次飽和紅，主 CTA 完全淹沒。表格儲存格裡的連結一律
   ink-1，hover 才轉品牌色。
   ⚠ 修訂點：原規格 hover 是「轉品牌色＋底線」，眼驗後**底線全數收掉**——40 列掃過去
   每列閃一條線是純噪音，且 .cell-qty 早就因為「底線干擾等寬數字掃視」單獨破例了，
   代表這條規則本來就站不住。現在三者統一：hover 只換色。
   排除 .btn／.dropdown-item／.badge：那些是動作元件，各有自己的色彩語彙。 */
.table td a:not(.btn):not(.dropdown-item):not(.badge){
  color: var(--awe-ink-1); text-decoration: none; }
.table td a:not(.btn):not(.dropdown-item):not(.badge):hover{
  color: var(--awe-brand); text-decoration: none; }
.cell-name{ font-weight: 500; color: var(--awe-ink-1); text-decoration: none; }
.cell-name:hover{ color: var(--awe-brand); text-decoration: none; }
/* 數量下鑽連結：同上，轉色不加底線 */
.table td a.cell-qty,.cell-qty{ color: var(--awe-ink-1); text-decoration: none; }
.table td a.cell-qty:hover,.cell-qty:hover{ color: var(--awe-brand); text-decoration: none; }
.is-zero{ color: var(--awe-ink-3); }        /* 零值退到背景，非零數字才跳出來 */
.col-total{ border-left: 1px solid var(--awe-line); }
td.col-total{ font-weight: 700; }
.cell-note{ font-size: var(--awe-fs-caption); color: var(--awe-ink-2); }
.cell-sub{ font-family: var(--awe-font-mono); font-size: var(--awe-fs-badge); color: var(--awe-ink-3); }
td.neg,.neg{ color: var(--awe-danger); font-weight: 700; }
tr.neg-row > td{ background: var(--awe-danger-soft); }
tr.neg-row:hover > td{ background: rgba(214, 57, 57, .11); }
/* DS-08｜排序圖示降噪：未排序欄的雙箭頭平時不出現（8～12 個欄頭同時掛雙箭頭＝一整排
   視覺噪音），hover／鍵盤聚焦該欄才淡入；正在排序的欄由 erp.js 換成單向箭頭（↑／↓），
   並把表頭字色加深到主文色——「哪一欄在排序」用顏色與方向兩個訊號一起講。 */
th.th-sort{ cursor: pointer; user-select: none; white-space: nowrap; transition: color .12s ease; }
th.th-sort:hover{ color: var(--awe-brand); }
th.th-sort .sort-ind{ opacity: 0; margin-left: .15rem; vertical-align: middle;
  transition: opacity .12s ease; }
th.th-sort .sort-ind .icon{ width: .875rem; height: .875rem; }
th.th-sort:hover .sort-ind,
th.th-sort:focus-visible .sort-ind{ opacity: .5; }
th.th-sort[aria-sort="ascending"],
th.th-sort[aria-sort="descending"]{ color: var(--awe-ink-1); }
th.th-sort[aria-sort="ascending"] .sort-ind,
th.th-sort[aria-sort="descending"] .sort-ind{ opacity: 1; color: var(--awe-brand); }
/* 回程錨點高亮：儲存後回列表，「剛存的是這筆」看得見 */
tr.row-hl > td{ animation: row-hl 2s ease-out; }
@keyframes row-hl{ 0%,60%{ background: var(--awe-brand-soft); } 100%{ background: transparent; } }
/* DS-45｜日期分組標頭：一條細帶，不是一列假資料。
   ⚠ 選擇器刻意寫到 `.table tbody tr.day-sep > td`：分組列自己也是 tbody 裡的 td，
   若只寫 `.day-sep > td`(0,1,1) 會輸給上面的 `.table tbody td`(0,1,2)，字級被拉回 body 14px
   ——宣告寫了卻不生效（demo 原稿即有此隱性衝突，抽單一源時一併修掉）。 */
.table tbody tr.day-sep > td{ background: var(--awe-surface-2); color: var(--awe-ink-2);
  font-size: var(--awe-fs-caption); line-height: var(--awe-lh-band); font-weight: var(--awe-fw-label);
  letter-spacing: .04em; padding: .1875rem var(--awe-cell-x) !important;
  border-bottom: 1px solid var(--awe-line); }
.day-sep:hover > td{ background: var(--awe-surface-2); }
.day-sep .pg-n{ font-weight: 500; color: var(--awe-ink-3); margin-left: .25rem; }
/* 異動紀錄分頁：右欄窄，表格允許橫捲、不換行 */
.mv-table{ font-size: var(--awe-fs-caption); }
.mv-table td,.mv-table th{ padding: .25rem .3rem; vertical-align: top; }
.mv-table .badge{ font-size: var(--awe-fs-micro); }


/* ══════════════════════════════════════════════════════════════════════════════
   §11  兩層篩選語彙：segmented（資料範圍）／chip（附加條件）
   ══════════════════════════════════════════════════════════════════════════════
   拍板②（2026-08-11 papalu）：分頁語彙全站統一走 segmented（.seg-tabs），nav-tabs 退場。
   兩層要一眼分得出來，靠三件事同時成立：
     ① 形狀不同：分頁是一條連在一起的軌道（單選、必有一個選中）；chip 是各自獨立的膠囊
     ② 位置不同：分頁貼在卡頂（跟著卡片的身分走）；chip 在下面一層
     ③ 底色不同：分頁那層是白色卡面；chip 那層退到次面色，讀起來就是「附加條件」 */
.tabbar{ display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
  padding: .5rem var(--awe-card-pad); border-bottom: 1px solid var(--awe-line); }
.seg-tabs{ display: inline-flex; gap: 2px; padding: 3px; background: var(--awe-surface-2);
  border: 1px solid var(--awe-line); border-radius: var(--awe-radius-control); }
.seg-tab{ display: inline-flex; align-items: center; height: var(--awe-control-h-sm); padding: 0 .75rem;
  border-radius: var(--awe-radius-sm); font-size: var(--awe-fs-body); line-height: 1; color: var(--awe-ink-2);
  text-decoration: none; white-space: nowrap;
  transition: background-color .12s ease, color .12s ease; }
.seg-tab:hover{ color: var(--awe-ink-1); }
.seg-tab.active{ background: var(--awe-surface); color: var(--awe-brand); font-weight: 600;
  box-shadow: var(--awe-shadow-1); }
.seg-tab:focus-visible{ outline: none; box-shadow: 0 0 0 2px var(--awe-brand-line); }

.chipbar{ display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
  padding: .375rem var(--awe-card-pad); background: var(--awe-surface-2);
  border-bottom: 1px solid var(--awe-line); }
/* 維度名：chip 是「到貨日」這一條軸上的取值，把軸名寫出來比三顆孤立的按鈕好讀 */
.chip-dim{ font-size: var(--awe-fs-caption); font-weight: var(--awe-fw-label);
  color: var(--awe-ink-2); letter-spacing: .04em; margin-right: .125rem; }
.chip{ display: inline-flex; align-items: center; gap: .25rem; height: var(--awe-control-h-sm);
  padding: 0 .75rem;
  border: 1px solid var(--awe-line); border-radius: var(--awe-radius-pill);
  background: var(--awe-surface); color: var(--awe-ink-2);
  font-size: var(--awe-fs-caption); font-weight: 600; line-height: 1; cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease, color .12s ease; }
.chip:hover{ border-color: var(--awe-ink-3); color: var(--awe-ink-1); }
.chip:focus-visible{ outline: none; box-shadow: 0 0 0 3px var(--awe-brand-soft); }
.chip.on{ background: var(--awe-brand-soft); border-color: var(--awe-brand); color: var(--awe-brand); }
.chip.on .chip-x{ opacity: 1; }
.chip-x{ opacity: 0; width: .75rem; height: .75rem; margin-left: .125rem; }
.chip-x .icon{ width: .75rem; height: .75rem; }
/* 逾期那顆用 danger 家族（與品牌紅分工：它講的是「出事了」不是「你在這裡」） */
.chip[data-when="overdue"].on{ background: var(--awe-danger-soft); border-color: var(--awe-danger);
  color: var(--awe-danger); }
.chip-reset{ border: 0; background: transparent; color: var(--awe-ink-3);
  font-size: var(--awe-fs-caption); cursor: pointer; padding: 0 .25rem; }
/* 拍板④：hover 只換色，不加底線 */
.chip-reset:hover{ color: var(--awe-brand); text-decoration: none; }
.chipbar .count-pill{ margin-left: auto; }
/* 舊式快篩 chip（正式頁 markup 尚未換形前的過渡；切片 5／6b 收掉） */
.chip-on{ box-shadow: inset 0 0 0 2px var(--awe-brand); }
/* 可點的彙總徽章：形式仍是 toolbar 徽章，只多了「按得下去」 */
.badge-filter{ cursor: pointer; border: 1px solid transparent; }
.badge-filter:hover{ border-color: var(--awe-brand); }
.badge-filter.on{ outline: 2px solid var(--awe-brand); outline-offset: 1px; font-weight: 700; }


/* ══════════════════════════════════════════════════════════════════════════════
   §12  徽章（DS-D1 全部吃 badge 字階）
   ══════════════════════════════════════════════════════════════════════════════
   徽章高度鎖在列的行高之內：inline-block 若比行高高，會把整列的 line box 撐起來
   （每列多長 7px，一屏就少掉快兩列）。line-height + vertical-align 把它壓回同一條線上。 */
.badge-cat{ display: inline-block; white-space: nowrap; vertical-align: middle;
  font-size: var(--awe-fs-badge); line-height: var(--awe-lh-badge); font-weight: var(--awe-fw-badge);
  color: var(--awe-ink-2);
  background: var(--awe-surface-2); border: 1px solid var(--awe-line);
  border-radius: var(--awe-radius-pill); padding: 0 .5rem; }
.badge-flag{ font-size: var(--awe-fs-badge); line-height: var(--awe-lh-badge);
  font-weight: var(--awe-fw-badge); vertical-align: middle;
  border-radius: var(--awe-radius-pill); padding: 0 .4375rem; }
/* 狀態徽章：四個狀態四種語意，不共用同一顆灰 */
.badge-state{ display: inline-block; white-space: nowrap; vertical-align: middle;
  font-size: var(--awe-fs-badge); line-height: var(--awe-lh-badge); font-weight: 600; padding: 0 .5rem;
  border-radius: var(--awe-radius-pill); border: 1px solid transparent; }
.state-pending{ color: var(--awe-ink-2); background: var(--awe-surface-2); border-color: var(--awe-line); }
.state-partial{ color: var(--awe-warn); background: var(--awe-warn-soft); border-color: var(--awe-warn-line); }
.state-done{ color: var(--awe-ok); background: var(--awe-ok-soft); border-color: var(--awe-ok-line); }
.state-cancelled{ color: var(--awe-ink-3); background: transparent; border-color: var(--awe-line);
  text-decoration: line-through; }
.badge-day{ display: inline-block; vertical-align: middle; font-size: var(--awe-fs-badge);
  line-height: var(--awe-lh-badge);
  font-weight: 600; padding: 0 .4375rem; border-radius: var(--awe-radius-pill); }
.badge-overdue{ color: var(--awe-danger); background: var(--awe-danger-soft);
  border: 1px solid rgba(214, 57, 57, .3); }
.badge-today{ color: var(--awe-brand); background: var(--awe-brand-soft);
  border: 1px solid var(--awe-brand-line); }
/* 缺圖用灰框占位表達，不再是 40 列 100% 的橘色徽章（V-07） */
.thumb-none{ display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px;
  border: 1px dashed var(--awe-line); border-radius: var(--awe-radius-sm); color: var(--awe-ink-2);
  background: var(--awe-surface-2); }


/* ══════════════════════════════════════════════════════════════════════════════
   §13  列操作（DS-D2 走 control-h-sm）
   ══════════════════════════════════════════════════════════════════════════════
   一顆主動作＋一個溢位選單；WCAG 2.5.8 觸擊目標 ≥24px（本站取 28px），
   破壞性動作與主動作拉開 ≥16px。

   ── 拍板⑤（2026-08-11 papalu 眼驗）｜動作鈕在儲存格內置中 ──────────────────
   原本動作欄跟著數字欄一起 text-end 靠右，於是「入倉／編輯／更正」這一排鈕會黏在
   表格最右緣、右邊只剩卡片內距那幾 px，而左邊留一大片空白——看起來像是被擠出去的，
   不像一個有自己欄寬的欄位。動作鈕不是數字，沒有「小數點對齊」的理由要靠右。
   ⚠ 正式頁 markup 不動（那些 td 身上的 .text-end 留著），所以置中要在樣式層用
   :has() 把「內容只有動作控件」的儲存格挑出來覆蓋掉 text-align：
     ① td > .row-actions            → pending／design-demo-pending／styleguide
     ② td > .btn 且該 btn 是唯一子元素 → products（編輯）／stock_in・adjust（更正）
   ②的 :only-child 是防呆：混了文字或數字的儲存格不會被誤抓進來。
   ⚠ 必須 !important：markup 上的 .text-end 是 Bootstrap 工具類、本身就帶 !important，
     非 !important 的規則不論選擇器多重都贏不了它（實測 computed 仍是 right）。
     等後續切片把那些 .text-end 從動作欄 markup 拿掉，這裡的 !important 可一併退場。
   同時把動作格的左右內距補成對稱：DS-06 讓末欄 padding-right = card-pad(20px)、
   其餘欄 10px，動作欄若沿用就會「內容置中但看起來偏左 5px」——置中要對得起眼睛。
   （尚未涵蓋：categories.php 的「刪除」在 <form> 裡、且同表另一欄也是 <form>＋輸入框，
     純選擇器分不開；那格要置中需要補一層 .row-actions wrapper，留給後續切片。） */
.table td:has(> .row-actions),
.table td:has(> .btn:only-child){ text-align: center !important; }
.card-table tr td:last-child:has(> .row-actions),
.card-table tr td:last-child:has(> .btn:only-child){ padding-left: var(--awe-card-pad); }
.row-actions{ display: inline-flex; align-items: center; gap: .25rem; justify-content: center; }
.row-actions .btn{ height: var(--awe-control-h-sm); min-width: var(--awe-control-h-sm);
  min-height: var(--awe-control-h-sm);
  padding: 0 .5rem; font-size: var(--awe-fs-caption);
  border-radius: var(--awe-radius-control); display: inline-flex; align-items: center;
  justify-content: center; }
.row-actions .btn .icon{ width: 1rem; height: 1rem; }
.row-actions .row-actions-sep{ margin-left: 1rem; }
.row-actions > form{ display: inline-flex; margin: 0; }
.row-actions .dropdown-menu form{ display: block; margin: 0; }
.row-actions .dropdown-menu .dropdown-item{ width: 100%; text-align: left; min-height: 2rem; }


/* ══════════════════════════════════════════════════════════════════════════════
   §14  Modal（DS-47／DS-48／DS-49）
   ══════════════════════════════════════════════════════════════════════════════ */
/* DS-48｜外殼：Tabler 的 modal border-color 是 transparent、shadow 幾乎看不見。 */
.modal-content{ border-radius: var(--awe-radius-card); border: 1px solid var(--awe-line);
  box-shadow: var(--awe-shadow-2); }
.modal-header{ padding: .875rem var(--awe-card-pad); border-bottom: 1px solid var(--awe-line); }
.modal-title{ font-size: var(--awe-fs-section); line-height: var(--awe-lh-section);
  font-weight: var(--awe-fw-section); color: var(--awe-ink-1); }
.modal-body{ padding: var(--awe-card-pad); }
.modal-footer{ padding: .75rem var(--awe-card-pad); border-top: 1px solid var(--awe-line); gap: .5rem; }
/* DS-49｜標籤不該和內文同權重：13px/600/ink-2 */
.modal .form-label{ font-size: var(--awe-fs-label); line-height: var(--awe-lh-label);
  font-weight: var(--awe-fw-label); color: var(--awe-ink-2); margin-bottom: .25rem; }
.modal .form-control{ height: var(--awe-control-h); min-height: var(--awe-control-h);
  font-size: var(--awe-fs-body);
  border-radius: var(--awe-radius-control); border: 1px solid var(--awe-line); }
.modal .form-control:focus{ border-color: var(--awe-brand); box-shadow: 0 0 0 3px var(--awe-brand-soft); }
/* DS-47｜數量欄：46px／20px／600／tabular-nums（現況 52.57px／400／無等寬數字）。
   ⚠ Tabler 的 .form-control-lg 帶 min-height:calc(…)＝52.57px，它會蓋過我們宣告的 height，
   padding 也自帶 .5rem 1rem——只寫 height 完全量不出 46px（demo 原稿即有此隱性衝突）。
   故 height／min-height／padding／line-height 一起收，數字才真的落在 46px 上。 */
.modal .form-control-lg{ height: var(--awe-control-h-lg); min-height: var(--awe-control-h-lg);
  padding: 0 .75rem; font-size: var(--awe-fs-display-sm); line-height: 1.25;
  font-weight: 600; font-variant-numeric: tabular-nums; }
/* 排程摘要（排程／已入倉／剩餘）：動作前唯一要對的三個數字，排成一條而不是一句話 */
.rc-facts{ display: flex; gap: .5rem; margin-bottom: .75rem; }
.rc-fact{ flex: 1; padding: .375rem .625rem; background: var(--awe-surface-2);
  border: 1px solid var(--awe-line); border-radius: var(--awe-radius-control); }
.rc-fact dt{ font-size: var(--awe-fs-badge); line-height: var(--awe-lh-badge);
  font-weight: var(--awe-fw-badge); color: var(--awe-ink-2); }
.rc-fact dd{ margin: 0; font-size: var(--awe-fs-fact); line-height: var(--awe-lh-fact); font-weight: 600;
  color: var(--awe-ink-1); font-variant-numeric: tabular-nums; }
.rc-fact.rc-remain dd{ color: var(--awe-brand); }
.rc-warn{ display: flex; gap: .375rem; align-items: flex-start; margin-top: .375rem;
  font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption); color: var(--awe-danger); }
.rc-warn .icon{ width: 1rem; height: 1rem; flex: none; }


/* ══════════════════════════════════════════════════════════════════════════════
   §15  倉別卡與商品選取器（DS-59）
   ══════════════════════════════════════════════════════════════════════════════ */
/* DS-59｜.on 用 1px border ＋ brand-soft 底。舊版用 border 2px，選中時內容位移 1px。 */
.wh-cards{ display: flex; gap: .5rem; flex-wrap: wrap; }
.wh-card{ position: relative; flex: 1; min-width: 96px; padding: .5rem .375rem; text-align: center;
  border: 1px solid var(--awe-line); border-radius: var(--awe-radius-control);
  background: var(--awe-surface); user-select: none;
  transition: border-color .12s ease, background-color .12s ease; }
.wh-card.selectable{ cursor: pointer; }
.wh-card.selectable:hover{ border-color: var(--awe-brand-line); }
.wh-card.selectable:focus-visible{ outline: none; border-color: var(--awe-brand);
  box-shadow: 0 0 0 3px var(--awe-brand-soft); }
.wh-card.on{ border-color: var(--awe-brand); background: var(--awe-brand-soft); }
.wh-card b{ display: block; font-size: var(--awe-fs-body); color: var(--awe-ink-1); }
.wh-card small{ display: block; font-size: var(--awe-fs-badge); line-height: var(--awe-lh-badge);
  color: var(--awe-ink-2); font-weight: 400; }
.wh-card .after{ color: var(--awe-brand); font-weight: 600; }
.wh-card .whk{ position: absolute; top: 3px; left: 4px; font-size: var(--awe-fs-micro); line-height: 1;
  font-weight: 600; color: var(--awe-ink-3); background: var(--awe-surface-2);
  border: 1px solid var(--awe-line); border-radius: var(--awe-radius-xs); padding: 1px 3px; }
.wh-card.on .whk{ color: var(--awe-brand); border-color: var(--awe-brand-line); }

.picker-menu{ position: absolute; z-index: 1050; left: 0; right: 0; top: 100%;
  background: var(--awe-surface); border: 1px solid var(--awe-line);
  border-radius: 0 0 var(--awe-radius-control) var(--awe-radius-control);
  box-shadow: var(--awe-shadow-2); max-height: 280px; overflow: auto; }
.picker-menu .item{ padding: .375rem .625rem; cursor: pointer; display: flex; gap: .5rem;
  align-items: center; font-size: var(--awe-fs-body); }
.picker-menu .item:hover,.picker-menu .item.hl{ background: var(--awe-brand-soft); }
/* 截斷提示若排在第 9 列會被 max-height 的捲軸吃掉 -> 釘在捲動容器底部，永遠看得到 */
.picker-menu .pp-note{ position: sticky; bottom: 0; padding: .375rem .625rem;
  font-size: var(--awe-fs-caption); color: var(--awe-ink-2);
  border-top: 1px solid var(--awe-line); background: var(--awe-surface-2); }
.picker-menu .pp-miss-note{ border-top: none; color: var(--awe-ink-1); }
.pcard{ display: flex; gap: .625rem; align-items: center; padding: .5rem .625rem;
  border: 1px solid var(--awe-brand); border-radius: var(--awe-radius-control);
  background: var(--awe-surface); font-size: var(--awe-fs-body); }
.pcard img,.pcard .noimg{ width: 40px; height: 40px; object-fit: cover; flex: none;
  border-radius: var(--awe-radius-sm); border: 1px solid var(--awe-line); }
.pcard .noimg{ display: flex; align-items: center; justify-content: center;
  font-size: var(--awe-fs-badge); color: var(--awe-ink-3); background: var(--awe-surface-2); }
.pp-miss{ border-color: var(--awe-danger) !important;
  box-shadow: 0 0 0 3px var(--awe-danger-soft) !important; animation: pp-shake .3s; }
@keyframes pp-shake{ 25%{ transform: translateX(-3px); } 75%{ transform: translateX(3px); } }


/* ══════════════════════════════════════════════════════════════════════════════
   §16  表單頁共用件（DS-78）
   ══════════════════════════════════════════════════════════════════════════════ */
/* DS-78｜表單動作列常駐：長表單捲動時「儲存／返回」不再沉在 1500px 底部。
   舊版自帶硬寫值（shadow 0 -2px 8px rgba(0,0,0,.06)／radius 4px），改吃 token。 */
.form-actions-sticky{ position: sticky; bottom: 0; z-index: 20; background: var(--awe-surface);
  border-top: 1px solid var(--awe-line); padding: .625rem .75rem; margin-top: .25rem;
  border-radius: var(--awe-radius-card) var(--awe-radius-card) 0 0;
  box-shadow: var(--awe-shadow-up); }
/* 未儲存指示 */
.dirty-dot{ display: none; align-items: center; gap: .35rem; color: var(--awe-danger);
  font-weight: 600; font-size: var(--awe-fs-label); }
.is-dirty .dirty-dot{ display: inline-flex; }
.dirty-dot::before{ content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--awe-danger); }
/* 三步驟流程（Tabler .steps ＋ 卡內 .step-n 圓圈；形本身待切片 6a／6b 收斂，此處只走 token） */
.steps-flow{ margin-bottom: var(--awe-gap); }
.step-n{ display: inline-flex; width: 22px; height: 22px; border: 2px solid var(--awe-brand);
  color: var(--awe-brand); border-radius: 50%; align-items: center; justify-content: center;
  font-weight: 700; font-size: var(--awe-fs-caption); margin-right: 6px; flex: none; }
.step-n.done{ background: var(--awe-brand); color: #fff; }
/* Tabler 的 .steps 假設「一定照順序走」（.active 之後的一律灰掉）。本站三步驟拍板為可跳填，
   故補一顆 .step-done：即使排在目前步驟之後，只要已填好就照樣是完成色。 */
.steps .step-item.step-done{ color: var(--awe-ink-1); }
.steps .step-item.step-done:before,.steps .step-item.step-done:after{ background: var(--tblr-steps-color); }


/* ══════════════════════════════════════════════════════════════════════════════
   §17  頁尾
   ══════════════════════════════════════════════════════════════════════════════ */
.footer{ background: transparent; border-top: 1px solid var(--awe-line); padding: .5rem 0;
  font-size: var(--awe-fs-caption); color: var(--awe-ink-3); }


/* ══════════════════════════════════════════════════════════════════════════════
   §18  toast（拍板①｜DS-21／DS-D7）
   ══════════════════════════════════════════════════════════════════════════════
   現況（erp.js）用 Bootstrap 的 .text-bg-success / -danger / -info ＝ 100% 飽和實心
   綠／紅／藍，寬約 390px、無 token 圓角與陰影，而且那顆綠與那顆藍根本不在 token 表內
   （＝憑空多出兩個色相）。
   拍板①收斂為：白卡面 ＋ 左側語意色圖示 ＋ shadow-2 ＋ 左緣 3px 語意色條。
   語意靠圖示與色條講，不靠整片飽和底色淹沒版面——飽和紅仍然只留給主 CTA。
   位置：右上（Tabler toast-container 的既有位置），不佔文件流版位。
   ※ 切片 1 只立形（styleguide 可眼驗）；erp.js 的行為改寫屬後續切片。 */
.awe-toast{ position: relative; overflow: hidden;
  background: var(--awe-surface); border: 1px solid var(--awe-line);
  border-radius: var(--awe-radius-card); box-shadow: var(--awe-shadow-2);
  font-size: var(--awe-fs-body); color: var(--awe-ink-1); }
.awe-toast::before{ content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--awe-ink-3); }
.awe-toast .toast-body{ padding: .625rem .75rem; }
.awe-toast .stat-ico{ width: 1.75rem; height: 1.75rem; }
.awe-toast .stat-ico .icon{ width: 1rem; height: 1rem; }
.awe-toast-ok::before{ background: var(--awe-ok-dot); }
.awe-toast-ok .stat-ico{ background: var(--awe-ok-soft); color: var(--awe-ok); }
.awe-toast-danger::before{ background: var(--awe-danger); }
.awe-toast-danger .stat-ico{ background: var(--awe-danger-soft); color: var(--awe-danger); }


/* ══════════════════════════════════════════════════════════════════════════════
   §19  樣式看板（styleguide.php）專用的展示容器
   ══════════════════════════════════════════════════════════════════════════════
   只有色塊與圓角/陰影樣張這兩個「拿來把 token 畫出來」的容器，不是任何產品元件的複本。
   放這裡而不是放進 styleguide.php 的 <style>，是為了讓「全站樣式只有 theme.css 一個檔」
   這條規則沒有例外可鑽（PCSP 規則 15）。 */
.sg-chip{ width: 2rem; height: 2rem; flex: none; border-radius: var(--awe-radius-control);
  border: 1px solid var(--awe-line); }
.sg-box{ width: 4rem; height: 3rem; margin-bottom: .25rem;
  background: var(--awe-surface); border: 1px solid var(--awe-line); }


/* ══════════════════════════════════════════════════════════════════════════════
   §20  窄寬度（<992px 側欄收合）：密度收一階，資訊順序不變
   ══════════════════════════════════════════════════════════════════════════════ */
@media (max-width: 991.98px){
  :root{ --awe-fs-display: 24px; --awe-lh-display: 30px; --awe-card-pad: 1rem; --awe-cell-x: .625rem; }
  /* 拍板⑦配套：display 這一階原本只收 --awe-fs-display 一顆，-lg／-sm 兩顆漏收。
     統計帶主角（.stat-primary 走 -lg）在窄寬度是最容易撐爆分段的那一個，要一起收。 */
  :root{ --awe-fs-display-lg: 26px; --awe-lh-display-lg: 32px; }
  .toolbar{ padding: .375rem 1rem; }
  .filter-search{ flex: 1 1 100%; max-width: 100%; }
  .filter-select{ flex: 1 1 40%; max-width: none; }
}
/* 手機寬度｜拍板⑦的邊界條件：分段一旦窄到放不下「數值＋單位」，nowrap 會讓數字直接
   溢出分隔線（實測 375px 下 design-demo-pending 的主分段溢出 41px、styleguide 40px）。
   數字不准折行也不准被裁，那就只剩「把字級再收一階」這條路——與 §20 同一個手法，
   只是再往下一格。收完實測三頁分段皆 0 溢出。 */
@media (max-width: 575.98px){
  :root{
    --awe-fs-display:    20px; --awe-lh-display:    26px;
    --awe-fs-display-lg: 22px; --awe-lh-display-lg: 28px;
    --awe-fs-display-sm: 17px; --awe-lh-display-sm: 23px;
  }
  .stat-ico{ width: 1.75rem; height: 1.75rem; }
  .stat-ico .icon{ width: 1rem; height: 1rem; }
}


/* ══════════════════════════════════════════════════════════════════════════════
   ===== N-proposal ===== ✅ 全數轉正，本區塊已無任何宣告（只留去向對照）
   ══════════════════════════════════════════════════════════════════════════════
   切片 N（UX2 前置設計提案）＝ demo 從未定義過的 8 顆元件（N-d～N-k）的提案形，
   2026-08-12 papalu 一次拍板「10 題全數照建議案」，其後逐片轉正。
   2026-08-14 切片 10 收官：最後三顆（N-e／N-f／N-g）落地 import.php，
   依切片 N 的收尾動作①，`np-` 前綴的宣告與 `--np-*` 暫放值**整段刪除**（禁留兩份）。

   | 提案件 | 盤點 ID | 拍板 | 正式形所在 | 落地頁 |
   |---|---|---|---|---|
   | N-d 表單頁空狀態 | DS-58 | 案 A | slice-5 的 `.empty-inline`（與 N-b 同一顆，未搬第二份） | stock_in／adjust |
   | N-e 說明／凍結公告帶 | DS-67 | 案 A（中性） | slice-10 `.state-note`／`.help-fold` | import |
   | N-f 檔案上傳控件 | DS-68 | 案 A（放置區） | slice-10 `.file-drop` ＋ erp.js `fileDrop()` | import |
   | N-g 匯入結果表 | DS-71 | 案 A（原因用文字） | slice-10 `.rc-ok`／`.rc-danger`／`.err-line`／`.err-raw` | import |
   | N-h TinyMCE 外框 | DS-73 | 案 A | slice-8 的真 `.tox-*` 覆寫 ＋ erp.js `aweEditorInit()` | product_edit |
   | N-i 圖片區 | DS-74 | 案 A | slice-8 `.img-strip`／`.img-thumb`／`.img-add`… | product_edit |
   | N-j inline-edit 列 | DS-81 | 案 A | slice-7 `.cell-read`／`.cell-edit`／`.is-editing` | categories |
   | N-k 窄表單版型 | DS-86 | 案 A | slice-9 `.narrow-form` ＋ `--awe-narrow-w` | password |

   **未採用的對案一律不轉正**（留著就是第二種形）：N-e 的琥珀狀態帶（`.np-notice-warn`）／
   N-f 的單行 38px 控件（`.np-fileline`）／N-g 的原因 badge（`.np-err-tag`）／
   N-j 的假 disabled（`.np-locked`）。其中 N-g 的 badge 分類**等原因碼收斂後**再議
   （屆時只加一顆 badge、版型不必改，見 AWE-sliceN-proposal.md N-g 案 B）。
   提案期的 A／B 並排展示容器（`.np-optgrid`／`.np-opt`／`.np-why`／`.np-before`）
   隨最後一顆轉正一併刪除——styleguide §9 已全部改成渲染**正式形**。
   ══════════════════════════════════════════════════════════════════════════════ */


/* ══════════════════════════════════════════════════════════════════════════════
   ===== slice-4 =====（UX2 切片 4｜balances 庫存看板）
   ══════════════════════════════════════════════════════════════════════════════ */

/* DS-09｜`.is-zero` 在表格內失效的修正（既有 §10 那條保持原樣，本條只補特異度）。
   §10 的 `.is-zero{color:var(--awe-ink-3)}` 特異度 (0,1,0)，但 Tabler 的
   `.table > :not(caption) > * > *{ color: var(--tblr-table-color-state,…) }` 是 (0,1,1)
   ——**在 `.table` 內部它一律贏**，所以零值儲存格量到的仍是 ink-1（實測 CDP
   getMatchedStylesForNode：兩條都命中，勝者是 Tabler 那條）。兩頁 demo 也同樣失效，
   等於「標準答案」在這一顆上從來沒真的成立過。
   這裡用 `.table td.is-zero`(0,1,2) 蓋過去，class 名與語意都不變。 */
.table td.is-zero{ color: var(--awe-ink-3); }

/* DS-31 配套｜page-header 在 992～1100px 的「標題被壓成一字一行」修正。
   成因：`.page-header` 的左欄是 `.col`（flex-basis:0），右欄 `.col-auto` 放資料時效＋
   btn-list＋帳號。中文沒有詞界 → 左欄的 min-content ＝**一個字**，於是右欄一長，
   標題不是換行而是「垂直排成一行一字」（實測 balances 992px 標題高 112px＝四行）。
   本片替 balances 補上三顆動作鈕後這條路徑才被踩到，但**兩頁 demo 早就是壞的**
   （demo 992／1024 皆 112px、1100px 56px）——標準答案自己沒守住，不能照抄。
   解法：標題與 pretitle 不換行 → 左欄的 min-content 變回整串文字寬 → 放不下時
   `.row` 自己把右欄整塊擠到第二列（Bootstrap 的 row 本來就 flex-wrap:wrap），
   讀序仍是「標題 → 動作」。
   ⚠ 兩個踩過的坑（都靠實拍抓出來，box 幾何量測看不到）：
     ① 只加 `white-space:nowrap` **不夠**：Bootstrap 的 `.col` 是 `flex:1 0 0%`＋
        `.row > *{flex-shrink:0}`，basis 是 0 → 換行判斷用的假想寬也是 0，永遠「塞得下」，
        於是欄寬保持 ~0、標題文字直接**溢出欄外**壓在資料時效戳上（992px 實拍）。
        所以要一併把 basis 改回 auto，換行判斷才看得到真正的文字寬度。
        ⚠ 只寫 `flex-basis:auto` 還不夠：Bootstrap 另有 `.row > *{width:100%}`，
        basis:auto 會去讀 width ＝ 100% → 左欄整條吃滿、右欄被擠到第二列（1440px
        也照擠）。必須連 `width:auto` 一起給，basis 才會落在內容寬。
     ② 給 `.ph-utility{flex-wrap:wrap}` 更糟：右欄自己先在內部斷行（鈕在上、時效戳
        掉到第二行），col-auto 因此仍塞得進同一列 → 整塊往左推、重疊照舊。
        右欄必須維持不可斷，才逼得動整欄換列。 */
.page-header .page-title,
.page-header .page-pretitle{ white-space: nowrap; }
.page-header .row > .col{ flex-basis: auto; width: auto; }

/* ⚠ 技術債登記（切片 4／5 audit §1.1① 裁定）：上面這兩條的作用面是全站 `page_header()`
   產物、與 balances markup 無關，暫留本區塊；建議後續切片整段搬進 `_layout` 共用件段落，
   並在 AWE-design-sweep-r1.md 補一條對應 DS。 */
/* ===== /slice-4 ===== */


/* ══════════════════════════════════════════════════════════════════════════════
   ===== slice-5 ===== ｜UX2 切片 5（pending.php 待入倉，含 3 modal）
   ══════════════════════════════════════════════════════════════════════════════
   本區塊只放切片 5 名下的缺口；demo class（.seg-tabs／.chip／.badge-today／
   .badge-state／.rc-facts／.scope-note／.count-pill）切片 1 已抽入上方各節，此處不重寫。 */

/* ── BLOCK-5-1（audit AWE-slice45-audit.md §2.1）｜兩層 bar 的負外距歸零 ──────────
   症狀：chipbar 的 surface-2 灰底帶比所在 `.card` 左右各寬出 7px，灰色矩形壓在卡片圓角
   外緣的畫布上（四寬 × 雙引擎 100% 復現；demo 標準答案是 -1/-1 ＝ 貼齊卡片 1px 邊框內緣）。
   根因：Tabler core 自帶 `.toolbar{ margin: 0 -.5rem }`，與 `_layout.php::filter_bar()` 產出的
   `.toolbar` **class 撞名**；§9 的 `.toolbar` 只覆寫了 padding／flex-wrap，沒有把 margin 歸零，
   所以 Tabler 的 -8px 一直贏（實測 computed `margin-left/right = -8px`；-8 ＋ 卡片 1px 邊框 ＝ +7）。
   demo 的兩條 bar 是**不帶 `.toolbar` class 的裸 div** → 沒有撞名 → 齊平。
   ⚠ 這條缺陷在切片 3 就存在（基準的 `.toolbar` 同樣量到 +7/+7，balances／products 皆是），
     只是底色透明時看不見；切片 5 給 chipbar 上了 surface-2 底色才把它顯影。
     根治應該是在 §9 的 `.toolbar` 補 `margin:0`——但那是切片 3 的地盤、會動到既有區塊，
     故本片只治自己這兩條（形與 demo 一致即可），全站那條列進交棒待辦。 */
.tabbar,.chipbar{ margin-left: 0; margin-right: 0; }

/* ── DS-53｜表內空狀態的無框變體 ──────────────────────────────────────────────
   切片 1 的 styleguide 7.2 用三顆 inline 宣告湊出這個形（.zero-hint 塞進 <td> 時要脫掉
   卡片的框與底），這裡收成一顆正式 class 給產品頁用。
   ✅ 2026-08-12 拍板後（N-d 案 A）已淘汰提案期的 `.np-empty-inline`：產品頁與 styleguide
   一律吃這一顆，沒有第二份。（本註記由切片 10 修正——原文寫的是拍板前的狀態。） */
.empty-inline{ border: 0; box-shadow: none; background: transparent;
  justify-content: center; text-align: left; padding: 1rem var(--awe-card-pad); }
.empty-inline .zero-hint-body{ color: var(--awe-ink-3); }
/* 空狀態的兩個出口要看得出來可點：它們不吃 DS-29 的「表內連結一律 ink-1」——那條治的是
   「一屏 40 列品名各閃一次品牌紅」，而空狀態一屏只有這一列、連結就是唯一的下一步。
   ⚠ 選擇器刻意堆到 (0,5,2) 才壓得過 DS-29 的 `.table td a:not():not():not()`(0,4,2)。 */
.table td .zero-hint.empty-inline .zero-hint-body a:not(.btn){ color: var(--awe-brand); }
.table td .zero-hint.empty-inline .zero-hint-body a:not(.btn):hover{ color: var(--awe-brand-ink); }

/* ── DS-52｜pending 這一張表的欄寬紀律 ────────────────────────────────────────
   問題：備註欄用 inline `style="max-width:180px"` 硬寫，品名欄則完全沒有寬度規範
   → 兩欄搶寬度，900px 下品名散成 3 行、⋮ 鈕被推到捲動區右緣外。
   解法同 demo：品名給明確百分比（它是掃視時真正要讀的東西），其餘欄退到內容寬，
   備註鎖 170px 並靠 .text-truncate ＋ title 存全文。
   ⚠ 選擇器刻意收在 `#pr-table`：這組寬度屬於這一張表、不是全站規則。demo 把它寫在
   頁內 <style>，但正式頁的 <head> 由 page_header() 產、沒有頁級 style slot，
   故落在 theme.css 並用 ID 圈住作用域（不外溢到別頁的表格）。 */
#pr-table th:nth-child(1),#pr-table td:nth-child(1){ white-space: nowrap; width: 1%; }
#pr-table th:nth-child(2){ width: 36%; min-width: 12rem; }
#pr-table th.text-end,#pr-table td.text-end{ white-space: nowrap; width: 1%; }
#pr-table th:nth-child(6),#pr-table td:nth-child(6){ white-space: nowrap; width: 1%; }
#pr-table th:nth-child(7),#pr-table td:nth-child(7){ width: 170px; max-width: 170px; }
/* 剩餘＝這頁真正要看的數字（還有多少沒到），用字重拉主從；為 0 時退回常態字重（.is-zero 管顏色） */
#pr-table td.qty-remain{ font-weight: 700; }
#pr-table td.qty-remain.is-zero{ font-weight: 400; }
/* <992px｜備註再收 30px，讓整張表塞得進捲動區＝列尾的 ⋮ 不會被切在右緣外。
   為什麼是動備註而不是動品名：備註本來就是 truncate ＋ title 存全文（少 30px 不少資訊），
   品名的 min-width 一旦鬆手就會散成三行——那正是 DS-52 要修的症狀。
   量測（900px）：可視 882px；備註 170px 時表寬 908（⋮ 溢出 10px），140px 時 878（⋮ 不溢出）。 */
@media (max-width: 991.98px){
  #pr-table th:nth-child(7),#pr-table td:nth-child(7){ width: 140px; max-width: 140px; }
}
/* ===== /slice-5 ===== */


/* ══════════════════════════════════════════════════════════════════════════════
   ===== slice-6a ===== ｜UX2 切片 6a（stock_in.php 直接入倉）
   ══════════════════════════════════════════════════════════════════════════════
   解 DS-54（品牌紅收斂）／DS-55（步驟語彙去重）／DS-56（數量控件）／DS-58＝N-d（空狀態）／
   DS-60（更正入口 affordance）。空狀態不在本區塊——它吃的是切片 5 已立的 `.empty-inline`
   （N-d 拍板後直接沿用正式 class，不複製第二份宣告）。 */

/* ── DS-54｜頁首導引句的連結不吃品牌紅 ──────────────────────────────────────
   「有排程的貨請走『待入倉』→ 入倉」這句是路線指引，不是本頁的動作。它原本吃全站
   link 色（--tblr-link-color ＝ 品牌紅），在一頁只准一顆 CTA ＋ active 的紀律下是多的那一顆。
   規則沿用 DS-29（表內連結）：可點性靠 ink-1 ＋ 字重講，hover 才轉品牌色。 */
.route-note a{ color: var(--awe-ink-1); font-weight: 600; }
.route-note a:hover,.route-note a:focus-visible{ color: var(--awe-brand); }

/* ── DS-55／DS-54｜卡內步驟標題與序號圓圈 ────────────────────────────────────
   頂部 Tabler `.steps` 已從 markup 移除（兩套講同一件事）；留下來的這一套要自己站得住：
     ① 標題走 --awe-fs-section（15/600）＝ 和站內所有區塊標題同一階，原本是裸 <b>(14/700)；
     ② 括號裡的操作提示退到 caption/ink-2——它是附註不是標題的一部分；
     ③ 序號圓圈改中性（surface-2 ＋ line ＋ ink-2）。一頁三顆紅圈圈把「你在這裡」的
        訊號稀釋掉了，而序號本身只是「第幾格」，不是狀態。
     ④ 完成態走 --awe-ok 家族＝ 與 `.state-done` 同一顆語意色（站內「完成」已經是綠的），
        品牌紅整頁只剩 CTA ＋ 側欄 active。
   ⚠ §16 的 `.step-n` 基底（尺寸／圓形／字重）仍是單一源，本區只覆寫顏色與字階；
     待切片 6b（DS-64）同步後，§16 的 `.steps-flow`／`.steps .step-item.step-done`
     兩條會沒有使用者，屆時一併退場（交棒待辦）。 */
.step-head{ display: flex; align-items: center; gap: .375rem; flex-wrap: wrap;
  margin-bottom: .5rem;
  font-size: var(--awe-fs-section); line-height: var(--awe-lh-section);
  font-weight: var(--awe-fw-section); color: var(--awe-ink-1); }
.step-head .step-n{ margin-right: 0; }
.step-head .step-hint{ font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption);
  font-weight: 400; color: var(--awe-ink-2); }
.step-n{ border-width: 1px; border-color: var(--awe-line); background: var(--awe-surface-2);
  color: var(--awe-ink-2); font-size: var(--awe-fs-badge); }
.step-n.done{ border-color: var(--awe-ok-line); background: var(--awe-ok-soft);
  color: var(--awe-ok); }

/* ── DS-56｜數量欄收進「主數量欄」那一階 ────────────────────────────────────
   現況 `.input-group-lg` 量到 52.57px（Tabler 的 min-height calc 值），與同頁的
   36px 控件並存＝一頁三種控件高。本站已經有一顆拍過板的主數量欄規格：DS-47 的
   modal 數量欄（46px／20px／600／tabular-nums）——同樣是「這個畫面唯一要打的數字」，
   沒有理由長成第二種。本頁因此只剩兩階：36px 一般控件 ＋ 46px 主數量欄（刻意的主從）。
   ⚠ 與 DS-47 同一個坑：Tabler 的 min-height 會蓋過 height，padding 也自帶值，
     必須 height／min-height／padding／line-height 一起收才真的落在 46px。
   ⚠ −／＋ 是 flex item（min-width:auto），inline `width:44px` 壓不過內容寬（實測渲染 50px）
     → 要用 flex-basis ＋ min-width 一起鎖，尺寸也才進得了單一源。
   原生 number spinner 一併關掉：它是第三個改數字的方式，而且會偷走輸入框寬度。 */
.qty-stepper{ width: 220px; }
.qty-stepper > .btn{ flex: 0 0 40px; width: 40px; min-width: 40px; padding: 0;
  height: var(--awe-control-h-lg); min-height: var(--awe-control-h-lg);
  display: inline-flex; align-items: center; justify-content: center; }
.qty-stepper > .btn .icon{ width: 1.125rem; height: 1.125rem; }
.qty-stepper > .form-control{ height: var(--awe-control-h-lg); min-height: var(--awe-control-h-lg);
  padding: 0 .5rem; font-size: var(--awe-fs-display-sm); line-height: 1.25; font-weight: 600;
  font-variant-numeric: tabular-nums; appearance: textfield; -moz-appearance: textfield; }
.qty-stepper > .form-control::-webkit-outer-spin-button,
.qty-stepper > .form-control::-webkit-inner-spin-button{ -webkit-appearance: none; margin: 0; }
/* ===== /slice-6a ===== */


/* ══════════════════════════════════════════════════════════════════════════════
   ===== slice-6b ===== ｜UX2 切片 6b（adjust.php 盤點調整）
   ══════════════════════════════════════════════════════════════════════════════
   解 DS-61（帳面／差額 tile）／DS-62（盤差原因 chip）／DS-63（今日小計 0 值降權）／
   DS-64（步驟語彙去重）／DS-65（近期紀錄列）／DS-66（日期分隔）＋ adjust 既有橫向溢出。
   多數缺口靠既有正式 class 直接換形，本區塊只放「換形後才需要的那幾條」：
     · DS-62／DS-64／DS-66 完全走既有 `.chip`／`.step-head`+`.step-n`（切片 6a）／`.day-sep`+
       `.pg-n`+`.badge-today`，一行 CSS 都不必新增——這正是單一源該有的樣子。
     · DS-63 走 `.is-zero`（§10 既有）＋ markup 條件式，同樣無新宣告。 */

/* ── DS-61｜事實 tile 的狀態色與括號限定語 ──────────────────────────────────
   tile 本體＝ `.rc-fact`（切片 1 已抽的單一源，與 pending 入倉 modal 同一顆）。
   ⚠ `.rc-fact dd` 的 color 是 (0,1,1)，會壓過 `.neg`／`.is-zero` 的 (0,1,0)
     ——狀態色宣告不到 dd 上（`.text-success` 因為帶 !important 反而會贏，
     三種狀態就會一綠兩黑地不一致）。這裡把選擇器堆到 (0,2,1) 統一收齊。
   ⚠ 只換色不換字重：`.neg` 自帶 font-weight:700，但 `.rc-fact dd` 的 600 特異度較高
     會贏——三種狀態字重一致是刻意的，tile 靠顏色講語意就夠。 */
.rc-fact dd.neg{ color: var(--awe-danger); }
.rc-fact dd.is-zero{ color: var(--awe-ink-3); }
/* 「−1,234」與「（盤虧）」拆兩段：數字走 fact 字階（18px），括號限定語退到 caption。
   992px 下 col-4 的 tile 內寬只剩約 100px，同字階連寫必折行、tile 高度會隨打字跳動；
   拆開後數字那段 nowrap、限定語自己換行，版面才穩。限定語自帶 ink-2，
   不跟著 dd 的狀態色走（它講的是「這是什麼」不是「偏離多少」）。 */
.ad-fact-n{ white-space: nowrap; }
.ad-fact-sfx{ margin-left: .25rem; font-size: var(--awe-fs-caption);
  line-height: var(--awe-lh-caption); font-weight: var(--awe-fw-caption);
  color: var(--awe-ink-2); }

/* ── 既有橫向溢出（基準即有：chromium 992=+95／1200=+8、WebKit 1200=+13）────────
   根因不是表格太寬（表格太寬本來就該由 `.table-responsive` 的 overflow-x 吃掉），
   而是 `<th>` 裡的 `.visually-hidden`：Bootstrap 給它 `position:absolute`，而
   `.table-responsive` 是 `position:static` ⇒ 它的 containing block 不是那個捲動容器，
   overflow 剪不到它，於是它跟著表格的自然寬度跑到視窗外、把 document.scrollWidth 撐大。
   （同型缺陷會出現在任何「.table-responsive 內含絕對定位子孫」的地方。）
   ✅ 2026-08-13｜拍板 C：本頁的 `#ad-recent-wrap{position:relative}` 已**收斂為全站一條規則**
   （見檔尾 slice-7 區塊「拍板 C」），此處不再留局部 copy——同一個修法留兩份，
   下次改一份就會產生兩種行為。本頁的溢出仍歸零，由那條全站規則承擔。 */

/* ── DS-65｜近期紀錄列的欄寬紀律（＝溢出的第二手：表格不再超過容器）──────────
   問題：品名靠 PHP `mb_strimwidth(30)` 硬截、原因欄用 inline `style="max-width:220px"`，
   兩個都是把欄寬寫死在內容裡；再加上 `.small`(12px) 與主表 14px 兩種臨時字階混在同一格。
   解法同 DS-52（pending）：欄寬全部回到 CSS，內容只管內容。
   `table-layout:fixed` ＋ `width:100%`：這張表在右欄（<992px 才滿版），寬度是被壓縮的一方，
   固定版面才能讓「時間／差額／更正」三個定寬欄先拿走該拿的，剩下全給品名與原因；
   副作用是表格永遠不會超過容器＝溢出從源頭消失（與上面的 position:relative 互為雙保險）。
   ⚠ 選擇器收在 `#ad-recent-tbl`：這組寬度屬於這一張表，不是全站規則（同 DS-52 的作法）。 */
#ad-recent-tbl{ table-layout: fixed; width: 100%; min-width: 22rem; }
#ad-recent-tbl th:nth-child(1),#ad-recent-tbl td:nth-child(1){ width: 4rem; }
#ad-recent-tbl th:nth-child(3),#ad-recent-tbl td:nth-child(3){ width: 8.75rem; }
#ad-recent-tbl th:nth-child(4),#ad-recent-tbl td:nth-child(4){ width: 4.25rem; }
#ad-recent-tbl .cell-name,#ad-recent-tbl .cell-note,#ad-recent-tbl .cell-sub{ display: block; }
/* ── 992–1399px｜卡片最窄的那一段（`.col-lg-5` 只剩 289–430px）──────────────
   實測過三種做法，都有代價，最後取的是③＋④的組合：
     ① 純 `width:100%` ⇒ 品名欄被擠到 25px＝等於看不到品名（992px 實測）。
     ② 只靠 `.table-responsive` 橫捲（＝基準行為，基準在 992 捲 175px）⇒「差額」整欄
        被捲出視線，而那是這張清單最該一眼看到的數字。
     ③ 差額欄收回只放數字、把 `帳面 X → 實盤 Y` 那一行讓出來（全文本來就在第二欄的
        title 裡，零資訊損失）。
     ④ 表格留一條 22rem 下限：③ 之後 992px 仍只剩 73px 給品名，下限線把它拉回 140px，
        代價是這一段還會橫捲 63px（仍比基準的 175px 少 64%）；1200px 起就完全不捲了。
   ⚠ 差額欄的 5rem 是量出來的：`−99,999`（14px/700）＋ cell 內距 ＝ 78px，再窄就會把
     數字折成兩行（3.5rem 時實測 `−9,999` 折行）。7 位數以上的極端值仍會折行——那是
     刻意留的降級方式（折行不會蓋到隔壁欄，切字才會）。
   ⇒ 版面隨卡片寬單調變化：卡片寬（<992 滿版／≥1400）顯示明細行，卡片窄時收起。 */
@media (min-width: 992px) and (max-width: 1399.98px){
  #ad-recent-tbl th:nth-child(3),#ad-recent-tbl td:nth-child(3){ width: 5rem; }
  #ad-recent-tbl .cell-sub{ display: none; }
}
/* 兩行的字階走 demo 語彙：主體 `.cell-name`(14/500)、註記 `.cell-note`(12/ink-2)，
   全文留在 title。第三行「帳面 X → 實盤 Y」移到差額欄下方走 `.cell-sub`（等寬數字）
   ——數字跟數字讀在一起，第二欄只回答「是誰、為什麼」。 */
/* ⚠ 刻意**不**給 `.cell-sub` nowrap：欄寬是固定的（table-layout:fixed），nowrap ＋ 固定寬
   ＝ 極端值（如「帳面 10,049 → 實盤 10,049」約 163px）直接壓到隔壁欄上。讓它自然折行
   ——常見值仍是一行，只有極端值才長成兩行，換來的是「一位數字都不會被切掉」。 */
#ad-recent-tbl .cell-sub{ overflow-wrap: anywhere; }
/* 空狀態列不吃固定欄寬（它是 colspan=4 的引導列，不是資料列） */
#ad-recent-tbl tr.ad-empty > td{ width: auto; }
/* ===== /slice-6b ===== */


/* ══════════════════════════════════════════════════════════════════════════════
   ===== slice-7 ===== ｜UX2 切片 7（products.php ＋ categories.php）＋ 拍板 C
   ══════════════════════════════════════════════════════════════════════════════
   解 DS-36～41（products）／DS-82～84（categories）／DS-09 的 products 殘留
   ＋ N-j（DS-81）拍板案 A 的正式形 ＋ 拍板 C（H-1 全站化）。
   多數缺口一行 CSS 都不必新增（走既有正式 class 換形即可）：
     · DS-36／DS-39 走 `page_header()` 既有的 pretitle／btn-list slot（切片 2）。
     · DS-38 走 §13 `.row-actions`（與 pending／stock_in／adjust 同一顆形）。
     · DS-40 走 §10 `.cell-name` ＋ DS-29 的全站連結規則。
     · DS-41／DS-09／DS-37 是 markup 與條件式，無樣式。
     · DS-83 走既有 `.card-header`／`.card-title`（§6）。
   本區塊只放「換形後才需要的那幾條」。 */

/* ── 拍板 C（2026-08-13 papalu 准）｜H-1 全站化：捲動容器成為絕對定位子孫的 containing block
   ──────────────────────────────────────────────────────────────────────────────
   根因（切片 6b 在 adjust.php 查出、並在 stock_in.php 復現）：
   Bootstrap 給 `.visually-hidden` 的是 `position:absolute !important`，而 `.table-responsive`
   是 `position:static` ⇒ 捲動容器**不是**它的 containing block，`overflow-x` 剪不到它；
   於是那顆 sr-only 的 `<span>` 跟著表格的自然寬度跑到視窗外，把 `document.scrollWidth`
   撐大＝整頁多一條橫捲軸（表格自己明明已經在容器內橫捲了）。
   這不是某一頁的個案：任何「`.table-responsive` 內含絕對定位子孫」都會踩到，而全站
   6 個頁面的表頭都有 `<th><span class="visually-hidden">…</span></th>`（a11y 要留）。
   ⇒ 一條全站規則取代各頁的局部修（6b 的 `#ad-recent-wrap` 已同步移除）。

   ⚠ 副作用與界線（實測坐實，不是推論）：
     加了 `position:relative` 之後，容器內的絕對定位子孫會**改由容器剪裁**——列操作的
     ⋮ 下拉選單若走 Popper 預設的 `absolute` 策略就會被裁掉。站內三處有表內下拉
     （pending／products／design-demo-pending）**都已經**用 `popperConfig.strategy='fixed'`
     （fixed 的 containing block 是視窗，不受祖先 overflow 影響）⇒ 不受此規則影響。
     往後任何新增的表內下拉，一律沿用 fixed 策略；這條界線寫在這裡，不要再各自試。
   ⚠ 不改 `overflow`／不動 `z-index`：sticky 表頭（`.table-sticky`）與 sticky tfoot 皆不受影響
     （`position:sticky` 不吃 containing block 這條路徑）。 */
.table-responsive{ position: relative; }

/* ── DS-38 配套｜列操作的「純圖示鈕」（本片第一次出現，實測抓出兩個 Tabler 遺留）──
   §13 的 `.row-actions .btn .icon{ width:1rem; height:1rem }` 只覆寫了兩個屬性，但 Tabler 的
   `.btn .icon` 還帶另外兩個：
     ① `min-width: var(--tblr-btn-icon-size)` ⇒ width:1rem 被 min-width 頂住，
        沒掛 `btn-sm` 的鈕實測 **20×16 ＝ 圖被橫向拉扁**（pending 的 ⋮ 之所以正常，
        只是因為它剛好掛了 btn-sm 把那顆變數調小——形不該靠「有沒有記得加 btn-sm」撐著）。
     ② `margin: 0 calc(padding-x/2) 0 calc(padding-x/-4)` ⇒ 那是替「圖示＋文字」鈕留的字距，
        在**純圖示**鈕上就是把圖示推離水平中心。
   `:only-child` 是防呆：`入倉`／`更正` 那種圖示＋文字的鈕不受影響，仍吃 Tabler 的字距。 */
.row-actions .btn > .icon:only-child{ min-width: 1rem; margin: 0; }

/* ── N-j 轉正（DS-81／拍板案 A）｜inline-edit 列 ─────────────────────────────
   read 態＝一般表格列；點鉛筆後**該列就地**換成 38px 正常控件＋儲存／取消。
   `.is-editing` 掛在 `<tr>` 上，同一份 markup 只換態、不換結構（其餘列完全不受影響）。
   class 由提案期的 `np-` 前綴轉正（`np-cell-read/np-cell-edit/np-editing/np-edit-hint`
   → `cell-read/cell-edit/is-editing/edit-hint`），N-proposal 區塊的那一段已整段刪除。 */
.cell-edit{ display: none; align-items: center; gap: .5rem; }
.cell-edit .form-control{ height: var(--awe-control-h); min-height: var(--awe-control-h);
  max-width: 14rem; font-size: var(--awe-fs-body); border-radius: var(--awe-radius-control); }
/* 提案期漏掉的一階：edit 態的儲存／取消若吃 Tabler 預設高（36px）就與 38px 的輸入框
   差 2px——一列裡三個控件對不齊，正是 DS-17／DS-84 要收的那種「沒做完」訊號。
   §13 的 28px 是**列操作**那一階（唯讀列上的圖示鈕），edit 態這一列已經是表單，
   同一列的控件必須同高。（styleguide §9.7 的樣張同步拿掉 `btn-sm`。） */
.cell-edit .btn{ height: var(--awe-control-h); min-height: var(--awe-control-h);
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--awe-radius-control); }
.is-editing .cell-read{ display: none; }
.is-editing .cell-edit{ display: inline-flex; }
/* ⚠ 撞名實測（切片 5 §5 自檢清單第 4 條）：提案期寫的是 `.is-editing > td`(0,1,1)，
   但 §10 有一條 `.table tbody tr:hover > td{ background: var(--awe-surface-2) }`(0,2,3)
   ——滑鼠停在正在編輯的那一列時（＝編輯期間的常態）它一律贏，品牌淡底當場消失，
   「我正在改這一列」這個唯一的視覺訊號在最需要的時候不見。選擇器補到同級以上，
   並把 hover 態一起點名（編輯中的列不吃一般的 hover 回饋——它已經有自己的狀態色）。 */
.table tbody tr.is-editing > td,
.table tbody tr.is-editing:hover > td{ background: var(--awe-brand-soft); }
.edit-hint{ font-size: var(--awe-fs-caption); color: var(--awe-ink-3); white-space: nowrap; }

/* ── DS-84｜表單型的 toolbar（新增列）────────────────────────────────────────
   §9 的兩階規則（控件 38px／按鈕 28px）講的是**篩選列**：那一列的按鈕是附加條件的開關，
   與輸入框不是同一個動作。`categories` 的新增列不一樣——輸入框與「新增類別」是**同一個
   動作的兩半**（打字→送出），按鈕矮一階會讀成兩件事。此修飾子只做這一件事：
   把送出鈕拉回與輸入框同高。 */
.toolbar-form .btn{ height: var(--awe-control-h); min-height: var(--awe-control-h);
  font-size: var(--awe-fs-body); padding: 0 .875rem; }
/* ⚠ 實拍抓到（幾何量測看不到）：`.toolbar` 的契約是「輸入框都包在 `.filter-search`／
   `.filter-select` 裡」，那兩顆才帶 flex-basis。裸 `.form-control` 進來會吃 Bootstrap 的
   `width:100%` → 在 `flex-wrap:wrap` 的列裡整條佔滿，送出鈕被擠到第二行（實拍：
   「新類別名稱」一整條、「新增類別」掉到下一列）。表單型 toolbar 的輸入框給一個
   可縮的 basis，窄寬度仍會自己收，但不會再把同伴擠掉。 */
.toolbar-form .form-control{ width: auto; flex: 0 1 13.75rem; min-width: 6rem; }
/* card-footer 自己已經有內距，toolbar 的上下內距在這裡是多的一層 */
.card-footer > .toolbar-flush{ padding-top: 0; padding-bottom: 0; }

/* ── categories 欄寬｜欄寬回到 CSS，內容只管內容（同 DS-52／DS-65 的作法）──────
   原本第三欄寫死 `style="width:180px"`（給的是「更名」文字鈕的寬度）；改走 .row-actions
   之後只需要容納兩顆 28px 鈕。商品數欄給固定寬，讓類別名（唯一會變長的欄）吃剩下的。
   ⚠ 選擇器收在 `#cat-table`：這組寬度屬於這一張表，不是全站規則。 */
#cat-table th:nth-child(2),#cat-table td:nth-child(2){ width: 6rem; }
#cat-table th:nth-child(3),#cat-table td:nth-child(3){ width: 6.5rem; }
/* ===== /slice-7 ===== */


/* ══════════════════════════════════════════════════════════════════════════════
   ===== slice-8 ===== ｜UX2 切片 8（product_edit.php）＋ N-h／N-i 轉正
   ══════════════════════════════════════════════════════════════════════════════
   解 DS-75（庫存資訊卡）／DS-76（分頁語彙）／DS-77（異動紀錄工具列控件高）
   ＋ N-h（DS-73 TinyMCE）與 N-i（DS-74 圖片區）兩顆拍板案 A 的正式形。
   DS-79（返回鈕位置）走切片 2 已建的 `page_header()` `back` slot，**無樣式、無 markup 新增**。

   本區塊的兩條界線：
     ① 只放「換形後才需要的那幾條」——能走既有正式 class 的一律不新增宣告
        （分頁走 §11 `.seg-tabs`、控件高走 §9 `.toolbar`、徽章字階走 §12）。
     ② 第三方元件（TinyMCE）的覆寫收在本區塊一處，不散進頁面 inline style。 */

:root{
  /* 商品縮圖邊長（N-i 轉正，原 `--np-thumb`）。⚠ 位置屬 §1 的密度組，但切片 8 的硬紀律是
     「既有區塊禁動」，故先落在本區塊；下次 theme.css 重整時併回 §1（見切片 8 報告交棒）。 */
  --awe-thumb: 72px;
}


/* ── DS-75｜庫存資訊的倉別卡：3+2 收斂成 2×2＋合計自己一段 ────────────────────
   現況：`.wh-cards` 是 flex ＋ `.wh-card{flex:1}`，5 張進 col-lg-4 的窄欄自然折成 3+2，
   第二列兩張各拉到 163／165px＝比第一列的 107px 寬 55%。「同一組同權重的格子」被容器
   寬度決定成兩種寬度，讀起來像後兩張比較重要（實際上「預購倉」跟前三倉是同一階）。
   收斂：倉別卡走固定兩欄的 grid（每列都是等寬），合計自己一段——它本來就不是第 N+1 個倉，
   是那些倉的合計。
   ⚠ 修飾子而非改 §15：`.wh-cards` 在 stock_in／adjust／pending／demo／styleguide 是
     「可選取的倉別卡」（flex ＋ selectable），那裡沒有合計卡也不需要固定欄數。 */
.wh-grid{ display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.wh-grid > .wh-card{ flex: none; min-width: 0; }
/* 合計卡＝這一區的主角。強調走**字級**（同 §7 `.stat-primary`「靠字級與品牌色拉主從，
   不靠放大卡片」的既定作法），不再靠 inline `border-width:2px` ——那顆 hack 的顏色仍是
   中性 `--awe-line`，只是「變粗的灰框」，強調意圖沒有任何色彩或層級訊號（DS-75 原文）。
   底色退到 surface-2＝「這一格是合計不是倉別」，同時避開品牌紅配額（全站只給主 CTA 與 active）。
   FN3-1：合計從一張（舊「總庫存」）變兩張（可售／在手總量，定案 2）⇒ 不再整列橫跨，
   兩張各佔一欄併成一列；主從由 `.wh-sellable` 的字級講，不靠佔滿整列講。 */
.wh-sum{ background: var(--awe-surface-2); }
.wh-sum .stat-value{ display: block; margin-top: 0;
  font-size: var(--awe-fs-body); line-height: var(--awe-lh-body); }
.wh-sellable .stat-value{ font-size: var(--awe-fs-display-sm); line-height: var(--awe-lh-display-sm); }
/* ── FN3-1｜倉別數為**奇數**時的尾列孤兒 ────────────────────────────────────
   兩欄 grid ＋ 5 張倉別卡 ⇒ 第 5 張獨自佔第三列的左半，右半是一個空洞——
   讀起來像「還有一張卡沒載出來」。讓最後一張整列橫跨，那一列就變成一個完整的段。
   寫成**通則**（倉別卡是 <a>、合計卡是 <div>，故用 `:nth-of-type` 只數倉別卡）而不是
   「第 5 張特別處理」：第 6 倉出現時偶數自然回到 2×3，不必再回來改一次。 */
.wh-grid > a.wh-card:last-of-type:nth-of-type(odd){ grid-column: 1 / -1; }
/* 公關倉＝「在倉裡但不算可售」的那一格 ⇒ 走琥珀（--awe-warn，站內既有的 partial 語意色）。
   卡上直接掛「不入可售」小旗，因為只寫在頁面說明裡的話，讀數字的人不會回頭去讀說明。 */
.wh-pr{ background: var(--awe-warn-soft); border-color: var(--awe-warn-line); }
.pr-flag{ display: inline-block; margin-left: .25rem; padding: 0 .25rem; border-radius: var(--awe-radius-sm);
  font-size: var(--awe-fs-micro); line-height: calc(var(--awe-lh-micro) + 2px); font-weight: var(--awe-fw-badge);
  color: var(--awe-warn); background: var(--awe-warn-soft); border: 1px solid var(--awe-warn-line);
  vertical-align: middle; letter-spacing: 0; }
.wh-pr .pr-flag{ background: transparent; }
/* 倉別卡是連結（點進該倉的異動紀錄），合計卡不是 → 拍板③「可點的要有 hover 態、
   不可點純靜態」在 wh-card 家族的落地。用 `[href]` 挑出來，markup 不必多掛 class。 */
.wh-card[href]:hover{ border-color: var(--awe-brand-line); }
.wh-card[href]:focus-visible{ outline: none; border-color: var(--awe-brand);
  box-shadow: 0 0 0 3px var(--awe-brand-soft); }


/* ── DS-76／DS-77｜分頁與分組都走 §11 segmented（拍板②：nav-tabs／btn-group 退場）──
   `.seg-tabs`／`.seg-tab` 本體在 §11，本區塊只補兩件「用在 <button> 與窄欄」才需要的事。 */
/* ① seg-tab 用在 <button>（異動類型分組是 client 端篩選，不是連結）：把 UA 的按鈕外觀歸零。
      §11 的宣告是為 <a> 寫的，沒有處理 background／border／font 繼承。 */
button.seg-tab{ background: transparent; border: 0; font-family: inherit; cursor: pointer; }
/* ② 篩選列裡的 segmented 必須可換行。理由與切片 3 fix-r1 對 `.btn-group` 的根治逐字相同：
      inline-flex 的 min-content 寬＝所有分頁相加，放在 col-lg-4（992px 下內寬僅 221px）
      不會縮、只會把 document.scrollWidth 一路撐出去。允許換行後寬度永遠 ≤ 容器，
      且不必藏任何一顆分頁（優於水平捲動的隱藏內容）。 */
.toolbar .seg-tabs{ flex-wrap: wrap; row-gap: 2px; }
/* 已載入筆數／「更早」那一列：`.toolbar.toolbar-flush` ⇒ 「更早」自動吃 §9 的 28px 緊湊階
   （現況 `btn-sm` 實測 20px，不屬於任何一階），count-pill 也回到同一條中線。
   本行只收 card 內嵌時多出來的上緣線；高度規則沿用 §9，不另立第二份。 */
.toolbar-flush + .form-hint{ margin-top: .25rem; }


/* ── N-h 轉正（DS-73／拍板 h-1 案 A）｜TinyMCE ＝一顆大號 form-control ──────────
   ⚠ **為什麼需要拉高特異度**：TinyMCE 6 的 skin CSS 是**執行期**才被 append 進 <head> 的，
     位置永遠在 `theme.css` 之後 ⇒ 同特異度必輸（實測 `.tox .tox-editor-header` 這種
     (0,2,0) 的規則寫在 theme.css 完全不生效）。故本組一律以 `.tox.tox-tinymce` 開頭
     （(0,2,0) 起跳）並在確實被 skin 蓋掉的宣告上補 `!important`——與 §13 為了贏過
     Bootstrap 工具類的 `.text-end` 而用 `!important` 是同一類理由，逐條都有實測依據。
   ⚠ 內容區（iframe）不吃外層的 CSS 變數（是另一份 document）⇒ 字型／字階由
     `erp.js` 的 `aweEditorInit()` 在 init 當下讀 token 值產生 `content_style`，
     **不在任何地方硬寫第二份數值**。 */
.tox.tox-tinymce{ border: 1px solid var(--awe-line) !important;
  border-radius: var(--awe-radius-control) !important; }
/* focus 態與所有 .form-control 同一個語彙（品牌色框＋brand-soft 光暈）。
   TinyMCE 自己的 focus 訊號是 `.tox-edit-area::before` 的 2px 藍框（#2d6adf，站內無此色）
   ——那是第二套 focus 語彙，關掉。 */
.tox.tox-tinymce:focus-within{ border-color: var(--awe-brand) !important;
  box-shadow: 0 0 0 3px var(--awe-brand-soft); }
.tox.tox-tinymce .tox-edit-area::before{ display: none !important; }
/* toolbar ＝ 它的表頭：surface-2 底 ＋ 1px --awe-line 下緣。
   現況是白底 ＋ 一道 rgba(34,47,62,…) 的深色投影（＝盤點說的「站內唯一一條深色分隔線」，
   實際是 box-shadow 不是 border，故 border-bottom 量到 0px）。 */
.tox.tox-tinymce .tox-editor-header{ background: var(--awe-surface-2) !important;
  border-bottom: 1px solid var(--awe-line) !important; box-shadow: none !important;
  padding: 0 !important; }
.tox.tox-tinymce .tox-toolbar,
.tox.tox-tinymce .tox-toolbar__primary,
.tox.tox-tinymce .tox-toolbar-overlord{ background: transparent !important; }
/* 工具鈕高度本來就是 28px（＝--awe-control-h-sm，巧合但正確），只收上下外距：
   預設 `margin:6px 1px 5px 0` 把 toolbar 撐到 47px。 */
.tox.tox-tinymce .tox-tbtn{ height: var(--awe-control-h-sm); margin: .25rem .0625rem;
  border-radius: var(--awe-radius-sm); color: var(--awe-ink-2); }
.tox.tox-tinymce .tox-tbtn svg{ fill: var(--awe-ink-2); }
.tox.tox-tinymce .tox-tbtn:hover{ background: var(--awe-surface); }
.tox.tox-tinymce .tox-tbtn:hover svg{ fill: var(--awe-ink-1); }
.tox.tox-tinymce .tox-tbtn:focus-visible{ box-shadow: 0 0 0 2px var(--awe-brand-line); }
.tox.tox-tinymce .tox-tbtn--enabled,
.tox.tox-tinymce .tox-tbtn--enabled:hover{ background: var(--awe-brand-soft); }
.tox.tox-tinymce .tox-tbtn--enabled svg{ fill: var(--awe-brand); }
/* statusbar：拍板 h-1 案 A ＝砍掉 element path（「p」對零售人員沒有意義）、留 resize 手把
   （長文商品介紹能拉高是實用能力）。整條退到 surface-2，與 toolbar 收成同一對表頭／表尾。 */
.tox.tox-tinymce .tox-statusbar{ background: var(--awe-surface-2) !important;
  border-top: 1px solid var(--awe-line) !important;
  min-height: 0; height: auto; padding: .125rem .375rem; }
.tox.tox-tinymce .tox-statusbar__path{ display: none !important; }
.tox.tox-tinymce .tox-statusbar__resize-handle{ color: var(--awe-ink-3); }


/* ── N-i 轉正（DS-74／拍板 i-1 案 A）｜圖片上傳／排序／主圖標記區 ────────────────
   三件事（提案原文）：①「加圖」變成 strip 的最後一格（72×72），空態與有料態同一個版位
   語彙、觸擊區從 20px 變成 72px；②「主圖」改成淡底品牌色徽章＋第一格下緣 2px 品牌條，
   位置本身就是規則、不必用飽和紅來喊；③拖曳落點用一條 2px 直立指示條，不是整排縮圖跳位。 */
.img-strip{ display: flex; flex-wrap: wrap; gap: .5rem; align-items: flex-start; }
.img-thumb{ position: relative; width: var(--awe-thumb); height: var(--awe-thumb); flex: none;
  border: 1px solid var(--awe-line); border-radius: var(--awe-radius-sm);
  background: var(--awe-surface-2); overflow: hidden; cursor: grab; user-select: none; }
.img-thumb img{ width: 100%; height: 100%; object-fit: cover; display: block; }
.img-thumb-ph{ width: 100%; height: 100%; display: flex; align-items: center; justify-content: center;
  color: var(--awe-ink-3); }
.img-thumb-ph .icon{ width: 1.25rem; height: 1.25rem; }
.img-thumb.is-main{ border-color: var(--awe-brand-line); }
.img-thumb.is-main::after{ content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--awe-brand); }
/* 主圖徽章走 §12 的 badge 字階（11/16）＋淡底細框，與 `.badge-day` 同一種「品牌色但不飽和」 */
.img-main{ position: absolute; left: 2px; bottom: 4px; z-index: 1;
  display: inline-flex; align-items: center; gap: .125rem;
  font-size: var(--awe-fs-badge); line-height: var(--awe-lh-badge); font-weight: 600;
  padding: 0 .375rem; border-radius: var(--awe-radius-pill);
  color: var(--awe-brand); background: var(--awe-surface); border: 1px solid var(--awe-brand-line); }
.img-main .icon{ width: .75rem; height: .75rem; }
/* 拖曳把手：純提示（整格都可拖），平時淡出、hover／鍵盤聚焦才實，與刪除鈕同一組節奏 */
.img-grip{ position: absolute; top: 2px; left: 2px; z-index: 1; color: var(--awe-ink-2);
  opacity: 0; pointer-events: none; transition: opacity .12s ease; }
.img-grip .icon{ width: .875rem; height: .875rem;
  background: var(--awe-surface); border-radius: var(--awe-radius-pill); }
/* 刪除鈕：觸擊區補到 28px（現況 18px，低於本站 WCAG 取值），平時淡、hover／focus 才實 */
.img-del{ position: absolute; top: 0; right: 0;
  width: var(--awe-control-h-sm); height: var(--awe-control-h-sm); padding: 0; border: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--awe-ink-1); cursor: pointer; opacity: 0;
  transition: opacity .12s ease; }
.img-del .icon{ width: .875rem; height: .875rem;
  background: var(--awe-surface); border: 1px solid var(--awe-line);
  border-radius: var(--awe-radius-pill); box-shadow: var(--awe-shadow-1); }
.img-thumb:hover .img-grip,
.img-thumb:hover .img-del,
.img-del:focus-visible{ opacity: 1; }
.img-del:hover .icon{ color: var(--awe-danger); border-color: var(--awe-danger-line); }
.img-thumb.is-dragging{ opacity: .4; }
/* 落點指示條：拖曳時插在兩張縮圖之間（不是把整排縮圖先搬過去） */
.img-drop-mark{ width: 2px; height: var(--awe-thumb); flex: none;
  border-radius: var(--awe-radius-pill); background: var(--awe-brand); }
/* 加圖格＝strip 尾端的 72px 虛線方格。⚠ **自足一顆、刻意不掛 `.file-drop`**：
   2026-08-14 切片 10 裁定不收成同一組——這邊是「選檔即上傳、可多張、沒有已選檔態」，
   `.file-drop`（N-f）那邊是「選檔先站著、單張、按 CTA 才送出」，共用的只有拖曳守衛一件事，
   硬收成一顆會讓兩邊都長出一堆 if。（本註記由切片 10 更新——原文是 N-f 尚未轉正時的措辭。） */
.img-add{ width: var(--awe-thumb); height: var(--awe-thumb); flex: none;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .125rem;
  border: 1px dashed var(--awe-line); border-radius: var(--awe-radius-sm);
  background: var(--awe-surface-2); color: var(--awe-ink-2); cursor: pointer; text-align: center;
  transition: border-color .14s ease, background-color .14s ease, color .14s ease; }
.img-add > .icon{ width: 1.25rem; height: 1.25rem; color: var(--awe-ink-3); }
.img-add-label{ font-size: var(--awe-fs-badge); line-height: var(--awe-lh-badge); }
.img-add:hover{ border-color: var(--awe-brand); background: var(--awe-brand-soft);
  color: var(--awe-brand); }
.img-add:hover > .icon{ color: var(--awe-brand); }
.img-add:focus-visible{ outline: none; border-color: var(--awe-brand);
  box-shadow: 0 0 0 3px var(--awe-brand-soft); }
/* 上傳／刪除的即時回饋（`#img-msg`）：兩種語意各自吃既有色 token，不自帶字級。 */
.img-msg{ display: none; align-items: center; gap: .25rem;
  font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption); }
.img-msg.is-on{ display: inline-flex; }
.img-msg .icon{ width: .875rem; height: .875rem; flex: none; }
.img-msg.is-ok{ color: var(--awe-ok); }
.img-msg.is-error{ color: var(--awe-danger); }
/* 「上傳中…」是過程不是結果 ⇒ 中性色。用綠色講進行中，成功時就沒有第二個訊號可用了。 */
.img-msg.is-busy{ color: var(--awe-ink-2); }
/* ===== /slice-8 ===== */


/* ══════════════════════════════════════════════════════════════════════════════
   ===== slice-9 ===== ｜UX2 切片 9（login.php ＋ password.php）
   ══════════════════════════════════════════════════════════════════════════════
   解 DS-85（password 標題重複）／DS-87（CTA 滿寬紅鈕）／DS-88（無退出路徑）
   ＋ DS-90（login lockup inline 硬寫、兩處 copy）／DS-91（login 卡內無標題）
   ＋ N-k（DS-86）拍板案 A 的正式形。

   本區塊的兩條界線：
     ① 能走既有正式 class 的一律不新增宣告——卡片走 §6 `.card`、標題走 §6 `.card-title`、
        分區標籤走 §6 `.section-label`、說明走 §6 `.section-hint`、按鈕走 §2／Tabler
        `.btn-primary`／`.btn-ghost-secondary`。真正新增的只有「窄表單版型」與
        「品牌 lockup 的大號變體」兩件事。
     ② lockup 的 markup 單一源在 `_layout.php::brand_lockup()`（PHP helper），本檔只放
        「大號變體與側欄的差異」那兩條；side／login 兩處的字級來源仍是同一顆 token。 */

:root{
  /* 單一任務窄表單最大寬（N-k 轉正，原 `--np-narrow-w`）。 */
  --awe-narrow-w:      32.5rem;  /* 520px */
  /* 未登入頁 lockup 的 logo 高（原本是 login.php 的 inline `style="height:3.6rem"`）。 */
  --awe-brand-logo-lg: 3.6rem;   /* 57.6px；側欄版仍走 §3 的 .navbar-brand-image 2.4rem */
  /* ⚠ 兩顆的位置本屬 §1（1.6 密度／1.7 尺寸），但本片硬紀律是「既有區塊禁動」，故先落在
     本區塊；下次 theme.css 重整時併回 §1（同切片 8 的 `--awe-thumb`，見交棒待辦）。 */
}


/* ── N-k 轉正｜單一任務窄表單版型（DS-86 拍板案 A：左對齊 ＋ 固定最大寬）────────
   置中是「未登入／單一任務全螢幕」的語彙（`login.php` 保留）；已登入內頁左邊有側欄、
   上面有 page-header，內容再置中就會出現兩條對不齊的軸——眼睛會一直在兩個中線之間找基準。
   實測（1440，動工前）：password 的表單卡 x=650.67／w=378.66，與 page-header 標題的
   左緣 x=256 差 **394.67px** ＝ 每次進頁都要重新找一次基準。
   版型本身是**可複用件**：未來任何「單一任務窄表單」內頁都掛 `.narrow-form`。 */
.narrow-form{ max-width: var(--awe-narrow-w); }
/* 控件回到全站 38px 一階（現況 36px＝Tabler 預設，比篩選列／modal 都矮一階）。 */
.narrow-form .form-control{ height: var(--awe-control-h); min-height: var(--awe-control-h);
  font-size: var(--awe-fs-body); border-radius: var(--awe-radius-control); }
/* 表單標籤回到 label 階（13/600/ink-2）；現況吃 Tabler 的 14px/500 ＝ 與內文同權重。 */
.narrow-form .form-label{ font-size: var(--awe-fs-label); line-height: var(--awe-lh-label);
  font-weight: var(--awe-fw-label); color: var(--awe-ink-2); margin-bottom: .25rem; }
/* DS-87／DS-88｜動作列：主 CTA 不吃滿寬（滿寬是登入頁的形），並排一條退出路徑。
   細線把「填欄位」與「送出／離開」分成兩段，動作區才不是浮在最後一個欄位下面。 */
.narrow-form-actions{ display: flex; align-items: center; gap: .5rem;
  padding-top: .25rem; border-top: 1px solid var(--awe-line); margin-top: .25rem; }


/* ── DS-90｜品牌 lockup 的大號變體（未登入頁）──────────────────────────────
   markup 單一源在 `_layout.php::brand_lockup()`；側欄版與 login 版**逐字相同**，
   差別只有這一個 modifier class。原本 login.php 用 inline
   `style="font-size:1.425rem;line-height:1.25;color:var(--tblr-body-color)"` 硬寫
   （實測 22.8px/28.5px），與側欄的 `--awe-fs-section` 15px 是兩個不在字階表上的值；
   這裡改吃 title 階（20/28）＝ 未登入頁沒有 page-title，lockup 本身就是那一頁的標題。 */
.brand-lockup-lg .navbar-brand-image{ height: var(--awe-brand-logo-lg); }
.brand-lockup-lg .sb-brand-text{ font-size: var(--awe-fs-title);
  line-height: var(--awe-lh-title); }
/* ===== /slice-9 ===== */


/* ══════════════════════════════════════════════════════════════════════════════
   ===== slice-10 ===== ｜UX2 切片 10（import.php）＋ N-e／N-f／N-g 轉正
   ══════════════════════════════════════════════════════════════════════════════
   解 DS-69（批次表未入卡、死 class `table-dark`）／DS-72（凍結狀態訊號自相矛盾）
   ＋ N-e（DS-67）／N-f（DS-68）／N-g（DS-71）三顆拍板案 A 的正式形。

   本區塊的三條界線：
     ① 能走既有正式 class 的一律不新增宣告——卡片走 §6 `.card`／`.card-header`／
        `.card-title`，表格走 §10 `.table.card-table`，摘要 tile 走 §14 `.rc-facts`／
        `.rc-fact`（入倉 modal 那一顆，本片只是把它用在第二個場景），說明走 §6
        `.section-hint`，空狀態走 slice-5 `.zero-hint.empty-inline`。
        真正新增的只有「狀態帶」「規則說明摺疊」「檔案放置區」三件事。
     ② 三顆都是**可複用件**，命名刻意不綁 import：任何「這頁被限制／唯讀」走
        `.state-note`、任何「參考資料不必每次讀」走 `.help-fold`、任何檔案上傳走
        `.file-drop`（行為單一源在 erp.js `fileDrop()`）。
     ③ 放置區的**行為**（外部拖檔必 preventDefault，否則瀏覽器把檔案當導航目標整頁離開）
        寫在 erp.js，不在這裡；CSS 只負責三個態的外觀。 */

:root{
  /* 檔案放置區高度（N-f 轉正，原 `--np-drop-h`）。空態與已選檔態**同高**是刻意的：
     選完檔版面不跳動，下方的 CTA 才不會在按下去前一刻換位置。 */
  --awe-drop-h: 7.5rem;   /* 120px */
  /* ⚠ 位置本屬 §1（1.7 尺寸），但本片硬紀律是「既有區塊禁動」，故先落在本區塊；
     下次 theme.css 重整時與 slice-8 `--awe-thumb`／slice-9 `--awe-narrow-w` 一起併回 §1。 */
}


/* ── N-e 轉正｜狀態帶（DS-67 拍板案 A：拆成狀態帶＋規則說明，語意色走中性）────────
   現況是 warning(48px) ＋ info(70px) 兩條滿版 alert 疊在頁頂：兩條同權重、同滿版、
   不同色相，讀者無從判斷哪一條真的要讀，而「凍結」這件必讀的事被一整段欄位對應規則稀釋。
   拆成兩種東西，因為它們本來就是兩種東西：
     ① `.state-note` ＝「這頁現在是什麼狀態」：必讀、**一行**、常駐，右端掛 `.badge-frozen`；
     ② `.help-fold` ＝ 參考資料，不是每次進頁都要重讀 → 預設收合，收合時只佔一行。
   語意色走**中性**（surface-2＋ink），不走琥珀：凍結是刻意的設定狀態不是異常，
   每次進頁都被橘色喊一次，真正的警示色會被鈍化（拍板 e-2）。
   與既有語彙的關係：`.state-note` 是 §11 `.scope-note`（品牌淡底細帶）的中性表親——
   同樣是「一條細帶講一件範圍／狀態的事」，`.scope-note` 講「你在看哪一段資料」，
   `.state-note` 講「這頁被限制了」。不新增第四個色相（現況的 info 藍就是那個第四色相）。 */
.state-note{ display: flex; align-items: flex-start; gap: .5rem;
  padding: .5rem var(--awe-card-pad);
  border: 1px solid var(--awe-line); border-radius: var(--awe-radius-card);
  background: var(--awe-surface-2); color: var(--awe-ink-1);
  font-size: var(--awe-fs-body); line-height: var(--awe-lh-body); }
.state-note > .icon{ width: 1.125rem; height: 1.125rem; flex: none; margin-top: .125rem;
  color: var(--awe-ink-3); }
/* 主句與補充句排成**同一行**（放不下才換行）——狀態帶的價值就在「一行講完」。
   窄寬度自然折行，不會擠爆。 */
.state-note-txt{ display: flex; flex-wrap: wrap; align-items: baseline;
  gap: .125rem .5rem; min-width: 0; }
.state-note-title{ font-weight: 600; }

/* 規則說明摺疊：收合時只佔一行；summary 吃 label 階（13/600/ink-2）＝
   它是一個「可以打開的標籤」，不是第二條 alert。 */
.help-fold{ border: 1px solid var(--awe-line); border-radius: var(--awe-radius-card);
  background: var(--awe-surface); }
.help-fold > summary{ display: flex; align-items: center; gap: .375rem; cursor: pointer;
  padding: .5rem var(--awe-card-pad); list-style: none;
  font-size: var(--awe-fs-label); line-height: var(--awe-lh-label);
  font-weight: var(--awe-fw-label); color: var(--awe-ink-2); }
/* WebKit 的 <summary> 預設帶一顆 disclosure triangle，且它不是 ::marker 而是自有偽元素
   ⇒ 只寫 list-style:none 在 Safari 仍會多出一個三角形（與我們自己的 chevron 撞成兩個）。 */
.help-fold > summary::-webkit-details-marker{ display: none; }
.help-fold > summary:hover{ color: var(--awe-ink-1); }
.help-fold > summary:focus-visible{ outline: none; color: var(--awe-ink-1);
  box-shadow: inset 0 0 0 2px var(--awe-brand-soft); border-radius: var(--awe-radius-card); }
.help-fold > summary .icon{ width: 1rem; height: 1rem; color: var(--awe-ink-3);
  transition: transform .14s ease; }
.help-fold[open] > summary .icon{ transform: rotate(180deg); }
.help-fold[open] > summary{ border-bottom: 1px solid var(--awe-line); }
.help-fold-body{ padding: .625rem var(--awe-card-pad);
  font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption); color: var(--awe-ink-2); }
.help-fold-body b{ color: var(--awe-ink-1); font-weight: 600; }


/* ── N-f 轉正｜檔案放置區（DS-68 拍板案 A：可拖放的全尺寸放置區）─────────────
   現況是原生 `<input type=file>`：「選擇檔案／未選擇任何檔案」是 OS 控件外觀，
   每個 OS／瀏覽器長不一樣、完全不吃 token，那句灰字也不在字階內。
   正式形是一塊 token 化的放置區，三個態：空態（虛線框）→ 拖入中（`.is-over` 品牌色框
   ＋淡底）→ 已選檔（`.is-picked` 實線框、檔案圖示、檔名／大小、更換／移除）。
   結構紀律：真正的 `<input type=file>` **留在 DOM 內**（絕對定位、透明、鋪滿整塊），
   不是 display:none 的隱藏欄位——三個理由：
     ① 點整塊 = 點到 input ⇒ 開檔案選擇器不需要任何 JS；
     ② input 仍可聚焦 ⇒ Tab／Space 原生可用，`required` 的驗證泡泡也才有東西可以指
        （對 display:none 的欄位送出，Chrome 會丟 "not focusable" 並**靜默不送出**）；
     ③ 已選檔那一態的動作鈕靠 `.file-actions` 的 z-index 疊在 input 之上，
        點動作鈕不會誤觸開檔。 */
.file-drop{ position: relative; display: flex;
  min-height: var(--awe-drop-h); padding: 1rem var(--awe-card-pad);
  border: 1px dashed var(--awe-line); border-radius: var(--awe-radius-card);
  background: var(--awe-surface-2); color: var(--awe-ink-2);
  transition: border-color .14s ease, background-color .14s ease; }
.file-drop-input{ position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; cursor: pointer; }
/* 兩個態各自一個 wrapper，靠 class 切換顯示——JS 只改 `.is-picked` 與兩行文字，
   **不重建 markup**：重建會連同裡面那顆 input 一起換掉，剛選好的檔案就沒了。 */
.file-drop-empty{ flex: 1; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: .25rem; text-align: center; }
.file-drop-empty > .icon{ width: 1.5rem; height: 1.5rem; color: var(--awe-ink-3); }
.file-drop-title{ font-size: var(--awe-fs-body); line-height: var(--awe-lh-body);
  font-weight: 600; color: var(--awe-ink-1); }
.file-drop-title em{ font-style: normal; color: var(--awe-brand); }
.file-drop-hint{ font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption);
  color: var(--awe-ink-3); }
/* hover 只在空態給（已選檔是安定狀態，不必每次滑過就閃一次品牌色） */
.file-drop:not(.is-picked):hover,
.file-drop.is-over{ border-color: var(--awe-brand); background: var(--awe-brand-soft); }
.file-drop.is-over .file-drop-empty > .icon{ color: var(--awe-brand); }
/* 焦點環掛在**外框**上（可聚焦的是裡面那顆透明 input，焦點環畫在它身上看不見）。
   用 `:has(:focus-visible)` 而非 `:focus-within`：後者連滑鼠點擊都會留下焦點環，
   點完檔案選擇器回來那一圈會一直亮著。 */
.file-drop:has(.file-drop-input:focus-visible){ border-color: var(--awe-brand);
  box-shadow: 0 0 0 3px var(--awe-brand-soft); }
/* 已選檔：實線框＋左圖示＋檔名／大小／動作，仍是**同一個高度格**（不跳版） */
.file-drop-picked{ display: none; flex: 1; align-items: center; gap: .75rem; text-align: left; }
.file-drop.is-picked{ border-style: solid; border-color: var(--awe-line);
  background: var(--awe-surface); }
.file-drop.is-picked .file-drop-empty{ display: none; }
.file-drop.is-picked .file-drop-picked{ display: flex; }
.file-ico{ width: 2.5rem; height: 2.5rem; flex: none; border-radius: var(--awe-radius-control);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--awe-brand-soft); color: var(--awe-brand); }
.file-ico .icon{ width: 1.25rem; height: 1.25rem; }
.file-meta{ min-width: 0; flex: 1; }
.file-name{ font-size: var(--awe-fs-body); line-height: var(--awe-lh-body); font-weight: 600;
  color: var(--awe-ink-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-size{ font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption);
  color: var(--awe-ink-3); font-variant-numeric: tabular-nums; }
/* 動作鈕疊在透明 input 之上（同為定位元素，靠 z-index 決定命中誰）。
   `.row-actions` 是既有的 28px 動作群（§12），這裡只補堆疊順序。 */
.file-drop .file-actions{ position: relative; z-index: 1; }


/* ── N-g 轉正｜匯入結果（DS-71 拍板案 A：摘要三 tile ＋ 無框線 card-table）──────
   現況兩件事：①摘要塞在一整段 alert 句子裡（「資料 40 列、成功 37…」要用讀的才知道
   有沒有出事）；②錯誤明細是 `table-sm table-bordered bg-white` ＝ 全站**唯一**一處
   全框線表格，而且沒有包在卡片裡，裸貼在畫布上。
   正式形：摘要走既有 `.rc-facts`（＝入倉 modal 那三顆 tile——「動作**後**要對的數字」
   與「動作**前**要對的數字」是同一件事，不該長成兩種樣子；本片**不新增元件**，
   只是把既有元件用在第二個場景），明細走一般 `.card-table`，框線靠列底線就夠。
   本區塊只補兩件 tile 沒有的事：語意色，與兩個欄位紀律。 */
/* tile 語意色：跟隨 §14 既有的 `.rc-fact.rc-remain dd` 寫法（modifier 掛在 tile 上、
   只換 dd 的色），數字本身的字階與字重不動。異常＝0 時**不上色**（沒有異常就沒有
   要指的東西，全站紅色仍然稀缺）。 */
.rc-fact.rc-ok dd{ color: var(--awe-ok); }
.rc-fact.rc-danger dd{ color: var(--awe-danger); }
/* 列號欄：窄且靠右等寬——這個數字唯一的用途是拿去對 xlsx 的行號。
   （等寬由 §10 的 `.table .text-end` 一併給，這裡只定寬。） */
.err-line{ width: 5.5rem; }
/* 原始值：等寬字。錯的常常是「看不見的東西」（前後空白、全形數字），
   比例字型會把它們藏起來。 */
.err-raw{ font-family: var(--awe-font-mono); font-size: var(--awe-fs-badge);
  color: var(--awe-ink-2); }
/* ===== /slice-10 ===== */


/* ══════════════════════════════════════════════════════════════════════════════
   ===== slice-H =====  UX2 H 清單收官輪（交棒待辦一次結清）
   ══════════════════════════════════════════════════════════════════════════════
   本區塊只裝「H 清單裡真的需要新宣告」的兩件事（H-16 的兩個態）。其餘 H 項全部靠
   **既有 class 的正確使用**解掉，一行 CSS 都不必新增——那才是切片 1~10 把單一源立起來
   的目的：H-7（categories 商品數 0）吃 §10 既有 `.is-zero`；H-9（emptyRow 引導列形）吃
   切片 5 既有 `.zero-hint.empty-inline`；H-11（balances 品名）吃 §10 既有 `.cell-name`；
   H-8 是刪一個從來沒有宣告的死 class；R-1 是把 `.bg-primary-lt` 換成站內既有的中性
   類別徽章形。新增宣告愈少，代表尺立得愈準。 */

/* ── H-16｜加圖格的「拖入中」態 ──────────────────────────────────────────────
   問題：拖著檔案經過圖片區時，`.img-add` 只有 `:hover` 會亮——而**拖曳中的游標不觸發
   hover**，整段拖曳沒有任何「放這裡」的即時訊號。
   解法：沿用 N-f `.file-drop.is-over` 已立的**同一個態名與同一組視覺**（品牌色框＋
   brand-soft 底＋圖示轉品牌色），不為第二個放置場景發明第二種拖入態。
   ⚠ 值與 `.img-add:hover` 刻意逐字相同：兩者講的是同一句話（「放這裡」），
   只是觸發途徑不同（滑鼠停留 vs 拖曳經過）；既有 `:hover` 那條屬 slice-8 區塊、不動它。 */
.img-add.is-over{ border-color: var(--awe-brand); background: var(--awe-brand-soft);
  color: var(--awe-brand); }
.img-add.is-over > .icon{ color: var(--awe-brand); }

/* ── H-16｜圖片區訊息的中性語意 ──────────────────────────────────────────────
   混合拖放（圖片＋非圖片一起拖進來）原本以 `.is-error` 紅字收尾，把一次「部分成功」
   報成失敗。補第四種語意：中性通知——與 `.is-busy` 同色（ink-2），但那是「進行中」、
   這是「做完了，附帶一句要知道的事」，兩者語意不同故不合併成同一顆。 */
.img-msg.is-info{ color: var(--awe-ink-2); }
/* ===== /slice-H ===== */


/* ══════════════════════════════════════════════════════════════════════════════
   ===== fn2-slice1 =====  入倉 modal 多倉一次分配（FN2 功能片・切片 1）
   ══════════════════════════════════════════════════════════════════════════════
   本區塊只裝兩顆真的沒有的東西：①卡內數量欄 `.wh-qty` ②「已分配／未分配」即時列
   `.alloc-line`。其餘全部吃既有單一源，一行都不重寫：
     · 有分配數量的倉卡＝§15 既有 `.wh-card.on`（品牌框＋brand-soft 底），
       不為「已填數量」另立 `.has-qty` 第二種亮法（mockup 用的是 has-qty，值與 `.on` 逐字相同）
     · 「入後 N」小字＝§15 既有 `.wh-card .after`，開關走 Bootstrap `.d-none`
     · 超額紅字＝§14 既有 `.rc-warn`（只換文案，不換形）
     · 三格事實區＝§14 既有 `.rc-facts`／`.rc-fact.rc-remain`（照舊，本片沒動） */

/* ── 卡內分配數量欄 ────────────────────────────────────────────────────────────
   控件本體（邊框／圓角／高度／focus 態）吃 `.form-control` ＋ §14 `.modal .form-control`；
   這裡只補「卡內數字欄」自己的四件事：置中、fact 級字階、等寬數字、去掉 spinner。
   ⚠ 選擇器必須是 `.form-control.wh-qty`（0,2,0）：§14 的 `.modal .form-control` 也是
   (0,2,0) 且把 font-size 釘在 body 級，單寫 `.wh-qty`（0,1,0）會被它壓過去、字階量不出 18px。
   本區塊在檔尾 ⇒ 同特異度由順序決勝，18px 生效。 */
.form-control.wh-qty{ margin-top: .375rem; padding-left: .25rem; padding-right: .25rem;
  text-align: center; font-size: var(--awe-fs-fact); line-height: var(--awe-lh-fact);
  font-weight: 600; font-variant-numeric: tabular-nums;
  -moz-appearance: textfield; appearance: textfield; }
/* 上下微調鈕：卡片只有 ~110px 寬，spinner 會把三位數字擠掉（原生上下鍵語意不受影響） */
.wh-qty::-webkit-outer-spin-button,
.wh-qty::-webkit-inner-spin-button{ -webkit-appearance: none; margin: 0; }
/* placeholder 的「0」是「這個倉沒分配」的靜默狀態 ⇒ 退 ink-3 ＋不加粗，別讀成已填 0 */
.wh-qty::placeholder{ color: var(--awe-ink-3); font-weight: 400; }

/* ── 已分配／未分配 即時列 ─────────────────────────────────────────────────────
   位置在標籤與倉卡之間＝「輸入時眼睛不用離開這一段」。三種狀態各有語意色：
   未滿（ink-1 預設）／剛好滿額（`.is-full`＝ok 綠，講「配完了」）／超額（`.is-over`＝
   danger 紅，講「這樣不能送」，與同時出現的 `.rc-warn` 同一個色家族）。 */
.alloc-line{ display: flex; gap: .75rem; align-items: baseline; margin: 0 0 .5rem;
  font-size: var(--awe-fs-label); line-height: var(--awe-lh-label);
  font-weight: var(--awe-fw-label); font-variant-numeric: tabular-nums; }
.alloc-line .un{ color: var(--awe-ink-2); }
.alloc-line.is-full .sum{ color: var(--awe-ok); }
.alloc-line.is-over .sum{ color: var(--awe-danger); }
/* ===== /fn2-slice1 ===== */


/* ══════════════════════════════════════════════════════════════════════════════
   ===== fn3-slice1 ===== ｜FN3-1（公關倉開倉＋看板兩個數字＋五倉版面）
   ══════════════════════════════════════════════════════════════════════════════
   定案 2：「總庫存」一詞退場，看板末尾改「可售」＋「在手總量」。
   本區塊只放**這一片才需要**的三件事：
     ① 兩支色欄（公關倉琥珀＝不入可售／可售綠＝這張表的答案欄）
     ② 品名欄的寬度下限（欄數 8 → 10 之後的擠壓，F6 兩硬點之一）
     ③ 統計帶上公關倉分段的同一顆語意色
   `.wh-grid` 尾列孤兒與合計卡（F6 的另一硬點）收在上面的 slice-8 區塊，
   與它要修飾的原始宣告放在一起——**不為了「本片的東西放一起」而讓同一個元件的
   規則散成兩處**（那正是 §15 與 slice-8 各有一份 .wh-card 時踩過的形）。 */

/* ── ① 兩支色欄 ──────────────────────────────────────────────────────────────
   ⚠ 底色一律以 `background-image`（單色漸層）疊在既有 `background-color` 之上，
     **不能寫 `background: <半透明色>`**：表頭是 sticky（`.table-sticky thead th`）、
     表尾也是 sticky，一旦底色變半透明，捲動時下方的資料列會直接透出來。
     疊圖層則保留了原本那層不透明的 surface／surface-2，整格仍然是實心的。
   ⚠ hover 那一條必須另外寫：`.table tbody tr:hover > td{ background: … }` 是
     **shorthand**，會把 background-image 一併重設為 none ⇒ 滑過該列時色欄會閃掉。
     特異度上 (0,3,3) > (0,2,3)，故把同一張圖層再宣告一次即可，不動 hover 的底色。 */
.table th.col-pr, .table td.col-pr,
.table tbody tr:hover > td.col-pr{
  background-image: linear-gradient(var(--awe-warn-soft), var(--awe-warn-soft)); }
.table th.col-sell, .table td.col-sell,
.table tbody tr:hover > td.col-sell{
  background-image: linear-gradient(var(--awe-ok-soft), var(--awe-ok-soft)); }
/* 表頭的欄名再上一層語意色。只染 `.th-main`（倉名／口徑名），不染 `（件）` 小字——
   單位不是這一欄的身分。 */
.table thead th.col-pr .th-main{ color: var(--awe-warn); }
.table thead th.col-sell .th-main{ color: var(--awe-ok); }

/* ── ② 品名欄寬度下限（F6：多一個數字欄的擠壓）──────────────────────────────
   欄數 8 → 10（第 5 倉＋兩個口徑）之後，`table-layout:auto` 會先壓縮最有彈性的
   那一欄——正好是品名。品名是這張表唯一用來認人的欄，被擠成三行時掃讀成本最高。
   給它一個地板，剩下的塞不下就讓 `.table-responsive` 橫向捲：**寧可捲，不要擠**
   （同 §10 對數量欄 `white-space:nowrap` 的既有判斷，只是換到品名這一側）。
   ⚠ 只鎖品名是不夠的（`dev/fn3-1-layout-harness.html` 首版實測）：擠壓不會消失，
     它只是**搬家**——品名有了地板之後，下一個最有彈性的「類別」被壓成一字一行
     （「類／別」「娃／娃」直排）。類別欄裝的是一顆徽章，本來就不該斷行，
     因此連它一起收掉；兩欄都不讓步，剩下的差額才會真的交給橫向捲。 */
.table th.col-name, .table td.col-name{ min-width: 11rem; }
.table th.col-cat, .table td.col-cat{ white-space: nowrap; }

/* ── ③ 統計帶的公關倉分段 ────────────────────────────────────────────────────
   與表格色欄同一顆語意色，讓「哪一段的量不算可售」在兩個地方講同一句話。
   分段不是 sticky，故可以直接吃半透明底（同 §7 `.stat-danger` 的既有形）。 */
.seg-pr{ background: var(--awe-warn-soft); }
.seg-pr .stat-label{ color: var(--awe-warn); }
/* ===== /fn3-slice1 ===== */

/* ═══════════════════════════════════════════════════════════════════════════
   ===== fn3-slice2 =====  調撥 primitive（FN3 功能片・切片 2）
   ───────────────────────────────────────────────────────────────────────────
   本區塊只裝一顆真的沒有的東西：**倉卡的「來源倉」態**。其餘一行都不重寫，
   全部吃既有單一源（規則 15 兩層紀律）：
     · 三格事實區（來源倉剩餘／已分配／未分配）＝ §14 既有 `.rc-facts`／`.rc-fact.rc-remain`
     · 「已分配／未分配」即時列＝ fn2-slice1 既有 `.alloc-line`（含 `.is-full`／`.is-over`）
     · 卡內數量欄＝ fn2-slice1 既有 `.form-control.wh-qty`
     · 有分配數量的卡＝ §15 既有 `.wh-card.on`
     · 超額紅字＝ §14 既有 `.rc-warn`（只換文案，不換形）
     · 三步驟卡頭＝ 切片 6a 既有 `.step-head` ＋ `.step-n`
   ⇒ 調撥畫面與入倉畫面長得一樣，不是因為有人照抄了一遍，而是因為它們吃同一份宣告。

   ── 為什麼「來源倉」需要自己的態 ──────────────────────────────────────────
   來源倉那張卡在目標分配區裡是**在場但不可用**：它必須看得到（要知道現有多少、
   要知道自己選的是哪一個），但不能填數字（自己撥給自己無意義）。
   既有三個態都講不了這件事——`.on`＝作用中、預設＝可填、`disabled` 只在 input 上。
   刻意**不用降低整張卡透明度**的做法：那會連「現有 N（件）」一起變淡，
   而那個數字正是使用者這一刻最需要讀的（上限就是它）。
   改為：底色退到 surface-2（＝「這一格不是輸入區」）、框線維持既有 line 不加重，
   再用一行 ink-3 小字明講原因。 */
.wh-card.is-src{ background: var(--awe-surface-2); border-style: dashed; }
.wh-card.is-src .whk{ color: var(--awe-ink-3); }
/* 來源註記：與 `.wh-card small`（badge 級距）同族，只換顏色——它是說明不是數字 */
.wh-card .srcnote{ color: var(--awe-ink-3); }
/* 來源倉卡不進 hover／focus 的可點視覺：它在這一組裡本來就不可選 */
.wh-card.is-src.selectable:hover{ border-color: var(--awe-line); }
/* ===== /fn3-slice2 ===== */

/* ═══════════════════════════════════════════════════════════════════════════
   ===== am1fix =====  帳號管理 UX 修復片（AM-1-fix／AWE-T26）
   ───────────────────────────────────────────────────────────────────────────
   本區塊只裝三件既有語彙講不出來的東西，其餘全部吃單一源（規則 15 兩層紀律）：
     · 面板外框＝既有 `.alert.alert-warning` ＋ `.card`／`.card-body`／`.section-label`
       （逐條沿用 twofa.php 復原碼一次性顯示的視覺語言，不另開第二套）
     · 帳號名＝§10 既有 `.cell-code`；modal 外框／表單控件＝§14 既有 `.modal *`
     · 動作鈕＝既有 `.btn.btn-outline-*`（危險色分工照舊）
   新增的三件：①要交給別人的密碼那一行；②modal 內的動作分段；③剛動過的那一列。

   ── ① 一次性臨時密碼 ──────────────────────────────────────────────────────
   它與復原碼有一個關鍵差別：復原碼是**自己抄下來收好**（8 組、badge 級距、兩欄排），
   臨時密碼是**當場唸給／交給另一個人**——所以它要大到隔著螢幕也讀得出來，
   且大小寫必須一眼分得清（`I`／`l`、`0`／`O` 已在產碼字母表排除，字體再補一層）。
   ⇒ 走字階表最大的 display 階 ＋ 等寬字（不是新尺寸，是既有 token）。 */
.cred-secret{ font-family: var(--awe-font-mono);
  font-size: var(--awe-fs-display); line-height: var(--awe-lh-display);
  font-weight: var(--awe-fw-display); color: var(--awe-ink-1);
  letter-spacing: .04em; word-break: break-all;
  background: var(--awe-surface-2); border: 1px solid var(--awe-line);
  border-radius: var(--awe-radius-control); padding: .25rem .625rem; }
/* 密碼與複製鈕同一行，窄幅（375px）自然折成兩行——鈕不縮、密碼不被擠到溢出 */
.cred-secret-row{ display: flex; flex-wrap: wrap; align-items: center; gap: .75rem; }
/* 帳號／有效期限：兩則事實並排，窄幅折行。dt 走標籤階、dd 走內文階 */
.cred-facts{ display: flex; flex-wrap: wrap; gap: .25rem 2rem; margin: 0; }
.cred-facts > div{ display: flex; align-items: baseline; gap: .5rem; }
.cred-facts dt{ font-size: var(--awe-fs-label); line-height: var(--awe-lh-label);
  font-weight: var(--awe-fw-label); color: var(--awe-ink-2); }
.cred-facts dd{ font-size: var(--awe-fs-body); line-height: var(--awe-lh-body);
  color: var(--awe-ink-1); margin: 0; }
/* 複製回饋：只換色，不換尺寸——鈕在原地變形會讓旁邊的密碼跟著跳 */
.btn.is-copied{ border-color: var(--awe-ok-line); color: var(--awe-ok);
  background: var(--awe-ok-soft); }
.btn.is-copy-failed{ border-color: var(--awe-danger-line); color: var(--awe-danger);
  background: var(--awe-danger-soft); }
/* execCommand 退路用的暫存 textarea：要在視窗內（否則 iOS 不選取）但不可見、不佔位、不搶捲動 */
.awe-copy-sink{ position: fixed; top: 0; left: 0; width: 1px; height: 1px;
  padding: 0; border: 0; opacity: 0; pointer-events: none; }

/* ── ② modal 內的動作分段 ─────────────────────────────────────────────────
   一座 modal 裡有三～四個**各自獨立的表單**，讀者要一眼分得出「這一顆鈕管的是
   哪一件事」。用細線分段而不是卡中卡：modal 本身已是一層卡，再套一層會讓
   內距疊到兩倍、窄幅更擠。段首吃既有 `.section-label`，說明走 caption 階。 */
.acct-act + .acct-act{ border-top: 1px solid var(--awe-line);
  margin-top: 1rem; padding-top: 1rem; }
.acct-act-note{ font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption);
  color: var(--awe-ink-2); margin: 0 0 .625rem; }
/* 下拉與鈕同一行，窄幅折行後下拉仍撐滿（不會縮成一小截） */
.acct-act-row{ display: flex; flex-wrap: wrap; gap: .5rem; }
.acct-act-row .form-select{ flex: 1 1 12rem; min-width: 0; }
/* 群組說明清單：不是選項本身，是選項的註腳 ⇒ 最小的字、最淡的色、不用項目符號 */
.acct-group-legend{ list-style: none; margin: .625rem 0 0; padding: 0;
  font-size: var(--awe-fs-badge); line-height: var(--awe-lh-badge);
  color: var(--awe-ink-3); }
.acct-group-legend li + li{ margin-top: .25rem; }
.acct-group-legend b{ color: var(--awe-ink-2); font-weight: var(--awe-fw-label); }

/* ── ③ 剛動過的那一列 ─────────────────────────────────────────────────────
   302 之後瀏覽器靠 `#acct-<id>` 錨點捲到位，但錨點只負責「捲到」，
   不負責「是這一列」。淡品牌底＋左緣一道品牌線＝掃一眼就對得上，
   而且它是既有的品牌淡底語彙（`--awe-brand-soft`／`--awe-brand`），不是新顏色。
   刻意不做閃爍動畫：這一列上面有停用／解鎖這類要看清楚的狀態，動的東西會搶走它。 */
.table tr.row-focus > td{ background: var(--awe-brand-soft); }
.table tr.row-focus > td:first-child{ box-shadow: inset 3px 0 0 0 var(--awe-brand); }
/* ===== /am1fix ===== */

/* ═══════════════════════════════════════════════════════════════════════════
   ===== t31 =====  憑證面板落進管理 modal（AWE-T31／papalu 2026-08-28 拍板 ③）
   ───────────────────────────────────────────────────────────────────────────
   本區塊**零新元件**：面板 markup 與頁面上方那一份逐字相同（`cred_panel()` 單一源），
   這裡只處理「同一份面板換一個容器」帶來的兩件排版事，其餘全部吃既有 token。

   ── 卡中卡 ────────────────────────────────────────────────────────────────
   am1fix 區塊 ② 已經寫過這條理由：**modal 本身已是一層卡**，再套一層卡會讓內距疊到
   兩倍、窄幅（375px）更擠。所以面板進 modal 之後把外框那一層收掉——留底色與圓角
   （它仍要與上面的說明文分得開），拿掉陰影與外框、內距降一階。
   刻意**不改 markup**：換 class 就等於兩個落點各有一份長相，改一邊忘另一邊。

   ⚠ 面板外緣的 `mb-3` **刻意不在這裡覆寫**：Tabler 的間距 utility 帶 `!important`，
   寫了也不會生效（首版寫過 `margin-bottom: 0`，實測被 `.mb-3` 蓋掉＝一行死碼）。
   量測結果：面板下緣 16px ＋ 下一段 `.acct-act` 的 16px，兩段之間 32px 有細線分隔，
   在 375px 讀起來是對的 ⇒ 不需要為了它去動共用 markup。 */
.modal-body .cred-panel{ box-shadow: none; border: 0; background: var(--awe-surface-2); }
.modal-body .cred-panel > .card-body{ padding: 1rem; }
/* 密碼那一行在 modal 內是「卡中卡的卡中卡」⇒ 它自己的底改用最上層的 surface，
   否則同色疊同色，大字反而糊在背景裡（色仍全部走 token，不是新顏色） */
.modal-body .cred-panel .cred-secret{ background: var(--awe-surface); }

/* ── r2 ②｜動作鈕一律靠右（papalu 2026-08-28 眼驗回饋）────────────────────────
   mockup 的動作鈕都在右邊。「變更群組」那顆本來就在右（它在 `.acct-act-row` 這個
   flex 裡、下拉 `flex:1` 把它推過去），其餘四顆（重設密碼／停用·復用／解除 2FA／
   移除信任裝置）是表單的直接子元素 ⇒ 靠左。**對齊既有的那一顆**，不是新規則。

   做法刻意**不碰按鈕自己的 display／width**：改讓表單成為 flex 欄、由鈕 `align-self`
   跳到右緣。理由是 WebKit 對表單元件的 intrinsic sizing 自成一族（`display:block`
   ＋`margin-left:auto` 在某些版本會讓鈕撐滿），而 papalu 主力是 Safari。
   `align-items` 維持預設 `stretch` ⇒ 段首、說明文、下拉列、面板寬度**逐一如舊**。 */
.modal-body .acct-act{ display: flex; flex-direction: column; }
.modal-body .acct-act > .btn{ align-self: flex-end; }

/* ── r2 ③｜鈕與底下的憑證面板要分得開（同上回饋）──────────────────────────
   面板緊貼在「重設密碼」那顆鈕下面，讀起來像同一塊。補一個區塊間距——
   吃既有的 `--awe-gap`（§1 的區塊間距 token），不另立數字。
   選擇器刻意收在 `.acct-act >` 之內：modal 裡還有一則「這是你自己的帳號」`.alert`，
   它是 `.modal-body` 的直接子元素、不在動作表單內 ⇒ 不受影響。 */
.modal-body .acct-act > .alert{ margin-top: var(--awe-gap); }
/* ===== /t31 ===== */

/* ═══════════════════════════════════════════════════════════════════════════
   ===== t37-1 =====  權限群組表收合式（AWE-T37-1／papalu 2026-08-30 拍板）
   ───────────────────────────────────────────────────────────────────────────
   本區塊只裝**一件**既有語彙講不出來的東西：「一整列都是展開開關」的那顆鈕。
   其餘全部吃單一源（規則 15 兩層紀律）：
     · 展開／收合的行為＝Tabler core 打包的 Bootstrap `.collapse`（零新 JS、零新依賴）
     · 列上的字＝§6 既有 `.section-label` ＋ Tabler `.text-secondary`／`.badge`
     · 勾選表與儲存鈕＝既有 `.table`／`.btn.btn-primary`（本片把它換回全站的實心主鈕）

   ── 為什麼是 `<button>` 而不是在 `<div>` 上掛 click ────────────────────────
   它是一個開關，鍵盤要按得動、螢幕報讀器要念得出「已展開／已收合」。原生 button
   ＋ `aria-expanded`（Bootstrap 自己會翻）把這兩件事一次拿到，不必補任何 JS。
   代價是要把 button 的預設外觀整顆卸掉——下面這條規則做的就是這件事。
   ⚠ `type="button"` 在 markup 那一側（它在 `<form>` 裡，預設 submit 會變成誤送）。 */
.acct-gk + .acct-gk{ margin-top: .5rem; }
.acct-gk-head{ display: flex; align-items: flex-start; gap: .5rem;
  width: 100%; text-align: left; padding: .5rem .625rem; cursor: pointer;
  border: 1px solid var(--awe-line); border-radius: var(--awe-radius-control);
  background: var(--awe-surface-2); color: var(--awe-ink-1); }
.acct-gk-head:hover{ border-color: var(--awe-brand-line); }
/* 焦點環沿 §7 `.seg-tab`／`.filter-clear` 的同一種寫法（不另立第二套焦點樣式） */
.acct-gk-head:focus-visible{ outline: none; box-shadow: 0 0 0 2px var(--awe-brand-line); }
/* 摘要是兩層：上一行是「名字・人數・鍵數・系統群組」，下一行才是那一組的說明。
   兩者字階不同（標籤階 vs 註記階）⇒ 直排，不是把說明擠進同一行。 */
.acct-gk-sum{ display: flex; flex-direction: column; gap: .125rem; min-width: 0; flex: 1 1 auto; }
.acct-gk-note{ font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption);
  color: var(--awe-ink-3); }
/* 箭頭：收著時朝下（「下面還有東西」），展開時翻上來（「按這裡收起來」）。
   `aria-expanded` 由 Bootstrap 維護 ⇒ 樣式跟著**真正的狀態**走，不是跟著第二個 class。
   `flex: 0 0 auto` 讓它在窄幅不被長群組名壓扁。 */
.acct-gk-caret{ flex: 0 0 auto; margin-top: .0625rem; transition: transform .15s ease; }
.acct-gk-head[aria-expanded="true"] .acct-gk-caret{ transform: rotate(180deg); }
/* 展開之後：表格與上面那一列要分得開，儲存鈕與表格也要。兩處都吃 §1 的間距語彙。 */
.acct-gk .table-responsive{ margin-top: .5rem; }
.acct-gk .collapse .btn{ margin-bottom: .25rem; }
/* ===== /t37-1 ===== */

/* ===== t39｜歷史檔期折疊箭頭會轉（AU-AWE-001 F-01；沿 t37-1 caret 語彙，aria-expanded＝Bootstrap collapse 自維護）===== */
.cmp-hist-caret{ transition: transform .15s ease; }
[data-bs-target="#campaign-history"][aria-expanded="true"] .cmp-hist-caret{ transform: rotate(180deg); }
/* ===== /t39 ===== */

/* ===== T49｜商品圖裁切面板（410 v1.11 切片 T49；整座面板由 `erp.js` 的 aweImageCropper() 建）=====
   為什麼樣式在這裡而不是跟著 JS 走：規則 15 的兩層紀律——顏色／圓角／字階一律吃 token，
   改一個值全站跟著改。面板本身是「暫時蓋在畫面上的一張卡」，所以它的形沿 `.card` 的語彙
   （surface ＋ radius-card ＋ shadow-2），不另立第二套視覺。
   ⚠ 不用 Bootstrap 的 `.modal`：那一套要 JS 實例、要 backdrop 元素、還會鎖 body 的捲動；
     這裡只需要「蓋住、置中、按 Esc 收掉」三件事，一層 fixed ＋ grid 就到位。 */
.awe-crop{ position: fixed; inset: 0; z-index: 1080;
  display: grid; place-items: center; padding: 1rem;
  background: rgba(24, 36, 51, .55); }
.awe-crop-box{ width: min(30rem, 100%); max-height: 100%; overflow: auto;
  display: flex; flex-direction: column; gap: .75rem; padding: 1rem;
  background: var(--awe-surface); border-radius: var(--awe-radius-card);
  box-shadow: var(--awe-shadow-2); }
.awe-crop-head{ display: flex; align-items: baseline; gap: .5rem; }
.awe-crop-title{ font-size: var(--awe-fs-section); line-height: var(--awe-lh-section);
  font-weight: var(--awe-fw-section); color: var(--awe-ink-1); }
.awe-crop-count{ font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption);
  color: var(--awe-ink-2); }
/* 取景舞台：正方形（aspect-ratio）＝畫面上看到的框就是輸出的框，不必另外畫遮罩。
   `touch-action: none` 是拖曳與雙指縮放的前提——沒有它，手機上會變成捲頁面。 */
.awe-crop-stage{ position: relative; width: 100%; aspect-ratio: 1 / 1;
  border: 1px solid var(--awe-line); border-radius: var(--awe-radius-control);
  overflow: hidden; background: var(--awe-surface-2);
  touch-action: none; cursor: grab; }
.awe-crop-stage:active{ cursor: grabbing; }
.awe-crop-canvas{ display: block; width: 100%; height: 100%; }
.awe-crop-tools{ display: flex; align-items: center; gap: .75rem; }
.awe-crop-zoom{ flex: 1 1 auto; }
.awe-crop-foot{ display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  flex-wrap: wrap; }
.awe-crop-actions{ display: flex; gap: .5rem; margin-left: auto; }
.awe-crop-size{ font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption);
  color: var(--awe-ink-2); }
/* 壓不進伺服器上限時照實說（`--awe-danger` 是破壞性／擋下語意的專用色，與品牌紅分工） */
.awe-crop-size.is-over{ color: var(--awe-danger); font-weight: var(--awe-fw-label); }
.awe-crop-hint{ margin: 0; font-size: var(--awe-fs-caption); line-height: var(--awe-lh-caption);
  color: var(--awe-ink-3); }
/* 面板開著時鎖住背景捲動（手機上尤其明顯：拖曳到邊緣會連背景一起滑） */
body.awe-crop-open{ overflow: hidden; }
/* ===== /T49 ===== */
