/* ── Safe-area + curved-corner primitives (2026-08-27) ──────────────────────
   Declared here because ux-polish.css loads FIRST and unconditionally.
   css/mobile.css — where all 41 existing env() rules live — is gated in
   index.html to `media="(max-width: 768px)"`, and every modern iPhone is
   852-956 CSS px wide in LANDSCAPE. So rotating the phone drops the entire
   phone stylesheet, including every safe-area rule, in precisely the
   orientation where safe-area-inset-left/right becomes 44-59px and starts to
   matter. These tokens are available at every width, so an edge-anchored rule
   can be corrected in its BASE declaration instead of only in a phone override.

   --corner-gutter is geometry, not taste. A screen with corner radius R clips
   anything at height h above the bottom edge unless it is inset
   R - sqrt(R^2 - (R-h)^2). At R~55 (modern iPhone) and h=18, that is ~14px;
   15px clears it with margin. Cole, 2026-08-27: "because the edges of my
   iPhone screen are curved, it's cutting off the corners of the message and
   the send button."
   viewport-fit=cover is set on index.html:5 and portal.html:5, so these
   env() values resolve to real numbers rather than 0. */
:root {
  --sa-t: env(safe-area-inset-top, 0px);
  --sa-b: env(safe-area-inset-bottom, 0px);
  --sa-l: env(safe-area-inset-left, 0px);
  --sa-r: env(safe-area-inset-right, 0px);
  --corner-gutter: 15px;
  --edge-l: max(var(--corner-gutter), var(--sa-l));
  --edge-r: max(var(--corner-gutter), var(--sa-r));
  --edge-b: max(18px, calc(10px + var(--sa-b)));
}

/* ═══════════════════════════════════════════════════════
   Interior Moderna — UX Polish Layer
   Premium, architectural, gallery-driven aesthetic
   ═══════════════════════════════════════════════════════ */

/* ── Enhanced Color Palette ── */
:root {
  --sidebar-bg: #fafafa;
  --sidebar-hover: rgba(166, 124, 82, 0.10);
  --sidebar-active-border: var(--accent);
  --transition-smooth: cubic-bezier(0.4, 0, 0.2, 1);
  --shadow-sm: 0 1px 3px rgba(0,0,0,0.04);
  --shadow-md: 0 4px 12px rgba(0,0,0,0.06);
  --shadow-lg: 0 8px 32px rgba(0,0,0,0.1);
  --shadow-xl: 0 16px 48px rgba(0,0,0,0.15);
}

/* ── Wide Viewport Constraint ── */
#mainContent > div {
  max-width: 1600px;
  margin-left: auto;
  margin-right: auto;
}

/* ── Typography Refinements ── */
body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

.page-title {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.5px;
  line-height: 1.2;
}

.page-subtitle {
  font-size: 13px;
  color: var(--text-muted);
  margin-top: 4px;
  letter-spacing: 0.01em;
}

/* ── Enhanced Header ── */
.header {
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  background: rgba(255, 255, 255, 0.92);
  box-shadow: var(--shadow-sm);
}

.logo {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--text);
}

.logo-sub {
  font-size: 10px;
  color: var(--text-dim);
  font-weight: 400;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  margin-top: 1px;
}

/* ── Enhanced Sidebar ── */
.sidebar {
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border);
  padding: 12px 0 24px;
  transition: width 0.3s var(--transition-smooth);
}

/* Collapsible sections */
.nav-section {
  margin-bottom: 4px;
}

.nav-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 6px 20px;
  cursor: pointer;
  user-select: none;
  border-radius: 0;
  transition: background 0.15s;
}

.nav-section-header:hover {
  background: var(--sidebar-hover);
}

.nav-section-title {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 1.4px;
  color: var(--text-dim);
  font-weight: 600;
  padding: 0;
  margin-bottom: 0;
  cursor: pointer;
}

.nav-section-arrow {
  width: 14px;
  height: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-dim);
  transition: transform 0.25s var(--transition-smooth);
  font-size: 8px;
  flex-shrink: 0;
  transform: rotate(90deg);
}

.nav-section-header.collapsed .nav-section-arrow {
  transform: rotate(0deg);
}

.nav-section-items {
  overflow: hidden;
  transition: max-height 0.3s var(--transition-smooth), opacity 0.2s ease;
  max-height: 800px;
  opacity: 1;
  padding: 0 12px;
}

.nav-section-items.collapsed {
  max-height: 0;
  opacity: 0;
  padding-top: 0;
  padding-bottom: 0;
}

/* Enhanced nav items */
.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 12px;
  border-radius: 6px;
  cursor: pointer;
  color: var(--text-muted);
  transition: background-color 0.15s var(--transition-smooth), border-color 0.15s var(--transition-smooth), color 0.15s var(--transition-smooth), box-shadow 0.15s var(--transition-smooth), transform 0.15s var(--transition-smooth), opacity 0.15s var(--transition-smooth);
  font-size: 13px;
  position: relative;
  margin: 1px 0;
}

.nav-item:hover {
  background: var(--sidebar-hover);
  color: var(--text);
}

.nav-item.active {
  background: var(--accent-dim);
  color: var(--text);
  font-weight: 500;
}

.nav-item.active::before {
  content: '';
  position: absolute;
  left: -12px;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 60%;
  background: var(--accent);
  border-radius: 0 2px 2px 0;
}

.nav-item .icon {
  width: 20px;
  text-align: center;
  font-size: 14px;
  flex-shrink: 0;
  opacity: 0.8;
}

.nav-item.active .icon {
  opacity: 1;
}

.nav-item .badge {
  margin-left: auto;
  background: var(--red-dim);
  color: var(--red);
  font-size: 10px;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 10px;
  min-width: 18px;
  text-align: center;
}

/* Pinned section styling */
.nav-section-pinned {
  border-bottom: 1px solid var(--border);
  padding-bottom: 8px;
  margin-bottom: 8px;
}

.nav-section-pinned .nav-section-title {
  color: var(--accent);
}

/* ── Enhanced Card Styling ── */
.stat-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 18px;
  transition: border-color 0.2s, box-shadow 0.2s;
}

.stat-card:hover {
  border-color: var(--border-hover);
  box-shadow: var(--shadow-sm);
}

.stat-label {
  font-size: 10px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.8px;
  margin-bottom: 8px;
  font-weight: 600;
}

.stat-value {
  font-size: 28px;
  font-weight: 700;
  font-family: var(--font-mono);
  letter-spacing: -0.5px;
  line-height: 1;
}

/* ── View Transitions ── */
.main {
  position: relative;
}

/* viewFadeIn lives in css/modern-theme.css (the later, more specific copy
   always won the cascade; this one was a stale duplicate — 2026-09-03). */

/* ── Loading Skeleton States ── */
.skeleton {
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 50%, var(--surface-2) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: var(--radius-sm);
}

.skeleton-text {
  height: 14px;
  margin-bottom: 8px;
  width: 80%;
}

.skeleton-text.short {
  width: 40%;
}

.skeleton-text.medium {
  width: 60%;
}

.skeleton-card {
  height: 80px;
  border-radius: var(--radius);
}

.skeleton-row {
  display: flex;
  gap: 12px;
  margin-bottom: 12px;
}

.skeleton-row .skeleton {
  flex: 1;
  height: 80px;
}

@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

/* ── Enhanced Loading Spinner ── */
.loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 60px 0;
  color: var(--text-dim);
  font-size: 13px;
  letter-spacing: 0.3px;
}

.spinner {
  width: 24px;
  height: 24px;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* ── Table Enhancements ── */
table {
  border-collapse: separate;
  border-spacing: 0;
}

/* 2026-09-03 UX audit round 4: dropped backdrop-filter here — `th` already
   carries an opaque background (modern-theme.css:1116 / :2679 / :5838
   `var(--surface-2)`), so every header cell of every table paid for a blur
   layer the compositor re-sampled on each scroll frame while painting nothing
   visible. Removes scroll jank on wide tables (orders, cost chain, price menu).
   Same removal the 2026-09-01 mega-audit made in css/messages.css:2518 / :5043
   / :7702 / :7791. position/top/z-index stay (duplicate of
   modern-theme.css:5838, harmless). */
table th {
  position: sticky;
  top: 0;
  z-index: var(--z-raised);
}

/* ── Command Palette Styles ── */
.cp-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0);
  z-index: var(--z-overlay);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: 12vh;
  transition: background 0.15s;
}

.cp-overlay.cp-visible {
  background: rgba(0, 0, 0, 0.5);
}

.cp-modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  width: 92%;
  max-width: 580px;
  box-shadow: var(--shadow-xl);
  overflow: hidden;
  transform: scale(0.98) translateY(-8px);
  opacity: 0;
  transition: transform 0.2s var(--transition-smooth), opacity 0.15s;
}

.cp-visible .cp-modal {
  transform: scale(1) translateY(0);
  opacity: 1;
}

.cp-input-wrap {
  display: flex;
  align-items: center;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  gap: 12px;
}

.cp-search-icon {
  color: var(--text-dim);
  flex-shrink: 0;
}

.cp-input {
  flex: 1;
  background: none;
  border: none;
  color: var(--text);
  font-size: 15px;
  font-family: var(--font);
  outline: none;
  line-height: 1.4;
}

.cp-input:focus {
  box-shadow: 0 0 0 2px var(--accent);
  border-radius: 2px;
}

.cp-input::placeholder {
  color: var(--text-dim);
}

.cp-kbd {
  font-size: 10px;
  color: var(--text-dim);
  background: var(--surface-3);
  padding: 2px 6px;
  border-radius: 4px;
  font-family: var(--font-mono);
  border: 1px solid var(--border);
}

.cp-results {
  max-height: 380px;
  overflow-y: auto;
  padding: 4px 0;
}

.cp-category {
  padding: 10px 18px 4px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-dim);
  font-weight: 600;
}

.cp-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 18px;
  cursor: pointer;
  transition: background 0.08s;
  border-radius: 0;
}

.cp-item:hover,
.cp-item.cp-focused {
  background: var(--surface-2);
}

.cp-item.cp-focused {
  background: var(--accent-dim);
}

.cp-icon {
  width: 30px;
  height: 30px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  flex-shrink: 0;
}

.cp-icon-nav {
  background: var(--surface-3);
  color: var(--text-muted);
}

.cp-icon-action {
  background: var(--blue-dim);
  color: var(--blue);
}

.cp-icon-order {
  background: var(--green-dim);
  color: var(--green);
}

.cp-icon-customer {
  background: var(--blue-dim);
  color: var(--blue);
}

.cp-icon-product {
  background: var(--accent-dim);
  color: var(--text);
}

.cp-text {
  flex: 1;
  min-width: 0;
}

.cp-title {
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cp-sub {
  font-size: 11px;
  color: var(--text-dim);
  margin-top: 1px;
}

.cp-pin-btn {
  font-size: 14px;
  color: var(--text-dim);
  cursor: pointer;
  padding: 2px 4px;
  border-radius: 4px;
  transition: color 0.15s, transform 0.15s;
  flex-shrink: 0;
  opacity: 0;
}

.cp-item:hover .cp-pin-btn,
.cp-item.cp-focused .cp-pin-btn {
  opacity: 1;
}

.cp-pin-btn:hover {
  color: var(--accent);
  transform: scale(1.15);
}

.cp-pin-btn.cp-pinned {
  color: var(--accent);
  opacity: 1;
}

.cp-enter {
  font-size: 10px;
  color: var(--text-dim);
  padding: 1px 6px;
  background: var(--surface-3);
  border-radius: 4px;
  font-family: var(--font-mono);
  flex-shrink: 0;
  opacity: 0;
}

.cp-item:hover .cp-enter,
.cp-item.cp-focused .cp-enter {
  opacity: 1;
}

.cp-empty {
  padding: 32px 18px;
  text-align: center;
  color: var(--text-dim);
  font-size: 13px;
}

.cp-loading {
  padding: 16px;
  display: flex;
  justify-content: center;
}

.cp-footer {
  padding: 8px 18px;
  border-top: 1px solid var(--border);
  font-size: 10px;
  color: var(--text-dim);
  display: flex;
  gap: 16px;
  background: var(--surface-2);
}

.cp-footer kbd {
  display: inline-block;
  padding: 1px 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 9px;
  margin: 0 2px;
}

/* ── Enhanced Mobile Responsive ── */
/* Drawer width + elevation belong to the ≤768px slide-in drawer only. At
   769–900 the sidebar is still an inline grid rail (192px column), so a fixed
   280px width overhangs the main view — moved to the ≤768 block below. */
@media (max-width: 768px) {
  .sidebar {
    width: 280px;
    box-shadow: 4px 0 32px rgba(0,0,0,0.3);
  }
}
@media (max-width: 900px) {
  .sidebar {
    padding-top: 16px;
  }

  .main {
    padding: 16px;
    padding-bottom: 80px;
  }

  .page-title {
    font-size: 18px;
  }

  .stat-card {
    padding: 14px;
  }

  .stat-value {
    font-size: 22px;
  }

  /* Tables become horizontally scrollable */
  .table-container,
  .main table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* Touch-friendly buttons */
  .refresh-btn,
  .bulk-btn,
  .btn-sm {
    min-height: 44px;
    min-width: 44px;
  }

  .cp-modal {
    width: 96%;
    max-width: none;
    margin: 0 8px;
  }

  .cp-item {
    padding: 10px 16px;
  }

  /* Page header on mobile: row with wrap. Stays inline when actions fit
     (the common case — Refresh, Save, small icon buttons), only drops to
     a second line when the action area genuinely won't fit. Prior behavior
     (column-always) wasted ~50px of vertical space on every mobile screen. */
  .page-header {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    row-gap: 8px;
  }
  .page-header > :first-child { min-width: 0; flex: 1 1 60%; }
  .page-header > :not(:first-child) { flex: 0 0 auto; }
}

@media (max-width: 480px) {
  .main {
    padding: 12px;
    padding-bottom: 72px;
  }

  .page-title {
    font-size: 16px;
  }

  .cp-overlay {
    padding-top: 4vh;
  }

  .cp-results {
    max-height: 50vh;
  }

  .cp-footer {
    flex-wrap: wrap;
    gap: 8px;
  }

  /* Stat cards on smallest screens: compact grid, NOT one-per-row.
     (2026-07-16 mobile-density pass: the old `1fr !important` here was the
     blanket escape hatch that stacked every stat band one tile per row on
     phones, defeating the denser mobile.css rules. Density layer in
     css/mobile.css owns the real treatment; this is just a same-intent
     fallback for markup outside #mainContent.) */
  .stats-row {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 6px;
  }

  .stat-card {
    padding: 8px 10px;
  }
}

/* ── Warehouse Mobile (375px phones, glove-friendly) ── */
@media (max-width: 430px) {
  /* Larger touch targets for gloved hands */
  button, .btn, .btn-sm, .btn-xs,
  input[type="checkbox"], input[type="radio"],
  select, .tab-btn, .nav-tab {
    min-height: 44px;
    min-width: 44px;
  }

  /* Scan input — big and easy to read */
  .scan-input {
    font-size: 20px !important;
    padding: 14px 16px !important;
    min-height: 56px !important;
  }

  /* Modals: shrink max-height so keyboard doesn't cover inputs */
  .journey-modal,
  .modal-content,
  [class*="modal-"] {
    max-height: 65dvh;
    max-height: 65vh; /* fallback for browsers without dvh */
  }

  /* Bulk action bar: full-width strip at bottom instead of floating pill */
  .bulk-action-bar {
    left: 12px !important;
    right: 12px !important;
    bottom: calc(64px + 12px + env(safe-area-inset-bottom, 0px)) !important;
    transform: none !important;
    width: auto !important;
    box-sizing: border-box !important;
    border-radius: 12px !important;
    border-bottom: none !important;
    padding: 12px 16px !important;
    justify-content: space-between !important;
    flex-wrap: wrap !important;
    gap: 8px !important;
  }

  .bulk-btn {
    min-height: 44px !important;
    padding: 10px 16px !important;
    font-size: 13px !important;
  }

  /* Warehouse pick-list table: hide non-critical columns */
  /* Table cells: more breathing room for touch */
  /* Page header at very-small widths: row with wrap. Action buttons
     (Refresh, Save, small icon buttons) sit inline and only drop when
     the action area genuinely won't fit. */
  .page-header {
    flex-direction: row !important;
    flex-wrap: wrap !important;
    align-items: center !important;
    gap: 8px !important;
    row-gap: 6px !important;
  }
  .page-header > :first-child { min-width: 0 !important; flex: 1 1 60% !important; }
  .page-header > :not(:first-child) { flex: 0 0 auto !important; }

  /* Bigger close/action buttons in modals */
  .journey-close, [class*="modal-close"], .close-btn {
    min-width: 44px;
    min-height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}

/* ── Smooth scrollbar in sidebar ── */
.sidebar::-webkit-scrollbar {
  width: 4px;
}

.sidebar::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 2px;
}

.sidebar::-webkit-scrollbar-thumb:hover {
  background: var(--border-hover);
}

/* ── Section divider line between nav groups ── */
.nav-section + .nav-section {
  border-top: 1px solid var(--border);
  padding-top: 4px;
  margin-top: 4px;
}

/* ── Empty state refinement ── */
.empty-state {
  text-align: center;
  padding: 60px 24px;
  color: var(--text-dim);
}

.empty-state .icon {
  font-size: 40px;
  margin-bottom: 12px;
  opacity: 0.5;
}

.empty-state p {
  font-size: 14px;
  line-height: 1.6;
}

/* ── Focus visible for accessibility ── */
.nav-item:focus-visible,
.cp-item:focus-visible,
.refresh-btn:focus-visible,
.btn:focus-visible,
.action-btn:focus-visible,
.tab-btn:focus-visible,
.tab:focus-visible,
.filter-btn:focus-visible,
.feed-filter-btn:focus-visible,
.segment-chip:focus-visible,
.date-preset-btn:focus-visible,
.bulk-btn:focus-visible,
.export-btn:focus-visible,
.note-save-btn:focus-visible,
.scan-mode-btn:focus-visible,
.notification-bell-btn:focus-visible,
.toggle-btn:focus-visible,
.pick-list-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

/* ── Subtle hover lift for interactive cards ── */
.stat-card,
.wh-grid-cell {
  transition: border-color 0.2s, box-shadow 0.2s, transform 0.15s;
}

.stat-card:hover {
  transform: translateY(-1px);
}

/* ═══════════════════════════════════════════════════════════════════════════ */
/* ── Deep Lookup Panel ──────────────────────────────────────────────────── */
/* ═══════════════════════════════════════════════════════════════════════════ */

/* Lookup badge in command palette results */
.cp-item-lookup { border-left: 3px solid var(--accent); }
.cp-icon-lookup { color: var(--accent); font-size: 1.15rem; }
.cp-lookup-badge {
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent);
  background: rgba(var(--accent-rgb, 99,102,241), 0.12);
  padding: 2px 6px;
  border-radius: 4px;
  margin-left: auto;
  flex-shrink: 0;
}

/* Overlay */
.dl-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0);
  z-index: calc(var(--z-overlay) + 10); /* was 210 — deep-lookup panel above command-palette base overlay */
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s;
}
.dl-overlay.dl-visible { background: rgba(0, 0, 0, 0.55); }

/* Panel */
.dl-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  width: 96%;
  max-width: 780px;
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 25px 60px rgba(0,0,0,0.35);
  transform: scale(0.97) translateY(-12px);
  opacity: 0;
  transition: transform 0.2s ease-out, opacity 0.15s;
}
.dl-visible .dl-panel {
  transform: scale(1) translateY(0);
  opacity: 1;
}

.dl-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px 12px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.dl-panel-title {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--text);
}
.dl-close-btn {
  background: none;
  border: none;
  font-size: 1.4rem;
  cursor: pointer;
  color: var(--text-dim);
  padding: 4px 8px;
  border-radius: 6px;
}
.dl-close-btn {
  transition: background 0.15s, color 0.15s;
}
.dl-close-btn:hover { background: var(--hover); color: var(--text); }

.dl-panel-body {
  overflow-y: auto;
  padding: 16px 20px 24px;
  flex: 1;
  min-height: 0;
}

/* Loading / Error states */
.dl-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 40px 0;
  color: var(--text-dim);
}
.dl-error {
  text-align: center;
  padding: 40px 20px;
  color: var(--text-dim);
}
.dl-error p:first-child { font-size: 1.1rem; font-weight: 600; color: var(--text); margin-bottom: 8px; }
.dl-error-detail { font-size: 0.85rem; opacity: 0.7; }

/* Summary cards row */
.dl-summary-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  margin-bottom: 16px;
}
.dl-card {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 14px;
}
.dl-card-label { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-dim); margin-bottom: 4px; }
.dl-card-value { font-size: 1rem; font-weight: 600; color: var(--text); }
.dl-card-link { cursor: pointer; color: var(--accent); }
.dl-card-link:hover { text-decoration: underline; }

/* Note and tags */
.dl-note {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 0.85rem;
  margin-bottom: 12px;
  color: var(--text-dim);
}
.dl-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 12px; }
.dl-tag {
  font-size: 0.7rem;
  padding: 2px 8px;
  border-radius: 4px;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text-dim);
}

/* Badges */
.dl-badge {
  display: inline-block;
  font-size: 0.7rem;
  padding: 2px 8px;
  border-radius: 4px;
  font-weight: 500;
  text-transform: capitalize;
  white-space: nowrap;
}
/* Collapsible sections */
.dl-section { margin-bottom: 8px; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.dl-section-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  cursor: pointer;
  background: var(--bg);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text);
  user-select: none;
  transition: background 0.15s;
}
.dl-section-header:hover { background: var(--hover); }
.dl-chevron { font-size: 0.7rem; color: var(--text-dim); width: 12px; text-align: center; }
.dl-section-title { flex: 1; }
.dl-section-count { font-weight: 400; color: var(--text-dim); font-size: 0.8rem; }
.dl-section-body { padding: 12px 14px; }
.dl-empty { font-size: 0.85rem; color: var(--text-dim); font-style: italic; padding: 8px 0; }

/* Key-Value grid */
.dl-kv-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 6px 16px;
}
.dl-kv { display: flex; gap: 8px; font-size: 0.85rem; padding: 2px 0; }
.dl-k { color: var(--text-dim); min-width: 100px; flex-shrink: 0; }
.dl-v { color: var(--text); font-weight: 500; word-break: break-word; }

/* Tables */
.dl-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
.dl-table th {
  text-align: left;
  padding: 6px 10px;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  border-bottom: 1px solid var(--border);
}
.dl-table td {
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
}
.dl-table tr:last-child td { border-bottom: none; }
.dl-cell-link { cursor: pointer; color: var(--accent); }
.dl-cell-link:hover { text-decoration: underline; }

/* Alerts */
.dl-alert {
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
  margin-bottom: 6px;
}
.dl-alert-warn { background: rgba(234,179,8,0.1); color: var(--yellow); border: 1px solid rgba(234,179,8,0.2); }
.dl-alert-danger { background: rgba(239,68,68,0.1); color: var(--red); border: 1px solid rgba(239,68,68,0.2); }

/* Risk row */
.dl-risk-row { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }

/* AI Summary */
.dl-ai-summary {
  margin-top: 10px;
  padding: 10px 12px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.85rem;
  color: var(--text-dim);
  line-height: 1.5;
}

/* Order rows (clickable) */
.dl-order-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: background 0.15s;
}
.dl-order-row:hover { background: var(--hover); }
.dl-order-row:last-child { border-bottom: none; }
.dl-order-num { font-weight: 600; color: var(--accent); min-width: 70px; }
.dl-order-items { width: 100%; font-size: 0.78rem; color: var(--text-dim); margin-top: 2px; }

/* Ticket cards */
.dl-ticket-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.85rem;
}
.dl-ticket-card:last-child { border-bottom: none; }
.dl-ticket-link { color: var(--accent); font-weight: 500; text-decoration: none; }
.dl-ticket-link:hover { text-decoration: underline; }
.dl-ticket-subj { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dl-ticket-date { color: var(--text-dim); font-size: 0.78rem; }

/* Refund / Return cards */
.dl-refund-card, .dl-return-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.85rem;
}
.dl-refund-card:last-child, .dl-return-card:last-child { border-bottom: none; }
.dl-refund-note { width: 100%; font-size: 0.78rem; color: var(--text-dim); font-style: italic; }

/* Gmail cards */
.dl-gmail-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
  font-size: 0.85rem;
}
.dl-gmail-card:last-child { border-bottom: none; }
.dl-gmail-subj { font-weight: 500; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dl-gmail-excerpt { width: 100%; font-size: 0.78rem; color: var(--text-dim); margin-top: 2px; max-height: 40px; overflow: hidden; }

/* Product hero */
.dl-product-hero {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  margin-bottom: 16px;
}
.dl-product-img {
  width: 80px;
  height: 80px;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--border);
  flex-shrink: 0;
}
.dl-product-title { font-size: 1rem; font-weight: 600; color: var(--text); margin-bottom: 4px; }
.dl-product-meta { font-size: 0.82rem; color: var(--text-dim); }

/* Issues list */
.dl-issues-list { margin-top: 8px; font-size: 0.85rem; }
.dl-issues-list ul { margin: 4px 0 0 16px; padding: 0; }
.dl-issues-list li { margin-bottom: 2px; color: var(--text-dim); }

/* Fulfillment card */
.dl-fulfillment-card {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px 16px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
}
.dl-fulfillment-card:last-child { border-bottom: none; }

/* Timeline */
.dl-timeline { position: relative; padding-left: 20px; }
.dl-tl-item {
  position: relative;
  padding: 6px 0 12px 16px;
  border-left: 2px solid var(--border);
}
.dl-tl-item:last-child { border-left-color: transparent; }
.dl-tl-dot {
  position: absolute;
  left: -7px;
  top: 10px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--border);
  border: 2px solid var(--surface);
}
.dl-tl-green .dl-tl-dot { background: var(--green); }
.dl-tl-blue .dl-tl-dot { background: var(--blue); }
.dl-tl-red .dl-tl-dot { background: var(--red); }
.dl-tl-orange .dl-tl-dot { background: var(--orange); }
.dl-tl-label { font-size: 0.85rem; font-weight: 600; color: var(--text); }
.dl-tl-detail { font-size: 0.8rem; color: var(--text-dim); margin-top: 2px; }
.dl-tl-date { font-size: 0.72rem; color: var(--text-dim); opacity: 0.7; margin-top: 2px; }

/* Mobile responsive */
@media (max-width: 640px) {
  .dl-panel {
    width: 100%;
    max-width: 100%;
    max-height: 100vh;
    border-radius: 0;
  }
  .dl-summary-row { grid-template-columns: 1fr 1fr; }
  .dl-kv-grid { grid-template-columns: 1fr; }
  .dl-product-hero { flex-direction: column; }
}

/* ═══════════════════════════════════════════════════════
   Warehouse Mobile Fixes — audit-mobile-warehouse.md
   ═══════════════════════════════════════════════════════ */

/* C1: Receiving view — stack columns on mobile */
@media (max-width: 768px) {
  .location-layout {
    grid-template-columns: 1fr;
  }
  .shelf-list {
    max-height: 50vh;
  }
}

/* C2: Pick bulk action bar — remove sidebar offset on mobile */
@media (max-width: 768px) {
  .pick-bulk-bar {
    left: 0 !important;
    right: 0 !important;
    border-radius: 0 !important;
    padding: 10px 16px;
  }
}

/* C3: Table horizontal scroll — force min-width to trigger scroll */
@media (max-width: 768px) {
  .table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .table-scroll table {
    min-width: 620px;
  }
}

/* H1: Nav items — enforce 44px touch targets.
   Note: `display` deliberately omitted. The base `.nav-item` rule already
   declares `display: flex`, and inline `display: none` (set by
   applySidebarPermissions for views the role can't access) must win. A
   `display: flex !important` here previously beat the inline rule, leaking
   admin-only items into the warehouse-role mobile nav. */
@media (max-width: 768px) {
  .nav-item {
    padding: 12px 16px !important;
    min-height: 44px !important;
    align-items: center !important;
  }
}

/* H2: Pick list card action buttons — 3-up horizontal at 44px touch height
   on mobile. Was: flex-direction: column (3 stacked rows = 168px tall card
   actions). Each pick-list card was ~344px tall, only 1-2 fit per scroll
   page. Going horizontal halves the action row to ~52px while keeping
   44px touch targets. */
@media (max-width: 768px) {
  .pick-list-card-actions {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 6px;
  }
  .pick-list-card-actions button {
    min-height: 44px;
    font-size: 13px;
    padding: 8px 10px;
    flex: 1 1 0;
    min-width: 0;
  }
}

/* H3: Pick list grid — single column on narrow screens */
@media (max-width: 480px) {
  .pick-list-grid {
    grid-template-columns: 1fr;
  }
}

/* M1: Pick tab group — scroll instead of overflow/clip */
@media (max-width: 768px) {
  .pick-tab-group {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    flex-wrap: nowrap;
  }
  .pick-tab {
    white-space: nowrap;
    flex-shrink: 0;
  }
}

/* M8: Warehouse grid cells — touch feedback */
.wh-grid-cell {
  cursor: pointer;
  -webkit-tap-highlight-color: rgba(166, 124, 82, 0.2);
}
.wh-grid-cell:active {
  background: rgba(166, 124, 82, 0.12);
}

/* ═══════════════════════════════════════════════════════
   Enhanced Mobile & Tablet Responsiveness
   Added 2026-04-03 — U1 UX Sprint
   ═══════════════════════════════════════════════════════ */

/* ── Tablet (1024px) ── */
@media (max-width: 1024px) {
  /* Notification panel narrower on tablet */
  .jarvis-notification-panel { width: 320px !important; }

  /* Morning brief grid adjustments */
  .brief-grid { grid-template-columns: 1fr !important; }

  /* Approval queue: stat cards 2-per-row */
}

/* ── Mobile (768px) ── */
@media (max-width: 768px) {
  /* Notification panel near-full-width */
  .jarvis-notification-panel {
    position: fixed !important;
    top: 56px !important;
    left: 8px !important;
    right: 8px !important;
    width: auto !important;
    max-height: 70vh !important;
    border-radius: var(--radius) !important;
    box-shadow: var(--shadow-xl) !important;
  }

  /* Morning brief compact */
  .brief-grid { grid-template-columns: 1fr !important; gap: 12px !important; }
  .brief-metric-value { font-size: 20px !important; }

  /* Approval queue mobile */
  .aq-category-tabs { overflow-x: auto; -webkit-overflow-scrolling: touch; flex-wrap: nowrap !important; }
  .aq-category-tabs > * { white-space: nowrap; flex-shrink: 0; }
  .aq-filter-bar { flex-direction: column !important; }
  .aq-table { min-width: 640px; }

  /* Support inbox: stack action buttons */
  .hub-fu-row { flex-direction: column !important; }
  .hub-fu-row .hub-fu-actions { align-self: flex-end; }

  /* Customer intelligence: single column cards */

  /* Batch action bar responsive */
  #aqBatchBar { left: 0 !important; padding: 10px 12px !important; flex-direction: column !important; gap: 8px !important; }

  /* Jarvis insight cards: full width */
  .sup-jarvis-insight { margin-left: 0 !important; margin-right: 0 !important; }

  /* Data tables: scroll wrapper */
  .data-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .data-table-wrap table { min-width: 600px; }
}

/* ── Small Mobile (480px) ── */
@media (max-width: 480px) {
  /* Notification panel full width */
  .jarvis-notification-panel { left: 4px !important; right: 4px !important; }

  /* Single column everything */

  /* Support inbox buttons full width */
  .hub-fu-actions { width: 100%; }
  .hub-fu-actions button { width: 100%; }

  /* Batch bar buttons stack */
  #aqBatchBar > div:last-child { flex-direction: column !important; width: 100%; }
}

/* ═══════════════════════════════════════════════════════
   Round 4 — UX Polish Additions
   ═══════════════════════════════════════════════════════ */

/* ── Pressed / Active States ── */
.btn:active,
.action-btn:active,
.tab-btn:active,
.tab:active,
.filter-btn:active,
.feed-filter-btn:active,
.segment-chip:active,
.date-preset-btn:active,
.bulk-btn:active,
.export-btn:active,
.note-save-btn:active,
.scan-mode-btn:active,
.pick-list-card:active,
.toggle-btn:active,
.notification-bell-btn:active {
  transform: scale(0.97);
  opacity: 0.9;
}

.nav-item:active,
.cp-item:active {
  transform: scale(0.99);
  background: var(--sidebar-hover);
}

/* ── Table Row Hover (light mode fix) ── */
tr:hover td {
  background: var(--hover, rgba(0, 0, 0, 0.03));
}

/* Global smooth scroll: declared once, in css/modern-theme.css (beside its
   reduced-motion override). The copy that lived here was a duplicate. */

/* ── Text Selection Styling ── */
::selection {
  background: rgba(166, 124, 82, 0.25);
  color: var(--text);
}

/* ── Panel/Modal Scrollbar Styling ── */
.dl-panel-body::-webkit-scrollbar,
.cp-results::-webkit-scrollbar,
.side-panel::-webkit-scrollbar,
.notification-panel::-webkit-scrollbar,
.jarvis-global-panel::-webkit-scrollbar {
  width: 4px;
}

.dl-panel-body::-webkit-scrollbar-thumb,
.cp-results::-webkit-scrollbar-thumb,
.side-panel::-webkit-scrollbar-thumb,
.notification-panel::-webkit-scrollbar-thumb,
.jarvis-global-panel::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 2px;
}

.dl-panel-body::-webkit-scrollbar-thumb:hover,
.cp-results::-webkit-scrollbar-thumb:hover,
.side-panel::-webkit-scrollbar-thumb:hover,
.notification-panel::-webkit-scrollbar-thumb:hover,
.jarvis-global-panel::-webkit-scrollbar-thumb:hover {
  background: var(--border-hover);
}

/* ── Missing cursor:pointer on clickable rows ── */
.pd-loc-row { cursor: pointer; }
.pd-loc-row:hover td { background: var(--hover, rgba(0, 0, 0, 0.03)); }

/* ── Reduced Motion Guards ── */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  .skeleton {
    animation: none;
    background: var(--surface-2);
  }
  .spinner {
    animation: none;
    border-top-color: var(--accent);
  }
  #aqBatchBar > div:last-child button { width: 100%; }
}

/* ═══════════════════════════════════════════════════════════
   COLOR-06 — Canonical status badge utilities
   Used by refunds, support, labels, support-insights views.
   Coordination note: when R3-C's .status-badge[data-severity]
   lands, migrate these to that system and remove this block.
   ═══════════════════════════════════════════════════════════ */

/* Base badge */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  line-height: 1.4;
}

/* Semantic variants — all use design-token CSS vars */
.badge-green {
  background: var(--green-dim);
  color: var(--green);
}
.badge-red {
  background: var(--red-dim);
  color: var(--red);
}
.badge-yellow {
  background: var(--yellow-dim);
  color: var(--yellow);
}
.badge-blue {
  background: var(--blue-dim);
  color: var(--blue);
}
.badge-gray {
  background: var(--surface-2);
  color: var(--text-muted);
  border: 1px solid var(--border);
}

/* ═══════════════════════════════════════════════════════════
   UTIL-01 — Inline-style extraction utilities (R6-A5)
   Replace repeated inline style="…" patterns with stable classes.
   Add new entries here; never move them to a component file.
   ═══════════════════════════════════════════════════════════ */

/* font-size:11px;color:var(--text-dim) — secondary/dim metadata labels */
.u-meta-dim {
  font-size: 11px;
  color: var(--text-dim);
}

/* font-size:11px;color:var(--text-muted);margin-top:4px — sub-line helper text */
.u-muted-sm {
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 4px;
}

/* font-size:10px;font-weight:600;color:var(--text-dim);text-transform:uppercase;margin-bottom:4px
   Section / field label caps (accounting, P&L, supplier cards, etc.) */
.u-label-caps {
  font-size: 10px;
  font-weight: 600;
  color: var(--text-dim);
  text-transform: uppercase;
  margin-bottom: 4px;
}

/* font-weight:600 standalone — bold value/number cells */
.u-bold {
  font-weight: 600;
}

/* text-align:right — numeric columns / right-aligned cells */
.u-text-right {
  text-align: right;
}

/* ═══════════════════════════════════════════════════════════════════════
   Round-24 utility classes — RESTORED 2026-07-30
   ═══════════════════════════════════════════════════════════════════════
   Commit e47ac9608 ("refactor(css): extract 557 inline-styles → 14 utility
   classes") stripped the inline styles and applied these class names across
   ~490 sites in 40+ view files, but only ever shipped CSS for one of the
   fourteen (.u-empty-state, in dashboard.css). Everything else was dead
   markup, so the styling the refactor removed was simply lost.

   Verified with a computed-style probe (bare element vs class-carrying
   element, same tag, same parent):
     - at 1280px: 13 of 14 classes were byte-identical to a bare element;
     - at  390px: 10 of 14 still inert. The four that did anything only got
       fragments from css/mobile.css — e.g. `.u-filters` received `gap` and
       `flex-wrap` but never `display:flex`, so both were inert anyway, and
       mobile.css:6719's comment ("the .u-filters parent flex-wraps") was
       describing behavior that did not exist.

   The declarations below are the DOMINANT original inline styles recovered
   from that commit's own diff, with the occurrence count from the diff shown
   per rule. css/mobile.css keeps winning on phones: its rules are
   `#mainContent`-scoped and therefore more specific than these bases.

   Deliberately excluded: nothing — but note that this family is mostly the
   loading-skeleton system (.u-panel wraps `main.innerHTML` skeleton blocks in
   most of its 97 bare usages), which is why every view's loading state has
   been rendering flush with no padding, gap, or column layout.
   ─────────────────────────────────────────────────────────────────────── */

/* color:var(--text-muted) — x77 in the round-24 diff */
.u-muted {
  color: var(--text-muted);
}

/* font-size:12px;color:var(--text-muted) — x68.
   Expressed via --fs-sm (=12px in css/modern-theme.css) so call sites that used
   the token instead of the literal convert losslessly. */
.u-text-sm-muted {
  font-size: var(--fs-sm, 12px);
  color: var(--text-muted);
}

/* font-size:11px;color:var(--text-muted) — x74.
   Expressed via --fs-xs (=11px in css/modern-theme.css) so call sites that used
   the token instead of the literal convert losslessly. */
.u-text-xs-muted {
  font-size: var(--fs-xs, 11px);
  color: var(--text-muted);
}

/* overflow:hidden;text-overflow:ellipsis;white-space:nowrap — the single-line
   truncation triple. Repeated inline on every text cell of wide tables; there was
   no utility for it, which is why cost-chain carried it inline 5x per row. */
.u-ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* border-bottom:1px solid var(--border) — x14 */
.u-border-b {
  border-bottom: 1px solid var(--border);
}

/* display:flex;align-items:center;gap:8px — x21 */
.u-flex-center {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* display:flex;justify-content:space-between;align-items:center — x13 */
.u-flex-between {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

/* display:flex;flex-direction:column;gap:4px — x16 */
.u-flex-col-sm {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* width:100%;border-collapse:collapse — x15. mobile.css adds min-width:560px. */
.u-table {
  width: 100%;
  border-collapse: collapse;
}

/* padding:32px;display:flex;flex-direction:column;gap:16px — x29.
   The loading-skeleton wrapper set on `main` before a view's data arrives.

   SCOPED to panels that actually contain skeleton blocks (`:has`), which is
   what the original inline style was for — 69 of the 97 bare `class="u-panel"`
   sites. A blanket `.u-panel` layout rule is NOT safe here: the other 28 bare
   sites carry their own inline styles that set some but not all of these
   properties, so the class would fill in the rest and change their layout.
   Concretely, js/views/logistics.js:1436 is
   `class="u-panel" style="display:flex;align-items:center;justify-content:space-between"`
   — a horizontal row. Inline does not set flex-direction, so an unscoped
   `flex-direction: column` would stack it vertically. The five compound
   usages (.spm-sup-master / .spm-src-card / .spm-src-head / .sp-material-empty)
   are excluded for the same reason: they own their own layout. */
.u-panel:has(> .skeleton-block) {
  padding: 32px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* display:flex;gap:16px;flex-wrap:wrap — x7. Skeleton filter row inside
   .u-panel; mobile.css:6722 forces its children to full width. */
.u-filters {
  display: flex;
  gap: 16px;
  flex-wrap: wrap;
}

/* Skeleton block sizes. Only ever applied to `.skeleton-block`, so they are
   scoped to it to avoid colliding with any future non-skeleton use.
   u-select-md: width:200px;height:28px;border-radius:6px (the title block).
   u-input-lg / u-input-sm: the x32/x32 pair from the diff, mapped by name —
   lg is the 36px block, sm the 28px stacked rows that carry the 4px gap. */
.skeleton-block.u-select-md {
  width: 200px;
  height: 28px;
  border-radius: 6px;
}

.skeleton-block.u-input-lg {
  width: 100%;
  height: 36px;
  border-radius: 4px;
}

.skeleton-block.u-input-sm {
  width: 100%;
  height: 28px;
  border-radius: 4px;
  margin-top: 4px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   STICKY HEADERS MUST NOT LEAVE A SEE-THROUGH BAND ABOVE THEM
   Cole 2026-08-06: "i hate when there is blank space above a sticky header and
   you can see stuff behind it. fix it permanently everywhere."

   THE BUG, measured on the Daily Plan hub before this shipped: the fixed app
   header ends at y=57 and the sticky subtab bar pins at y=71, so page content
   painted through a 14px strip between them — you could read yesterday's date
   scrolling past above the tab bar.

   WHY IT HAPPENS, and why it keeps happening: `position: sticky; top: 0` pins
   to the top of the element's SCROLL CONTAINER, not to the viewport. When that
   container starts below a fixed header — or carries padding-top — the band
   between the two is owned by nobody, and whatever scrolls underneath shows.
   Nothing about the sticky element itself looks wrong, which is why this is
   found by eye and not by reading the CSS.

   THE FIX: an upward bleed. The sticky element paints the page background over
   the band above itself, so there is never an uncovered strip regardless of
   what caused the offset. `position: sticky` is a positioned element, so it is
   already the containing block for this pseudo-element.

   THE RULE (CLAUDE.md "Sticky headers"): every new sticky header carries
   `.im-sticky-head`, or is added to the selector list below. Enforced by
   `scripts/check_sticky_header_bleed.py` at pre-commit.
   ══════════════════════════════════════════════════════════════════════════ */
:root { --sticky-head-bleed: 24px; }

.im-sticky-head::before,
.hub-subtabs::before,
.pick-tab-group.hub-subtabs::before,
/* Every sticky top-anchored header found by scripts/check_sticky_header_bleed.py
   on the 2026-08-06 sweep. Each pins inside a scroll container that starts below
   the app header, so each had the same uncovered strip. */
.iv2-head::before,
.msg-split-group-head::before,
.stp-header::before,
.mto-detail-header::before,
.customer-story-panel .cs-panel-header::before,
/* The Messages page header. Missed by the 2026-08-06 sweep because the gate
   parsed the comment above its rule as part of the selector, and the word
   "header" in that comment matched this list — so it read as already covered.
   Measured live: app header ended at 57, this pinned at 71, 14px uncovered. */
.msg-page-header::before,
#hub-return-modal .hub-return-modal-hdr::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: var(--sticky-head-bleed);
  /* The PAGE background, not the bar's — the band should read as empty space,
     not as a taller header. */
  background: var(--bg, #f5f4ef);
  pointer-events: none;
}

/* Same band, different colour behind it. The Messages kind filter pins inside
   `.msg-thread-list`, whose 8px padding-top is the uncovered strip — and that
   list sits on `.msg-shell`, which paints `--surface`. Painting `--bg` here
   would read as a grey rectangle inside a white panel, so this one masks with
   the surface it actually sits on. */
/* 2026-09-03 mega-audit: `.msg-thread-section-head` ("Messages" / "Tasks") pins
   in the SAME `.msg-thread-list` scroller as the kind filter above, through the
   same 8px padding-top, so thread rows scrolled visibly through the strip above
   the section labels. It had gone unreported because the gate's `"th"` hint was
   matched as a SUBSTRING and silently exempted every selector containing
   "thread" — fixed in scripts/check_sticky_header_bleed.py the same day. */
.msg-kind-filter::before,
.msg-thread-section-head::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: var(--sticky-head-bleed);
  background: var(--surface, #fff);
  pointer-events: none;
}

/* The bleed only works from a positioned box. A sticky header that somehow
   lost its `position` would otherwise paint the strip at the page origin. */
.im-sticky-head {
  position: sticky;
  top: 0;
  z-index: var(--z-raised, 30);
  background: var(--surface, #fff);
}

/* ── Incubated-brand home (2026-08-31) ────────────────────────────────────
   Cole: "make this really cool and a nice wow experience for her."
   Every colour is a token, so the palette applyBrandTheme() sets from
   brand_theme paints this view too — no hardcoded burgundy anywhere. Type
   scale follows the apple-design lens: tracking goes NEGATIVE as the display
   size grows, leading tightens with it. */
.brand-home { max-width: 1100px; margin: 0 auto; padding: 16px 0 56px; }

.brand-home-hero { padding: clamp(28px, 5vw, 56px) 0 34px; }
.brand-home-kicker, .bf-eyebrow {
  display: block; margin: 0 0 10px; color: var(--accent);
  font-size: .72rem; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
}
.brand-home-hero h1 {
  font-size: clamp(2rem, 5vw, 3.25rem);
  line-height: 1.04;
  letter-spacing: -0.025em;      /* large type reads too loose at 0 */
  margin: 0;
  color: var(--text);
}
.brand-home-hero p {
  margin: 10px 0 0;
  font-size: 14px;
  letter-spacing: 0.14em;        /* small type wants the opposite sign */
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 600;
}

.brand-home-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 14px;
  margin-bottom: 28px;
}
.brand-home-stat {
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--text) 12%, transparent);
  border-radius: 16px;
  padding: 20px 18px;
  min-height: 128px;
}
.brand-home-stat-value {
  font-size: 30px; font-weight: 700; line-height: 1.1;
  letter-spacing: -0.02em; color: var(--text);
}
.brand-home-stat-label {
  margin-top: 6px; font-size: 12px; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: color-mix(in srgb, var(--text) 62%, transparent);
}
/* "none yet" is a business fact and is allowed to look calm. A dash means we
   could not read it, and the view says so in words rather than styling. */
.brand-home-stat-note {
  margin-top: 4px; font-size: 11px;
  color: color-mix(in srgb, var(--text) 45%, transparent);
}

.brand-home-card {
  background: var(--surface);
  border: 1px solid color-mix(in srgb, var(--text) 12%, transparent);
  border-radius: 16px;
  padding: 24px;
  margin-bottom: 20px;
}
.brand-home-state { border-style: dashed; }
.brand-home-state p { max-width: 62ch; margin: 8px 0 0; color: color-mix(in srgb, var(--text) 66%, transparent); line-height: 1.55; }
.brand-home-state.error { border-color: color-mix(in srgb, var(--danger, #b00020) 48%, transparent); }
.brand-home-inline-error { margin: -6px 0 16px; color: var(--danger, #b00020); font-size: .875rem; line-height: 1.45; }
.brand-home-retry, .bf-retry {
  margin-top: 16px; border: 1px solid var(--accent); border-radius: 999px;
  background: var(--accent); color: var(--surface); padding: 9px 15px;
  font: inherit; font-weight: 700; cursor: pointer;
}
.brand-home-retry:focus-visible, .bf-retry:focus-visible, .bf-switch input:focus-visible + .bf-slider {
  outline: 3px solid color-mix(in srgb, var(--accent) 45%, transparent); outline-offset: 3px;
}
.brand-home-card h2 {
  margin: 0; font-size: 19px; letter-spacing: -0.01em; color: var(--text);
}
.brand-home .data-table, .brand-home .data-table th, .brand-home .data-table td { color: var(--text); }
.brand-home-sub {
  margin: 6px 0 18px;
  font-size: 13px; line-height: 1.55;
  max-width: 62ch;               /* measure, not full bleed */
  color: color-mix(in srgb, var(--text) 65%, transparent);
}
/* Wide content scrolls inside its own container — the page body must never
   scroll horizontally. */
.brand-home-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* Price-menu references are identifiers a founder may copy into a factory
   thread. They must not break across lines: `PR-R1-ME-DBR` over four lines can
   be copied as a different SKU. The nested scroller takes the modest overflow
   on a narrow phone, never the page body. */
.brand-home-scroll .mono { white-space: nowrap; overflow-wrap: normal; word-break: normal; }

.brand-home-kinds {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 10px;
}
.brand-home-kinds li {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 34%, transparent);
  color: var(--text);
  border-radius: 999px; padding: 7px 14px; font-size: 13px;
}
.brand-home-loading { min-height: 290px; color: color-mix(in srgb, var(--text) 55%, transparent); }
.brand-home-loading h1 { margin: 0; font-size: clamp(1.6rem, 3vw, 2.3rem); letter-spacing: -.02em; color: var(--text); }
.brand-home-loading-grid, .bf-loading-grid { display: grid; gap: 14px; grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: 28px; }
.brand-home-loading-grid i, .bf-loading-grid i {
  display: block; min-height: 108px; border-radius: 16px;
  background: linear-gradient(100deg, var(--surface) 15%, color-mix(in srgb, var(--text) 6%, var(--surface)) 42%, var(--surface) 68%);
  background-size: 200% 100%; animation: brand-loading-sheen 1.2s ease-in-out infinite;
}
@keyframes brand-loading-sheen { to { background-position: -200% 0; } }

@media (max-width: 640px) {
  .brand-home { padding: 4px 0 36px; }
  .brand-home-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-bottom: 20px; }
  .brand-home-stat { min-height: 112px; padding: 16px 14px; }
  .brand-home-stat-value { font-size: 1.6rem; }
  .brand-home-card { padding: 19px 16px; margin-bottom: 14px; }
  .brand-home-loading-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .brand-home-scroll .data-table { min-width: 390px; }
}

@media (prefers-reduced-motion: reduce) {
  .brand-home * { transition: none !important; animation: none !important; }
}

/* ── Brand-skinned shell: secondary text derives from the BRAND's text ─────
   A brand skin adopts :root[data-theme="dark"] wholesale (see applyBrandTheme)
   because that palette is already tuned. But two of its tokens are tuned
   against a near-black ground (#0a0a09) and land on the brand's own header
   colour instead. Measured on Pepper Row (#6B2028): the subtitle directly
   under the wordmark came out at 3.45:1 — fine for large text, under the
   4.5:1 floor for the 12px uppercase it actually is.
   Deriving it from --text and --surface makes it correct for ANY brand
   ground rather than for this one, which is the point: the next brand will
   not be burgundy. */
body.brand-skinned {
  --shell-secondary-text: color-mix(in srgb, var(--text) 76%, var(--surface));
  --sidebar-section-title: color-mix(in srgb, var(--text) 76%, var(--surface));
}

/* ── Brand lockup: logo → wordmark → monogram ─────────────────────────────
   Cole: "have the logo on her home page and on the top … not be buggy when
   you expand and collapse and see it from mobile or desktop."

   All three children are always in the DOM and only their visibility
   changes, so a resize never reflows the header mid-drag. The container is
   the fixed piece: `min-width: 0` plus a flex row means a long brand name
   truncates instead of pushing the header controls off-screen — the failure
   mode a text wordmark has that an image does not. */
.brand-lockup {
  display: flex;
  align-items: center;
  gap: 10px;
}
/* ⛔ NO `min-width: 0` here, and that absence is deliberate.
   The first cut had it on the lockup AND the inner text block, reasoning that
   a pathologically long brand name would otherwise push the header controls
   off-screen. It does prevent that — by letting flex shrink the lockup below
   its own content, which truncated "Pepper Row" to "PEPPER R…" at 1008px.
   Measured: .header-left collapsed to 105.7px while the wordmark needed 110.
   A normal name breaking at a normal width is a much worse bug than the one
   it was guarding against.
   The cap belongs on the TEXT, by content length — `max-width` in `ch` lets
   every realistic name render in full and still stops a runaway one. */
.brand-lockup .logo {
  max-width: 22ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* ⚠️ Gated on .brand-skinned. Ungated, `white-space: nowrap` + a 28ch cap
   clipped Interior Moderna's own Spanish subtitle — measured, "Centro de
   control de operaciones" needs 183px against a 154px box, while English
   (154) and Chinese both fit. The cap exists for a runaway BRAND name; it has
   no business narrowing the house shell in another language. */
body.brand-skinned .brand-lockup .logo-sub {
  max-width: 28ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ⛔ [hidden] MUST be restated. `display: block` below is an AUTHOR rule and
   beats the user-agent's `[hidden] { display: none }`, so the empty <img>
   shipped in every header — Interior Moderna's included — rendered as a 26px
   box. Measured on brand 1: the login card gained ~52px of blank space above
   the wordmark and the header wordmark shifted 10px right. The monogram right
   below has always had this line; the logo did not. */
.brand-logo[hidden] { display: none !important; }
.brand-logo {
  height: 26px;
  width: auto;
  max-width: 150px;
  object-fit: contain;       /* never distort someone's logo to fit a box */
  display: block;
  flex: 0 0 auto;
}
/* When a real logo is present the wordmark would repeat it. */
body.has-brand-logo .header .brand-lockup .logo { display: none; }

.brand-monogram {
  flex: 0 0 auto;
  width: 30px; height: 30px;
  border-radius: 9px;
  display: none;             /* revealed only by the narrow-width rule below */
  place-items: center;
  background: var(--accent);
  color: var(--bg);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.02em;
  line-height: 1;
}
.brand-monogram[hidden] { display: none !important; }

/* Small applications — the case the monogram exists for. Pepper Row's brand
   book calls it "the monogram, for small applications" (p.6-7), so this is
   her identity system, not a workaround.
   Gated on .has-brand-monogram so a brand WITHOUT one keeps its wordmark
   rather than losing its name to an empty circle. */
@media (max-width: 768px) {
  /* ⛔ .brand-skinned is REQUIRED on every one of these selectors. Without it
     Interior Moderna collapsed to "IM" on mobile the moment brand 1 got a
     monogram row — a visible change to Cole's own dashboard that nobody asked
     for. Caught by measuring `wordmarkVisible` after the migration, not by
     looking at it. An incubated brand opts into this; the house brand's shell
     stays byte-identical. */
  body.brand-skinned.has-brand-monogram:not(.has-brand-logo)
    .header .brand-monogram { display: grid; }
  body.brand-skinned.has-brand-monogram:not(.has-brand-logo)
    .header .brand-lockup .logo,
  body.brand-skinned.has-brand-monogram:not(.has-brand-logo)
    .header .brand-lockup .logo-sub { display: none; }
  .brand-logo { height: 22px; max-width: 108px; }
}

/* The login card: centred, and the wordmark stays even with a logo — this is
   the one place where seeing the name spelled out is worth the repetition. */
.login-brand-logo {
  height: 40px; max-width: 200px;
  margin: 0 auto 12px;
}

/* Home hero lockup. */
.brand-home-hero .brand-home-logo {
  height: 56px; max-width: 280px;
  width: auto; object-fit: contain;
  display: block; margin-bottom: 18px;
}
@media (max-width: 640px) {
  .brand-home-hero .brand-home-logo { height: 42px; max-width: 220px; }
}

/* Price-menu thumbnails on the brand home. The column only renders when at
   least one item has a photo, so there is no empty gutter on a brand whose
   supplier has not sent any yet. */
.brand-home-photo { width: 56px; padding-right: 0; }
.brand-home-photo img {
  width: 44px; height: 44px;
  object-fit: cover;                 /* never distort a product shot */
  border-radius: 8px;
  display: block;
  background: color-mix(in srgb, var(--text) 6%, transparent);
}

/* ── Owner preview bar ────────────────────────────────────────────────────
   Shown only while an owner is viewing another brand's shell. It has to be
   unmistakable: the whole page is wearing someone else's identity, and the
   one thing that must never be ambiguous is whose dashboard you are looking
   at. Fixed to the top so it survives scrolling, and it offsets the app
   rather than covering the header. */
body.brand-preview { padding-top: 38px; }
#brandPreviewBar {
  position: fixed; inset: 0 0 auto 0; z-index: 100000;
  height: 38px;
  display: flex; align-items: center; justify-content: center; gap: 16px;
  background: #1c1b1a; color: #f4f3ee;
  font: 500 13px/1 system-ui, sans-serif;
  letter-spacing: 0.01em;
  box-shadow: 0 1px 0 rgba(0,0,0,.35);
}
#brandPreviewBar[hidden] { display: none; }
#brandPreviewBar .bpb-what { opacity: .82; }
#brandPreviewBar .bpb-what b { opacity: 1; font-weight: 600; }
#brandPreviewBar a {
  color: #f4f3ee; text-decoration: none;
  border: 1px solid rgba(244,243,238,.35);
  border-radius: 999px; padding: 4px 12px;
}
#brandPreviewBar a:hover { background: rgba(244,243,238,.12); }
@media (max-width: 600px) {
  #brandPreviewBar { gap: 10px; font-size: 12px; }
  #brandPreviewBar .bpb-what { max-width: 45vw; overflow: hidden;
                               text-overflow: ellipsis; white-space: nowrap; }
}

/* ── Features (brand self-serve catalogue) ─────────────────────────────────
   Cole 2026-08-31: "there should be a tab where she can add and remove
   certain tabs and features that exist." Tokens only — this surface is
   rendered under a brand's own palette, so a hardcoded colour here would be
   Interior Moderna's colour on someone else's dashboard. */
.bf-wrap { max-width: 1100px; padding: clamp(20px, 4vw, 44px) 0 56px; }
.bf-title { margin: 0 0 6px; font-size: clamp(2rem, 4vw, 3rem); letter-spacing: -.03em; line-height: 1.04; color: var(--text); }
.bf-sub { max-width: 62ch; color: var(--text-muted, #666); margin: 0 0 16px; line-height: 1.55; }
.bf-note, .bf-summary, .bf-feedback { border: 1px solid var(--border, #e5e5e5); border-radius: 14px; background: var(--bg-subtle, #fafafa); }
.bf-note { max-width: 76ch; padding: 13px 15px; margin: 0 0 28px; color: var(--text-muted, #666); line-height: 1.5; }
.bf-summary { display: inline-block; padding: 8px 12px; margin: 0 0 18px; color: var(--text-muted, #666); font-size: .86rem; }
.bf-summary strong { color: var(--text, #222); font-variant-numeric: tabular-nums; }
.bf-status { min-height: 1.4em; margin: 0; color: var(--text-muted, #666); font-size: .875rem; }
.bf-feedback { max-width: 680px; padding: 18px; color: var(--text-muted, #666); line-height: 1.5; }
.bf-feedback p, .bf-feedback h2 { margin: 0; }
.bf-feedback.error { border-color: color-mix(in srgb, var(--danger, #b00020) 48%, transparent); color: var(--danger, #b00020); }
.bf-cluster { font-size: .78rem; text-transform: uppercase; letter-spacing: .1em; color: var(--text-muted, #666); margin: 32px 0 12px; }
.bf-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.bf-card { border: 1px solid var(--border, #e5e5e5); border-radius: 16px; padding: 18px; background: var(--surface, #fff); display: flex; flex-direction: column; gap: 11px; min-height: 178px; transition: transform 160ms ease, box-shadow 160ms ease, border-color 160ms ease; }
@media (hover: hover) { .bf-card:not(.locked):not(.saving):hover { transform: translateY(-2px); box-shadow: 0 10px 26px color-mix(in srgb, var(--text) 10%, transparent); border-color: color-mix(in srgb, var(--accent) 42%, var(--border)); } }
.bf-card.locked { opacity: .7; }
.bf-card.saving { opacity: .7; }
.bf-head { display: flex; align-items: flex-start; gap: 8px; justify-content: space-between; }
.bf-label { color: var(--text, #222); font-size: 1.02rem; font-weight: 700; letter-spacing: -.01em; }
.bf-badge { font-size: .72rem; line-height: 1.2; padding: 4px 8px; border-radius: 999px; border: 1px solid var(--border, #e5e5e5); white-space: nowrap; color: var(--text); }
.bf-badge.ready { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.bf-badge.held { color: var(--text-muted, #666); }
.bf-desc { margin: 0; font-size: .91rem; color: var(--text-muted, #666); flex: 1; line-height: 1.5; }
.bf-foot { display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 10px; }
.bf-views, .bf-state { font-size: .78rem; color: var(--text-muted, #666); }
.bf-state { min-width: 43px; text-align: right; font-weight: 700; }
/* Press feedback on pointer-down, and a switch that cannot be dragged into a
   state the server would refuse. */
.bf-switch { position: relative; display: inline-block; width: 44px; height: 26px; }
.bf-switch input { opacity: 0; width: 100%; height: 100%; margin: 0; position: absolute; inset: 0; cursor: pointer; }
.bf-slider { position: absolute; inset: 0; cursor: pointer; border-radius: 999px;
             background: var(--border, #ccc); transition: background 140ms ease; }
.bf-slider::before { content: ""; position: absolute; height: 20px; width: 20px;
                     left: 3px; top: 3px; border-radius: 50%;
                     background: var(--surface, #fff);
                     transition: transform 140ms ease; }
.bf-switch input:checked + .bf-slider { background: var(--accent, #2f6f4f); }
.bf-switch input:checked + .bf-slider::before { transform: translateX(18px); }
.bf-switch input:disabled + .bf-slider { cursor: not-allowed; opacity: .5; }
.bf-switch input:disabled { cursor: not-allowed; }
.bf-loading-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 24px; }
.bf-loading-grid i { min-height: 178px; }
@media (max-width: 540px) { .bf-grid { grid-template-columns: 1fr; } .bf-card { min-height: 0; } .bf-note { margin-bottom: 22px; } }
@media (prefers-reduced-motion: reduce) {
  .bf-slider, .bf-slider::before { transition: none; }
}

/* Pepper Row's ready product and marketing views share the brand's calm
   recovery treatment. Scoped to the partner skin: Interior Moderna's dense
   operational surfaces keep their existing visual language. */
body.brand-skinned[data-brand-id="2"] .prod-catalog-preview-status {
  margin: 0; padding: 10px 14px; border-bottom: 1px solid var(--border);
  color: var(--text-muted); background: var(--surface-2); font-size: .84rem;
  line-height: 1.45;
}
body.brand-skinned[data-brand-id="2"] .pr-workflow-state {
  max-width: 680px; margin-top: 24px; padding: 22px; border: 1px solid var(--border);
  border-radius: 16px; background: var(--surface);
}
body.brand-skinned[data-brand-id="2"] .pr-workflow-state h2 { margin: 0; color: var(--text); font-size: 1.1rem; }
body.brand-skinned[data-brand-id="2"] .pr-workflow-state p { margin: 8px 0 0; color: var(--text-muted); line-height: 1.5; }
body.brand-skinned[data-brand-id="2"] .pr-workflow-state-error { border-color: color-mix(in srgb, var(--danger, #b00020) 48%, var(--border)); }
body.brand-skinned[data-brand-id="2"] .pr-workflow-retry {
  margin-top: 16px; padding: 9px 14px; border: 1px solid var(--accent); border-radius: 999px;
  background: var(--accent); color: var(--surface); font: inherit; font-weight: 700; cursor: pointer;
}
body.brand-skinned[data-brand-id="2"] .pr-workflow-retry:focus-visible { outline: 3px solid color-mix(in srgb, var(--accent) 45%, transparent); outline-offset: 3px; }
body.brand-skinned[data-brand-id="2"] .mo-header-right { flex-wrap: wrap; }
body.brand-skinned[data-brand-id="2"] .mo-header-right .export-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px; min-height: 36px;
  padding: 7px 12px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface);
  color: var(--text); font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-semibold); cursor: pointer;
}
body.brand-skinned[data-brand-id="2"] .mo-header-right .export-btn:hover { background: var(--surface-2); border-color: var(--accent); }
body.brand-skinned[data-brand-id="2"] .mo-header-right .export-btn:focus-visible { outline: 3px solid color-mix(in srgb, var(--accent) 45%, transparent); outline-offset: 3px; }

/* ── "Being connected to your data" panel ─────────────────────────────────
   Cole 2026-08-31: "i want isa able to have all tabs if she wants and add and
   remove tabs as she chooses." Every tab opens; one not yet wired to a brand's
   data lands here instead of firing requests the server would refuse. Tokens
   only — this renders under the BRAND's palette. */
.bnc-wrap { display: flex; justify-content: center; padding: 10vh 20px; }
.bnc-card { max-width: 520px; text-align: center; }
.bnc-kicker { font-size: .72rem; letter-spacing: .14em; text-transform: uppercase;
              color: var(--text-muted, #666); margin-bottom: 10px; }
.bnc-title { margin: 0 0 12px; font-size: clamp(1.4rem, 3vw, 2rem);
             line-height: 1.1; letter-spacing: -0.01em; }
.bnc-body { color: var(--text-muted, #666); line-height: 1.6; margin: 0 0 10px; }
.bnc-quiet { font-size: .88rem; }
