/* ============================================================
   theme_br.css — BR Scripts redesign (Tiger direction)
   Components and shell only. All design tokens live in
   `brscripts/static/tokens.css` — DO NOT redefine them here.

   Load order in base.html (intentional):
     styles.css -> layout_v2_wide.css -> tokens.css -> theme_br.css
   styles.css/layout_v2_wide.css load first so unmigrated templates
   keep their legacy rules; tokens.css and theme_br.css load LAST so
   the new shell wins on shared class names. This deliberately
   deviates from the v2 phase-0 README's prescribed reverse order —
   Codex confirmed v2's order would re-assert the legacy dark
   sidebar shell from styles.css.

   Structure:
     1. Base reset + typography
     2. App layout (sidebar + topbar + main)
     3. Components (buttons, cards, tables, pills, etc.)
     4. Forms / states / flash / run-toast
     5. Legacy-compat overrides (`!important` blocks; deleted in Phase 4)
   ============================================================ */

/* Tokens (light + dark) live in tokens.css — single source of truth.
   Do NOT redefine `:root` variables in this file. */

/* ============================================================
   SHELL — base reset, sidebar, topbar, page, components
   (ported from handoff/mocks/shell.css; Tiger flavor selectors
   have had `body[data-direction="tiger"]` prefix stripped so
   the rules apply unconditionally.)
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  font-family: var(--font-sans);
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  font-feature-settings: 'cv11', 'ss01';
}
h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--text);
  margin: 0;
  font-weight: 600;
  letter-spacing: -0.01em;
}
h1 { font-size: 22px; letter-spacing: -0.02em; }
h2 { font-size: 17px; }
h3 { font-size: 15px; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }

/* App layout */
.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  min-height: 100vh;
  width: 100%;
}
.app[data-collapsed="true"] { grid-template-columns: var(--sidebar-w-collapsed) 1fr; }
/* Legacy hook: existing JS toggles `body.sidebar-collapsed` instead of
   data-collapsed on .app — keep both working. */
body.sidebar-collapsed .app { grid-template-columns: var(--sidebar-w-collapsed) 1fr; }

/* Authenticated shell layout. The app grid owns sidebar/content placement;
   legacy page content must not add fixed-sidebar offsets inside it. */
body.has-sidebar {
  display: block;
  background: var(--bg);
}
body.has-sidebar > .app {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
}
body.has-sidebar.sidebar-collapsed > .app {
  grid-template-columns: var(--sidebar-w-collapsed) 1fr;
}
body.has-sidebar > .app .sidebar {
  position: sticky !important;
  top: 0;
  height: 100vh;
  width: var(--sidebar-w) !important;
  display: flex !important;
  grid-column: 1;
}
/* Pin .main to the second grid column explicitly. Without this, when
   the sidebar is `display:none` (e.g. at <=700px), .main falls back to
   column 1 (which is 0px wide on phones) and renders at 0×0. */
body.has-sidebar > .app > .main { grid-column: 2; }
body.has-sidebar.sidebar-collapsed > .app .sidebar {
  width: var(--sidebar-w-collapsed) !important;
}
/* Legacy stylesheet positions `<main>` and `.page-content` with
   margin-left to account for the fixed sidebar. Under the grid that
   margin pushes content off-screen. */
body.has-sidebar > .app main,
body.has-sidebar > .app .main,
body.has-sidebar > .app .page-content { margin-left: 0 !important; }

/* Match the legacy responsive breakpoints so the column reservation
   tracks the actual sidebar width on narrow viewports. */
@media (max-width: 1100px) {
  body.has-sidebar > .app,
  body.has-sidebar.sidebar-collapsed > .app {
    grid-template-columns: var(--sidebar-w-collapsed) 1fr;
  }
  body.has-sidebar > .app .sidebar,
  body.has-sidebar.sidebar-collapsed > .app .sidebar {
    width: var(--sidebar-w-collapsed) !important;
  }
}
@media (max-width: 700px) {
  /* On phone widths the legacy rule hides the sidebar entirely.
     Mirror that by collapsing the column to 0 and hiding the aside.
     The .topbar-menu-btn (visible only at this width) re-opens it as a
     slide-in via `body.sidebar-mobile-open`. */
  body.has-sidebar > .app { grid-template-columns: 0 1fr; }
  body.has-sidebar > .app .sidebar { display: none !important; }
  body.has-sidebar.sidebar-mobile-open > .app .sidebar {
    display: flex !important;
    position: fixed !important;
    left: 0; top: 0;
    width: min(280px, 86vw) !important;
    height: 100vh;
    z-index: 1100;
    box-shadow: var(--shadow-lg);
  }
}

/* ============= SIDEBAR ============= */
.sidebar {
  background: var(--sidebar-bg);
  color: var(--sidebar-fg);
  border-right: 1px solid var(--sidebar-border);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
}
.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 14px 14px;
  border-bottom: 1px solid var(--sidebar-border);
  background: transparent;
}
.sidebar-brand-mark {
  width: 30px; height: 30px;
  border-radius: 8px;
  background: var(--brand);
  color: var(--brand-fg);
  display: grid; place-items: center;
  font-weight: 700;
  font-size: 13px;
  flex-shrink: 0;
  box-shadow: var(--shadow-sm);
}
.sidebar-brand-text { min-width: 0; flex: 1; }
.sidebar-brand-name {
  font-weight: 600;
  color: var(--sidebar-fg);
  font-size: 13.5px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  white-space: nowrap;
  display: block;
}
.sidebar-brand-env {
  font-size: 10.5px;
  color: var(--sidebar-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  display: block;
}
.sidebar-toggle {
  background: transparent;
  border: 1px solid transparent;
  color: var(--sidebar-muted);
  width: 28px; height: 28px;
  border-radius: 6px;
  display: grid; place-items: center;
  flex-shrink: 0;
}
.sidebar-toggle:hover { background: var(--surface-2); color: var(--sidebar-fg); }
.sidebar-toggle [data-lucide] { width: 16px; height: 16px; }

.sidebar-nav {
  flex: 1;
  overflow-y: auto;
  padding: 10px 8px 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* Legacy and new section-label class names both supported */
.sidebar-section,
.sidebar-section-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--sidebar-muted);
  padding: 12px 10px 6px;
  font-weight: 600;
}
.sidebar-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border-radius: 7px;
  color: var(--sidebar-fg);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  position: relative;
  text-decoration: none;
}
/* Tiger sidebar visual states. */
.sidebar-item {
  color: var(--sidebar-fg) !important;
  border-left: none !important;
}
.sidebar-item:hover {
  background: color-mix(in srgb, var(--sidebar-active-bg) 60%, transparent) !important;
  color: var(--sidebar-fg) !important;
}
.sidebar-item.is-active {
  background: var(--sidebar-active-bg) !important;
  color: var(--sidebar-active-fg) !important;
  font-weight: 600;
}
.sidebar-item [data-lucide],
.sidebar-item .sidebar-ic,
.sidebar-item .sidebar-icon {
  width: 18px; height: 18px; flex-shrink: 0;
  color: currentColor;
  opacity: 0.85;
}
.sidebar-item .sidebar-label { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-item .sidebar-badge,
.sidebar-item .sidebar-alert-badge {
  background: var(--danger);
  color: #fff;
  border-radius: 999px;
  font-size: 10px;
  padding: 1px 6px;
  font-weight: 700;
  line-height: 1.5;
}

/* SPEC §4.4: no chevrons on parent items, no <details> dropdown
   element. The previous click-to-expand structure has been removed.
   Sidebar parents are now flat <a class="sidebar-item">; sub-lists
   render inline as a sibling <div class="sidebar-sub"> and CSS shows
   them only when the parent has `.is-active` (see below). */

/* SPEC §4.5: sub-items appear ONLY when the parent is active.
   Flat-<a> sidebar markup pairs each parent .sidebar-item with a
   sibling .sidebar-sub. The sibling is hidden by default and shown
   only when the immediately preceding .sidebar-item has .is-active. */
.sidebar-sub,
.sidebar-submenu {
  display: none;
  flex-direction: column;
  gap: 1px;
  margin: 1px 0 4px;
  padding-left: 28px;
  background: transparent !important;
  border-top: none !important;
  border-bottom: none !important;
}
.sidebar-item.is-active + .sidebar-sub,
.sidebar-item.is-active + .sidebar-submenu {
  display: flex;
}
.sidebar-subitem {
  padding: 5px 10px;
  border-radius: 6px;
  font-size: 12.5px;
  color: var(--sidebar-muted) !important;
  cursor: pointer;
  position: relative;
  text-decoration: none;
  display: block;
  border-left: none !important;
}
.sidebar-subitem:hover {
  color: var(--sidebar-fg) !important;
  background: color-mix(in srgb, var(--sidebar-active-bg) 40%, transparent) !important;
}
.sidebar-subitem.is-active {
  color: var(--sidebar-active-fg) !important;
  font-weight: 600;
  border-left-color: transparent !important;
}
.sidebar-subitem.is-active::before {
  content: '';
  position: absolute;
  left: -6px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 14px; border-radius: 2px;
  background: var(--brand);
}
.sidebar-subitem--external::after {
  content: " \2197";
  color: var(--sidebar-muted);
  font-size: 11px;
}
/* Danger variant (Logout link). The base `.sidebar-subitem` rule
   above uses `!important` to win over legacy white-on-dark color, so
   this variant must also use `!important` to win over the base. */
.sidebar-subitem--danger { color: var(--danger) !important; }
.sidebar-subitem--danger:hover { color: var(--danger) !important; }

/* Calculator mockup pass: keep the global shell intact, but give the
   Buyback calculator route the Tiger spacing and active states shown in
   the selected design. */
body.buyback-calculator-page {
  --sidebar-w: 182px;
}
body.buyback-calculator-page .main > main.wide {
  max-width: none;
  margin: 18px 0 0;
  padding: 0;
}
body.buyback-calculator-page .main > main.wide > .page {
  padding: 20px 24px 42px;
}
body.buyback-calculator-page .report-issue-btn {
  display: none;
}
body.buyback-calculator-page .sidebar-brand {
  padding: 16px 12px 14px;
}
body.buyback-calculator-page .sidebar-brand-mark {
  width: 30px;
  height: 30px;
  border-radius: 9px;
}
body.buyback-calculator-page .sidebar-nav {
  padding: 12px 8px 14px;
  gap: 3px;
}
body.buyback-calculator-page .sidebar-section,
body.buyback-calculator-page .sidebar-section-label {
  padding: 14px 10px 7px;
}
body.buyback-calculator-page .sidebar-item {
  gap: 10px;
  padding: 8px 9px;
  border-radius: 8px;
}
body.buyback-calculator-page .sidebar-item [data-lucide],
body.buyback-calculator-page .sidebar-item .sidebar-ic,
body.buyback-calculator-page .sidebar-item .sidebar-icon {
  width: 17px;
  height: 17px;
}
body.buyback-calculator-page .sidebar-item.is-active {
  background: color-mix(in srgb, var(--brand) 14%, #ffffff) !important;
  color: #c8541c !important;
}
body.buyback-calculator-page .sidebar-sub,
body.buyback-calculator-page .sidebar-submenu {
  gap: 2px;
  margin: 3px 0 7px;
  padding-left: 28px;
}
body.buyback-calculator-page .sidebar-subitem {
  padding: 7px 9px;
  border-radius: 7px;
}
body.buyback-calculator-page .sidebar-subitem.is-active {
  background: color-mix(in srgb, var(--brand) 10%, #ffffff) !important;
  color: #c8541c !important;
}
.sidebar-submenu-divider {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--sidebar-muted);
  padding: 8px 10px 4px;
  font-weight: 600;
}

.sidebar-footer {
  border-top: 1px solid var(--sidebar-border);
  padding: 10px 10px 12px;
  display: flex;
  align-items: center;
  gap: 10px;
}
.sidebar-user-avatar {
  width: 30px; height: 30px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent);
  display: grid; place-items: center;
  font-weight: 700;
  font-size: 11.5px;
  flex-shrink: 0;
}
.sidebar-user-name { font-size: 12.5px; font-weight: 600; color: var(--sidebar-fg); line-height: 1.2; }
.sidebar-user-role { font-size: 10.5px; color: var(--sidebar-muted); }

/* Theme toggle in sidebar footer (icon-swap pattern from EXTRAS §3) */
.sidebar-theme-switch {
  border-top: 1px solid var(--sidebar-border);
  padding: 8px 10px;
  flex-shrink: 0;
}
.sidebar-theme-btn {
  background: transparent;
  border: 1px solid transparent;
  color: var(--sidebar-muted);
  width: 100%;
  min-height: 36px;
  border-radius: 7px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 8px;
  text-align: left;
}
.sidebar-theme-btn:hover { background: var(--surface-2); color: var(--sidebar-fg); }
.sidebar-theme-btn [data-lucide] { width: 16px; height: 16px; flex-shrink: 0; }
.sidebar-theme-btn .theme-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12.5px;
  font-weight: 600;
}
.sidebar-theme-switch-dot {
  position: relative;
  width: 28px;
  height: 16px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--sidebar-muted) 35%, transparent);
  background: color-mix(in srgb, var(--sidebar-muted) 20%, transparent);
  flex-shrink: 0;
}
.sidebar-theme-switch-dot::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--sidebar-muted);
  transition: transform 0.15s ease, background-color 0.15s ease;
}
[data-theme="dark"] .sidebar-theme-switch-dot {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: var(--accent-soft);
}
[data-theme="dark"] .sidebar-theme-switch-dot::after {
  background: var(--accent);
  transform: translateX(12px);
}
.theme-icon-dark,
.theme-icon-moon { display: none; }
[data-theme="dark"] .theme-icon-light,
[data-theme="dark"] .theme-icon-sun { display: none; }
[data-theme="dark"] .theme-icon-dark,
[data-theme="dark"] .theme-icon-moon { display: inline-flex; }

/* ============= MAIN / TOPBAR ============= */
.main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--bg);
}
header.topbar,
.topbar {
  height: 56px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-elev);
  display: flex !important;
  align-items: center;
  gap: 16px;
  padding: 0 24px;
  position: sticky;
  top: 0;
  z-index: 10;
}
.crumbs {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--text-muted);
}
.crumbs .crumb-sep { color: var(--text-subtle); }
.crumbs .crumb-active { color: var(--text); font-weight: 600; }

/* Topbar search — visual chrome only in Phase 0; the ⌘K command palette
   lands in the EXTRAS phase. Rendered as a `<button type="button" disabled>`
   so the placeholder is announced honestly to AT and Tab order — never a
   clickable thing that does nothing. The :not(:disabled) hover rule below
   is forward-leaning: when the palette ships, drop the `disabled` attr in
   the template and the button lights up automatically. */
.topbar-search {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 10px;
  width: 260px;
  font: inherit;
  font-size: 13px;
  color: var(--text-muted);
  text-align: left;
  /* Reset native button chrome so the placeholder reads as the input
     chip it visually mimics, not as a chrome button. */
  appearance: none;
  -webkit-appearance: none;
}
.topbar-search:not(:disabled) { cursor: pointer; }
.topbar-search:not(:disabled):hover { border-color: var(--border-strong); color: var(--text); }
.topbar-search:disabled {
  cursor: not-allowed;
  opacity: 0.7;
}
.topbar-search [data-lucide] { width: 14px; height: 14px; flex-shrink: 0; }
.topbar-search-text { flex: 1; text-align: left; }
.topbar-search-kbd {
  font-family: var(--font-mono);
  font-size: 11px;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 6px;
  color: var(--text-subtle);
}
.topbar-actions { display: flex; align-items: center; gap: 6px; }
.topbar-iconbtn {
  width: 32px; height: 32px;
  border-radius: 8px;
  background: transparent;
  border: 1px solid transparent;
  display: grid; place-items: center;
  color: var(--text-muted);
}
.topbar-iconbtn:hover { background: var(--surface-2); color: var(--text); }
.topbar-iconbtn [data-lucide] { width: 18px; height: 18px; }

/* Mobile menu trigger — visible only at <=700px where the sidebar is
   hidden. Lives in the topbar so navigation is always reachable.
   Toggles `body.sidebar-mobile-open` via [data-sidebar-mobile-toggle]. */
.topbar-menu-btn {
  display: none;
  width: 36px; height: 36px;
  border-radius: 8px;
  background: transparent;
  border: 1px solid var(--border);
  align-items: center;
  justify-content: center;
  color: var(--text);
  margin-right: auto;
  flex-shrink: 0;
}
.topbar-menu-btn:hover { background: var(--surface-2); }
.topbar-menu-btn [data-lucide] { width: 18px; height: 18px; }
@media (max-width: 700px) {
  .topbar-menu-btn { display: inline-flex; }
}

/* Mobile slide-in scrim — backdrop that closes the open sidebar
   on click. Only rendered/visible at <=700px when the sidebar is
   in its mobile-open state. */
.sidebar-mobile-scrim {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1099;
  background: rgba(10, 18, 30, 0.5);
}
@media (max-width: 700px) {
  body.sidebar-mobile-open .sidebar-mobile-scrim { display: block; }
}

/* ============= PAGE WRAPPER (full-bleed) ============= */
/* `.page` owns the ONE horizontal gutter between sidebar and content
   (layout_v2_wide.css zeroes <main> side padding and page-shell width
   caps so this 24px gutter is identical on every page). */
.page {
  padding: 24px 24px 40px;
  width: 100%;
  max-width: none;
  margin: 0;
  min-width: 0;
}
.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
}
.page-header-copy { min-width: 0; }
.page-heading-title {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 500;
  margin: 0 0 4px;
  letter-spacing: -0.015em;
}
.page-subtitle { color: var(--text-muted); font-size: 13.5px; max-width: 560px; }
.page-header-actions { display: flex; gap: 8px; flex-shrink: 0; align-items: center; }

/* Card titles + metric values stay Inter (Tiger flavor) */
.card-title, .metric-value, h2, h3 { font-family: var(--font-sans); }
/* Cards keep Tiger's smaller radius */
.card { border-radius: var(--radius); }

/* ============= BUTTONS ============= */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  font-size: 13px;
  font-weight: 500;
  font-family: inherit;
  box-shadow: var(--shadow-sm);
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
}
.btn:hover { background: var(--surface-hover); }
.btn--primary {
  background: var(--brand);
  color: var(--brand-fg);
  border-color: var(--brand);
}
.btn--primary:hover { background: var(--brand-deep); }
.btn--danger {
  background: var(--danger);
  color: #fff;
  border-color: var(--danger);
}
.btn--danger:hover { background: color-mix(in srgb, var(--danger) 86%, #000); }
.btn--archive {
  background: #fff1f2;
  color: #991b1b;
  border-color: #fecdd3;
}
.btn--archive:hover {
  background: #ffe4e6;
  border-color: #fda4af;
}
.btn--ghost { background: transparent; border-color: transparent; box-shadow: none; color: var(--text-muted); }
.btn--ghost:hover { background: var(--surface-2); color: var(--text); }
.btn--sm { padding: 4px 9px; font-size: 12px; border-radius: 6px; }
.btn [data-lucide], .btn .btn-ic { width: 14px; height: 14px; }

/* ============= TABS / SUBNAV ============= */
.subnav {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 20px;
  overflow-x: auto;
}
.subnav-tab {
  padding: 10px 14px;
  font-size: 13px;
  color: var(--text-muted);
  font-weight: 500;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
  background: transparent;
  border-left: none;
  border-right: none;
  border-top: none;
}
.subnav-tab:hover { color: var(--text); }
.subnav-tab.is-active {
  color: var(--text);
  border-bottom-color: var(--brand);
  font-weight: 600;
}
.subnav-tab .count {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  background: var(--surface-2);
  border-radius: 999px;
  font-size: 11px;
  color: var(--text-muted);
  font-weight: 500;
}

/* `_keepa_engine_header.html` Bucket 3 helpers. `.subnav--secondary` renders
   the Price Engine secondary tab row directly under the primary Keepa row.
   `.keepa-engine-subnav` keeps both rows visible without horizontal
   sidescrollers on narrow viewports. Bucket 3 audit: page-scoped to a single
   shared partial, in theme_br.css, Tiger-tokens-only, no legacy-prefix
   collision. */
.keepa-engine-subnav {
  flex-wrap: wrap;
  row-gap: 0;
  overflow-x: visible;
}

.subnav.subnav--secondary {
  margin-top: -8px;
  font-size: 13px;
}

/* `platform_alerts.html` Bucket 3 page-scoped helpers. The 6-tile severity
   summary needs auto-fit responsive collapse (Tiger `.grid-N` is fixed-column
   count). The four export/header actions also need a mobile wrap to avoid
   page-level horizontal overflow. Same pattern as `.dashboard-metric-grid`
   (theme_br.css L934) and `.auto-buy-pipeline-metric-grid`. Bucket 3 audit:
   page-specific, in theme_br.css, pure layout, no legacy-prefix collision. */
.platform-alerts-page-header {
  flex-wrap: wrap;
}

.platform-alerts-header-actions {
  flex-wrap: wrap;
  justify-content: flex-end;
}

.platform-alerts-summary-grid {
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}

@media (max-width: 700px) {
  .platform-alerts-page-header {
    display: block;
  }

  .platform-alerts-header-actions {
    margin-top: 12px;
    justify-content: stretch;
  }

  .platform-alerts-header-actions form {
    flex: 1 1 100%;
  }

  .platform-alerts-header-actions .btn {
    width: 100%;
    justify-content: center;
    text-align: center;
    white-space: normal;
  }
}

/* `contact_detail.html` Bucket 3 helpers. The page uses Tiger primitives for
   header, metrics, cards, forms, and buttons; these helpers only size the
   contact identity, responsive meta tiles, and two-column detail layout. */
.contact-detail-header {
  flex-wrap: wrap;
  align-items: center;
}

.contact-detail-identity {
  display: flex;
  align-items: center;
  gap: 12px;
}

.contact-detail-avatar {
  width: 42px;
  height: 42px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  background: var(--brand-soft);
  color: var(--brand-deep);
  font-weight: 700;
}

.contact-detail-meta-grid {
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

.contact-detail-meta-grid .metric-value {
  overflow-wrap: anywhere;
}

.contact-detail-grid {
  align-items: start;
}

.contact-detail-grid .card {
  min-width: 0;
}

.contact-detail-grid .card-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.contact-detail-page .empty-state {
  padding: 20px;
}

@media (max-width: 820px) {
  .contact-detail-grid {
    grid-template-columns: 1fr;
  }
}

/* `ticket_detail.html` Bucket 3 helpers. The migrated page uses Tiger cards,
   kv rows, forms, buttons, and comment surfaces; these helpers constrain only
   the back-link row, editable metadata forms, and mobile collapse. */
.ticket-detail-subnav {
  flex-wrap: wrap;
  overflow-x: visible;
}

.ticket-detail-subnav .subnav-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.ticket-detail-kv .kv-row {
  grid-template-columns: 160px minmax(0, 1fr);
}

.ticket-detail-inline-form {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.ticket-detail-inline-form .input {
  flex: 1 1 280px;
}

.ticket-detail-inline-form .select {
  flex: 1 1 220px;
}

.ticket-detail-grid {
  align-items: start;
}

.ticket-detail-grid .card {
  min-width: 0;
}

.ticket-detail-page .card-head {
  flex-wrap: wrap;
}

.ticket-detail-page .empty-state {
  padding: 20px;
}

.ticket-detail-page .comment-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  width: 100%;
}

/* `bids.html` Bucket 3 helpers. The JS-heavy bids surface keeps `bids-*`
   hooks for dynamic rows; markup-level chrome moves to Tiger page header,
   subnav, cards, tables, and buttons. These helpers keep tabs/actions
   visible and prevent toolbar collapse on narrow screens. */
.bids-page-header,
.bids-page-header-actions,
.bids-panel .card-head,
.bids-panel .page-header-actions {
  flex-wrap: wrap;
}

.bids-subnav {
  flex-wrap: wrap;
  overflow-x: visible;
}

@media (max-width: 820px) {
  .ticket-detail-page .ticket-detail-grid,
  .ticket-detail-page .ticket-detail-kv .kv-row {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 520px) {
  .ticket-detail-inline-form {
    display: grid;
    grid-template-columns: 1fr;
    align-items: stretch;
  }

  .ticket-detail-inline-form .input,
  .ticket-detail-inline-form .select,
  .ticket-detail-inline-form .btn {
    flex: 1 1 100%;
    width: 100%;
    min-width: 0;
  }

  .ticket-detail-inline-form .btn,
  .ticket-detail-page .card-head .btn {
    justify-content: center;
    white-space: normal;
  }

  .ticket-detail-page .comment-summary .btn {
    flex: 1 1 100%;
    width: 100%;
    min-width: 0;
  }
}

.bids-page .card {
  min-width: 0;
}

@media (max-width: 700px) {
  .bids-page-header {
    display: block;
  }

  .bids-page-header-actions {
    margin-top: 12px;
  }

  .bids-page-header-actions .btn,
  .bids-panel .page-header-actions .btn {
    width: 100%;
    justify-content: center;
    white-space: normal;
  }

  .bids-panel .page-header-actions {
    width: 100%;
  }
}

/* `ftp_connection.html` Bucket 3 helpers. The migration keeps FTP-specific
   operational rows and data-vbc JS hooks, while rendered chrome now uses
   Tiger headers, subnav, cards, tables, banners, pills, buttons, and inputs.
   These helpers only handle renamed tab panels and responsive overflow. */
.ftp-subnav {
  flex-wrap: wrap;
  overflow-x: visible;
}

.ftp-tab-panel {
  display: grid;
  gap: 16px;
  min-width: 0;
}

.ftp-tab-panel[hidden] {
  display: none !important;
}

.ftp-page .card,
.ftp-page .table-wrap {
  min-width: 0;
}

.ftp-page .card-head {
  flex-wrap: wrap;
}

.ftp-page .table {
  min-width: 720px;
}

.ftp-page .banner {
  margin-bottom: 12px;
}

.ftp-page .ftp-stat,
.ftp-page .ftp-sched,
.ftp-page .ftp-sched-left,
.ftp-page .ftp-sched-right,
.ftp-page .ftp-sched-group,
.ftp-page .ftp-sched-time-row {
  min-width: 0;
}

.ftp-page .ftp-stat {
  overflow: visible;
}

.ftp-page .ftp-stat-value,
.ftp-page .ftp-stat-meta {
  white-space: normal !important;
  overflow: visible;
  text-overflow: clip;
  overflow-wrap: anywhere;
}

.ftp-page .ftp-sched {
  grid-template-columns: minmax(0, 1fr);
  overflow: visible;
}

.ftp-page .ftp-sched-left {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}

.ftp-page .ftp-sched-group--tz {
  grid-column: 1 / -1;
}

.ftp-page .ftp-sched-bare {
  width: 100%;
  min-width: 0;
}

.ftp-page .ftp-sched-right {
  flex-wrap: wrap;
  grid-column: 1 / -1;
  width: 100%;
  justify-content: flex-start;
}

.ftp-page .ftp-sched-status {
  flex: 1 1 220px;
  min-width: 0;
  max-width: 100%;
  flex-wrap: wrap;
}

.ftp-page .ftp-sched-status-badge,
.ftp-page .ftp-sched-status-meta {
  min-width: 0;
  max-width: 100%;
  white-space: normal;
  overflow-wrap: anywhere;
}

@media (max-width: 700px) {
  .ftp-page-header {
    display: block;
  }

  .ftp-page .ftp-sched-left {
    grid-template-columns: 1fr;
  }

  .ftp-page .table {
    min-width: 640px;
  }

  .ftp-page .ftp-sched-save-btn {
    width: 100%;
  }
}

/* `vendor_book_check.html` Bucket 3 helpers. Scoped polish for the five-tab
   Vendor API Scan admin surface: compact cards, metrics, forms, async tables,
   API examples, and utility empty states. */
.vendor-book-subnav {
  flex-wrap: wrap;
  overflow-x: visible;
  margin-bottom: 18px;
}

.vendor-book-tab-panel {
  display: grid;
  gap: 14px;
  min-width: 0;
}

.vendor-book-upload-top-grid {
  display: grid;
  grid-template-columns: minmax(0, 3fr) minmax(300px, 2fr);
  gap: 14px;
  align-items: stretch;
}

.vendor-book-upload-top-grid > .vendor-book-card {
  min-width: 0;
}

.vendor-book-tab-panel[hidden] {
  display: none !important;
}

.vendor-book-page .card,
.vendor-book-page .table-wrap {
  min-width: 0;
}

.vendor-book-card {
  border-radius: 8px;
}

.vendor-book-page .card-body {
  padding: 14px 16px;
}

.vendor-book-card-head,
.vendor-book-key-actions,
.vendor-book-log-filter-actions,
.vendor-book-test-actions,
.vendor-book-client-create-form {
  flex-wrap: wrap;
}

.vendor-book-card-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: 15px;
  font-weight: 650;
  letter-spacing: 0;
}

.vendor-book-card-title [data-lucide] {
  width: 18px;
  height: 18px;
  color: var(--text-muted);
}

.vendor-book-key-heading,
.vendor-book-key-value {
  display: block;
}

.vendor-book-key-heading {
  margin-top: 8px;
}

.vendor-book-key-value,
.vendor-book-base-url,
.vendor-book-api-endpoint code,
.vendor-book-scope-summary {
  overflow-wrap: anywhere;
}

.vendor-book-form,
.vendor-book-test-grid,
.vendor-book-api-contract,
.vendor-book-program-form,
.vendor-book-scope-picker,
.vendor-book-scope-cell {
  display: grid;
  gap: 12px;
}

.vendor-book-upload-form {
  grid-template-columns: 1fr;
  align-items: stretch;
  gap: 14px;
}

.vendor-book-upload-body,
.vendor-book-upload-card {
  display: grid;
}

.vendor-book-upload-card {
  align-content: start;
}

.vendor-book-upload-body {
  gap: 14px;
}

.vendor-book-guide-notes {
  display: grid;
  gap: 9px;
  color: var(--text-muted);
  font-size: 12px;
  line-height: 1.45;
}

.vendor-book-guide-notes p {
  margin: 0;
}

.vendor-book-guide-notes strong {
  color: var(--text);
  font-weight: 700;
}

.vendor-book-upload-controls {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

.vendor-book-program-form {
  grid-template-columns: minmax(130px, 0.6fr) minmax(220px, 1fr) auto;
  align-items: end;
  margin-bottom: 12px;
}

.vendor-book-client-create-form {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: min(520px, 100%);
}

.vendor-book-client-create-form .input {
  flex: 1 1 220px;
  min-width: 220px;
}

.vendor-book-field--action {
  align-self: end;
}

.vendor-book-dropzone {
  position: relative;
  display: grid;
  grid-template-columns: 38px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  min-height: 76px;
  padding: 12px 14px;
  border: 1px dashed var(--border-strong);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
}

.vendor-book-dropzone:hover {
  border-color: var(--brand);
  background: var(--bg-elev);
}

.vendor-book-dropzone .vendor-book-file-input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.vendor-book-dropzone-icon,
.vendor-book-metric-icon {
  display: inline-grid;
  place-items: center;
  border-radius: 8px;
  flex: 0 0 auto;
}

.vendor-book-dropzone-icon {
  width: 38px;
  height: 38px;
  background: var(--surface-2);
}

.vendor-book-dropzone-icon [data-lucide] {
  width: 20px;
  height: 20px;
}

.vendor-book-dropzone-copy {
  display: grid;
  gap: 2px;
  min-width: 0;
  font-size: 12px;
}

.vendor-book-file-text {
  overflow: hidden;
  color: var(--text);
  font-size: 13px;
  text-overflow: ellipsis;
  white-space: normal;
}

.vendor-book-choose-file {
  position: relative;
  z-index: 1;
  pointer-events: none;
}

.vendor-book-upload-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 16px;
  align-items: center;
  justify-content: flex-end;
}

.vendor-book-upload-actions .btn {
  justify-content: center;
}

.vendor-book-upload-actions .btn--primary {
  min-width: 150px;
}

.vendor-book-metric-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(136px, 1fr));
  gap: 10px;
  margin-bottom: 12px;
}

.vendor-book-metric-strip--four {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.vendor-book-metric {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  grid-template-areas:
    "icon label"
    "icon value";
  align-items: center;
  gap: 2px 10px;
  min-width: 0;
  min-height: 58px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

.vendor-book-metric--summary {
  min-height: 76px;
}

.vendor-book-metric-icon {
  grid-area: icon;
  width: 32px;
  height: 32px;
}

.vendor-book-metric-icon [data-lucide] {
  width: 17px;
  height: 17px;
}

.vendor-book-metric-icon--green { background: var(--ok-soft); color: var(--ok); }
.vendor-book-metric-icon--blue { background: var(--info-soft); color: var(--info); }
.vendor-book-metric-icon--orange { background: var(--brand-soft); color: var(--brand-deep); }
.vendor-book-metric-icon--red { background: var(--danger-soft); color: var(--danger); }
.vendor-book-metric-icon--purple { background: color-mix(in srgb, var(--chart-3) 14%, var(--surface)); color: var(--chart-3); }

.vendor-book-metric-label {
  grid-area: label;
  color: var(--text-muted);
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1.25;
}

.vendor-book-metric-value {
  grid-area: value;
  min-width: 0;
  color: var(--text);
  font-size: 18px;
  font-weight: 650;
  line-height: 1.15;
  letter-spacing: 0;
  overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums;
}

.vendor-book-metric-value--compact {
  font-size: 13px;
  line-height: 1.25;
}

.vendor-book-client-kpi-card .card-body {
  padding-top: 0;
}

.vendor-book-client-kpi-head {
  align-items: flex-start;
  gap: 16px;
}

.vendor-book-client-kpi-copy {
  min-width: 0;
}

.vendor-book-client-kpi-controls {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-left: auto;
  white-space: nowrap;
}

.vendor-book-client-kpi-window-form {
  margin: 0;
}

.vendor-book-client-kpi-select {
  width: 98px;
  min-height: 34px;
  padding: 6px 30px 6px 10px;
  font-size: 13px;
  font-weight: 600;
}

.vendor-book-client-kpi-window {
  display: inline-flex;
  align-items: center;
  padding-right: 10px;
}

.vendor-book-client-kpi-updated {
  color: var(--text-muted);
  font-size: 12px;
}

.vendor-book-page .vendor-book-client-kpi-table {
  width: max(100%, 920px);
  min-width: 920px;
}

.vendor-book-client-kpi-table {
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 13px;
}

.vendor-book-client-kpi-table th {
  padding: 9px 14px;
  background: var(--surface);
  color: var(--text-muted);
  font-size: 13px;
  font-weight: 600;
  text-transform: none;
  vertical-align: middle;
}

.vendor-book-client-kpi-table td {
  padding: 10px 14px;
  font-size: 13px;
}

.vendor-book-client-kpi-table th:nth-child(1) { width: 18%; }
.vendor-book-client-kpi-table th:nth-child(2) { width: 11%; }
.vendor-book-client-kpi-table th:nth-child(3) { width: 11%; }
.vendor-book-client-kpi-table th:nth-child(4) { width: 11%; }
.vendor-book-client-kpi-table th:nth-child(5) { width: 11%; }
.vendor-book-client-kpi-table th:nth-child(6) { width: 12%; }
.vendor-book-client-kpi-table th:nth-child(7) { width: 13%; }
.vendor-book-client-kpi-table th:nth-child(8) { width: 13%; }

.vendor-book-kpi-sort {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  line-height: 1.2;
  text-align: left;
  cursor: pointer;
}

.vendor-book-kpi-sort:hover {
  color: var(--text);
}

.vendor-book-kpi-sort [data-lucide] {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
}

.vendor-book-kpi-sort--blocked [data-lucide] {
  color: var(--danger);
}

.vendor-book-kpi-sort--ok [data-lucide] {
  color: var(--ok);
}

.vendor-book-kpi-sort--warning [data-lucide] {
  color: var(--brand);
}

.vendor-book-kpi-sort-sub {
  display: block;
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 500;
}

.vendor-book-kpi-sort-indicator::before {
  content: "\2195";
  color: var(--text-muted);
  font-size: 11px;
  opacity: 0.65;
}

.vendor-book-client-kpi-table th[aria-sort="ascending"] .vendor-book-kpi-sort-indicator::before {
  content: "\2191";
  color: var(--brand);
  opacity: 1;
}

.vendor-book-client-kpi-table th[aria-sort="descending"] .vendor-book-kpi-sort-indicator::before {
  content: "\2193";
  color: var(--brand);
  opacity: 1;
}

.vendor-book-kpi-num {
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-weight: 650;
}

.vendor-book-client-kpi-table td.vendor-book-kpi-value--blocked {
  color: var(--danger);
}

.vendor-book-client-kpi-table td.vendor-book-kpi-value--ok {
  color: var(--ok);
}

.vendor-book-client-kpi-table td.vendor-book-kpi-value--warning {
  color: var(--brand-deep);
}

.vendor-book-client-kpi-empty {
  min-height: 74px;
}

.vendor-book-metric-value--trend,
.vendor-book-activity-cell {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.vendor-book-period {
  color: var(--text-subtle);
  font-size: 10px;
  font-weight: 650;
  text-transform: uppercase;
}
/* Dark: --text-subtle (#6e7a8f) on the metric card = 3.67:1, AA fail for
   this 10px label. Bump to --text-muted (~6:1) in dark only. */
[data-theme="dark"] .vendor-book-period {
  color: var(--text-muted);
}

.vendor-book-sync-note {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--text-muted);
  font-size: 11.5px;
  font-weight: 650;
  white-space: nowrap;
}

.vendor-book-sync-note [data-lucide] {
  width: 14px;
  height: 14px;
}

.vendor-book-sync-note--stale {
  color: var(--warn);
}

.vendor-book-sync-note--stale [data-lucide] {
  stroke: var(--warn);
}

.vendor-book-trend {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 18px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 10.5px;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
}

.vendor-book-trend--up,
.vendor-book-trend--new {
  background: var(--ok-soft);
  color: var(--ok);
}

.vendor-book-trend--down {
  background: var(--danger-soft);
  color: var(--danger);
}

.vendor-book-trend--pending {
  background: var(--warn-soft);
  color: var(--warn);
}

.vendor-book-activity-cell strong {
  min-width: 20px;
  color: var(--text);
  font-size: 13px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

.vendor-book-table-wrap {
  box-shadow: none;
  max-width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
}

.vendor-book-data-table th {
  padding: 7px 8px;
  font-size: 11px;
  letter-spacing: 0;
  line-height: 1.2;
  white-space: normal;
}

.vendor-book-data-table .vendor-book-tip-trigger {
  white-space: normal;
}

.vendor-book-data-table td {
  padding: 8px;
  vertical-align: middle;
  overflow-wrap: normal;
  word-break: normal;
}

.vendor-book-page .table {
  width: 100%;
  min-width: 0;
  table-layout: fixed;
}

.vendor-book-page .vendor-book-uploads-table {
  width: max(100%, 1280px);
  min-width: 1280px;
}

.vendor-book-uploads-table {
  font-size: 12px;
}

.vendor-book-clients-table {
  font-size: 12px;
}

.vendor-book-lookup-table {
  font-size: 12px;
}

.vendor-book-archive-table {
  min-width: 0;
}

.vendor-book-log-filter-actions,
.vendor-book-test-actions,
.vendor-book-copy-field,
.vendor-book-code-head,
.vendor-book-api-contract-summary {
  display: flex;
  gap: 8px;
  align-items: center;
}

.vendor-book-programs-table th:nth-child(1) { width: 42%; }
.vendor-book-programs-table th:nth-child(2) { width: 22%; }
.vendor-book-programs-table th:nth-child(3) { width: 16%; }
.vendor-book-programs-table th:nth-child(4) { width: 20%; }

.vendor-book-program-actions {
  text-align: right;
  white-space: nowrap;
}

.vendor-book-program-actions > * {
  display: inline-flex;
  vertical-align: middle;
}

.vendor-book-cell-actions .row {
  margin: 0;
}

.vendor-book-program-actions > .row,
.vendor-book-client-actions > .row,
.vendor-book-lookup-table td.vendor-book-cell-actions > .row {
  display: inline-flex;
}

.vendor-book-uploads-table th:nth-child(1) { width: 7%; }
.vendor-book-uploads-table th:nth-child(2) { width: 6%; }
.vendor-book-uploads-table th:nth-child(3) { width: 9%; }
.vendor-book-uploads-table th:nth-child(4) { width: 6%; }
.vendor-book-uploads-table th:nth-child(5) { width: 6%; }
.vendor-book-uploads-table th:nth-child(6) { width: 7%; }
.vendor-book-uploads-table th:nth-child(7) { width: 7%; }
.vendor-book-uploads-table th:nth-child(8) { width: 7%; }
.vendor-book-uploads-table th:nth-child(9) { width: 6%; }
.vendor-book-uploads-table th:nth-child(10) { width: 6%; }
.vendor-book-uploads-table th:nth-child(11) { width: 6%; }
.vendor-book-uploads-table th:nth-child(12) { width: 6%; }
.vendor-book-uploads-table th:nth-child(13) { width: 6%; }
.vendor-book-uploads-table th:nth-child(14) { width: 15%; }

.vendor-book-uploads-table th,
.vendor-book-uploads-table td {
  padding-left: 7px;
  padding-right: 7px;
}

.vendor-book-uploads-table td:nth-child(6),
.vendor-book-uploads-table td:nth-child(7),
.vendor-book-uploads-table td:nth-child(8),
.vendor-book-uploads-table td:nth-child(9),
.vendor-book-uploads-table td:nth-child(10),
.vendor-book-uploads-table td:nth-child(11),
.vendor-book-uploads-table td:nth-child(12) {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.vendor-book-upload-actions-cell {
  text-align: left;
  white-space: normal;
}

.vendor-book-upload-actions-cell > * {
  display: flex;
  width: fit-content;
  margin-bottom: 5px;
}

.vendor-book-upload-actions-cell > *:last-child {
  margin-bottom: 0;
}

.vendor-book-upload-actions-cell .btn {
  min-height: 26px;
  padding: 4px 7px;
}

.vendor-book-clients-table th:nth-child(1) { width: 12%; }
.vendor-book-clients-table th:nth-child(2) { width: 9%; }
.vendor-book-clients-table th:nth-child(3) { width: 12%; }
.vendor-book-clients-table th:nth-child(4) { width: 27%; }
.vendor-book-clients-table th:nth-child(5) { width: 7%; }
.vendor-book-clients-table th:nth-child(6) { width: 10%; }
.vendor-book-clients-table th:nth-child(7) { width: 9%; }
.vendor-book-clients-table th:nth-child(8) { width: 14%; }

.vendor-book-clients-table td {
  padding-top: 7px;
  padding-bottom: 7px;
}

.vendor-book-client-actions {
  text-align: right;
  white-space: normal;
}

.vendor-book-client-action-group {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: 4px;
  max-width: 100%;
}

.vendor-book-client-actions > *,
.vendor-book-client-action-group > * {
  display: inline-flex;
  margin: 0;
  vertical-align: middle;
}

.vendor-book-client-actions > *:first-child {
  margin-left: 0;
}

.vendor-book-client-actions .btn {
  min-height: 26px;
  padding: 4px 6px;
  white-space: nowrap;
}

.vendor-book-lookup-table th:nth-child(1) { width: 5.5%; }
.vendor-book-lookup-table th:nth-child(2) { width: 8%; }
.vendor-book-lookup-table th:nth-child(3) { width: 7%; }
.vendor-book-lookup-table th:nth-child(4) { width: 7%; }
.vendor-book-lookup-table th:nth-child(5) { width: 6%; }
.vendor-book-lookup-table th:nth-child(6) { width: 7%; }
.vendor-book-lookup-table th:nth-child(7) { width: 9.5%; }
.vendor-book-lookup-table th:nth-child(8) { width: 5.5%; }
.vendor-book-lookup-table th:nth-child(9) { width: 3.5%; }
.vendor-book-lookup-table th:nth-child(10) { width: 8%; }
.vendor-book-lookup-table th:nth-child(11) { width: 6%; }
.vendor-book-lookup-table th:nth-child(12) { width: 7.5%; }
.vendor-book-lookup-table th:nth-child(13) { width: 10%; }
.vendor-book-lookup-table th:nth-child(14) { width: 9.5%; }

.vendor-book-lookup-table td:nth-child(8),
.vendor-book-lookup-table td:nth-child(9),
.vendor-book-lookup-table td:nth-child(11),
.vendor-book-lookup-table td:nth-child(12) {
  text-align: center;
}

.vendor-book-lookup-table td:nth-child(8),
.vendor-book-lookup-table td:nth-child(9) {
  font-variant-numeric: tabular-nums;
}

.vendor-book-lookup-table .vendor-book-cell-actions {
  text-align: center;
}

.vendor-book-data-table td.vendor-book-cell-actions {
  display: table-cell;
  vertical-align: middle;
}

.vendor-book-lookup-table td.vendor-book-cell-actions > * {
  display: inline-flex;
  vertical-align: middle;
}

.vendor-book-cell-buyer-bin,
.vendor-book-data-table code,
.vendor-book-lookup-table td:nth-child(10) {
  overflow-wrap: anywhere;
}

.vendor-book-lookup-table td:nth-child(13) {
  line-height: 1.25;
}

.vendor-book-table-footer {
  border: 1px solid var(--border);
  border-top: 0;
  border-radius: 0 0 8px 8px;
  background: var(--surface);
}

.vendor-book-page-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  height: 30px;
  padding: 0 9px;
  border: 1px solid var(--brand);
  border-radius: 7px;
  color: var(--brand-deep);
  background: var(--surface);
  font-size: 12px;
  font-weight: 600;
}

.vendor-book-compact-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 68px;
  padding: 14px;
  border: 1px dashed var(--border-strong);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text-muted);
  font-size: 13px;
  text-align: center;
}

.vendor-book-compact-empty [data-lucide] {
  width: 22px;
  height: 22px;
  color: var(--text-subtle);
}

.vendor-book-blocks-layout {
  display: grid;
  grid-template-columns: minmax(180px, 236px) minmax(180px, 236px) minmax(240px, 1fr);
  gap: 12px;
  align-items: stretch;
}

.vendor-book-blocks-empty {
  min-height: 76px;
}

.vendor-book-blocks-panel {
  grid-column: 1 / -1;
  min-width: 0;
}

.vendor-book-access-grid {
  display: grid;
  grid-template-columns: minmax(460px, 1fr) minmax(320px, 0.95fr);
  gap: 14px;
  align-items: start;
}

.vendor-book-scanner-card .card-body {
  display: grid;
  gap: 10px;
}

.vendor-book-copy-field {
  align-items: stretch;
}

.vendor-book-copy-field .input {
  flex: 1 1 auto;
  min-width: 0;
}

.vendor-book-copy-field .input {
  font-family: var(--font-mono);
  font-size: 12.5px;
}

.vendor-book-compact-help {
  margin: 0;
  color: var(--text-muted);
  font-size: 12.5px;
  line-height: 1.45;
}

.vendor-book-compact-help a {
  color: var(--brand-deep);
  text-decoration: none;
}

.vendor-book-scope-input {
  min-width: 130px;
}

.vendor-book-scope-picker {
  gap: 7px;
}

.vendor-book-scope-mode-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  align-items: center;
}

.vendor-book-scope-select-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

.vendor-book-scope-option,
.vendor-book-scope-check {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--text);
  font-size: 12.5px;
  line-height: 1.35;
}

.vendor-book-scope-cell {
  gap: 7px;
}

.vendor-book-scope-summary {
  color: var(--text-muted);
  font-size: 12px;
  line-height: 1.35;
}

.vendor-book-clients-table .vendor-book-scope-picker,
.vendor-book-clients-table .vendor-book-scope-cell {
  gap: 4px;
}

.vendor-book-clients-table .vendor-book-scope-select-row {
  gap: 6px;
}

.vendor-book-clients-table .vendor-book-scope-option,
.vendor-book-clients-table .vendor-book-scope-summary {
  font-size: 11.5px;
  line-height: 1.25;
}

.vendor-book-clients-table .vendor-book-scope-summary {
  display: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.vendor-book-clients-table .vendor-book-scope-option input {
  margin: 0;
}

.vendor-book-scope-dropdown {
  position: relative;
}

.vendor-book-scope-options {
  position: absolute;
  z-index: 1200;
  top: calc(100% + 6px);
  right: 0;
  display: grid;
  gap: 6px;
  width: min(320px, 82vw);
  max-height: 260px;
  overflow-y: auto;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  box-shadow: var(--shadow-lg);
}

.vendor-book-scope-options[hidden] {
  display: none !important;
}

.vendor-book-base-url {
  color: var(--text-muted);
  font-size: 12px;
}

.vendor-book-api-contract {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
}

.vendor-book-api-contract-block,
.vendor-book-api-contract-summary,
.vendor-book-test-result {
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
}

.vendor-book-api-contract-title {
  margin-bottom: 8px;
  font-weight: 700;
}

.vendor-book-api-endpoint {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.vendor-book-api-endpoint span {
  padding: 2px 6px;
  border-radius: 5px;
  color: var(--brand-deep);
  background: var(--brand-soft);
  font-size: 10px;
  font-weight: 700;
}

.vendor-book-api-contract-note {
  margin: 0 0 10px;
  color: var(--text-muted);
  font-size: 12.5px;
  line-height: 1.45;
}

.vendor-book-code-head {
  justify-content: space-between;
  margin: 4px 0 6px;
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 600;
}

.vendor-book-api-contract-pre,
.vendor-book-payload-pre {
  overflow-x: auto;
  margin: 0;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--text);
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.55;
}

.vendor-book-api-contract-summary {
  margin-top: 12px;
  color: var(--text-muted);
  font-size: 12.5px;
  line-height: 1.45;
}

.vendor-book-api-contract-summary [data-lucide] {
  width: 16px;
  height: 16px;
  color: var(--info);
  flex: 0 0 auto;
}

.vendor-book-log-filters {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 12px;
  align-items: end;
  margin-bottom: 12px;
}

.vendor-book-log-filter {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.vendor-book-log-filter label {
  color: var(--text-muted);
  font-size: 12px;
  font-weight: 600;
}

.vendor-book-log-filter input,
.vendor-book-log-filter select {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font: 500 13px/1.4 var(--font-sans);
  box-sizing: border-box;
}

.vendor-book-log-filter select {
  appearance: none;
  padding-right: 32px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' stroke='%235a6778' stroke-width='1.5' fill='none' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
}

.vendor-book-log-filter--message {
  grid-column: span 2;
}

.vendor-book-log-filter-actions {
  justify-content: flex-start;
}

.vendor-book-log-panel {
  min-width: 0;
}

.vendor-book-test-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: end;
  margin-top: 12px;
}

.vendor-book-test-actions {
  margin-top: 12px;
}

.vendor-book-test-actions .btn:disabled {
  border-color: var(--border);
  background: var(--surface-2);
  color: var(--text-subtle);
  box-shadow: none;
  cursor: not-allowed;
}

.vendor-book-test-result {
  margin-top: 12px;
  background: var(--surface);
}

.vendor-book-test-result-badge {
  display: inline-flex;
  margin-bottom: 6px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-muted);
  font-size: 11.5px;
  font-weight: 700;
}

.vendor-book-test-result-badge--ok { background: var(--ok-soft); color: var(--ok); }
.vendor-book-test-result-badge--blocked,
.vendor-book-test-result-badge--error { background: var(--danger-soft); color: var(--danger); }

.vendor-book-test-result-message,
.vendor-book-test-result-meta {
  color: var(--text-muted);
}

.vendor-book-test-payload-card .card-body {
  padding-top: 12px;
}

.vendor-book-payload-empty {
  display: grid;
  justify-items: center;
  gap: 6px;
  min-height: 118px;
  padding: 18px;
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--text-muted);
  text-align: center;
  font-size: 13px;
}

.vendor-book-payload-empty [data-lucide] {
  width: 26px;
  height: 26px;
  color: var(--text-subtle);
}

.vendor-book-payload-empty strong {
  color: var(--text);
  font-weight: 600;
}

.vendor-book-payload-pre {
  max-height: 460px;
}

.vendor-book-row--inactive {
  opacity: 0.68;
}

.vendor-book-info,
.vendor-book-tip-trigger {
  cursor: help;
}

.vendor-book-info {
  display: inline-grid;
  place-items: center;
  width: 16px;
  height: 16px;
  margin-left: 4px;
  border-radius: 999px;
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 700;
}

.vendor-book-tip-trigger {
  border-bottom: 1px dotted var(--border-strong);
}

.vendor-book-tooltip {
  position: fixed;
  z-index: 1400;
  max-width: min(320px, calc(100vw - 24px));
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-lg);
  font-size: 12px;
  line-height: 1.45;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-2px);
  transition: opacity 120ms ease, transform 120ms ease;
}

.vendor-book-tooltip.is-visible {
  opacity: 1;
  transform: translateY(0);
}

@media (max-width: 1180px) {
  .vendor-book-access-grid,
  .vendor-book-log-filters {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .vendor-book-dropzone,
  .vendor-book-log-filter--message {
    grid-column: 1 / -1;
  }

  .vendor-book-metric-strip--four,
  .vendor-book-test-grid,
  .vendor-book-api-contract {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 1100px) {
  .vendor-book-upload-top-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 760px) {
  .vendor-book-upload-form,
  .vendor-book-upload-controls,
  .vendor-book-program-form,
  .vendor-book-access-grid,
  .vendor-book-log-filters,
  .vendor-book-metric-strip--four,
  .vendor-book-test-grid,
  .vendor-book-api-contract,
  .vendor-book-blocks-layout {
    grid-template-columns: 1fr;
  }

  .vendor-book-blocks-panel,
  .vendor-book-log-filter--message {
    grid-column: auto;
  }

  .vendor-book-client-create-form,
  .vendor-book-client-create-form .input,
  .vendor-book-copy-field,
  .vendor-book-test-actions,
  .vendor-book-log-filter-actions,
  .vendor-book-card-head .page-header-actions {
    width: 100%;
  }

  .vendor-book-client-kpi-head {
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
  }

  .vendor-book-client-kpi-controls {
    width: 100%;
    margin-left: 0;
    flex-wrap: wrap;
    white-space: normal;
  }

  .vendor-book-sync-note {
    min-width: 0;
    white-space: normal;
  }

  .vendor-book-client-create-form .btn,
  .vendor-book-copy-field .btn,
  .vendor-book-test-actions .btn,
  .vendor-book-log-filter-actions .btn,
  .vendor-book-upload-actions .btn {
    width: 100%;
    justify-content: center;
  }

  .vendor-book-upload-actions {
    flex-direction: column;
    align-items: stretch;
  }

  .vendor-book-page .table {
    min-width: 760px;
  }

  .vendor-book-table-wrap {
    overflow-x: auto;
    overflow-y: hidden;
  }
}

/* ============= CARDS ============= */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.card-head {
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.card-title { font-size: 14px; font-weight: 600; }
.card-subtitle { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.card-body { padding: 16px 18px; }
.card-body--flush { padding: 0; }

/* ============= AUTH SHELL =============
   Centered card layout for unauthenticated pages (login, etc). The anon
   branch in base.html lacks the sidebar shell and its `<main>` is
   class-less by default, so a bare `.card` would stretch to full width.
   `.auth-shell` adds max-width + auto margin only — visuals come from
   `.card`. Phase 3 has documented intent (see base.html:310 comment) to
   replace this with a brand split-screen layout in a future PR; this
   helper keeps the structure swappable without churning login.html
   again at that time.
*/
.auth-shell {
  max-width: 400px;
  margin: 80px auto;
}
.auth-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* ============= METRIC TILES ============= */
.metric {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.metric-label {
  font-size: 11.5px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
  display: flex; align-items: center; gap: 6px;
}
.metric-value {
  font-size: 26px;
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--text);
}
.metric-value--compact { font-size: 18px; line-height: 1.25; }
.metric-delta {
  font-size: 12px;
  color: var(--text-muted);
  display: flex; align-items: center; gap: 4px;
}
.metric-delta.up { color: var(--ok); }
.metric-delta.down { color: var(--danger); }
.metric-delta [data-lucide] { width: 12px; height: 12px; }
.metric--ok { border-color: color-mix(in srgb, var(--ok) 32%, var(--border)); background: var(--ok-soft); }
.metric--warn { border-color: color-mix(in srgb, var(--warn) 40%, var(--border)); background: var(--warn-soft); }
.metric--danger { border-color: color-mix(in srgb, var(--danger) 36%, var(--border)); background: var(--danger-soft); }

/* ============= PILLS / STATUS ============= */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 600;
  background: var(--surface-2);
  color: var(--text-muted);
  line-height: 1.6;
  white-space: nowrap;
}
.pill .dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
}
.pill [data-lucide] { width: 12px; height: 12px; margin-right: 4px; }
.pill--ok { background: var(--ok-soft); color: var(--ok); }
.pill--warn { background: var(--warn-soft); color: var(--warn); }
.pill--danger { background: var(--danger-soft); color: var(--danger); }
.pill--info { background: var(--info-soft); color: var(--info); }
.pill--brand { background: var(--brand-soft); color: var(--brand-deep); }
/* PR-3b2b: `.pill--muted` Tiger primitive — neutral (off-state, secondary,
 * informational) status that doesn't merit `--info` blue. Used by
 * diagnostics.html for muted state (e.g., webhook integration types,
 * inactive workers count). Codex round-1 review flag — was missing from
 * Tiger pill modifiers, causing visual regression at two callsites. */
.pill--muted { background: var(--surface-2); color: var(--text-muted); }

/* ============= TABLES ============= */
.table-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  /* `overflow-x: auto` lets wide tables scroll horizontally at narrow
     viewports instead of clipping columns; `overflow-y: hidden` keeps
     the rounded-corner crop intact and avoids spurious vertical
     scrollbars on static tables. */
  overflow-x: auto;
  overflow-y: hidden;
  box-shadow: var(--shadow-sm);
}
.table-toolbar {
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 10px;
  background: var(--bg-elev);
}
.table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.table th {
  text-align: left;
  font-size: 11.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-subtle);
  padding: 9px 14px;
  background: var(--bg-elev);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.table td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  vertical-align: middle;
}
.table tr:last-child td { border-bottom: none; }
.table tr:hover td { background: var(--surface-2); }
.table td.num { font-variant-numeric: tabular-nums; text-align: right; }
.table td.mono { font-family: var(--font-mono); font-size: 12.5px; }
.table td.muted { color: var(--text-muted); }
/* PR-3b2b: `.table tr.row-{ok,warn,danger}` row-tone tinting. Replaces the
 * retired `.diagnostics-v2__table .row-{ok,warn,crit}` cascade — Tiger
 * doesn't have built-in row tones. Applies an inset 3px shadow on the
 * first cell so a tinted left bar reads at a glance. */
.table tr.row-ok td:first-child { box-shadow: inset 3px 0 0 var(--ok); }
.table tr.row-warn td:first-child { box-shadow: inset 3px 0 0 var(--warn); }
.table tr.row-danger td:first-child { box-shadow: inset 3px 0 0 var(--danger); }
/* PR-3b2c: `.table tr.row-muted` row-tone for de-emphasized rows
 * (Workers tab uses this for on-demand-only workers). Replaces the
 * retired `.workers-v2__row-muted` cascade. */
.table tr.row-muted td:first-child { box-shadow: inset 3px 0 0 var(--text-subtle); }

/* ============= CHIPS ============= */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-muted);
  cursor: pointer;
}
.chip:hover { color: var(--text); border-color: var(--border-strong); }
.chip.is-active { background: var(--brand-soft); color: var(--brand-deep); border-color: transparent; }

/* ============= SEARCH FIELD (horizontal) =============
   `.field` is the horizontal icon+input pill (topbar search,
   table filter bars). Distinct from `.form-field` below. */
.field {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  font-size: 13px;
  color: var(--text-muted);
}
.field input { border: none; background: transparent; outline: none; flex: 1; font-size: 13px; color: var(--text); font-family: inherit; }
.field [data-lucide], .field svg { width: 14px; height: 14px; flex-shrink: 0; }

/* ============= LAYOUT HELPERS ============= */
.grid { display: grid; gap: 14px; }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* PR-3b2c: `.grid-5` Tiger extension for 5-column KPI rows. Diagnostics
 * Workers tab summary row is 5 stat tiles (Registered / Firing / No Fire /
 * Broken / Coverage Drift). */
.grid-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
/* PR-3b2c: `.swatch` Tiger primitive for color legend swatches (10x10
 * tone-tinted box rendered as `<i class="swatch swatch--ok">`). Used in
 * the Workers tab legend that explains row-tone colors. */
.swatch { display: inline-block; width: 10px; height: 10px; border-radius: 2px; }
.swatch--ok { background: var(--ok); }
.swatch--warn { background: var(--warn); }
.swatch--danger { background: var(--danger); }
.swatch--muted { background: var(--text-subtle); }
.stack { display: flex; flex-direction: column; gap: 16px; }
.row { display: flex; align-items: center; gap: 10px; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
/* PR-3b2a: wrap modifier for `.row`. Bare `.row` is no-wrap; the diagnostics
 * page status pill row + chart-range toolbar need wrap on narrow viewports. */
.row--wrap { flex-wrap: wrap; }
.text-muted { color: var(--text-muted); }
.text-danger { color: var(--danger); font-weight: 600; }
.ml-auto { margin-left: auto; }
.mt-2 { margin-top: 8px; }
.mt-3 { margin-top: 12px; }
.mt-4 { margin-top: 16px; }
.mt-6 { margin-top: 24px; }
.mb-2 { margin-bottom: 8px; }
.mb-3 { margin-bottom: 12px; }
.mb-4 { margin-bottom: 16px; }

/* ============= POPOVER (details/summary dropdown) =============
   Click `<summary>` to open `.popover-menu` floating below. Used by
   table-toolbar filters (multi-select checkboxes), inline overflow
   menus, etc. The native `<details>` element drives the open/close
   state; CSS handles the absolute positioning so the menu doesn't
   shift surrounding layout. */
.popover { position: relative; }
.popover > summary { list-style: none; cursor: pointer; }
.popover > summary::-webkit-details-marker { display: none; }
.popover-menu {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 20;
  min-width: 220px;
  max-height: 280px;
  overflow: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: 10px;
  flex-direction: column;
  gap: 6px;
  box-shadow: var(--shadow-lg);
}
.popover[open] > .popover-menu { display: flex; }
.popover-menu label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  cursor: pointer;
}

/* ============= INLINE-EDIT PATTERN =============
   `.action-stack` wraps a row of action buttons + a hidden rename
   form. Existing dashboard JS (data-edit-toggle / data-edit-form /
   data-edit-cancel) toggles `is-active` on the form; CSS uses :has()
   to hide the action row while editing. */
.action-stack { display: flex; flex-direction: column; gap: 6px; }
.action-row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.action-stack:has(.edit-form.is-active) .action-row { display: none; }

.script-archive-panel {
  border-top: 1px solid var(--line);
  padding-top: 12px;
}
.script-archive-summary {
  align-items: center;
  cursor: pointer;
  display: flex;
  gap: 8px;
  list-style: none;
  margin-bottom: 10px;
}
.script-archive-summary::-webkit-details-marker {
  display: none;
}

.sx-archive-banner {
  align-items: center;
  background: #fff1f2;
  border: 1px solid #fecdd3;
  border-radius: 8px;
  color: #7f1d1d;
  display: flex;
  gap: 12px;
  justify-content: space-between;
  margin: 0 0 16px;
  padding: 12px 14px;
}

.sx-archive-banner span {
  color: #991b1b;
  margin-left: 8px;
}

.sx-archive-banner-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.edit-form { display: none; gap: 6px; align-items: center; flex-wrap: wrap; }
.edit-form.is-active { display: flex; }
.edit-toggle.is-hidden { display: none; }

/* ============= DASHBOARD TAB MIGRATION ============= */
.dashboard-section-head {
  align-items: flex-start;
  flex-wrap: wrap;
}

.dashboard-actions,
.dashboard-inline {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.dashboard-strong {
  font-weight: 600;
  color: var(--text);
}

.dashboard-filter-grid {
  display: grid;
  gap: 14px;
  align-items: end;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-elev);
}
.dashboard-filter-grid--runs { grid-template-columns: minmax(180px, 1fr) minmax(380px, 1.8fr) minmax(160px, 0.8fr) minmax(240px, 0.9fr) auto; }
/* Halve only the Date <select>, not the whole Date column. The column
   still has to fit the custom-range two-input row when the user picks
   "Custom range" (caught by Codex round 1 — naively halving the column
   crushed the from/to inputs). The select cap delivers the user's
   visual intent ("Date dropdown about half width") without breaking
   the custom-range layout. */
.dashboard-filter-grid--runs #runs-range { max-width: 130px; }
.dashboard-filter-grid--tickets { grid-template-columns: minmax(160px, 0.9fr) minmax(180px, 1fr) minmax(160px, 0.9fr) minmax(240px, 1.1fr) minmax(230px, 1.2fr) auto; }
.dashboard-filter-actions {
  align-self: end;
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
}
.dashboard-check-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  min-width: 0;
}
.dashboard-check-grid--compact { gap: 8px; }

.dashboard-date-range {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-muted);
}
.dashboard-date-range[data-run-date-range] { display: none; }
.dashboard-date-range[data-run-date-range].is-active { display: flex; }

.dashboard-metric-grid {
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}
.dashboard-card-grid {
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}

.dashboard-toggle-form {
  display: none;
  padding: 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}
.dashboard-toggle-form.is-active {
  display: block;
}
.dashboard-form-grid {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.dashboard-field-wide {
  grid-column: 1 / -1;
}

.dashboard-upload-row {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) auto;
  gap: 16px;
  align-items: end;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-elev);
}
.dashboard-page-size-form {
  display: flex;
  align-items: center;
  gap: 8px;
  justify-content: flex-end;
}
.dashboard-select-sm { width: auto; min-width: 92px; }

.dashboard-mono-link {
  font-family: var(--font-mono);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--brand-deep);
}
.dashboard-mono-link:hover { text-decoration: underline; }

/* Per-status tones — five distinct colors so the filter chips and the
   table pills visually map 1:1 to the result row's status. */
.dashboard-status[data-status="requested"] { background: var(--brand-soft); color: var(--brand-deep); }
.dashboard-status[data-status="running"] { background: var(--info-soft); color: var(--info); }
.dashboard-status[data-status="queued"] { background: var(--warn-soft); color: var(--warn); }
.dashboard-status[data-status="success"],
.dashboard-status[data-status="completed"] { background: var(--ok-soft); color: var(--ok); }
.dashboard-status[data-status="error"],
.dashboard-status[data-status="error_manual"],
.dashboard-status[data-status="failed"] { background: var(--danger-soft); color: var(--danger); }

/* Status-chip filter — interactive cousin of .dashboard-status. The
   container lets chips wrap inline; the chips themselves are <button>
   elements with aria-pressed state. Hidden <input type="checkbox">
   siblings carry the form-submit value (synced via inline JS). */
.dashboard-status-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.dashboard-status-chip {
  display: inline-flex;
  align-items: center;
  padding: 3px 10px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--text-muted);
  font: 600 12px 'Inter', sans-serif;
  cursor: pointer;
  user-select: none;
  transition: background-color 120ms, color 120ms, border-color 120ms;
}
.dashboard-status-chip:hover {
  background: var(--surface-hover);
  color: var(--text);
}
.dashboard-status-chip:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}
.dashboard-status-chip[aria-pressed="true"][data-status="requested"] { background: var(--brand-soft); color: var(--brand-deep); border-color: color-mix(in srgb, var(--brand) 30%, transparent); }
.dashboard-status-chip[aria-pressed="true"][data-status="running"]   { background: var(--info-soft);  color: var(--info);       border-color: color-mix(in srgb, var(--info) 30%, transparent); }
.dashboard-status-chip[aria-pressed="true"][data-status="queued"]    { background: var(--warn-soft);  color: var(--warn);       border-color: color-mix(in srgb, var(--warn) 30%, transparent); }
.dashboard-status-chip[aria-pressed="true"][data-status="error"]     { background: var(--danger-soft); color: var(--danger);    border-color: color-mix(in srgb, var(--danger) 30%, transparent); }
.dashboard-status-chip[aria-pressed="true"][data-status="success"]   { background: var(--ok-soft);    color: var(--ok);         border-color: color-mix(in srgb, var(--ok) 30%, transparent); }

.dashboard-live-row td {
  padding-top: 0;
  background: var(--surface);
}
.dashboard-live-log {
  display: none;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #0f172a;
  overflow: hidden;
}
.dashboard-live-log.is-open { display: block; }
.dashboard-log-output {
  max-height: 360px;
  min-height: 180px;
  margin: 0;
  padding: 12px;
  overflow: auto;
  color: #e2e8f0;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  white-space: pre-wrap;
}

.dashboard-rich-text {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
}
.dashboard-rich-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px;
  border-bottom: 1px solid var(--border);
  background: var(--bg-elev);
}
.dashboard-rich-select {
  width: auto;
  min-width: 110px;
  min-height: 30px;
  padding-block: 4px;
}
.dashboard-rich-editor {
  min-height: 140px;
  padding: 12px;
  outline: none;
  color: var(--text);
}
.dashboard-rich-editor:focus {
  box-shadow: inset 0 0 0 2px color-mix(in oklab, var(--brand) 35%, transparent);
}
.dashboard-rich-source { display: none; }

.dashboard-alert-table,
.dashboard-runs-table,
.dashboard-scheduled-table,
.dashboard-contacts-table {
  min-width: 920px;
}

@media (max-width: 1220px) {
  .dashboard-filter-grid,
  .dashboard-filter-grid--runs,
  .dashboard-filter-grid--tickets {
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  }
  .dashboard-filter-actions { justify-content: flex-start; }
  .dashboard-upload-row { grid-template-columns: 1fr; }
}

/* Scrollbar */
.sidebar-nav::-webkit-scrollbar { width: 6px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--sidebar-muted) 40%, transparent); border-radius: 3px; }

/* Data viz */
.bar {
  height: 6px;
  border-radius: 4px;
  background: var(--surface-2);
  overflow: hidden;
  position: relative;
}
.bar > span {
  display: block;
  height: 100%;
  background: var(--brand);
  border-radius: 4px;
}
.spark { display: block; width: 100%; height: 42px; }
.spark path.area { fill: var(--brand); opacity: 0.12; }
.spark path.line { stroke: var(--brand); stroke-width: 1.8; fill: none; }

.hr { height: 1px; background: var(--border); border: none; margin: 0; }

.dashed-box {
  border: 1px dashed var(--border-strong);
  border-radius: 8px;
  padding: 12px;
  color: var(--text-subtle);
  font-family: var(--font-mono);
  font-size: 12px;
  text-align: center;
  background: var(--bg-elev);
}

/* Lucide icon defaults across the app */
[data-lucide] {
  width: 16px;
  height: 16px;
  stroke-width: 1.75;
  vertical-align: -3px;
}

/* ============================================================
   FORMS / STATES — ported from handoff/mocks/forms-and-states.css
   ============================================================ */

.input,
.select,
.textarea {
  width: 100%;
  padding: 8px 10px;
  font: 500 13px/1.4 'Inter', sans-serif;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  outline: none;
  box-sizing: border-box;
  transition: border-color 120ms, box-shadow 120ms;
}
.textarea { min-height: 96px; resize: vertical; font-family: 'Inter', sans-serif; }
.textarea--mono {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12.5px;
  line-height: 1.55;
}

/* ============= GLOSSARY SHELL =============
   Layout helpers for purchase_bot_audit_glossary.html. The page is a
   single narrow-card editor surface in the authenticated branch — the
   authenticated `<main>` is class-less by default, so the template
   provides its own centering and width cap. Visuals come from `.card`;
   these helpers are layout-only.
*/
.glossary-shell {
  max-width: 860px;
  margin: 24px auto;
  padding: 0 20px 48px;
}
.glossary-header {
  margin-bottom: 20px;
}
.glossary-actions-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 12px;
}

/* ============= ADMIN PAGE PERF SHELL =============
   Layout helpers for admin_page_perf.html. Wide-format admin diagnostic
   surface; the authenticated `<main>` in base.html is class-less by
   default, so the template provides its own centering and width cap.
   Sibling spacing inside the shell uses a single consistent rhythm via
   the `> * + *` rule (24px between major sections; the h3 subheading
   gets slightly more vertical breathing room).
*/
.admin-page-perf-shell {
  max-width: 1600px;
  margin: 0 auto;
  padding: 24px 32px 48px;
}
.admin-page-perf-shell > * + * {
  margin-top: 20px;
}
.admin-page-perf-shell > h3 {
  margin-top: 24px;
  margin-bottom: 12px;
}
.admin-page-perf-alerts {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.admin-page-perf-alert-meta {
  display: flex;
  gap: 10px;
  align-items: center;
  margin-bottom: 4px;
}
.admin-page-perf-alert-detail {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-muted);
  white-space: pre-wrap;
  margin-top: 4px;
}

/* Generic responsive grid for `.metric` siblings — auto-fit columns sized
   to the metric's content. Likely reusable by future migrated templates
   that surface a row of dashboard counters; namespaced neutrally.
*/
.metric-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
}

/* ============= ADMIN USERS SHELL =============
   Layout helpers for admin_users.html. Authenticated `<main>` is
   class-less by default; the template provides its own centering and
   width cap. Sibling rhythm via `> * + *` matches the admin-page-perf
   pattern.
*/
.admin-users-shell {
  max-width: 1400px;
  margin: 0 auto;
  padding: 24px 32px 48px;
}
.admin-users-shell > * + * {
  margin-top: 20px;
}
.admin-users-identity {
  display: flex;
  align-items: center;
  gap: 10px;
}
.admin-users-avatar {
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-2);
  color: var(--text-muted);
  font: 600 12px 'Inter', sans-serif;
  text-transform: uppercase;
}
.admin-users-sort-link {
  color: inherit;
  text-decoration: none;
}
.admin-users-sort-link:hover {
  color: var(--brand-deep);
}
.admin-users-sort-link.is-active {
  color: var(--text);
  font-weight: 700;
}
.admin-users-sort-arrow {
  font-size: 11px;
  margin-left: 2px;
}

/* ============= ADMIN USER EDIT SHELL =============
   Layout helpers for admin_user_edit.html. Form-with-sidecard layout
   wrapped in the legacy .panel surface (panel preserved per the
   Phase 2.5 deferred-utility plan; visuals stay consistent with other
   .panel pages until that sweep lands).
*/
.admin-user-edit-shell {
  max-width: 1200px;
  margin: 24px auto;
}
.admin-user-edit-layout {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: 20px;
  margin-top: 16px;
}
@media (max-width: 900px) {
  .admin-user-edit-layout {
    grid-template-columns: 1fr;
  }
}
.admin-user-edit-section + .admin-user-edit-section {
  margin-top: 28px;
}
.admin-user-edit-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
  margin-top: 12px;
}
.admin-user-edit-grid--access {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
@media (max-width: 700px) {
  .admin-user-edit-grid--access {
    grid-template-columns: 1fr;
  }
}
.admin-user-edit-toggle-card {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  cursor: pointer;
}
.admin-user-edit-toggle-card > input[type="checkbox"] {
  margin-top: 3px;
}
.admin-user-edit-toggle-card > span {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.admin-user-edit-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

/* ============= CREDENTIALS NOTE PAGE =============
   Layout helpers for credentials_note.html. The textarea persists its
   resized width/height via two CSS custom properties set on the
   element's inline `style="..."` attribute (Python templates the saved
   values; JS then reads/writes the resulting offsetWidth/offsetHeight
   into hidden form inputs on every resize so the size survives the
   round trip). Helper names deliberately use the `credentials-note-page-`
   prefix so they don't substring-match the LEGACY_CLASS_BASES entry
   `credentials-note-shell`.
*/
.credentials-note-page {
  max-width: 1080px;
  margin: 24px auto;
}
.credentials-note-page-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
  margin-bottom: 8px;
}
.credentials-note-page-textarea {
  /* Cap the saved width at the container so a width persisted from a
     wider viewport doesn't overflow when the user reopens the page in a
     narrower sidebar layout. Caught by Codex round 2 — matches the
     legacy rule's `min(100%, ...)` clamp. */
  width: min(100%, var(--credentials-note-width, 100%));
  height: var(--credentials-note-height, 480px);
  min-height: 360px;
  /* Override the .textarea base `resize: vertical`. The credentials
     editor's ResizeObserver-driven JS persists BOTH width and height
     (see template inline script + the matching --credentials-note-*
     CSS custom props), and the toolbar advertises "Resizable editor".
     Caught by Codex round 1 review of the Phase 3.x migration. */
  resize: both;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 13px;
  line-height: 1.5;
}
.credentials-note-page-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
}

/* ============= PROFILE PAGE =============
   Layout helpers for profile.html. Wrapped in legacy `.panel` + `.ghost`
   shared utilities preserved per the Phase 2.5 deferral. The Edit button
   keeps its legacy `.ghost` class alongside the new `.btn .btn--ghost`
   so visuals match other migrated pages while the Phase 2.5 utility
   sweep stays deferred.
*/
.profile-page {
  max-width: 720px;
  margin: 24px auto;
}
.profile-page-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
  margin-top: 16px;
}
.profile-page-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

/* ============= AWS DETAILS PAGE =============
   Layout helpers for aws_details.html. Single-form maintenance-note
   page wrapped in legacy `.panel` (preserved per Phase 2.5 deferral).
   The original template's only `.panel` consumer; total surface is
   2 helpers + the .panel wrap.
*/
.aws-details-page {
  max-width: 960px;
  margin: 24px auto;
}
.aws-details-page-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 12px;
}

/* ============= KEEPA TIGER OVERLAY =============
   `.keepa-tiger-overlay` lives on the keepa_dashboard.html page wrapper.
   It scopes Tiger-tone retargets onto the legacy bbs-* / function-page-*
   classes that the page (and its included _keepa_engine_header.html) use.
   This is a SURGICAL FIX, not a global token rewrite: rules outside the
   overlay scope keep their legacy behavior, so engine_dashboard and
   other LEGACY templates that share these class definitions are not
   affected.

   The user-visible regressions this fixes on the Keepa dashboard:
   1. Active subnav tab — was `background:#1e3a8a;color:#fff` deep navy,
      now Tiger orange underline + brand-deep text.
   2. Primary button (Keepa Settings) — explicit btn.btn--primary on the
      anchor renders Tiger orange via the existing .btn--primary rule.
   3. bbs-stat side accents — retargeted to Tiger ok / warn / danger
      tokens.
   4. Metric numbers — display-typography token + larger weight, matching
      theme_br's .metric-value. (Polish 2: --font-display now resolves to
      Inter; hierarchy via weight + size, not family-switch.)
   5. Warning banners — warm amber accent.
   6. Healthy broker pulse — green accent.
   7. The bbs-pill base + variants — retargeted to soft tokens so they
      match the in-Tiger pill family the migrated dashboards use.
*/

/* Active subnav tab — orange underline + brand-deep text instead of
   the legacy `background:#1e3a8a;color:#fff` filled state. */
.keepa-tiger-overlay .function-page-tab.is-active,
.keepa-tiger-overlay .function-page-tab[aria-current="page"] {
  background: transparent;
  color: var(--brand-deep);
  border-color: transparent;
  border-bottom: 2px solid var(--brand);
  border-radius: 0;
  /* Polish 2 §4a: weight 600 (was 700). Matches the Scripts canonical
     .subnav-tab.is-active rule. */
  font-weight: 600;
}
.keepa-tiger-overlay .function-page-tab.is-active:hover,
.keepa-tiger-overlay .function-page-tab[aria-current="page"]:hover {
  /* Polish 2 §4a: hover stays flat — no background change. The earlier
     `var(--surface-2)` paint on active-tab hover collided with the
     app-wide flat-tab treatment because `.keepa-tiger-overlay` (0,3,1)
     out-specifics the global flat rule. Codex round-3 review flag. */
  background: transparent;
  color: var(--brand-deep);
}

/* Metric cards — soften card chrome, retarget side accent + value
   typography to Tiger primitives. */
.keepa-tiger-overlay .bbs-stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.keepa-tiger-overlay .bbs-stat::before {
  background: var(--border);
}
.keepa-tiger-overlay .bbs-stat--ok::before { background: var(--ok); }
.keepa-tiger-overlay .bbs-stat--warn::before,
.keepa-tiger-overlay .keepa-dashboard-stat--warn::before { background: var(--warn); }
.keepa-tiger-overlay .bbs-stat--danger::before { background: var(--danger); }
.keepa-tiger-overlay .bbs-stat__value,
.keepa-tiger-overlay .keepa-dashboard-stat-xl,
.keepa-tiger-overlay .keepa-dashboard-stat-lg {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.1;
  color: var(--text);
}

/* Banners — retarget bbs-intro variants to Tiger semantic accents. */
.keepa-tiger-overlay .bbs-intro {
  border-radius: var(--radius);
}
.keepa-tiger-overlay .bbs-intro.keepa-dashboard-banner--danger {
  background: var(--danger-soft);
  border-left: 3px solid var(--danger);
  color: var(--text);
}
.keepa-tiger-overlay .bbs-intro.keepa-dashboard-banner--warn {
  background: var(--warn-soft);
  border-left: 3px solid var(--warn);
  color: var(--text);
}

/* Pill family — retarget legacy bbs-pill variants to Tiger soft tokens
   so the per-status colors match the in-table .pill rendering used on
   already-Tiger pages. */
.keepa-tiger-overlay .bbs-pill {
  background: var(--surface-2);
  color: var(--text-muted);
  border: 1px solid transparent;
}
.keepa-tiger-overlay .bbs-pill--ok    { background: var(--ok-soft);    color: var(--ok); }
.keepa-tiger-overlay .bbs-pill--warn  { background: var(--warn-soft);  color: var(--warn); }
.keepa-tiger-overlay .bbs-pill--danger{ background: var(--danger-soft);color: var(--danger); }
.keepa-tiger-overlay .bbs-pill--info,
.keepa-tiger-overlay .keepa-dashboard-pill--info { background: var(--info-soft); color: var(--info); }
.keepa-tiger-overlay .bbs-pill--primary { background: var(--brand-soft); color: var(--brand-deep); }
/* `.bbs-pill--running` is a pulse-state modifier, NOT a color modifier
   in this codebase. The template always pairs it with a color
   variant (--ok for healthy / --primary for running-other / --danger
   for failure). Don't retarget --running here — that would override
   the paired color variant via CSS source-order tie-break. The
   green/red/brand color comes from the paired modifier. Caught by
   Codex round 1: the broker healthy-running pill emits
   `bbs-pill bbs-pill--ok bbs-pill--running` and was rendering brand
   orange instead of the intended green --ok. */
/* `.auto-buy-pipeline-metric-grid` — Bucket 3 page-scoped helper for
   `auto_buy_pipeline.html`. The pipeline detail card surfaces 10 KPI
   metrics; Tiger `.grid-5` is a fixed 5-column grid with no
   responsive override (Codex round-1 P2, PR-auto-buy-pipeline). The
   `auto-fit` + `minmax(170px, 1fr)` combo lets the row collapse from
   5×2 → 4×3 → 3×4 → 2×5 → 1×10 as the viewport narrows, matching the
   `.dashboard-metric-grid` precedent at L934.

   Bucket 3 audit:
     1. Page-specific — used only by `auto_buy_pipeline.html`.
     2. Lives in theme_br.css ✅.
     3. Uses no colour/typography tokens — pure layout.
     4. No legacy-prefix collision — `auto-buy-pipeline-` is not in
        `LEGACY_CLASS_BASES` (banned bases are `ab-page-`, `abp-`,
        `abs-` — `auto-buy-pipeline-` is the unprefixed full path
        and does not collide). */
.auto-buy-pipeline-metric-grid {
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
}

/* `.auto-buy-settings .grid.grid-3` — Bucket 3 page-scoped helper
   for `auto_buy_settings.html`: Tiger `.grid-3` is a fixed
   three-column grid with no breakpoint, so the Credentials and Checkout
   Configuration input rows force three narrow columns on phones.
   Single-column collapse below 700px. Pure layout — no colour or
   typography. Bucket 3 audit: page-specific, in theme_br.css,
   Tiger-tokens-only, no legacy-prefix collision. */
@media (max-width: 700px) {
  .auto-buy-settings .grid.grid-3 {
    grid-template-columns: 1fr;
  }
}

/* `auto_buy_index.html` - Bucket 3 helpers for the Phase 1 Auto Buy index
   migration. The template now uses Tiger primitives for the page header,
   subnav, cards, banners, tables, forms, toggle cards, metrics, and buttons;
   these helpers only supply page-specific responsive grids, selected-row
   tone, inline action forms, and compact file/action cells. */
.auto-buy-index-kv-grid {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.auto-buy-index-upload-grid {
  grid-template-columns: minmax(220px, 320px) minmax(220px, 1fr) auto;
  align-items: end;
}
.auto-buy-index-settings-grid,
.auto-buy-index-feature-grid {
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}
.auto-buy-index-rule-grid {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.auto-buy-index-step {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  gap: 14px;
  align-items: start;
  padding-top: 4px;
}
.auto-buy-index-step + .auto-buy-index-step {
  border-top: 1px solid var(--border);
  padding-top: 16px;
}
.auto-buy-index-pipeline-step {
  margin-top: 4px;
}
.auto-buy-index-upload-actions {
  align-self: end;
}
.auto-buy-index-book-flags {
  justify-content: space-between;
}
.auto-buy-index-rule-card {
  cursor: pointer;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: flex-start;
}
.auto-buy-index-rule-card:has(input:checked) {
  border-color: var(--brand);
  background: var(--brand-soft);
}
.auto-buy-index-rule-card input[type="checkbox"] {
  margin-top: 2px;
}
.auto-buy-index-selected-row td {
  background: var(--info-soft);
}
.auto-buy-index-file-cell {
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.auto-buy-index-table-actions {
  gap: 6px;
}
.auto-buy-index-inline-form {
  display: inline-flex;
  margin: 0;
}
.auto-buy-index .banner-body p {
  margin: 0;
}
@media (max-width: 820px) {
  .auto-buy-index-upload-grid {
    grid-template-columns: 1fr;
  }
  .auto-buy-index-upload-actions {
    justify-content: flex-start;
  }
  .auto-buy-index-step {
    grid-template-columns: 1fr;
  }
}

/* `.purchase-bot-alerts .grid-2` — Bucket 3 page-scoped helper for
   `purchase_bot_alerts.html`. The legacy `.alerts-layout` stacked
   its two columns under a `<= 820px` media query; Tiger `.grid-2`
   ships no responsive override (Codex round-1 P2). Single-column
   collapse below 900px keeps the create-form + Slack-preview /
   saved-triggers columns from squeezing the inputs. Bucket 3
   audit: page-specific, in theme_br.css, pure layout, no
   legacy-prefix collision. */
@media (max-width: 900px) {
  .purchase-bot-alerts .grid.grid-2 {
    grid-template-columns: 1fr;
  }
}

/* `.purchase-bot-alerts [data-rules-container] .row` rule-row sizing.
   The legacy `.alert-rule__field` / `.alert-rule__op` /
   `.alert-rule__val` had explicit flex bases so the field selector
   stayed wide while the operator + value stayed compact. Tiger
   `.row` (`display: flex`) puts `.select` / `.input` (both
   `width: 100%`) into equal-width slots, squeezing the operator
   `>=` chip. Restore the legacy proportions. Codex round-3 P2. */
.purchase-bot-alerts [data-rules-container] .row > .select:first-child {
  flex: 2 1 180px;
}
.purchase-bot-alerts [data-rules-container] .row > .select:nth-child(2) {
  flex: 0 0 110px;
}
.purchase-bot-alerts [data-rules-container] .row > .input {
  flex: 1 1 120px;
}

/* `.bbs-page.keepa-priority-tiers` — Bucket 3 page-scoped helper
   (Spec §11.13). Re-tones the page text colour from the legacy
   `.bbs-page { color: var(--bbs-text) }` hard-coded slate-900 to
   the Tiger responsive `var(--text)` token. Without this, Tiger
   `.card` children inside `.bbs-page` inherit dark navy text in
   dark mode, rendering nearly invisible against the dark
   `var(--surface)` card background. Codex round-2 review flag,
   PR-keepa-priority-tiers (mirrors the `.bbs-page.diagnostics-page`
   companion shipped in PR #159 / PR-3b2d for the same root cause).

   Bucket 3 audit:
     1. Page-specific — used only by `keepa_priority_tiers.html`.
     2. Lives in theme_br.css ✅.
     3. Uses Tiger tokens — `var(--text)` only.
     4. No legacy-prefix collision — `keepa-priority-tiers` is not
        in `LEGACY_CLASS_BASES`. */
.bbs-page.keepa-priority-tiers {
  color: var(--text);
}

/* `.bbs-page.keepa-custom-run-page` - Bucket 3 helpers for
   `keepa_custom_run.html`. The shared Keepa header partial still expects the
   `.bbs-page` wrapper, so this page scopes only the builder body: readiness
   metrics, step cards, bucket toggles, upload progress, and mobile collapse.
   Visual treatment stays on Tiger primitives (`.metric`, `.card`, `.banner`,
   `.form-field`, `.input`, `.textarea`, `.toggle-card`, `.btn`). */
.bbs-page.keepa-custom-run-page {
  color: var(--text);
}
.keepa-custom-run {
  margin-top: 18px;
}
.keepa-custom-run-readiness-grid,
.keepa-custom-run-estimate-grid {
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.keepa-custom-run-metric-unit {
  margin-left: 2px;
  color: var(--text-muted);
  font-size: 0.78em;
  font-weight: 600;
}
.keepa-custom-run-step-head {
  justify-content: flex-start;
  align-items: flex-start;
}
.keepa-custom-run-step-title {
  min-width: 0;
}
.keepa-custom-run-input-grid,
.keepa-custom-run-bucket-grid {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.keepa-custom-run-file {
  min-height: 42px;
  padding: 8px 10px;
  font-size: 13px;
}
.keepa-custom-run-upload-status p,
.keepa-custom-run-preview p,
.keepa-custom-run-preview ul {
  margin: 0;
}
.keepa-custom-run-progress {
  width: 100%;
  height: 8px;
  margin-top: 8px;
}
.keepa-custom-run-bucket-card {
  cursor: pointer;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: flex-start;
}
.keepa-custom-run-bucket-card:has(input:checked) {
  border-color: var(--brand);
  background: var(--brand-soft);
}
.keepa-custom-run-bucket-card input[type="checkbox"] {
  margin-top: 2px;
}
.keepa-custom-run-bucket-examples {
  margin-top: 4px;
  font-size: 12px;
  line-height: 1.5;
}
.keepa-custom-run-rules-row {
  align-items: flex-start;
}
.keepa-custom-run-hours-field {
  flex: 0 0 240px;
}
.keepa-custom-run-hours-input {
  display: flex;
  gap: 8px;
  align-items: center;
}
.keepa-custom-run-hours-input .input {
  width: 90px;
}
.keepa-custom-run-rule-note {
  flex: 1 1 320px;
}
.keepa-custom-run-preview ul {
  padding-left: 18px;
}
@media (max-width: 700px) {
  .keepa-custom-run-hours-field,
  .keepa-custom-run-rule-note {
    flex-basis: 100%;
  }
}

/* `.mono` standalone utility — Bucket 2 hygiene fix. Spec §11.13
   already lists `.mono` as a Tiger typography helper, but the only
   shipping rule was `.table td.mono` (theme_br.css L746), so
   `<code class="mono">` / `<span class="mono">` / `<pre class="mono">`
   in migrated templates rendered with default browser font. Add the
   bare class so the documented primitive actually applies. Codex
   round-1 review flag (PR-keepa-settings). */
.mono {
  font-family: var(--font-mono);
  font-size: 12.5px;
}

.input:hover, .select:hover, .textarea:hover { border-color: var(--border-strong); }
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--brand) 25%, transparent);
}
.input:disabled, .select:disabled, .textarea:disabled {
  background: var(--surface-2);
  color: var(--text-subtle);
  cursor: not-allowed;
}
.input[aria-invalid="true"],
.select[aria-invalid="true"],
.textarea[aria-invalid="true"] {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--danger) 20%, transparent);
}

.select {
  appearance: none;
  padding-right: 32px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' stroke='%235a6778' stroke-width='1.5' fill='none' stroke-linecap='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
}

/* Form field wrapper: label + hint + control.
   `.form-field` is distinct from `.field` (horizontal search pill above). */
.form-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.form-field-label,
.field-label {
  font: 500 12px/1.3 'Inter', sans-serif;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.form-field-hint,
.field-hint {
  font: 400 12px/1.4 'Inter', sans-serif;
  color: var(--text-subtle);
}
.form-field-error,
.field-error {
  font: 500 12px/1.4 'Inter', sans-serif;
  color: var(--danger);
}

.check,
.radio {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font: 500 13px 'Inter', sans-serif;
  color: var(--text);
  cursor: pointer;
  user-select: none;
}
.check input[type="checkbox"],
.radio input[type="radio"] {
  appearance: none;
  width: 16px;
  height: 16px;
  border: 1.5px solid var(--border-strong);
  border-radius: 4px;
  background: var(--surface);
  cursor: pointer;
  flex-shrink: 0;
  transition: background 120ms, border-color 120ms;
}
.radio input[type="radio"] { border-radius: 50%; }
.check input[type="checkbox"]:checked,
.radio input[type="radio"]:checked {
  background: var(--brand);
  border-color: var(--brand);
}
.check input[type="checkbox"]:checked {
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='8' viewBox='0 0 10 8'><path d='M1 4l3 3 5-6' stroke='white' stroke-width='1.8' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
}
.radio input[type="radio"]:checked {
  box-shadow: inset 0 0 0 3px var(--surface);
}
.check input:focus-visible,
.radio input:focus-visible {
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--brand) 25%, transparent);
}

.switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  font: 500 13px 'Inter', sans-serif;
  color: var(--text);
}
.switch input { appearance: none; position: absolute; opacity: 0; }
.switch-track {
  width: 36px;
  height: 20px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  position: relative;
  transition: background 160ms, border-color 160ms;
  flex-shrink: 0;
}
.switch-track::after {
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: 14px; height: 14px;
  background: var(--surface);
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(0,0,0,0.15);
  transition: transform 160ms;
}
.switch input:checked + .switch-track {
  background: var(--brand);
  border-color: var(--brand);
}
.switch input:checked + .switch-track::after {
  transform: translateX(16px);
  background: #fff;
}
.switch input:focus-visible + .switch-track {
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--brand) 25%, transparent);
}

.file-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 24px;
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--text-muted);
  text-align: center;
  font: 500 13px 'Inter', sans-serif;
  cursor: pointer;
  transition: background 120ms, border-color 120ms;
}
.file-drop:hover,
.file-drop.is-dragover {
  background: var(--brand-soft);
  border-color: var(--brand);
  color: var(--brand-deep);
}
.file-drop input[type="file"] { display: none; }

.form-grid {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.form-actions {
  display: flex;
  gap: 10px;
  align-items: center;
  padding-top: 12px;
  margin-top: 16px;
  border-top: 1px solid var(--border);
}
.form-actions .spacer { flex: 1; }

.kv-table {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
}
.kv-row {
  display: grid;
  grid-template-columns: 200px 1fr auto;
  gap: 16px;
  align-items: center;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}
.kv-row:last-child { border-bottom: none; }
.kv-row:nth-child(even) { background: var(--surface-2); }
.kv-label { color: var(--text-muted); font-weight: 500; }
.kv-value { color: var(--text); font-variant-numeric: tabular-nums; min-width: 0; }

.toggle-card {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 12px;
  align-items: center;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  cursor: pointer;
}
.toggle-card:hover { border-color: var(--border-strong); background: var(--surface-hover); }
.toggle-card-title { font-weight: 600; font-size: 13px; color: var(--text); }
.toggle-card-desc { font-size: 12px; color: var(--text-muted); margin-top: 2px; }

/* TABLE FOOTER / PAGINATION */
.table-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border-top: 1px solid var(--border);
  background: var(--surface-2);
  font-size: 12.5px;
  color: var(--text-muted);
}
.table-footer-text { font-variant-numeric: tabular-nums; }
.table-footer-actions { display: flex; gap: 6px; }

/* EMPTY / LOADING / ERROR STATES */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 48px 24px;
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface);
  text-align: center;
}
.empty-state-icon {
  width: 40px; height: 40px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%;
  background: var(--surface-2);
  color: var(--text-muted);
}
.empty-state-title {
  font: 500 15px 'Inter', sans-serif;
  color: var(--text);
}
.empty-state-desc {
  font: 400 13px/1.5 'Inter', sans-serif;
  color: var(--text-muted);
  max-width: 360px;
}
.empty-state-actions { margin-top: 8px; display: flex; gap: 8px; }

.skel {
  background: linear-gradient(
    90deg,
    var(--surface-2) 0%,
    var(--surface-hover) 40%,
    var(--surface-2) 80%
  );
  background-size: 200% 100%;
  animation: skel-shimmer 1.4s ease-in-out infinite;
  border-radius: 4px;
  color: transparent !important;
}
.skel-line { height: 12px; margin: 6px 0; }
.skel-line.lg { height: 18px; }
.skel-line.sm { height: 10px; }
.skel-block { height: 72px; }
@keyframes skel-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

.spinner {
  display: inline-block;
  width: 14px; height: 14px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 600ms linear infinite;
  vertical-align: -2px;
}
@keyframes spin { to { transform: rotate(360deg); } }

.banner {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: 13px;
}
.banner-icon { flex-shrink: 0; width: 18px; height: 18px; }
.banner-title { font-weight: 600; color: var(--text); }
.banner-body { color: var(--text-muted); margin-top: 2px; }
.banner-actions { margin-top: 8px; display: flex; gap: 8px; }
.banner--danger { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); }
.banner--danger .banner-body { color: var(--text); }
.banner--warn { background: var(--warn-soft); border-color: var(--warn); color: var(--warn); }
.banner--warn .banner-body { color: var(--text); }
.banner--info { background: var(--info-soft); border-color: var(--info); color: var(--info); }
.banner--info .banner-body { color: var(--text); }
.banner--ok { background: var(--ok-soft); border-color: var(--ok); color: var(--ok); }
.banner--ok .banner-body { color: var(--text); }

/* `vendor_scanner.html` - Bucket 3 helpers for the standalone scanner.
   The page does not extend `base.html`, so these helpers supply the centered
   scanner shell, input affordance, live lookup states, and fixed scan history
   while the markup uses Tiger `.card`, `.page-header`, `.input`, `.select`,
   `.btn`, `.grid`, `.banner`, and `.text-muted` primitives. */
.vendor-scanner-body {
  min-height: 100vh;
  overflow-x: hidden;
  background: var(--bg);
  color: var(--text);
}
.vendor-scanner-shell {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: clamp(16px, 4vw, 32px);
  padding-bottom: 220px;
}
.vendor-scanner-panel {
  width: min(860px, 100%);
}
.vendor-scanner-header {
  justify-content: center;
  text-align: center;
}
.vendor-scanner-header .page-header-copy {
  align-items: center;
}
.vendor-scanner-form-grid {
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.vendor-scanner-actions {
  justify-content: center;
}
.vendor-scanner-note {
  text-align: center;
}
.vendor-scanner-input-wrap {
  position: relative;
}
.vendor-scanner-input {
  min-height: 52px;
  padding-left: 42px;
  font-size: 20px;
  letter-spacing: 0.05em;
}
.vendor-scanner-input-prefix {
  position: absolute;
  left: 14px;
  top: 50%;
  z-index: 1;
  transform: translateY(-50%);
  color: var(--text-muted);
  font-size: 20px;
  pointer-events: none;
}
.vendor-scanner-spinner {
  display: none;
  width: 34px;
  height: 34px;
  margin: 0 auto;
  border: 3px solid var(--border);
  border-top-color: var(--brand);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
.vendor-scanner-spinner.is-visible {
  display: block;
}
.vendor-scanner-result {
  display: none;
  padding: 24px;
  border: 2px solid transparent;
  border-radius: var(--radius);
  background: var(--surface);
  text-align: center;
}
.vendor-scanner-result.is-visible {
  display: block;
}
.vendor-scanner-result--ok {
  background: var(--ok-soft);
  border-color: var(--ok);
}
.vendor-scanner-result--blocked {
  background: var(--danger-soft);
  border-color: var(--danger);
}
.vendor-scanner-result--warning,
.vendor-scanner-result--error {
  background: var(--warn-soft);
  border-color: var(--warn);
}
.vendor-scanner-result-status {
  margin-bottom: 8px;
  font-size: 42px;
  line-height: 1;
  font-weight: 800;
  letter-spacing: 0.04em;
}
.vendor-scanner-result-isbn {
  margin-bottom: 8px;
  color: var(--text-muted);
  font-family: var(--font-mono);
  font-size: 14px;
}
.vendor-scanner-result-message {
  color: var(--text);
  font-size: 18px;
  font-weight: 700;
}
.vendor-scanner-result-meta {
  margin-top: 8px;
  color: var(--text-muted);
  font-size: 13px;
}
.vendor-scanner-writeback-actions {
  display: none;
  justify-content: center;
  gap: 10px;
  margin-top: 14px;
  flex-wrap: wrap;
}
.vendor-scanner-writeback-actions.is-visible {
  display: flex;
}
.vendor-scanner-history {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  display: none;
  max-height: 200px;
  overflow: auto;
  background: var(--surface);
  border-top: 1px solid var(--border);
}
.vendor-scanner-history.is-visible {
  display: block;
}
.vendor-scanner-history-row {
  display: grid;
  grid-template-columns: 10px minmax(120px, 160px) minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  padding: 7px 12px;
  border-bottom: 1px solid var(--border);
  font-size: 12px;
}
.vendor-scanner-history-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
}
.vendor-scanner-history-dot--ok {
  background: var(--ok);
}
.vendor-scanner-history-dot--blocked {
  background: var(--danger);
}
.vendor-scanner-history-dot--warning,
.vendor-scanner-history-dot--error {
  background: var(--warn);
}
.vendor-scanner-history-isbn {
  color: var(--text);
  font-family: var(--font-mono);
}
.vendor-scanner-history-msg {
  min-width: 0;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.vendor-scanner-history-time {
  color: var(--text-muted);
  white-space: nowrap;
}
@media (max-width: 640px) {
  .vendor-scanner-shell {
    align-items: start;
  }
  .vendor-scanner-result-status {
    font-size: 32px;
  }
  .vendor-scanner-history-row {
    grid-template-columns: 10px minmax(0, 1fr) auto;
  }
  .vendor-scanner-history-msg {
    grid-column: 2 / -1;
    white-space: normal;
  }
}

.error-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: calc(100vh - 200px);
  gap: 12px;
  text-align: center;
}
.error-page-code {
  font: 500 64px var(--font-display);
  color: var(--brand);
  line-height: 1;
}
.error-page-title { font: 500 20px var(--font-display); color: var(--text); }
.error-page-body { font-size: 14px; color: var(--text-muted); max-width: 420px; }

/* FLASH MESSAGES — supports both legacy `<li class="{{cat}}">` and
   new `<li class="flash--{{cat}}">` so unmigrated callers keep working. */
.flash {
  list-style: none;
  margin: 0 0 16px 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.flash li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 14px;
  border-radius: var(--radius);
  font-size: 13px;
  border: 1px solid var(--border);
  background: var(--surface);
}
.flash .flash--success, .flash li.success { background: var(--ok-soft); border-color: var(--ok); color: var(--text); }
.flash .flash--error,   .flash li.error,
.flash .flash--danger,  .flash li.danger  { background: var(--danger-soft); border-color: var(--danger); color: var(--text); }
.flash .flash--warning, .flash li.warning { background: var(--warn-soft); border-color: var(--warn); color: var(--text); }
.flash .flash--info,    .flash li.info,
.flash .flash--message, .flash li.message { background: var(--info-soft); border-color: var(--info); color: var(--text); }
.flash li::before {
  content: "";
  width: 8px; height: 8px; border-radius: 50%;
  background: currentColor;
  opacity: 0.6;
  flex-shrink: 0;
  margin-top: 6px;
}

/* RUN TOAST — class names + data attrs match the polling JS in base.html. */
.run-toast {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 5000;
  max-width: 360px;
  pointer-events: none;
}
.run-toast-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column-reverse;
  gap: 8px;
}
.run-toast-item {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px 12px;
  align-items: center;
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--brand);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  font-size: 12.5px;
  pointer-events: auto;
  animation: run-toast-in 240ms ease-out;
}
@keyframes run-toast-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.run-toast-name {
  font-weight: 600;
  color: var(--text);
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  grid-column: 1;
}
.run-toast-status {
  grid-column: 2;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 2px 8px;
  border-radius: 999px;
}
.run-toast-status[data-status="running"],
.run-toast-status[data-status="queued"]   { background: var(--info-soft); color: var(--info); }
.run-toast-status[data-status="success"],
.run-toast-status[data-status="completed"]{ background: var(--ok-soft); color: var(--ok); }
.run-toast-status[data-status="failed"],
.run-toast-status[data-status="error"]    { background: var(--danger-soft); color: var(--danger); }
.run-toast-status[data-status="warning"]  { background: var(--warn-soft); color: var(--warn); }

.run-toast-meta {
  grid-column: 1 / -1;
  color: var(--text-muted);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
}
.run-toast-dismiss {
  grid-column: 1 / -1;
  justify-self: end;
  font-size: 11px;
  color: var(--text-subtle);
  cursor: pointer;
}
.run-toast-dismiss:hover { color: var(--text); }

.run-toast-item:has([data-status="success"]),
.run-toast-item:has([data-status="completed"]) { border-left-color: var(--ok); }
.run-toast-item:has([data-status="failed"]),
.run-toast-item:has([data-status="error"])     { border-left-color: var(--danger); }
.run-toast-item:has([data-status="warning"])   { border-left-color: var(--warn); }

/* REPORT-ISSUE BUTTON + MODAL */
.report-issue-btn {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 4000;
  padding: 10px 14px;
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 999px;
  box-shadow: var(--shadow);
  font: 500 12.5px 'Inter', sans-serif;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: background 120ms, border-color 120ms, transform 120ms;
}
.report-issue-btn:hover {
  background: var(--brand-soft);
  border-color: var(--brand);
  color: var(--brand-deep);
  transform: translateY(-1px);
}
.report-issue-btn::before {
  content: "";
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--brand);
}
body:has(.run-toast-item) .report-issue-btn { bottom: 84px; }

.modal-scrim {
  position: fixed;
  inset: 0;
  z-index: 10000;
  background: rgba(10, 18, 30, 0.5);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.modal-scrim.is-open { display: flex; }
.modal {
  width: 100%;
  max-width: 480px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.modal-title { font: 500 18px var(--font-display); color: var(--text); }
.modal-body { font-size: 13px; color: var(--text-muted); }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }

/* FOCUS RING (A11Y) */
*:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 4px;
}
.btn:focus-visible, .input:focus-visible, .select:focus-visible,
.textarea:focus-visible { outline: none; }

/* Full-bleed contract lives in tokens.css (load-bearing). */

/* ============================================================
   PHASE 3.1 — Purchase Bot Dashboard
   Scoped helpers for purchase_bot_dashboard.html (Phase 3.1).

   Visual treatment ported verbatim from styles.css .purchase-* rules
   (lines 1500-2530) with class names renamed `purchase-*` ->
   `purchase-bot-*`. Shared classes (purchase-pagination, -panel-wide,
   -dropdown-filter, -dropdown-filter-btn, -dropdown-panel, -flag-badge,
   flag-* modifiers, has-selection) are intentionally NOT migrated here
   — other templates still consume them. Phase 4 sweep deletes the
   legacy purchase-* halves and may consolidate to .card / .table /
   .pill primitives.

   Z-index stack (preserved verbatim from legacy):
     .purchase-bot-header sticky table header   z=900, top=56px
     .purchase-bot-check-actions sticky bottom  z=910
     .purchase-bot-filter-row     z=1002 + isolation: isolate
     .purchase-dropdown-panel (legacy, kept)    z=1200
     Right-edge clamp on rightmost-column dropdown preserved in styles.css
     under `.purchase-filter-row > div:last-child .purchase-dropdown-panel`
     (kept legacy because purchase-dropdown-panel is bucket-B).

   See handoff/phase-3-1-pre/collision-report.md for migration baseline.
   ============================================================ */

/* ---- PAGE SHELL ----
   Replaces .function-page-* for purchase_bot_dashboard. Other Purchase
   Bot subpages (alerts, rules, audit-glossary) keep the legacy
   .function-page-* shell from styles.css until they migrate. */
.purchase-bot-page-shell {
  max-width: 1380px;
  margin: 0 auto 1.5rem;
}

.purchase-bot-page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.purchase-bot-page-header h2 {
  margin: 0;
  font-size: 1.65rem;
  font-weight: 700;
}

.purchase-bot-page-subtitle {
  margin: 0.35rem 0 0;
  color: #6b7280;
  font-size: 0.9rem;
}

.purchase-bot-page-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 0.9rem;
  margin-bottom: 14px;
  padding: 0;
  border-bottom: 1px solid #cbd5e1;
}

.purchase-bot-page-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px 14px;
  border: 1px solid #cbd5e1;
  border-bottom: none;
  border-radius: 6px 6px 0 0;
  background: #fff;
  color: #475569;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 0.82rem;
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  box-sizing: border-box;
  margin-bottom: -1px; /* sits on top of the container's bottom border */
}

.purchase-bot-page-tab:hover {
  background: #f1f5f9;
  color: #0f172a;
}

.purchase-bot-page-tab.is-active,
.purchase-bot-page-tab[aria-current="page"] {
  background: #1e3a8a;
  color: #fff;
  border-color: #1e3a8a;
}

.purchase-bot-page-tab.is-active:hover,
.purchase-bot-page-tab[aria-current="page"]:hover {
  background: #1e40af;
  color: #fff;
}

.purchase-bot-page-tab[disabled],
.purchase-bot-page-tab.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

/* ---- PURCHASE-BOT TABLE + ROWS + COMPONENTS ---- */
.purchase-bot-table {
  display: flex;
  flex-direction: column;
  gap: 0;
  width: 100%;
  margin-top: 12px;
  border-top: 1px solid #e5e7eb;
  font-family: var(--site-table-font-family);
}

.purchase-bot-row {
  display: grid;
  grid-template-columns:
    82px
    minmax(0, 0.35fr)
    minmax(0, 0.265fr)
    minmax(0, 0.245fr)
    58px
    56px
    68px
    68px
    86px
    72px
    86px
    86px
    86px
    58px
    58px
    58px
    58px
    116px
    18px;
  gap: 5px;
  padding: 10px 4px;
  border-bottom: 1px solid #e5e7eb;
  align-items: center;
  min-width: 0;
  font-size: var(--site-table-body-font-size);
}

.purchase-bot-row > * {
  min-width: 0;
}

.purchase-bot-row:nth-child(2n+1):not(.purchase-bot-header):not(.purchase-bot-filter-row) {
  background: #f8fafc;
}

.purchase-bot-row:hover:not(.purchase-bot-header):not(.purchase-bot-filter-row) {
  background: #eef2f8;
}

.purchase-bot-row.is-flagged {
  opacity: 0.55;
}

.purchase-bot-row.is-flagged:hover {
  opacity: 0.85;
}

.purchase-bot-header {
  position: sticky;
  top: 56px;
  z-index: 900;
  font-weight: 700;
  background: #fff;
  border-bottom: 2px solid #cbd5e1;
  padding-top: 16px;
  padding-bottom: 8px;
  font-size: var(--site-table-header-font-size);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  align-items: end;
}

.purchase-bot-summary-bar {
  padding: 6px 10px;
  font-size: 0.8rem;
  color: #475569;
  background: #f1f5f9;
  border-bottom: 1px solid #e5e7eb;
}

.purchase-bot-header a {
  color: #0b3d91;
  text-decoration: none;
}

.purchase-bot-header span {
  color: #0b3d91;
}

.purchase-bot-header a:hover {
  text-decoration: underline;
}

.purchase-bot-header .purchase-bot-header-right {
  text-align: right;
  display: block;
  align-self: flex-end;
}

.purchase-bot-header .purchase-shortage-header {
  text-align: center;
}

.purchase-bot-header .purchase-bot-qty-header {
  text-align: center;
  display: block;
  align-self: flex-end;
}

.purchase-bot-truncate {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.purchase-bot-expand-toggle {
  font-size: 11px;
  line-height: 1.2;
  padding: 1px 5px;
  border: 1px solid #c7d6f5;
  background: #eef4ff;
  color: #0b3d91;
  border-radius: 4px;
  cursor: pointer;
  vertical-align: baseline;
  margin-left: 2px;
}

.purchase-bot-expand-toggle:hover {
  background: #e1ebff;
}

.purchase-bot-col-header-toggle {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 4px;
}

.purchase-bot-expandable-text.is-expanded {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  word-break: break-word;
}

.purchase-bot-cost {
  color: #b91c1c;
  font-weight: 700;
  font-size: 0.85rem;
  white-space: nowrap;
  text-align: right;
}

.purchase-bot-profit {
  color: #166534;
  font-weight: 700;
  font-size: 0.85rem;
  white-space: nowrap;
  text-align: right;
}

.purchase-bot-sale-price {
  font-weight: 600;
  font-size: 0.85rem;
  white-space: nowrap;
  text-align: right;
  color: #1e3a5f;
}

.purchase-bot-numeric {
  text-align: right;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.purchase-bot-shortage {
  text-align: center;
  padding-right: 0;
}

.purchase-bot-qty-cell {
  text-align: center;
}

.purchase-bot-demand-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 3px;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  line-height: 1.4;
}

.purchase-bot-demand-badge.is-used {
  background: #dbeafe;
  color: #1e40af;
}

.purchase-bot-demand-badge.is-new {
  background: #dcfce7;
  color: #166534;
}

.purchase-bot-condition-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 3px;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  line-height: 1.4;
  white-space: nowrap;
}

.purchase-bot-condition-badge.is-used {
  background: #dbeafe;
  color: #1e40af;
}

.purchase-bot-condition-badge.is-new {
  background: #dcfce7;
  color: #166534;
}

.purchase-bot-native-cost {
  font-size: 0.8rem;
  white-space: nowrap;
  text-align: right;
  color: #78716c;
  font-variant-numeric: tabular-nums;
}

.purchase-bot-channel-badge {
  display: inline-block;
  padding: 2px 6px;
  border-radius: 3px;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.purchase-bot-channel-badge.is-mbs {
  background: #e0edff;
  color: #1a56a0;
}

.purchase-bot-channel-badge.is-fba {
  background: #fef3cd;
  color: #856404;
}

.purchase-bot-dashboard-header {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.purchase-bot-arb-refresh-card {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin: 12px 0 16px;
  padding: 12px 14px;
  border: 1px solid #d9e2f3;
  border-radius: 8px;
  background: #f8fbff;
}

.purchase-bot-arb-refresh-card.is-running {
  border-color: #c7d6f5;
  background: #eef4ff;
}

.purchase-bot-arb-refresh-card.is-error {
  border-color: #fecaca;
  background: #fef2f2;
}

.purchase-bot-arb-refresh-copy {
  min-width: 0;
  flex: 1 1 auto;
}

.purchase-bot-arb-refresh-title-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 6px;
  flex-wrap: wrap;
}

.purchase-bot-arb-refresh-title {
  font-size: 0.82rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #1b325f;
}

.purchase-bot-arb-refresh-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 24px;
  padding: 0 10px;
  border-radius: 999px;
  background: #dbeafe;
  color: #1d4ed8;
  font-size: 0.78rem;
  font-weight: 700;
}

.purchase-bot-arb-refresh-card.is-error .purchase-bot-arb-refresh-pill {
  background: #fee2e2;
  color: #b91c1c;
}

.purchase-bot-arb-refresh-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  font-size: 0.85rem;
  color: #475569;
}

.purchase-bot-arb-refresh-meta span {
  white-space: nowrap;
}

.purchase-bot-arb-refresh-error {
  margin-top: 8px;
  font-size: 0.82rem;
  color: #b91c1c;
}

.purchase-bot-arb-refresh-form {
  flex: 0 0 auto;
}

.purchase-bot-filter-actions {
  margin-top: 10px;
}

.purchase-bot-filter-toolbar {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.purchase-bot-filter-toolbar .button-link,
.purchase-bot-filter-toolbar button.button-link {
  font-family: var(--site-button-font-family);
  font-size: var(--site-button-font-size);
  font-weight: 600;
  padding: 6px 16px;
  border-radius: 4px;
  line-height: var(--site-button-line-height);
  text-align: center;
  box-sizing: border-box;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 34px;
  width: auto;
}

.purchase-bot-filter-toolbar .purchase-bot-show-flagged-toggle {
  font-family: var(--site-button-font-family);
  font-size: var(--site-button-font-size);
  font-weight: 600;
  padding: 0 10px;
  border-radius: 4px;
  line-height: var(--site-button-line-height);
  text-align: left;
  width: 170px;
  height: 34px;
  box-sizing: border-box;
  text-decoration: none;
}

.purchase-bot-filter-toolbar-left {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.purchase-bot-filter-toolbar-right {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: flex-end;
  width: auto;
}

.purchase-bot-toolbar-toggle-row {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
}

.purchase-bot-apply-button {
  border: none;
  background: #166534;
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.purchase-bot-apply-button:hover {
  background: #15803d;
}

.purchase-bot-clear-button {
  background: #b91c1c;
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.purchase-bot-clear-button:hover {
  background: #991b1b;
}

.purchase-bot-filter-toolbar .button-muted {
  background: #6b7280;
  border: 1px solid #6b7280;
}

.purchase-bot-filter-toolbar .button-muted:hover {
  background: #4b5563;
}

.purchase-bot-filter-row {
  position: relative;
  z-index: 1002;
  isolation: isolate;
  background: #f8fafc;
}

.purchase-bot-filter-row > div {
  min-width: 0;
  width: 100%;
  overflow: visible;
  box-sizing: border-box;
  padding: 0;
  justify-self: stretch;
}

.purchase-bot-filter-row input[type="text"],
.purchase-bot-filter-row input[type="number"],
.purchase-bot-filter-row select {
  width: 100%;
  max-width: 100%;
  margin-top: 0;
  padding: 4px 5px;
  font-size: 0.78rem;
  box-sizing: border-box;
}

.purchase-bot-filter-row > div:last-child .purchase-dropdown-panel {
  left: auto;
  right: 0;
}

.purchase-bot-range-inputs {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 0;
  width: 100%;
  min-width: 0;
  align-items: stretch;
  box-sizing: border-box;
  justify-self: stretch;
}

.purchase-bot-range-inputs input[type="number"] {
  width: 100%;
  min-width: 0;
  max-width: none;
  height: 22px;
  padding: 2px 4px;
  font-size: 0.74rem;
  line-height: 1.1;
  box-sizing: border-box;
  text-align: left;
}

.purchase-bot-range-inputs input[type="number"]::placeholder {
  text-align: left;
}

.purchase-bot-flags-cell {
  font-size: 0.65rem;
  color: #9ca3af;
  overflow: hidden;
  text-overflow: ellipsis;
  display: flex;
  gap: 2px;
  align-items: center;
}

.purchase-bot-buy-links {
  display: flex;
  gap: 3px;
  flex-wrap: wrap;
  align-items: center;
}

.purchase-bot-buy-links .amazon-link-button {
  padding: 3px 6px;
  font-size: 0.7rem;
}

.purchase-bot-check-cell {
  text-align: center;
}

.purchase-bot-check-cell input[type="checkbox"] {
  cursor: pointer;
  width: 16px;
  height: 16px;
}

.purchase-bot-row.is-checked {
  opacity: 0.45;
  background: #f1f5f9;
}

.purchase-bot-row.is-checked:hover {
  opacity: 0.70;
}

.purchase-bot-check-actions {
  position: sticky;
  bottom: 0;
  z-index: 910;
  background: #0b3d91;
  color: #fff;
  padding: 10px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  border-radius: 8px 8px 0 0;
  font-size: 0.85rem;
  font-weight: 600;
  box-shadow: 0 -2px 8px rgba(0,0,0,0.15);
}

.purchase-bot-check-actions form {
  display: flex;
  align-items: center;
  gap: 10px;
}

.purchase-bot-check-actions .button-link {
  background: #fff;
  color: #0b3d91;
  padding: 5px 14px;
  border-radius: 4px;
  font-weight: 700;
  font-size: 0.8rem;
}

.purchase-bot-flag-glossary {
  margin: 4px 0 8px;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
  background: #f8fafc;
  font-size: 0.82rem;
}

.purchase-bot-flag-glossary > summary {
  cursor: pointer;
  padding: 7px 12px;
  font-weight: 600;
  color: #374151;
  user-select: none;
  list-style: none;
}

.purchase-bot-flag-glossary > summary::-webkit-details-marker {
  display: none;
}

.purchase-bot-flag-glossary > summary::before {
  content: "\25B6";
  display: inline-block;
  margin-right: 6px;
  font-size: 0.6rem;
  transition: transform 0.15s;
  vertical-align: middle;
}

.purchase-bot-flag-glossary[open] > summary::before {
  transform: rotate(90deg);
}

.purchase-bot-flag-glossary-count {
  font-weight: 400;
  color: #9ca3af;
  font-size: 0.78rem;
}

.purchase-bot-flag-glossary-body {
  padding: 6px 12px 10px;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.purchase-bot-flag-glossary-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.purchase-bot-flag-glossary-item .purchase-flag-badge {
  flex-shrink: 0;
  font-size: 0.68rem;
  padding: 2px 6px;
}

.purchase-bot-flag-glossary-item > span:last-child {
  color: #4b5563;
  font-size: 0.8rem;
}

.purchase-bot-show-flagged-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  color: #92400e;
  cursor: pointer;
  border: 1px solid #fbbf24;
  background: #fef3c7;
  user-select: none;
  width: 170px;
  height: 34px;
  padding: 0 10px;
  border-radius: 4px;
  font-size: 0.82rem;
  font-weight: 600;
  box-sizing: border-box;
  white-space: nowrap;
}

.purchase-bot-hide-days-toggle {
  width: 132px;
  justify-content: space-between;
  gap: 4px;
  overflow: hidden;
}

.purchase-bot-show-flagged-toggle:hover {
  background: #fde68a;
}

.purchase-bot-show-flagged-toggle input[type="checkbox"] {
  margin: 0;
  cursor: pointer;
  flex: 0 0 auto;
}

.purchase-bot-toggle-days-input {
  width: 2rem;
  min-width: 2rem;
  max-width: 2rem;
  height: 18px;
  padding: 0 2px;
  font-size: 0.7rem;
  border: 1px solid #cbd5e1;
  border-radius: 3px;
  box-sizing: border-box;
  flex: 0 0 2rem;
  text-align: center;
  appearance: textfield;
  -moz-appearance: textfield;
}

.purchase-bot-toggle-days-input::-webkit-outer-spin-button,
.purchase-bot-toggle-days-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.purchase-bot-toggle-label {
  font-size: 0.78rem;
  color: #64748b;
}

/* ---- RESPONSIVE ---- */
@media (max-width: 900px) {
  .purchase-bot-arb-refresh-card {
    flex-direction: column;
    align-items: stretch;
  }

  .purchase-bot-arb-refresh-meta span {
    white-space: normal;
  }

  .purchase-bot-arb-refresh-form .button-link,
  .purchase-bot-arb-refresh-form button {
    width: 100%;
  }
}

/* ---- STATE OVERRIDES ----
   Trap 2: explicit `display: none` for JS-toggled `is-hidden` so the
   migrated element doesn't depend on legacy styles.css `.is-hidden`
   bare-class rule (which is a cross-cutting collision, will be
   consolidated in Phase 2.5). */
.purchase-bot-arb-refresh-error.is-hidden { display: none; }

/* ---- INLINE-STYLE FIXES (guardrail compliance) ----
   Replace `style="padding: 6px 12px 10px;"` on three <details><div>
   stat blocks (US run / Non-US run / Raw run) and
   `style="margin-left:auto;"` on the sticky check-actions form. */
.purchase-bot-stat-block-body { padding: 6px 12px 10px; }
.purchase-bot-check-actions > form { margin-left: auto; }

/* ============================================================
   PHASE 3.2 — Keepa Dashboard
   Scoped helpers for keepa_dashboard.html (Phase 3.2).

   Visual treatment for the 35 bucket-A only-here classes ported
   verbatim from styles.css `.bbs-*` rules with class names renamed
   `bbs-*` -> `keepa-dashboard-*` via .claude/tmp/gen_phase32_css.py.
   Compound selectors that mix bucket-A with bucket-B preserve the
   bucket-B parts (e.g. `.bbs-table th.keepa-dashboard-sortable`).

   Bucket-B classes (47 shared `bbs-*` shell classes consumed by 6
   other unmigrated templates) are intentionally NOT migrated here —
   Phase 3.3 will consolidate the bbs-* shell. State classes
   (`is-active`, `is-checked`, `is-flagged`, `is-open`, `is-running`,
   `is-error`, `is-expanded`, `is-empty`, `is-hidden`) kept verbatim
   per state-class policy; their compound rules with bucket-A classes
   were captured by the rename script.

   Inline-style consolidation: 11 helper components + 3 straggler
   helpers replace 60 inline style violations across 1258 template
   lines. See handoff/phase-3-2-pre/helper-classes.md for the
   line-by-line replacement map.

   `--bar` custom property on `.keepa-dashboard-list__bar::after`
   passes via the inline-style allow-list relaxation landed in
   atomic commit 1 (44478c0). See handoff-note.md Finding 3.

   See handoff/phase-3-2-pre/collision-report.md for migration baseline.
   ============================================================ */

/* ---- BUCKET-A SCOPED HELPERS ----
   35 only-here classes renamed `bbs-*` -> `keepa-dashboard-*`.
   Each rule below is preceded by a single-line traceability comment
   recording the originating styles.css line number. */
/* src styles.css L5332: .schedule-runtime-badge */
.keepa-dashboard-schedule-runtime-badge {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  padding: 1px 8px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.4;
}

/* src styles.css L5342: .schedule-runtime-badge.is-ok */
.keepa-dashboard-schedule-runtime-badge.is-ok {
  background: #e9f8ef;
  color: #0b7a3b;
  border: 1px solid #b8e7ca;
}

/* src styles.css L5348: .schedule-runtime-badge.is-warning */
.keepa-dashboard-schedule-runtime-badge.is-warning {
  background: #fff4e6;
  color: #9a5800;
  border: 1px solid #ffd7a6;
}

/* src styles.css L5354: .schedule-runtime-badge.is-danger */
.keepa-dashboard-schedule-runtime-badge.is-danger {
  background: #fdecec;
  color: #b91c1c;
  border: 1px solid #f5b4b4;
}

/* src styles.css L5361: .schedule-runtime-badge.is-info */
.keepa-dashboard-schedule-runtime-badge.is-info {
  background: #e7f0fe;
  color: #1e40af;
  border: 1px solid #b8d3fb;
}

/* src styles.css L5368: .keepa-honesty-badges */
.keepa-dashboard-honesty-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px 12px;
  margin-bottom: 12px;
  background: #f9fafb;
  border: 1px solid #e5e7eb;
  border-radius: 6px;
}

/* src styles.css L5379: .keepa-honesty-badges .badge-label */
.keepa-dashboard-honesty-badges .keepa-dashboard-badge-label {
  margin-right: 6px;
  font-size: 11px;
  color: #6b7280;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* src styles.css L19603: .bbs-stat--warn::before */
.keepa-dashboard-stat--warn::before {
  background: var(--bbs-warn);
}

/* src styles.css L19682: .bbs-pill--info */
.keepa-dashboard-pill--info {
  background: var(--bbs-info-soft);
  color: var(--bbs-info);
  border-color: #bae6fd;
}

.keepa-cache-page {
  gap: 0;
}

.keepa-cache-main > .page {
  padding-top: 14px;
}

.keepa-cache-breadcrumb {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-muted);
}

.keepa-cache-breadcrumb a {
  color: var(--brand);
  text-decoration: none;
}

.keepa-cache-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  margin-bottom: 14px;
}

.keepa-cache-heading {
  display: flex;
  align-items: center;
  min-width: 0;
  gap: 14px;
}

.keepa-cache-heading__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  border-radius: 8px;
  color: var(--brand);
  background: var(--brand-soft);
  border: 1px solid color-mix(in srgb, var(--brand) 22%, var(--border));
}

.keepa-cache-heading__icon [data-lucide] {
  width: 21px;
  height: 21px;
}

.keepa-cache-heading__title {
  margin: 0 0 2px;
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 650;
  color: var(--text);
  letter-spacing: 0;
}

.keepa-cache-heading__subtitle {
  margin: 0;
  color: var(--text-muted);
  font-size: 13.5px;
  line-height: 1.35;
}

.keepa-cache-context {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  color: var(--text-muted);
  font-size: 13px;
  white-space: nowrap;
}

.keepa-cache-context > span + span {
  position: relative;
  padding-left: 14px;
}

.keepa-cache-context > span + span::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--text-muted);
  transform: translateY(-50%);
}

.keepa-cache-icon-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
}

.keepa-cache-icon-button [data-lucide] {
  width: 16px;
  height: 16px;
}

.keepa-cache-tabs {
  margin-bottom: 12px;
}

.keepa-cache-alert-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: 12px;
  margin-bottom: 12px;
}

.keepa-cache-alert {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 50px;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
}

.keepa-cache-alert--success {
  border-color: #a7e8bb;
  background: #f3fff6;
}

.keepa-cache-alert--warning {
  border-color: #f6d58b;
  background: #fffaf0;
}

.keepa-cache-alert__icon {
  display: inline-flex;
  color: var(--ok);
  flex: 0 0 auto;
}

.keepa-cache-alert--warning .keepa-cache-alert__icon {
  color: var(--warn);
}

.keepa-cache-alert__icon [data-lucide] {
  width: 19px;
  height: 19px;
}

.keepa-cache-alert__body {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  flex: 1 1 auto;
  font-size: 12.5px;
  color: var(--text-muted);
}

.keepa-cache-alert__body strong {
  color: var(--text);
  font-size: 13px;
  font-weight: 700;
}

.keepa-cache-alert__action {
  margin: 0;
}

.keepa-cache-alert-details {
  position: relative;
  flex: 0 0 auto;
}

.keepa-cache-alert-details > summary {
  list-style: none;
  cursor: pointer;
}

.keepa-cache-alert-details > summary::-webkit-details-marker {
  display: none;
}

.keepa-cache-alert-details > summary::marker {
  content: "";
}

.keepa-cache-alert-details__panel {
  position: absolute;
  z-index: 30;
  top: calc(100% + 8px);
  right: 0;
  width: min(360px, calc(100vw - 48px));
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  color: var(--text);
}

.keepa-cache-alert-details__panel dl {
  display: grid;
  gap: 8px;
  margin: 0;
}

.keepa-cache-alert-details__panel div {
  display: grid;
  grid-template-columns: minmax(120px, 0.8fr) minmax(0, 1fr);
  gap: 10px;
  align-items: baseline;
}

.keepa-cache-alert-details__panel dt {
  margin: 0;
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0;
}

.keepa-cache-alert-details__panel dd {
  margin: 0;
  color: var(--text);
  font-size: 12px;
  text-align: right;
}

.keepa-cache-domain-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}

.keepa-cache-domain-label {
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
}

.keepa-cache-domain-chips {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.keepa-cache-domain-chip {
  min-width: 48px;
  height: 32px;
  padding: 0 13px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
}

.keepa-cache-domain-chip:hover {
  border-color: var(--brand);
}

.keepa-cache-domain-chip.is-active {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--brand-fg);
}

.keepa-cache-filter-summary {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  margin-left: auto;
  color: var(--text-muted);
  font-size: 12.5px;
}

.keepa-cache-filter-summary strong {
  color: var(--text);
}

.keepa-cache-clear-link {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--brand);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}

.keepa-cache-table-panel {
  overflow: visible;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

.keepa-cache-toolbar {
  display: grid;
  grid-template-columns: minmax(360px, 1fr) auto auto minmax(360px, auto);
  gap: 14px;
  align-items: start;
  padding: 14px 18px 12px;
  border-bottom: 1px solid var(--border);
}

.keepa-cache-search-group {
  min-width: 0;
}

.keepa-cache-search-line {
  display: flex;
  align-items: center;
  gap: 10px;
}

.keepa-cache-search-input {
  width: min(100%, 460px);
  min-width: 260px;
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 13px;
}

.keepa-cache-search-input:focus {
  outline: 2px solid color-mix(in srgb, var(--brand) 22%, transparent);
  border-color: var(--brand);
}

.keepa-cache-search-help {
  margin-top: 6px;
  color: var(--text-muted);
  font-size: 12px;
}

.keepa-cache-load-status {
  display: block;
  margin-top: 4px;
  color: var(--text-muted);
  font-size: 12px;
}

.keepa-cache-load-status:empty {
  display: none;
}

.keepa-cache-select {
  height: 36px;
  min-width: 116px;
  padding: 0 34px 0 12px;
  border: 1px solid var(--border);
  border-radius: 7px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 13px;
}

.keepa-cache-pager {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  min-height: 36px;
  color: var(--text-muted);
  font-size: 13px;
  white-space: nowrap;
}

.keepa-cache-table-panel .keepa-dashboard-table-wrap-scroll {
  display: block;
  max-width: 100%;
  overflow-x: auto;
  overflow-y: visible;
  overscroll-behavior-x: contain;
  scrollbar-gutter: stable both-edges;
  -webkit-overflow-scrolling: touch;
}

.keepa-cache-table {
  margin: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  table-layout: fixed;
  width: 100%;
  min-width: max(1420px, calc(var(--keepa-cache-column-count, 13) * 128px));
}

.keepa-cache-table [data-cache-column="title"] {
  width: 320px;
}

.keepa-cache-table thead th {
  background: #f8fafc;
  color: var(--text);
  font-size: 12px;
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: 0;
  overflow: visible;
  padding: 9px 8px;
  text-overflow: clip;
  text-transform: none;
  white-space: normal !important;
}

.keepa-cache-table tbody td {
  font-size: 12px;
  line-height: 1.25;
  padding: 9px 8px;
  vertical-align: top;
}

.keepa-cache-table tbody td.keepa-cache-cell--compact {
  max-height: 4.75em;
}

.keepa-cache-cell__display {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  overflow-wrap: anywhere;
  white-space: normal;
}

.keepa-cache-cell-raw {
  margin-top: 4px;
}

.keepa-cache-cell-raw summary {
  cursor: pointer;
  color: var(--text-muted);
  font-size: 11px;
  line-height: 1.2;
}

.keepa-cache-cell-raw pre {
  max-height: 180px;
  max-width: 420px;
  overflow: auto;
  margin: 4px 0 0;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #f8fafc;
  color: var(--text);
  font-size: 11px;
  white-space: pre-wrap;
}

@media (max-width: 1180px) {
  .keepa-cache-header,
  .keepa-cache-context {
    align-items: flex-start;
    flex-wrap: wrap;
  }
  .keepa-cache-alert-grid {
    grid-template-columns: 1fr;
  }
  .keepa-cache-toolbar {
    grid-template-columns: 1fr;
  }
  .keepa-cache-pager {
    justify-content: flex-start;
    flex-wrap: wrap;
  }
  .keepa-cache-filter-summary {
    margin-left: 0;
  }
}

@media (max-width: 700px) {
  .keepa-cache-main > .page {
    padding-top: 10px;
  }
  .keepa-cache-search-line {
    align-items: stretch;
    flex-wrap: wrap;
  }
  .keepa-cache-search-input {
    width: 100%;
    min-width: 0;
    flex: 1 1 100%;
  }
  .keepa-cache-search-line .btn {
    flex: 1 1 96px;
  }
}

/* src styles.css L24045: .bbs-chip-row */
.keepa-dashboard-chip-row {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 8px;
  margin-bottom: 14px;
}

.keepa-dashboard-chip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  background: #fff;
  border: 1px solid var(--bbs-border);
  border-radius: var(--bbs-radius-sm);
  font-size: 0.85rem;
  box-shadow: var(--bbs-shadow-sm);
}

.keepa-dashboard-chip--button {
  width: 100%;
  color: inherit;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
}

.keepa-dashboard-chip--button:hover {
  border-color: var(--bbs-primary);
}

/* src styles.css L24065: .bbs-chip__label */
.keepa-dashboard-chip__label {
  color: var(--bbs-text-soft);
  font-weight: 600;
}

/* src styles.css L24066: .bbs-chip__value */
.keepa-dashboard-chip__value {
  font-weight: 700;
  color: var(--bbs-text);
  font-variant-numeric: tabular-nums;
}

/* src styles.css L24067: .bbs-chip__sub */
.keepa-dashboard-chip__sub {
  font-size: 0.72rem;
  color: var(--bbs-text-muted);
}

/* src styles.css L24068: .bbs-chip.is-empty */
.keepa-dashboard-chip.is-empty {
  opacity: 0.6;
}

/* src styles.css L24069: .bbs-chip.is-active */
.keepa-dashboard-chip.is-active {
  border-color: var(--bbs-primary);
  background: var(--bbs-primary-soft);
}

/* src styles.css L24100: .bbs-list__value */
.keepa-dashboard-list__value {
  color: var(--bbs-text);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* src styles.css L24102: .bbs-list__bar */
.keepa-dashboard-list__bar {
  height: 6px;
  border-radius: 3px;
  background: var(--bbs-primary-soft);
  flex: 1 1 auto;
  margin: 0 12px;
  overflow: hidden;
  min-width: 60px;
}

/* src styles.css L24111: .bbs-list__bar::after */
.keepa-dashboard-list__bar::after {
  content: "";
  display: block;
  height: 100%;
  background: var(--bbs-primary);
  width: var(--bar, 30%);
}

/* src styles.css L24120: .bbs-pipeline */
.keepa-dashboard-pipeline {
  display: grid;
  grid-template-columns: 1fr auto 1fr auto 1fr;
  gap: 10px;
  align-items: stretch;
  padding: 14px 16px;
  background: #fff;
  border: 1px solid var(--bbs-border);
  border-radius: var(--bbs-radius);
  box-shadow: var(--bbs-shadow-sm);
  margin-bottom: 14px;
}

/* src styles.css L24132: .bbs-pipeline__node */
.keepa-dashboard-pipeline__node {
  padding: 10px 12px;
  background: #f8fafc;
  border: 1px solid var(--bbs-border);
  border-radius: var(--bbs-radius-sm);
  min-width: 0;
}

/* src styles.css L24139: .bbs-pipeline__node--hub */
.keepa-dashboard-pipeline__node--hub {
  background: linear-gradient(180deg, #fff 0%, var(--bbs-primary-soft) 100%);
  border-color: #c7d6f5;
}

/* src styles.css L24143: .bbs-pipeline__role */
.keepa-dashboard-pipeline__role {
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--bbs-primary);
  font-weight: 700;
  margin-bottom: 2px;
}

/* src styles.css L24151: .bbs-pipeline__name */
.keepa-dashboard-pipeline__name {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--bbs-text);
  margin-bottom: 4px;
}

/* src styles.css L24157: .bbs-pipeline__desc */
.keepa-dashboard-pipeline__desc {
  font-size: 0.78rem;
  color: var(--bbs-text-soft);
  line-height: 1.4;
}

/* src styles.css L24162: .bbs-pipeline__desc code */
.keepa-dashboard-pipeline__desc code {
  background: var(--bbs-primary-soft);
  color: var(--bbs-primary);
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 0.92em;
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

/* src styles.css L24170: .bbs-pipeline__arrow */
.keepa-dashboard-pipeline__arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--bbs-primary);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
  min-width: 50px;
  position: relative;
}

/* src styles.css L24182: .bbs-pipeline__arrow::before */
.keepa-dashboard-pipeline__arrow::before {
  content: "";
  position: absolute;
  inset: 50% 0 auto 0;
  height: 1px;
  background: repeating-linear-gradient(90deg, #c7d6f5 0 4px, transparent 4px 8px);
}

/* src styles.css L24189: .bbs-pipeline__arrow > span */
.keepa-dashboard-pipeline__arrow > span {
  background: #fff;
  padding: 2px 6px;
  border-radius: 999px;
  position: relative;
  z-index: 1;
  border: 1px solid var(--bbs-border);
}

/* (Removed: duplicate `.keepa-dashboard-pipeline__arrow` + `::before` rules
   that the rename script erroneously extracted from inside an @media
   (max-width: 900px) block in styles.css and emitted as top-level rules.
   The mobile-only padding/min-height + connector-hide stay in the
   @media block at the end of this section. Plus an orphan `}` from the
   same parser bug. Caught by Codex round 2 review of PR #69.) */

.keepa-dashboard-summary-chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

/* src styles.css L24232: .bbs-form-grid */
.keepa-dashboard-form-grid {
  display: grid;
  gap: 12px;
}

/* src styles.css L24234: .bbs-form-grid--3 */
.keepa-dashboard-form-grid--3 {
  grid-template-columns: repeat(3, 1fr);
}

/* src styles.css L24235: .bbs-form-grid--4 */
.keepa-dashboard-form-grid--4 {
  grid-template-columns: repeat(4, 1fr);
}

/* src styles.css L24236: .bbs-form-grid--6 */
.keepa-dashboard-form-grid--6 {
  grid-template-columns: repeat(6, 1fr);
}

.keepa-dashboard-field {
  min-width: 0;
}

/* src styles.css L24249: .bbs-field label */
.keepa-dashboard-field label {
  display: block;
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--bbs-text-muted);
  font-weight: 700;
  margin-bottom: 4px;
}

/* src styles.css L24260: .bbs-field input, .bbs-field select, .bbs-field textarea */
.keepa-dashboard-field input,
.keepa-dashboard-field select,
.keepa-dashboard-field textarea {
  width: 100%;
  padding: 7px 10px;
  font-size: 0.88rem;
  background: #fff;
  border: 1px solid var(--bbs-border-strong);
  border-radius: 5px;
  color: var(--bbs-text);
  font-family: inherit;
  font-variant-numeric: tabular-nums;
  box-sizing: border-box;
}

/* src styles.css L24274: .bbs-field input:focus, .bbs-field select:focus, .bbs-field textarea:focus */
.keepa-dashboard-field input:focus,
.keepa-dashboard-field select:focus,
.keepa-dashboard-field textarea:focus {
  outline: none;
  border-color: var(--bbs-primary);
  box-shadow: 0 0 0 3px rgba(11, 61, 145, 0.12);
}

/* src styles.css L24279: .bbs-field input[readonly] */
.keepa-dashboard-field input[readonly] {
  background: #f8fafc;
  color: var(--bbs-text-muted);
}

/* src styles.css L24280: .bbs-field__hint */
.keepa-dashboard-field__hint {
  font-size: 0.72rem;
  color: var(--bbs-text-muted);
  margin-top: 3px;
  line-height: 1.4;
}

/* src styles.css L24281: .bbs-field__hint a */
.keepa-dashboard-field__hint a {
  color: var(--bbs-primary);
  text-decoration: none;
}

/* src styles.css L24282: .bbs-field__hint a:hover */
.keepa-dashboard-field__hint a:hover {
  text-decoration: underline;
}

/* src styles.css L24294: .bbs-run-panel__body */
.keepa-dashboard-run-panel__body {
  padding: 12px 16px;
  border-bottom: 1px solid var(--bbs-border);
  background: #fff;
}

/* src styles.css L24299: .bbs-run-panel__body:last-child */
.keepa-dashboard-run-panel__body:last-child {
  border-bottom: none;
}

/* src styles.css L24300: .bbs-run-panel__hint */
.keepa-dashboard-run-panel__hint {
  color: var(--bbs-text-soft);
  font-size: 0.82rem;
  line-height: 1.45;
}

/* src styles.css L24307: .bbs-live-dot */
.keepa-dashboard-live-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--bbs-ok);
  margin-right: 5px;
  vertical-align: middle;
  animation: bbs-pulse 1.4s ease-in-out infinite;
}



.keepa-dashboard-log-collapse td {
  padding: 0 !important;
  border-bottom: none !important;
  background: var(--bbs-terminal-bg);
}

/* src styles.css L24346: .bbs-log-collapse pre */
.keepa-dashboard-log-collapse pre {
  margin: 0;
  padding: 14px 18px;
  background: var(--bbs-terminal-bg);
  color: var(--bbs-terminal-text);
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.78rem;
  line-height: 1.5;
  max-height: 420px;
  overflow: auto;
  white-space: pre-wrap;
  word-break: break-word;
  border-top: 1px solid #1e293b;
}

/* src styles.css L24402: .bbs-stat-grid--5 */
.keepa-dashboard-stat-grid--5 {
  grid-template-columns: repeat(5, 1fr);
}

/* src styles.css L24405: .bbs-stat-grid--5 .bbs-stat */
.keepa-dashboard-stat-grid--5 .bbs-stat {
  padding: 8px 10px 8px 12px;
}

/* src styles.css L24408: .bbs-stat-grid--5 .bbs-stat__value */
.keepa-dashboard-stat-grid--5 .bbs-stat__value {
  font-size: 1.05rem;
}

/* src styles.css L24409: .bbs-stat-grid--5 .bbs-stat__label */
.keepa-dashboard-stat-grid--5 .bbs-stat__label {
  font-size: 0.62rem;
}

/* src styles.css L24410: .bbs-stat-grid--5 .bbs-stat__sub */
.keepa-dashboard-stat-grid--5 .bbs-stat__sub {
  font-size: 0.7rem;
}



.keepa-dashboard-stat-grid--scripts {
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 8px;
}

/* src styles.css L24419: .bbs-stat-grid--scripts .bbs-stat */
.keepa-dashboard-stat-grid--scripts .bbs-stat {
  padding: 8px 10px 8px 12px;
}

/* src styles.css L24422: .bbs-stat-grid--scripts .bbs-stat__label */
.keepa-dashboard-stat-grid--scripts .bbs-stat__label {
  font-size: 0.72rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--bbs-text);
  font-weight: 600;
  margin-bottom: 2px;
}

/* src styles.css L24430: .bbs-stat-grid--scripts .bbs-stat__value */
.keepa-dashboard-stat-grid--scripts .bbs-stat__value {
  font-size: 1.1rem;
  line-height: 1;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
}

/* src styles.css L24437: .bbs-stat-grid--scripts .bbs-stat__sub */
.keepa-dashboard-stat-grid--scripts .bbs-stat__sub {
  margin-top: 2px;
  font-size: 0.7rem;
}

/* src styles.css L24441: .bbs-stat-grid--scripts .bbs-summary-chips */
.keepa-dashboard-stat-grid--scripts .keepa-dashboard-summary-chips {
  margin-top: 4px;
  gap: 4px;
}

/* src styles.css L24445: .bbs-stat-grid--scripts .bbs-summary-chip */
.keepa-dashboard-stat-grid--scripts .bbs-summary-chip {
  padding: 1px 6px;
  font-size: 0.7rem;
}

/* src styles.css L24451: .bbs-table th.bbs-sortable */
.bbs-table th.keepa-dashboard-sortable {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

/* src styles.css L24456: .bbs-table th.bbs-sortable:hover */
.bbs-table th.keepa-dashboard-sortable:hover {
  background: var(--bbs-primary-soft);
  color: var(--bbs-primary);
}

/* src styles.css L24457: .bbs-table th.bbs-sortable::after */
.bbs-table th.keepa-dashboard-sortable::after {
  content: " \2195";
  display: inline-block;
  margin-left: 2px;
  color: #94a3b8;
  font-weight: 400;
}

/* src styles.css L24464: .bbs-table th.bbs-sortable.bbs-sorted-asc::after */
.bbs-table th.keepa-dashboard-sortable.keepa-dashboard-sorted-asc::after {
  content: " \25B2";
  color: var(--bbs-primary);
}

/* src styles.css L24465: .bbs-table th.bbs-sortable.bbs-sorted-desc::after */
.bbs-table th.keepa-dashboard-sortable.keepa-dashboard-sorted-desc::after {
  content: " \25BC";
  color: var(--bbs-primary);
}

/* src styles.css L24511: .bbs-stat, .bbs-chip */
.bbs-stat,
.keepa-dashboard-chip {
  overflow: visible;
}

/* src styles.css L24518: .bbs-stat .tooltip-label::after, .bbs-chip .tooltip-label::after */
.bbs-stat .tooltip-label::after,
.keepa-dashboard-chip .tooltip-label::after {
  min-width: 220px;
  max-width: min(360px, calc(100vw - 40px));
  white-space: normal;
  word-break: normal;
  overflow-wrap: break-word;
}


/* ---- HELPER COMPONENTS (11 components / 14 selectors) ----
   Inline-style consolidation per handoff/phase-3-2-pre/helper-classes.md.
   Token discipline: var(--bbs-*) references kept verbatim (Phase 3.3
   consolidates bbs-* tokens into tokens.css). Hardcoded #f1f5f9 / #f8fafc
   carry comments flagging them as candidates for --surface-2 in a future
   token-system pass. */

/* Helper 1 — Banner tones (no base; .bbs-intro provides border-left structure
   per pre-flight Finding 4). Replaces 4 inline-styles at template lines
   102, 106, 116 (danger) and 113 (warn). */
.keepa-dashboard-banner--danger {
  border-left-color: var(--bbs-danger);
  background: var(--bbs-danger-soft);
  color: var(--bbs-danger);
}
.keepa-dashboard-banner--warn {
  border-left-color: var(--bbs-warn);
  background: var(--bbs-warn-soft);
  color: var(--bbs-warn);
}

/* Helper 2 — Headline row. Replaces 2 inline-styles at lines 126, 193. */
.keepa-dashboard-headline-row {
  display: flex;
  align-items: baseline;
  gap: 20px;
  flex-wrap: wrap;
}

/* Helper 3 — Stat font sizes. Replaces 5 inline-styles at lines 127 (xl),
   196, 203, 210 (lg), 542 (md). The hero variant nests under
   `.bbs-stat--solo.bbs-stat--hero` in styles.css (`.bbs-stat__value`
   gets `font-size: 1.55rem` there); the old inline `font-size: 2rem`
   beat that via inline specificity, but a bare `.keepa-dashboard-stat-xl`
   loses (single class < compound class + descendant). Match the legacy
   parent chain to win specificity (caught by Codex round 5 review). */
.bbs-stat--solo.bbs-stat--hero .keepa-dashboard-stat-xl,
.keepa-dashboard-stat-xl { font-size: 2rem; }
.keepa-dashboard-stat-lg { font-size: 1.55rem; }
.keepa-dashboard-stat-md { font-size: 1rem; }

/* Helper 4 — Empty row. Replaces 6 inline-styles at lines 372, 463, 511,
   583, 695, 1034. The helper is applied to <td> elements inside
   .bbs-table; .bbs-table td has specificity (0,1,1) which beats a single-
   class (0,1,0), so the helper would otherwise lose for text-align /
   padding. Scoped as .bbs-table td.keepa-dashboard-empty-row to match
   the legacy specificity (caught by Codex round 6 review of PR #69). */
.bbs-table td.keepa-dashboard-empty-row,
.keepa-dashboard-empty-row {
  text-align: center;
  color: var(--bbs-text-muted);
  padding: 14px;
}

/* Helper 5 — Row actions (2-helper variant pattern; preserves visual
   variance). Base = lines 412, 552 (gap 8, no wrap). Modifier --wrap =
   line 640 (gap 10 + wrap). Zero visual change vs original inline. */
.keepa-dashboard-row-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}
.keepa-dashboard-row-actions--wrap {
  gap: 10px;
  flex-wrap: wrap;
}

.keepa-dashboard-inline-field {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--bbs-text-soft);
  font-weight: 600;
}

.keepa-dashboard-cache-search {
  min-width: 260px;
  max-width: min(520px, 52vw);
  min-height: 38px;
  resize: vertical;
  border: 1px solid var(--bbs-border);
  border-radius: var(--bbs-radius-sm);
  padding: 7px 9px;
  font: inherit;
  color: var(--bbs-text);
  background: #fff;
}

/* Helper 6 — Truncate. Replaces 3 inline-styles at lines 449, 460, 578.
   `max-width` stays inline per use (allow-listed; values vary
   220/140/360/conditional). */
.keepa-dashboard-truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Helper 7 — Mem-bar (container + fill). Replaces 2 inline-styles at lines
   215 (container) and 216 (fill). Width supplied inline per row via
   `style="width:{{ pct }}%;"` — width is allow-listed. */
.keepa-dashboard-mem-bar {
  margin-top: 12px;
  height: 6px;
  background: #f1f5f9;  /* no token; subtle row stripe, candidate for --surface-2 in token consolidation */
  border-radius: 3px;
  overflow: hidden;
}
.keepa-dashboard-mem-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, #16a34a 0%, #b45309 70%, #b91c1c 100%);
  /* no token; pressure gradient (green->orange->red), candidate for --pressure-* token tier in Phase 3.3+ */
}

/* Helper 8 — Cache-column panel cluster. Replaces 7 inline-styles at lines
   653, 655, 656, 657, 658, 664, 666. z-index 20 chosen to clear the local
   panel context; verify in smoke that it stacks above sticky table header
   / banner; bump if other UI overlaps. */
.keepa-dashboard-cache-column-panel-anchor {
  position: relative;
}
.keepa-dashboard-cache-column-panel {
  position: absolute;
  top: 32px;
  right: 0;
  z-index: 1200;  /* matches Phase 3.1 .purchase-dropdown-panel precedent; sits above .bbs-card__head sticky z=1000 */
  background: #fff;
  border: 1px solid var(--bbs-border);
  border-radius: 6px;
  box-shadow: var(--bbs-shadow-md);
  padding: 10px;
  overflow: auto;  /* preserved from original inline; ensures the column list scrolls when cache_column_defs exceed max-height (caught by Codex round 2 review of PR #69) */
}
.keepa-dashboard-cache-column-panel-label {
  font-size: 0.78rem;
  color: var(--bbs-text-muted);
  margin-bottom: 6px;
}
.keepa-dashboard-cache-column-panel-search {
  width: 100%;
  padding: 4px 8px;
  margin-bottom: 6px;
  font-size: 0.82rem;
  border: 1px solid var(--bbs-border);
  border-radius: 4px;
}
.keepa-dashboard-cache-column-panel-row {
  display: flex;
  gap: 4px;
  margin-bottom: 6px;
}
.keepa-dashboard-cache-column-panel-options {
  font-size: 0.82rem;
}
.keepa-dashboard-cache-column-panel-option {
  display: block;
  padding: 3px 0;
}

/* Helper 9 — Actions right. Replaces 2 inline-styles at lines 887, 962. */
.keepa-dashboard-actions-right {
  display: flex;
  justify-content: flex-end;
  margin-top: 12px;
}
.keepa-dashboard-actions-right--no-margin {
  margin-top: 0;
}

/* Helper 10 — Text tone utilities (scoped, NOT bare). Replaces 5 inline-styles
   at lines 240, 1026, 1027 (muted) and 327 (warn). Plus part of inline at
   313 (combined font-size + color — the color half via --warn). */
.keepa-dashboard-text--muted { color: var(--bbs-text-muted); }
.keepa-dashboard-text--warn  { color: var(--bbs-warn); }

/* Helper 11 — Microchip. Replaces 4 inline-styles at lines 419, 557, 643, 649.
   Relies on a wrapping span/badge component for border/bg/radius; this
   helper contributes only size + padding. Phase 3.3+ candidate for
   promotion to .chip--xs primitive once 2+ templates use it. */
.keepa-dashboard-microchip {
  font-size: 0.78rem;
  padding: 2px 6px;
}

/* Helper 12 — Card-flush + margin-zero. Replaces 6 inline-styles at lines
   822, 834, 835, 918, 933, 934. */
.keepa-dashboard-card--flush {
  margin: 0;
  border-radius: 0;
  box-shadow: none;
  border: 0;
  border-top: 1px solid var(--bbs-border);
}
/* Background lives on the <summary> child only — `.bbs-section__summary`
   paints its own white/open-state background, so applying the grey to the
   <details> parent inverted the intended header/body treatment in the
   refresh-worker admin sections (caught by Codex round 4 review of PR #69).
   The `[open]` variant covers the open state — `.bbs-section[open] >
   .bbs-section__summary` has higher specificity in styles.css and would
   otherwise restore the white background when the admin expands the
   section (caught by Codex round 5 review of PR #69). */
.keepa-dashboard-card--flush > .bbs-section__summary,
.bbs-section.keepa-dashboard-card--flush[open] > .bbs-section__summary {
  background: #f8fafc;  /* no token; subtle row stripe, candidate for --surface-2 in token consolidation */
}
.keepa-dashboard-card--margin-zero {
  margin: 0;
}

/* ---- STRAGGLERS (3 single-purpose helpers) ----
   Per spec, NOT grouped into a utility surface — semantic names in the
   keepa-dashboard-* namespace. The line-310 `color:inherit` case is
   deferred to template-edit step (verify against .bbs-page reset; if
   redundant, drop the inline). The line-234 `--bar:` and line-691
   conditional `max-width:` both pass via existing allow-list rules. */

/* Replaces inline at template line 276: `style="margin-top:8px;"` */
.keepa-dashboard-margin-top-sm {
  margin-top: 8px;
}

/* Replaces inline at template lines 341, 475: `style="padding:0;"` on
   table cells (semantic name preferred over `.padding-zero`). */
.keepa-dashboard-cell--flush {
  padding: 0;
}

/* Replaces inline at template line 678: `style="overflow-x:auto;"`
   on the table-wrap container. */
.keepa-dashboard-table-wrap-scroll {
  overflow-x: auto;
}

/* ---- SPEC-EXTENSION HELPERS (8 rules — patterns the helper-classes spec missed) ----
   These cover inline-style patterns surfaced during template-edit step that
   weren't included in handoff/phase-3-2-pre/helper-classes.md. Surface in
   the post-build collision-report.md as spec deltas. */

/* <a> reset (was Straggler line-310 'verify' case; resolved as a real helper
   because dropping the inline would inherit theme_br.css <a> styling, a
   visual change). */
.keepa-dashboard-stat-link {
  color: inherit;
  text-decoration: none;
}

/* Hero "tokens consumed · 1h" suffix span (line 140). */
.keepa-dashboard-token-suffix {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--bbs-text-soft);
}

/* "/100" suffix span on script cards (line 329). spec line-313 was flagged as
   "split: font-size handled separately, color via Helper #10" but no
   font-size helper at 0.65rem existed. Single combined helper instead. */
.keepa-dashboard-stat-suffix {
  font-size: 0.65rem;
  color: var(--bbs-text-muted);
  font-weight: 600;
}

/* (Removed duplicate `.keepa-dashboard-small-select` and
   `.keepa-dashboard-form-margin-zero` rules — pre-existing
   `.keepa-dashboard-microchip` (Helper #11) and
   `.keepa-dashboard-card--margin-zero` (Helper #12) cover the same
   property values; consolidated post-build per Claude Design's review.
   Template usages renamed to the canonical helper names.) */

/* Inline checkbox label inside form (line 898) — large compound style.
   Lives inside `<div class="keepa-dashboard-field">`, whose
   `.keepa-dashboard-field label` rule has higher specificity than a
   single-class selector and was masking display/font/color/text-transform/
   letter-spacing of this helper. Scoped under .keepa-dashboard-field to
   match (caught by Codex round 5 review). */
.keepa-dashboard-field .keepa-dashboard-inline-checkbox-label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 500;
  text-transform: none;
  font-size: 0.85rem;
  color: var(--bbs-text);
  letter-spacing: normal;
  margin-top: 0;
  padding: 7px 0;
}

/* `.bbs-intro` banner with margin-top/margin-bottom overrides (line 994). */
.keepa-dashboard-banner--margins {
  margin-top: 12px;
  margin-bottom: 8px;
}

/* margin-top: 12px (line 903 form-grid). Sibling to keepa-dashboard-margin-top-sm
   which is 8px. */
.keepa-dashboard-margin-top-md {
  margin-top: 12px;
}

/* Keepa Refresh Worker page cleanup: scoped to /keepa?tab=refresh_worker. */
.krw-page {
  display: grid;
  gap: 12px;
}

.krw-status-strip,
.krw-title-card,
.krw-kpi-card,
.krw-card,
.krw-support-card,
.krw-events {
  background: #fff;
  border: 1px solid var(--bbs-border);
  border-radius: 8px;
  box-shadow: var(--bbs-shadow-sm);
}

.krw-status-strip {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: stretch;
  overflow: hidden;
}

.krw-status-strip__item {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding: 12px 14px;
  border-right: 1px solid var(--bbs-border);
}

.krw-status-strip__item:last-child {
  border-right: 0;
}

.krw-status-strip__item:nth-child(3n) {
  border-right: 0;
}

.krw-status-strip__icon,
.krw-kpi-card__icon,
.krw-title-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  color: var(--bbs-primary);
}

.krw-status-strip__icon {
  width: 30px;
  height: 30px;
  border-radius: 999px;
  background: var(--bbs-primary-soft);
}

.krw-status-strip__icon svg,
.krw-kpi-card__icon svg,
.krw-title-card__icon svg,
.krw-support-card header svg,
.krw-coverage-item__label svg,
.krw-status-item svg,
.krw-events summary svg {
  width: 16px;
  height: 16px;
  stroke-width: 2;
}

.krw-status-strip__copy {
  display: grid;
  gap: 1px;
  min-width: 0;
}

.krw-status-strip__label,
.krw-kpi-card__head,
.krw-step,
.krw-support-card header span,
.krw-support-card dt,
.krw-summary-list dt {
  font-size: 0.72rem;
  color: var(--bbs-text-muted);
  font-weight: 700;
  letter-spacing: 0;
}

.krw-status-strip__copy strong {
  font-size: 0.94rem;
  color: var(--bbs-text);
  line-height: 1.15;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.krw-status-strip__copy span:last-child {
  font-size: 0.7rem;
  color: var(--bbs-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.krw-tone-ok .krw-status-strip__icon,
.krw-tone-ok.krw-status-item svg {
  color: var(--bbs-ok);
  background: var(--bbs-ok-soft);
}

.krw-tone-warn .krw-status-strip__icon,
.krw-tone-warn.krw-status-item svg {
  color: var(--bbs-warn);
  background: var(--bbs-warn-soft);
}

.krw-tone-danger .krw-status-strip__icon,
.krw-tone-danger.krw-status-item svg {
  color: var(--bbs-danger);
  background: var(--bbs-danger-soft);
}

.krw-tone-muted .krw-status-strip__icon,
.krw-tone-muted.krw-status-item svg {
  color: var(--bbs-text-muted);
  background: #f1f5f9;
}

.krw-title-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  padding: 22px 24px;
}

.krw-title-card .krw-status-strip {
  grid-column: 1 / -1;
  box-shadow: none;
  background: #f8fafc;
  border-radius: 6px;
}

.krw-title-card__icon {
  width: 54px;
  height: 54px;
  border-radius: 999px;
  background: var(--bbs-primary);
  color: #fff;
}

.krw-title-card__icon svg {
  width: 28px;
  height: 28px;
}

.krw-title-card__copy {
  min-width: 0;
}

.krw-step {
  color: var(--bbs-primary);
}

.krw-title-card h2,
.krw-section-head h3,
.krw-support-card h3 {
  margin: 0;
  color: var(--bbs-text);
  letter-spacing: 0;
}

.krw-title-card h2 {
  font-size: 1.72rem;
  line-height: 1.1;
  margin-top: 2px;
}

.krw-title-card p,
.krw-section-head p,
.krw-support-card p,
.krw-title-card__detail {
  color: var(--bbs-text-soft);
  font-size: 0.84rem;
  line-height: 1.4;
}

.krw-title-card p {
  margin: 6px 0 0;
}

.krw-title-card__detail {
  display: block;
  margin-top: 4px;
}

.krw-title-card__detail--warn {
  color: var(--bbs-warn);
}

.krw-range-selector {
  display: inline-grid;
  grid-template-columns: repeat(4, 1fr);
  border: 1px solid #b8cff8;
  border-radius: 6px;
  overflow: hidden;
  min-width: 230px;
}

.krw-range-selector__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 36px;
  padding: 0 16px;
  border-right: 1px solid #dbe7fb;
  color: var(--bbs-text);
  text-decoration: none;
  font-size: 0.82rem;
  font-weight: 700;
}

.krw-range-selector__item:last-child {
  border-right: 0;
}

.krw-range-selector__item.is-active {
  background: #eff6ff;
  color: var(--bbs-primary);
  box-shadow: inset 0 0 0 1px var(--bbs-primary);
}

.krw-kpi-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 10px;
}

.krw-kpi-card {
  min-width: 0;
  padding: 14px 16px;
}

.krw-kpi-card__head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.krw-kpi-card__icon {
  color: var(--bbs-primary);
}

.krw-kpi-card > strong {
  display: block;
  color: var(--bbs-text);
  font-size: 1.45rem;
  line-height: 1.1;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.krw-kpi-card__delta,
.krw-kpi-card__sub {
  margin-top: 8px;
  font-size: 0.72rem;
  color: var(--bbs-text-muted);
}

.krw-kpi-card__delta.is-up {
  color: var(--bbs-ok);
}

.krw-kpi-card__delta.is-down {
  color: var(--bbs-danger);
}

.krw-main-grid,
.krw-secondary-grid,
.krw-throughput-grid {
  display: grid;
  gap: 12px;
  align-items: stretch;
}

.krw-main-grid {
  grid-template-columns: minmax(0, 2.2fr) minmax(230px, 0.78fr);
}

.krw-secondary-grid {
  grid-template-columns: minmax(0, 1.28fr) minmax(320px, 0.9fr);
}

.krw-throughput-grid {
  grid-template-columns: minmax(0, 0.9fr) minmax(320px, 1.1fr);
}

.krw-card {
  padding: 16px;
  min-width: 0;
}

.krw-section-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.krw-section-head h3 {
  font-size: 0.98rem;
}

.krw-section-head p {
  margin: 3px 0 0;
}

.krw-section-note {
  display: block;
  margin-top: 4px;
  color: var(--bbs-text-muted);
  font-size: 0.72rem;
  line-height: 1.25;
}

.krw-chip,
.krw-pill {
  display: inline-flex;
  align-items: center;
  min-height: 22px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 700;
  color: var(--bbs-primary);
  background: var(--bbs-primary-soft);
  white-space: nowrap;
}

.krw-pill--ok {
  color: var(--bbs-ok);
  background: var(--bbs-ok-soft);
}

.krw-pill--warn {
  color: var(--bbs-warn);
  background: var(--bbs-warn-soft);
}

.krw-chart-frame {
  min-height: 320px;
}

.krw-throughput-chart {
  display: block;
  width: 100%;
  height: 320px;
}

.krw-chart-grid {
  stroke: #dbe3ef;
  stroke-dasharray: 3 4;
  stroke-width: 1;
}

.krw-chart-area {
  fill: url(#krwAreaGradient);
}

.krw-chart-line {
  fill: none;
  stroke: #2563eb;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.krw-chart-low {
  fill: #fff;
  stroke: var(--bbs-danger);
  stroke-width: 3;
}

.krw-chart-y-label,
.krw-chart-x-label {
  fill: var(--bbs-text-muted);
  font-size: 10px;
  font-weight: 600;
}

.krw-chart-x-label {
  text-anchor: middle;
}

.krw-empty-chart {
  min-height: 320px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--bbs-text-muted);
  border: 1px dashed var(--bbs-border);
  border-radius: 6px;
  background: #f8fafc;
}

.krw-summary-list,
.krw-support-card dl {
  display: grid;
  margin: 0;
}

.krw-summary-list {
  gap: 0;
}

.krw-summary-list > div {
  padding: 10px 0;
  border-bottom: 1px solid var(--bbs-border);
}

.krw-summary-list > div:last-child {
  border-bottom: 0;
}

.krw-summary-list dd {
  margin: 2px 0 0;
  color: var(--bbs-text);
  font-size: 1.16rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.krw-summary-list span {
  color: var(--bbs-text-muted);
  font-size: 0.72rem;
}

.krw-summary-list .is-danger dd {
  color: var(--bbs-danger);
}

.krw-coverage-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
}

.krw-coverage-item,
.krw-status-item {
  min-width: 0;
}

.krw-coverage-item__label {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--bbs-text);
  font-size: 0.72rem;
  font-weight: 700;
  min-height: 32px;
}

.krw-coverage-item__label svg {
  color: var(--bbs-primary);
}

.krw-coverage-item strong,
.krw-status-item strong {
  display: block;
  color: var(--bbs-text);
  font-size: 1rem;
  line-height: 1.1;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.krw-coverage-item > span {
  display: block;
  margin-top: 5px;
  color: var(--bbs-text-muted);
  font-size: 0.72rem;
}

.krw-coverage-item > em {
  display: block;
  margin-top: 4px;
  color: var(--bbs-text-muted);
  font-size: 0.68rem;
  font-style: normal;
}

.krw-coverage-columns {
  margin-top: 7px;
  color: var(--bbs-text-muted);
  font-size: 0.68rem;
}

.krw-coverage-columns summary {
  cursor: pointer;
  color: var(--bbs-text);
  font-weight: 700;
}

.krw-field-table {
  display: grid;
  gap: 0;
  max-height: 360px;
  overflow: auto;
  margin: 6px 0 0;
  padding: 0;
  border-top: 1px solid var(--bbs-border);
}

.krw-field-row {
  display: grid;
  grid-template-columns:
    minmax(150px, 1.1fr)
    minmax(170px, 1.25fr)
    minmax(110px, 0.75fr)
    minmax(92px, 0.65fr)
    minmax(120px, 0.85fr)
    minmax(78px, 0.5fr);
  gap: 8px;
  align-items: start;
  padding: 8px 0;
  border-bottom: 1px solid var(--bbs-border);
}

.krw-field-row--head {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 7px 0;
  color: var(--bbs-text);
  background: var(--surface, #fff);
  font-size: 0.64rem;
  font-weight: 800;
  text-transform: uppercase;
}

.krw-field-row span {
  min-width: 0;
  overflow-wrap: anywhere;
}

.krw-field-row strong {
  display: block;
  color: var(--bbs-text);
  font-size: 0.68rem;
  line-height: 1.25;
}

.krw-field-row em {
  display: block;
  margin-top: 2px;
  color: var(--bbs-text-muted);
  font-size: 0.64rem;
  font-style: normal;
}

.krw-coverage-columns code {
  overflow-wrap: anywhere;
  color: var(--bbs-text);
  font-size: 0.66rem;
}

.krw-field-status {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 70px;
  padding: 3px 7px;
  border-radius: 999px;
  border: 1px solid var(--bbs-border);
  background: rgba(148, 163, 184, 0.12);
  color: var(--bbs-text);
  font-size: 0.62rem;
  font-weight: 800;
  text-transform: uppercase;
}

.krw-field-status--ok {
  color: #166534;
  border-color: rgba(22, 101, 52, 0.28);
  background: rgba(34, 197, 94, 0.12);
}

.krw-field-status--warn {
  color: #92400e;
  border-color: rgba(146, 64, 14, 0.28);
  background: rgba(245, 158, 11, 0.12);
}

.krw-field-status--danger {
  color: #991b1b;
  border-color: rgba(153, 27, 27, 0.28);
  background: rgba(239, 68, 68, 0.12);
}

.krw-progress,
.krw-mini-bar {
  height: 6px;
  border-radius: 999px;
  background: #e8eef7;
  overflow: hidden;
}

.krw-progress {
  margin-top: 8px;
}

.krw-mini-bar {
  margin-top: 10px;
}

.krw-progress span,
.krw-mini-bar span {
  display: block;
  height: 100%;
  width: min(100%, max(0%, var(--pct, 0%)));
  border-radius: inherit;
  background: linear-gradient(90deg, #16a34a, #2563eb);
}

.krw-status-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}

.krw-status-item {
  display: grid;
  gap: 5px;
  border-left: 1px solid var(--bbs-border);
  padding-left: 12px;
}

.krw-status-item:first-child {
  border-left: 0;
  padding-left: 0;
}

.krw-status-item span,
.krw-status-item em {
  color: var(--bbs-text-muted);
  font-size: 0.72rem;
  font-style: normal;
  font-weight: 700;
}

.krw-support-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 12px;
}

.krw-support-card {
  min-width: 0;
  padding: 16px;
}

.krw-support-card header {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 12px;
}

.krw-support-card header > svg {
  flex: 0 0 auto;
  color: var(--bbs-primary);
}

.krw-support-card header > div {
  min-width: 0;
  flex: 1 1 auto;
}

.krw-support-card h3 {
  font-size: 0.95rem;
}

.krw-support-card dl {
  gap: 8px;
}

.krw-support-card dl > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.krw-support-card dt {
  flex: 0 0 auto;
}

.krw-support-card dd {
  margin: 0;
  color: var(--bbs-text);
  font-size: 0.82rem;
  font-weight: 700;
  text-align: right;
  min-width: 0;
  overflow-wrap: anywhere;
}

.krw-support-card p {
  margin: 10px 0 0;
}

.krw-card-action {
  margin: 12px 0 0;
}

.krw-inline-details {
  margin-top: 12px;
  border-top: 1px solid var(--bbs-border);
  padding-top: 10px;
}

.krw-inline-details summary {
  cursor: pointer;
  color: var(--bbs-primary);
  font-size: 0.82rem;
  font-weight: 800;
}

.krw-inline-details form {
  margin-top: 12px;
}

.krw-events {
  overflow: hidden;
}

.krw-events > summary {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  min-height: 56px;
  padding: 0 16px;
  cursor: pointer;
  list-style: none;
}

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

.krw-events > summary span {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--bbs-text);
  font-weight: 800;
}

.krw-events > summary small {
  color: var(--bbs-text-muted);
  font-size: 0.78rem;
  font-weight: 700;
}

.krw-events[open] > summary {
  border-bottom: 1px solid var(--bbs-border);
}

.krw-events[open] > summary svg:last-child {
  transform: rotate(180deg);
}

.krw-events .bbs-table {
  margin: 0;
}

/* ---- @MEDIA RESPONSIVE OVERRIDES ----
   Ported verbatim from styles.css (lines 24236-24237, 24382-24386, 24422-24426,
   24427-24432 partial, 24601-24602) with bucket-A class names renamed.

   The legacy `@media (max-width: 540px) { .bbs-form-grid--2, .bbs-form-grid--3,
   .bbs-form-grid--4, .bbs-form-grid--6 { grid-template-columns: 1fr; } }` mixed
   bucket-A (`--3/--4/--6`) with bucket-B (`--2`). The bucket-A halves move
   here; the bucket-B `.bbs-form-grid--2` half stays in styles.css under its
   own @media wrapper. */

@media (max-width: 820px) { .keepa-dashboard-chip-row { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 540px) { .keepa-dashboard-chip-row { grid-template-columns: repeat(2, 1fr); } }

@media (max-width: 900px) {
  .keepa-dashboard-pipeline { grid-template-columns: 1fr; }
  .keepa-dashboard-pipeline__arrow { padding: 4px 0; min-height: 16px; }
  .keepa-dashboard-pipeline__arrow::before { display: none; }
}

@media (max-width: 900px) {
  .keepa-dashboard-form-grid--3, .keepa-dashboard-form-grid--4, .keepa-dashboard-form-grid--6 {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 540px) {
  .keepa-dashboard-form-grid--3, .keepa-dashboard-form-grid--4, .keepa-dashboard-form-grid--6 {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 1100px) { .keepa-dashboard-stat-grid--5 { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 720px)  { .keepa-dashboard-stat-grid--5 { grid-template-columns: repeat(2, 1fr); } }

@media (max-width: 1260px) {
  .krw-status-strip { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .krw-status-strip__item:nth-child(3n) { border-right: 1px solid var(--bbs-border); }
  .krw-status-strip__item:nth-child(4n) { border-right: 0; }
  .krw-kpi-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .krw-support-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .krw-coverage-grid { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
}

@media (max-width: 900px) {
  .krw-title-card { grid-template-columns: auto minmax(0, 1fr); }
  .krw-range-selector { grid-column: 1 / -1; width: 100%; }
  .krw-main-grid,
  .krw-secondary-grid,
  .krw-throughput-grid { grid-template-columns: 1fr; }
  .krw-status-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .krw-status-strip__item:nth-child(2n) { border-right: 0; }
  .krw-field-row {
    grid-template-columns: minmax(150px, 1fr) minmax(150px, 1fr);
  }
  .krw-field-row--head {
    display: none;
  }
}

@media (max-width: 640px) {
  .krw-title-card {
    grid-template-columns: 1fr;
    padding: 18px;
  }
  .krw-title-card__icon {
    width: 44px;
    height: 44px;
  }
  .krw-status-strip,
  .krw-kpi-grid,
  .krw-support-grid,
  .krw-coverage-grid,
  .krw-status-grid {
    grid-template-columns: 1fr;
  }
  .krw-field-row {
    grid-template-columns: 1fr;
  }
  .krw-status-strip__item,
  .krw-status-strip__item:nth-child(2n),
  .krw-status-strip__item:nth-child(4n) {
    border-right: 0;
    border-bottom: 1px solid var(--bbs-border);
  }
  .krw-status-strip__item:last-child {
    border-bottom: 0;
  }
  .krw-status-item,
  .krw-status-item:first-child {
    border-left: 0;
    padding-left: 0;
    border-bottom: 1px solid var(--bbs-border);
    padding-bottom: 10px;
  }
  .krw-status-item:last-child {
    border-bottom: 0;
    padding-bottom: 0;
  }
  .krw-events > summary {
    grid-template-columns: minmax(0, 1fr) auto;
  }
  .krw-events > summary small {
    grid-column: 1 / -1;
  }
}

/* ════════════════════════════════════════════════════════════════════════
   POLISH 3 — bare `header { … }` element-selector leak neutralizer
   ════════════════════════════════════════════════════════════════════════
   Background:
     styles.css L32  (legacy navy nav)   — bare `header { ... }` setting
                                           position: sticky, top, z-index,
                                           navy bg + white color, padding,
                                           grid layout. Normal priority.
     styles.css L13981 (modern nav strip) — bare `header { ... }` re-asserting
                                           position: sticky, top, z-index,
                                           box-shadow halo. Plus the rule
                                           used to carry display/padding/
                                           background/color !important
                                           markers that clobbered every
                                           `<header class="...">` element
                                           in the DOM. Polish 3 removes
                                           those !important markers so
                                           per-class layout rules can win
                                           on specificity (see styles.css
                                           edit in this same commit).

   Both rules were intended for the app's top-level navigation header,
   but the bare element-selector form leaks the four NON-!important
   chrome properties (position: sticky, top: 0, z-index: 1000, box-shadow)
   onto every `<header>` element in the document — including local
   content headers like `.bbs-card__head`, `.page-header`,
   `.diagnostics-v2__card-head`, `.engine-card__header`, the no-class
   `<header>` wrappers inside `admin_user_edit.html`'s
   `.admin-user-edit-section`, etc. (47 such consumers across 7 class
   signatures + 3 unclassed wrappers as of d523541.)

   The intentional consumer is `<header class="topbar">` (base.html L259),
   which has its own theme_br.css rule (§TOPBAR above, L373) that sets
   the sticky+border+height chrome it actually needs. Polish 3 exempts
   `.topbar` from the neutralizer.

   Scope (matches Andrew's polish-3 brief):
     - Sticky positioning leak ............ position: sticky → static
     - Stack ordering leak ................ top: 0 + z-index: 1000 → auto
     - Halo/shadow leak ................... box-shadow: 0 8px 24px → none
     - Forced zero padding on consumers ... addressed by removing
                                            !important markers from
                                            styles.css L13981 in the
                                            same commit (per-class rules
                                            now win on specificity).
     - Navy background leak ............... already pre-empted by L13981's
                                            background: transparent (which
                                            is left in place after the
                                            !important markers are
                                            removed), and per-class rules
                                            now win where they want a
                                            non-transparent fill.

   The selector `header:not(.topbar)` has specificity (0,1,1) — beats
   bare `header { … }` (0,0,1) but loses to per-class rules (0,1,0
   beats us via tie-break? no — class selector specificity is 0,1,0;
   element+class selector is 0,1,1; we win). Per-class rules with
   !important still win over us, which is correct.

   Future proofing: the test_design_guardrails.py sentinel
   `test_polish_3_header_neutralizer_present` fails if this rule is
   removed without a same-PR replacement. */
header:not(.topbar) {
  position: static;
  top: auto;
  z-index: auto;
  box-shadow: none;
}

/* ════════════════════════════════════════════════════════════════════════
   POLISH 2 — flat title + flat tabs + clean card alignment (app-wide)
   ════════════════════════════════════════════════════════════════════════
   Sources of truth:
     - handoff/phase-keepa-polish-2-pre/alignment-note.md
     - handoff/phase-keepa-polish-2-pre/build-prompt.md
     - https://scripts.book-runners.net/?tab=scripts (live canonical render)

   Scripts (`/?tab=scripts`) is the canonical Tiger expression. The rules
   below pull every consumer of the legacy `.bbs-header*` page-title block
   and the legacy `.function-page-tab*` tab pills onto the same flat shape
   that the Scripts page already uses via `.page-header` + `.subnav-tab`.
   theme_br.css loads after styles.css, so equal-specificity overrides
   win on cascade order — no `!important` required.

   App-wide propagation by design (build prompt §4d). Side effects:
     - Buyback (`buyback_site.html`) renders flat title + flat tabs.
     - Engine dashboard (`engine_dashboard.html`) renders flat title +
       flat tabs.
     - Any other consumer of `.bbs-header` / `.function-page-tab*` /
       `.bbs-card` flips to the same Tiger flat treatment.
   No template, route, schema, or behavior changes — pure CSS.

   Out of scope (still parked at `phase-keepa-ia-pre/`):
     - Renaming / reordering / collapsing Keepa tabs.
   ════════════════════════════════════════════════════════════════════════ */

/* ── §4 / Issue 2 — Page-title block sits flat on the page background ──
   Mirrors the Scripts `.page-header` / `.page-heading-title` / `.page-subtitle`
   shape (theme_br.css §PAGE WRAPPER above). The Buyback / Keepa / Engine
   pages keep their `.bbs-header__*` markup; only the chrome changes.
*/
.bbs-header {
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
  /* Drop the legacy 18px/20px vertical pad — the page wrapper already
     supplies the gutter. Keep the spacing below the header so the tab
     row doesn't crash into the title. */
  padding: 0;
  margin: 0 0 var(--space-5);
}
.bbs-header__title {
  /* Inter-only world (Polish 2 §3): hierarchy via weight + size. The
     legacy rule was 1.6rem / weight 700 — keep weight 700, normalize
     size + spacing to match the Scripts `.page-heading-title`. */
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.015em;
  margin: 4px 0 6px;
  color: var(--text);
}
.bbs-header__subtitle {
  color: var(--text-muted);
  font-size: 13.5px;
  max-width: 70ch;
  margin: 0;
}
.bbs-header__eyebrow {
  /* Already small-caps brand-orange; just normalize against tokens. */
  color: var(--brand-deep);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 700;
}

/* ── §4 / Issue 2 — Tab strip sits flat. No row chrome, no per-tab pills.
   Active tab = font-weight 600 + 2px var(--brand) border-bottom only.
   This mirrors `.subnav` / `.subnav-tab` (theme_br.css §TABS / SUBNAV).
*/
.function-page-tabs {
  display: flex;
  flex-wrap: nowrap;
  gap: 2px;
  margin: 0 0 var(--space-5);
  padding: 0;
  border: none;
  border-bottom: 1px solid var(--border);
  background: transparent;
  border-radius: 0;
  overflow-x: auto;
}
.function-page-tab {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 10px 14px;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  margin-bottom: -1px;
  color: var(--text-muted);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.function-page-tab:hover {
  background: transparent;
  color: var(--text);
  border-bottom-color: transparent;
}
.function-page-tab.is-active,
.function-page-tab[aria-current="page"] {
  background: transparent;
  color: var(--text);
  border-color: transparent;
  border-bottom: 2px solid var(--brand);
  border-radius: 0;
  font-weight: 600;
}
.function-page-tab.is-active:hover,
.function-page-tab[aria-current="page"]:hover {
  background: transparent;
  color: var(--text);
}
.function-page-tab[disabled],
.function-page-tab.is-disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

/* Secondary tab row (Price Engine sub-row). The legacy rule painted the
   row with a soft-blue gradient + a darker active fill; flatten it. */
.function-page-tabs--engine,
.function-page-tabs--secondary {
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  padding: 0;
  margin: -8px 0 var(--space-5);
}
.function-page-tab--engine,
.function-page-tab--secondary {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 0;
  color: var(--text-muted);
  font-size: 13px;
  padding: 8px 12px;
}
.function-page-tab--engine:hover,
.function-page-tab--secondary:hover {
  background: transparent;
  color: var(--text);
}
.function-page-tab--engine.is-active,
.function-page-tab--secondary.is-active {
  background: transparent;
  color: var(--text);
  border-color: transparent;
  border-bottom: 2px solid var(--brand);
  font-weight: 600;
}
.function-page-tab--engine.is-active:hover,
.function-page-tab--secondary.is-active:hover {
  background: transparent;
  color: var(--text);
}
/* The `__sep` separator between the Keepa primary row and the Price
   Engine sub-row was a styled pipe character that only made sense
   alongside the pill chrome. Hide it; flat rows don't need it. */
.function-page-tabs .function-page-tabs__sep { display: none; }

/* Specificity-booster overrides — `.bbs-page` is the page wrapper class
   on every Keepa / Engine / Buyback page that includes
   `_keepa_engine_header.html` (and on the Buyback dashboard). styles.css
   has a `.bbs-page .function-page-tabs { margin: 0 0 14px }` rule (0,2,0)
   that beat my single-class (0,1,0) margin rule on those pages. Re-state
   the layout properties at the same compound specificity so my values
   stick deterministically. Codex round-1 review flag.

   Diagnostics page now uses the Tiger `.subnav` / `.subnav-tab` system
   verbatim (PR-1 swap; `.diagnostics-tabs` markup retired). The legacy
   bespoke dark-pill `.diagnostics-tabs` rules in styles.css are dead
   code — kept only because PR-3b1 explicitly defers dead-namespace
   sweeps to PR-3b2. The `.bbs-page .function-page-tabs` rule below
   still matches Keepa, Engine, and Buyback pages, where the Tiger
   subnav rebody applies. */
.bbs-page .function-page-tabs {
  margin: 0 0 var(--space-5);
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  padding: 0;
}
/* The Price Engine sub-row sits directly below the primary Keepa tab
   row and snugs up via `margin-top: -8px`. The compound `.bbs-page
   .function-page-tabs` selector above (0,2,0) is more specific than the
   plain `.function-page-tabs--engine` rule (0,1,0), so without this
   matching-specificity restate the engine row would lose its snug top
   margin on Keepa/Engine pages. Codex round-2 review flag. */
.bbs-page .function-page-tabs--engine,
.bbs-page .function-page-tabs--secondary {
  margin: -8px 0 var(--space-5);
}
.bbs-page .bbs-header {
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
  margin: 0 0 var(--space-5);
}

/* Responsive header — drop the legacy padding the @media in styles.css
   re-asserted (we set padding:0 above; keep the tighter type at narrow
   widths). */
@media (max-width: 640px) {
  .bbs-header { padding: 0; }
  .bbs-header__title { font-size: 20px; }
}

/* ── §6 / Issue 4 — Single consistent left edge inside every .bbs-card ──
   Diagnosis: the head / body / list-item children of a .bbs-card all
   already pad to 16px horizontally, but `.bbs-card__head` carries a
   border-bottom + redundant white background that visually frames the
   title as a separate strip — making the body feel "more indented"
   relative to the title even though both align at x=16px from the
   card edge. Strip the visual frame so head / body read as one
   continuous content area; standardize padding on tokens.

   No structural / markup changes. No negative margins introduced.
*/
.bbs-card__head {
  /* Drop the head's separator border + redundant fill. The card border
     already encloses; the title doesn't need its own framed strip. */
  background: transparent;
  border-bottom: none;
  /* Standardize padding on tokens. Top/bottom 12px, sides 16px so the
     head visually sits inside the same gutter as the body.

     `!important` here is load-bearing: `.bbs-card__head` is rendered as a
     `<header>` element (template markup, see keepa_dashboard.html L303),
     and styles.css L13981 has a bare `header { padding: 0 !important; … }`
     rule meant for the platform nav strip. That rule's `!important`
     beats this class selector's normal-priority padding, which forced
     the card title flush to x=0 while the body sat at x=16 — the exact
     "left-edge zigzag" Issue 4 was raised against. Match the cascade
     strength so the title aligns with the body. Smoke-confirmed via
     preview_inspect post-fix. */
  padding: var(--space-3) var(--space-4) 0 !important;
  /* The same legacy `header` rule sets `box-shadow`, `position: sticky`,
     `top`, `z-index` at normal priority. Override them here at the
     higher class-selector specificity so card-heads don't inherit
     platform-nav chrome (notably an 8/24 dropshadow that read as a
     halo under the card title before this fix). */
  box-shadow: none;
  position: static;
  top: auto;
  z-index: auto;
}
.bbs-card__title {
  /* No negative margin. `margin: 0` was already correct in styles.css —
     re-state explicitly here so a future drift doesn't sneak past. */
  margin: 0;
}
.bbs-card__sub {
  margin: 0;
}
.bbs-card__body {
  padding: var(--space-3) var(--space-4) var(--space-4);
}
/* Optional flush variant — for cards that legitimately need a full-bleed
   table or list snug to the card edge. Add `bbs-card--flush` to opt in;
   today, no caller does. Documented per build-prompt §6c. */
.bbs-card.bbs-card--flush > .bbs-card__body { padding: 0; }
.bbs-card.bbs-card--flush > .bbs-list li { padding-left: var(--space-4); padding-right: var(--space-4); }

/* Legacy `.bbs-card` chrome predates the Tiger dark tokens and hard-codes
   white surfaces plus BBS-local text variables. Rebind the card family in
   dark mode so Keepa / Engine / shared BBS panels stay readable.
   `.bbs-page` is included so page-header titles/subtitles (which use the
   BBS-local --bbs-text / --bbs-text-soft tokens) become legible on the
   dark surface (P0 dark-mode contrast fix 2026-05-26). */
[data-theme="dark"] .bbs-page,
[data-theme="dark"] .bbs-card,
[data-theme="dark"] .keepa-dashboard-chip {
  --bbs-text: var(--text);
  --bbs-text-soft: var(--text-muted);
  --bbs-text-muted: var(--text-muted);
  --bbs-border: var(--border);
  --bbs-primary-soft: rgba(59, 130, 246, 0.16);
}

[data-theme="dark"] .bbs-card,
[data-theme="dark"] .keepa-dashboard-chip {
  background: var(--surface);
  border-color: var(--border);
  box-shadow: none;
}

[data-theme="dark"] .bbs-card__head {
  background: transparent;
}

/* Engine / Keepa dashboard status tab renders `.bbs-stat` cards and
   `.bbs-summary-chip` pills DIRECTLY on the page (not inside a `.bbs-card`),
   so the dark `.bbs-card` rebind above never reaches their hard-coded light
   surfaces — `.bbs-stat { background:#ffffff }`, the `.bbs-stat--hero` white
   gradient, and `.bbs-summary-chip { background:#f8fafc }`. The `--bbs-*`
   TEXT tokens ARE already dark-correct here (these elements sit under
   `.bbs-page`), so near-white `--bbs-text` (#e6eaf2) text landed on a white
   card for a ~1.15 contrast ratio (effectively invisible). Flip ONLY the
   surfaces; the text tokens stay as-is. Scoped to `main.keepa-dashboard-main`
   so verified buyback `.bbs-page` surfaces are untouched.
   (dark-mode wave-8 engine status, 2026-05-31) */
[data-theme="dark"] main.keepa-dashboard-main .bbs-stat {
  background: var(--surface);
  box-shadow: none;
}
[data-theme="dark"] main.keepa-dashboard-main .bbs-stat--hero {
  background: var(--surface);
  border-color: var(--border-strong);
}
[data-theme="dark"] main.keepa-dashboard-main .bbs-summary-chip {
  background: var(--surface-2);
}

/* `.engine-tone--*` color the status chips/banners with the BBS semantic
   tokens (`--bbs-warn` #b45309, `--bbs-ok` #16a34a, `--bbs-danger` #b91c1c),
   which are tuned for light surfaces and are NOT remapped in dark mode. On the
   dark chip surface above the warn tone gave only 2.87 contrast ("Does not
   match saved rules"). Re-point them at the brighter dark Tiger semantic
   tokens so chip + banner text clears WCAG AA on the dark engine surfaces.
   (dark-mode wave-8 engine status, 2026-05-31) */
[data-theme="dark"] main.keepa-dashboard-main .engine-tone--ok { color: var(--ok); }
[data-theme="dark"] main.keepa-dashboard-main .engine-tone--warn { color: var(--warn); }
[data-theme="dark"] main.keepa-dashboard-main .engine-tone--danger { color: var(--danger); }

/* Buyback Site / BookScouter Cache page cleanup. Scoped to the tab body so
   the shared app shell, sidebar, and other Buyback tabs keep their chrome. */
.bbs-bs-page {
  margin-top: 0;
}

.bbs-bs-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(300px, 320px);
  gap: 16px;
  align-items: start;
}

.bbs-bs-alert {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-bottom: 12px;
  padding: 10px 12px;
  line-height: 1.35;
}

.bbs-bs-main {
  min-width: 0;
}

.bbs-bs-side {
  display: grid;
  gap: 10px;
}

.bbs-bs-table-card {
  overflow: hidden;
}

.bbs-bs-table-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 14px;
  padding: 16px 16px 12px;
}

.bbs-bs-table-head h3,
.bbs-bs-metric-card h3 {
  margin: 0;
  color: var(--text);
  font-size: 14px;
  line-height: 1.2;
  font-weight: 700;
}

.bbs-bs-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
}

.bbs-bs-download {
  flex: 0 0 112px;
  justify-content: center;
  height: 34px;
  padding: 0 10px;
}

.bbs-bs-download [data-lucide],
.bbs-bs-search [data-lucide] {
  width: 14px;
  height: 14px;
}

.bbs-bs-select,
.bbs-bs-search {
  height: 34px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface);
  color: var(--text);
  box-shadow: none;
}

.bbs-bs-select {
  flex: 0 0 120px;
  width: 120px;
  min-width: 0;
  padding: 0 26px 0 10px;
  font: inherit;
  font-size: 12px;
}

.bbs-bs-search {
  display: inline-flex;
  align-items: center;
  flex: 0 0 160px;
  gap: 6px;
  min-width: 0;
  padding: 0 10px;
  color: var(--text-muted);
}

.bbs-bs-search input {
  width: 100%;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 12px;
}

.bbs-bs-search input::placeholder {
  color: var(--text-muted);
}

.bbs-bs-table-wrap {
  margin: 0;
  overflow-x: auto;
}

.bbs-table.bbs-bs-table {
  width: 100%;
  min-width: 0;
  table-layout: fixed;
  font-size: 12px;
}

.bbs-table.bbs-bs-table th,
.bbs-table.bbs-bs-table td {
  padding: 4px 6px;
  vertical-align: middle;
}

.bbs-table.bbs-bs-table thead th {
  background: #f8fafc;
  color: var(--text-subtle);
  font-size: 10px;
  letter-spacing: 0.035em;
}

.bbs-table.bbs-bs-table .bbs-sort-button {
  display: block;
  width: 100%;
  background: transparent;
  color: inherit;
  font-size: inherit;
  letter-spacing: inherit;
  text-transform: uppercase;
  white-space: normal;
  line-height: 1.2;
  box-shadow: none;
  text-decoration: none;
}

.bbs-table.bbs-bs-table .bbs-sort-button:hover,
.bbs-table.bbs-bs-table .bbs-sort-button:focus {
  background: transparent;
  color: inherit;
}

.bbs-table.bbs-bs-table .bbs-sort-button:focus-visible {
  border-radius: 4px;
  outline: 2px solid color-mix(in srgb, var(--brand) 35%, transparent);
  outline-offset: 2px;
}

.bbs-table.bbs-bs-table .bbs-sort-button::after {
  content: none !important;
}

.bbs-table.bbs-bs-table thead th:nth-child(1) { width: 10.8%; }
.bbs-table.bbs-bs-table thead th:nth-child(2) { width: 7.2%; }
.bbs-table.bbs-bs-table thead th:nth-child(3) { width: 7.2%; }
.bbs-table.bbs-bs-table thead th:nth-child(4) { width: 7.2%; }
.bbs-table.bbs-bs-table thead th:nth-child(5) { width: 4.4%; }
.bbs-table.bbs-bs-table thead th:nth-child(6) { width: 4.8%; }
.bbs-table.bbs-bs-table thead th:nth-child(7) { width: 7%; }
.bbs-table.bbs-bs-table thead th:nth-child(8) { width: 15%; }
.bbs-table.bbs-bs-table thead th:nth-child(9) { width: 7%; }
.bbs-table.bbs-bs-table thead th:nth-child(10) { width: 13.6%; }
.bbs-table.bbs-bs-table thead th:nth-child(11) { width: 7%; }
.bbs-table.bbs-bs-table thead th:nth-child(12) { width: 8.8%; }

.bbs-table.bbs-bs-table td {
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.25;
  white-space: nowrap;
}

.bbs-table.bbs-bs-table td:nth-child(1),
.bbs-table.bbs-bs-table td:nth-child(2),
.bbs-table.bbs-bs-table td[data-sort-key="highest_price"],
.bbs-table.bbs-bs-table td[data-sort-key="second_price"] {
  white-space: nowrap;
}

.bbs-table.bbs-bs-table td[data-sort-key="highest_seller"],
.bbs-table.bbs-bs-table td[data-sort-key="second_seller"] {
  max-width: none;
  white-space: nowrap;
  line-height: 1.25;
}

.bbs-table.bbs-bs-table td[data-sort-key="freshness"] {
  overflow-wrap: normal;
}

.bbs-table.bbs-bs-table td[data-sort-key="highest_price"] strong,
.bbs-table.bbs-bs-table td[data-sort-key="second_price"] strong {
  color: var(--text);
  font-size: 12.5px;
  font-weight: 800;
}

.bbs-table.bbs-bs-table .bbs-pill {
  padding: 2px 6px;
  font-size: 10.5px;
  line-height: 1.2;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

.bbs-bs-zero-note {
  margin-top: 2px;
  font-size: 11px;
  line-height: 1.2;
}

.bbs-bs-zero-note summary {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bbs-bs-zero-note[open] div {
  white-space: normal;
}

.bbs-bs-table-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px 14px;
  border-top: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 13px;
}

.bbs-bs-pagination {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.bbs-bs-page-link,
.bbs-bs-page-ellipsis {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  height: 30px;
  border-radius: 6px;
  font-size: 12px;
  text-decoration: none;
}

.bbs-bs-page-link {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
}

.bbs-bs-page-link:hover {
  color: var(--text);
  border-color: var(--border-strong);
}

.bbs-bs-page-link.is-active {
  color: var(--brand-deep);
  border-color: var(--brand);
  background: color-mix(in srgb, var(--brand) 8%, var(--surface));
}

.bbs-bs-page-link.is-disabled {
  opacity: 0.45;
  pointer-events: none;
}

.bbs-bs-page-ellipsis {
  color: var(--text-muted);
}

.bbs-bs-metric-card {
  padding: 13px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  box-shadow: none;
}

.bbs-bs-metric-card h3 {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.bbs-bs-metric-card h3 [data-lucide] {
  width: 15px;
  height: 15px;
  color: var(--brand);
}

.bbs-bs-metric-grid {
  display: grid;
  gap: 10px;
}

.bbs-bs-metric-grid--3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.bbs-bs-metric-grid--4 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.bbs-bs-metric-grid strong,
.bbs-bs-single-metric strong,
.bbs-bs-card-number {
  display: block;
  color: var(--text);
  font-size: 18px;
  line-height: 1.1;
  font-weight: 800;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

.bbs-bs-metric-grid span,
.bbs-bs-single-metric span,
.bbs-bs-muted,
.bbs-bs-metric-card p,
.bbs-bs-metric-card code {
  display: block;
  margin-top: 4px;
  color: var(--text-muted);
  font-size: 11.5px;
  line-height: 1.4;
}

.bbs-bs-single-metric {
  margin-top: 10px;
  padding-top: 9px;
  border-top: 1px solid var(--border);
}

.bbs-bs-metric-label {
  position: relative;
  display: inline-block;
  cursor: help;
  text-decoration: underline dotted rgba(100, 116, 139, 0.7);
  text-underline-offset: 3px;
}

.bbs-bs-metric-label::after {
  position: absolute;
  left: 0;
  bottom: calc(100% + 8px);
  z-index: 30;
  width: min(250px, 78vw);
  padding: 8px 10px;
  border: 1px solid rgba(15, 23, 42, 0.16);
  border-radius: 6px;
  background: #0f172a;
  color: #fff;
  box-shadow: 0 10px 24px rgba(15, 23, 42, 0.18);
  content: attr(data-bbs-tooltip);
  font-size: 11px;
  font-weight: 500;
  line-height: 1.35;
  opacity: 0;
  pointer-events: none;
  text-align: left;
  text-decoration: none;
  transform: translateY(4px);
  transition: opacity 0.12s ease, transform 0.12s ease, visibility 0.12s ease;
  visibility: hidden;
  white-space: normal;
}

.bbs-bs-metric-label::before {
  position: absolute;
  left: 12px;
  bottom: calc(100% + 3px);
  z-index: 31;
  width: 10px;
  height: 10px;
  background: #0f172a;
  content: "";
  opacity: 0;
  pointer-events: none;
  transform: translateY(4px) rotate(45deg);
  transition: opacity 0.12s ease, transform 0.12s ease, visibility 0.12s ease;
  visibility: hidden;
}

.bbs-bs-metric-grid--4 > div:nth-child(even) .bbs-bs-metric-label::after,
.bbs-bs-metric-grid--3 > div:nth-child(3) .bbs-bs-metric-label::after {
  right: 0;
  left: auto;
}

.bbs-bs-metric-grid--4 > div:nth-child(even) .bbs-bs-metric-label::before,
.bbs-bs-metric-grid--3 > div:nth-child(3) .bbs-bs-metric-label::before {
  right: 12px;
  left: auto;
}

.bbs-bs-metric-label:hover::after,
.bbs-bs-metric-label:hover::before,
.bbs-bs-metric-label:focus-visible::after,
.bbs-bs-metric-label:focus-visible::before {
  opacity: 1;
  transform: translateY(0);
  visibility: visible;
}

.bbs-bs-accent {
  color: var(--brand) !important;
}

.bbs-bs-danger {
  color: var(--danger) !important;
}

.bbs-bs-worker-line {
  margin-bottom: 9px;
}

.bbs-bs-metric-card code {
  padding: 0;
  background: transparent;
  border: 0;
  color: var(--text);
  font-family: var(--font-mono);
  overflow-wrap: anywhere;
}

.bbs-bs-progress {
  height: 5px;
  margin-top: 10px;
  border-radius: 999px;
  background: var(--surface-2);
  overflow: hidden;
}

.bbs-bs-progress span {
  display: block;
  width: min(100%, max(0%, var(--bs-progress, 0%)));
  height: 100%;
  border-radius: inherit;
  background: var(--brand);
}

@media (max-width: 1180px) {
  .bbs-bs-layout {
    grid-template-columns: 1fr;
  }

  .bbs-bs-side {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 760px) {
  .bbs-bs-table-head,
  .bbs-bs-table-footer {
    align-items: stretch;
    flex-direction: column;
  }

  .bbs-bs-actions {
    justify-content: flex-start;
  }

  .bbs-bs-side,
  .bbs-bs-metric-grid--3,
  .bbs-bs-metric-grid--4 {
    grid-template-columns: 1fr;
  }
}

/* ════════════════════════════════════════════════════════════════════════
   DIAGNOSTICS PAGE — PR-1 layout-only override (post PR-3b1)
   ════════════════════════════════════════════════════════════════════════
   PR-1 replaced `.diagnostics-shell` (banned `LEGACY_CLASS_BASES` entry)
   with `.bbs-page` and `.function-page-tabs.diagnostics-tabs` (also
   banned) with the Tiger-canonical `.subnav` / `.subnav-tab` pattern.
   The `.bbs-page` wrapper has no intrinsic grid/gap, so without this
   rule the hero sits flush against the tab strip — the rule below
   restores the predictable hero / tab strip / per-tab vertical rhythm
   the legacy `.diagnostics-shell` provided.

   PR-3b1 retired the rest of the PR-1 transitional cascade: the
   dark-coupled `.diagnostics-main .subnav` border-color override
   (legacy diagnostics tone `#2a3244`), the `.diagnostics-main .subnav
   { margin-bottom: 0 }` double-gap mitigation (the grid-gap is now the
   only source of spacing), and the `.diagnostics-main .subnav-tab`
   light-on-dark label tones. With the forced-dark chrome gone, the
   default Tiger `.subnav` / `.subnav-tab` styles (using `var(--border)`
   / `var(--text-muted)` / `var(--text)`) render correctly on the now-
   responsive Diagnostics surface.

   The grid-rhythm rule below keeps `.diagnostics-main` scope only as a
   page-specific layout cue; it carries no chrome and is theme-agnostic.
   PR-3b2 (primitive markup migration) will replace `.bbs-page` with
   the Tiger `.page` wrapper and may retire this rule entirely.
*/

/* PR-3b2d: restore the Diagnostics page rhythm + responsive text color
   that the deleted `.diagnostics-main .bbs-page` rule used to supply.
   The base `.bbs-page` rule in styles.css L18145+ hard-codes
   `color: var(--bbs-text)` (= `#0f172a`, dark navy) — fine for
   Buyback / Keepa / Engine pages, but it renders default `.banner` /
   `.text-muted` text invisible against Tiger's dark-mode `--surface`
   on Diagnostics. The companion class `.diagnostics-page` (added to
   the `.bbs-page` wrapper in `diagnostics.html`) re-tones the page
   to the Tiger responsive `--text` token and re-establishes the
   per-section vertical grid rhythm. Codex round-1 review flag
   (PR-3b2d). */
.bbs-page.diagnostics-page {
  display: grid;
  gap: var(--space-5);
  color: var(--text);
}

/* ════════════════════════════════════════════════════════════════════════
   DIAGNOSTICS PR-2 — utility / semantic classes for inline-style sweep
   ════════════════════════════════════════════════════════════════════════
   Replaces inline `style="font-size: ...; margin: ...; color: ..."` etc.
   on `diagnostics.html` so the page can join `ALLOW_LIST_MIGRATED` without
   tripping `test_no_uncontrolled_inline_styles` / `test_no_inline_color`.

   Naming follows the existing `.diagnostics-v2__*` BEM family used
   throughout the page (see styles.css L20720+); new modifiers/utilities
   are prefixed `.diagnostics-v2__` so they read as extensions of the v2
   family. Custom properties resolve through the existing `--d2-*` page-
   local tokens defined alongside that family.

   The `.diagnostics-main` body class still forces a dark surface
   regardless of `data-theme` (a future PR-3 retires that and these
   `--d2-*` tones become light/dark responsive). For now these classes
   are page-scoped via the `--d2-*` palette and read correctly on the
   forced-dark surface. */

/* Typography size modifiers */
.diagnostics-v2__text--xs { font-size: 11px; }
.diagnostics-v2__text--sm { font-size: 12px; }
.diagnostics-v2__text--md { font-size: 13px; }

/* Spacing utilities — margin-top / margin-bottom / margin-right */
.diagnostics-v2__mt-0 { margin-top: 0; }
.diagnostics-v2__mt-1 { margin-top: 4px; }
.diagnostics-v2__mt-2 { margin-top: 8px; }
.diagnostics-v2__mt-3 { margin-top: 10px; }
.diagnostics-v2__mt-4 { margin-top: 12px; }
.diagnostics-v2__mt-5 { margin-top: 14px; }
.diagnostics-v2__mt-6 { margin-top: 16px; }
.diagnostics-v2__mt-section { margin-top: 18px; }
.diagnostics-v2__mb-0 { margin-bottom: 0; }
.diagnostics-v2__mb-3 { margin-bottom: 10px; }
.diagnostics-v2__mb-4 { margin-bottom: 14px; }
.diagnostics-v2__mr-1 { margin-right: 4px; }

/* Highlighted text — restores `var(--text)` color for a span inside
   a `.diagnostics-v2__muted` block (e.g., a name highlighted in muted prose). */
.diagnostics-v2__highlight { color: var(--text); }

/* Page-local recommended-action accent — warm orange `#9a7200`. The hex
   is preserved as the page-local accent it always was (no token exists
   for it). PR-3 / future polish can promote it to a token if the palette
   grows. */
.diagnostics-v2__recommended-action {
  font-size: 11px;
  color: #9a7200;
}

/* Action row — used by the Webhooks tab to stack the test form, a muted
   helper note, and the recent-output list horizontally. */
.diagnostics-v2__action-row {
  margin-top: 16px;
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
}

/* `<details><summary>` styling used by the Retention tab explainers. */
.diagnostics-v2__summary {
  cursor: pointer;
  padding: 12px 16px;
  color: var(--text);
  font-weight: 600;
}
.diagnostics-v2__summary-meta {
  font-weight: 400;
  font-size: 12px;
  margin-left: 8px;
}

/* PR-3b2b: `.diagnostics-v2__card-body--bordered-top` /
 * `.__card-body--bordered-top-flush` retired. Callsites migrated to
 * Tiger `.card-body` / `.card-body--flush`, which inherit border-top
 * from the base `.card-body` rule in this file at L599-610. Codex
 * round-1 cascade-leak flag. */

/* Retention tab explainer paragraphs / lists — consistent rhythm. */
.diagnostics-v2__explainer-p {
  margin: 0 0 10px 0;
  font-size: 13px;
  color: var(--text);
}
.diagnostics-v2__explainer-list {
  font-size: 12px;
  line-height: 1.7;
  padding-left: 20px;
}
.diagnostics-v2__muted-list {
  font-size: 12px;
  line-height: 1.7;
  color: var(--text-muted);
  padding-left: 20px;
  margin: 0 0 12px 0;
}

/* Single-line truncation for table cell content (e.g., error_text on
   retention runs). */
.diagnostics-v2__truncate-line {
  margin-top: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Link-styled button — alerts-table acknowledge form button. */
.diagnostics-v2__link-button {
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
}

/* Retention table caption / notes-meta — small, padded note. */
.diagnostics-v2__notes-meta {
  font-size: 11px;
  padding: 0 16px 12px;
}

/* Margin compose modifiers for the legacy `.diagnostics-v2__muted`
   class — original rules don't carry margin defaults, so these flesh
   out the patterns the inline styles were doing case-by-case. */
.diagnostics-v2__muted--no-margin { margin: 0; }
.diagnostics-v2__muted--leading { margin: 0 0 12px; }
.diagnostics-v2__muted--p { margin: 0 0 10px 0; }

/* Diagnostics Daily App Email */
.bbs-page.diagnostics-page:has(.daily-email-workbench) {
  gap: 16px;
}

body.has-sidebar .page:has(.daily-email-workbench) {
  box-sizing: border-box;
  padding: 16px 18px 24px;
}

.daily-email-content-logo {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  color: #ffffff;
  background: linear-gradient(135deg, #ff6a16 0%, #f04f23 48%, #122a63 49%, #06164d 100%);
  font-size: 14px;
  font-weight: 900;
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.72);
}

.daily-email-content-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 18px;
  margin-bottom: 8px;
  padding: 0 0 4px;
}

.daily-email-content-title {
  display: flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.daily-email-content-title > div {
  min-width: 0;
  max-width: 100%;
}

.daily-email-content-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  color: #344775;
  font-size: 12px;
  font-weight: 700;
}

.daily-email-content-breadcrumb strong {
  color: #101b3d;
}

.daily-email-content-title h2 {
  margin: 3px 0 0;
  color: #07164b;
  font-size: 25px;
  line-height: 1.15;
  font-weight: 900;
}

.daily-email-content-title p {
  margin: 3px 0 0;
  color: #405174;
  font-size: 13px;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.daily-email-freshness-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 10px;
  padding: 8px 12px;
  border: 1px solid #dce3ef;
  border-radius: 6px;
  color: #344775;
  background: #ffffff;
  font-size: 12px;
  font-weight: 700;
}

.daily-email-freshness-line span {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  overflow-wrap: anywhere;
}

.daily-email-freshness-line svg {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  color: #0b63ff;
}

.daily-email-refresh-form {
  flex: 0 0 auto;
}

.daily-email-refresh-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-height: 30px;
  padding: 0 10px;
  border: 1px solid #c8d5e7;
  border-radius: 6px;
  color: #07164b;
  background: #f8fbff;
  font-size: 12px;
  font-weight: 900;
  white-space: nowrap;
}

.daily-email-refresh-button:disabled {
  cursor: wait;
  opacity: 0.68;
}

.daily-email-toolbar {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.daily-email-action-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 36px;
  padding: 0 16px;
  border: 1px solid #d9e1ef;
  border-radius: 6px;
  color: #0b63ff;
  background: #ffffff;
  font-size: 13px;
  font-weight: 800;
  white-space: nowrap;
}

.daily-email-action-btn svg {
  width: 16px;
  height: 16px;
}

.daily-email-action-btn:disabled {
  cursor: not-allowed;
  opacity: 0.58;
}

.daily-email-action-btn--compact {
  padding: 0 14px;
}

.daily-email-action-btn--primary {
  border-color: #07164b;
  color: #ffffff;
  background: #07164b;
  box-shadow: 0 9px 18px rgba(7, 22, 75, 0.14);
}

.daily-email-workbench {
  width: 100%;
  max-width: none;
  min-width: 0;
  margin: 0 auto;
}

.daily-email-config-form {
  display: block;
}

.daily-email-controls {
  display: grid;
  grid-template-columns: minmax(190px, 1fr) minmax(160px, 0.8fr) minmax(220px, 1.2fr) minmax(300px, 1.6fr) minmax(138px, 0.65fr);
  align-items: center;
  gap: 0;
  overflow: hidden;
  margin-bottom: 12px;
  padding: 12px 16px;
  border: 1px solid #dce3ef;
  border-radius: 8px;
  background: #ffffff;
  box-shadow: 0 5px 16px rgba(15, 27, 61, 0.04);
}

.daily-email-control {
  box-sizing: border-box;
  min-width: 0;
  min-inline-size: 0;
  margin: 0;
  padding: 0 16px;
  border-right: 1px solid #dfe6f1;
}

.daily-email-control:first-child {
  padding-left: 0;
}

.daily-email-control:last-child {
  padding-right: 0;
  border-right: 0;
}

.daily-email-control span,
.daily-email-control legend {
  display: block;
  margin: 0 0 10px;
  color: #344775;
  font-size: 13px;
  font-weight: 800;
}

.daily-email-select,
.daily-email-recipient-box,
.daily-email-subject-shell {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  min-height: 38px;
  padding: 0 14px;
  border: 1px solid #d9e2f1;
  border-radius: 7px;
  color: #142044;
  background: #ffffff;
  font-size: 13px;
  font-weight: 700;
}

select.daily-email-select {
  appearance: none;
}

.daily-email-recipient-box {
  justify-content: flex-start;
  overflow: hidden;
}

.daily-email-recipient-chip {
  display: inline-flex;
  align-items: center;
  flex: 0 0 auto;
  min-height: 24px;
  padding: 0 10px;
  border-radius: 6px;
  color: #182346;
  background: #f4f7fc;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

.daily-email-recipient-chip--more {
  color: #0b63ff;
  background: #eaf2ff;
}

.daily-email-recipient-chip--empty {
  color: #405174;
  background: #eef4ff;
}

.daily-email-recipient-note {
  display: inline-flex !important;
  align-items: center;
  min-height: 24px;
  margin: 0 !important;
  padding: 0 9px;
  border: 1px solid #d9e2f1;
  border-radius: 5px;
  color: #0b63ff !important;
  background: #ffffff;
  font-size: 11px !important;
  font-weight: 800 !important;
  flex: 0 0 auto;
  white-space: nowrap;
}

.daily-email-recipient-box > svg {
  margin-left: auto;
}

.daily-email-subject-shell input {
  min-width: 0;
  flex: 1 1 auto;
  border: 0;
  outline: 0;
  color: #142044;
  background: transparent;
  font: 700 13px/1.3 var(--font-sans);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.daily-email-subject-shell em {
  flex: 0 0 auto;
  color: #73809a;
  font-size: 11px;
  font-style: normal;
  font-weight: 700;
}

.daily-email-control--width {
  border: 0;
}

.daily-email-width-toggle {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  min-width: 0;
}

.daily-email-width-toggle input {
  position: absolute;
  opacity: 0;
}

.daily-email-width-toggle span {
  display: grid;
  place-items: center;
  min-width: 0;
  min-height: 38px;
  margin: 0;
  border: 1px solid #d9e2f1;
  border-radius: 7px;
  color: #344775;
  background: #ffffff;
}

.daily-email-width-toggle input:checked + span {
  border-color: #0b63ff;
  color: #0b63ff;
  box-shadow: inset 0 0 0 1px rgba(11, 99, 255, 0.16);
}

.daily-email-main-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(340px, 380px);
  gap: 14px;
  align-items: start;
}

.daily-email-preview-shell {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: clamp(760px, calc(100vh - 250px), 980px);
  padding: 0;
  border: 1px solid #dce3ef;
  border-radius: 8px;
  background: #ffffff;
  box-shadow: 0 6px 18px rgba(15, 27, 61, 0.04);
}

.daily-email-preview-card {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  overflow: hidden;
  margin: 0;
  border: 0;
  border-radius: 8px 8px 0 0;
  color: #0f1b3d;
  background: #ffffff;
}

.daily-email-brand-strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  min-height: 66px;
  padding: 0 16px;
  color: #ffffff;
  background: #06164d;
}

.daily-email-brand-lockup {
  display: flex;
  align-items: center;
  gap: 10px;
}

.daily-email-brand-mark {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 7px;
  color: #ffffff;
  background: #ff6417;
  font-size: 20px;
  font-weight: 900;
  letter-spacing: 0;
}

.daily-email-brand-lockup strong,
.daily-email-brand-lockup span,
.daily-email-report-meta span,
.daily-email-report-meta strong {
  display: block;
}

.daily-email-brand-lockup strong {
  color: #fff;
  font-size: 21px;
  line-height: 1;
  letter-spacing: 0;
}

.daily-email-brand-lockup span {
  margin-top: 2px;
  color: #dbe8ff;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0;
}

.daily-email-report-meta {
  text-align: right;
  color: #ffffff;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.35;
}

.daily-email-report-intro {
  padding: 15px 16px 8px;
}

.daily-email-report-intro h1 {
  margin: 0;
  color: #091640;
  font-size: 25px;
  line-height: 1.15;
  font-weight: 900;
}

.daily-email-report-intro p {
  margin-top: 8px;
  color: #344775;
  font-size: 14px;
  font-weight: 600;
}

.daily-email-status-banner {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 16px 10px;
  min-height: 54px;
  padding: 0 16px;
  border: 1px solid #a8e5c2;
  border-radius: 8px;
  background: #f1fbf6;
}

.daily-email-status-banner--warn {
  border-color: #ffd5ae;
  background: #fff7ed;
}

.daily-email-status-banner--danger {
  border-color: #ffc4c4;
  background: #fff2f2;
}

.daily-email-status-banner--muted {
  border-color: #dfe6f1;
  background: #f7f9fd;
}

.daily-email-status-banner > svg {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  color: #26b35c;
}

.daily-email-status-banner--warn > svg { color: #f26419; }
.daily-email-status-banner--danger > svg { color: #d71920; }
.daily-email-status-banner--muted > svg { color: #73809a; }

.daily-email-status-banner strong {
  display: block;
  color: #0f5f32;
  font-size: 14px;
  font-weight: 900;
}

.daily-email-status-banner--warn strong { color: #a94700; }
.daily-email-status-banner--danger strong { color: #9f1515; }
.daily-email-status-banner--muted strong { color: #405174; }

.daily-email-status-banner span {
  display: block;
  margin-top: 4px;
  color: #24365f;
  font-size: 13px;
  font-weight: 600;
}

.daily-email-kpi-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  margin: 0 16px 10px;
  border: 1px solid #dfe6f1;
  border-radius: 8px;
  overflow: hidden;
}

.daily-email-kpi {
  position: relative;
  min-width: 0;
  min-height: 128px;
  padding: 12px 12px 11px;
  border-right: 1px solid #dfe6f1;
  background: #ffffff;
}

.daily-email-kpi:last-child {
  border-right: 0;
}

.daily-email-kpi-icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  margin-bottom: 8px;
  background: #eef5ff;
}

.daily-email-kpi-copy span,
.daily-email-kpi-copy small {
  display: block;
  color: #24365f;
  font-size: 12px;
  font-weight: 800;
  line-height: 1.35;
}

.daily-email-kpi-copy strong {
  display: block;
  margin-top: 8px;
  color: #07164b;
  font-size: 28px;
  line-height: 1.05;
  font-weight: 900;
}

.daily-email-kpi--unavailable .daily-email-kpi-copy strong {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  min-height: 28px;
  padding: 0 10px;
  border: 1px solid #dce4f0;
  border-radius: 999px;
  background: #f6f8fb;
  color: #4b5875;
  font-size: 13px;
  font-weight: 800;
  line-height: 28px;
}

.daily-email-change {
  margin-top: 7px;
  font-size: 12px;
  font-weight: 900;
}

.daily-email-change--up {
  color: #1ca753;
}

.daily-email-change--down {
  color: #e02424;
}

.daily-email-kpi-copy em {
  display: block;
  margin-top: 2px;
  color: #64748b;
  font-size: 10px;
  font-style: normal;
  font-weight: 700;
}

.daily-email-kpi--blue .daily-email-kpi-icon { color: #0b63ff; background: #eaf2ff; }
.daily-email-kpi--danger .daily-email-kpi-icon { color: #f02d2d; background: #fff0f0; }
.daily-email-kpi--orange .daily-email-kpi-icon { color: #ff6a16; background: #fff3e8; }
.daily-email-kpi--purple .daily-email-kpi-icon { color: #8a2cff; background: #f3ebff; }
.daily-email-kpi--teal .daily-email-kpi-icon { color: #0ca8b8; background: #e8fbfd; }
.daily-email-kpi--green .daily-email-kpi-icon { color: #19a34a; background: #eefaf3; }

.daily-email-table-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin: 0 16px 10px;
}

.daily-email-table-card,
.daily-email-summary-card,
.daily-email-side-card {
  border: 1px solid #dfe6f1;
  border-radius: 8px;
  background: #ffffff;
}

.daily-email-table-card {
  overflow: hidden;
}

.daily-email-table-card header,
.daily-email-summary-card header,
.daily-email-side-card header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.daily-email-table-card header {
  justify-content: flex-start;
  padding: 11px 14px 6px;
}

.daily-email-table-card h2,
.daily-email-summary-card h2,
.daily-email-side-card h2 {
  margin: 0;
  color: #0f1b3d;
  font-size: 14px;
  line-height: 1.2;
  font-weight: 900;
}

.daily-email-table-card--purple header svg { color: #8a2cff; }
.daily-email-table-card--blue header svg { color: #0b63ff; }

.daily-email-table-card table {
  width: 100%;
  table-layout: fixed;
  border-collapse: collapse;
}

.daily-email-table-card th,
.daily-email-table-card td {
  padding: 6px 14px;
  border-bottom: 1px solid #edf1f7;
  color: #203152;
  font-size: 12px;
  font-weight: 700;
  text-align: left;
  overflow-wrap: anywhere;
}

.daily-email-table-card th {
  color: #405174;
  font-size: 11px;
  font-weight: 900;
}

.daily-email-table-card th:nth-child(2),
.daily-email-table-card td:nth-child(2),
.daily-email-table-card th:nth-child(3),
.daily-email-table-card td:nth-child(3) {
  text-align: right;
}

.daily-email-table-card tr.is-total td {
  color: #07164b;
  font-size: 14px;
  font-weight: 900;
}

.daily-email-table-change--up {
  color: #1ca753 !important;
}

.daily-email-table-change--down {
  color: #e02424 !important;
}

.daily-email-table-change--neutral,
.daily-email-change--neutral {
  color: #73809a !important;
}

.daily-email-empty-row td,
.daily-email-empty-state {
  color: #73809a !important;
  font-size: 12px;
  font-weight: 700;
}

.daily-email-empty-state {
  margin-top: 10px !important;
}

.daily-email-summary-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
  margin: 0 16px 12px;
}

.daily-email-summary-card {
  position: relative;
  min-height: 148px;
  padding: 12px;
}

.daily-email-summary-card h2 {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.daily-email-status-pill,
.daily-email-registration-pill,
.daily-email-priority {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 24px;
  padding: 0 9px;
  border-radius: 5px;
  font-size: 12px;
  font-weight: 900;
}

.daily-email-status-pill--ok,
.daily-email-registration-pill.is-ok {
  color: #168844;
  background: #dcf7e7;
}

.daily-email-status-pill--warn,
.daily-email-registration-pill.is-warning {
  color: #e06600;
  background: #fff0de;
}

.daily-email-status-pill--danger,
.daily-email-registration-pill.is-danger {
  color: #d71920;
  background: #ffe8e8;
}

.daily-email-status-pill--muted {
  color: #5f6f8f;
  background: #eef2f7;
}

.daily-email-summary-card dl {
  display: grid;
  gap: 8px;
  margin: 13px 0 0;
}

.daily-email-summary-card dl div {
  display: flex;
  justify-content: space-between;
  gap: 10px;
}

.daily-email-summary-card dt,
.daily-email-summary-card dd {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
}

.daily-email-summary-card dt {
  color: #344775;
}

.daily-email-summary-card dd {
  color: #07164b;
  font-weight: 900;
  text-align: right;
  white-space: nowrap;
}

.daily-email-summary-empty {
  margin: 12px 0 0;
  color: #5f6f8f;
  font-size: 12px;
  line-height: 1.35;
  font-weight: 700;
}

.daily-email-preview-note {
  margin: auto 0 0;
  padding: 12px 14px 14px;
  color: #405174;
  font-size: 13px;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.daily-email-side-panel {
  display: grid;
  gap: 7px;
  min-width: 0;
}

.daily-email-side-card {
  padding: 10px 12px;
}

.daily-email-side-card--state {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  border-color: #dcf0e4;
  background: #f4fbf7;
}

.daily-email-side-card--state.daily-email-side-card--warn {
  border-color: #ffe0bf;
  background: #fff8ef;
}

.daily-email-side-card--state.daily-email-side-card--danger {
  border-color: #ffc4c4;
  background: #fff4f4;
}

.daily-email-side-card--state.daily-email-side-card--muted {
  border-color: #dfe6f1;
  background: #f7f9fd;
}

.daily-email-side-card--state > svg {
  width: 32px;
  height: 32px;
  color: #22ad58;
}

.daily-email-side-card--state.daily-email-side-card--warn > svg { color: #f26419; }
.daily-email-side-card--state.daily-email-side-card--danger > svg { color: #d71920; }
.daily-email-side-card--state.daily-email-side-card--muted > svg { color: #73809a; }

.daily-email-side-card h2 {
  margin-bottom: 5px;
}

.daily-email-side-card p {
  margin: 0;
  color: #344775;
  font-size: 12px;
  line-height: 1.35;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.daily-email-info-list,
.daily-email-registration {
  margin: 0;
}

.daily-email-info-list div {
  display: flex;
  gap: 6px;
  margin-top: 5px;
  color: #10204a;
  font-size: 12px;
  line-height: 1.25;
  font-weight: 700;
}

.daily-email-info-list dt,
.daily-email-info-list dd {
  margin: 0;
}

.daily-email-delivery-status--ok {
  color: #19a34a;
  font-weight: 900;
}

.daily-email-delivery-status--warn {
  color: #f26419;
  font-weight: 900;
}

.daily-email-delivery-status--danger {
  color: #d71920;
  font-weight: 900;
}

.daily-email-delivery-status--muted {
  color: #73809a;
  font-weight: 900;
}

.daily-email-registration-pill {
  margin-bottom: 9px;
}

.daily-email-registration-meta,
.daily-email-registration-detail {
  margin-top: 6px;
  color: #10204a;
  font-size: 12px;
  line-height: 1.3;
  font-weight: 700;
  overflow-wrap: anywhere;
}

.daily-email-registration-detail {
  color: #d97706;
}

.daily-email-check-list {
  display: grid;
  gap: 7px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.daily-email-check-list li {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #10204a;
  font-size: 12px;
  font-weight: 800;
}

.daily-email-check-list svg {
  width: 15px;
  height: 15px;
  color: #20a855;
}

.daily-email-action-list header a {
  color: #0b63ff;
  font-size: 11px;
  font-weight: 900;
  text-decoration: none;
  overflow-wrap: anywhere;
}

.daily-email-action-item {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) 68px 80px;
  gap: 10px;
  align-items: center;
  padding: 9px 0;
  border-top: 1px solid #edf1f7;
}

.daily-email-action-item > svg {
  color: #ff6a16;
}

.daily-email-action-item strong {
  display: block;
  color: #10204a;
  font-size: 12px;
  line-height: 1.2;
  font-weight: 900;
}

.daily-email-action-item p {
  margin-top: 3px;
  color: #405174;
  font-size: 11px;
  line-height: 1.25;
}

.daily-email-action-item em {
  color: #344775;
  font-size: 11px;
  font-style: normal;
  font-weight: 800;
}

.daily-email-priority--danger {
  color: #d71920;
  border: 1px solid #ff8d8d;
  background: #fff2f2;
}

.daily-email-priority--warn {
  color: #f26419;
  border: 1px solid #ffa66f;
  background: #fff3e8;
}

.daily-email-priority--info {
  color: #0b63ff;
  border: 1px solid #9dc4ff;
  background: #edf5ff;
}

.daily-email-json-card {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr);
  gap: 12px;
}

.daily-email-json-card > div {
  min-width: 0;
}

.daily-email-file-icon {
  display: grid;
  place-items: center;
  width: 42px;
  height: 52px;
  border: 2px solid #07164b;
  border-radius: 5px;
  color: #07164b;
  font-size: 22px;
  font-weight: 900;
}

.daily-email-json-card p + p {
  margin-top: 8px;
}

.daily-email-json-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 34px;
  margin-top: 12px;
  padding: 0 14px;
  border: 1px solid #bfd4ff;
  border-radius: 6px;
  color: #0b63ff;
  background: #ffffff;
  font-size: 12px;
  font-weight: 800;
}

.daily-email-json-popover {
  width: min(840px, calc(100vw - 48px));
  max-height: min(720px, calc(100vh - 48px));
  margin: auto;
  padding: 0;
  border: 1px solid #d9e2f1;
  border-radius: 8px;
  background: #ffffff;
  box-shadow: 0 24px 70px rgba(15, 27, 61, 0.22);
}

.daily-email-json-popover::backdrop {
  background: rgba(7, 22, 75, 0.22);
}

.daily-email-json-popover-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 16px;
  border-bottom: 1px solid #dfe6f1;
  color: #07164b;
}

.daily-email-json-popover-head button {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 1px solid #dfe6f1;
  border-radius: 6px;
  color: #344775;
  background: #ffffff;
}

.daily-email-json-popover pre {
  max-height: 620px;
  margin: 0;
  padding: 16px;
  overflow: auto;
  color: #10204a;
  background: #f7f9fd;
  font: 12px/1.5 "JetBrains Mono", monospace;
}

.daily-email-config-form:has(#daily-preview-mobile:checked) .daily-email-preview-card {
  max-width: 430px;
  margin-right: auto;
  margin-left: auto;
}

@media (max-width: 1540px) {
  .daily-email-controls {
    grid-template-columns: minmax(170px, 1fr) minmax(150px, 0.8fr) minmax(200px, 1.15fr) minmax(280px, 1.45fr) minmax(124px, 0.6fr);
  }

  .daily-email-control {
    padding-right: 16px;
    padding-left: 16px;
  }

  .daily-email-control:first-child {
    padding-left: 0;
  }

  .daily-email-control:last-child {
    padding-right: 0;
  }

  .daily-email-main-grid {
    grid-template-columns: minmax(0, 1fr) 340px;
  }

  .daily-email-action-item {
    grid-template-columns: 22px minmax(0, 1fr) 66px;
  }

  .daily-email-action-item em {
    display: none;
  }
}

@media (max-width: 1280px) {
  .daily-email-controls,
  .daily-email-main-grid {
    grid-template-columns: 1fr;
  }

  .daily-email-control {
    padding: 10px 0;
    border-right: 0;
    border-bottom: 1px solid #dfe6f1;
  }

  .daily-email-control:last-child {
    border-bottom: 0;
  }

  .daily-email-recipient-box {
    align-items: flex-start;
    flex-wrap: wrap;
    row-gap: 6px;
    min-height: auto;
    padding-top: 8px;
    padding-bottom: 8px;
  }

  .daily-email-recipient-chip {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .daily-email-subject-shell input {
    font-size: 12px;
  }

  .daily-email-kpi-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .daily-email-kpi:nth-child(4) {
    border-right: 0;
  }
}

@media (max-width: 900px) {
  .daily-email-content-header,
  .daily-email-content-title {
    align-items: flex-start;
    flex-direction: column;
  }

  .daily-email-toolbar {
    justify-content: flex-start;
    flex-wrap: wrap;
  }

  .daily-email-freshness-line {
    align-items: flex-start;
    flex-direction: column;
  }

  .daily-email-table-grid,
  .daily-email-summary-grid {
    grid-template-columns: 1fr;
  }

  .daily-email-kpi-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .daily-email-brand-strip {
    align-items: flex-start;
    flex-direction: column;
    padding: 16px;
  }

  .daily-email-report-meta {
    text-align: left;
  }

  .daily-email-preview-card {
    margin: 0 10px;
  }
}

@media (max-width: 700px) {
  .daily-email-workbench {
    width: 100%;
    max-width: 100%;
  }

  body.has-sidebar .page:has(.daily-email-workbench) {
    padding-right: 12px;
    padding-left: 12px;
  }

  .daily-email-preview-note {
    font-size: 12px;
    line-height: 1.35;
  }

  .daily-email-action-list header {
    align-items: flex-start;
    flex-wrap: wrap;
  }

  .daily-email-action-list header a {
    max-width: 100%;
    margin-left: 0;
    overflow-wrap: anywhere;
    white-space: normal;
  }

  .daily-email-json-card {
    grid-template-columns: 42px minmax(0, 1fr);
    gap: 10px;
  }

  .daily-email-json-card p {
    font-size: 11.5px;
  }

  .daily-email-side-card h2,
  .daily-email-side-card p,
  .daily-email-side-card dd,
  .daily-email-registration-meta,
  .daily-email-registration-detail,
  .daily-email-empty-state,
  .daily-email-json-card p {
    max-width: 100%;
    overflow-wrap: anywhere;
  }

  body.has-sidebar:has(.daily-email-workbench) .topbar {
    gap: 10px;
    min-width: 0;
    padding: 0 14px;
  }

  body.has-sidebar:has(.daily-email-workbench) .topbar-menu-btn {
    margin-right: 0;
  }

  body.has-sidebar:has(.daily-email-workbench) .topbar-search {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    margin-left: 0;
  }

  body.has-sidebar:has(.daily-email-workbench) .topbar-search-text {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  body.has-sidebar:has(.daily-email-workbench) .topbar-search-kbd {
    display: none;
  }
}

/* Scripts-to-Arb monitoring board */
.s2a-board {
  max-width: 1540px;
  margin: 0 auto;
  padding: 28px 28px 34px;
  color: var(--text, #0f172a);
}

.s2a-board [hidden] {
  display: none !important;
}

.s2a-hero {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-bottom: 20px;
}

/* ---- Scripts-to-Arb header v2: title row + slim full-width stat-strip ----
   Replaces the old 2-col hero + 4-card meta-grid with a title row
   (copy | S3 links | search) and one horizontal labelled strip that spans the
   full board width (matching the KPI cards below).
   Token-based so the existing [data-theme="dark"] .s2a-* layer applies. */
.s2a-hero__main { display: flex; align-items: flex-start; gap: 28px; }
.s2a-hero__copy { flex: 1 1 auto; min-width: 0; }
.s2a-hero__main .s2a-folder-links { flex: 0 0 auto; align-self: center; margin-left: auto; }
.s2a-hero__main .s2a-folder-links a { display: inline-flex; align-items: center; gap: 5px; }
.s2a-hero__main .s2a-folder-links a svg { width: 13px; height: 13px; }
.s2a-hero__main .s2a-search { flex: 0 0 auto; align-self: center; }

.s2a-strip {
  display: flex;
  width: 100%;            /* span the full board width, matching the KPI cards below */
  align-items: stretch;
  flex-wrap: wrap;
  border: 1px solid var(--border, #dbe3f1);
  border-radius: 12px;
  background: var(--surface, #fff);
  box-shadow: var(--shadow-sm, 0 6px 18px rgba(15, 23, 42, 0.04));
}
.s2a-strip-cell {
  display: flex;
  flex: 1 1 auto;         /* grow to fill the full width so cells span the strip */
  min-width: 0;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  padding: 11px 15px;
  border-left: 1px solid var(--border, #e8edf5);
}
.s2a-strip-cell:first-child { border-left: 0; }
.s2a-strip-cell--controls { flex: 0 0 auto; }  /* controls stay compact at the right edge */
.s2a-strip-cell--freshness { justify-content: center; }
.s2a-strip-label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  /* --text-muted (light #5a6778 ~6:1, dark #9aa5b8) passes AA in BOTH themes;
     --text-subtle would be 3.0:1 on the light surface. */
  color: var(--text-muted, #5a6778);
}
.s2a-strip-val {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  color: var(--text, #182341);
}
.s2a-strip-val strong { font-weight: 800; }
.s2a-strip-val > svg { width: 15px; height: 15px; color: var(--text-subtle, #8a93a6); }
/* compact the freshness chip inside the strip so the row stays one line */
.s2a-strip-cell--freshness .s2a-freshness-chip {
  min-height: 28px;
  padding: 0 10px;
  font-size: 12.5px;
  font-weight: 800;
}
.s2a-chip-sep { color: var(--text-subtle, #9aa3b6); margin: 0 2px; }
.s2a-chip-chev { width: 13px; height: 13px; margin-left: 2px; color: var(--text-subtle, #9aa3b6); }
.s2a-strip-controls { gap: 12px; }
.s2a-strip-controls .s2a-schedule-form,
.s2a-strip-controls .s2a-runnow-form { display: inline-flex; align-items: center; }
.s2a-strip-controls .s2a-schedule-input-row {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}
.s2a-strip-controls .s2a-schedule-input-row input {
  flex: 0 0 auto;
  width: 58px;
  min-height: 32px;
  text-align: center;
}
.s2a-strip-controls .s2a-small-btn { min-height: 32px; padding: 0 13px; }
.s2a-strip-controls .s2a-run-now-btn { display: inline-flex; align-items: center; gap: 6px; }

@media (max-width: 1500px) {
  /* Below ~1500px the 5 cells can't share one row cleanly (the app sidebar eats
     width). Drop the controls to a clean full-width second row instead of
     leaving a gap; the 4 stat cells stay on row one. Wrap so the cadence +
     Run-now controls never overflow as the row narrows. */
  .s2a-strip-cell--controls {
    margin-left: 0;
    flex: 1 0 100%;
    flex-flow: row wrap;
    align-items: center;
    gap: 12px;
    border-left: 0;
    border-top: 1px solid var(--border, #e8edf5);
  }
  .s2a-strip-controls { flex-wrap: wrap; }
}
@media (max-width: 1180px) {
  .s2a-hero__main { flex-wrap: wrap; }
  .s2a-hero__main .s2a-search { margin-left: auto; }
}
@media (max-width: 760px) {
  /* Mobile: stack the strip cells full-width with horizontal dividers so
     nothing clips; let the title row and search go full-width too. */
  .s2a-strip { flex-direction: column; }
  .s2a-strip-cell { border-left: 0; border-top: 1px solid var(--border, #e8edf5); }
  .s2a-strip-cell:first-child { border-top: 0; }
  .s2a-strip-controls { flex-wrap: wrap; }
  .s2a-hero__main { flex-direction: column; align-items: stretch; }
  .s2a-hero__main .s2a-folder-links,
  .s2a-hero__main .s2a-search { margin-left: 0; align-self: stretch; }
  .s2a-search--global { width: 100%; }
}

.s2a-breadcrumb {
  margin-top: 22px;
  color: #53658c;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
}

.s2a-title {
  margin: 10px 0 8px;
  color: #111638;
  font-size: 32px;
  line-height: 1.08;
  font-weight: 850;
}

.s2a-subtitle {
  max-width: 720px;
  margin: 0;
  color: #415276;
  font-size: 13px;
  line-height: 1.55;
}

.s2a-hero__tools {
  display: grid;
  gap: 14px;
  justify-items: end;
}

.s2a-search {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 42px;
  padding: 0 12px;
  border: 1px solid #dbe3f1;
  border-radius: 10px;
  background: #fff;
  color: #5b6b91;
  box-shadow: 0 8px 22px rgba(15, 23, 42, 0.04);
}

.s2a-search--global {
  width: 290px;
}

.s2a-search svg {
  width: 17px;
  height: 17px;
}

.s2a-search input {
  min-width: 0;
  width: 100%;
  border: 0;
  outline: 0;
  background: transparent;
  color: #182341;
  font-size: 13px;
}

.s2a-search kbd {
  padding: 2px 7px;
  border: 1px solid #dce4f4;
  border-radius: 6px;
  color: #7d8bad;
  font-size: 12px;
  font-family: inherit;
  background: #f7f9fd;
}

.s2a-meta-grid {
  display: grid;
  width: 100%;
  grid-template-columns: max-content minmax(250px, 1fr) minmax(300px, 1.15fr);
  gap: 14px;
  align-items: center;
}

.s2a-meta-card {
  border: 1px solid #dbe3f1;
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 10px 26px rgba(15, 23, 42, 0.04);
}

.s2a-folder-links {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 150px;
  font-size: 12px;
  font-weight: 750;
  line-height: 1.25;
}

.s2a-folder-links a {
  color: #1d4ed8;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.s2a-meta-card {
  position: relative;
  display: grid;
  gap: 10px;
  padding: 14px 16px;
  align-content: center;
}

.s2a-meta-row {
  display: flex;
  align-items: center;
  gap: 10px;
  color: #53658c;
  font-size: 13px;
}

.s2a-meta-row strong {
  color: #182341;
  font-weight: 850;
}

.s2a-meta-row svg {
  width: 16px;
  height: 16px;
  color: #53658c;
}

.s2a-copy-btn,
.s2a-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid #dbe3f1;
  background: #fff;
  color: #1c6ef2;
  cursor: pointer;
}

/* ============================================================
   Wave 3 dark-mode overrides — /ftp-connection contrast fixes.

   Audit on /ftp-connection (Wave 1 + 2 dark-mode pass) returned
   4 P0 + 5 P1 contrast failures plus 1 light-surface P1, all
   inside .ftp-* classes from styles.css §15740–16230. Root cause
   is the same as Wave 1/1.5: light-mode hex literals on text
   color, and one card with hardcoded white background, with no
   [data-theme="dark"] rebind. Below scopes every rebind to
   [data-theme="dark"] .ftp-page so only the dark theme is
   affected and nothing else on the page leaks.
   ============================================================ */

/* `.ftp-stat` card (styles.css L15797) hardcodes `background: #fff`
   and `border-color: #e5e7eb`. The audit flagged .ftp-stat--unknown
   specifically as a light-surface P1, but every variant inherits
   the same white bg — rebind the base so the card surface stops
   reading as a bright white slab on dark. Variants share the same
   background via cascade; only the base rule needs the surface flip
   and the neutral 3-side border. The status-conveying left border
   is preserved per-variant below so colors keep reading at a glance. */
[data-theme="dark"] .ftp-page .ftp-stat {
  background: var(--surface-2);
  border-color: var(--border);
}

/* Variant-specific left-border restores. styles.css L15810-L15814
   sets these in hardcoded hex; without these restores the base
   `border-color: var(--border)` above would neutralize the
   semantic status color (green/red/brand) on dark. --unknown and
   --idle intentionally fall through to the neutral base border. */
[data-theme="dark"] .ftp-page .ftp-stat--connected {
  border-left-color: var(--ok);
}
[data-theme="dark"] .ftp-page .ftp-stat--error {
  border-left-color: var(--danger);
}
[data-theme="dark"] .ftp-page .ftp-stat--active {
  border-left-color: var(--brand);
}

/* `.ftp-stat-label` (L15816) is #94a3b8 — that's the legacy
   "subtle slate" used as muted-on-white, which lands at 2.56 on
   dark surfaces. Dark-mode --text-muted (#9aa5b8) on --surface-2
   (#222a39) is ~6.6:1, well past WCAG AA. */
[data-theme="dark"] .ftp-page .ftp-stat-label {
  color: var(--text-muted);
}

/* `.ftp-stat-value` (L15825) is #1a2f6e (deep navy). On the
   newly-dark .ftp-stat surface it would be nearly invisible.
   Bind the base value text to --text so the plain/--unknown/--idle
   path is legible. The colored variants (--connected/--error/
   --active) set their own status colors at L15834-L15836; because
   this dark sheet loads AFTER styles.css, those variant colors
   would be clobbered by this base rule, so we restore them below. */
[data-theme="dark"] .ftp-page .ftp-stat-value {
  color: var(--text);
}

/* Variant-specific value-text restores. Connected/active keep their
   semantic status colors. Error keeps the red left border, but value
   text uses --text because --danger on --surface-2 is sub-AA in dark
   mode. --unknown and --idle correctly fall through to var(--text). */
[data-theme="dark"] .ftp-page .ftp-stat--connected .ftp-stat-value {
  color: var(--ok);
}
[data-theme="dark"] .ftp-page .ftp-stat--error .ftp-stat-value {
  color: var(--text);
}
[data-theme="dark"] .ftp-page .ftp-stat--active .ftp-stat-value {
  color: var(--brand);
}

/* `.ftp-stat-meta` (L15838) is #94a3b8 — same 2.56 failure as
   .ftp-stat-label. Same fix: dark --text-muted on --surface-2. */
[data-theme="dark"] .ftp-page .ftp-stat-meta {
  color: var(--text-muted);
}

/* `.ftp-page-title` (L15772) and `.ftp-eyebrow` (L15758) hardcode
   #1a2f6e on near-white. The audit flagged the .ftp-hover-help
   span inside the title at 1.49 because it inherits this color.
   Flip the title (and eyebrow) to --text so the inherited color
   on the hover-help span passes contrast on the dark page. */
[data-theme="dark"] .ftp-page .ftp-page-title {
  color: var(--text);
}

[data-theme="dark"] .ftp-page .ftp-page-subtitle {
  color: var(--text-muted);
}

[data-theme="dark"] .ftp-page .ftp-eyebrow {
  color: var(--text);
  background: var(--surface-2);
}

/* `.ftp-hover-help` (L16161) sets no color itself — it inherits
   from its parent. The Wave 3 follow-up bound it to `inherit`, but
   the partner-table `<th>` it inherits from resolves to a muted
   header color on dark, landing the "Partner" span at 3.94 (below
   AA 4.5). Bind the hover-help directly to --text (#e6eaf2), which
   clears 4.5:1 on every dark table-header surface (>=9.9:1).
   The dotted underline color (rgba(37,99,235,0.45)) is bright
   enough on dark to stay legible. */
[data-theme="dark"] .ftp-page .ftp-hover-help {
  color: var(--text);
}

/* `.ftp-conn-partner-name` (L16191) hardcodes #1a2f6e — 1.27 on
   dark surfaces. The partner-card title is the primary readable
   string in each row, so use --text (not --text-muted). */
[data-theme="dark"] .ftp-page .ftp-conn-partner-name {
  color: var(--text);
}

/* `.ftp-conn-partner-host` + `.ftp-conn-folder-meta`
   + `.ftp-conn-file-meta` + `.ftp-table-meta` (L16196) all share
   color: #64748b — 3.35 on dark surfaces. These are secondary
   metadata strings (host, port, file meta), so --text-muted is
   the right token (passes ~6.6:1). */
[data-theme="dark"] .ftp-page .ftp-conn-partner-host,
[data-theme="dark"] .ftp-page .ftp-conn-folder-meta,
[data-theme="dark"] .ftp-page .ftp-conn-file-meta,
[data-theme="dark"] .ftp-page .ftp-table-meta {
  color: var(--text-muted);
}

/* `.ftp-conn-status-text` (L16215) has no color itself; color
   comes from the variant class. The P1 at 3.35 ("Not checked")
   is the --unknown variant (L16228) which hardcodes #64748b.
   While here, also rebind --connected (#15803d) and
   --error/--failed (#b91c1c) — those deep status colors will
   also fail on dark surfaces — to the dark-mode --ok / --danger
   tokens, which both pass AA on --surface-2. (Per the task brief:
   "Use --ok / --warn / --danger for status text in colored
   states".) */
[data-theme="dark"] .ftp-page .ftp-conn-status--connected {
  color: var(--ok);
}

[data-theme="dark"] .ftp-page .ftp-conn-status--error,
[data-theme="dark"] .ftp-page .ftp-conn-status--failed {
  color: var(--danger);
}

[data-theme="dark"] .ftp-page .ftp-conn-status--unknown {
  color: var(--text-muted);
}
.s2a-copy-btn {
  width: 24px;
  height: 24px;
  border-radius: 6px;
}

.s2a-copy-btn svg,
.s2a-icon-btn svg {
  width: 15px;
  height: 15px;
}

.s2a-status-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 999px;
}

.s2a-status-dot--ok {
  background: #19a862;
}

.s2a-freshness-wrap {
  position: relative;
}

.s2a-freshness-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 30px;
  padding: 0 12px;
  border: 1px solid #e5edf7;
  border-radius: 999px;
  background: #fbfdff;
  color: #182341;
  font-size: 13px;
  font-weight: 850;
  cursor: pointer;
}

.s2a-popover,
.s2a-filter-panel,
.s2a-columns-panel {
  position: absolute;
  z-index: 20;
  top: calc(100% + 8px);
  right: 0;
  min-width: 240px;
  padding: 14px;
  border: 1px solid #dbe3f1;
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 18px 42px rgba(15, 23, 42, 0.14);
}

.s2a-freshness-form {
  display: grid;
  gap: 10px;
}

.s2a-freshness-form label,
.s2a-filter-panel label,
.s2a-columns-panel label {
  display: grid;
  gap: 6px;
  color: #53658c;
  font-size: 12px;
  font-weight: 750;
}

.s2a-freshness-input-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.s2a-freshness-input-row input,
.s2a-filter-panel select {
  width: 100%;
  min-height: 34px;
  border: 1px solid #dbe3f1;
  border-radius: 8px;
  padding: 0 10px;
  color: #182341;
  background: #fff;
}

.s2a-freshness-form p {
  margin: 0;
  color: #6d7894;
  font-size: 11px;
  line-height: 1.4;
}

.s2a-small-btn,
.s2a-tool-btn,
.s2a-icon-btn {
  min-height: 38px;
  border-radius: 9px;
}

.s2a-small-btn {
  border: 1px solid #dbe3f1;
  background: #fff;
  color: #182341;
  font-weight: 800;
  cursor: pointer;
}

.s2a-small-btn--primary {
  border-color: #fb5a16;
  background: #fb5a16;
  color: #fff;
}

.s2a-kpis {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 16px;
  margin-bottom: 18px;
}

.s2a-kpi {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 104px;
  padding: 18px;
  border: 1px solid #dbe3f1;
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 12px 28px rgba(15, 23, 42, 0.045);
}

.s2a-kpi span {
  display: block;
  color: #53658c;
  font-size: 12px;
  font-weight: 850;
  text-transform: uppercase;
}

.s2a-kpi strong {
  display: block;
  margin-top: 8px;
  color: #111638;
  font-size: 27px;
  line-height: 1;
}

.s2a-kpi small {
  display: block;
  margin-top: 8px;
  color: #415276;
  font-size: 13px;
}

.s2a-kpi > svg {
  width: 50px;
  height: 50px;
  padding: 13px;
  border-radius: 14px;
}

.s2a-kpi--catalog > svg {
  color: #7d3cff;
  background: #f0e6ff;
}

.s2a-kpi--present {
  border-color: #d4ecd9;
  background: linear-gradient(135deg, #fff, #eefaf1);
}

.s2a-kpi--present > svg {
  color: #fff;
  background: #20b463;
}

.s2a-kpi--missing {
  border-color: #f8d9a9;
  background: linear-gradient(135deg, #fff, #fff6e8);
}

.s2a-kpi--missing > svg {
  color: #ff8a00;
  background: #fff4df;
}

.s2a-kpi--source > svg {
  color: #1c6ef2;
  background: #eaf2ff;
}

.s2a-kpi--error > svg {
  color: #8a3ffc;
  background: #f2e8ff;
}

.s2a-banner,
.s2a-flash {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  margin-bottom: 18px;
  padding: 14px 16px;
  border: 1px solid #dbeafe;
  border-radius: 10px;
  background: #f5fbff;
  color: #27456f;
  font-size: 13px;
}

.s2a-banner svg {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  color: #1c6ef2;
}

.s2a-banner strong,
.s2a-banner span {
  display: block;
}

.s2a-banner span {
  margin-top: 3px;
}

.s2a-flashes {
  margin-bottom: 16px;
}

.s2a-flash {
  margin-bottom: 8px;
}

.s2a-flash--success {
  border-color: #c9efd6;
  background: #f1fbf4;
  color: #17633b;
}

.s2a-flash--error {
  border-color: #ffd4d4;
  background: #fff6f6;
  color: #9c2424;
}

.s2a-midgrid {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(440px, 0.92fr);
  gap: 18px;
  margin-bottom: 18px;
}

.s2a-card {
  border: 1px solid #dbe3f1;
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.045);
  overflow: hidden;
}

.s2a-card-head,
.s2a-table-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  min-height: 64px;
  padding: 18px;
  border-bottom: 1px solid #e5ebf5;
}

.s2a-card-head h2,
.s2a-table-head h2 {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  color: #111638;
  font-size: 18px;
  line-height: 1.2;
}

.s2a-card-head h2 span {
  font-size: 13px;
}

.s2a-card-head p,
.s2a-table-head p {
  margin: 4px 0 0;
  color: #53658c;
  font-size: 13px;
}

.s2a-card-head > svg,
.s2a-table-head h2 svg {
  width: 15px;
  height: 15px;
  color: #1c6ef2;
}

.s2a-card-head a {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: #0a6cff;
  font-size: 13px;
  font-weight: 800;
  text-decoration: none;
  white-space: nowrap;
}

.s2a-card-head a svg {
  width: 15px;
  height: 15px;
}

.s2a-health-body {
  display: grid;
  grid-template-columns: 0.95fr 1.05fr;
  min-height: 255px;
}

.s2a-donut-wrap,
.s2a-line-wrap {
  padding: 18px;
}

.s2a-donut-wrap {
  border-right: 1px solid #e5ebf5;
}

.s2a-donut-wrap h3,
.s2a-line-wrap h3 {
  margin: 0;
  color: #17203e;
  font-size: 14px;
}

.s2a-donut-wrap p {
  margin: 4px 0 14px;
  color: #53658c;
  font-size: 13px;
  font-weight: 750;
}

.s2a-donut {
  width: 132px;
  height: 132px;
  margin: 0 18px 0 0;
  display: inline-grid;
  place-items: center;
  border-radius: 50%;
  background:
    radial-gradient(circle at center, #fff 0 48%, transparent 49%),
    conic-gradient(
      #1fb463 0 var(--present),
      #f8b11a var(--present) calc(var(--present) + var(--stale)),
      #ff3b3b calc(var(--present) + var(--stale)) calc(var(--present) + var(--stale) + var(--missing)),
      #74809f calc(var(--present) + var(--stale) + var(--missing)) 100%
    );
  vertical-align: middle;
  box-shadow: inset 0 0 0 1px rgba(15, 23, 42, 0.04);
}

.s2a-donut div {
  display: grid;
  place-items: center;
  width: 82px;
  height: 82px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 6px 18px rgba(15, 23, 42, 0.08);
}

.s2a-donut strong {
  color: #111638;
  font-size: 28px;
  line-height: 1;
}

.s2a-donut span {
  color: #53658c;
  font-size: 12px;
  font-weight: 750;
}

.s2a-legend {
  display: inline-grid;
  gap: 10px;
  min-width: 220px;
  margin: 0;
  vertical-align: middle;
}

.s2a-legend div {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 10px;
}

.s2a-legend dt,
.s2a-legend dd {
  margin: 0;
  color: #415276;
  font-size: 13px;
}

.s2a-legend dt {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.s2a-legend dd {
  font-weight: 800;
}

.s2a-dot {
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 999px;
}

.s2a-dot--green { background: #1fb463; }
.s2a-dot--amber { background: #f8b11a; }
.s2a-dot--red { background: #ff3b3b; }
.s2a-dot--slate { background: #74809f; }

.s2a-mini-legend {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin: 14px 0 8px;
  color: #415276;
  font-size: 12px;
}

.s2a-line-chart {
  position: relative;
  height: 145px;
  margin: 6px 0 0 28px;
  border-left: 1px solid #e4eaf4;
  background:
    linear-gradient(#e7edf6 1px, transparent 1px) 0 20% / 100% 40px,
    linear-gradient(#e7edf6 1px, transparent 1px) 0 60% / 100% 40px;
}

.s2a-chart-axis {
  position: absolute;
  left: -28px;
  color: #53658c;
  font-size: 12px;
}

.s2a-chart-axis--top { top: 14px; }
.s2a-chart-axis--mid { top: 65px; }
.s2a-chart-axis--bottom { bottom: 4px; }

/* Real data-driven trend: an SVG polyline on a normalized 0-100 viewBox, so
   the line follows the data instead of hardcoded CSS offsets (the bug that
   froze the old placeholder chart). */
.s2a-line-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.s2a-svg-line {
  fill: none;
  stroke-width: 2px;
  stroke-linejoin: round;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}

.s2a-svg-line--present { stroke: #1fb463; }
.s2a-svg-line--missing { stroke: #ff3b3b; }

.s2a-line-empty {
  height: 145px;
  margin: 6px 0 0 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0 16px;
  color: #53658c;
  font-size: 12.5px;
}

.s2a-chart-labels {
  position: relative;
  height: 16px;
  margin: 8px 12px 0 32px;
  color: #53658c;
  font-size: 12px;
}

.s2a-chart-labels span {
  position: absolute;
  transform: translateX(-50%);
  white-space: nowrap;
}

.s2a-chart-labels span:first-child { transform: translateX(0); }
.s2a-chart-labels span:last-child { transform: translateX(-100%); }

.s2a-activity-list {
  display: grid;
  gap: 2px;
  padding: 12px 18px 18px;
}

.s2a-activity-row {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  min-height: 48px;
}

.s2a-activity-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 999px;
}

.s2a-activity-icon svg {
  width: 15px;
  height: 15px;
}

.s2a-activity-icon--ok { color: #fff; background: #1fb463; }
.s2a-activity-icon--info { color: #fff; background: #1c6ef2; }
.s2a-activity-icon--upload { color: #1fb463; background: transparent; }
.s2a-activity-icon--file { color: #7d3cff; background: #f2e8ff; }
.s2a-activity-icon--warn { color: #ff8a00; background: #fff4df; }

.s2a-activity-row strong,
.s2a-activity-row span {
  display: block;
}

.s2a-activity-row strong {
  color: #111638;
  font-size: 13px;
}

.s2a-activity-row span,
.s2a-activity-row time {
  color: #415276;
  font-size: 12px;
}

.s2a-activity-row time {
  white-space: nowrap;
}

.s2a-table-card {
  overflow: visible;
}

.s2a-table-head {
  align-items: flex-start;
  min-height: 74px;
  overflow: visible;
}

.s2a-table-actions {
  position: relative;
  display: flex;
  flex: 0 0 auto;
  flex-wrap: nowrap;
  justify-content: flex-end;
  gap: 10px;
}

.s2a-table-actions .s2a-search {
  width: 230px;
}

.s2a-toolbar-popover {
  position: relative;
}

.s2a-tool-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 14px;
  border: 1px solid #dbe3f1;
  background: #fff;
  color: #182341;
  font-size: 13px;
  font-weight: 800;
  cursor: pointer;
}

.s2a-tool-btn svg {
  width: 16px;
  height: 16px;
}

.s2a-icon-btn {
  width: 42px;
}

.s2a-filter-panel {
  display: grid;
  grid-template-columns: repeat(2, minmax(150px, 1fr));
  gap: 10px;
  min-width: 340px;
}

.s2a-columns-panel {
  display: grid;
  gap: 8px;
  min-width: 205px;
}

.s2a-columns-panel label {
  grid-template-columns: auto 1fr;
  align-items: center;
}

.s2a-table-wrap {
  position: relative;
  overflow-x: auto;
}

.s2a-table {
  width: 100%;
  min-width: 1180px;
  border-collapse: collapse;
}

.s2a-table th,
.s2a-table td {
  padding: 12px 14px;
  border-bottom: 1px solid #e5ebf5;
  color: #17203e;
  font-size: 13px;
  text-align: left;
  vertical-align: middle;
}

.s2a-table th {
  color: #53658c;
  font-size: 11px;
  font-weight: 850;
  text-transform: uppercase;
  background: #fbfcff;
}

.s2a-table td:nth-child(6),
.s2a-table td:nth-child(7),
.s2a-table td:nth-child(8) {
  font-weight: 850;
}

.s2a-sort-button {
  width: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.s2a-sort-button:hover,
.s2a-sort-button:focus-visible {
  color: #0a6cff;
}

.s2a-sort-button:focus-visible {
  outline: 2px solid #fb5a16;
  outline-offset: 3px;
  border-radius: 4px;
}

.s2a-sort-indicator {
  display: inline-block;
  min-width: 12px;
  color: #8b98b6;
  font-size: 11px;
  line-height: 1;
}

.s2a-sort-indicator::before { content: "\2195"; }
.s2a-table th[aria-sort="ascending"] .s2a-sort-indicator,
.s2a-table th[aria-sort="descending"] .s2a-sort-indicator { color: #0a6cff; }
.s2a-table th[aria-sort="ascending"] .s2a-sort-indicator::before { content: "\25B2"; }
.s2a-table th[aria-sort="descending"] .s2a-sort-indicator::before { content: "\25BC"; }

.s2a-source {
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 12.5px;
  font-weight: 850;
}

.s2a-source--need {
  color: #1d2d4e;
}

.s2a-type-pill,
.s2a-condition,
.s2a-status {
  display: inline-flex;
  align-items: center;
  min-height: 22px;
  padding: 0 8px;
  border-radius: 999px;
  font-size: 12px;
  font-weight: 800;
  white-space: nowrap;
}

.s2a-type-pill {
  color: #415276;
  background: #eef2f7;
}

.s2a-type-pill--buy {
  color: #0a5bd8;
  background: #e8f1ff;
}

.s2a-type-pill--sell {
  color: #b65316;
  background: #fff0e5;
}

.s2a-type-pill--internal {
  color: #53658c;
  background: #edf1f7;
}

.s2a-condition {
  color: #53658c;
  background: #eef2f7;
}

.s2a-guide {
  display: block;
  max-width: 420px;
  overflow: hidden;
  color: #111638;
  font-weight: 800;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.s2a-guide-sub {
  display: block;
  max-width: 420px;
  overflow: hidden;
  margin-top: 3px;
  color: #7180a0;
  font-size: 12px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.s2a-status--present {
  color: #12824b;
  background: #dff7e8;
}

.s2a-status--stale {
  color: #b45309;
  background: #fff0d2;
}

.s2a-status--missing {
  color: #d32f2f;
  background: #ffe1e1;
}

.s2a-status--source {
  color: #53658c;
  background: #eef2f7;
}

.s2a-status--error {
  color: #b91c1c;
  background: #ffe1e1;
}

.s2a-empty {
  padding: 28px;
  color: #53658c;
  font-size: 14px;
  text-align: center;
}

.s2a-table-foot {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 13px 18px 16px;
  color: #53658c;
  font-size: 12px;
}

.s2a-table-foot code,
.s2a-banner code {
  padding: 1px 5px;
  border-radius: 5px;
  background: #f1f5fb;
  color: #1d2d4e;
}

@media (max-width: 1280px) {
  .s2a-hero {
    grid-template-columns: 1fr;
  }
  .s2a-hero__tools {
    justify-items: stretch;
  }
  .s2a-search--global {
    justify-self: end;
  }
  .s2a-kpis {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .s2a-midgrid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 900px) {
  .s2a-board {
    padding: 18px 14px 28px;
  }
  .s2a-meta-grid,
  .s2a-health-body {
    grid-template-columns: 1fr;
  }
  .s2a-donut-wrap {
    border-right: 0;
    border-bottom: 1px solid #e5ebf5;
  }
  .s2a-kpis {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .s2a-table-head {
    display: grid;
  }
  .s2a-table-actions,
  .s2a-table-actions .s2a-search {
    width: 100%;
  }
  .s2a-table-actions {
    flex-wrap: wrap;
  }
}

@media (max-width: 560px) {
  .s2a-kpis {
    grid-template-columns: 1fr;
  }
  .s2a-title {
    font-size: 27px;
  }
}
/* Reports */
.reports-page {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.reports-header {
  align-items: flex-start;
  display: flex;
  gap: 16px;
  justify-content: space-between;
}

.reports-header h1 {
  font-size: 24px;
  margin: 0 0 6px;
}

.reports-meta {
  color: var(--text-muted);
  display: flex;
  flex-wrap: wrap;
  font-size: 13px;
  gap: 12px;
}

.reports-error {
  color: var(--danger);
  font-size: 13px;
  margin-top: 8px;
}

.reports-refresh-form {
  flex: 0 0 auto;
}

.reports-tabs {
  border-bottom: 1px solid var(--border);
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.reports-tab {
  border-bottom: 2px solid transparent;
  color: var(--text-muted);
  font-weight: 600;
  padding: 10px 12px;
  text-decoration: none;
}

.reports-tab.is-active {
  border-bottom-color: var(--brand);
  color: var(--text);
}

.reports-form {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.reports-form-grid {
  display: grid;
  gap: 16px 22px;
  grid-template-columns: minmax(260px, 1fr) minmax(260px, 1fr);
}

.reports-form-grid--extract {
  grid-template-columns: minmax(260px, 1fr) minmax(260px, 1fr) minmax(260px, 1fr);
}

.reports-form fieldset {
  border: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 16px;
  margin: 0;
  min-width: 0;
  padding: 0;
}

.reports-form legend,
.reports-field {
  color: var(--text);
  display: block;
  font-size: 13px;
  font-weight: 700;
  margin-bottom: 6px;
}

.reports-form label {
  color: var(--text);
  font-size: 13px;
}

.reports-field input,
.reports-field select,
.reports-filter-input {
  border: 1px solid var(--border);
  border-radius: 6px;
  display: block;
  margin-top: 6px;
  min-height: 34px;
  padding: 6px 9px;
  width: 100%;
  /* Token surfaces so the builder inputs flip in dark mode — the browser
     default white background read as a light slab on the dark theme
     (dark-mode-runtime P1 on /reports after PR A re-enabled the form). */
  background: var(--surface);
  color: var(--text);
}

/* Bare UA checkboxes/radios in the report builders render white in dark
   mode; scoped color-scheme + accent matches the .ab-queue-card precedent
   (theme_br.css §D bare-form-control fix). */
/* (The source-picker rows live inside .reports-form, so this also covers
   their checkboxes.) */
[data-theme="dark"] .reports-form input[type="checkbox"],
[data-theme="dark"] .reports-form input[type="radio"] {
  accent-color: var(--accent);
  color-scheme: dark;
}

.reports-results-shell {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.reports-results-filters {
  align-items: end;
  display: grid;
  gap: 12px;
  grid-template-columns: minmax(180px, 0.8fr) minmax(160px, 0.7fr) minmax(220px, 1fr) auto;
}

.reports-results-filters .reports-field {
  margin-bottom: 0;
}

.reports-results-filters .reports-field input,
.reports-results-filters .reports-field select {
  border-radius: 8px;
  min-height: 40px;
}

.reports-results-filter-actions {
  align-items: center;
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  min-height: 34px;
}

.reports-results-count {
  color: var(--text-muted);
  font-size: 13px;
  margin-bottom: 10px;
}

.reports-results-table {
  border-collapse: separate;
  border-spacing: 0;
  table-layout: fixed;
  width: 100%;
}

.reports-results-table .rp-col-run { width: 5%; }
.reports-results-table .rp-col-type { width: 8%; }
.reports-results-table .rp-col-status { width: 10.5%; }
.reports-results-table .rp-col-user { width: 8.5%; }
.reports-results-table .rp-col-source { width: 5.5%; }
.reports-results-table .rp-col-rows { width: 6%; }
.reports-results-table .rp-col-submitted { width: 18%; }
.reports-results-table .rp-col-timing { width: 18%; }
.reports-results-table .rp-col-output { width: 15%; }

.reports-results-table td,
.reports-results-table th {
  line-height: 1.35;
  padding: 13px 10px;
  vertical-align: middle;
}

.reports-results-table th {
  background: var(--surface);
  color: var(--text);
  font-size: 12px;
  font-weight: 750;
  white-space: nowrap;
}

.reports-results-table td {
  color: var(--text);
  font-size: 13px;
}

.reports-results-table tbody tr {
  background: var(--surface);
  border-radius: 8px;
  transition: background-color 0.12s ease;
}

.reports-results-table tbody tr:nth-child(even) {
  background: color-mix(in srgb, var(--surface-2) 62%, var(--surface));
}

.reports-results-table tbody tr:hover {
  background: color-mix(in srgb, var(--brand-soft) 34%, var(--surface));
}

.reports-results-table tbody td {
  border-top: 1px solid color-mix(in srgb, var(--border) 58%, transparent);
}

.reports-results-table tbody tr:first-child td {
  border-top: 1px solid var(--border);
}

.reports-results-table td:nth-child(1),
.reports-results-table th:nth-child(1),
.reports-results-table td:nth-child(5),
.reports-results-table th:nth-child(5),
.reports-results-table td:nth-child(6),
.reports-results-table th:nth-child(6) {
  text-align: center;
}

.reports-results-table td:nth-child(7),
.reports-results-table th:nth-child(7) {
  text-align: right;
}

.reports-results-table td:nth-child(4),
.reports-results-table th:nth-child(4),
.reports-results-table td:nth-child(8),
.reports-results-table th:nth-child(8),
.reports-results-table td:nth-child(9),
.reports-results-table th:nth-child(9) {
  white-space: nowrap;
}

.reports-sort-link {
  align-items: center;
  color: var(--text);
  display: inline-flex;
  gap: 5px;
  max-width: 100%;
  text-decoration: none;
}

.reports-sort-link > span:first-child {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.reports-results-table th:nth-child(5) .reports-sort-link > span:first-child,
.reports-results-table th:nth-child(6) .reports-sort-link > span:first-child {
  line-height: 1.15;
  white-space: normal;
}

.reports-sort-link:hover,
.reports-sort-link.is-active {
  color: var(--brand);
  text-decoration: none;
}

.reports-sort-link.is-active {
  font-weight: 800;
}

.reports-sort-link__state {
  align-items: center;
  background: var(--brand-soft);
  border-radius: 999px;
  color: var(--brand-deep);
  display: inline-flex;
  font-size: 10px;
  height: 17px;
  justify-content: center;
  line-height: 1;
  width: 17px;
}

.reports-field-row {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.reports-source-grid {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.reports-source-panel {
  border: 1px solid var(--border);
  border-radius: 8px;
  min-width: 0;
  overflow: hidden;
}

.reports-source-panel__head {
  align-items: center;
  background: var(--surface-2);
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 12px;
}

.reports-source-panel__head h3 {
  font-size: 14px;
  margin: 0 0 4px;
}

.reports-source-panel__head span {
  color: var(--text-muted);
  font-size: 12px;
}

.reports-select-all {
  align-items: center;
  border: 1px solid var(--border);
  border-radius: 999px;
  display: inline-flex;
  gap: 6px;
  padding: 6px 10px;
  white-space: nowrap;
}

.reports-filter-input {
  border-left: 0;
  border-radius: 0;
  border-right: 0;
  margin: 0;
}

.reports-source-list {
  max-height: 420px;
  overflow: auto;
}

.reports-source-grid--full-lists .reports-source-panel {
  overflow: visible;
}

.reports-source-grid--full-lists .reports-source-list {
  max-height: none;
  overflow: visible;
}

.reports-source-grid--price-extract > div {
  grid-column: 1 / -1;
}

.reports-source-row {
  align-items: flex-start;
  border-top: 1px solid var(--border);
  display: flex;
  gap: 8px;
  padding: 8px 10px;
}

/* The source filter hides non-matching rows via the hidden attribute;
   display:flex above defeats the UA [hidden] rule, so restate it (prod
   incident 2026-06-12: typing in the filter visibly did nothing). */
.reports-source-row[hidden] { display: none; }

.reports-empty,
.reports-placeholder {
  color: var(--text-muted);
  padding: 16px;
}

.reports-results-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  padding: 0;
}

.reports-results-panel .rp-results-summary {
  padding: 14px 14px 8px;
}

.reports-results-panel .reports-results-table {
  margin: 0;
}

.reports-results-panel .reports-results-table th:first-child,
.reports-results-panel .reports-results-table td:first-child {
  padding-left: 12px;
}

.reports-results-panel .reports-results-table th:last-child,
.reports-results-panel .reports-results-table td:last-child {
  padding-right: 12px;
}

.rp-cell-meta {
  display: block;
  font-size: 11.5px;
  gap: 0;
  margin-top: 3px;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rp-cell-error {
  font-size: 11.5px;
  line-height: 1.35;
  margin-top: 4px;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rp-run-link {
  color: var(--text);
  font-variant-numeric: tabular-nums;
  font-weight: 750;
  text-decoration: none;
}

.rp-run-link:hover {
  color: var(--brand);
  text-decoration: underline;
}

.rp-type-label {
  display: inline-block;
  max-width: 100%;
}

.rp-empty-dash {
  color: var(--text-muted);
}

.rp-source-cell {
  min-width: 0;
  position: relative;
}

.rp-source-summary {
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: default;
  display: inline-flex;
  justify-content: center;
  min-height: 28px;
  min-width: 34px;
  padding: 4px 10px;
  position: relative;
}

.rp-source-summary:hover,
.rp-source-summary:focus {
  background: var(--surface-2);
  border-color: var(--border);
  outline: 0;
}

.rp-source-summary__main {
  display: none;
  max-width: 72px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rp-source-summary__count {
  color: var(--text);
  font-size: 12px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  min-width: 0;
  padding: 0;
  text-align: center;
}

.rp-source-popover {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 16px 40px rgba(15, 23, 42, 0.16);
  color: var(--text);
  display: none;
  left: 0;
  max-height: 280px;
  min-width: 260px;
  overflow: auto;
  padding: 10px 12px;
  position: absolute;
  top: calc(100% + 8px);
  white-space: normal;
  z-index: 30;
}

.rp-source-summary:hover .rp-source-popover,
.rp-source-summary:focus .rp-source-popover,
.rp-source-summary:focus-within .rp-source-popover {
  display: block;
}

.rp-source-popover strong,
.rp-source-popover span {
  display: block;
}

.rp-source-popover strong {
  font-size: 12px;
  margin-bottom: 2px;
}

.rp-source-popover span {
  color: var(--text-muted);
  font-size: 11.5px;
  margin-bottom: 8px;
}

.rp-source-popover ul {
  display: grid;
  gap: 5px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.rp-source-popover li {
  color: var(--text);
  font-size: 12px;
  line-height: 1.35;
}

.rp-output-actions {
  align-items: center;
  display: flex;
  gap: 8px;
  justify-content: flex-start;
  min-width: 0;
}

.rp-date-cell {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
  line-height: 1.2;
}

.rp-download-menu {
  position: relative;
}

.rp-download-menu summary {
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 7px;
  color: var(--text);
  cursor: pointer;
  display: inline-flex;
  font-size: 12px;
  font-weight: 650;
  gap: 5px;
  height: 34px;
  list-style: none;
  padding: 0 8px;
  white-space: nowrap;
}

.rp-download-menu summary::-webkit-details-marker {
  display: none;
}

.rp-download-menu summary svg {
  height: 14px;
  transition: transform 0.12s ease;
  width: 14px;
}

.rp-download-menu[open] summary {
  border-color: color-mix(in srgb, var(--brand) 55%, var(--border));
  color: var(--brand-deep);
}

.rp-download-menu[open] summary svg {
  transform: rotate(180deg);
}

.rp-download-menu__panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 16px 40px rgba(15, 23, 42, 0.16);
  display: grid;
  gap: 2px;
  min-width: 220px;
  padding: 8px;
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 25;
}

.rp-download-item {
  align-items: center;
  border-radius: 7px;
  color: var(--brand-deep);
  display: flex;
  gap: 9px;
  padding: 8px;
  text-decoration: none;
}

.rp-download-item:hover {
  background: var(--surface-2);
  text-decoration: none;
}

.rp-download-item svg {
  color: var(--brand);
  flex: 0 0 auto;
  height: 17px;
  width: 17px;
}

.rp-download-item span {
  display: grid;
  min-width: 0;
}

.rp-download-item strong {
  color: var(--brand-deep);
  font-size: 12px;
  font-weight: 750;
  max-width: 170px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rp-download-item small {
  color: var(--text-muted);
  font-size: 11px;
}

.rp-view-error {
  align-items: center;
  color: var(--danger);
  display: inline-flex;
  font-size: 12.5px;
  font-weight: 750;
  gap: 6px;
  text-decoration: none;
  white-space: nowrap;
}

.rp-view-error svg {
  height: 16px;
  width: 16px;
}

.rp-rerun-link {
  align-items: center;
  border: 1px solid var(--border);
  border-radius: 7px;
  color: var(--text-muted);
  display: inline-flex;
  height: 34px;
  justify-content: center;
  text-decoration: none;
  width: 32px;
}

.rp-rerun-link:hover {
  background: var(--surface-2);
  color: var(--brand);
  text-decoration: none;
}

.rp-rerun-link svg {
  height: 15px;
  width: 15px;
}

[data-theme="dark"] .reports-results-panel,
[data-theme="dark"] .rp-source-popover,
[data-theme="dark"] .rp-download-menu__panel {
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.38);
}

[data-theme="dark"] .rp-source-summary,
[data-theme="dark"] .rp-download-menu summary,
[data-theme="dark"] .rp-rerun-link {
  background: var(--surface-2);
}

[data-theme="dark"] .rp-download-menu[open] summary {
  color: var(--accent);
}

.reports-actions {
  display: flex;
  justify-content: flex-end;
}

.reports-data-shell {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.reports-data-kpis {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.reports-data-kpi {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px;
}

.reports-data-kpi span {
  color: var(--text-muted);
  display: block;
  font-size: 12px;
  font-weight: 700;
  margin-bottom: 6px;
  text-transform: uppercase;
}

.reports-data-kpi strong {
  color: var(--text);
  font-size: 24px;
  line-height: 1;
}

.reports-data-grid {
  display: grid;
  gap: 18px;
  grid-template-columns: minmax(320px, 0.8fr) minmax(420px, 1.2fr);
}

.reports-data-table {
  margin: 0;
  width: 100%;
}

.reports-data-table td,
.reports-data-table th {
  vertical-align: top;
}

@media (max-width: 980px) {
  .reports-form-grid,
  .reports-form-grid--extract,
  .reports-results-filters,
  .reports-source-grid,
  .reports-data-grid,
  .reports-data-kpis {
    grid-template-columns: 1fr;
  }

  .reports-header {
    align-items: stretch;
    flex-direction: column;
  }
}

/* ============================================================
   Dark-mode P0 contrast fixes (audit 2026-05-26).
   Surgical overrides for legacy hardcoded light-mode colors
   in shared chrome that remain on bespoke .keepa-* / .bbs-*
   namespaces awaiting Phase-4 Tiger migration.
   ============================================================ */

/* Keepa cache health alerts — hardcoded pastel backgrounds
   (`#f3fff6`, `#fffaf0`) make the alert body (which uses
   var(--text)/var(--text-muted)) unreadable in dark mode.
   Rebind to dark surfaces with status-tinted borders. */
[data-theme="dark"] .keepa-cache-alert--success {
  background: var(--ok-soft);
  border-color: var(--ok);
}

[data-theme="dark"] .keepa-cache-alert--warning {
  background: var(--warn-soft);
  border-color: var(--warn);
}

/* Keepa cache snapshot table header — hardcoded `#f8fafc`
   background pairs with var(--text) which goes light in dark
   mode, giving 1.15 contrast. Use a dark surface that still
   distinguishes thead from tbody. */
[data-theme="dark"] .keepa-cache-table thead th {
  background: var(--surface-2);
}

/* Note: brand-on-brand button contrast (.btn--primary, active
   domain chip, sidebar-brand-mark) is fixed by adjusting the
   --brand-fg token in tokens.css for dark mode rather than
   per-selector here — see the :root[data-theme="dark"] block
   in tokens.css. White-on-#ff8750 was 2.38; near-black is ~9. */

/* ============================================================
   Wave 1 extension — buyback-site card SURFACES (audit 2026-05-26).
   The Wave 1 .bbs-page token-rebind made --bbs-text resolve to the
   global light --text in dark mode. That fixed page-header text but
   exposed 11 P0 contrast failures on card / panel / pill / empty-state
   surfaces in styles.css that hardcode light backgrounds (#ffffff,
   #f1f5f9, #f8fafc, #fafbfd, etc.) and never got a dark-theme variant.
   The text colors inside these surfaces now resolve light (correct)
   on top of light backgrounds (broken) = invisible.
   Fix: rebind only the SURFACES (background + border) to dark tokens.
   Text colors continue to inherit from the Wave 1 .bbs-page rebind.
   ============================================================ */

/* Status pill base — `.bbs-pill` hardcodes #f1f5f9 bg + #e2e8f0 border
   in styles.css L18284. Color is var(--bbs-text-soft) → light text on
   light pill = 2.27. (Status variants .bbs-pill--ok/--warn/--danger
   keep their tinted soft tokens which already adapt via tokens.css.) */
[data-theme="dark"] .bbs-page .bbs-pill {
  background: var(--surface-2);
  border-color: var(--border);
}

/* Idle pricing-file panel — `.bbs-idle-panel` (styles.css L18726) uses
   var(--bbs-primary-softer) which is a light pastel. Inner <strong>
   and .bbs-idle-panel__text use --bbs-text / --bbs-text-soft, now
   light, so contrast was 1.14 and 2.36. Rebind to dark surface. */
[data-theme="dark"] .bbs-page .bbs-idle-panel {
  background: var(--surface-2);
  border-color: var(--border-strong);
}

/* Side card (Hard rules + Run summary) — `.bbs-side-card` hardcodes
   `background: #ffffff` (styles.css L20244). Inner h3 / dt / dd use
   --bbs-text → light on white = 1.21. */
[data-theme="dark"] .bbs-page .bbs-side-card {
  background: var(--surface);
  border-color: var(--border);
}

/* Rules card (Hard rules editor body) — `.bbs-rules-card` hardcodes
   `background: #ffffff` (styles.css L19317). dt label, dd value, and
   the .bo-mono spans inside all inherit light --bbs-text → 1.21 / 2.49.
   Also rebind the row separator (#f1f5f9) so the divider stays subtle
   instead of cutting across as a bright bar. */
[data-theme="dark"] .bbs-page .bbs-rules-card {
  background: var(--surface);
  border-color: var(--border);
}
[data-theme="dark"] .bbs-page .bbs-rules-card__row {
  border-bottom-color: var(--border);
}

/* Collapsible section chrome — `.bbs-section` and its <summary> child
   both hardcode `background: #ffffff` (styles.css L18743, L18751).
   The "Recent Pricing Files" <span> inside the summary inherits light
   --bbs-text → 1.21. Override both bg + the `[open]` summary tone +
   the count-badge background, all to dark tokens. */
[data-theme="dark"] .bbs-page .bbs-section {
  background: var(--surface);
  border-color: var(--border);
}
[data-theme="dark"] .bbs-page .bbs-section__summary {
  background: var(--surface);
}
[data-theme="dark"] .bbs-page .bbs-section[open] > .bbs-section__summary {
  background: var(--surface-hover);
  border-bottom-color: var(--border);
}
[data-theme="dark"] .bbs-page .bbs-section__summary:hover {
  background: var(--surface-hover);
}
[data-theme="dark"] .bbs-page .bbs-section__title-count {
  background: var(--surface-hover);
  color: var(--text-muted);
}

/* Empty-state panel — `.bbs-empty` hardcodes `background: #fafbfd`
   (styles.css L18919). The placeholder text and the <em> "Re-run"
   inside both inherit light --bbs-text-muted → 2.40 both. */
[data-theme="dark"] .bbs-page .bbs-empty {
  background: var(--surface-2);
  border-color: var(--border);
}

/* Anchor editor (Buy Box Used selector) — `.bbs-anchor-editor__group`
   hardcodes `background: #fff` and `.bbs-anchor-option` hardcodes
   `background: #f8fafc` + `color: #334155`. The __title span uses
   var(--bbs-tiger-text) and the __label inherits the slate text; both
   land at 1.21 on the light card bg. Rebind surfaces; rebind the
   hardcoded option text to dark --text. */
[data-theme="dark"] .bbs-page .bbs-anchor-editor__group {
  background: var(--surface);
  border-color: var(--border);
}
[data-theme="dark"] .bbs-page .bbs-anchor-editor__group--new {
  background: var(--brand-soft);
  border-color: var(--brand);
}
[data-theme="dark"] .bbs-page .bbs-anchor-option {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--text);
}
[data-theme="dark"] .bbs-page .bbs-anchor-option--locked {
  background: var(--brand-soft);
  border-color: var(--brand);
}
/* Anchor summary chips (the row of currently-active anchor labels —
   `.bbs-anchor-summary span` at styles.css L20329 — hardcodes
   `background: #f8fafc` + `color: #334155`). */
[data-theme="dark"] .bbs-page .bbs-anchor-summary span {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--text);
}
/* Anchor option state pill ("Active" / "Inactive") — hardcoded
   `background: #f1f5f9; color: #64748b` (inactive). The "Active"
   green (#dcfce7 / #137447) keeps reasonable contrast in dark mode
   so leave it; just dark the inactive default. */
[data-theme="dark"] .bbs-page .bbs-anchor-option__state {
  background: var(--surface-hover);
  color: var(--text-muted);
}

/* ============================================================
   Wave 1.5 — buyback-site pill VARIANTS + side-card link
   (audit follow-up 2026-05-26). After the Wave 1 extension
   rebound `.bbs-pill` and `.bbs-side-card` SURFACES to dark
   tokens, three contrast P0s remained on /buyback-site:

     - .bbs-pill--warn ("Warning")   contrast 2.87
     - .bbs-pill--danger ("Blocked") contrast 2.23
     - .bbs-side-card__link ("Full editor →") contrast 1.59

   Root cause: the variant rules in styles.css (L18379-18380)
   only set background+color, and the BBS-local `--bbs-warn` /
   `--bbs-danger` / `--bbs-primary` tokens are NEVER rebound in
   dark mode — they stay at their deep-light-mode hex values
   (#b45309, #b91c1c, #0b3d91). After the Wave 1 extension forced
   the pill base bg to var(--surface-2) and the side-card bg to
   var(--surface), those deep colors land on dark surfaces with
   no flip. Override the color to the bright dark-mode status
   tokens (--warn / --danger) and --accent for the link.
   ============================================================ */

/* Warning pill — keep var(--surface-2) bg from Wave 1 ext;
   swap text from deep amber #b45309 to dark-mode --warn
   (#e0a33a) for ~6.5:1 contrast on #222a39. */
[data-theme="dark"] .bbs-page .bbs-pill--warn {
  color: var(--warn);
  border-color: var(--warn-soft);
}

/* Blocked / danger pill. Wave 5 (2026-05-29): the runtime crawler
   re-measured var(--danger) #e85c4d on var(--surface-2) #222a39 at
   4.16 — under the 4.5 floor. Lighten to #f0796b (= 5.25:1). */
[data-theme="dark"] .bbs-page .bbs-pill--danger {
  color: #f0796b;
  border-color: var(--danger-soft);
}

/* "Full editor →" link inside `.bbs-side-card` —
   `.bbs-side-card__link` (styles.css L20347) hardcodes
   `color: var(--bbs-primary)` = deep navy #0b3d91. On the
   side-card's dark var(--surface) = #1b2230 that lands at
   1.59. Wave 5 (2026-05-29): var(--accent) #4f8cc9 measured
   at exactly 4.50 (fails the ≥4.5 rounding check); lighten to
   #6aa3d8 (= 5.95:1). */
[data-theme="dark"] .bbs-page .bbs-side-card__link {
  color: #6aa3d8;
}

/* ============================================================
   WAVE 2 — App shell P1 contrast overrides (sidebar + topbar)
   ------------------------------------------------------------
   The Phase 2 runtime audit (post-Wave 1) found 33 P1 contrast
   failures clustered on shell elements that appear on every
   route. Each element's base rule resolves to
   var(--sidebar-muted) (#6e7a8f) or var(--text-subtle)
   (#6e7a8f) in dark mode, which lands at ~4.46:1 against the
   sidebar (#0a0e15) or topbar (#171c25) — just under the
   WCAG AA 4.5:1 floor.

   These overrides bump the failing selectors to
   var(--sidebar-fg) / var(--text) (the high-contrast token,
   #c3cbd9 / #e6eaf2) only inside dark mode, so light mode
   cannot regress. We override per-selector rather than
   rewriting the --sidebar-muted token to keep dim styling
   intact on the truly secondary spots (icon buttons, theme
   switch dot border, etc.).
   ============================================================ */

/* Brand env label ("Production") under sidebar header.
   Base: L178 color: var(--sidebar-muted). */
[data-theme="dark"] .sidebar-brand-env {
  color: var(--sidebar-fg);
}

/* Sidebar section dividers ("Operations", "Admin").
   Base: L204-212 color: var(--sidebar-muted). */
[data-theme="dark"] .sidebar-section,
[data-theme="dark"] .sidebar-section-label {
  color: var(--sidebar-fg);
}

/* Nested nav links ("Calculator", "Price Extract", etc.).
   Base: L284-294 color: var(--sidebar-muted) !important.
   !important needed to win over base !important. Exclude the
   .is-active (L299) and --danger (L319) variants — those base
   rules already set var(--sidebar-active-fg) / var(--danger)
   with !important, and equal-specificity later-source rules
   would clobber them. The external arrow ::after token
   (L311-315) is rebound separately below. */
[data-theme="dark"] .sidebar-subitem:not(.is-active):not(.sidebar-subitem--danger) {
  color: var(--sidebar-fg) !important;
}
[data-theme="dark"] .sidebar-subitem--external::after {
  color: currentColor;
}

/* User initials avatar circle ("DA"). Base: L400-409 uses
   bg: var(--accent-soft) #182a3e + color: var(--accent)
   #4f8cc9 — lands at 4.12:1, worst of the cluster. Swap to
   --surface-2 / --text for ~11:1. */
[data-theme="dark"] .sidebar-user-avatar {
  background: var(--surface-2);
  color: var(--text);
}

/* Role label under user name ("Admin").
   Base: L411 color: var(--sidebar-muted). */
[data-theme="dark"] .sidebar-user-role {
  color: var(--sidebar-fg);
}

/* "Dark mode" toggle label at sidebar footer. Label inherits
   color from .sidebar-theme-btn (L419-431, color:
   var(--sidebar-muted)); target the label directly so the
   button chrome (icon, switch dot) keeps its dim styling. */
[data-theme="dark"] .sidebar-theme-btn .theme-label {
  color: var(--sidebar-fg);
}

/* Topbar search "⌘K" keyboard-shortcut pill.
   Base: L541-549 color: var(--text-subtle) on bg-elev. */
[data-theme="dark"] .topbar-search-kbd {
  color: var(--text);
}

/* ============================================================
   Wave 4 — purchase-bot dashboard + shared chrome
   (audit 2026-05-28). 20 P1 contrast / light-surface failures
   across 6 routes: /admin/users, /alerts, /auto-buy/settings,
   /purchase-bot-dashboard, /, and shared widgets that show on
   multiple pages. Three cross-cutting rules (.panel, .table th,
   .purchase-dropdown-filter-btn) clear two routes each.
   All overrides scoped to [data-theme="dark"]; page-scope
   ancestor `.purchase-bot-page-shell` is used where the rule
   could otherwise restyle unrelated form controls.
   ============================================================ */

/* ---- Cross-cutting #1: legacy .panel surface ----
   `.panel` (styles.css L2472) hardcodes `background: #fff` +
   `color: rgb(29, 36, 51)` (= light --text baked in). Used on
   `/` dashboard tabs (section.panel.tab-panel) and on
   /purchase-bot-dashboard (section.panel.purchase-panel-wide).
   Same fix clears both routes. Inner `.panel h3` / .panel-title
   hardcodes `#e3edff` bg + `#cddcff` border — rebind to dark
   surface-2 so the header bar reads instead of glowing.

   PR #1006 review: `.panel` is a legacy primitive on MANY
   un-audited pages (admin edit, credentials note, AWS details,
   profile, diagnostics, auto-buy detail). The audit only proved
   the two co-class combos below — `.panel.tab-panel` (dashboard
   tabs) and `.panel.purchase-panel-wide` (purchase-bot main
   content) — so the selectors are pinned to those combos rather
   than bare `.panel`. */
[data-theme="dark"] .panel.tab-panel,
[data-theme="dark"] .panel.purchase-panel-wide {
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-sm);
}
[data-theme="dark"] .panel.tab-panel h3,
[data-theme="dark"] .panel.tab-panel .panel-title,
[data-theme="dark"] .panel.purchase-panel-wide h3,
[data-theme="dark"] .panel.purchase-panel-wide .panel-title {
  background: var(--surface-2);
  border-bottom-color: var(--border);
  color: var(--text);
}
[data-theme="dark"] .panel.tab-panel h3[data-collapsible-toggle]::after,
[data-theme="dark"] .panel.tab-panel .panel-title[data-collapsible-toggle]::after,
[data-theme="dark"] .panel.purchase-panel-wide h3[data-collapsible-toggle]::after,
[data-theme="dark"] .panel.purchase-panel-wide .panel-title[data-collapsible-toggle]::after {
  color: var(--accent);
}

/* ---- Cross-cutting #2: shared `.table th` column headers (GLOBAL) ----
   `.table th` (theme_br.css L2549) sets color: var(--text-subtle)
   (#6e7a8f in dark) on background: var(--bg-elev) (#171c25) =
   ~3.94 contrast (AA fail). Bump th text to --text-muted (#9aa5b8 in
   dark) = ~6.5 contrast on #171c25. The global `a { color: inherit }`
   (theme_br.css L55) means the sortable header links (dashboard
   Script-name/Created/…, /contacts Name, /tickets Script,
   /scheduled Script-Name, /auto-buy ID) inherit the th color, so
   this single rule clears both the th text AND its sort links.

   Wave 10 (audit 2026-05-31): the full runtime crawl proved every
   generic `.table` page in dark mode, so this supersedes the four
   page-scoped rules added in PR #1006 (.admin-users-shell,
   .auto-buy-settings, .keepa-priority-tiers, .admin-page-perf-shell)
   and the .auto-buy-pipeline-shell scope below. Going global also
   means any NEW `.table` inherits a passing dark header for free —
   future edits no longer need a per-page header override. */
[data-theme="dark"] .table th {
  color: var(--text-muted);
}

/* ---- Cross-cutting #3: shared `.purchase-dropdown-filter-btn` ----
   `.purchase-dropdown-filter-btn` (styles.css L1126) hardcodes
   `background: #fff` + `border: 1px solid #d1d5db` + `color: #374151`.
   Shared widget — appears on /alerts (2 instances) and
   /purchase-bot-dashboard (2 instances). One rebind clears both. */
[data-theme="dark"] .purchase-dropdown-filter-btn {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--text);
}
[data-theme="dark"] .purchase-dropdown-filter-btn::after {
  color: var(--text-subtle);
}
[data-theme="dark"] .purchase-dropdown-filter-btn.has-selection {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--text);
}

/* ---- /admin/users form-field-hint ----
   `.form-field-hint` (theme_br.css L3734) uses `color:
   var(--text-subtle)` (#6e7a8f in dark) which lands at 3.67
   on the form background. Bump to --text-muted (#9aa5b8).

   PR #1006 review: `.form-field-hint` / `.field-hint` appear in
   forms across the app; the audit only proved /admin/users.
   Scoped to the page wrapper `.admin-users-shell`
   (admin_users.html L13) so other forms keep their baseline. */
[data-theme="dark"] .admin-users-shell .form-field-hint,
[data-theme="dark"] .admin-users-shell .field-hint {
  color: var(--text-muted);
}

/* ============================================================
   purchase-bot card / surface rebinds.

   Scope discipline:
   - `.purchase-bot-page-shell` ONLY wraps the top header strip
     in `purchase_bot_dashboard.html` (lines 4-32: page title,
     subtitle, tabs). It CLOSES before the main `<section
     class="panel purchase-panel-wide">` opens. Header-strip
     rules below stay scoped to `.purchase-bot-page-shell`.
   - Main dashboard content lives under `.purchase-panel-wide`
     (arb-refresh card, glossary, summary bar, rows, expand
     toggle, native form controls, toggle label). Those rules
     are scoped to `.purchase-panel-wide`.
   - `.purchase-flag-badge.flag-*` is a SHARED widget — also
     used by `auto_buy_detail.html` (~L350) on /auto-buy/<id>.
     Those rules are un-scoped so the dark variants apply
     everywhere the badge renders.

   Audit: 2026-05-28 wave 4 follow-up after Codex caught the
   `.purchase-bot-page-shell` scope mis-target on commit e79e9427.
   ============================================================ */

/* Page subtitle "Monitor purchase bot activity" — hardcoded
   `color: #6b7280` (theme_br.css L4450) lands at 3.85 on the
   dashboard bg. Bump to --text-muted. Lives in the header
   strip → stays under `.purchase-bot-page-shell`. */
[data-theme="dark"] .purchase-bot-page-shell .purchase-bot-page-subtitle {
  color: var(--text-muted);
}

/* Page tabs — hardcoded `background: #fff`, `color: #475569`,
   `border: 1px solid #cbd5e1` (theme_br.css L4464). Lives in
   the header strip → stays under `.purchase-bot-page-shell`. */
[data-theme="dark"] .purchase-bot-page-shell .purchase-bot-page-tabs {
  border-bottom-color: var(--border);
}
[data-theme="dark"] .purchase-bot-page-shell .purchase-bot-page-tab {
  background: var(--surface);
  border-color: var(--border);
  color: var(--text-muted);
}
[data-theme="dark"] .purchase-bot-page-shell .purchase-bot-page-tab:hover {
  background: var(--surface-hover);
  color: var(--text);
}
[data-theme="dark"] .purchase-bot-page-shell .purchase-bot-page-tab.is-active,
[data-theme="dark"] .purchase-bot-page-shell .purchase-bot-page-tab[aria-current="page"] {
  background: var(--brand);
  color: var(--brand-fg);
  border-color: var(--brand);
}

/* Arb-refresh card — hardcoded `background: #f8fbff` +
   `border: #d9e2f3` (theme_br.css L4781). Running / error
   variants use `#eef4ff` / `#fef2f2`. Rebind all three.
   Lives in `.purchase-panel-wide` (main content). */
[data-theme="dark"] .purchase-panel-wide .purchase-bot-arb-refresh-card {
  background: var(--surface-2);
  border-color: var(--border);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-arb-refresh-card.is-running {
  background: var(--accent-soft);
  border-color: var(--accent);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-arb-refresh-card.is-error {
  background: var(--danger-soft);
  border-color: var(--danger);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-arb-refresh-title {
  color: var(--text);
}
/* Audit 2026-05-28 wave 4 follow-up 2: pill text was --accent
   on --accent-soft = 4.12 contrast (under AA 4.5). Same shape
   for the .is-error variant: --danger on --danger-soft = 4.16.
   Bump pill text to --text in both states; the colored surface
   still telegraphs the status. */
[data-theme="dark"] .purchase-panel-wide .purchase-bot-arb-refresh-pill {
  background: var(--accent-soft);
  color: var(--text);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-arb-refresh-card.is-error .purchase-bot-arb-refresh-pill {
  background: var(--danger-soft);
  color: var(--text);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-arb-refresh-meta {
  color: var(--text-muted);
}
/* Audit 2026-05-28 wave 4 follow-up 2: --danger (#e85c4d) on
   --danger-soft card bg = 4.16 contrast (under AA 4.5). Lift to
   --text; the surrounding red surface keeps the error semantic. */
[data-theme="dark"] .purchase-panel-wide .purchase-bot-arb-refresh-error {
  color: var(--text);
}

/* Flag glossary details — `details.purchase-bot-flag-glossary`
   hardcodes `background: #f8fafc` + `border: #e5e7eb`
   (theme_br.css L5096). Inner summary / count / items also
   carry hardcoded #374151 / #9ca3af / #4b5563 text. Lives in
   `.purchase-panel-wide` (main content). */
[data-theme="dark"] .purchase-panel-wide .purchase-bot-flag-glossary {
  background: var(--surface-2);
  border-color: var(--border);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-flag-glossary > summary {
  color: var(--text);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-flag-glossary-count {
  color: var(--text-subtle);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-flag-glossary-item > span:last-child {
  color: var(--text-muted);
}

/* Flag badges — `.purchase-flag-badge.flag-*` variants
   (styles.css L1312+) all use light pastel bg + deep colored
   text + light pastel border. On dark mode the audit reports
   the rgb(254,242,242) base specifically (flag-ex). Map each
   variant to its dark *-soft surface token + readable foreground.
   UN-SCOPED: shared widget used by both /purchase-bot-dashboard
   and /auto-buy/<id> (auto_buy_detail.html ~L350). */
[data-theme="dark"] .purchase-flag-badge.flag-ex {
  background: var(--danger-soft);
  color: var(--text);
  border-color: var(--danger);
}
[data-theme="dark"] .purchase-flag-badge.flag-sa {
  background: var(--warn-soft);
  color: var(--warn);
  border-color: var(--warn);
}
[data-theme="dark"] .purchase-flag-badge.flag-sr {
  background: var(--warn-soft);
  color: var(--warn);
  border-color: var(--warn);
}
[data-theme="dark"] .purchase-flag-badge.flag-ep {
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--border-strong);
}
/* Audit 2026-05-28 wave 4 follow-up 2: --accent (#4f8cc9) on
   --accent-soft (#182a3e) = 4.12 contrast (under AA 4.5). Lift
   text to --text; the accent border + soft bg still mark "AN". */
[data-theme="dark"] .purchase-flag-badge.flag-an {
  background: var(--accent-soft);
  color: var(--text);
  border-color: var(--accent);
}
[data-theme="dark"] .purchase-flag-badge.flag-bl {
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--border-strong);
}
[data-theme="dark"] .purchase-flag-badge.flag-pt {
  background: var(--surface-2);
  color: var(--text-muted);
  border-color: var(--border);
}

/* Summary bar above the table — `.purchase-bot-summary-bar`
   hardcodes `background: #f1f5f9` + `color: #475569`
   (theme_br.css L4587). Lives in `.purchase-panel-wide`. */
[data-theme="dark"] .purchase-panel-wide .purchase-bot-summary-bar {
  background: var(--surface-2);
  color: var(--text-muted);
  border-bottom-color: var(--border);
}

/* Row striping + header — `.purchase-bot-row` zebra stripe
   resolves to #f8fafc light tint; the row header band is #fff.
   `.purchase-bot-header` is sticky-on-table, light by default.
   Lives in `.purchase-panel-wide`. */
[data-theme="dark"] .purchase-panel-wide .purchase-bot-row:nth-child(2n+1):not(.purchase-bot-header):not(.purchase-bot-filter-row) {
  background: var(--surface-2);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-row:hover:not(.purchase-bot-header):not(.purchase-bot-filter-row) {
  background: var(--surface-hover);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-header {
  background: var(--bg-elev);
  border-bottom-color: var(--border);
  color: var(--text);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-header a,
[data-theme="dark"] .purchase-panel-wide .purchase-bot-header span {
  color: var(--accent);
}

/* Expand toggle pill — `.purchase-bot-expand-toggle` hardcodes
   `background: #eef4ff` + `border: #c7d6f5` + `color: #0b3d91`.
   Lives in `.purchase-panel-wide`. Use --text on the accent surface
   because --accent on --accent-soft / --surface-hover is sub-AA. */
[data-theme="dark"] .purchase-panel-wide .purchase-bot-expand-toggle {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--text);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-expand-toggle:hover {
  background: var(--surface-hover);
  color: var(--text);
}

/* Native <input> / <select> inside purchase-bot main panel —
   scope-bound to .purchase-panel-wide to avoid clobbering
   every form on the app. Covers the bare `input` finding plus
   `.purchase-bot-toggle-days-input` plus the filter-row inputs
   that use light bg by browser default. */
[data-theme="dark"] .purchase-panel-wide input[type="text"],
[data-theme="dark"] .purchase-panel-wide input[type="number"],
[data-theme="dark"] .purchase-panel-wide input[type="search"],
[data-theme="dark"] .purchase-panel-wide input:not([type]),
[data-theme="dark"] .purchase-panel-wide select {
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--border);
}
[data-theme="dark"] .purchase-panel-wide input[type="text"]::placeholder,
[data-theme="dark"] .purchase-panel-wide input[type="number"]::placeholder,
[data-theme="dark"] .purchase-panel-wide input[type="search"]::placeholder {
  color: var(--text-subtle);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-toggle-days-input {
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--border);
}

/* Audit 2026-05-28 wave 4 follow-up 2: `.purchase-bot-filter-row`
   (theme_br.css L4964) hardcodes `background: #f8fafc` (light
   tint), which overrode the zebra-stripe-only dark rule above
   and rendered the filter row at light surface 248,250,252.
   The :not(.purchase-bot-filter-row) exclusion in the zebra
   rule meant the filter row never got a dark bg. Rebind to
   --surface-2 so it matches the rest of the table chrome. */
[data-theme="dark"] .purchase-panel-wide .purchase-bot-filter-row {
  background: var(--surface-2);
}

/* Toggle label "Hide for" — `.purchase-bot-toggle-label`
   (theme_br.css L5219) hardcodes `color: #64748b`. Its parent
   wrapper `.purchase-bot-show-flagged-toggle` (L5160) hardcodes
   a light yellow pill (`background: #fef3c7` + `color: #92400e`
   + `border: 1px solid #fbbf24`) with no dark override. Audit
   2026-05-28 wave 4 follow-up 2 saw the label at #64748b on
   #fef3c7 = 2.23 contrast (REGRESSION). Wave-4-follow-up-1's
   `.purchase-panel-wide .purchase-bot-toggle-label` rule did
   apply, but with --text-muted (#9aa5b8) on the light yellow
   pill it stayed under AA. Real fix: rebind the wrapper pill
   to dark warn tokens, then the label inherits clean against
   --warn-soft. */
[data-theme="dark"] .purchase-panel-wide .purchase-bot-show-flagged-toggle {
  background: var(--warn-soft);
  border-color: var(--warn);
  color: var(--text);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-show-flagged-toggle:hover {
  background: var(--surface-hover);
}
[data-theme="dark"] .purchase-panel-wide .purchase-bot-toggle-label {
  color: var(--text);
}

/* ============================================================
   WAVE 5 — buyback-site runtime-audit follow-up (2026-05-29).
   The runtime crawler against current main (sha 0fbf8363) still
   found 11 P1s on /buyback-site: six elements hardcode light
   surfaces (so the Wave 1 dark token rebind never reaches them)
   and five text colours sit below the WCAG AA 4.5:1 floor on the
   dark card surfaces. All scoped to `[data-theme="dark"] .bbs-page`
   so light mode and every other route are untouched. The two pill
   /link contrast bumps live in the Wave 1.5 block above; the rest
   are below.
   ------------------------------------------------------------ */

/* Status strips + schedule rows hardcode warm/green pastel
   backgrounds (#fffbeb / #f0fdf4) with deep amber/green text.
   On dark that renders as a bright bar; rebind the family to the
   elevated dark surface so the inherited --text reads light. */
[data-theme="dark"] .bbs-page .bbs-status-strip,
[data-theme="dark"] .bbs-page .bbs-schedule-row,
[data-theme="dark"] .bbs-page .bbs-schedule-row--enabled,
[data-theme="dark"] .bbs-page .bbs-schedule-row--disabled,
[data-theme="dark"] .bbs-page .bbs-schedule-row--warning,
[data-theme="dark"] .bbs-page .bbs-epeg-row {
  background: var(--surface-2);
  border-color: var(--border-strong);
  color: var(--text);
}
/* Danger / warning / info banner variants hardcode #fef2f2 /
   #fefce8 / #eff6ff. Keep a subtle status tint via the dark
   *-soft surface + status border, light text on top. */
[data-theme="dark"] .bbs-page .bbs-schedule-row--danger,
[data-theme="dark"] .bbs-page .bbs-banner--danger {
  background: var(--danger-soft);
  border-color: var(--danger);
  color: var(--text);
}
[data-theme="dark"] .bbs-page .bbs-banner--warning {
  background: var(--warn-soft);
  border-color: var(--warn);
  color: var(--text);
}
[data-theme="dark"] .bbs-page .bbs-banner--info {
  background: var(--brand-soft);
  border-color: var(--brand);
  color: var(--text);
}

/* Hard-rules editor numeric inputs hardcode `background: #ffffff`. */
[data-theme="dark"] .bbs-page .bbs-rules-card__input {
  background: var(--surface-2);
  border-color: var(--border-strong);
  color: var(--text);
}
[data-theme="dark"] .bbs-page .bbs-rules-card__input:invalid {
  background: var(--danger-soft);
}

/* Anchor-editor explanatory note hardcodes #f8fafc / #334155. */
[data-theme="dark"] .bbs-page .bbs-anchor-note {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--text);
}

/* Outline button hardcodes a white fill + deep-navy text; flip both
   or the label vanishes on the dark surface. */
[data-theme="dark"] .bbs-page .bbs-btn--outline {
  background: var(--surface-2);
  border-color: var(--border-strong);
  color: var(--text);
}
[data-theme="dark"] .bbs-page .bbs-btn--outline:hover {
  background: var(--surface-hover);
}

/* Rule tag hardcodes orange-50 fill / orange-900 text. */
[data-theme="dark"] .bbs-page .bbs-rule-tag {
  background: var(--warn-soft);
  border-color: var(--border-strong);
  color: var(--warn);
}

/* "Enabled" ok-pill: base var(--bbs-ok) #16a34a = 4.37 on
   var(--surface-2). Swap to the dark --ok token (#3ab87d = 5.71). */
[data-theme="dark"] .bbs-page .bbs-pill--ok {
  color: var(--ok);
  border-color: var(--ok-soft);
}

/* Anchor-editor hint text hardcodes slate-500 #64748b = 3.35.
   Use the dark --text-muted token (#9aa5b8 = 6.41). */
[data-theme="dark"] .bbs-page .bbs-anchor-editor__hint {
  color: var(--text-muted);
}

/* ============================================================
   WAVE 6 — broad runtime-audit long-tail (2026-05-29).

   Broad runtime audit (24 remaining UI routes, light+dark) found
   116 findings / 92 P1+ on 15 routes never covered by Waves 1-5.
   Root causes are the same recurring two: (a) feature namespaces
   that hardcode light hex with no [data-theme="dark"] rebind, and
   (b) saturated status text (--info / --danger) sitting one step
   below AA on its own *-soft tint. Everything below is scoped to
   [data-theme="dark"]; nothing leaks into the light theme.
   ============================================================ */

/* ---- 6A. Shared shell (cascades across the form/settings pages:
   /admin/users/new, /credentials-note, /profile, /aws-details,
   /diagnostics). The pages already render dark TEXT tokens
   (--text #e6eaf2, --text-muted #9aa5b8) correctly; they fail only
   because the bare `section.panel` surface never flips, so light-on-
   light. styles.css §2472 `.panel` hardcodes a white background and
   has no dark rebind. `.panel.tab-panel` / `.panel.purchase-panel-wide`
   (theme_br.css §11710) are MORE specific (0,2,0 > 0,1,1) so this
   element-scoped rule does not touch the dashboard/purchase panels. */
[data-theme="dark"] section.panel {
  background: var(--surface);
  border-color: var(--border);
  color: var(--text);
}

/* `.panel h3` / `.panel .panel-title` (styles.css §2490) hardcodes a
   light-blue header bar (#e3edff bg / #cddcff border) on EVERY h3 nested
   under a `.panel` — including the section headers + sidebar h3 on the
   create/edit-user form. Flip the bar to dark, scoped to the audited
   shell so untested `.panel` pages keep their baseline. */
[data-theme="dark"] .admin-user-edit-shell h3,
[data-theme="dark"] .admin-user-edit-shell .panel-title {
  background: var(--surface-2);
  border-bottom-color: var(--border);
  color: var(--text);
}

/* `.form-field-hint` is only dark-bound inside .admin-users-shell /
   .purchase-bot-page-shell; bare usage on admin_user_edit / upload /
   keepa custom-run / glossary lands #6e7a8f (=3.67). Bind the bare
   selector to --text-muted (#9aa5b8 ≥ 4.5 on every dark surface). */
[data-theme="dark"] .form-field-hint {
  color: var(--text-muted);
}

/* `.text-danger` (theme_br.css §2641) is var(--danger) #e85c4d, which
   lands 3.88-4.36 on warn/danger-soft tints. The lighter #f0796b
   (=5.2-5.7 on those tints) is the same red Wave 1.5 settled on. */
[data-theme="dark"] .text-danger {
  color: #f0796b;
}

/* Saturated status text one step below AA on its own *-soft tint:
   --info #4f8cc9 on --info-soft #182a3e = 4.12; --danger #e85c4d on
   --danger-soft #3a1f1a = 4.36. The *-soft tokens are background-only
   (never used as a text color), so rather than darken the tint and
   wash out the badge, lighten the TEXT: #6aa3d8 (=5.45) / #f0796b
   (=5.55). Covers .pill--info/.pill--danger and the dashboard status
   chips' running/error toggled states. */
[data-theme="dark"] .pill--info,
[data-theme="dark"] .dashboard-status-chip[aria-pressed="true"][data-status="running"] {
  color: #6aa3d8;
}
[data-theme="dark"] .pill--danger,
[data-theme="dark"] .dashboard-status-chip[aria-pressed="true"][data-status="error"] {
  color: #f0796b;
}

/* ---- 6B. /scripts-to-arb (.s2a-* namespace, theme_br.css §9890-11035).
   A full feature board authored entirely in light hex with zero dark
   rebind. Scope every override to .s2a-board so it can't leak. ---- */

/* Hero text: --title #111638 (1.06) and --subtitle #415276 (2.39)
   are near-black; breadcrumb #53658c (3.2) is muted. */
[data-theme="dark"] .s2a-board .s2a-title { color: var(--text); }
[data-theme="dark"] .s2a-board .s2a-subtitle,
[data-theme="dark"] .s2a-board .s2a-breadcrumb,
[data-theme="dark"] .s2a-board .s2a-meta-row,
[data-theme="dark"] .s2a-board .s2a-empty,
[data-theme="dark"] .s2a-board .s2a-table-foot,
[data-theme="dark"] .s2a-board .s2a-kpi small,
[data-theme="dark"] .s2a-board .s2a-kpi span,
[data-theme="dark"] .s2a-board .s2a-guide-sub { color: var(--text-muted); }
[data-theme="dark"] .s2a-board .s2a-meta-row strong,
[data-theme="dark"] .s2a-board .s2a-guide,
[data-theme="dark"] .s2a-board .s2a-kpi strong,
[data-theme="dark"] .s2a-board .s2a-source--need { color: var(--text); }

/* White / near-white card + control surfaces. */
[data-theme="dark"] .s2a-board .s2a-search,
[data-theme="dark"] .s2a-board .s2a-meta-card,
[data-theme="dark"] .s2a-board .s2a-kpi,
[data-theme="dark"] .s2a-board .s2a-card,
[data-theme="dark"] .s2a-board .s2a-copy-btn,
[data-theme="dark"] .s2a-board .s2a-icon-btn,
[data-theme="dark"] .s2a-board .s2a-tool-btn,
[data-theme="dark"] .s2a-board .s2a-small-btn,
[data-theme="dark"] .s2a-board .s2a-freshness-chip,
[data-theme="dark"] .s2a-board .s2a-popover,
[data-theme="dark"] .s2a-board .s2a-filter-panel,
[data-theme="dark"] .s2a-board .s2a-columns-panel {
  background: var(--surface);
  border-color: var(--border);
  color: var(--text);
}
[data-theme="dark"] .s2a-board .s2a-kpi--present,
[data-theme="dark"] .s2a-board .s2a-kpi--missing {
  background: var(--surface);
  border-color: var(--border);
}
[data-theme="dark"] .s2a-board .s2a-search input { color: var(--text); }

/* Cadence / freshness number inputs are bare `<input type="number">` with
   no class, so they keep the UA white background in dark mode. The runtime
   audit flagged #rebuild_interval_hours_top (the always-visible schedule
   card) as a P1 light surface; #max_keepa_data_age_hours and
   #rebuild_interval_hours share the identical defect but sit inside the
   collapsed `.s2a-popover`, so the crawler couldn't measure them. Bind every
   number input under .s2a-board to the dark surface tokens like the other
   s2a controls. (Table `<th data-sort-type="number">` are not inputs, so the
   sort headers are unaffected.) */
[data-theme="dark"] .s2a-board input[type="number"] {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--text);
}
[data-theme="dark"] .s2a-board input[type="number"]::placeholder {
  color: var(--text-muted);
}

[data-theme="dark"] .s2a-board .s2a-search kbd,
[data-theme="dark"] .s2a-board .s2a-table-foot code,
[data-theme="dark"] .s2a-board .s2a-banner code,
[data-theme="dark"] .s2a-board code {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--text-muted);
}

/* Links: --folder-links a / generic anchors are #1d4ed8 (=2.78). */
[data-theme="dark"] .s2a-board .s2a-folder-links a,
[data-theme="dark"] .s2a-board a { color: #6aa3d8; }

/* Info banner (#f5fbff bg / #27456f text) → brand-soft tint. */
[data-theme="dark"] .s2a-board .s2a-banner,
[data-theme="dark"] .s2a-board .s2a-flash {
  background: var(--brand-soft);
  border-color: var(--border-strong);
  color: var(--text);
}

/* Table: header #fbfcff bg / #53658c text, body text #17203e. */
[data-theme="dark"] .s2a-board .s2a-table th {
  background: var(--surface-2);
  color: var(--text-muted);
  border-color: var(--border);
}
[data-theme="dark"] .s2a-board .s2a-table td {
  color: var(--text);
  border-color: var(--border);
}

/* Sort controls fall back to #0a6cff (=3.16:1 on surface-2, sub-AA) for the
   hovered/focused button and the active sorted-column indicator. (The idle
   indicator #8b98b6 = 4.98:1 already clears AA, so it's left alone.) Rebind the
   two failing states to the established AA-safe s2a accent #6aa3d8 (=5.38:1). */
[data-theme="dark"] .s2a-board .s2a-sort-button:hover,
[data-theme="dark"] .s2a-board .s2a-sort-button:focus-visible,
[data-theme="dark"] .s2a-board .s2a-table th[aria-sort="ascending"] .s2a-sort-indicator,
[data-theme="dark"] .s2a-board .s2a-table th[aria-sort="descending"] .s2a-sort-indicator {
  color: #6aa3d8;
}

/* Pills / status badges — light tints + saturated text. Rebind to the
   dark soft/semantic tokens (each pair clears AA on dark). */
[data-theme="dark"] .s2a-board .s2a-type-pill,
[data-theme="dark"] .s2a-board .s2a-condition,
[data-theme="dark"] .s2a-board .s2a-type-pill--internal,
[data-theme="dark"] .s2a-board .s2a-status--source {
  background: var(--surface-2);
  color: var(--text-muted);
}
[data-theme="dark"] .s2a-board .s2a-type-pill--buy {
  background: var(--info-soft);
  color: #6aa3d8;
}
[data-theme="dark"] .s2a-board .s2a-type-pill--sell,
[data-theme="dark"] .s2a-board .s2a-status--stale {
  background: var(--warn-soft);
  color: var(--warn);
}
[data-theme="dark"] .s2a-board .s2a-status--present {
  background: var(--ok-soft);
  color: var(--ok);
}
[data-theme="dark"] .s2a-board .s2a-status--missing,
[data-theme="dark"] .s2a-board .s2a-status--error {
  background: var(--danger-soft);
  color: #f0796b;
}

/* Guide Health card: head/donut/line/legend/activity blocks (theme_br.css
   §10479-10775) are authored entirely in light hex with no dark rebind —
   near-black headings (#111638 / #17203e), muted #53658c / #415276 body,
   white #fff donut center, and #e5ebf5 / #e4eaf4 / #e7edf6 hairline
   borders + gridlines. Flip every one to a dark token, still scoped to
   .s2a-board. */
[data-theme="dark"] .s2a-board .s2a-card-head,
[data-theme="dark"] .s2a-board .s2a-table-head {
  border-bottom-color: var(--border);
}
[data-theme="dark"] .s2a-board .s2a-card-head h2,
[data-theme="dark"] .s2a-board .s2a-table-head h2,
[data-theme="dark"] .s2a-board .s2a-donut-wrap h3,
[data-theme="dark"] .s2a-board .s2a-line-wrap h3,
[data-theme="dark"] .s2a-board .s2a-donut strong,
[data-theme="dark"] .s2a-board .s2a-activity-row strong,
[data-theme="dark"] .s2a-board .s2a-legend dd {
  color: var(--text);
}
[data-theme="dark"] .s2a-board .s2a-card-head p,
[data-theme="dark"] .s2a-board .s2a-table-head p,
[data-theme="dark"] .s2a-board .s2a-donut-wrap p,
[data-theme="dark"] .s2a-board .s2a-donut span,
[data-theme="dark"] .s2a-board .s2a-legend dt,
[data-theme="dark"] .s2a-board .s2a-mini-legend,
[data-theme="dark"] .s2a-board .s2a-chart-axis,
[data-theme="dark"] .s2a-board .s2a-chart-labels,
[data-theme="dark"] .s2a-board .s2a-line-empty,
[data-theme="dark"] .s2a-board .s2a-activity-row span,
[data-theme="dark"] .s2a-board .s2a-activity-row time {
  color: var(--text-muted);
}
[data-theme="dark"] .s2a-board .s2a-card-head a {
  color: #6aa3d8;
}
[data-theme="dark"] .s2a-board .s2a-donut-wrap {
  border-right-color: var(--border);
}
[data-theme="dark"] .s2a-board .s2a-donut div {
  background: var(--surface);
}
[data-theme="dark"] .s2a-board .s2a-line-chart {
  border-left-color: var(--border);
  background:
    linear-gradient(var(--border) 1px, transparent 1px) 0 20% / 100% 40px,
    linear-gradient(var(--border) 1px, transparent 1px) 0 60% / 100% 40px;
}

/* ---- 6C. /bids (.bids-* namespace + table, styles.css §7762-8085).
   Toolbar, filters, table and pagination all hardcode light hex.
   styles.css §12945-13014 declares the WHOLE bids surface/text/border
   set with `!important`, so a non-important dark override never wins no
   matter how specific. Every flip below must therefore also be
   `!important` to beat the light `!important` block. ---- */
[data-theme="dark"] .bids-toolbar {
  background: var(--surface-2) !important;
  border-bottom-color: var(--border) !important;
}
[data-theme="dark"] .bids-toolbar label { color: var(--text-muted) !important; }
[data-theme="dark"] .bids-toolbar input[type="text"],
[data-theme="dark"] .bids-toolbar input[type="search"],
[data-theme="dark"] .bids-toolbar input[type="number"],
[data-theme="dark"] .bids-toolbar select {
  background: var(--surface) !important;
  border-color: var(--border-strong) !important;
  color: var(--text) !important;
}
[data-theme="dark"] .bids-summary { border-color: var(--border); }
[data-theme="dark"] .bids-results-meta,
[data-theme="dark"] #bids-count-label { color: var(--text-muted) !important; }

[data-theme="dark"] .bids-table thead th {
  background: var(--surface-2) !important;
  color: var(--text) !important;
  border-bottom-color: var(--border-strong) !important;
}
[data-theme="dark"] .bids-table thead th:hover { background: var(--surface-hover) !important; }
[data-theme="dark"] .bids-table tbody td { border-bottom-color: var(--border); }
[data-theme="dark"] .bids-table tbody tr:nth-child(odd) { background: var(--surface-2) !important; }
[data-theme="dark"] .bids-table tbody tr:hover { background: var(--surface-hover) !important; }
[data-theme="dark"] .bids-table .col-short-warn { color: var(--warn); }
[data-theme="dark"] .bids-table .col-short-crit { color: #f0796b; }
/* styles.css ships .col-bid-key-num as #6b7280, which is ~3.1:1 over the dark
   row surfaces (AA fail). Lift to --text-muted (= 5.79:1 on --surface-2). */
[data-theme="dark"] .bids-table .col-bid-key-num { color: var(--text-muted); }

[data-theme="dark"] .bids-pagination button {
  background: var(--surface);
  border-color: var(--border-strong);
  color: var(--text);
}
[data-theme="dark"] .bids-pagination button:hover:not(:disabled) {
  background: var(--surface-hover);
  border-color: var(--accent);
}

/* `.ops-alert-summary-card` (styles.css §3469) + its state tints.
   The card surface and the three state fills are all light hex; the
   .tooltip-label inside inherits a muted color that only fails because
   the card behind it is light — flipping the surface restores it. */
[data-theme="dark"] .ops-alert-summary-card {
  background: var(--surface-2);
  border-color: var(--border);
}
[data-theme="dark"] .ops-alert-summary-card.state-danger {
  background: var(--danger-soft);
  border-color: var(--danger);
}
[data-theme="dark"] .ops-alert-summary-card.state-warn {
  background: var(--warn-soft);
  border-color: var(--warn);
}
[data-theme="dark"] .ops-alert-summary-card.state-ok {
  background: var(--ok-soft);
  border-color: var(--ok);
}

/* ---- 6D. /diagnostics — chart card + muted note hardcode near-white
   (rgba(255,255,255,.94) / rgba(248,250,252,.9)). Flip the surfaces;
   the eyebrow/subtitle text already use light tokens. ---- */
[data-theme="dark"] .diagnostics-chart-card {
  background: var(--surface);
  border-color: var(--border);
}
[data-theme="dark"] .diagnostics-chart-card p.muted {
  background: var(--surface-2);
  color: var(--text-muted);
}

/* ---- 6E. Cross-cutting `.btn--danger` (theme_br.css §653). The button
   fill is var(--danger) #e85c4d with #fff text = ~3.3 contrast in dark
   (AA fail for the button label). Darken the fill to #c0392b (=5.44 vs
   white) only in dark; light theme keeps the brighter brand red. Shared
   widget — appears on /contacts (delete) and other destructive actions. */
[data-theme="dark"] .btn--danger {
  background: #c0392b;
  border-color: #c0392b;
}
[data-theme="dark"] .btn--danger:hover {
  background: color-mix(in srgb, #c0392b 86%, #000);
}

/* ---- 6E-bis. Cross-cutting `.btn--archive` (theme_br.css §659). Authored
   light-only: background #fff1f2 (rgb 255,241,242) + #991b1b text. In dark the
   pink fill stays a near-white slab (light-surface fail) on the dashboard
   Scripts tab Archive button and anywhere else archive actions appear. Recolor
   to a soft dark-red tint with a light-red label; archive is a softer
   destructive action than delete so it stays lighter than `.btn--danger`. */
[data-theme="dark"] .btn--archive {
  background: var(--danger-soft);
  color: #f3b4ab;
  border-color: color-mix(in srgb, var(--danger) 40%, var(--border));
}
[data-theme="dark"] .btn--archive:hover {
  background: color-mix(in srgb, var(--danger) 22%, var(--surface-2));
  border-color: color-mix(in srgb, var(--danger) 55%, var(--border));
}

/* ---- Wave 10. Diagnostics v2 → Health (`.dv2h-*`, inline <style> in
   templates/diagnostics_v2/health.html L16). The component reads design
   tokens with LIGHT hex fallbacks that don't exist in dark:
     .dv2h-cell            background: var(--surface-1, #fff)        -> white slab
     .dv2h-banner--degraded var(--color-danger-bg/-fg/-border)      -> light pink
     .dv2h-topbar/.dv2h-row var(--border-subtle, #e3e6ea)           -> light border
     .dv2h-rowstate[...]    hardcoded light pill fills (#eceef1 …)   -> light pills
   Result in dark: cells are white (P0 1.21 contrast on .dv2h-cell-label /
   .dv2h-cell-state), degraded banner + state pills stay light. Repaint
   surfaces/borders to dark tokens and re-tint the state pills; the colored
   state bars (border-left-color) already read fine on dark and are left
   alone. All selectors are [data-theme="dark"]-scoped so they beat the
   inline component rules on specificity regardless of source order. */
[data-theme="dark"] .dv2h-cell {
  background: var(--surface-2);
  /* Leave border-left-color alone — every cell carries data-state and the
     [data-state] rules paint the 4px state bar on the left edge. */
  border-top-color: var(--border);
  border-right-color: var(--border);
  border-bottom-color: var(--border);
}
[data-theme="dark"] .dv2h-topbar,
[data-theme="dark"] .dv2h-row {
  border-color: var(--border);
}
[data-theme="dark"] .dv2h-banner--degraded {
  background: var(--danger-soft);
  color: #f3b4ab;
  border-color: color-mix(in srgb, var(--danger) 45%, var(--border));
}
[data-theme="dark"] .dv2h-rowstate[data-state="ok"]       { background: color-mix(in srgb, #2e9e5b 22%, var(--surface-2)); color: #7ed3a0; }
[data-theme="dark"] .dv2h-rowstate[data-state="watch"]    { background: color-mix(in srgb, #d8a012 22%, var(--surface-2)); color: #e8c45e; }
[data-theme="dark"] .dv2h-rowstate[data-state="critical"] { background: color-mix(in srgb, #c0392b 24%, var(--surface-2)); color: #f0a097; }
[data-theme="dark"] .dv2h-rowstate[data-state="stale"]    { background: color-mix(in srgb, #8e44ad 24%, var(--surface-2)); color: #c79be0; }
[data-theme="dark"] .dv2h-rowstate[data-state="partial"]  { background: color-mix(in srgb, #2f6fb0 24%, var(--surface-2)); color: #8fbce8; }
[data-theme="dark"] .dv2h-rowstate[data-state="unknown"]  { background: color-mix(in srgb, #8a909a 22%, var(--surface-2)); color: #c2c8d2; }

/* ---- Wave 7. Standalone AutoBuy (`.sab-*`, styles.css §26336+). The whole
   namespace was authored light-only (PRs #915/#928/#929 post-dated the dark
   pass): white cards, #1d2433/#111827 headings, #667085 body, light pastel
   pill/notice surfaces. In dark every card became a white slab and the
   "Standalone AutoBuy" h1 dropped to 1.2:1. None of the light rules use
   !important, so these scoped overrides win on specificity alone. */

/* Surfaces: white cards/wraps -> --surface, borders -> --border. */
[data-theme="dark"] .sab-toolbar,
[data-theme="dark"] .sab-account,
[data-theme="dark"] .sab-accounts,
[data-theme="dark"] .sab-runs,
[data-theme="dark"] .sab-orders,
[data-theme="dark"] .sab-detail,
[data-theme="dark"] .sab-table-wrap,
[data-theme="dark"] .sab-detail-summary > div,
[data-theme="dark"] .sab-info-panel {
  background: var(--surface);
  border-color: var(--border);
}
[data-theme="dark"] .sab-summary-grid > div,
[data-theme="dark"] .sab-account-grid span {
  border-color: var(--border);
}

/* Headings + body text. */
[data-theme="dark"] .sab-header h1,
[data-theme="dark"] .sab-section-head h2,
[data-theme="dark"] .sab-account-grid strong,
[data-theme="dark"] .sab-summary-grid strong,
[data-theme="dark"] .sab-event strong,
[data-theme="dark"] .sab-orders-bar h2,
[data-theme="dark"] .sab-detail-top h2,
[data-theme="dark"] .sab-panel-head h3,
[data-theme="dark"] .sab-table th,
[data-theme="dark"] .sab-table a,
[data-theme="dark"] .sab-detail-summary strong,
[data-theme="dark"] .sab-item-row strong,
[data-theme="dark"] .sab-info-list dd,
[data-theme="dark"] .sab-advanced summary,
[data-theme="dark"] .sab-address summary {
  color: var(--text);
}
[data-theme="dark"] .sab-header p,
[data-theme="dark"] .sab-account p,
[data-theme="dark"] .sab-section-note,
[data-theme="dark"] .sab-detail-top p,
[data-theme="dark"] .sab-orders-actions span,
[data-theme="dark"] .sab-empty,
[data-theme="dark"] .sab-pagination,
[data-theme="dark"] .sab-run-counts,
[data-theme="dark"] .sab-order-asin a,
[data-theme="dark"] .sab-account-grid span,
[data-theme="dark"] .sab-form label,
[data-theme="dark"] .sab-tabs a,
[data-theme="dark"] .sab-detail-summary span,
[data-theme="dark"] .sab-item-row span,
[data-theme="dark"] .sab-info-list dt,
[data-theme="dark"] .sab-panel-head span,
[data-theme="dark"] .sab-summary-grid span,
[data-theme="dark"] .sab-section-head span,
[data-theme="dark"] .sab-muted,
[data-theme="dark"] .sab-event span,
[data-theme="dark"] .sab-event p {
  color: var(--text-muted);
}

/* Tabs. */
[data-theme="dark"] .sab-tabs {
  border-bottom-color: var(--border);
}
[data-theme="dark"] .sab-tabs a.is-active {
  background: var(--surface);
  border-color: var(--border);
  color: var(--text);
}

/* Buttons + form controls. */
[data-theme="dark"] .sab-secondary {
  background: var(--surface);
  border-color: var(--border);
  color: var(--text);
}
[data-theme="dark"] .sab-form input,
[data-theme="dark"] .sab-form select,
[data-theme="dark"] .sab-order-search,
[data-theme="dark"] .sab-orders-actions select {
  background: var(--surface-2);
  border-color: var(--border);
  color: var(--text);
}
[data-theme="dark"] .sab-page-link {
  border-color: var(--border);
  color: var(--text);
}

/* Tables. */
[data-theme="dark"] .sab-table th,
[data-theme="dark"] .sab-table td {
  border-top-color: var(--border);
}
[data-theme="dark"] .sab-table tr.is-selected {
  background: var(--surface-hover);
}

/* Notice + error banners (light pastel -> dark soft tokens). */
[data-theme="dark"] .sab-notice {
  background: var(--warn-soft);
  border-left-color: var(--warn);
  color: var(--warn);
}
[data-theme="dark"] .sab-error {
  /* var(--danger) #e85c4d on var(--danger-soft) #3a1f1a = 4.36:1 (AA fail for
     body text). Lift text to the same #f0796b (= 5.50:1) used for danger text
     elsewhere; keep the saturated --danger on the accent stripe (3:1 is fine). */
  background: var(--danger-soft);
  border-left-color: var(--danger);
  color: #f0796b;
}

/* Event log items. */
[data-theme="dark"] .sab-event {
  background: var(--surface-2);
  border-left-color: var(--border-strong);
}
[data-theme="dark"] .sab-event--ok {
  border-left-color: var(--ok);
}
[data-theme="dark"] .sab-event--warning {
  border-left-color: var(--warn);
}

/* Status pills: light pastels -> dark soft surfaces + lightened text. */
[data-theme="dark"] .sab-status,
[data-theme="dark"] .sab-status--muted {
  background: var(--surface-2);
  color: var(--text-muted);
}
[data-theme="dark"] .sab-status--placed,
[data-theme="dark"] .sab-status--ready {
  background: var(--ok-soft);
  color: var(--ok);
}
[data-theme="dark"] .sab-status--warning {
  background: var(--warn-soft);
  color: var(--warn);
}
[data-theme="dark"] .sab-status--failed {
  /* var(--danger) on --danger-soft = 4.36:1 (AA fail); lift to #f0796b = 5.50:1. */
  background: var(--danger-soft);
  color: #f0796b;
}
[data-theme="dark"] .sab-status--running {
  /* --accent (#4f8cc9) on --accent-soft = ~4.1:1 (AA fail for pill text).
     Lighter sky-blue clears 4.5 (~5.4:1) while keeping the blue read. */
  background: var(--accent-soft);
  color: #6aa3d8;
}

/* ============================================================
   Dark-mode wave 9 (2026-05-31) — seeded detail pages
   ------------------------------------------------------------
   Runtime audit of the 8 detail routes (/scripts/<id>,
   /contacts/<id>, /tickets/<id>, /auto-buy/<id>,
   /auto-buy/pipeline/<id>, /standalone-auto-buy/orders/<id>)
   surfaced 45 findings (9 P0 / 36 P1) clustered into areas A-D;
   area E (status chips) was added after adversarial review caught
   unseeded chip variants rendering light-on-light in dark mode.
   All overrides are CSS-token-only, scoped to [data-theme="dark"];
   no business logic touched. Source values cited inline so a
   future reader can diff against styles.css.
   ============================================================ */

/* ---- A. Shared rich-text editor (contacts + tickets) ----
   styles.css L530-575 hard-codes a white editor (#fff) with a
   #f8fbff toolbar. In dark mode the white surface + light body
   text collapse to ~1.2:1 (ticket P0: editor body text). Re-point
   the whole widget at dark Tiger surfaces. */
[data-theme="dark"] .rich-text {
  background: var(--surface);
  border-color: var(--border);
}
[data-theme="dark"] .rich-text-toolbar {
  background: var(--surface-2);
  border-bottom-color: var(--border);
}
[data-theme="dark"] .rich-text-toolbar button,
[data-theme="dark"] .rich-text-toolbar select {
  background: var(--surface);
  border-color: var(--border-strong);
  color: var(--text);
}
[data-theme="dark"] .rich-text-toolbar button:hover {
  background: var(--surface-hover);
}
[data-theme="dark"] .rich-text-editor {
  color: var(--text);
}

/* ---- B. Script detail (/scripts/<id>) `.sx-*` ----
   styles.css L21296 defines the whole sx-* design system as LIGHT
   custom properties on `.sx-shell` with no dark override, so every
   surface/text on the page rendered light (h1 title 1.04:1 P0,
   upload banner 1.7/2.13 P0, breadcrumb 2.46 P0, stat labels P1…).
   Remap only the STRUCTURAL tokens to dark Tiger tokens; the
   saturated accent tokens (--sx-brand/-accent/-danger/-warn/-upload)
   stay as-is because they back buttons/badges that carry white text
   (sx-btn-download, sx-count). --sx-brand-2 is text/stripe-only, so
   it lifts to the same #6aa3d8 link blue used elsewhere. */
[data-theme="dark"] .sx-shell {
  --sx-bg: var(--bg);
  --sx-surface: var(--surface);
  --sx-surface-2: var(--surface-2);
  --sx-border: var(--border);
  --sx-border-strong: var(--border-strong);
  --sx-text: var(--text);
  --sx-text-2: var(--text-muted);
  --sx-muted: var(--text-muted);
  --sx-brand-2: #6aa3d8;
  --sx-shadow-sm: none;
  --sx-shadow-md: none;
  /* "Soft" tint tokens (L21308-21314) are light pastel fills meant to sit
     behind dark text. Only --sx-accent-soft is actually rendered today
     (.sx-schedule-icon, .sx-version-tag--current), but remap all four so a
     future template that uses one as a dark-mode surface stays legible. */
  --sx-accent-soft: var(--ok-soft);
  --sx-danger-soft: var(--danger-soft);
  --sx-warn-soft: var(--warn-soft);
  --sx-upload-soft: var(--accent-soft);
}
/* Hard-coded light surfaces the token remap can't reach. */
[data-theme="dark"] .sx-page-head {
  /* L21340 white gradient -> flat dark surface. */
  background: var(--surface);
}
[data-theme="dark"] .sx-description--truncated::after {
  /* L21369 fade-to-#fff overlay -> fade to the new dark head surface. */
  background: linear-gradient(to bottom, transparent, var(--surface));
}
[data-theme="dark"] .sx-eyebrow {
  /* L21351 #e0e7ff chip + --sx-brand (navy) text -> dark accent chip. */
  background: var(--accent-soft);
  color: #9db8e8;
}
[data-theme="dark"] .sx-btn-ghost,
[data-theme="dark"] .sx-btn-icon {
  /* L21400/L21406 hard #fff button faces. */
  background: var(--surface);
}
[data-theme="dark"] .sx-output-run {
  /* L21718 --sx-brand (navy) run-id text on a dark surface-2 head. */
  color: var(--sx-brand-2);
}
[data-theme="dark"] .sx-stat-muted::before {
  /* L21437 #cbd5e1 stat stripe. */
  background: var(--border-strong);
}
[data-theme="dark"] .sx-card--collapsible [data-sx-toggle]:hover {
  /* L21598 #f1f5f9 hover. */
  background: var(--surface-hover);
}
[data-theme="dark"] .sx-upload-file {
  /* L21507 #fff file input + #c4b5fd border. */
  background: var(--surface-2);
  border-color: var(--border-strong);
}
/* Native file inputs in the script shell. .sx-upload-file (script_detail.html
   L133) gets a dark box above, but the bare Input-Files picker (L169,
   data-upload-files, NO class) had no dark styling at all, and — more subtly —
   NEITHER input's UA ``::file-selector-button`` is reachable by a class rule:
   the browser-native "Choose Files" button stays light in dark mode. The
   runtime contrast detector can't introspect that pseudo-element, so the crawl
   read clean while the button was plainly white (Codex bg06vnm2q). Theme the
   bare box (scoped to .sx-shell so it can't leak to file inputs elsewhere) and
   both native buttons. Box treatment mirrors .sx-upload-file; no light-mode
   change since these rules are dark-only. */
[data-theme="dark"] .sx-shell input[type="file"] {
  background: var(--surface-2);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  color: var(--text);
}
[data-theme="dark"] .sx-shell input[type="file"]::file-selector-button {
  background: var(--surface-hover);
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  color: var(--text);
}
[data-theme="dark"] .sx-upload-banner {
  /* L21463 light-purple gradient + #a78bfa dashed border. Keep a
     faint purple identity but on a dark base. */
  background: #1d1b2e;
  border-color: #4b3a6b;
  box-shadow: none;
}
[data-theme="dark"] .sx-upload-title {
  /* L21490 #4c1d95 on light -> light lavender on dark banner. */
  color: #cdbdf7;
}
[data-theme="dark"] .sx-upload-sub {
  /* L21494 #6b21a8 -> lifted lavender. */
  color: #b9a9d9;
}
[data-theme="dark"] .sx-upload-sub code {
  /* L21497 rgba(255,255,255,.6) chip -> translucent dark chip. */
  background: rgba(127, 144, 180, 0.18);
  color: #cdbdf7;
}
/* Bare <input> faces default to browser white in dark mode. Both live
   inside `.sx-shell`; flip to dark form surfaces (sr-input-sm is also
   used on buyback tables, so scope that one to the script shell). */
[data-theme="dark"] .sx-part-size-input,
[data-theme="dark"] .sx-shell .sr-input-sm {
  background: var(--surface-2);
  border-color: var(--border-strong);
  color: var(--text);
}
/* Populated-state sx-* surfaces only rendered once a script has a version /
   active schedule (empty DB never reached these, so the first audit missed
   them — Codex finding). */
[data-theme="dark"] .sx-version-tag {
  /* L21849 hard #f1f5f9 chip (light-on-light vs --sx-text). */
  background: var(--surface-2);
}
[data-theme="dark"] .sx-version-tag--current {
  /* L21852 --sx-accent-soft chip + #166534 text -> dark green chip + light
     green text (the soft-token remap already shifts the fill; pin both so
     the pairing can't drift). */
  background: var(--ok-soft);
  color: var(--ok);
}
[data-theme="dark"] .sx-btn-run {
  /* L21402 --sx-accent (#16a34a) under #fff text is 3.30:1. Darken to the
     same green styles.css already uses for :hover (#15803d -> 5.0:1 AA). */
  background: #15803d;
}
[data-theme="dark"] .sx-btn-run:hover {
  background: #166534;
}
[data-theme="dark"] .sx-count--ok {
  /* L21626 --sx-accent badge under #fff text, same 3.30:1 fail. */
  background: #15803d;
}
[data-theme="dark"] .sx-schedule-icon {
  /* L21742 --sx-accent text on --sx-accent-soft fill. The fill now remaps to
     ok-soft; lift the glyph to --ok so it clears on the darker green. */
  color: var(--ok);
}
[data-theme="dark"] .schedule-row.is-active {
  /* L21892 #eef4ff fill + #c7d6f5 border (JS-toggled selected schedule row). */
  background: var(--surface-2);
  border-color: var(--border);
}
/* The rule above (0,3,0) is beaten in the scheduler card by the light
   `.sx-card .sx-scheduler-form .schedule-row.is-active` (0,4,0, styles.css
   L21892), so in dark mode the *expanded* active row stayed #eef4ff. The
   crawler now force-expands the collapsed Scheduler card (Codex by5def07p),
   which exposed the still-light fill. Match the light selector + add the
   theme prefix (0,5,0) so the dark fill actually wins. The #eef4ff fill also
   sank the .schedule-label text (var(--sx-muted) ~2.25:1); on --surface-2 it
   recovers to ~5.8:1, so no separate label rule is needed. */
[data-theme="dark"] .sx-card .sx-scheduler-form .schedule-row.is-active {
  background: var(--surface-2);
  border-color: var(--border);
}
/* Script-detail form controls (.sd-*) declare no/white backgrounds
   (styles.css L15264-15267: .sd-input/.sd-textarea inherit the UA field
   white; .sd-select hard-codes background:#fff). In dark mode the bare
   field stayed white. These are 0,1,0 light rules, so a 0,2,0 theme-scoped
   override wins. Surfaces/border/text only — no sizing or layout. */
[data-theme="dark"] .sd-input,
[data-theme="dark"] .sd-select,
[data-theme="dark"] .sd-textarea {
  background: var(--surface-2);
  border-color: var(--border-strong);
  color: var(--text);
}

/* ---- C. Auto Buy detail (/auto-buy/<id>) `.ab-*` ----
   SENSITIVE AREA — surfaces/text only, no layout/logic changes.
   styles.css hard-codes a white "Run Health" card, white live-log
   panel, light meta strip and dim labels. Bare <span>/<strong> text
   (e.g. "$6.00", "Live Log") fell to ~1.14:1 because the light
   surface stayed put while body text went light; flipping the
   surfaces restores contrast. */
[data-theme="dark"] .ab-meta-grid {
  background: var(--surface-2);            /* L10248 #f8f9fb */
}
[data-theme="dark"] .ab-meta-label,
[data-theme="dark"] .ab-page-subtitle,
[data-theme="dark"] .abd-summary-meta {
  color: var(--text-muted);                /* L10259 #888 / L7632 #6b7280 / L14228 #6b7280 */
}
[data-theme="dark"] .ab-rule-on {
  background: var(--ok-soft);               /* L10297 #d4edda/#155724 */
  color: var(--ok);
}
[data-theme="dark"] .ab-rule-off {
  background: var(--surface-2);             /* L10302 #f0f0f0/#999 (2.5:1) */
  color: var(--text-muted);
}
[data-theme="dark"] .ab-guide-card {
  background: var(--surface);               /* L10597 #f0f9ff + #bfdbfe border */
  border-color: var(--border);
}
[data-theme="dark"] .ab-guide-card-title {
  color: #9db8e8;                           /* L10607 #1e40af */
}
[data-theme="dark"] .ab-guide-card-body,
[data-theme="dark"] .ab-run-health-headline,
[data-theme="dark"] .ab-run-health-metric-value {
  color: var(--text);                       /* L10616/#334155, L10634/#0f172a, L10685/#0f172a */
}
[data-theme="dark"] .ab-run-health-detail,
[data-theme="dark"] .ab-run-health-metric-label,
[data-theme="dark"] .ab-run-health-footnote {
  color: var(--text-muted);                 /* L10639/#475569, L10678/#64748b, L10695/#334155 */
}
[data-theme="dark"] .ab-run-health-percent {
  background: var(--accent-soft);           /* L10649 #dbeafe/#1d4ed8 */
  color: #6aa3d8;
}
[data-theme="dark"] .ab-run-health-metric {
  background: var(--surface-2);             /* L10666 #f8fbff + #dbeafe border */
  border-color: var(--border);
}
[data-theme="dark"] .ab-new-run-panel {
  background: var(--surface);               /* L7255 #fff + #e5e7eb border */
  border-color: var(--border);
}
[data-theme="dark"] .ab-new-run-panel summary {
  background: var(--surface-2);             /* L7269 #f8f9fb + #e5e7eb border */
  border-bottom-color: var(--border);
}
/* "Back to Auto Buy" outline button (a.vbc-btn--outline, 1.59:1 P0).
   styles.css L5284 sets #0b3d91 text + #c7d6f5 border, used app-wide
   on vendor/FTP pages too — so SCOPE to the auto-buy page header only
   to avoid touching untested vbc surfaces. */
[data-theme="dark"] .ab-page-header .vbc-btn--outline {
  border-color: var(--border-strong);
  color: #9db8e8;
}
[data-theme="dark"] .ab-page-header .vbc-btn--outline:hover {
  background: var(--surface-hover);         /* L5291 #e7eefc */
}
/* Same #0b3d91 outline button appears in the queue toolbar ("Clear") and the
   queue pager ("Prev"/"Next"). Those only render with active filters / >50
   visible items, so the empty-state audit never exercised them (Codex
   finding). Scope to the auto-buy queue containers, mirroring the header fix
   above to keep untested vbc surfaces untouched. */
[data-theme="dark"] .ab-queue-filter-actions .vbc-btn--outline,
[data-theme="dark"] .ab-queue-pagination .vbc-btn--outline {
  border-color: var(--border-strong);
  color: #9db8e8;
}
[data-theme="dark"] .ab-queue-filter-actions .vbc-btn--outline:hover,
[data-theme="dark"] .ab-queue-pagination .vbc-btn--outline:hover {
  background: var(--surface-hover);
}
/* The run-items queue (a shared .vbc-card/.vbc-table component) only renders
   once a run has >=1 visible item, so the empty-state audit never reached it;
   seeding 51 items exposed the whole table as a light island in dark mode
   (card #fff, header #f8f9fb, white rows -> body text 1.21:1). The vbc-* table
   is also used on vendor & FTP pages, so EVERY override is scoped to the
   auto-buy queue card (.ab-queue-card) — no global vbc surface is touched. */
[data-theme="dark"] .ab-queue-card {
  background: var(--surface);              /* .vbc-card L4969 #fff */
  border-color: var(--border);            /* L4970 #e5e7eb */
  box-shadow: none;
}
[data-theme="dark"] .ab-queue-card .vbc-card-header {
  background: var(--surface-2);            /* L4982 #f8f9fb */
  border-bottom-color: var(--border);     /* L4983 #e5e7eb */
}
[data-theme="dark"] .ab-queue-card .vbc-subtitle,
[data-theme="dark"] .ab-queue-card .vbc-table-footer-text {
  color: var(--text-muted);               /* L4964 #6b7280 / L7217 #5c6780 */
}
[data-theme="dark"] .ab-queue-visible-count {
  background: var(--surface-2);            /* L10422 #f8fafc */
  border-color: var(--border-strong);     /* L10423 #e2e8f0 */
  color: var(--text-muted);               /* L10424 #475569 */
}
[data-theme="dark"] .ab-queue-card .vbc-table th {
  background: var(--surface-2);            /* L5444 #f8f9fb */
  border-bottom-color: var(--border);     /* L5445 #e5e7eb */
  color: var(--text-muted);               /* L5447 #6b7280 */
}
[data-theme="dark"] .ab-queue-card .vbc-table td,
[data-theme="dark"] .ab-queue-card .ab-items-table th,
[data-theme="dark"] .ab-queue-card .ab-items-table td {
  border-bottom-color: var(--border);     /* L5456 #f0f1f3 / L10503 #e5e7eb */
}
[data-theme="dark"] .ab-queue-card .vbc-table tbody tr:hover {
  background: var(--surface-hover);        /* L5476 #fafbfd */
}
[data-theme="dark"] .ab-queue-card .ab-decision-detail {
  color: var(--text-muted);                /* L10576 #667085 */
}
/* Profit column: #1a7a3a green is 2.95:1 on the dark row; #b42318 red pairs
   with it. Lift both to the dark Tiger status tokens (--ok 6.3:1, --danger
   4.6:1). Scoped to the queue card so the same classes elsewhere are untouched. */
[data-theme="dark"] .ab-queue-card .ab-profit-pos {
  color: var(--ok);                        /* L10011 #1a7a3a */
}
[data-theme="dark"] .ab-queue-card .ab-profit-neg {
  color: var(--danger);                    /* L10016 #b42318 */
}
/* Sort-link + ASIN-link hover land on #0b3d91 (navy, invisible on dark);
   lift to the page's link blue. Hover-only, so not screenshot-audited. */
[data-theme="dark"] .ab-queue-card .ab-queue-table th a:hover,
[data-theme="dark"] .ab-queue-card .ab-cell-mono a:hover {
  color: #9db8e8;
}
/* Generating-state queue: the .vbc-stat summary grid + the .ab-queue-note only
   render when run.status is generating/queued_generation/generation_failed, so
   the DRAFT fixture never showed them. Both are hard light islands in dark mode
   (vbc-stat #f7f9fc bg + #123a7a navy value text -> ~invisible; ab-queue-note
   #fff8e8 amber bg). /auto-buy/2 (GENERATING) now audits this branch. */
[data-theme="dark"] .ab-queue-card .vbc-stat {
  background: var(--surface-2);            /* styles.css L7092 #f7f9fc */
  border-color: var(--border);            /* L7090 #d8deea */
}
[data-theme="dark"] .ab-queue-card .vbc-stat-label {
  color: var(--text-muted);               /* L7100 #66758f */
}
[data-theme="dark"] .ab-queue-card .vbc-stat-value {
  color: var(--text);                     /* L7110 #123a7a navy on dark */
}
[data-theme="dark"] .ab-queue-card .ab-queue-note {
  background: var(--warn-soft);           /* L10456 #fff8e8 */
  border-color: var(--warn);              /* L10457 #f4d9a5 */
  color: var(--text);                     /* L10458 #8a5b00; neutral reads easier than saturated amber for a full sentence */
}
/* Review-ready queue: the per-row select checkbox and the .ab-qty-input number
   input only render when run.status == review_ready. Both are bare UA form
   controls (no bg/color set) that render white in dark mode. color-scheme:dark
   makes the spinner/checkbox glyphs use the dark palette. /auto-buy/3 audits this. */
[data-theme="dark"] .ab-queue-card .ab-qty-input {
  background: var(--surface-2);           /* styles.css L10028: no bg -> white */
  border-color: var(--border-strong);     /* L7439 #ccc */
  color: var(--text);
  color-scheme: dark;
}
[data-theme="dark"] .ab-queue-card .ab-col-select input[type="checkbox"] {
  accent-color: var(--accent);
  color-scheme: dark;
}

/* ---- D. Dim links + one stray table header ----
   Standalone order detail: .sab-back-link (L26731 #2563eb, 3.08:1)
   and the Order-Items product URL (.sab-item-row a, L26815 #2563eb,
   3.08:1) -> the same #6aa3d8 link blue used across the sab-* set.
   Pipeline detail: generic `.table th` is --text-subtle (3.94:1);
   matches the established per-page scoping pattern (theme_br L11784)
   via the `.auto-buy-pipeline-shell` wrapper added to the template. */
[data-theme="dark"] .sab-back-link,
[data-theme="dark"] .sab-item-row a {
  color: #6aa3d8;
}
/* (.auto-buy-pipeline-shell .table th retired Wave 10 — now covered by the
   global [data-theme="dark"] .table th rule at §Cross-cutting #2.) */

/* ---- E. Status chips (run-level + per-row decision) ----
   Both chip families are defined only as LIGHT pastel fills in styles.css with
   no dark rebind, so every status variant rendered as a light island in dark
   mode and several pair sub-AA on their own fill (.ab-status-cancelled
   #666/#e0e0e0 4.35:1, .ab-item-status-excluded_by_user #888/#e0e0e0 2.69:1).
   The earlier fixtures only ever produced draft/generating/review_ready run
   chips and pending_review/approved row chips, so the cancelled run chip and
   excluded_by_user row chip were never screenshot-audited (Codex finding).
   /auto-buy/4 (CANCELLED, carrying one excluded_by_user row) now exercises
   both. Remap each semantic family to the dark Tiger soft tokens. Run chips are
   scoped to .purchase-panel-wide (the auto-buy detail/index shell); row chips to
   .ab-queue-card, mirroring the queue-table scoping above so the same classes on
   untested pages stay untouched. Source line refs are to styles.css. */

/* Run-level status chip (.ab-meta-grid > .ab-status, L10035-10116). */
[data-theme="dark"] .purchase-panel-wide .ab-status-draft,
[data-theme="dark"] .purchase-panel-wide .ab-status-cancelled {
  background: var(--surface-2);             /* L10046/L10114 #e0e0e0 */
  color: var(--text-muted);                 /* L10047 #555 / L10115 #666 (4.35:1) */
}
[data-theme="dark"] .purchase-panel-wide .ab-status-generating,
[data-theme="dark"] .purchase-panel-wide .ab-status-executing,
[data-theme="dark"] .purchase-panel-wide .ab-status-queued_generation,
[data-theme="dark"] .purchase-panel-wide .ab-status-running,
[data-theme="dark"] .purchase-panel-wide .ab-status-paused,
[data-theme="dark"] .purchase-panel-wide .ab-status-completed_with_exceptions,
[data-theme="dark"] .purchase-panel-wide .ab-status-checkout_uncertain {
  background: var(--warn-soft);             /* L10052/L10072/L10082/L10092/L10104 amber fills */
  color: var(--warn);
}
[data-theme="dark"] .purchase-panel-wide .ab-status-review_ready,
[data-theme="dark"] .purchase-panel-wide .ab-status-completed {
  background: var(--ok-soft);               /* L10057 #d4edda / L10087 #b8e6c8 */
  color: var(--ok);
}
[data-theme="dark"] .purchase-panel-wide .ab-status-approved,
[data-theme="dark"] .purchase-panel-wide .ab-status-queued,
[data-theme="dark"] .purchase-panel-wide .ab-status-queued_execution {
  background: var(--accent-soft);           /* L10062 #cce5ff / L10067/L10077 #e2d8f0 */
  color: #9db8e8;
}
[data-theme="dark"] .purchase-panel-wide .ab-status-generation_failed,
[data-theme="dark"] .purchase-panel-wide .ab-status-execution_failed,
[data-theme="dark"] .purchase-panel-wide .ab-status-failed {
  background: var(--danger-soft);           /* L10098/L10109 #f8d7da */
  /* --danger (#e85c4d) on --danger-soft is only 4.36:1 — sub-AA for the
     'Generation Failed' chip (runtime_contrast flagged /auto-buy/5). This
     brighter red clears AA (~4.95:1) while staying clearly in the danger hue. */
  color: #ee6b58;
}

/* Per-row decision chip (.ab-queue-card .ab-item-status, L10215-10240). */
[data-theme="dark"] .ab-queue-card .ab-item-status-pending_review,
[data-theme="dark"] .ab-queue-card .ab-item-status-excluded_by_user {
  background: var(--surface-2);             /* L10223/L10238 #e0e0e0 */
  color: var(--text-muted);                 /* L10224 #555 / L10239 #888 (2.69:1) */
}
[data-theme="dark"] .ab-queue-card .ab-item-status-approved,
[data-theme="dark"] .ab-queue-card .ab-item-status-demand-filled {
  background: var(--accent-soft);           /* L10228 #cce5ff / L10233 #e0e7ff */
  color: #9db8e8;
}

/* ---- F. Failure / alert banners + Run Log table ----
   The error banner (.ab-error-box, run.error_message), the stale-run alert
   (.ab-error-box--warn, run_alert) and the Run Log table (.ab-table, renders
   only when AutoBuyExecLog rows exist) are all hard light fills in styles.css
   with no dark rebind — so the failure/log states, exactly when an operator
   needs the diagnostics, show light islands in dark mode. None were reachable
   from the earlier fixtures (no error_message / stale heartbeat / exec-log
   rows), so the audit never visited them (Codex finding). /auto-buy/2 now
   carries a stale heartbeat (warn banner) and /auto-buy/5 (GENERATION_FAILED)
   carries an error_message + exec-log rows. Scoped to .purchase-panel-wide so
   the shared .ab-table on untested pages stays untouched. */
[data-theme="dark"] .purchase-panel-wide .ab-error-box {
  background: var(--danger-soft);           /* styles.css L10265 #f8d7da */
  border-color: var(--danger);
  color: var(--text);                       /* L10266 #721c24 -> light body text */
}
[data-theme="dark"] .purchase-panel-wide .ab-error-box--warn {
  background: var(--warn-soft);             /* L14211 #fff7e6 */
  border-color: var(--warn);                /* L14212 #f5c27a */
  color: var(--text);                       /* L14213 #9a5800 */
}
[data-theme="dark"] .purchase-panel-wide .ab-table th {
  background: var(--surface-2);             /* L9891 #f8f9fb */
  color: var(--text-muted);                 /* L9892 #6b7280 */
  border-bottom-color: var(--border-strong);/* L9900 #e5e7eb */
}
[data-theme="dark"] .purchase-panel-wide .ab-table td {
  border-bottom-color: var(--border);       /* L9915 #f0f1f3 */
}
[data-theme="dark"] .purchase-panel-wide .ab-table tbody tr:hover {
  background: var(--surface-hover);         /* L9930 #fafbfd */
}
[data-theme="dark"] .purchase-panel-wide .ab-table th a,
[data-theme="dark"] .purchase-panel-wide .ab-table th a:hover {
  color: #9db8e8;                           /* L9904/L9909 #0b3d91 navy on dark */
}

/* Amazon-reports footer captions ship --text-subtle (#6e7a8f) inline in their
   template <style> blocks, which fails WCAG AA on the dark surfaces:
   .amzn-kpi-foot on the KPI card (rgb 27,34,48) = 3.67:1, and .amzn-foot on the
   page bg (rgb 15,19,26) = 4.29:1 — both < 4.5. Same fix pattern as
   .vendor-book-period above: bump to --text-muted (#9aa5b8) in dark only, which
   measures ~6.4:1 / ~7.5:1 on those surfaces. Higher specificity (0,2,0) than the
   inline class rule (0,1,0), so it wins without !important; light mode untouched. */
[data-theme="dark"] .amzn-kpi-foot,
[data-theme="dark"] .amzn-foot {
  color: var(--text-muted);
}

/* Forecast page, same failure class on its POPULATED branch (surfaced
   2026-06-10 by the populated-state audit fixtures): .fc-tile-foot and
   .fc-muted ship --text-subtle on the dark KPI card (3.67:1), and the
   .fc-pill low-confidence variant re-overrides the safe base --text-muted
   back to --text-subtle. Bump all three to --text-muted in dark only; the
   pill's border follows its text so the low tone stays visually coherent. */
[data-theme="dark"] .fc-tile-foot,
[data-theme="dark"] .fc-muted,
[data-theme="dark"] .fc-pill[data-tone="low"] {
  color: var(--text-muted);
}
[data-theme="dark"] .fc-pill[data-tone="low"] {
  border-color: var(--text-muted);
}

/* Inventory page, same failure class on its POPULATED branch (surfaced
   2026-06-10 by the populated-state audit fixtures): KPI tile footers and
   the trend chart's axis date labels ship --text-subtle on the dark card
   (3.67:1). */
[data-theme="dark"] .inv-kpi-foot,
[data-theme="dark"] .inv-trend-axis {
  color: var(--text-muted);
}

/* Sales section of the inventory page (sx-*), same --text-subtle failure on
   its populated branch. The .sx-tile-foot[data-pending] warn variant keeps
   its --warn color: equal specificity (0,2,0) but the page <style> loads
   after this sheet, so the variant wins the tie on source order. */
[data-theme="dark"] .sx-banner-note,
[data-theme="dark"] .sx-tile-foot {
  color: var(--text-muted);
}


/* ── Buyback Site: inline-colour styles extracted to classes ──────────────
   dark-mode-static gate (PR #1139): touching buyback_site.html promoted its
   legacy inline colour styles to gating P1 findings. 1:1 extraction — same
   --bbs-* tokens, no visual change. Lives here (not styles.css) because
   styles.css carries 305 legacy !important P1s that gate the moment the
   file is touched. */
.bbs-note { margin: 0; color: var(--bbs-text-soft); }
.bbs-note--mb12 { margin-bottom: 12px; }
.bbs-note--mb14 { margin-bottom: 14px; }
.bbs-note--mt12 { margin-top: 12px; }
.bbs-text-danger { color: var(--bbs-danger); }
.bbs-td-muted { color: var(--bbs-text-muted); }
.bbs-link-primary { color: var(--bbs-primary); }
.bbs-link-primary--bold { font-weight: 700; }
.bbs-calc__hint--warn { padding: 10px 14px 0; color: var(--bbs-warn); }
.bbs-calc__hint--mono { color: var(--bbs-text); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.78rem; }
.bbs-subhead { margin: 0 0 6px; font-size: 0.82rem; color: var(--bbs-text-muted); text-transform: uppercase; letter-spacing: 0.06em; }
.bbs-row-highlight { background: var(--bbs-primary-softer); }
.bbs-row-highlight--total { font-weight: 700; }


/* ── Reports rebuild PR B: Data tab source registry + results polish ──────
   rp-* is the Reports page-scoped namespace (Bucket 3 helpers; tokens only). */
.rp-source-registry {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 14px;
  margin-bottom: 18px;
}
.rp-source-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.rp-source-card__title { margin: 0; font-size: 15px; font-weight: 700; color: var(--text); }
.rp-source-card__count {
  margin: 10px 0 6px;
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}
.rp-source-card__count-label { font-size: 12px; font-weight: 500; color: var(--text-muted); }
.rp-source-card__role { margin: 0 0 10px; font-size: 12.5px; line-height: 1.5; color: var(--text-muted); }
.rp-source-card__meta {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 11.5px;
  color: var(--text-muted);
  border-top: 1px solid var(--border);
  padding-top: 8px;
}
.rp-source-card__feeds { color: var(--text); }
.rp-source-card__error { color: var(--danger); }

/* Builder numeric fields hold <=6-digit dollar/row values - full-width
   inputs read as giant empty bars (operator feedback 2026-06-12). */
.reports-field--num input {
  width: 160px;
  max-width: 160px;
}

/* Checkbox rule rows: inline box + label text, not the block input layout */
.reports-field--checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
}
.reports-field--checkbox input[type="checkbox"] {
  display: inline-block;
  width: auto;
  min-height: 0;
  margin: 0;
}

/* Results tab: status summary strip */
.rp-results-summary {
  display: flex;
  gap: 9px;
  flex-wrap: wrap;
  margin-bottom: 4px;
}
.rp-results-summary .pill { font-variant-numeric: tabular-nums; }

/* ── Builder rules design system (operator feedback 2026-06-12, condensed
   in round 2: "too blocky and long") — ONE segmented panel with internal
   column dividers instead of floating cards; tight vertical rhythm. ── */
.rp-rules-row {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  display: grid;
  gap: 0;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: stretch;
  overflow: hidden;
}
.rp-rules-row--four { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.rp-rule-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  padding: 16px 18px;
}
.rp-rule-card + .rp-rule-card { border-left: 1px solid var(--border); }
/* Icon-badged section heads (operator mockup 2026-06-12) */
.rp-rule-card__head {
  align-items: flex-start;
  display: flex;
  gap: 10px;
}
.rp-rule-card__icon {
  align-items: center;
  background: var(--brand-soft);
  border-radius: 999px;
  color: var(--brand-deep);
  display: inline-flex;
  flex: 0 0 auto;
  height: 34px;
  justify-content: center;
  width: 34px;
}
.rp-rule-card__icon svg { height: 16px; width: 16px; }
.rp-rule-card__copy { min-width: 0; }
.rp-rule-card__head h3 {
  color: var(--text);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  margin: 1px 0 2px;
  text-transform: uppercase;
}
.rp-rule-card__head p {
  color: var(--text-muted);
  font-size: 12px;
  line-height: 1.4;
  margin: 0;
}
.rp-rule-card__divider { border-top: 1px dashed var(--border); }

.rp-choice-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.rp-choice {
  align-items: flex-start;
  border: 1px solid var(--border);
  border-radius: 8px;
  cursor: pointer;
  display: flex;
  gap: 9px;
  padding: 10px 12px;
  transition: border-color 0.12s ease, background-color 0.12s ease;
}
.rp-choice:hover { border-color: var(--text-muted); }
/* Warm brand-tinted checked state (operator mockup 2026-06-12) */
.rp-choice:has(input:checked) {
  background: var(--brand-soft);
  border-color: var(--brand);
}
.rp-choice input[type="radio"],
.rp-choice input[type="checkbox"] {
  accent-color: var(--brand);
  flex: 0 0 auto;
  margin-top: 2px;
}
.rp-choice__body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.rp-choice__title { color: var(--text); font-size: 12.5px; font-weight: 600; }
.rp-choice__desc { color: var(--text-muted); font-size: 11.5px; line-height: 1.35; }

.rp-field-grid {
  display: grid;
  gap: 8px 10px;
  grid-template-columns: repeat(auto-fill, minmax(135px, 1fr));
}
.rp-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.rp-field__label { color: var(--text); font-size: 12.5px; font-weight: 600; }
.rp-field__control { display: flex; }
.rp-field__control input {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  min-height: 36px;
  padding: 6px 10px;
  text-align: right;
  width: 100%;
  max-width: 150px;
}
.rp-field__control--affixed input {
  border-bottom-left-radius: 0;
  border-top-left-radius: 0;
}
.rp-field__affix {
  align-items: center;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-bottom-left-radius: 8px;
  border-top-left-radius: 8px;
  border-right: 0;
  color: var(--text-muted);
  display: inline-flex;
  font-size: 12px;
  font-weight: 600;
  padding: 0 9px;
}
.rp-field__hint { color: var(--text-muted); font-size: 11.5px; line-height: 1.35; }

/* Inline-label variant: "Max cached age  [hrs|any]" (operator mockup) */
.rp-field--inline {
  align-items: center;
  flex-direction: row;
  gap: 12px;
  justify-content: space-between;
}
.rp-field--inline .rp-field__control { flex: 0 0 auto; }
.rp-field--inline .rp-field__control input { max-width: 110px; }

/* Select with a leading icon (Schedule cadence, operator mockup) */
.rp-field__control--iconed { position: relative; }
.rp-field__control--iconed svg {
  color: var(--text-muted);
  height: 15px;
  left: 10px;
  pointer-events: none;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 15px;
}
/* Doubled class beats the later `.rp-schedule select` padding reset. */
.rp-field__control--iconed.rp-field__control--iconed select { padding-left: 32px; }

.rp-status-value { font-weight: 600; }
.rp-status-value--ok { color: var(--ok); }

/* Mixed fields on one wrapping row (rows-per-CSV + email, etc.) */
.rp-field-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
}
.rp-field-row .rp-field { flex: 0 0 auto; }
.rp-field-row .rp-field--text { flex: 1 1 180px; }

/* Checkbox + companion field on one line (e.g. Keepa toggle + max age) */
.rp-inline-pair {
  align-items: flex-start;
  display: flex;
  gap: 10px;
}
.rp-inline-pair .rp-choice { flex: 1 1 auto; min-width: 0; }
.rp-inline-pair .rp-field { flex: 0 0 auto; width: 120px; }
.rp-inline-pair .rp-field__control input { max-width: 120px; }

.rp-src-meta {
  color: var(--text-muted);
  font-size: 11.5px;
  margin-left: 6px;
  white-space: nowrap;
}

/* Source freshness chips: a report against a weeks-old vendor list is a
   buying risk — flag it at selection time. */
.rp-src-age {
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  margin-left: 6px;
  padding: 1px 7px;
  white-space: nowrap;
}
.rp-src-age--aging {
  background: var(--warn-soft);
  color: var(--warn);
}
.rp-src-age--stale {
  background: color-mix(in srgb, var(--danger) 16%, transparent);
  color: var(--danger);
}

/* Sticky run bar: the source lists are page-height; keep the CTA and the
   live selection count in view. */
.rp-builder-actions {
  align-items: center;
  background: var(--bg);
  border-top: 1px solid var(--border);
  bottom: 0;
  display: flex;
  gap: 16px;
  justify-content: flex-end;
  margin: 0 -4px;
  padding: 12px 4px;
  position: sticky;
  z-index: 5;
}
.rp-selection-summary {
  color: var(--text);
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: pre;
}
.rp-selection-summary--empty { color: var(--text-muted); font-weight: 500; }

/* "Run again" prefill banner + free-text fields (notify emails) */
.rp-prefill-note {
  align-items: center;
  background: var(--surface-2);
  border: 1px solid var(--accent);
  border-radius: 8px;
  color: var(--text);
  display: flex;
  font-size: 13px;
  gap: 10px;
  margin-bottom: 14px;
  padding: 10px 14px;
}
.rp-prefill-note svg { color: var(--accent); flex: 0 0 auto; height: 16px; width: 16px; }
.rp-field--text input {
  max-width: none;
  text-align: left;
  font-variant-numeric: normal;
}

/* Schedule controls (builders) + schedules panel (Results) */
.rp-schedule {
  border-top: 1px dashed var(--border);
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 10px;
}
.rp-schedule select,
.rp-schedule input[type="time"] {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 13px;
  min-height: 36px;
  padding: 6px 10px;
  width: 100%;
  max-width: 170px;
}
/* Day/time/label sit on ONE wrapping row — the stacked version doubled the
   card height (operator round 2: condense). */
.rp-schedule__when { display: flex; flex-wrap: wrap; gap: 8px 10px; }
.rp-schedule__when .rp-field { flex: 0 0 auto; }
.rp-schedule__when .rp-field--text { flex: 1 1 160px; }
/* display:flex beats the UA [hidden] rule — restate it for the schedule
   controls (and any rp-field toggled by JS). */
.rp-schedule__when[hidden],
.rp-field[hidden] { display: none; }
.rp-schedules-panel h2 { font-size: 16px; margin: 18px 0 10px; }
.rp-schedule-action { display: inline-block; margin-right: 10px; }
.rp-schedule-action .button-link {
  background: none;
  border: 0;
  cursor: pointer;
  padding: 0;
}

/* Sourcing Tiers extras: file inputs, output explainer card */
.rp-field input[type="file"] {
  border: 1px dashed var(--border);
  border-radius: 6px;
  color: var(--text-muted);
  font-size: 12px;
  padding: 8px;
  width: 100%;
}
.rp-rule-card--info { background: var(--surface-2); }
.rp-output-list {
  color: var(--text-muted);
  display: flex;
  flex-direction: column;
  font-size: 12.5px;
  gap: 8px;
  line-height: 1.5;
  list-style: none;
  margin: 0;
  padding: 0;
}
.rp-output-list strong { color: var(--text); font-weight: 600; }

@media (max-width: 1280px) {
  /* Two-up keeps the condensed feel on laptop viewports (Codex round 2);
     dividers: left border on column 2, top border on row 2. */
  .rp-rules-row--four { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rp-rules-row--four .rp-rule-card + .rp-rule-card { border-left: 0; }
  .rp-rules-row--four .rp-rule-card:nth-child(2n) { border-left: 1px solid var(--border); }
  .rp-rules-row--four .rp-rule-card:nth-child(n+3) { border-top: 1px solid var(--border); }
}
@media (max-width: 980px) {
  .rp-rules-row,
  .rp-rules-row--four { grid-template-columns: 1fr; }
  .rp-rule-card + .rp-rule-card,
  .rp-rules-row--four .rp-rule-card:nth-child(2n) {
    border-left: 0;
    border-top: 1px solid var(--border);
  }
}
