/* ─── design system tokens — OpenAI. Verbatim :root contract. ─────── */
:root {
  /* ─── Surface ──────────────────────────────────────────────────── */
  --bg:           #ffffff;
  --surface:      #f5f5f5;             /* pearl — card surface, elevated panel */
  --surface-warm: #fafafa;             /* mist — section break, footer */

  /* ─── Foreground ───────────────────────────────────────────────── */
  --fg:   #0d0d0d;                     /* ink black — primary text, brand mark */
  --fg-2: #1a1a1a;                     /* soft black — alternative headings */
  --muted: #6e6e6e;                    /* slate — secondary text, captions */
  --meta:  #9b9b9b;                    /* ash — tertiary, placeholder */

  /* ─── Border ───────────────────────────────────────────────────── */
  --border:      #e5e5e5;             /* hairline — standard separator */
  --border-soft: #ededed;             /* card outline on white surface */

  /* ─── Accent ───────────────────────────────────────────────────── */
  --accent:        #10a37f;           /* OpenAI Teal — links, highlight, CTA */
  --accent-on:     #ffffff;
  --accent-hover:  #0a7a5e;           /* teal deep — hover/pressed */
  --accent-active: color-mix(in oklab, var(--accent), black 14%);

  /* ─── Semantic ─────────────────────────────────────────────────── */
  --success: #10a37f;                 /* teal — success path */
  --warn:    #f5a623;                 /* amber — advisory */
  --danger:  #ef4146;                 /* error — validation, destructive */

  /* ─── Typography ───────────────────────────────────────────────── */
  --font-display: "Signifier", "Source Serif Pro", Georgia, ui-serif, serif;
  --font-body:    "Söhne", "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono:    "Söhne Mono", ui-monospace, "JetBrains Mono", Menlo, Consolas, monospace;

  --text-xs:   12px;                  /* label — eyebrow, uppercase nav */
  --text-sm:   13px;                  /* caption — metadata, badges */
  --text-base: 16px;                  /* body — standard reading */
  --text-lg:   18px;                  /* body large — lede paragraphs */
  --text-xl:   20px;                  /* h3 — sub-section */
  --text-2xl:  28px;                  /* h2 — section heading */
  --text-3xl:  40px;                  /* h1 — page heading */
  --text-4xl:  56px;                  /* display — Signifier editorial hero */

  --leading-body:     1.65;
  --leading-tight:    1.08;
  --tracking-display: -0.02em;

  /* ─── Spacing ──────────────────────────────────────────────────── */
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  20px;
  --space-6:  24px;
  --space-8:  32px;
  --space-12: 48px;
  --space-16: 64px;

  --section-y-desktop: 96px;
  --section-y-tablet:  64px;
  --section-y-phone:   48px;

  /* ─── Radius ───────────────────────────────────────────────────── */
  --radius-sm:   12px;
  --radius-md:   16px;
  --radius-lg:   16px;
  --radius-pill: 9999px;

  /* ─── Elevation ────────────────────────────────────────────────── */
  --elev-flat:   none;
  --elev-ring:   0 0 0 1px var(--border);
  --elev-raised: 0 4px 16px rgba(13, 13, 13, 0.06);

  /* ─── Focus ────────────────────────────────────────────────────── */
  --focus-ring: 0 0 0 3px rgba(16, 163, 127, 0.12);

  /* ─── Motion ───────────────────────────────────────────────────── */
  --motion-fast:   150ms;
  --motion-base:   220ms;
  --ease-standard: cubic-bezier(0.16, 1, 0.3, 1);

  /* ─── Layout ───────────────────────────────────────────────────── */
  --container-max:            1200px;
  --container-gutter-desktop: 48px;
  --container-gutter-tablet:  24px;
  --container-gutter-phone:   24px;
}

/* ─── reset & base ──────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
}
img, svg { display: block; max-width: 100%; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font: inherit; cursor: pointer; }
h1, h2, h3, h4 { font-family: var(--font-body); line-height: 1.25; margin: 0; font-weight: 600; }
h1 { font-size: var(--text-2xl); letter-spacing: -0.01em; }
h2 { font-size: var(--text-xl); }
h3 { font-size: var(--text-lg); }
p  { margin: 0; text-wrap: pretty; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-sm); }
.ds-table tbody tr:focus-visible { outline-offset: -2px; border-radius: 0; }

/* ─── layout primitives ─────────────────────────────────────────── */
.container {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-gutter-desktop);
}
.row { display: flex; align-items: center; gap: var(--space-3); }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); }
.stack > * + * { margin-top: var(--space-3); }
.meta { font-size: var(--text-xs); color: var(--muted); line-height: 1.45; }
.num  { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.mono { font-family: var(--font-mono); }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ─── app header (mirrors ops-shell-header) ─────────────────────── */
.app-header {
  position: sticky; top: 0; z-index: 30;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.app-header-bar { display: flex; align-items: center; gap: var(--space-6); padding-block: var(--space-3); }
.brand { display: inline-flex; align-items: baseline; gap: var(--space-2); color: var(--fg); font-weight: 600; }
.brand strong {
  font-size: var(--text-xs); letter-spacing: 0.08em;
  background: var(--fg); color: var(--bg);
  padding: 4px 8px; border-radius: var(--radius-pill);
}
.brand span { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.06em; color: var(--muted); }
.mainnav { display: flex; gap: var(--space-1); margin-inline-end: auto; flex-wrap: wrap; }
.mainnav button {
  background: transparent; border: 1px solid transparent; border-radius: var(--radius-pill);
  color: var(--muted); padding: 6px 14px; font-size: var(--text-sm);
  transition: color var(--motion-fast) var(--ease-standard), background var(--motion-fast) var(--ease-standard);
}
.mainnav button:hover { color: var(--fg); background: var(--surface-warm); }
.mainnav button[aria-current="page"] { color: var(--bg); font-weight: 500; background: var(--fg); border-color: var(--fg); }
.session { display: flex; align-items: center; gap: var(--space-3); }

/* ─── toolbar ───────────────────────────────────────────────────── */
.toolbar { background: var(--surface-warm); border-bottom: 1px solid var(--border); }
.toolbar-inner { display: flex; align-items: center; gap: var(--space-4); padding-block: var(--space-3); flex-wrap: wrap; }
.toolbar-title { font-size: var(--text-lg); font-weight: 600; margin-inline-end: var(--space-2); }
.toolbar-spacer { margin-inline-start: auto; }

/* ─── controls ──────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: 8px 16px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); background: var(--bg); color: var(--fg);
  font-size: var(--text-sm); font-weight: 500; white-space: nowrap;
  transition: background var(--motion-fast) var(--ease-standard), border-color var(--motion-fast) var(--ease-standard), color var(--motion-fast) var(--ease-standard);
}
.btn:hover { background: var(--surface-warm); border-color: color-mix(in oklab, var(--border), black 12%); }
.btn:disabled, .btn-primary:disabled {
  background: var(--surface); color: var(--muted); border-color: var(--border);
  cursor: not-allowed;
}
.btn:hover { text-decoration: none; }
.btn-primary { background: var(--fg); color: var(--bg); border-color: var(--fg); }
.btn-primary:hover { background: var(--fg-2); color: var(--bg); border-color: var(--fg-2); }
.btn-outline { background: var(--bg); color: var(--accent); }
.btn-outline:hover { background: var(--accent); color: var(--accent-on); border-color: var(--accent); }
.btn-sm { padding: 4px 12px; font-size: var(--text-xs); border-radius: var(--radius-pill); }

.input, select.input {
  padding: 6px 12px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--bg); color: var(--fg); font: inherit; font-size: var(--text-sm);
}
.input::placeholder { color: var(--muted); }
.input:focus { border-color: var(--accent); box-shadow: var(--focus-ring); outline: none; }
.field-inline { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); color: var(--muted); }
.search { min-width: 260px; }

/* ─── box / panel ───────────────────────────────────────────────── */
.box { border: 1px solid var(--border-soft); border-radius: var(--radius-md); background: var(--bg); overflow: hidden; }
.box-header {
  background: var(--bg); border-bottom: 1px solid var(--border);
  padding: var(--space-4) var(--space-5);
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
}
.box-header h2, .box-header h3 { font-size: var(--text-base); font-weight: 600; }
.box-body { padding: var(--space-5); }
.box-row { padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border-soft); }
.box-row:last-child { border-bottom: 0; }
.box-footer { padding: var(--space-3) var(--space-5); background: var(--surface-warm); border-top: 1px solid var(--border); font-size: var(--text-xs); color: var(--muted); }

/* ─── kpi strip ─────────────────────────────────────────────────── */
.kpi-grid { display: grid; grid-template-columns: repeat(6, 1fr); gap: var(--space-3); }
.kpi { border: 1px solid var(--border-soft); border-radius: var(--radius-md); padding: var(--space-3) var(--space-5); background: var(--bg); }
.kpi-label { font-size: var(--text-xs); color: var(--muted); }
.kpi-value { font-variant-numeric: tabular-nums; font-size: var(--text-2xl); font-weight: 500; line-height: 1.2; letter-spacing: -0.01em; margin-top: var(--space-1); color: var(--fg); }
.kpi-value .unit { font-size: var(--text-sm); font-weight: 400; color: var(--muted); margin-inline-start: 2px; letter-spacing: 0; }
.kpi-note { font-size: var(--text-xs); color: var(--meta); margin-top: var(--space-1); line-height: 1.45; }
.kpi.is-alert .kpi-label::before, .kpi.is-warn .kpi-label::before {
  content: ""; display: inline-block; width: 6px; height: 6px; border-radius: var(--radius-pill);
  margin-inline-end: 6px; vertical-align: middle;
}
.kpi.is-alert .kpi-label::before { background: var(--danger); }
.kpi.is-warn .kpi-label::before { background: var(--warn); }

/* ─── state pills ───────────────────────────────────────────────── */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: var(--radius-pill);
  font-size: var(--text-xs); font-weight: 500; white-space: nowrap;
  background: var(--surface); color: var(--fg); border: 1px solid transparent;
}
.pill::before { content: ""; width: 6px; height: 6px; border-radius: var(--radius-pill); background: var(--meta); }
.pill-ok::before      { background: var(--accent); }
.pill-warn::before    { background: var(--warn); }
.pill-danger::before  { background: var(--danger); }
.pill-ink::before     { background: var(--fg); }
.pill-neutral::before { background: var(--meta); }
.pill-quiet { background: var(--bg); color: var(--muted); border-color: var(--border); }
.pill-quiet::before { display: none; }

.counter { margin-inline-start: 6px; color: var(--meta); font-variant-numeric: tabular-nums; font-size: var(--text-xs); }
button[aria-selected="true"] .counter, button[aria-current="page"] .counter { color: inherit; }

/* ─── underline tabs ────────────────────────────────────────────── */
.tabs { display: flex; gap: var(--space-1); border-bottom: 1px solid var(--border); overflow-x: auto; }
.tabs button {
  background: transparent; border: 0; border-bottom: 2px solid transparent;
  padding: var(--space-3) var(--space-3); color: var(--muted); font-size: var(--text-sm);
  white-space: nowrap; border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  transition: color var(--motion-fast) var(--ease-standard), background var(--motion-fast) var(--ease-standard);
}
.tabs button:hover { color: var(--fg); background: var(--surface-warm); }
.tabs button[aria-selected="true"] { color: var(--fg); font-weight: 600; border-bottom-color: var(--fg); }

/* ─── data table ────────────────────────────────────────────────── */
/* 一屏优先：表格超过一定高度就自己滚，不把整页顶长；表头吸顶 */
.table-scroll { overflow: auto; max-height: min(46vh, 430px); }
/* 订单进度这张表是主视图，多给点高度，一屏放到 10 行不用滚 */
[data-od-id="order-board"] .table-scroll { max-height: min(75vh, 600px); }
.ds-table thead th { position: sticky; top: 0; z-index: 1; }
.ds-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.ds-table th, .ds-table td { padding: var(--space-2) var(--space-4); text-align: left; border-bottom: 1px solid var(--border-soft); vertical-align: middle; }
.ds-table thead th { background: var(--bg); color: var(--muted); font-weight: 500; font-size: var(--text-xs); letter-spacing: 0.04em; white-space: nowrap; border-bottom: 1px solid var(--border); }
.ds-table tbody tr { transition: background var(--motion-fast) var(--ease-standard); }
.ds-table tbody tr:hover { background: var(--surface-warm); }
#order-table tbody tr { cursor: pointer; }
.ds-table tbody tr:last-child td { border-bottom: 0; }
.ds-table .num-col { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
.ds-table .date-col { white-space: nowrap; }

/* order table: 顺位调整 + inline ship-date edit */
/* 行首「第几个做」+ 上下移。常驻但很淡，鼠标进到行里才醒过来。 */
#order-table td .cell-main.mono { display: inline-flex; align-items: center; }
#order-table .rank { display: inline-flex; align-items: center; gap: var(--space-2); margin-inline-end: var(--space-3); }
#order-table .rank-no {
  min-width: 12px; text-align: right; font-size: var(--text-xs); color: var(--meta);
  font-variant-numeric: tabular-nums; font-family: var(--font-body);
}
#order-table tbody tr:hover .rank-no { color: var(--fg); }
#order-table .rank-btns { display: grid; gap: 1px; }
#order-table .rank-btns button {
  display: grid; place-items: center; width: 20px; height: 13px; padding: 0;
  border: 0; background: transparent; color: color-mix(in oklab, var(--meta), white 40%);
  border-radius: 4px; cursor: pointer;
  transition: color var(--motion-fast) var(--ease-standard), background var(--motion-fast) var(--ease-standard);
}
#order-table tbody tr:hover .rank-btns button:not(:disabled) { color: var(--muted); }
#order-table .rank-btns button:hover:not(:disabled) { background: var(--fg); color: var(--bg); }
#order-table .rank-btns button:disabled { opacity: 0.25; cursor: default; }
#order-table .rank-btns button:focus-visible { outline: none; box-shadow: var(--focus-ring); background: var(--surface); color: var(--fg); }
.eta-input {
  font: inherit; font-family: var(--font-mono); font-size: var(--text-xs); color: var(--muted);
  background: transparent; border: 1px solid transparent; border-radius: var(--radius-sm);
  padding: 3px 4px; margin: -3px -4px; cursor: pointer;
}
.eta-input:hover { border-color: var(--border); background: var(--surface-warm); color: var(--fg); }
.eta-input:focus-visible { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); background: var(--bg); color: var(--fg); }
/* 订单信息栏的就地编辑：平时看着就是一行右对齐的字，hover 才露边框。
   和 .eta-input 同一套观感，只是这些在 <dl> 里，要跟着 dd 右对齐。 */
.fact-input {
  font: inherit; font-size: var(--text-sm); color: var(--fg); text-align: right;
  background: transparent; border: 1px solid transparent; border-radius: var(--radius-sm);
  padding: 3px 4px; margin: -3px -4px; cursor: pointer; max-width: 100%;
}
.fact-input:hover { border-color: var(--border); background: var(--surface-warm); }
.fact-input:focus-visible { outline: none; border-color: var(--accent); box-shadow: var(--focus-ring); background: var(--bg); cursor: text; }
.fact-input[type="number"] { width: 5em; }
/* 下拉框被 flex 挤窄会把颜色名切掉（「White Birc」）。撑到内容宽，
   窄的时候靠 .deflist div 的 flex-wrap 整行换行，切字比换行难看得多。 */
select.fact-input { cursor: pointer; min-width: max-content; }
.th-sort {
  background: none; border: 0; padding: 0; font: inherit; color: var(--muted);
  letter-spacing: inherit; cursor: pointer; display: inline-flex; align-items: center; gap: 4px;
}
.th-sort:hover { color: var(--fg); }
.th-sort::after { content: "\2195"; color: var(--meta); font-size: 11px; }
th[aria-sort="ascending"] .th-sort, th[aria-sort="descending"] .th-sort { color: var(--fg); }
th[aria-sort="ascending"] .th-sort::after  { content: "\2191"; color: var(--fg); }
th[aria-sort="descending"] .th-sort::after { content: "\2193"; color: var(--fg); }
.cell-main { font-weight: 500; }
.cell-sub { font-size: var(--text-xs); color: var(--muted); margin-top: 2px; }
/* 副标题跟主标题同一行，省掉整表一行的高度 */
.cell-inline { font-size: var(--text-xs); color: var(--muted); font-family: var(--font-body); margin-inline-start: var(--space-3); }
/* 交期后面的天数：只给数字，负数就是已经逾期，红的一眼看得见 */
.eta-days { margin-inline-start: var(--space-2); color: var(--muted); }
.eta-days[data-over] { color: var(--danger); }
/* 现有量：红 = 已经跌到安全线以下。安全线本身不上表，红不红就是它的全部作用 */
.stock-qty[data-low] { color: var(--danger); font-weight: 600; }

/* ─── progress / load bars ──────────────────────────────────────── */
.bar { height: 6px; border-radius: var(--radius-pill); background: color-mix(in oklab, var(--fg), white 90%); overflow: hidden; }
.bar > span { display: block; height: 100%; background: var(--fg); border-radius: var(--radius-pill); }
.bar.is-done > span { background: var(--fg); }
.bar.is-over > span { background: var(--danger); }
.bar.is-idle > span { background: var(--border); }
.load { display: grid; gap: 5px; }
.load-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2); font-size: var(--text-xs); }
.load-head strong { font-variant-numeric: tabular-nums; font-weight: 500; }
.load-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--space-6); }
.load-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-6); }

/* ─── machine counter cards ─────────────────────────────────────── */
.machine-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3); }
.machine { border: 1px solid var(--border-soft); border-radius: var(--radius-md); overflow: hidden; }
.machine-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); padding: var(--space-3) var(--space-4); background: var(--bg); border-bottom: 1px solid var(--border-soft); font-size: var(--text-sm); font-weight: 600; }
.machine-body { padding: var(--space-4); display: grid; gap: var(--space-2); }
.machine-total { font-variant-numeric: tabular-nums; font-size: var(--text-2xl); font-weight: 500; line-height: 1.2; letter-spacing: -0.01em; }
.machine-total .unit { font-size: var(--text-xs); color: var(--muted); font-weight: 400; margin-inline-start: 4px; }
.machine-delta { font-size: var(--text-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.machine-sub { display: flex; justify-content: space-between; font-size: var(--text-xs); color: var(--muted); border-top: 1px solid var(--border-soft); padding-top: var(--space-2); }

/* ─── stacked bar chart ─────────────────────────────────────────── */
.stackbar { display: flex; height: 10px; border-radius: var(--radius-pill); overflow: hidden; }
.stackbar > span { display: block; }
.stackbar .seg-effective { background: var(--accent); }
.stackbar .seg-zero { background: color-mix(in oklab, var(--fg), white 88%); }
.legend { display: flex; gap: var(--space-4); font-size: var(--text-xs); color: var(--muted); flex-wrap: wrap; }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
.legend .k-effective { background: var(--accent); }
.legend .k-zero { background: color-mix(in oklab, var(--fg), white 88%); }

/* column chart — checkpoint deltas */
.colchart { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); align-items: end; height: 152px; padding-top: 20px; }
.colchart .col { display: grid; grid-template-rows: 1fr auto; height: 100%; gap: 6px; justify-items: center; }
.colchart .col-track { display: flex; align-items: flex-end; width: 100%; height: 100%; }
.colchart .col-fill { width: 100%; background: var(--fg); border-radius: 4px 4px 0 0; position: relative; min-height: 2px; }
.colchart .col-fill[data-zero="true"] { background: color-mix(in oklab, var(--fg), white 88%); }
.colchart .col-val { position: absolute; top: -20px; left: 0; right: 0; text-align: center; font-variant-numeric: tabular-nums; font-size: var(--text-xs); color: var(--fg); }
.colchart .col-label { font-variant-numeric: tabular-nums; font-size: var(--text-xs); color: var(--muted); }

/* ─── two-pane layouts ──────────────────────────────────────────── */
.pane-2-1 { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: var(--space-6); align-items: start; }
.pane-1-1 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); align-items: start; }
.page { padding-block: var(--space-6) var(--space-8); display: grid; gap: var(--space-6); }
[hidden] { display: none !important; }

/* ─── definition rows ───────────────────────────────────────────── */
.deflist { display: grid; gap: 0; }
.deflist div { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-2) 0; border-bottom: 1px solid var(--border-soft); font-size: var(--text-sm); }
.deflist div:last-child { border-bottom: 0; }
.deflist dt { color: var(--muted); font-size: var(--text-xs); margin: 0; }
.deflist dd { margin: 0; font-variant-numeric: tabular-nums; text-align: right; }

/* ─── 锁屏 ─────────────────────────────────────────────────────── */

/* ─── 轻提示（白字墨黑底 19:1）─────────────────────────────────── */
/* 顶部居中。落在 sticky 表头下面一点：那条 bar 大约 60px 高，
   压在上面会把导航挡掉半截。 */
.toast {
  position: fixed; inset-block-start: 76px; inset-inline-start: 50%;
  transform: translateX(-50%); z-index: 60;
  background: var(--fg); color: var(--bg);
  padding: var(--space-3) var(--space-5); border-radius: var(--radius-pill);
  font-size: var(--text-sm); box-shadow: var(--elev-raised);
}

/* ─── 操作记录 ─────────────────────────────────────────────────── */
/* 分页条：订单表和 Log 共用，只有一页时整条 hidden */
.pager {
  display: flex; align-items: center; justify-content: center; gap: var(--space-3);
  padding: var(--space-3) var(--space-5); border-top: 1px solid var(--border-soft);
  font-size: var(--text-xs); color: var(--muted);
}

.log-row {
  display: flex; align-items: baseline; gap: var(--space-4);
  padding: var(--space-3) var(--space-5); border-bottom: 1px solid var(--border-soft);
  font-size: var(--text-sm);
}
.log-row:last-child { border-bottom: 0; }
.log-row time { font-variant-numeric: tabular-nums; color: var(--meta); font-size: var(--text-xs); flex: none; }
#order-page-content .box-body p { font-size: var(--text-sm); line-height: 1.6; }

/* ─── 建单表单 / 资料上传 ───────────────────────────────────────── */
/* align-content:start —— 不然同一行里带说明和不带说明的两格会把输入框拉得高低不齐 */
.form-field { display: grid; gap: var(--space-2); align-content: start; font-size: var(--text-sm); color: var(--muted); }
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-5); }
.form-wide { grid-column: 1 / -1; }
.form-grid .form-field .meta { line-height: 1.4; }
.upload-slot { display: grid; gap: var(--space-2); }
.upload-slot p { font-size: var(--text-sm); }
.upload-slot .btn { cursor: pointer; }
@media (max-width: 700px) { .form-grid { grid-template-columns: minmax(0, 1fr); } }

/* ─── 工序进度（订单详情页）─────────────────────────────────────
 * 一行一道工序，只回答两件事：现在什么状态、开工要的料和单据齐没齐。
 * 数量和进度回写都在「工序追踪」里做 —— 同一个数字不放两页。      */
.step-list { list-style: none; margin: 0; padding: 0; }
.step-row { display: grid; gap: var(--space-3); padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border-soft); }
.step-row:last-child { border-bottom: 0; }
.step-row[data-s="doing"] { background: color-mix(in oklab, var(--accent), white 96%); }
.step-row-head { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.step-idx {
  width: 20px; height: 20px; flex: none; border-radius: var(--radius-pill);
  display: grid; place-items: center; font-size: 11px; font-variant-numeric: tabular-nums;
  background: var(--surface); color: var(--muted);
}
.step-row[data-s="done"]  .step-idx { background: var(--fg); color: var(--bg); }
.step-row[data-s="doing"] .step-idx { background: var(--accent); color: var(--accent-on); }
.step-name { font-weight: 500; }
.step-note { font-size: var(--text-xs); color: var(--muted); }
/* 资料和材料：一行两项（开料的门板 / 柜体 / CNC 正好三行），对勾就是开关。 */
.step-check { list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2) var(--space-5);
  margin-inline-start: calc(20px + var(--space-3)); font-size: var(--text-xs); }
@media (max-width: 1100px) { .step-check { grid-template-columns: minmax(0, 1fr); } }
.step-check > li { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: var(--space-2); }
.step-check .ready-flag { width: 18px; height: 18px; flex: none; }
.step-check .ready-flag svg { width: 12px; height: 12px; }
.check-flag { padding: 0; border: 0; background: none; line-height: 0; cursor: pointer; border-radius: var(--radius-pill); }
.check-flag:hover .ready-flag { outline: 1px solid var(--border); }
.check-flag:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.bar.is-doing > span { background: var(--accent); }
.bar.is-done  > span { background: var(--fg); }
.step-input {
  width: 72px; padding: 4px var(--space-2); font-size: var(--text-sm);
  font-variant-numeric: tabular-nums; text-align: right;
}
.step-input:disabled { background: var(--surface); color: var(--muted); cursor: not-allowed; }
/* 数量回写跟着动作一起靠右，中间那段名字/状态自己撑开 */
.step-qty { margin-inline-start: auto; display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.step-qty .step-input { width: 5.5rem; }
.step-act { display: inline-flex; gap: var(--space-2); }

/* ─── 订单详情整页 ──────────────────────────────────────────────── */
#order-back, #create-back { justify-self: start; }
#order-page-content { display: grid; gap: var(--space-6); }
.order-page-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--space-6); flex-wrap: wrap;
}
.order-page-head h1 { font-size: var(--text-3xl); line-height: 1.15; letter-spacing: -0.01em; margin-block: var(--space-1); }
.stack-boxes { display: grid; gap: var(--space-6); align-content: start; }
/* 时间轴多一列放「回写进度」，按钮列宽固定，避免各行按钮左右错开 */
.mat-table th { font-size: var(--text-xs); color: var(--muted); font-weight: 500; text-align: left; padding-bottom: var(--space-2); border-bottom: 1px solid var(--border); }
.mat-table th:last-child, .mat-table td:last-child { text-align: right; }
.mat-table td:nth-child(2), .mat-table th:nth-child(2) { white-space: nowrap; }

.empty { padding: var(--space-12) var(--space-4); text-align: center; color: var(--muted); font-size: var(--text-sm); }
.empty.is-inline { padding: var(--space-4) var(--space-5); text-align: left; font-size: var(--text-xs); }


/* ─── step track — 开料 · 封边 · 六面钻 · 组装 · 包装 ─────────────── */
.track, .track-head { display: grid; grid-template-columns: repeat(5, 1fr); gap: 4px; min-width: 236px; }
.track i { display: block; height: 8px; border-radius: var(--radius-pill); background: var(--surface); }
.track i[data-s="done"]   { background: var(--fg); }
.track i[data-s="doing"]  { background: var(--accent); }
.track-head span { font-size: var(--text-xs); color: var(--muted); letter-spacing: 0; text-align: center; font-weight: 400; }

/* ─── material kit chips — 板 / 门 / 金 ─────────────────────────── */
#f-board-stock[data-bad="1"] { color: var(--danger); }
/* binary 有/没有 readiness flag — green when ready, red otherwise. 订单表的材料齐/不齐、订单信息的资料齐/不齐都用它。 */
/* 备齐 = 绿对勾，没备齐 = 红叉。 */
.ready-flag { display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: var(--radius-pill); }
.ready-flag[data-ok="true"]  { color: var(--accent-hover); background: color-mix(in oklab, var(--accent), white 86%); }
.ready-flag[data-ok="false"] { color: color-mix(in oklab, var(--danger), black 20%); background: color-mix(in oklab, var(--danger), white 88%); }

/* ─── pipeline — 5 道工序既是概览也是页签 ───────────────────────── */
.pipeline { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--space-3); }
.pipe { text-align: left; background: var(--bg); border: 1px solid var(--border-soft); border-radius: var(--radius-md); padding: var(--space-4) var(--space-5); display: grid; gap: var(--space-2); align-content: start; transition: border-color var(--motion-fast) var(--ease-standard), background var(--motion-fast) var(--ease-standard); }
.pipe:hover { border-color: color-mix(in oklab, var(--border), black 16%); background: var(--surface-warm); }
.pipe[aria-selected="true"] { border-color: var(--fg); box-shadow: inset 0 0 0 1px var(--fg); background: var(--bg); }
.pipe-name { font-size: var(--text-sm); font-weight: 600; color: var(--fg); display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.pipe-value { font-size: var(--text-2xl); font-weight: 500; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; line-height: 1.2; color: var(--fg); }
.pipe-value .unit { font-size: var(--text-xs); color: var(--muted); margin-inline-start: 3px; letter-spacing: 0; }
.pipe-meta { font-size: var(--text-xs); color: var(--meta); line-height: 1.5; display: grid; gap: 2px; }

/* ─── inline progress ───────────────────────────────────────────── */
#step-side { display: grid; gap: var(--space-6); align-content: start; }
.progress-num { display: inline-flex; align-items: center; gap: var(--space-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
#step-side .box-body { display: grid; grid-template-columns: 2fr 3fr; gap: var(--space-6); align-items: center; }
@media (max-width: 900px) { #step-side .box-body { grid-template-columns: 1fr; } }
.progress-num .bar { width: 48px; flex: none; }

/* 密排统计条：一行说完三类料的欠账，替掉三张 KPI 卡 */
/* ─── 提货 ─────────────────────────────────────────────────────── */
/* 导航上的待办计数。不主动戳一下，没人会想起来点开「提货」看有没有人在等批。 */
.mainnav .badge {
  display: inline-block; margin-inline-start: 6px; min-width: 17px; padding: 0 5px;
  border-radius: 999px; background: var(--danger); color: #fff;
  font-size: 11px; line-height: 17px; text-align: center; font-variant-numeric: tabular-nums;
}
.mainnav button[aria-current="page"] .badge { background: var(--bg); color: var(--danger); }
.pk-slot { font-variant-numeric: tabular-nums; white-space: nowrap; }
.pk-slot[data-bad] { color: var(--danger); }
.pk-note { display: block; color: var(--muted); font-size: var(--text-xs); margin-top: 2px; max-width: 34ch; }
dialog {
  border: 1px solid var(--border); border-radius: 10px; padding: 0;
  width: min(460px, calc(100% - 32px)); background: var(--bg); color: var(--fg);
}
dialog::backdrop { background: rgb(13 13 13 / .35); }

.statbar {
  display: flex; flex-wrap: wrap; gap: var(--space-6) var(--space-8);
  padding: var(--space-3) var(--space-5);
  border: 1px solid var(--border-soft); border-radius: var(--radius-md); background: var(--bg);
}
.statbar > div { display: flex; align-items: baseline; gap: var(--space-2); font-size: var(--text-sm); }
.statbar b { font-size: var(--text-xl); font-weight: 500; font-variant-numeric: tabular-nums; }
.statbar .meta { flex: none; }
.kpi-3 { grid-template-columns: repeat(3, 1fr); }
.switch-inline { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); color: var(--muted); cursor: pointer; }
.switch-inline input { accent-color: var(--accent); width: 15px; height: 15px; }

/* ─── 动效 ──────────────────────────────────────────────────────
 * 只有三处：切视图、开对话框、弹提示。都靠 hidden→display 的切换
 * 自动重放，不需要 JS 触发。时长走设计系统的 150/220ms。          */
@keyframes od-rise  { from { opacity: 0; transform: translateY(6px); } }
@keyframes od-fade  { from { opacity: 0; } }
@keyframes od-toast { from { opacity: 0; transform: translateX(-50%) translateY(-8px); } }

.page  { animation: od-rise var(--motion-base) var(--ease-standard) both; }
.toast  { animation: od-toast var(--motion-base) var(--ease-standard) both; }
/* 条形图和齐套圆片在重算后柔和过渡，不做入场动画（表格会整体重绘） */
.bar > span { transition: width var(--motion-base) var(--ease-standard), background var(--motion-fast) var(--ease-standard); }
.track i { transition: background var(--motion-base) var(--ease-standard); }
.btn, .pill { transition: background var(--motion-fast) var(--ease-standard), border-color var(--motion-fast) var(--ease-standard), color var(--motion-fast) var(--ease-standard); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important; animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
}

/* ─── responsive ────────────────────────────────────────────────── */
@media (max-width: 1180px) {
  .kpi-grid { grid-template-columns: repeat(3, 1fr); }
  .pipeline { grid-template-columns: repeat(3, 1fr); }
  .machine-grid { grid-template-columns: repeat(2, 1fr); }
  .load-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 1011px) {
  .container { padding-inline: var(--container-gutter-tablet); }
  /* table-layout:auto 会先挤扁文字列再溢出 —— 给下限，把压缩交给横滚 */
  .table-scroll .ds-table { min-width: 860px; }
  .table-scroll #order-table { min-width: 900px; }
  /* 窄屏砍掉冗余列：3=进度%（工序轨已表达）、5=柜数（抽屉里有），
     让订单号拿回宽度。列序变动时同步改这里。 */
  #order-table th:nth-child(3), #order-table td:nth-child(3),
  #order-table th:nth-child(5), #order-table td:nth-child(5) { display: none; }
  .pane-2-1, .pane-1-1 { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 700px) {
  .container { padding-inline: var(--container-gutter-phone); }
  .kpi-grid { grid-template-columns: repeat(2, 1fr); }
  .pipeline { grid-template-columns: repeat(2, 1fr); }
  .machine-grid, .load-grid, .load-grid-3 { grid-template-columns: minmax(0, 1fr); }
  .app-header-bar { flex-wrap: wrap; gap: var(--space-2); }
  .search { min-width: 0; width: 100%; }
  .toolbar-spacer { margin-inline-start: 0; }
}
