/* =============================================================================
   CPQCalculator — App components (theme.css)
   S1 (2026-07-12): ALL token + [data-theme] definitions moved to tokens.css —
   the single source of truth, loaded by EVERY page BEFORE this file.
   This file is components only. Never (re)define [data-theme] blocks here.
   ============================================================================= */

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-sans, Inter, "Segoe UI", Arial, sans-serif);
  /* S11 (Igor 2026-07-12): decorative corner-glow gradients removed product-wide —
     clean flat page background; hierarchy comes from panels and type, not glows. */
  background: var(--bg);
  color: var(--text, #e2e8f0);
  min-height: 100vh;
}

a {
  color: inherit;
  text-decoration: none;
}

.container {
  width: min(var(--page-measure, 1180px), calc(100% - 2 * var(--gutter, 32px)));
  margin: 0 auto;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  backdrop-filter: blur(var(--blur-backdrop, 10px));
  border-bottom: 1px solid var(--border, rgba(148, 163, 184, 0.22));
  background: var(--bg-header, rgba(2, 6, 23, 0.78));
}

.header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: var(--header-h, 64px);
  gap: 20px;
}

.brand {
  font-weight: var(--fw-extrabold, 800);
  font-size: 1.12rem;
  letter-spacing: -0.01em;
  color: var(--text-strong, #f1f5f9);
  white-space: nowrap;
}

.brand span {
  color: var(--brand);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.muted {
  color: var(--muted);
}

.card {
  background: var(--gradient-panel, linear-gradient(180deg, rgba(30, 41, 59, 0.86), rgba(15, 23, 42, 0.92)));
  border: 1px solid var(--border, rgba(148, 163, 184, 0.22));
  border-radius: var(--radius-3xl, 16px);
}

.hero {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 24px;
  padding: 52px 0 34px;
}

.hero h1 {
  margin: 0 0 12px;
  font-size: clamp(1.9rem, 3vw, 3rem);
  line-height: var(--lh-tight, 1.1);
}

.hero p {
  color: var(--muted);
  line-height: var(--lh-relaxed, 1.6);
}

/* S3 — ONE button grammar. .button.* (legacy names, kept for the contract)
   renders identically to the canonical .btn-* family below. */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2, 8px);
  border: 1px solid transparent;
  border-radius: var(--radius-md, 8px);
  padding: 10px 18px;
  font-family: inherit;
  font-weight: var(--fw-semibold, 600);
  font-size: var(--fs-sm, 0.85rem);
  color: var(--text, #e2e8f0);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--duration-base, 0.2s) var(--ease, ease),
              border-color var(--duration-base, 0.2s) var(--ease, ease),
              transform var(--duration-fast, 0.15s) var(--ease, ease);
}
.button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.button:disabled { opacity: 0.5; cursor: not-allowed; }
.button:active:not(:disabled) { transform: translateY(1px); }

.button.primary {
  background: var(--gradient-cta, linear-gradient(90deg, #10b981, #2563eb));
  color: var(--accent-text, #fff);
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(2, 6, 23, 0.30));
}
.button.primary:hover:not(:disabled) {
  background: var(--gradient-cta-hover, linear-gradient(90deg, #34d399, #3b82f6));
  transform: translateY(-1px);
}

.button.ghost {
  background: var(--control-bg, rgba(30, 41, 59, 0.8));
  border-color: var(--border-strong, rgba(148, 163, 184, 0.35));
  color: var(--text, #e2e8f0);
}
.button.ghost:hover:not(:disabled) {
  border-color: var(--border-emphasis, rgba(148, 163, 184, 0.55));
  background: var(--bg-elevated, #1e293b);
}

.button.danger {
  background: var(--danger-bg, rgba(239, 68, 68, 0.15));
  border-color: var(--danger-border, rgba(239, 68, 68, 0.45));
  color: var(--danger, #ef4444);
}

.section {
  margin: 18px 0 24px;
}

.section h2 {
  margin: 0 0 10px;
  font-size: 1.45rem;
}

.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
}

.feature {
  padding: 14px;
}

.feature h3 {
  margin: 0 0 8px;
}

.feature p {
  margin: 0;
  color: var(--muted);
  font-size: 0.95rem;
}

.auth-box,
.page-box {
  width: min(980px, 92vw);
  margin: 32px auto;
  padding: 18px;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.form-grid > .card {
  min-width: 0;
}

label {
  display: block;
  font-size: 0.86rem;
  color: var(--muted);
}

input,
select,
textarea {
  margin-top: 6px;
  width: 100%;
  padding: 10px 12px;
  border-radius: var(--radius-md, 8px);
  border: 1px solid var(--border, rgba(148, 163, 184, 0.22));
  background: var(--field-bg, rgba(2, 6, 23, 0.7));
  color: var(--text, #e2e8f0);
  font-family: inherit;
  font-size: var(--fs-sm, 0.85rem);
  transition: border-color var(--duration-fast, 0.15s), box-shadow var(--duration-fast, 0.15s);
}
input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--accent, #10b981);
  box-shadow: var(--focus-ring, 0 0 0 3px rgba(16, 185, 129, 0.10));
}
input::placeholder,
textarea::placeholder { color: var(--text-subtle, #64748b); }

.upload-zone {
  border: 2px dashed var(--border-emphasis, rgba(148, 163, 184, 0.55));
  border-radius: var(--radius-2xl, 14px);
  padding: 26px;
  text-align: center;
  cursor: pointer;
  transition: var(--duration-base, 0.2s) var(--ease, ease);
}

.upload-zone.drag {
  border-color: var(--brand);
  background: var(--accent-bg, rgba(16, 185, 129, 0.10));
}

.mono {
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
}

.status {
  border-radius: var(--radius-lg, 10px);
  padding: 10px 12px;
  margin: 10px 0;
  font-size: 0.92rem;
}

.status.ok {
  background: var(--ok-bg, rgba(16, 185, 129, 0.12));
  border: 1px solid var(--ok-border, rgba(16, 185, 129, 0.35));
}

.status.warn {
  background: var(--warn-bg, rgba(245, 158, 11, 0.15));
  border: 1px solid var(--warn-border, rgba(245, 158, 11, 0.45));
}

.status.err {
  background: var(--danger-bg, rgba(239, 68, 68, 0.15));
  border: 1px solid var(--danger-border, rgba(239, 68, 68, 0.45));
}

.status.info {
  background: var(--info-bg, rgba(59, 130, 246, 0.12));
  border: 1px solid var(--info-border, rgba(59, 130, 246, 0.40));
}

.row {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
}

.tabs {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.tab-btn {
  background: var(--control-bg, rgba(30, 41, 59, 0.85));
  border: 1px solid var(--border-strong, rgba(148, 163, 184, 0.35));
  color: var(--text, #e2e8f0);
  padding: 8px 11px;
  border-radius: var(--radius-md, 8px);
  cursor: pointer;
}

.tab-btn.active {
  border-color: var(--brand);
  box-shadow: 0 0 0 1px var(--ok-border, rgba(16, 185, 129, 0.35)) inset;
}

/* S3 — ONE table style: borderless rows + uppercase mono header (promoted
   from order_status / admin cockpit; replaces the gridlined legacy look). */
table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-sm, 0.85rem);
}

th,
td {
  border: none;
  border-bottom: 1px solid var(--border-subtle, rgba(148, 163, 184, 0.10));
  padding: 9px 10px;
  text-align: left;
  vertical-align: top;
}

thead th {
  background: transparent;
  font-family: var(--font-mono, ui-monospace, Menlo, Consolas, monospace);
  font-size: var(--fs-3xs, 0.70rem);
  font-weight: var(--fw-semibold, 600);
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--text-subtle, #64748b);
  border-bottom: 1px solid var(--border, rgba(148, 163, 184, 0.22));
}

tbody td { color: var(--text-mid, #cbd5e1); font-variant-numeric: tabular-nums; }
tbody tr:last-child td { border-bottom: none; }

.scenario-report-wrap {
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
}

.scenario-report-wrap table {
  min-width: 860px;
}

.scenario-line-material-list {
  width: 100%;
  overflow-y: auto;
}

.badge {
  display: inline-block;
  border-radius: var(--radius-pill, 999px);
  font-size: 0.76rem;
  padding: 2px 8px;
  border: 1px solid var(--border-strong, rgba(148, 163, 184, 0.35));
}

.badge.ok {
  color: var(--accent-faint, #86efac);
  border-color: var(--ok-border, rgba(16, 185, 129, 0.35));
}

.badge.warn {
  color: var(--warn-bright, #fcd34d);
  border-color: var(--warn-border, rgba(245, 158, 11, 0.45));
}

.badge.danger,
.badge.err {
  color: var(--danger, #ef4444);
  border-color: var(--danger-border, rgba(239, 68, 68, 0.45));
}

.badge.info {
  color: var(--info, #60a5fa);
  border-color: var(--info-border, rgba(59, 130, 246, 0.40));
}

.badge.neutral { color: var(--text-muted, #94a3b8); }

.footer {
  text-align: center;
  color: var(--muted);
  padding: 26px 0;
  font-size: 0.85rem;
}

@media (max-width: 980px) {
  .hero {
    grid-template-columns: 1fr;
  }
  .grid-3,
  .form-grid {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
   Role-based visibility — P3
   ============================================================ */

/* Early-class set by inline <head> script; body class set later by quote.js.
   Both selectors listed so both paths (URL-driven early class on <html>,
   actual-role-driven class on <body>) produce the same visual result. */
html.role-customer .eng-only,
body.role-customer .eng-only { display: none !important; }

html:not(.role-customer) .customer-only,
body:not(.role-customer) .customer-only { display: none !important; }

/* Customer layout: right column content is empty for now; collapse grid to
   2 columns so the UI doesn't leave an awkward blank 30% stripe. */
html.role-customer .quote-workspace,
body.role-customer .quote-workspace {
  grid-template-columns: minmax(280px, 30%) 1fr;
}

.price-slot-placeholder {
  padding: var(--space-6);
  text-align: center;
  border: 1px dashed var(--border);
  border-radius: var(--radius-xl);
  background: var(--bg-surface);
  margin-top: var(--space-4);
}

.price-slot-placeholder .placeholder-text {
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

/* ============================================================
   P3.1 — Customer polish (tolerance warn, combobox, custom fields)
   ============================================================ */

/* Tolerance "Specific…" inline warning (customer view). */
.tol-specific-warn {
  margin-top: var(--space-1);
  color: var(--warn);
  font-size: var(--fs-xs);
}
.tol-specific-warn[hidden] { display: none; }

/* Pending engineer review — replacement content for #customerPriceSlot when
   needs_engineer_review=true comes back from the analyzer. */
.pending-review-title {
  color: var(--warn);
  font-weight: 600;
  font-size: var(--fs-base);
  margin-bottom: var(--space-2);
}
.pending-review-body {
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

/* Material combobox (customer view single-field search). */
.material-row-customer {
  display: flex;
  gap: var(--space-2);
  align-items: flex-end;
  margin-top: var(--space-1);
}
.material-row-customer .combobox-wrap { flex: 1; min-width: 0; }
.material-row-customer .qty-customer { width: 90px; flex-shrink: 0; }
.combobox-wrap { position: relative; }
.combobox-list {
  position: absolute; top: 100%; left: 0; right: 0;
  max-height: 260px; overflow-y: auto;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  margin: 4px 0 0 0; padding: 0;
  list-style: none;
  z-index: 100;
}
.combobox-list li {
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
  color: var(--text);
  font-size: var(--fs-sm);
}
.combobox-list li:hover,
.combobox-list li[aria-selected="true"] {
  background: var(--accent-bg);
  color: var(--accent-faint);
}
.combobox-list[hidden] { display: none; }

/* "Can't find your material/finish?" expandable custom-fields (Task 4). */
.custom-field-trigger { margin-top: var(--space-1); }
.custom-field-trigger[hidden] { display: none; }
.custom-link {
  color: var(--text-muted);
  font-size: var(--fs-xs);
  text-decoration: underline dotted;
  cursor: pointer;
}
.custom-link:hover { color: var(--accent-faint); }
.custom-field-box {
  position: relative;
  margin-top: var(--space-2);
  padding: var(--space-3);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius-md);
  background: var(--warn-bg);
}
.custom-field-box textarea {
  width: 100%;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-2);
  color: var(--text);
  font-size: var(--fs-sm);
  resize: vertical;
  min-height: 60px;
}
.custom-field-warn {
  margin-top: var(--space-2);
  color: var(--warn);
  font-size: var(--fs-xs);
}
.custom-field-close {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: 18px;
  cursor: pointer;
  line-height: 1;
}
.custom-field-close:hover { color: var(--text); }
.custom-field-box[hidden] { display: none; }

/* ============================================================
   P3.5 — Customer premium refresh (foundation)
   New classes are namespace-pure (.panel, .workspace, .page*, .side,
   .price-hero, .viewer, .tweaks etc.). They are NOT applied anywhere
   in this commit — structure comes in P3.5 commit 2. Rules here add
   no visual change until those classes appear in quote.html.
   ============================================================ */

/* Decorative orbs for the customer-view background — softer than the
   landing orbs in --gradient-decor-blue/emerald. Scoped to customer
   mode only via body.role-customer, applied on a ::before overlay so
   it layers behind content without disturbing existing body rules. */
body.role-customer {
  background: var(--bg-page);
}
/* S11 — customer orb overlay removed with the rest of the corner glows. */

/* Page shell — used by customer-mode layout in commit 2. */
.page {
  max-width: var(--container-wide, 1400px);
  margin: 0 auto;
  padding: var(--space-8) var(--space-6) var(--space-16);
}
.page-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-8);
}
.page-title h1 {
  margin: 0;
  font-size: var(--fs-xl);
  font-weight: var(--fw-semibold);
  color: var(--text-strong);
  letter-spacing: -0.01em;
}
.page-title .sub {
  color: var(--text-muted);
  font-size: var(--fs-sm);
}
.crumbs {
  display: flex;
  gap: var(--space-2);
  font-size: var(--fs-xs);
  color: var(--text-subtle);
  margin-bottom: 6px;
}
.crumbs .sep { color: var(--text-subtle); opacity: 0.6; }

/* Two-column customer workspace. */
.workspace {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 380px);
  gap: var(--space-6);
  align-items: start;
}
@media (max-width: 1000px) {
  .workspace { grid-template-columns: 1fr; }
}

/* Right-column sticky aside. */
.side {
  position: sticky;
  top: calc(var(--header-h, 64px) + var(--space-4));
  display: grid;
  gap: var(--space-4);
}

/* Panel — the premium container. NOTE: distinct from legacy .qpanel;
   old engineer panels keep using .qpanel and stay unchanged. */
.panel {
  background: var(--gradient-panel, linear-gradient(180deg, rgba(30,41,59,.86), rgba(15,23,42,.92)));
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  overflow: hidden;
  transition: border-color var(--duration-base) var(--ease);
}
.panel + .panel { margin-top: var(--space-4); }
.panel:hover { border-color: var(--border-strong); }

.panel-hdr {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--border-subtle);
  user-select: none;
}
.panel-hdr.clickable { cursor: pointer; }
.panel-hdr.clickable:hover { background: rgba(30, 41, 59, 0.35); }
.panel-hdr h2 {
  flex: 1;
  margin: 0;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text-strong);
  letter-spacing: -0.005em;
}
.panel-hdr .hint {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  font-weight: var(--fw-medium);
}
.panel-hdr .panel-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
  border: 1px solid var(--border);
  background: rgba(30, 41, 59, 0.5);
}
.panel-hdr .panel-badge.ok {
  color: var(--accent-faint);
  border-color: var(--accent);
  background: var(--accent-bg);
}
.panel-hdr .panel-badge.warn {
  color: var(--warn);
  border-color: var(--warn-border);
  background: var(--warn-bg);
}
.chev {
  width: 22px;
  height: 22px;
  border-radius: var(--radius-sm);
  display: grid;
  place-items: center;
  color: var(--text-muted);
  transition: transform var(--duration-base) var(--ease),
              color var(--duration-fast);
}
.panel-hdr.clickable:hover .chev { color: var(--text); }
.panel[data-open="true"] .chev { transform: rotate(90deg); }

.panel-body {
  padding: var(--space-5);
  display: grid;
  gap: var(--space-5);
}

/* Collapse — CSS-only, grid-template-rows trick preserves focus.
   The .collapse-inner must have min-height:0 + overflow:hidden so the
   clipped height actually collapses to zero. */
.collapse {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows var(--duration-slow) var(--ease),
              opacity var(--duration-base) var(--ease);
  opacity: 1;
}
.panel[data-open="false"] .collapse {
  grid-template-rows: 0fr;
  opacity: 0;
}
.collapse > .collapse-inner {
  min-height: 0;
  overflow: hidden;
}

/* "Hidden" collapse mode (used by Tweaks panel) — no animation, just off. */
.panel[data-open="false"][data-mode="hidden"] .panel-body { display: none; }

/* Density toggle (driven by body[data-density]). */
body[data-density="compact"] .panel { padding: 0; }
body[data-density="compact"] .panel-hdr { padding: var(--space-3) var(--space-4); }
body[data-density="compact"] .panel-body { padding: var(--space-4); }

/* ============================================================
   P3.5 — Customer premium layout (commit 2)
   Layout primitives for Parts / Specs / Price panels, sticky
   aside (price hero + 3D preview), and the Tweaks tray.
   All selectors target classes that appear only in the new
   customer premium tree (.page, .workspace, .panel, .price-hero,
   .tweaks, etc.) — they never match engineer/admin markup.
   ============================================================ */

/* Scoped row helpers for the customer workspace. The global
   flex `.row` (line 231) is used by admin/login/index; we
   avoid overriding it by scoping these under .workspace.
   `.breaks .row` below uses a higher-specificity grid rule
   for the price table. */
.workspace .row {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: 1fr;
  align-items: start;
}
.workspace .row-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.workspace .row-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.workspace .row-hero {
  grid-template-columns: minmax(0, 1fr) 120px;
  align-items: end;
}
@media (max-width: 720px) {
  .workspace .row-2,
  .workspace .row-4,
  .workspace .row-hero { grid-template-columns: 1fr; }
}

/* Upload zone (customer premium). Distinct from legacy
   `.upload-zone` (line 191) which powers the engineer zone. */
.upload {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: var(--space-4);
  align-items: center;
  padding: var(--space-5);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  background: rgba(15, 23, 42, 0.45);
  cursor: pointer;
  transition: border-color var(--duration-base) var(--ease),
              background var(--duration-base) var(--ease);
}
.upload:hover,
.upload:focus-visible {
  border-color: var(--accent);
  background: var(--accent-bg-soft);
  outline: none;
}
.upload .upload-ic {
  width: 42px; height: 42px;
  display: grid; place-items: center;
  border-radius: var(--radius-md);
  background: rgba(16, 185, 129, 0.10);
  color: var(--accent-soft);
}
.upload .upload-body { display: grid; gap: 2px; }
.upload .upload-body strong {
  font-size: var(--fs-sm);
  color: var(--text-strong);
  font-weight: var(--fw-semibold);
}
.upload .upload-body span {
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

/* Parts list — one row per part. */
.partlist {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-4);
}
.part {
  display: grid;
  grid-template-columns: 28px 44px minmax(0, 1fr) auto 90px 28px;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: rgba(15, 23, 42, 0.4);
  transition: border-color var(--duration-fast) var(--ease),
              background var(--duration-fast) var(--ease);
}
.part:hover { border-color: var(--border); }
.part.selected {
  border-color: var(--accent);
  background: var(--accent-bg-soft);
}
.part[data-shadow="true"] {
  opacity: 0.55;
  pointer-events: none;
}
.part-idx {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  color: var(--text-subtle);
  text-align: center;
}
.part-thumb {
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  background: rgba(30, 41, 59, 0.6);
  color: var(--text-muted);
}
.part-meta { min-width: 0; }
.part-name {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.part-name .example-tag {
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  color: var(--text-subtle);
  margin-left: 6px;
}
.part-spec {
  font-size: var(--fs-xs);
  color: var(--text-muted);
  margin-top: 2px;
}
.part-spec .dot { opacity: 0.5; margin: 0 4px; }
.part-qty {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.part-qty button {
  width: 26px; height: 28px;
  background: transparent;
  border: none;
  color: var(--text);
  font-size: var(--fs-sm);
  cursor: pointer;
  transition: background var(--duration-fast);
}
.part-qty button:hover:not(:disabled) { background: rgba(30, 41, 59, 0.6); }
.part-qty button:disabled { color: var(--text-subtle); cursor: not-allowed; }
.part-qty input {
  width: 44px;
  height: 28px;
  background: transparent;
  border: none;
  border-left: 1px solid var(--border-subtle);
  border-right: 1px solid var(--border-subtle);
  color: var(--text-strong);
  font-size: var(--fs-sm);
  text-align: center;
  -moz-appearance: textfield;
}
.part-qty input::-webkit-outer-spin-button,
.part-qty input::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}
.part-qty input:focus { outline: none; }
.part-price { text-align: right; }
.part-price .v {
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text-strong);
  line-height: 1.1;
}
.part-price .s {
  font-size: var(--fs-2xs);
  color: var(--text-subtle);
}
.part-act {
  width: 28px; height: 28px;
  display: grid; place-items: center;
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
  transition: background var(--duration-fast), color var(--duration-fast);
}
.part-act:hover:not(:disabled) {
  background: rgba(30, 41, 59, 0.6);
  color: var(--text);
}
.part-act:disabled { color: var(--text-subtle); cursor: not-allowed; }

/* Price breaks table. Grid layout avoids <table>'s baseline
   quirks and keeps alignment predictable across breakpoints.
   `.breaks .row` wins over the global flex `.row` by
   specificity (2 classes vs 1). */
.breaks {
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.breaks .row {
  display: grid;
  grid-template-columns: 60px 1fr 1fr 1fr;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  border-top: 1px solid var(--border-subtle);
  font-size: var(--fs-sm);
  color: var(--text);
  align-items: center;
}
.breaks .row:first-child { border-top: none; }
.breaks .row.h {
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  background: rgba(15, 23, 42, 0.55);
  padding: var(--space-2) var(--space-4);
}
.breaks .row.cur {
  background: var(--accent-bg-soft);
  color: var(--text-strong);
  font-weight: var(--fw-medium);
}
.breaks .row .ta-r { text-align: right; }
.breaks .row.cur .ta-r.pv {
  color: var(--accent-soft);
  font-weight: var(--fw-semibold);
}

/* Regional pills. */
.regions {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.region {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: rgba(15, 23, 42, 0.5);
  color: var(--text);
  font-size: var(--fs-xs);
  cursor: pointer;
  transition: border-color var(--duration-fast),
              background var(--duration-fast);
}
.region:hover { border-color: var(--border-strong); }
.region .flag {
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}
.region .v {
  font-weight: var(--fw-medium);
  color: var(--text);
}
.region.active {
  border-color: var(--accent);
  background: var(--accent-bg);
  color: var(--text-strong);
}
.region.active .flag,
.region.active .v { color: var(--accent-faint); }
.region.active.eu { border-color: var(--accent-2); background: rgba(59, 130, 246, 0.10); }
.region.active.eu .flag,
.region.active.eu .v { color: var(--accent-2-soft); }
.region.active.china { border-color: var(--warn); background: var(--warn-bg); }
.region.active.china .flag,
.region.active.china .v { color: var(--warn-bright); }

/* Price hero — the centerpiece of the sticky aside. */
.price-hero {
  position: relative;
  padding: var(--space-6);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background:
    linear-gradient(180deg, rgba(16, 185, 129, 0.08), rgba(59, 130, 246, 0.05)),
    var(--gradient-panel);
  display: grid;
  gap: var(--space-4);
}
.price-eyebrow {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: var(--fs-xs);
  color: var(--text-muted);
}
.price-eyebrow .live {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--accent-soft);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
}
.price-eyebrow .live::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  animation: pulse 1.8s var(--ease) infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.4; transform: scale(0.85); }
}
.price-big {
  font-size: var(--fs-3xl);
  font-weight: var(--fw-extrabold);
  color: var(--text-strong);
  line-height: 1;
  letter-spacing: -0.02em;
}
.price-big .per {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
  margin-left: 8px;
  letter-spacing: 0;
}
.price-meta {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-subtle);
}
.price-meta .k {
  font-size: var(--fs-2xs);
  color: var(--text-subtle);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.price-meta .v {
  margin-top: 2px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-strong);
}

/* CTA group + button variants. */
.ctas {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-2);
}
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 10px 16px;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  background: transparent;
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text);
  cursor: pointer;
  text-decoration: none;
  transition: background var(--duration-base) var(--ease),
              border-color var(--duration-base) var(--ease),
              transform var(--duration-fast) var(--ease),
              opacity var(--duration-fast);
}
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn-gradient {
  background: var(--gradient-cta);
  color: var(--accent-text);
  border-color: transparent;
  box-shadow: var(--shadow-sm, 0 1px 2px rgba(2, 6, 23, 0.30));
}
.btn-gradient:hover:not(:disabled) {
  background: var(--gradient-cta-hover);
  transform: translateY(-1px);
}
.btn-gradient:disabled {
  background: var(--gradient-cta);
  filter: grayscale(0.3);
}
.btn-ghost {
  background: rgba(30, 41, 59, 0.5);
  border-color: var(--border);
  color: var(--text);
}
.btn-ghost:hover:not(:disabled) {
  background: rgba(30, 41, 59, 0.8);
  border-color: var(--border-strong);
}
.btn-sm {
  padding: 6px 12px;
  font-size: var(--fs-xs);
}
.btn-link {
  display: inline-block;
  padding: 6px 0;
  font-size: var(--fs-xs);
  color: var(--accent-soft);
  text-decoration: none;
  text-align: center;
}
.btn-link:hover { color: var(--accent-faint); text-decoration: underline; }

/* 3D viewer placeholder (ghost SVG + legend). */
.viewer {
  position: relative;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--viewer-bg, #0d1526); /* S11: flat neutral bed */
  overflow: hidden;
  display: grid;
  place-items: center;
}
.viewer-ghost {
  width: 70%;
  height: 70%;
  opacity: 0.6;
}
.viewer-legend {
  position: absolute;
  bottom: var(--space-3);
  left: var(--space-3);
  right: var(--space-3);
  display: flex;
  gap: var(--space-3);
  flex-wrap: wrap;
  font-size: var(--fs-3xs);
  color: var(--text-muted);
}
.viewer-legend span { display: inline-flex; align-items: center; gap: 4px; }
.viewer-legend span::before {
  content: "";
  width: 8px; height: 8px;
  border-radius: 50%;
  background: currentColor;
}
.viewer-legend .cy { color: var(--accent-soft); }
.viewer-legend .ef { color: var(--accent-2-soft); }
.viewer-legend .hl { color: var(--warn-bright); }
.viewer-legend .pk { color: #a78bfa; } /* violet-400 — only local use */

/* T1a step 3 — view-switch toolbar (front / top / iso). Injected by viewer.js
   into the .viewer container, overlaid top-LEFT of the canvas (the top-RIGHT
   corner is owned by the legacy-mode badge, which is wider and sits at a higher
   z-index — anchoring the toolbar left keeps both fully visible). Theme-token
   styled with literal fallbacks so it also renders in viewer-sandbox.html,
   which loads theme.css but NOT tokens.css. */
.viewer-views {
  position: absolute;
  top: var(--space-3, 12px);
  left: var(--space-3, 12px);
  z-index: 6;   /* above the legacy-mode badge (z-5) so a wide toolbar is never obscured */
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  border-radius: var(--radius-md, 8px);
  background: var(--control-bg, rgba(30, 41, 59, 0.85));
  border: 1px solid var(--border-subtle, rgba(148, 163, 184, 0.18));
  box-shadow: var(--shadow-md, 0 8px 24px rgba(2, 6, 23, 0.38));
  backdrop-filter: blur(6px);
}
.viewer-views button {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 8px;
  font-size: var(--fs-3xs, 11px);
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--text-muted, #94a3b8);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm, 6px);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.viewer-views button:hover {
  color: var(--text-strong, #f1f5f9);
  background: var(--bg-elevated, #1e293b);
  border-color: var(--border, rgba(148, 163, 184, 0.28));
}
.viewer-views button:active { transform: translateY(0.5px); }
.viewer-views button svg { width: 13px; height: 13px; flex: none; }
.viewer-views .vv-lbl { white-space: nowrap; }

/* Tweaks tray (engineer/admin only). Fixed bottom-right; the
   aside is hidden for everyone else via .eng-or-admin-only. */
.tweaks {
  position: fixed;
  right: var(--space-5);
  bottom: var(--space-5);
  z-index: 40;
  width: 240px;
  padding: var(--space-4);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--gradient-panel);
  backdrop-filter: blur(var(--blur-backdrop));
  display: grid;
  gap: var(--space-3);
  box-shadow: var(--shadow-lg, 0 20px 48px rgba(2, 6, 23, 0.48));
}
.tweaks h4 {
  margin: 0 0 4px;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}
.tweaks .seg {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  width: 100%;
}
.tweaks .seg button {
  flex: 1;
  padding: 6px 8px;
  background: transparent;
  border: none;
  color: var(--text-muted);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-medium);
  cursor: pointer;
  transition: background var(--duration-fast), color var(--duration-fast);
}
.tweaks .seg button + button { border-left: 1px solid var(--border-subtle); }
.tweaks .seg button:hover { color: var(--text); }
.tweaks .seg button.active {
  background: var(--accent-bg);
  color: var(--accent-faint);
}

/* Helper text under the Specs panel explaining where shared
   fields (Finish/Roughness/Tolerance/Threads) still live. */
.panel-note {
  margin: var(--space-3) 0 0;
  padding: var(--space-3) var(--space-4);
  border-left: 2px solid var(--accent);
  background: var(--accent-bg-soft);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: var(--fs-xs);
  color: var(--text-mid);
  line-height: var(--lh-normal);
}

/* Role gating for .eng-or-admin-only. Body-only selector so
   /eng_view and /admin keep the Tweaks tray visible even though
   <html> may still carry a role-customer class if someone
   navigates via client-side routing. Matches the pattern used
   by .eng-only / .customer-only earlier in the cascade. */
body:not(.role-engineer):not(.role-admin):not(.role-planner) .eng-or-admin-only {
  display: none !important;
}

/* Tighter workspace spacing on small viewports. */
@media (max-width: 1000px) {
  .side { position: static; }
  .page { padding: var(--space-6) var(--space-4) var(--space-10); }
}
@media (max-width: 640px) {
  .part {
    grid-template-columns: 28px 40px minmax(0, 1fr) auto;
  }
  .part .part-qty,
  .part .part-price { grid-column: 3 / -1; justify-self: end; }
  .part .part-act { grid-row: 1; grid-column: 4; }
  .tweaks { right: var(--space-3); bottom: var(--space-3); width: 200px; }
}

/* P4 Phase A — part row status badges (pending review / error). */
.part-status-badge {
  display: inline-block;
  padding: 1px 6px;
  border-radius: var(--radius-xs);
  font-size: var(--fs-3xs);
  font-weight: var(--fw-medium);
  margin-left: var(--space-2);
  text-transform: uppercase;
  letter-spacing: .05em;
  vertical-align: middle;
}
.part-status-badge.warn {
  color: var(--warn);
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
}
.part-status-badge.danger {
  color: var(--danger);
  background: var(--danger-bg, rgba(239, 68, 68, 0.15));
  border: 1px solid var(--danger-border, rgba(239, 68, 68, 0.45));
}

/* =============================================================================
   T12 — breakdown flip cards (chart on the back of the live EOS table).
   All colours via tokens (incl. --chart-1..7) so the cards re-theme for free.
   ============================================================================= */
.t12-flip{ position:relative; border:1px solid var(--border); border-radius:var(--radius-xl,12px); background:var(--gradient-panel); overflow:hidden; margin-bottom:var(--space-3); transition:height var(--duration-base) var(--ease); }
.t12-cbar{ display:flex; align-items:center; gap:var(--space-3); padding:9px var(--space-3); border-bottom:1px solid var(--border-subtle); position:relative; z-index:2; }
.t12-title{ display:inline-flex; align-items:center; gap:7px; background:none; border:none; cursor:pointer; font:inherit; font-size:var(--fs-sm); font-weight:var(--fw-semibold); color:var(--text-strong); padding:0; }
.t12-caret{ color:var(--text-subtle); transition:transform var(--duration-fast); display:inline-block; }
.t12-flip:not(.t12-collapsed) .t12-caret{ transform:rotate(90deg); }
.t12-pending{ font-size:var(--fs-2xs); color:var(--accent-soft); border:1px solid var(--accent); border-radius:var(--radius-pill); padding:2px 9px; background:var(--accent-bg); animation:t12pulse 1.1s ease-in-out infinite; }
@keyframes t12pulse{ 0%,100%{ opacity:.5 } 50%{ opacity:1 } }
.t12-spacer{ flex:1; }
.t12-facetoggle{ display:flex; border:1px solid var(--border); border-radius:var(--radius-pill); overflow:hidden; }
.t12-facetoggle button{ font:inherit; font-size:var(--fs-2xs); font-weight:var(--fw-semibold); padding:5px 12px; background:transparent; border:none; border-left:1px solid var(--border-subtle); color:var(--text-muted); cursor:pointer; transition:all var(--duration-fast); }
.t12-facetoggle button:first-child{ border-left:none; }
.t12-facetoggle button.active{ background:var(--accent-bg); color:var(--accent-faint); }
.t12-collapsed .t12-fold{ display:none; }
.t12-fold{ transform-origin:center center; backface-visibility:hidden; will-change:transform; transition:transform .28s var(--ease), opacity .22s var(--ease), filter .28s var(--ease); }
.t12-flip[data-axis="x"] .t12-fold{ transform-origin:center top; }
.t12-fold.t12-unfold{ transition:transform .42s cubic-bezier(.34,1.3,.5,1), opacity .24s var(--ease); }
.t12-fold.t12-folding{ opacity:.32; filter:brightness(.6); }
.t12-flip[data-axis="y"] .t12-fold.t12-folding{ transform:scaleX(.02); }
.t12-flip[data-axis="x"] .t12-fold.t12-folding{ transform:scaleY(.02); }
.t12-cbody{ padding:var(--space-4); overflow-x:auto; }

/* chart mode toggle */
.t12-chartctl{ display:flex; gap:var(--space-3); margin-bottom:var(--space-4); }
.t12-seg{ display:flex; border:1px solid var(--border); border-radius:var(--radius-sm); overflow:hidden; }
.t12-seg button{ font:inherit; font-size:var(--fs-xs); font-weight:var(--fw-semibold); padding:6px 12px; background:transparent; border:none; border-left:1px solid var(--border-subtle); color:var(--text-muted); cursor:pointer; }
.t12-seg button:first-child{ border-left:none; }
.t12-seg button.active{ background:var(--accent-bg); color:var(--accent-faint); }

/* donut */
.t12-donutwrap{ display:grid; grid-template-columns:260px 1fr; gap:var(--space-6); align-items:center; }
@media (max-width:640px){ .t12-donutwrap{ grid-template-columns:1fr; } }
.t12-donut{ position:relative; width:260px; height:260px; margin:0 auto; }
.t12-donut svg{ width:100%; height:100%; display:block; }
.t12-rot{ transform:rotate(-90deg); transform-origin:100px 100px; }
.t12-slice{ fill:none; stroke-width:30; stroke-linecap:butt; cursor:pointer; transition:stroke-width var(--duration-base) var(--ease), opacity var(--duration-base) var(--ease); }
.t12-donut.dim .t12-slice{ opacity:.3; }
.t12-donut.dim .t12-slice.hot{ opacity:1; stroke-width:38; }
.t12-center{ position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; pointer-events:none; padding:0 42px; }
.t12-cap{ font-size:var(--fs-3xs); color:var(--text-subtle); text-transform:uppercase; letter-spacing:.06em; }
.t12-val{ font-family:var(--font-mono); font-size:1.45rem; font-weight:var(--fw-bold); color:var(--text-strong); line-height:1.05; margin-top:3px; }
.t12-mrg{ font-family:var(--font-mono); font-size:var(--fs-2xs); color:var(--accent-soft); margin-top:5px; border:1px solid var(--accent); border-radius:var(--radius-pill); padding:2px 9px; }
.t12-priceln{ font-size:var(--fs-xs); color:var(--text-muted); margin-top:5px; }
.t12-priceln b{ color:var(--text-strong); font-family:var(--font-mono); }
.t12-manual{ color:var(--warn-bright); margin-left:4px; }

/* legend + region pills */
.t12-side{ min-width:0; }
.t12-legend{ display:grid; gap:1px; }
.t12-lg{ display:grid; grid-template-columns:13px 1fr auto auto; align-items:center; gap:var(--space-3); padding:6px 9px; border-radius:var(--radius-sm); transition:background var(--duration-fast); }
.t12-lg:hover, .t12-lg.hot{ background:var(--bg-sunken); }
.t12-sw{ width:12px; height:12px; border-radius:3px; flex:none; }
.t12-lgn{ font-size:var(--fs-sm); color:var(--text); }
.t12-lgp{ font-family:var(--font-mono); font-size:var(--fs-sm); color:var(--text-mid); }
.t12-lgv{ font-family:var(--font-mono); font-size:var(--fs-xs); color:var(--text-subtle); text-align:right; min-width:56px; }
.t12-mk{ font-family:var(--font-mono); font-size:.7em; color:var(--accent-soft); font-weight:var(--fw-bold); }
.t12-pills{ display:flex; flex-wrap:wrap; gap:var(--space-2); margin-top:var(--space-4); padding-top:var(--space-3); border-top:1px solid var(--border-subtle); }
.t12-rp{ display:inline-flex; align-items:center; gap:6px; font:inherit; font-size:var(--fs-xs); font-weight:var(--fw-medium); padding:5px 11px; border-radius:var(--radius-pill); border:1px solid var(--border); background:var(--bg-surface); color:var(--text-muted); cursor:pointer; transition:all var(--duration-fast); }
.t12-rp.on{ border-color:var(--accent); background:var(--accent-bg); color:var(--text-strong); }
.t12-rec{ font-size:.56rem; color:var(--accent-faint); border:1px solid var(--accent); border-radius:var(--radius-pill); padding:0 6px; }

/* compare bars */
.t12-cmp{ display:grid; gap:var(--space-4); }
.t12-cmprow{ display:grid; grid-template-columns:90px 1fr auto; align-items:center; gap:var(--space-3); }
.t12-cmplbl{ font-size:var(--fs-sm); font-weight:var(--fw-semibold); color:var(--text-strong); display:flex; align-items:center; gap:6px; }
.t12-stack{ display:flex; height:28px; border-radius:var(--radius-sm); overflow:hidden; background:var(--bg-sunken); }
.t12-segb{ height:100%; cursor:pointer; transition:filter var(--duration-fast); min-width:0; }
.t12-segb:hover{ filter:brightness(1.14); }
.t12-cmptot{ font-family:var(--font-mono); font-size:var(--fs-sm); color:var(--text); font-weight:var(--fw-semibold); min-width:70px; text-align:right; }
.t12-cmplegend{ display:flex; flex-wrap:wrap; gap:var(--space-3) var(--space-5); margin-top:var(--space-4); padding-top:var(--space-3); border-top:1px solid var(--border-subtle); }
.t12-clitem{ display:inline-flex; align-items:center; gap:6px; font-size:var(--fs-xs); color:var(--text-muted); }

/* time bar */
.t12-timebar{ display:flex; height:40px; border-radius:var(--radius-md); overflow:hidden; background:var(--bg-sunken); border:1px solid var(--border-subtle); }
.t12-tseg{ height:100%; display:flex; align-items:center; justify-content:center; cursor:pointer; overflow:hidden; transition:filter var(--duration-fast); }
.t12-tseg:hover{ filter:brightness(1.14); }
.t12-tseg span{ font-family:var(--font-mono); font-size:var(--fs-2xs); font-weight:var(--fw-semibold); color:#fff; white-space:nowrap; padding:0 4px; text-shadow:0 1px 2px rgba(0,0,0,.4); }
.t12-timelegend{ display:flex; flex-wrap:wrap; gap:var(--space-3) var(--space-5); margin-top:var(--space-3); }
.t12-tlitem{ display:inline-flex; align-items:center; gap:7px; font-size:var(--fs-xs); }
.t12-tln{ color:var(--text); }
.t12-tlv{ font-family:var(--font-mono); color:var(--text-muted); }
.t12-annot{ margin-top:var(--space-4); padding:9px var(--space-3); border:1px dashed var(--border-strong); border-radius:var(--radius-md); background:var(--bg-surface); font-size:var(--fs-xs); color:var(--text-mid); }
.t12-tpc{ font-family:var(--font-mono); font-weight:var(--fw-bold); color:var(--text-strong); }

/* tooltip */
.t12-tip{ position:fixed; z-index:2000; pointer-events:none; background:var(--bg-elevated); border:1px solid var(--border-strong); border-radius:var(--radius-sm); box-shadow:0 16px 44px rgba(0,0,0,.5); padding:8px 11px; font-size:var(--fs-xs); opacity:0; transform:translateY(4px); transition:opacity var(--duration-fast); max-width:240px; }
.t12-tip.show{ opacity:1; transform:translateY(0); }
.t12-ttn{ display:flex; align-items:center; gap:7px; color:var(--text-strong); font-weight:var(--fw-semibold); }
.t12-ttr{ display:flex; justify-content:space-between; gap:18px; margin-top:5px; color:var(--text-muted); }
.t12-ttr b{ color:var(--text); font-family:var(--font-mono); }

/* ---- T12 Totals-by-region chart (3rd card): compare bars / waterfall / LT ---- */
.t12-ccgroup{ display:flex; align-items:center; gap:var(--space-2); }
.t12-cclabel{ font-size:var(--fs-3xs); color:var(--text-subtle); text-transform:uppercase; letter-spacing:.06em; font-weight:var(--fw-semibold); }
.t12-note{ margin-top:var(--space-4); padding:8px var(--space-3); border-left:2px solid var(--border-strong); background:var(--bg-surface); border-radius:0 var(--radius-sm) var(--radius-sm) 0; font-size:var(--fs-xs); color:var(--text-muted); line-height:1.5; }
.t12-rdot{ width:9px; height:9px; border-radius:50%; flex:none; display:inline-block; }

/* compare bars */
.t12-cmpbars{ display:grid; gap:var(--space-3); }
.t12-cmpbar{ display:grid; grid-template-columns:96px 1fr; align-items:center; gap:var(--space-4); }
.t12-cbl{ font-size:var(--fs-sm); font-weight:var(--fw-semibold); color:var(--text); display:flex; align-items:center; gap:7px; }
.t12-ctrack{ position:relative; height:34px; background:var(--bg-sunken); border-radius:var(--radius-sm); overflow:hidden; cursor:default; }
.t12-cfill{ position:absolute; left:0; top:0; bottom:0; border-radius:var(--radius-sm); transition:width var(--duration-base) var(--ease); }
.t12-cval{ position:absolute; top:50%; transform:translateY(-50%); right:11px; font-family:var(--font-mono); font-size:var(--fs-sm); font-weight:var(--fw-semibold); color:var(--text-strong); }
.t12-csub{ color:var(--text-subtle); font-size:.74em; margin-left:6px; }

/* waterfall */
.t12-wf-row{ display:flex; align-items:center; gap:var(--space-2); margin-bottom:var(--space-3); flex-wrap:wrap; font-size:var(--fs-sm); }
.t12-wf-svg{ width:100%; max-width:640px; margin:0 auto; height:auto; display:block; }
.t12-wf-svg text{ font-family:var(--font-mono); font-variant-numeric:tabular-nums; }
.t12-wf-c{ fill:var(--text-subtle); }
.t12-wf-v{ fill:var(--text-mid); font-weight:600; }
.t12-wf-vt{ fill:var(--text-strong); font-weight:700; }
.t12-wf-axis{ stroke:var(--border-subtle); }
.t12-wf-conn{ stroke:var(--border-strong); stroke-dasharray:3 4; }
.t12-wf-legend{ display:flex; flex-wrap:wrap; gap:var(--space-3) var(--space-5); margin-top:var(--space-4); padding-top:var(--space-3); border-top:1px solid var(--border-subtle); }
.t12-wf-li{ display:inline-flex; align-items:center; gap:8px; font-size:var(--fs-xs); color:var(--text-muted); }
.t12-wf-li b{ color:var(--text); font-weight:var(--fw-semibold); font-family:var(--font-mono); }
.t12-wf-degrade{ display:flex; align-items:center; gap:var(--space-3); padding:var(--space-4); border:1px dashed var(--border-strong); border-radius:var(--radius-md); background:var(--bg-surface); font-size:var(--fs-sm); color:var(--text-muted); }

/* LT by quantity */
.t12-lt-bars{ display:grid; gap:var(--space-3); }
.t12-lt-row{ display:grid; grid-template-columns:96px 1fr 64px; align-items:center; gap:var(--space-4); }
.t12-lt-lbl{ font-size:var(--fs-sm); font-weight:var(--fw-semibold); color:var(--text); display:flex; align-items:center; gap:7px; }
.t12-lt-track{ position:relative; height:28px; background:var(--bg-sunken); border-radius:var(--radius-sm); overflow:hidden; }
.t12-lt-fill{ position:absolute; left:0; top:0; bottom:0; background:var(--accent-2); border-radius:var(--radius-sm); transition:width var(--duration-base) var(--ease); }
.t12-lt-val{ font-family:var(--font-mono); font-size:var(--fs-sm); font-weight:var(--fw-semibold); color:var(--text-strong); text-align:right; }
.t12-lt-val .t12-u{ color:var(--text-subtle); font-size:.74em; }


/* =============================================================================
   S3 (2026-07-12) — shared primitives
   ============================================================================= */

/* Page banner — one page-title pattern (mirrors admin .ck-banner / profile). */
.page-banner {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-6, 24px);
  flex-wrap: wrap;
  margin-bottom: var(--space-6, 24px);
}
.page-banner h1 {
  margin: 0 0 var(--space-2, 8px);
  font-size: var(--fs-xl, 1.5rem);
  font-weight: var(--fw-extrabold, 800);
  letter-spacing: -0.02em;
  color: var(--text-strong, #f1f5f9);
}
.page-banner p {
  margin: 0;
  color: var(--text-muted, #94a3b8);
  max-width: 60ch;
  line-height: var(--lh-relaxed, 1.6);
}

/* Stat tiles — KPI primitives (dashboards S6, admin telemetry S9).
   Parallel to (never replacing) the live .t12-* chart classes. */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-3, 12px);
}
.stat-tile {
  background: var(--gradient-panel, linear-gradient(180deg, rgba(30,41,59,0.86), rgba(15,23,42,0.92)));
  border: 1px solid var(--border, rgba(148, 163, 184, 0.22));
  border-radius: var(--radius-xl, 12px);
  padding: var(--space-4, 16px) var(--space-5, 20px);
  display: grid;
  gap: 6px;
  align-content: start;
  min-width: 0;
}
.stat-tile .k {
  font-family: var(--font-mono, ui-monospace, Menlo, Consolas, monospace);
  font-size: var(--fs-3xs, 0.70rem);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-subtle, #64748b);
}
.stat-tile .v {
  font-size: var(--fs-xl, 1.5rem);
  font-weight: var(--fw-extrabold, 800);
  color: var(--text-strong, #f1f5f9);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  line-height: var(--lh-tight, 1.1);
}
.stat-tile .v .unit {
  font-size: var(--fs-sm, 0.85rem);
  font-weight: var(--fw-medium, 500);
  color: var(--text-muted, #94a3b8);
  letter-spacing: 0;
}
.stat-tile .d { font-size: var(--fs-xs, 0.78rem); color: var(--text-muted, #94a3b8); }
.stat-tile.accent .v { color: var(--accent-soft, #34d399); }
.stat-tile.warn .v { color: var(--warn-bright, #fbbf24); }
.stat-tile.danger .v { color: var(--danger, #ef4444); }

/* Stat chart cards — fixed slots for hand-rolled SVG/CSS charts. */
.stat-charts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-4, 16px);
}
.stat-card {
  background: var(--gradient-panel, linear-gradient(180deg, rgba(30,41,59,0.86), rgba(15,23,42,0.92)));
  border: 1px solid var(--border, rgba(148, 163, 184, 0.22));
  border-radius: var(--radius-xl, 12px);
  padding: var(--space-4, 16px) var(--space-5, 20px);
  display: grid;
  gap: var(--space-3, 12px);
  align-content: start;
  min-width: 0;
}
.stat-card .sc-hd {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3, 12px);
}
.stat-card .sc-hd h4 {
  margin: 0;
  font-size: var(--fs-sm, 0.85rem);
  font-weight: var(--fw-semibold, 600);
  color: var(--text-strong, #f1f5f9);
}
.stat-card .sc-hd .hint {
  font-family: var(--font-mono, ui-monospace, Menlo, Consolas, monospace);
  font-size: var(--fs-2xs, 0.72rem);
  color: var(--text-subtle, #64748b);
}

/* Empty / skeleton states for stat surfaces. */
.stat-empty {
  border: 1px dashed var(--border-strong, rgba(148, 163, 184, 0.35));
  border-radius: var(--radius-lg, 10px);
  padding: var(--space-6, 24px);
  text-align: center;
  color: var(--text-subtle, #64748b);
  font-size: var(--fs-xs, 0.78rem);
}
.stat-skeleton {
  height: 12px;
  border-radius: var(--radius-pill, 999px);
  background: var(--bg-elevated, #1e293b);
  animation: statPulse 1.8s ease-in-out infinite;
}
@keyframes statPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }


/* =============================================================================
   S4 (2026-07-12) — one chrome. App nav = underline active tab (Igor pick 1d,
   marketing parity), one brand size, shared app footer.
   ============================================================================= */
.nav-links a.nav-link {
  padding: 7px 12px;
  border-radius: var(--radius-md, 8px);
  font-size: var(--fs-sm, 0.85rem);
  font-weight: var(--fw-medium, 500);
  color: var(--text-muted, #94a3b8);
  transition: color var(--duration-fast, 0.15s), background var(--duration-fast, 0.15s);
}
.nav-links a.nav-link:hover { color: var(--text, #e2e8f0); background: var(--bg-elevated, #1e293b); }
.nav-links a.nav-link.active { color: var(--text-strong, #f1f5f9); }
.nav-links a.nav-link.active::after {
  content: "";
  display: block;
  height: 2px;
  margin-top: 5px;
  border-radius: var(--radius-pill, 999px);
  background: var(--accent, #10b981);
}

.app-footer {
  border-top: 1px solid var(--border-subtle, rgba(148, 163, 184, 0.10));
  margin-top: var(--space-16, 64px);
  padding: var(--space-8, 32px) 0 var(--space-10, 40px);
}
.app-footer .af-row {
  display: flex;
  align-items: center;
  gap: var(--space-6, 24px);
  flex-wrap: wrap;
}
.app-footer .af-brand { font-size: 1rem; }
.af-links { display: flex; gap: var(--space-2, 8px); flex-wrap: wrap; }
.af-links a {
  padding: 6px 10px;
  border-radius: var(--radius-md, 8px);
  font-size: var(--fs-xs, 0.78rem);
  color: var(--text-muted, #94a3b8);
  transition: color var(--duration-fast, 0.15s), background var(--duration-fast, 0.15s);
}
.af-links a:hover { color: var(--text, #e2e8f0); background: var(--bg-elevated, #1e293b); }
.af-legal { margin-left: auto; font-size: var(--fs-2xs, 0.72rem); color: var(--text-subtle, #64748b); }
@media print { .app-footer { display: none !important; } }
