/* PRISM v0.0.1 — minimal CSS, QQE/manufacturing aesthetic.
   Navy primary, neutral surfaces, sans-serif, clean lines. */

:root {
  /* Brand palette */
  --color-primary:        #0f2c4a;   /* QQE navy */
  --color-primary-hover:  #163a60;
  --color-primary-soft:   #e7eef6;
  --color-accent:         #1f6fc4;   /* lighter blue for links / focus */
  --color-bg:             #f5f7fa;
  --color-surface:        #ffffff;
  --color-border:         #d8dde5;
  --color-border-strong:  #b9c1cd;
  --color-text:           #1c2530;
  --color-text-muted:     #5e6975;
  --color-good:           #1f8b4c;
  --color-warn:           #c97a17;

  --shadow-sm: 0 1px 2px rgba(15, 44, 74, 0.06);
  --shadow-md: 0 4px 12px rgba(15, 44, 74, 0.08);
  --radius-sm: 4px;
  --radius-md: 8px;
  --radius-lg: 12px;

  --sidebar-width: 250px;
}

/* ---------- Reset / base ---------- */
* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  height: 100%;
}

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 14px;
  color: var(--color-text);
  background: var(--color-bg);
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';  /* Inter's typographic alternates — better digits + I */
}

a { color: var(--color-accent); text-decoration: none; }
a:hover { text-decoration: underline; }

button {
  font-family: inherit;
  cursor: pointer;
}

input, select, textarea {
  font-family: inherit;
  font-size: 14px;
  color: var(--color-text);
}

/* ---------- App shell ----------
   Locked to viewport height so the topbar + sidebar stay put while only
   the main content area scrolls. Pre-2026-04-28 was min-height:100vh which
   let the WHOLE page scroll, sliding the sidebar nav out of view. */
.app {
  display: grid;
  grid-template-columns: var(--sidebar-width) 1fr;
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "topbar topbar"
    "sidebar main";
  height: 100vh;
  overflow: hidden;
}
.main {
  overflow-y: auto;
  overflow-x: hidden;
}
.sidebar {
  overflow-y: auto;
}

/* Sidebar collapsed state — hide sidebar entirely, main takes full width.
   Toggled via .sidebar-toggle button in topbar; persisted in localStorage. */
.app.sidebar-collapsed {
  grid-template-columns: 1fr;
  grid-template-areas:
    "topbar"
    "main";
}
.app.sidebar-collapsed .sidebar { display: none; }

.topbar  { grid-area: topbar; }
.sidebar { grid-area: sidebar; }
.main    { grid-area: main; }

/* Sidebar toggle — TWO buttons (in-sidebar + floating expand) pinned to the
   IDENTICAL viewport coordinates so toggling produces zero positional shift.
   Only one is visible at a time (controlled by .app.sidebar-collapsed).
   Vars below let us tweak the anchor point in one place. */
:root {
  --sidebar-toggle-top: 96px;    /* anchor: 16px below the topbar (80px as of the
                                    2026-08-13 Nova lockup; was 76 for a 60px bar) */
  --sidebar-toggle-left: 14px;
  --sidebar-toggle-size: 36px;
}

/* In-sidebar collapse button — light glyph on navy sidebar bg.
   Position: fixed so it lands at exact viewport coords (matches floating). */
.sidebar-toggle--in-sidebar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  top: var(--sidebar-toggle-top);
  left: var(--sidebar-toggle-left);
  width: var(--sidebar-toggle-size);
  height: var(--sidebar-toggle-size);
  z-index: 50;
  border: 1px solid rgba(255,255,255,0.10);
  border-radius: 8px;
  background: rgba(255,255,255,0.02);
  color: rgba(255,255,255,0.78);
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.sidebar-toggle--in-sidebar:hover {
  background: rgba(255,255,255,0.08);
  color: #fff;
  border-color: rgba(255,255,255,0.22);
}
.sidebar-toggle--in-sidebar:focus-visible {
  outline: 2px solid #3a7bd5;
  outline-offset: 2px;
}
/* Hide the in-sidebar button when collapsed (the floating one takes over) */
.app.sidebar-collapsed .sidebar-toggle--in-sidebar { display: none; }

/* Floating "show sidebar" button — only visible when sidebar is collapsed.
   Same fixed coordinates as the in-sidebar button so toggling = zero jump. */
.sidebar-expand-floating {
  display: none;
  position: fixed;
  top: var(--sidebar-toggle-top);
  left: var(--sidebar-toggle-left);
  z-index: 50;
  width: var(--sidebar-toggle-size);
  height: var(--sidebar-toggle-size);
  align-items: center;
  justify-content: center;
  background: white;
  border: 1px solid var(--color-border, #e2e6ee);
  border-radius: 8px;
  color: var(--color-text, #1a2236);
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(0,0,0,0.08);
  transition: background 0.12s ease, border-color 0.12s ease;
}
.sidebar-expand-floating:hover {
  background: #f4f6fa;
  border-color: #c8cfdb;
}
.app.sidebar-collapsed .sidebar-expand-floating { display: inline-flex; }

/* Mobile hamburger + backdrop — hidden on desktop, shown by the ≤720px
   media query below. Independent of the desktop collapse pair above. */
.mobile-nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--color-border, #e2e6ee);
  border-radius: 8px;
  background: #fff;
  color: var(--color-text, #1a2236);
  cursor: pointer;
  flex: 0 0 auto;
}
.mobile-nav-toggle:hover { background: #f4f6fa; }

.mobile-nav-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(15, 44, 74, 0.45);
  z-index: 39;
}

/* ---------- Top header (logo banner) ---------- */
.topbar {
  background: #ffffff;
  border-bottom: 1px solid var(--color-border);
  /* Compacted 2026-05-22: was 16px/28px which combined with a 96px logo gave
     a ~128px topbar — 14% of a 900px viewport eaten before any data shows.
     Target ~56px (Linear/Notion-class).
     2026-08-12: 8px → 4px. The Nova mark went 44 → 52px and the logo is the
     tallest thing in here, so it drives the bar's height; trading 4px of padding
     keeps the total at 60px instead of letting it grow to 68. */
  padding: 4px 20px;
  display: flex;
  align-items: center;
  gap: 20px;
  box-shadow: 0 1px 0 rgba(15, 44, 74, 0.04);
  position: relative;
  z-index: 5;
}

.topbar-brand {
  flex: 0 0 auto;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  transition: opacity 0.12s ease;
}
.topbar-brand:hover { opacity: 0.85; }

.topbar-logo {
  /* 2026-05-22: 96 → 40. 2026-06-04: MAVIS wordmark, asset whitespace-trimmed
     so the mark fills its box — 44px here reads larger than the old padded 56px
     while keeping the topbar ~60px.
     2026-08-13 (Nova2): the FULL lockup, "BY QQE" included (Max's call after
     seeing both). The tagline is 11% of the lockup's height, so it sets the
     floor: at 56px tall it renders ~5px and turns to mush, at 64px it's ~7px
     and legibly reads BY QQE. 64 cleared that bar; 72 is Max's call on top of
     it, for presence rather than legibility.
     Cost: the bar goes 60 → 80px with .topbar's 4px padding — worth knowing the
     2026-05-22 compaction fought to get this to ~56px, so this is the tallest
     the shell has been since. Anything keyed off the old height moves with it
     (see --sidebar-toggle-top).
     2.31:1, so it renders 166x72. The tagline-less cut (nova_wordmark.png) is
     still in the asset set if the bar ever has to come back down. */
  height: 72px;
  width: auto;
  display: block;
}

.topbar-spacer { flex: 1; }

/* Tagline — sits next to the logo, brand voice anchor */
.topbar-tagline {
  flex: 1 1 auto;
  font-size: 14px;
  font-weight: 500;
  color: var(--color-text-muted);
  letter-spacing: 0.01em;
  padding-left: 24px;
  font-style: italic;
}

/* ============================================================
   TOPBAR SHOP PULSE — month-shipments progress bar + KPI pills.
   The progress bar is the visual centerpiece; pills are at-a-glance
   shop health metrics (Days Safe, Scrap %, Past Due).
   ============================================================ */
.topbar-shippulse {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  margin: 0 28px;
  min-width: 0;
}

.shippulse-progress {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}

.shippulse-progress-head {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  white-space: nowrap;
}

.shippulse-month {
  font-weight: 600;
  color: var(--color-text);
  letter-spacing: 0.01em;
}

.shippulse-numbers {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  font-feature-settings: "tnum";
}

.shippulse-actual {
  font-weight: 700;
  color: var(--color-primary);
  font-size: 13px;
}

.shippulse-divider {
  color: var(--color-text-muted);
  font-weight: 400;
}

.shippulse-plan {
  color: var(--color-text-muted);
  font-weight: 500;
}

.shippulse-pct {
  font-weight: 700;
  color: var(--color-primary);
  margin-left: 4px;
  background: rgba(15, 44, 74, 0.06);
  padding: 1px 8px;
  border-radius: 4px;
  font-size: 11px;
}

.shippulse-bar {
  height: 9px;
  background: rgba(15, 44, 74, 0.12);
  border: 1px solid rgba(15, 44, 74, 0.10);
  border-radius: 5px;
  overflow: hidden;
  position: relative;
}

.shippulse-bar-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, #0f2c4a 0%, #1e3a8a 50%, #2563eb 100%);
  border-radius: 4px;
  transition: width 0.6s cubic-bezier(0.16, 1, 0.3, 1);
  box-shadow:
    0 0 0 1px rgba(37, 99, 235, 0.25),
    0 0 12px rgba(37, 99, 235, 0.45);
}

/* Color the bar based on % to plan: behind goal (red) → on pace (blue) → exceeding (green) */
.shippulse-bar-fill.on-pace {
  background: linear-gradient(90deg, #0f2c4a 0%, #1e40af 50%, #2563eb 100%);
  box-shadow: 0 0 0 1px rgba(37, 99, 235, 0.3), 0 0 12px rgba(37, 99, 235, 0.5);
}
.shippulse-bar-fill.behind {
  background: linear-gradient(90deg, #92400e 0%, #d97706 50%, #f59e0b 100%);
  box-shadow: 0 0 0 1px rgba(245, 158, 11, 0.3), 0 0 12px rgba(245, 158, 11, 0.5);
}
.shippulse-bar-fill.exceeding {
  background: linear-gradient(90deg, #14532d 0%, #16a34a 50%, #22c55e 100%);
  box-shadow: 0 0 0 1px rgba(34, 197, 94, 0.3), 0 0 12px rgba(34, 197, 94, 0.5);
}

/* KPI pills — color-graded variants (override base .pulse-pill) */
.pulse-pill.pulse-good {
  background: rgba(34, 197, 94, 0.10);
  border-color: rgba(34, 197, 94, 0.25);
}
.pulse-pill.pulse-good .pulse-val { color: #15803d; }

.pulse-pill.pulse-warn {
  background: rgba(245, 158, 11, 0.12);
  border-color: rgba(245, 158, 11, 0.30);
}
.pulse-pill.pulse-warn .pulse-val { color: #b45309; }

.pulse-pill.pulse-bad {
  background: rgba(239, 68, 68, 0.10);
  border-color: rgba(239, 68, 68, 0.30);
}
.pulse-pill.pulse-bad .pulse-val { color: #b91c1c; }

/* Live-pulse pills — Quotes today · $ in flight · VLM status */
.topbar-pulse {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-right: 24px;
}
.pulse-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  background: rgba(15, 44, 74, 0.05);
  border: 1px solid rgba(15, 44, 74, 0.08);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  color: var(--color-text);
  white-space: nowrap;
  transition: background 0.15s ease;
}
.pulse-pill:hover { background: rgba(15, 44, 74, 0.08); }
/* Pulse-pill icon slot — inline-flex centering 2026-05-22 so the lucide
   SVG aligns cleanly with the value text regardless of font baseline. */
.pulse-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  line-height: 1;
  color: currentColor;
  opacity: 0.85;
}
.pulse-icon svg { display: block; }
.pulse-val {
  font-weight: 700;
  font-feature-settings: "tnum";
  color: var(--color-primary);
}
.pulse-label { color: var(--color-text-muted); font-size: 11px; }
.pulse-date {
  font-weight: 500;
  color: var(--color-text);
  font-feature-settings: "tnum";
}
.pulse-divider {
  color: var(--color-text-muted);
  margin: 0 2px;
  opacity: 0.7;
}
.pulse-dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  position: relative;
}
.pulse-dot-ok {
  background: #22c55e;
  box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.6);
  animation: pulse-glow 2s ease-out infinite;
}
@keyframes pulse-glow {
  0%   { box-shadow: 0 0 0 0    rgba(34, 197, 94, 0.55); }
  60%  { box-shadow: 0 0 0 7px  rgba(34, 197, 94, 0); }
  100% { box-shadow: 0 0 0 0    rgba(34, 197, 94, 0); }
}

/* Compress shop-pulse on narrow viewports so it doesn't crash into user info */
@media (max-width: 1300px) {
  .topbar-shippulse { margin: 0 16px; }
  .topbar-pulse .pulse-pill .pulse-label { display: none; }
}
@media (max-width: 1000px) {
  .topbar-shippulse .shippulse-month { display: none; }
}
@media (max-width: 800px) {
  .topbar-shippulse { display: none; }
  .topbar-pulse { display: none; }
}

.topbar-user {
  display: flex;
  align-items: center;
  gap: 12px;
}

.user-meta-inline {
  text-align: right;
}

.user-meta-inline .user-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text);
}

.user-meta-inline .user-role {
  font-size: 11px;
  color: var(--color-text-muted);
}

/* ---------- Sidebar ---------- */
.sidebar {
  background: var(--color-primary);
  color: #fff;
  display: flex;
  flex-direction: column;
  padding: 24px 0;
}

.brand {
  margin: 0 12px 24px;
  padding: 18px 14px 14px;
  background: #ffffff;
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.brand-icon {
  width: 96px;
  height: 96px;
  object-fit: contain;
  display: block;
}

.brand-text {
  text-align: center;
}

.brand-name {
  font-family: 'Inter', sans-serif;
  font-weight: 800;
  font-size: 22px;
  letter-spacing: 3px;
  color: var(--color-primary);
  line-height: 1;
}

.brand-tagline {
  font-family: 'Inter', sans-serif;
  font-weight: 500;
  font-size: 9px;
  letter-spacing: 4px;
  color: var(--color-text-muted);
  margin-top: 4px;
}

.nav {
  flex: 1;
  /* Top padding clears the fixed-position sidebar-toggle button (at y=142px,
     36px tall). Sidebar top = topbar height (~128px), so we need ~56px
     padding-top so the first "MAIN" label sits below the button. */
  padding: 56px 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Section headers — small, muted, uppercase, separates groups of nav items.
   First label has no top margin so it doesn't push the whole nav down. */
.nav-section-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.35);
  padding: 0 12px;
  margin: 18px 0 6px;
}
.nav-section-label:first-child { margin-top: 6px; }

/* Nav items — pill-style, rounded, subtle border. The pill bg lifts on hover
   and the active state gets a rainbow gradient stripe on the left edge that
   echoes the prism in the logo. */
/* HTML `[hidden]` is `display:none` from the user-agent stylesheet, but
   `.nav-item { display: flex }` below has higher specificity and wins.
   Force-hide hidden nav items so the [hidden] attribute actually works. */
.nav-item[hidden] { display: none !important; }
.nav-item {
  position: relative;
  padding: 10px 14px;
  color: rgba(255, 255, 255, 0.78);
  font-size: 13px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  border-radius: 8px;
  border: 1px solid transparent;
  background: rgba(255, 255, 255, 0.02);
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.12s ease;
  overflow: hidden;
}

.nav-item:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.10);
  color: #fff;
  text-decoration: none;
}

.nav-item.active {
  background: linear-gradient(90deg, rgba(37, 99, 235, 0.20) 0%, rgba(37, 99, 235, 0.08) 100%);
  border-color: rgba(96, 165, 250, 0.35);
  color: #fff;
  box-shadow: 0 2px 8px rgba(37, 99, 235, 0.25), inset 0 0 0 1px rgba(255, 255, 255, 0.04);
}

/* Rainbow accent stripe on the left edge of active item — picks up the prism
   refraction from the logo. Inset slightly from the rounded corners. */
.nav-item.active::before {
  content: '';
  position: absolute;
  left: 4px;
  top: 8px;
  bottom: 8px;
  width: 3px;
  border-radius: 2px;
  background: linear-gradient(180deg,
    #ef4444 0%,    /* red */
    #f59e0b 25%,   /* orange */
    #22c55e 50%,   /* green */
    #3b82f6 75%,   /* blue */
    #a855f7 100%); /* violet */
  box-shadow: 0 0 8px rgba(255, 255, 255, 0.4);
}
.nav-item.active .nav-icon {
  opacity: 1;
  color: #fff;
}
.nav-item.active .nav-label {
  font-weight: 600;
}

.nav-icon {
  font-size: 16px;
  opacity: 0.65;
  width: 18px;
  height: 18px;
  /* Switched to inline-flex 2026-05-22 so the inline lucide SVGs center
     consistently inside the slot regardless of font baseline. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  transition: opacity 0.15s ease;
  flex: 0 0 18px;
}
.nav-icon svg { display: block; }
.nav-item:hover .nav-icon { opacity: 1; }

.nav-label { letter-spacing: 0.005em; }

.sidebar-footer {
  padding: 16px 24px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

/* Release badge — small muted pill in the sidebar footer. */
.version-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.10);
  background: rgba(255, 255, 255, 0.03);
  font-size: 11.5px;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.55);
  user-select: none;
}
.version-badge-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #22c55e;
  box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.18);
  flex: 0 0 auto;
}
.version-badge-label { font-weight: 600; }
.version-badge-num {
  font-weight: 700;
  color: rgba(255, 255, 255, 0.82);
}
/* Release badge shows for ALL roles, trials included (Max 2026-06-19). The old
   body[data-user-role$="_trial"] hide rule was removed. */

.user-chip {
  display: flex;
  align-items: center;
  gap: 10px;
}

.user-avatar {
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--color-accent);
  color: #fff;
  font-weight: 600;
  font-size: 13px;
  display: flex; align-items: center; justify-content: center;
}

.user-name { font-size: 13px; font-weight: 500; color: #fff; }
.user-role { font-size: 11px; color: rgba(255, 255, 255, 0.5); }

.version {
  margin-top: 12px;
  font-size: 10px;
  color: rgba(255, 255, 255, 0.35);
  letter-spacing: 1px;
}

/* ---------- Hero banner (rotating imagery + tagline) ---------- */
/* .hero-strip / .hero-strip-inline removed 2026-05-22 after experiment.
   Kept the legacy .hero block below in case any future view wants to
   reintroduce a brand banner. */

/* Legacy .hero block kept for any view that still references it directly.
   Hidden via height:0 instead of removed so any older selector chain that
   touches .hero on focus/active states doesn't paint a gap. */
.hero {
  position: relative;
  width: 100%;
  height: 200px;
  overflow: hidden;
  background: var(--color-primary);  /* shows during initial image load */
  margin-bottom: 24px;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}

.hero-images {
  position: absolute;
  inset: 0;
}

.hero-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  opacity: 0;
  transition: opacity 1.4s ease-in-out;
  will-change: opacity;
}

.hero-img.active {
  opacity: 1;
}

/* Subtle dark gradient anchored to the bottom-left so the tagline is legible
   regardless of which image is active. Lighter on the right where there's
   often content (CNC equipment, fixtures). */
.hero-overlay {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, rgba(15, 44, 74, 0.55) 0%, rgba(15, 44, 74, 0.18) 45%, rgba(15, 44, 74, 0) 70%),
    linear-gradient(180deg, rgba(15, 44, 74, 0) 50%, rgba(15, 44, 74, 0.30) 100%);
  pointer-events: none;
}

.hero-tagline {
  position: absolute;
  bottom: 24px;
  left: 32px;
  color: #fff;
  font-family: 'Inter', sans-serif;
  z-index: 2;
  text-shadow: 0 1px 12px rgba(15, 44, 74, 0.6);
}

.hero-tagline-line {
  font-size: 26px;
  font-weight: 700;
  letter-spacing: 0.5px;
  line-height: 1.15;
}

.hero-tagline-accent {
  font-size: 18px;
  font-weight: 500;
  letter-spacing: 0.5px;
  line-height: 1.15;
  margin-top: 4px;
  /* Subtle gradient picks up the spectrum / prism theme */
  background: linear-gradient(90deg, #ffd6c2, #ffeac2, #d6e8c2, #c2dde8, #d6c2e8);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* Fallback for browsers without background-clip:text */
  text-shadow: none;
}

@media (max-width: 720px) {
  .hero { height: 140px; margin-bottom: 16px; }
  .hero-tagline { left: 16px; bottom: 14px; }
  .hero-tagline-line { font-size: 18px; }
  .hero-tagline-accent { font-size: 13px; }
}

/* ---------- Main ---------- */
.main {
  padding: 32px 40px;
  overflow-y: auto;
  position: relative;
  /* Faint crystalline triangular pattern — nods to the prism logo without competing */
  background-color: var(--color-bg);
  background-image:
    linear-gradient(135deg, rgba(15, 44, 74, 0.025) 25%, transparent 25%),
    linear-gradient(225deg, rgba(15, 44, 74, 0.025) 25%, transparent 25%),
    linear-gradient(45deg, rgba(15, 44, 74, 0.018) 25%, transparent 25%),
    linear-gradient(315deg, rgba(15, 44, 74, 0.018) 25%, transparent 25%);
  background-size: 80px 80px;
  background-position: 0 0, 40px 0, 40px -40px, 0px 40px;
}

/* Subtle gradient overlay at the top of main — suggests light hitting a surface */
.main::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 220px;
  background: linear-gradient(180deg, rgba(31, 111, 196, 0.04) 0%, transparent 100%);
  pointer-events: none;
  z-index: 0;
}

.main > * {
  position: relative;
  z-index: 1;
}

.page-header {
  margin-bottom: 24px;
}

/* Per-tab maturity pill (tab-status.js) — anchored top-right of the header. */
.page-header.has-tab-status {
  position: relative;
  padding-right: 180px;
}
.tab-status-pill {
  position: absolute;
  top: 0;
  right: 0;
  display: flex;
  align-items: center;
}
.tab-status-badge {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: nowrap;
}
.tab-status-select {
  appearance: none;
  -webkit-appearance: none;
  padding: 4px 26px 4px 12px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 9px center;
}
.tab-status-select:disabled { opacity: 0.6; cursor: default; }
@media (max-width: 720px) {
  .page-header.has-tab-status { padding-right: 0; }
  .tab-status-pill { position: static; margin-top: 8px; }
}

.page-header h1 {
  font-size: 24px;
  font-weight: 600;
  color: var(--color-text);
}

.page-subtitle {
  margin-top: 4px;
  color: var(--color-text-muted);
  font-size: 14px;
}

/* Machines tab capacity-source provenance line (2026-08-11). Smaller than the
   subtitle it sits under — it's metadata about the numbers, not a description of
   the page. Uses `display:none` under [hidden] explicitly: a bare [hidden] loses
   to any class rule that sets an explicit display, which is the app-wide bug class
   swept on 2026-08-06. */
.mach-source-note {
  font-size: 12px;
  font-style: italic;
}
.mach-source-note[hidden] { display: none; }
.mach-source-note.mach-source-warn {
  color: var(--color-warn, #b45309);
  font-style: normal;
  font-weight: 600;
}

.grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}

/* ---------- Upload zone ---------- */
.upload-zone {
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: 22px 16px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
/* Large variant for Smart Quote — makes the drop target feel substantial,
   since this is now the primary action on the page. (Max 4/30) */
.upload-zone-large {
  padding: 64px 16px;
  min-height: 220px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.upload-zone-large .upload-icon { font-size: 36px; margin-bottom: 14px; }
.upload-zone-large .upload-primary { font-size: 16px; }

/* Smart Quote v2: let the upload card fill its height so there's no dead space
   below the manual-entry panel — the dropzone grows to match the (taller) Quote
   Details column, and the "Build a part manually" panel sits at the bottom.
   (Max 2026-06-19) */
#sqv2InputPanel > .card:first-child { display: flex; flex-direction: column; }
#sqv2InputPanel > .card:first-child #sqv2UploadZone { flex: 1 1 auto; min-height: 300px; }

.upload-zone:hover,
.upload-zone.dragover {
  border-color: var(--color-accent);
  background: var(--color-primary-soft);
}

.upload-icon {
  font-size: 28px;
  color: var(--color-primary);
  margin-bottom: 8px;
}

.upload-primary {
  font-size: 14px;
  color: var(--color-text);
  font-weight: 500;
}

.upload-secondary {
  font-size: 12px;
  color: var(--color-text-muted);
  margin-top: 2px;
}

.link { color: var(--color-accent); cursor: pointer; }

.or-divider {
  text-align: center;
  margin: 16px 0;
  font-size: 11px;
  color: var(--color-text-muted);
  letter-spacing: 2px;
}

/* ---------- Progress card (loading state with stepper + facts) ---------- */
.progress-card {
  margin-top: 18px;
  padding: 18px 18px 16px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: linear-gradient(180deg, #fafcff 0%, #f5f8fc 100%);
  box-shadow: var(--shadow-sm);
  animation: progress-fade-in 0.25s ease-out;
}

@keyframes progress-fade-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.stage-stepper {
  list-style: none;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0;
  margin: 0 0 16px 0;
  padding: 0;
  position: relative;
}

.stage-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  position: relative;
  font-size: 11px;
  color: var(--color-text-muted);
  font-weight: 500;
  letter-spacing: 0.4px;
  text-transform: uppercase;
}

/* Connecting line — sits behind the pills */
.stage-step:not(:last-child)::after {
  content: '';
  position: absolute;
  top: 14px;             /* center of 28px pill */
  left: calc(50% + 16px);
  right: calc(-50% + 16px);
  height: 2px;
  background: var(--color-border-strong);
  z-index: 0;
  transition: background 0.25s ease;
}
.stage-step.done:not(:last-child)::after {
  background: var(--color-good);
}

.stage-pill {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: #e3e8ef;
  color: var(--color-text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 700;
  border: 2px solid transparent;
  position: relative;
  z-index: 1;
  transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}

.stage-step.active .stage-pill {
  background: var(--color-accent);
  color: #fff;
  border-color: rgba(31, 111, 196, 0.25);
  animation: stage-pulse 1.4s ease-in-out infinite;
}
.stage-step.active .stage-label {
  color: var(--color-accent);
}

.stage-step.done .stage-pill {
  background: var(--color-good);
  color: #fff;
}
.stage-step.done .stage-label {
  color: var(--color-good);
}

.stage-step.error .stage-pill {
  background: #c93434;
  color: #fff;
}
.stage-step.error .stage-label {
  color: #c93434;
}

@keyframes stage-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(31, 111, 196, 0.45); }
  50%      { box-shadow: 0 0 0 6px rgba(31, 111, 196, 0); }
}

/* Slim progress bar */
.progress-bar {
  height: 4px;
  background: #e3e8ef;
  border-radius: 2px;
  overflow: hidden;
  margin-bottom: 10px;
}
.progress-bar-fill {
  height: 100%;
  width: 0%;
  background: linear-gradient(90deg, var(--color-accent) 0%, var(--color-primary) 100%);
  transition: width 0.4s ease;
}

.progress-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}
.progress-elapsed {
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  color: var(--color-text-muted);
  min-width: 38px;
}
.progress-status {
  flex: 1;
  font-size: 12px;
  color: var(--color-text);
  font-weight: 500;
}
.btn-cancel {
  padding: 6px 12px;
  font-size: 11px;
}

.progress-fact {
  font-size: 12px;
  color: var(--color-text-muted);
  font-style: italic;
  line-height: 1.4;
  min-height: 34px;
  padding: 8px 10px;
  border-left: 2px solid var(--color-accent);
  background: rgba(31, 111, 196, 0.04);
  border-radius: 0 4px 4px 0;
  opacity: 1;
  transition: opacity 0.2s ease;
}
.progress-fact.fading {
  opacity: 0;
}

/* ---------- Error card (replaces progress card on failure) ---------- */
.error-card {
  margin-top: 18px;
  padding: 18px 18px 16px;
  border: 1px solid #e8b4b4;
  border-left: 4px solid #c93434;
  border-radius: var(--radius-md);
  background: #fcf3f3;
  animation: progress-fade-in 0.25s ease-out;
}
.error-icon {
  font-size: 18px;
  color: #c93434;
  margin-bottom: 4px;
  font-weight: 700;
}
.error-title {
  font-size: 14px;
  font-weight: 600;
  color: #8a1f1f;
  margin-bottom: 8px;
}
.error-detail {
  font-family: 'Inter', monospace;
  font-size: 12px;
  color: #6b2828;
  background: rgba(201, 52, 52, 0.06);
  padding: 8px 10px;
  border-radius: 4px;
  max-height: 140px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-word;
  margin-bottom: 12px;
}
.error-card .btn {
  border-color: #c93434;
  color: #8a1f1f;
}
.error-card .btn:hover {
  background: rgba(201, 52, 52, 0.08);
  border-color: #8a1f1f;
}

/* ---------- Result pane ---------- */
.confidence-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}

.badge {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 12px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
.badge-good { background: rgba(31, 139, 76, 0.12); color: var(--color-good); }
.badge-warn { background: rgba(201, 122, 23, 0.12); color: var(--color-warn); }
.badge-neutral { background: rgba(96, 96, 96, 0.12); color: #888; }

/* Pricing Decision card (anchor pipeline, Max 2026-05-08) */
.anchor-mode-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.anchor-warnings {
  margin-top: 14px;
  padding: 10px 14px;
  background: rgba(201, 122, 23, 0.08);
  border-left: 3px solid var(--color-warn);
  border-radius: 4px;
}
.anchor-warnings .warning-line {
  font-size: 14px;
  color: var(--color-warn);
  line-height: 1.5;
}
.anchor-warnings .warning-line + .warning-line {
  margin-top: 6px;
}

.confidence-pct {
  font-size: 18px;
  font-weight: 600;
  color: var(--color-good);
}

.kv-grid {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 16px;
  margin-bottom: 14px;
}

.kv-grid .kv-key {
  font-size: 12px;
  color: var(--color-text-muted);
}

.kv-grid .kv-val {
  font-size: 13px;
  color: var(--color-text);
  font-weight: 500;
}

/* ---------- Ops table ---------- */
.ops-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

.ops-table th,
.ops-table td {
  padding: 9px 8px;
  text-align: left;
  border-bottom: 1px solid var(--color-border);
}

.ops-table th {
  font-weight: 600;
  color: var(--color-text-muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.ops-table .num { text-align: right; font-variant-numeric: tabular-nums; }

.ops-table tfoot .total-row td {
  font-weight: 700;
  color: var(--color-primary);
  border-top: 2px solid var(--color-border-strong);
  border-bottom: none;
  padding-top: 12px;
}
/* Extended-total row: visually bigger / brighter — this is the number that
   ships to the customer (per-piece × qty). Subtle emphasis above the
   per-piece row without overshouting it. */
.ops-table tfoot .total-row.total-extended td {
  font-size: 15px;
  border-top: 1px solid var(--color-border);
  padding-top: 8px;
  color: var(--color-primary);
  background: var(--color-primary-soft, #f4f7fb);
}

/* Inline margin input on the result panel — small, right-aligned, lets the
   quoter fiddle the margin and see the price update immediately without
   opening Review & Edit. (Max 4/30) */
.ops-table tfoot .total-row.margin-row td {
  border-top: 1px solid var(--color-border);
  padding-top: 8px;
  font-weight: 500;
  color: var(--color-text-muted, #5b6577);
}
.inline-margin-select {
  padding: 5px 8px;
  font-size: 13px;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  font-variant-numeric: tabular-nums;
  margin-right: 4px;
  background: #fff;
  min-width: 180px;
  cursor: pointer;
}
.inline-margin-select:focus {
  border-color: var(--color-accent);
  outline: none;
  box-shadow: 0 0 0 2px rgba(31, 111, 196, 0.12);
}
.inline-margin-input {
  width: 80px;
  padding: 5px 8px;
  font-size: 13px;
  text-align: right;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  font-variant-numeric: tabular-nums;
  margin-right: 4px;
}
.inline-margin-input:focus {
  border-color: var(--color-accent);
  outline: none;
  box-shadow: 0 0 0 2px rgba(31, 111, 196, 0.12);
}
.margin-status {
  font-size: 11px;
  margin-left: 8px;
  font-style: italic;
}

/* ---------- Footer ---------- */
.page-footer {
  margin-top: 32px;
  padding-top: 16px;
  border-top: 1px solid var(--color-border);
  text-align: center;
}

.muted { color: var(--color-text-muted); font-size: 12px; letter-spacing: 0.5px; }

/* ---------- Responsive ---------- */
@media (max-width: 1100px) {
  .grid-2 { grid-template-columns: 1fr; }
}

@media (max-width: 720px) {
  .app {
    grid-template-columns: 1fr;
    grid-template-areas:
      "topbar"
      "main";
  }
  .main { padding: 20px; }
  /* Width was the mobile constraint back when the wordmark was 4.48:1 (44px tall
     = 197px wide, on a bar that also holds the hamburger and the shop-pulse pills
     at 390px). The Nova lockup is 2.31:1, so 52px is only 120px — width stopped
     being the binding constraint and the tagline's legibility took over. 52 is
     the mobile floor for BY QQE staying readable; 58 tracks the desktop bump to
     72 proportionally, and 8px padding holds the mobile bar at 74px rather than
     letting it reach the desktop 80. */
  .topbar { padding: 8px 16px; }
  .topbar-logo { height: 58px; }
  .topbar-user .user-meta-inline { display: none; }

  .mobile-nav-toggle { display: inline-flex; }

  /* Desktop collapse controls (Ctrl+B pair) don't apply at this width —
     the hamburger + drawer replace them entirely. */
  .sidebar-toggle--in-sidebar,
  .sidebar-expand-floating { display: none !important; }

  /* Sidebar becomes an off-canvas drawer instead of a grid column. Was
     `display:none` unconditionally here before 2026-07-10, which left mobile
     users with NO way to navigate between views — no hamburger existed to
     bring it back. */
  .sidebar {
    display: flex;
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: min(80vw, 280px);
    z-index: 40;
    transform: translateX(-100%);
    transition: transform 0.2s ease;
    box-shadow: 2px 0 12px rgba(0, 0, 0, 0.25);
  }
  .app.mobile-nav-open .sidebar { transform: translateX(0); }
  .app.mobile-nav-open .mobile-nav-backdrop { display: block; }

  /* .nav's 56px top padding clears the fixed in-sidebar toggle button, which
     is hidden at this width — drop the offset so the drawer isn't wasting
     space above the first section label. */
  .nav { padding-top: 16px; }
}

/* ---------- View switching (SPA routing) ---------- */
.view[hidden] { display: none; }

/* ---------- Placeholder cards (Dashboard / Quote History / Customers / Settings) ---------- */
.placeholder-card {
  text-align: center;
  padding: 56px 32px;
  max-width: 600px;
  margin: 0 auto;
}
.placeholder-icon {
  font-size: 44px;
  margin-bottom: 16px;
  color: var(--color-primary);
  opacity: 0.55;
}
.placeholder-heading {
  font-size: 22px;
  font-weight: 700;
  color: var(--color-text);
  margin-bottom: 12px;
  letter-spacing: 0.3px;
}
.placeholder-body {
  color: var(--color-text-muted);
  font-size: 14px;
  line-height: 1.6;
  margin-bottom: 16px;
}
.placeholder-depends {
  color: var(--color-text-muted);
  font-size: 12px;
  font-style: italic;
  opacity: 0.85;
}
.placeholder-depends code {
  font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
  font-size: 11px;
  background: var(--color-primary-soft);
  padding: 1px 6px;
  border-radius: 3px;
  font-style: normal;
}

/* ---------- Materials table (real data view) ---------- */
.materials-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  margin-top: 16px;
}
.materials-table th,
.materials-table td {
  padding: 9px 12px;
  text-align: left;
  border-bottom: 1px solid var(--color-border);
}
.materials-table th {
  font-weight: 600;
  color: var(--color-text-muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  background: var(--color-bg);
  position: sticky;
  top: 0;
}
.materials-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.materials-table tr:hover td {
  background: var(--color-primary-soft);
}
.materials-meta {
  font-size: 12px;
  color: var(--color-text-muted);
  margin-top: 12px;
  font-style: italic;
}

/* ---------- Pricing detail in result panel (per-piece + extended total) ---------- */
.price-summary {
  margin-top: 16px;
  padding: 14px 16px;
  background: var(--color-primary-soft);
  border-radius: var(--radius-sm);
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 6px 24px;
  font-size: 13px;
}
.price-summary .ps-label {
  color: var(--color-text-muted);
}
.price-summary .ps-val {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
  text-align: right;
}
.price-summary .ps-extended {
  font-size: 16px;
  font-weight: 700;
  color: var(--color-primary);
  border-top: 1px solid rgba(15, 44, 74, 0.1);
  padding-top: 8px;
  margin-top: 4px;
}

/* ============================================================
   DASHBOARD VIEW
   Hero strip + responsive widget grid + heatmap + tables.
   ============================================================ */

/* Hero stat strip — 4 big numbers across the top */
.dash-hero {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 20px;
}
.dash-stat {
  background: #fff;
  border: 1px solid rgba(15, 44, 74, 0.08);
  border-radius: 10px;
  padding: 18px 20px;
  box-shadow: 0 1px 3px rgba(15, 44, 74, 0.04);
}
.dash-stat-label {
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-muted, #64748b);
  margin-bottom: 6px;
  display: flex; align-items: center; gap: 8px;
}
.dash-stat-value {
  font-size: 28px;
  font-weight: 700;
  color: var(--color-primary);
  font-feature-settings: "tnum";
}
.dash-stat-sub {
  font-size: 11px;
  color: #777;
  margin-top: 4px;
  font-feature-settings: "tnum";
}
.dash-stat-sub .sd-pos { color: #006100; font-weight: 600; }
.dash-stat-sub .sd-neg { color: #9C0006; font-weight: 600; }

/* Widget grid — 12 col, widgets default to 6 col, .dash-w-wide spans 12 */
.dash-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 16px;
}
.dash-widget {
  grid-column: span 6;
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  min-height: 200px;
}
.dash-widget.dash-w-wide { grid-column: span 12; }
@media (max-width: 1100px) {
  .dash-hero { grid-template-columns: repeat(2, 1fr); }
  .dash-widget { grid-column: span 12; }
}

.dash-widget-head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(15, 44, 74, 0.06);
}
.dash-widget-head h3 {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  color: var(--color-primary);
  letter-spacing: 0.01em;
}

/* Empty/loading states */
.dash-empty {
  color: var(--color-muted, #94a3b8);
  font-size: 13px;
  font-style: italic;
  text-align: center;
  padding: 12px;
}

/* Chart canvas wrappers — Chart.js with responsive:true + maintainAspectRatio:false
   needs an explicit-height parent with position:relative, otherwise it grows
   infinitely on every resize event. (Don't remove these or the bars eat the page.) */
.chart-container {
  position: relative;
  width: 100%;
  height: 220px;
  flex: 0 0 auto;
}
.chart-container-tall { height: 280px; }

/* Doughnut/pie polish — soft drop shadow on the canvas itself so slices feel
   lifted off the card. Only applies to charts containing pie/doughnut canvases
   (the `data-chart-type=pie` attribute is set by render fns when they create
   doughnut charts). Box-shadow on canvas needs filter syntax to look right. */
.chart-container canvas {
  filter: drop-shadow(0 4px 10px rgba(15, 44, 74, 0.10))
          drop-shadow(0 1px 3px rgba(15, 44, 74, 0.08));
}
.cust-shape-pie canvas {
  filter: drop-shadow(0 3px 8px rgba(15, 44, 74, 0.10));
}

/* Leaderboard list (top customers) */
.dash-leaderboard {
  list-style: none; padding: 0; margin: 0;
  counter-reset: lb;
}
.dash-leaderboard li {
  counter-increment: lb;
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid rgba(15, 44, 74, 0.05);
  font-size: 13px;
}
.dash-leaderboard li:last-child { border-bottom: none; }
.dash-leaderboard li::before {
  content: counter(lb) ".";
  font-weight: 700; color: var(--color-muted, #94a3b8);
  margin-right: 10px; min-width: 20px;
}
.dash-leaderboard .lb-name { flex: 1; color: var(--color-primary); }
.dash-leaderboard .lb-val { font-weight: 600; color: var(--color-primary); font-feature-settings: "tnum"; }

/* Heatmap (capacity) */
.dash-heatmap {
  display: flex; flex-direction: column; gap: 2px;
  font-size: 11px;
}
.heatmap-row {
  display: grid;
  grid-template-columns: 130px repeat(8, 1fr);
  gap: 2px;
}
.heatmap-header { font-weight: 600; color: var(--color-muted, #64748b); }
.heatmap-h, .heatmap-cell {
  padding: 8px 4px;
  text-align: center;
  border-radius: 3px;
  font-feature-settings: "tnum";
}
.heatmap-label {
  padding: 8px 8px;
  font-weight: 500;
  color: var(--color-primary);
  white-space: nowrap;
}
.heatmap-cell {
  font-weight: 600;
  color: rgba(15, 44, 74, 0.85);
}
.heatmap-cell.hot {
  color: #fff;
  font-weight: 700;
}

/* Machine utilization list */
.dash-machines { list-style: none; padding: 0; margin: 0; }
.dash-machines li {
  padding: 10px 0;
  border-bottom: 1px solid rgba(15, 44, 74, 0.05);
}
.dash-machines li:last-child { border-bottom: none; }
.mach-head { display: flex; justify-content: space-between; font-size: 13px; margin-bottom: 4px; }
.mach-name { color: var(--color-primary); font-weight: 600; }
.mach-pct { font-weight: 700; font-feature-settings: "tnum"; }
.mach-bar { height: 6px; background: #f1f5f9; border-radius: 3px; overflow: hidden; }
.mach-bar-fill { height: 100%; transition: width 0.3s ease; }
.mach-meta { font-size: 11px; color: var(--color-muted, #64748b); margin-top: 4px; }

/* Stick-priced parts table */
.dash-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.dash-table th, .dash-table td {
  padding: 8px 12px;
  text-align: left;
  border-bottom: 1px solid rgba(15, 44, 74, 0.06);
}
.dash-table th {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-muted, #64748b);
}
.dash-table td.num, .dash-table th.num { text-align: right; font-feature-settings: "tnum"; }
.dash-table tbody tr:hover { background: rgba(15, 44, 74, 0.02); }

/* Delta column — color-grades the price-divergence indicator on re-quote candidates.
   Green = predict says HIGHER than ship p50 (we've been under-charging). Red = lower. */
.dash-table td.delta-pos  { color: #15803d; font-weight: 700; }
.dash-table td.delta-neg  { color: #b91c1c; font-weight: 700; }
.dash-table td.delta-flat { color: var(--color-muted, #94a3b8); }

/* Activity feed */
.dash-activity { list-style: none; padding: 0; margin: 0; }
.dash-activity li {
  display: grid;
  grid-template-columns: 110px 1fr 100px;
  gap: 12px;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid rgba(15, 44, 74, 0.05);
  font-size: 13px;
}
.dash-activity li:last-child { border-bottom: none; }
.act-time { font-size: 11px; color: var(--color-muted, #64748b); font-feature-settings: "tnum"; }
.act-body { color: var(--color-primary); }
.act-total { text-align: right; font-weight: 700; color: var(--color-primary); font-feature-settings: "tnum"; }
.act-mode {
  display: inline-block;
  font-size: 10px;
  padding: 1px 6px;
  border-radius: 3px;
  margin-left: 6px;
  text-transform: uppercase;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.mode-formula              { background: #dbeafe; color: #1e40af; }
.mode-anchor               { background: #fef3c7; color: #92400e; }
.mode-premium_opportunity  { background: #ddd6fe; color: #5b21b6; }
.mode-stick                { background: #fee2e2; color: #991b1b; }

/* ============================================================
   QUOTE HISTORY VIEW
   ============================================================ */

/* Filter / search controls */
.qh-controls {
  display: flex;
  gap: 16px;
  align-items: flex-end;
  padding: 14px 18px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.qh-control { display: flex; flex-direction: column; gap: 4px; }
.qh-control label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}
.qh-control input[type="search"], .qh-control select {
  padding: 7px 12px;
  border: 1px solid rgba(15, 44, 74, 0.15);
  border-radius: 6px;
  font-size: 13px;
  font-family: inherit;
  background: #fff;
  color: var(--color-text);
  min-width: 220px;
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.qh-control input[type="search"]:focus, .qh-control select:focus {
  border-color: #2563eb;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}
.qh-control select { min-width: 150px; }

.qh-control-toggle { padding-bottom: 7px; }
.qh-checkbox {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; cursor: pointer; color: var(--color-text);
}
.qh-checkbox input[type="checkbox"] {
  width: 16px; height: 16px; cursor: pointer; accent-color: #2563eb;
}

.qh-meta {
  margin-left: auto;
  font-size: 12px;
  color: var(--color-text-muted);
  font-feature-settings: "tnum";
  padding-bottom: 7px;
}

/* Results table */
.qh-table-wrap { padding: 0; overflow: hidden; }
.qh-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.qh-table thead th {
  padding: 10px 12px;
  text-align: left;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
  background: rgba(15, 44, 74, 0.025);
  border-bottom: 1px solid rgba(15, 44, 74, 0.1);
  position: sticky; top: 0;
}
.qh-table tbody td {
  padding: 10px 12px;
  border-bottom: 1px solid rgba(15, 44, 74, 0.05);
  vertical-align: middle;
}
.qh-table tbody td.num, .qh-table thead th.num {
  text-align: right;
  font-feature-settings: "tnum";
}
.qh-row { cursor: pointer; transition: background 0.1s ease; }
.qh-part-link { color: #1F4E79; text-decoration: none; border-bottom: 1px dotted #1F4E79; }
.qh-part-link:hover { color: #163a5a; border-bottom-style: solid; }
.qh-row:hover { background: rgba(15, 44, 74, 0.025); }
.qh-row.expanded { background: rgba(37, 99, 235, 0.04); }

.qh-col-expand { width: 28px; }
.qh-expand-icon {
  display: inline-block;
  width: 16px; height: 16px;
  text-align: center; line-height: 16px;
  font-size: 10px; color: var(--color-text-muted);
  transition: transform 0.15s ease;
}
.qh-row.expanded .qh-expand-icon { transform: rotate(90deg); color: #2563eb; }

.qh-col-actions { width: 100px; text-align: right; }
.qh-actions {
  display: flex; gap: 4px; justify-content: flex-end;
}
.qh-action-btn {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid rgba(15, 44, 74, 0.12);
  background: #fff;
  border-radius: 5px;
  font-size: 13px;
  cursor: pointer;
  color: var(--color-text);
  transition: all 0.15s ease;
}
.qh-action-btn:hover { background: rgba(15, 44, 74, 0.05); border-color: rgba(15, 44, 74, 0.25); }
.qh-action-btn.qh-trash:hover { background: #fef2f2; border-color: #fecaca; color: #b91c1c; }

/* Margin select on each row */
.qh-margin-select {
  padding: 3px 8px;
  border: 1px solid rgba(15, 44, 74, 0.15);
  border-radius: 5px;
  font-size: 12px;
  font-family: inherit;
  background: #fff;
  color: var(--color-text);
  font-feature-settings: "tnum";
  cursor: pointer;
  outline: none;
}
.qh-margin-select:focus { border-color: #2563eb; }
.qh-margin-changed {
  color: #2563eb;
  font-weight: 700;
}

/* Expanded detail panel */
.qh-detail-row td {
  padding: 0 !important;
  background: rgba(37, 99, 235, 0.03);
  border-bottom: 1px solid rgba(15, 44, 74, 0.08);
}
.qh-detail {
  padding: 16px 20px 20px;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 24px;
}
@media (max-width: 900px) { .qh-detail { grid-template-columns: 1fr; } }

.qh-detail-section h4 {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}
.qh-detail-grid {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 12px;
  font-size: 12px;
}
.qh-detail-grid dt {
  color: var(--color-text-muted);
  white-space: nowrap;
}
.qh-detail-grid dd {
  margin: 0;
  color: var(--color-text);
  font-feature-settings: "tnum";
  font-weight: 500;
}

/* Quantity-breaks section — spans full detail width (all 3 columns). */
.qh-detail-section-full { grid-column: 1 / -1; }
.qh-break-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
  font-feature-settings: "tnum";
}
.qh-break-table th {
  text-align: right;
  padding: 4px 10px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
  border-bottom: 1px solid rgba(15, 44, 74, 0.12);
}
.qh-break-table th:first-child,
.qh-break-table td:first-child { text-align: left; }
.qh-break-table td {
  text-align: right;
  padding: 5px 10px;
  color: var(--color-text);
  border-bottom: 1px solid rgba(15, 44, 74, 0.06);
}
.qh-break-table tr.qh-break-primary td { background: rgba(124, 58, 237, 0.06); font-weight: 700; }
.qh-break-dot { color: #7c3aed; font-size: 9px; }
.qh-qty-breaks {
  display: inline-block;
  margin-left: 4px;
  padding: 1px 6px;
  border-radius: 9px;
  background: rgba(124, 58, 237, 0.12);
  color: #6d28d9;
  font-size: 10px;
  font-weight: 700;
}

/* Pagination */
.qh-pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 16px;
  padding: 16px 0;
}
/* See the .prism-badge[hidden] note in styles_tokens.css — an explicit `display`
   beats the UA's `[hidden]{display:none}` (equal specificity, later in source), so
   every hidden-toggled element needs its own guard. renderQuoteHistory() hides the
   pager on a single page (app.js:7186/7223); without this it sat there empty. */
.qh-pagination[hidden] { display: none; }
.qh-page-info {
  font-size: 13px;
  color: var(--color-text-muted);
  font-feature-settings: "tnum";
}

/* Trash confirm modal — `hidden` attribute is the source of truth.
   Use :not([hidden]) so the flex layout only applies when actually shown,
   otherwise display:flex overrides the browser's hidden=display:none. */
.qh-modal[hidden] { display: none; }
.qh-modal {
  position: fixed; inset: 0;
  background: rgba(15, 44, 74, 0.5);
  display: flex; justify-content: center; align-items: center;
  z-index: 50;
  backdrop-filter: blur(2px);
}
.qh-modal-card {
  background: #fff;
  border-radius: 10px;
  padding: 24px;
  max-width: 440px;
  box-shadow: 0 20px 50px rgba(15, 44, 74, 0.3);
}
.qh-modal-card h3 {
  margin: 0 0 8px;
  font-size: 16px;
  color: var(--color-primary);
}
.qh-modal-card p {
  margin: 0 0 16px;
  font-size: 13px;
  color: var(--color-text);
  line-height: 1.5;
}
.qh-modal-card code {
  background: rgba(15, 44, 74, 0.06);
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 12px;
}
.qh-modal-actions {
  display: flex; justify-content: flex-end; gap: 8px;
}
.btn-danger {
  background: #b91c1c;
  color: #fff;
  border: 1px solid #b91c1c;
}
.btn-danger:hover { background: #991b1b; border-color: #991b1b; }

/* ============================================================
   CUSTOMERS VIEW — card grid
   ============================================================ */
.cust-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 16px;
}
.cust-card {
  background: #fff;
  border: 1px solid rgba(15, 44, 74, 0.08);
  border-radius: 10px;
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
  cursor: default;
}
.cust-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(15, 44, 74, 0.08);
  border-color: rgba(15, 44, 74, 0.18);
}
.cust-card-name {
  font-size: 15px;
  font-weight: 700;
  color: var(--color-primary);
  letter-spacing: 0.005em;
}
.cust-card-rev {
  font-size: 24px;
  font-weight: 800;
  color: var(--color-primary);
  font-feature-settings: "tnum";
  line-height: 1.1;
}
.cust-card-rev-label {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-muted);
  margin-bottom: 2px;
}
.cust-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  font-size: 12px;
  color: var(--color-text-muted);
  padding-top: 10px;
  border-top: 1px solid rgba(15, 44, 74, 0.06);
}
.cust-card-meta strong {
  color: var(--color-text);
  font-weight: 600;
  font-feature-settings: "tnum";
}
.cust-card-empty {
  font-size: 11px;
  font-style: italic;
  color: var(--color-text-muted);
}

/* Card becomes clickable when there's data; expanded state spans full row */
.cust-card.has-data { cursor: pointer; }
.cust-card.has-data:active { transform: translateY(0); }
.cust-card.expanded {
  grid-column: 1 / -1;
  cursor: default;
  transform: none;
  border-color: rgba(37, 99, 235, 0.4);
  box-shadow: 0 6px 24px rgba(37, 99, 235, 0.12);
}
.cust-card.expanded:hover { transform: none; }

.cust-drilldown {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 24px;
  padding-top: 16px;
  margin-top: 6px;
  border-top: 1px solid rgba(15, 44, 74, 0.08);
}
@media (max-width: 900px) { .cust-drilldown { grid-template-columns: 1fr; } }

.cust-drilldown h4 {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

/* Top-parts list */
.cust-recent-list { list-style: none; padding: 0; margin: 0; }
.cust-recent-list li {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 8px;
  align-items: center;
  padding: 6px 0;
  border-bottom: 1px solid rgba(15, 44, 74, 0.05);
  font-size: 12px;
}
.cust-recent-list li:last-child { border-bottom: none; }
.cust-recent-pn { font-weight: 700; color: var(--color-primary); }
.cust-recent-meta { color: var(--color-text-muted); font-size: 11px; }
.cust-recent-price { color: var(--color-primary); font-weight: 600; font-feature-settings: "tnum"; }

/* Quick stats stack (margin / avg $/pc / since) */
.cust-stats { display: flex; flex-direction: column; gap: 14px; }
.cust-stat-block {
  display: flex; flex-direction: column;
  background: rgba(15, 44, 74, 0.03);
  border-radius: 6px;
  padding: 10px 12px;
}
.cust-stat-label {
  font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--color-text-muted);
  margin-bottom: 2px;
}
.cust-stat-value {
  font-size: 18px; font-weight: 700;
  color: var(--color-primary);
  font-feature-settings: "tnum";
}
.cust-stat-sub {
  font-size: 11px; color: var(--color-text-muted); margin-top: 2px;
}

/* Pie chart wrapper inside drilldown */
.cust-shape-pie { position: relative; height: 180px; }

/* Bottom revenue-share card */
.cust-rev-pie-card {
  margin-top: 16px;
  padding: 18px 20px;
}

/* ============================================================
   MATERIALS REDESIGN — hero stats + family chips + two-pane list/detail
   Replaces the older card grid with a more polished demo-worthy layout.
   ============================================================ */

/* Family filter chips strip */
.mat-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 16px 0;
}
.mat-chip {
  padding: 6px 14px;
  border: 1px solid rgba(15, 44, 74, 0.12);
  border-radius: 999px;
  background: #fff;
  color: var(--color-text);
  font-size: 13px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
  white-space: nowrap;
}
.mat-chip:hover {
  background: rgba(15, 44, 74, 0.04);
  border-color: rgba(15, 44, 74, 0.25);
}
.mat-chip.active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
  font-weight: 600;
}

/* Two-pane layout */
.mat-layout {
  display: grid;
  grid-template-columns: 380px 1fr;
  gap: 16px;
  align-items: flex-start;
}
@media (max-width: 1100px) {
  .mat-layout { grid-template-columns: 1fr; }
}

.mat-list-card {
  padding: 14px;
  position: sticky;
  top: 16px;
  max-height: calc(100vh - 120px);
  display: flex;
  flex-direction: column;
}
.mat-list-controls {
  display: flex;
  gap: 8px;
  margin-bottom: 10px;
}
.mat-search {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid rgba(15, 44, 74, 0.15);
  border-radius: 6px;
  font-size: 13px;
  font-family: inherit;
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.mat-search:focus {
  border-color: #2563eb;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}
.mat-sort {
  padding: 8px 10px;
  border: 1px solid rgba(15, 44, 74, 0.15);
  border-radius: 6px;
  font-size: 12px;
  font-family: inherit;
  background: #fff;
  color: var(--color-text);
  outline: none;
  cursor: pointer;
}
.mat-list-meta {
  font-size: 11px;
  color: var(--color-text-muted);
  font-feature-settings: "tnum";
  margin-bottom: 6px;
  padding: 0 4px;
}
.mat-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
  flex: 1;
}
.mat-list-item {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 6px;
  padding: 9px 11px;
  border-radius: 7px;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background 0.1s, border-color 0.1s;
}
.mat-list-item:hover {
  background: rgba(15, 44, 74, 0.04);
}
.mat-list-item.active {
  background: rgba(37, 99, 235, 0.08);
  border-color: rgba(37, 99, 235, 0.25);
}
.mat-list-name {
  font-weight: 700;
  font-size: 14px;
  color: var(--color-primary);
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mat-list-fam {
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--mat-color-bg, rgba(148, 163, 184, 0.15));
  color: var(--mat-color, #475569);
  white-space: nowrap;
  margin-top: 1px;
  display: inline-block;
}
.mat-list-meta-row {
  grid-column: 1 / -1;
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--color-text-muted);
  font-feature-settings: "tnum";
}
.mat-list-cost {
  font-size: 13px;
  font-weight: 700;
  color: var(--color-primary);
  font-feature-settings: "tnum";
  text-align: right;
}

/* Detail pane */
.mat-detail-card {
  padding: 28px 32px;
  min-height: 400px;
}
.mat-detail-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  border-bottom: 1px solid rgba(15, 44, 74, 0.08);
  padding-bottom: 16px;
  margin-bottom: 18px;
}
.mat-detail-name {
  font-size: 32px;
  font-weight: 800;
  color: var(--color-primary);
  letter-spacing: -0.015em;
  line-height: 1;
  margin: 0 0 6px;
}
.mat-detail-fam {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--mat-color-bg, rgba(148, 163, 184, 0.15));
  color: var(--mat-color, #475569);
  display: inline-block;
}
.mat-detail-cost-block {
  text-align: right;
}
.mat-detail-cost {
  font-size: 32px;
  font-weight: 800;
  color: var(--color-primary);
  line-height: 1;
  font-feature-settings: "tnum";
}
.mat-detail-cost-unit {
  font-size: 12px;
  color: var(--color-text-muted);
  font-weight: 600;
  margin-top: 4px;
}

/* Stat grid in detail */
.mat-detail-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px;
  margin-bottom: 20px;
}
.mat-detail-stat {
  background: rgba(15, 44, 74, 0.025);
  border-radius: 8px;
  padding: 12px 14px;
}
.mat-detail-stat-label {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
  margin-bottom: 4px;
}
.mat-detail-stat-value {
  font-size: 18px;
  font-weight: 700;
  color: var(--color-primary);
  font-feature-settings: "tnum";
}

/* Section labels in detail */
.mat-detail-section {
  margin-top: 20px;
}
.mat-detail-section h4 {
  margin: 0 0 10px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-muted);
}
.mat-detail-notes {
  background: rgba(37, 99, 235, 0.04);
  border-left: 3px solid rgba(37, 99, 235, 0.4);
  padding: 12px 16px;
  border-radius: 0 6px 6px 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--color-text);
}

/* Related materials */
.mat-related {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.mat-related-pill {
  background: #fff;
  border: 1px solid rgba(15, 44, 74, 0.12);
  border-radius: 6px;
  padding: 7px 12px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s;
}
.mat-related-pill:hover {
  background: rgba(37, 99, 235, 0.05);
  border-color: rgba(37, 99, 235, 0.4);
}
.mat-related-pill strong {
  color: var(--color-primary);
  margin-right: 6px;
}
.mat-related-pill .price {
  color: var(--color-text-muted);
  font-feature-settings: "tnum";
}

/* Jobs-using-this-material table */
.mat-jobs-meta {
  font-size: 11px;
  font-weight: 500;
  color: var(--color-text-muted);
  text-transform: none;
  letter-spacing: 0;
  margin-left: 6px;
}
.mat-jobs-wrap {
  overflow-x: auto;
}
.mat-jobs-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}
.mat-jobs-table th {
  padding: 8px 10px;
  text-align: left;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
  background: rgba(15, 44, 74, 0.025);
  border-bottom: 1px solid rgba(15, 44, 74, 0.1);
}
.mat-jobs-table td {
  padding: 8px 10px;
  border-bottom: 1px solid rgba(15, 44, 74, 0.05);
  color: var(--color-text);
}
.mat-jobs-table th.num, .mat-jobs-table td.num {
  text-align: right;
  font-feature-settings: "tnum";
}
.mat-jobs-table tbody tr:hover {
  background: rgba(15, 44, 74, 0.02);
}

/* ============================================================
   MATERIAL CATALOG — card grid (replaces the old table)
   Each material is a baseball-card-style tile: huge name,
   color-coded family chip, hero $/lb number, relative-cost bar
   showing how this material's price stacks against the most
   expensive in the catalog.
   ============================================================ */
.mat-catalog-card { padding: 18px 20px; }
.mat-catalog-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 14px;
}
.mat-catalog-meta {
  font-size: 12px;
  color: var(--color-text-muted);
  font-feature-settings: "tnum";
}

.mat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}

.mat-card {
  position: relative;
  background: #fff;
  border: 1px solid rgba(15, 44, 74, 0.08);
  border-radius: 10px;
  padding: 16px 18px 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
  overflow: hidden;
}
.mat-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(15, 44, 74, 0.08);
  border-color: rgba(15, 44, 74, 0.18);
}

/* Top stripe — color flag for the material's family. Acts as the visual
   identity so you can spot Optical vs Numeric grade at a glance. */
.mat-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 4px;
  background: var(--mat-color, #94a3b8);
}

.mat-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  padding-top: 4px;
}
.mat-name {
  font-size: 22px;
  font-weight: 800;
  color: var(--color-primary);
  letter-spacing: -0.01em;
  line-height: 1;
}
.mat-family-chip {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 3px 8px;
  border-radius: 999px;
  background: var(--mat-color-bg, rgba(148, 163, 184, 0.15));
  color: var(--mat-color, #475569);
  white-space: nowrap;
  flex-shrink: 0;
}

.mat-cost-block {
  display: flex;
  align-items: baseline;
  gap: 4px;
  padding-top: 2px;
}
.mat-cost {
  font-size: 28px;
  font-weight: 800;
  color: var(--color-primary);
  font-feature-settings: "tnum";
  line-height: 1;
}
.mat-cost-unit {
  font-size: 12px;
  font-weight: 600;
  color: var(--color-text-muted);
}
.mat-cost-empty {
  font-size: 16px;
  font-weight: 600;
  font-style: italic;
  color: var(--color-text-muted);
  font-feature-settings: "tnum";
}

/* Relative-cost bar — width = this cost / max cost. Lets you spot the
   premium materials (TSC 4 stub aside, the 214 grade towers over 124, etc). */
.mat-bar-track {
  height: 5px;
  background: rgba(15, 44, 74, 0.06);
  border-radius: 3px;
  overflow: hidden;
}
.mat-bar-fill {
  height: 100%;
  background: var(--mat-color, #94a3b8);
  border-radius: 3px;
  transition: width 0.5s cubic-bezier(0.16, 1, 0.3, 1);
  opacity: 0.85;
}

.mat-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 11px;
  color: var(--color-text-muted);
  border-top: 1px solid rgba(15, 44, 74, 0.05);
  padding-top: 8px;
  margin-top: 2px;
}
.mat-density {
  font-feature-settings: "tnum";
}

/* ============================================================
   HERO STAT STRIP — used by Machines (and reusable elsewhere).
   5 cards across, each with a colored circular icon + label + value + sub.
   ============================================================ */
.hero-stat-strip {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 14px;
  margin-bottom: 16px;
}
@media (max-width: 1300px) { .hero-stat-strip { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 800px)  { .hero-stat-strip { grid-template-columns: repeat(2, 1fr); } }

.hero-stat-card {
  display: flex;
  align-items: center;
  gap: 14px;
  background: #fff;
  border: 1px solid rgba(15, 44, 74, 0.08);
  border-radius: 12px;
  padding: 16px 18px;
  box-shadow: 0 1px 3px rgba(15, 44, 74, 0.04);
  transition: transform 0.12s, box-shadow 0.12s;
}
.hero-stat-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(15, 44, 74, 0.06);
}
.hero-stat-icon {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  font-weight: 700;
  flex-shrink: 0;
}
.hero-icon-blue    { background: rgba(37, 99, 235, 0.12);  color: #2563eb; }
.hero-icon-purple  { background: rgba(139, 92, 246, 0.13); color: #8b5cf6; }
.hero-icon-green   { background: rgba(16, 185, 129, 0.13); color: #10b981; }
.hero-icon-amber   { background: rgba(245, 158, 11, 0.15); color: #f59e0b; }
.hero-icon-emerald { background: rgba(34, 197, 94, 0.13);  color: #15803d; }
.hero-icon-red     { background: rgba(239, 68, 68, 0.12);  color: #ef4444; }

.hero-stat-body { flex: 1; min-width: 0; }
.hero-stat-label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-muted);
}
.hero-stat-value {
  font-size: 26px;
  font-weight: 800;
  color: var(--color-primary);
  font-feature-settings: "tnum";
  line-height: 1.05;
  margin: 2px 0;
}
.hero-stat-sub {
  font-size: 11px;
  color: var(--color-text-muted);
}

.machines-kpi-rail {
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 10px;
}
.machines-kpi-rail .hero-stat-card {
  padding: 9px 12px;
  gap: 9px;
  border-radius: 8px;
  box-shadow: none;
}
.machines-kpi-rail .hero-stat-card:hover {
  transform: none;
  box-shadow: 0 3px 10px rgba(15, 44, 74, 0.06);
}
.machines-kpi-rail .hero-stat-icon {
  width: 32px;
  height: 32px;
  border-radius: 7px;
  font-size: 15px;
}
.machines-kpi-rail .hero-stat-label {
  font-size: 9px;
  letter-spacing: 0.05em;
}
.machines-kpi-rail .hero-stat-value {
  font-size: 20px;
  margin: 0;
}
.machines-kpi-rail .hero-stat-sub {
  font-size: 10px;
}
@media (max-width: 1300px) { .machines-kpi-rail { grid-template-columns: repeat(5, minmax(120px, 1fr)); } }
@media (max-width: 980px)  { .machines-kpi-rail { grid-template-columns: repeat(2, 1fr); } }

/* Active-Machine Runtime card — clickable, expands a by-shift dropdown */
.mach-rt-card { position: relative; cursor: pointer; }
.mach-rt-card:focus-visible { outline: 2px solid rgba(37, 99, 235, .5); outline-offset: 2px; }
.mach-rt-caret { font-size: 8px; color: #94a3b8; margin-left: 2px; transition: transform .15s; display: inline-block; }
.mach-rt-card.open .mach-rt-caret { transform: rotate(180deg); }
.mach-rt-dropdown {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 40;
  background: #fff;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(15, 44, 74, 0.14);
  padding: 8px 10px 9px;
}
.mach-rt-dropdown[hidden] { display: none; }
.mach-run-trend-dd { right: auto; width: 320px; }
#runTrendChart { position: relative; }
.mach-run-trend-svg { width: 100%; height: auto; display: block; }
.mach-run-trend-grid { stroke: #eef2f6; stroke-width: 1; }
.mach-run-trend-axis { fill: #94a3b8; font-size: 9px; }
.mach-run-trend-hit { cursor: pointer; }
.mach-run-trend-note { margin-top: 6px; font-size: 9px; color: #94a3b8; line-height: 1.35; }
.mach-run-trend-tip {
  position: absolute; pointer-events: none; transform: translate(-50%, -135%);
  background: #0f2c4a; color: #fff; font-size: 10.5px; font-weight: 600;
  padding: 3px 7px; border-radius: 5px; white-space: nowrap;
  opacity: 0; transition: opacity .1s; z-index: 5;
}
.mach-run-trend-tip.show { opacity: 1; }

/* Daily production performance — uptime line + scrap-rate bars (Machines tab) */
.mach-rs-card { margin-top: 16px; }
.mach-rs-controls { display: flex; gap: 8px; flex-wrap: wrap; }
.mach-rs-body { position: relative; margin-top: 4px; }
.mach-rs-svg { width: 100%; height: auto; display: block; }
.mach-rs-hit { cursor: pointer; }
.mach-rs-bar { fill: #f59e0b; fill-opacity: .8; }
.mach-rs-line { stroke: #2563eb; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.mach-rs-linedot { fill: #2563eb; }
.mach-rs-axis-r { fill: #64748b; font-size: 9px; }
.mach-rs-tgt { stroke-width: 1.4; stroke-dasharray: 5 4; }
.mach-rs-tgt-up { stroke: #2563eb; stroke-opacity: .55; }
.mach-rs-tgt-scrap { stroke: #ca8a04; stroke-opacity: .7; }
.mach-rs-tgt-lbl { font-size: 8.5px; font-weight: 600; }
.mach-rs-tgt-up-lbl { fill: #2563eb; fill-opacity: .85; }
.mach-rs-tgt-scrap-lbl { fill: #a16207; fill-opacity: .95; }
/* Legend */
.mach-rs-legend { display: flex; gap: 16px; flex-wrap: wrap; margin: 8px 0 2px; font-size: 11px; color: #475569; }
.mach-rs-leg { display: inline-flex; align-items: center; gap: 6px; }
.mach-rs-leg-bar { width: 12px; height: 10px; background: linear-gradient(to top, #16a34a, #eab308 55%, #dc2626); opacity: .85; border-radius: 2px; }
.mach-rs-leg-line { width: 14px; height: 2px; background: #2563eb; border-radius: 2px; }
.mach-rs-leg-dash { width: 14px; height: 0; border-top: 2px dashed #94a3b8; }
/* Correlation readout + caveat */
.mach-rs-corr {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px;
  margin: 6px 0 2px; font-size: 12px;
}
.mach-rs-r { font-size: 18px; font-weight: 700; letter-spacing: -0.01em; }
.mach-rs-r.rs-ok { color: #16a34a; }
.mach-rs-r.rs-warn { color: #d97706; }
.mach-rs-r.muted { color: #94a3b8; font-size: 13px; font-weight: 600; }
.mach-rs-rword { font-weight: 600; color: #334155; text-transform: capitalize; }
.mach-rs-rhint { color: #64748b; }
.mach-rs-rbasis { color: #94a3b8; font-size: 11px; }
.mach-rs-caveat { color: #94a3b8; line-height: 1.4; }
.mach-rt-dd-head {
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 10px; font-weight: 600; color: #334155; margin-bottom: 6px;
}
.mach-rt-dd-head span { font-weight: 400; color: #94a3b8; font-size: 9px; }
.mach-rt-dd-shifts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.mach-rt-dd-shifts > div {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 6px 4px; border: 1px solid #eef2f7; border-radius: 6px; background: #f8fafc;
}
.mach-rt-dd-shifts span { font-size: 9px; color: #94a3b8; text-transform: uppercase; letter-spacing: .04em; }

/* Topbar calendar-pill ship heatmap — click "work days left" to drop down a
   small month calendar shaded by that day's shipped $ (GitHub-contribution
   style). Reuses .mach-rt-dropdown's shell (position/shadow/border), adds its
   own grid/legend. Anchored to the RIGHT edge since the pill sits near the
   topbar's right side — a left-anchored dropdown would run off-screen. */
.cal-pill { position: relative; cursor: pointer; }
.cal-pill:focus-visible { outline: 2px solid rgba(37, 99, 235, .5); outline-offset: 2px; }
.cal-pill-caret { font-size: 8px; color: #94a3b8; margin-left: 1px; transition: transform .15s; display: inline-block; }
.cal-pill.open .cal-pill-caret { transform: rotate(180deg); }
.cal-heatmap-dropdown { left: auto; right: 0; width: 240px; cursor: default; }
.cal-hm-head {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 11px; font-weight: 600; color: #334155; margin-bottom: 2px;
}
.cal-hm-sub { font-weight: 400; color: #94a3b8; font-size: 9px; margin-bottom: 6px; }
.cal-hm-nav {
  border: none; background: none; cursor: pointer; color: #94a3b8;
  font-size: 15px; line-height: 1; padding: 2px 6px; border-radius: 4px;
}
.cal-hm-nav:hover { background: rgba(15, 44, 74, 0.08); color: #334155; }
.cal-hm-nav:disabled { opacity: .3; cursor: default; }
.cal-hm-nav:disabled:hover { background: none; }
.cal-hm-dow, .cal-hm-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.cal-hm-dow { margin-bottom: 3px; }
.cal-hm-dow span { text-align: center; font-size: 8.5px; color: #94a3b8; text-transform: uppercase; }
.cal-hm-day {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 4px;
  display: flex; align-items: center; justify-content: center;
  font-size: 9px; font-weight: 600; color: #64748b;
  background: #f1f5f9;
  cursor: default;
}
.cal-hm-day.cal-hm-empty { background: transparent; }
.cal-hm-day.cal-hm-weekend { background: #f8fafc; color: #cbd5e1; }
.cal-hm-day.cal-hm-future { background: #f8fafc; color: #cbd5e1; }
.cal-hm-day.cal-hm-today { box-shadow: 0 0 0 1.5px #0f2c4a inset; }
.cal-hm-day[data-tier="1"] { background: #dbeafe; color: #1e3a8a; }
.cal-hm-day[data-tier="2"] { background: #93c5fd; color: #1e3a8a; }
.cal-hm-day[data-tier="3"] { background: #3b82f6; color: #fff; }
.cal-hm-day[data-tier="4"] { background: #0f2c4a; color: #fff; }
.cal-hm-legend {
  display: flex; align-items: center; justify-content: flex-end; gap: 3px;
  margin-top: 7px; font-size: 8.5px; color: #94a3b8;
}
.cal-hm-swatch { width: 9px; height: 9px; border-radius: 2px; background: #f1f5f9; }
.cal-hm-swatch[data-tier="1"] { background: #dbeafe; }
.cal-hm-swatch[data-tier="2"] { background: #93c5fd; }
.cal-hm-swatch[data-tier="3"] { background: #3b82f6; }
.cal-hm-swatch[data-tier="4"] { background: #0f2c4a; }
/* Scrap heatmap legend swatches — same light-pink → deep-red ramp the Scrap
   tab's own calendar already uses (renderScrapCalendar's colorFor), so the
   topbar dropdown reads as the same visual language, not a new palette. */
.cal-hm-swatch--scrap[data-tier="1"] { background: #ffd9d9; }
.cal-hm-swatch--scrap[data-tier="2"] { background: #ff9999; }
.cal-hm-swatch--scrap[data-tier="3"] { background: #e04a4a; }
.cal-hm-swatch--scrap[data-tier="4"] { background: #9c0006; }
.cal-hm-tip {
  position: absolute; pointer-events: none; transform: translate(-50%, -135%);
  background: #0f2c4a; color: #fff; font-size: 10px; font-weight: 600;
  padding: 3px 7px; border-radius: 5px; white-space: nowrap;
  opacity: 0; transition: opacity .1s; z-index: 5; left: 50%; top: 0;
}
.cal-hm-tip.show { opacity: 1; }
.cal-hm-note { margin-top: 6px; font-size: 9px; color: #94a3b8; line-height: 1.35; }
.mach-rt-dd-shifts strong { font-size: 15px; color: #0f2c4a; }
/* Clickable shift tile → expands the hours-breakdown detail panel below. */
.mach-rt-shift { cursor: pointer; transition: background .12s, border-color .12s; }
.mach-rt-shift:hover { background: #eef4ff; border-color: #cdddf7; }
.mach-rt-shift.is-open { background: #e7f0ff; border-color: #93b4e8; box-shadow: inset 0 0 0 1px #93b4e8; }
.mach-rt-shift-detail { margin-top: 7px; padding: 8px 10px; border: 1px solid #e2e8f0; border-radius: 6px; background: #fbfdff; }
.mach-rt-shift-detail[hidden] { display: none; }
.mach-rt-det-head { font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: #94a3b8; margin-bottom: 6px; }
.mach-rt-det-bar { display: flex; width: 100%; height: 10px; border-radius: 4px; overflow: hidden; background: #eef2f6; margin-bottom: 8px; }
.mach-rt-det-bar .mfd-sb-seg { height: 100%; }
.mach-rt-det-row { display: flex; justify-content: space-between; align-items: center; font-size: 11px; color: #475569; padding: 2px 0; }
.mach-rt-det-row span { display: inline-flex; align-items: center; gap: 6px; }
.mach-rt-det-row strong { font-size: 12px; font-variant-numeric: tabular-nums; color: #0f2c4a; }
.mach-rt-det-row .mfd-sb-d { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }
.mach-rt-when { font-style: normal; color: #b0bac6; font-size: 8px; letter-spacing: 0; }
.mach-rt-when:not(:empty)::before { content: "· "; }
.mach-rt-dd-note { margin-top: 7px; font-size: 9px; color: #94a3b8; line-height: 1.35; }

/* Exclude-from-runtime toggle in the machine drawer */
/* Exclude-from-runtime control — flat: a label row + three shift pills (tap to
   drop a shift) + a reason picker that reveals when any shift is dropped. */
.mfd-excl {
  margin-top: 10px; padding-top: 9px; border-top: 1px solid #eef2f7;
  font-size: 11px; color: #475569;
}
.mfd-excl-head { display: flex; align-items: baseline; gap: 8px; }
.mfd-excl-head > span:first-child { font-weight: 700; color: #475569; letter-spacing: .01em; }
.mfd-excl-shifts { display: flex; align-items: center; gap: 6px; margin-top: 7px; }
/* Pill = one shift. Default (counting): neutral outline. .excl (dropped): red +
   strikethrough so the excluded shifts read at a glance. */
.mfd-shpill {
  flex: 1 1 0; padding: 5px 0; border-radius: 7px;
  font-size: 12px; font-weight: 700; letter-spacing: .02em;
  border: 1px solid var(--color-border, #dbe2ea); background: #fff; color: #64748b;
  cursor: pointer; transition: border-color .12s, background .12s, color .12s;
}
.mfd-shpill:hover { border-color: #cbd5e1; background: #f8fafc; }
.mfd-shpill.excl { border-color: #e6a4a4; background: #fbe9e9; color: #a32d2d; text-decoration: line-through; text-decoration-color: #d99; }
.mfd-shpill.excl:hover { background: #f7dede; }
/* "All" pill — compact action set off to the right; no strikethrough (it's a
   verb, not a shift), just the same red fill when everything's dropped. */
.mfd-shpill-all { flex: 0 0 auto; padding: 5px 12px; margin-left: 4px; color: #94a3b8; }
.mfd-shpill-all.excl { text-decoration: none; }
/* Why-excluded reason picker. */
.mfd-excl-reason { display: flex; align-items: center; gap: 7px; margin-top: 8px; font-size: 11px; color: #475569; }
.mfd-excl-reason[hidden] { display: none; }
.mfd-excl-select {
  flex: 1 1 auto; font-size: 12px; padding: 5px 8px;
  border: 1px solid var(--color-border, #dbe2ea); border-radius: 6px;
  background: #fff; color: #1b3a5b; cursor: pointer;
}

/* ============================================================
   MACHINES — Capacity Overview stacked bar + health filter chips
   ============================================================ */
.mach-cap-card { padding: 18px 20px; margin-bottom: 16px; }
.mach-cap-card-compact {
  padding: 10px 14px 12px;
  margin-bottom: 12px;
}
.mach-cap-card-compact .mach-cap-head {
  margin-bottom: 8px;
}
.mach-cap-card-compact .card-title {
  font-size: 13px;
}
.mach-cap-card-compact .muted {
  font-size: 10px !important;
}
.mach-cap-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 14px;
}
.mach-chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.mach-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid rgba(15, 44, 74, 0.12);
  border-radius: 999px;
  background: #fff;
  color: var(--color-text);
  font-size: 12px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.mach-chip:hover {
  background: rgba(15, 44, 74, 0.04);
  border-color: rgba(15, 44, 74, 0.25);
}
.mach-chip.active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}
.chip-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  display: inline-block;
}
.dot-overloaded { background: #dc2626; }
.dot-near       { background: #f59e0b; }
.dot-healthy    { background: #10b981; }
.dot-underused  { background: #94a3b8; }
.chip-n {
  font-size: 11px;
  font-weight: 700;
  color: var(--color-text-muted);
  font-feature-settings: "tnum";
  margin-left: 2px;
}
.mach-chip.active .chip-n { color: rgba(255, 255, 255, 0.85); }

/* Stacked overview bar — 4 segments showing % distribution */
.mach-cap-stack {
  display: flex;
  height: 38px;
  border-radius: 8px;
  overflow: hidden;
  background: rgba(15, 44, 74, 0.04);
}
.mach-cap-seg {
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  font-feature-settings: "tnum";
  transition: width 0.6s cubic-bezier(0.16, 1, 0.3, 1);
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
}
.seg-overloaded { background: linear-gradient(90deg, #b91c1c, #dc2626); }
.seg-near       { background: linear-gradient(90deg, #b45309, #f59e0b); }
.seg-healthy    { background: linear-gradient(90deg, #16a34a, #10b981); }
.seg-underused  { background: linear-gradient(90deg, #64748b, #94a3b8); }

/* ============================================================
   MACHINES — Main 2-col layout: card grid (left) + sidebar panels (right)
   ============================================================ */
.mach-layout {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 16px;
  align-items: flex-start;
}
@media (max-width: 1200px) {
  .mach-layout { grid-template-columns: 1fr; }
}

.mach-side {
  display: flex;
  flex-direction: column;
  gap: 14px;
  position: sticky;
  top: 16px;
}

.mach-side-card { padding: 14px 16px; }
.mach-side-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(15, 44, 74, 0.08);
}
.mach-side-head h3 {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--color-primary);
  letter-spacing: 0.005em;
}
.mach-side-icon {
  width: 24px; height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 700;
}
.mach-side-icon-bad  { background: rgba(220, 38, 38, 0.12);  color: #b91c1c; }
.mach-side-icon-good { background: rgba(16, 185, 129, 0.13); color: #15803d; }
.mach-side-icon-info { background: rgba(37, 99, 235, 0.10);  color: #1e40af; }

.mach-side-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.mach-side-list li {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 10px;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid rgba(15, 44, 74, 0.05);
  font-size: 12px;
  cursor: pointer;
  transition: background 0.12s;
  border-radius: 4px;
  padding: 8px 6px;
}
.mach-side-list li:hover { background: rgba(15, 44, 74, 0.03); }
.mach-side-list li:last-child { border-bottom: none; }
.mach-side-rank {
  width: 22px; height: 22px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(15, 44, 74, 0.08);
  color: var(--color-primary);
  border-radius: 50%;
  font-size: 11px;
  font-weight: 700;
  font-feature-settings: "tnum";
}
.mach-side-name {
  font-weight: 700;
  color: var(--color-primary);
  font-feature-settings: "tnum";
}
.mach-side-mini-bar {
  width: 100%;
  height: 4px;
  background: rgba(15, 44, 74, 0.06);
  border-radius: 2px;
  margin-top: 2px;
  overflow: hidden;
}
.mach-side-mini-bar-fill {
  height: 100%;
  border-radius: 2px;
}
.mach-side-mini-bar-fill.bad  { background: #dc2626; }
.mach-side-mini-bar-fill.good { background: #10b981; }
.mach-side-slack {
  font-size: 12px;
  font-weight: 700;
  font-feature-settings: "tnum";
  white-space: nowrap;
}
.mach-side-slack.bad  { color: #b91c1c; }
.mach-side-slack.good { color: #15803d; }

/* Recommendations — stacked cards inside the panel */
.mach-rec-item {
  background: rgba(15, 44, 74, 0.025);
  border-left: 3px solid var(--rec-color, #2563eb);
  padding: 10px 12px;
  border-radius: 0 6px 6px 0;
  margin-bottom: 8px;
  font-size: 12px;
}
.mach-rec-item:last-child { margin-bottom: 0; }
.mach-rec-title {
  font-weight: 700;
  color: var(--color-primary);
  margin-bottom: 4px;
  font-size: 12px;
}
.mach-rec-body {
  color: var(--color-text);
  line-height: 1.4;
}
.mach-rec-body strong {
  color: var(--color-primary);
  font-feature-settings: "tnum";
}
.mach-rec-bad  { --rec-color: #dc2626; }
.mach-rec-warn { --rec-color: #f59e0b; }
.mach-rec-info { --rec-color: #2563eb; }

/* Status pill on machine cards */
.mach-status-pill {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
}
.mach-status-pill.overloaded { background: rgba(220, 38, 38, 0.12); color: #b91c1c; }
.mach-status-pill.near       { background: rgba(245, 158, 11, 0.15); color: #b45309; }
.mach-status-pill.healthy    { background: rgba(16, 185, 129, 0.13); color: #15803d; }
.mach-status-pill.underused  { background: rgba(148, 163, 184, 0.18); color: #475569; }
.danger-text { color: #b91c1c !important; }

.mach-toolbar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 12px 0 16px;
  flex-wrap: wrap;
}
.mach-search,
.mach-sort {
  min-height: 38px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid rgba(15, 44, 74, 0.12);
  background: #fff;
  border-radius: 8px;
  padding: 0 11px;
  color: var(--color-text-muted);
  box-shadow: 0 1px 2px rgba(15, 44, 74, 0.03);
}
.mach-search {
  flex: 1 1 260px;
  max-width: 440px;
}
.mach-search input,
.mach-sort select {
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--color-text);
  font: inherit;
}
.mach-search input {
  width: 100%;
  min-width: 0;
}
.mach-sort span {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.mach-sort select {
  min-width: 132px;
  cursor: pointer;
}
.mach-source {
  margin-left: auto;
  color: var(--color-text-muted);
  font-size: 11px;
}

/* ============================================================
   MACHINES VIEW — card grid of CNC mills with capacity + parts drilldown
   ============================================================ */
.mach-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px;
}

/* ---- Floor Layout map ---- */
.mach-floor-card {
  margin-bottom: 12px;
  padding: 18px 20px 20px;
  border-color: rgba(15, 44, 74, 0.14);
}
.mach-floor-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; margin-bottom: 10px;
}
.mach-floor-actions {
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}
.mach-map-chips {
  justify-content: flex-end;
  max-width: 620px;
}
.mach-floor-legend { display: flex; gap: 14px; flex-wrap: wrap; }
/* Held-out-of-runtime list under the legend (audit F13) */
.mach-excl-list { margin: 6px 0 2px; font-size: 12px; color: var(--text-muted, #5b6b7d); }
.mach-excl-list summary { cursor: pointer; font-weight: 600; }
.mach-excl-list ul { margin: 4px 0 0; padding-left: 18px; }
.mach-excl-list li { margin: 2px 0; }
.mach-excl-list .mex-note { margin: 4px 0 0; font-style: italic; }
.mach-excl-list .mex-none { color: #b45309; }
.mfd-excl-who { margin-top: 6px; }
.mfl-item { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: var(--text-muted, #5b6b7d); }
.mfl-dot { width: 11px; height: 11px; border-radius: 3px; display: inline-block; }
.mfl-mill  { background: #e6eef7; border: 1px solid #b9cde2; }
.mfl-umc   { background: #1f6feb; }
.mfl-lathe { background: #fde2c4; border: 1px solid #e8b87a; }
.mfl-zone  { background: #eef0f2; border: 1px dashed #c2c9d1; }

/* view-mode toggle */
.mach-floor-modes { display: inline-flex; background: #eef1f5; border-radius: 8px; padding: 3px; gap: 2px; }
.mfm-btn {
  border: none; background: transparent; cursor: pointer;
  font: inherit; font-size: 12px; font-weight: 600; color: #5b6b7d;
  padding: 5px 12px; border-radius: 6px; transition: all .12s ease;
}
.mfm-btn:hover { color: #1b3a5b; }
.mfm-btn.active { background: #fff; color: #1f6feb; box-shadow: 0 1px 3px rgba(15,44,74,.12); }

/* metadata strip */
.mach-floor-metabar {
  display: flex; gap: 18px; align-items: center; flex-wrap: wrap;
  margin-bottom: 8px; font-size: 11px; color: #5b6b7d;
}
.mfmeta-k { opacity: .7; }
/* Find-a-machine box (audit F22) */
.mfmeta-find input { font: inherit; font-size: 12px; padding: 2px 8px; border: 1px solid #c8d3df; border-radius: 6px; width: 150px; max-width: 40vw; background: transparent; color: inherit; }
.mfmeta-find .mf-find-hit { font: inherit; font-size: 11px; padding: 1px 6px; border: 1px solid #c8d3df; border-radius: 4px; background: transparent; color: inherit; cursor: pointer; }
.mfmeta strong { color: #1b3a5b; }
.mfmeta-right { margin-left: auto; opacity: .7; font-style: italic; }
/* Audit #38 — the live badge and feed warning must not read "Live" over a frozen board. */
.mfmeta-right.is-warn { opacity: 1; color: #b26a00; font-weight: 600; font-style: normal; }
.mfmeta-right.is-bad { opacity: 1; color: #b3261e; font-weight: 700; font-style: normal; }
.mach-feed-warn[hidden] { display: none !important; }
.mach-feed-warn { display: block; margin: 6px 0; padding: 6px 10px; border-radius: 6px;
  background: #fdecea; color: #8a1c14; border: 1px solid #f3b8b1; font-size: 13px; font-weight: 600; }

/* utilization-mode legend dots */
.mfl-over    { background: #e5484d; }
.mfl-near    { background: #f5a623; }
.mfl-healthy { background: #30a46c; }
.mfl-under   { background: #8b9aa8; }
.mfl-nodata  { background: #eceff2; border: 1px solid #b6c0ca; }
.mfl-cmm     { background: #dceafe; border: 1px solid #7aa7ef; }
.mfl-pickup  { background: #fdf0c8; border: 1px solid #e3b23c; }
.mfl-runpickup { background: linear-gradient(90deg, #d7f0e3 50%, #fdf0c8 50%); border: 1px solid #30a46c; }
.mfl-idle    { background: #fbeaea; border: 1px solid #e0b4b6; }
.mfl-unmapped { background: #fff; border: 1px dashed #c2c9d1; }
.mfl-selected { background: #fff; border: 2px solid #0b63ce; box-shadow: 0 0 0 1px rgba(11,99,206,.25); }
.mfl-baseload { background: #5b8def; }
.mfl-spotbuy  { background: #3aa99a; }

.mach-floor {
  border: 1px solid rgba(15, 44, 74, 0.1);
  border-radius: 10px;
  padding: 10px;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.86), rgba(244,247,251,0.92)),
    #f4f7fb;
  overflow: auto hidden;
  min-width: 0;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.mach-floor::-webkit-scrollbar { display: none; }
#machFloorStage { display: block; }
#machFloorStage canvas { border-radius: 8px; }

.mach-floor-workbench {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: 14px;
  align-items: start;
}

.mach-floor-rightcol {
  position: sticky;
  top: 76px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.mach-floor-inspector {
  min-height: 300px;
  border: 1px solid rgba(15, 44, 74, 0.14);
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 8px 22px rgba(15, 44, 74, 0.07);
  padding: 14px;
}

/* Lathes widget — sits under the selected-machine panel in the right column */
.mach-floor-lathes-widget {
  border: 1px solid rgba(15, 44, 74, 0.14);
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 8px 22px rgba(15, 44, 74, 0.07);
  padding: 13px 15px 15px;
}
.mlw-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 11px; }
.mlw-head > span:first-child { font-weight: 800; font-size: 14px; letter-spacing: .2px; }
.mlw-meta { font-size: 10.5px; color: var(--prism-ink-muted); font-weight: 600; letter-spacing: .3px; }
.mlw-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 7px; }
.mlw-tile {
  position: relative;
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  border: 1px solid var(--prism-line);
  border-left: 3px solid var(--prism-accent);
  border-radius: 8px;
  background: var(--prism-panel, #fff);
  padding: 8px 10px;
  cursor: pointer; font: inherit; text-align: left;
  transition: transform .08s, box-shadow .08s;
}
.mlw-tile:hover { transform: translateY(-1px); box-shadow: 0 3px 8px rgba(15,44,74,0.1); }
.mlw-tile.mlw-sel { outline: 2px solid #0b63ce; outline-offset: 1px; }
.mlw-id { font-weight: 800; font-size: 14px; line-height: 1.05; color: var(--prism-ink, #1b3a5b); }
.mlw-sub { font-size: 9.5px; opacity: .72; text-transform: capitalize; line-height: 1.2; }

/* drag/save controls + hint */
.mf-tools { display: inline-flex; gap: 6px; margin-left: auto; }
.mfmeta-right { margin-left: 12px; }
.mf-tool-btn {
  border: 1px solid #cdd6e0; background: #fff; color: #1b3a5b;
  font: inherit; font-size: 11px; font-weight: 600; cursor: pointer;
  padding: 4px 11px; border-radius: 6px; transition: all .12s ease;
}
.mf-tool-btn:hover:not(:disabled) { background: #eef3fb; border-color: #9db9e0; }
.mf-tool-primary { background: #1f6feb; color: #fff; border-color: #1f6feb; }
.mf-tool-primary:hover:not(:disabled) { background: #1a5fd0; }
.mf-tool-btn:disabled { opacity: .5; cursor: default; }
.mfl-hint { font-size: 10px; color: #9aa6b2; font-style: italic; margin-left: 8px; }
.mach-floor-mills { min-width: 0; }
.mach-floor-banks-head, .mach-floor-support-head {
  font-size: 10px; text-transform: uppercase; letter-spacing: .7px;
  color: #7a8794; font-weight: 700; margin-bottom: 10px;
}
/* banks = physical machine groups laid out left→right with aisle gaps */
.mach-floor-banks {
  display: flex;
  align-items: stretch;
  justify-content: center;
  gap: 0;
  padding-bottom: 6px;
}
.mfbank {
  flex: 0 0 auto;
  background: rgba(255,255,255,.55);
  border: 1px solid rgba(15,44,74,.09);
  border-radius: 10px;
  padding: 9px 9px 11px;
}
.mfbank-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-bottom: 8px; padding-bottom: 6px;
  border-bottom: 1px dashed rgba(15,44,74,.12);
}
.mfbank-name { font-size: 11px; font-weight: 700; color: #2c3e52; white-space: nowrap; }
.mfbank-tag { font-size: 9px; font-weight: 700; color: #6f42c1; background: #f0e9fb; padding: 1px 6px; border-radius: 999px; margin-left: 4px; }
.mfbank-n { font-size: 10px; font-weight: 700; color: #8a97a5; background: #eef1f5; border-radius: 999px; padding: 1px 7px; }
.mfbank-cols { display: flex; gap: 6px; }
.mach-floor-col { display: flex; flex-direction: column; gap: 5px; }

/* aisle / walkway between banks — intentional open floor, not dead space */
.mach-floor-aisle {
  flex: 1 1 60px;                /* grow to absorb leftover width as walkway */
  min-width: 44px; max-width: 140px;
  align-self: stretch;
  margin: 26px 6px 0;           /* drop below the bank header line */
  display: flex; align-items: center; justify-content: center;
  border-left: 1px dashed rgba(31,111,235,.22);
  border-right: 1px dashed rgba(31,111,235,.22);
}
.mfaisle-label {
  writing-mode: vertical-rl; transform: rotate(180deg);
  font-size: 9px; letter-spacing: 2px; text-transform: uppercase;
  color: #9aa6b2; font-weight: 700; user-select: none;
}

.mft {
  position: relative;
  width: 58px; min-height: 46px;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1px; padding: 5px 3px 7px;
  border-radius: 7px; cursor: pointer;
  font-family: inherit; line-height: 1.05;
  overflow: hidden;
  transition: transform .1s ease, box-shadow .1s ease, border-color .1s ease;
}
.mft-id  { font-size: 12px; font-weight: 800; letter-spacing: .2px; }
.mft-sub { font-size: 7.5px; opacity: .7; text-transform: uppercase; letter-spacing: .2px; text-align: center; line-height: 1; }
.mft-util { font-size: 9px; font-weight: 800; }
.mft:hover { transform: translateY(-1px); box-shadow: 0 3px 10px rgba(15,44,74,.16); z-index: 2; }
.mft.is-sel { outline: 2px solid #1f6feb; outline-offset: 1px; box-shadow: 0 0 0 4px rgba(31,111,235,.15); }
/* utilization micro-bar pinned to tile bottom */
.mft-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: rgba(15,44,74,.08); }
.mft-bar-fill { display: block; height: 100%; }
.mfu-bar-overloaded { background: #e5484d; }
.mfu-bar-near       { background: #f5a623; }
.mfu-bar-healthy    { background: #30a46c; }
.mfu-bar-underused  { background: #8b9aa8; }

.mft-mill { background: #e6eef7; border: 1px solid #b9cde2; color: #1b3a5b; }
.mft-new  { background: #eaf4ec; border: 1px solid #aed4b7; color: #1f5132; }
.mft-umc  { background: #6f42c1; border: 1px solid #5a32a3; color: #fff; }
.mft-lathe{ background: #fde2c4; border: 1px solid #e8b87a; color: #7a4a14; }

/* utilization-mode tile colors */
.mfu-overloaded { background: #fde0e1; border: 1px solid #e5484d; color: #8b1a1f; }
.mfu-near       { background: #fdeccb; border: 1px solid #f5a623; color: #7a4f06; }
.mfu-healthy    { background: #d7f0e3; border: 1px solid #30a46c; color: #14532d; }
.mfu-underused  { background: #eceff2; border: 1px solid #b6c0ca; color: #50606f; }
.mfu-nodata     { background: #fff; border: 1px dashed #c8d0d9; color: #9aa6b2; }
.mft-util { font-size: 9px; font-weight: 700; opacity: .9; }

.mach-floor-support {
  display: flex; flex-direction: column; gap: 8px;
  background: rgba(255,255,255,.5);
  border: 1px solid rgba(15,44,74,.08);
  border-radius: 10px; padding: 12px;
}
.mach-floor-zone {
  border: 1px solid #d8dee6; border-radius: 8px;
  padding: 11px 12px; background: #fff;
  display: flex; flex-direction: column; gap: 2px;
}
.mfz-name { font-size: 12px; font-weight: 700; color: #36475a; }
.mfz-sub  { font-size: 9px; text-transform: uppercase; letter-spacing: .4px; color: #8a97a5; }
.mfz-tool { background: #fffbe6; border: 1px solid #e8d98a; }
.mfz-wax  { background: #fbfcfd; border: 1px dashed #c2c9d1; }
.mfz-fire { background: #fff1ee; border: 1px solid #f0a99a; }
.mfz-fire .mfz-name { color: #a3341f; }
.mfz-muted { opacity: .55; border-style: dashed; }
.mach-floor-lathes {
  border: 1px solid #e8b87a; border-radius: 8px;
  padding: 10px 12px; background: #fff8ef;
}
.mfz-lathes-label {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 12px; font-weight: 700; color: #7a4a14; margin-bottom: 8px;
}
.mach-floor-lathecol { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; }
.mach-floor-lathecol .mft { width: 100%; min-width: 0; min-height: 38px; }

.mfd-empty {
  height: 100%;
  min-height: 322px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 7px;
  color: #5b6b7d;
}
.mfd-empty-k,
.mfd-kicker {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: #7a8794;
}
.mfd-empty strong { color: #1b3a5b; font-size: 16px; line-height: 1.2; }
.mfd-empty span:last-child { font-size: 12px; line-height: 1.35; }
.mfd-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.mfd-id {
  display: block;
  margin-top: 1px;
  font-size: 34px;
  line-height: 1;
  color: #102a43;
  letter-spacing: 0;
}
.mfd-crit-wrap { display: inline-flex; align-items: center; gap: 4px; margin-top: 6px; }
.mfd-crit-toggle {
  font-size: 10px; font-weight: 800; letter-spacing: .02em;
  color: #94a3b8; background: #f4f7fb; border: 1px solid rgba(15,44,74,.1);
  border-radius: 999px; padding: 3px 9px; cursor: pointer; transition: all .12s ease;
}
.mfd-crit-toggle:hover { border-color: rgba(11,99,206,.4); color: #1b3a5b; }
.mfd-crit-toggle.is-on { color: #b45309; background: #fef3e2; border-color: #f3c98b; }
.mfd-crit-toggle.is-manual { box-shadow: 0 0 0 1px rgba(11,99,206,.35) inset; }
.mfd-crit-reset {
  font-size: 11px; color: #94a3b8; background: transparent; border: 0;
  cursor: pointer; padding: 2px 4px; border-radius: 5px;
}
.mfd-crit-reset:hover { color: #0b63ce; background: #eef1f5; }
.mfd-dl-link {
  display: inline-flex; align-items: center; margin-left: 6px; margin-top: 6px;
  font-size: 10px; color: #94a3b8; text-decoration: none; letter-spacing: .01em;
}
.mfd-dl-link:hover { color: #0b63ce; text-decoration: underline; }
.mfd-band {
  padding: 4px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 800;
  white-space: nowrap;
}
.mfd-spec {
  margin-top: 10px;
  font-size: 13px;
  font-weight: 700;
  color: #1b3a5b;
}
.mfd-location {
  margin-top: 3px;
  font-size: 12px;
  color: #5b6b7d;
}
.mfd-util-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-top: 18px;
  font-size: 12px;
  color: #5b6b7d;
}
.mfd-util-row strong {
  font-size: 20px;
  color: #102a43;
}
.mfd-meter {
  height: 9px;
  margin-top: 7px;
  border-radius: 999px;
  background: rgba(15,44,74,.08);
  overflow: hidden;
}
.mfd-meter span {
  display: block;
  height: 100%;
  min-width: 4px;
  border-radius: inherit;
  background: #1f6feb;
}
.mfd-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: 14px;
}
.mfd-grid div {
  border: 1px solid rgba(15,44,74,.08);
  border-radius: 8px;
  padding: 9px;
  background: #f8fafc;
}
.mfd-grid span {
  display: block;
  font-size: 10px;
  color: #7a8794;
  text-transform: uppercase;
  letter-spacing: .05em;
  font-weight: 700;
}
.mfd-grid strong {
  display: block;
  margin-top: 3px;
  font-size: 13px;
  color: #1b3a5b;
}
.mfd-muted { margin-top: 14px; font-size: 12px; font-style: italic; opacity: .72; }
/* live inspector — history section */
.mfd-grid.mfd-grid-3 { grid-template-columns: 1fr 1fr 1fr; margin-top: 8px; }
.mfd-sec-label {
  margin-top: 14px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: #7a8794;
}
.mfd-shifts { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-top: 6px; }
.mfd-sh {
  border: 1px solid rgba(15,44,74,.08);
  border-radius: 8px;
  padding: 8px 6px;
  background: #f8fafc;
  text-align: center;
}
.mfd-sh span { display: block; font-size: 10px; font-weight: 700; color: #7a8794; letter-spacing: .04em; }
.mfd-sh strong { display: block; margin-top: 3px; font-size: 14px; color: #1b3a5b; }
.mfd-na { color: #b6c0ca; }
.mfd-sh-click { cursor: pointer; transition: border-color .12s, background .12s; }
.mfd-sh-click:hover { border-color: rgba(37,99,235,.45); background: #eef4ff; }
.mfd-do-detail {
  margin-top: 6px;
  border: 1px solid rgba(37,99,235,.22);
  border-radius: 8px;
  padding: 8px 10px;
  background: #f5f9ff;
}
.mfd-do-hd { font-size: 10px; font-weight: 700; color: #7a8794; letter-spacing: .04em; text-transform: uppercase; margin-bottom: 4px; }
.mfd-do-row { display: flex; justify-content: space-between; align-items: baseline; font-size: 12px; padding: 2px 0; }
.mfd-do-k { color: #5b6b7a; }
.mfd-do-v { font-weight: 700; color: #1b3a5b; font-variant-numeric: tabular-nums; }
.mfd-do-total { margin-top: 3px; padding-top: 5px; border-top: 1px dashed rgba(15,44,74,.18); }
.mfd-do-total .mfd-do-v { color: #b4530a; }
.mfd-spark { margin-top: 6px; border: 1px solid rgba(15,44,74,.08); border-radius: 8px; padding: 4px 6px; background: #f8fafc; }

/* "This shift so far" breakdown bar (machine drawer) */
.mfd-shiftbar { display: flex; margin-top: 6px; height: 16px; border-radius: 6px; overflow: hidden; background: #eef2f6; box-shadow: inset 0 0 0 1px rgba(15,44,74,.08); }
.mfd-sb-seg { height: 100%; }
.mfd-sb-seg.run  { background: #30a46c; }
.mfd-sb-seg.cmm  { background: #7aa7ef; }
.mfd-sb-seg.dead { background: #dcb6b8; }
.mfd-sb-seg.backlog { background: #e8b34d; }
.mfd-sb-seg.rem  { background: transparent; }
.mfd-sb-legend { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 5px; font-size: 11px; color: #5b6b7a; }
.mfd-sb-k { display: inline-flex; align-items: center; gap: 4px; font-variant-numeric: tabular-nums; }
.mfd-sb-d { width: 9px; height: 9px; border-radius: 2px; display: inline-block; }
.mfd-sb-d.run  { background: #30a46c; }
.mfd-sb-d.cmm  { background: #7aa7ef; }
.mfd-sb-d.dead { background: #dcb6b8; }
.mfd-sb-d.backlog { background: #e8b34d; }

/* Three-shift activity stack (machine drawer) — one .mfd-shiftrow per shift. */
.mfd-shiftrow { margin-top: 10px; }
.mfd-shiftrow:first-of-type { margin-top: 6px; }
.mfd-shiftrow-lbl { font-size: 11px; font-weight: 700; color: #1b3a5b; letter-spacing: .02em; }
.mfd-shiftrow-lbl .mfd-muted { font-weight: 400; }
.mfd-shiftbar-empty { background: repeating-linear-gradient(45deg, #eef2f6, #eef2f6 6px, #e3e8ee 6px, #e3e8ee 12px); }

/* Machine drawer — Operators (who runs this machine, per shift) */
.mfd-op-rows { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.mfd-op-row {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 8px; border: 1px solid rgba(15,44,74,.08); border-radius: 6px; background: #f8fafc;
  font-size: 12.5px;
}
.mfd-op-row { flex-wrap: wrap; }
.mfd-op-shift { width: 30px; flex: none; font-weight: 700; color: #7a8794; font-size: 11px; }
.mfd-op-display { flex: 1; color: #1b3a5b; }
.mfd-op-people { flex: 1; display: flex; flex-wrap: wrap; gap: 4px; align-items: center; color: #1b3a5b; }
.mfd-op-faint { color: #94a3b8; font-size: 11px; }
.mfd-op-chip {
  display: inline-flex; align-items: center; gap: 3px;
  background: #eef3f8; border: 1px solid #d3deea; border-radius: 10px;
  padding: 1px 4px 1px 8px; font-size: 12px; color: #1b3a5b;
}
.mfd-op-remove {
  background: transparent; border: 0; cursor: pointer; color: #94a3b8;
  font-size: 14px; line-height: 1; padding: 0 2px;
}
.mfd-op-remove:hover { color: #b3261e; }
.mfd-op-input, .mfd-op-select, .mfd-op-add-select {
  flex: 1; padding: 3px 6px; border: 1px solid #c7d2e0; border-radius: 4px; font-size: 12px;
  background: #fff; color: #1b3a5b; max-width: 100%;
}
.mfd-op-edit, .mfd-op-add {
  flex: none; background: transparent; border: 0; cursor: pointer; color: #7a8794; font-size: 12px; padding: 2px 4px;
}
.mfd-op-edit:hover, .mfd-op-add:hover { color: #1b3a5b; }

/* ===== Machines tab: CMM + trend cards (below the floor map) ===== */
.cmm-card { margin-top: 16px; }
.cmm-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.cmm-age { color: #94a3b8; font-style: italic; }
.cmm-collapse {
  flex: none; width: 26px; height: 26px; border-radius: 7px; border: 1px solid rgba(15,44,74,.12);
  background: #f8fafc; color: #50606f; font-size: 16px; line-height: 1; cursor: pointer;
}
.cmm-collapse:hover { background: #eef2f6; }
.cmm-empty { padding: 14px; font-size: 12px; color: #7a8794; font-style: italic; }
.cmm-empty.cmm-empty-err { color: #b91c1c; font-style: normal; }

.cmm-totals { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 14px; }
.cmm-stat { border: 1px solid rgba(15,44,74,.08); border-radius: 10px; padding: 10px 12px; background: #f8fafc; }
.cmm-stat span { display: block; font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: #7a8794; }
.cmm-stat strong { display: block; margin-top: 4px; font-size: 20px; color: #1b3a5b; }
.cmm-stat.warn { background: #fff7ed; border-color: #f5cda0; }
.cmm-stat.warn strong { color: #b45309; }

.cmm-2col { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 14px; }
@media (max-width: 900px) { .cmm-2col { grid-template-columns: 1fr; } .cmm-totals { grid-template-columns: repeat(2, 1fr); } }
.cmm-panel { border: 1px solid rgba(15,44,74,.08); border-radius: 10px; padding: 12px; background: #fff; }
.cmm-panel-head { font-size: 12px; font-weight: 700; color: #1b3a5b; margin-bottom: 8px; display: flex; align-items: center; gap: 8px; }
.cmm-panel-n { background: #e6eef7; color: #1b3a5b; border-radius: 20px; padding: 1px 9px; font-size: 11px; }
.cmm-panel-sub { font-weight: 400; font-size: 10px; color: #94a3b8; margin-left: auto; }
.cmm-showall { margin-left: auto; border: none; background: none; color: #0b63ce; font-size: 11px; font-weight: 600; cursor: pointer; }

/* CMM Runtime — compact 3-tile room-utilization panel */
.cmm-rt-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.cmm-rt-tile {
  border: 1px solid rgba(15,44,74,.08); border-radius: 8px; padding: 8px 10px;
  background: #fbfdff; text-align: center; cursor: pointer; transition: background .12s, border-color .12s;
}
.cmm-rt-tile:hover { background: #eef4ff; border-color: #cdddf7; }
.cmm-rt-tile.open { background: #e7f0ff; border-color: #93b4e8; box-shadow: inset 0 0 0 1px #93b4e8; }
.cmm-rt-tile.open .mach-rt-caret { transform: rotate(180deg); }
.cmm-rt-tile:focus-visible { outline: 2px solid rgba(37, 99, 235, .5); outline-offset: 2px; }
.cmm-rt-label { font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: #94a3b8; }
.cmm-rt-value { font-size: 20px; font-weight: 700; color: #1b3a5b; font-variant-numeric: tabular-nums; margin: 2px 0; }
.cmm-rt-value.amber { color: #9a6b1a; }
.cmm-rt-value-cap { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: #94a3b8; margin-bottom: 4px; }
.cmm-rt-value-cap.amber { color: #b8860b; }
.cmm-rt-shifts { font-size: 10px; color: #64748b; }
/* Machine-vs-manual split under the by-shift row. Empty when no real manual check
   landed in the window, so :empty collapses the margin instead of leaving a gap.
   Two block lines rather than one ragged wrap — the tile is ~140px wide. */
.cmm-rt-split { font-size: 10px; color: #8a6d1f; margin-top: 4px; line-height: 1.25; }
.cmm-rt-split:empty { display: none; }
.cmm-rt-split-t { display: block; font-weight: 600; }
.cmm-rt-split-s { display: block; color: #a08a52; }
.cmm-rt-manual-row { color: #8a6d1f; }
.cmm-rt-dropdown { margin-top: 8px; padding-top: 8px; border-top: 1px dashed rgba(15,44,74,.12); text-align: left; }
.cmm-rt-dropdown[hidden] { display: none; }
.cmm-rt-why { font-size: 10px; color: #94a3b8; margin: 2px 0 8px; }
.cmm-thr-slow { color: #c0392b; font-weight: 700; }
.cmm-thr-fast { color: #1f8a4c; font-weight: 700; }
@media (max-width: 480px) { .cmm-rt-row { grid-template-columns: 1fr; } }

/* CMM Runtime — 7-day / 30-day utilization trend charts */
.cmm-rt-trends { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 12px; padding-top: 10px; border-top: 1px solid rgba(15,44,74,.08); }
@media (max-width: 560px) { .cmm-rt-trends { grid-template-columns: 1fr; } }
.cmm-rt-trend-head { font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: #94a3b8; margin-bottom: 4px; }
.cmm-rt-trend-range { display: flex; justify-content: space-between; font-size: 9px; color: #94a3b8; margin-top: 2px; }

/* Interactive trend chart — hover crosshair + snap-to-point tooltip */
.cmm-tc-wrap { position: relative; }
.cmm-tc-svg { width: 100%; height: 90px; display: block; cursor: crosshair; }
.cmm-tc-grid { stroke: #eef2f6; stroke-width: 1; }
.cmm-tc-ytick { font-size: 7px; fill: #b6c0cc; }
.cmm-tc-axislabel { font-size: 7px; fill: #94a3b8; letter-spacing: .03em; }
.cmm-tc-fill { fill: rgba(122, 167, 239, .18); stroke: none; }
.cmm-tc-line { fill: none; stroke: #4c8bef; stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; }
.cmm-tc-crosshair { stroke: #94a3b8; stroke-width: 1; stroke-dasharray: 2,2; }
.cmm-tc-dot { fill: #1b3a5b; stroke: #fff; stroke-width: 1.2; }
.cmm-tc-tooltip {
  position: absolute; top: 2px; transform: translateX(-50%);
  background: #1b3a5b; color: #fff; font-size: 10px; font-weight: 600;
  padding: 3px 7px; border-radius: 5px; white-space: nowrap; pointer-events: none;
  box-shadow: 0 2px 6px rgba(15,44,74,.25);
}

/* live queue */
.cmm-queue { display: flex; flex-direction: column; gap: 5px; max-height: 360px; overflow-y: auto; }
.cmm-q-row {
  display: grid; grid-template-columns: 52px 1fr auto auto; align-items: center; gap: 8px;
  width: 100%; text-align: left; border: 1px solid rgba(15,44,74,.07); border-radius: 8px;
  padding: 7px 9px; background: #f8fafc; cursor: pointer; font-size: 12px;
}
.cmm-q-row:hover { background: #eef4fb; border-color: #b9cde2; }
.cmm-q-unmapped { opacity: .62; cursor: default; }
.cmm-q-mach { font-weight: 800; color: #1b3a5b; }
.cmm-q-mid { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.cmm-q-part { font-weight: 600; color: #334155; }
.cmm-q-op { font-size: 10px; color: #94a3b8; }
.cmm-q-right { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }
.cmm-q-time { font-size: 10px; color: #7a8794; }
.cmm-ready { font-size: 10px; font-weight: 700; color: #b45309; }
.cmm-runlong { font-size: 10px; font-weight: 700; color: #b5473b; }
/* progress readout — sits in its own column in the middle band of the row so
   it's readable without hiding in the tiny right-hand stack, but kept as plain
   colored text (no filled chip) so it stays subtle */
.cmm-progress {
  justify-self: end; font-variant-numeric: tabular-nums; white-space: nowrap;
  font-size: 12px; font-weight: 600; color: #3f7355; letter-spacing: .2px;
}
.cmm-progress strong { font-weight: 700; }
.cmm-progress-sep { opacity: .45; margin: 0 1px; }
.cmm-progress.over { color: #b5473b; }
.cmm-progress-empty { display: block; }
.cmm-badge { font-size: 10px; font-weight: 700; border-radius: 5px; padding: 1px 7px; }
.cmm-badge.st-staged { background: #eef2f6; color: #50606f; }
.cmm-badge.st-prog { background: #d7f0e3; color: #14532d; }
.cmm-badge.st-ready { background: #dbeafe; color: #1e40af; }
.cmm-badge.st-done { background: #fdeccb; color: #7a4f06; }
.cmm-badge.st-closed { background: #e6eef7; color: #1b3a5b; }

/* trends */
.cmm-trend-row { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.cmm-trend-label { flex: none; width: 86px; font-size: 11px; color: #7a8794; font-weight: 600; }
.cmm-trend-label strong { display: block; font-size: 16px; color: #1b3a5b; }
.cmm-spark { flex: 1; min-width: 0; }
.cmm-trend-axis { display: flex; justify-content: space-between; font-size: 10px; color: #b6c0ca; margin-top: 2px; }

/* by-machine table */
.cmm-table-wrap { overflow-x: auto; }
.cmm-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.cmm-table th { text-align: left; font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: #7a8794; padding: 6px 10px; border-bottom: 1px solid rgba(15,44,74,.1); }
.cmm-table td { padding: 7px 10px; border-bottom: 1px solid rgba(15,44,74,.05); color: #334155; }
.cmm-table tr[data-mach] { cursor: pointer; }
.cmm-table tr[data-mach]:hover td { background: #eef4fb; }
.cmm-t-mach { font-weight: 800; color: #1b3a5b; }
.cmm-t-bad { color: #b91c1c; font-weight: 700; }
.cmm-atcmm { background: #d7f0e3; color: #14532d; border-radius: 5px; padding: 1px 7px; font-weight: 700; }

/* worst-pickup-wait strip — folded into the By Machine panel, top 5 as compact chips */
.cmm-off-strip-row { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.cmm-off-strip-label { font-size: 10px; font-weight: 700; color: #94a3b8; text-transform: uppercase; letter-spacing: .04em; white-space: nowrap; }
.cmm-off-shift {
  border: 1px solid rgba(15,44,74,.18); border-radius: 6px;
  padding: 3px 8px; font-size: 11px; font-weight: 600; color: #1b3a5b; background: #fff; cursor: pointer;
}
.cmm-off-strip { display: flex; flex-wrap: wrap; gap: 6px; }
.cmm-off-chip {
  display: inline-flex; align-items: center; gap: 5px; border: 1px solid rgba(185,28,28,.18);
  border-radius: 20px; padding: 3px 10px 3px 6px; background: #fef6f5; cursor: pointer;
  font-size: 11px; font-weight: 700; color: #1b3a5b;
}
.cmm-off-chip:hover { background: #fdeceb; border-color: rgba(185,28,28,.32); }
.cmm-off-chip strong { color: #b91c1c; }
.cmm-off-chip-rank {
  display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px;
  border-radius: 50%; background: #b45309; color: #fff; font-size: 9px; font-weight: 800;
}
.cmm-off-empty { font-size: 11px; color: #94a3b8; }

/* part CMM-time lookup — compact, sits in the trend card */
.cmm-partlookup { margin-top: 12px; padding-top: 10px; border-top: 1px dashed rgba(15,44,74,.12); }
.cmm-part-search {
  width: 100%; box-sizing: border-box; border: 1px solid rgba(15,44,74,.18); border-radius: 6px;
  padding: 5px 9px; font-size: 12px; color: #1b3a5b; background: #fff;
}
.cmm-part-results { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.cmm-part-none { font-size: 11px; color: #94a3b8; font-style: italic; padding: 2px; }
.cmm-part-row {
  display: grid; grid-template-columns: auto auto 1fr; align-items: baseline; gap: 10px;
  border: 1px solid rgba(15,44,74,.07); border-radius: 7px; padding: 6px 9px; background: #f8fafc;
}
.cmm-part-pn { font-weight: 800; color: #1b3a5b; font-size: 13px; }
.cmm-part-time { font-weight: 800; color: #0b63ce; font-size: 15px; white-space: nowrap; }
.cmm-part-time small { font-size: 9px; font-weight: 600; color: #94a3b8; margin-left: 3px; text-transform: uppercase; }
.cmm-part-meta { font-size: 10px; color: #94a3b8; text-align: right; }

/* by-machine search + drill-down detail */
.cmm-mach-search {
  width: 100%; box-sizing: border-box; border: 1px solid rgba(15,44,74,.18); border-radius: 6px;
  padding: 5px 9px; font-size: 12px; color: #1b3a5b; background: #fff; margin-bottom: 8px;
}
.cmm-table tr.cmm-t-sel td { background: #e2edfb; box-shadow: inset 2px 0 0 #0b63ce; }
.cmm-mach-detail {
  margin-top: 12px; border: 1px solid rgba(15,44,74,.12); border-radius: 9px;
  background: #fbfdff; padding: 12px;
}
.cmm-md-head { font-size: 13px; font-weight: 700; color: #1b3a5b; display: flex; align-items: center; gap: 8px; }
.cmm-md-head strong { font-size: 15px; }
.cmm-md-close { margin-left: auto; border: none; background: none; color: #7a8794; font-size: 14px; cursor: pointer; line-height: 1; padding: 2px 4px; }
.cmm-md-close:hover { color: #b91c1c; }
.cmm-md-stats { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 4px; }
.cmm-md-stat {
  display: flex; flex-direction: column; gap: 1px; background: #fff;
  border: 1px solid rgba(15,44,74,.08); border-radius: 7px; padding: 5px 10px; min-width: 84px;
}
.cmm-md-stat span { font-size: 9px; text-transform: uppercase; letter-spacing: .05em; color: #94a3b8; }
.cmm-md-stat strong { font-size: 14px; color: #1b3a5b; }
.cmm-md-sub { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: #7a8794; font-weight: 700; margin: 12px 0 4px; }
.cmm-md-active td { background: #fff7ed; }

/* "usually runs" / "dedicated to" line in the machine detail */
.cmm-md-usual { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; margin: 8px 0 2px; font-size: 13px; }
.cmm-md-usual-k { font-size: 9px; text-transform: uppercase; letter-spacing: .05em; color: #7a8794; font-weight: 700; }
.cmm-md-pn { font-weight: 800; color: #1b3a5b; }
.cmm-md-pct { font-weight: 700; color: #0b63ce; font-size: 12px; }
.cmm-md-dot { color: #cbd5e1; }

/* part → machine "cell" chips in the part lookup */
.cmm-cell { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: 5px; margin-top: 6px; }
.cmm-cell-k { font-size: 9px; text-transform: uppercase; letter-spacing: .05em; color: #94a3b8; font-weight: 700; margin-right: 2px; }
.cmm-cell-mach {
  border: 1px solid rgba(11,99,206,.25); background: #eef4fb; color: #0b63ce; border-radius: 6px;
  padding: 2px 7px; font-size: 11px; font-weight: 700; cursor: pointer; line-height: 1.4;
}
.cmm-cell-mach:hover { background: #dce9fa; }
.cmm-cell-mach small { font-weight: 600; color: #7a8794; margin-left: 3px; font-size: 9px; }

/* Lowest Runtime leaderboard */
.mwr-card { padding: 14px 16px; margin-bottom: 16px; }
.mwr-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.mwr-head-l { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.mwr-title { margin: 0; font-size: 13px; font-weight: 800; color: #1b3a5b; }
.mwr-sub { font-size: 10px; color: #94a3b8; }
.mwr-window {
  font-size: 10px; font-weight: 700; color: #64748b; letter-spacing: .02em;
  background: #eef1f5; border-radius: 999px; padding: 2px 8px; white-space: nowrap;
}
.mwr-controls { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.mwr-toggle { display: inline-flex; background: #eef1f5; border-radius: 999px; padding: 2px; gap: 1px; }
.mwr-toggle-btn {
  font-size: 10px; font-weight: 700; color: #64748b; letter-spacing: .02em;
  background: transparent; border: 0; border-radius: 999px; padding: 3px 9px;
  cursor: pointer; transition: background .12s ease, color .12s ease; white-space: nowrap;
}
.mwr-toggle-btn:hover { color: #1b3a5b; }
.mwr-toggle-btn.active { background: #fff; color: #1b3a5b; box-shadow: 0 1px 2px rgba(15,44,74,.14); }
.mwr-body { display: flex; flex-direction: column; gap: 3px; }
.mwr-item { display: flex; flex-direction: column; }
.mwr-row {
  display: grid; grid-template-columns: 20px 52px 1fr 112px 12px; align-items: center; gap: 10px;
  width: 100%; cursor: pointer; text-align: left; border: 0; border-radius: 7px;
  padding: 6px 8px; background: transparent; transition: background .12s ease;
}
.mwr-row:hover { background: #f4f7fb; }
.mwr-row:hover .mwr-chev { color: #0b63ce; }
.mwr-row.expanded { background: #f4f7fb; }
.mwr-row.expanded .mwr-chev { color: #0b63ce; transform: rotate(90deg); }
.mwr-rank { font-size: 11px; font-weight: 700; color: #b0bccb; text-align: center; font-variant-numeric: tabular-nums; }
.mwr-id { font-weight: 800; color: #1b3a5b; font-size: 12px; letter-spacing: .01em; }
.mwr-bar { height: 8px; border-radius: 999px; background: #eef1f5; overflow: hidden; }
.mwr-bar-fill { display: block; height: 100%; border-radius: 999px; min-width: 3px; transition: width .3s ease; }
/* fixed-width trailing box so the 1fr bar track is identical on every row,
   whether or not an excl badge is present */
.mwr-end { display: flex; align-items: center; justify-content: flex-end; gap: 6px; }
.mwr-pct { font-size: 12px; font-weight: 800; text-align: right; font-variant-numeric: tabular-nums; }
.mwr-excl {
  font-size: 9px; font-weight: 700; color: #94a3b8;
  background: #eef1f5; border-radius: 4px; padding: 1px 5px; white-space: nowrap;
}
.mwr-chev { color: #c3cddb; font-size: 13px; font-weight: 700; text-align: center; transition: color .12s ease, transform .12s ease; display: inline-block; }

/* Lowest Runtime row expand — per-shift breakdown, inline instead of jumping to the floor map */
.mwr-detail {
  margin: 2px 4px 8px; padding: 10px 10px 10px 42px; border-radius: 7px;
  background: #f8fafc; border: 1px solid rgba(15,44,74,.08);
  animation: mwrDetailIn .15s ease;
}
@keyframes mwrDetailIn { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: translateY(0); } }
.mwr-shift-grid { display: flex; flex-direction: column; gap: 6px; }
.mwr-shift-row { display: grid; grid-template-columns: 32px 1fr 90px; align-items: center; gap: 10px; }
.mwr-shift-name { font-size: 10px; font-weight: 700; color: #64748b; }
.mwr-shift-bar { height: 6px; border-radius: 999px; background: #eef1f5; overflow: hidden; }
.mwr-shift-bar-fill { display: block; height: 100%; border-radius: 999px; min-width: 3px; transition: width .3s ease; }
.mwr-shift-end { display: flex; align-items: center; justify-content: flex-end; gap: 6px; }
.mwr-shift-pct { font-size: 11px; font-weight: 800; text-align: right; font-variant-numeric: tabular-nums; }
.mwr-shift-empty .mwr-shift-bar-fill { opacity: .5; }
.mwr-shift-na { font-size: 10px; font-weight: 700; color: #b0bccb; }
.mwr-detail-floor-link {
  margin-top: 10px; font-size: 10px; font-weight: 700; color: #0b63ce;
  background: transparent; border: 0; padding: 0; cursor: pointer;
}
.mwr-detail-floor-link:hover { text-decoration: underline; }

/* inline empty state inside the inspector (unmapped machine) */
.mfd-empty-inline { display: flex; flex-direction: column; gap: 3px; margin-top: 8px; padding: 10px;
  background: #f8fafc; border: 1px dashed rgba(15,44,74,.15); border-radius: 8px; }
.mfd-empty-inline span:last-child { font-size: 11px; color: #64748b; line-height: 1.4; }

/* inspector: "running / last ran" part line */
.mfd-runpart { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px; margin: 4px 0 8px;
  padding: 6px 9px; background: #eef4fb; border: 1px solid rgba(11,99,206,.18); border-radius: 7px; }
.mfd-runpart-k { font-size: 9px; text-transform: uppercase; letter-spacing: .05em; color: #5b7da8; font-weight: 700; }
.mfd-runpart-pn { font-size: 15px; font-weight: 800; color: #0b63ce; }
.mfd-runpart-meta { font-size: 10px; color: #7a8794; margin-left: auto; }

/* inspector: "Planned (CNC board)" section — plan-by-machine list */
.mfd-plan-list { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.mfd-plan-row { display: flex; align-items: baseline; gap: 8px;
  padding: 6px 9px; background: #f8fafc; border: 1px solid rgba(15,44,74,.08); border-radius: 7px; }
.mfd-plan-job { font-size: 11px; font-weight: 700; color: #1b3a5b; }
.mfd-plan-pn { font-size: 12px; font-weight: 700; color: #0b63ce; flex: 1; }
.mfd-plan-when { font-size: 10px; color: #7a8794; }
.mfd-actions {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
  margin-top: 16px;
}
.mfd-act {
  border: 1px solid #cdd6e0; background: #f7f9fc; color: #1b3a5b;
  font: inherit; font-size: 12px; font-weight: 600; cursor: pointer;
  padding: 8px 12px; border-radius: 7px; transition: all .12s ease;
}
.mfd-act:hover { background: #1f6feb; color: #fff; border-color: #1f6feb; }
.mfd-act:disabled { opacity: .48; cursor: default; }
.mfd-act:disabled:hover { background: #f7f9fc; color: #1b3a5b; border-color: #cdd6e0; }
.mfd-close { position: absolute; right: 8px; bottom: 8px; border: none; background: none; cursor: pointer; color: #8a97a5; font-size: 14px; padding: 2px 6px; border-radius: 5px; }
.mfd-close:hover { background: #eef1f5; color: #1b3a5b; }

@media (max-width: 1100px) {
  .mach-floor-workbench { grid-template-columns: 1fr; }
  .mach-floor-inspector { position: static; min-height: auto; }
  .mfd-empty { min-height: 120px; }
}

@media (max-width: 880px) {
  .mach-floor-head { align-items: stretch; flex-direction: column; }
  .mach-floor-actions { justify-content: flex-start; }
  .mach-map-chips { justify-content: flex-start; }
}

.mach-card {
  position: relative;
  background: #fff;
  border: 1px solid rgba(15, 44, 74, 0.08);
  border-radius: 10px;
  padding: 16px 18px 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: transform 0.12s ease, box-shadow 0.12s ease, border-color 0.12s ease;
  overflow: hidden;
  cursor: pointer;
}
.mach-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(15, 44, 74, 0.08);
  border-color: rgba(15, 44, 74, 0.18);
}
.mach-card.expanded {
  grid-column: 1 / -1;
  cursor: default;
  transform: none;
  border-color: rgba(37, 99, 235, 0.4);
  box-shadow: 0 6px 24px rgba(37, 99, 235, 0.12);
}

/* Top stripe colored by utilization band */
.mach-card::before {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 4px;
  background: var(--mach-color, #94a3b8);
}

.mach-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  padding-top: 4px;
}
.mach-name {
  font-size: 22px;
  font-weight: 800;
  color: var(--color-primary);
  letter-spacing: -0.01em;
  line-height: 1;
}
.mach-tier-chip {
  display: inline-block; vertical-align: middle; margin-left: 8px;
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px;
  padding: 2px 7px; border-radius: 999px;
}
.mach-tier-chip.tier-base { background: #dbe9fb; color: #1b3a5b; }
.mach-tier-chip.tier-spot { background: #d7f0ea; color: #0f5b50; }
.mach-tier-chip.tier-lathe { background: #fdecd2; color: #7a4a14; }
.mach-5ax-badge {
  display: inline-block; vertical-align: middle; margin-left: 6px;
  font-size: 8px; font-weight: 800; letter-spacing: .5px;
  padding: 2px 6px; border-radius: 999px; background: #6f42c1; color: #fff;
}
.mach-card-spec {
  margin-top: 4px; font-size: 10px; font-weight: 600; letter-spacing: .3px;
  text-transform: uppercase; color: #8a97a5;
}
.mach-gap {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 6px; padding-top: 7px; border-top: 1px dashed rgba(15,44,74,.1);
  font-size: 11px; color: #8a97a5;
}
.mach-gap.gap-pos span:last-child { color: #16794a; font-weight: 700; }
.mach-gap.gap-neg span:last-child { color: #c0392b; font-weight: 700; }
/* cross-link flash when selected from the floor map */
.mach-card.linked { outline: 2px solid #1f6feb; outline-offset: 1px; box-shadow: 0 0 0 4px rgba(31,111,235,.14); }
.mach-card-sub {
  margin-top: 5px;
  color: var(--color-text-muted);
  font-size: 11px;
  line-height: 1.25;
}
.mach-util-pill {
  font-size: 11px;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--mach-color-bg, rgba(148, 163, 184, 0.15));
  color: var(--mach-color, #475569);
  font-feature-settings: "tnum";
}

.mach-bar-track {
  height: 8px;
  background: rgba(15, 44, 74, 0.08);
  border-radius: 4px;
  overflow: hidden;
  position: relative;
}
.mach-util-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  color: var(--color-text-muted);
  font-size: 11px;
  font-weight: 700;
  font-feature-settings: "tnum";
}
.mach-bar-fill {
  height: 100%;
  background: var(--mach-color, #94a3b8);
  border-radius: 4px;
  transition: width 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}

.mach-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 12px;
  font-size: 12px;
  padding-top: 4px;
}
.mach-stat-label {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}
.mach-stat-value {
  font-size: 14px;
  font-weight: 700;
  color: var(--color-primary);
  font-feature-settings: "tnum";
}
.mach-stat-value.delta-pos { color: #15803d; }
.mach-stat-value.delta-neg { color: #b91c1c; }

.mach-footer {
  display: flex; justify-content: space-between; align-items: center;
  border-top: 1px solid rgba(15, 44, 74, 0.06);
  padding-top: 8px;
  font-size: 11px;
  color: var(--color-text-muted);
}
.mach-rev {
  font-weight: 700;
  color: var(--color-primary);
  font-feature-settings: "tnum";
  font-size: 13px;
}

/* Drilldown — list of parts running on this machine */
.mach-drilldown {
  border-top: 1px solid rgba(15, 44, 74, 0.08);
  padding-top: 14px;
  margin-top: 6px;
}
.mach-drilldown h4 {
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}
.mach-parts-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12px;
}
.mach-parts-table th, .mach-parts-table td {
  padding: 6px 10px;
  text-align: left;
  border-bottom: 1px solid rgba(15, 44, 74, 0.05);
}
.mach-parts-table th {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
  background: rgba(15, 44, 74, 0.025);
}
.mach-parts-table td.num, .mach-parts-table th.num {
  text-align: right;
  font-feature-settings: "tnum";
}

@media (max-width: 720px) {
  .mach-toolbar {
    align-items: stretch;
  }
  .mach-search,
  .mach-sort,
  .mach-source {
    width: 100%;
    max-width: none;
    margin-left: 0;
  }
  .mach-sort {
    justify-content: space-between;
  }
}


/* ============================================================
   KNOWLEDGE BASE — left nav of WoT subdocs + right pane that
   renders the selected doc's markdown.
   ============================================================ */
.kb-layout {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 16px;
  align-items: flex-start;
}
@media (max-width: 900px) {
  .kb-layout { grid-template-columns: 1fr; }
}

.kb-sidebar {
  background: #fff;
  border: 1px solid rgba(15, 44, 74, 0.08);
  border-radius: 10px;
  padding: 12px;
  position: sticky;
  top: 16px;
  max-height: calc(100vh - 120px);
  overflow-y: auto;
}
.kb-search {
  width: 100%;
  padding: 8px 12px;
  margin-bottom: 8px;
  border: 1px solid rgba(15, 44, 74, 0.15);
  border-radius: 6px;
  font-size: 13px;
  font-family: inherit;
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.kb-search:focus {
  border-color: #2563eb;
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}

.kb-nav {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.kb-nav-item {
  display: block;
  padding: 9px 12px;
  border-radius: 6px;
  font-size: 13px;
  cursor: pointer;
  color: var(--color-text);
  border: 1px solid transparent;
  transition: background 0.12s, border-color 0.12s;
}
.kb-nav-item:hover {
  background: rgba(15, 44, 74, 0.04);
  border-color: rgba(15, 44, 74, 0.08);
}
.kb-nav-item.active {
  background: rgba(37, 99, 235, 0.08);
  border-color: rgba(37, 99, 235, 0.25);
  color: var(--color-primary);
  font-weight: 600;
}
.kb-nav-num {
  display: inline-block;
  width: 22px;
  font-size: 11px;
  font-weight: 700;
  color: var(--color-text-muted);
  font-feature-settings: "tnum";
}
.kb-nav-item.active .kb-nav-num { color: #2563eb; }

.kb-content {
  padding: 28px 36px;
  min-height: 400px;
  max-width: 880px;
  font-size: 14px;
  line-height: 1.65;
}
.kb-content h1 {
  font-size: 26px;
  font-weight: 800;
  color: var(--color-primary);
  margin: 0 0 16px;
  padding-bottom: 12px;
  border-bottom: 2px solid rgba(15, 44, 74, 0.08);
  letter-spacing: -0.01em;
}
.kb-content h2 {
  font-size: 18px;
  font-weight: 700;
  color: var(--color-primary);
  margin: 28px 0 10px;
  letter-spacing: -0.005em;
}
.kb-content h3 {
  font-size: 15px;
  font-weight: 700;
  color: var(--color-primary);
  margin: 20px 0 8px;
}
.kb-content p {
  margin: 10px 0;
  color: var(--color-text);
}
.kb-content ul, .kb-content ol {
  margin: 10px 0;
  padding-left: 24px;
}
.kb-content li {
  margin: 4px 0;
}
.kb-content code {
  background: rgba(15, 44, 74, 0.06);
  padding: 1px 6px;
  border-radius: 3px;
  font-size: 12.5px;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  color: #1e3a8a;
}
.kb-content pre {
  background: rgba(15, 44, 74, 0.04);
  padding: 12px 16px;
  border-radius: 6px;
  overflow-x: auto;
  font-size: 12px;
  line-height: 1.5;
  border: 1px solid rgba(15, 44, 74, 0.08);
}
.kb-content pre code {
  background: transparent;
  padding: 0;
  color: var(--color-text);
}
.kb-content blockquote {
  border-left: 3px solid rgba(37, 99, 235, 0.4);
  padding: 6px 14px;
  margin: 12px 0;
  background: rgba(37, 99, 235, 0.04);
  color: var(--color-text);
  font-style: italic;
}
.kb-content table {
  width: 100%;
  border-collapse: collapse;
  margin: 14px 0;
  font-size: 12.5px;
}
.kb-content table th, .kb-content table td {
  padding: 8px 12px;
  text-align: left;
  border-bottom: 1px solid rgba(15, 44, 74, 0.08);
}
.kb-content table th {
  background: rgba(15, 44, 74, 0.03);
  font-weight: 700;
  color: var(--color-primary);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.kb-content a {
  color: #2563eb;
  text-decoration: none;
  border-bottom: 1px solid rgba(37, 99, 235, 0.3);
}
.kb-content a:hover {
  border-bottom-color: #2563eb;
}
.kb-content hr {
  border: none;
  border-top: 1px solid rgba(15, 44, 74, 0.08);
  margin: 24px 0;
}

/* ============================================================
   TOOLING COMMAND CENTER
   Tool-crib UI: KPI health bar, sub-tabs (Catalog / Reorder Queue /
   Speed-Feed History), global detail + cart drawers. Scoped loosely
   with `.tl-` / `.tc-` prefixes to avoid bleed into other views.
   Reuses the .qh-table pattern for dense tables (sticky uppercase
   headers, tnum numeric cols, hover rows) per design-system rule.
   ============================================================ */

[data-view="tooling"] .page-header { margin-bottom: 16px; }

/* ---- Header cart button ---- */
.tc-cartbtn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--prism-panel);
  border: 1px solid var(--prism-line-strong);
  border-radius: var(--prism-radius-sm);
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 700;
  font-family: inherit;
  color: var(--prism-ink);
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.tc-cartbtn:hover { background: var(--prism-panel-muted); border-color: #9eadbd; }
.tc-cartbtn:focus-visible { outline: 2px solid var(--prism-blue); outline-offset: 2px; }
.tc-cartbtn .tc-cc {
  background: var(--prism-blue);
  color: #fff;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 800;
  min-width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 6px;
  font-feature-settings: "tnum";
}
.tc-headrow {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

/* ---- KPI health bar ---- */
.tc-kpis {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 10px;
  margin-bottom: 18px;
}
.tc-kpi {
  background: var(--prism-panel);
  border: 1px solid var(--prism-line);
  border-radius: var(--prism-radius-md);
  padding: 12px 14px;
  box-shadow: 0 1px 2px rgba(15, 44, 74, 0.04);
  cursor: pointer;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
  position: relative;
  overflow: hidden;
  text-align: left;
  font-family: inherit;
}
.tc-kpi:hover { border-color: var(--prism-line-strong); box-shadow: var(--prism-shadow-panel); }
.tc-kpi:focus-visible { outline: 2px solid var(--prism-blue); outline-offset: 2px; }
.tc-kpi.on { border-color: var(--prism-blue); box-shadow: 0 0 0 2px var(--prism-blue-soft); }
.tc-kpi .tc-kl {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--prism-ink-soft);
}
.tc-kpi .tc-kv {
  font-family: 'Fira Code', ui-monospace, monospace;
  font-size: 26px;
  font-weight: 800;
  margin-top: 4px;
  letter-spacing: -0.01em;
  color: var(--prism-ink);
}
.tc-kpi.crit .tc-kv { color: var(--prism-red); }
.tc-kpi.warn .tc-kv { color: var(--prism-amber); }
.tc-kpi::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: transparent;
}
.tc-kpi.crit::before { background: var(--prism-red); }
.tc-kpi.warn::before { background: var(--prism-amber); }
@media (max-width: 1100px) { .tc-kpis { grid-template-columns: repeat(3, 1fr); } }

/* ---- Sub-tabs ---- */
.tc-subtabs {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--prism-line);
  margin-bottom: 18px;
}
.tc-subtab {
  appearance: none;
  background: none;
  border: none;
  cursor: pointer;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--prism-ink-soft);
  padding: 10px 16px;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  display: inline-flex;
  align-items: center;
  gap: 7px;
}
.tc-subtab:hover { color: var(--prism-ink); }
.tc-subtab:focus-visible { outline: 2px solid var(--prism-blue); outline-offset: 2px; }
.tc-subtab.on { color: var(--prism-blue); border-bottom-color: var(--prism-blue); }
.tc-subtab .tc-badge {
  font-size: 11px;
  font-weight: 800;
  padding: 1px 7px;
  border-radius: 20px;
  background: var(--prism-panel-subtle);
  color: var(--prism-ink-muted);
  font-family: 'Fira Code', ui-monospace, monospace;
}
.tc-subtab.on .tc-badge { background: var(--prism-blue-soft); color: var(--prism-blue); }
.tc-subtab .tc-badge.crit { background: var(--prism-red-soft); color: var(--prism-red); }

.tc-panel[hidden] { display: none; }

/* ---- Shared card/table chrome ---- */
.tc-card {
  background: var(--prism-panel);
  border: 1px solid var(--prism-line);
  border-radius: var(--prism-radius-md);
  box-shadow: 0 1px 2px rgba(15, 44, 74, 0.04);
}
.tc-tbl-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 14px;
  border-bottom: 1px solid var(--prism-line);
  gap: 12px;
  flex-wrap: wrap;
}
.tc-tbl-top .tc-note { font-size: 12px; color: var(--prism-ink-soft); }
.tc-search { position: relative; flex: 1; max-width: 360px; }
.tc-search input {
  width: 100%;
  border: 1px solid var(--prism-line-strong);
  border-radius: var(--prism-radius-sm);
  padding: 7px 12px;
  font-size: 13px;
  font-family: inherit;
  color: var(--prism-ink);
  min-height: 34px;
}
.tc-search input:focus {
  outline: none;
  border-color: var(--prism-blue);
  box-shadow: 0 0 0 3px rgba(31, 111, 196, 0.15);
}
/* ---- Catalog facet/sort filter bar ---- */
.tc-catfilter { margin-bottom: 14px; }
.tc-facetrow {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  padding: 10px 14px;
  border-top: 1px solid var(--prism-line);
}
.tc-facet { display: flex; flex-direction: column; gap: 3px; }
.tc-facet label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--prism-ink-soft);
}
.tc-facet select {
  border: 1px solid var(--prism-line-strong);
  border-radius: var(--prism-radius-sm);
  padding: 6px 9px;
  font-size: 12.5px;
  font-family: inherit;
  color: var(--prism-ink);
  background: var(--prism-panel);
  min-width: 118px;
  min-height: 32px;
}
.tc-facet select:focus-visible {
  outline: none;
  border-color: var(--prism-blue);
  box-shadow: 0 0 0 3px rgba(31, 111, 196, 0.15);
}
.tc-facet-size { min-width: 0; }
.tc-sizerange { display: flex; align-items: center; gap: 5px; color: var(--prism-ink-soft); font-size: 12px; }
.tc-sizerange input[type="number"] {
  width: 58px;
  border: 1px solid var(--prism-line-strong);
  border-radius: var(--prism-radius-sm);
  padding: 6px 7px;
  font-size: 12.5px;
  font-family: 'Fira Code', ui-monospace, monospace;
  color: var(--prism-ink);
  background: var(--prism-panel);
  min-height: 32px;
}
.tc-sizerange input[type="number"]:focus-visible {
  outline: none;
  border-color: var(--prism-blue);
  box-shadow: 0 0 0 3px rgba(31, 111, 196, 0.15);
}

.tc-chiprow {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  padding: 0 14px 12px;
}
/* Guard — see .qh-pagination[hidden] above. tcRenderFilterChips() hides this row
   when no filters are active (app.js:12170); without it the empty row kept its
   12px bottom padding under the toolbar permanently. */
.tc-chiprow[hidden] { display: none; }
.tc-fchip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 700;
  padding: 3px 6px 3px 10px;
  border-radius: 999px;
  background: var(--prism-blue-soft);
  color: var(--prism-blue);
  border: 1px solid var(--prism-blue-line);
  cursor: pointer;
  font-family: inherit;
}
.tc-fchip:hover { background: var(--prism-blue); color: #fff; border-color: var(--prism-blue); }
.tc-fchip:focus-visible { outline: 2px solid var(--prism-blue); outline-offset: 2px; }
.tc-fchip .tc-fchip-x { font-size: 13px; line-height: 1; }
.tc-fchip-clear {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--prism-ink-soft);
  background: none;
  border: none;
  cursor: pointer;
  font-family: inherit;
  padding: 3px 4px;
  text-decoration: underline;
}
.tc-fchip-clear:hover { color: var(--prism-ink); }
.tc-fchip-clear:focus-visible { outline: 2px solid var(--prism-blue); outline-offset: 2px; }

.tc-sfnote {
  padding: 12px 16px;
  background: var(--prism-blue-soft);
  border: 1px solid var(--prism-blue-line);
  border-radius: var(--prism-radius-md);
  font-size: 12.5px;
  color: var(--prism-blue);
  margin-bottom: 14px;
  font-weight: 600;
}
.tc-empty, .tc-error, .tc-skeleton-note {
  padding: 40px 24px;
  text-align: center;
  color: var(--prism-ink-soft);
  font-size: 13px;
}
.tc-error {
  color: var(--prism-red);
  background: var(--prism-red-soft);
  border-radius: var(--prism-radius-md);
  margin: 14px;
  padding: 16px;
  text-align: left;
}

/* ---- Skeleton loading ---- */
.tc-skel-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
.tc-skel-card {
  height: 118px;
  border-radius: var(--prism-radius-md);
  background: linear-gradient(90deg, var(--prism-panel-subtle) 25%, var(--prism-panel-muted) 37%, var(--prism-panel-subtle) 63%);
  background-size: 400% 100%;
  animation: tc-shimmer 1.4s ease infinite;
}
@keyframes tc-shimmer {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}
@media (prefers-reduced-motion: reduce) {
  .tc-skel-card { animation: none; opacity: 0.6; }
}

/* ---- Status stripe / dot — 5-state model (verbatim from stockState) ---- */
.tc-st { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; font-size: 11px; white-space: nowrap; }
.tc-st .tc-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.tc-st.st-out    { color: var(--prism-red); }    .tc-st.st-out .tc-dot    { background: var(--prism-red); }
.tc-st.st-reorder{ color: var(--prism-red); }    .tc-st.st-reorder .tc-dot{ background: var(--prism-red); }
.tc-st.st-low    { color: var(--prism-amber); }  .tc-st.st-low .tc-dot    { background: var(--prism-amber); }
.tc-st.st-ok     { color: var(--prism-green); }  .tc-st.st-ok .tc-dot     { background: var(--prism-green); }
.tc-st.st-unknown{ color: var(--prism-ink-soft);}.tc-st.st-unknown .tc-dot{ background: var(--prism-ink-soft); }

/* On-Order pill overrides the red visual per spec — an out-but-on-order
   tool shouldn't scream red. */
.tc-onorder-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10.5px;
  font-weight: 800;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--prism-blue-soft);
  color: var(--prism-blue);
  border: 1px solid var(--prism-blue-line);
  white-space: nowrap;
}
/* Overdue, or never given a due date (TL-2): an on-order tool is out of Order
   Now, so a delivery nobody received must not sit there looking routine. */
.tc-onorder-pill.tc-onorder-warn {
  background: var(--prism-amber-soft);
  color: var(--prism-amber);
  border-color: var(--prism-amber-line);
}
/* A freshness caveat in the Tooling header: no pull ever recorded (TL-2), or
   the supplier share unreachable (TL-4). */
.tc-fresh-warn {
  display: inline-block;
  margin-left: 6px;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 600;
  background: var(--prism-amber-soft);
  color: var(--prism-amber);
  border: 1px solid var(--prism-amber-line);
}

/* Table row stripe (reorder queue) */
.qh-table tr.tc-row-out     td.tc-stripe { border-left: 3px solid var(--prism-red); }
.qh-table tr.tc-row-reorder td.tc-stripe { border-left: 3px solid var(--prism-red); }
.qh-table tr.tc-row-low     td.tc-stripe { border-left: 3px solid var(--prism-amber); }
.qh-table tr.tc-row-ok      td.tc-stripe { border-left: 3px solid var(--prism-green); }
.qh-table tr.tc-row-unknown td.tc-stripe { border-left: 3px solid var(--prism-ink-soft); }
.qh-table td.tc-stripe { padding-left: 9px; }
.qh-table tr.tc-row-onorder td.tc-stripe { border-left-color: var(--prism-blue-line); }

.qh-table .tc-suggest { font-weight: 800; color: var(--prism-blue); font-family: 'Fira Code', ui-monospace, monospace; }
.qh-table .tc-needs { font-size: 11px; color: var(--prism-amber); font-weight: 700; }
.qh-table .tc-missing { color: var(--prism-ink-soft); font-style: italic; font-size: 11.5px; }
.qh-table .tc-tid { font-weight: 800; font-size: 13px; font-family: 'Fira Code', ui-monospace, monospace; }
.qh-table .tc-desc-cell { color: var(--prism-ink-muted); max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
.qh-table tbody tr.tc-clickrow { cursor: pointer; }
.qh-table tbody tr.tc-clickrow:focus-visible { outline: 2px solid var(--prism-blue); outline-offset: -2px; }

.tc-add {
  appearance: none;
  border: 1px solid var(--prism-blue-line);
  background: var(--prism-blue-soft);
  color: var(--prism-blue);
  border-radius: var(--prism-radius-sm);
  font-size: 11px;
  font-weight: 800;
  padding: 4px 9px;
  cursor: pointer;
  font-family: inherit;
  white-space: nowrap;
}
.tc-add:hover { background: var(--prism-blue); color: #fff; border-color: var(--prism-blue); }
.tc-add:focus-visible { outline: 2px solid var(--prism-blue); outline-offset: 2px; }
.tc-add.in { background: var(--prism-green-soft); border-color: var(--prism-green-line); color: var(--prism-green); }
.tc-add:disabled { opacity: 0.6; cursor: default; }

/* ---- print thumbnail ---- */
.tc-thumb { border: 1px solid var(--prism-line); border-radius: var(--prism-radius-sm); background: #fbfdff; display: block; object-fit: contain; }
.tc-thumb.sm { width: 44px; height: 34px; }
.tc-thumb.lg { width: 100%; height: 190px; object-fit: contain; background: var(--prism-panel-subtle); }
.tc-thumb-none {
  display: flex; align-items: center; justify-content: center;
  color: var(--prism-ink-soft); font-size: 10px; font-style: italic;
  background: var(--prism-panel-subtle);
  border: 1px solid var(--prism-line); border-radius: var(--prism-radius-sm);
}
.tc-thumb-none.sm { width: 44px; height: 34px; }
.tc-thumb-none.lg { width: 100%; height: 190px; font-size: 12px; }

/* ---- Catalog cards ---- */
.tc-catgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(226px, 1fr)); gap: 10px; }
.tc-catcard {
  background: var(--prism-panel);
  border: 1px solid var(--prism-line);
  border-radius: var(--prism-radius-md);
  padding: 11px 12px;
  cursor: pointer;
  border-left: 3px solid var(--prism-line);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
  text-align: left;
  font-family: inherit;
  display: block;
  width: 100%;
}
.tc-catcard:hover { box-shadow: var(--prism-shadow-panel); border-color: var(--prism-line-strong); }
.tc-catcard:focus-visible { outline: 2px solid var(--prism-blue); outline-offset: 2px; }
.tc-catcard.st-out, .tc-catcard.st-reorder { border-left-color: var(--prism-red); }
.tc-catcard.st-low { border-left-color: var(--prism-amber); }
.tc-catcard.st-ok { border-left-color: var(--prism-green); }
.tc-catcard.st-unknown { border-left-color: var(--prism-ink-soft); }
.tc-catcard.st-onorder { border-left-color: var(--prism-blue-line); }
.tc-cc-row { display: flex; gap: 10px; }
.tc-cc-body { flex: 1; min-width: 0; }
.tc-cc-top { display: flex; justify-content: space-between; align-items: center; gap: 6px; }
.tc-cc-top .tc-tid { font-family: 'Fira Code', ui-monospace, monospace; font-weight: 800; font-size: 13px; color: var(--prism-ink); }
.tc-cc-desc { font-size: 11.5px; color: var(--prism-ink-muted); margin: 5px 0; height: 30px; overflow: hidden; }
.tc-cc-meta { display: flex; justify-content: space-between; font-size: 11px; color: var(--prism-ink-soft); font-family: 'Fira Code', ui-monospace, monospace; }
.tc-cc-sf {
  margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--prism-line);
  font-size: 11px; color: var(--prism-ink-soft);
  display: flex; justify-content: space-between; font-family: 'Fira Code', ui-monospace, monospace;
}
.tc-cc-sf .tc-missing { font-family: inherit; }

.tc-chip {
  font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: var(--prism-radius-sm);
  background: var(--prism-panel-subtle); color: var(--prism-ink-muted);
  font-family: 'Fira Code', ui-monospace, monospace;
}
.tc-chip-row { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 4px; }

/* Clickable feed chips — selecting one reveals that feed's step-over/step-down */
.tc-feedchip {
  cursor: pointer; border: 1px solid transparent;
  font-family: 'Fira Code', ui-monospace, monospace;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}
.tc-feedchip:hover { border-color: var(--prism-blue-line); }
.tc-feedchip.active { background: var(--prism-blue-soft); color: var(--prism-blue); border-color: var(--prism-blue-line); }
.tc-feedchip:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(31, 111, 196, 0.2); }
.tc-feedstep {
  margin-top: 6px; font-size: 11.5px; color: var(--prism-ink-muted);
  display: flex; gap: 16px; align-items: baseline; min-height: 16px;
}
.tc-feedstep .tc-k { font-size: 10.5px; color: var(--prism-ink-soft); font-weight: 600; margin-right: 4px; }
.tc-feedstep .tc-v { font-family: 'Fira Code', ui-monospace, monospace; font-weight: 700; color: var(--prism-ink); }
.tc-feedstep .tc-hint { color: var(--prism-ink-soft); font-style: italic; }

/* ---- Drawers (detail + cart share the scrim; only one open) ---- */
.tc-scrim {
  position: fixed; inset: 0; background: rgba(15, 44, 74, 0.28);
  opacity: 0; pointer-events: none; transition: opacity 0.2s ease; z-index: 2000;
}
.tc-scrim.on { opacity: 1; pointer-events: auto; }
@media (prefers-reduced-motion: reduce) { .tc-scrim { transition: none; } }

.tc-drawer {
  position: fixed; top: 0; right: 0; bottom: 0;
  background: var(--prism-panel);
  box-shadow: -8px 0 30px rgba(15, 44, 74, 0.18);
  transform: translateX(100%);
  transition: transform 0.22s ease;
  z-index: 2001;
  display: flex;
  flex-direction: column;
}
.tc-drawer.on { transform: none; }
/* Guard — see .qh-pagination[hidden] above. These drawers were never *visible*
   while closed (translateX(100%) parks them offscreen), so this one hid in plain
   sight: `hidden` was silently doing nothing, which left a closed
   role="dialog" aria-modal="true" panel in the a11y tree with every button inside
   it still Tab-focusable. Safe against the open transition — tcShowDrawer() clears
   `hidden` and forces a reflow BEFORE adding .on (app.js:12787-12803). */
.tc-drawer[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .tc-drawer { transition: none; } }
.tc-drawer-detail { width: 460px; max-width: 94vw; }
.tc-drawer-cart { width: 400px; max-width: 92vw; }
.tc-dw-head {
  padding: 15px 16px; border-bottom: 1px solid var(--prism-line);
  display: flex; justify-content: space-between; align-items: flex-start; gap: 12px;
}
.tc-dw-head h2 { font-size: 16px; font-weight: 800; margin: 0; }
.tc-dw-x {
  appearance: none; border: none; background: none; font-size: 22px;
  cursor: pointer; color: var(--prism-ink-soft); line-height: 1; padding: 2px 4px;
}
.tc-dw-x:hover { color: var(--prism-ink); }
.tc-dw-x:focus-visible { outline: 2px solid var(--prism-blue); outline-offset: 2px; border-radius: 3px; }
.tc-dw-body { flex: 1; overflow-y: auto; }

.tc-dp-id { font-size: 20px; font-weight: 800; font-family: 'Fira Code', ui-monospace, monospace; }
.tc-dp-desc { font-size: 12px; color: var(--prism-ink-muted); margin-top: 2px; }
.tc-dp-sect { padding: 13px 16px; border-bottom: 1px solid var(--prism-line); }
.tc-dp-sect:last-child { border-bottom: none; }
.tc-dp-lbl {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  color: var(--prism-ink-soft); margin-bottom: 8px; display: flex; justify-content: space-between; align-items: center;
}
.tc-dp-lbl a { color: var(--prism-blue); text-decoration: none; font-weight: 700; text-transform: none; letter-spacing: 0; font-size: 11.5px; }
.tc-dp-lbl a:hover { text-decoration: underline; }
.tc-dp-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; }
.tc-dp-f { display: flex; flex-direction: column; gap: 3px; }
.tc-dp-f .tc-k { font-size: 10.5px; color: var(--prism-ink-soft); font-weight: 600; }
.tc-dp-f .tc-v { font-size: 14px; font-weight: 700; font-family: 'Fira Code', ui-monospace, monospace; color: var(--prism-ink); }
.tc-dp-f .tc-v.tc-miss { color: var(--prism-ink-soft); font-weight: 600; font-style: italic; font-size: 12px; font-family: inherit; }
.tc-dp-f .tc-v.tc-hl { color: var(--prism-blue); }

/* Inline-editable field — click value to edit */
.tc-editf { display: flex; flex-direction: column; gap: 3px; position: relative; }
.tc-editf .tc-v {
  cursor: pointer;
  border-radius: var(--prism-radius-sm);
  padding: 2px 4px;
  margin: -2px -4px;
  transition: background 0.1s ease;
}
.tc-editf .tc-v:hover { background: var(--prism-blue-soft); }
.tc-editf .tc-v:focus-visible { outline: 2px solid var(--prism-blue); outline-offset: 1px; }
.tc-editf input {
  font-family: 'Fira Code', ui-monospace, monospace;
  font-size: 13px;
  font-weight: 700;
  padding: 4px 6px;
  border: 1px solid var(--prism-blue);
  border-radius: var(--prism-radius-sm);
  box-shadow: 0 0 0 3px rgba(31, 111, 196, 0.14);
  outline: none;
  color: var(--prism-ink);
  width: 100%;
}

.tc-acts { display: grid; grid-template-columns: 1fr 1fr; gap: 7px; }
.tc-abtn {
  appearance: none; font-family: inherit; font-size: 12px; font-weight: 700;
  border-radius: var(--prism-radius-sm); padding: 8px; cursor: pointer;
  border: 1px solid var(--prism-line-strong); background: #fff; color: var(--prism-ink);
}
.tc-abtn:hover { background: var(--prism-panel-muted); }
.tc-abtn:focus-visible { outline: 2px solid var(--prism-blue); outline-offset: 2px; }
.tc-abtn:disabled { opacity: 0.55; cursor: default; }
.tc-abtn.pri { background: var(--prism-blue); border-color: var(--prism-blue); color: #fff; }
.tc-abtn.pri:hover { background: #113f69; }
.tc-abtn.full { grid-column: 1 / -1; }

/* Inline action prompt (qty / part# / date) shown under an action button */
.tc-prompt {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding: 10px;
  background: var(--prism-panel-muted);
  border: 1px solid var(--prism-line);
  border-radius: var(--prism-radius-sm);
  margin-top: 2px;
}
.tc-prompt label { display: flex; flex-direction: column; gap: 3px; font-size: 10.5px; color: var(--prism-ink-soft); font-weight: 600; }
.tc-prompt input {
  font-family: inherit; font-size: 13px; padding: 5px 8px;
  border: 1px solid var(--prism-line-strong); border-radius: var(--prism-radius-sm);
  width: 100px;
}
.tc-prompt input:focus { outline: none; border-color: var(--prism-blue); box-shadow: 0 0 0 3px rgba(31, 111, 196, 0.14); }

.tc-sfkv { font-size: 11px; color: var(--prism-ink-soft); margin: 8px 0 3px; font-weight: 600; }

.tc-toast {
  font-size: 11.5px;
  font-weight: 700;
  padding: 2px 0;
}
.tc-toast.ok { color: var(--prism-green); }
.tc-toast.err { color: var(--prism-red); }
.tc-toast.busy { color: var(--prism-ink-soft); font-weight: 600; }

/* ---- Cart drawer ---- */
.tc-dw-item {
  display: flex; justify-content: space-between; align-items: center;
  padding: 11px 16px; border-bottom: 1px solid rgba(15, 44, 74, 0.05);
  gap: 10px;
}
.tc-dw-item .tc-di-id { font-weight: 800; font-size: 13px; font-family: 'Fira Code', ui-monospace, monospace; }
.tc-dw-item .tc-di-sub { font-size: 11px; color: var(--prism-ink-soft); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.tc-dw-item .tc-di-qty {
  width: 52px; font-family: 'Fira Code', ui-monospace, monospace; font-size: 12px;
  padding: 3px 5px; border: 1px solid var(--prism-line-strong); border-radius: var(--prism-radius-sm);
}
.tc-dw-item .tc-rm {
  border: none; background: none; color: var(--prism-red); cursor: pointer;
  font-size: 11px; font-weight: 700; font-family: inherit; margin-top: 2px;
}
.tc-dw-item .tc-rm:hover { text-decoration: underline; }
.tc-dw-item .tc-di-r { text-align: right; font-family: 'Fira Code', ui-monospace, monospace; flex: 0 0 auto; }
.tc-cart-group-head {
  padding: 10px 16px 4px;
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--prism-ink-soft);
  background: var(--prism-panel-muted);
}
.tc-dw-foot {
  border-top: 1px solid var(--prism-line); padding: 16px;
  display: flex; flex-direction: column; gap: 10px;
}
.tc-dw-total { display: flex; justify-content: space-between; font-size: 14px; font-weight: 800; }
.tc-dw-total .tc-tv { font-family: 'Fira Code', ui-monospace, monospace; }
.tc-dw-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.tc-dw-empty { padding: 50px 24px; text-align: center; color: var(--prism-ink-soft); font-size: 13px; }

/* ---- Job link chips inside drawer (jobList → Part 360) ---- */
.tc-job-chip {
  display: inline-flex;
  background: var(--prism-panel-subtle);
  border: 1px solid var(--prism-line);
  padding: 2px 8px;
  border-radius: var(--prism-radius-sm);
  font-family: 'Fira Code', ui-monospace, monospace;
  font-size: 11px;
  color: var(--prism-blue);
  text-decoration: none;
}
.tc-job-chip:hover { background: var(--prism-blue-soft); border-color: var(--prism-blue-line); text-decoration: underline; }
.tc-job-more { display: inline-block; padding: 2px 8px; font-size: 11px; color: var(--prism-ink-soft); }

/* ---- Order history (detail drawer) ---- */
.tc-order-hist-row {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid var(--prism-line);
  font-size: 12px;
  color: var(--prism-ink-muted);
  align-items: center;
}
.tc-order-hist-row:last-child { border-bottom: none; }
.tc-order-hist-row .tc-tid { font-size: 12px; }
.tc-order-hist-row .num { font-family: 'Fira Code', ui-monospace, monospace; }

/* ---- Orders tab — expandable line-item sub-row ---- */
.tc-order-detail-row td { padding: 0; background: var(--prism-panel-subtle); }
.tc-order-lines { padding: 10px 16px; }
.tc-order-line {
  display: grid;
  grid-template-columns: 1.2fr 2.4fr 0.6fr 0.8fr;
  gap: 10px;
  padding: 5px 0;
  font-size: 12px;
  color: var(--prism-ink-muted);
  align-items: center;
}
.tc-order-line .tc-tid { font-size: 12px; }
.tc-order-line .num { font-family: 'Fira Code', ui-monospace, monospace; text-align: right; }
.tc-order-line-head {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--prism-ink-soft);
  border-bottom: 1px solid var(--prism-line);
  margin-bottom: 4px;
}
.tc-order-note { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--prism-line); font-size: 12px; color: var(--prism-ink-soft); font-style: italic; }

@media (max-width: 720px) {
  .tc-kpis { grid-template-columns: repeat(2, 1fr); }
  .tc-acts, .tc-dp-grid, .tc-dw-actions { grid-template-columns: 1fr; }
  .tc-drawer-detail, .tc-drawer-cart { width: 100vw; }
  .tc-order-hist-row, .tc-order-line { grid-template-columns: 1fr 1fr; row-gap: 2px; }
}
.ins-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 14px;
}
.ins-card {
  position: relative;
  background: #fff;
  border: 1px solid rgba(15, 44, 74, 0.08);
  border-left: 4px solid var(--ins-color, #94a3b8);
  border-radius: 10px;
  padding: 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  transition: transform 0.12s, box-shadow 0.12s;
}
.ins-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 16px rgba(15, 44, 74, 0.08);
}
/* Insights loading skeleton — shimmer placeholders while the multi-endpoint
   aggregation runs. No hover lift on skeletons. */
.ins-card.ins-skeleton {
  border-left-color: #e2e8f0;
  pointer-events: none;
}
.ins-card.ins-skeleton:hover { transform: none; box-shadow: none; }
.skel {
  display: block;
  border-radius: 6px;
  background: linear-gradient(90deg, #eef2f7 25%, #e2e8f0 37%, #eef2f7 63%);
  background-size: 400% 100%;
  animation: skel-shimmer 1.4s ease infinite;
}
.skel-line { height: 12px; }
.skel-icon { width: 36px; height: 36px; border-radius: 8px; flex: 0 0 auto; }
@keyframes skel-shimmer {
  0%   { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}
@media (prefers-reduced-motion: reduce) {
  .skel { animation: none; }
}
.ins-head {
  display: flex; align-items: center; gap: 10px;
}
.ins-icon {
  font-size: 22px;
  width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  background: var(--ins-color-bg, rgba(148, 163, 184, 0.15));
  border-radius: 8px;
}
.ins-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--color-primary);
  letter-spacing: 0.005em;
  flex: 1;
}
.ins-severity {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--ins-color-bg, rgba(148, 163, 184, 0.15));
  color: var(--ins-color, #475569);
  white-space: nowrap;
}
.ins-body {
  font-size: 13px;
  color: var(--color-text);
  line-height: 1.5;
}
.ins-body strong {
  color: var(--color-primary);
  font-weight: 700;
  font-feature-settings: "tnum";
}
.ins-cta {
  font-size: 11px;
  color: #2563eb;
  font-weight: 600;
  margin-top: 2px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  align-self: flex-start;
}
.ins-cta:hover { text-decoration: underline; }

.ins-detail {
  border-top: 1px solid rgba(15, 44, 74, 0.07);
  display: flex;
  flex-direction: column;
  gap: 3px;
  list-style: none;
  margin: 2px 0 0 44px;
  padding: 8px 0 0;
}

.ins-detail li {
  color: var(--ins-muted, #64748b);
  font-size: 12px;
  line-height: 1.4;
  padding-left: 12px;
  position: relative;
}

.ins-detail li::before {
  color: var(--ins-color, #94a3b8);
  content: '·';
  font-size: 16px;
  left: 0;
  line-height: 1;
  position: absolute;
  top: 1px;
}

/* Insights polish pass, scoped to the real view section so sidebar nav items
   with matching data-view values never inherit page-level treatment. */
section[data-view="insights"] {
  --ins-surface: #ffffff;
  --ins-muted-surface: #f8fafc;
  --ins-border: #dbe4ee;
  --ins-border-soft: #e7edf4;
  --ins-text: #172331;
  --ins-muted: #64748b;
  --ins-blue: #174f82;
  --ins-shadow: 0 1px 2px rgba(15, 44, 74, 0.05), 0 12px 28px rgba(15, 44, 74, 0.07);
  padding: 18px 20px 28px;
}

section[data-view="insights"] .page-header {
  background: transparent;
  border: 0;
  margin-bottom: 14px;
}

section[data-view="insights"] .page-header h1 {
  color: var(--ins-text);
  font-size: 30px;
  font-weight: 750;
  letter-spacing: 0;
}

section[data-view="insights"] .page-subtitle {
  color: var(--ins-muted);
  max-width: 720px;
}

.ins-summary {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin-bottom: 14px;
}

.ins-summary-card {
  background: var(--ins-surface);
  border: 1px solid var(--ins-border);
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(15, 44, 74, 0.04);
  min-width: 0;
  padding: 12px 14px;
}

.ins-summary-card strong {
  color: var(--ins-text);
  display: block;
  font-size: 24px;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  margin-top: 6px;
}

.ins-summary-label {
  color: var(--ins-muted);
  display: block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: uppercase;
}

.ins-summary-bad { border-left: 4px solid #b91c1c; }
.ins-summary-warn { border-left: 4px solid #b45309; }
.ins-summary-info { border-left: 4px solid #2563eb; }

section[data-view="insights"] .ins-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

section[data-view="insights"] .ins-card {
  background: linear-gradient(180deg, #ffffff 0%, #f9fbfd 100%);
  border-color: var(--ins-border);
  border-radius: 8px;
  box-shadow: var(--ins-shadow);
  min-height: 142px;
  padding: 16px 18px;
  transition: border-color 0.12s ease, box-shadow 0.12s ease, transform 0.12s ease;
}

section[data-view="insights"] .ins-card:hover {
  border-color: #cbd8e6;
  box-shadow: 0 2px 4px rgba(15, 44, 74, 0.06), 0 16px 34px rgba(15, 44, 74, 0.10);
}

section[data-view="insights"] .ins-head {
  align-items: flex-start;
}

section[data-view="insights"] .ins-icon {
  align-items: center;
  border: 1px solid rgba(15, 44, 74, 0.08);
  color: var(--ins-color, #475569);
  display: inline-flex;
  flex: 0 0 auto;
  height: 34px;
  justify-content: center;
  width: 34px;
}

.ins-title-wrap {
  flex: 1;
  min-width: 0;
}

section[data-view="insights"] .ins-title {
  color: var(--ins-text);
  display: block;
  font-size: 15px;
  letter-spacing: 0;
  line-height: 1.25;
}

section[data-view="insights"] .ins-severity {
  border: 1px solid rgba(15, 44, 74, 0.06);
  letter-spacing: 0;
  padding: 3px 8px;
  text-transform: none;
}

section[data-view="insights"] .ins-body {
  color: var(--ins-text);
  margin-left: 44px;
}

section[data-view="insights"] .ins-body strong {
  color: var(--ins-text);
}

section[data-view="insights"] .ins-cta {
  background: #ffffff;
  border: 1px solid var(--ins-border);
  border-radius: 7px;
  color: var(--ins-blue);
  font-size: 12px;
  margin-left: 44px;
  margin-top: 4px;
  padding: 6px 9px;
  text-decoration: none;
}

section[data-view="insights"] .ins-cta:hover {
  background: #f8fafc;
  border-color: #cbd8e6;
  text-decoration: none;
}

.ins-empty {
  background: var(--ins-surface);
  border: 1px solid var(--ins-border);
  border-radius: 8px;
  box-shadow: var(--ins-shadow);
  color: var(--ins-muted);
  grid-column: 1 / -1;
  padding: 18px;
}

section[data-view="insights"] > .muted {
  color: var(--ins-muted);
}

@media (max-width: 1050px) {
  .ins-summary,
  section[data-view="insights"] .ins-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 720px) {
  section[data-view="insights"] {
    padding: 14px;
  }

  section[data-view="insights"] .page-header h1 {
    font-size: 26px;
  }

  section[data-view="insights"] .ins-head {
    flex-wrap: wrap;
  }

  section[data-view="insights"] .ins-body,
  section[data-view="insights"] .ins-cta {
    margin-left: 0;
  }
}

/* Notes indicator — only shows if the material has notes; tooltip on hover */
.mat-notes-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: rgba(15, 44, 74, 0.08);
  color: var(--color-text-muted);
  font-size: 10px;
  font-weight: 700;
  cursor: help;
  font-style: normal;
}
.mat-notes-icon:hover { background: rgba(37, 99, 235, 0.15); color: #2563eb; }

/* Pricing-mode pill — reuse existing .act-mode style for consistency */
.qh-mode-pill {
  display: inline-block;
  font-size: 9px;
  padding: 1px 5px;
  border-radius: 3px;
  margin-left: 4px;
  text-transform: uppercase;
  font-weight: 600;
  letter-spacing: 0.04em;
  vertical-align: middle;
}

/* ============================================================
   Review & Edit panel — replaces the kv-grid display when active.
   Compact 2- and 3-col grids, accent left border, sticky action bar.
   Per Project_Docs/Review_Edit_Panel_Spec.md.
   ============================================================ */
.edit-pane {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 14px 16px 16px;
  margin: 4px 0 0;
  border-left: 3px solid var(--color-primary);
  background: #fafbfd;
  border-radius: 0 8px 8px 0;
}

/* Modal variant — extracted to body level so it works from any view (Smart
   Quote, New Quote, Quote History, etc.) instead of being trapped inside
   one view section. Position: fixed centered overlay with backdrop. */
.edit-pane-modal,
.edit-pane-modal.confirm-mode,
.edit-pane-modal.confirm-mode-critical {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 1000;
  background: rgba(15, 25, 40, 0.45);    /* backdrop — always dark, regardless of mode */
  display: flex;
  flex-direction: row;                   /* override .edit-pane's column → row so justify-content centers horizontally */
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  padding: 32px 16px;
  margin: 0;
  border-left: none;
  border-radius: 0;
}
.edit-pane-modal[hidden] { display: none !important; }
.edit-pane-modal-card {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 18px 22px 20px;
  max-width: 760px;
  width: 100%;
  background: #fafbfd;
  border-left: 3px solid var(--color-primary);
  border-radius: 0 8px 8px 0;
  box-shadow: 0 16px 48px rgba(15, 25, 40, 0.25), 0 4px 16px rgba(15, 25, 40, 0.15);
  margin: auto 0;
  /* Card is the scroll container (not the backdrop) so the sticky .edit-actions
     footer reliably pins to the card's bottom edge — the Re-quote button used to
     float mid-content and require scrolling (Max 2026-06-03). */
  max-height: calc(100vh - 64px);
  overflow-y: auto;
}
.edit-pane-modal.confirm-mode .edit-pane-modal-card {
  border-left-color: #d39000;
  background: #fffaf0;
}
.edit-pane-modal.confirm-mode-critical .edit-pane-modal-card {
  border-left-color: #b03030;
  background: #fdf3f3;
}
/* HTML `[hidden]` is `display: none` from the user-agent stylesheet, which
   loses specificity to `.edit-pane { display: flex }`. Restore it explicitly
   so toggling .hidden in JS actually hides the pane. */
.edit-pane[hidden],
.result-pane[hidden] { display: none !important; }
.edit-pane-head { margin-bottom: 2px; }
.edit-pane-title {
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text);
  margin: 0 0 4px;
  letter-spacing: 0.02em;
}
.edit-pane-sub {
  font-size: 12px;
  color: var(--color-text-muted, #5b6577);
  margin: 0;
  line-height: 1.45;
}
.edit-pane-sub strong { color: var(--color-text); font-weight: 600; }

.edit-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.edit-section-title {
  font-size: 11px;
  font-weight: 700;
  color: var(--color-primary);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  border-bottom: 1px solid var(--color-border, #e2e6ee);
  padding-bottom: 4px;
}
.edit-section-unit {
  font-size: 10px;
  font-weight: 500;
  color: var(--color-text-muted, #888);
  text-transform: none;
  letter-spacing: 0;
  margin-left: 4px;
}

.edit-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px 12px;
}
.edit-grid-2 { grid-template-columns: 1fr 1fr; }
.edit-grid-3 { grid-template-columns: 1fr 1fr 1fr; }
.edit-grid .span-2 { grid-column: span 2; }

.edit-field {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;   /* let inputs shrink in narrow grids */
}
/* Guard — see .qh-pagination[hidden] above. The only bare-`hidden` .edit-field is
   the orphan [data-dim="width"] one, which app.js:2748 hides UNCONDITIONALLY
   because the 3-dim schema never reads it (rect width lives in editId). Both the
   markup attribute and that assignment were dead, so the quoter got an extra
   "Width" box in the edit pane that accepted input and threw it away. */
.edit-field[hidden] { display: none; }
.edit-label {
  font-size: 11px;
  font-weight: 500;
  color: var(--color-text-muted, #5b6577);
  letter-spacing: 0.02em;
}
.edit-field input[type="text"],
.edit-field input[type="number"],
.edit-field select {
  width: 100%;
  padding: 6px 9px;
  font-size: 13px;
  font-family: inherit;
  color: var(--color-text);
  background: #fff;
  border: 1px solid var(--color-border, #e2e6ee);
  border-radius: 5px;
  outline: none;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.edit-field input:focus,
.edit-field select:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 2px rgba(15, 44, 74, 0.10);
}
.edit-field input[type="number"] { font-variant-numeric: tabular-nums; }

/* Highlight fields that VLM left null/zero — yellow ⚠ corner outline so the
   quoter knows where to focus (per spec). Set via JS class .edit-missing. */
.edit-field.edit-missing input,
.edit-field.edit-missing select {
  border-color: #f6c453;
  box-shadow: 0 0 0 2px rgba(246, 196, 83, 0.18);
}
.edit-field.edit-missing .edit-label::after {
  content: " ⚠";
  color: #d39000;
  font-size: 11px;
}

.edit-check {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  color: var(--color-text);
  cursor: pointer;
  user-select: none;
}
.edit-check input[type="checkbox"] {
  width: 14px;
  height: 14px;
  margin: 0;
  accent-color: var(--color-primary);
  cursor: pointer;
}

.edit-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  align-items: center;
  /* Bleed over the card's side + bottom padding so the sticky bar spans the
     full card width and sits flush at the bottom (content scrolls under it). */
  margin: 4px -22px -20px;
  padding: 12px 22px 16px;
  border-top: 1px solid var(--color-border, #e2e6ee);
  border-radius: 0 0 8px 0;
  position: sticky;
  bottom: 0;
  z-index: 5;
  background: #fafbfd;   /* matches .edit-pane bg so it doesn't show under transparent buttons */
}
.edit-actions .btn { padding-inline: 14px; }

/* Material combobox — custom dropdown (replaces native <datalist>). */
.combobox { position: relative; width: 100%; }
.combobox > input { width: 100%; }
.combobox-panel {
  position: absolute;
  top: calc(100% + 3px);
  left: 0;
  right: 0;
  z-index: 60;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: #fff;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(15, 25, 40, 0.16);
  max-height: 240px;
  overflow-y: auto;
}
.combobox-panel[hidden] { display: none; }
.combobox-panel li {
  padding: 7px 10px;
  border-radius: 4px;
  font-size: 13px;
  color: #1e293b;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.combobox-panel li.active,
.combobox-panel li:hover { background: #eef2ff; }
.combobox-empty {
  padding: 8px 10px;
  font-size: 12px;
  color: #94a3b8;
  font-style: italic;
  cursor: default;
}

.edit-error {
  font-size: 12px;
  color: #b03030;
  background: #fdecec;
  border: 1px solid #f3c5c5;
  border-radius: 5px;
  padding: 8px 10px;
  margin-top: 6px;
}

/* ============================================================
   Pre-quote dim-confirmation mode — same #editPane, different framing.
   When .edit-pane has .confirm-mode, switch the accent to amber so the
   user knows this is a verification step (not a free-form edit), and
   surface a sanity-flag banner above the form.
   ============================================================ */
.edit-pane.confirm-mode {
  border-left-color: #d39000;
  background: #fffaf0;
}
.edit-pane.confirm-mode .edit-actions {
  background: #fffaf0;
}
.edit-pane.confirm-mode .edit-section-title {
  color: #8a5a00;
}

/* CRITICAL state — extraction looks like a default-bias stub. Switch palette
   to red so it's visually obvious the user MUST fix this, not just verify. */
.edit-pane.confirm-mode-critical {
  border-left-color: #b03030;
  background: #fdf3f3;
}
.edit-pane.confirm-mode-critical .edit-actions { background: #fdf3f3; }
.edit-pane.confirm-mode-critical .edit-section-title { color: #802020; }
.edit-pane.confirm-mode-critical .confirm-flags {
  background: #fde0e0;
  border-color: #d09090;
  color: #5a1010;
}
.edit-pane.confirm-mode-critical .confirm-flags-title {
  color: #802020;
}
.edit-pane.confirm-mode-critical .edit-pane-title {
  color: #802020;
}

.confirm-flags {
  background: #fff5d8;
  border: 1px solid #f0c97c;
  border-radius: 6px;
  padding: 10px 12px;
  font-size: 12px;
  color: #5a3a00;
}
.confirm-flags[hidden] { display: none; }
.confirm-flags-title {
  font-weight: 700;
  font-size: 12px;
  margin-bottom: 6px;
  letter-spacing: 0.02em;
}
.confirm-flags-list {
  margin: 0;
  padding-left: 18px;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
.confirm-flags-list li {
  line-height: 1.4;
}
.confirm-flags-list li.sev-critical { color: #802020; font-weight: 600; }
.confirm-flags-list li.sev-high { color: #a0290e; }
.confirm-flags-list li.sev-med  { color: #8a5a00; }

/* Suspect-field highlight — distinct from .edit-missing (yellow) by being
   amber/red. Used when a sanity rule fired on this specific field. */
.edit-field.edit-suspect input,
.edit-field.edit-suspect select {
  border-color: #d96a4a;
  box-shadow: 0 0 0 2px rgba(217, 106, 74, 0.18);
  background: #fff8f5;
}
.edit-field.edit-suspect .edit-label::after {
  content: " ⚠";
  color: #a0290e;
  font-size: 11px;
}

/* Diff highlight on the kv-grid after a re-quote — fields that changed get a
   green pulse for a few seconds so the user can see what actually moved.
   Set via JS class .kv-changed on the <dd>. */
.kv-grid .kv-val.kv-changed {
  animation: kv-flash 2.4s ease-out;
  position: relative;
}
@keyframes kv-flash {
  0%   { background: rgba(46, 184, 100, 0.32); border-radius: 3px; }
  100% { background: transparent; }
}

@media (max-width: 720px) {
  .edit-grid-3 { grid-template-columns: 1fr 1fr; }
  .edit-grid-2 { grid-template-columns: 1fr; }
  .edit-grid .span-2 { grid-column: span 1; }
}

/* Quick-adjust margin input inside the Estimated Operations price-summary.
   Inline editable — type any % and press Enter (or tab) to fire /api/requote. */
.price-summary .ps-margin-cell {
  /* Override the default ps-val styling so the input fits cleanly */
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
  padding: 0;
}
.ps-margin-input {
  width: 70px;
  padding: 3px 6px;
  font-size: 13px;
  font-family: inherit;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--color-text);
  background: #fff;
  border: 1px solid var(--color-border, #e2e6ee);
  border-radius: 4px;
  outline: none;
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}
.ps-margin-input:hover { border-color: #c8cfdb; }
.ps-margin-input:focus {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 2px rgba(15, 44, 74, 0.10);
}
.ps-margin-input:disabled { opacity: 0.6; cursor: wait; }
.ps-margin-cell::after {
  content: "%";
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text-muted, #5b6577);
}

/* Tooling command-center CSS lives in one contiguous block — see
   "TOOLING COMMAND CENTER" near the .kb-content rules above. */

/* 2026-05-01: More-features dropdown in edit pane */
.edit-more-features {
  margin-top: 0.75rem;
  border-top: 1px dashed var(--border, #e2e8f0);
  padding-top: 0.5rem;
}
.edit-more-features > summary {
  cursor: pointer;
  font-size: 0.85rem;
  color: var(--text-muted, #64748b);
  font-weight: 500;
  padding: 0.25rem 0;
  user-select: none;
  list-style: none;
}
.edit-more-features > summary::before {
  content: "▸ ";
  display: inline-block;
  transition: transform 0.15s ease;
}
.edit-more-features[open] > summary::before {
  content: "▾ ";
}
.edit-more-features > summary:hover {
  color: var(--text, #0f172a);
}

/* ==========================================================================
   Settings view — profile, change password, user management.
   Added 2026-05-04 alongside the auth foundation rollout.
   ========================================================================== */
.settings-form { margin: 0; }
.settings-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1rem 1.25rem;
  margin-bottom: 1rem;
}
.settings-field { display: flex; flex-direction: column; gap: 0.375rem; }
/* Guard — see .qh-pagination[hidden] above. #addUserCustomRoleField is shown only
   when the role dropdown is on the "Custom…" sentinel (settings.js:703/725);
   without this the Add User modal always showed a free-text custom-role box next
   to the dropdown, inviting a typo'd role on an account that had a real one. */
.settings-field[hidden] { display: none; }
.settings-field-wide { grid-column: 1 / -1; }
.settings-label {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--color-text);
  letter-spacing: 0.01em;
}
.settings-hint {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  margin-top: 0.125rem;
}
.settings-field input[type="text"],
.settings-field input[type="email"],
.settings-field input[type="password"],
.settings-field select,
.settings-field textarea {
  padding: 0.5rem 0.625rem;
  font-size: 0.875rem;
  font-family: inherit;
  color: var(--color-text);
  background: #fff;
  border: 1px solid var(--color-border-strong);
  border-radius: 6px;
  width: 100%;
  box-sizing: border-box;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.settings-field input:focus,
.settings-field select:focus,
.settings-field textarea:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(31, 111, 196, 0.15);
}
.settings-field input:disabled {
  background: var(--color-bg);
  color: var(--color-text-muted);
  cursor: not-allowed;
}
.settings-field textarea {
  resize: vertical;
  min-height: 64px;
  font-family: inherit;
}
.settings-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  margin-top: 0.5rem;
}
.settings-status {
  display: none;
  margin: 0.5rem 0 0.75rem 0;
  padding: 0.5rem 0.75rem;
  font-size: 0.8125rem;
  border-radius: 6px;
  border: 1px solid transparent;
}
.settings-status-success {
  display: block;
  color: #1f5e3a;
  background: #e6f4ec;
  border-color: #b9deca;
}
.settings-status-error {
  display: block;
  color: #8b1c1c;
  background: #fdecec;
  border-color: #f4c8c8;
}
.settings-status-info {
  display: block;
  color: var(--color-text);
  background: var(--color-primary-soft);
  border-color: var(--color-border);
}

/* User management table */
.settings-table-wrap {
  overflow-x: auto;
  border: 1px solid var(--color-border);
  border-radius: 8px;
}
.settings-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}
.settings-table thead th {
  text-align: left;
  padding: 0.625rem 0.75rem;
  background: var(--color-primary-soft);
  font-weight: 600;
  color: var(--color-text);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--color-border);
}
.settings-table tbody td {
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--color-border);
  vertical-align: middle;
}
.settings-table tbody tr:last-child td { border-bottom: none; }
.settings-table tbody tr:hover { background: var(--color-bg); }
.settings-inline-input {
  padding: 0.3125rem 0.5rem;
  font-size: 0.8125rem;
  font-family: inherit;
  border: 1px solid var(--color-border);
  border-radius: 4px;
  background: #fff;
  width: 100%;
  box-sizing: border-box;
}
.settings-inline-input:focus {
  outline: none;
  border-color: var(--color-accent);
}
.settings-row-actions {
  display: flex;
  gap: 0.375rem;
  white-space: nowrap;
}
.btn-small {
  padding: 0.3125rem 0.625rem;
  font-size: 0.75rem;
}
.btn-danger {
  background: #b3261e;
  color: #fff;
  border: 1px solid #8c1d17;
}
.btn-danger:hover { background: #8c1d17; }
.card-subtitle {
  font-size: 0.8125rem;
  margin: -0.375rem 0 0.75rem 0;
}

/* Audit log filters + action pills */
.audit-filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 0.75rem 1rem;
  align-items: end;
}
.audit-action-pill {
  display: inline-block;
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  background: var(--color-primary-soft);
  color: var(--color-primary);
  white-space: nowrap;
}
.audit-action-login_success    { background: #e6f4ec; color: #1f5e3a; }
.audit-action-login_failed     { background: #fdecec; color: #8b1c1c; }
.audit-action-logout           { background: #f1f3f6; color: #5e6975; }
.audit-action-quote_created    { background: #e7eef6; color: #0f2c4a; }
.audit-action-quote_requoted   { background: #fff4e0; color: #8a5a00; }
.audit-action-quote_deleted    { background: #fdecec; color: #8b1c1c; }
.audit-action-user_created,
.audit-action-user_updated,
.audit-action-user_deleted,
.audit-action-password_reset,
.audit-action-config_updated   { background: #fdf3e0; color: #8a5a00; }

/* ==========================================================================
   Edit Views modal (Settings → User Management → "Edit views" button)
   ========================================================================== */
.views-modal {
  position: fixed;
  inset: 0;
  z-index: 1100;
  display: flex;
  align-items: center;
  justify-content: center;
}
.views-modal[hidden] { display: none; }
.views-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 44, 74, 0.45);
  backdrop-filter: blur(2px);
}
.views-modal-card {
  position: relative;
  width: 100%;
  max-width: 540px;
  margin: 0 1rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 12px;
  box-shadow: 0 16px 48px rgba(15, 44, 74, 0.18);
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 2rem);
  overflow: hidden;
}
.views-modal-head {
  padding: 1.25rem 1.5rem 0.5rem;
  border-bottom: 1px solid var(--color-border);
  padding-bottom: 1rem;
}
.views-modal-title {
  margin: 0 0 0.25rem 0;
  font-size: 1.0625rem;
  font-weight: 700;
  color: var(--color-text);
}
.views-modal-sub {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--color-text-muted);
}
.views-modal-body {
  padding: 1rem 1.5rem;
  overflow-y: auto;
}
.views-modal-roledefault {
  font-size: 0.75rem;
  margin-bottom: 0.875rem;
  padding: 0.5rem 0.625rem;
  background: var(--color-primary-soft);
  border: 1px solid var(--color-border);
  border-radius: 6px;
}
.views-modal-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0.5rem 0.875rem;
}
.views-modal-check {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4375rem 0.5rem;
  border-radius: 6px;
  cursor: pointer;
  transition: background-color 0.12s;
}
.views-modal-check:hover { background: var(--color-bg); }
.views-modal-check input[type="checkbox"] {
  margin: 0;
  flex: 0 0 auto;
  cursor: pointer;
}
.views-modal-check-label {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-text);
}
.views-modal-check-label .views-modal-check-default {
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-good);
}
/* View packages — a strip of grant shortcuts above the flat checkbox grid.
   Deliberately styled as BUTTONS, not checkboxes: a package isn't a value that
   gets submitted, it's an action that fills the boxes below, and a checkbox
   would imply the tri-state is something you can save. */
.views-modal-packages {
  margin-bottom: 0.875rem;
  padding-bottom: 0.875rem;
  border-bottom: 1px solid var(--color-border);
}
.views-modal-packages[hidden] { display: none; }
.views-pkg-label {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  margin-bottom: 0.5rem;
}
.views-pkg-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.375rem;
}
.views-pkg {
  display: inline-flex;
  align-items: baseline;
  gap: 0.375rem;
  padding: 0.3125rem 0.625rem;
  border: 1px solid var(--color-border-strong);
  border-radius: 999px;
  background: var(--color-surface);
  color: var(--color-text);
  cursor: pointer;
  font-size: 0.75rem;
  font-weight: 700;
  transition: background-color 0.12s, border-color 0.12s, color 0.12s;
}
.views-pkg:hover {
  background: var(--color-primary-soft);
  border-color: var(--prism-blue);
}
.views-pkg:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(31, 111, 196, 0.2);
}
.views-pkg-count {
  font-size: 0.6875rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}
/* Tri-state, set by syncPackageChips(): none / some / all. `some` is the one
   that carries information — it says this user is mid-package, which is exactly
   the case an admin is usually trying to find. */
.views-pkg[data-state="some"] {
  background: var(--prism-amber-soft);
  border-color: var(--prism-amber-line);
  color: var(--prism-amber);
}
.views-pkg[data-state="some"] .views-pkg-count { color: var(--prism-amber); }
.views-pkg[data-state="all"] {
  background: var(--prism-green-soft);
  border-color: var(--prism-green-line);
  color: var(--prism-green);
}
.views-pkg[data-state="all"] .views-pkg-count { color: var(--prism-green); }

/* Split locked-pair warnings. Advisory only — never blocks or overrides the
   save (Max 2026-08-17: warn, don't override). */
/* Sits between the package strip and the grid — see the markup comment. */
.views-modal-warnings {
  margin-bottom: 0.875rem;
  display: flex;
  flex-direction: column;
  gap: 0.375rem;
}
.views-modal-warnings[hidden] { display: none; }
.views-modal-warn {
  display: flex;
  flex-direction: column;
  gap: 0.1875rem;
  padding: 0.5rem 0.625rem;
  border: 1px solid var(--prism-amber-line);
  border-left: 3px solid var(--prism-amber);
  border-radius: 6px;
  background: var(--prism-amber-soft);
  color: var(--prism-ink);
  font-size: 0.75rem;
  line-height: 1.45;
}
.views-warn-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.views-warn-why {
  color: var(--prism-ink-muted);
  padding-right: 4.5rem;   /* clears the action button's column */
}
.views-warn-fix {
  flex: 0 0 auto;
  padding: 0.1875rem 0.5rem;
  border: 1px solid var(--prism-amber);
  border-radius: 4px;
  background: transparent;
  color: var(--prism-amber);
  cursor: pointer;
  font-size: 0.6875rem;
  font-weight: 700;
  white-space: nowrap;
}
.views-warn-fix:hover { background: var(--prism-amber); color: #fff; }
.views-warn-fix:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(154, 91, 0, 0.25);
}

.views-modal-foot {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
  padding: 0.875rem 1.5rem;
  border-top: 1px solid var(--color-border);
  background: var(--color-bg);
}

/* View password modal — reveal input + copy button row */
.view-pw-row {
  display: flex;
  gap: 0.5rem;
  align-items: stretch;
}
.view-pw-input {
  flex: 1 1 auto;
  padding: 0.5rem 0.75rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.9375rem;
  color: var(--color-text);
  background: #fff;
  border: 1px solid var(--color-border-strong);
  border-radius: 6px;
  letter-spacing: 0.02em;
}
.view-pw-input:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(31, 111, 196, 0.15);
}

/* Settings sub-headings (used inside cards for grouped form sections). */
.settings-subhead {
  font-size: 0.8125rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-muted);
  margin: 1.25rem 0 0.625rem 0;
  padding-bottom: 0.375rem;
  border-bottom: 1px solid var(--color-border);
}
.settings-subhead:first-child { margin-top: 0.25rem; }

/* Settings polish pass: shadcn-inspired form surfaces, scoped to the settings
   view section so sidebar nav items with data-view="settings" stay untouched. */
section[data-view="settings"] {
  --settings-surface: #ffffff;
  --settings-muted-surface: #f8fafc;
  --settings-border: #dbe4ee;
  --settings-border-soft: #e7edf4;
  --settings-text: #172331;
  --settings-muted: #64748b;
  --settings-blue: #174f82;
  --settings-focus: rgba(37, 99, 235, 0.16);
  --settings-shadow: 0 1px 2px rgba(15, 44, 74, 0.05), 0 12px 28px rgba(15, 44, 74, 0.07);
  align-items: start;
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  padding: 18px 20px 28px;
}

section[data-view="settings"] .page-header {
  background:
    linear-gradient(135deg, rgba(23, 79, 130, 0.08) 0%, rgba(15, 118, 110, 0.06) 42%, rgba(255, 255, 255, 0.92) 100%),
    #ffffff;
  border: 1px solid var(--settings-border);
  border-left: 4px solid var(--settings-blue);
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(15, 44, 74, 0.04);
  grid-column: 1 / -1;
  margin-bottom: 0;
  padding: 18px 20px;
}

section[data-view="settings"] .page-header h1 {
  color: var(--settings-text);
  font-size: 30px;
  font-weight: 750;
  letter-spacing: 0;
}

section[data-view="settings"] .page-subtitle {
  color: var(--settings-muted);
  max-width: 720px;
}

section[data-view="settings"] > .card {
  background: linear-gradient(180deg, #ffffff 0%, #fbfcfe 100%);
  border: 1px solid var(--settings-border);
  border-radius: 8px;
  box-shadow: var(--settings-shadow);
  margin-bottom: 0;
  min-width: 0;
  padding: 18px 20px;
}

section[data-view="settings"] > #settingsShopConfig,
section[data-view="settings"] > #settingsUsers,
/* View access is a two-pane table — in one column of the settings grid its
   detail pane collapses to ~320px and the role checkboxes wrap to one per row. */
section[data-view="settings"] > #settingsViewAccess {
  grid-column: 1 / -1;
}

section[data-view="settings"] > .card:hover {
  border-color: #cbd8e6;
}

section[data-view="settings"] .card-title {
  align-items: center;
  color: var(--settings-text);
  display: flex;
  font-size: 17px;
  font-weight: 750;
  gap: 9px;
  letter-spacing: 0;
  margin-bottom: 4px;
}

section[data-view="settings"] .card-title::before {
  background: var(--settings-blue);
  border: 0;
  border-radius: 999px;
  color: var(--settings-blue);
  content: "";
  display: inline-block;
  height: 22px;
  width: 4px;
}

section[data-view="settings"] #settingsProfile .card-title::before {
  background: #2563eb;
}

section[data-view="settings"] #settingsPassword .card-title::before {
  background: #b45309;
}

section[data-view="settings"] #settingsShopConfig .card-title::before {
  background: #0f766e;
}

section[data-view="settings"] #settingsUsers .card-title::before {
  background: #7c3aed;
}

section[data-view="settings"] .card-subtitle,
section[data-view="settings"] .muted,
section[data-view="settings"] .settings-hint {
  color: var(--settings-muted);
}

section[data-view="settings"] .settings-grid {
  gap: 14px 18px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-bottom: 14px;
}

section[data-view="settings"] #settingsProfile .settings-grid,
section[data-view="settings"] #settingsPassword .settings-grid {
  grid-template-columns: 1fr;
}

section[data-view="settings"] #settingsProfile .settings-field-wide {
  grid-column: auto;
}

section[data-view="settings"] .settings-field {
  gap: 6px;
  min-width: 0;
}

section[data-view="settings"] .settings-label {
  color: var(--settings-text);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0;
}

section[data-view="settings"] .settings-field input[type="text"],
section[data-view="settings"] .settings-field input[type="email"],
section[data-view="settings"] .settings-field input[type="password"],
section[data-view="settings"] .settings-field input[type="number"],
section[data-view="settings"] .settings-field select,
section[data-view="settings"] .settings-field textarea,
section[data-view="settings"] .settings-inline-input {
  background: #ffffff;
  border: 1px solid var(--settings-border);
  border-radius: 8px;
  color: var(--settings-text);
  font-size: 14px;
  min-height: 36px;
  padding: 8px 10px;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

section[data-view="settings"] .settings-field input[type="text"]:not(:disabled),
section[data-view="settings"] .settings-field input[type="email"]:not(:disabled),
section[data-view="settings"] .settings-field input[type="password"]:not(:disabled),
section[data-view="settings"] .settings-field input[type="number"]:not(:disabled),
section[data-view="settings"] .settings-field textarea {
  box-shadow: inset 0 1px 0 rgba(15, 44, 74, 0.03);
}

section[data-view="settings"] .settings-field input:focus,
section[data-view="settings"] .settings-field select:focus,
section[data-view="settings"] .settings-field textarea:focus,
section[data-view="settings"] .settings-inline-input:focus {
  border-color: #9cc6ee;
  box-shadow: 0 0 0 3px var(--settings-focus);
  outline: none;
}

section[data-view="settings"] .settings-field input:disabled {
  background: var(--settings-muted-surface);
  border-color: var(--settings-border-soft);
  color: var(--settings-muted);
}

section[data-view="settings"] .settings-field textarea {
  min-height: 72px;
}

section[data-view="settings"] .settings-actions {
  gap: 8px;
  margin-top: 8px;
}

section[data-view="settings"] .btn {
  border-radius: 8px;
  font-weight: 700;
  min-height: 36px;
}

section[data-view="settings"] .btn-primary {
  background: var(--settings-blue);
  border-color: var(--settings-blue);
  box-shadow: 0 1px 2px rgba(15, 44, 74, 0.08);
}

section[data-view="settings"] .btn-primary:hover {
  background: #123f68;
  border-color: #123f68;
}

section[data-view="settings"] .btn-secondary,
section[data-view="settings"] .btn-small {
  background: #ffffff;
  border: 1px solid var(--settings-border);
  color: var(--settings-text);
}

section[data-view="settings"] .btn-secondary:hover,
section[data-view="settings"] .btn-small:hover {
  background: var(--settings-muted-surface);
  border-color: #cbd8e6;
}

section[data-view="settings"] .settings-status {
  border-radius: 8px;
  font-size: 12px;
  line-height: 1.45;
  padding: 9px 11px;
}

section[data-view="settings"] .settings-status-info {
  background: #eef6ff;
  border-color: #cfe4fb;
  color: #16456f;
}

section[data-view="settings"] .settings-status-success {
  background: #ecfdf5;
  border-color: #bbf7d0;
  color: #166534;
}

section[data-view="settings"] .settings-status-error {
  background: #fef2f2;
  border-color: #fecaca;
  color: #991b1b;
}

section[data-view="settings"] .settings-subhead {
  border-bottom: 1px solid var(--settings-border-soft);
  color: var(--settings-muted);
  font-size: 12px;
  letter-spacing: 0;
}

section[data-view="settings"] details.settings-tier-help {
  background: var(--settings-muted-surface);
  border: 1px solid var(--settings-border-soft);
  border-radius: 8px;
  padding: 10px 12px;
}

section[data-view="settings"] details.settings-tier-help > summary {
  color: var(--settings-blue) !important;
  letter-spacing: 0;
}

section[data-view="settings"] .settings-table-wrap {
  background: #ffffff;
  border: 1px solid var(--settings-border);
  border-radius: 8px;
}

section[data-view="settings"] .settings-table {
  border-collapse: separate;
  border-spacing: 0;
}

section[data-view="settings"] .settings-table thead th {
  background: var(--settings-muted-surface);
  border-bottom: 1px solid var(--settings-border);
  color: var(--settings-muted);
  letter-spacing: 0;
  text-transform: none;
}

section[data-view="settings"] .settings-table tbody td {
  border-bottom: 1px solid var(--settings-border-soft);
  color: var(--settings-text);
}

section[data-view="settings"] .settings-table tbody tr:hover {
  background: #f8fafc;
}

@media (max-width: 1050px) {
  section[data-view="settings"] {
    grid-template-columns: 1fr;
  }

  section[data-view="settings"] .settings-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  section[data-view="settings"] #settingsProfile .settings-grid,
  section[data-view="settings"] #settingsPassword .settings-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 720px) {
  section[data-view="settings"] {
    padding: 14px;
  }

  section[data-view="settings"] .page-header h1 {
    font-size: 26px;
  }

  section[data-view="settings"] .settings-grid {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
   ADMIN HEALTH
   Lightweight internal readiness/status surface.
   ============================================================ */
.admin-health-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
}

.admin-health-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.875rem;
  margin-bottom: 1rem;
}

.admin-health-tile {
  min-height: 110px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: #fff;
  padding: 1rem;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.admin-health-label {
  color: var(--color-muted);
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.admin-health-tile strong {
  color: var(--color-primary);
  font-size: 1.65rem;
  line-height: 1.1;
  font-feature-settings: "tnum";
}

.admin-health-muted {
  color: var(--color-muted);
  font-size: 0.78rem;
}

.admin-health-status-text.status-ok { color: #047857; }
.admin-health-status-text.status-warn { color: #b45309; }
.admin-health-status-text.status-bad { color: #b91c1c; }

.admin-health-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  gap: 1rem;
  align-items: start;
}

.admin-health-main,
.admin-health-side {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.admin-health-list {
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}

.admin-health-row {
  display: grid;
  grid-template-columns: 12px minmax(0, 1fr) auto;
  gap: 0.75rem;
  align-items: center;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  padding: 0.75rem;
}

.admin-health-row strong {
  display: block;
  color: var(--color-primary);
  font-size: 0.9rem;
}

.admin-health-row span:not(.admin-health-dot) {
  display: block;
  color: var(--color-muted);
  font-size: 0.78rem;
  margin-top: 0.125rem;
}

.admin-health-row em {
  color: var(--color-muted);
  font-size: 0.75rem;
  font-style: normal;
  font-weight: 800;
  text-transform: uppercase;
}

.admin-health-dot {
  width: 10px;
  height: 10px;
  border-radius: 999px;
  display: block;
}

.admin-health-dot.status-ok,
.admin-health-pill.status-ok {
  background: #dcfce7;
  color: #047857;
}

.admin-health-dot.status-warn,
.admin-health-pill.status-warn {
  background: #fef3c7;
  color: #b45309;
}

.admin-health-dot.status-bad,
.admin-health-pill.status-bad {
  background: #fee2e2;
  color: #b91c1c;
}

.admin-health-dot.status-ok,
.admin-health-dot.status-warn,
.admin-health-dot.status-bad {
  color: transparent;
}

.admin-health-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 64px;
  border-radius: 999px;
  padding: 0.25rem 0.5rem;
  font-size: 0.7rem;
  font-weight: 800;
  text-transform: uppercase;
}

.admin-health-path {
  display: block;
  color: var(--color-muted);
  font-size: 0.72rem;
  margin-top: 0.1875rem;
  word-break: break-word;
}

.admin-health-table td {
  vertical-align: top;
}

.admin-health-kv {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.admin-health-kv-row {
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  border-bottom: 1px solid var(--color-border);
  padding: 0.45rem 0;
}

.admin-health-kv-row:last-child {
  border-bottom: none;
}

.admin-health-kv-row span {
  color: var(--color-muted);
  font-size: 0.78rem;
}

.admin-health-kv-row strong {
  color: var(--color-primary);
  font-size: 0.78rem;
  text-align: right;
  font-feature-settings: "tnum";
}

@media (max-width: 1180px) {
  .admin-health-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .admin-health-layout {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 720px) {
  .admin-health-header {
    flex-direction: column;
  }
  .admin-health-grid {
    grid-template-columns: 1fr;
  }
}


/* ============================================================
   Shop Dashboard (admin-only mirror of QQE Daily Tracking Report)
   Layout: KPI tile strip (4×2) + section cards. Traffic-light
   coloring on tiles + status pills.
   ============================================================ */
.sd-kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 12px;
  margin-bottom: 1rem;
}
@media (max-width: 1100px) {
  .sd-kpi-grid { grid-template-columns: repeat(2, 1fr); }
}

/* Today's Action Items strip — "what should I do RIGHT NOW" synthesizer.
   Sits between KPIs and Critical Production. Each item is a colored pill
   tile with click-to-drill behavior. */
.sd-action-strip {
  background: linear-gradient(135deg, #fff 0%, #fafbfd 100%);
  border: 1px solid #e0e6ee;
  border-left: 4px solid #F2C037;
  border-radius: 10px;
  padding: 12px 16px;
  margin-bottom: 1rem;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.sd-action-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}
.sd-action-title {
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #1F4E79;
}
.sd-action-summary {
  font-size: 11px;
  font-weight: 600;
  padding: 3px 10px;
  border-radius: 999px;
  background: #f0f3f8;
  color: #555;
}
/* Softer pastel palette 2026-05-22 — replaced Excel-saturated red/yellow/green
   with the prism token system. Reads as graded, not alarming. */
.sd-action-summary.sd-bad  { background: var(--prism-red-soft);   color: var(--prism-red); }
.sd-action-summary.sd-warn { background: var(--prism-amber-soft); color: var(--prism-amber); }
.sd-action-summary.sd-good { background: var(--prism-green-soft); color: var(--prism-green); }
.sd-action-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 8px;
}
.sd-action-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 8px;
  background: #f5f7fa;
  cursor: default;
  transition: background 0.12s ease, transform 0.12s ease;
}
.sd-action-item[role="button"] { cursor: pointer; }
.sd-action-item[role="button"]:hover {
  background: #ecf0f5;
  transform: translateY(-1px);
}
.sd-action-item.sd-action-bad  { background: var(--prism-red-soft); border-left: 3px solid var(--prism-red); }
.sd-action-item.sd-action-bad[role="button"]:hover  { background: #FFD0D5; }
.sd-action-item.sd-action-warn { background: var(--prism-amber-soft); border-left: 3px solid var(--prism-amber); }
.sd-action-item.sd-action-warn[role="button"]:hover { background: #FFEEB8; }
.sd-action-item.sd-action-good { background: var(--prism-green-soft); border-left: 3px solid var(--prism-green); }
.sd-action-item.sd-action-good[role="button"]:hover { background: #CFEED4; }
.sd-action-icon { font-size: 18px; line-height: 1; flex-shrink: 0; margin-top: 1px; }
.sd-action-text { min-width: 0; flex: 1; }
.sd-action-item-title {
  font-size: 13px;
  font-weight: 600;
  color: #1a1a1a;
  margin-bottom: 2px;
  font-variant-numeric: tabular-nums;
}
.sd-action-item-sub {
  font-size: 11px;
  color: #555;
  line-height: 1.35;
}
.sd-tile {
  border: 1px solid #d0d0d0;
  border-radius: 8px;
  padding: 14px 12px;
  background: #ffffff;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  min-height: 110px;
  justify-content: space-between;
}
.sd-tile-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: #7f7f7f;
  text-transform: uppercase;
  margin-bottom: 4px;
}
.sd-tile-value {
  font-size: 28px;
  font-weight: 700;
  line-height: 1.1;
  color: #1a1a1a;
}
.sd-tile-delta {
  font-size: 11px;
  font-style: italic;
  color: #555;
  margin-top: 4px;
}
/* Second-source live figure (2026-07-07) — sits below the hand-xlsx delta,
   deliberately quieter so the hand-typed number stays the visual headline. */
.sd-tile-live {
  font-size: 10px;
  color: var(--prism-ink-muted, #8a8a8a);
  margin-top: 3px;
  display: flex;
  align-items: center;
  gap: 5px;
  flex-wrap: wrap;
}
.sd-tile-live .jb-fresh-pill { padding: 1px 6px; font-size: 9px; }
/* KPI tile tone backgrounds — softened 2026-05-22 to prism tokens. */
.sd-tile.sd-good   { background: var(--prism-green-soft); border-color: var(--prism-green-line); }
.sd-tile.sd-good   .sd-tile-value, .sd-tile.sd-good   .sd-tile-delta { color: var(--prism-green); }
.sd-tile.sd-warn   { background: var(--prism-amber-soft); border-color: var(--prism-amber-line); }
.sd-tile.sd-warn   .sd-tile-value, .sd-tile.sd-warn   .sd-tile-delta { color: var(--prism-amber); }
.sd-tile.sd-bad    { background: var(--prism-red-soft);   border-color: var(--prism-red-line); }
.sd-tile.sd-bad    .sd-tile-value, .sd-tile.sd-bad    .sd-tile-delta { color: var(--prism-red); }

/* KPI grouping (2026-05-08): 8 tiles in one big grid was hard to scan. Now
   split into Money / Production / Inventory subgroups with subtle labels. */
.sd-kpi-group {
  margin-bottom: 1rem;
}
.sd-kpi-group-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #888;
  margin: 0 0 6px 4px;
}
.sd-kpi-row {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
}
@media (max-width: 1100px) {
  .sd-kpi-row { grid-template-columns: repeat(2, 1fr); }
}
/* Inventory group only has 2 tiles — let them fill the row instead of leaving
   an empty 3rd column. */
.sd-kpi-group:last-child .sd-kpi-row { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 1100px) {
  .sd-kpi-group:last-child .sd-kpi-row { grid-template-columns: repeat(2, 1fr); }
}

/* "This Month vs Last Year" comparison tile (replaces the old Open SO
   Backlog widget — apples-to-apples matched-window comparison). 3 cells:
   this month so far / same window LY / last year full month. */
.sd-yoy-compare {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-top: 8px;
}
@media (max-width: 800px) { .sd-yoy-compare { grid-template-columns: 1fr; } }
.sd-yoy-cell {
  background: #f5f7fa;
  border-radius: 8px;
  padding: 14px 16px;
  border-left: 3px solid #d0d6de;
}
.sd-yoy-cell.sd-yoy-cell-current { border-left-color: #1F4E79; background: #e9f0f7; }
.sd-yoy-cell.sd-yoy-cell-ly      { border-left-color: #94a3b8; }
.sd-yoy-cell.sd-yoy-cell-target  { border-left-color: #6FBF73; background: #f0f8f1; }
.sd-yoy-cell-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #555;
  margin-bottom: 4px;
}
.sd-yoy-cell-value {
  font-size: 22px;
  font-weight: 700;
  color: #1a1a1a;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.sd-yoy-cell-sub {
  font-size: 11px;
  color: #666;
  margin-top: 4px;
}
.sd-yoy-stale-note {
  grid-column: 1 / -1;
  margin-top: 4px;
  padding: 8px 12px;
  background: #FFEB9C;
  border-left: 3px solid #9C5700;
  border-radius: 4px;
  font-size: 11px;
  color: #9C5700;
}

/* Make the whole YoY card clickable as a single drill-in target.
   Same hover affordance as KPI tiles. */
.sd-card-clickable {
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.sd-card-clickable:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(31, 78, 121, 0.10);
}

/* Universal click affordance for KPI tiles (2026-05-08). Hover lift, cursor
   pointer, focus ring for keyboard a11y. Click handlers wired in app.js
   route to drill-in destinations (Pulse, Shop Floor, in-page scroll). */
.sd-tile-clickable {
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
  position: relative;
}
.sd-tile-clickable:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(31, 78, 121, 0.12);
  border-color: #1F4E79;
}
.sd-tile-clickable:active {
  transform: translateY(0);
}
.sd-tile-clickable:focus-visible {
  outline: 2px solid #1F4E79;
  outline-offset: 2px;
}
/* Tiny chevron in the corner to telegraph clickability without being loud */
.sd-tile-clickable::after {
  content: '↗';
  position: absolute;
  top: 8px;
  right: 10px;
  font-size: 11px;
  color: rgba(0,0,0,0.25);
  transition: color 0.15s ease, transform 0.15s ease;
}
.sd-tile-clickable:hover::after {
  color: #1F4E79;
  transform: translate(2px, -2px);
}

.sd-card { margin-bottom: 1rem; padding: 14px 16px; }
.sd-card-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.5rem;
}
/* Accent-bar header — replaces per-section emoji icons as the visual anchor.
   Added 2026-05-22. One treatment, token-driven, scales to any future section. */
.sd-card-head h3 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  padding-left: 10px;
  border-left: 3px solid var(--prism-blue, #174f82);
  line-height: 1.3;
}
.sd-pill {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 999px;
  background: #f0f0f0;
  color: #555;
}
.sd-pill.sd-good { background: var(--prism-green-soft); color: var(--prism-green); }
.sd-pill.sd-warn { background: var(--prism-amber-soft); color: var(--prism-amber); }
.sd-pill.sd-bad  { background: var(--prism-red-soft);   color: var(--prism-red); }

/* A panel that FAILED, as distinct from a panel that is empty (audit finding
   13). The two used to be indistinguishable — a blank chart under a neutral
   pill, and on the CMM tab a failure message sharing its class with "no
   matches". This must not look like a data state: it is a statement about the
   server, not about the shop, so it takes the red rail and says so in words. */
.sd-panel-fail {
  border-left: 3px solid var(--prism-red);
  background: var(--prism-red-soft);
  color: var(--prism-ink);
  padding: 10px 14px;
  margin: 10px 0;
  font-size: 13px;
  line-height: 1.55;
  border-radius: 0 var(--prism-radius-sm) var(--prism-radius-sm) 0;
}
.sd-panel-fail-note {
  display: block;
  margin-top: 5px;
  font-size: 12px;
  color: var(--prism-ink-muted);
}

.sd-two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
@media (max-width: 900px) { .sd-two-col { grid-template-columns: 1fr; } }

.sd-table-wrap { overflow-x: auto; }
.sd-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.sd-table th, .sd-table td {
  padding: 6px 8px;
  border-bottom: 1px solid #eaeaea;
  text-align: left;
}
.sd-table th {
  background: #5B9BD5;
  color: #ffffff;
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.sd-table td.sd-num { text-align: right; font-variant-numeric: tabular-nums; }
.sd-table td.sd-center { text-align: center; }
.sd-table tr.sd-row-bad   { background: rgba(255,199,206,0.4); }
.sd-table tr.sd-row-warn  { background: rgba(255,235,156,0.4); }
.sd-table tr.sd-row-good  { background: rgba(198,239,206,0.3); }
.sd-status {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 4px;
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.03em;
}
.sd-status.sd-good { background: var(--prism-green-soft); color: var(--prism-green); }
.sd-status.sd-warn { background: var(--prism-amber-soft); color: var(--prism-amber); }
.sd-status.sd-bad  { background: var(--prism-red-soft);   color: var(--prism-red); }

.sd-bar {
  display: inline-block;
  height: 10px;
  border-radius: 4px;
  background: #5B9BD5;
  vertical-align: middle;
  min-width: 4px;
}
.sd-bar-track {
  display: inline-block;
  width: 80px;
  height: 10px;
  background: #eee;
  border-radius: 4px;
  overflow: hidden;
  vertical-align: middle;
  margin-right: 6px;
}
.sd-bar-track .sd-bar { display: block; height: 100%; border-radius: 0; }
.sd-bar.sd-bar-over { background: #F8696B; }

.sd-footer { font-size: 11px; color: #999; font-style: italic; text-align: right; margin: 0.5rem 0 0; }

.sd-pos { color: #006100; font-weight: 600; }
.sd-neg { color: #9C0006; font-weight: 600; }

/* Manual refresh button (in dashboard subtitle) */
.sd-refresh-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px; height: 22px;
  margin-left: 6px;
  border: 1px solid #d8dee7;
  background: white;
  border-radius: 50%;
  cursor: pointer;
  font-size: 12px;
  color: #1F4E79;
  transition: transform 0.2s ease, background 0.15s ease;
  vertical-align: middle;
}
.sd-refresh-btn:hover { background: #f0f4f8; transform: rotate(120deg); }
.sd-refresh-btn:disabled { opacity: 0.5; cursor: wait; }

/* ============================================================
   Phase 2/3 — pace hero, sparklines, gauges, history, modal
   ============================================================ */

/* Page header: month context pill on the right */
.sd-page-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 16px;
  flex-wrap: wrap;
}

/* Compact variant — title + refresh + month-context all on one row.
   Added 2026-05-22 so the dashboard hero card slides up under the title
   instead of leaving a gap for a now-collapsed subtitle. */
.sd-page-header-compact {
  align-items: center;
  margin-bottom: 12px;
}
.sd-page-header-compact h1 { margin: 0; }
.sd-page-header-compact .sd-title-block { display: flex; flex-direction: column; gap: 4px; }
.sd-page-header-compact .sd-title-row    { display: flex; align-items: center; gap: 10px; }
.sd-page-header-compact .sd-refresh-slot { display: inline-flex; align-items: center; }
.sd-month-context {
  display: flex;
  gap: 12px;
  font-size: 11px;
  color: #555;
  text-align: right;
}
.sd-month-context .mc-pill {
  padding: 4px 10px;
  background: #f4f6f9;
  border: 1px solid #d8dee7;
  border-radius: 999px;
}
.sd-month-context .mc-pill strong { color: #1F4E79; font-weight: 600; }

/* HERO pace card */
.sd-pace-hero {
  background: linear-gradient(135deg, #1F4E79 0%, #2E6BAC 50%, #5B9BD5 100%);
  color: white;
  border-radius: 12px;
  padding: 22px 24px;
  margin-bottom: 1.25rem;
  position: relative;
  overflow: hidden;
  box-shadow: 0 6px 24px rgba(31, 78, 121, 0.18);
}
.sd-pace-hero::before {
  /* subtle radial accent in the corner */
  content: '';
  position: absolute;
  top: -40%; right: -10%;
  width: 60%; height: 200%;
  background: radial-gradient(circle, rgba(255,255,255,0.06) 0%, transparent 60%);
  pointer-events: none;
}
.sd-pace-headline { display: flex; flex-direction: column; gap: 2px; margin-bottom: 16px; }
.sd-pace-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  opacity: 0.7;
  text-transform: uppercase;
}
.sd-pace-value {
  font-size: 44px;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  animation: sd-fadeUp 0.4s ease-out;
}
.sd-pace-vs-plan {
  font-size: 14px;
  font-weight: 500;
  opacity: 0.92;
  margin-top: 4px;
}
.sd-pace-vs-plan.sd-pace-good    { color: #C6EFCE; }
.sd-pace-vs-plan.sd-pace-warn    { color: #FFEB9C; }
.sd-pace-vs-plan.sd-pace-bad     { color: #FFB3BA; }
.sd-pace-vs-plan.sd-pace-neutral { color: rgba(255,255,255,0.92); }

.sd-pace-track-wrap { margin: 14px 0 18px; }
.sd-pace-track {
  position: relative;
  height: 14px;
  background: rgba(255,255,255,0.18);
  border-radius: 999px;
  overflow: visible;
}
.sd-pace-fill {
  position: absolute;
  top: 0; left: 0;
  height: 100%;
  background: linear-gradient(90deg, #C6EFCE 0%, #ffffff 100%);
  border-radius: 999px;
  transition: width 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
  box-shadow: 0 0 12px rgba(255,255,255,0.4);
  z-index: 2;
}
.sd-pace-fill.sd-pace-fill-bad {
  background: linear-gradient(90deg, #FFB3BA 0%, #ffd6da 100%);
}
.sd-pace-fill.sd-pace-fill-warn {
  background: linear-gradient(90deg, #F2C037 0%, #FFEB9C 100%);
}
/* Ghosted projection extension — sits behind the actual fill, shows where the
   pace puts us by month-end. Stripey to read as "forecast" not "real". */
.sd-pace-projected-fill {
  position: absolute;
  top: 0;
  height: 100%;
  background: repeating-linear-gradient(
    -45deg,
    rgba(255,255,255,0.32) 0,
    rgba(255,255,255,0.32) 4px,
    rgba(255,255,255,0.12) 4px,
    rgba(255,255,255,0.12) 8px
  );
  border-radius: 0 999px 999px 0;
  transition: width 0.6s cubic-bezier(0.2, 0.8, 0.2, 1), left 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
  z-index: 1;
}
.sd-pace-marker {
  position: absolute;
  top: -4px;
  width: 3px;
  height: 22px;
  background: #ffffff;
  border-radius: 2px;
  box-shadow: 0 0 0 2px rgba(31, 78, 121, 0.5);
  z-index: 3;
}
/* Plan-prorated marker — "where you should be by today" if you were perfectly
   on pace. Shorter, dashed, sits inside the track. Visual reference for
   "are we ahead/behind plan pace TODAY" without the projection-doom math. */
.sd-pace-prorated-marker {
  position: absolute;
  top: 1px;
  width: 2px;
  height: 12px;
  background: rgba(255,255,255,0.85);
  border-radius: 1px;
  box-shadow: 0 0 0 1px rgba(31, 78, 121, 0.4);
  z-index: 2;
  transition: left 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.sd-pace-track-labels {
  display: flex;
  justify-content: space-between;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin-top: 6px;
  opacity: 0.85;
}

.sd-pace-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin: 14px 0 18px;
}
@media (max-width: 800px) { .sd-pace-stats { grid-template-columns: repeat(2, 1fr); } }
.sd-pace-stat {
  background: rgba(255,255,255,0.1);
  border-radius: 8px;
  padding: 10px 12px;
}
.sd-pace-stat-label {
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.78;
  margin-bottom: 4px;
}
.sd-pace-stat-value {
  font-size: 18px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.sd-pace-stat-sub {
  font-size: 10px;
  opacity: 0.7;
  margin-top: 2px;
  font-variant-numeric: tabular-nums;
}
/* Stat tiers — colored left edge for at-a-glance pass/fail on the
   Pace-Needed and other operational tiles. */
.sd-pace-stat.sd-pace-stat-good { box-shadow: inset 3px 0 0 #C6EFCE; }
.sd-pace-stat.sd-pace-stat-warn { box-shadow: inset 3px 0 0 #FFEB9C; }
.sd-pace-stat.sd-pace-stat-bad  { box-shadow: inset 3px 0 0 #FFB3BA; }

/* Today strip — a row of "what shipped today vs yesterday" cells. */
.sd-pace-today {
  background: rgba(255,255,255,0.07);
  border-radius: 10px;
  padding: 12px 14px;
  margin-bottom: 14px;
}
.sd-pace-today-head {
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.7;
  margin-bottom: 8px;
  font-weight: 700;
}
.sd-pace-today-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
}
@media (max-width: 800px) { .sd-pace-today-grid { grid-template-columns: repeat(2, 1fr); } }
.sd-pace-today-cell {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.sd-pace-today-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  opacity: 0.78;
}
.sd-pace-today-value {
  font-size: 20px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.sd-pace-today-delta {
  font-size: 11px;
  opacity: 0.85;
}
.sd-pace-today-delta.sd-pace-today-up   { color: #C6EFCE; }
.sd-pace-today-delta.sd-pace-today-down { color: #FFB3BA; }

/* What-changed strip — small chips showing diffs since last refresh. */
.sd-pace-changes {
  background: rgba(255,255,255,0.07);
  border-radius: 10px;
  padding: 10px 14px;
  margin-bottom: 14px;
}
.sd-pace-changes-head {
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.7;
  margin-bottom: 8px;
  font-weight: 700;
}
.sd-pace-changes-list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.sd-pace-change {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-radius: 999px;
  font-size: 12px;
  background: rgba(255,255,255,0.12);
}
.sd-pace-change.sd-pace-change-good { background: rgba(198, 239, 206, 0.22); }
.sd-pace-change.sd-pace-change-bad  { background: rgba(255, 179, 186, 0.22); }
.sd-pace-change-icon { font-size: 13px; }

.sd-pace-chart-wrap { margin-top: 8px; }
.sd-pace-chart {
  display: block;
  width: 100%;
  height: 180px;
  background: rgba(255,255,255,0.06);
  border-radius: 8px;
}
.sd-pace-chart-legend {
  display: flex;
  gap: 18px;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.85;
  margin-top: 6px;
}
.sd-legend-dot {
  display: inline-block;
  width: 10px; height: 10px;
  border-radius: 50%;
  margin-right: 4px;
  vertical-align: middle;
}

/* KPI tile upgrades — icons + sparklines. Hover lift moved to
   .sd-tile-clickable so non-clickable tiles (e.g. Days Safe) stay still. */
.sd-tile {
  position: relative;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.sd-tile-icon {
  position: absolute;
  top: 10px;
  left: 12px;
  font-size: 14px;
  opacity: 0.7;
}
.sd-tile-spark {
  width: 100%;
  height: 22px;
  margin-top: 6px;
  display: block;
}
.sd-tile-value {
  animation: sd-fadeUp 0.35s ease-out;
}
@keyframes sd-fadeUp {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Section-header emoji icons hidden 2026-05-22.
   Scrap page had 17 emoji-prefixed h3s (two adjacent 🥧 pies, etc.) and
   Dashboard had 13 more, all from different font sources. Replaced with a
   unified accent-bar header treatment on .sd-card-head h3 above. Markup
   unchanged (spans still exist) — reverse by removing display:none. */
.sd-h-icon {
  display: inline-flex;
  align-items: center;
  vertical-align: -3px;
  margin-right: 7px;
  color: var(--color-accent, #4F46E5);
}
.sd-h-icon svg { display: block; }
.sd-card-hint {
  font-size: 11px;
  color: #888;
  font-style: italic;
  margin: -0.25rem 0 0.5rem;
}

/* Trend column — for table rows w/ inline sparkline */
.sd-trend-cell {
  text-align: center;
  vertical-align: middle;
  width: 100px;
}
.sd-trend-spark {
  width: 80px;
  height: 22px;
  display: inline-block;
  vertical-align: middle;
}

/* Clickable rows */
.sd-table-clickable tbody tr { cursor: pointer; }
.sd-table-clickable tbody tr:hover {
  background: rgba(91, 155, 213, 0.12);
}

/* Inventory dial gauges */
.sd-gauges {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 16px;
  padding: 8px 0;
}
@media (max-width: 600px) { .sd-gauges { grid-template-columns: 1fr; } }
.sd-gauge {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 12px 8px;
  border: 1px solid #eaeaea;
  border-radius: 8px;
  background: #fafbfc;
}
.sd-gauge-svg { width: 100%; max-width: 160px; height: auto; }
.sd-gauge-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #555;
  margin-bottom: 6px;
  min-height: 28px;
  display: flex; align-items: center;
}
.sd-gauge-value {
  font-size: 16px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: #1a1a1a;
  margin-top: 2px;
}
.sd-gauge-range {
  font-size: 10px;
  color: #777;
  margin-top: 2px;
}
.sd-gauge-status {
  margin-top: 8px;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 10px;
  border-radius: 999px;
}
.sd-gauge-info {
  background: #f0f0f0;
  border-radius: 8px;
  padding: 16px 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.sd-gauge-info .sd-gauge-label { color: #555; }
.sd-gauge-info .sd-gauge-value { font-size: 22px; }

/* Multi-year trends grid */
.sd-history-card { background: #fafbfc; }
.sd-history-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
  margin-top: 8px;
}
@media (max-width: 800px) { .sd-history-grid { grid-template-columns: 1fr; } }
.sd-history-tile {
  background: white;
  border: 1px solid #e6e9ee;
  border-radius: 8px;
  padding: 12px;
  position: relative;
}
.sd-history-tile-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 4px;
}
.sd-history-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #555;
  text-transform: uppercase;
}
.sd-history-current {
  font-size: 14px;
  font-weight: 700;
  color: #1F4E79;
  font-variant-numeric: tabular-nums;
}
.sd-history-callout {
  font-size: 11px;
  color: #888;
  margin-top: 2px;
  margin-bottom: 4px;
  font-style: italic;
}
.sd-history-chart {
  width: 100%;
  height: 130px;
  display: block;
}
.sd-history-callout {
  font-size: 11px;
  color: #555;
  margin-top: 2px;
  margin-bottom: 4px;
}

/* Modal */
.sd-modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 24, 38, 0.6);
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  animation: sd-overlay-in 0.18s ease-out;
}
.sd-modal-overlay[hidden] { display: none !important; }
@keyframes sd-overlay-in { from { opacity: 0; } to { opacity: 1; } }
.sd-modal {
  background: white;
  border-radius: 12px;
  max-width: 720px;
  width: 100%;
  max-height: 86vh;
  overflow: auto;
  position: relative;
  box-shadow: 0 20px 60px rgba(0,0,0,0.3);
  animation: sd-modal-in 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
}
@keyframes sd-modal-in { from { opacity: 0; transform: scale(0.96) translateY(8px); } to { opacity: 1; transform: none; } }
.sd-modal-close {
  position: absolute;
  top: 8px; right: 12px;
  background: none;
  border: none;
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
  color: #777;
  padding: 4px 8px;
  z-index: 1;
}
.sd-modal-close:hover { color: #1a1a1a; }
.sd-modal-body { padding: 22px 26px; }
.sd-modal-body h2 { margin: 0 0 4px; font-size: 22px; font-weight: 700; }
.sd-modal-body h2 .sd-modal-pn { color: #1F4E79; font-variant-numeric: tabular-nums; }
.sd-modal-header-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.sd-modal-p360-link {
  font-size: 12px;
  font-weight: 600;
  color: #4F46E5;
  text-decoration: none;
  padding: 4px 10px;
  border: 1px solid #C7D2FE;
  border-radius: 6px;
  background: #EEF2FF;
  white-space: nowrap;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.sd-modal-p360-link:hover { background: #E0E7FF; border-color: #A5B4FC; }
.sd-modal-body h3 { margin: 18px 0 6px; font-size: 13px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: #555; }
.sd-modal-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin: 12px 0; }
.sd-modal-stat { background: #f5f7fa; border-radius: 6px; padding: 8px 10px; }
.sd-modal-stat-label { font-size: 10px; color: #777; letter-spacing: 0.06em; text-transform: uppercase; }
.sd-modal-stat-value { font-size: 16px; font-weight: 700; color: #1a1a1a; font-variant-numeric: tabular-nums; }
.sd-modal-quotes-table { width: 100%; font-size: 12px; border-collapse: collapse; }
.sd-modal-quotes-table th, .sd-modal-quotes-table td { padding: 5px 6px; border-bottom: 1px solid #eee; text-align: left; }
.sd-modal-quotes-table th { background: #5B9BD5; color: white; font-size: 10px; letter-spacing: 0.04em; text-transform: uppercase; }
.sd-modal-empty { color: #888; font-style: italic; padding: 8px 0; }

/* Mobile polish — ensure tile grid stacks earlier on phone */
@media (max-width: 720px) {
  .sd-kpi-grid { grid-template-columns: 1fr 1fr; gap: 8px; }
  .sd-tile-value { font-size: 22px; }
  .sd-pace-value { font-size: 32px; }
  .sd-pace-stats { grid-template-columns: 1fr 1fr; }
  .sd-table { font-size: 12px; }
  .sd-table th, .sd-table td { padding: 4px 5px; }
}
@media (max-width: 480px) {
  .sd-kpi-grid { grid-template-columns: 1fr; }
}

/* Dashboard trust/polish pass, scoped to the shop dashboard only.
   Inspired by shadcn/ui's restrained card/table language: small radius,
   clear borders, quiet surfaces, strong hierarchy, and fewer heavy fills. */
[data-view="shop-dashboard"] {
  --sd-surface: #ffffff;
  --sd-muted-surface: #f8fafc;
  --sd-border: #dbe4ee;
  --sd-border-soft: #e7edf4;
  --sd-text: #172331;
  --sd-muted: #64748b;
  --sd-blue: #174f82;
  --sd-blue-soft: #e8f1fb;
  --sd-shadow: 0 1px 2px rgba(15, 44, 74, 0.05), 0 12px 28px rgba(15, 44, 74, 0.08);
}

/* Title block moved INTO the hero card, pinned top-right 2026-06-12.
   Refresh sits left of the text (markup order). The standalone page-header
   was retired — date pills were redundant with the topbar calendar pill. */
[data-view="shop-dashboard"] .sd-hero-title {
  position: absolute;
  top: 22px;
  right: 24px;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 10px;
}

[data-view="shop-dashboard"] .sd-hero-title h1 {
  margin: 0;
  color: var(--sd-text);
  font-size: 26px;
  font-weight: 750;
  letter-spacing: 0;
}

[data-view="shop-dashboard"] .sd-month-context {
  align-items: center;
  color: var(--sd-muted);
  gap: 8px;
}

[data-view="shop-dashboard"] .sd-month-context .mc-pill {
  background: var(--sd-surface);
  border: 1px solid var(--sd-border);
  border-radius: 999px;
  box-shadow: 0 1px 2px rgba(15, 44, 74, 0.04);
  color: var(--sd-muted);
  padding: 6px 11px;
}

[data-view="shop-dashboard"] .sd-month-context .mc-pill strong {
  color: var(--sd-blue);
}

[data-view="shop-dashboard"] .sd-refresh-btn {
  border-color: var(--sd-border);
  box-shadow: 0 1px 2px rgba(15, 44, 74, 0.04);
  height: 28px;
  width: 28px;
}

[data-view="shop-dashboard"] .sd-pace-hero {
  background: var(--sd-surface);
  border: 1px solid var(--sd-border);
  border-radius: 8px;
  box-shadow: var(--sd-shadow);
  color: var(--sd-text);
  padding: 24px;
}

[data-view="shop-dashboard"] .sd-pace-hero::before {
  display: none;
}

[data-view="shop-dashboard"] .sd-pace-label,
[data-view="shop-dashboard"] .sd-pace-today-head,
[data-view="shop-dashboard"] .sd-pace-changes-head,
[data-view="shop-dashboard"] .sd-pace-stat-label {
  letter-spacing: 0;
  opacity: 1;
  color: var(--sd-muted);
}

[data-view="shop-dashboard"] .sd-pace-value {
  color: var(--sd-text);
  font-size: 42px;
  font-weight: 800;
  letter-spacing: 0;
}

[data-view="shop-dashboard"] .sd-pace-vs-plan {
  color: var(--sd-muted);
}

[data-view="shop-dashboard"] .sd-pace-vs-plan.sd-pace-good,
[data-view="shop-dashboard"] .sd-pace-vs-plan.sd-pace-neutral {
  color: var(--prism-green);
}

[data-view="shop-dashboard"] .sd-pace-vs-plan.sd-pace-warn {
  color: var(--prism-amber);
}

[data-view="shop-dashboard"] .sd-pace-vs-plan.sd-pace-bad {
  color: var(--prism-red);
}

[data-view="shop-dashboard"] .sd-pace-track {
  background: #e8eef5;
  height: 12px;
}

[data-view="shop-dashboard"] .sd-pace-fill {
  background: linear-gradient(90deg, #0f766e 0%, #2563eb 100%);
  box-shadow: none;
}

[data-view="shop-dashboard"] .sd-pace-marker {
  background: var(--sd-text);
  box-shadow: 0 0 0 3px #ffffff, 0 0 0 4px var(--sd-border);
  height: 24px;
  top: -6px;
}

[data-view="shop-dashboard"] .sd-pace-prorated-marker {
  background: var(--prism-amber);
  box-shadow: 0 0 0 3px #ffffff, 0 0 0 4px rgba(154, 91, 0, 0.22);
  height: 18px;
  top: -3px;
  width: 3px;
}

[data-view="shop-dashboard"] .sd-pace-track-labels {
  color: var(--sd-muted);
  display: grid;
  gap: 8px;
  grid-template-columns: auto auto auto auto;
  letter-spacing: 0;
  opacity: 0.82;
  text-transform: none;
}

[data-view="shop-dashboard"] .sd-pace-track-labels span:nth-child(2),
[data-view="shop-dashboard"] .sd-pace-track-labels span:nth-child(3) {
  text-align: center;
}

[data-view="shop-dashboard"] .sd-pace-track-labels span:last-child {
  text-align: right;
}

[data-view="shop-dashboard"] .sd-pace-stat,
[data-view="shop-dashboard"] .sd-pace-today,
[data-view="shop-dashboard"] .sd-pace-changes {
  background: var(--sd-muted-surface);
  border: 1px solid var(--sd-border);
  border-radius: 8px;
}

[data-view="shop-dashboard"] .sd-pace-stat-value,
[data-view="shop-dashboard"] .sd-pace-today-value {
  color: var(--sd-text);
}

[data-view="shop-dashboard"] .sd-pace-stat-sub,
[data-view="shop-dashboard"] .sd-pace-today-delta {
  color: var(--sd-muted);
  opacity: 1;
}

[data-view="shop-dashboard"] .sd-pace-today-delta.sd-pace-today-up {
  color: var(--prism-green);
}

[data-view="shop-dashboard"] .sd-pace-today-delta.sd-pace-today-down {
  color: var(--prism-red);
}

[data-view="shop-dashboard"] .sd-pace-chart {
  background: linear-gradient(180deg, #f8fafc 0%, #ffffff 100%);
  border: 1px solid var(--sd-border);
  border-radius: 8px;
}

[data-view="shop-dashboard"] .sd-pace-chart-legend {
  color: var(--sd-muted);
  letter-spacing: 0;
  opacity: 1;
}

[data-view="shop-dashboard"] .sd-pace-chart-legend .sd-legend-dot {
  border: 1px solid var(--sd-border);
}

[data-view="shop-dashboard"] .sd-pace-chart-legend span:nth-child(1) .sd-legend-dot {
  background: #2563eb !important;
}

[data-view="shop-dashboard"] .sd-pace-chart-legend span:nth-child(2) .sd-legend-dot {
  background: #94a3b8 !important;
}

[data-view="shop-dashboard"] .sd-pace-chart-legend span:nth-child(3) .sd-legend-dot {
  background: #38bdf8 !important;
}

[data-view="shop-dashboard"] .sd-kpi-grid {
  align-items: stretch;
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin-bottom: 16px;
}

[data-view="shop-dashboard"] .sd-kpi-group {
  background: var(--sd-surface);
  border: 1px solid var(--sd-border);
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(15, 44, 74, 0.04);
  margin-bottom: 0;
  min-width: 0;
  padding: 12px;
}

[data-view="shop-dashboard"] .sd-kpi-group:last-child {
  grid-column: 1 / -1;
}

[data-view="shop-dashboard"] .sd-kpi-group-label {
  color: var(--sd-muted);
  letter-spacing: 0;
  margin: 0 0 10px;
}

[data-view="shop-dashboard"] .sd-kpi-row,
[data-view="shop-dashboard"] .sd-kpi-group:last-child .sd-kpi-row {
  gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
}

[data-view="shop-dashboard"] .sd-tile {
  align-items: flex-start;
  background: var(--sd-muted-surface);
  border: 1px solid var(--sd-border-soft);
  border-radius: 8px;
  box-shadow: none;
  justify-content: flex-start;
  min-height: 120px;
  min-width: 0;
  overflow: hidden;
  padding: 14px 14px 12px;
  text-align: left;
}

[data-view="shop-dashboard"] .sd-tile-label {
  color: var(--sd-muted);
  letter-spacing: 0;
  margin-left: 28px;
}

[data-view="shop-dashboard"] .sd-tile-value {
  color: var(--sd-text);
  font-size: 28px;
  font-weight: 800;
  letter-spacing: 0;
  max-width: 100%;
  overflow-wrap: anywhere;
  text-align: left;
}

[data-view="shop-dashboard"] .sd-tile-delta {
  color: var(--sd-muted);
  font-style: normal;
  line-height: 1.3;
  overflow-wrap: anywhere;
}

[data-view="shop-dashboard"] .sd-tile.sd-good,
[data-view="shop-dashboard"] .sd-tile.sd-warn,
[data-view="shop-dashboard"] .sd-tile.sd-bad {
  background: var(--sd-muted-surface);
}

[data-view="shop-dashboard"] .sd-tile.sd-good { border-left: 4px solid var(--prism-green); }
[data-view="shop-dashboard"] .sd-tile.sd-warn { border-left: 4px solid var(--prism-amber); }
[data-view="shop-dashboard"] .sd-tile.sd-bad  { border-left: 4px solid var(--prism-red); }

[data-view="shop-dashboard"] .sd-tile.sd-good .sd-tile-value { color: var(--prism-green); }
[data-view="shop-dashboard"] .sd-tile.sd-warn .sd-tile-value { color: var(--prism-amber); }
[data-view="shop-dashboard"] .sd-tile.sd-bad .sd-tile-value  { color: var(--prism-red); }

[data-view="shop-dashboard"] .sd-tile-icon {
  color: var(--sd-muted);
  left: 14px;
  opacity: 0.78;
  top: 14px;
}

[data-view="shop-dashboard"] .sd-tile-clickable:hover {
  border-color: var(--sd-blue);
  box-shadow: 0 8px 20px rgba(15, 44, 74, 0.10);
  transform: translateY(-1px);
}

[data-view="shop-dashboard"] .sd-card,
[data-view="shop-dashboard"] .sd-action-strip {
  background: var(--sd-surface);
  border: 1px solid var(--sd-border);
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(15, 44, 74, 0.04);
  padding: 16px 18px;
}

[data-view="shop-dashboard"] .sd-card-head {
  align-items: flex-start;
  gap: 12px;
}

[data-view="shop-dashboard"] .sd-card-head h3 {
  border-left-color: var(--sd-blue);
  color: var(--sd-text);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0;
}

[data-view="shop-dashboard"] .sd-card-hint {
  color: var(--sd-muted);
  font-style: normal;
}

[data-view="shop-dashboard"] .sd-pill,
[data-view="shop-dashboard"] .sd-action-summary,
[data-view="shop-dashboard"] .sd-status {
  border-radius: 999px;
  font-weight: 700;
  letter-spacing: 0;
}

[data-view="shop-dashboard"] .sd-action-strip {
  border-left: 4px solid var(--prism-amber);
}

[data-view="shop-dashboard"] .sd-action-title {
  color: var(--sd-text);
  letter-spacing: 0;
}

[data-view="shop-dashboard"] .sd-action-item {
  background: var(--sd-muted-surface);
  border: 1px solid var(--sd-border-soft);
  border-left-width: 4px;
  border-radius: 8px;
}

[data-view="shop-dashboard"] .sd-action-item-title {
  color: var(--sd-text);
  font-weight: 700;
}

[data-view="shop-dashboard"] .sd-action-item-sub {
  color: var(--sd-muted);
}

[data-view="shop-dashboard"] .sd-table {
  border-collapse: separate;
  border-spacing: 0;
  font-size: 13px;
}

[data-view="shop-dashboard"] .sd-table th {
  background: var(--sd-muted-surface);
  border-bottom: 1px solid var(--sd-border);
  color: var(--sd-muted);
  letter-spacing: 0;
}

[data-view="shop-dashboard"] .sd-table td {
  border-bottom: 1px solid var(--sd-border-soft);
  color: var(--sd-text);
  padding: 8px 10px;
}

[data-view="shop-dashboard"] .sd-table-clickable tbody tr:hover {
  background: var(--sd-blue-soft);
}

[data-view="shop-dashboard"] .sd-table tr.sd-row-bad,
[data-view="shop-dashboard"] .sd-table tr.sd-row-warn,
[data-view="shop-dashboard"] .sd-table tr.sd-row-good {
  background: transparent;
}

[data-view="shop-dashboard"] .sd-stacked-bar,
[data-view="shop-dashboard"] .sd-bar-track {
  background: #e5eaf1;
  border-radius: 999px;
}

@media (max-width: 980px) {
  [data-view="shop-dashboard"] .sd-kpi-grid {
    grid-template-columns: 1fr;
  }

  [data-view="shop-dashboard"] .sd-kpi-group:last-child {
    grid-column: auto;
  }
}

@media (max-width: 720px) {
  /* Drop the title out of absolute-positioning so it stacks above the
     headline instead of colliding with the (smaller) $-value. */
  [data-view="shop-dashboard"] .sd-hero-title {
    position: static;
    justify-content: flex-end;
    margin-bottom: 8px;
  }
  [data-view="shop-dashboard"] .sd-hero-title h1 {
    font-size: 22px;
  }

  [data-view="shop-dashboard"] .sd-pace-value {
    font-size: 34px;
  }

  [data-view="shop-dashboard"] .sd-pace-stats,
  [data-view="shop-dashboard"] .sd-pace-today-grid {
    grid-template-columns: 1fr;
  }

  [data-view="shop-dashboard"] .sd-pace-track-labels {
    grid-template-columns: 1fr 1fr;
  }

  [data-view="shop-dashboard"] .sd-pace-track-labels span {
    text-align: left !important;
  }
}

/* ============================================================
   Scrap dashboard — disposition bar, daily chart, hero variant
   ============================================================ */
/* Pulse — shadcn-inspired readable trend surface. Mirrors the dashboard's
   quiet component treatment while making "what changed" visible first. */
section[data-view="pulse"] {
  --sd-surface: #ffffff;
  --sd-muted-surface: #f8fafc;
  --sd-border: #dbe4ee;
  --sd-border-soft: #e7edf4;
  --sd-text: #172331;
  --sd-muted: #64748b;
  --sd-blue: #174f82;
  --sd-blue-soft: #e8f1fb;
  --sd-shadow: 0 1px 2px rgba(15, 44, 74, 0.05), 0 12px 28px rgba(15, 44, 74, 0.07);
  background: linear-gradient(180deg, #f8fafc 0%, #eef3f8 52%, #f8fafc 100%);
  padding: 18px 20px 28px;
}

section[data-view="pulse"] .sd-page-header {
  align-items: flex-start;
  background: transparent;
  border: 0;
  margin-bottom: 14px;
}

section[data-view="pulse"] .sd-page-header h1 {
  color: var(--sd-text);
  font-size: 30px;
  font-weight: 750;
  letter-spacing: 0;
}

section[data-view="pulse"] .page-subtitle {
  color: var(--sd-muted);
  max-width: 680px;
}

section[data-view="pulse"] .sd-month-context {
  align-items: center;
  color: var(--sd-muted);
  gap: 8px;
}

section[data-view="pulse"] .sd-month-context .mc-pill {
  background: var(--sd-surface);
  border: 1px solid var(--sd-border);
  border-radius: 999px;
  box-shadow: 0 1px 2px rgba(15, 44, 74, 0.04);
  color: var(--sd-muted);
  padding: 6px 11px;
}

section[data-view="pulse"] .sd-month-context .mc-pill strong {
  color: var(--sd-blue);
}

.pulse-brief {
  background: linear-gradient(180deg, #ffffff 0%, #f9fbfd 100%);
  border: 1px solid var(--sd-border);
  border-radius: 8px;
  box-shadow: var(--sd-shadow);
  margin-bottom: 14px;
  padding: 16px;
}

.pulse-brief-head {
  align-items: flex-start;
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.pulse-eyebrow {
  color: var(--sd-muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: uppercase;
}

.pulse-brief h2 {
  color: var(--sd-text);
  font-size: 18px;
  line-height: 1.2;
  margin: 2px 0 0;
}

.pulse-brief-grid {
  display: grid;
  gap: 10px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.pulse-brief-card {
  align-items: flex-start;
  background: #ffffff;
  border: 1px solid var(--sd-border-soft);
  border-left: 4px solid var(--sd-border);
  border-radius: 8px;
  display: flex;
  gap: 10px;
  min-height: 112px;
  min-width: 0;
  padding: 12px;
}

.pulse-brief-card.pulse-good { border-left-color: var(--prism-green); }
.pulse-brief-card.pulse-bad { border-left-color: var(--prism-red); }
.pulse-brief-card.pulse-neutral { border-left-color: var(--sd-blue); }

.pulse-brief-icon {
  align-items: center;
  background: var(--sd-muted-surface);
  border: 1px solid var(--sd-border);
  border-radius: 8px;
  color: var(--sd-muted);
  display: inline-flex;
  flex: 0 0 auto;
  height: 32px;
  justify-content: center;
  width: 32px;
}

.pulse-good .pulse-brief-icon { color: var(--prism-green); }
.pulse-bad .pulse-brief-icon { color: var(--prism-red); }

.pulse-brief-copy {
  min-width: 0;
}

.pulse-brief-title {
  color: var(--sd-muted);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.25;
}

.pulse-brief-value {
  color: var(--sd-text);
  font-size: 22px;
  font-weight: 800;
  line-height: 1.1;
  margin-top: 4px;
  overflow-wrap: anywhere;
}

.pulse-brief-meta {
  color: var(--sd-muted);
  font-size: 12px;
  line-height: 1.35;
  margin-top: 6px;
}

.pulse-loading {
  color: var(--sd-muted);
  grid-column: 1 / -1;
  min-height: auto;
}

section[data-view="pulse"] .sd-card,
section[data-view="pulse"] .sd-history-card {
  background: var(--sd-surface);
  border: 1px solid var(--sd-border);
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(15, 44, 74, 0.04);
  padding: 16px 18px;
}

section[data-view="pulse"] .sd-two-col {
  gap: 14px;
}

section[data-view="pulse"] .sd-card-head {
  align-items: flex-start;
  gap: 12px;
}

section[data-view="pulse"] .sd-card-head h3 {
  border-left-color: var(--sd-blue);
  color: var(--sd-text);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0;
}

section[data-view="pulse"] .sd-card-hint {
  color: var(--sd-muted);
  font-style: normal;
}

section[data-view="pulse"] .sd-pill,
section[data-view="pulse"] .sd-status {
  border-radius: 999px;
  font-weight: 700;
  letter-spacing: 0;
}

section[data-view="pulse"] .sd-table {
  border-collapse: separate;
  border-spacing: 0;
  font-size: 13px;
}

section[data-view="pulse"] .sd-table th {
  background: var(--sd-muted-surface);
  border-bottom: 1px solid var(--sd-border);
  color: var(--sd-muted);
  letter-spacing: 0;
  text-transform: none;
}

section[data-view="pulse"] .sd-table td {
  border-bottom: 1px solid var(--sd-border-soft);
  color: var(--sd-text);
  padding: 9px 10px;
  vertical-align: middle;
}

section[data-view="pulse"] .sd-table tbody tr:hover {
  background: #f8fafc;
}

section[data-view="pulse"] .sd-table tr.sd-row-watch,
section[data-view="pulse"] .sd-table tr.sd-row-steady {
  background: transparent;
}

section[data-view="pulse"] .sd-table tr.sd-row-watch td:first-child {
  box-shadow: inset 3px 0 0 var(--prism-red);
}

section[data-view="pulse"] .sd-table tr.sd-row-steady td:first-child {
  box-shadow: inset 3px 0 0 var(--prism-green);
}

section[data-view="pulse"] .sd-pos { color: var(--prism-green); }
section[data-view="pulse"] .sd-neg { color: var(--prism-red); }

section[data-view="pulse"] .chart-container {
  background: linear-gradient(180deg, #f8fafc 0%, #ffffff 100%);
  border: 1px solid var(--sd-border);
  border-radius: 8px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
  padding: 12px;
}

section[data-view="pulse"] .qva-card .chart-container {
  background: #ffffff;
}

section[data-view="pulse"] .sd-gauge,
section[data-view="pulse"] .sd-gauge-info,
section[data-view="pulse"] .sd-history-tile {
  background: #ffffff;
  border: 1px solid var(--sd-border-soft);
  border-radius: 8px;
  box-shadow: none;
}

section[data-view="pulse"] .sd-history-title,
section[data-view="pulse"] .sd-gauge-label {
  color: var(--sd-muted);
  letter-spacing: 0;
}

section[data-view="pulse"] .sd-history-current,
section[data-view="pulse"] .sd-gauge-value {
  color: var(--sd-text);
}

section[data-view="pulse"] .sd-history-callout {
  background: var(--sd-muted-surface);
  border: 1px solid var(--sd-border-soft);
  border-radius: 6px;
  color: var(--sd-muted);
  font-style: normal;
  padding: 5px 7px;
}

section[data-view="pulse"] .qva-shape-pills {
  gap: 8px;
}

section[data-view="pulse"] .qva-pill,
section[data-view="pulse"] .qva-search-input {
  background: #ffffff;
  border-color: var(--sd-border);
  border-radius: 8px;
}

section[data-view="pulse"] .qva-pill:hover,
section[data-view="pulse"] .qva-search-row:hover {
  background: #f8fafc;
}

section[data-view="pulse"] .qva-pill.active {
  background: #eef6ff;
  border-color: #9cc6ee;
  color: var(--sd-blue);
}

@media (max-width: 1100px) {
  .pulse-brief-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 720px) {
  section[data-view="pulse"] .sd-page-header h1 {
    font-size: 26px;
  }

  .pulse-brief-head {
    align-items: flex-start;
    flex-direction: column;
  }

  .pulse-brief-grid {
    grid-template-columns: 1fr;
  }
}

.scrap-hero {
  background: linear-gradient(135deg, #5C1F1F 0%, #8C2828 50%, #B85A5A 100%);
  box-shadow: 0 6px 24px rgba(140, 40, 40, 0.18);
}
.scrap-disposition-bar {
  display: flex;
  height: 36px;
  border-radius: 10px;
  overflow: hidden;
  background: rgba(255,255,255,0.12);
  margin: 14px 0 18px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.scrap-disposition-segment {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 4px 6px;
  color: white;
  transition: width 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
  min-width: 0;
  overflow: hidden;
}
.scrap-disposition-segment.seg-scrap  { background: #9C0006; }
.scrap-disposition-segment.seg-rework { background: #D69200; }
.scrap-disposition-segment.seg-stock  { background: #5B9BD5; }
.scrap-disposition-segment .seg-label { font-size: 9px; opacity: 0.9; line-height: 1.1; }
.scrap-disposition-segment .seg-value { font-size: 14px; font-weight: 700; }

/* Scrap KPI grid — 4 tiles instead of 8 */
.scrap-kpi-grid { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 900px) { .scrap-kpi-grid { grid-template-columns: repeat(2, 1fr); } }

/* Daily fallout — split layout (cumulative line + calendar heatmap) */
/* Disposition Confirmation Dashboard — Total / Confirmed / Unconfirmed matrix */
.scrap-disp-table { width: 100%; max-width: 620px; }
.scrap-disp-table th.sd-num { text-align: right; }
.scrap-disp-table td.scrap-disp-metric { text-align: left; font-weight: 600; color: var(--prism-text); }
.scrap-disp-table tr.scrap-disp-conf   { background: rgba(198,239,206,0.35); }
.scrap-disp-table tr.scrap-disp-unconf { background: rgba(255,199,206,0.35); }
.scrap-disp-table tr.scrap-disp-conf   td.sd-num { color: #1e7d3c; font-weight: 600; }
.scrap-disp-table tr.scrap-disp-unconf td.sd-num { color: #9C0006; font-weight: 600; }

/* All Parts This Month — scroll-capped + click-to-sort headers */
.scrap-allparts-wrap { max-height: 420px; overflow-y: auto; }
.scrap-allparts-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}
.scrap-allparts-table th.sd-num { text-align: right; }
.scrap-ap-th:hover { background: #4a86c4; }
.scrap-ap-th.sorted { background: #3f78b3; }
.scrap-ap-th[data-dir="desc"]::after { content: " \25be"; font-size: 9px; opacity: 0.9; }
.scrap-ap-th[data-dir="asc"]::after  { content: " \25b4"; font-size: 9px; opacity: 0.9; }

.scrap-daily-split {
  display: grid;
  grid-template-columns: 1.3fr 1fr;
  gap: 18px;
  margin-top: 8px;
}
@media (max-width: 980px) { .scrap-daily-split { grid-template-columns: 1fr; } }

.scrap-daily-panel {
  background: #fafbfc;
  border-radius: 8px;
  padding: 12px;
}
.scrap-daily-panel-title {
  margin: 0 0 4px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #1F4E79;
}
/* Chart panel is a flex column so the legend can sit flush at the bottom-left */
.scrap-cumul-panel {
  display: flex;
  flex-direction: column;
}
.scrap-cumul-chart {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 880 / 340;
}
.scrap-cumul-legend {
  display: flex;
  gap: 14px;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #666;
  margin-top: auto;
  padding-top: 10px;
  flex-wrap: wrap;
}
.scrap-cumul-legend .leg-dot {
  display: inline-block;
  width: 18px; height: 3px;
  margin-right: 5px;
  vertical-align: middle;
  border-radius: 2px;
}

/* Calendar header — title row + month nav arrows */
.scrap-cal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
}
.scrap-cal-header .scrap-daily-panel-title { margin: 0; }
.scrap-cal-nav {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.scrap-cal-nav-btn {
  background: white;
  border: 1px solid #d8dee7;
  width: 24px;
  height: 24px;
  border-radius: 6px;
  font-size: 14px;
  color: #1F4E79;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  transition: background 0.12s ease;
}
.scrap-cal-nav-btn:hover { background: #f0f4f8; }
.scrap-cal-nav-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.scrap-cal-month-label {
  font-size: 12px;
  font-weight: 700;
  color: #1F4E79;
  letter-spacing: 0.04em;
  min-width: 80px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* Calendar heatmap */
.scrap-cal-wrap {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
  font-size: 10px;
}
.scrap-cal-day-name {
  text-align: center;
  font-weight: 700;
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #888;
  padding: 2px 0;
}
.scrap-cal-cell {
  aspect-ratio: 1 / 1;
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: space-between;
  padding: 4px 5px;
  font-size: 10px;
  color: #333;
  position: relative;
  background: #f0f0f0;
  border: 1px solid #e8e8e8;
  cursor: default;
  transition: transform 0.1s ease;
}
.scrap-cal-cell:hover { transform: scale(1.05); z-index: 1; }
.scrap-cal-cell.future {
  background: repeating-linear-gradient(45deg, #f7f7f7, #f7f7f7 4px, #efefef 4px, #efefef 8px);
  color: #aaa;
}
.scrap-cal-cell.weekend { background: #f0f4f8; }
.scrap-cal-cell.empty {
  background: transparent;
  border: none;
}
.scrap-cal-cell .cal-day {
  font-weight: 700;
  font-size: 11px;
  color: inherit;
}
.scrap-cal-cell .cal-amount {
  font-size: 9px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  align-self: flex-end;
}
.scrap-cal-cell.has-data {
  color: white;
}
.scrap-cal-cell.has-data .cal-day { color: white; }
.scrap-cal-cell.today {
  outline: 2px solid #1F4E79;
  outline-offset: 1px;
}

/* Chronic offenders — emphasize danger */
.scrap-chronic-card {
  border-left: 4px solid #9C0006;
}
.scrap-chronic-card .sd-card-head h3 { color: #9C0006; }

/* Share-by-part pie chart + legend */
.scrap-pie-wrap {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 16px;
  align-items: center;
  margin-top: 6px;
}
@media (max-width: 700px) {
  .scrap-pie-wrap { grid-template-columns: 1fr; }
}
.scrap-pie {
  width: 100%;
  max-width: 280px;
  height: auto;
  display: block;
}
.scrap-pie-legend {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.scrap-pie-legend .pie-row {
  display: grid;
  grid-template-columns: 14px 60px 1fr 60px;
  gap: 6px;
  align-items: center;
  cursor: default;
}
.scrap-pie-legend .pie-swatch {
  width: 12px; height: 12px; border-radius: 2px;
}
.scrap-pie-legend .pie-pn {
  font-weight: 600;
  color: #1a1a1a;
}
.scrap-pie-legend .pie-pct {
  text-align: right;
  color: #555;
  font-weight: 600;
}
.scrap-pie-legend .pie-amt {
  text-align: right;
  color: #888;
  font-size: 11px;
}
.scrap-pie-slice { transition: opacity 0.15s ease; }
.scrap-pie-slice:hover { opacity: 0.85; }

/* Inline disposition mix bar (for table cells) — fills available column width */
.scrap-mix {
  display: flex;
  height: 12px;
  width: 100%;
  min-width: 80px;
  max-width: 320px;
  border-radius: 3px;
  overflow: hidden;
  background: #eee;
  vertical-align: middle;
  margin-right: 6px;
}
.scrap-mix > span { display: block; height: 100%; }
/* Make the MIX column take available space in the top-10 tables */
#scrapTop10FalloutTable th:nth-child(5),
#scrapTop10FalloutTable td:nth-child(5),
#scrapTop10ScrapTable th:nth-child(5),
#scrapTop10ScrapTable td:nth-child(5) {
  width: 30%;
  min-width: 140px;
}
.scrap-mix .seg-scrap  { background: #9C0006; }
.scrap-mix .seg-rework { background: #D69200; }
.scrap-mix .seg-stock  { background: #5B9BD5; }

/* Frequency bar (for chronic offenders — N of 6 months) */
.scrap-freq-cell { display: flex; align-items: center; gap: 6px; }
.scrap-freq-bar {
  display: inline-block;
  height: 8px;
  width: 80px;
  background: #eee;
  border-radius: 3px;
  overflow: hidden;
}
.scrap-freq-bar > span {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, #9C0006, #D69200);
}

/* ============================================================
   JobBOSS Scrap Detail — bars, heatmap, segmented toggle
   ============================================================ */
.jbs-card {
  background: linear-gradient(180deg, #fafbfc 0%, white 100%);
  border-left: 4px solid #1F4E79;
}
.jbs-stats-row {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 12px;
  margin-top: 8px;
}
@media (max-width: 900px) { .jbs-stats-row { grid-template-columns: repeat(2, 1fr); } }
.jbs-stat {
  background: white;
  border: 1px solid #e6e9ee;
  border-radius: 6px;
  padding: 8px 10px;
}
.jbs-stat-label {
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #888;
}
.jbs-stat-value {
  font-size: 18px;
  font-weight: 700;
  color: #1F4E79;
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
}
.jbs-stat-sub { font-size: 10px; color: #999; }
.jbs-stat.bad .jbs-stat-value { color: #9C0006; }

/* Segmented toggle (This Month / All-Time) */
.jbs-toggle {
  display: inline-flex;
  background: #f0f4f8;
  border-radius: 6px;
  padding: 2px;
  gap: 1px;
}
.jbs-toggle-btn {
  background: transparent;
  border: 0;
  padding: 4px 10px;
  border-radius: 4px;
  font-size: 11px;
  font-weight: 600;
  color: #666;
  cursor: pointer;
  letter-spacing: 0.04em;
  transition: background 0.12s ease, color 0.12s ease;
}
.jbs-toggle-btn:hover { color: #1F4E79; }
.jbs-toggle-btn.active {
  background: #1F4E79;
  color: white;
}

/* Horizontal bars (reasons + work centers) */
.jbs-bars {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 6px;
}
.jbs-bar-row {
  display: grid;
  grid-template-columns: 130px 1fr 90px;
  gap: 8px;
  align-items: center;
  font-size: 12px;
}
.jbs-bar-label {
  color: #1a1a1a;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-align: right;
}
.jbs-bar-track {
  display: block;
  background: #f0f4f8;
  border-radius: 4px;
  height: 18px;
  overflow: hidden;
  position: relative;
  min-width: 0;
}
.jbs-bar-fill {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, #1F4E79, #5B9BD5);
  border-radius: 4px;
  transition: width 0.4s cubic-bezier(0.2, 0.8, 0.2, 1);
  min-width: 2px;
}
.jbs-bar-row.danger .jbs-bar-fill {
  background: linear-gradient(90deg, #9C0006, #D69200);
}
.jbs-bar-value {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: #555;
  text-align: right;
}
/* Rate bars carry a second (sub) line: $/hr headline + total-$ underneath */
.jbs-bar-sub {
  display: block;
  font-size: 10px;
  font-weight: 500;
  color: #94a3b8;
}
.jbs-bars-empty {
  color: #999;
  font-style: italic;
  padding: 12px 0;
  text-align: center;
}

/* Trailing-window card — Scrap by Machine + Scrap by Operator side by side */
.jbs-window-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
  margin-top: 8px;
}
@media (max-width: 860px) {
  .jbs-window-grid { grid-template-columns: 1fr; }
}
.jbs-subhead {
  font-size: 12px;
  font-weight: 700;
  color: #1F4E79;
  margin: 0 0 2px;
}

/* Part Deep-Dive Export — reuses the operator-search row/input styling; only
   the window select and the status line are new. */
.scrap-dd-row { max-width: 560px; align-items: center; }
.scrap-dd-window {
  padding: 7px 8px;
  border: 1px solid #d5dae2;
  border-radius: 6px;
  font-size: 12px;
  background: white;
  color: #333;
}
.scrap-dd-status { font-size: 11px; min-height: 15px; }

/* CNC scrap-vs-runtime headline */
.scrap-corr-stats { margin: 10px 0 12px; }
.scrap-corr-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 8px;
}
.scrap-corr-read {
  font-size: 11px;
  color: #666;
  margin: 10px 0 0;
  line-height: 1.5;
}
.scrap-corr-gap {
  font-size: 11px;
  color: #a06a1a;
  background: #fdf6ec;
  border: 1px solid #f0dcae;
  border-radius: 6px;
  padding: 6px 9px;
  margin: 8px 0 0;
}
a.btn.disabled { opacity: 0.5; pointer-events: none; }
.scrap-dd-ok   { color: #1e7b34; font-weight: 600; }
.scrap-dd-warn { color: #9C0006; font-weight: 600; }

/* Search by Operator */
.jbs-emp-search {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid #e6e9ee;
}
.jbs-emp-search-row {
  display: flex;
  gap: 8px;
  margin: 6px 0 10px;
  max-width: 420px;
}
.jbs-emp-search-input {
  flex: 1;
  padding: 7px 10px;
  border: 1px solid #d5dae2;
  border-radius: 6px;
  font-size: 12px;
}
.jbs-emp-search-results { display: flex; flex-direction: column; gap: 10px; }
.jbs-emp-result {
  background: white;
  border: 1px solid #e6e9ee;
  border-radius: 6px;
  padding: 10px 12px;
}
.jbs-emp-result.excluded { background: #fdf6ec; border-color: #f0dcae; }
.jbs-emp-result-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-size: 13px;
}
.jbs-emp-result-name { font-weight: 700; color: #1F4E79; }
.jbs-emp-result-code { font-size: 10px; color: #999; margin-left: 6px; }
.jbs-emp-result-total { font-weight: 700; color: #9C0006; font-variant-numeric: tabular-nums; }
.jbs-emp-result-reason { font-size: 11px; color: #666; margin-top: 4px; }
.jbs-emp-result-note { font-size: 11px; color: #a06a1a; margin-top: 4px; }
.jbs-emp-result-events {
  margin-top: 6px;
  font-size: 11px;
  color: #555;
}
.jbs-emp-result-events table { width: 100%; border-collapse: collapse; margin-top: 4px; }
.jbs-emp-result-events td { padding: 3px 4px; border-bottom: 1px solid #f0f2f5; }

/* Heatmap — top parts × top reasons */
.jbs-heatmap-wrap { overflow-x: auto; margin-top: 6px; }
.jbs-heatmap {
  border-collapse: collapse;
  width: 100%;
  font-size: 12px;
}
.jbs-heatmap th, .jbs-heatmap td {
  padding: 6px 10px;
  border: 1px solid #eaeaea;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.jbs-heatmap th {
  background: #1F4E79;
  color: white;
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  font-weight: 600;
}
.jbs-heatmap th.jbs-heat-part-th {
  background: #f4f6f9;
  color: #1F4E79;
  text-align: left;
  width: 70px;
}
.jbs-heatmap td.jbs-heat-part {
  text-align: left;
  font-weight: 700;
  background: #f4f6f9;
  color: #1F4E79;
}
.jbs-heatmap td.jbs-heat-total {
  background: #f4f6f9;
  font-weight: 700;
  color: #1F4E79;
}
.jbs-heatmap tr:hover td {
  outline: 1px solid #5B9BD5;
}
.jbs-heat-cell-value { display: block; font-weight: 600; }
.jbs-heat-cell-events { font-size: 9px; color: rgba(0,0,0,0.55); }

/* Stacked progress bar (boxed/shipped vs in-QC vs to-go) */
.sd-stacked-bar {
  display: inline-block;
  width: 80px;
  height: 10px;
  background: #eee;
  border-radius: 4px;
  overflow: hidden;
  vertical-align: middle;
  margin-right: 6px;
  position: relative;
  white-space: nowrap;
  font-size: 0;
}
.sd-stack-actual {
  display: inline-block;
  height: 100%;
  background: #5B9BD5;
  vertical-align: top;
}
.sd-stack-qc {
  display: inline-block;
  height: 100%;
  background: #FFEB9C;
  vertical-align: top;
}

/* ============================================================
   Shop Floor view — work-center load + active jobs + by-part
   ============================================================ */
.sf-tabs {
  display: flex;
  gap: 6px;
  border-bottom: 1px solid #e0e6ee;
  margin-bottom: 12px;
}
.sf-tab {
  background: transparent;
  border: 1px solid transparent;
  border-bottom: none;
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 600;
  color: #666;
  cursor: pointer;
  border-radius: 8px 8px 0 0;
  position: relative;
  bottom: -1px;
}
.sf-tab:hover { color: #1F4E79; }
.sf-tab.active {
  background: white;
  color: #1F4E79;
  border-color: #e0e6ee;
}

/* Work-center load bar — fills the available column width so the bar grows
   on wide screens instead of leaving a sea of empty space to the right. */
.sf-wc-table .sf-wc-load-th { width: 100%; }
.sf-wc-load-cell {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 240px;
}
.sf-load-bar {
  display: block;
  flex: 1;
  height: 12px;
  background: #f0f3f8;
  border-radius: 999px;
  overflow: hidden;
  min-width: 120px;
}
.sf-load-fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  transition: width 0.3s ease;
}
.sf-load-fill.sd-good { background: #6FBF73; }
.sf-load-fill.sd-warn { background: #F2C037; }
.sf-load-fill.sd-bad  { background: #E06A6F; }
/* Shop-floor flow + coverage cues */
.sf-incoming {
  color: #1F4E79;
  font-weight: 600;
  white-space: nowrap;
}
.sf-incoming-key {
  color: #1F4E79;
  font-weight: 600;
}
.sf-next {
  color: #6b7280;
  font-weight: 600;
  white-space: nowrap;
}
.sf-cov {
  cursor: help;
  font-weight: 700;
}
.sf-risk {
  cursor: help;
  font-size: 12px;
  margin-left: 2px;
}
.sf-risk-chronic   { color: #9C0006; }
.sf-risk-recurring { color: #B36b00; }
.sf-risk-callout {
  margin-top: 6px;
  padding: 6px 10px;
  border-radius: 6px;
  font-size: 12px;
  font-weight: 600;
}
.sf-risk-callout.sf-risk-chronic   { background: #FFC7CE; color: #9C0006; }
.sf-risk-callout.sf-risk-recurring { background: #FFF1CC; color: #8a5a00; }
.sf-load-pct {
  font-size: 12px;
  color: #555;
  font-variant-numeric: tabular-nums;
  min-width: 36px;
  text-align: right;
}

/* Op route boxes (compact "where in the route is this job?" indicator) */
.sf-op-row { display: inline-flex; gap: 2px; }
.sf-op-box {
  display: inline-block;
  width: 14px;
  height: 14px;
  background: #e8eaee;
  border-radius: 2px;
}
.sf-op-box.sf-op-done    { background: #6FBF73; }
.sf-op-box.sf-op-current { background: #1F4E79; box-shadow: 0 0 0 2px rgba(31,78,121,0.25); }
.sf-op-box.sf-op-open    { background: #cdd2d8; }

/* Active jobs filter bar */
.sf-jobs-filter {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 10px;
}
.sf-jobs-filter input[type="text"] {
  padding: 6px 10px;
  border: 1px solid #d0d6de;
  border-radius: 6px;
  font-size: 13px;
  flex: 1;
  max-width: 320px;
}
.sf-checkbox { font-size: 13px; color: #555; display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }

/* By-Part pane */
.sf-part-search {
  width: 100%;
  max-width: 380px;
  padding: 10px 14px;
  border: 1px solid #d0d6de;
  border-radius: 8px;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  margin-bottom: 14px;
}
.sf-part-result {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Job Locations tab — freshness row (right side of the page header) + a
   hero-styled search card so the tab reads as a purpose-built lookup tool
   instead of a bare <input> on a blank page. */
.jl-fresh-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.card.jl-card {
  padding: 28px 24px 22px;
  background: linear-gradient(180deg, var(--prism-blue-soft) 0%, var(--prism-panel) 70%);
  border: 1px solid var(--prism-blue-line);
}
/* Active/Closed segmented toggle — centered above the search bar. */
.jl-toggle {
  display: flex;
  width: fit-content;
  margin: 0 auto 14px;
  background: var(--prism-panel);
  border: 1px solid var(--prism-blue-line);
  border-radius: 999px;
  padding: 3px;
  gap: 2px;
}
.jl-toggle-btn {
  border: none;
  background: transparent;
  color: var(--prism-ink-muted);
  font-size: 13px;
  font-weight: 600;
  padding: 6px 20px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.jl-toggle-btn:hover { color: var(--prism-blue); }
.jl-toggle-btn.is-active { background: var(--prism-blue); color: #fff; }
.jl-search-row {
  position: relative;
  max-width: 560px;
  margin: 0 auto 14px;
}
.jl-search-icon {
  position: absolute;
  left: 6px;
  top: 50%;
  transform: translateY(-50%);
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--prism-blue);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  pointer-events: none;
}
.jl-search-input.sf-part-search {
  max-width: none;
  width: 100%;
  padding: 15px 18px 15px 52px;
  font-size: 17px;
  border: 1px solid var(--prism-blue-line);
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(23, 79, 130, 0.08);
  margin-bottom: 0;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.jl-search-input.sf-part-search:focus {
  outline: none;
  border-color: var(--prism-blue);
  box-shadow: 0 0 0 3px rgba(23, 79, 130, 0.16);
}
/* Customer / description search pick list (audit P2-4). */
.jl-hit-table { width: 100%; margin-top: 8px; }
.jl-hit-job {
  border: 1px solid var(--prism-blue-line); background: transparent; color: var(--prism-blue);
  border-radius: 6px; padding: 2px 8px; font-weight: 700; cursor: pointer; font-variant-numeric: tabular-nums;
}
.jl-hit-job:hover { background: rgba(23, 79, 130, 0.08); }
.jl-stats {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 4px;
}
/* Guard — see .qh-pagination[hidden] above. #jlAmbient is only un-hidden once the
   summary actually arrives (app.js:5644); without this it occupied its row from
   first paint, so the tab opened with a blank strip where the counts belong. */
.jl-stats[hidden] { display: none; }
.sf-part-summary h4 { margin: 0 0 2px; font-size: 18px; }
.sf-alias-note { font-size: 12px; font-weight: 400; color: #888; }
/* Route color key — swatches reuse the .sf-op-* cell styles so the legend can
   never drift from the actual cell coloring. */
.sf-legend { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 8px; }
.sf-legend-item { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: #666; }
.sf-legend-swatch {
  width: 14px; height: 14px; border-radius: 3px;
  border: 1px solid #d0d6de; box-shadow: none;
}
.sf-part-summary .muted { color: #666; font-size: 12px; }

/* Per-job route detail blocks (used in pane + modal) */
.sf-job-block {
  background: #f5f7fa;
  border-radius: 8px;
  padding: 12px 14px;
}
.sf-job-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  font-size: 13px;
  margin-bottom: 8px;
}
.sf-job-head .muted { color: #666; }
.sf-job-qty { font-size: 15px; font-weight: 600; color: #333; }
.sf-job-head-main {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  flex: 1;
  min-width: 0;
}
/* Hero remaining-hours figure — the #1 thing a PM/quoter looks up a job for,
   so it gets real visual weight instead of hiding in the muted qty/ops line. */
.sf-job-hrs {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  line-height: 1.05;
  flex-shrink: 0;
}
.sf-job-hrs-num { font-size: 24px; font-weight: 800; color: var(--prism-blue); }
.sf-job-hrs-label { font-size: 10px; color: #888; text-transform: uppercase; letter-spacing: 0.03em; }
.sf-job-hrs-none .sf-job-hrs-num { color: #aaa; }
.sf-job-hrs-done .sf-job-hrs-num { color: #087345; }
.sf-job-due {
  font-size: 12px;
  font-weight: 600;
  color: var(--prism-ink-muted);
  background: var(--prism-panel-subtle);
  border-radius: 999px;
  padding: 1px 9px;
}
.sf-job-due-late { color: #9C0006; background: #FFC7CE; }
.sf-route {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 4px;
}
.sf-op-cell {
  background: white;
  border: 1px solid #d0d6de;
  border-radius: 6px;
  padding: 6px 9px;
  min-width: 110px;
  font-size: 11px;
}
/* Two colored states only (Max 2026-07-08): green = complete, blue = running
   right now (real labor today). Everything else — queued, current-op guess,
   future — is neutral so the one live signal actually stands out. */
.sf-op-cell.sf-op-done,    .sf-legend-swatch.sf-op-done    { background: #E6F4E6; border-color: #6FBF73; }
.sf-op-cell.sf-op-open,    .sf-legend-swatch.sf-op-open    { background: white;   border-color: #d0d6de; }
.sf-op-cell.sf-op-open    { opacity: 0.85; }
/* Solid brand blue (not a pale tint — Max: pale blue was invisible on the
   blue-tinted card). Light text inside overrides the default dark-blue ink. */
.sf-op-cell.sf-op-running, .sf-legend-swatch.sf-op-running { background: #1F4E79; border-color: #163a5c; }
.sf-op-cell.sf-op-running .sf-op-cell-wc  { color: #fff; }
.sf-op-cell.sf-op-running .sf-op-cell-hrs { color: rgba(255,255,255,0.85); }
/* Labor logged today, nobody clocked in at the last pull (audit P2-5) — an
   outline in the same blue, so it reads as "touched today", not "running". */
.sf-op-cell.sf-op-worked,  .sf-legend-swatch.sf-op-worked  { background: white; border: 2px dashed #1F4E79; }
.sf-op-cell-wc   { font-weight: 700; color: #1F4E79; font-size: 11px; }
.sf-op-cell-hrs  { color: #555; font-size: 10px; font-weight: 600; margin-top: 2px; }
/* Per-op quantities (2026-08-04). Rendered only when JobBOSS actually holds
   them — an absent line means "never logged," so it must not look like a zero.
   Scrap gets the only warm color on the route so "where did we lose parts"
   reads at a glance without competing with the running/complete states. */
.sf-op-cell-qty  { color: #555; font-size: 10px; font-weight: 600; margin-top: 1px; }
.sf-op-scrap     { color: #B4232B; font-weight: 700; }
.sf-op-cell.sf-op-had-scrap { border-color: #B4232B; }
.sf-op-cell.sf-op-running .sf-op-cell-qty { color: rgba(255,255,255,0.85); }
.sf-op-cell.sf-op-running .sf-op-scrap    { color: #FFB3B3; }
.sf-op-box.sf-op-had-scrap  { box-shadow: inset 0 0 0 2px #B4232B; }
.sf-job-scrap    { color: #B4232B; font-weight: 700; }
/* Fallout that exceeds the ordered qty — data entry, not production. Muted
   amber, not alarm red: the point is "don't trust this number," not "panic." */
.sf-job-scrap.sf-job-scrap-suspect { color: #8A6100; font-weight: 700; }
.sf-op-arrow {
  display: inline-flex;
  align-items: center;
  color: #aaa;
  font-size: 12px;
  padding: 0 2px;
}

.sf-current-callout {
  margin-top: 8px;
  padding: 6px 10px;
  background: #fff8e1;
  border-left: 3px solid #F2C037;
  border-radius: 4px;
  font-size: 12px;
}

/* Supervisor-check column dots */
.sf-sup-yes { color: #6FBF73; font-weight: 700; }
.sf-sup-no  { color: #E06A6F; font-size: 16px; }
.sf-sup-na  { color: #aaa; }

/* Active Jobs table rows are clickable → open job detail drawer */
#sfJobsTable tbody tr[data-job] { cursor: pointer; }
#sfJobsTable tbody tr[data-job]:hover td { background: #eef4fb; }

/* By Part pane: job header is a clickable link into the job detail drawer */
.sf-job-link {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  font-size: 17px;
  font-weight: 700;
  color: #1F4E79;
  cursor: pointer;
}
.sf-job-link:hover { text-decoration: underline; }
/* Plain-text job # (2026-09-29): the drawer it used to open can't show here. */
.sf-job-link.is-static { cursor: text; }
.sf-job-link.is-static:hover { text-decoration: none; }

/* Modal-embedded shop-floor block (when SD modal pulls per-part data) */
.sf-modal-job {
  background: #f5f7fa;
  border-radius: 6px;
  padding: 8px 10px;
  margin-bottom: 6px;
  font-size: 12px;
}
.sf-modal-job .sf-op-row { margin-top: 4px; }
.sf-current-pill {
  display: inline-block;
  background: #DCE9F4;
  color: #1F4E79;
  border-radius: 4px;
  padding: 1px 6px;
  font-weight: 700;
  font-size: 11px;
}
.sf-jump-link {
  background: #1F4E79;
  color: white;
  border: none;
  border-radius: 6px;
  padding: 8px 14px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  margin-top: 10px;
}
.sf-jump-link:hover { background: #163a5a; }

/* ============================================================
   FAIR view — LAM First Article Inspection Report builder.
   Three-step flow: drop print → review/edit dim list → generate.
   Phase 1 = visual scaffold; backend wiring lands next sprint.
   Color choices match the Thomas-balloon spec where it makes sense
   (the dropzone icon hex #1171E8 is the same blue Thomas uses for
   his BQI balloons). See Knowledge_Base/FAIR/Thomas_Balloon_Spec.md.
   ============================================================ */
.fair-phase-banner {
  border-color: #c98e2a;
  background: #fff8e6;
  color: #7a5b1a;
  padding: 12px 16px;
  margin-bottom: 16px;
  font-size: 0.875rem;
}
.fair-phase-banner code {
  background: rgba(122, 91, 26, 0.10);
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 12px;
}

.fair-card {
  margin-bottom: 18px;
}
.fair-card-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 14px;
}
.fair-step-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-primary);
  color: #fff;
  font-weight: 700;
  font-size: 13px;
  flex-shrink: 0;
}
.fair-step-sub {
  margin-left: 8px;
  font-size: 12px;
  color: var(--color-text-muted, #6b7280);
  font-weight: 400;
}
/* CMM report drop (STEP 4) — optional auto-fill of measured actuals */
.fair-cmm-drop {
  border: 1.5px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  margin-bottom: 16px;
  background: #fafbfd;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.fair-cmm-drop:hover,
.fair-cmm-drop:focus-within {
  border-color: #1171E8;
  background: #f2f7ff;
}
.fair-cmm-drop.fair-dropzone-drag {
  border-color: #1171E8;
  background: #e6f0ff;
}
.fair-cmm-drop-main {
  display: flex;
  align-items: center;
  gap: 12px;
}
.fair-cmm-drop-icon {
  color: #1171E8;
  line-height: 0;
  flex-shrink: 0;
}
.fair-cmm-drop-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.fair-cmm-drop-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--color-text);
}
.fair-cmm-drop-opt {
  font-weight: 400;
  color: var(--color-text-muted);
}
.fair-cmm-drop-sub {
  font-size: 12px;
  color: var(--color-text-muted);
}
.fair-cmm-status {
  margin-top: 10px;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  line-height: 1.4;
}
.fair-cmm-status.is-ok {
  background: var(--color-success-soft, #e9f7ef);
  color: var(--color-success-strong, #1a7f47);
}
.fair-cmm-status.is-warn {
  background: var(--color-warning-soft, #fff4e0);
  color: var(--color-warning-strong, #9a6700);
}
.fair-cmm-status.is-err {
  background: var(--color-danger-soft, #fdecec);
  color: var(--color-danger-strong, #b42318);
}
.fair-cmm-status.is-busy {
  background: var(--color-primary-soft);
  color: var(--color-text-muted);
}
.fair-cmm-files {
  margin: 6px 0 0;
  padding-left: 18px;
}
.fair-cmm-files li { margin: 2px 0; }
.fair-cmm-remove {
  margin-left: 6px;
  padding: 0 6px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: inherit;
  font-size: 15px;
  line-height: 1.2;
  cursor: pointer;
  opacity: 0.7;
}
.fair-cmm-remove:hover { opacity: 1; background: rgba(0, 0, 0, 0.08); }
/* "Your FAIR jobs from the last 24 h" resume strip above the drop zone (FAIR-12).
   No display rule on the container, so its [hidden] attribute still hides it. */
.fair-recent-jobs {
  margin-bottom: 12px;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  background: var(--color-primary-soft);
  font-size: 13px;
}
.fair-recent-title { font-weight: 600; margin-bottom: 4px; }
.fair-recent-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 3px 0;
  overflow-wrap: anywhere;
}

/* Bundle form (STEP 4) — labeled grid of inputs + dropdowns */
.fair-bundle-form { margin-bottom: 16px; }
.fair-bundle-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px 16px;
  margin-bottom: 8px;
}
@media (min-width: 900px) {
  .fair-bundle-grid { grid-template-columns: repeat(3, 1fr); }
}
.fair-bundle-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.fair-bundle-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted, #6b7280);
}
.fair-bundle-label em {
  color: #dc2626;
  font-style: normal;
  margin-left: 2px;
}
.fair-bundle-field input,
.fair-bundle-field select,
.fair-bundle-field textarea {
  padding: 6px 8px;
  border: 1px solid var(--color-border, #d1d5db);
  border-radius: 4px;
  font-size: 13px;
  background: #fff;
}
.fair-bundle-field textarea {
  resize: vertical;
  font-family: inherit;
  line-height: 1.4;
}
.fair-bundle-field input:focus,
.fair-bundle-field select:focus,
.fair-bundle-field textarea:focus {
  outline: none;
  border-color: var(--color-primary, #1171E8);
  box-shadow: 0 0 0 2px rgba(17, 113, 232, 0.15);
}
/* Full-width field (spans the grid) — used for Supplier Comments. */
.fair-bundle-field-full { margin: 4px 0 12px; }
.fair-bundle-advanced {
  margin-top: 10px;
  padding: 10px 12px;
  background: var(--color-bg-subtle, #f9fafb);
  border-radius: 4px;
  font-size: 12px;
}
.fair-bundle-advanced summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--color-text-muted, #6b7280);
  margin-bottom: 8px;
}
.fair-bundle-advanced[open] summary { margin-bottom: 12px; }
.fair-bundle-subhead {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-text-muted, #6b7280);
  margin: 12px 0 6px;
}
.fair-bundle-subhead:first-of-type { margin-top: 0; }
.fair-audit-list {
  margin: 8px 0 4px 0;
  padding-left: 18px;
  font-size: 12px;
}
.fair-audit-list li { margin-bottom: 4px; }
.fair-audit-list code {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 11px;
  padding: 1px 4px;
  background: rgba(220, 38, 38, 0.08);
  border-radius: 3px;
  color: #991b1b;
}
.fair-audit-list-warn code {
  background: rgba(234, 179, 8, 0.12);
  color: #92400e;
}
.fair-audit-warn-banner {
  margin: 6px 0 4px;
  padding: 6px 10px;
  background: #fffbeb;
  border-left: 3px solid #eab308;
  font-size: 12px;
  color: #92400e;
}
.fair-card-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--color-text);
  margin: 0;
}
.fair-card-status {
  margin-left: auto;
  font-size: 12px;
  color: var(--color-text-muted);
}
.fair-card-status-warn {
  color: #7a5b1a;
  background: #fff8e6;
  padding: 4px 10px;
  border-radius: 4px;
  border: 1px solid #c98e2a;
}

/* ---------- STEP 1: dropzone ---------- */
.fair-dropzone {
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: 40px 20px;
  text-align: center;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
  background: #fafbfd;
}
.fair-dropzone:hover,
.fair-dropzone:focus {
  border-color: #1171E8;
  background: #f0f6ff;
  outline: none;
}
.fair-dropzone-drag {
  border-color: #1171E8;
  background: #e6f0ff;
}
.fair-dropzone-icon {
  font-size: 40px;
  color: #1171E8;
  line-height: 1;
  margin-bottom: 10px;
}
.fair-dropzone-primary {
  font-size: 15px;
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: 4px;
}
.fair-dropzone-secondary {
  font-size: 13px;
  color: var(--color-text-muted);
}
.fair-dropzone-link {
  color: var(--color-accent);
  text-decoration: underline;
}

.fair-file-preview {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 12px;
  padding: 10px 14px;
  background: var(--color-primary-soft);
  border-radius: var(--radius-sm);
  font-size: 13px;
}
/* Guard — see .qh-pagination[hidden] above. Hidden until a print is chosen and
   re-hidden on reset (fair.js:171/918); without this a tinted empty preview strip
   sat under the dropzone as if a file were already loaded. */
.fair-file-preview[hidden] { display: none; }
.fair-file-name {
  font-weight: 600;
  color: var(--color-text);
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fair-file-size {
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.fair-meta-row {
  display: flex;
  gap: 12px;
  margin-top: 16px;
  align-items: flex-end;
  flex-wrap: wrap;
}
/* Guard — see .qh-pagination[hidden] above. Same pair as .fair-file-preview
   (fair.js:172/919): the part/rev fields are meant to appear only once a file is
   staged, and instead prompted for metadata about a print nobody had picked yet. */
.fair-meta-row[hidden] { display: none; }
.fair-meta-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
  min-width: 140px;
}
.fair-meta-field-narrow {
  flex: 0 0 80px;
  min-width: 80px;
}
.fair-meta-label {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--color-text-muted);
}
.fair-meta-field input {
  padding: 8px 10px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: 14px;
}
.fair-meta-field input:focus {
  border-color: var(--color-accent);
  outline: none;
  box-shadow: 0 0 0 3px rgba(31, 111, 196, 0.15);
}

/* ---------- Buttons (FAIR-scoped — sister palette to .btn but tighter) ---------- */
.fair-btn {
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.fair-btn-primary {
  background: var(--color-primary);
  color: #fff;
  border-color: var(--color-primary);
}
.fair-btn-primary:hover { background: var(--color-primary-hover); border-color: var(--color-primary-hover); }
.fair-btn-primary:disabled {
  background: #c5cbd3;
  color: #fff;
  border-color: #c5cbd3;
  cursor: not-allowed;
}
.fair-btn-large { padding: 11px 22px; font-size: 14px; }
.fair-btn-ghost {
  background: #fff;
  color: var(--color-primary);
  border-color: var(--color-border);
}
.fair-btn-ghost:hover { background: var(--color-primary-soft); border-color: var(--color-primary); }
.fair-btn-ghost-sm {
  background: transparent;
  color: var(--color-text-muted);
  border-color: var(--color-border);
  padding: 4px 10px;
  font-size: 12px;
}
.fair-btn-ghost-sm:hover { background: var(--color-primary-soft); color: var(--color-text); }

/* ---------- STEP 2: dim table ---------- */
.fair-table-toolbar {
  display: flex;
  gap: 12px;
  align-items: center;
  margin-bottom: 10px;
}
.fair-table-help {
  font-size: 12px;
  color: var(--color-text-muted);
}
.fair-table-wrap {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  overflow: auto;
  max-height: 60vh;
}
.fair-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.fair-table thead th {
  position: sticky;
  top: 0;
  background: var(--color-primary-soft);
  color: var(--color-text);
  font-weight: 600;
  text-align: left;
  padding: 8px 8px;
  border-bottom: 1px solid var(--color-border);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  white-space: nowrap;
}
.fair-table tbody td {
  padding: 4px 6px;
  border-bottom: 1px solid #eef0f4;
  vertical-align: middle;
}
.fair-table tbody tr:hover { background: #fafbfd; }
.fair-table input[type="text"],
.fair-table input[type="number"],
.fair-table select {
  width: 100%;
  padding: 5px 6px;
  border: 1px solid transparent;
  border-radius: 3px;
  font-size: 13px;
  background: transparent;
}
.fair-table input:hover,
.fair-table select:hover {
  border-color: var(--color-border);
  background: #fff;
}
.fair-table input:focus,
.fair-table select:focus {
  border-color: var(--color-accent);
  background: #fff;
  outline: none;
  box-shadow: 0 0 0 2px rgba(31, 111, 196, 0.12);
}
.fair-balloon-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  padding: 2px 8px;
  background: #1171E8;
  color: #fff;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.fair-row-skipped { opacity: 0.45; background: #f7f8fa; }
.fair-row-skipped .fair-balloon-pill { background: #b9c1cd; }

/* OCR×VLM cross-check: a value the print-reader and OCR disagree on. Badge-only
   hint — "verify this against the drawing." */
.fair-row-verify { background: #fff7e6; }
.fair-row-verify td { box-shadow: inset 0 -1px 0 #f0c36d; }
.fair-verify-badge {
  display: inline-block;
  margin-left: 4px;
  color: #b9770a;
  font-size: 13px;
  font-weight: 700;
  cursor: help;
  vertical-align: middle;
}
/* Row with no balloon position (e.g. "+ Add missed dim") — numbered on the
   inspection sheet, no balloon on the BQI (FAIR-5). */
.fair-row-noloc {
  display: block;
  margin-top: 2px;
  color: #b9770a;
  font-size: 10px;
  font-weight: 600;
  white-space: nowrap;
  cursor: help;
}
/* GD&T symbol picker — in the table Nominal column AND the position-editor legend. */
.fair-gdt-select { width: 100%; }
.fair-legend-gdt-select {
  display: inline-block;
  margin-top: 2px;
  max-width: 100%;
  font-size: 11px;
  padding: 1px 4px;
  border: 1px solid #f0c36d;
  border-radius: 4px;
  background: #fffdf7;
  color: #1171E8;
  font-weight: 600;
}

/* Inline nominal/tol editors in the position-editor legend — edit a dim's
   value without scrolling up to the table. */
.fair-legend-val {
  display: flex;
  gap: 4px;
  margin-top: 3px;
  align-items: center;
}
.fair-legend-val input {
  font-size: 11px;
  padding: 1px 4px;
  border: 1px solid var(--color-border, #d8dee6);
  border-radius: 4px;
  background: var(--color-surface, #fff);
  color: var(--color-text, #1f2937);
}
.fair-legend-val input:focus {
  outline: none;
  border-color: #1171E8;
  box-shadow: 0 0 0 2px rgba(17, 113, 232, 0.15);
}
.fair-legend-nom { width: 78px; font-weight: 600; }
.fair-legend-tol { width: 56px; }

.fair-col-num    { width: 60px;  text-align: center; }
.fair-col-page   { width: 60px; }
.fair-col-type   { width: 110px; }
.fair-col-nominal{ width: 110px; }
.fair-col-tol    { width: 90px; }
.fair-col-notes  { min-width: 200px; }
.fair-col-mc     { width: 110px; }
.fair-col-tool   { width: 200px; }
.fair-col-skip   { width: 70px;  text-align: center; }
.fair-col-action { width: 36px;  text-align: center; }

.fair-skip-label {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  color: var(--color-text-muted);
  cursor: pointer;
}
.fair-row-del {
  background: transparent;
  border: none;
  color: #b9c1cd;
  font-size: 18px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 3px;
}
.fair-row-del:hover {
  color: #8b1c1c;
  background: #fdeded;
}

.fair-table-empty {
  display: none;
  padding: 30px 20px;
  text-align: center;
  font-size: 13px;
  color: var(--color-text-muted);
  background: #fafbfd;
}

/* ---------- STEP 3: generate ---------- */
.fair-generate-row {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.fair-generate-help {
  font-size: 12px;
  color: var(--color-text-muted);
  flex: 1;
  min-width: 240px;
}
.fair-generate-hint {
  font-size: 12px;
  color: var(--color-warning, #b45309);
  font-style: italic;
}
.fair-downloads {
  margin-top: 14px;
}
.fair-download-status {
  padding: 12px 16px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  line-height: 1.5;
}
.fair-download-status-pending {
  background: #fff8e6;
  border: 1px solid #c98e2a;
  color: #7a5b1a;
}
.fair-download-status-pending strong {
  display: block;
  margin-bottom: 2px;
}

/* Phase 2 status variants — added when fair.js wired to /api/fair/*. */
.fair-card-status-pending {
  color: #7a5b1a;
  background: #fff8e6;
  padding: 4px 10px;
  border-radius: 4px;
  border: 1px solid #c98e2a;
}
.fair-card-status-success {
  color: #1f8b4c;
  background: #eaf7ef;
  padding: 4px 10px;
  border-radius: 4px;
  border: 1px solid #1f8b4c;
}
.fair-card-status-error {
  color: #8b1c1c;
  background: #fdeded;
  padding: 4px 10px;
  border-radius: 4px;
  border: 1px solid #8b1c1c;
}
/* Actionable extraction error card — replaces the old thin red status line.
   Title + detail + a classified hint + a Retry button. */
.fair-error-card {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 12px 0;
  padding: 14px 16px;
  background: #fdeded;
  border: 1px solid #e7a3a3;
  border-left: 4px solid #b42318;
  border-radius: 8px;
}
/* CRITICAL: the display:flex above outranks the UA [hidden]{display:none}, so
   without this guard the card's hidden attribute is ignored and the default
   "Extraction failed" template shows the instant Step 2 reveals — regardless of
   actual extraction state (the week-long phantom-failure bug). Keep this. */
.fair-error-card[hidden] { display: none !important; }
.fair-error-icon {
  color: #b42318;
  flex: 0 0 auto;
  margin-top: 1px;
}
.fair-error-body { flex: 1 1 auto; min-width: 0; }
.fair-error-title {
  font-weight: 700;
  color: #7a1612;
  font-size: 14px;
}
.fair-error-detail {
  margin-top: 3px;
  color: #8b2a26;
  font-size: 13px;
  word-break: break-word;
}
.fair-error-hint {
  margin-top: 8px;
  color: #6b4a16;
  background: #fff6e0;
  border: 1px solid #f0d79a;
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 12.5px;
  line-height: 1.45;
}
.fair-error-retry {
  flex: 0 0 auto;
  align-self: center;
  white-space: nowrap;
}
.fair-extraction-notes {
  margin-top: 10px;
  padding: 10px 14px;
  background: #f0f6ff;
  border-left: 3px solid #1171E8;
  border-radius: var(--radius-sm);
  font-size: 12px;
  color: var(--color-text);
  white-space: pre-wrap;
  line-height: 1.5;
}
.fair-download-status-success {
  background: #eaf7ef;
  border: 1px solid #1f8b4c;
  color: #1f5532;
}
.fair-download-status-error {
  background: #fdeded;
  border: 1px solid #8b1c1c;
  color: #8b1c1c;
}
.fair-download-buttons {
  margin-top: 12px;
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
.fair-download-tip {
  margin-top: 12px;
  font-size: 12px;
  color: var(--color-text-muted);
  line-height: 1.5;
}

/* Skipped-rows toggle (shown in fair-table-empty when skip count > 0) */
.fair-skip-toggle-hint {
  font-weight: 400;
  color: var(--color-text-muted);
  font-size: 11px;
  margin-left: 6px;
}

/* Position-edit step (2.5) — draggable balloon preview */
.fair-position-help {
  margin: 0 0 12px;
  font-size: 13px;
  color: var(--color-text-muted);
  line-height: 1.5;
}
.fair-position-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}
.fair-position-status {
  font-size: 12px;
  color: var(--color-text-muted);
}
.fair-position-pages {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.fair-position-page {
  border: 1px solid var(--color-border, #ddd);
  border-radius: 6px;
  padding: 10px;
  background: #fafbfc;
}
.fair-position-page h4 {
  margin: 0 0 8px;
  font-size: 13px;
  color: var(--color-text-muted);
  font-weight: 500;
}
.fair-position-layout {
  display: grid;
  grid-template-columns: 1fr 280px;
  gap: 12px;
  /* align-items defaults to 'stretch' so the legend column matches the
     page-image column's height — no more wasted whitespace below short
     legends, and the legend can scroll inside its own column when long. */
}
@media (max-width: 1100px) {
  .fair-position-layout { grid-template-columns: 1fr; }
}
.fair-position-canvas-wrap {
  position: relative;
  display: inline-block;
  max-width: 100%;
  /* Cap the canvas to a viewport-relative height so a tall print doesn't
     blow out the page and push the legend below the fold. Transform-based
     zoom/pan handles in-canvas navigation; the user can also natively scroll
     when the wrap content overflows. */
  max-height: 78vh;
  border: 1px solid #ccc;
  background: white;
  /* `auto` so a print that's taller than the cap gets a vertical scrollbar
     (Max's request — was `hidden` which silently truncated). Zoom-pan still
     works because the stack uses CSS transform, not layout flow. */
  overflow: auto;
  touch-action: none;  /* prevent default trackpad pan when zooming */
}
.fair-position-canvas-wrap.fair-panning { cursor: grabbing !important; }
/* Stack — the layer that gets transform: scale + translate applied to it.
   Sized by its non-positioned child (img), so its natural size matches
   the page image. Transform happens via inline style from applyPageTransform. */
.fair-position-stack {
  position: relative;
  display: block;
  transform-origin: 0 0;
  /* No transition — transform updates need to be instant during drag/zoom */
}
.fair-position-legend {
  font-size: 12px;
  /* Match the canvas cap so dense prints with 30+ items don't stretch the
     grid row to absurd heights. Legend scrolls internally past the cap. */
  max-height: 78vh;
  overflow-y: auto;
  border: 1px solid var(--color-border, #ddd);
  border-radius: 4px;
  background: white;
  padding: 4px 0;
  /* Min height so very short legends still look like a panel, not a stub */
  min-height: 200px;
}
.fair-position-legend-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 5px 10px;
  border-bottom: 1px solid #f0f0f0;
  cursor: pointer;
  /* No transition — hover highlight is instant */
}
.fair-position-legend-item:hover,
.fair-position-legend-item.active {
  background: #fff7ed;             /* match the balloon orange family */
  box-shadow: inset 4px 0 0 #f97316;  /* thick left accent — eye-catches even when scrolled */
}
.fair-position-legend-item {
  transition: none !important;  /* instant highlight — Max wants zero lag on hover */
}
.fair-position-legend-item:last-child {
  border-bottom: none;
}
.fair-position-legend-num {
  flex: 0 0 auto;
  background: #1171E8;
  color: white;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: 600;
  font-size: 11px;
  padding: 1px 5px;
  border-radius: 3px;
  min-width: 28px;
  text-align: center;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition: background 0.1s ease, box-shadow 0.1s ease;
}
.fair-position-legend-num:hover {
  background: #0d5fc4;
  box-shadow: 0 0 0 2px rgba(17, 113, 232, 0.25);
}
.fair-position-legend-num:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgba(17, 113, 232, 0.45);
}
.fair-position-legend-num.editing {
  background: white;
  padding: 0;
  box-shadow: 0 0 0 2px #1171E8;
}
.fair-position-legend-num-input {
  width: 36px;
  border: none;
  outline: none;
  background: transparent;
  font-family: inherit;
  font-weight: inherit;
  font-size: 11px;
  color: #1171E8;
  text-align: center;
  padding: 1px 2px;
  -moz-appearance: textfield;
}
.fair-position-legend-num-input::-webkit-outer-spin-button,
.fair-position-legend-num-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.fair-position-legend-text {
  flex: 1;
  color: var(--color-text);
  line-height: 1.35;
  word-break: break-word;
}
.fair-position-legend-type {
  display: block;
  font-size: 10px;
  color: var(--color-text-muted);
  margin-top: 2px;
}
.fair-position-page-img {
  display: block;
  max-width: 100%;
  height: auto;
  user-select: none;
  pointer-events: none;
}
.fair-position-overlay {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  pointer-events: none;   /* children re-enable */
}
.fair-position-leaders {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  pointer-events: none !important;   /* SVG children should not intercept hover */
  z-index: 5;
}
.fair-position-leaders line {
  pointer-events: none !important;
}
.fair-position-leaders line {
  stroke: #1171E8;
  stroke-width: 0.15;
  stroke-dasharray: 0.5 0.4;
  opacity: 0;
  /* No transition — instant on/off on hover */
}
.fair-position-leaders line.active {
  opacity: 0.75;
  stroke-width: 0.3;
}
.fair-position-size-control {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--color-text-muted);
}
.fair-position-size-control input[type="range"] {
  width: 100px;
}
.fair-position-size-value {
  min-width: 30px;
  font-weight: 600;
  color: var(--color-text);
}
.fair-position-balloon {
  position: absolute;
  /* Anchor: balloon's RIGHT edge sits --balloon-gap-px LEFT of (x_norm,
     y_norm), where (x_norm, y_norm) is the LEFT edge / vertical midline of the
     dim text. --balloon-gap-px is set per-overlay in renderPositionEditor() as
     a PRINT-RELATIVE gap (BALLOON_GAP_PT mapped through the 120dpi page-image
     scale) so the preview matches the exported PDF's balloon.js BALLOON_GAP_PT.
     Falls back to 6px if JS hasn't set it. This matches Thomas's convention —
     balloon in the whitespace BEFORE the dim, not overlapping it. */
  /* --fair-inv-zoom (set per-page in applyPageTransform = 1/zoom) counter-
     scales the marker so it stays a CONSTANT screen size while the print
     image zooms. Anchored at the right edge (the dim side) so it keeps
     hugging the callout. Without this the markers grew/shrank with zoom and
     buried the print when zoomed out. */
  transform-origin: 100% 50%;
  transform: translate(calc(-100% - var(--balloon-gap-px, 6px)), -50%) scale(var(--fair-inv-zoom, 1));
  background: #1171E8;
  color: white;
  font-family: Arial, Helvetica, sans-serif;
  /* font-size driven by --balloon-font-px set on the overlay container.
     Range 10-40px (≈6-24pt PDF). */
  font-size: var(--balloon-font-px, 18px);
  font-weight: 600;
  padding: 1px 4px 1px 2px;
  border-radius: 3px;
  cursor: grab;
  user-select: none;
  pointer-events: auto;
  white-space: nowrap;
  line-height: 1.2;
  box-shadow: 0 1px 2px rgba(0,0,0,0.2);
  z-index: 10;
  /* Force no transitions on any property — hover state must be instant.
     (Without !important some browsers apply default background transition.) */
  transition: none !important;
}
.fair-position-balloon:hover {
  background: #f97316;     /* orange — strong contrast vs default blue */
  outline: 3px solid #fed7aa;
  outline-offset: 1px;
  z-index: 100;
  /* Keep the SAME translate as the base transform — otherwise the balloon
     teleports horizontally on hover (cursor leaves it → un-hovers → teleports
     back → spazz loop). Only add the 1.25x scale for visual pop. */
  transform: translate(calc(-100% - 6px), -50%) scale(calc(1.25 * var(--fair-inv-zoom, 1)));
}
.fair-position-balloon.dragging {
  cursor: grabbing;
  background: #ea580c;
  outline: 3px solid #fed7aa;
  outline-offset: 1px;
  z-index: 1000;
  transform: translate(calc(-100% - 6px), -50%) scale(calc(1.25 * var(--fair-inv-zoom, 1)));
}
.fair-position-balloon.is-edited::after {
  content: '✎';
  font-size: 8px;
  margin-left: 3px;
  opacity: 0.7;
}
.fair-position-balloon.is-new {
  background: #16a34a;
  outline: 2px solid #bbf7d0;
}
.fair-position-balloon.is-new:hover { background: #15803d; }

/* Floating tooltip shown next to cursor on balloon hover.
   No transition / fade — Max wants instant. */
.fair-hover-tip {
  position: fixed;
  z-index: 10000;
  pointer-events: none;
  max-width: 360px;
  padding: 5px 9px;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.35;
  color: #1f2937;
  background: #fff;
  border: 1px solid #d0d7de;
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.18);
  white-space: pre-wrap;
  word-break: break-word;
}
.fair-hover-tip[hidden] { display: none; }

/* Delete button (trash icon) on each LEGEND row — right side, visible
   on row hover. Replaces the old per-balloon × button. */
.fair-legend-del {
  flex: 0 0 auto;
  padding: 3px 5px;
  border: 1px solid transparent;
  background: transparent;
  color: #9ca3af;
  line-height: 0;
  border-radius: 3px;
  cursor: pointer;
  margin-left: auto;
  align-self: center;
  opacity: 0;
  transition: opacity 0.08s ease;
}
.fair-legend-del svg { display: block; pointer-events: none; }
.fair-position-legend-item:hover .fair-legend-del,
.fair-legend-del:focus-visible {
  opacity: 1;
}
.fair-legend-del:hover {
  color: #b91c1c;
  border-color: #fecaca;
  background: #fef2f2;
}

/* "+ Add Balloon" per-page button */
.fair-add-balloon-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 12px;
  padding: 3px 10px;
  font-size: 12px;
  font-weight: 600;
  border: 1px solid #16a34a;
  background: #f0fdf4;
  color: #15803d;
  border-radius: 4px;
  cursor: pointer;
  vertical-align: middle;
}
.fair-add-balloon-btn:hover { background: #dcfce7; }
.fair-add-balloon-btn.armed {
  background: #16a34a;
  color: white;
  box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.25);
}

/* Reset View + zoom hint */
.fair-zoom-reset-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 8px;
  padding: 3px 9px;
  font-size: 12px;
  font-weight: 500;
  border: 1px solid #d0d7de;
  background: white;
  color: #475569;
  border-radius: 4px;
  cursor: pointer;
  vertical-align: middle;
}
.fair-zoom-reset-btn:hover { background: #f3f4f6; }
.fair-zoom-hint {
  margin-left: 10px;
  font-size: 11px;
  color: #94a3b8;
  font-weight: 400;
  vertical-align: middle;
  user-select: none;
}

/* Place-mode visual cue on the canvas */
.fair-position-canvas-wrap.fair-place-mode { cursor: crosshair !important; }
.fair-position-canvas-wrap.fair-place-mode::after {
  content: 'Click on the print to drop balloon — Esc to cancel';
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  background: #16a34a;
  color: white;
  font-size: 11px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 4px;
  z-index: 500;
  pointer-events: none;
  box-shadow: 0 2px 6px rgba(0,0,0,0.2);
}
.fair-position-canvas-wrap.fair-place-mode {
  outline: 2px dashed #16a34a;
  outline-offset: -2px;
}

/* ===========================================================================
   Part 360 — "answer me everything about this part" view (2026-05-13)
   =========================================================================== */
.p360-search-card { padding: 14px 16px; margin-bottom: 16px; }
.p360-search-row { display: flex; gap: 8px; align-items: center; }
.p360-search-row input[type="search"] {
  flex: 1;
  padding: 9px 12px;
  font-size: 15px;
  border: 1px solid var(--color-border, #d0d7de);
  border-radius: 6px;
  background: var(--color-surface, #fff);
}
.p360-search-row input[type="search"]:focus {
  outline: none;
  border-color: var(--color-accent, #2563eb);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);
}
.p360-search-hint { font-size: 12px; margin-top: 6px; }
.p360-search-hint code {
  background: var(--color-surface-alt, #f4f6f8);
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 11px;
}

/* ── Hero / Part-profile card ── */
.p360-hero-card {
  padding: 22px 26px;
  margin-bottom: 14px;
  display: grid;
  grid-template-columns: 1fr 240px;
  gap: 24px;
  align-items: center;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}
@media (max-width: 900px) { .p360-hero-card { grid-template-columns: 1fr; } .p360-hero-preview { display: none; } }
.p360-hero-main { min-width: 0; display: flex; flex-direction: column; gap: 12px; }
.p360-hero-headline { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.p360-hero-headline h2 {
  margin: 0;
  font-size: 36px;
  font-weight: 700;
  letter-spacing: -0.8px;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.p360-alias-note { font-size: 12.5px; color: var(--color-text-muted, #6b7280); }

.p360-hero-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.p360-chip {
  display: inline-flex; align-items: center;
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  padding: 3px 9px;
  border-radius: 999px;
  line-height: 1.6;
}
.p360-chip[hidden] { display: none; }      /* defensive against specificity */
.p360-chip-status      { background: #DCFCE7; color: #166534; }
.p360-chip-status-cold { background: #E2E8F0; color: #475569; }
.p360-chip-warn        { background: #FEF3C7; color: #92400E; }
.p360-chip-shape       { background: #EEF2FF; color: #3730A3; }

.p360-hero-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 6px 24px;
  margin: 0;
  font-size: 13px;
}
.p360-hero-fields > div { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.p360-hero-fields dt {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--color-text-muted, #6b7280);
  margin: 0;
}
.p360-hero-fields dd { margin: 0; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ── Hero action strip — STP / PDF / Router / Re-quote shortcuts ── */
.p360-hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 4px;
}
.p360-hero-action {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  color: #1F2937;
  background: #fff;
  border: 1px solid #E2E8F0;
  border-radius: 8px;
  padding: 6px 12px;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.p360-hero-action:hover { background: #F8FAFC; border-color: #CBD5E1; }
.p360-hero-action[disabled],
.p360-hero-action-disabled {
  color: #94A3B8;
  background: #F8FAFC;
  cursor: not-allowed;
  border-color: #E2E8F0;
}
.p360-hero-action-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px; height: 18px;
  border-radius: 4px;
  background: #EEF2FF;
  color: #4F46E5;
  font-size: 11px;
}
.p360-hero-action-primary {
  color: #fff;
  background: #4F46E5;
  border-color: #4F46E5;
}
.p360-hero-action-primary:hover { background: #4338CA; border-color: #4338CA; }
.p360-hero-action-primary .p360-hero-action-icon { background: rgba(255,255,255,0.2); color: #fff; }

.p360-hero-preview {
  width: 240px; height: 200px;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, #f8fafc 0%, #eef2ff 100%);
  border-radius: 12px;
  color: var(--color-text-muted, #6b7280);
  overflow: hidden;
  position: relative;
}
.p360-hero-preview iframe {
  width: 100%; height: 100%;
  border: 0;
  background: #fff;
}
.p360-hero-preview-empty {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.3px;
  text-align: center;
  padding: 16px;
  color: var(--color-text-muted, #94a3b8);
}
.p360-hero-preview-open {
  position: absolute;
  bottom: 6px;
  right: 8px;
  font-size: 10.5px;
  font-weight: 600;
  background: rgba(15, 23, 42, 0.75);
  color: #fff;
  padding: 3px 8px;
  border-radius: 6px;
  text-decoration: none;
  letter-spacing: 0.3px;
}
.p360-hero-preview-open:hover { background: rgba(15, 23, 42, 0.9); }

/* ── Empty-state landing — top parts + currently in production ── */
/* :not([hidden]) so the hidden HTML attribute reliably collapses the landing
   once a part is loaded — without this guard our display:grid wins over the
   user-agent [hidden] rule on equal specificity. */
.p360-landing:not([hidden]) {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-top: 12px;
}
@media (max-width: 1100px) { .p360-landing:not([hidden]) { grid-template-columns: 1fr; } }
.p360-landing-panel { padding: 18px 20px; box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04); border-radius: 10px; }
.p360-landing-list { list-style: none; padding: 0; margin: 0; counter-reset: p360rank; }
.p360-landing-row {
  display: grid;
  grid-template-columns: 26px 80px 1fr auto;
  align-items: baseline;
  gap: 10px;
  padding: 9px 4px;
  border-bottom: 1px solid #F1F5F9;
  cursor: pointer;
  transition: background 0.12s ease;
}
.p360-landing-row:last-child { border-bottom: none; }
.p360-landing-row:hover { background: #F8FAFC; }
.p360-landing-rank {
  counter-increment: p360rank;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--color-text-muted, #94a3b8);
  font-variant-numeric: tabular-nums;
}
.p360-landing-rank::before { content: counter(p360rank) ". "; }
.p360-landing-pn { font-weight: 600; font-size: 13.5px; color: var(--color-accent, #2563eb); font-variant-numeric: tabular-nums; }
.p360-landing-meta { font-size: 12px; color: var(--color-text-muted, #6b7280); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.p360-landing-stat { font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums; text-align: right; }

/* ── Hero tiles — 6-column row of icon · label · value · spark · delta ── */
.p360-hero {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 10px;
  margin-bottom: 12px;
}
@media (max-width: 1400px) { .p360-hero { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 700px)  { .p360-hero { grid-template-columns: repeat(2, 1fr); } }
.p360-tile {
  background: var(--color-surface, #fff);
  border: 1px solid var(--color-border-light, #eaecef);
  border-radius: 10px;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 148px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}
.p360-tile-head { display: flex; align-items: center; gap: 10px; }
.p360-tile-icon {
  width: 28px; height: 28px;
  border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  background: #EEF2FF;
  color: #4F46E5;
  font-size: 14px; font-weight: 600;
}
.p360-tile-label {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--color-text-muted, #6b7280);
}
.p360-tile-value {
  font-size: 28px;
  font-weight: 700;
  letter-spacing: -0.6px;
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
  color: #0F172A;
}
.p360-tile-value-sm { font-size: 18px; letter-spacing: -0.3px; }
/* Authoritative price tile — Sales Packaging Matrix. Green accent so the
   curated current price reads as the primary anchor next to noisy historicals. */
.p360-tile-authoritative {
  border-color: #1F7A4D;
  box-shadow: 0 1px 2px rgba(31, 122, 77, 0.12);
  background: linear-gradient(180deg, #F4FBF7 0%, #fff 36%);
}
.p360-tile-authoritative .p360-tile-icon { background: #DCF3E7; color: #1F7A4D; }
.p360-tile-authoritative .p360-tile-value { color: #135C39; }
/* Subtler sparkline — light stroke, no fill, push to row baseline */
.p360-tile-spark { height: 20px; margin-top: auto; opacity: 0.55; }
.p360-tile-spark svg { width: 100%; height: 100%; }
.p360-tile-delta {
  font-size: 11.5px;
  color: var(--color-text-muted, #6b7280);
  font-variant-numeric: tabular-nums;
  display: flex; align-items: baseline; gap: 6px;
}
.p360-tile-delta strong {
  font-weight: 600;
  font-size: 12px;
}
.p360-tile-delta-up   strong { color: #15803D; }
.p360-tile-delta-down strong { color: #B91C1C; }
.p360-tile-delta-flat strong { color: var(--color-text-muted, #6b7280); }

/* ── Body grid — two independent flex columns so cards stack tight w/o
   row-aligned gaps. With CSS Grid each row's height is forced to the tallest
   card in that row → short cards get empty space below. Flex columns let
   each column flow on its own. ── */
.p360-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  align-items: start;
}
@media (max-width: 1100px) { .p360-grid { grid-template-columns: 1fr; } }
.p360-col { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.p360-card {
  padding: 18px 20px;
  display: flex;
  flex-direction: column;
  border-radius: 10px;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
}
/* Guard — see .qh-pagination[hidden] above. #p360ScrapCard is hidden when the part
   has no scrap history (app.js:18159); without this an empty bordered card sat in
   the column claiming there was a scrap section to read. */
.p360-card[hidden] { display: none; }

.p360-card-head {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 10px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--color-border-light, #eaecef);
}
.p360-card-head h3 { margin: 0; font-size: 14px; font-weight: 600; letter-spacing: -0.1px; }
.p360-card-icon {
  width: 24px; height: 24px;
  border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  background: #EEF2FF;
  color: #4F46E5;
  font-size: 12px;
}
.p360-card-count { margin-left: auto; font-size: 11px; }
.p360-card-more {
  display: block;
  margin-top: 8px;
  text-align: center;
  font-size: 12px;
  color: var(--color-accent, #2563eb);
  text-decoration: none;
  padding: 6px;
  border-top: 1px solid var(--color-border-light, #eaecef);
}
.p360-card-more:hover { background: var(--color-surface-alt, #f8fafc); }
/* Guard — see .qh-pagination[hidden] above. The three "show more" links are hidden
   when the list is already short enough to be fully shown (app.js:17900/17924/17973);
   without this all three rendered permanently, offering to expand nothing. */
.p360-card-more[hidden] { display: none; }

.p360-table-wrap { overflow-x: auto; }
.p360-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.p360-table th, .p360-table td {
  text-align: left;
  padding: 9px 10px;
  border-bottom: 1px solid #F1F5F9;
}
.p360-table tbody tr:last-child td { border-bottom: none; }
.p360-table th {
  font-weight: 600;
  color: var(--color-text-muted, #6b7280);
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  padding-bottom: 8px;
  border-bottom: 1px solid #E2E8F0;
  background: transparent;
}
.p360-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.p360-table tbody tr { transition: background 0.12s ease; }
.p360-table tbody tr:hover { background: #F8FAFC; }

/* Material code chip — same chip language as hero status pills */
.p360-mat-chip {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  background: #EEF2FF;
  color: #4338CA;
  padding: 2px 8px;
  border-radius: 999px;
  letter-spacing: 0.2px;
}

/* ── Part Intelligence list — derived risk flags + quick stats ── */
.p360-intel-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.p360-intel-row {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 8px 4px;
  font-size: 12.5px;
  line-height: 1.4;
}
.p360-intel-row + .p360-intel-row { border-top: 1px solid #F1F5F9; padding-top: 10px; }
.p360-intel-bullet {
  width: 8px; height: 8px;
  border-radius: 50%;
  margin-top: 6px;
  flex-shrink: 0;
}
.p360-intel-bullet-ok   { background: #16A34A; }
.p360-intel-bullet-warn { background: #D97706; }
.p360-intel-bullet-risk { background: #DC2626; }
.p360-intel-bullet-info { background: #6366F1; }
.p360-intel-text { min-width: 0; }
.p360-intel-text strong { font-weight: 600; }
.p360-intel-sub { font-size: 11.5px; color: var(--color-text-muted, #6b7280); margin-top: 2px; }
.p360-intel-action {
  display: inline-block;
  margin-top: 6px;
  font-size: 11.5px;
  font-weight: 600;
  color: #4F46E5;
  text-decoration: none;
  padding: 4px 10px;
  border: 1px solid #C7D2FE;
  border-radius: 6px;
  background: #EEF2FF;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.p360-intel-action:hover { background: #E0E7FF; border-color: #A5B4FC; }

/* ── Production footprint card — which floor machines run this PN (live CMM) ── */
.p360-footprint-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; margin-bottom: 12px; }
.p360-footprint-head h3 { margin: 2px 0 0; }
.p360-footprint-body { display: flex; flex-direction: column; gap: 12px; }
.p360-fp-cell { display: flex; align-items: baseline; flex-wrap: wrap; gap: 10px; }
.p360-fp-cell-label { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: #7a8794; font-weight: 700; }
.p360-fp-machines { display: flex; flex-wrap: wrap; gap: 6px; }
.p360-fp-mach {
  border: 1px solid rgba(11,99,206,.25); background: #eef4fb; color: #0b63ce; border-radius: 7px;
  padding: 4px 10px; font-size: 13px; font-weight: 800; cursor: pointer; line-height: 1.3;
}
.p360-fp-mach:hover { background: #dce9fa; }
.p360-fp-mach small { font-weight: 600; color: #7a8794; margin-left: 4px; font-size: 10px; }
/* Static variant — rendered instead of a <button> when the user has no Machines
   grant, so the cell still reads but doesn't offer a click that would bounce.
   Neutral rather than blue: blue is this app's affordance colour. */
.p360-fp-mach-static {
  background: var(--prism-panel-subtle);
  border-color: var(--prism-line);
  color: var(--prism-ink-muted);
  cursor: default;
}
.p360-fp-mach-static:hover { background: var(--prism-panel-subtle); }
.p360-fp-stats { display: flex; flex-wrap: wrap; gap: 18px; }
.p360-fp-stat { display: flex; flex-direction: column; gap: 1px; }
.p360-fp-stat span { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: #7a8794; font-weight: 600; }
.p360-fp-stat strong { font-size: 16px; color: #1b3a5b; }
.p360-fp-stat em { font-size: 10px; font-style: normal; }
.p360-fp-note { font-size: 11px; line-height: 1.4; }

/* ── Scrap card — per-part scrap history (hidden when none) ── */
.p360-scrap-summary {
  display: flex; flex-wrap: wrap; gap: 14px;
  font-size: 12px;
  margin-bottom: 10px;
}
.p360-scrap-summary .p360-scrap-stat {
  display: flex; flex-direction: column; gap: 2px;
}
.p360-scrap-summary .p360-scrap-stat-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.3px;
  text-transform: uppercase;
  color: var(--color-text-muted, #6b7280);
}
.p360-scrap-summary .p360-scrap-stat-value {
  font-size: 17px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.p360-scrap-summary .p360-scrap-stat-value-bad { color: #B91C1C; }
.p360-scrap-summary .p360-scrap-stat-value-warn { color: #B45309; }
.p360-scrap-summary .p360-scrap-stat-sub { font-size: 10px; }
.p360-scrap-reasons {
  list-style: none; padding: 0; margin: 0 0 10px;
  display: flex; flex-wrap: wrap; gap: 6px;
}
.p360-scrap-reasons li {
  font-size: 11px;
  padding: 3px 9px;
  background: #FEE2E2;
  color: #991B1B;
  border-radius: 999px;
  font-weight: 500;
}
.p360-scrap-reasons li strong { font-weight: 700; margin-left: 4px; font-variant-numeric: tabular-nums; }

/* ── Similar Parts compact rows w/ score badge + sparkline ── */
.p360-similar-list { list-style: none; padding: 0; margin: 0; }
.p360-similar-row {
  display: grid;
  grid-template-columns: 70px 1fr 60px 40px;
  align-items: center;
  gap: 10px;
  padding: 8px 4px;
  border-bottom: 1px solid var(--color-border-light, #eaecef);
}
.p360-similar-row:last-child { border-bottom: none; }
.p360-similar-pn {
  font-weight: 600; font-size: 13px;
  color: var(--color-accent, #2563eb);
  text-decoration: none;
}
.p360-similar-pn:hover { text-decoration: underline; cursor: pointer; }
.p360-similar-meta { font-size: 11.5px; min-width: 0; }
.p360-similar-line1 { color: var(--color-text, #1f2937); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.p360-similar-line2 { color: var(--color-text-muted, #6b7280); font-size: 10.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.p360-similar-spark { height: 22px; }
.p360-similar-spark svg { width: 100%; height: 100%; }
.p360-similar-score {
  text-align: center;
  font-size: 12px;
  font-weight: 600;
  padding: 4px 0;
  border-radius: 999px;
  background: var(--color-surface-alt, #f4f6f8);
  font-variant-numeric: tabular-nums;
}
.p360-similar-score-hi  { background: #DCFCE7; color: #166534; }
.p360-similar-score-mid { background: #FEF3C7; color: #92400E; }
.p360-similar-score-lo  { background: #FEE2E2; color: #991B1B; }

.p360-avq-row { display: flex; justify-content: space-between; padding: 4px 0; font-size: 13px; }
.p360-avq-row strong { font-variant-numeric: tabular-nums; }
.p360-avq-delta { border-top: 1px dashed var(--color-border-light, #eaecef); margin-top: 4px; padding-top: 6px; }
.p360-avq-good strong { color: #1A7F37; }
.p360-avq-high strong { color: #9C0006; }
.p360-avq-low  strong { color: #B25E00; }
.p360-avq-caveat { font-size: 11px; line-height: 1.35; margin-top: 6px; padding-top: 6px; border-top: 1px dashed var(--color-border-light, #eaecef); }
.p360-avq-chart-wrap { position: relative; width: 100%; flex: 0 0 auto; height: 200px; margin-top: 6px; }
.p360-avq-chart-wrap[hidden] { display: none; }

.p360-features-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 8px;
}
.p360-feature {
  background: #F8FAFC;
  padding: 8px 10px;
  border-radius: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.p360-feature-label {
  font-size: 10.5px;
  letter-spacing: 0.2px;
  line-height: 1.2;
  word-break: break-word;
}
.p360-feature-value {
  font-size: 16px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
/* Boolean-true flags — chip-style with a check mark, no value */
.p360-feature-flag {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  background: #ECFDF5;
}
.p360-feature-check {
  width: 18px; height: 18px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: #16A34A;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  flex-shrink: 0;
}
.p360-feature-flag-label {
  font-size: 12px;
  font-weight: 600;
  color: #166534;
  line-height: 1.25;
  word-break: break-word;
}

.p360-files { list-style: none; padding: 0; margin: 0; font-size: 12px; }
.p360-files li { padding: 4px 0; }
.p360-files code { font-size: 11px; word-break: break-all; }

/* Smart Quote notes banner — surfaces the quoter's free-text notes at the
   top of the result pane (the engine doesn't auto-apply material/process
   hints from notes, so making them visible avoids confusion). */
.smart-notes-banner {
  padding: 10px 14px;
  margin: 0 0 12px 0;
  border-left: 3px solid #4F46E5;
  background: #EEF2FF;
  border-radius: 6px;
  font-size: 13px;
  color: #1E1B4B;
}
.smart-notes-banner[hidden] { display: none; }
.smart-notes-banner strong { font-weight: 600; }

/* ============================================================
   MATERIAL PRICER VIEW — added 2026-05-20
   Live material cost calculator. Layout matches the Pricer.xlsx
   we ship to Brad — but reactive + integrated into Prism nav.
   ============================================================ */
.mp-toolbar {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}
/* Source-age pills (audit finding 30). `order:-1` puts them on the LEFT of the
   right-aligned toolbar, so they read before the units toggle rather than being
   the last thing on the row — the prices below are only as good as these dates.
   Empty until the two fetches land, and it collapses to nothing rather than
   reserving a gap. */
.mp-freshness {
  order: -1;
  margin-right: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.mp-freshness:empty { display: none; }
.mp-units-toggle {
  display: inline-flex;
  background: #F1F5F9;
  border-radius: 999px;
  padding: 4px;
  gap: 2px;
}
.mp-units-btn {
  padding: 6px 18px;
  border: none;
  background: transparent;
  font-size: 12px;
  font-weight: 700;
  color: #64748B;
  border-radius: 999px;
  cursor: pointer;
  transition: all 0.15s;
}
.mp-units-btn:hover { color: #1E293B; }
.mp-units-active {
  background: #3B82F6;
  color: #FFF !important;
  box-shadow: 0 1px 3px rgba(59, 130, 246, 0.35);
}

.mp-layout {
  display: grid;
  grid-template-columns: 1fr 1.6fr;
  gap: 16px;
  margin-bottom: 16px;
}
@media (max-width: 1100px) {
  .mp-layout { grid-template-columns: 1fr; }
}

.mp-inputs-card,
.mp-summary-card,
.mp-table-card { padding: 18px; }

.mp-input-grid {
  display: grid;
  grid-template-columns: 90px 1fr;
  gap: 10px 14px;
  align-items: center;
  margin-top: 12px;
}
.mp-input-grid label {
  font-size: 12px;
  font-weight: 600;
  color: #475569;
  text-align: right;
}
.mp-input-unit-label {
  font-weight: 400;
  color: #94A3B8;
  font-size: 11px;
}
.mp-input {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #CBD5E1;
  border-radius: 6px;
  font-size: 14px;
  font-weight: 600;
  color: #0F172A;
  background: #FEFCE8;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.mp-input:focus {
  outline: none;
  border-color: #3B82F6;
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
}
select.mp-input { background: #FFF; }

.mp-warning {
  margin-top: 14px;
  padding: 10px 14px;
  background: #FEE2E2;
  border-left: 3px solid #DC2626;
  color: #991B1B;
  font-size: 13px;
  font-weight: 600;
  border-radius: 4px;
}

/* Catalog / blank endpoint error banner.
   Spans full width below the two-col layout; icon + text (not color-only).
   Contrast: #7C2D12 on #FEF3C7 ≈ 7:1 — passes AA. */
.mp-catalog-error {
  grid-column: 1 / -1;
  margin-top: 10px;
  padding: 10px 14px;
  background: #FEF3C7;
  border-left: 3px solid #D97706;
  color: #7C2D12;
  font-size: 13px;
  font-weight: 600;
  border-radius: 4px;
  outline: none;
}
.mp-catalog-error:focus-visible {
  outline: 2px solid #D97706;
  outline-offset: 2px;
}

.mp-summary-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  margin-top: 12px;
}
.mp-summary-tile {
  padding: 14px;
  background: #F8FAFC;
  border-radius: 8px;
  border: 1px solid #E2E8F0;
}
.mp-summary-label {
  font-size: 10px;
  font-weight: 700;
  color: #64748B;
  letter-spacing: 0.05em;
  margin-bottom: 6px;
}
.mp-summary-value {
  font-size: 18px;
  font-weight: 700;
  color: #0F172A;
}
.mp-summary-sub {
  font-size: 11px;
  color: #94A3B8;
  margin-top: 2px;
}

.mp-table-card { padding: 18px; }
.mp-table-wrap {
  overflow-x: auto;
  margin-top: 12px;
}
.mp-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.mp-table th {
  background: #1E293B;
  color: #F8FAFC;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 10px 12px;
  text-align: left;
  position: sticky;
  top: 0;
}
.mp-table td {
  padding: 9px 12px;
  border-bottom: 1px solid #F1F5F9;
  vertical-align: middle;
}
.mp-table tbody tr:nth-child(even) td { background: #FAFAFA; }
.mp-table tbody tr:hover td { background: #EFF6FF; }
.mp-cell-code {
  font-weight: 700;
  color: #1D4ED8;
  font-size: 13px;
}
.mp-cell-desc { color: #334155; }
.mp-cell-vendor { color: #64748B; font-size: 12px; }
.mp-cell-uom { color: #64748B; font-size: 12px; white-space: nowrap; }
.mp-cell-rate { color: #475569; text-align: right; font-variant-numeric: tabular-nums; }
.mp-cell-markup { color: #94A3B8; font-style: italic; font-size: 12px; text-align: right; font-variant-numeric: tabular-nums; }
.mp-cell-cost {
  font-weight: 700;
  color: #15803D;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-size: 14px;
}
.mp-cell-total {
  color: #475569;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.mp-badge {
  display: inline-block;
  padding: 1px 6px;
  font-size: 10px;
  font-weight: 700;
  border-radius: 999px;
  margin-left: 4px;
  vertical-align: middle;
}
.mp-badge-tariff {
  background: #FEE2E2;
  color: #B91C1C;
}
.mp-row-lowest td {
  background: #FEF3C7 !important;
  border-bottom-color: #FCD34D !important;
}
.mp-row-lowest .mp-cell-code::before {
  content: '★ ';
  color: #D97706;
}

.mp-lowest {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 18px 24px;
  background: linear-gradient(135deg, #1E40AF 0%, #1E3A8A 100%);
  color: #FFF;
  border-radius: 12px;
  margin-top: 16px;
  box-shadow: 0 4px 12px rgba(30, 64, 175, 0.25);
}
.mp-lowest-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.7);
  margin-bottom: 4px;
}
.mp-lowest-mat {
  font-size: 16px;
  color: #FFF;
}
.mp-lowest-mat strong { font-weight: 700; }
.mp-lowest-cost {
  font-size: 28px;
  font-weight: 700;
  color: #FFF;
  font-variant-numeric: tabular-nums;
}
.mp-lowest-right { text-align: right; }

/* Material Pricer — Summary layout. The 3D blank preview was removed 2026-07-10
   (Max); the three summary tiles now span the full card width as a KPI row. */
.mp-summary-layout {
  margin-top: 12px;
}
.mp-summary-stack {
  display: flex;
  flex-direction: row;
  gap: 12px;
}
@media (max-width: 720px) {
  .mp-summary-stack { flex-direction: column; }
}
.mp-summary-stack .mp-summary-tile {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* Material code column — stacked code + description for compactness */
.mp-cell-code-label {
  font-weight: 700;
  color: #1D4ED8;
  font-size: 13px;
}
.mp-cell-code-desc {
  color: #64748B;
  font-size: 11px;
  font-weight: 400;
}
.mp-cell-notes {
  color: #94A3B8;
  font-style: italic;
  font-size: 11px;
}

/* Material Pricer — oversize / no-stocked-fit estimate rows: a $ figure that
   needs a sourcing decision. material-pricer.js adds this class, and there was
   no rule behind it, so only the inline badge showed (Q-17). */
.mp-row-oversize td {
  background: #FFFBEB;
}
.mp-row-oversize .mp-cell-cost,
.mp-row-oversize .mp-cell-total {
  color: #92400E;
}

/* Material Pricer — no-fit rows: muted/grayed so they're visually de-emphasized */
.mp-row-nofit td {
  opacity: 0.55;
  background: #FAFAFA !important;
}
.mp-row-nofit .mp-cell-cost,
.mp-row-nofit .mp-cell-total {
  color: #94A3B8 !important;
  font-weight: 500;
}
.mp-row-nofit .mp-cell-notes {
  color: #B91C1C;
  font-style: italic;
  font-size: 11px;
}
.mp-nofit {
  color: #94A3B8;
  font-weight: 400;
}

/* ---- Quoted vs Actual — shape filter pills + sortable table -------------- */
.qva-shape-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 8px 0 10px;
}
.qva-pill {
  padding: 3px 10px;
  border-radius: 20px;
  border: 1px solid var(--sd-border);
  background: var(--sd-muted-surface);
  color: var(--prism-text);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
  line-height: 1.6;
}
.qva-pill:hover { background: var(--sd-hover); }
.qva-pill.active {
  background: var(--prism-blue);
  border-color: var(--prism-blue);
  color: #fff;
}
.qva-shape-dot {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  margin-right: 5px;
  vertical-align: middle;
}
.qva-ratio-low  { color: var(--prism-green); font-weight: 600; }
.qva-ratio-high { color: var(--prism-red);   font-weight: 600; }

/* search bar */
.qva-search-wrap {
  position: relative;
  margin-top: 10px;
}
.qva-search-input {
  width: 100%;
  box-sizing: border-box;
  padding: 6px 10px;
  border: 1px solid var(--sd-border);
  border-radius: 6px;
  font-size: 13px;
  background: var(--sd-muted-surface);
  color: var(--prism-text);
  outline: none;
}
.qva-search-input:focus {
  border-color: var(--prism-blue);
  background: #fff;
}
.qva-search-results {
  position: absolute;
  left: 0; right: 0;
  background: #fff;
  border: 1px solid var(--sd-border);
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
  z-index: 50;
  overflow: hidden;
}
.qva-search-row {
  display: flex;
  gap: 12px;
  align-items: center;
  padding: 7px 12px;
  font-size: 12px;
  border-bottom: 1px solid var(--sd-border-soft);
}
.qva-search-row:last-child { border-bottom: none; }
.qva-search-row:hover { background: var(--sd-hover); }
.qva-search-pn { font-weight: 600; min-width: 52px; }
.qva-search-empty { padding: 10px 12px; font-size: 12px; color: var(--prism-muted); }

/* taller chart in QvA card */
.qva-card .chart-container { height: 340px; }

/* QvA drilldown modal */
.qva-detail-modal { max-width: 880px; width: 92vw; max-height: 86vh; overflow: hidden; display: flex; flex-direction: column; }
.qva-detail-modal .sd-modal-body { overflow-y: auto; }
.qva-detail-shape { font-size: 13px; color: var(--prism-muted); }
.qva-detail-p360-link { text-decoration: none; cursor: pointer; }
.qva-detail-p360-link:hover { text-decoration: underline; }
.qva-detail-stats {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 12px; padding: 10px 14px; margin: 12px 0;
  background: var(--sd-muted-surface);
  border: 1px solid var(--sd-border-soft);
  border-radius: 6px;
}
.qva-detail-stats > div { display: flex; flex-direction: column; gap: 2px; }
.qva-detail-stats span.muted { font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; }
.qva-detail-stats strong { font-size: 15px; font-variant-numeric: tabular-nums; }
.qva-detail-chart-wrap {
  height: 220px;
  background: linear-gradient(180deg, #f8fafc 0%, #ffffff 100%);
  border: 1px solid var(--sd-border);
  border-radius: 8px;
  padding: 10px;
  margin-bottom: 14px;
}
.qva-detail-table-wrap { max-height: 280px; overflow-y: auto; border: 1px solid var(--sd-border-soft); border-radius: 6px; }
.qva-detail-table { font-size: 12px; }
.qva-detail-table th { position: sticky; top: 0; background: var(--sd-muted-surface); z-index: 1; }
.qva-row-dropped td { opacity: 0.55; }

/* ── Data freshness trust banner (Quote Builder / Part 360 / Customer 360) ──────
   Informational, non-blocking. Reuses the same warn token as .badge-warn. Injected
   at the top of a view by renderFreshnessBanner() only when source data is stale. */
.freshness-banner {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 16px;
  padding: 10px 14px;
  border: 1px solid rgba(201, 122, 23, 0.30);
  border-left: 4px solid var(--color-warn, #c97a17);
  border-radius: 8px;
  background: rgba(201, 122, 23, 0.08);
  color: var(--color-warn, #c97a17);
  font-size: 13px;
  font-weight: 500;
}
.freshness-banner-icon { font-size: 14px; line-height: 1; }

/* ============================================================================
   Waterjet Auto-Programmer  (waterjet.js renders into #wjRoot)
   Manufacturing/CAM review workflow. Accent colors here mirror the canvas
   drawing in waterjet.js: OD #3b82f6, ID #22d3ee, pierce #f59e0b.
   ============================================================================ */
#wjRoot { --wj-od:#3b82f6; --wj-id:#22d3ee; --wj-pierce:#f59e0b; --wj-canvas:#0b1220; }
/* the hidden attribute must win over display:flex/grid set in component classes
   (.wj-banner/.wj-empty/.wj-anim etc. set display, which otherwise overrides [hidden]) */
#wjRoot [hidden] { display: none !important; }
.wj-head h1 { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }

/* badges */
.wj-badge { font-size:11px; font-weight:700; letter-spacing:.02em; padding:2px 8px; border-radius:999px; vertical-align:middle; text-transform:uppercase; }
.wj-badge-dev    { color:#b45309; background:#fef3c7; }
.wj-badge-exp    { color:#9333ea; background:#f3e8ff; }
.wj-badge-review { color:#b91c1c; background:#fee2e2; }
.wj-badge-synth  { color:#0369a1; background:#e0f2fe; text-transform:none; font-weight:600; }

/* stepper */
.wj-stepper { display:flex; align-items:center; gap:4px; flex-wrap:wrap; margin:4px 0 18px; padding:14px 16px;
  background:var(--color-surface,#fff); border:1px solid var(--color-border,#e2e8f0); border-radius:var(--prism-radius-md,12px); }
.wj-step { display:flex; align-items:center; gap:8px; padding:4px 6px; }
.wj-step-dot { width:24px; height:24px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  font-size:12px; font-weight:700; background:#e2e8f0; color:#64748b; flex:none; transition:.2s; }
.wj-step-label { font-size:12.5px; font-weight:600; color:#94a3b8; white-space:nowrap; }
.wj-step-line { flex:1; min-width:14px; height:2px; background:#e2e8f0; border-radius:2px; }
.wj-step.is-active   .wj-step-dot { background:var(--wj-od); color:#fff; box-shadow:0 0 0 4px rgba(59,130,246,.15); }
.wj-step.is-active   .wj-step-label { color:#1e293b; }
.wj-step.is-complete .wj-step-dot { background:#16a34a; color:#fff; }
.wj-step.is-complete .wj-step-label { color:#15803d; }
.wj-step.is-warning  .wj-step-dot { background:#f59e0b; color:#fff; }
.wj-step.is-warning  .wj-step-label { color:#b45309; }

/* two-column layout */
.wj-grid { display:grid; grid-template-columns:minmax(0,1fr); gap:18px; align-items:start; }
.wj-main { display:flex; flex-direction:column; gap:16px; min-width:0; }
/* inline operator notes (right-rail preflight + risk-flag panel removed — keep only the must-see safety line inline) */
.wj-make-note { margin:-4px 2px 0; padding:9px 12px; border:1px solid #f59e0b55; background:#fffbeb; color:#92400e; border-radius:9px; font-size:13px; line-height:1.35; }
.wj-dim-err { margin:8px 2px 0; padding:8px 11px; border:1px solid #ef444455; background:#fef2f2; color:#b91c1c; border-radius:9px; font-size:13px; font-weight:600; }
.wj-cut-caution { margin:0 0 8px; padding:8px 11px; border:1px solid #f59e0b66; background:#fffbeb; color:#92400e; border-radius:9px; font-size:12.5px; line-height:1.35; }
.wj-leadloc { font-size:11px; padding:2px 4px; margin-left:6px; }
.wj-offset-chips { display:inline-flex; gap:4px; margin-left:8px; }
.wj-offset-chips button { font-size:11px; padding:2px 8px; border-radius:11px; border:1px solid var(--border,#cbd5e1); background:transparent; color:var(--text-muted,#64748b); cursor:pointer; line-height:1.4; }
.wj-offset-chips button:hover { border-color:var(--accent,#2563eb); color:var(--accent,#2563eb); }
@media (prefers-color-scheme:dark){
  .wj-make-note { background:#1f1605; color:#fcd34d; border-color:#f59e0b40; }
  .wj-dim-err { background:#1f0a0a; color:#fca5a5; border-color:#ef444440; }
  .wj-cut-caution { background:#1f1605; color:#fcd34d; border-color:#f59e0b40; }
}
.wj-card { margin:0; }
.wj-card-title { font-size:14px; font-weight:700; color:#1e293b; margin:0 0 12px; }
.wj-sub { font-size:12px; font-weight:600; color:#475569; margin:16px 0 8px; }
.wj-muted { color:#94a3b8; font-weight:400; }
.wj-tiny { font-size:11.5px; }

/* dropzone */
.wj-dropzone { border:2px dashed #cbd5e1; border-radius:12px; padding:22px; text-align:center; cursor:pointer;
  background:#f8fafc; color:#475569; transition:.15s; }
.wj-dropzone:hover { border-color:var(--wj-od); background:#f0f7ff; }
.wj-dropzone.is-drag { border-color:var(--wj-od); background:#e0edff; }
.wj-dropzone.is-loaded { border-style:solid; border-color:#16a34a; background:#f0fdf4; }
.wj-drop-inner { display:flex; flex-direction:column; align-items:center; gap:6px; }
.wj-drop-inner svg { color:#94a3b8; }
.wj-dropzone.is-loaded .wj-drop-inner svg { color:#16a34a; }
.wj-drop-hint { font-size:11.5px; color:#94a3b8; }

/* sample cards + chips */
.wj-samples { display:flex; flex-wrap:wrap; gap:8px; }
.wj-sample-card { display:flex; flex-direction:column; align-items:flex-start; gap:1px; padding:8px 12px; min-width:84px;
  border:1px solid var(--color-border,#e2e8f0); border-radius:9px; background:#fff; cursor:pointer; transition:.12s; }
.wj-sample-card:hover { border-color:var(--wj-od); box-shadow:0 1px 4px rgba(0,0,0,.06); }
.wj-sample-card.is-active { border-color:var(--wj-od); background:#eff6ff; box-shadow:0 0 0 1px var(--wj-od) inset; }
.wj-sample-pn { font-family:ui-monospace,Menlo,monospace; font-weight:700; font-size:13px; color:#1e293b; }
/* "or type dimensions" entry — a first-class alternative to a file upload (no CAD needed for
   plain round / rect parts). Promoted out of the old collapsed "test shape" disclosure. */
.wj-or { display:flex; align-items:center; gap:10px; margin:14px 0 12px; color:#94a3b8;
  font-size:11.5px; font-weight:700; text-transform:uppercase; letter-spacing:.08em; }
.wj-or::before, .wj-or::after { content:''; flex:1; height:1px; background:#e2e8f0; }
.wj-typein { border:1px solid #dbe6f3; border-radius:12px; padding:14px 16px; background:#f7fbff; }
.wj-typein-head { font-size:12.5px; color:#475569; margin-bottom:10px; }
.wj-shapes { display:flex; flex-wrap:wrap; gap:8px; }
.wj-shape-chip { padding:7px 14px; border:1px solid var(--color-border,#e2e8f0); border-radius:999px; background:#fff;
  cursor:pointer; font-size:13px; font-weight:600; color:#475569; transition:.12s; }
.wj-shape-chip:hover { border-color:#0ea5e9; color:#0369a1; }
.wj-shape-chip.is-active { border-color:#0ea5e9; background:#e0f2fe; color:#0369a1; box-shadow:0 0 0 1px #0ea5e9 inset; }
.wj-select { padding:7px 10px; border:1px solid var(--color-border,#e2e8f0); border-radius:8px; font-size:13px; background:#fff; color:#1e293b; }
.wj-select-sm { padding:3px 6px; font-size:12px; }

/* polishing-carrier chips + pocket fitter */
.wj-carrier-chip { display:inline-flex; flex-direction:column; align-items:flex-start; gap:1px; padding:8px 15px;
  border:1px solid var(--color-border,#e2e8f0); border-radius:12px; background:#fff; cursor:pointer;
  font-size:13px; font-weight:700; color:#475569; transition:.12s; }
.wj-carrier-chip:hover { border-color:#0ea5e9; color:#0369a1; }
.wj-carrier-chip.is-active { border-color:#0ea5e9; background:#e0f2fe; color:#0369a1; box-shadow:0 0 0 1px #0ea5e9 inset; }
.wj-chip-sub { font-size:10.5px; font-weight:500; color:#94a3b8; letter-spacing:.2px; }
.wj-carrier-chip.is-active .wj-chip-sub { color:#0284c7; }
.wj-carrier-panel { margin-top:14px; padding:14px; border:1px solid #e2e8f0; border-radius:12px; background:#f8fafc; display:flex; flex-direction:column; gap:13px; }
.wj-seg { display:inline-flex; border:1px solid #cbd5e1; border-radius:9px; overflow:hidden; align-self:flex-start; }
.wj-seg-btn { padding:6px 16px; border:none; background:#fff; cursor:pointer; font-size:12.5px; font-weight:600; color:#64748b; }
.wj-seg-btn + .wj-seg-btn { border-left:1px solid #cbd5e1; }
.wj-seg-btn.is-active { background:#0ea5e9; color:#fff; }
.wj-fit { display:flex; align-items:center; gap:8px; font-size:13px; color:#475569; }
.wj-fit-max b { color:#0369a1; font-size:15px; }
.wj-fit-now b { color:#0f172a; font-size:15px; }
.wj-fit-sep { color:#cbd5e1; }
.wj-fit-over { margin-left:4px; padding:1px 8px; border-radius:999px; background:#fef3c7; color:#b45309; font-size:11px; font-weight:700; }
.wj-carrier-actions { display:flex; gap:9px; flex-wrap:wrap; }

/* cut scope + offsets */
.wj-scope { display:grid; grid-template-columns:1fr; gap:10px; }
.wj-check { display:flex; align-items:center; gap:9px; font-size:13.5px; color:#1e293b; cursor:pointer; }
.wj-check input { width:17px; height:17px; accent-color:var(--wj-od); cursor:pointer; }
.wj-offset-row { display:flex; align-items:center; gap:8px; padding-left:26px; font-size:12.5px; color:#64748b; }
.wj-offset-lab { min-width:96px; }
.wj-input { width:90px; padding:6px 8px; border:1px solid var(--color-border,#e2e8f0); border-radius:7px; font-size:13px; }
.wj-input.is-muted { opacity:.4; background:#f1f5f9; }
/* multi-body pick (a 3D model holding several solid bodies — usually a multi-up layout).
   Amber, because it is a decision the operator has to make about what gets cut, not a setting
   with a safe default. Hidden via [hidden] in the markup — no class here sets `display`, which
   would beat the attribute at equal specificity (see the 2026-08-05 sweep). */
.wj-bodypick { margin-top:14px; padding:10px 12px; border:1px solid #fcd34d; background:#fffbeb; border-radius:9px; }
.wj-bodypick-head { font-size:13px; color:#78350f; margin-bottom:8px; }
.wj-bodypick-btns { display:flex; gap:6px; flex-wrap:wrap; margin-bottom:6px; }
.wj-bodybtn { font-size:12.5px; padding:5px 12px; border:1px solid #e2e8f0; background:#fff; color:#334155;
  border-radius:999px; cursor:pointer; font-weight:600; }
.wj-bodybtn:hover { border-color:#94a3b8; }
.wj-bodybtn.is-on { background:#1d4ed8; border-color:#1d4ed8; color:#fff; }
.wj-scope-summary { display:flex; gap:8px; flex-wrap:wrap; margin-top:14px; }
.wj-pill { font-size:12px; padding:4px 10px; border-radius:999px; }
.wj-pill.is-in  { background:#eff6ff; color:#1d4ed8; }
.wj-pill.is-out { background:#f1f5f9; color:#94a3b8; }
.wj-guard { margin-top:10px; padding:8px 12px; background:#fee2e2; color:#b91c1c; border-radius:8px; font-size:13px; font-weight:600; }

/* actions */
.wj-actions { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.wj-ghost { background:transparent; color:#64748b; }
.wj-status { font-size:13px; color:#64748b; }
.wj-status.is-err { color:#dc2626; font-weight:600; }

/* preview / dry run */
.wj-banner { margin-bottom:12px; padding:8px 12px; background:#fef3c7; color:#92400e; border-radius:8px; font-size:12.5px; display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.wj-regen { padding:5px 14px; font-size:12.5px; white-space:nowrap; }
.wj-canvas-wrap { position:relative; }
.wj-canvas { width:100%; max-width:1200px; height:auto; aspect-ratio:1280/860; display:block; margin:0 auto;
  border:1px solid #1e293b; border-radius:10px; background:var(--wj-canvas); }
.wj-empty { position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center;
  text-align:center; color:#cbd5e1; font-size:14px; font-weight:600; pointer-events:none; }
.wj-anim { display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:12px; }
.wj-anim-btn { padding:5px 12px; font-size:12.5px; }
.wj-speed { font-size:12px; color:#64748b; display:flex; align-items:center; gap:6px; }
.wj-steplabel { font-size:12.5px; font-weight:700; color:#b45309; font-family:ui-monospace,Menlo,monospace; }
.wj-legend { display:flex; gap:16px; flex-wrap:wrap; margin-top:12px; padding-top:12px; border-top:1px solid #f1f5f9; }
.wj-leg { display:flex; align-items:center; gap:6px; font-size:12px; color:#64748b; }
.wj-sw { width:18px; height:0; border-top-width:3px; border-top-style:solid; display:inline-block; }
.wj-sw-od { border-color:var(--wj-od); }
.wj-sw-id { border-color:var(--wj-id); }
.wj-sw-excl { border-top-style:dashed; border-color:#64748b; }
.wj-sw-rapid { border-color:#94a3b8; border-top-style:dotted; }
.wj-dot { width:10px; height:10px; border-radius:50%; display:inline-block; }
.wj-dot-pierce { background:var(--wj-pierce); }

/* OMAX rules */
.wj-rule-warn { background:#fef2f2; border:1px solid #fecaca; color:#991b1b; padding:10px 12px; border-radius:9px; font-size:12.5px; line-height:1.5; margin-bottom:12px; }
.wj-rule-list { margin:0; padding-left:18px; font-size:12.5px; color:#475569; line-height:1.7; }

/* preflight */
.wj-pf-progress { display:flex; align-items:center; gap:10px; margin-bottom:12px; }
.wj-pf-bar { flex:1; height:7px; background:#e2e8f0; border-radius:4px; overflow:hidden; }
.wj-pf-bar span { display:block; height:100%; background:#16a34a; transition:width .2s; }
.wj-preflight { display:flex; flex-direction:column; gap:7px; }
.wj-pf-item { display:flex; align-items:flex-start; gap:9px; font-size:12.5px; color:#334155; cursor:pointer; line-height:1.4; }
.wj-pf-item input { width:16px; height:16px; margin-top:1px; accent-color:#16a34a; flex:none; cursor:pointer; }
.wj-pf-warn { margin-top:12px; font-size:12px; }
.wj-pf-incomplete { color:#b45309; font-weight:600; }
.wj-pf-ok { color:#15803d; font-weight:600; }

/* warnings */
.wj-warnings { display:flex; flex-direction:column; gap:8px; }
.wj-warn { display:flex; gap:8px; align-items:flex-start; padding:8px 11px; border-radius:8px; font-size:12.5px; line-height:1.45; }
.wj-warn.is-danger { background:#fef2f2; color:#991b1b; }
.wj-warn.is-warn   { background:#fffbeb; color:#92400e; }
.wj-warn.is-info   { background:#f0f9ff; color:#075985; }

/* bottom / output */
.wj-bottom { display:grid; grid-template-columns:minmax(0,1.4fr) minmax(0,1fr); gap:18px; margin-top:18px; }
@media (max-width:1080px){ .wj-bottom { grid-template-columns:1fr; } }
.wj-files { display:flex; flex-direction:column; gap:10px; }
.wj-file-card { display:flex; align-items:center; gap:12px; padding:11px 14px; border:1px solid var(--color-border,#e2e8f0); border-radius:10px; background:#fff; }
.wj-file-card.is-disabled { opacity:.7; background:#f8fafc; }
.wj-file-ic { width:34px; height:34px; border-radius:8px; background:#eff6ff; color:var(--wj-od); display:flex; align-items:center; justify-content:center; font-size:16px; flex:none; }
.wj-file-card.is-disabled .wj-file-ic { background:#f1f5f9; color:#94a3b8; }
.wj-file-body { flex:1; min-width:0; }
.wj-file-name { font-family:ui-monospace,Menlo,monospace; font-weight:700; font-size:13px; color:#1e293b; word-break:break-all; }
.wj-file-meta { font-size:11.5px; color:#94a3b8; }
.wj-dl { padding:5px 14px; font-size:12.5px; }
.wj-guts { margin-top:14px; }
.wj-guts summary { cursor:pointer; font-size:12.5px; font-weight:600; color:#475569; }
.wj-guts-tabs { display:flex; gap:8px; flex-wrap:wrap; margin:10px 0; }
.wj-gtab { font-size:12px; padding:4px 10px; }
.wj-code { background:var(--wj-canvas); color:#e2e8f0; padding:14px; border-radius:8px; overflow:auto; max-height:380px; font-size:11.5px; line-height:1.5; margin:0; }

/* program summary */
.wj-summary { display:flex; flex-direction:column; }
.wj-sum-row { display:flex; justify-content:space-between; gap:14px; padding:7px 0; border-bottom:1px solid #f1f5f9; font-size:13px; color:#475569; }
.wj-sum-row b { color:#1e293b; text-align:right; }
.wj-out { color:#94a3b8; font-weight:600; }
.wj-sum-note { margin-top:12px; padding:9px 12px; background:#fffbeb; color:#92400e; border-radius:8px; font-size:12px; line-height:1.5; }

/* parametric shape dimensions + pierce drag */
.wj-shape-dims { margin-top:12px; padding:12px 14px; background:#f8fafc; border:1px solid var(--color-border,#e2e8f0); border-radius:9px; }
.wj-dim-row { display:flex; flex-wrap:wrap; gap:16px; }
.wj-dim { display:flex; align-items:center; gap:7px; font-size:12.5px; color:#475569; }
.wj-dim > span:first-child { font-weight:600; color:#334155; }
.wj-dim input { width:74px; padding:5px 8px; border:1px solid var(--color-border,#e2e8f0); border-radius:7px; font-size:13px; }
.wj-pierce-hint { margin-top:10px; font-size:12px; color:#64748b; }
.wj-dot-bad { background:#dc2626; }

/* canvas zoom toolbar */
.wj-zoombar { position:absolute; top:10px; right:10px; display:flex; align-items:center; gap:5px; background:rgba(15,23,42,.72); padding:4px 7px; border-radius:9px; backdrop-filter:blur(2px); }
.wj-zoom-btn { width:26px; height:26px; border:none; border-radius:6px; background:#1e293b; color:#e2e8f0; font-size:16px; font-weight:700; cursor:pointer; line-height:1; display:flex; align-items:center; justify-content:center; padding:0; }
.wj-zoom-btn:hover { background:#334155; }
.wj-zoom-lvl { color:#cbd5e1; font-size:11px; font-family:ui-monospace,Menlo,monospace; min-width:36px; text-align:center; }
.wj-canvas.wj-adding { cursor:crosshair; }

/* per-feature select/deselect + add hole */
.wj-feat-head { font-size:12px; font-weight:600; color:#475569; margin:16px 0 8px; }
.wj-features { display:flex; flex-direction:column; gap:4px; max-height:200px; overflow:auto; }
.wj-feat { display:flex; align-items:center; gap:8px; font-size:12.5px; color:#334155; padding:4px 6px; border-radius:6px; }
.wj-feat:hover { background:#f8fafc; }
.wj-feat input[type=checkbox] { width:15px; height:15px; accent-color:var(--wj-od); cursor:pointer; }
.wj-feat.is-added { background:#ecfeff; }
.wj-feat-ic { color:#0891b2; font-weight:700; }
.wj-feat-lbl { font-family:ui-monospace,Menlo,monospace; flex:1; }
.wj-feat-dia { display:flex; align-items:center; gap:4px; color:#64748b; font-size:12px; }
.wj-feat-dia input { width:62px; padding:3px 6px; border:1px solid var(--color-border,#e2e8f0); border-radius:6px; font-size:12.5px; }
.wj-feat-x { border:none; background:#fee2e2; color:#b91c1c; width:20px; height:20px; border-radius:5px; cursor:pointer; font-size:14px; line-height:1; padding:0; }
.wj-feat-x:hover { background:#fecaca; }
.wj-addhole-btn { margin-top:10px; font-size:12.5px; padding:6px 12px; }

/* ---- polish pass + new status components (2026-06-09) ---- */
/* preview = the star: a touch more presence + room */
.wj-preview-card { box-shadow:0 1px 3px rgba(15,23,42,.06); }

/* at-a-glance preview badges */
.wj-pvbadges { display:flex; gap:8px; flex-wrap:wrap; margin-bottom:12px; }
.wj-pvbadges:empty { display:none; }
.wj-pvbadge { font-size:11.5px; font-weight:700; padding:3px 11px; border-radius:999px; letter-spacing:.01em; }
.wj-pvbadge.is-ok { background:#dcfce7; color:#15803d; }
.wj-pvbadge.is-bad { background:#fee2e2; color:#b91c1c; }
.wj-pvbadge.is-off { background:#f1f5f9; color:#94a3b8; }
.wj-pvbadge.is-neutral { background:#eff6ff; color:#1d4ed8; }
.wj-pvbadge.is-info { background:#e0f2fe; color:#0369a1; }

/* stale banner = red, not the soft amber default */
.wj-banner.is-stale { background:#fef2f2; color:#991b1b; border:1px solid #fecaca; font-weight:600; }

/* OMAX rules collapsed reference */
.wj-rules-details { margin-top:4px; }
.wj-rules-details summary { cursor:pointer; font-size:12.5px; font-weight:700; color:#64748b; padding:2px 0; }
.wj-rules-details summary:hover { color:#334155; }
.wj-rules-details .wj-rule-list { margin-top:10px; }
/* warnings card carries the most weight in the rail */
.wj-warn-card { border-color:#fecaca; }

/* preflight group headers */
.wj-pf-group { font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:#94a3b8; margin:12px 0 5px; }
.wj-pf-group:first-child { margin-top:2px; }

/* stale-file safety */
.wj-files-stale { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:10px 14px; margin-bottom:10px; background:#fef2f2; border:1px solid #fecaca; color:#991b1b; border-radius:10px; font-size:12.5px; font-weight:600; flex-wrap:wrap; }
.wj-file-stale { font-size:10px; font-weight:800; color:#b91c1c; background:#fee2e2; padding:1px 7px; border-radius:5px; margin-left:6px; }
.wj-file-card.is-disabled .wj-file-ic { background:#fef2f2; color:#dc2626; }

/* release / finish-line bar */
.wj-release { display:flex; align-items:center; gap:12px; padding:14px 18px; border-radius:12px; margin-bottom:18px; font-size:14px; flex-wrap:wrap; }
.wj-release:empty { display:none; }
.wj-release-dot { width:12px; height:12px; border-radius:50%; flex:none; }
.wj-release-lbl { font-weight:800; }
.wj-release-sub { font-weight:400; font-size:12.5px; opacity:.85; }
.wj-release.is-ok { background:#dcfce7; color:#15803d; } .wj-release.is-ok .wj-release-dot { background:#16a34a; }
.wj-release.is-warn { background:#fef3c7; color:#b45309; } .wj-release.is-warn .wj-release-dot { background:#f59e0b; }
.wj-release.is-danger { background:#fee2e2; color:#b91c1c; } .wj-release.is-danger .wj-release-dot { background:#dc2626; }


/* ============================================================
   WATERJET — operator-friendly pass (2026-06-19)
   Legibility bumps + plain-language control components for the
   computer-shy operator. Light card UI; bigger text + targets.
   ============================================================ */

/* --- legibility: bump the small type the operator squints at --- */
.wj-card-title { font-size: 16px; }
.wj-tiny { font-size: 12.5px; }
.wj-feat { font-size: 14px; }
.wj-check { font-size: 15px; }
.wj-step-label { font-size: 13.5px; }
.wj-status { font-size: 14px; }
.wj-feat-head { font-size: 13.5px; }
.wj-drop-hint { font-size: 12.5px; }
.wj-offset-row { font-size: 14px; color: #334155; }
.wj-offset-lab { min-width: 152px; font-weight: 600; color: #334155; }
.wj-input { width: 96px; font-size: 14.5px; padding: 9px 10px; min-height: 40px; }

/* --- stock callout: "what stock are you cutting out of" (inside the cut-scope card) --- */
.wj-substep { margin: 16px 0 8px; padding-top: 14px; border-top: 1px solid var(--color-border, #e2e8f0);
  font-size: 14.5px; font-weight: 800; color: #1e293b; }
.wj-stock-readout { margin: 8px 0 2px 26px; font-size: 13px; color: #475569; }
.wj-stock-readout b { color: #1e293b; font-weight: 700; }
.wj-stock-bad { color: #b91c1c; font-weight: 800; }

/* bigger, tappable dropdowns everywhere on the tab */
.wj-select { font-size: 14.5px; padding: 9px 12px; min-height: 40px; }
.wj-select-sm { font-size: 13px; padding: 3px 7px; min-height: 0; }
.wj-select:focus-visible, .wj-input:focus-visible,
.wj-leadtog:focus-visible, .wj-bulk .btn:focus-visible {
  outline: 2px solid var(--prism-blue); outline-offset: 1px;
}

/* --- "what to do next" coach line under the stepper --- */
.wj-coach { display: flex; align-items: center; gap: 10px; margin: -10px 0 18px;
  padding: 11px 16px; border-radius: 10px; font-size: 14.5px; line-height: 1.45; font-weight: 500; }
.wj-coach:empty { display: none; }
.wj-coach b { font-weight: 800; }
.wj-coach-ic { flex: none; width: 10px; height: 10px; border-radius: 50%; }
.wj-coach.is-go   { background: var(--prism-blue-soft);  color: #0f3a63; border: 1px solid var(--prism-blue-line); }
.wj-coach.is-go   .wj-coach-ic { background: var(--prism-blue); }
.wj-coach.is-warn { background: var(--prism-amber-soft); color: #7a4600; border: 1px solid var(--prism-amber-line); }
.wj-coach.is-warn .wj-coach-ic { background: var(--prism-amber); }
.wj-coach.is-busy { background: var(--prism-panel-subtle); color: var(--prism-ink-muted); border: 1px solid var(--prism-line); }
.wj-coach.is-busy .wj-coach-ic { background: var(--prism-ink-soft); }

/* --- per-feature row: name + kerf picture + lead picture + lead-out --- */
.wj-feat-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 8px; border-bottom: 1px solid var(--prism-line); }
.wj-feat-row:last-child { border-bottom: 0; }
.wj-feat-row:hover { background: #f8fafc; }
.wj-feat-name { display: flex; align-items: center; gap: 8px; flex: 1 1 190px; min-width: 150px; margin: 0; border: 0; padding: 0; cursor: pointer; }

/* the little inline pictures (kerf side / lead direction) sit in a chip */
.wj-ctl { display: inline-flex; align-items: center; gap: 6px; }
.wj-glyph { flex: none; border: 1px solid var(--prism-line); border-radius: 6px; background: #fff; padding: 1px; }

/* lead-out toggle — green "add", red "on" (drag the handle) */
.wj-leadtog { display: inline-flex; align-items: center; gap: 5px; min-height: 38px;
  padding: 7px 14px; border-radius: 999px; border: 1.5px solid var(--prism-green);
  background: #fff; color: var(--prism-green); font-size: 13px; font-weight: 700;
  cursor: pointer; white-space: nowrap; transition: background .12s, border-color .12s, color .12s; }
.wj-leadtog:hover { background: var(--prism-green-soft); }
.wj-leadtog.is-on { border-color: var(--prism-red); color: var(--prism-red); }
.wj-leadtog.is-on:hover { background: var(--prism-red-soft); }

/* --- cut-order column inside the merged feature row (sequence # + ▲▼ reorder) --- */
.wj-cut-seq { display: inline-flex; align-items: center; gap: 3px; flex: none; }
.wj-cut-num { min-width: 20px; text-align: center; font-weight: 800; font-size: 14px; color: var(--prism-blue); }
.wj-cut-num.is-skip { color: var(--prism-ink-soft); font-weight: 400; }
.wj-cut-arrow { width: 26px; height: 30px; padding: 0; border: 1.5px solid var(--prism-line-strong); border-radius: 6px;
  background: #fff; cursor: pointer; font-size: 12px; font-weight: 700; line-height: 1; color: var(--prism-ink); }
.wj-cut-arrow:hover:not(:disabled) { background: var(--prism-panel-subtle); border-color: var(--prism-blue); }
.wj-cut-arrow:disabled { opacity: .3; cursor: default; }
.wj-feat-row.is-skip { opacity: .55; }
.wj-skip-head { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  color: var(--prism-ink-soft); margin: 12px 0 4px; }
.wj-cut-resetwrap { margin-top: 8px; }
#wjCutReset { background: transparent; border: 0; text-decoration: underline; cursor: pointer;
  color: var(--prism-ink-muted); font-size: 12.5px; padding: 0; }
.wj-cut-caution { padding: 9px 13px; margin-bottom: 8px; border-radius: 9px; background: var(--prism-amber-soft);
  border: 1px solid var(--prism-amber-line); color: #7a4600; font-size: 13px; font-weight: 600; line-height: 1.4; }
#wjCutFix { background: transparent; border: 0; color: inherit; text-decoration: underline; cursor: pointer; font-weight: 800; padding: 0; }

/* --- Apply-to-all bar (set every feature at once) --- */
.wj-bulk { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 6px 0 12px; padding: 10px 14px; border: 1px solid var(--prism-blue-line);
  background: var(--prism-blue-soft); border-radius: 10px; }
.wj-bulk[hidden] { display: none; }
.wj-bulk-lbl { font-size: 13.5px; font-weight: 800; color: #0f3a63; }

/* --- one loud primary: Generate --- */
.wj-cta { font-size: 16px; font-weight: 800; min-height: 50px; padding: 14px 28px;
  box-shadow: 0 2px 8px rgba(15, 44, 74, .18); }

/* --- the one thing that scraps a part: make it a real card, not fine print --- */
.wj-make-note { display: flex; align-items: flex-start; gap: 10px; margin: 8px 2px 0;
  padding: 13px 16px; border: 1.5px solid var(--prism-amber-line); background: var(--prism-amber-soft);
  color: #7a4600; border-radius: 11px; font-size: 14.5px; line-height: 1.4; font-weight: 500; }
.wj-make-note svg { flex: none; margin-top: 1px; color: var(--prism-amber); }
.wj-make-note b { font-weight: 800; }

/* --- import / safety notes (what we noticed reading the file) --- */
.wj-notes { display: flex; flex-direction: column; gap: 6px; margin: 0 0 12px; }
.wj-notes:empty { display: none; }
.wj-note { display: flex; align-items: flex-start; gap: 9px; padding: 9px 13px; border-radius: 9px;
  font-size: 13.5px; line-height: 1.4; border: 1px solid; }
.wj-note-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; margin-top: 6px; }
.wj-note.is-info   { background: var(--prism-blue-soft);  color: #0f3a63; border-color: var(--prism-blue-line); }
.wj-note.is-info   .wj-note-dot { background: var(--prism-blue); }
.wj-note.is-warn   { background: var(--prism-amber-soft); color: #7a4600; border-color: var(--prism-amber-line); }
.wj-note.is-warn   .wj-note-dot { background: var(--prism-amber); }
.wj-note.is-danger { background: var(--prism-red-soft);   color: #8a1f1f; border-color: var(--prism-red-line); }
.wj-note.is-danger .wj-note-dot { background: var(--prism-red); }

/* --- loud "Ready for OMAX" finish line --- */
.wj-release { padding: 16px 20px; font-size: 15.5px; border-width: 1.5px; border-style: solid; border-color: transparent; }
.wj-release-dot { width: 14px; height: 14px; }
.wj-release-lbl { font-size: 16px; }
.wj-release-sub { font-size: 13.5px; }
.wj-release.is-ok { border-color: var(--prism-green-line); }
.wj-release.is-warn { border-color: var(--prism-amber-line); }
.wj-release.is-danger { border-color: var(--prism-red-line); }

/* ============================================================
   WATERJET — simplification pass (2026-07-13)
   Top-level job toggle (cut a part vs fill a carrier), demoted
   test-shapes disclosure, and an Advanced-settings gate so the
   feature list stays a plain checklist by default.
   ============================================================ */

/* top-level job toggle */
.wj-modetoggle { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 0 0 16px; }
@media (max-width: 560px) { .wj-modetoggle { grid-template-columns: 1fr; } }
.wj-mode-btn { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; text-align: left;
  padding: 14px 16px; border: 1.5px solid var(--prism-line-strong, #cbd5e1); border-radius: 12px;
  background: #fff; cursor: pointer; transition: border-color .12s, background .12s, box-shadow .12s; }
.wj-mode-btn:hover { border-color: var(--prism-blue, #2563eb); background: var(--prism-panel-subtle, #f8fafc); }
.wj-mode-btn.is-active { border-color: var(--prism-blue, #2563eb); background: var(--prism-blue-soft, #eff6ff);
  box-shadow: 0 0 0 1px var(--prism-blue, #2563eb) inset; }
.wj-mode-lbl { font-size: 15px; font-weight: 800; color: #1e293b; }
.wj-mode-btn.is-active .wj-mode-lbl { color: #0f3a63; }
.wj-mode-sub { font-size: 12.5px; font-weight: 500; color: #64748b; }

/* demoted "test shapes" disclosure — synthetic, not real work */
.wj-testshapes { margin-top: 14px; }
.wj-testshapes > summary { cursor: pointer; font-size: 13px; font-weight: 600; color: #64748b; list-style: none;
  padding: 6px 0; }
.wj-testshapes > summary::-webkit-details-marker { display: none; }
.wj-testshapes > summary::before { content: '▸ '; color: #94a3b8; }
.wj-testshapes[open] > summary::before { content: '▾ '; }
.wj-testshapes > summary:hover { color: #334155; }
.wj-testshapes .wj-shapes { margin-top: 10px; }

/* Advanced-settings gate on the features header */
.wj-feat-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.wj-adv-toggle { flex: none; background: transparent; border: 1.5px solid var(--prism-line-strong, #cbd5e1);
  border-radius: 999px; padding: 6px 14px; font-size: 12.5px; font-weight: 700; color: #64748b; cursor: pointer;
  transition: border-color .12s, background .12s, color .12s; }
.wj-adv-toggle:hover { border-color: var(--prism-blue, #2563eb); color: var(--prism-blue, #2563eb); }
.wj-adv-toggle.is-open { border-color: var(--prism-blue, #2563eb); background: var(--prism-blue-soft, #eff6ff);
  color: #0f3a63; }

/* ---------- Quote Builder condensed inputs ---------- */
.sqv2-input-summary {
  margin: 0 0 16px;
  border: 1px solid #dbe3ee;
  border-radius: 8px;
  background: #fff;
}
.sqv2-input-summary[hidden] { display: none; }
.sqv2-input-summary summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 12px 16px;
  cursor: pointer;
  list-style: none;
}
.sqv2-input-summary summary::-webkit-details-marker { display: none; }
.sqv2-input-summary strong {
  display: block;
  color: #0f172a;
  font-size: 13px;
}
.sqv2-input-summary em {
  display: block;
  color: #64748b;
  font-style: normal;
  font-size: 12px;
  margin-top: 2px;
}
.sqv2-input-summary b {
  color: #0f3f83;
  font-size: 12px;
  white-space: nowrap;
}
.view[data-view="smart-quote-v2"] #sqv2InputPanel.is-condensed { display: none; }


.sqv2-details-band {
  margin-bottom: 16px;
  border: 1px solid #dbe3ee;
  border-radius: 8px;
  background: #fff;
}
.sqv2-details-band > summary {
  padding: 12px 16px;
  cursor: pointer;
  color: #475569;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.04em;
  list-style: none;
  text-transform: uppercase;
}
.sqv2-details-band > summary::-webkit-details-marker { display: none; }
.sqv2-details-body { padding: 0 16px 16px; }


/* ============================================================
   Current Shop Floor (live PLC telemetry) — floor-live.js
   ============================================================ */
.fl-status { display: flex; align-items: center; }
.fl-badge { display: inline-block; padding: 4px 10px; border-radius: 999px; font-size: 12px; font-weight: 700; border: 1px solid transparent; }
.fl-badge-good { background: var(--prism-green-soft); color: var(--prism-green); border-color: var(--prism-green-line); }
.fl-badge-warn { background: var(--prism-amber-soft); color: var(--prism-amber); border-color: var(--prism-amber-line); }
.fl-badge-bad  { background: var(--prism-red-soft);   color: var(--prism-red);   border-color: var(--prism-red-line); }
/* Last good tiles kept on screen after a failed poll — visibly not live (audit #38). */
.fl-frozen { opacity: .45; filter: grayscale(.6); }

/* Pulse band */
.fl-hero { background: var(--prism-panel); border: 1px solid var(--prism-line); border-radius: 12px; padding: 16px 20px; margin-bottom: 16px; }
.fl-hero-top { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.fl-hero-head { display: flex; align-items: baseline; gap: 10px; }
.fl-hero-num { font-size: 34px; font-weight: 800; color: var(--prism-ink); line-height: 1; }
.fl-hero-sub { font-size: 15px; color: var(--prism-ink-muted); }
.fl-oee-row { display: flex; gap: 22px; }
.fl-oee-label { font-size: 12px; color: var(--prism-ink-muted); }
.fl-oee-val { font-size: 18px; font-weight: 700; color: var(--prism-ink); }
.fl-bar { display: flex; height: 14px; border-radius: 7px; overflow: hidden; margin-top: 14px; border: 1px solid var(--prism-line); background: var(--prism-panel-muted); }
.fl-seg { height: 100%; }
.fl-seg-run   { background: var(--prism-green); }
.fl-seg-fault { background: var(--prism-red); }
.fl-seg-stop  { background: #b7c0cc; }
.fl-seg-idle  { background: #e3e9f0; }
.fl-legend { display: flex; gap: 16px; margin-top: 10px; font-size: 12px; color: var(--prism-ink-muted); flex-wrap: wrap; }
.fl-leg { display: inline-flex; align-items: center; gap: 6px; }
.fl-leg-dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }

/* Fault strip */
.fl-fault-strip { display: flex; align-items: center; gap: 10px; background: var(--prism-red-soft); border: 1px solid var(--prism-red-line); color: var(--prism-red); border-radius: 12px; padding: 10px 14px; margin-bottom: 16px; font-size: 14px; font-weight: 600; }
.fl-fault-strip i { font-style: normal; font-size: 16px; }

/* Toolbar */
.fl-toolbar { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-bottom: 14px; }
.fl-search { padding: 7px 12px; border: 1px solid var(--prism-line); border-radius: var(--radius-sm); font-size: 13px; min-width: 220px; }

/* Department groups */
.fl-group { margin-bottom: 18px; }
.fl-group-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 9px; width: 100%; }
.fl-group-title { font-size: 16px; font-weight: 700; color: var(--prism-ink); }
.fl-group-meta { font-size: 13px; color: var(--prism-ink-muted); }
.fl-group-toggle { background: none; border: none; cursor: pointer; text-align: left; padding: 0; }
.fl-caret { font-size: 12px; color: var(--prism-ink-muted); margin-right: 2px; }

.fl-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(124px, 1fr)); gap: 8px; }
.fl-tile { position: relative; border: 1px solid var(--prism-line); border-radius: 10px; padding: 10px 12px; background: var(--prism-panel); }
.fl-tile-name { font-size: 15px; font-weight: 700; line-height: 1.15; }
/* PLC slot id, shown only where the machine NAME was guessed from the program
   string rather than hand-mapped. Two slots can derive to the same name, and
   without this they are identical on screen (audit findings 31/32). */
.fl-tile-slot { font-size: 10px; font-weight: 600; opacity: 0.6; letter-spacing: 0.02em; }
.fl-tile-sub { font-size: 12px; margin-top: 3px; text-transform: capitalize; color: var(--prism-ink-muted); }
/* status weighting — running + faulted pop, stopped/idle stay quiet */
.fl-tile.fl-running { background: var(--prism-green-soft); border-color: var(--prism-green-line); }
.fl-tile.fl-running .fl-tile-name, .fl-tile.fl-running .fl-tile-sub { color: var(--prism-green); }
.fl-tile.fl-faulted { background: var(--prism-red-soft); border-color: var(--prism-red-line); }
.fl-tile.fl-faulted .fl-tile-name, .fl-tile.fl-faulted .fl-tile-sub { color: var(--prism-red); }
.fl-tile.fl-stopped .fl-tile-name { color: var(--prism-ink-muted); }
.fl-tile.fl-idle { background: var(--prism-panel-muted); }
.fl-tile.fl-idle .fl-tile-name { color: var(--prism-ink-muted); }
/* no signal = the PLC lost this machine's I/O module; values are frozen. Dashed
   and hatched so it can never be mistaken for a quiet "idle" tile. */
.fl-seg-nosig { background: repeating-linear-gradient(45deg, #c9d0d9 0 4px, #eef1f5 4px 8px); }
.fl-tile.fl-nosignal { background: repeating-linear-gradient(45deg, var(--prism-panel-muted) 0 6px, var(--prism-panel) 6px 12px); border-style: dashed; }
.fl-tile.fl-nosignal .fl-tile-name, .fl-tile.fl-nosignal .fl-tile-sub { color: var(--prism-ink-muted); font-style: italic; }

/* live OEE chip on each tile */
.fl-tile-oee { position: absolute; top: 8px; right: 9px; font-size: 11px; font-weight: 800; padding: 1px 6px; border-radius: 999px; letter-spacing: .2px; }
.fl-oee-hi  { background: var(--prism-green-soft); color: var(--prism-green); }
.fl-oee-mid { background: #fdeccb; color: #7a4f06; }
.fl-oee-lo  { background: var(--prism-red-soft); color: var(--prism-red); }

/* OEE trends card */
.fl-trends-card { margin-top: 18px; border: 1px solid var(--prism-line); border-radius: 12px; padding: 16px 18px; background: var(--prism-panel); }
.fl-trends-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.fl-trends-title { font-size: 15px; font-weight: 800; }
.fl-trend-note { font-size: 11.5px; color: var(--prism-ink-muted); }
.fl-trends-grid { display: grid; grid-template-columns: minmax(220px, 1.4fr) minmax(220px, 1fr); gap: 22px; }
@media (max-width: 720px) { .fl-trends-grid { grid-template-columns: 1fr; } }
.fl-trend-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .6px; color: var(--prism-ink-muted); margin-bottom: 6px; }
.fl-trend-big { font-size: 30px; font-weight: 800; line-height: 1; margin-bottom: 6px; }
.fl-trend-big.fl-oee-hi { color: var(--prism-green); background: none; }
.fl-trend-big.fl-oee-mid { color: #b9770a; background: none; }
.fl-trend-big.fl-oee-lo { color: var(--prism-red); background: none; }
.fl-spark { display: block; width: 100%; height: 40px; }
.fl-shift-chart { display: flex; gap: 14px; align-items: flex-end; height: 110px; }
.fl-shift-col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; }
.fl-shift-bar-wrap { width: 100%; height: 72px; display: flex; align-items: flex-end; }
.fl-shift-bar { width: 100%; border-radius: 6px 6px 0 0; background: var(--prism-accent); min-height: 2px; transition: height .3s; }
.fl-shift-bar.fl-oee-hi { background: var(--prism-green); }
.fl-shift-bar.fl-oee-mid { background: #e6a417; }
.fl-shift-bar.fl-oee-lo { background: var(--prism-red); }
.fl-shift-val { font-size: 13px; font-weight: 800; margin-top: 5px; }
.fl-shift-lab { font-size: 10px; color: var(--prism-ink-muted); margin-top: 1px; text-align: center; }
.fl-lag { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--prism-line); }
.fl-lag-chip { display: inline-block; font-size: 12px; padding: 3px 9px; margin: 4px 6px 0 0; border-radius: 999px; background: var(--prism-red-soft); color: var(--prism-red); }
.fl-lag-chip b { font-weight: 800; }

/* attention strip — production machines stopped mid-shift */
.fl-att-strip { display: flex; flex-wrap: wrap; align-items: center; gap: 7px; margin: 10px 0 0; padding: 9px 13px; border: 1px solid #f5c16c; background: #fff6e6; border-radius: 10px; }
.fl-att-title { font-weight: 800; font-size: 12.5px; color: #8a5a06; margin-right: 4px; }
.fl-att-chip { display: inline-block; font-size: 12px; padding: 3px 9px; border-radius: 999px; background: #fff; border: 1px solid #f0d29a; color: #7a4f06; }
.fl-att-chip b { font-weight: 800; }

/* ============ PLC FINDER — coolant-flip identification tab ============ */
/* "which one lit up?" banner */
.plc-banner { display: flex; align-items: center; gap: 8px; margin: 0 0 14px; padding: 12px 16px;
  border: 1px solid var(--prism-green-line); background: var(--prism-green-soft); color: var(--prism-green);
  border-radius: 10px; font-size: 14px; }
/* Guard — see .qh-pagination[hidden] above. renderBanner() hides this when nothing
   has lit up (plc-id.js:98); without it an empty green "that's the machine you're
   standing at" bar was on screen before any slot had flipped. */
.plc-banner[hidden] { display: none; }
.plc-banner strong { font-weight: 800; letter-spacing: .3px; }
.plc-banner-bolt { font-size: 18px; }

.plc-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 12px; }
.plc-tile { position: relative; display: flex; align-items: center; gap: 12px;
  border: 1px solid var(--prism-line); border-radius: 12px; padding: 14px 15px; background: var(--prism-panel);
  transition: background .25s, border-color .25s, box-shadow .25s; }
.plc-tile .plc-body { flex: 1; min-width: 0; }
.plc-slot { font-size: 18px; font-weight: 800; line-height: 1.1; font-variant-numeric: tabular-nums; }
.plc-sub { font-size: 12px; margin-top: 3px; text-transform: capitalize; color: var(--prism-ink-muted); }
.plc-recent { font-size: 11px; margin-top: 4px; color: var(--prism-ink-muted); }
.plc-name-btn { font: inherit; font-size: 11px; padding: 3px 8px; border: 1px solid var(--prism-ink-muted, #64748b); border-radius: 6px; background: transparent; color: inherit; cursor: pointer; white-space: nowrap; }
.plc-state { font-size: 10.5px; font-weight: 800; text-transform: uppercase; letter-spacing: .6px; color: var(--prism-ink-muted); white-space: nowrap; }

/* the big coolant light — the whole point of the tab */
.plc-light { flex: none; width: 26px; height: 26px; border-radius: 50%;
  background: var(--prism-panel-muted); border: 2px solid var(--prism-line); transition: all .25s; }

/* coolant OFF: quiet, gray */
.plc-off { }
.plc-off.plc-offline { opacity: .6; }

/* coolant ON: light glows, tile pops */
.plc-on { background: var(--prism-green-soft); border-color: var(--prism-green); box-shadow: 0 0 0 1px var(--prism-green) inset; }
.plc-on .plc-slot { color: var(--prism-green); }
.plc-on .plc-state { color: var(--prism-green); }
.plc-on .plc-light { background: #17b26a; border-color: #0f8a50; box-shadow: 0 0 14px 3px rgba(23,178,106,.7); }

/* OFF→ON since last poll: hard flash so you can't miss it walking back to the screen */
.plc-flash { animation: plcFlash 1.1s ease-out 4; }
@keyframes plcFlash {
  0%   { box-shadow: 0 0 0 0 rgba(23,178,106,.85), 0 0 0 1px var(--prism-green) inset; }
  50%  { box-shadow: 0 0 0 10px rgba(23,178,106,0), 0 0 0 1px var(--prism-green) inset; }
  100% { box-shadow: 0 0 0 0 rgba(23,178,106,0), 0 0 0 1px var(--prism-green) inset; }
}

/* ============ SAW ROOM / BLANCHARD tab ============
   Deliberately reuses the Cell Uptime / Uptime History CSS classes verbatim
   (.cu-card, .cu-card-top, .cu-overall, .cuh-hm, .cuh-trend, .cuh-pop, etc.)
   instead of a parallel sb-prefixed clone — one machine here plays the role
   one cell plays there, so it should look like the same system, not a
   reskinned copy. Only genuinely new pieces (the room grouping wrapper, the
   grid's auto-fill sizing since ~40 machines don't fit Cell Uptime's fixed
   3x2, and the live current-shift runtime bar, which Cell Uptime's cards
   don't have) get their own rules below. */
.sb-room { margin-bottom: 24px; }
.sb-room-title { font-size: 13px; font-weight: 800; letter-spacing: .5px; text-transform: uppercase;
  color: var(--prism-ink-muted); margin: 0 0 10px; }
.sb-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 14px; }
.sb-card { padding: 14px 16px; gap: 8px; cursor: default; }
.sb-card:hover { box-shadow: 0 1px 2px rgba(16, 24, 40, .04); }
.sb-card-unmapped { opacity: .5; }
.sb-card-unmapped .cu-card-name { font-size: 20px; }
.sb-card .cu-card-name { font-size: 20px; }
.sb-card .cu-card-overall { font-size: 26px; }
.sb-card-status { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--prism-ink-muted); }
.sb-card-status.status-faulted { color: #e5484d; }
.sb-bar-track { height: 6px; border-radius: 4px; background: var(--prism-panel-muted); overflow: hidden; }
.sb-bar-fill { height: 100%; border-radius: 4px; transition: width .4s ease; }
.sb-card[role="button"] { cursor: pointer; }
.sb-card:hover { box-shadow: 0 2px 8px rgba(16,24,40,.08); }
.sb-card:focus-visible { outline: 2px solid var(--color-primary, #2563eb); outline-offset: -2px; }
.sb-card-open { grid-column: 1 / -1; }   /* an open card spans the row so its breakdown has room */
.sb-caret { display: inline-block; width: 1em; font-size: .8em; color: var(--prism-ink-muted); }

/* Expanded per-machine breakdown */
.sb-detail { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--prism-line); }
.sb-d-head { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px; color: var(--prism-ink-muted); margin-bottom: 8px; }
.sb-d-shifts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.sb-d-shift { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 8px 6px; border-radius: var(--prism-radius-sm, 4px); }
.sb-d-shift-label { font-size: 11px; font-weight: 600; letter-spacing: .03em; color: var(--prism-ink-muted); }
.sb-d-shift-val { font-size: 24px; font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1.1; }
.sb-d-last { font-size: 10px; color: var(--prism-ink-muted); }
.sb-d-map { margin-top: 10px; font-size: 12px; color: var(--prism-ink-soft); }
.sb-d-map code { font-family: var(--prism-mono, ui-monospace, monospace); font-size: 11.5px; background: var(--prism-panel-muted); padding: 1px 5px; border-radius: 3px; }
.sb-d-map-unmapped { font-style: italic; }
.sb-d-conf { font-weight: 700; }
.sb-d-conf-high { color: #30a46c; }
.sb-d-conf-medium { color: #f5a623; }
.sb-d-conf-low { color: #e5851f; }
.sb-d-verify { color: var(--prism-ink-muted); font-style: italic; }

/* Tooling command-center CSS lives in one contiguous block — see
   "TOOLING COMMAND CENTER" near the .kb-content rules above. */

/* ============ JOBBOSS-LIVE: shared ============
   Freshness pill for the part360 / schedule / customer360 lanes.
   Rendered by window.jobbossFreshnessBadge() in app.js. */
.jb-fresh-pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 600; line-height: 1.6;
  border: 1px solid transparent; white-space: nowrap;
}
.jb-fresh-pill .jb-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.jb-fresh-pill.is-fresh { background: rgba(16, 185, 129, 0.13); color: #15803d; border-color: rgba(16,185,129,0.25); }
.jb-fresh-pill.is-stale { background: rgba(245, 158, 11, 0.15); color: #b45309; border-color: rgba(245,158,11,0.3); }
/* Daily Report pill on the Shop Dashboard's dark-blue hero (2026-09-29): the
   translucent tints above vanish on blue, so give it a solid light ground and
   keep the state colour for the text. */
.sd-hero-title .jb-fresh-pill.is-fresh { background: #ecfdf5; }
.sd-hero-title .jb-fresh-pill.is-stale { background: #fffbeb; }
.sd-report-fresh:empty { display: none; }
/* Static-source pill (one-time xlsx export, not the live JobBOSS pull) — must
   read as visually distinct/neutral so it never looks like it's claiming
   live-freshness. Reuses the app's muted-ink tokens (no new colors). */
.jb-fresh-pill.is-static { background: var(--prism-panel-subtle); color: var(--prism-ink-muted); border-color: var(--prism-line); }
/* ============ /JOBBOSS-LIVE: shared ============ */

/* JOBBOSS-LIVE: data-quality tiles */
.dq-tile-badge {
  display: block;
  margin-top: 2px;
}
.dq-tile-badge:empty { display: none; }
.dq-tile-badge .jb-fresh-pill {
  padding: 1px 8px;
  font-size: 10.5px;
}
.dq-live-spine {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px 10px;
  margin: -4px 0 var(--prism-gap-lg);
  padding: 10px 14px;
  border: 1px solid var(--prism-line);
  border-radius: var(--prism-radius-md);
  background: var(--prism-panel);
}
.dq-live-spine .dq-live-spine-note {
  font-size: 12px;
  line-height: 1.5;
  color: var(--prism-ink-muted);
  flex: 1 1 320px;
  min-width: 0;
}
.dq-live-spine .dq-live-spine-note strong { color: var(--prism-ink); font-weight: 600; }
/* /JOBBOSS-LIVE: data-quality tiles */

/* JOBBOSS-LIVE: customer360 */
.c360-live-spine {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px 10px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border, rgba(0,0,0,0.08));
}
/* Guard — see .qh-pagination[hidden] above. Only un-hidden once /api/customer360/
   live-meta answers, and it deliberately stays hidden on a non-ok/403 response
   (app.js:21162-21175). Without this the divider rule and its padding drew anyway,
   so a permission-denied fetch left a stray line under the header. */
.c360-live-spine[hidden] { display: none; }
.c360-live-spine .c360-live-note {
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted, #6b7280);
  flex: 1 1 320px;
  min-width: 0;
}
.c360-live-spine .c360-live-note strong { color: var(--text, #111827); font-weight: 600; }
/* /JOBBOSS-LIVE: customer360 */

/* ============================================================
   VIEW: Cell Uptime — shop-floor TV board. Big, simple, readable
   from across the floor. Per-cell colors are computed in JS (a
   continuous red->yellow->green lerp) and applied inline, so no
   fixed threshold classes here.
   ============================================================ */
/* Fill the .main content area exactly (header natural height + grid takes the
   rest) instead of guessing a vh-minus-N offset — that broke every time the
   header widget's size changed. min-height:0 is required on the flex/grid
   children or they'd refuse to shrink below their content's natural size. */
/* :not([hidden]) so this doesn't out-specificity the `.view[hidden]{display:none}`
   tab-hider — without it the flex rule wins and the board renders on EVERY tab. */
section.view[data-view="cell-uptime"]:not([hidden]) { display: flex; flex-direction: column; height: 100%; }
/* 3-col grid: equal 1fr side tracks pin the DAILY/WEEKLY block to the TRUE middle
   regardless of title/toggle widths (old space-between only looked centered because
   the BETA pill counter-weighted the right). cell-uptime no longer carries a status
   pill, so drop the reserved 180px gutter that was shoving the block left. */
.cu-header { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 16px; flex: 0 0 auto; }
.cu-header.has-tab-status { padding-right: 0; }
.cu-header > div:first-child { justify-self: start; }
.cu-header > .cu-overall { justify-self: center; }
.cu-header > .cu-toggle { justify-self: end; }
.cu-overall { display: flex; gap: 36px; }
.cu-overall-item { text-align: center; }
.cu-overall-label { font-size: 15px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--color-text-muted, #5e6975); }
.cu-overall-val { font-size: 56px; font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1.1; }
.cu-overall-shifts { display: flex; gap: 10px; margin-top: 8px; }
.cu-overall-shift { display: flex; flex-direction: column; align-items: center; padding: 10px 18px; border-radius: var(--prism-radius-sm, 4px); min-width: 64px; }
.cu-overall-shift span { font-size: 13px; color: var(--color-text-muted, #5e6975); font-weight: 600; letter-spacing: .03em; }
.cu-overall-shift b { font-size: 32px; font-weight: 800; font-variant-numeric: tabular-nums; }
.cu-toggle { display: inline-flex; border: 1px solid var(--color-border, #dbe2ea); border-radius: var(--prism-radius-md, 8px); overflow: hidden; }
.cu-toggle-btn { border: none; background: #fff; color: var(--color-text-muted, #5e6975); font-size: 13px; font-weight: 600; padding: 8px 18px; cursor: pointer; }
.cu-toggle-btn + .cu-toggle-btn { border-left: 1px solid var(--color-border, #dbe2ea); }
.cu-toggle-btn.cu-active { background: var(--color-primary, #2563eb); color: #fff; }
.cu-board { margin-top: 18px; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.cu-empty { text-align: center; color: var(--color-text-muted, #5e6975); padding: 40px 0; grid-column: 1 / -1; }

/* Card grid — fixed 3-across/2-down (one card per physical cell, 6 total).
   Big and centered so the board reads at a glance from across the floor;
   flex:1 (on a min-height:0 ancestor chain) makes the grid exactly fill
   whatever's left under the header, instead of guessing a fixed height.
   Click a card to drop into its per-machine breakdown (collapsed by default). */
.cu-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(2, 1fr);
  gap: 16px; flex: 1 1 auto; min-height: 0;
}
.cu-card {
  background: #fff; border: 1px solid var(--color-border, #dbe2ea); border-top: 8px solid #8a97a5;
  border-radius: var(--prism-radius-md, 8px); padding: 18px 24px; cursor: pointer;
  box-shadow: 0 1px 2px rgba(16, 24, 40, .04);
  display: flex; flex-direction: column; justify-content: center; gap: 12px;
}
.cu-card-open { justify-content: flex-start; }
.cu-card:hover { box-shadow: 0 2px 8px rgba(16, 24, 40, .08); }
.cu-card:focus-visible { outline: 2px solid var(--color-primary, #2563eb); outline-offset: -2px; }
.cu-card-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.cu-card-name { font-size: 34px; font-weight: 700; }
.cu-card-overall-wrap { text-align: right; }
.cu-card-overall { font-size: 42px; font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1; }
.cu-card-overall-label { font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--color-text-muted, #5e6975); }
.cu-card-sub { font-size: 14px; font-weight: 500; color: var(--color-text-muted, #5e6975); margin: -8px 0 0; padding-left: 22px; }
.cu-caret { display: inline-block; width: 16px; color: var(--color-text-muted, #5e6975); font-size: 13px; }

.cu-card-shifts { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.cu-shift-block { border-radius: var(--prism-radius-sm, 4px); padding: 12px 8px; text-align: center; }
.cu-shift-label { font-size: 12px; font-weight: 600; letter-spacing: .04em; color: var(--color-text-muted, #5e6975); }
.cu-shift-val { font-size: 32px; font-weight: 800; font-variant-numeric: tabular-nums; }
.cu-shift-val .cu-na { font-size: 20px; font-weight: 500; opacity: .55; }
/* 14px, full strength: on a wall TV this date is what says "this is not today" (F20) */
.cu-shift-date { font-size: 14px; font-weight: 600; letter-spacing: .03em; color: var(--color-text-muted, #5e6975); opacity: .9; margin-top: 2px; }
.cu-shift-live .cu-shift-date { color: var(--prism-amber, #b45309); opacity: 1; }
.cu-overall-shift-date { font-size: 10px; font-weight: 600; letter-spacing: .03em; color: var(--color-text-muted, #5e6975); opacity: .7; }

.cu-detail { margin-top: 6px; padding-top: 16px; border-top: 1px solid var(--color-border, #dbe2ea); cursor: default; }
.cu-detail-head { padding-bottom: 8px; font-size: 13px; color: var(--color-text-muted, #5e6975); text-transform: uppercase; letter-spacing: .04em; }
.cu-detail-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.cu-chip { flex: 0 0 auto; min-width: 108px; border: 1px solid var(--color-border, #dbe2ea); border-radius: var(--prism-radius-sm, 4px); padding: 6px 10px; background: #f8fafc; }
.cu-chip-nodata { opacity: .55; }
.cu-chip-is-excluded { border-style: dashed; }
.cu-chip-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; margin-bottom: 4px; }
.cu-chip-id { font-size: 13px; font-weight: 700; }
.cu-chip-flag { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; padding: 1px 5px; border-radius: 3px; white-space: nowrap; }
.cu-chip-unmapped { background: #eef1f5; color: #8a97a5; }
.cu-chip-excluded { background: #fdf0c8; color: #854d0e; }
.cu-chip-shifts { display: flex; gap: 8px; }
.cu-chip-shift { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; }
/* A shift held out of the runtime avg: its number reads muted + struck so the
   chip still shows the honest %, just visibly not-counting. */
.cu-chip-shift-excl { color: #b0b7c0 !important; text-decoration: line-through; text-decoration-color: #cbd2da; }

/* Weekly Uptime Summary table — sits between the overall header and the board.
   Rows = production weeks (Sun→Fri), cols = 1st/2nd/3rd/Total, each cell tinted
   on the same red→green scale as the cards. flex:0 0 auto so the board below
   still fills the remaining kiosk height. */
.cu-weekly { flex: 0 0 auto; margin-top: 18px; }
.cu-weekly-head { font-size: 13px; font-weight: 600; letter-spacing: .03em; text-transform: uppercase; color: var(--color-text-muted, #5e6975); margin-bottom: 8px; }
.cu-weekly-wrap { overflow-x: auto; }
.cu-weekly-table { width: 100%; border-collapse: collapse; background: #fff; border: 1px solid var(--color-border, #dbe2ea); border-radius: var(--prism-radius-md, 8px); overflow: hidden; }
.cu-weekly-table th, .cu-weekly-table td { padding: 10px 14px; text-align: center; font-variant-numeric: tabular-nums; }
.cu-weekly-table thead th { font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--color-text-muted, #5e6975); background: #f8fafc; border-bottom: 1px solid var(--color-border, #dbe2ea); }
.cu-weekly-table thead th:first-child { text-align: left; }
.cu-wk-week { text-align: left; font-size: 14px; font-weight: 700; white-space: nowrap; color: var(--color-text, #1a2236); }
.cu-weekly-table tbody tr + tr th, .cu-weekly-table tbody tr + tr td { border-top: 1px solid var(--color-border, #dbe2ea); }
.cu-wk-cell { font-size: 16px; font-weight: 800; }

/* Mobile (≤720px): the board above is a wall-TV kiosk layout — a fixed
   3×2 grid that flex-fills the whole screen height with 34–56px fonts. On a
   phone that pushes cells 2/3 and the overall block off-screen (clipped, not
   scrolled, by .main's overflow-x:hidden). Unwind it: stack the header, drop
   to a single-column grid that flows + scrolls, and scale the type down.
   Added 2026-07-10 (Ryan's "see it on my phone" ask). Desktop untouched. */
@media (max-width: 720px) {
  .cu-header { grid-template-columns: 1fr; gap: 12px; }
  .cu-header > .cu-overall { justify-self: stretch; }
  .cu-header > .cu-toggle { justify-self: start; }
  .cu-overall { justify-content: space-around; gap: 12px; flex-wrap: wrap; }
  .cu-overall-val { font-size: 34px; }
  .cu-overall-label { font-size: 13px; }
  .cu-overall-shifts { gap: 6px; }
  .cu-overall-shift { padding: 6px 10px; min-width: 48px; }
  .cu-overall-shift b { font-size: 20px; }

  /* Weekly summary table — tighten padding + type so 5 columns fit a phone. */
  .cu-weekly { margin-top: 14px; }
  .cu-weekly-table th, .cu-weekly-table td { padding: 8px 6px; }
  .cu-wk-week { font-size: 12px; }
  .cu-wk-cell { font-size: 14px; }
  .cu-weekly-table thead th { font-size: 11px; }

  /* Board stops filling TV height — becomes a normal scrolling column. */
  .cu-board { flex: 0 0 auto; margin-top: 14px; }
  .cu-grid { grid-template-columns: 1fr; grid-template-rows: none; flex: 0 0 auto; min-height: 0; gap: 12px; }
  .cu-card { padding: 14px 16px; }
  .cu-card-name { font-size: 22px; }
  .cu-card-overall { font-size: 30px; }
  .cu-shift-val { font-size: 24px; }
  .cu-shift-block { padding: 10px 6px; }
}

/* ==========================================================================
   Odoo Data — shop-floor TV board. Live CMM queue + per-part ETA, sized for
   reading across the room: big rows, big part #, color-coded status badges,
   subtle per-bucket row tint. Theme-aware via the --prism-* tokens.
   ========================================================================== */
.od-header { display: flex; align-items: center; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.od-header h1 { font-size: 30px; }
.od-status { display: flex; gap: 10px; margin-left: auto; }
.od-chip { font-size: 15px; font-weight: 800; padding: 6px 14px; border-radius: 999px; letter-spacing: .01em; font-variant-numeric: tabular-nums; }
.od-chip-ready   { background: rgba(22,163,74,.16);  color: #15803d; }
.od-chip-reportReady { background: rgba(217,119,6,.16); color: #b45309; }
.od-chip-running { background: rgba(37,99,235,.16);  color: #1d4ed8; }
.od-chip-staged  { background: rgba(100,116,139,.18); color: #475569; }
.od-chip-hidden  { background: transparent; border: 1px dashed rgba(100,116,139,.6); color: #475569; }
.od-fresh { font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; }
.od-fresh .od-live  { color: #16a34a; }
.od-fresh .od-stale { color: #d97706; font-size: 24px; }
.od-chip-more    { background: transparent; border: 1px dashed rgba(100,116,139,.6); color: #475569; }

.od-board { margin-top: 16px; flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.od-table { width: 100%; border-collapse: collapse; }
.od-table thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--prism-panel); color: var(--prism-ink-soft);
  text-align: left; font-size: 15px; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
  padding: 12px 18px; border-bottom: 2px solid var(--prism-line);
}
.od-table .od-col-eta, .od-table .od-col-incmm { text-align: right; }
.od-row td { padding: 18px; border-bottom: 1px solid var(--prism-line); vertical-align: middle; }
.od-col-part   { font-size: 34px; font-weight: 800; color: var(--prism-ink); font-variant-numeric: tabular-nums; line-height: 1; }
.od-col-mach   { font-size: 26px; font-weight: 700; color: var(--prism-ink); font-variant-numeric: tabular-nums; }
.od-col-status { white-space: nowrap; }
.od-col-incmm  { text-align: right; font-size: 24px; font-weight: 800; color: var(--prism-ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.od-col-eta    { text-align: right; font-size: 28px; font-weight: 800; color: var(--prism-ink); font-variant-numeric: tabular-nums; white-space: nowrap; }

.od-badge { display: inline-block; font-size: 17px; font-weight: 900; padding: 8px 18px; border-radius: 999px; letter-spacing: .01em; }
.od-badge-ready   { background: rgba(22,163,74,.18);  color: #000; }
/* Amber = "nearly yours, not yet" — deliberately not the green of a released part. */
.od-badge-reportReady { background: rgba(217,119,6,.20); color: #000; }
.od-badge-running { background: rgba(37,99,235,.18);  color: #000; }
.od-badge-staged  { background: rgba(100,116,139,.20); color: #000; }

/* subtle full-row tint so the three buckets separate at a glance */
.od-row-ready   td { background: rgba(22,163,74,.06); }
.od-row-reportReady td { background: rgba(217,119,6,.06); }
.od-row-running td { background: rgba(37,99,235,.05); }

.od-eta-na   { color: var(--prism-ink-muted); font-weight: 600; }
/* /odoo-data?mach=H46 — that machine's rows (audit F25) */
.od-row-mine td { box-shadow: inset 0 0 0 9999px rgba(37,99,235,.12); }
.od-row-mine td:first-child { border-left: 6px solid #2563eb; }
.od-eta-soon { color: #1d4ed8; }
.od-eta-over { color: #b91c1c; }
.od-ready-tag { color: #15803d; font-size: 20px; font-weight: 800; }
.od-finalizing-tag { color: #b45309; font-size: 20px; font-weight: 800; }
.od-empty { text-align: center; color: var(--prism-ink-muted); padding: 60px 0; font-size: 22px; font-weight: 600; }

@media (prefers-color-scheme: dark) {
  .od-chip-ready   { background: rgba(34,197,94,.20);  color: #4ade80; }
  .od-chip-reportReady { background: rgba(245,158,11,.20); color: #fbbf24; }
  .od-chip-running { background: rgba(59,130,246,.20); color: #60a5fa; }
  .od-chip-staged  { background: rgba(148,163,184,.22); color: #cbd5e1; }
  .od-chip-hidden  { border-color: rgba(148,163,184,.6); color: #cbd5e1; }
  .od-fresh .od-live { color: #4ade80; }
  .od-badge-ready   { background: rgba(34,197,94,.22);  color: #4ade80; }
  .od-badge-reportReady { background: rgba(245,158,11,.22); color: #fbbf24; }
  .od-badge-running { background: rgba(59,130,246,.22); color: #60a5fa; }
  .od-badge-staged  { background: rgba(148,163,184,.24); color: #cbd5e1; }
  .od-row-ready   td { background: rgba(34,197,94,.08); }
  .od-row-reportReady td { background: rgba(245,158,11,.08); }
  .od-row-running td { background: rgba(59,130,246,.07); }
  .od-eta-soon { color: #60a5fa; }
  .od-eta-over { color: #f87171; }
  .od-ready-tag { color: #4ade80; }
  .od-finalizing-tag { color: #fbbf24; }
}

/* --- Kiosk / fullscreen mode: auto-applied while the Odoo Data view is active.
   Strips the topbar + sidebar so the whole screen is the board, tightens the
   padding, and scales part # / machine / ETA way up for reading from across the
   shop floor. Exit button (top-right) reveals the chrome again to navigate. --- */
.app.od-kiosk { grid-template-columns: 1fr; grid-template-rows: 1fr; grid-template-areas: "main"; --od-fit: 1; }
.app.od-kiosk .topbar,
.app.od-kiosk .sidebar,
.app.od-kiosk .sidebar-expand-floating { display: none !important; }
.app.od-kiosk .main { padding: 12px 24px; }
.app.od-kiosk .tab-status-pill { display: none !important; }   /* admin status setter — clutter on a TV */

/* fill the screen: the board region takes all leftover height and JS fits the
   ready + in-progress rows into it (fitOdooBoard sets --od-fit). Staged rows are
   low-priority — they render below and are clipped if the board is crowded. */
.app.od-kiosk .view[data-view="odoo-data"] { display: flex; flex-direction: column; height: 100%; }
.app.od-kiosk .od-board { flex: 1 1 auto; min-height: 0; overflow: hidden; margin-top: 8px; }

/* slim header — keep the count chips + freshness, shrink the title */
.app.od-kiosk .od-header { margin: 0; align-items: baseline; flex: 0 0 auto; }
.app.od-kiosk .od-header h1 { font-size: 20px; opacity: .8; }
.app.od-kiosk .od-chip { font-size: 17px; padding: 5px 14px; }
.app.od-kiosk .od-fresh { font-size: 15px; }
.app.od-kiosk .od-fresh .od-stale { font-size: 28px; }

/* the numbers — big for across-the-room reading; scale with --od-fit so a
   crowded board smooshes down to keep every ready + in-progress row on screen.
   Default (--od-fit:1) is the full size; JS only shrinks, never enlarges. */
.app.od-kiosk .od-table thead th { font-size: 18px; padding: 8px 22px; }
.app.od-kiosk .od-row td { padding: calc(20px * var(--od-fit)) 22px; }
.app.od-kiosk .od-col-part { font-size: calc(52px * var(--od-fit)); line-height: 1.04; }
.app.od-kiosk .od-col-mach { font-size: calc(40px * var(--od-fit)); }
.app.od-kiosk .od-col-incmm { font-size: calc(32px * var(--od-fit)); }
.app.od-kiosk .od-col-eta  { font-size: calc(46px * var(--od-fit)); }
.app.od-kiosk .od-badge { font-size: calc(22px * var(--od-fit)); padding: calc(9px * var(--od-fit)) calc(22px * var(--od-fit)); }
.app.od-kiosk .od-ready-tag { font-size: calc(26px * var(--od-fit)); }
.app.od-kiosk .od-finalizing-tag { font-size: calc(26px * var(--od-fit)); }
.app.od-kiosk .od-empty { font-size: 30px; padding: 90px 0; }

/* exit-kiosk button — hidden normally, small + muted top-right in kiosk */
.od-exit { display: none; }
.app.od-kiosk .od-exit {
  display: inline-flex; align-items: center; position: fixed; top: 10px; right: 14px; z-index: 60;
  font-size: 12px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  padding: 6px 12px; border-radius: 999px; cursor: pointer;
  background: var(--prism-panel-subtle, rgba(0,0,0,.06)); color: var(--prism-ink-muted);
  border: 1px solid var(--prism-line); opacity: .5; transition: opacity .15s;
}
.app.od-kiosk .od-exit:hover { opacity: 1; }

/* ==========================================================================
   Cell Uptime History — Cell×Day heatmap, shift-split trend, hour×dow heatmap.
   Series colors are the validated categorical palette (blue/aqua/yellow/violet);
   heatmap tints come from cellUptimeColor (shared with the board). Wide grids
   scroll inside their card (cuh-card-body overflow) so the page never breaks.
   ========================================================================== */
.cuh-header { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.cuh-body { display: flex; flex-direction: column; gap: 20px;
  --cuh-s-all: #2a78d6; --cuh-s1: #1baf7a; --cuh-s2: #eda100; --cuh-s3: #4a3aa7; }
.cuh-card { background: var(--prism-panel); border: 1px solid var(--prism-line); border-radius: var(--prism-radius-md); padding: 18px 20px; box-shadow: var(--prism-shadow-panel); }
.cuh-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.cuh-card-head-text { min-width: 0; }
.cuh-card-head h2 { font-size: 16px; font-weight: 700; color: var(--prism-ink); margin: 0; }
.cuh-card-head p { font-size: 12.5px; color: var(--prism-ink-soft); margin: 4px 0 14px; }
.cuh-shift-toggle { flex: none; }
.cuh-shift-toggle .cu-toggle-btn { padding: 6px 14px; }
.cuh-card-body { overflow-x: auto; }

.cuh-hm { display: grid; gap: 3px; min-width: max-content; font-variant-numeric: tabular-nums; }
.cuh-hm-colh { font-size: 11px; color: var(--prism-ink-soft); text-align: center; font-weight: 600; padding-bottom: 2px; }
.cuh-hm-colh-sm { font-size: 9.5px; }
.cuh-hm-rowh { font-size: 12.5px; color: var(--prism-ink-muted); font-weight: 600; display: flex; align-items: center; padding-right: 8px; white-space: nowrap; }
.cuh-rowh-avg { color: var(--prism-ink-soft); font-weight: 500; font-size: 11px; margin-left: 4px; }
.cuh-hm-rowh-sm { font-size: 11px; }
.cuh-hm-cell { min-height: 30px; border-radius: 4px; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; border: 1px solid var(--prism-line); }
.cuh-hm-hourdow .cuh-hm-cell { min-height: 24px; font-size: 10px; border-radius: 3px; }
.cuh-hm-empty { background: transparent !important; border-style: dashed; opacity: .45; }
.cuh-hm-cell[data-cuh-cell] { cursor: pointer; }
.cuh-hm-cell[data-cuh-cell]:hover { border-color: var(--prism-line-strong); box-shadow: var(--prism-shadow-panel); }

.cuh-pop { position: fixed; z-index: 1000; width: 190px; background: var(--prism-panel); border: 1px solid var(--prism-line); border-radius: var(--prism-radius-md); box-shadow: var(--prism-shadow-panel), 0 8px 20px rgba(15,44,74,.16); padding: 10px 12px; }
.cuh-pop[hidden] { display: none; }
.cuh-pop-head { font-size: 12.5px; font-weight: 700; color: var(--prism-ink); margin-bottom: 6px; }
.cuh-pop-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 2px 0; font-size: 12.5px; }
.cuh-pop-row-label { color: var(--prism-ink-muted); font-weight: 600; }
.cuh-pop-row-val { font-weight: 700; font-variant-numeric: tabular-nums; }
.cuh-pop-row-all { border-bottom: 1px solid var(--prism-line); margin-bottom: 4px; padding-bottom: 5px; }

.cuh-legendrow { display: flex; gap: 16px; margin-bottom: 6px; flex-wrap: wrap; }
.cuh-leg { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--prism-ink-muted); font-weight: 600; }
.cuh-leg i { width: 12px; height: 12px; border-radius: 3px; display: inline-block; }
/* States the auto-fit y range, so a truncated axis never reads as 0-based. */
.cuh-leg-note { margin-left: auto; font-size: 11px; color: var(--prism-ink-soft); font-weight: 500; }
.cuh-trend { width: 100%; height: auto; display: block; }
.cuh-grid { stroke: var(--prism-line); stroke-width: 1; }
.cuh-axis { fill: var(--prism-ink-soft); font-size: 10px; }
.cuh-linelabel { font-size: 11px; font-weight: 700; }
@media (prefers-color-scheme: dark) {
  /* same four hues stepped for the dark surface (validated palette dark column) */
  .cuh-body { --cuh-s-all: #3987e5; --cuh-s1: #199e70; --cuh-s2: #c98500; --cuh-s3: #9085e9; }
}

/* ==========================================================================
   Feedback tab (universal submit) + Feedback History (admin triage).
   ========================================================================== */
.fb-form-wrap { max-width: 640px; }
.fb-form { display: flex; flex-direction: column; gap: var(--prism-gap-xl); background: var(--prism-panel); border: 1px solid var(--prism-line); border-radius: var(--prism-radius-md); padding: 24px; box-shadow: var(--prism-shadow-panel); }
.fb-field { display: flex; flex-direction: column; gap: var(--prism-gap-sm); }
.fb-label { font-size: 13px; font-weight: 600; color: var(--prism-ink); }
.fb-optional { font-weight: 400; color: var(--prism-ink-soft); }
.fb-type-toggle, .fb-sev-toggle { display: flex; gap: var(--prism-gap-sm); flex-wrap: wrap; }
.fb-type-btn, .fb-sev-btn { flex: 1 1 auto; min-width: 90px; padding: 10px 12px; font-size: 13px; font-weight: 600; color: var(--prism-ink-muted); background: var(--prism-panel-muted); border: 1px solid var(--prism-line); border-radius: var(--prism-radius-sm); cursor: pointer; transition: all .12s ease; }
.fb-type-btn:hover, .fb-sev-btn:hover { border-color: var(--prism-line-strong); }
.fb-type-btn.active { color: #fff; background: var(--prism-blue); border-color: var(--prism-blue); }
.fb-sev-btn.active { color: var(--prism-blue); background: var(--prism-blue-soft); border-color: var(--prism-blue-line); }
.fb-textarea { width: 100%; padding: 12px; font: inherit; font-size: 14px; color: var(--prism-ink); background: var(--prism-panel); border: 1px solid var(--prism-line); border-radius: var(--prism-radius-sm); resize: vertical; }
.fb-textarea:focus { outline: none; border-color: var(--prism-blue); box-shadow: 0 0 0 3px var(--prism-blue-soft); }
.fb-context { font-size: 12px; color: var(--prism-ink-soft); }
.fb-shots { display: flex; gap: var(--prism-gap-sm); flex-wrap: wrap; }
.fb-shots:empty { display: none; }
.fb-shot { position: relative; width: 120px; height: 84px; border: 1px solid var(--prism-line); border-radius: var(--prism-radius-sm); overflow: hidden; background: var(--prism-panel-muted); }
.fb-shot img { width: 100%; height: 100%; object-fit: cover; display: block; }
.fb-shot-x { position: absolute; top: 3px; right: 3px; width: 22px; height: 22px; padding: 0; line-height: 20px; font-size: 14px; color: #fff; background: rgba(15, 23, 42, .75); border: 0; border-radius: 50%; cursor: pointer; }
.fb-shot-x:hover { background: var(--prism-red); }
.fb-drop { padding: 12px; font: inherit; font-size: 13px; color: var(--prism-ink-muted); background: var(--prism-panel-muted); border: 1px dashed var(--prism-line-strong); border-radius: var(--prism-radius-sm); cursor: pointer; text-align: center; }
.fb-drop:hover, .fb-drop.is-over { border-color: var(--prism-blue); color: var(--prism-blue); background: var(--prism-blue-soft); }
.fb-drop:disabled { opacity: .55; cursor: default; }
.fb-actions { display: flex; align-items: center; gap: var(--prism-gap-lg); }
.fb-status { font-size: 13px; font-weight: 500; }
.fb-status.ok { color: var(--prism-green); }
.fb-status.err { color: var(--prism-red); }

/* Feedback History */
.fb-filters { display: flex; gap: var(--prism-gap-sm); }
.fb-filters[hidden], .fbh-pane[hidden] { display: none !important; }
/* Feedback | GPU tab edits switch (2026-11-11) */
.fbh-kinds { display: inline-flex; gap: 2px; padding: 3px; margin: 0 0 var(--prism-gap-md); background: var(--prism-panel-subtle); border: 1px solid var(--prism-line); border-radius: var(--prism-radius-md); }
.fbh-kind { font: inherit; font-size: 13px; font-weight: 600; padding: 6px 14px; border: 0; border-radius: var(--prism-radius-sm); background: transparent; color: var(--prism-ink-muted); cursor: pointer; }
.fbh-kind:hover { color: var(--prism-ink); }
.fbh-kind.active { background: var(--prism-panel); color: var(--prism-ink); box-shadow: var(--shadow-sm); }
.fbh-kind:focus-visible { outline: 2px solid var(--prism-blue); outline-offset: 1px; }
.fbh-kind-n { font-size: 11px; font-weight: 700; color: var(--prism-blue); margin-left: 4px; }
.fbh-kind-n:empty { display: none; }
.fb-select, .fb-input { padding: 6px 10px; font: inherit; font-size: 13px; color: var(--prism-ink); background: var(--prism-panel); border: 1px solid var(--prism-line); border-radius: var(--prism-radius-sm); }
.fb-input { flex: 1; }
.fb-select:focus, .fb-input:focus { outline: none; border-color: var(--prism-blue); }
.fbh-list { display: flex; flex-direction: column; gap: var(--prism-gap-md); max-width: 860px; }
.fb-empty { padding: 32px; text-align: center; color: var(--prism-ink-soft); }
.fbh-card { background: var(--prism-panel); border: 1px solid var(--prism-line); border-left: 4px solid var(--prism-line-strong); border-radius: var(--prism-radius-md); padding: 14px 16px; box-shadow: var(--shadow-sm); }
.fbh-card.status-new { border-left-color: var(--prism-blue); }
.fbh-card.status-seen { border-left-color: var(--prism-amber); }
.fbh-card.status-resolved { border-left-color: var(--prism-green); opacity: .72; }
.fbh-head { display: flex; align-items: center; gap: var(--prism-gap-sm); flex-wrap: wrap; margin-bottom: 8px; }
.fbh-type { font-size: 12px; font-weight: 700; padding: 2px 8px; border-radius: 3px; background: var(--prism-panel-subtle); color: var(--prism-ink-muted); }
.fbh-type.type-bug { background: var(--prism-red-soft); color: var(--prism-red); }
.fbh-type.type-idea { background: var(--prism-blue-soft); color: var(--prism-blue); }
.fbh-type.type-data { background: var(--prism-amber-soft); color: var(--prism-amber); }
.fbh-sev { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; padding: 2px 7px; border-radius: 3px; }
.fbh-sev.sev-high { background: var(--prism-red-soft); color: var(--prism-red); }
.fbh-sev.sev-med { background: var(--prism-amber-soft); color: var(--prism-amber); }
.fbh-sev.sev-low { background: var(--prism-panel-subtle); color: var(--prism-ink-soft); }
.fbh-meta { font-size: 12px; color: var(--prism-ink-soft); }
.fbh-from { color: var(--prism-ink-muted); font-weight: 600; }
.fbh-status-sel { margin-left: auto; font-size: 12px; padding: 4px 8px; }
.fbh-shots { display: flex; gap: var(--prism-gap-sm); flex-wrap: wrap; margin: 8px 0; }
.fbh-shot { display: block; width: 180px; height: 120px; object-fit: cover; border: 1px solid var(--prism-line); border-radius: var(--prism-radius-sm); background: var(--prism-panel-muted); }
.fbh-shot:hover { border-color: var(--prism-blue); }
.fbh-body { font-size: 14px; line-height: 1.5; color: var(--prism-ink); margin-bottom: 10px; white-space: normal; }
.fbh-note-row { display: flex; gap: var(--prism-gap-sm); align-items: center; }
.btn-sm { padding: 6px 12px; font-size: 12px; }



/* ============================================================
   SCANNER — phone-first router-barcode scanner (admin pilot 2026-07-31).
   Shop-floor tool, not a desktop page: big tap targets, big type, high
   contrast, one-handed reach. Everything ≥48px touch height.
   ============================================================ */
.scan-card { max-width: 560px; padding: var(--prism-gap-xl); }
.scan-label { display: block; font-size: 15px; font-weight: 600; color: var(--prism-ink-muted); margin-bottom: var(--prism-gap-sm); }
.scan-entry-row { display: flex; gap: var(--prism-gap-sm); }
.scan-entry-row input {
  flex: 1; min-width: 0; font-size: 26px; font-weight: 600; letter-spacing: 0.03em;
  padding: 14px 16px; border: 2px solid var(--prism-line-strong); border-radius: var(--prism-radius-md);
  color: var(--prism-ink); background: var(--prism-panel);
}
.scan-entry-row input:focus { outline: none; border-color: var(--prism-blue); box-shadow: 0 0 0 3px var(--prism-blue-soft); }
.scan-lookup-btn {
  font-size: 18px; font-weight: 700; padding: 14px 22px; min-height: 56px;
  background: var(--prism-blue); color: #fff; border: none; border-radius: var(--prism-radius-md); cursor: pointer;
}
.scan-lookup-btn:active { background: var(--color-primary-hover); }
.scan-camera-btn {
  display: block; width: 100%; margin-top: var(--prism-gap-lg); min-height: 56px;
  font-size: 18px; font-weight: 700; padding: 14px 22px; cursor: pointer;
  background: var(--prism-panel); color: var(--prism-blue);
  border: 2px solid var(--prism-blue); border-radius: var(--prism-radius-md);
}
.scan-camera-btn:active { background: var(--prism-blue-soft); }
.scan-nocamera { margin-top: var(--prism-gap-md); font-size: 15px; line-height: 1.5; color: var(--prism-ink-muted); }
.scan-camera-wrap { position: relative; margin-top: var(--prism-gap-lg); border-radius: var(--prism-radius-md); overflow: hidden; background: #000; }
.scan-camera-wrap video { display: block; width: 100%; max-height: 60vh; object-fit: cover; }
/* Aim box. Kept INSIDE the middle-50%-height band scanner.js actually decodes
   (see makeZxingDecoder), so a barcode lined up in here is never cropped out.
   Wide and short: a Code 128 symbol is long and thin, and the whole symbol
   width has to be in frame to decode. */
.scan-reticle {
  position: absolute; left: 5%; right: 5%; top: 34%; height: 32%;
  border: 3px solid rgba(255, 255, 255, 0.85); border-radius: 8px;
  box-shadow: 0 0 0 2000px rgba(0, 0, 0, 0.25); pointer-events: none;
}
.scan-torch-btn {
  position: absolute; right: 12px; bottom: 12px; min-height: 48px; padding: 10px 18px;
  font-size: 16px; font-weight: 700; border: none; border-radius: var(--prism-radius-md);
  background: rgba(255, 255, 255, 0.9); color: var(--prism-ink); cursor: pointer;
}
.scan-torch-btn.scan-torch-on { background: var(--prism-amber-soft); box-shadow: 0 0 0 3px var(--prism-amber-line); }
.scan-status { margin-top: var(--prism-gap-lg); font-size: 17px; line-height: 1.5; color: var(--prism-ink); }
.scan-status-warn { color: var(--prism-amber); font-weight: 600; }
.scan-status-error { color: var(--prism-red); font-weight: 600; }
.scan-result { margin-top: var(--prism-gap-lg); border-top: 1px solid var(--prism-line); padding-top: var(--prism-gap-lg); }
.scan-result-main { font-size: 20px; line-height: 1.4; color: var(--prism-ink); }
.scan-result-main strong { font-size: 24px; }
.scan-result-arrow { color: var(--prism-ink-soft); }
.scan-result-warn {
  margin-top: var(--prism-gap-md); padding: 10px 14px; font-size: 15px; line-height: 1.5;
  color: var(--prism-amber); background: var(--prism-amber-soft);
  border: 1px solid var(--prism-amber-line); border-radius: var(--prism-radius-md);
}
.scan-alt-btn {
  display: block; width: 100%; margin-top: var(--prism-gap-md); padding: 12px 14px; min-height: 48px;
  text-align: left; font-size: 15px; line-height: 1.5; cursor: pointer;
  color: var(--prism-ink); background: var(--prism-panel-subtle);
  border: 1px solid var(--prism-line-strong); border-radius: var(--prism-radius-md);
}
.scan-alt-btn:active { background: var(--prism-blue-soft); }
/* Shown for the 1.5 s before a scan jumps to its job (SC-4). Big: it is the
   one chance to stop a misread of the neighbouring router's barcode. */
.scan-cancel-btn {
  display: block; width: 100%; margin-bottom: var(--prism-gap-md); min-height: 52px; padding: 12px 16px;
  font-size: 17px; font-weight: 700; cursor: pointer;
  color: var(--prism-red); background: var(--prism-panel-subtle);
  border: 2px solid var(--prism-red); border-radius: var(--prism-radius-md);
}
.scan-cancel-btn[hidden] { display: none; }
.scan-open-btn {
  display: block; margin-top: var(--prism-gap-lg); min-height: 56px; padding: 15px 22px;
  text-align: center; font-size: 19px; font-weight: 700; text-decoration: none;
  color: #fff; background: var(--prism-green); border-radius: var(--prism-radius-md);
}
.scan-open-btn:active { filter: brightness(0.9); }
@media (max-width: 720px) {
  .scan-card { max-width: none; }
  .scan-entry-row { flex-direction: column; }
  .scan-lookup-btn { width: 100%; }
}
.scan-secondary-btn {
  display: block; margin-top: var(--prism-gap-sm); min-height: 48px; padding: 13px 22px;
  text-align: center; font-size: 16px; font-weight: 600; text-decoration: none;
  color: var(--prism-blue); background: var(--prism-panel);
  border: 2px solid var(--prism-blue); border-radius: var(--prism-radius-md);
}
.scan-secondary-btn:active { background: var(--prism-blue-soft); }

/* ===== Shop Clock (2026-08-05) — grown out of the Scanner tab above; reuses
   .scan-card/.scan-entry-row/.scan-camera-btn/.scan-status/.scan-reticle
   verbatim, adds the clock/qty/scrap/machine/history components below. ===== */
.sc-employee-card { max-width: 560px; padding: var(--prism-gap-lg) var(--prism-gap-xl); }
.sc-employee-bar { display: flex; align-items: center; flex-wrap: wrap; gap: var(--prism-gap-sm); }
.sc-employee-name { font-size: 18px; font-weight: 700; color: var(--prism-ink); }
.sc-employee-prompt { font-size: 16px; color: var(--prism-ink-muted); }
.sc-employee-note { font-size: 13px; color: var(--prism-amber); }
.sc-employee-bar-flash { animation: sc-flash 0.3s ease-in-out 2; }
@keyframes sc-flash { 50% { background: var(--prism-amber-soft); } }

.sc-tabbar {
  display: flex; gap: 4px; max-width: 640px; padding: 4px;
  background: var(--prism-panel-soft, var(--prism-panel)); border: 2px solid var(--prism-line-strong);
  border-radius: var(--prism-radius-md); margin-bottom: var(--prism-gap-md);
}
.sc-tab-btn {
  flex: 1; padding: 10px 10px; min-height: 44px; border: none; border-radius: calc(var(--prism-radius-md) - 3px);
  background: none; color: var(--prism-ink-muted); font-size: 14px; font-weight: 700; cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.sc-tab-btn-active { background: var(--prism-blue); color: #fff; }
/* Count badge on the Clocked In tab. Without it an operator had to open the tab
   to find out whether they were still on the clock — the one thing a clock must
   never make you guess about. Red when something is actively running, amber when
   there's only banked-but-unlogged work. */
.sc-tab-btn { position: relative; }
.sc-tab-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; margin-left: 6px; padding: 0 5px;
  border-radius: 999px; background: var(--prism-amber); color: #fff;
  font-size: 12px; font-weight: 800; font-variant-numeric: tabular-nums; vertical-align: middle;
}
.sc-tab-count-running { background: var(--prism-red); }
.sc-tab-btn-alert:not(.sc-tab-btn-active) { color: var(--prism-red); }
.sc-tab-panel { max-width: 640px; }
/* Four tabs squeeze on a phone-width card — a 2x2 grid stays legible where
   flex-row-of-4 would truncate "Machine History"/"Clocked In". */
@media (max-width: 480px) {
  .sc-tabbar { display: grid; grid-template-columns: repeat(2, 1fr); gap: 4px; }
  .sc-tab-btn { font-size: 13px; padding: 10px 6px; }
}

/* Restored-punch banner (page load) and stale-punch notice (inside the panel).
   Both exist so recovered state is never silent — see announceRestore() /
   renderStaleNotice(). */
.sc-restore-notice, .sc-stale-notice {
  max-width: 640px; margin-bottom: var(--prism-gap-md);
  padding: var(--prism-gap-md) var(--prism-gap-lg);
  border: 2px solid var(--prism-amber-line); background: var(--prism-amber-soft);
  border-radius: var(--prism-radius-md); font-size: 14px; font-weight: 600; color: var(--prism-ink);
}
.sc-stale-notice { margin-bottom: 0; font-weight: 500; display: flex; flex-direction: column; gap: var(--prism-gap-sm); align-items: flex-start; }
/* `display: flex` above would otherwise beat the default `[hidden]{display:none}`
   — same specificity, and this rule comes later — leaving an empty amber box
   parked in the panel permanently. Any hidden-toggled element given an explicit
   display needs this companion rule. */
.sc-stale-notice[hidden] { display: none; }
.sc-stale-discard {
  padding: 8px 14px; min-height: 40px; border-radius: var(--prism-radius-md); cursor: pointer;
  border: 2px solid var(--prism-amber); background: var(--prism-panel); color: var(--prism-amber);
  font-size: 13px; font-weight: 700;
}

.sc-panel { max-width: 640px; padding: var(--prism-gap-xl); display: flex; flex-direction: column; gap: var(--prism-gap-lg); }
/* See the .prism-badge[hidden] note in styles_tokens.css: an explicit `display`
   on a class beats `[hidden]{display:none}` (equal specificity, later in source),
   so every hidden-toggled element here needs its own guard. Without this,
   #scPanelSection rendered an empty job panel before anything was even scanned.
   Audited 2026-08-06 — 5 elements in this section were affected. */
.sc-panel[hidden] { display: none; }
.sc-panel-header { display: flex; align-items: baseline; justify-content: space-between; gap: var(--prism-gap-sm); flex-wrap: wrap; }
.sc-job-header { font-size: 18px; color: var(--prism-ink); min-width: 0; }
.sc-job-header strong { font-size: 22px; }
.sc-job-line1 { line-height: 1.3; }
.sc-job-line2 { display: flex; flex-wrap: wrap; gap: var(--prism-gap-sm); margin-top: 6px; }
/* Order qty + due date — the "what am I making and is it hot" context the first
   cut left out. Due date is Delivery.Promised_Date (99.8% resolvable). */
.sc-job-chip {
  font-size: 13px; font-weight: 700; padding: 3px 10px; border-radius: 999px;
  background: var(--prism-panel-soft, var(--prism-blue-soft)); color: var(--prism-ink-muted);
}
.sc-job-chip-soon { background: var(--prism-amber-soft); color: var(--prism-amber); }
.sc-job-chip-late { background: var(--prism-red-soft, var(--prism-amber-soft)); color: var(--prism-red); }
.sc-job-desc { margin-top: 6px; font-size: 13px; color: var(--prism-ink-soft); overflow-wrap: anywhere; }

/* Which op the shared panel is currently bound to — the panel moves between
   rows, so this keeps the answer on screen without scrolling back up. */
.sc-panel-op-label {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--prism-gap-sm);
  padding-bottom: var(--prism-gap-sm); border-bottom: 1px solid var(--prism-line);
  font-size: 14px;
}
.sc-panel-op-seq { font-weight: 800; color: var(--prism-ink); }
.sc-panel-op-wc { font-weight: 700; color: var(--prism-blue); }
.sc-panel-op-desc { color: var(--prism-ink-muted); }
.sc-change-job-btn {
  background: none; border: none; color: var(--prism-blue); font-size: 14px; font-weight: 600;
  cursor: pointer; padding: var(--prism-gap-xs) 0; white-space: nowrap;
}

/* Op accordion — one row per operation on the scanned job. Tapping a row
   expands it into the shared #scOpPanel (moved in via JS, not cloned), so
   there's exactly one live set of clock/qty/scrap controls regardless of
   how many ops the job has. */
.sc-op-accordion { display: flex; flex-direction: column; gap: var(--prism-gap-sm); }
.sc-op-row {
  border: 2px solid var(--prism-line-strong); border-radius: var(--prism-radius-md);
  background: var(--prism-panel); overflow: hidden; transition: border-color 0.15s ease;
}
.sc-op-row-expanded { border-color: var(--prism-blue); }
.sc-op-row-head {
  width: 100%; display: flex; align-items: center; gap: var(--prism-gap-sm);
  padding: 14px var(--prism-gap-lg); min-height: 52px; background: none; border: none;
  cursor: pointer; text-align: left; font: inherit; font-size: 15px; color: var(--prism-ink);
}
.sc-op-row-head:active { background: var(--prism-blue-soft); }
.sc-op-row-chevron {
  font-size: 18px; line-height: 1; color: var(--prism-ink-soft); flex-shrink: 0;
  transition: transform 0.2s ease;
}
.sc-op-row-expanded .sc-op-row-chevron { transform: rotate(90deg); color: var(--prism-blue); }
/* Two-line row: identity on line 1, what the op actually IS on line 2. */
.sc-op-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.sc-op-row-line1 { display: flex; align-items: center; gap: var(--prism-gap-sm); min-width: 0; }
.sc-op-row-line2 { display: flex; align-items: baseline; gap: var(--prism-gap-sm); min-width: 0; }
.sc-op-row-seq { font-weight: 700; white-space: nowrap; }
.sc-op-row-wc { font-weight: 700; color: var(--prism-blue); white-space: nowrap; }
/* The op description. It USED to be display:none under 480px, which was a real
   bug, not a density trade: 99.0% of live active jobs (396/400 measured) have at
   least two ops sharing a work center — job 118094 ends with three consecutive
   'QC' ops that are CLEANING STATION, QC INSPECTION and PACKAGING — so on a
   phone the operator got three identical "Op 6 · QC" rows and no way to tell
   which was theirs. It is the ONLY distinguishing field, so it always renders.
   Wraps to two lines rather than truncating for the same reason. */
.sc-op-row-desc {
  color: var(--prism-ink); flex: 1; min-width: 0; font-size: 14px;
  overflow-wrap: anywhere;
}
.sc-op-row-progress {
  font-size: 12px; font-weight: 600; color: var(--prism-ink-soft); white-space: nowrap; flex-shrink: 0;
}
/* Finished work is folded by default (26.0% of ops on live jobs are already
   'C'); when unfolded it reads as background, not as something to act on. */
.sc-op-row-done { opacity: 0.62; }
.sc-op-row-done .sc-op-row-wc { color: var(--prism-ink-muted); }
.sc-op-fold {
  width: 100%; display: flex; align-items: center; gap: var(--prism-gap-sm);
  padding: 10px var(--prism-gap-lg); min-height: 44px; background: none; cursor: pointer;
  border: 1px dashed var(--prism-line-strong); border-radius: var(--prism-radius-md);
  font: inherit; font-size: 13px; font-weight: 600; color: var(--prism-ink-muted); text-align: left;
}
.sc-op-fold:active { background: var(--prism-blue-soft); }
.sc-op-fold-chevron { font-size: 15px; line-height: 1; }
.sc-op-row-badges { display: flex; align-items: center; gap: var(--prism-gap-sm); flex-shrink: 0; margin-left: auto; }
.sc-op-row-clocked {
  font-size: 12px; font-weight: 700; color: var(--prism-red); font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Banked-but-unlogged time — amber, not red: nothing is running, but the shop
   still hasn't captured this work. */
.sc-op-row-clocked-paused { color: var(--prism-amber); }
/* Height-animated collapse via the grid 0fr/1fr trick — no JS height math,
   no janky max-height guess. min-height:0 on the inner wrap is required for
   the grid item to actually shrink to 0 instead of clamping to content. */
.sc-op-row-body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.25s ease; }
.sc-op-row-expanded .sc-op-row-body { grid-template-rows: 1fr; }
.sc-op-row-body-inner { overflow: hidden; min-height: 0; }
.sc-op-panel {
  padding: var(--prism-gap-lg); border-top: 2px solid var(--prism-line);
  display: flex; flex-direction: column; gap: var(--prism-gap-lg);
}
.sc-op-panel[hidden] { display: none; } /* see .sc-panel[hidden] above */
/* Grouping wrappers for the desktop two-column panel (see the min-width:900px
   block at the end of this file). At phone width they reproduce the panel's own
   flex-column + gap exactly, so wrapping the children changed nothing here. */
.sc-op-panel-col { display: flex; flex-direction: column; gap: var(--prism-gap-lg); min-width: 0; }
/* NOTE: there is deliberately no `.sc-op-row-desc { display: none }` rule at
   phone width any more. See the comment on .sc-op-row-desc above — hiding it was
   what made ops on a shared work center indistinguishable on a phone, which is
   the exact device this tab is built for. */

.sc-clock-row { display: flex; align-items: center; gap: var(--prism-gap-lg); }
.sc-clock-btn {
  flex: 1; min-height: 72px; font-size: 22px; font-weight: 800; letter-spacing: 0.02em;
  border: none; border-radius: var(--prism-radius-md); cursor: pointer;
  background: var(--prism-green); color: #fff;
}
.sc-clock-btn.sc-clock-btn-running { background: var(--prism-red); }
.sc-clock-btn:active { filter: brightness(0.9); }
.sc-clock-timer {
  font-variant-numeric: tabular-nums; font-size: 22px; font-weight: 700; color: var(--prism-ink);
  min-width: 96px; text-align: center;
}

/* auto-fit, not repeat(3, 1fr): the columns wrap when the CONTAINER runs out of
   room rather than waiting on a viewport media query, so the third stepper can't
   end up clipped at a narrow width the query doesn't match. The 520px rule below
   still turns the steppers label-beside-controls on a real phone. */
.sc-qty-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--prism-gap-md); }
.sc-stepper {
  display: flex; flex-direction: column; align-items: center; gap: var(--prism-gap-sm);
  padding: var(--prism-gap-md); border: 1px solid var(--prism-line); border-radius: var(--prism-radius-md);
}
.sc-stepper-label { font-size: 13px; font-weight: 600; color: var(--prism-ink-muted); text-align: center; }
.sc-stepper-controls { display: flex; align-items: center; gap: var(--prism-gap-sm); }
.sc-stepper-dec, .sc-stepper-inc {
  width: 40px; height: 40px; border-radius: 50%; border: 2px solid var(--prism-line-strong);
  background: var(--prism-panel); font-size: 20px; font-weight: 700; line-height: 1; cursor: pointer;
  color: var(--prism-ink);
}
.sc-stepper-dec:active, .sc-stepper-inc:active { background: var(--prism-blue-soft); border-color: var(--prism-blue); }
/* Now a real <input>, so it needs input affordances (and 16px+ font, or iOS
   Safari zooms the whole page on focus). Underline says "you can type here"
   without adding a heavy box inside an already-bordered stepper. */
.sc-stepper-value {
  font-size: 24px; font-weight: 800; width: 64px; text-align: center; color: var(--prism-ink);
  background: none; border: none; border-bottom: 2px solid var(--prism-line-strong);
  border-radius: 0; padding: 2px 0; font-variant-numeric: tabular-nums; font-family: inherit;
}
.sc-stepper-value:focus {
  outline: none; border-bottom-color: var(--prism-blue); background: var(--prism-blue-soft);
}
/* The target off the op's own Est_Required_Qty — the number the operator came to
   the machine needing, absent from the first cut entirely. */
.sc-qty-target {
  font-size: 15px; font-weight: 700; color: var(--prism-blue); text-align: center;
  padding: var(--prism-gap-sm) var(--prism-gap-md); background: var(--prism-blue-soft);
  border-radius: var(--prism-radius-md);
}
.sc-qty-target.sc-qty-target-over { color: var(--prism-amber); background: var(--prism-amber-soft); }
@media (max-width: 520px) {
  .sc-qty-grid { grid-template-columns: 1fr; }
  /* Stacked one-per-row on a phone, the label reads better beside the controls
     than above them. */
  .sc-stepper { flex-direction: row; justify-content: space-between; }
  .sc-stepper-label { text-align: left; }
}

.sc-scrap-reason-row, .sc-field-row { display: flex; flex-direction: column; gap: var(--prism-gap-sm); }
/* Without this the scrap-reason chips were on screen permanently — renderQty()
   sets `hidden` when scrap is 0, and the CSS above silently overrode it, so the
   panel always asked for a scrap reason even with nothing scrapped. */
.sc-scrap-reason-row[hidden] { display: none; }
.sc-field-label { font-size: 14px; font-weight: 600; color: var(--prism-ink-muted); }
.sc-chip-row { display: flex; flex-wrap: wrap; gap: var(--prism-gap-sm); }
.sc-chip {
  padding: 10px 16px; min-height: 44px; border: 2px solid var(--prism-line-strong);
  border-radius: 999px; background: var(--prism-panel); color: var(--prism-ink);
  font-size: 14px; font-weight: 600; cursor: pointer;
}
.sc-chip.sc-chip-selected { background: var(--prism-amber-soft); border-color: var(--prism-amber); color: var(--prism-amber); }
.sc-other-input, .sc-select, .sc-notes-input {
  font-size: 16px; padding: 12px 14px; min-height: 48px;
  border: 2px solid var(--prism-line-strong); border-radius: var(--prism-radius-md);
  color: var(--prism-ink); background: var(--prism-panel); width: 100%;
}
.sc-notes-input { min-height: 64px; font-family: inherit; resize: vertical; }

.sc-complete-row { display: flex; align-items: center; gap: var(--prism-gap-sm); flex-wrap: wrap; }
.sc-mark-complete-btn {
  padding: 12px 18px; min-height: 48px; border: 2px solid var(--prism-line-strong);
  border-radius: var(--prism-radius-md); background: var(--prism-panel); color: var(--prism-ink);
  font-size: 15px; font-weight: 600; cursor: pointer;
}
.sc-complete-confirm {
  padding: var(--prism-gap-md); border: 2px solid var(--prism-amber-line); background: var(--prism-amber-soft);
  border-radius: var(--prism-radius-md); display: flex; flex-direction: column; gap: var(--prism-gap-sm);
}
/* Without this the "Mark this operation complete?" confirmation was permanently
   open, with its Yes button live — so the deliberate confirm step this dialog
   exists to provide wasn't actually a step at all. */
.sc-complete-confirm[hidden] { display: none; }
.sc-complete-confirm p { margin: 0; font-size: 14px; color: var(--prism-ink); }
.sc-confirm-yes, .sc-confirm-no {
  padding: 10px 16px; min-height: 44px; border-radius: var(--prism-radius-md); cursor: pointer;
  font-size: 14px; font-weight: 700; border: none;
}
.sc-confirm-yes { background: var(--prism-amber); color: #fff; }
.sc-confirm-no { background: var(--prism-panel); border: 2px solid var(--prism-line-strong); color: var(--prism-ink); }

.sc-submit-btn {
  min-height: 60px; font-size: 19px; font-weight: 800; border: none; cursor: pointer;
  border-radius: var(--prism-radius-md); background: var(--prism-blue); color: #fff;
}
.sc-submit-btn:active { filter: brightness(0.9); }
.sc-submit-status { font-size: 14px; color: var(--prism-green); text-align: center; }
/* "Nothing to log yet" — a refusal, not a success. */
.sc-submit-status.sc-submit-status-warn { color: var(--prism-amber); font-weight: 600; }

/* Header row on the two history tabs, carrying the refresh control. Machine
   History previously had NO way to re-fetch at all (the load function
   early-returned once a work center had loaded). */
.sc-history-head { display: flex; align-items: center; justify-content: space-between; gap: var(--prism-gap-sm); }
.sc-refresh-btn {
  background: none; border: none; color: var(--prism-blue); font-size: 14px; font-weight: 600;
  cursor: pointer; padding: var(--prism-gap-xs) 0; white-space: nowrap; min-height: 32px;
}
.sc-refresh-btn:active { opacity: 0.6; }

.sc-history-section { border-top: 1px solid var(--prism-line); padding-top: var(--prism-gap-md); }
.sc-history-title { margin: 0 0 var(--prism-gap-sm); font-size: 15px; font-weight: 700; color: var(--prism-ink); }
.sc-history-empty { font-size: 14px; color: var(--prism-ink-soft); font-style: italic; }
.sc-history-empty.sc-history-err { color: var(--prism-red, #b3261e); font-style: normal; font-weight: 600; }
.sc-history-warn { color: #b26a00; font-style: normal; font-weight: 600; }
.sc-history-row {
  display: flex; flex-wrap: wrap; gap: var(--prism-gap-sm); align-items: baseline;
  padding: var(--prism-gap-sm) 0; border-bottom: 1px solid var(--prism-line); font-size: 14px;
}
.sc-history-row:last-child { border-bottom: none; }
.sc-history-when { font-weight: 700; color: var(--prism-ink); min-width: 56px; }
.sc-history-who { font-weight: 600; color: var(--prism-ink); }
.sc-history-what { color: var(--prism-ink-muted); }
.sc-history-note { flex-basis: 100%; color: var(--prism-ink-soft); font-style: italic; font-size: 13px; }

.sc-receipts {
  max-width: 640px; margin-top: var(--prism-gap-lg); padding: var(--prism-gap-md) var(--prism-gap-lg);
  border: 1px dashed var(--prism-line-strong); border-radius: var(--prism-radius-md);
}
.sc-receipts-label { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--prism-ink-soft); margin-bottom: var(--prism-gap-sm); }
.sc-receipt-row { display: flex; gap: var(--prism-gap-md); font-size: 14px; color: var(--prism-ink-muted);
  padding: 4px 0; }
.sc-receipt-row span:first-child { font-variant-numeric: tabular-nums; min-width: 64px; color: var(--prism-ink-soft); }

/* My History tab — real JobBOSS labor tickets for one employee, newest
   first. Rows are clickable: tap one to jump back into that job's op
   accordion on the Scan tab, same idea as the Scanner tab's job-open. */
.sc-my-history-card { max-width: 640px; padding: var(--prism-gap-xl); }
.sc-my-history-status { font-size: 14px; color: var(--prism-ink-muted); padding: var(--prism-gap-md) 0; }
.sc-my-history-status.sc-my-history-status-warn { color: var(--prism-amber); }
.sc-my-history-list { display: flex; flex-direction: column; gap: var(--prism-gap-sm); }
.sc-mh-row {
  width: 100%; display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--prism-gap-sm);
  padding: 12px 14px; border: 2px solid var(--prism-line-strong); border-radius: var(--prism-radius-md);
  background: var(--prism-panel); cursor: pointer; text-align: left; font: inherit; font-size: 14px; color: var(--prism-ink);
}
.sc-mh-row:active { background: var(--prism-blue-soft); border-color: var(--prism-blue); }
.sc-mh-when { font-weight: 700; min-width: 68px; color: var(--prism-ink); }
.sc-mh-job { font-weight: 700; color: var(--prism-blue); white-space: nowrap; }
.sc-mh-part { color: var(--prism-ink-soft); white-space: nowrap; }
.sc-mh-desc { color: var(--prism-ink-muted); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sc-mh-qty { color: var(--prism-ink-muted); white-space: nowrap; }
.sc-mh-qty.sc-mh-qty-scrap { color: var(--prism-red); font-weight: 700; }
.sc-mh-note { flex-basis: 100%; color: var(--prism-ink-soft); font-style: italic; font-size: 13px; }
.sc-mh-who { color: var(--prism-ink); font-weight: 600; white-space: nowrap; } /* Machine History rows only — who worked it */

/* Clocked In tab — every punch with unsaved state, across every job touched
   this session. Two-part row: tap the left side to reopen it on the Scan
   tab; the right side clocks out in place without navigating. */
.sc-ci-list { display: flex; flex-direction: column; gap: var(--prism-gap-sm); }
.sc-ci-row {
  display: flex; align-items: center; gap: var(--prism-gap-sm);
  border: 2px solid var(--prism-line-strong); border-radius: var(--prism-radius-md); background: var(--prism-panel);
}
.sc-ci-open-btn {
  flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--prism-gap-sm);
  padding: 12px 14px; border: none; background: none; cursor: pointer; text-align: left; font: inherit;
  font-size: 14px; color: var(--prism-ink);
}
.sc-ci-open-btn:active { background: var(--prism-blue-soft); }
.sc-ci-job { font-weight: 700; color: var(--prism-blue); white-space: nowrap; }
.sc-ci-part { color: var(--prism-ink-soft); white-space: nowrap; }
.sc-ci-desc { color: var(--prism-ink-muted); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sc-ci-qty { color: var(--prism-ink-muted); white-space: nowrap; font-size: 13px; }
.sc-ci-timer {
  font-weight: 700; color: var(--prism-red); font-variant-numeric: tabular-nums; white-space: nowrap; padding-left: 8px;
}
.sc-ci-idle { color: var(--prism-ink-soft); font-size: 13px; white-space: nowrap; padding-left: 8px; }
/* Time that was worked and banked but never logged — the case that used to
   vanish entirely (clock out with 0 qty left no punch and no receipt). */
.sc-ci-paused {
  color: var(--prism-amber); font-size: 13px; font-weight: 700; white-space: nowrap;
  padding-left: 8px; font-variant-numeric: tabular-nums;
}
.sc-ci-stale { color: var(--prism-amber); font-size: 12px; font-weight: 600; padding-left: 8px; max-width: 130px; }
.sc-ci-row-stale { border-color: var(--prism-amber-line); background: var(--prism-amber-soft); }
.sc-ci-out-btn {
  flex-shrink: 0; margin-right: 10px; padding: 8px 14px; min-height: 40px; border: none;
  border-radius: var(--prism-radius-md); background: var(--prism-red); color: #fff;
  font-size: 13px; font-weight: 700; cursor: pointer;
}
/* "Log" on a punch that's already stopped — nothing is running, so it shouldn't
   shout in stop-red like the live Clock Out does. */
.sc-ci-log-btn { background: var(--prism-blue); }

/* ===== Clock-out drawer (2026-08-06) =====
   Tapping Clock Out opens this instead of stopping the clock immediately, so the
   operator reports good/in-progress/scrap and notes at the moment they finish —
   the one moment they actually know those numbers. The wrapper owns the border so
   the row and its drawer read as a single unit while open. */
.sc-ci-row-wrap { border: 2px solid var(--prism-line-strong); border-radius: var(--prism-radius-md); background: var(--prism-panel); }
.sc-ci-row-wrap-open { border-color: var(--prism-blue); }
/* The row itself no longer draws its own border — the wrapper does. */
.sc-ci-row-wrap > .sc-ci-row { border: none; background: none; }
.sc-ci-row-wrap > .sc-ci-row-stale { background: var(--prism-amber-soft); border-radius: calc(var(--prism-radius-md) - 2px); }

.sc-ci-drawer {
  padding: var(--prism-gap-lg); border-top: 2px solid var(--prism-line);
  display: flex; flex-direction: column; gap: var(--prism-gap-md);
}
.sc-ci-d-target {
  font-size: 14px; font-weight: 700; color: var(--prism-blue); text-align: center;
  padding: var(--prism-gap-sm); background: var(--prism-blue-soft); border-radius: var(--prism-radius-md);
}
.sc-ci-d-target.sc-qty-target-over { color: var(--prism-amber); background: var(--prism-amber-soft); }
/* ALWAYS one field per row, label left / stepper right. Deliberately NOT a
   3-column grid with a phone media query: the drawer is nested inside a list row,
   so its usable width is set by its CONTAINER, not the viewport — a viewport query
   leaves the third field clipped whenever the column is narrow but the window
   isn't. One-per-row cannot clip at any width, and on the phone this tab is built
   for it's what the media query would have produced anyway. */
.sc-ci-d-grid { display: flex; flex-direction: column; gap: var(--prism-gap-sm); }
.sc-ci-d-field {
  display: flex; flex-direction: row; align-items: center; justify-content: space-between;
  gap: var(--prism-gap-sm); min-width: 0;
}
.sc-ci-d-label { font-size: 13px; font-weight: 600; color: var(--prism-ink-muted); }
.sc-ci-d-stepper { display: flex; align-items: center; gap: 6px; }
.sc-ci-d-dec, .sc-ci-d-inc {
  width: 40px; height: 40px; flex-shrink: 0; border-radius: 50%;
  border: 2px solid var(--prism-line-strong); background: var(--prism-panel);
  font-size: 20px; font-weight: 700; line-height: 1; cursor: pointer; color: var(--prism-ink);
}
.sc-ci-d-dec:active, .sc-ci-d-inc:active { background: var(--prism-blue-soft); border-color: var(--prism-blue); }
/* 16px+ or iOS Safari zooms the page on focus. */
.sc-ci-d-qty {
  width: 58px; font-size: 20px; font-weight: 800; text-align: center; color: var(--prism-ink);
  background: none; border: none; border-bottom: 2px solid var(--prism-line-strong);
  border-radius: 0; padding: 2px 0; font-variant-numeric: tabular-nums; font-family: inherit;
}
.sc-ci-d-qty:focus { outline: none; border-bottom-color: var(--prism-blue); background: var(--prism-blue-soft); }
.sc-ci-d-reason { display: flex; flex-direction: column; gap: var(--prism-gap-sm); }
.sc-ci-d-chips { display: flex; flex-wrap: wrap; gap: var(--prism-gap-sm); }
.sc-ci-d-notes {
  font-size: 16px; padding: 10px 12px; min-height: 60px; width: 100%;
  border: 2px solid var(--prism-line-strong); border-radius: var(--prism-radius-md);
  color: var(--prism-ink); background: var(--prism-panel); font-family: inherit; resize: vertical;
}
.sc-ci-d-actions { display: flex; flex-direction: column; gap: var(--prism-gap-sm); }
.sc-ci-d-confirm {
  min-height: 56px; font-size: 18px; font-weight: 800; border: none; cursor: pointer;
  border-radius: var(--prism-radius-md); background: var(--prism-red); color: #fff;
}
.sc-ci-d-confirm:active { filter: brightness(0.9); }
/* Deliberately quiet: pausing is the secondary path, logging is the point. */
.sc-ci-d-pause {
  min-height: 44px; font-size: 14px; font-weight: 700; cursor: pointer;
  border-radius: var(--prism-radius-md); background: var(--prism-panel);
  border: 2px solid var(--prism-line-strong); color: var(--prism-ink-muted);
}
.sc-ci-d-status { font-size: 14px; font-weight: 600; color: var(--prism-amber); text-align: center; }
.sc-ci-d-status[hidden] { display: none; }
.sc-ci-d-grid[hidden], .sc-ci-d-reason[hidden], .sc-ci-d-actions[hidden] { display: none; }
/* Confirmation on this tab — the logged row disappears, so this is the only
   feedback the operator gets here. */
.sc-ci-flash {
  padding: var(--prism-gap-md) var(--prism-gap-lg); margin-bottom: var(--prism-gap-md);
  border: 2px solid var(--prism-green); border-radius: var(--prism-radius-md);
  font-size: 14px; font-weight: 600; color: var(--prism-ink);
}
.sc-ci-flash[hidden] { display: none; }

/* ===== Durable sync (2026-08-17) =====
   Punches are POSTed to Prism and queued in a device outbox until confirmed.
   These surfaces are the difference between "saved" and "we hope so". */
.sc-sync-banner {
  max-width: 640px; margin-bottom: var(--prism-gap-md);
  padding: var(--prism-gap-md) var(--prism-gap-lg);
  border: 2px solid var(--prism-amber); border-radius: var(--prism-radius-md);
  background: var(--prism-amber-soft); color: var(--prism-ink);
  font-size: 14px; font-weight: 600;
}
.sc-sync-banner[hidden] { display: none; }

/* Per-receipt state. Pending is deliberately quiet and "Not saved" deliberately
   loud — the failure has to out-shout the four rows of success above it. */
.sc-receipt-sync { margin-left: auto; font-weight: 700; white-space: nowrap; }
.sc-receipt-sync-ok { color: var(--prism-green); }
.sc-receipt-sync-pending { color: var(--prism-ink-soft); font-weight: 600; }
.sc-receipt-sync-error { color: var(--prism-red); }

/* Source chip on My History rows — a Prism punch and a JobBOSS ticket are
   different records and the list must never blur them together. */
.sc-mh-src {
  flex-shrink: 0; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  background: var(--prism-line); color: var(--prism-ink-muted);
}
.sc-mh-src-punch { background: var(--prism-blue-soft); color: var(--prism-blue); }

/* ===== Desktop layout (2026-08-17) =====
   Everything above is sized for a phone held in one hand at a machine: 48px+
   controls, one column, 640px caps. On a desk monitor that reads as a giant
   phone screenshot with two thirds of the window empty. This block widens the
   containers, splits the action panel into two columns, aligns the history
   lists into real columns, and takes the touch padding back down — without
   touching any of the phone rules, which stay the default. 900px is the
   breakpoint because the op panel's two columns need ~430px each to hold the
   qty steppers and the machine select without wrapping.

   The 16px input font-size is a phone-only requirement (iOS Safari zooms the
   page on focus below it), so desktop drops to 14px. */
@media (min-width: 900px) {
  .sc-employee-card,
  .sc-tab-panel,
  .sc-panel,
  .sc-my-history-card,
  .sc-sync-banner,
  .sc-restore-notice { max-width: 1180px; }

  /* Tabs read as a segmented control, not four full-width phone buttons. */
  .sc-tabbar { display: flex; gap: var(--prism-gap-sm); }
  .sc-tab-btn { flex: 0 1 auto; min-width: 150px; min-height: 40px; font-size: 14px; padding: 8px 18px; }

  .sc-employee-card { padding: var(--prism-gap-md) var(--prism-gap-lg); }
  .sc-employee-name { font-size: 16px; }

  /* Scan entry doesn't need to span a 1180px card. */
  #scScanSection { max-width: 620px; }

  /* --- the action panel: two columns --- */
  .sc-op-panel {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    column-gap: var(--prism-gap-xl);
    row-gap: var(--prism-gap-lg);
    align-items: start;
  }
  /* Full-width rails above and below the two columns. */
  .sc-panel-op-label,
  .sc-stale-notice,
  .sc-history-section { grid-column: 1 / -1; }
  .sc-op-panel-col { gap: var(--prism-gap-md); }

  .sc-clock-btn { min-height: 56px; font-size: 18px; }
  .sc-clock-timer { font-size: 20px; }
  .sc-stepper-dec, .sc-stepper-inc { min-width: 38px; min-height: 38px; }
  .sc-stepper-value { font-size: 15px; }
  .sc-chip { min-height: 34px; padding: 6px 13px; font-size: 13px; }
  .sc-other-input, .sc-select, .sc-notes-input { font-size: 14px; min-height: 38px; padding: 8px 11px; }
  .sc-notes-input { min-height: 76px; }
  .sc-mark-complete-btn { min-height: 38px; padding: 8px 14px; font-size: 14px; }
  .sc-submit-btn { min-height: 46px; font-size: 16px; }

  /* --- history + clocked-in lists: aligned columns, not wrapped flex --- */
  /* when | source | job | part | description | qty — description takes the
     slack, everything else is content-width so the eye can run down a column.
     The note keeps its own full-width row underneath via grid-column: 1/-1. */
  .sc-mh-row {
    display: grid;
    grid-template-columns: max-content max-content max-content max-content minmax(0, 1fr) max-content;
    align-items: baseline;
    column-gap: var(--prism-gap-md);
    padding: 9px var(--prism-gap-md);
  }
  .sc-mh-row:hover { background: var(--prism-blue-soft); border-color: var(--prism-blue); }
  .sc-mh-note { grid-column: 1 / -1; margin-top: 3px; }
  /* A JobBOSS row has no part number on ~some tickets and a punch may have no
     description; an empty grid cell is fine, a collapsed one is not — so the
     row keeps its columns even when a cell is missing. */
  .sc-mh-when { min-width: 0; white-space: nowrap; }

  .sc-ci-row { padding: 9px var(--prism-gap-md); }
  .sc-ci-open-btn:hover { background: var(--prism-blue-soft); }
  .sc-ci-out-btn:hover { filter: brightness(1.08); }
  .sc-ci-d-grid { flex-direction: row; flex-wrap: wrap; gap: var(--prism-gap-lg); }
  .sc-ci-d-field { flex: 1 1 160px; }
  .sc-ci-d-actions { flex-direction: row; justify-content: flex-end; }
  .sc-ci-d-confirm, .sc-ci-d-pause { flex: 0 1 220px; }

  /* Receipts sit under the tabs as a footnote — no reason for them to be as
     wide as the card. */
  .sc-receipts { max-width: 780px; }

  /* Pointer devices get hover affordances the phone build has no use for. */
  .sc-op-row-head:hover { background: var(--prism-blue-soft); }
  .sc-refresh-btn:hover { text-decoration: underline; }
}

/* ============================================================================
   Wire Saw ROI (`wire-saw-roi`) — standalone make-vs-buy calculator for
   outsourcing slicing to Slicing Tech. Deliberately plain: this is a port of a
   one-sheet Excel file and it should read like one. Three cards — inputs,
   result, price list — on one row at desk width, stacked on narrow.
   Added 2026-09-11.
   ============================================================================ */
/* Calculator is a narrow input column against the result; Reference is an
   even two-up. Only four fields land on the left now — the spreadsheet's blue
   cells — so the column no longer needs to be as wide as the answer. */
.wsr-grid {
  display: grid;
  grid-template-columns: minmax(260px, 320px) minmax(320px, 1fr);
  gap: 16px;
  align-items: start;
}
.wsr-grid-ref { grid-template-columns: minmax(280px, 1fr) minmax(280px, 1fr); }

/* In-page section switch — this view mirrors the workbook, and the workbook is
   two sheets: the calculation, and the numbers behind it. Not a second nav
   entry; the quoter should land on the calculator every time. */
.wsr-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--color-border);
}
.wsr-tab {
  padding: 8px 16px;
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  color: var(--color-text-muted);
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  cursor: pointer;
}
.wsr-tab:hover { color: var(--color-text); }
.wsr-tab.is-active {
  color: var(--color-primary);
  border-bottom-color: var(--color-primary);
}
.wsr-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
  padding: 16px 18px 18px;
}
.wsr-card h2 {
  margin: 0 0 12px;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* --- stock shape -----------------------------------------------------------
   Round core vs rectangular block (2026-09-18). A segmented pair rather than a
   <select>, because it swaps the diagram and one form row underneath it — the
   quoter should see both states exist without opening anything. */
.wsr-shape {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  margin-bottom: 12px;
  padding: 3px;
  background: var(--color-surface-alt, var(--color-primary-soft));
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}
.wsr-shape-btn {
  padding: 6px 8px;
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  color: var(--color-text-muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.wsr-shape-btn:hover { color: var(--color-text); }
.wsr-shape-btn.is-active {
  color: var(--color-text);
  background: var(--color-surface);
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-sm);
}

/* Splits the two price lists on Reference. */
.wsr-subhead {
  margin: 18px 0 6px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.wsr-subhead:first-of-type { margin-top: 4px; }

/* --- the T / d / L diagram ------------------------------------------------ */
/* Sits above the four inputs so the symbols are defined where they're typed.
   Rebuilt from Sheet1's native Excel shapes — see diagramHtml() for the trace.
   The rect twin (diagramRectHtml) reuses every class below; its box faces are
   plain <path>s, so .wsr-dia-body path / .wsr-dia-slice path already cover
   them and only the round version's <ellipse> rules go unused. */
.wsr-diagram {
  display: block;
  width: 100%;
  height: auto;
  margin: 0 0 4px;
  color: var(--color-text-muted);   /* dimension arrows inherit this */
}
.wsr-dia-body path { fill: var(--color-primary-soft); stroke: var(--color-border-strong); stroke-width: 1.5; }
.wsr-dia-face { fill: #dae5f1; stroke: var(--color-border-strong); stroke-width: 1.5; }
/* The slice is the thing being bought or cut, so it's the one filled shape. */
.wsr-dia-slice path { fill: var(--color-accent); fill-opacity: 0.22; stroke: var(--color-accent); stroke-width: 1.5; }
.wsr-dia-slice ellipse { fill: var(--color-accent); fill-opacity: 0.38; stroke: var(--color-accent); stroke-width: 1.5; }
.wsr-dia-dim path { fill: none; stroke: currentColor; stroke-width: 1; }
.wsr-dia-ext { stroke-dasharray: 2 2; opacity: 0.55; }
.wsr-dia-label text {
  font-size: 13px;
  font-style: italic;
  font-weight: 600;
  fill: var(--color-accent);
}
.wsr-dia-note {
  margin: 0 0 14px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--color-text-muted);
}

/* --- inputs --------------------------------------------------------------- */
.wsr-fields { display: flex; flex-direction: column; gap: 10px; }
.wsr-field { display: flex; flex-direction: column; gap: 3px; }
.wsr-field-label {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 12.5px;
  color: var(--color-text);
}
.wsr-sym {
  font-style: italic;
  font-weight: 600;
  color: var(--color-accent);
}
.wsr-unit { margin-left: auto; font-size: 11.5px; color: var(--color-text-muted); }
/* The spreadsheet's blue fill meant "you are meant to change this" — keep the
   cue rather than the colour, since here every input is editable. */
.wsr-input {
  width: 100%;
  padding: 6px 8px;
  font: inherit;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
  background: var(--color-primary-soft);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
}
.wsr-input:focus {
  outline: none;
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(31, 111, 196, 0.16);
}
.wsr-hint { font-size: 11.5px; line-height: 1.45; color: var(--color-text-muted); }
/* #wsrOverLoad is a .wsr-hint toggled by the `hidden` attribute. That works
   today only because the rule above sets no `display` — add one and the UA's
   [hidden]{display:none} loses on equal specificity and the note becomes
   permanent. Same trap as .qh-pagination and .mach-source-note above; it has
   cost this project a full day once already. */
.wsr-hint[hidden] { display: none !important; }

/* Blue fill = "you are meant to change this", carried over from the sheet. It
   only carries meaning if the Reference constants DON'T wear it — those are
   editable but not part of quoting a job, so they read as plain fields. */
.wsr-pane[data-pane="ref"] .wsr-input {
  background: var(--color-surface);
  border-color: var(--color-border);
}
.wsr-pane[data-pane="ref"] .wsr-input:focus { border-color: var(--color-accent); }
.wsr-reset {
  margin-top: 16px;
  padding: 6px 12px;
  font: inherit;
  font-size: 12.5px;
  color: var(--color-text-muted);
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.wsr-reset:hover { color: var(--color-text); border-color: var(--color-border-strong); }
/* First click of Reset when it would throw edits away (WS-1): says what, asks again. */
.wsr-reset.wsr-reset-armed {
  color: var(--prism-red);
  border-color: var(--prism-red);
  font-weight: 700;
}

/* --- verdict -------------------------------------------------------------- */
.wsr-verdict {
  padding: 12px 14px;
  margin-bottom: 14px;
  border: 1px solid transparent;
  border-left-width: 4px;
  border-radius: var(--radius-sm);
}
.wsr-verdict-head { font-size: 15px; font-weight: 600; }
.wsr-verdict-sub { margin-top: 3px; font-size: 12.5px; color: var(--color-text-muted); }
.wsr-verdict-buy { background: #eef7f1; border-color: var(--color-good); color: #146034; }
.wsr-verdict-make { background: #fdf3e7; border-color: var(--color-warn); color: #8a5210; }
.wsr-verdict-none { background: var(--color-bg); border-color: var(--color-border-strong); color: var(--color-text-muted); }

/* --- result table --------------------------------------------------------- */
.wsr-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.wsr-table th,
.wsr-table td { padding: 5px 0; text-align: left; font-weight: 400; }
.wsr-table td {
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
}
.wsr-table th { color: var(--color-text-muted); }
.wsr-grp th {
  padding-top: 14px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-primary);
  border-bottom: 1px solid var(--color-border);
}
.wsr-grp:first-child th { padding-top: 0; }
/* The break-even IS the deliverable — the sheet highlighted it yellow. */
.wsr-hi th,
.wsr-hi td {
  padding: 8px 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--color-text);
  background: #fdf6dd;
}

/* --- price list ----------------------------------------------------------- */
.wsr-note { margin: 0 0 10px; font-size: 11.5px; line-height: 1.45; color: var(--color-text-muted); }
.wsr-price-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.wsr-price-table th {
  padding-bottom: 5px;
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.wsr-price-table td { padding: 2px 4px 2px 0; }
.wsr-price-input {
  width: 100%;
  padding: 4px 6px;
  font: inherit;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}
.wsr-price-input:focus { outline: none; border-color: var(--color-accent); }
.wsr-del {
  padding: 2px 7px;
  font: inherit;
  font-size: 14px;
  line-height: 1;
  color: var(--color-text-muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.wsr-del:hover { color: #a12; border-color: var(--color-border); }
.wsr-addrow {
  margin-top: 10px;
  padding: 5px 10px;
  font: inherit;
  font-size: 12.5px;
  color: var(--color-accent);
  background: transparent;
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.wsr-addrow:hover { border-color: var(--color-accent); }

@media (max-width: 1100px) {
  .wsr-grid, .wsr-grid-ref { grid-template-columns: 1fr; }
}


/* ============================================================================
   View access (`#settingsViewAccess`) — the grant table read by TAB instead of
   by user. Two panes: the tab list on the left, the roles + people who can open
   the selected one on the right.

   Colour carries one distinction and it is the load-bearing one: a person who
   INHERITS from their role reads neutral, a person on a personal OVERRIDE reads
   amber. An override is immune to every future role change, so it is a state
   somebody needs to notice rather than a detail.
   Added 2026-09-11.
   ============================================================================ */
.va-layout {
  display: grid;
  grid-template-columns: minmax(220px, 300px) minmax(320px, 1fr);
  gap: 18px;
  align-items: start;
}
.va-filter {
  width: 100%;
  padding: 6px 9px;
  margin-bottom: 8px;
  font: inherit;
  font-size: 13px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}
.va-filter:focus { outline: none; border-color: var(--color-accent); }
.va-list {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 460px;
  overflow-y: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}
.va-list li + li { border-top: 1px solid var(--color-border-soft, var(--color-border)); }
.va-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 7px 10px;
  font: inherit;
  font-size: 13px;
  text-align: left;
  color: var(--color-text);
  background: transparent;
  border: 0;
  border-left: 3px solid transparent;
  cursor: pointer;
}
.va-item:hover { background: var(--color-bg); }
.va-item.is-active {
  background: var(--color-primary-soft);
  border-left-color: var(--color-primary);
  font-weight: 600;
}
.va-item-label { flex: 1 1 auto; }
.va-item-meta { display: flex; gap: 4px; flex: 0 0 auto; }

.va-chip {
  display: inline-block;
  padding: 1px 7px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 999px;
}
.va-chip-users { min-width: 26px; text-align: center; }
/* A tab no role grants is the promotion backlog — built, then parked. */
.va-chip-orphan { color: #8a5210; background: #fdf3e7; border-color: var(--color-warn); }
.va-chip-role { color: #146034; background: #eef7f1; border-color: var(--color-good); }
.va-chip-override { color: #8a5210; background: #fdf3e7; border-color: var(--color-warn); }

.va-detail { min-width: 0; }
.va-detail-head h3 { margin: 0 0 2px; font-size: 16px; }
.va-detail-head p { margin: 0 0 14px; font-size: 12.5px; }
.va-sub {
  margin: 18px 0 4px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--color-primary);
}
.va-note { margin: 0 0 10px; font-size: 11.5px; line-height: 1.45; }
.va-empty { font-size: 12.5px; padding: 8px 2px; }

.va-roles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 6px;
}
.va-role {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 9px;
  font-size: 12.5px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.va-role:hover { border-color: var(--color-border-strong); }
.va-role.is-granted { background: var(--color-primary-soft); border-color: var(--color-accent); }
.va-role-label { flex: 1 1 auto; }
.va-role-count {
  flex: 0 0 auto;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}

.va-users { margin-top: 6px; font-size: 12.5px; }
.va-users td { padding: 5px 8px 5px 0; vertical-align: middle; }
.va-users tr + tr td { border-top: 1px solid var(--color-border); }
.va-inactive { opacity: 0.55; }

@media (max-width: 1000px) {
  .va-layout { grid-template-columns: 1fr; }
  .va-list { max-height: 260px; }
}

/* Provenance line on the Quote Builder "JobBoss Says" card. The card mixes a
   live JobBOSS figure (scrap) with a static index (prices + history), and until
   2026-09-15 it named neither — the server shipped indexMeta for exactly this
   and the client discarded it (audit finding 30). `is-stale` fires past 30 days;
   the index was 98 days old when this landed. */
.sqv2-jb-prov { font-size: 11px; margin: 2px 0 0; opacity: 0.85; }
.sqv2-jb-prov.is-stale { color: var(--prism-amber, #b45309); opacity: 1; font-weight: 600; }

/* Cell Uptime staleness line. This view is an unattended wall TV on a 15s poll
   whose fetch used to swallow failures and repaint the previous numbers, with no
   age indicator anywhere in its markup (audit finding 38). Sized for reading at
   a distance, and silent while the board is fresh. */
.cu-fresh { margin: 4px 0 0; font-size: 22px; font-weight: 700; line-height: 1.2; }
.cu-fresh:empty { display: none; }
.cu-fresh.is-warn { color: var(--prism-amber, #b45309); }
.cu-fresh.is-bad { color: var(--prism-red, #b91c1c); }

/* ── Waterjet: one-screen cut settings (2026-10-27) ───────────────────────────── */
.wj-hide { display:none !important; }
.wj-strip { display:flex; flex-wrap:wrap; align-items:center; gap:10px 22px; padding:4px 0 2px; }
.wj-sfield { display:inline-flex; align-items:center; gap:8px; font-size:14px; color:#334155; }
.wj-sfield[hidden] { display:none; }
.wj-sfield .wj-input { width:84px; }
.wj-unit { font-size:12.5px; color:#64748b; }
.wj-strip-help { margin:6px 0 4px 0; }
.wj-seg { display:inline-flex; border:1px solid #cbd5e1; border-radius:8px; overflow:hidden; background:#fff; }
.wj-seg button { border:0; background:transparent; padding:6px 14px; font-size:13.5px; color:#334155; cursor:pointer; }
.wj-seg button + button { border-left:1px solid #cbd5e1; }
.wj-seg button.is-on { background:#0f172a; color:#fff; font-weight:600; }
.wj-more { border-top:1px solid #e2e8f0; margin-top:10px; }
.wj-more > summary { cursor:pointer; list-style:none; padding:10px 2px; font-size:14px; font-weight:600; color:#334155; display:flex; align-items:center; gap:6px; }
.wj-more > summary::-webkit-details-marker { display:none; }
.wj-more > summary::before { content:'▸'; font-size:12px; color:#64748b; transition:transform .12s; }
.wj-more[open] > summary::before { transform:rotate(90deg); }
.wj-more-sum { font-weight:400; font-size:13px; color:#64748b; }
.wj-more-body { padding:2px 0 12px 16px; }
.wj-dlbar { display:flex; flex-wrap:wrap; gap:12px; align-items:stretch; margin-bottom:12px; }
.wj-dlbar[hidden] { display:none; }
.wj-dlbar .wj-release { flex:1 1 260px; margin-bottom:0; padding:10px 14px; }
.wj-dlbar .wj-files { flex:2 1 360px; flex-direction:row; flex-wrap:wrap; align-items:center; gap:10px; }
.wj-dlbar .wj-file-card { flex:1 1 220px; padding:8px 12px; }

/* Tooling print viewer (zoom + download) */
.tc-zoomable { cursor: zoom-in; }
.tc-dp-lbl a + a { margin-left: 10px; }
.tc-pv { position: fixed; inset: 0; z-index: 10000; background: rgba(10,14,22,.92); display: flex; flex-direction: column; }
.tc-pv-bar { display: flex; align-items: center; gap: 10px; padding: 8px 14px; background: #0f172a; color: #fff; }
.tc-pv-title { flex: 1; font-size: 14px; }
.tc-pv-zoomctl { display: inline-flex; align-items: center; gap: 6px; }
.tc-pv-zoomctl button, .tc-pv-btn { background: #1e293b; color: #fff; border: 1px solid #334155; border-radius: 6px; padding: 5px 11px; font-size: 13px; cursor: pointer; text-decoration: none; }
.tc-pv-zoomctl button:hover, .tc-pv-btn:hover { background: #334155; }
.tc-pv-pct { min-width: 44px; text-align: center; font-size: 12px; font-family: 'Fira Code', ui-monospace, monospace; }
.tc-pv-stage { flex: 1; position: relative; overflow: hidden; display: flex; align-items: center; justify-content: center; cursor: grab; touch-action: none; }
.tc-pv-stage.dragging { cursor: grabbing; }
.tc-pv-frame { width: 100%; height: 100%; border: 0; background: #fff; }
.tc-pv-img { max-width: 100%; max-height: 100%; background: #fff; transform-origin: center center; user-select: none; }
.tc-pv-note { color: #fbbf24; font-size: 12px; }

/* ---- Scrap % over time (Scrap tab) ---- */
.scrap-track .sd-card-head { flex-wrap: wrap; gap: 8px 12px; }
.scrap-track-ranges { display: inline-flex; gap: 4px; margin-left: auto; flex-wrap: wrap; }
.scrap-track-btn { border: 1px solid var(--line, #d7dde6); background: var(--panel, #fff); color: var(--ink, #1f2937); border-radius: 999px; padding: 4px 12px; font: inherit; font-size: 12.5px; cursor: pointer; }
.scrap-track-btn:hover { border-color: #1f4e8c; }
.scrap-track-btn.active { background: #1f4e8c; border-color: #1f4e8c; color: #fff; font-weight: 600; }
.scrap-track-wrap { position: relative; }
.scrap-track-chart { width: 100%; height: auto; display: block; }
.scrap-track-chart .st-grid { stroke: var(--line, #e5e9f0); stroke-width: 1; }
.scrap-track-chart .st-axis { fill: var(--muted, #6b7280); font-size: 11px; }
.scrap-track-chart .st-bar { fill: #9C0006; opacity: .82; }
.scrap-track-chart .st-bar-last { opacity: 1; }
.scrap-track-chart .st-bar-partial { opacity: .5; }
.scrap-track-chart .st-bar-hover { opacity: 1; fill: #1f4e8c; }
.scrap-track-chart .st-last { fill: #9C0006; font-size: 13px; font-weight: 700; }
.scrap-track-chart .st-val { fill: var(--ink, #1f2937); font-size: 10.5px; }
.scrap-track-chart .st-month { fill: var(--muted, #6b7280); font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; }
.scrap-track-chart .st-month-rule { stroke: var(--line, #d7dde6); stroke-width: 1; stroke-dasharray: 2 3; }
.scrap-track-tip { position: absolute; top: 6px; transform: translateX(-50%); background: #1f2937; color: #fff; border-radius: 6px; padding: 6px 10px; font-size: 12px; line-height: 1.4; pointer-events: none; white-space: nowrap; }
.scrap-track-tip .muted { color: #cbd5e1; }
.scrap-track-note { font-size: 12px; margin-top: 6px; }
