:root {
  --bg: #f6f7f9;
  --chrome: #1e2430;
  --chrome-2: #262d3b;
  --chrome-border: #343d4e;
  --text-on-chrome: #e8ebf0;
  --muted-on-chrome: #9aa4b5;
  --accent: #3b82f6;
  --warn: #b45309;          /* amber-700 — "待补全" advisory (distinct from red error) */
  --warn-border: #f59e0b;   /* amber-500 */
  --warn-bg: #fff7ed;       /* amber-50 */
  --panel: #ffffff;
  --panel-border: #e2e6ec;
  --ink: #2a3140;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }

/* `hidden` must actually hide. Any element given an explicit display — flex,
   grid — otherwise ignores the attribute, which had been worked around one
   element at a time until a new one was added without the workaround and its
   quantity box stayed on screen in a dialog that has no quantity. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--ink);
}
/* The page is a column: the toolbar takes the height it needs (one row, or more when it wraps)
   and #workspace takes the rest. No toolbar height is hard-coded anywhere. Only #toolbar and
   #workspace are in flow here: #login-gate and #toast are position:fixed, dialogs are closed or
   in the top layer. */
body { display: flex; flex-direction: column; }

/* ---------- Toolbar ---------- */
/* When the controls don't fit on one row, the toolbar WRAPS to another row instead of squeezing
   a label onto two lines or pushing controls off-screen (owner ruling 2026-09-29, option B —
   feedback.md §8.4; the row had already been overcrowded below ~1400px). One row stays exactly
   as before: 48px tall, items centred at the same offset (border-box: 4px padding + the 1px
   border leave a 39px content box, and a 34px group sits at 6.5px, as it did in 48px with no
   padding). Every control keeps its label on one line (white-space is inherited). */
#toolbar {
  display: flex;
  flex: none;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  min-height: 48px;
  padding: 4px 12px;
  white-space: nowrap;
  background: var(--chrome);
  border-bottom: 1px solid var(--chrome-border);
  user-select: none;
}

.brand {
  font-weight: 700;
  font-size: 15px;
  color: var(--text-on-chrome);
  margin-right: 6px;
  letter-spacing: 0.2px;
}
.brand span { color: var(--accent); font-weight: 600; }

.tb-group {
  display: flex;
  align-items: center;
  gap: 2px;
  background: var(--chrome-2);
  border: 1px solid var(--chrome-border);
  border-radius: 8px;
  padding: 2px;
}

.tb-spacer { flex: 1; }

#toolbar button {
  appearance: none;
  border: none;
  background: transparent;
  color: var(--text-on-chrome);
  font: inherit;
  font-size: 13px;
  padding: 5px 10px;
  border-radius: 6px;
  cursor: pointer;
  min-width: 32px;
}
#toolbar button:hover { background: rgba(255, 255, 255, 0.09); }
#toolbar button:active { background: rgba(255, 255, 255, 0.16); }
#toolbar button:disabled { opacity: 0.35; cursor: default; background: transparent; }
.zoom-label { min-width: 52px; font-variant-numeric: tabular-nums; }

#doc-select {
  appearance: none;
  background: transparent;
  border: none;
  color: var(--text-on-chrome);
  font: inherit;
  font-size: 13px;
  padding: 5px 8px;
  border-radius: 6px;
  max-width: 170px;
  text-overflow: ellipsis;
  cursor: pointer;
  outline: none;
}
#doc-select:hover { background: rgba(255, 255, 255, 0.09); }
#doc-select option { color: #2a3140; background: #fff; }
/* At phone width the document group (mode chip + flow name + 5 buttons, ~390px) is wider than a
   whole toolbar row, and wrapping can't split a group, so its last buttons would be clipped. The
   flow name (already capped at 170px with an ellipsis) gives up width in that one case. This is
   NOT a breakpoint: with the toolbar wrapping, flexbox moves groups to a new row before shrinking
   any, so the name only narrows when its group can't fit even on a row of its own — never at
   desktop widths (walked: 170px at 1280–1920). */
#doc-controls { min-width: 0; }
#doc-select { min-width: 4em; }

#mode-chip {
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: 10px;
  margin-left: 4px;
  white-space: nowrap;
}
#mode-chip.design { background: #1d4ed8; color: #dbeafe; }
#mode-chip.order { background: #15803d; color: #dcfce7; }
#mode-chip.editing { background: #b45309; color: #ffedd5; }
#mode-chip.closed { background: #475569; color: #e2e8f0; }

#dev-chip {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  padding: 3px 8px;
  border-radius: 10px;
  background: #b45309;
  color: #ffedd5;
  cursor: help;
}

/* ---------- Layout ---------- */
#workspace {
  display: flex;
  flex: 1;
  min-height: 0;   /* fills whatever the toolbar leaves — was calc(100% - 48px), which a wrapped toolbar would overrun */
}

/* ---------- Palette ---------- */
#palette {
  width: 156px;
  flex: none;
  background: var(--panel);
  border-right: 1px solid var(--panel-border);
  padding: 12px 10px;
  overflow-y: auto;
  user-select: none;
}

.palette-title {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: #8b93a5;
  margin-bottom: 10px;
}

.palette-item {
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  padding: 6px 6px 4px;
  margin-bottom: 8px;
  cursor: grab;
  text-align: center;
  background: #fff;
  transition: border-color 0.1s, box-shadow 0.1s;
}
.palette-item:hover {
  border-color: var(--accent);
  box-shadow: 0 1px 4px rgba(59, 130, 246, 0.25);
}
.palette-item svg { width: 100%; height: 40px; display: block; }
.palette-item span { font-size: 11.5px; color: #5a6275; }
.pv { fill: #eef2f8; stroke: #5b6470; stroke-width: 1.5; }

.palette-hint {
  font-size: 11.5px;
  line-height: 1.45;
  color: #98a0b0;
  margin-top: 14px;
}

/* ---------- Canvas ---------- */
#canvas-wrap { position: relative; flex: 1; min-width: 0; }

#canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  background: var(--bg);
  touch-action: none;
  display: block;
}

#stats-bar {
  position: absolute;
  left: 50%;
  top: 10px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 12px;
  color: #3c4354;
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid var(--panel-border);
  border-radius: 20px;
  padding: 5px 16px;
  white-space: nowrap;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
}
.stat-status { display: inline-flex; align-items: center; gap: 4px; }
.stat-status i {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
}
.stat-link { color: #b45309; cursor: pointer; font-weight: 600; }
.stat-link:hover { text-decoration: underline; }
.stat-idle { color: #b45309; font-weight: 600; }
.stat-late { color: #dc2626; font-weight: 600; }
.stat-seq { color: #dc2626; font-weight: 600; cursor: pointer; }
.stat-seq:hover { text-decoration: underline; }
.stat-seq.stat-advisory { color: #b45309; }   /* advisory warn — amber, still clickable */

#doc-dates {
  margin-top: 14px;
  padding: 10px 12px;
  background: #f6f8fb;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
  font-size: 12.5px;
  line-height: 1.9;
  color: #3c4354;
}
#doc-dates:empty { display: none; }
.doc-headline { font-size: 13px; font-weight: 650; color: var(--ink, #18212e); margin: 2px 0 4px; }
#doc-actions { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
#doc-actions:empty { display: none; }

#hint-bar {
  position: absolute;
  left: 50%;
  bottom: 10px;
  transform: translateX(-50%);
  font-size: 11.5px;
  color: #8b93a5;
  background: rgba(255, 255, 255, 0.85);
  border: 1px solid var(--panel-border);
  border-radius: 20px;
  padding: 4px 14px;
  pointer-events: none;
  white-space: nowrap;
}

/* ---------- SVG content ---------- */
.node { cursor: grab; }
.node.dragging { cursor: grabbing; }
.node .shape { transition: filter 0.1s; }
.node:hover .shape { filter: brightness(0.97); }
.node.selected .shape {
  stroke: var(--accent) !important;
  stroke-width: 2.5;
}
.node text {
  pointer-events: none;
  user-select: none;
}

.port {
  fill: #fff;
  stroke: var(--accent);
  stroke-width: 1.5;
  cursor: crosshair;
  opacity: 0;
  transition: opacity 0.12s;
}
.node:hover .port, .node.selected .port { opacity: 1; }
.port:hover { fill: var(--accent); }

.edge-hit {
  fill: none;
  stroke: transparent;
  stroke-width: 14;
  cursor: pointer;
}
.edge-line {
  fill: none;
  stroke: #5b6470;
  stroke-width: 1.8;
  pointer-events: none;
}
.edge.selected .edge-line { stroke: var(--accent); stroke-width: 2.4; }
/* the schedule ignores rework edges; the eye must be able to tell */
.edge.rework .edge-line { stroke-dasharray: 6 4; }
.edge-label {
  font-size: 12px;
  fill: #3c4354;
  paint-order: stroke;
  stroke: var(--bg);
  stroke-width: 4;
  stroke-linejoin: round;
  pointer-events: none;
  user-select: none;
}

.status-dot { pointer-events: none; }
/* Per-shape reminder: an outsourced step with no supplier named yet. */
.sup-badge { fill: #f59e0b; stroke: #fff; stroke-width: 1.5; }
.sup-badge-mark { fill: #fff; font-weight: 700; font-size: 9px; text-anchor: middle; dominant-baseline: central; pointer-events: none; }

.log-entry {
  font-size: 11px;
  color: #8b93a5;
  line-height: 1.7;
  font-variant-numeric: tabular-nums;
}

.resize-handle { cursor: nwse-resize; }

.lane-body { pointer-events: none; }
.lane-header { cursor: grab; }
.lane-title { pointer-events: none; user-select: none; }
.lane.selected .lane-body, .lane.selected .lane-header {
  stroke: var(--accent);
  stroke-width: 1.5;
}

.edge-end {
  fill: #fff;
  stroke: var(--accent);
  stroke-width: 2;
  cursor: crosshair;
}
.edge-end:hover { fill: var(--accent); }

.temp-edge {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.8;
  stroke-dasharray: 6 4;
  pointer-events: none;
}
.marquee {
  fill: rgba(59, 130, 246, 0.10);
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-dasharray: 5 4;
  pointer-events: none;
}

.drop-target .shape {
  stroke: var(--accent) !important;
  stroke-width: 2.5;
}

/* ---------- Properties panel ---------- */
#panel-resizer {
  flex: none;
  width: 5px;
  cursor: col-resize;
  background: transparent;
  transition: background 0.12s;
}
#panel-resizer:hover, #panel-resizer.dragging { background: var(--accent); }

/* The panel is the work surface in production mode.
   Width is user-adjustable via the drag handle; this is only the default. */
#props {
  width: 360px;
  flex: none;
  background: var(--panel);
  border-left: 1px solid var(--panel-border);
  padding: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

/* ---- sticky head: identity, standing, next action ---- */
#panel-head {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--panel);
  border-bottom: 1px solid var(--panel-border);
  padding: 12px 14px 10px;
}

#panel-sub {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: #8b93a5;
}
#panel-title {
  font-size: 16px;
  font-weight: 650;
  color: var(--ink);
  line-height: 1.3;
  margin-top: 3px;
  word-break: break-word;
}

/* how long a step has been held up: stated in the 受阻 section, which is on
   screen exactly when the number means something */
#block-days {
  font-size: 12px;
  font-weight: 600;
  color: #b91c1c;
  margin-top: 8px;
}
#block-days:empty { display: none; }

/* actions styled by intent: forward move filled, exceptions outlined */
#status-btns {
  display: flex;
  gap: 8px;
  margin-top: 10px;
}
#status-btns:empty { display: none; }
.act {
  flex: 1;
  padding: 9px 8px;
  font: inherit;
  font-size: 13px;
  font-weight: 650;
  border-radius: 8px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: filter 0.1s, background 0.1s;
}
.act:hover { filter: brightness(0.95); }
/* 受阻 (red) and 恢复 (blue) are the only actions the panel head ever shows */
.act.outline-red   { background: #fff; color: #dc2626; border-color: #fecaca; }
.act.outline-red:hover { background: #fef2f2; filter: none; }
.act.outline-blue  { background: #fff; color: #1d4ed8; border-color: #bfdbfe; }
.act.outline-blue:hover { background: #eff6ff; filter: none; }

/* ---- body sections ---- */
#panel-body { padding: 12px 14px 16px; }

.sec {
  border-top: 1px solid var(--panel-border);
  padding: 12px 0 4px;
}
.sec:first-child { border-top: none; padding-top: 2px; }

.sec-head {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: #8b93a5;
  margin-bottom: 8px;
}
details.sec > summary.sec-head {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 6px;
  user-select: none;
}
details.sec > summary.sec-head::-webkit-details-marker { display: none; }
details.sec > summary.sec-head::before {
  content: "▸";
  font-size: 9px;
  transition: transform 0.12s;
}
details.sec[open] > summary.sec-head::before { transform: rotate(90deg); }

.sec.alert {
  background: #fef2f2;
  border: 1px solid #fecaca;
  border-radius: 8px;
  padding: 10px 12px;
  margin-top: 12px;
}
.sec.alert .sec-head { color: #b91c1c; }

.fld-label {
  display: block;
  font-size: 11.5px;
  font-weight: 600;
  color: #5a6275;
  margin: 9px 0 4px;
}
.note-line {
  font-size: 12px;
  margin-top: 8px;
  padding: 6px 9px;
  border-radius: 6px;
  background: #f1f5f9;
  color: #475569;
}
.note-line.warn { background: #fef2f2; color: #b91c1c; font-weight: 600; }

#props textarea {
  width: 100%;
  font: inherit;
  font-size: 13px;
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  padding: 6px 8px;
  resize: vertical;
  outline: none;
}
#props textarea:focus { border-color: var(--accent); }

#props input, #props select {
  width: 100%;
  background: #fff;
  font: inherit;
  font-size: 13px;
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  padding: 6px 8px;
  outline: none;
}
#props input:focus, #props select:focus { border-color: var(--accent); }
#props input:disabled, #props select:disabled, #props textarea:disabled {
  background: #f1f5f9;
  color: #64748b;
  border-color: transparent;
  cursor: default;
  opacity: 1;
}

#shape-type-btns {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
}
.shape-btn {
  padding: 4px 2px;
  border-radius: 6px;
  border: 1px solid var(--panel-border);
  background: #fff;
  cursor: pointer;
}
.shape-btn svg { width: 100%; height: 20px; display: block; }
.shape-btn:hover { background: #f2f5f9; }
.shape-btn.active {
  border-color: var(--accent);
  background: #eff6ff;
}

#edge-style-btns {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 5px;
}
.seg-btn:disabled { opacity: 0.55; cursor: default; }

/* One row per material: name, quantity, and how it stands against stock. */
.req-row {
  display: grid;
  grid-template-columns: 1fr 52px auto auto;
  gap: 6px;
  align-items: center;
  padding: 3px 0;
}
.req-row + .req-row { border-top: 1px solid #eef1f5; }
.req-name { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.req-row input { padding: 3px 5px; font-size: 12px; }
.req-state { font-size: 11px; color: #6b7280; white-space: nowrap; }
.req-row.short .req-state { color: #b42318; font-weight: 600; }
.req-row button {
  border: 0; background: none; cursor: pointer;
  color: #9aa3ad; font-size: 15px; line-height: 1; padding: 2px 4px;
}
.req-row button:hover { color: #b42318; }
#req-lines { margin-bottom: 8px; }

/* The item list is a filtered list box, not a dropdown: 323 items and growing,
   and people recognise an item by SKU or by name, so one search covers both. */
#prop-item {
  margin-top: 5px;
  padding: 0;
  font-size: 12.5px;
}
#prop-item option { padding: 3px 7px; }
#prop-item:disabled { opacity: 0.6; }
.seg-btn {
  font: inherit;
  font-size: 11.5px;
  padding: 5px 4px;
  border-radius: 6px;
  border: 1px solid var(--panel-border);
  background: #fff;
  cursor: pointer;
  color: #3c4354;
  white-space: nowrap;
}
.seg-btn:hover { background: #f2f5f9; }
.seg-btn.active {
  border-color: var(--accent);
  background: #eff6ff;
  font-weight: 600;
}

#swatches { display: flex; flex-wrap: wrap; gap: 6px; }
.swatch {
  width: 24px;
  height: 24px;
  border-radius: 6px;
  border: 1px solid rgba(0, 0, 0, 0.15);
  cursor: pointer;
}
.swatch.active { outline: 2px solid var(--accent); outline-offset: 1px; }

.props-btn {
  width: 100%;
  margin-top: 14px;
  font: inherit;
  font-size: 13px;
  padding: 7px 10px;
  border-radius: 6px;
  border: 1px solid var(--panel-border);
  background: #fff;
  cursor: pointer;
}
.props-btn:hover { background: #f2f5f9; }
.props-btn.danger { color: #d43c3c; border-color: #ecc8c8; }
.props-btn.danger:hover { background: #fdf1f1; }
.props-btn.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
}
.props-btn.primary:hover { background: #2f6fe0; }

#order-source {
  font-size: 11.5px;
  color: #8b93a5;
  margin-top: 8px;
}

#toast {
  position: fixed;
  left: 50%;
  bottom: 44px;
  transform: translateX(-50%);
  z-index: 80;
  background: #1e2430;
  color: #e8ebf0;
  font-size: 13px;
  padding: 9px 18px;
  border-radius: 20px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
  pointer-events: none;
  white-space: nowrap;
}

/* ---------- Dialogs ----------
   One shared shell for every <dialog> in the app: same border, radius, padding,
   shadow, backdrop, and max sizing. Pick a width with a size modifier class
   (.dlg-sm/md/lg/wide) rather than styling each dialog by id — see index.html. */
dialog {
  border: 1px solid var(--panel-border);
  border-radius: 14px;
  padding: 20px 22px;
  width: 460px;              /* default; the size modifiers below override it */
  max-width: 94vw;
  max-height: 88vh;
  min-width: 280px;          /* room for the resize handle; no min-height, so short
                                dialogs size to their content */
  overflow: auto;
  resize: both;              /* drag the corner to resize; drag the title to move */
  background: var(--panel);
  color: var(--ink);
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.18);
}
/* Light veil so the flow stays visible behind an open dialog (which can be
   dragged aside to read it). */
dialog::backdrop { background: rgba(15, 20, 30, 0.08); }
/* The title bar doubles as the drag handle. */
.dlg-title { cursor: move; user-select: none; }
/* quick-filter chip row inside a picker dialog */
.dlg-quick { display: flex; gap: 6px; margin: 8px 0 2px; flex-wrap: wrap; }
.dlg-chip {
  border: 1px solid var(--panel-border);
  background: #fff;
  color: var(--ink);
  border-radius: 999px;
  padding: 3px 12px;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.dlg-chip:hover { background: #f2f5f9; }
.dlg-chip.on { background: var(--accent); border-color: var(--accent); color: #fff; }

.dlg-sm   { width: 320px; }
.dlg-md   { width: 460px; }
.dlg-lg   { width: 680px; }
.dlg-wide { width: 820px; }
/* WO-040: near-fullscreen editor. Fixed height + a flex column so the inner table
   scrolls while the toolbar/footer stay put; still draggable + corner-resizable. */
.dlg-full { width: min(1280px, 96vw); height: min(900px, 92vh); max-width: 96vw; max-height: 92vh; }
/* overflow:hidden so ONLY the table scrolls — the toolbar + Cancel/Save footer stay
   pinned and reachable (a tall list was pushing the footer out of the dialog).
   IMPORTANT: gate on [open] — an unconditional author `display:flex` overrides the UA
   `dialog:not([open]){display:none}`, leaving the dialog visible after .close() (that was
   the "Cancel doesn't work" bug). With [open], a closed dialog falls back to display:none. */
#bom-edit-dialog[open] { display: flex; flex-direction: column; overflow: hidden; }
#bom-edit-dialog #bom-edit-table { flex: 1 1 auto; max-height: none; min-height: 0; overflow: auto; }
#bom-edit-dialog .bom-edit-foot, #bom-edit-dialog .dlg-actions { flex: 0 0 auto; }

/* WO-040 two-level BOM group editor */
.bom-grp { border: 1px solid var(--panel-border); border-radius: 10px; margin: 8px 0; padding: 6px 8px 8px; }
.bom-grp-ung { border-style: dashed; }
.bom-grp-head, .bom-sub-head { display: flex; align-items: center; gap: 6px; margin: 2px 0 6px; }
.bom-grp-title { font-weight: 600; font-size: 12px; color: #6b7280; }
.bom-grp-name { flex: 1; font-weight: 600; padding: 4px 8px; border: 1px solid #c7ced8; border-radius: 6px; font: inherit; font-size: 13px; background: #fff; color: var(--ink); }
.bom-sub { margin: 6px 0 6px 16px; border-left: 2px solid var(--panel-border); padding-left: 8px; }
.bom-sub-name { flex: 1; padding: 3px 8px; border: 1px solid #c7ced8; border-radius: 6px; font: inherit; font-size: 12px; background: #fff; color: var(--ink); }
.bom-grp-btn { border: 1px solid var(--panel-border); background: #fff; color: var(--ink); cursor: pointer; border-radius: 6px; padding: 2px 8px; font: inherit; font-size: 12px; line-height: 1.4; }
.bom-grp-btn:hover:not(:disabled) { background: #f2f5f9; }
.bom-grp-btn:disabled { opacity: .4; cursor: default; }
.bom-grp-btn.danger { color: #b91c1c; }
.bom-rowadd { margin: 4px 0 2px; }
.bom-row-add { font-size: 12px; padding: 2px 10px; }
.bom-grp-add-wrap { margin: 10px 0 2px; }

/* Release gateway wizard (投产/完成修改) — one gate per step */
.gate-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.gate-progress { display: flex; gap: 6px; }
.gate-pip { width: 20px; height: 5px; border-radius: 3px; background: #e2e6ec; }
.gate-pip.ok { background: #15803d; }
.gate-pip.pend { background: #dc2626; }   /* a blocking gate still pending — red */
.gate-pip.warn { background: #e0a92e; }   /* an unmet advisory warn — amber */
.gate-pip.cur { background: #2563eb; }
.gate-step-head { font-size: 14px; font-weight: 650; margin: 14px 0 4px; }
.gate-why { font-size: 12px; color: #6b7280; line-height: 1.5; margin-bottom: 10px; }
.gate-summary { font-size: 12px; font-weight: 650; margin-bottom: 10px; }
.gate-summary.ok { color: #15803d; }
.gate-summary.bad { color: #b42318; }
.gate-summary.warn { color: #b45309; }   /* advisory — amber, not the red of a hard gate */
#gate-list { min-height: 90px; max-height: 48vh; overflow-y: auto; }
.gate-clear { display: flex; align-items: center; gap: 8px; padding: 18px 4px; font-size: 13px; color: #15803d; }
.gate-clear::before { content: "✓"; font-weight: 700; }
.gate-row { display: flex; align-items: center; gap: 8px; padding: 6px 2px; font-size: 13px; }
.gate-item { flex: 1; min-width: 0; text-align: left; border: 0; background: none; font: inherit; font-size: 13px; color: #2563eb; cursor: pointer; padding: 0; }
.gate-item:hover { text-decoration: underline; }
.gate-dur { width: 72px; padding: 5px 6px; border: 1px solid #c7ced8; border-radius: 6px; font: inherit; font-size: 13px; }
.gate-sup { margin-top: 0; width: auto; flex: none; padding: 4px 12px; }
.gate-bom { padding: 8px 2px; border-bottom: 1px solid #f0f2f5; }
.gate-bom:last-child { border-bottom: 0; }
.gate-bom-name { font-size: 13px; margin-bottom: 6px; }
.gate-note { flex: 1; font-size: 12px; color: #6b7280; }
.gate-spec-list { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 2px 4px; }
.gate-spec-miss { font-size: 12px; background: #fff7ed; color: #b45309; border: 1px solid #fed7aa; border-radius: 999px; padding: 2px 10px; }
/* Layer-4 draft POs: one block per supplier / category / un-reconciled group */
.gate-po { padding: 6px 2px; border-bottom: 1px solid #f0f2f5; }
.gate-po:last-of-type { border-bottom: 0; }
.gate-po-head { font-size: 12px; font-weight: 650; color: #334155; margin-bottom: 4px; }
.gate-po-head.warn { color: #b45309; }
.gate-po-line { font-size: 13px; padding: 2px 0 2px 10px; }
.gate-po-onhand { color: #6b7280; font-size: 12px; }
.gate-buy { margin-top: 10px; width: auto; }
.gate-order { margin-top: 4px; }
.gate-vn-ro { font-variant-numeric: tabular-nums; font-weight: 600; letter-spacing: .02em;
  padding: 8px 10px; background: #f6f8fb; border: 1px solid var(--panel-border); border-radius: 8px; }
.gate-vn-ro.unset { color: #b45309; font-weight: 500; }
/* the product/specs readout on the last step — multi-line, lighter than the VN */
.gate-product-ro { white-space: pre-line; font-weight: 500; letter-spacing: 0; line-height: 1.5; font-size: 12.5px; }
.gate-verify { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }
#gate-qty { width: 110px; padding: 7px 9px; border: 1px solid var(--panel-border); border-radius: 8px;
  font: inherit; font-variant-numeric: tabular-nums; }
#gate-qty:focus { outline: none; border-color: var(--accent); }
#gate-qty:disabled { background: #f6f8fb; color: #6b7280; }
.gate-handoff-opt { display: flex; align-items: center; gap: 8px; margin-top: 14px;
  font-size: 13px; color: #3c4354; cursor: pointer; user-select: none; }
.gate-handoff-opt input { width: 15px; height: 15px; margin: 0; cursor: pointer; }
.gate-foot { justify-content: space-between; align-items: center; }
.gate-foot-btns { display: flex; gap: 8px; }
/* Footer buttons size to their label — the base .props-btn width:100% squeezed
   them in this flex row, wrapping the shorter Chinese labels (下一步 / 上一步). */
.gate-foot .props-btn { width: auto; white-space: nowrap; }
.props-btn:disabled { opacity: .45; cursor: not-allowed; }

#block-dialog input, #block-dialog select {
  width: 100%;
  box-sizing: border-box;
  font: inherit;
  font-size: 13px;
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  padding: 6px 8px;
  outline: none;
}
#block-dialog input:focus, #block-dialog select:focus { border-color: var(--accent); }
#edit-dialog textarea {
  width: 100%;
  font: inherit;
  font-size: 13px;
  line-height: 1.5;
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  padding: 8px 10px;
  resize: vertical;
  min-height: 84px;
  outline: none;
}
#edit-dialog textarea:focus { border-color: var(--accent); }

.dlg-title { font-size: 15px; font-weight: 650; color: var(--ink); }
.dlg-actions {
  display: flex;
  gap: 8px;
  margin-top: 16px;
}
.dlg-actions .props-btn { margin-top: 0; }

#sched-note:empty { display: none; }
#sec-order-log { margin-top: 14px; }

/* ---------- Schedule: plan vs actual ---------- */
/* one row per date: label, the box, the signature. 结束 has no third column
   of its own — the sign-off box is the third column for both dates. */
#sched-grid {
  display: grid;
  grid-template-columns: auto 1fr 18px;
  gap: 6px 8px;
  align-items: center;
}
#sched-grid > input[type="checkbox"] {
  margin: 0;
  width: 15px;
  height: 15px;
  justify-self: center;
  accent-color: #2e7d32;
}
/* a projection is the system talking; a signed date is a person talking, and
   the two must not look alike in a box that holds either */
#sched-grid input.projected {
  color: #8b93a5;
  font-style: italic;
  background: #f8fafc;
}
#sched-grid input[readonly] { border-color: #e4e8ef; }
.sg-l {
  font-size: 11px;
  font-weight: 600;
  color: #5a6275;
}
.sg-v {
  font-size: 12px;
  color: #2a3140;
  font-variant-numeric: tabular-nums;
}
.sg-v input {
  width: 100%;
  padding: 4px 5px;
  font-size: 12px;
}

/* ---------- Inline label editor ---------- */
#inline-editor {
  position: fixed;
  z-index: 50;
  border: 1.5px solid var(--accent);
  border-radius: 4px;
  background: #fff;
  font-family: inherit;
  text-align: center;
  resize: none;
  overflow: hidden;
  outline: none;
  padding: 2px 4px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
}

/* ---------- Palette drag ghost ---------- */
#drag-ghost {
  position: fixed;
  z-index: 60;
  pointer-events: none;
  opacity: 0.75;
  width: 110px;
}
#drag-ghost svg { width: 100%; display: block; }

/* ---------- Sign-in gate ---------- */
#login-gate {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: var(--chrome);
  display: flex;
  align-items: center;
  justify-content: center;
}

#login-card {
  width: 340px;
  background: var(--panel);
  border-radius: 14px;
  padding: 26px 28px 24px;
  box-shadow: 0 14px 50px rgba(0, 0, 0, 0.35);
}
.login-brand { font-size: 19px; font-weight: 700; color: var(--ink); }
.login-brand span { color: var(--accent); }
.login-sub { font-size: 12.5px; color: #8b93a5; margin: 4px 0 14px; }
#login-card input {
  width: 100%;
  font: inherit;
  font-size: 13px;
  border: 1px solid var(--panel-border);
  border-radius: 6px;
  padding: 8px 10px;
  outline: none;
}
#login-card input:focus { border-color: var(--accent); }
#login-error { font-size: 12px; color: #dc2626; margin-top: 10px; min-height: 0; }
#login-error:empty { display: none; }
#login-btn { margin-top: 16px; }

/* ---------- Cloud status in the toolbar ---------- */
#save-state {
  font-size: 11.5px;
  padding: 3px 8px;
  border-radius: 10px;
  white-space: nowrap;
  color: var(--muted-on-chrome);
  /* Fixed floor for the routine save cycle, so the toolbar can't flip between one and two rows
     (and the canvas jump) on every save: the badge is always as wide as its widest routine
     label, per language. Measured border-box: Saving… 61.8 / Saved 49.3 (EN), 保存中… 59.8 /
     已保存 50.5 (ZH). Sized to the label and no wider: at ZH 1440 the row has ~4px to spare,
     and a one-size 64px floor was enough to push it onto a second row. The rare failed/conflict
     states are wider and may push past it: a one-off shift on an error the user should notice. */
  min-width: 62px;
  text-align: center;
}
:root[lang|="zh"] #save-state { min-width: 60px; }
#save-state:empty { display: none; }
#save-state.saving { color: #cbd5e1; }
#save-state.saved  { color: #86efac; }
#save-state.failed { background: #b91c1c; color: #fee2e2; font-weight: 600; }
#save-state.conflict { background: #b45309; color: #ffedd5; font-weight: 600; cursor: pointer; }
#btn-account { max-width: 130px; overflow: hidden; text-overflow: ellipsis; }

/* A material shortage in the stats bar: the one number that says a plan is
   waiting on something nobody has ordered yet. */
.stat-warn { color: #b42318; font-weight: 600; }

/* ---------- Material picker ---------- */
#dlg-item-search { width: 100%; }

/* BOM link-material filters (category number quick-filter + location placeholder) */
.dlg-filtbar { display: flex; gap: 14px; flex-wrap: wrap; margin: 8px 0 2px; }
.dlg-filt { position: relative; display: flex; align-items: center; gap: 6px; flex: 1 1 260px; min-width: 0; }
.dlg-filt-label { font-size: 12px; color: var(--muted, #667); white-space: nowrap; }
.dlg-filt input { flex: 1 1 auto; min-width: 0; }
.dlg-filt input:disabled { background: #f4f6f9; color: #9aa4b2; cursor: not-allowed; }
.dlg-filt-note { font-size: 11px; color: #9aa4b2; white-space: nowrap; }
.dlg-filt-chip { border: 1px solid #cdd8e6; background: #e8f0fe; color: #1a4a8a; border-radius: 999px;
  padding: 3px 10px; font-size: 12px; cursor: pointer; white-space: nowrap; }
.dlg-filt-chip:hover { background: #d8e6fc; }
.dlg-cat-cands { position: absolute; top: 100%; left: 0; right: 0; z-index: 5; margin-top: 3px;
  max-height: 240px; overflow-y: auto; background: #fff; border: 1px solid #cdd8e6;
  border-radius: 8px; box-shadow: 0 6px 20px rgba(20,40,80,.14); }
.dlg-cat-cand { padding: 5px 10px; font-size: 13px; cursor: pointer; display: flex; gap: 8px; align-items: baseline; }
.dlg-cat-cand:hover { background: #f6f8fb; }
.dlg-cat-cand.active { background: #e8f0fe; }
.dlg-catnum { font-variant-numeric: tabular-nums; color: #1a4a8a; font-weight: 600; min-width: 42px; }

#dlg-item-results {
  margin-top: 8px;
  max-height: 380px;
  min-height: 140px;
  overflow-y: auto;
  border: 1px solid var(--panel-border);
  border-radius: 8px;
}
#dlg-item-results:empty { border-style: dashed; }

.pick-row {
  display: grid;
  grid-template-columns: 62px 0 minmax(0, 1fr) auto;
  gap: 10px;
  align-items: baseline;
  padding: 6px 9px;
  cursor: pointer;
  font-size: 12.5px;
}
.pick-row + .pick-row { border-top: 1px solid #f0f3f7; }
.pick-row:hover { background: #f6f8fb; }
.pick-row.on { background: #e8f0fe; }
.pick-sku {
  color: #8b93a5;
  font-variant-numeric: tabular-nums;
  font-size: 11.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* a drawing number is the part's name to whoever drew it, so it reads as text
   rather than as a faint reference */

.pick-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* the drawing number on its own line, labelled, so it cannot be mistaken for
   the SKU or lost to a narrow column */
/* widened only when the list holds a drawing; the empty span stays in place so
   the remaining columns keep their tracks */
#dlg-item-results.has-dwg .pick-row { grid-template-columns: 62px 134px minmax(0, 1fr) auto; }

.pick-dwg {
  font-size: 11.5px;
  color: #3c4354;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.pick-meta { color: #6b7280; font-size: 11px; white-space: nowrap; }

.dlg-qty {
  display: flex; align-items: center; gap: 6px;
  font-size: 12.5px; margin-right: auto; white-space: nowrap;
}
.dlg-qty input { width: 64px; padding: 4px 6px; }

/* Picks gathered before committing: one trip, several materials. */
.dlg-addrow { display: flex; align-items: center; gap: 8px; margin-top: 10px; }
.dlg-addrow .props-btn { margin-top: 0; }

#dlg-basket {
  margin-top: 10px;
  border-top: 1px solid var(--panel-border);
  padding-top: 8px;
  max-height: 132px;
  overflow-y: auto;
}
.basket-row {
  display: grid;
  grid-template-columns: 62px 1fr auto auto;
  gap: 8px;
  align-items: baseline;
  padding: 3px 0;
  font-size: 12.5px;
}
.basket-qty { color: #3c4354; font-variant-numeric: tabular-nums; }
.basket-row button {
  border: 0; background: none; cursor: pointer;
  color: #9aa3ad; font-size: 15px; line-height: 1; padding: 0 2px;
}
.basket-row button:hover { color: #b42318; }

/* Equipment sits under materials in the same section: used, not consumed. */
.sec-head-sub { margin-top: 16px; }
#eq-lines { margin-bottom: 8px; }
#eq-lines .req-row { grid-template-columns: 1fr auto auto; }

/* What an item is, shown beside its name in the picker. */
.pick-kind {
  margin-left: 6px;
  font-size: 10.5px;
  color: #8b93a5;
  background: #f2f4f8;
  border-radius: 4px;
  padding: 1px 5px;
  white-space: nowrap;
}

/* An outsourced line carries one more control: whose material it is. The name
   gives up width for it rather than the answer being truncated — a half-read
   "vendor sup…" is the one thing here that must stay unambiguous. */
.req-row.outsourced { grid-template-columns: minmax(0, 1fr) 42px auto auto auto; }
.req-row.outsourced .req-name { font-size: 12px; }
.req-src {
  font-size: 10.5px;
  padding: 1px 2px;
  max-width: 82px;
  border-radius: 4px;
}

/* The chosen supplier reads as a value, not a form control. */
.sup-row { display: flex; align-items: baseline; gap: 8px; }
#sup-name { flex: 1; font-size: 13px; }
#sup-name.muted { color: #9aa3ad; }
#btn-clear-supplier {
  border: 0; background: none; cursor: pointer;
  color: #9aa3ad; font-size: 11.5px; padding: 2px 4px;
}
#btn-clear-supplier:hover { color: #b42318; }

/* A duration nobody has estimated: said quietly, with a way to settle it. */
#dur-unset {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: -8px;
  margin-bottom: 14px;
  font-size: 11.5px;
  color: #b45309;
}
#dur-unset span { flex: 1; line-height: 1.4; }
#btn-confirm-dur {
  border: 1px solid #e2e6ec;
  background: #fff;
  border-radius: 6px;
  cursor: pointer;
  font: inherit;
  font-size: 11.5px;
  padding: 3px 8px;
  color: #3c4354;
  white-space: nowrap;
}
#btn-confirm-dur:hover { border-color: var(--accent); color: var(--accent); }

/* What the whole flow needs, shown when nothing in particular is selected. */
#doc-resources { margin-top: 14px; }
.res-head {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: #8b93a5;
  margin: 12px 0 4px;
}
.res-head:first-child { margin-top: 0; }
.res-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 4px 6px;
  margin: 0 -6px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 12.5px;
}
.res-row:hover { background: #f2f5f9; }
.res-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.res-qty { font-size: 12px; color: #475569; white-space: nowrap; font-variant-numeric: tabular-nums; }
.res-meta { font-size: 11px; color: #6b7280; white-space: nowrap; }
.res-row.short .res-meta { color: #b42318; font-weight: 600; }
.res-row.amber .res-meta { color: #b45309; font-weight: 600; }


/* What a step makes, listed like what it consumes but without a stock column. */
#prod-lines { margin-bottom: 8px; }
#prod-lines .req-row { grid-template-columns: 1fr 52px auto; }

/* Step library — palette entry, and the picker dialog list */
.palette-btn { width:100%; margin-top:6px; padding:8px 10px; border:1px dashed #c7ced8;
  border-radius:8px; background:#fff; color:#2a3140; cursor:pointer; font:inherit; font-size:13px; text-align:left; }
.palette-btn:hover { border-color:#8aa0bd; background:#f6f9fe; }
#lib-search { width:100%; }
#lib-list { max-height:52vh; overflow:auto; margin:8px 0; }
.lib-row { display:flex; align-items:center; gap:8px; padding:8px 10px; border:1px solid #e6eaf0;
  border-radius:8px; margin-bottom:6px; cursor:pointer; }
.lib-row:hover { border-color:#8aa0bd; background:#f6f9fe; }
.lib-main { flex:1; min-width:0; }
.lib-label { font-weight:600; }
.lib-meta { font-size:12px; color:#6b7280; margin-top:2px; }
.lib-del { border:0; background:none; color:#b6bcc6; cursor:pointer; font-size:16px; line-height:1; padding:2px 6px; }
.lib-del:hover { color:#dc2626; }
.lib-empty { color:#6b7280; text-align:center; padding:24px 8px; }
.lib-sug { font-size:12px; color:#0e7490; margin-top:3px; display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.lib-adopt { border:1px solid #0e7490; background:#ecfeff; color:#0e7490; border-radius:6px;
  padding:1px 8px; font:inherit; font-size:11px; cursor:pointer; }
.lib-adopt:hover { background:#0e7490; color:#fff; }

/* Shortage → 采购 handoff button in the flow resource roll-up */
.res-buy { display:block; width:100%; text-align:left; margin:2px 0 10px; padding:8px 11px;
  border:1px solid #b45309; background:#fff7ed; color:#9a3412; border-radius:8px;
  font:inherit; font-size:12px; font-weight:600; cursor:pointer; }
.res-buy:hover { background:#b45309; color:#fff; }

/* Work-instruction images */
.instr-images { display:flex; flex-wrap:wrap; gap:6px; margin:6px 0; }
.instr-thumb { position:relative; width:64px; height:64px; }
.instr-thumb img { width:100%; height:100%; object-fit:cover; border-radius:6px; border:1px solid #c7ced8; background:#f3f6fa; }
.instr-del { position:absolute; top:-6px; right:-6px; width:18px; height:18px; border-radius:50%; border:0;
  background:#dc2626; color:#fff; font-size:12px; line-height:1; cursor:pointer; padding:0; }
.instr-add { display:inline-block; margin-top:2px; padding:5px 10px; border:1px dashed #c7ced8; border-radius:8px;
  font-size:12px; color:#566274; cursor:pointer; }
.instr-add:hover { border-color:#8aa0bd; color:#2a3140; }

/* Bill of materials — document panel summary + import/match dialogs */
/* Ownership: a compact chip in the canvas top-right corner */
#doc-owner-chip { position:absolute; right:10px; bottom:10px; z-index:5;
  display:flex; align-items:center; gap:8px; }
.owner-chip-ro { display:inline-flex; align-items:center; gap:5px; font-size:12px; font-weight:600;
  color:#b45309; background:rgba(255,247,237,.95); border:1px solid #fed7aa; border-radius:20px;
  padding:4px 12px; white-space:nowrap; box-shadow:0 1px 4px rgba(0,0,0,.06); }
.owner-chip-ro::before { content:"🔒"; }
.owner-chip-btn { font:inherit; font-size:12px; font-weight:600; color:#2563eb;
  background:rgba(255,255,255,.95); border:1px solid var(--panel-border); border-radius:20px;
  padding:4px 12px; cursor:pointer; white-space:nowrap; box-shadow:0 1px 4px rgba(0,0,0,.06); }
.owner-chip-btn:hover { background:#eff4ff; }
/* transfer dialog */
#owner-user-list { max-height:44vh; overflow-y:auto; margin:6px 0; display:flex; flex-direction:column; gap:2px; }
.owner-user { text-align:left; border:0; background:none; font:inherit; font-size:13px; padding:7px 8px;
  border-radius:6px; cursor:pointer; color:var(--ink); }
.owner-user:hover { background:#f2f5f9; }
.owner-user-email { color:#6b7280; font-size:12px; }
.owner-email-row { display:flex; gap:8px; align-items:center; margin-top:4px; }
.owner-email-row input { flex:1; min-width:0; padding:6px 8px; border:1px solid #c7ced8; border-radius:6px; font:inherit; font-size:13px; }
.owner-email-row .props-btn { width:auto; flex:none; margin-top:0; }
.doc-vn { margin:.4rem 0; font-size:.9rem; display:flex; align-items:center; gap:.4rem; flex-wrap:wrap; }
.doc-vn-val { font-variant-numeric:tabular-nums; font-weight:600; letter-spacing:.02em; }
.doc-vn-val.unset { color:#b45309; font-weight:500; }
.doc-vn-btn { width:auto; margin:0; padding:4px 10px; }
/* 出厂序列号 (台号) list on the order page */
.doc-units { margin:.5rem 0 .2rem; font-size:.9rem; }
.doc-units-head { display:flex; align-items:center; gap:.4rem; margin-bottom:.3rem; }
.doc-units-count { font-variant-numeric:tabular-nums; opacity:.7; }
.doc-units-hint { opacity:.65; font-size:.85rem; }
.unit-sn-list { display:flex; flex-direction:column; gap:2px; }
.unit-sn-row { display:flex; align-items:center; gap:.5rem; padding:2px 6px; border-radius:5px; background:rgba(127,127,127,.06); }
.unit-sn-idx { font-variant-numeric:tabular-nums; opacity:.55; font-size:.8rem; min-width:2.6em; }
.unit-sn-val { font-variant-numeric:tabular-nums; font-weight:600; letter-spacing:.02em; }
.unit-sn-status { margin-left:auto; font-size:.78rem; padding:1px 7px; border-radius:999px; }
.unit-sn-row.pending .unit-sn-status { background:#fef3c7; color:#92400e; }
.unit-sn-row.done .unit-sn-status { background:#dcfce7; color:#166534; }
.unit-sn-row.void .unit-sn-status { background:#f3f4f6; color:#6b7280; }
.unit-sn-row.void .unit-sn-val { text-decoration:line-through; opacity:.6; }
.unit-sn-note { font-size:.78rem; opacity:.7; }
.unit-sn-acts { display:flex; gap:.3rem; margin-left:.4rem; }
.unit-sn-act { background:none; border:0; padding:1px 4px; font:inherit; font-size:.78rem; cursor:pointer; color:inherit; opacity:.6; text-decoration:underline; }
.unit-sn-act:hover { opacity:1; }
.doc-qty { margin:.3rem 0; font-size:.9rem; display:flex; align-items:center; gap:.4rem; }
.doc-qty-val { font-variant-numeric:tabular-nums; font-weight:600; }
/* Product spec dialog */
.prod-tpl-picker { display:flex; gap:8px; margin:4px 0 12px; flex-wrap:wrap; }
.prod-tpl { padding:6px 14px; border:1px solid #c7ced8; border-radius:8px; background:#fff; cursor:pointer; font:inherit; font-size:13px; }
.prod-tpl.on { border-color:var(--accent); background:#eef4ff; color:var(--accent); font-weight:600; }
.prod-tpl:disabled { opacity:.5; cursor:default; }
.prod-spec-form { max-height:52vh; overflow-y:auto; }
.prod-sec { border:1px solid #eef1f5; border-radius:10px; padding:8px 12px; margin-bottom:10px; }
.prod-sec-h { font-weight:600; font-size:12.5px; color:#516079; margin-bottom:6px; }
.prod-row { display:flex; align-items:center; gap:10px; padding:4px 0; }
.prod-flbl { flex:0 0 130px; font-size:13px; color:#3c4354; }
.prod-flbl em { color:#9aa3b0; font-style:normal; font-size:11px; }
.prod-f { flex:1; min-width:0; padding:5px 8px; border:1px solid #c7ced8; border-radius:6px; font:inherit; font-size:13px; background:#fff; color:var(--ink); }
.prod-f:focus { outline:none; border-color:var(--accent); }
/* the include-in-name checkbox at the right of each field row */
.prod-inname { flex:0 0 auto; display:flex; align-items:center; cursor:pointer; }
.prod-inname input { cursor:pointer; }
.prod-name-preview { margin-top:12px; font-size:13px; color:#3c4354; display:flex; gap:8px; align-items:flex-start; }
#product-name-preview { white-space:pre-line; line-height:1.5; }

/* ---- Admin template editor (Phase 2b) ---- */
.dlg-actions-gap { flex:1; }
.props-btn.subtle { background:transparent; border-color:transparent; color:#516079; }
.props-btn.subtle:hover { background:#eef1f5; }
.tpl-admin { display:flex; gap:14px; min-height:340px; flex-wrap:wrap; }
.tpl-admin-list { flex:1 1 168px; max-width:220px; border-right:1px solid #eef1f5; padding-right:10px; overflow-y:auto; max-height:60vh; }
.tpl-li { display:block; width:100%; text-align:left; padding:7px 9px; border:1px solid transparent; border-radius:8px; background:transparent; cursor:pointer; font:inherit; margin-bottom:3px; }
.tpl-li:hover { background:#f4f6f9; }
.tpl-li.on { background:#eef4ff; border-color:var(--accent); }
.tpl-li-label { display:block; font-size:13px; font-weight:600; color:var(--ink); }
.tpl-li-meta { display:block; font-size:11px; color:#9aa3b0; }
.tpl-admin-edit { flex:1; min-width:0; overflow-y:auto; max-height:60vh; }
.tpl-head { display:flex; gap:12px; align-items:flex-end; flex-wrap:wrap; margin-bottom:10px; }
.tpl-hf { display:flex; flex-direction:column; gap:3px; font-size:11px; color:#516079; }
.tpl-hf input { padding:5px 8px; border:1px solid #c7ced8; border-radius:6px; font:inherit; font-size:13px; }
.tpl-hf-sm input { width:64px; }
.tpl-hf input:disabled { background:#f4f6f9; color:#9aa3b0; }
.tpl-hf-chk { display:flex; align-items:center; gap:5px; font-size:12.5px; color:#3c4354; }
.tpl-sec { border:1px solid #eef1f5; border-radius:10px; padding:8px 12px; margin-bottom:10px; }
.tpl-sec-h { display:flex; align-items:center; gap:8px; font-weight:600; font-size:12.5px; color:#516079; margin-bottom:6px; }
.tpl-sec-label { flex:0 1 130px; min-width:0; padding:4px 7px; border:1px solid #c7ced8; border-radius:6px; font:inherit; font-size:12.5px; font-weight:600; }
.tpl-sec-en, .tpl-sec-short { flex:0 1 100px; min-width:0; padding:4px 7px; border:1px solid #c7ced8; border-radius:6px; font:inherit; font-size:12px; font-weight:400; }
.tpl-sec-short { flex-basis:74px; }
.tpl-frow { display:flex; gap:6px; align-items:center; padding:3px 0; flex-wrap:wrap; }
.tpl-f { padding:4px 7px; border:1px solid #c7ced8; border-radius:6px; font:inherit; font-size:12.5px; background:#fff; color:var(--ink); min-width:0; }
.tpl-f:focus { outline:none; border-color:var(--accent); }
.tpl-f-key { flex:0 0 96px; }
.tpl-f-en { flex:0 0 96px; }
.tpl-f-short { flex:0 0 66px; }
.tpl-f-type { flex:0 0 70px; }
.tpl-f-unit { flex:0 0 56px; }
.tpl-f-opts { flex:1 1 140px; }
.tpl-inname { flex:0 0 auto; display:flex; align-items:center; gap:3px; font-size:11px; color:#516079; cursor:pointer; }
.tpl-inname input { cursor:pointer; }
.tpl-f:disabled { background:#f4f6f9; color:#c1c8d2; }
.tpl-del-f, .tpl-del-sec { flex:0 0 auto; width:22px; height:22px; border:none; border-radius:6px; background:transparent; color:#b0b7c2; cursor:pointer; font-size:16px; line-height:1; }
.tpl-del-f:hover, .tpl-del-sec:hover { background:#fdecec; color:#c0392b; }
.tpl-add-f, .tpl-add-sec { margin-top:4px; padding:3px 10px; border:1px dashed #c7ced8; border-radius:6px; background:transparent; color:#516079; cursor:pointer; font:inherit; font-size:12px; }
.tpl-add-f:hover, .tpl-add-sec:hover { border-color:var(--accent); color:var(--accent); }
.tpl-add-sec { display:block; margin:0 0 12px; }
.tpl-name-note { font-size:11.5px; color:#8a93a3; margin:2px 0 6px; }
.tpl-line-src { font-size:12px; color:#3d6ae0; background:#eef4fb; border:1px solid #cfe0f5; border-radius:6px; padding:4px 8px; margin:6px 0; }
.tpl-line-src.warn { color:#8a5a00; background:#fff6e6; border-color:#f0d9a8; }
/* the product name can be multi-line (one line per section) — preserve the breaks */
.doc-product-name { white-space:pre-line; }
.tpl-json-area { width:100%; min-height:340px; padding:10px; border:1px solid #c7ced8; border-radius:8px; font:12px/1.5 ui-monospace,Menlo,Consolas,monospace; color:var(--ink); resize:vertical; }
.tpl-admin-msg { font-size:12px; color:#516079; margin-right:8px; }
.doc-bom { margin:.5rem 0; font-size:.9rem; }
.doc-bom-empty { margin:.5rem 0; }
.doc-bom-head { display:flex; align-items:center; gap:.4rem; flex-wrap:wrap; }
.doc-bom-count { color:#b45309; font-weight:600; }
.doc-bom-count.ok { color:#15803d; }
.doc-bom-btns { display:flex; gap:6px; margin-top:5px; flex-wrap:nowrap; }
/* size each button to its label so all three sit on one line (the base
   .props-btn width:100% otherwise stacked them). Shrink gracefully if narrow. */
.doc-bom-btns .props-btn { margin-top:0; width:auto; flex:0 1 auto; min-width:0; white-space:nowrap; padding:7px 8px; }

.bom-file-row { display:flex; align-items:center; gap:10px; margin:8px 0 6px; flex-wrap:wrap; }
.bom-file-btn { display:inline-block; padding:5px 12px; border:1px solid #8aa0bd; border-radius:8px;
  background:#f6f9fe; color:#2a3140; font-size:12px; cursor:pointer; }
.bom-file-btn:hover { background:#e6eefb; }
.bom-file-name { font-size:12px; color:#15803d; max-width:220px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bom-or { font-size:11px; color:#9aa3b0; }
#bom-paste { width:100%; box-sizing:border-box; font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:12px; padding:8px; border:1px solid #c7ced8; border-radius:8px; resize:vertical; }
.bom-map-row { display:flex; flex-wrap:wrap; gap:10px; margin:10px 0 6px; }
.bom-map-row label { display:flex; flex-direction:column; gap:3px; font-size:12px; }
.bom-map-row select { padding:4px 6px; border:1px solid #c7ced8; border-radius:6px; font:inherit; }
.bom-preview-tbl { width:100%; border-collapse:collapse; font-size:12px; margin-top:4px; }
.bom-preview-tbl th, .bom-preview-tbl td { text-align:left; padding:3px 8px; border-bottom:1px solid #eef1f5;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:180px; }
.bom-preview-tbl th { color:#6b7280; font-weight:600; }

.bom-cell-name { flex:1; min-width:0; font-size:13px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bom-ref { color:#6b7280; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11px; margin-right:2px; }
.bom-qty { color:#9aa3b0; font-size:11px; margin-left:6px; }
.bom-side { font-size:10.5px; font-style:normal; padding:0 5px; border-radius:5px; }
.bom-side.in { color:#3730a3; background:#e0e7ff; }
.bom-side.out { color:#9a3412; background:#ffedd5; }

/* Coverage editor: one block per BOM line, its allocations as chips */
#bom-match-list { max-height:56vh; overflow-y:auto; }
.bom-line { padding:9px 4px; border-bottom:1px solid #eef1f5; }
.bom-line.done { opacity:.72; }
.bom-line-head { display:flex; align-items:center; gap:6px; font-size:13px; }
.bom-remain { margin-left:auto; font-size:11px; font-weight:600; color:#b45309; white-space:nowrap; }
.bom-remain.ok { color:#15803d; }
.bom-chips { display:flex; flex-wrap:wrap; gap:6px; margin:6px 0 0; }
.bom-chip { display:inline-flex; align-items:center; gap:5px; padding:2px 4px 2px 8px;
  background:#f2f5f9; border:1px solid #e1e7ef; border-radius:12px; font-size:12px; }
.bom-chip-name { max-width:150px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  border:0; background:none; font:inherit; color:inherit; cursor:pointer; padding:0; }
.bom-chip-name:hover { color:#2563eb; text-decoration:underline; }
.bom-chip-qty { color:#6b7280; font-size:11px; }
.bom-chip-del { border:0; background:none; color:#b6bcc6; cursor:pointer; font-size:14px; line-height:1; padding:0 2px; }
.bom-chip-del:hover { color:#dc2626; }
.bom-alloc-add { display:flex; align-items:center; gap:6px; margin-top:7px; }
.bom-alloc-step { flex:1; min-width:0; max-width:200px; padding:4px 6px; border:1px solid #c7ced8; border-radius:6px; font:inherit; font-size:12px; }
.bom-alloc-qty { width:56px; padding:4px 6px; border:1px solid #c7ced8; border-radius:6px; font:inherit; font-size:12px; }
/* the button must size to its label, or (being .props-btn, width:100%) it eats
   the row and squeezes the step <select> down to a few unusable pixels */
.bom-alloc-add .props-btn, .bom-alloc-add-btn { margin-top:0; width:auto; flex:none; }
.bom-alloc-step { max-width:none; }

/* Per-step BOM pane */
#sec-bom-step .sec-head { margin-bottom:6px; }
.bom-step-line { display:flex; align-items:center; gap:6px; padding:4px 0; font-size:12px; }
.bom-step-line .bom-cell-name { flex:1; min-width:0; }
.bom-unmatch { border:0; background:none; color:#b6bcc6; cursor:pointer; font-size:15px; line-height:1; padding:0 4px; }
.bom-unmatch:hover { color:#dc2626; }
#bom-step-attach { margin-top:6px; display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
#bom-step-add-btn { margin-top:0; }
.bom-link { border:0; background:none; font:inherit; font-size:12px; color:#2563eb;
  cursor:pointer; padding:0; text-decoration:underline; }
.bom-link:hover { color:#1d4ed8; }

/* BOM material picker dialog — the whole BOM, listed to choose from */
#bom-pick-search { width:100%; box-sizing:border-box; margin:6px 0; padding:6px 8px;
  border:1px solid #c7ced8; border-radius:6px; font:inherit; font-size:13px; }
#bom-pick-list { max-height:56vh; overflow-y:auto; }
.bom-pick-row { display:flex; align-items:center; gap:8px; padding:7px 2px; border-bottom:1px solid #eef1f5; font-size:13px; }
.bom-pick-row .bom-cell-name { flex:1; min-width:0; }
.bom-pick-spec { color:#9aa3b0; font-size:11px; margin-left:6px; }
/* Material grade (材料 — TC4/6061…) as a subtle chip beside a BOM line's name. */
.bom-spec { display:inline-block; margin:0 4px; padding:0 6px; border-radius:6px;
  background:#eef2f8; color:#516079; font-size:11px; font-weight:600; vertical-align:middle; }

/* ---- Edit BOM dialog ---- */
#bom-edit-table { max-height:56vh; overflow-y:auto; margin-top:4px; }
.bom-edit-row { display:grid; grid-template-columns:1fr 60px 1.3fr 0.85fr 0.85fr 0.85fr 50px 46px 56px 210px;
  gap:5px; align-items:center; padding:3px 2px; }
.bom-edit-head { position:sticky; top:0; background:var(--panel); z-index:1;
  font-size:11px; font-weight:600; color:#6b7280; padding-bottom:5px; }
.bom-edit-head span:nth-child(9) { text-align:center; }
/* read-only 图号/ID shown in front of a stock-linked line (WO-040) */
.bom-edit-refro { font-family:ui-monospace,Menlo,monospace; font-size:11px; color:#2f9e58;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bom-edit-row input { width:100%; padding:4px 6px; border:1px solid #c7ced8; border-radius:6px;
  font:inherit; font-size:12px; background:#fff; color:var(--ink); }
.bom-edit-row input:focus { outline:none; border-color:var(--accent); }
.bom-edit-row input[type=number] { text-align:right; font-variant-numeric:tabular-nums; }
.bom-edit-alloc { text-align:center; font-size:12px; color:#8b93a5; font-variant-numeric:tabular-nums;
  border:1px solid transparent; background:transparent; cursor:pointer; border-radius:6px; padding:2px 4px; font-family:inherit; }
.bom-edit-alloc:hover { background:#eef2f7; color:var(--ink); }
.bom-edit-alloc.open { border-color:var(--accent); color:var(--ink); background:#eef4fb; }
.bom-edit-alloc.over { color:#dc2626; font-weight:700; }
/* WO-040 ②: inline 工序分配 panel under a row */
.bom-alloc-panel { margin:1px 2px 8px; padding:7px 10px; background:rgba(0,0,0,0.025); border-radius:8px; }
/* WO-040/WO-042 图号 preview (read-only) */
.bom-drawnum-prefix { margin-bottom:8px; }
.bom-drawnum-new { font-family:ui-monospace,Menlo,monospace; font-weight:600; color:#1f4e79; }
.bom-drawnum-cur { color:#8b93a5; font-family:ui-monospace,Menlo,monospace; }
.bom-drawnum-need { color:#b45309; font-size:12px; }
.bom-drawnum-linked { color:#2f9e58; font-size:12px; }
.bom-drawnum-exists { color:#b45309; font-size:11px; }       /* already in stock — reuse */
.bom-drawnum-willcreate { color:#2f9e58; font-size:11px; }   /* new — will register at 投产 */
.bom-edit-del { border:none; background:transparent; color:#b91c1c; cursor:pointer;
  font-size:16px; line-height:1; border-radius:6px; padding:2px 6px; }
.bom-edit-del:hover { background:#fde8e8; }
.bom-edit-acts { display:flex; align-items:center; justify-content:flex-end; gap:1px; }
.bom-edit-mv { border:none; background:transparent; cursor:pointer; opacity:.6; font-size:12px; line-height:1; border-radius:6px; padding:2px 3px; color:var(--ink); }
.bom-edit-mv:hover:not(:disabled) { background:#eef2f7; opacity:1; }
.bom-edit-mv:disabled { opacity:.22; cursor:default; }
.bom-row-grp { max-width:96px; margin:0 3px; padding:2px 4px; border:1px solid #c7ced8; border-radius:6px; font:inherit; font-size:11px; background:#fff; color:var(--ink); }
.bom-row-class { width:100%; padding:2px 4px; border:1px solid #c7ced8; border-radius:6px; font:inherit; font-size:11px; background:#fff; color:var(--ink); }
.bom-edit-pick { border:none; background:transparent; cursor:pointer; opacity:.65;
  font-size:13px; line-height:1; border-radius:6px; padding:2px 5px; }
.bom-edit-pick:hover { background:#eef2f7; opacity:1; }
.bom-edit-pick.linked { color:#2f9e58; opacity:1; }
.bom-edit-dwg { border:none; background:transparent; cursor:pointer; opacity:.6;
  font-size:13px; line-height:1; border-radius:6px; padding:2px 4px; }
.bom-edit-dwg:hover { background:#eef2f7; opacity:1; }
.bom-edit-dwg.has { opacity:1; }
/* "待补全" advisory highlights (amber) — distinct from the red .over over-allocation error.
   Purely visual; never blocks Save. (owner 2026-09-11) */
.bom-row-warn { color:var(--warn); font-weight:700; margin-right:3px; }
/* cross-group duplicate = a "check this" pill (reads as 重复), amber family but a bordered tag
   so it is not mistaken for the ⚠ 待补全 marker. */
.bom-row-dup { display:inline-block; font-size:10px; font-weight:700; line-height:1.5; color:var(--warn);
  border:1px solid var(--warn-border); background:var(--warn-bg); border-radius:8px; padding:0 5px; margin-right:3px; }
/* 生成图号 wizard */
.drawnum-steps { display:flex; flex-wrap:wrap; gap:6px; margin-top:4px; }
.drawnum-step { font-size:11px; padding:2px 8px; border-radius:10px; background:#eef2f7; color:#6b7280; }
.drawnum-step.cur { outline:2px solid var(--accent); }
.drawnum-step.ok { background:#e7f5ec; color:#2f7a44; }
.drawnum-step.warn { background:var(--warn-bg); color:var(--warn); }
.drawnum-step.bad { background:#fdeaea; color:#c0392b; }
.drawnum-body { margin:10px 0; min-height:120px; }
.drawnum-gate { font-size:13px; padding:3px 0; }
.drawnum-gate.ok .drawnum-mark { color:#2f9e58; }
.drawnum-gate.block .drawnum-mark { color:#c0392b; }
.drawnum-gate.warn .drawnum-mark { color:var(--warn); }
.drawnum-gate.pending .drawnum-mark { color:#9aa4b5; }
.drawnum-mark { display:inline-block; width:16px; font-weight:700; }
.drawnum-prefix { font-size:18px; font-weight:700; color:var(--accent); margin:6px 0; font-family:monospace; }
.drawnum-prefix.bad { color:#c0392b; }
.drawnum-spacer { flex:1; }
.drawnum-sec { margin:8px 0; }
.drawnum-sec-head { font-weight:700; font-size:12px; color:#6b7280; margin-bottom:4px; }
.drawnum-item { padding:6px 8px; border:1px solid var(--panel-border); border-radius:6px; margin:4px 0; font-size:13px; }
.drawnum-item.resolved { color:#2f7a44; background:#f2fbf5; border-color:#cde9d6; }
.drawnum-cands { display:flex; flex-wrap:wrap; gap:5px; margin:5px 0; }
.drawnum-pick { display:inline-flex; gap:3px; align-items:center; }
.drawnum-link { font-size:12px; padding:2px 8px; border:1px solid var(--accent); background:#eef4fb; color:#1e40af; border-radius:6px; cursor:pointer; }
.drawnum-link:hover { background:#dceafc; }
.note-line.ok { color:#2f7a44; }
.drawnum-ok { color:#2f7a44; font-weight:600; }
.bom-edit-row input.bom-cell-need { border:1.5px solid var(--warn-border); background:var(--warn-bg); }
.bom-edit-row input.bom-cell-need::placeholder { color:var(--warn); opacity:.75; }
.bom-edit-alloc.need { color:var(--warn); border-color:var(--warn-border); background:var(--warn-bg); font-weight:700; }
.bom-edit-dwg.need { opacity:1; background:var(--warn-bg); }
/* identity-v2 R1-d: engineer-initiated "加入目录" (promote to library) */
.bom-edit-promote { border:none; background:transparent; cursor:pointer; opacity:.6;
  font-size:13px; line-height:1; border-radius:6px; padding:2px 4px; }
.bom-edit-promote:hover { background:#eef2f7; opacity:1; }
.bom-dwg-row { margin:8px 0; }
/* WO-040 two-level group editor */
.bom-grp { border:1px solid #d7dde6; border-radius:8px; margin:8px 0; padding:2px 6px 6px; background:#fbfcfe; }
.bom-grp-ung { background:#f6f7f9; border-style:dashed; }
.bom-grp-head { display:flex; align-items:center; gap:5px; padding:5px 2px; }
.bom-grp-title { font-weight:700; font-size:12px; color:#6b7280; }
.bom-grp-name { flex:1; font-weight:700; font-size:13px; padding:4px 7px; border:1px solid #c7ced8;
  border-radius:6px; background:#fff; color:var(--ink); }
.bom-grp-name:focus, .bom-sub-name:focus { outline:none; border-color:var(--accent); }
.bom-grp-btn { border:1px solid #d0d7e2; background:#fff; color:#4b5563; cursor:pointer; font-size:12px;
  line-height:1; border-radius:6px; padding:4px 7px; white-space:nowrap; }
.bom-grp-btn:hover:not(:disabled) { background:#eef2f7; }
.bom-grp-btn:disabled { opacity:.35; cursor:default; }
.bom-grp-btn.danger { color:#b91c1c; }
.bom-grp-btn.danger:hover:not(:disabled) { background:#fde8e8; }
.bom-sub { margin:4px 0 4px 14px; border-left:2px solid #e2e8f0; padding-left:8px; }
.bom-sub-head { display:flex; align-items:center; gap:5px; padding:3px 2px; }
.bom-sub-name { flex:1; font-size:12px; padding:3px 7px; border:1px solid #c7ced8; border-radius:6px;
  background:#fff; color:var(--ink); }
.bom-rowadd { padding:3px 2px 2px; }
.bom-rowadd .props-btn, .bom-grp-add-wrap .props-btn { font-size:12px; padding:3px 10px; }
.bom-grp-add-wrap { margin-top:10px; }
/* Group cards (collapsible) — soft-blue header band + crisp left accent stripe (owner mockup
   2026-09-11). Flow is a single light theme; colors are the mockup's blues. The 未分组 bucket
   keeps the plain dashed .bom-grp look above and is NOT a card. */
.bom-grp-card { border:1px solid var(--panel-border); border-left:3px solid var(--accent);
  border-radius:0 8px 8px 0;   /* square left corner so the accent stripe reads as one crisp bar */
  background:#fff; padding:0; overflow:hidden; }
.bom-grp-card > .bom-grp-head { background:#e6f1fb; padding:7px 10px; gap:8px; margin:0; cursor:pointer; }
.bom-grp-card > .bom-grp-head:focus-visible { outline:2px solid var(--accent); outline-offset:-2px; }
.bom-grp-chevron { color:#1e40af; font-size:11px; width:12px; text-align:center; user-select:none; }
.bom-grp-seq { flex:none; background:#cfe1f7; color:#1e40af; font-size:11px; font-weight:700;
  padding:1px 8px; border-radius:10px; white-space:nowrap; }
.bom-grp-card .bom-grp-name { flex:1; font-weight:700; font-size:14px; color:#1e3a8a;
  background:transparent; border:1px solid transparent; border-radius:6px; padding:3px 7px; }
.bom-grp-card .bom-grp-name:hover { background:#fff; border-color:#c7d7ee; }
.bom-grp-card .bom-grp-name:focus { background:#fff; border-color:var(--accent); outline:none; }
.bom-grp-count { flex:none; font-size:11px; color:#5b6b8c; white-space:nowrap; }
.bom-grp-acts { flex:none; display:flex; gap:4px; }
.bom-grp-body { padding:2px 8px 8px; }
.bom-edit-foot { display:flex; align-items:center; gap:8px; margin-top:10px; }
.bom-edit-foot .danger { margin-left:auto; }
.bom-pick-status { font-size:11px; color:#b45309; white-space:nowrap; }
.bom-pick-qty { width:52px; padding:4px 6px; border:1px solid #c7ced8; border-radius:6px; font:inherit; font-size:12px; }
.bom-pick-add { border:1px solid #2f6f4f; background:#eafaf1; color:#256; border-radius:6px;
  padding:3px 10px; font:inherit; font-size:12px; cursor:pointer; white-space:nowrap; }
.bom-pick-add:hover { background:#256; color:#fff; }
.bom-pick-here { font-size:11px; color:#15803d; white-space:nowrap; }
.bom-pick-done { font-size:11px; color:#9aa3b0; white-space:nowrap; }

/* WO-028 回收站 (recycle bin) dialog */
.trash-sub { font-size: 12.5px; color: #8a95a6; margin: 2px 0 4px; }
#trash-list { display: flex; flex-direction: column; gap: 8px;
  max-height: 58vh; overflow-y: auto; margin: 12px 0 2px; padding: 1px; }
.trash-row { display: flex; align-items: center; gap: 12px;
  padding: 11px 13px; border: 1px solid var(--panel-border); border-radius: 10px;
  background: #fff; transition: border-color .12s ease, box-shadow .12s ease; }
.trash-row:hover { border-color: #cdd8e8; box-shadow: 0 2px 10px rgba(30, 40, 60, .07); }
.trash-ico { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 9px;
  display: grid; place-items: center; font-size: 16px; line-height: 1; }
.trash-ico--design { background: #eef2fb; color: #3b6fd4; }
.trash-ico--order  { background: #fdf1e4; color: #c47d1a; }
.trash-main { min-width: 0; flex: 1 1 auto; display: flex; flex-direction: column; gap: 5px; }
.trash-name { font-size: 14px; font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trash-meta { display: flex; align-items: center; gap: 8px; min-width: 0; }
.trash-badge { flex: 0 0 auto; font-size: 11px; font-weight: 600; padding: 1px 8px;
  border-radius: 999px; letter-spacing: .02em; }
.trash-badge--design { background: #eef2fb; color: #3b6fd4; }
.trash-badge--order  { background: #fdf1e4; color: #b9760f; }
.trash-when { font-size: 12px; color: #8a95a6;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trash-acts { display: flex; gap: 8px; flex: 0 0 auto; }
.trash-btn { font: inherit; font-size: 12.5px; font-weight: 500; padding: 6px 14px;
  border-radius: 7px; border: 1px solid var(--panel-border); background: #fff;
  color: var(--ink); cursor: pointer; white-space: nowrap;
  transition: background .12s ease, border-color .12s ease; }
.trash-restore { border-color: #bcd3f5; color: #2f6fe0; }
.trash-restore:hover { background: #eef4fe; border-color: #8fb6f0; }
.trash-purge { color: #c23b3b; border-color: #eccaca; }
.trash-purge:hover { background: #fdf1f1; border-color: #e3aeae; }
.trash-empty { display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 40px 0 34px; color: #9aa5b4; }
.trash-empty-ico { font-size: 30px; opacity: .45; line-height: 1; }
.trash-empty-text { font-size: 13px; }
