/* ── R42 webfont：Noto Sans TC 自託管子集 ────────────────────────────
   依 repo 實際用字（static 三檔＋i18n，1377 字）以 pyftsubset 切的
   woff2，離線可用、零 CDN；四檔合計約 720KB。font-display: swap 讓
   無 CJK 系統字型的環境先畫 fallback、字型到齊再換。 */
@font-face {
  font-family: "Noto Sans TC";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/NotoSansTC-400.woff2") format("woff2");
}
@font-face {
  font-family: "Noto Sans TC";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("fonts/NotoSansTC-500.woff2") format("woff2");
}
@font-face {
  font-family: "Noto Sans TC";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("fonts/NotoSansTC-600.woff2") format("woff2");
}
@font-face {
  font-family: "Noto Sans TC";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("fonts/NotoSansTC-700.woff2") format("woff2");
}

/* ── Design tokens（R28 tokenize pass）──────────────────────────────
   全站顏色／間距／字級的唯一來源（single source of truth）。所有值都是從
   token 化前的既有樣式「原值抽出」——純重構、渲染零變化。改主題改這裡，
   不要在規則裡散改 hex。對照文件：docs/design/tokens.md。
   app.js 的報表圖表色盤以 COLORS（frozen）鏡射這裡的 --chart-*／--line-warm
   （Chart.js 不吃 CSS 變數）——兩處請同步改。 */
:root {
  /* ── bark／espresso（#258 側欄深咖啡系）── */
  --sidebar-bg: #40302a;                       /* 側欄／手機頂欄底色 */
  --sidebar-text: #ead9c8;                     /* 側欄主要文字 */
  --sidebar-muted: rgba(234, 217, 200, 0.55);  /* 側欄次要文字／群組標籤 */
  --sidebar-line: rgba(255, 255, 255, 0.12);   /* 側欄髮絲線（品牌底線、群組分隔） */
  --sidebar-hover: rgba(255, 255, 255, 0.08);  /* 側欄項目 hover 水洗 */
  --white: #ffffff;                            /* 共用純白（側欄強調字、幽靈鈕底、列印底） */

  /* ── crust／accent（麵殼棕主色系）── */
  --accent: #8b5e3c;            /* 主按鈕、標題、強調色 */
  --accent-light: #d4a373;      /* hover、次按鈕底、表頭框線 */
  --chart-primary: #a57e52;     /* 報表 FPY 線／生產柱（app.js 鏡射） */
  --chart-secondary: #664832;   /* 報表毛利線（app.js 鏡射） */
  --chart-text: #4a3f35;        /* 圖表文字（app.js 鏡射） */

  /* ── rust（破壞性列內按鈕：刪除／取消）── */
  --btn-danger: #a05d4d;          /* 列內刪除／取消／移除鈕底（白字 5.04:1 ≥AA，R61） */
  --btn-danger-hover: #96513f;    /* 取消鈕 hover */

  /* ── cream／surface（暖米白表面階梯）── */
  --bg: #f8f5f2;             /* 頁面底（暖米白） */
  --card: #ffffff;           /* 白卡 */
  --surface-sunk: #f0ede9;   /* 凹陷面：pre、手機卡式列、編輯列、trace 空狀態 */
  --surface-hover: #faf8f6;  /* 表列 hover 水洗、追溯卡底 */

  /* ── ink（文字階梯）── */
  --text: #333333;        /* 內文 */
  --text-muted: #666;     /* 次要文字：hint、瓷磚小標、code */
  --text-soft: #8a7563;   /* 暖灰褐：卡片分組小標、空狀態文字 */

  /* ── lines（框線，暖 → 淡）── */
  --line: #e7ddd1;        /* 主框線（卡片 h3 底線、空狀態虛線框） */
  --line-warm: #e0d6c8;   /* 追溯卡框線 ＋ 圖表網格線（app.js 鏡射） */
  --line-dash: #ddd2c4;   /* 手機卡式列的虛線分隔 */
  --line-input: #ddd;     /* 表單輸入框（input/select/textarea） */
  --line-soft: #eee;      /* 資料表列橫線 */

  /* ── semantic（狀態語義色：-text 字 ／ -bg 底）── */
  --success-text: #1e7e34;  --success-bg: #e6f4ea;  /* status-open／in_progress */
  --warning-text: #856404;  --warning-bg: #fff3cd;  /* status-partial／released */
  --danger-text: #721c24;   --danger-bg: #f8d7da;    /* status-closed／cancelled、警示磚、錯誤 */
  --info-text: #2a5885;     --info-bg: #e3ecf7;     /* status-completed */
  --warning-soft: #fff6e6;        /* 儀表板低庫存列底 */
  --warning-soft-hover: #ffefd4;  /* 低庫存列 hover */
  --draft-text: #5a4a3a;    --draft-bg: #eee9e4;    /* status-draft（中性 draft 標籤） */

  /* ── neutral buttons（無彩度按鈕）── */
  --btn-disabled: #cbbfb4;        /* 停用鈕底 */
  --btn-neutral: #8d8d8d;         /* 編輯列「取消」底 */
  --btn-neutral-hover: #6f6f6f;   /* 「取消」hover */

  /* ── elevation／scrim／print ── */
  --shadow-color: rgba(0, 0, 0, 0.06);   /* 卡片陰影色 */
  --shadow-card: 0 1px 4px rgba(0, 0, 0, 0.06);
  --shadow-drawer: 0 0 40px rgba(0, 0, 0, 0.35);  /* 手機抽屜開啟陰影 */
  --scrim: rgba(0, 0, 0, 0.4);                     /* 抽屜遮罩 */
  --print-ink: #000;                               /* 列印文字 */

  /* ── radius ── */
  --radius-sm: 6px;     /* 按鈕、輸入框、pre */
  --radius-md: 8px;     /* 瓷磚、卡式列、圖表盒、追溯卡 */
  --radius-card: 12px;  /* 白卡 */

  /* ── type scale（rem；出現次數標註）── */
  --fs-xs: 0.8rem;    /* 微標籤：狀態標籤、hint、列內小鈕 */
  --fs-sm: 0.85rem;   /* 次要列／小鈕 */
  --fs-md: 0.9rem;    /* 資料表、次要 UI（最常用） */
  --fs-lg: 0.95rem;   /* 側欄項目、表單選項列 */
  --fs-base: 1rem;    /* 表單控件、按鈕 */
  --fs-xl: 1.05rem;   /* 列印區塊小標、圖示 */

  /* ── spacing scale（rem）── */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --gap-nav: 0.6rem;  /* 側欄／頂欄列內 gap（不在線性刻度上） */
}

body {
  font-family: "Noto Sans TC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  margin: 0;
}

/* ── #258 側邊欄頁面：app shell ──────────────────────────────────
   桌機（>1200px）：左側常駐側欄（群組標籤 + 項目全展開，無下拉）。
   641–1200px：收合為圖示欄。≤640px：側欄變滑入抽屜（#263）＋頂欄漢堡。
   版型：grid 兩欄 — 側欄欄位背景全高（.sidebar-inner 只負責 sticky 與
   短視窗捲動），長頁面不會露出側欄底下的內容區底色。 */
.app-shell {
  display: grid;
  grid-template-columns: 236px minmax(0, 1fr);
  min-height: 100vh;
}

#sidebar {
  position: relative;
  z-index: 60;
  background: var(--sidebar-bg);
  color: var(--sidebar-text);
}

.sidebar-inner {
  position: sticky;
  top: 0;
  max-height: 100vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: var(--gap-nav);
  padding: 1rem 1rem 0.85rem;
  border-bottom: 1px solid var(--sidebar-line);
}

.brand-mark {
  font-size: 1.35rem;
  line-height: 1;
}

.sidebar-brand h1 {
  margin: 0;
  font-size: 1.15rem;
  color: var(--white);
}

.sidebar-brand p {
  margin: 0;
  font-size: 0.72rem;
  color: var(--sidebar-muted);
}

/* 導覽：分頁切換契約仍是 #tabs button[data-tab] ↔ section[id].active；
   這裡只換殼 — 群組以小標籤呈現、項目永遠展開（沒有 hover 下拉）。 */
#tabs {
  display: block;
  padding: 0.5rem 0.6rem 1.25rem;
}

.nav-group-label {
  margin: 0.9rem 0.75rem 0.3rem;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  color: var(--sidebar-muted);
}

.nav-menu {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.nav-menu button {
  display: flex;
  align-items: center;
  gap: var(--gap-nav);
  width: 100%;
  box-sizing: border-box;
  text-align: left;
  background: transparent;
  color: var(--sidebar-text);
  border: none;
  border-radius: var(--radius-md);
  padding: 0.55rem 0.75rem;
  font-size: var(--fs-lg);
  cursor: pointer;
}

.nav-menu button:hover {
  background: var(--sidebar-hover);
  color: var(--white);
}

.nav-menu button.active {
  background: var(--accent);
  color: var(--white);
}

.nav-icon {
  flex: 0 0 auto;
  font-size: var(--fs-xl);
  line-height: 1;
}

.nav-group.active > .nav-group-label {
  color: var(--white);
}

/* 遮罩：只在 ≤640px 抽屜開啟時出現（樣式在該媒體查詢內） */
.sidebar-scrim {
  display: none;
}

.app-main {
  min-width: 0;
  grid-column: 2;
  padding: 1.1rem 1.4rem 3rem;
}

/* 頂欄：≤640px 才出現（漢堡 + 品牌 + 目前分頁） */
.topbar {
  display: none;
}

main {
  display: grid;
  gap: var(--space-5);
  max-width: 1160px;
  margin: 0 auto;
}

.tab {
  display: none;
}

.tab.active {
  display: block;
}

/* 子項 min-width:auto 會被寬表／canvas 撐開、整頁橫移 — 全寬度歸零，
   寬表由各容器 overflow-x 內部捲動（行動裝置媒體查詢裡逐容器列出）。 */
main section {
  min-width: 0;
}

/* ── #274 數據表格 / #284 表單布局：工具列 + 卡片階層 ─────────────
   section 不再自帶白底（內容區已是米白），白卡片下放到實質區塊：
   工具列（標題＋主操作靠右）、表單卡、列表卡、面板卡。 */
.tab-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
}

.tab-toolbar h2 {
  margin: 0;
  font-size: 1.25rem;
  color: var(--accent);
}

.list-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}

/* #284 表單布局：h3 變 fieldset 風格的分組小標（表單卡與列表卡共用） */
.list-toolbar h3 {
  margin: 0;
  font-size: var(--fs-lg);
  color: var(--accent);
}

/* R28 列表搜尋：list-toolbar 右側的「搜尋 + 重新整理」群組（七個主要列表
   共用）。輸入框寬度收斂，手機由 max-width 保證與按鈕同行塞得下。 */
.list-tools {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.list-search {
  width: 10rem;
  max-width: 42vw;
  padding: 0.4rem 0.6rem;
  font-size: var(--fs-md);
}

.form-card,
.list-card {
  background: var(--card);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 1.1rem 1.25rem;
}

.form-card {
  display: grid;
  gap: var(--space-3);
  align-self: start;
}

.form-card h3 {
  margin: 0.25rem 0 0;
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--text-soft);
  border-bottom: 1px solid var(--line);
  padding-bottom: 0.4rem;
}

.two-col {
  display: grid;
  gap: var(--space-5);
}

@media (min-width: 700px) {
  .two-col {
    grid-template-columns: 1fr 1fr;
  }
}

/* ── #267 列表—详情布局（工單）→ R37 三欄工作檯（350 #257＋#267）：
   ≥1280px 列表窗格、詳情窗格（#wo-detail-box）、工作隊列（.work-queue-pane）
   三欄並排；更窄版型依序堆疊（＝原本行為）。詳情內容與單一 /full 抓取
   完全不變；list-pane 與 detail-box 仍是 .wo-split 的直接子元素。 */
.wo-split {
  display: grid;
  gap: var(--space-5);
  align-items: start;
}

.wo-list-pane {
  display: grid;
  gap: var(--space-5);
  min-width: 0;
}

.wo-detail-pane {
  min-width: 0;
}

.wo-detail-empty {
  background: var(--card);
  border: 1.5px dashed var(--line);
  border-radius: var(--radius-card);
  padding: 2rem 1.25rem;
  text-align: center;
  color: var(--text-soft);
  font-size: var(--fs-lg);
}

/* 契約錨點（harness 結構性驗證 .wo-split{grid-template-columns）：三欄 =
   列表 21fr ／詳情 19fr ／工作隊列 200px 固定（R37-fix：隊列收窄、
   列表窗格加寬，七欄工單表不再擠爆）。 */
@media (min-width: 1280px) {
  .wo-split {
    grid-template-columns: minmax(0, 21fr) minmax(0, 19fr) minmax(0, 200px);
  }
}

/* ── R26 #267 對稱（銷售／出貨）→ R37 三欄工作檯：與上方 .wo-split 完全同構
   的列表—詳情分屏，≥1280px 同樣加第三欄 .work-queue-pane（訂單 tab 與出貨
   tab 各一份）；更窄版型堆疊，詳情開啟後由 app.js scrollIntoView。
   （刻意保持獨立的 .so-* 規則而非合併選取器，讓兩個分屏可各自演進。） */
.so-split {
  display: grid;
  gap: var(--space-5);
  align-items: start;
}

.so-list-pane {
  display: grid;
  gap: var(--space-5);
  min-width: 0;
}

.so-detail-pane {
  min-width: 0;
}

.so-detail-empty {
  background: var(--card);
  border: 1.5px dashed var(--line);
  border-radius: var(--radius-card);
  padding: 2rem 1.25rem;
  text-align: center;
  color: var(--text-soft);
  font-size: var(--fs-lg);
}

/* 契約錨點（harness 結構性驗證 .so-split{grid-template-columns）：三欄 =
   列表 21fr ／詳情 19fr ／工作隊列 200px 固定（與 .wo-split 同構）。 */
@media (min-width: 1280px) {
  .so-split {
    grid-template-columns: minmax(0, 21fr) minmax(0, 19fr) minmax(0, 200px);
  }
}

/* ── R37-fix 窄窗格表格衛生（≥1280px 三欄工作檯）── 列表窗格變窄後：
   ID／狀態／FPY／金額等短欄禁止斷行（工單 ID 不再折成三行、狀態標籤
   不再直排），操作鈕不疊羅漢；真放不下時由列表／詳情容器內部橫捲
   （與 ≤640px 同一套 overflow 慣例）。1280–1500px 之間再以 display:none
   收掉工單表的次級欄 FPY／到期日 — 只藏視覺，td[data-label] DOM 計數
   與模板欄位一支不動（harness check 9 的 7 計數仍過）。 */
@media (min-width: 1280px) {
  .wo-split td[data-label="工單 ID"],
  .wo-split td[data-label="狀態"],
  .wo-split td[data-label="FPY"],
  .wo-split td[data-label="目標"],
  .so-split td[data-label="訂單 ID"],
  .so-split td[data-label="出貨單 ID"],
  .so-split td[data-label="狀態"],
  .so-split td[data-label="金額"],
  .so-split td[data-label="到期日"] {
    white-space: nowrap;
  }

  .wo-split .data-table .wo-actions,
  .so-split .data-table .wo-actions {
    flex-wrap: nowrap;
  }

  #workorder-list,
  #sales-order-list,
  #shipment-list,
  #wo-detail-box,
  #sales-detail-box,
  #shipment-detail-box {
    overflow-x: auto;
  }

  /* 200px 隊列窗格：label 與 meta 改直角堆疊，不互相擠壓。 */
  .work-queue-list button {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.1rem;
  }
}

/* 1280–1500px：螢幅剛過三欄門檻、list-pane 仍偏窄 — 收掉工單表次級欄
   （FPY／到期日）讓七欄變五欄從容排版；≥1500px 恢復全欄。
   R40：nav-top 版型側欄讓出橫向空間，次級欄全程保留 — 本規則限左軌
   （body:not(.nav-top)；nav-top 只在 ≥1280px 生效，恰與本斷點重合）。 */
@media (min-width: 1280px) and (max-width: 1499px) {
  body:not(.nav-top) #workorder-list th:nth-child(4),
  body:not(.nav-top) #workorder-list td:nth-child(4),
  body:not(.nav-top) #workorder-list th:nth-child(6),
  body:not(.nav-top) #workorder-list td:nth-child(6) {
    display: none;
  }
}

/* ── R37 工作隊列窗格（三個 split 共用）── 白卡 × 三個隊列組（待投料工單／
   待揀批出貨／低庫存）；內容由 app.js workQueue 快取渲染（既有 refresh
   已抓回的資料客戶端衍生，零新增請求），點項目走既有 button[data-tab]
   路徑跳分頁。≥1280px 是 split 的第三欄；更窄堆疊在詳情窗格之後。 */
.work-queue-pane {
  min-width: 0;
}

.work-queue-card {
  background: var(--card);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 1.1rem 1.25rem;
}

.work-queue-card > h3 {
  margin: 0 0 0.6rem;
  font-size: var(--fs-lg);
  color: var(--accent);
  border-bottom: 1px solid var(--line);
  padding-bottom: 0.4rem;
}

.work-queue-group + .work-queue-group {
  margin-top: var(--space-4);
  border-top: 1px dashed var(--line-dash);
  padding-top: var(--space-3);
}

.work-queue-group h4 {
  margin: 0 0 0.4rem;
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--text-soft);
}

.work-queue-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.35rem;
}

.work-queue-list button {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
  box-sizing: border-box;
  text-align: left;
  background: var(--surface-sunk);
  color: var(--text);
  padding: 0.4rem 0.55rem;
  font-size: var(--fs-sm);
  border-radius: var(--radius-sm);
}

.work-queue-list button:hover {
  background: var(--accent-light);
  color: var(--white);
}

.work-queue-list .work-queue-meta {
  flex: 0 0 auto;
  font-size: var(--fs-xs);
  color: var(--text-muted);
  white-space: nowrap;
}

.work-queue-list button:hover .work-queue-meta {
  color: var(--white);
}

.work-queue-empty {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  padding: 0.1rem 0.55rem;
}

textarea {
  font-family: monospace;
  padding: 0.5rem;
  border: 1px solid var(--line-input);
  border-radius: var(--radius-sm);
  font-size: var(--fs-md);
}

h1 {
  margin: 0;
  color: var(--accent);
}

form {
  display: grid;
  gap: var(--space-3);
}

label {
  display: grid;
  gap: var(--space-1);
  font-size: var(--fs-md);
}

input,
select,
textarea {
  padding: 0.5rem;
  border: 1px solid var(--line-input);
  border-radius: var(--radius-sm);
  font-size: var(--fs-base);
  font-family: inherit; /* 表單控制項不吃 UA 預設字（無 CJK 系統會豆腐） */
}

select {
  background: var(--white);
  min-height: 2.5rem;
}

button {
  background: var(--accent);
  color: var(--white);
  border: none;
  padding: 0.65rem;
  border-radius: var(--radius-sm);
  font-size: var(--fs-base);
  font-family: inherit; /* 表單控制項不吃 UA 預設字（無 CJK 系統會豆腐） */
}

button:hover {
  background: var(--accent-light);
}

/* 工具列上的次要操作（重新整理／匯出 CSV）：描邊低調款 */
button.btn-ghost {
  background: var(--white);
  color: var(--accent);
  border: 1px solid var(--accent-light);
  padding: 0.4rem 0.75rem;
  font-size: var(--fs-md);
}

button.btn-ghost:hover {
  background: var(--accent-light);
  color: var(--white);
}

pre {
  background: var(--surface-sunk);
  padding: 0.75rem;
  border-radius: var(--radius-sm);
  min-height: 1.5rem;
  white-space: pre-wrap;
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 0.75rem;
  font-size: var(--fs-md);
  table-layout: auto;
}

.data-table th,
.data-table td {
  padding: 0.6rem 0.4rem;
  border-bottom: 1px solid var(--line-soft);
  text-align: left;
  vertical-align: top;
  overflow-wrap: break-word;
}

.data-table th {
  color: var(--accent);
  font-weight: 600;
  border-bottom: 2px solid var(--accent-light);
}

/* R27 訂單詳情明細的 合計 表尾（app.js 渲染 tfoot .so-total-row）：
   上框線與表頭的 2px accent 呼應，金額用 accent 色 — 與瓷磚一致。 */
.data-table tfoot td {
  border-bottom: none;
  border-top: 2px solid var(--accent-light);
  color: var(--accent);
  font-weight: 600;
}

/* R27 金額欄表頭不直拆 — 自動版面下欄窄，「金額」兩字會被疊成直排。 */
#sales-order-list .data-table th {
  white-space: nowrap;
}

/* ── R62 配方列表：ID／產出欄不再逐字斷行、動作列不再被卡緣裁切 ─────
   1440 實測：自動版面下長名稱＋chips 把 ID 欄擠到一兩字寬（12 碼 code
   折成直行）、操作欄 min-content 撐破卡片右緣。對策：ID／產出單行不折、
   動作列允許折行（空間不足時按鈕換行而非溢出）——table width:100% 恆
   成立，不引入 overflow 容器（.row-menu ⋯ 下拉是絕對定位，會被裁）。 */
#recipe-list .data-table td[data-label="ID"] code,
#recipe-list .data-table td[data-label="產出"] {
  white-space: nowrap;
}

#recipe-list .data-table .wo-actions {
  flex-wrap: wrap;
}

/* R62：名稱鈕例外於 R46 F13 的表格鈕 nowrap — 名稱是內容不是操作，長名
   （含外部代碼）必須能折行；否則名稱欄 min-content 撐破整表（1440 實測
   620px > 容器 530px），操作欄整排被推出卡緣裁切。操作鈕維持 nowrap。 */
#recipe-list .data-table .recipe-name-btn {
  white-space: normal;
}

/* ── R64② 採購清單（放大頁缺料比對）────────────────────────────── */
.shopping-short td {
  background: var(--danger-bg);
}

#scale-shopping-box {
  margin-top: 0.75rem;
  overflow-x: auto;
}

/* ── R63 新手順序引導（配方頁頂部建檔鏈）＋子配方列控制項 ────────── */
.prereq-banner {
  margin: 0 0 0.75rem;
  padding: 0.6rem 0.75rem;
  background: var(--info-bg);
  color: var(--info-text);
  border: 1px dashed var(--line-input);
  border-radius: var(--radius-md);
  font-size: var(--fs-sm);
}

.prereq-jump {
  background: var(--accent-light);
  padding: 0.2rem 0.5rem;
  font-size: var(--fs-sm);
}

/* 配方列切到「配方」模式時收起的原料控制項（原料名稱/單位/類別/廢棄率） */
.hidden-ing-control {
  display: none;
}

.data-table tr:hover {
  background: var(--surface-hover);
}

.data-table code {
  font-size: 0.75rem;
  color: var(--text-muted);
  word-break: break-all;
}

/* 手機（≤640px）：單手、沾了麵粉也要能用 —
   側欄變漢堡抽屜（#263）；多欄資料表不再硬擠進畫面：高頻列表改為堆疊卡片，
   其余（報表金額矩陣、工單／訂單明細、大量進貨預覽等）由所在容器橫向捲動；
   所有按鈕（含側欄選單項目、列內小按鈕）≥40px 觸控高度。
   卡片版型全部收在媒體查詢內，桌面（>640px）外觀不變。 */
@media (max-width: 640px) {
  /* ── #263 導航抽屜布局：側欄收進畫面外，漢堡鈕開、遮罩／選項關 ── */
  .app-shell {
    grid-template-columns: minmax(0, 1fr);
  }

  #sidebar {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    width: min(280px, 84vw);
    transform: translateX(-100%);
    transition: transform 0.25s ease;
  }

  .sidebar-inner {
    max-height: 100vh;
  }

  body.nav-open #sidebar {
    transform: none;
    box-shadow: var(--shadow-drawer);
  }

  body.nav-open .sidebar-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 50;
    background: var(--scrim);
  }

  .app-main {
    grid-column: 1;
    margin-left: 0;
    padding: 0 0.9rem 3rem;
  }

  .topbar {
    position: sticky;
    top: 0;
    z-index: 40;
    display: flex;
    align-items: center;
    gap: var(--gap-nav);
    margin: 0 -0.9rem 1rem;
    padding: 0.5rem 0.9rem;
    background: var(--sidebar-bg);
    color: var(--sidebar-text);
  }

  .topbar-brand {
    font-weight: 700;
    color: var(--white);
  }

  .topbar-title {
    margin-left: auto;
    font-size: var(--fs-sm);
    color: var(--sidebar-muted);
    /* R62：390px 實測被版型／佈景晶片擠到一字一行直排並溢出頂欄 —
       單行＋ellipsis，寬度上限讓位給晶片；過窄時以刪節號截斷。 */
    flex: 0 1 auto;
    min-width: 0;
    max-width: 40%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .nav-toggle {
    background: transparent;
    color: var(--white);
    font-size: 1.4rem;
    line-height: 1;
    padding: 0.3rem 0.5rem;
  }

  .nav-toggle:hover {
    background: var(--sidebar-line);
  }

  /* 審查 #D(a)：main 是 grid — 子項預設 min-width:auto 會被寬表撐開、整頁橫移
     （報表每日明細曾撐到 813px）。歸零後寬表由各容器的 overflow-x 內部捲動。 */
  main > section {
    min-width: 0;
  }

  /* 報表圖表手機改單欄 — 兩欄並排每個不到 160px，圖例擠成一團 */
  .report-charts {
    grid-template-columns: 1fr;
  }

  /* 資料表由 app.js 注入下列既有清單／明細容器 — 讓容器自己橫向捲動 */
  #dashboard-lists .dashboard-group,
  #recipe-list,
  #ingredient-list,
  #inventory-list,
  #workorder-list,
  #wo-detail-box,
  #workcenter-list,
  #timeline-box,
  #assignment-log,
  #sales-order-list,
  #sales-detail-box,
  #purchase-order-list,
  #partner-list,
  #report-table,
  #restock-box,
  #bulk-preview-box,
  #recipe-buy-result-box,
  #trace-result-box {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  .data-table {
    /* fixed + width:100% 會把多欄硬折行；改成自動版面讓表格自然變寬，
       超出容器的部分由上面的 overflow-x 捲動 */
    table-layout: auto;
    width: max-content;
    min-width: 100%;
  }

  /* 觸控目標：所有按鈕（含 .nav-menu 選單項目）至少 40px 高 */
  button {
    box-sizing: border-box;
    min-height: 40px;
  }

  #tabs button {
    touch-action: manipulation;
  }

  /* ── 卡片式堆疊（二期）── 工單列表與庫存列表：
     thead 隱藏、每列 tr 變成一張卡片、td 用 ::before 顯示 data-label
     欄位名（app.js 列模板已加上 data-label）。其余資料表仍走上面的
     橫向捲動；桌面（>640px）套不到此媒體查詢，外觀不變。 */
  #workorder-list .data-table thead,
  #inventory-list .data-table thead {
    display: none;
  }

  #workorder-list .data-table,
  #inventory-list .data-table {
    /* 覆蓋上面的橫向捲動版型：卡片不走 max-content 寬表 */
    width: 100%;
    min-width: 0;
  }

  #workorder-list .data-table tr,
  #inventory-list .data-table tr {
    display: block;
    background: var(--surface-sunk);
    border-radius: var(--radius-md);
    padding: 0.35rem 0.75rem;
    margin-bottom: 0.6rem;
  }

  #workorder-list .data-table td[data-label],
  #inventory-list .data-table td[data-label] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: 0.35rem 0;
    border-bottom: 1px dashed var(--line-dash);
  }

  /* 欄位名在左、值在右；只對有 data-label 的 td 顯示（空狀態「無工單 /
     無庫存」的 placeholder td 沒有屬性，維持普通段落外觀） */
  #workorder-list .data-table td[data-label]::before,
  #inventory-list .data-table td[data-label]::before {
    content: attr(data-label);
    flex: 0 0 auto;
    font-weight: 600;
    font-size: var(--fs-xs);
    color: var(--accent);
  }

  #workorder-list .data-table tr td:last-child,
  #inventory-list .data-table tr td:last-child {
    border-bottom: none;
  }

  #workorder-list .data-table .wo-actions,
  #inventory-list .data-table .wo-actions {
    justify-content: flex-end;
  }

  /* ── 卡片式堆疊（三期）── 其余高頻列表（配方／原料／合作對象／採購單／
     訂單／補貨建議）沿用二期的同一組規則：thead 隱藏、tr 變卡片、
     td[data-label] 以 ::before 顯示欄位名。 */
  #recipe-list .data-table thead,
  #ingredient-list .data-table thead,
  #partner-list .data-table thead,
  #purchase-order-list .data-table thead,
  #sales-order-list .data-table thead,
  #restock-box .data-table thead {
    display: none;
  }

  #recipe-list .data-table,
  #ingredient-list .data-table,
  #partner-list .data-table,
  #purchase-order-list .data-table,
  #sales-order-list .data-table,
  #restock-box .data-table {
    /* 覆蓋上面的橫向捲動版型：卡片不走 max-content 寬表 */
    width: 100%;
    min-width: 0;
  }

  #recipe-list .data-table tr,
  #ingredient-list .data-table tr,
  #partner-list .data-table tr,
  #purchase-order-list .data-table tr,
  #sales-order-list .data-table tr,
  #restock-box .data-table tr {
    display: block;
    background: var(--surface-sunk);
    border-radius: var(--radius-md);
    padding: 0.35rem 0.75rem;
    margin-bottom: 0.6rem;
  }

  #recipe-list .data-table td[data-label],
  #ingredient-list .data-table td[data-label],
  #partner-list .data-table td[data-label],
  #purchase-order-list .data-table td[data-label],
  #sales-order-list .data-table td[data-label],
  #restock-box .data-table td[data-label] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: 0.35rem 0;
    border-bottom: 1px dashed var(--line-dash);
  }

  #recipe-list .data-table td[data-label]::before,
  #ingredient-list .data-table td[data-label]::before,
  #partner-list .data-table td[data-label]::before,
  #purchase-order-list .data-table td[data-label]::before,
  #sales-order-list .data-table td[data-label]::before,
  #restock-box .data-table td[data-label]::before {
    content: attr(data-label);
    flex: 0 0 auto;
    font-weight: 600;
    font-size: var(--fs-xs);
    color: var(--accent);
  }

  #recipe-list .data-table tr td:last-child,
  #ingredient-list .data-table tr td:last-child,
  #partner-list .data-table tr td:last-child,
  #purchase-order-list .data-table tr td:last-child,
  #sales-order-list .data-table tr td:last-child,
  #restock-box .data-table tr td:last-child {
    border-bottom: none;
  }

  #recipe-list .data-table .wo-actions,
  #ingredient-list .data-table .wo-actions,
  #partner-list .data-table .wo-actions,
  #purchase-order-list .data-table .wo-actions,
  #sales-order-list .data-table .wo-actions {
    justify-content: flex-end;
  }

  /* 補貨建議卡片：輸入欄列表。第一列「勾選 + 原料名」併行（清單標頭感、
     checkbox 不佔整列）；數值與輸入欄 label 左／值右各佔一列。
     tr 改 flex-wrap 讓前兩個 td 同列，其餘 td[data-label] flex-basis 100%。 */
  #restock-box .data-table tr {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
  }

  #restock-box .data-table td:first-child,
  #restock-box .data-table td:nth-child(2) {
    display: flex;
    align-items: center;
    padding: 0.35rem 0;
    border-bottom: none;
  }

  #restock-box .data-table td:first-child {
    flex: 0 0 auto;
    padding-right: 0.5rem;
  }

  #restock-box .data-table td:nth-child(2) {
    flex: 1 1 auto;
    font-weight: 600;
    overflow-wrap: anywhere;
  }

  #restock-box .data-table td[data-label] {
    flex: 1 1 100%;
  }
}

/* ── 圖示欄（≥641px；R37 起 1280px 以上收為同一條 64px 圖示軌）──
   側欄收窄成圖示欄：只用 CSS 藏 .nav-text（display:none）與 .nav-group-label
   （font-size:0 → 讓位成分隔線），DOM 一字不動 — button[data-tab] 仍 14 個、
   .nav-group 仍 5 個且順序不變，圖示置中、active 態保留。≤640px 抽屜與
   ≤1200px 既有圖示欄行為完全不變（同一組規則自然涵蓋）。 */
@media (min-width: 641px) {
  .app-shell {
    grid-template-columns: 64px minmax(0, 1fr);
  }

  .sidebar-brand {
    justify-content: center;
    padding: 0.85rem 0.4rem;
    flex-wrap: wrap; /* R40：品牌區版型切換器換行置底，64px 圖示軌塞得下 */
  }

  .brand-text {
    display: none;
  }

  .nav-group-label {
    margin: 0.6rem 0 0.2rem;
    font-size: 0;
    text-align: center;
  }

  .nav-group + .nav-group .nav-group-label {
    border-top: 1px solid var(--sidebar-line);
    padding-top: 0.6rem;
  }

  .nav-menu button {
    justify-content: center;
    padding: 0.6rem 0;
  }

  .nav-text {
    display: none;
  }

  .nav-icon {
    font-size: 1.2rem;
  }

  #tabs {
    padding: 0.4rem 0.4rem 1.25rem;
  }
}

/* ── R62 側欄收合切換（WordPress 式）──────────────────────────────
   body.rail-expanded 把 ≥641px 的 64px 圖示軌展開為 200px icon＋文字側欄。
   只在未開頂欄時生效（nav-top 無側欄，:not(.nav-top) 排除）；≤640px 抽屜
   恆有字，本區規則全部包在 641 媒體查詢內自然不波及。展開偏好存
   localStorage「breadiary.rail」，首繪前由 index.html inline script 套 class。
   DOM 契約不變：button[data-tab] 數量與順序、.nav-group 5 組、群組標籤
   仍是 div（收合 font-size:0 分隔線 ↔ 展開恢復字級）。 */
#nav-rail-toggle {
  /* 基底隱藏：只有「≥641px 且未開頂欄」才顯示（下方媒體查詢開啟）——
     ≤640px 抽屜與 nav-top 頂欄本來就沒有圖示軌可切。 */
  display: none;
}

@media (min-width: 641px) {
  body:not(.nav-top) #nav-rail-toggle {
    display: flex;
  }

  body.rail-expanded:not(.nav-top) .app-shell {
    grid-template-columns: 200px minmax(0, 1fr);
  }

  body.rail-expanded:not(.nav-top) .sidebar-brand {
    justify-content: flex-start;
    padding: 0.85rem 0.75rem;
    row-gap: 0.45rem;
  }

  body.rail-expanded:not(.nav-top) .brand-text {
    display: block;
  }

  body.rail-expanded:not(.nav-top) .nav-group-label {
    font-size: 0.72rem;
    text-align: left;
  }

  body.rail-expanded:not(.nav-top) .nav-menu button {
    justify-content: flex-start;
    padding: 0.6rem 0.75rem;
    gap: 0.5rem;
  }

  body.rail-expanded:not(.nav-top) .nav-text {
    display: inline;
  }

  /* 展開時品牌區三顆切換器（版型／側欄／佈景）一併恢復文案 —
     蓋過上方 641–1279 與 ≥1280 :not(.nav-top) 的藏文案規則（特異度較高）。 */
  body.rail-expanded:not(.nav-top) .sidebar-brand .nav-layout-text {
    display: inline;
  }
}

/* stepper */
.stepper {
  display: flex;
  gap: var(--space-1);
  align-items: center;
}

.stepper input {
  width: 80px;
  text-align: center;
}

.stepper button {
  width: 2rem;
  padding: 0.45rem 0;
  font-size: 1.1rem;
  line-height: 1;
  background: var(--accent-light);
}

.stepper button:hover {
  background: var(--accent);
}

/* dashboard（#273 儀表盤：瓷磚保留，落地頁仍是戰情） */
.dashboard-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--space-4);
  margin: 0.75rem 0 1rem;
}

.tile {
  background: var(--card);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: 1rem;
  text-align: center;
}

.tile h3 {
  margin: 0 0 0.5rem;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.tile p {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--accent);
}

/* 瓷磚內的說明小字（如庫存價值的「n 筆未計價」註記）— 蓋過 .tile p 的大數字樣式 */
.tile p.hint {
  margin-top: 0.35rem;
  font-size: 0.75rem;
  font-weight: 400;
  color: var(--text-muted);
}

.tile.tile-alert {
  background: var(--danger-bg);
  color: var(--danger-text);
}

.tile.tile-alert h3,
.tile.tile-alert p {
  color: var(--danger-text);
}

/* R27 金額瓷磚（今日營收／今日毛利）：數值色沿用 .tile p 的 accent（與庫存
   價值一致）；tabular-nums 讓兩位小數金額（R38 fmtTWD）變動時數字寬度穩定不跳動。
   ≤640px 由 .dashboard-tiles 的 auto-fit 網格自然換行，不需額外規則。 */
.tile.tile-money p {
  font-variant-numeric: tabular-nums;
}

/* R28 負毛利警示色：今日毛利為負時整磚轉警示 — 沿用 .tile-alert 既有的
   紅系配色（var(--danger-bg) 底 / var(--danger-text) 字），不引入新色。 */
.tile.tile-neg {
  background: var(--danger-bg);
}

.tile.tile-neg h3,
.tile.tile-neg p {
  color: var(--danger-text);
}

/* 低庫存列：淡淡的警示底色 + 名稱前 ⚠（儀表板低庫存表） */
#dashboard-lists tr.low-stock-row td {
  background: var(--warning-soft);
}

#dashboard-lists tr.low-stock-row:hover td {
  background: var(--warning-soft-hover);
}

.dashboard-lists {
  display: grid;
  gap: var(--space-5);
}

/* 儀表板的三張列表（低庫存／即將到期／已過期）在 R25 卡片階層下自帶白卡 */
.dashboard-group {
  background: var(--card);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 1rem 1.25rem;
}

.dashboard-group h3 {
  margin: 0 0 0.5rem;
  color: var(--accent);
  font-size: var(--fs-base);
}

/* ── R37 戰情便當盒（350 #273 儀表盤 × #272 便當盒，≥1280px）── 純 CSS grid
   重排：#dashboard-tiles（6 磚）、#dashboard-kpi（3 磚）、#qc-gate-tile、
   #dashboard-lists（3 群組）、#refresh-dashboard、#dashboard-result 的 id／
   磚 h3 標題／金額格式（fmtTWD）一律不動，只換版型 —
   上排 6 磚一列；中排左 生產 KPI、右 品管（QC 磚＋hint）；下排三張列表
   並排成便當格，1440×900 一屏收束。#dashboard.active 蓋過 .tab.active 的
   display:block（未選中仍由 .tab display:none 收起）。dashboard payload
   沒有時間序列 → 不做本週長條等視覺（不為視覺憑空生料、零新增請求）。 */
@media (min-width: 1280px) {
  #dashboard.active {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
    gap: var(--space-2) var(--space-5);
    align-items: start;
  }

  #dashboard.active .tab-toolbar,
  #dashboard-lists {
    grid-column: 1 / -1;
  }

  #dashboard-tiles {
    grid-column: 1 / -1;
    margin: 0;
  }

  #dashboard > h3.kpi-title:first-of-type {
    grid-column: 1;
    grid-row: 3;
  }

  #dashboard > h3.kpi-title:nth-of-type(2) {
    grid-column: 2;
    grid-row: 3;
  }

  #dashboard-kpi {
    grid-column: 1;
    grid-row: 4;
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  #qc-gate-tile {
    grid-column: 2;
    grid-row: 4;
  }

  #dashboard > .hint {
    grid-column: 2;
    grid-row: 5;
  }

  #dashboard-lists {
    grid-row: 6;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    align-items: start;
  }
}

/* recipe ingredient rows */
.recipe-ing-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  margin-bottom: 0.75rem;
}

.recipe-ing-row input,
.recipe-ing-row select {
  flex: 1 1 100px;
  min-width: 80px;
}

.recipe-ing-row .remove-recipe-ing {
  flex: 0 0 auto;
  background: var(--btn-danger);
  padding: 0.45rem 0.6rem;
  font-size: var(--fs-sm);
}

#add-recipe-ingredient {
  margin-bottom: 0.75rem;
  background: var(--accent-light);
}

/* R46 走查 F13：表格操作欄按鈕文字不斷行 — 「標記已生產」曾被欄寬擠成
   一字一行直排。按鈕寬隨文字，欄位過擠時整表橫捲（既有 RWD 契約）。 */
.data-table button {
  white-space: nowrap;
}

/* R58 單鈕群組：標籤與唯一鈕文字重複 → 左軌/抽屜藏標籤；nav-top 的群組列
   是結構性第一列，維持顯示。 */
#tabs .nav-group.solo-group .nav-group-label {
  display: none;
}

body.nav-top #tabs .nav-group.solo-group .nav-group-label {
  display: block;
}

/* R56 報表視圖切換：日期/產品之間的分隔 */
.report-range-sep {
  display: inline-block;
  width: 1px;
  height: 1.2rem;
  background: var(--line-input);
  margin: 0 0.4rem;
  vertical-align: middle;
}

/* R48-c 版本 diff：有差異的原料列高亮 */
tr.diff-changed td {
  background: var(--warning-bg);
}

/* ── R50 智慧補貨：比對列＋縮放 ── */
.restock-match-row {
  display: flex;
  gap: 0.4rem;
  align-items: center;
  margin-bottom: 0.4rem;
}

.restock-match-row select {
  flex: 1;
  min-width: 0;
}

.restock-match-row .restock-qty,
.restock-match-row .restock-unit,
.restock-match-row .restock-cost {
  width: 5.5rem;
}

.restock-match-row .restock-subtotal {
  min-width: 4.5rem;
  white-space: nowrap;
}

.restock-match-row .restock-scale {
  padding: 0.3rem 0.45rem;
  font-size: var(--fs-sm);
}

.restock-scale-all {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  margin-bottom: 0.6rem;
}

#buy-photo-preview {
  max-width: 100%;
  max-height: 320px;
  display: block;
  margin: 0.5rem 0;
  border: 1px solid var(--line-input);
  border-radius: var(--radius-sm);
}

#buy-photo-preview.hidden {
  display: none;
}

/* ── R49 配方管理 UX：家族樹＋名稱即檢視＋meta chips＋列內動作選單 ── */
.recipe-name-cell {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.tree-glyph {
  color: var(--text-muted);
  user-select: none;
}

/* 名稱即檢視：像連結的純文字鈕（primary read 動作） */
.recipe-name-btn {
  background: none;
  border: none;
  padding: 0;
  color: var(--accent);
  font: inherit;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.recipe-name-btn:hover {
  background: none;
  color: var(--accent);
  text-decoration: underline;
}

.recipe-meta-chips {
  display: inline-flex;
  gap: 0.3rem;
}

.meta-chip {
  background: var(--cream);
  color: var(--text-muted);
  border-radius: 9999px;
  padding: 0.05rem 0.5rem;
  font-size: var(--fs-xs);
  white-space: nowrap;
}

/* 列內「⋯更多」選單：原生 details，點外部收合（app.js 統一監聽） */
.row-menu {
  position: relative;
}

.row-menu summary {
  list-style: none;
  cursor: pointer;
  background: var(--accent-light);
  color: var(--white);
  border-radius: var(--radius-sm);
  padding: 0.3rem 0.6rem;
  font-size: var(--fs-sm);
  user-select: none;
}

.row-menu summary::-webkit-details-marker {
  display: none;
}

.row-menu[open] summary {
  background: var(--accent);
}

.row-menu-items {
  position: absolute;
  left: 0; /* 向左展開：動作欄貼著容器右緣，right:0 會被 overflow 裁切 */
  top: calc(100% + 4px);
  min-width: 7.5rem;
  background: var(--white);
  border: 1px solid var(--line-input);
  border-radius: var(--radius-sm);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
  z-index: 40;
  display: flex;
  flex-direction: column;
  padding: 0.25rem;
}

.row-menu-items button {
  background: none;
  color: var(--text);
  text-align: left;
  padding: 0.4rem 0.6rem;
  border-radius: var(--radius-sm);
}

.row-menu-items button:hover {
  background: var(--accent-light);
  color: var(--white);
}

.row-menu-items .delete-row {
  color: var(--btn-danger);
}

/* list row delete buttons */
.data-table .delete-row {
  background: var(--btn-danger);
  padding: 0.3rem 0.6rem;
  font-size: var(--fs-sm);
}

/* 列內取消鈕（採購單／銷售訂單取消）：與刪除同色系（破壞性動作） */
.data-table .cancel-row {
  background: var(--btn-danger);
  padding: 0.3rem 0.6rem;
  font-size: var(--fs-sm);
}

.data-table .cancel-row:hover {
  background: var(--btn-danger-hover);
}

/* list row inline edit */
.data-table .edit-row-btn {
  background: var(--accent-light);
  padding: 0.3rem 0.6rem;
  font-size: var(--fs-sm);
}

.data-table .edit-row-btn:hover {
  background: var(--accent);
}

.data-table tr.edit-row td {
  background: var(--surface-sunk);
  border-bottom: 2px solid var(--accent-light);
}

.edit-title {
  font-weight: 600;
  color: var(--accent);
  font-size: var(--fs-md);
}

.edit-hint {
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

.edit-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: flex-end;
}

.edit-form label {
  display: flex;
  flex-direction: column;
  font-size: var(--fs-xs);
  margin: 0;
}

.edit-form input {
  width: 7rem;
  min-width: 5rem;
}

.edit-form button {
  flex: 0 0 auto;
  padding: 0.45rem 0.6rem;
  font-size: var(--fs-sm);
}

.edit-form button[type="submit"] {
  background: var(--accent);
}

.edit-form button[type="submit"]:disabled {
  background: var(--btn-disabled);
  cursor: not-allowed;
}

.edit-form .edit-cancel {
  background: var(--btn-neutral);
}

.edit-form .edit-cancel:hover {
  background: var(--btn-neutral-hover);
}

/* ── R44 配方版本歷史 ── 列展開區沿用編輯列的沉底底色；內嵌版本表縮排
   呈現，回滾鈕沿用 accent。回滾＝owner 專屬：manager 不像 baker 有
   .owner-only 藏匿（店長看得到大部分寫入入口），此處比照 .delete-row
   明確藏鈕 — 後端 403 為準，前端只是不顯示。 */
.data-table tr.history-row td {
  background: var(--surface-sunk);
  border-bottom: 2px solid var(--accent-light);
}

.history-box {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-2) 0;
}

.history-table {
  width: min(560px, 100%);
  font-size: var(--fs-sm);
}

.history-table .rollback-btn {
  background: var(--accent);
  color: #fff;
}

body[data-role="manager"] .rollback-btn {
  display: none !important;
}


.status-tag {
  display: inline-block;
  padding: 0.2rem 0.5rem;
  border-radius: 4px;
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: uppercase;
}

.status-open {
  background: var(--success-bg);
  color: var(--success-text);
}

.status-partial {
  background: var(--warning-bg);
  color: var(--warning-text);
}

.status-closed {
  background: var(--danger-bg);
  color: var(--danger-text);
}

/* work orders */
.kpi-title {
  margin: 1rem 0 0;
  color: var(--accent);
  font-size: var(--fs-base);
}

.wo-id {
  font-size: 0.85em;
}

.wo-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.wo-actions button {
  padding: 0.25rem 0.5rem;
  font-size: var(--fs-xs);
}


.wo-detail h4 {
  margin: 0.75rem 0 0.35rem;
  color: var(--accent);
  font-size: var(--fs-lg);
}

/* R28 工單列印卡：詳情第一列 — 工單資訊（左）與「列印」鈕（右）同一行 */
.wo-detail-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
}

.wo-detail-head h4 {
  margin: 0.75rem 0 0.35rem;
}

.wo-detail .wo-print-btn {
  flex: 0 0 auto;
  background: var(--accent-light);
  padding: 0.3rem 0.7rem;
  font-size: var(--fs-sm);
}

.wo-detail .data-table {
  margin-bottom: var(--space-2);
}

/* #267 詳情窗格本體：桌機靠在右欄、手機堆疊在列表下 — 同一張白卡 */
.wo-detail {
  background: var(--card);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 1.1rem 1.25rem;
}

.wo-mini-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: flex-end;
  margin-bottom: var(--space-2);
}

.wo-mini-form label {
  display: flex;
  flex-direction: column;
  font-size: var(--fs-sm);
  margin: 0;
}

.wo-mini-form input,
.wo-mini-form select {
  width: 8rem;
  min-width: 6rem;
}

.wo-mini-form button {
  flex: 0 0 auto;
  background: var(--accent-light);
  padding: 0.45rem 0.6rem;
  font-size: var(--fs-sm);
}

.wo-blockers {
  color: var(--danger-text);
  font-size: var(--fs-md);
  margin: 0.25rem 0;
}

.status-draft {
  background: var(--draft-bg);
  color: var(--draft-text);
}

.status-released {
  background: var(--warning-bg);
  color: var(--warning-text);
}

.status-in_progress {
  background: var(--success-bg);
  color: var(--success-text);
}

.status-completed {
  background: var(--info-bg);
  color: var(--info-text);
}

.status-cancelled {
  background: var(--danger-bg);
  color: var(--danger-text);
}

/* R45 稽核：denied（被拒的寫入嘗試）整列淡紅底，掃視時跳出 */
tr.audit-denied td {
  background: var(--danger-bg);
}

/* reports */
.report-range {
  display: flex;
  gap: var(--space-2);
  margin: 0.5rem 0 1rem;
}
.report-charts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
  margin-bottom: 1.5rem;
}
.chart-box {
  background: var(--card);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
  padding: 1rem;
  height: 280px;
  position: relative;
  /* grid 子項預設 min-width:auto 會被 canvas 初始寬度（300px）撐死、
     手機上把整頁撐到橫移 — 歸零讓 Chart.js 依容器重設大小 */
  min-width: 0;
}
.chart-box canvas {
  max-height: 100%;
}
pre[id$="-result"]:empty {
  display: none;
}

/* buy（進貨） */
.hidden {
  display: none;
}

.buy-mode-row {
  display: flex;
  gap: var(--space-5);
  align-items: center;
}

.buy-mode-option {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 0.35rem;
  font-size: var(--fs-lg);
}

.hint {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  margin: 0;
}

/* 單價即時小計（審查 #1）：數量 × 單價送出前現形 */
.subtotal {
  font-weight: 600;
  color: var(--accent);
}

/* 列內小按鈕：批次 ID 複製（審查 #13）、追溯反查（審查 #13） */
.copy-batch,
.trace-reverse {
  background: var(--accent-light);
  padding: 0.2rem 0.5rem;
  font-size: var(--fs-xs);
}

.copy-batch:hover,
.trace-reverse:hover {
  background: var(--accent);
}

.trace-actions {
  margin-top: var(--space-2);
}

#bulk-paste {
  width: 100%;
  box-sizing: border-box;
}

.bulk-table th,
.bulk-table td {
  font-size: var(--fs-sm);
}

tr.bulk-row-error td {
  background: var(--danger-bg);
}

.bulk-errors {
  color: var(--danger-text);
  font-size: var(--fs-md);
  margin: var(--space-2) 0 0;
}

button:disabled {
  background: var(--btn-disabled);
  cursor: not-allowed;
}

#buy-post-actions {
  margin-top: var(--space-2);
}

#goto-inventory {
  background: var(--accent-light);
  padding: 0.45rem 0.75rem;
  font-size: var(--fs-md);
}

/* 投料生產：列容器間距；列本身沿用 .wo-mini-form 佈局 */
.wo-cons-rows {
  display: grid;
  gap: 6px;
  margin: 6px 0;
}
.wo-cons-row select {
  min-width: 260px;
  max-width: 100%;
}

/* R26 配方放大出口：放大成功後的動作列 — 新配方名稱欄＋「存成新配方」／
   「以此開工單」兩顆按鈕（成功計算前整列元素各自 hidden）。 */
.scale-exit-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

.scale-exit-row input {
  max-width: 18rem;
}

.scale-exit-row button {
  background: var(--accent-light);
  padding: 0.45rem 0.75rem;
  font-size: var(--fs-md);
}

/* buy（進貨）：補貨建議 / 配方採購建議面板；庫存 tab 的批次追溯面板同一組卡片樣式 */
.buy-panel,
.tool-panel {
  background: var(--card);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 1rem 1.25rem;
  margin-bottom: 1rem;
}

.buy-panel h3,
.tool-panel h3 {
  margin-top: 0;
}

.buy-panel > button,
.buy-actions-row button {
  background: var(--accent-light);
  padding: 0.45rem 0.75rem;
  font-size: var(--fs-md);
}

#refresh-restock {
  margin-bottom: var(--space-2);
}

.buy-actions-row {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

.restock-table input[type="text"] {
  width: 7rem;
  min-width: 5rem;
}

.restock-table input[type="checkbox"] {
  width: 1rem;
  height: 1rem;
}

/* ── 批次追溯（庫存 tab）── 查詢結果卡片：根節點（批號／批次）在上，
   來源／流向表格內縮呈現上下游行；查無資料用和緩的提示樣式。 */
.trace-card {
  background: var(--surface-hover);
  border: 1px solid var(--line-warm);
  border-radius: var(--radius-md);
  padding: 0.75rem 1rem;
  margin-top: var(--space-2);
}

.trace-root {
  margin: 0 0 0.25rem;
  font-size: var(--fs-lg);
}

.trace-branch {
  margin: var(--space-2) 0 0;
  padding-left: 0.75rem;
  border-left: 3px solid var(--accent-light);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--accent);
}

.trace-card .data-table {
  margin-top: 0.35rem;
}

.trace-empty {
  margin: var(--space-2) 0 0;
  padding: 0.6rem 0.75rem;
  background: var(--surface-sunk);
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font-size: var(--fs-md);
}

/* ── 配方列印檢視（R18-4）── #print-sheet 在螢幕上永遠隱藏；列印時整個應用
   殼層（側欄／頂欄／main 內所有分頁與表單）退出，只印這張配方卡。
   內容由 app.js 在按下配方列的「列印」時動態填入。 */
#print-sheet {
  display: none;
}

@media print {
  .app-shell {
    display: none !important;
  }

  #print-sheet {
    display: block;
    background: var(--white);
    color: var(--print-ink);
    padding: 0;
  }

  .print-title {
    margin: 0 0 0.25rem;
    font-size: 1.4rem;
  }

  .print-meta {
    margin: 0 0 0.75rem;
    font-size: var(--fs-md);
  }

  /* R28 工單列印卡的區塊小標（投料清單／產出記錄／品檢結果） */
  .print-section {
    margin: 0.9rem 0 0.3rem;
    font-size: var(--fs-xl);
  }

  .print-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-base);
  }

  .print-table th,
  .print-table td {
    border: 1px solid var(--text-muted);
    padding: 0.4rem 0.6rem;
    text-align: left;
  }

  .print-total {
    margin: 0.75rem 0 0;
    font-size: var(--fs-xl);
    font-weight: 600;
  }
}

@media (max-width: 640px) {
  .list-tools button,
  .list-tools h2,
  .list-tools h3 {
    white-space: nowrap;
  }
}

/* ── R35 出貨 tab + 配方溯源（Phase 2/3 UI 補齊）────────────────── */
.shipment-line-row {
  display: flex;
  gap: 0.5rem;
  align-items: end;
  margin-bottom: 0.5rem;
}

.recipe-source-link {
  margin-left: 0.35rem;
  text-decoration: none;
  font-size: var(--fs-sm);
}

/* ── R38 UI 評估修復（ui_evaluation_20260912.md）────────────────── */

/* #1 報表範圍鈕：全域 button 是滿底色（accent），非 active 鈕因此看起來
   像選中 — 給 .report-days 明確的 ghost 底，選中態才唯一。 */
.report-days {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--text-muted);
  padding: 0.35rem 0.8rem;
}
.report-days:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.report-days.active {
  background: var(--accent);
  color: var(--white);
  border-color: var(--accent);
}

/* #7 結果回饋：錯誤／成功分樣（app.js show() 依訊息前綴切換 class） */
pre.result-err {
  background: var(--danger-bg);
  color: var(--danger-text);
  border-left: 3px solid var(--btn-danger);
}
pre.result-ok {
  border-left: 3px solid var(--accent);
}

/* #8 1280–1500px 工單表欄位收合提示：預設隱藏，僅該斷點顯示 */
.cols-hint {
  display: none;
  font-size: var(--fs-sm);
  color: var(--text-muted);
  white-space: nowrap;
}
@media (min-width: 1280px) and (max-width: 1499px) {
  body:not(.nav-top) .wo-split .cols-hint {
    display: inline;
  }
}

/* ── R38 管線分頁（E 流程時間線，350 #277＋#285）──────────────────
   頂列（品牌＋專案標題＋G1 契約 badge＋列印備料單）、九階段橫向 stepper
   （done 綠勾／current 橘放大／todo 灰）、當前階段卡（備料＝FEFO 備料表）、
   今日批次動態垂直時間線。≤1280px 堆疊＋stepper 橫向捲動；≤640px 抽屜／
   頂欄機制不動（沿用全域行動規則）。 */
.pipeline-topbar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 0.9rem 1.1rem;
  margin-bottom: var(--space-5);
}
.pipeline-topbar h3 {
  margin: 0;
  font-size: var(--fs-xl);
  color: var(--accent);
}
.pipeline-brand {
  color: var(--text-soft);
  font-weight: 600;
  white-space: nowrap;
}
/* G1 契約 badge：工單連結的銷售訂單（這爐的契約）一眼可辨。 */
.pipeline-contract-badge {
  background: var(--info-bg);
  color: var(--info-text);
  border: 1px solid var(--info-text);
  border-radius: 999px;
  padding: 0.15rem 0.7rem;
  font-size: var(--fs-sm);
  font-weight: 600;
  white-space: nowrap;
}
.pipeline-topbar .btn-ghost {
  margin-left: auto;
}
/* 九階段 stepper：單行橫向排列，節點間以短線相連；窄版整條橫向捲動
   （不換行、不擠壓節點）。 */
.pipeline-stepper {
  list-style: none;
  display: flex;
  align-items: flex-start;
  margin: 0 0 var(--space-5);
  padding: 1rem 1.1rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  overflow-x: auto;
}
.pipeline-step {
  flex: 1 0 auto;
  min-width: 5.2rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  position: relative;
  padding: 0 0.5rem;
  text-align: center;
}
/* 節點間連接線：左鄰節點的圓心連到本節點的圓心高度。 */
.pipeline-step + .pipeline-step::before {
  content: "";
  position: absolute;
  top: 1rem;
  right: 100%;
  width: 0.5rem;
  height: 2px;
  background: var(--line-warm);
}
.pipeline-step-dot {
  width: 2rem;
  height: 2rem;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  font-weight: 700;
  background: var(--surface-sunk);
  color: var(--text-muted);
  border: 2px solid var(--line);
  flex: 0 0 auto;
}
.pipeline-step.done .pipeline-step-dot {
  background: var(--success-bg);
  color: var(--success-text);
  border-color: var(--success-text);
}
/* current：橘色放大 — 現在做到哪一眼可見。 */
.pipeline-step.current .pipeline-step-dot {
  background: var(--accent);
  color: var(--white);
  border-color: var(--accent);
  transform: scale(1.25);
  box-shadow: 0 0 0 4px var(--accent-light);
}
.pipeline-step.todo .pipeline-step-dot {
  opacity: 0.55;
}
.pipeline-step-label {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  white-space: nowrap;
}
.pipeline-step.done .pipeline-step-label {
  color: var(--success-text);
}
.pipeline-step.current .pipeline-step-label {
  color: var(--accent);
  font-weight: 700;
}
/* 當前階段卡。 */
.pipeline-stage-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 1rem 1.1rem;
  margin-bottom: var(--space-5);
}
.pipeline-stage-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: 0.5rem;
}
.pipeline-stage-head h3 {
  margin: 0;
}
.pipeline-stage-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}
/* 今日批次動態：垂直時間線（左軸線＋節點圓點）。 */
.pipeline-timeline-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 1rem 1.1rem;
}
.pipeline-timeline-card h3 {
  margin: 0;
}
.pipeline-timeline {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0 0 0 1.25rem;
  border-left: 2px solid var(--line-warm);
}
.pipeline-timeline li {
  position: relative;
  padding: 0.35rem 0 0.35rem 0.6rem;
}
.pipeline-timeline li::before {
  content: "";
  position: absolute;
  left: -1.48rem;
  top: 0.8rem;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--accent-light);
  border: 2px solid var(--card);
  box-shadow: 0 0 0 1.5px var(--accent-light);
}
.pipeline-timeline time {
  color: var(--text-muted);
  font-size: var(--fs-sm);
  margin-right: 0.5rem;
}
.pipeline-timeline .pipeline-timeline-text {
  margin-left: 0.5rem;
}
.pipeline-timeline .pipeline-timeline-empty {
  color: var(--text-soft);
}
/* ≤1280px：堆疊版 — 區塊依序直排（本來就單欄），stepper 收緊節點並靠
   橫向捲動（上下的 overflow-x 已內建），階段卡標題與動作鈕改上下堆疊。 */
@media (max-width: 1280px) {
  .pipeline-step {
    min-width: 4.6rem;
  }
  .pipeline-stage-head {
    flex-direction: column;
    align-items: flex-start;
  }
  .pipeline-topbar .btn-ghost {
    margin-left: 0;
  }
}

/* ── R39 爐位設備檔＋當日時間線 ────────────────────────────────────
   設備格（溫度範圍 180–250°C、盤 3600×4cm、預熱 15分）折行反而難掃讀；
   時間線時間欄用 tabular-nums 對齊起訖。 */
#workcenter-list .data-table td:nth-child(4),
#workcenter-list .data-table td:nth-child(5),
#workcenter-list .data-table td:nth-child(6) {
  white-space: nowrap;
}

#timeline-box .data-table td:first-child {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* ── R40 版型切換（左軌／頂欄，localStorage「breadiary.nav」）────────
   同一棵 DOM（#sidebar 內容一字不動）：body.nav-top 時 #sidebar 重排為
   頂欄 — 第一列品牌＋切換器（右緣）、#tabs 變 5 群組橫排（display:contents
   把群組標籤排上第一列）＋作用中群組的子分頁第二列。nav-top 只在 ≥1280px
   生效：641–1279px 一律既有 64px 圖示軌、≤640px 一律既有抽屜（RWD 不重爆）。
   切換是純 class＋重排（app.js），零資料重抓。 */
.nav-layout-toggle {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  background: transparent;
  color: var(--sidebar-text);
  border: 1px solid var(--sidebar-line);
  border-radius: var(--radius-sm);
  padding: 0.3rem 0.55rem;
  font-size: var(--fs-xs);
  cursor: pointer;
}

.nav-layout-toggle:hover {
  background: var(--sidebar-hover);
  color: var(--white);
}

/* 按壓態（nav-top 作用中）＝accent 實底，兩顆切換器由 app.js 同步。 */
.nav-layout-toggle.active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--white);
}

.nav-layout-toggle .nav-icon {
  font-size: 0.9rem;
}

/* 行動頂欄那顆：深底上的低調描邊款（樣式與品牌區共用，僅間距不同） */
.nav-layout-toggle-topbar {
  flex: 0 0 auto;
}

/* 左軌圖示欄／桌機左軌：品牌區切換器收成純圖示小方鈕（文案讓位）。
   641–1279px nav-top 無效（左軌語意），一律藏文案。 */
@media (min-width: 641px) and (max-width: 1279px) {
  .sidebar-brand .nav-layout-text {
    display: none;
  }
}

@media (min-width: 1280px) {
  body:not(.nav-top) .sidebar-brand .nav-layout-text {
    display: none;
  }
}

/* review P3-3：圖示欄的群組標籤是 font-size:0 分隔線 — 停用滑鼠命中，
   不可再誤觸切換（nav-top 下標籤是可見入口，不套用）。 */
@media (min-width: 641px) {
  body:not(.nav-top) .nav-group-label {
    pointer-events: none;
  }
}

/* ── nav-top 頂欄版型（≥1280px 才生效）──────────────────────────── */
@media (min-width: 1280px) {
  body.nav-top .app-shell {
    grid-template-columns: minmax(0, 1fr);
  }

  body.nav-top #sidebar {
    grid-column: 1;
    grid-row: 1;
    border-bottom: 1px solid var(--sidebar-line);
  }

  body.nav-top .app-main {
    grid-column: 1;
    grid-row: 2;
  }

  body.nav-top .sidebar-inner {
    position: static;
    max-height: none;
    overflow-y: visible;
    display: block;
  }

  /* 第一列：品牌（恢復文字）＋切換器貼右緣 */
  body.nav-top .sidebar-brand {
    justify-content: flex-start;
    padding: 0.6rem 1.1rem;
  }

  body.nav-top .brand-text {
    display: block;
  }

  body.nav-top .sidebar-brand .nav-layout-toggle {
    margin-left: auto;
  }

  /* 第二列：5 群組標籤橫排；display:contents 讓標籤上第一列、子分頁落
     第二列 — display:contents 的子項必須釘死列位置，否則 auto-placement
     會讓標籤與空 menu 交錯換行。 */
  body.nav-top #tabs {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, auto));
    justify-content: flex-start;
    column-gap: var(--space-5);
    padding: 0 1.1rem 0.55rem;
    overflow-x: auto;
  }

  body.nav-top .nav-group {
    display: contents;
  }

  body.nav-top .nav-group-label {
    grid-row: 1;
    margin: 0.5rem 0 0.35rem;
    font-size: 0.72rem; /* 蓋過圖示軌的 font-size:0 分隔線樣式 */
    letter-spacing: 0.14em;
    text-align: left;
    white-space: nowrap;
    cursor: pointer;
    border-top: none;
    padding-top: 0;
  }

  /* 圖示軌的 .nav-group + .nav-group 分隔線規則特異度 (0,3,0) 高於上面的
     (0,2,1) — nav-top 下必須以等位以上的 nav-top 上下文規則蓋回，否則後四個
     群組標籤殘留分隔線＋padding 下移（review P2-1）。margin 一併釘回。 */
  body.nav-top .nav-group + .nav-group .nav-group-label {
    grid-row: 1;
    margin: 0.5rem 0 0.35rem;
    border-top: none;
    padding-top: 0;
  }

  /* review P2-2：nav-top 下群組標籤是群組切換入口（app.js 加 role=button＋
     tabindex=0＋Enter/Space）；此處只負責可視互動樣式。 */
  body.nav-top .nav-group-label:focus-visible {
    outline: 1px solid var(--accent-light);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
  }

  body.nav-top .nav-group-label:hover {
    color: var(--white);
  }

  body.nav-top .nav-group.active > .nav-group-label {
    color: var(--accent-light);
  }

  body.nav-top .nav-menu {
    grid-row: 2;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 0.1rem;
  }

  body.nav-top .nav-menu button {
    width: auto;
    justify-content: center;
    padding: 0.45rem 0.7rem;
    white-space: nowrap;
  }

  /* 頂欄模式恢復項目文字（蓋過圖示軌的 .nav-text 隱藏規則） */
  body.nav-top .nav-text {
    display: inline;
  }

  body.nav-top .nav-icon {
    font-size: 1rem;
  }

  /* 子分頁第二列：只放作用中群組（點群組標籤切換，app.js 既有路徑） */
  body.nav-top .nav-group:not(.active) .nav-menu button {
    display: none;
  }

  /* 三欄工作檯：頂欄讓出橫向空間 — 列表窗格取回較寬比例（FPY／到期日
     全欄由上面的 body:not(.nav-top) 收合規則讓出），隊列窗格維持 200px。 */
  body.nav-top .wo-split,
  body.nav-top .so-split {
    grid-template-columns: minmax(0, 24fr) minmax(0, 18fr) minmax(0, 200px);
  }
}

/* ── R41 RBAC：登入卡＋角色導航過濾＋危險鈕角色藏匿 ──────────────────
   未登入（body.logged-out）首屏＝登入卡、應用殼層整個藏起；登入後角色
   決定「看得到什麼」：#tabs 按 nav-hidden 藏按鈕／空群組；baker 額外藏
   刪除／取消／改價／編輯入口（owner-only class 與既有危險鈕 class）——
   後端 403 為準，前端只是不顯示。 */

#login-view {
  display: none;
}

body.logged-out #login-view {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 60;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  background: var(--bg);
}

body.logged-out .app-shell {
  display: none;
}

.login-card {
  width: min(360px, 100%);
  box-shadow: 0 8px 24px var(--shadow-color);
}

.login-brand {
  margin: 0.25rem 0 0;
  font-size: 1.3rem;
  color: var(--accent);
}

.login-hint {
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

.login-demo {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  padding-top: var(--space-3);
  border-top: 1px dashed var(--line);
}

.login-demo-label {
  font-size: var(--fs-xs);
  color: var(--text-soft);
}

.login-demo button {
  font-size: var(--fs-xs);
  padding: 0.4rem 0.7rem;
  background: var(--surface-sunk);
  color: var(--text);
  border: 1px solid var(--line);
}

.login-demo button:hover {
  background: var(--surface-hover);
  border-color: var(--accent-light);
}

/* 側欄登入者列（whoami ＋ 登出） */
.sidebar-session {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin: 0 var(--space-3) var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--sidebar-line);
}

.whoami {
  font-size: var(--fs-xs);
  color: var(--sidebar-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.logout-btn {
  font-size: var(--fs-xs);
  padding: 0.35rem 0.7rem;
  background: var(--sidebar-hover);
  color: var(--sidebar-text);
  border: 1px solid var(--sidebar-line);
}

.logout-btn:hover {
  background: rgba(255, 255, 255, 0.16);
}

/* 角色導航過濾：藏按鈕；群組按鈕全藏時整組藏（app.js 同步 class） */
#tabs button.nav-hidden,
#tabs .nav-group.nav-hidden {
  display: none !important;
}

/* 危險鈕前端同步藏 — 後端 403 為準，前端只是不顯示。viewer 不藏（全讀
   展示，寫入吃後端 403）。
   baker（R41＋R43 品檢遷出）：刪除／取消／轉工單／收貨／列內編輯（含改價）
   與 owner-only 整張表單，另加品檢表單（quality-checks 歸 qc）。
   manager（R43）：除改價外全開 — 只藏刪除鈕與金額欄（.money-write）；
   取消／收貨／轉工單／release 都看得到也按得下去。
   purchaser（R43）：進貨/採購/原料/庫存可寫 — 藏刪除、取消與 owner-only
   表單（庫存手動入庫表單以 .write-inventory 豁免）；收貨鈕保留。
   qc（R43）：唯一可寫＝品檢 — 工單頁寫入入口全藏（投料區含 .wo-cons-rows
   與投料鈕 wrapper，review P3 併入 .wo-production-form 類），只留品檢表單。 */
body[data-role="baker"] .owner-only,
body[data-role="baker"] .delete-row,
body[data-role="baker"] .cancel-row,
body[data-role="baker"] .so-convert,
body[data-role="baker"] .po-receive,
body[data-role="baker"] .edit-row-btn,
body[data-role="baker"] .wo-qc-form,
body[data-role="baker"] .money-write {
  display: none !important;
}
body[data-role="manager"] .delete-row,
body[data-role="manager"] .money-write {
  display: none !important;
}
body[data-role="purchaser"] .delete-row,
body[data-role="purchaser"] .cancel-row,
body[data-role="purchaser"] .owner-only:not(.write-inventory),
body[data-role="purchaser"] #partner-form,
body[data-role="purchaser"] #partner-list .edit-row-btn {
  display: none !important;
}
body[data-role="qc"] .delete-row,
body[data-role="qc"] .cancel-row,
body[data-role="qc"] .owner-only,
body[data-role="qc"] .wo-transition,
body[data-role="qc"] .wo-output-form,
body[data-role="qc"] .wo-production-form {
  display: none !important;
}

/* ── R48 配方檢視（viewer）＋複製／變體＋衍生徽章 ──
   唯讀面板展開列沿用 history-row 的沉底底色（.history-box 提供縱向間距）。
   衍生徽章與來源鏈是 R48-b 的讀端：欄位缺失（舊後端）時前端整個不渲染，
   這裡只定義樣子。 */
.data-table tr.recipe-view-row td {
  background: var(--surface-sunk);
  border-bottom: 2px solid var(--accent-light);
}

.recipe-view-table {
  width: 100%;
  font-size: var(--fs-sm);
}

.recipe-view-meta,
.recipe-view-lineage {
  margin: 0;
  font-size: var(--fs-sm);
}

.recipe-view-lineage {
  color: var(--accent);
}

.recipe-derived-badge {
  display: inline-block;
  margin-left: 0.35rem;
  padding: 0.1rem 0.45rem;
  border-radius: 4px;
  background: var(--accent-light);
  color: #fff;
  font-size: var(--fs-xs);
}

/* 歷史面板內的版本快照檢視：與版本表以分隔線區隔 */
.recipe-version-view {
  border-top: 1px solid var(--line-warm);
  padding-top: var(--space-2);
}

/* R48 走查修正：配方列 8 個操作鈕曾把欄寬擠成一字一行直排 — 給操作欄
   一個下限寬度讓 .wo-actions 能橫排 wrap（約兩鈕一列），列高回正常；
   再大會反過來擠配方名稱欄（two-col 卡片寬度有限）。 */
#recipe-list .data-table td[data-label="操作"] {
  min-width: 13rem;
}

/* R48 走查修正續：.two-col 的 grid 子項預設 min-width:auto — 配方表
   （8 鈕操作欄）比卡片寬時會把整頁撐出橫移。比照 main>section 歸零，
   寬表由 #recipe-list 自己內部橫捲（≤640px 既有慣例推廣到全寬度）。 */
.two-col > * {
  min-width: 0;
}

#recipe-list {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}


/* ══ R57 夜色佈景（Croquettes 色系）═════════════════════════════════════
   參考 ~/projets/catinder 的 design-tokens（深藍黑底 #0B0E14/#151A23、
   磚紅主色 #CA4053→#B8563C、青綠圖表強調 #3DD6C3——AA 對比已於來源
   專案修訂）。映射到本專案 60 token：只覆蓋顏色類 token，間距/字級不動。
   包在 @media screen：列印恆為暖焙（print 用的 --white/--print-ink 不受
   影響）。切換存 localStorage「breadiary.theme」，由 index.html 首繪前
   inline script 套到 <html>（防閃），app.js 同步兩顆切換器。 */
@media screen {
  html[data-theme="night"] {
    color-scheme: dark; /* 表單控件/捲軸跟隨 */

    /* bark 側欄 → catinder 深藍黑系 */
    --sidebar-bg: #151a23;
    --sidebar-text: #f4f6fa;
    --sidebar-muted: rgba(244, 246, 250, 0.55);
    --sidebar-line: rgba(255, 255, 255, 0.1);
    --sidebar-hover: rgba(255, 255, 255, 0.07);
    --white: #ffffff; /* 鈕面文字（列印底在 print 端不受此塊影響） */

    /* crust 主色 → 沿 catinder 的雙色分離：文字用 primaryTint 慣例的淡粉
       （#e8abb3 對深底 ≈9.7:1），按鈕填色才用飽和磚紅 --accent-fill
       （白字 4.65:1）。暖焙把兩者共用一個 token 是棕色的特權——深底不行。 */
    --accent: #e8abb3;
    --accent-light: rgba(202, 64, 83, 0.28);
    --accent-fill: #ca4053;
    --accent-fill-hover: #b8563c;
    --chart-primary: #3dd6c3;
    --chart-secondary: #e8abb3;
    --chart-text: #9aa3b2;

    --btn-danger: #b8563c;
    --btn-danger-hover: #a94f61;

    /* cream 表面 → 深藍黑階梯 */
    --bg: #0b0e14;
    --card: #151a23;
    --surface-sunk: #1c2330;
    --surface-hover: #1a202b;
    --cream: #1c2330; /* R49 meta-chip 引用但未定義——夜色補深階 */

    /* ink → 貓卡文字階梯 */
    --text: #f4f6fa;
    --text-muted: #9aa3b2;
    --text-soft: #7e8898;

    /* lines → 白色半透明髮絲 */
    --line: rgba(255, 255, 255, 0.1);
    --line-warm: rgba(255, 255, 255, 0.08);
    --line-dash: rgba(255, 255, 255, 0.12);
    --line-input: rgba(255, 255, 255, 0.18);
    --line-soft: rgba(255, 255, 255, 0.07);

    /* semantic：深底半透明 + 亮文字 */
    --success-text: #7bd88f;  --success-bg: rgba(80, 200, 120, 0.16);
    --warning-text: #f5c065;  --warning-bg: rgba(245, 158, 11, 0.16);
    --danger-text: #ff8a9b;   --danger-bg: rgba(255, 84, 112, 0.16);
    --info-text: #7eb3e8;     --info-bg: rgba(90, 150, 220, 0.16);
    --warning-soft: rgba(245, 158, 11, 0.1);
    --warning-soft-hover: rgba(245, 158, 11, 0.16);
    --draft-text: #b3bccc;    --draft-bg: rgba(154, 163, 178, 0.14);

    --btn-disabled: #4a5160;
    --btn-neutral: #6b7280;
    --btn-neutral-hover: #8b93a1;

    --shadow-color: rgba(0, 0, 0, 0.4);
    --shadow-card: 0 1px 4px rgba(0, 0, 0, 0.4);
    --scrim: rgba(4, 6, 10, 0.6);
  }

  /* --white 雙重用途的定點疏導：select/幽靈鈕/列內選單面板改吃卡片底；
     表單控件 UA 預設白底也一併壓深。 */
  html[data-theme="night"] body input,
  html[data-theme="night"] body select,
  html[data-theme="night"] body textarea {
    background: var(--card);
    color: var(--text);
  }
  html[data-theme="night"] body button.btn-ghost {
    background: var(--card);
    color: var(--accent);
    border-color: var(--line-input);
  }
  html[data-theme="night"] body button.btn-ghost:hover {
    background: var(--accent);
    color: #fff;
  }
  html[data-theme="night"] body .row-menu-items {
    background: var(--card);
  }
  html[data-theme="night"] body .row-menu-items button {
    background: none;
    color: var(--text);
  }
  html[data-theme="night"] body .row-menu-items button:hover {
    background: var(--accent);
    color: #fff;
  }
  /* 列印鈕浮層陰影加深（白底陰影在深底看不見） */
  html[data-theme="night"] body .row-menu-items {
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
  }
  /* 瓷磚數值＝資料第一 → 近白（粉紅 tint 只留給品牌/互動元素）。
     tile-neg 的警示磚維持自己的語義色對。 */
  html[data-theme="night"] body .tile p {
    color: var(--text);
  }
  html[data-theme="night"] body .tile.tile-neg p,
  html[data-theme="night"] body .tile.tile-neg h3 {
    color: var(--danger-text);
  }
  /* QC Gate 綠卡上的文字：紅字對深綠底對比不足 → 近白＋停止鈕保持磚紅 */
  html[data-theme="night"] body .tile.status-in_progress h3,
  html[data-theme="night"] body .tile.status-in_progress p:not(.hint) {
    color: var(--text);
  }
  /* 按鈕填色：base button 規則吃 --accent（現在是淡粉文字色）——夜色下
     以 :where（零特異度）改為磚紅填色＋白字；class 鈕（ghost/danger/
     status）照樣贏過這條。hover 走 --accent-light 半透明紅洗＝變亮。 */
  html[data-theme="night"] body :where(button) {
    background: var(--accent-fill);
    color: #fff;
  }
  html[data-theme="night"] body :where(button):hover {
    background: var(--accent-light);
    color: #fff;
  }
/* ── R59 確認對話框（#12 原生 confirm 替代）── */
.confirm-overlay {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
}

.confirm-box {
  background: var(--card);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
  padding: 1.25rem 1.5rem;
  max-width: 24rem;
  width: calc(100% - 2rem);
}

.confirm-message {
  margin: 0 0 1rem;
  font-size: var(--fs-base);
  line-height: 1.5;
}

.confirm-actions {
  display: flex;
  gap: 0.5rem;
  justify-content: flex-end;
}

.confirm-ok {
  background: var(--accent);
}

.confirm-ok.confirm-danger {
  background: var(--btn-danger);
}

.confirm-ok.confirm-danger:hover {
  background: var(--btn-danger-hover);
}

  html[data-theme="night"] body .wo-transition,
  html[data-theme="night"] body .po-receive,
  html[data-theme="night"] body .restock-scale {
    color: #fff;
  }
  /* R59 對話框：取消＝幽靈樣式；破壞性確認＝危險紅（:where 的磚紅填色
     會蓋掉 .btn-ghost/.confirm-danger —— 以更高特異度奪回）。 */
  html[data-theme="night"] body .confirm-overlay .confirm-cancel {
    background: var(--card);
    color: var(--accent);
    border: 1px solid var(--line-input);
  }
  html[data-theme="night"] body .confirm-overlay .confirm-ok.confirm-danger {
    background: var(--btn-danger);
  }
  /* R62 夜色語義分離：accent-fill（#ca4053）與 btn-danger（#b8563c）在深底
     幾乎同色（accent-fill-hover 甚至是同一個色號），主要 CTA 與破壞動作
     無法一眼區分 — 破壞鈕改幽靈描邊（透明底＋danger-text 邊框文字，
     hover 墊 danger-bg），把「實心紅」讓給品牌 accent。暖焙維持實底。
     不加 .data-table 前綴：出貨詳情的取消鈕（.wo-actions 是表格兄弟節點）
     也要幽靈化（ReviewR62 #2）。 */
  html[data-theme="night"] body .delete-row,
  html[data-theme="night"] body .cancel-row,
  html[data-theme="night"] body .remove-recipe-ing,
  html[data-theme="night"] body .confirm-overlay .confirm-ok.confirm-danger {
    background: transparent;
    color: var(--danger-text);
    border: 1px solid var(--danger-text);
  }
  html[data-theme="night"] body .delete-row:hover,
  html[data-theme="night"] body .cancel-row:hover,
  html[data-theme="night"] body .remove-recipe-ing:hover,
  html[data-theme="night"] body .confirm-overlay .confirm-ok.confirm-danger:hover {
    background: var(--danger-bg);
  }
  html[data-theme="night"] body .row-menu-items .delete-row {
    /* 選單項維持純文字樣式 — 不繼承幽靈描邊的邊框盒子（ReviewR62 #3） */
    background: none;
    border: none;
    color: var(--danger-text);
  }
  html[data-theme="night"] body .row-menu-items .delete-row:hover {
    background: var(--danger-bg);
  }
}
