:root {
  /* Neutral */
  --bg: #f3f4f6;
  --surface: #ffffff;
  --surface-subtle: #f8f9fb;
  --surface-hover: #f2f4f7;
  --text: #111827;
  --text-secondary: #4b5563;
  --border: #e4e7ec;
  --border-row: #eef0f3;
  --border-control: #d0d5dd;
  /* Input borders must reach 3:1 against white (WCAG 1.4.11). */
  --border-strong: #8a93a2;
  --row-hover-bg: #f7f9fc;
  --row-selected-bg: #eef4ff;

  /* Brand: graphite navy chrome + one accent */
  --primary: #1b2536;
  --primary-hover: #243044;
  --sidebar-text: #c9d1dc;
  --sidebar-text-active: #ffffff;
  --sidebar-muted: #8e9aad;
  --sidebar-active-bg: #2c3a52;
  --sidebar-active-bar: #7aa2ff;
  --sidebar-badge-bg: #3a4963;
  --accent: #2257d6;
  --accent-hover: #1b47b3;
  --accent-tint: #edf3ff;
  --on-fill: #ffffff;

  /* Semantic */
  --success: #15803d;
  --success-bg: #ecf8f0;
  --success-line: #b7e1c4;
  --warning: #a15c07;
  --warning-bg: #fef4e2;
  --warning-strong: #f5a524;
  --danger: #b42318;
  --danger-hover: #912018;
  --danger-bg: #fef1f0;

  /* Status pairs: background / text / dot. Text is AA on its background. */
  --st-planned-bg: #f1f3f6;
  --st-planned-text: #3f4a5a;
  --st-planned-dot: #8a94a6;
  --st-in-progress-bg: #eaf1ff;
  --st-in-progress-text: #1e4fb8;
  --st-in-progress-dot: #2f6fed;
  --st-on-hold-bg: #fdf3e3;
  --st-on-hold-text: #8a4b00;
  --st-on-hold-dot: #d98a0b;
  --st-in-repair-bg: #fff0e8;
  --st-in-repair-text: #a13b0a;
  --st-in-repair-dot: #ea6a1f;
  --st-completed-bg: #eaf7ef;
  --st-completed-text: #146c34;
  --st-completed-dot: #22a355;
  --st-shipped-bg: #e8f6f5;
  --st-shipped-text: #0d625c;
  --st-shipped-dot: #14a39a;
  --st-returned-bg: #f4edfd;
  --st-returned-text: #5b21b6;
  --st-returned-dot: #8b5cf6;
  --st-scrapped-bg: #fdeeee;
  --st-scrapped-text: #a11b1b;
  --st-scrapped-dot: #dc3a3a;
  --st-qc-waiting-bg: #fdf6d8;
  --st-qc-waiting-text: #7a5a00;
  --st-qc-waiting-dot: #d4a20b;
  --qc-col-bg: #eef3fd;
  --qc-col-text: var(--text);

  /* Type */
  --font-family: "Segoe UI Variable Text", "Segoe UI", system-ui, -apple-system, Arial, sans-serif;
  --font-size-meta: 13px;
  --font-size-label: 13px;
  --font-size-table: 14px;
  --font-size-body: 15px;
  --font-size-touch: 16px;
  --font-size-h3: 15px;
  --font-size-h2: 16px;
  --font-size-drawer-title: 18px;
  --font-size-h1: 22px;
  --font-size-stat: 24px;
  --font-size-badge: 13px;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  --line-height-body: 1.45;
  --line-height-tight: 1.25;

  /* Spacing */
  --space-2xs: 2px;
  --space-xs: 4px;
  --space-sm: 8px;
  --space-gap-tight: 6px;
  --space-gap-loose: 12px;
  --space-md: 16px;
  --space-lg: 24px;
  --space-xl: 32px;
  --space-button-x: 14px;
  --space-badge-x: 8px;
  --space-input-y: 6px;
  --space-input-x: 10px;
  --space-cell-y: 10px;
  --space-cell-x: 12px;

  /* Radius */
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-pill: 999px;

  /* Borders */
  --border-width: 1px;
  --border-width-strong: 2px;
  --focus-ring-width: 2px;
  --focus-ring-offset: 2px;

  /* Sizes */
  --sidebar-width: 240px;
  --sidebar-width-collapsed: 64px;
  --topbar-height: 56px;
  --control-height: 36px;
  --control-height-sm: 32px;
  --nav-item-height: 40px;
  --touch-target: 44px;
  --checkbox-touch: 24px;
  --icon-size: 16px;
  --icon-size-nav: 18px;
  --stat-icon-size: 36px;
  --drawer-width: 480px;
  --content-max: 1600px;
  --panel-max-width: 600px;
  --popover-min-width: 280px;
  --search-width: 360px;

  /* Overlays only: drawer, toast, action bar, popover, dialog. Surfaces stay flat. */
  --shadow-overlay: 0 12px 32px rgb(16 24 40 / 0.14), 0 2px 6px rgb(16 24 40 / 0.08);
  --scrim: rgb(16 24 40 / 0.28);
  --scrim-modal: rgb(16 24 40 / 0.4);
  --on-dark-border: rgb(255 255 255 / 0.24);
  --on-dark-hover: rgb(255 255 255 / 0.1);

  /* Motion: short, functional, disabled under prefers-reduced-motion */
  --motion-fast: 120ms;
  --motion-base: 180ms;
  --ease: cubic-bezier(0.2, 0.8, 0.2, 1);

  /* Layers */
  --z-sticky: 2;
  --z-topbar: 20;
  --z-actionbar: 30;
  --z-drawer: 40;
  --z-toast: 50;

  /* Legacy: still read by page-specific rules not yet migrated to the new shell (milestone 2). */
  --marker-width: 4px;
  --matrix-max-height: 70vh;
  --matrix-header-max-height: 220px;
}

*, *::before, *::after { box-sizing: border-box; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-family);
  font-size: var(--font-size-body);
  line-height: var(--line-height-body);
  -webkit-font-smoothing: antialiased;
}
h1, .page-title { font-size: var(--font-size-h1); font-weight: var(--font-weight-semibold); line-height: var(--line-height-tight); margin: 0 0 var(--space-md); letter-spacing: -0.01em; }
h2 { font-size: var(--font-size-h2); font-weight: var(--font-weight-semibold); line-height: var(--line-height-tight); margin: var(--space-lg) 0 var(--space-gap-loose); }
h3 { font-size: var(--font-size-h3); font-weight: var(--font-weight-semibold); margin: var(--space-md) 0 var(--space-sm); }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
:focus-visible { outline: var(--focus-ring-width) solid var(--accent); outline-offset: var(--focus-ring-offset); }
/* --accent fails 3:1 on the dark chrome (sidebar, action bar); use the lighter accent already
   reserved for the active-nav-item bar, which reaches 6.19:1 on --primary. */
.sidebar :focus-visible, .action-bar > :focus-visible, .action-bar > .popover > summary:focus-visible { outline-color: var(--sidebar-active-bar); }
.muted { color: var(--text-secondary); }
.icon { width: var(--icon-size); height: var(--icon-size); flex: none; vertical-align: -3px; }

/* Shell */
.app-shell { display: grid; grid-template-columns: var(--sidebar-width) minmax(0, 1fr); min-height: 100vh; }
.sidebar { position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column; gap: var(--space-xs); padding: var(--space-gap-loose) 10px; background: var(--primary); color: var(--sidebar-text); overflow-y: auto; }
.sidebar-brand { display: flex; align-items: center; min-height: var(--touch-target); padding: 0 10px; margin-bottom: var(--space-sm); color: var(--sidebar-text-active); font-weight: var(--font-weight-semibold); font-size: var(--font-size-body); }
.sidebar-nav { display: flex; flex-direction: column; gap: var(--space-2xs); }
.sidebar-section { margin: var(--space-md) 0 var(--space-xs); padding: 0 10px; font-size: var(--font-size-meta); font-weight: var(--font-weight-semibold); color: var(--sidebar-muted); }
.nav-item { position: relative; display: flex; align-items: center; gap: 10px; min-height: var(--nav-item-height); padding: 0 10px; border-radius: var(--radius-sm); color: var(--sidebar-text); font-size: var(--font-size-table); font-weight: var(--font-weight-medium); text-decoration: none; }
.nav-item .icon { width: var(--icon-size-nav); height: var(--icon-size-nav); }
.nav-item:hover { background: var(--primary-hover); color: var(--sidebar-text-active); text-decoration: none; }
.nav-item[aria-current="page"] { background: var(--sidebar-active-bg); color: var(--sidebar-text-active); box-shadow: inset 3px 0 0 var(--sidebar-active-bar); }
.nav-badge { margin-left: auto; min-width: 22px; height: 20px; padding: 0 var(--space-gap-tight); border-radius: var(--radius-pill); background: var(--sidebar-badge-bg); color: var(--sidebar-text-active); font-size: var(--font-size-meta); font-weight: var(--font-weight-semibold); font-variant-numeric: tabular-nums; display: inline-grid; place-items: center; }
.nav-badge.is-attention { background: var(--warning-strong); color: var(--primary); }
.nav-badge[hidden] { display: none; }
.sidebar-footer { margin-top: auto; padding-top: var(--space-sm); }
.sidebar-toggle { width: 100%; justify-content: flex-start; gap: 10px; background: transparent; border-color: transparent; color: var(--sidebar-muted); }
.sidebar-toggle:hover { background: var(--primary-hover); color: var(--sidebar-text-active); }
.app-main { min-width: 0; display: flex; flex-direction: column; }
.topbar { position: sticky; top: 0; z-index: var(--z-topbar); display: flex; align-items: center; gap: var(--space-md); min-height: var(--topbar-height); padding: 0 var(--space-lg); background: var(--surface); border-bottom: var(--border-width) solid var(--border); }
.breadcrumbs { display: flex; align-items: center; gap: var(--space-gap-tight); min-width: 0; font-size: var(--font-size-table); color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.breadcrumbs a { color: var(--text-secondary); }
.breadcrumbs [aria-current="page"] { color: var(--text); font-weight: var(--font-weight-medium); }
.topbar-search { position: relative; margin-left: auto; width: min(var(--search-width), 40vw); }
.topbar-search .icon { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--text-secondary); pointer-events: none; }
.topbar-search input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]) { width: 100%; padding-left: 34px; background: var(--surface-subtle); }
.user-menu { position: relative; }
.user-menu > summary { display: flex; align-items: center; gap: 10px; padding: var(--space-sm); border-radius: var(--radius-sm); cursor: pointer; list-style: none; }
.user-menu > summary::-webkit-details-marker { display: none; }
.user-menu > summary:hover { background: var(--surface-hover); }
.avatar { width: 32px; height: 32px; border-radius: var(--radius-pill); display: grid; place-items: center; background: var(--accent-tint); color: var(--accent); font-size: var(--font-size-meta); font-weight: var(--font-weight-semibold); line-height: 1; }
.user-name { display: block; font-size: var(--font-size-table); font-weight: var(--font-weight-medium); line-height: var(--line-height-tight); }
.user-tab { display: block; font-size: var(--font-size-meta); color: var(--text-secondary); line-height: var(--line-height-tight); }
.menu-panel { position: absolute; right: 0; top: calc(100% + 6px); min-width: 220px; padding: var(--space-xs); background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--radius-md); box-shadow: var(--shadow-overlay); display: flex; flex-direction: column; }
.menu-panel a, .menu-panel button { display: flex; align-items: center; gap: var(--space-sm); width: 100%; min-height: var(--control-height); padding: 0 10px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--text); font-weight: var(--font-weight-normal); text-decoration: none; justify-content: flex-start; }
.menu-panel a:hover, .menu-panel button:hover { background: var(--surface-hover); text-decoration: none; }
.bell-menu { position: relative; }
.bell-menu > summary { display: flex; align-items: center; justify-content: center; position: relative; width: var(--control-height-sm); height: var(--control-height-sm); border-radius: var(--radius-sm); color: var(--text-secondary); cursor: pointer; list-style: none; }
.bell-menu > summary::-webkit-details-marker { display: none; }
.bell-menu > summary:hover { background: var(--surface-hover); color: var(--text); }
.bell-count { position: absolute; top: var(--space-2xs); right: var(--space-2xs); min-width: var(--space-md); height: var(--space-md); padding: 0 var(--space-2xs); border-radius: var(--radius-pill); background: var(--accent); color: var(--on-fill); font-size: var(--font-size-meta); font-weight: var(--font-weight-semibold); font-variant-numeric: tabular-nums; display: inline-grid; place-items: center; line-height: 1; }
.menu-panel.bell-panel { min-width: var(--popover-min-width); max-height: calc(100vh - var(--topbar-height) - var(--space-lg)); overflow-y: auto; }
.bell-empty { margin: 0; padding: var(--space-sm) var(--space-input-x); color: var(--text-secondary); }
.content { width: 100%; max-width: var(--content-max); margin: 0 auto; padding: var(--space-lg); }
.content-wide { max-width: none; }
.content-auth { max-width: var(--panel-max-width); }
.skip-link { position: absolute; left: -9999px; top: var(--space-sm); z-index: var(--z-toast); padding: var(--space-sm) var(--space-md); background: var(--surface); border: var(--border-width) solid var(--accent); border-radius: var(--radius-sm); }
.skip-link:focus { left: var(--space-sm); }
.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Collapsed rail: user toggle, or automatically on tablet widths */
html.sidebar-collapsed .app-shell { grid-template-columns: var(--sidebar-width-collapsed) minmax(0, 1fr); }
html.sidebar-collapsed .nav-label, html.sidebar-collapsed .sidebar-section, html.sidebar-collapsed .sidebar-brand-text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
html.sidebar-collapsed .nav-item, html.sidebar-collapsed .sidebar-toggle { justify-content: center; padding: 0; }
html.sidebar-collapsed .nav-badge { position: absolute; top: 2px; right: 4px; min-width: 18px; height: 16px; font-size: 11px; }
html.sidebar-collapsed .sidebar-toggle .icon { transform: rotate(180deg); }
@media (max-width: 1279px) {
  .app-shell { grid-template-columns: var(--sidebar-width-collapsed) minmax(0, 1fr); }
  .nav-label, .sidebar-section, .sidebar-brand-text { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .nav-item { justify-content: center; padding: 0; }
  .nav-badge { position: absolute; top: 2px; right: 4px; min-width: 18px; height: 16px; font-size: 11px; }
  .sidebar-toggle { display: none; }
  .table-scroll { overflow-x: auto; }
  /* .table-scroll becomes the sticky-positioning ancestor at this width, so the
     topbar-height offset would push the header 56px down and cover the first rows. */
  .table-scroll .data-table thead th { top: 0; }
}

/* Page header */
.page-header { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--space-md); margin-bottom: 20px; }
.page-header .page-title { margin: 0; }
.page-subtitle { margin: var(--space-xs) 0 0; color: var(--text-secondary); font-size: var(--font-size-table); }
.page-actions, .form-actions { display: flex; align-items: center; gap: var(--space-sm); flex-wrap: wrap; }

/* Section header: the one title pattern for a card or table-card on a detail page.
   Sits as the first child of .card/.table-card/.disclosure, own padding + border-bottom,
   so a plain-text hint (e.g. "Обновляется автоматически") never doubles up with the card
   body's own padding and never glues onto the title text. */
.card-header { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-gap-loose); padding: 10px var(--space-md); border-bottom: var(--border-width) solid var(--border); }
.card-header-title { margin: 0; font-size: var(--font-size-h2); font-weight: var(--font-weight-semibold); line-height: var(--line-height-tight); }
.card-header-hint { color: var(--text-secondary); font-size: var(--font-size-meta); font-weight: var(--font-weight-normal); white-space: nowrap; }
.card-header-actions { display: flex; align-items: center; gap: var(--space-sm); }

/* Disclosure: a <details> inside a card, its <summary> styled as a section header instead
   of the bare browser triangle floating outside any surface. */
.card > details > summary { display: flex; align-items: center; gap: var(--space-sm); padding: 10px var(--space-md); margin: 0; font-size: var(--font-size-h2); font-weight: var(--font-weight-semibold); line-height: var(--line-height-tight); cursor: pointer; list-style: none; }
.card > details > summary::-webkit-details-marker { display: none; }
.card > details > summary::before { content: ""; flex: none; border-style: solid; border-width: 4px 0 4px 5px; border-color: transparent transparent transparent currentColor; transition: transform var(--motion-fast) var(--ease); }
.card > details[open] > summary::before { transform: rotate(90deg); }
.card > details[open] > summary { border-bottom: var(--border-width) solid var(--border); }

/* Footer toolbar for a table-card whose table ends in an action button (e.g. "batch mark"),
   so the button never sits glued to the table's bottom edge. */
.table-card-actions { padding: 10px var(--space-md); border-top: var(--border-width) solid var(--border); }

/* Vertical gap above a form or disclosure embedded further down inside a card body. */
.subsection { margin-top: var(--space-lg); }

/* Vertical rhythm for a page's stacked top-level cards/table-cards (e.g. route.html), so a
   card never touches the one below it with no gap (V5). */
.stack-lg { display: flex; flex-direction: column; gap: var(--space-lg); }

/* Buttons */
button, .button { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-gap-tight); min-height: var(--control-height); padding: 0 var(--space-button-x); border: var(--border-width) solid var(--border-control); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); font: inherit; font-size: var(--font-size-table); font-weight: var(--font-weight-medium); line-height: 1; white-space: nowrap; text-decoration: none; cursor: pointer; transition: background-color var(--motion-fast) var(--ease), border-color var(--motion-fast) var(--ease), color var(--motion-fast) var(--ease); }
button:hover, .button:hover { background: var(--surface-hover); text-decoration: none; }
.primary { background: var(--accent); border-color: var(--accent); color: var(--on-fill); }
.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.danger { background: var(--danger); border-color: var(--danger); color: var(--on-fill); }
.danger:hover { background: var(--danger-hover); border-color: var(--danger-hover); }
.secondary.danger { background: var(--surface); color: var(--danger); border-color: var(--danger); }
.secondary.danger:hover { background: var(--danger-bg); }
.ghost { background: transparent; border-color: transparent; color: var(--text-secondary); }
.ghost:hover { background: var(--surface-hover); color: var(--text); }
.button-sm { min-height: var(--control-height-sm); padding: 0 10px; font-size: var(--font-size-meta); }
.icon-button { width: var(--control-height-sm); min-height: var(--control-height-sm); padding: 0; }
/* A submit button that reads as inline text, not a bordered control -- the notifications
   list's whole row text is the "open" action, so it must look like the cell-primary links
   used elsewhere rather than a boxed button. */
.link-button { display: inline; min-height: 0; padding: 0; border: 0; border-radius: 0; background: none; color: var(--text); font: inherit; font-size: inherit; font-weight: var(--font-weight-normal); text-align: left; white-space: normal; }
.link-button:hover { background: none; color: var(--accent); text-decoration: underline; }
.link-button.is-unread { font-weight: var(--font-weight-semibold); }
button:disabled, .button[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; }

/* Fields */
label { display: block; margin-bottom: var(--space-xs); font-size: var(--font-size-label); font-weight: var(--font-weight-medium); color: var(--text-secondary); }
input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]), select, textarea { min-height: var(--control-height); padding: var(--space-input-y) var(--space-input-x); border: var(--border-width) solid var(--border-strong); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); font: inherit; font-size: var(--font-size-table); }
input:not([type="checkbox"]):not([type="radio"]):hover, select:hover, textarea:hover { border-color: var(--text-secondary); }
input[type="checkbox"], input[type="radio"] { width: 16px; height: 16px; accent-color: var(--accent); }
fieldset { border: var(--border-width) solid var(--border); border-radius: var(--radius-md); padding: var(--space-gap-loose) var(--space-md); }
.field-hint { font-size: var(--font-size-meta); color: var(--text-secondary); margin: var(--space-xs) 0 0; }

/* Cards and tables */
.card { background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--radius-md); }
.card-body { padding: var(--space-md); }
.table-card { background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--radius-md); overflow: clip; }
.table-toolbar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-gap-loose); padding: 10px var(--space-md); border-bottom: var(--border-width) solid var(--border); font-size: var(--font-size-meta); color: var(--text-secondary); }
.live-indicator { display: inline-flex; align-items: center; gap: var(--space-gap-tight); }
.live-indicator::before { content: ""; width: 6px; height: 6px; border-radius: var(--radius-pill); background: var(--success); }
table { width: 100%; border-collapse: separate; border-spacing: 0; background: var(--surface); font-size: var(--font-size-table); }
thead th { background: var(--surface-subtle); color: var(--text-secondary); font-size: var(--font-size-label); font-weight: var(--font-weight-semibold); text-align: left; white-space: nowrap; padding: var(--space-cell-y) var(--space-cell-x); border-bottom: var(--border-width) solid var(--border); }
.data-table thead th { position: sticky; top: var(--topbar-height); z-index: var(--z-sticky); }
td, tbody th { padding: var(--space-cell-y) var(--space-cell-x); border-bottom: var(--border-width) solid var(--border-row); text-align: left; vertical-align: middle; font-weight: var(--font-weight-normal); }
tbody tr:last-child > td, tbody tr:last-child > th { border-bottom: 0; }
tbody tr:hover { background: var(--row-hover-bg); }
tbody tr.is-selected { background: var(--row-selected-bg); }
tbody tr.is-selected > :first-child { box-shadow: inset 3px 0 0 var(--accent); }
td.numeric, th.numeric { text-align: right; font-variant-numeric: tabular-nums; }
.cell-primary { font-weight: var(--font-weight-semibold); color: var(--text); font-variant-numeric: tabular-nums; }
a.cell-primary:hover { color: var(--accent); }
.cell-sub { display: block; font-size: var(--font-size-meta); color: var(--text-secondary); font-weight: var(--font-weight-normal); }
.text-attention { display: inline-flex; align-items: center; gap: var(--space-xs); color: var(--warning); font-weight: var(--font-weight-medium); white-space: nowrap; }
.cell-name { display: block; white-space: nowrap; }
.progress { width: 100%; height: 6px; border: 0; border-radius: var(--radius-pill); background: var(--border-row); overflow: hidden; appearance: none; }
.progress::-webkit-progress-bar { background: var(--border-row); border-radius: var(--radius-pill); }
.progress::-webkit-progress-value { background: var(--accent); border-radius: var(--radius-pill); }
.progress::-moz-progress-bar { background: var(--accent); }

/* Status badges: dot + text, never colour alone */
.badge { display: inline-flex; align-items: center; gap: var(--space-gap-tight); padding: var(--space-2xs) var(--space-badge-x) var(--space-2xs) 7px; border-radius: var(--radius-pill); background: var(--badge-bg, var(--st-planned-bg)); color: var(--badge-text, var(--st-planned-text)); font-size: var(--font-size-badge); font-weight: var(--font-weight-medium); line-height: 18px; white-space: nowrap; }
.badge::before { content: ""; width: 6px; height: 6px; border-radius: var(--radius-pill); background: var(--badge-dot, currentColor); flex: none; }
.st-planned, .rt-draft { --badge-bg: var(--st-planned-bg); --badge-text: var(--st-planned-text); --badge-dot: var(--st-planned-dot); }
.st-in_progress { --badge-bg: var(--st-in-progress-bg); --badge-text: var(--st-in-progress-text); --badge-dot: var(--st-in-progress-dot); }
.st-on_hold { --badge-bg: var(--st-on-hold-bg); --badge-text: var(--st-on-hold-text); --badge-dot: var(--st-on-hold-dot); }
.st-in_repair { --badge-bg: var(--st-in-repair-bg); --badge-text: var(--st-in-repair-text); --badge-dot: var(--st-in-repair-dot); }
.st-completed, .rt-approved, .outcome-restored { --badge-bg: var(--st-completed-bg); --badge-text: var(--st-completed-text); --badge-dot: var(--st-completed-dot); }
.st-shipped { --badge-bg: var(--st-shipped-bg); --badge-text: var(--st-shipped-text); --badge-dot: var(--st-shipped-dot); }
.st-returned, .rt-archived { --badge-bg: var(--st-returned-bg); --badge-text: var(--st-returned-text); --badge-dot: var(--st-returned-dot); }
.st-scrapped, .outcome-scrapped { --badge-bg: var(--st-scrapped-bg); --badge-text: var(--st-scrapped-text); --badge-dot: var(--st-scrapped-dot); }
.st-qc-waiting { --badge-bg: var(--st-qc-waiting-bg); --badge-text: var(--st-qc-waiting-text); --badge-dot: var(--st-qc-waiting-dot); }
.badge-outline { background: transparent; box-shadow: inset 0 0 0 1px var(--border-control); color: var(--text-secondary); }
.badge-outline::before { display: none; }
.tag { display: inline-block; margin-left: var(--space-sm); padding: 0 var(--space-gap-tight); border-radius: var(--radius-sm); background: var(--surface-hover); color: var(--text-secondary); font-size: var(--font-size-meta); }

/* Stat cards */
.stat-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-gap-loose); margin-bottom: var(--space-md); }
.stat-card { display: flex; align-items: center; gap: var(--space-gap-loose); min-height: 76px; padding: 14px var(--space-md); background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--radius-md); color: var(--text); text-decoration: none; }
a.stat-card:hover { border-color: var(--border-control); background: var(--surface-subtle); text-decoration: none; }
.stat-card[aria-current] { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.stat-icon { width: var(--stat-icon-size); height: var(--stat-icon-size); flex: none; display: grid; place-items: center; border-radius: var(--radius-md); background: var(--tone-bg, var(--surface-hover)); color: var(--tone-fg, var(--text-secondary)); }
.stat-icon .icon { width: var(--icon-size-nav); height: var(--icon-size-nav); }
.stat-label { display: block; font-size: var(--font-size-meta); color: var(--text-secondary); }
.stat-value { display: block; font-size: var(--font-size-stat); font-weight: var(--font-weight-semibold); line-height: var(--line-height-tight); font-variant-numeric: tabular-nums; }
.stat-hint { display: block; font-size: var(--font-size-meta); color: var(--text-secondary); }
.tone-info { --tone-bg: var(--accent-tint); --tone-fg: var(--accent); }
.tone-success { --tone-bg: var(--success-bg); --tone-fg: var(--success); }
.tone-warning { --tone-bg: var(--warning-bg); --tone-fg: var(--warning); }
.tone-danger { --tone-bg: var(--danger-bg); --tone-fg: var(--danger); }
@media (max-width: 1023px) { .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Filter bar */
.filter-bar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-gap-loose); padding: var(--space-gap-loose) var(--space-md); margin-bottom: var(--space-gap-loose); background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--radius-md); }
.filter-field { display: flex; flex-direction: column; flex: 1 1 150px; min-width: 150px; max-width: 220px; }
.filter-field label { font-size: var(--font-size-meta); }
.filter-field select, .filter-field input { width: 100%; }
.filter-search { position: relative; flex: 2 1 220px; max-width: 320px; }
.filter-search .icon { position: absolute; left: 10px; bottom: 10px; color: var(--text-secondary); pointer-events: none; }
.filter-search input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]) { padding-left: 34px; }
.filter-actions { display: flex; gap: var(--space-sm); margin-left: auto; }
.filter-tabs { display: flex; flex-wrap: wrap; gap: var(--space-xs); padding: var(--space-xs); margin-bottom: var(--space-gap-loose); background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--radius-md); width: fit-content; }
.filter-tabs a { padding: var(--space-gap-tight) var(--space-gap-loose); border-radius: var(--radius-sm); color: var(--text-secondary); font-size: var(--font-size-table); font-weight: var(--font-weight-medium); }
.filter-tabs a:hover { background: var(--surface-hover); text-decoration: none; }
.filter-tabs a[aria-current="page"] { background: var(--accent-tint); color: var(--accent); }

/* Action bar (appears only while rows are selected) */
.action-bar { position: sticky; bottom: var(--space-md); z-index: var(--z-actionbar); display: flex; align-items: center; gap: var(--space-sm); width: fit-content; max-width: 100%; margin: var(--space-gap-loose) auto 0; padding: var(--space-sm) var(--space-sm) var(--space-sm) var(--space-md); background: var(--primary); color: var(--on-fill); border-radius: var(--radius-md); box-shadow: var(--shadow-overlay); }
.action-bar[hidden] { display: none; }
.action-bar-count { margin-right: var(--space-sm); font-weight: var(--font-weight-semibold); white-space: nowrap; }
/* Child combinators only: the popover panel's own buttons sit on a white surface
   (.popover-panel), not the dark bar, and must keep their normal button/.primary styling. */
.action-bar > button, .action-bar > .popover > summary { background: transparent; border-color: var(--on-dark-border); color: var(--on-fill); }
.action-bar > button:hover, .action-bar > .popover > summary:hover { background: var(--on-dark-hover); }
.action-bar .primary, .action-bar > .popover > summary.primary { background: var(--accent); border-color: var(--accent); }
.action-bar .primary:hover, .action-bar > .popover > summary.primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.popover { position: relative; }
.popover > summary { list-style: none; }
.popover > summary::-webkit-details-marker { display: none; }
.popover-panel { position: absolute; bottom: calc(100% + var(--space-sm)); left: 0; min-width: var(--popover-min-width); display: flex; flex-direction: column; gap: var(--space-sm); padding: var(--space-gap-loose); background: var(--surface); color: var(--text); border: var(--border-width) solid var(--border); border-radius: var(--radius-md); box-shadow: var(--shadow-overlay); }
.popover-panel .primary { align-self: flex-start; }
/* Page-header popovers (e.g. "create" forms) open below the button, not above it. */
.popover-down .popover-panel { bottom: auto; top: calc(100% + var(--space-sm)); left: auto; right: 0; }

/* Pagination */
.pagination { display: flex; align-items: center; justify-content: space-between; gap: var(--space-gap-loose); padding: 10px var(--space-md); border-top: var(--border-width) solid var(--border); font-size: var(--font-size-meta); color: var(--text-secondary); }
.pagination-links { display: flex; gap: var(--space-xs); }
.pagination-links a, .pagination-links span { min-width: var(--control-height-sm); height: var(--control-height-sm); display: inline-grid; place-items: center; padding: 0 var(--space-sm); border-radius: var(--radius-sm); color: var(--text); }
.pagination-links a:hover { background: var(--surface-hover); text-decoration: none; }
.pagination-links [aria-current="page"] { background: var(--accent-tint); color: var(--accent); font-weight: var(--font-weight-semibold); }

/* Empty, loading, skeleton */
.empty-state { display: flex; flex-direction: column; align-items: center; gap: var(--space-sm); padding: 40px var(--space-lg); text-align: center; color: var(--text-secondary); }
.empty-state-icon { width: 44px; height: 44px; display: grid; place-items: center; border-radius: var(--radius-pill); background: var(--surface-hover); color: var(--text-secondary); }
.empty-state-icon .icon { width: 22px; height: 22px; }
.empty-state-title { margin: 0; font-size: var(--font-size-body); font-weight: var(--font-weight-semibold); color: var(--text); }
.empty-state-text { margin: 0; max-width: 420px; font-size: var(--font-size-table); }
.is-refreshable { transition: opacity var(--motion-fast) var(--ease); }
.is-refreshable.htmx-request { opacity: 0.55; pointer-events: none; }
.skeleton { display: block; height: 12px; border-radius: var(--radius-sm); background: var(--border-row); animation: skeleton-pulse 1.4s ease-in-out infinite; }
.skeleton-title { height: 20px; width: 60%; }
.skeleton-line { margin-top: var(--space-gap-loose); }
@keyframes skeleton-pulse { 50% { opacity: 0.45; } }

/* Drawer */
.drawer-scrim { position: fixed; inset: 0; z-index: var(--z-drawer); background: var(--scrim); }
.drawer-scrim[hidden], .drawer[hidden] { display: none; }
.drawer { position: fixed; top: 0; right: 0; bottom: 0; z-index: calc(var(--z-drawer) + 1); width: min(var(--drawer-width), 100vw); display: flex; flex-direction: column; background: var(--surface); box-shadow: var(--shadow-overlay); transform: translateX(16px); opacity: 0; transition: transform var(--motion-base) var(--ease), opacity var(--motion-base) var(--ease); }
.drawer.is-open { transform: none; opacity: 1; }
#drawer-body { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.drawer-header { display: flex; align-items: flex-start; gap: var(--space-gap-loose); padding: var(--space-md) 20px; border-bottom: var(--border-width) solid var(--border); }
.drawer-title { margin: 0; font-size: var(--font-size-drawer-title); font-weight: var(--font-weight-semibold); font-variant-numeric: tabular-nums; }
.drawer-title:focus { outline: none; }
.drawer-header .icon-button { margin-left: auto; }
.drawer-content { flex: 1; overflow-y: auto; padding: var(--space-md) 20px var(--space-lg); }
.drawer-footer { display: flex; justify-content: flex-end; gap: var(--space-sm); padding: var(--space-gap-loose) 20px; border-top: var(--border-width) solid var(--border); }
.facts { display: grid; grid-template-columns: 140px 1fr; gap: var(--space-sm) var(--space-md); margin: 0; font-size: var(--font-size-table); }
.facts dt { color: var(--text-secondary); }
.facts dd { margin: 0; font-weight: var(--font-weight-medium); }

/* Drive card two-column layout */
.drive-layout { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: var(--space-lg); align-items: start; }
.drive-main, .drive-side { display: flex; flex-direction: column; gap: var(--space-lg); min-width: 0; }
@media (max-width: 1279px) { .drive-layout { grid-template-columns: 1fr; } }
/* V6: the drive-card's narrow 1fr side column can overflow its table-card even above the
   1280px sidebar-collapse breakpoint (e.g. "Кто вёл привод"'s five columns). Scoped to this
   column only - a global unconditional .table-scroll { overflow-x: auto } would make every
   .table-scroll a sticky-positioning ancestor and break the desktop sticky header elsewhere
   (e.g. /assign), since the top: 0 reset below is scoped the same way. */
.drive-side .table-scroll { overflow-x: auto; }
.drive-side .table-scroll .data-table thead th { top: 0; }

/* Timeline */
.timeline { list-style: none; margin: 0; padding: 0; }
.timeline-item { position: relative; padding: 0 0 var(--space-md) 28px; }
.timeline-item::before { content: ""; position: absolute; left: 7px; top: 20px; bottom: 0; width: 2px; background: var(--border); }
.timeline-item:last-child::before { display: none; }
.timeline-item.is-done::before { background: var(--success-line); }
.timeline-marker { position: absolute; left: 0; top: 2px; width: 16px; height: 16px; display: grid; place-items: center; border-radius: var(--radius-pill); background: var(--surface); box-shadow: inset 0 0 0 2px var(--border-strong); }
.is-done .timeline-marker { background: var(--success); color: var(--on-fill); box-shadow: none; }
.is-done .timeline-marker .icon { width: 10px; height: 10px; stroke-width: 3; }
.is-current .timeline-marker { background: var(--accent-tint); box-shadow: inset 0 0 0 2px var(--accent); }
.is-current .timeline-marker::after { content: ""; width: 6px; height: 6px; border-radius: var(--radius-pill); background: var(--accent); }
.timeline-label { display: block; font-size: var(--font-size-meta); font-weight: var(--font-weight-semibold); color: var(--accent); }
.is-upcoming .timeline-label { color: var(--text-secondary); }
.timeline-title { display: block; font-size: var(--font-size-table); font-weight: var(--font-weight-medium); }
.is-upcoming .timeline-title { color: var(--text-secondary); font-weight: var(--font-weight-normal); }
.is-voided .timeline-title { text-decoration: line-through; color: var(--text-secondary); }
.timeline-meta { display: block; font-size: var(--font-size-meta); color: var(--text-secondary); }

/* Toasts and inline messages */
.toast-region { position: fixed; top: calc(var(--topbar-height) + var(--space-gap-loose)); right: var(--space-lg); z-index: var(--z-toast); display: flex; flex-direction: column; gap: var(--space-sm); width: min(380px, calc(100vw - 32px)); pointer-events: none; }
.toast { pointer-events: auto; display: flex; align-items: flex-start; gap: 10px; padding: var(--space-gap-loose) var(--space-sm) var(--space-gap-loose) var(--space-md); background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--radius-md); box-shadow: var(--shadow-overlay); font-size: var(--font-size-table); animation: toast-in var(--motion-base) var(--ease); }
.toast > .icon { margin-top: 2px; color: var(--toast-accent, var(--accent)); }
.toast-success { --toast-accent: var(--success); }
.toast-error { --toast-accent: var(--danger); }
.toast-info { --toast-accent: var(--accent); }
/* The kind is carried by the icon colour (--toast-accent), not by a coloured border: the
   toast markup carries one icon per kind and this shows only the one matching its class. */
.toast-icon { display: none; }
.toast-success .toast-icon-success, .toast-error .toast-icon-error, .toast-info .toast-icon-info { display: inline-block; }
.toast-title { display: block; font-weight: var(--font-weight-semibold); }
.toast-text { display: block; color: var(--text-secondary); }
.toast-close { margin-left: auto; width: 28px; min-height: 28px; padding: 0; background: transparent; border-color: transparent; color: var(--text-secondary); }
@keyframes toast-in { from { opacity: 0; transform: translateY(-4px); } }
.error-block, .notice-block { display: flex; gap: 10px; max-width: var(--panel-max-width); padding: var(--space-gap-loose) var(--space-md); border: var(--border-width) solid; border-radius: var(--radius-md); font-size: var(--font-size-table); }
.error-block { border-color: var(--danger); background: var(--danger-bg); color: var(--danger); }
.notice-block, .notice-repair { border-color: var(--st-in-repair-dot); background: var(--st-in-repair-bg); color: var(--st-in-repair-text); }

/* Confirm dialog */
dialog.modal { width: min(440px, calc(100vw - 32px)); padding: 0; border: 0; border-radius: var(--radius-lg); background: var(--surface); color: var(--text); box-shadow: var(--shadow-overlay); }
dialog.modal::backdrop { background: var(--scrim-modal); }
.modal-body { padding: 20px 20px var(--space-sm); }
.modal-title { margin: 0 0 var(--space-sm); font-size: var(--font-size-h2); font-weight: var(--font-weight-semibold); }
.modal-actions { display: flex; justify-content: flex-end; gap: var(--space-sm); padding: var(--space-gap-loose) 20px 20px; }

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

/* ============================================================================
   Page-specific rules kept from the old design (not yet migrated to the new
   shell / component library - see plan 09 milestone 2). They read the tokens
   above; --marker-width / --matrix-max-height / --matrix-header-max-height
   are kept in :root above only because these rules still use them.
   ========================================================================= */

.page-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-md);
  margin: var(--space-sm) 0 var(--space-lg);
}

.page-meta .muted {
  margin: 0;
}

.hint {
  color: var(--text-secondary);
  font-size: var(--font-size-label);
  margin: var(--space-xs) 0 0;
}

.decision-bar {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  margin-top: var(--space-lg);
}

details.rework > summary {
  display: inline-flex;
  align-items: center;
  min-height: var(--control-height);
  padding: 0 var(--space-button-x);
  border: var(--border-width) solid var(--danger);
  border-radius: var(--radius-sm);
  color: var(--danger);
  cursor: pointer;
  list-style: none;
  width: fit-content;
}

details.rework > summary::-webkit-details-marker {
  display: none;
}

details.rework[open] > summary {
  margin-bottom: var(--space-sm);
}

details.rework .rework-panel {
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-md);
  max-width: var(--panel-max-width);
}

#work-ops {
  display: block;
  overflow-x: auto;
}

/* #work-ops is a scroll container, so `.data-table thead th { position: sticky; top:
   var(--topbar-height) }` measures its offset inside the section instead of the page - the
   header then sits a few pixels over the first row and never sticks on page scroll. */
#work-ops .data-table thead th {
  position: static;
}

#work-ops table {
  font-size: var(--font-size-touch);
}

#work-ops tr.is-next,
#qc-stages tr.is-next {
  font-weight: var(--font-weight-bold);
  background: var(--accent-tint);
}

/* `table { border-collapse: separate }` ignores borders set on <tr>, so the accent bar has to
   sit on the first cell instead, same pattern as tbody tr.is-selected > :first-child. */
#work-ops tr.is-next > :first-child,
#qc-stages tr.is-next > :first-child {
  box-shadow: inset var(--marker-width) 0 0 var(--accent);
}

#work-ops td {
  vertical-align: middle;
}

#work-ops tr.is-next button,
#qc-stages tr.is-next button {
  font-weight: var(--font-weight-normal);
}

#work-ops button[name="single"],
#work-ops button[type="submit"] {
  min-height: var(--touch-target);
  font-size: var(--font-size-touch);
  vertical-align: middle;
}

#work-ops input[type="checkbox"] {
  width: var(--checkbox-touch);
  height: var(--checkbox-touch);
  vertical-align: middle;
}

#work-status:empty {
  margin: 0;
}

#batch-form {
  margin-top: var(--space-md);
}

#components table {
  font-size: var(--font-size-touch);
}

#components button {
  min-height: var(--touch-target);
  font-size: var(--font-size-touch);
}

#components details form {
  margin-top: var(--space-sm);
}

#components .install-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
}

#components .install-row label {
  display: inline;
  margin: 0;
  white-space: nowrap;
}

fieldset + fieldset {
  margin-top: var(--space-sm);
}

legend {
  padding: 0 var(--space-xs);
  font-weight: var(--font-weight-bold);
}

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

.log-form > div {
  display: flex;
  flex-direction: column;
}

.assignment {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md);
}

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

.repair-open {
  margin-top: var(--space-lg);
}

.status-change {
  margin-top: var(--space-lg);
}

tr.removed {
  color: var(--text-secondary);
}

/* Each model block is now wrapped in a .table-card (V11); the block-to-block gap moves to
   the card wrapper so it doesn't add an empty band inside the card's own clipped border. */
#matrix > .table-card + .table-card {
  margin-top: var(--space-lg);
}

.matrix-scroll {
  overflow: auto;
  max-height: var(--matrix-max-height);
  max-width: 100%;
}

.matrix-scroll table {
  font-size: var(--font-size-table);
}

.matrix-scroll caption {
  text-align: left;
  font-weight: var(--font-weight-bold);
  padding: var(--space-sm) 0;
}

.matrix-scroll th[scope="col"] {
  position: sticky;
  top: 0;
  z-index: 2;
  /* Same grey as every other thead th in the app (V11) - was --surface (white), which
     made this header row look like a different, lighter surface from the rest of the table
     chrome elsewhere. */
  background: var(--surface-subtle);
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  text-align: left;
  vertical-align: bottom;
  max-height: var(--matrix-header-max-height);
  padding: var(--space-sm) var(--space-xs);
  white-space: normal;
  overflow-wrap: anywhere;
  border-bottom: var(--border-width-strong) solid var(--border);
}

.matrix-scroll th[scope="col"]:first-child {
  writing-mode: horizontal-tb;
  transform: none;
  vertical-align: middle;
  max-height: none;
  position: sticky;
  top: 0;
  left: 0;
  z-index: 3;
  background: var(--surface-subtle);
  width: 1%;
  white-space: nowrap;
}

.matrix-scroll .op-pos {
  font-weight: var(--font-weight-bold);
}

.matrix-scroll th[scope="row"] {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--surface);
  text-align: left;
  white-space: nowrap;
  width: 1%;
  padding: var(--space-sm);
  border-bottom: var(--border-width) solid var(--border);
}

.matrix-scroll tbody tr:nth-child(even) th[scope="row"] {
  background: var(--bg);
}

.matrix-scroll td {
  text-align: center;
  font-size: var(--font-size-table);
  padding: var(--space-sm);
  border-bottom: var(--border-width) solid var(--border);
  font-variant-numeric: tabular-nums;
}

.matrix-scroll td.qc {
  background: var(--qc-col-bg);
  color: var(--qc-col-text);
}

.qc-marker {
  display: inline-block;
  margin-left: var(--space-2xs);
  padding-block: var(--space-2xs);
  padding-inline: var(--space-xs);
  border-radius: var(--radius-pill);
  background: var(--qc-col-bg);
  color: var(--qc-col-text);
  font-size: var(--font-size-label);
  font-weight: var(--font-weight-bold);
}

/* ============================================================================
   Task 10: route editor, routes list, admin, login, password, error page
   ========================================================================= */

.app-name {
  margin: 0 0 var(--space-sm);
  font-size: var(--font-size-h2);
  font-weight: var(--font-weight-semibold);
  color: var(--text);
}

#add-op {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-md);
}

#add-op .field-name {
  flex: 1 1 auto;
  min-width: 40ch;
}

#add-op .field-name input {
  width: 100%;
}

#add-op .field-norm input,
#add-op .field-position input {
  width: 8ch;
}

#ops input[name="name"] {
  width: 100%;
}

#ops input[name="norm"] {
  width: 8ch;
}

.admin-row-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
}
