/* ============================================================
   Gravel AI — v3 Design System
   Light theme, anchored to the corporate brand
   (cream shell · Newsreader serif · logo-colour accents)

   ┌─────────────────────────────────────────────────────────┐
   │  NON-DEVELOPER TWEAK ZONE                                 │
   │  Every colour, size and radius lives in :root below.      │
   │  Change a value there and refresh the browser — no build  │
   │  step, no tooling. Visible text lives in the .html file.  │
   └─────────────────────────────────────────────────────────┘
   ============================================================ */

:root {
  /* ---- Fonts ---- */
  --font-display: 'Newsreader', Georgia, 'Times New Roman', serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  /* ---- Brand surface colours ---- */
  --cream:        #f3f1ea;   /* page background */
  --cream-deep:   #ebe8dd;   /* subtle deeper cream */
  --sidebar-bg:   #faf9f4;   /* left sidebar */
  --card:         #ffffff;   /* cards / panels */

  /* ---- Ink (text) ---- */
  --ink:          #1f2333;   /* headings, logo navy */
  --ink-soft:     #4c5163;   /* body text */
  --ink-muted:    #8b8f9f;   /* captions, labels */

  /* ---- Logo accent palette ---- */
  --mint:         #7fd9b4;   /* hexagon */
  --peach:        #f2bd7e;   /* triangle */
  --pink:         #f0b2d4;   /* square */
  --periwinkle:   #8a8ef0;   /* circle */

  /* ---- Functional colours ---- */
  --primary:      #8a8ef0;   /* periwinkle — primary action */
  --primary-deep: #6d72de;   /* hover / pressed */
  --primary-tint: #ecedfc;   /* light periwinkle wash */
  --accent-green: #36c98e;   /* status dot / positive */
  --accent-orange:#e8a04d;   /* status dot / attention */
  --danger:       #e07a5f;
  --danger-tint:  #fbeae5;

  /* ---- Borders ---- */
  --border:       #e6e3d7;   /* warm border on cream */
  --border-card:  #eeece3;   /* hairline inside cards */
  --border-input: #dcd9cd;

  /* ---- Radius ---- */
  --radius-card:  18px;
  --radius-md:    12px;
  --radius-sm:    8px;
  --radius-pill:  999px;

  /* ---- Shadows ---- */
  --shadow-card:  0 1px 2px rgba(31,35,51,.04), 0 10px 30px rgba(31,35,51,.06);
  --shadow-pop:   0 12px 40px rgba(31,35,51,.16);

  /* ---- Layout metrics ---- */
  --sidebar-w:    258px;
  --topbar-h:     64px;
  --content-max:  1320px;

  --transition:   .18s ease;
}

/* ───────────────────────────── Reset / base ───────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-soft);
  background: var(--cream);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 { margin: 0; color: var(--ink); font-weight: 600; }

a { color: var(--primary-deep); text-decoration: none; }
a:hover { text-decoration: underline; }

button { font-family: inherit; cursor: pointer; }

::selection { background: var(--primary-tint); }

/* Scrollbars */
* { scrollbar-width: thin; scrollbar-color: #d4d1c4 transparent; }
*::-webkit-scrollbar { width: 9px; height: 9px; }
*::-webkit-scrollbar-thumb { background: #d8d5c8; border-radius: 99px; border: 2px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: #c4c1b2; background-clip: content-box; }

/* Eyebrow label — uppercase letter-spaced, used everywhere */
.eyebrow {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

/* ───────────────────────────── App shell ───────────────────────────── */
.app { display: flex; min-height: 100vh; }

/* ===== Sidebar ===== */
.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border);
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  transition: transform var(--transition);
}

.sidebar-logo {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 20px 22px 16px;
}
.sidebar-logo img { height: 27px; width: auto; max-width: 100%; }
.sidebar-logo .logo-sub {
  font-family: var(--font-display);
  font-size: 12px;
  font-style: italic;
  color: var(--ink-muted);
  padding-left: 2px;
}

.sidebar-nav {
  flex: 1;
  overflow-y: auto;
  padding: 8px 12px 16px;
}

.nav-group-label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: #a9a594;
  padding: 16px 12px 6px;
}

.nav-link {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 12px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  color: var(--ink-soft);
  transition: background var(--transition), color var(--transition);
}
.nav-link:hover { background: #efece1; color: var(--ink); text-decoration: none; }
.nav-link::before {
  content: '';
  width: 6px; height: 6px;
  border-radius: 2px;
  background: #cfccbc;
  flex-shrink: 0;
  transition: background var(--transition), transform var(--transition);
}
.nav-link:hover::before { background: var(--periwinkle); }

.nav-link.active {
  background: #fff;
  color: var(--ink);
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(31,35,51,.05), inset 0 0 0 1px var(--border-card);
}
.nav-link.active::before { background: var(--periwinkle); transform: scale(1.25); }

.nav-tag {
  margin-left: auto;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--primary-deep);
  background: var(--primary-tint);
  padding: 2px 7px;
  border-radius: var(--radius-pill);
}

/* Sidebar user card */
.sidebar-user {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 8px 14px 16px;
  padding: 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: #fff;
}
.sidebar-user .avatar {
  width: 36px; height: 36px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--mint);
  color: #14503b;
  font-weight: 700;
  font-size: 13px;
  flex-shrink: 0;
}
.sidebar-user > div:last-child { min-width: 0; }
.sidebar-user .u-name {
  font-size: 13px; font-weight: 600; color: var(--ink); line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sidebar-user .u-role {
  font-size: 11px; color: var(--ink-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ===== Main column ===== */
.main {
  flex: 1;
  margin-left: var(--sidebar-w);
  min-width: 0;
  display: flex;
  flex-direction: column;
  transition: margin-left var(--transition);
}

/* Desktop: collapse / expand the sidebar */
body.sidebar-collapsed .sidebar { transform: translateX(-100%); }
body.sidebar-collapsed .main { margin-left: 0; }

/* ===== Topbar ===== */
.topbar {
  height: var(--topbar-h);
  background: rgba(243,241,234,.85);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 26px;
  position: sticky;
  top: 0;
  z-index: 50;
}
.topbar-title {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 600;
  color: var(--ink);
}
.topbar-spacer { flex: 1; }

.icon-btn {
  background: none;
  border: none;
  width: 38px; height: 38px;
  border-radius: var(--radius-sm);
  display: grid; place-items: center;
  color: var(--ink-soft);
  font-size: 20px;
}
.icon-btn:hover { background: var(--cream-deep); color: var(--ink); }

.menu-toggle { display: grid; }   /* always visible — collapses the sidebar */

/* Topbar chips (credits / profile) */
.top-chip {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  background: #fff;
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-soft);
  transition: border-color var(--transition), background var(--transition);
}
.top-chip:hover { border-color: var(--periwinkle); text-decoration: none; }

/* credits chip is informational only — not clickable */
#creditChip { cursor: default; }
#creditChip:hover { border-color: var(--border); }

/* AI assistant CTA chip */
.top-chip-ai {
  background: var(--primary-tint);
  border-color: rgba(138, 142, 240, .4);
  color: var(--primary-deep);
  font-weight: 600;
}
.top-chip-ai:hover { background: #e3e4fb; border-color: var(--periwinkle); }
.top-chip .chip-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--accent-green); }
.top-chip strong { color: var(--ink); font-weight: 700; }
.top-chip .avatar-sm {
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--periwinkle); color: #fff;
  display: grid; place-items: center;
  font-size: 11px; font-weight: 700;
}

/* ===== Content ===== */
.content {
  flex: 1;
  width: 100%;
  max-width: var(--content-max);
  margin: 0 auto;
  padding: 26px 26px 60px;
}

/* ───────────────────────────── Cards ───────────────────────────── */
.card {
  background: var(--card);
  border: 1px solid var(--border-card);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}
.card-pad { padding: 22px 24px; }

/* ───────────────────────────── Search panel ───────────────────────────── */
.search-panel { padding: 30px 32px 24px; }

.search-head { text-align: center; margin-bottom: 22px; }
.search-head h1 {
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 500;
  letter-spacing: -.01em;
  color: var(--ink);
}
.search-head p {
  margin: 4px 0 0;
  color: var(--ink-muted);
  font-size: 14px;
}

.form-grid { display: flex; flex-direction: column; gap: 12px; }
.form-row { display: flex; gap: 12px; flex-wrap: wrap; }
.form-row > * { flex: 1 1 220px; min-width: 0; }
.form-row .shrink { flex: 0 0 auto; }

.field-label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-soft);
  margin-bottom: 5px;
}
.field-label .opt { color: var(--ink-muted); font-weight: 400; }

/* Inputs */
.input, textarea.input {
  width: 100%;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--border-input);
  border-radius: var(--radius-sm);
  padding: 10px 13px;
  transition: border-color var(--transition), box-shadow var(--transition);
}
textarea.input { resize: vertical; min-height: 46px; }
.input::placeholder { color: #b3b0a2; }
.input:focus {
  outline: none;
  border-color: var(--periwinkle);
  box-shadow: 0 0 0 3px var(--primary-tint);
}
.input.is-valid { border-color: var(--accent-green); background: #f3fbf7; }
.input.is-invalid { border-color: var(--danger); background: var(--danger-tint); }

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  padding: 11px 22px;
  transition: background var(--transition), box-shadow var(--transition), transform .05s;
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--primary); color: #fff; }
.btn-primary:hover { background: var(--primary-deep); box-shadow: 0 6px 18px rgba(138,142,240,.4); }
.btn-primary:disabled { background: #c3c5e8; box-shadow: none; cursor: not-allowed; }
.btn-ghost { background: #fff; border-color: var(--border); color: var(--ink-soft); }
.btn-ghost:hover { border-color: var(--periwinkle); color: var(--ink); }
.btn-search { font-size: 15px; padding: 12px 30px; }

/* small spinner inside button */
.btn .spin {
  width: 15px; height: 15px;
  border: 2px solid rgba(255,255,255,.45);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin .7s linear infinite;
  display: none;
}
.btn.loading .spin { display: block; }
@keyframes spin { to { transform: rotate(360deg); } }

/* Advanced search */
.adv-toggle {
  margin-top: 14px;
  font-size: 13px;
  color: var(--primary-deep);
  background: none; border: none;
  display: inline-flex; align-items: center; gap: 6px;
}
.adv-toggle:hover { text-decoration: underline; }
.adv-toggle .chev { transition: transform var(--transition); }
.adv-toggle[aria-expanded="true"] .chev { transform: rotate(180deg); }

.adv-panel {
  margin-top: 12px;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 10px;
}
.adv-panel[hidden] { display: none; }
.adv-card {
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 13px 15px;
  font-size: 12.5px;
}
.adv-card b { color: var(--ink); display: block; margin-bottom: 2px; }
.adv-card code {
  font-family: 'SFMono-Regular', Menlo, Consolas, monospace;
  font-size: 11.5px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 5px;
  color: var(--primary-deep);
}

/* ───────────────────────────── Onboarding empty state ───────────────────────────── */
#onboarding {
  text-align: center;
  padding: 60px 24px 48px;
}
.onboard-mark { margin: 0 auto 22px; }
#onboarding h2 {
  font-family: var(--font-display);
  font-size: 25px;
  font-weight: 500;
  color: var(--ink);
}
#onboarding .lead {
  max-width: 520px;
  margin: 8px auto 0;
  color: var(--ink-soft);
  font-size: 14.5px;
}
.example-label { margin-top: 26px; }
.example-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
  justify-content: center;
  margin-top: 12px;
}
.chip {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 8px 16px;
  font-size: 13px;
  color: var(--ink-soft);
  transition: all var(--transition);
}
.chip:hover {
  border-color: var(--periwinkle);
  color: var(--primary-deep);
  background: var(--primary-tint);
  transform: translateY(-1px);
}
.onboard-hint {
  margin-top: 30px;
  font-size: 12.5px;
  color: var(--ink-muted);
  display: flex; align-items: center; gap: 6px; justify-content: center;
}
.onboard-hint .arrow { animation: bob 1.6s ease-in-out infinite; }
@keyframes bob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }

/* ───────────────────────────── Shape cluster (brand mark) ───────────────────────────── */
.shape-cluster {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 5px;
  width: 56px; height: 56px;
}
.shape-cluster span { display: block; width: 100%; height: 100%; }
.shape-cluster .s-hex {
  background: var(--mint);
  clip-path: polygon(50% 0,100% 25%,100% 75%,50% 100%,0 75%,0 25%);
}
.shape-cluster .s-tri {
  background: var(--peach);
  clip-path: polygon(50% 8%,95% 92%,5% 92%);
  border-radius: 4px;
}
.shape-cluster .s-sq { background: var(--pink); border-radius: 7px; }
.shape-cluster .s-cir { background: var(--periwinkle); border-radius: 50%; }
.shape-cluster.lg { width: 72px; height: 72px; }

/* ───────────────────────────── Section ───────────────────────────── */
.section { margin-top: 30px; scroll-margin-top: 130px; }
.section-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 12px;
}
.section-head h3 {
  font-family: var(--font-display);
  font-size: 21px;
  font-weight: 600;
  color: var(--ink);
}
.section-head .count {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-muted);
}
.section-note { font-size: 13px; color: var(--ink-muted); margin: 0 0 12px; }

/* In-page jump nav */
.section-nav {
  position: sticky;
  top: var(--topbar-h);
  z-index: 40;
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  padding: 10px 0;
  margin-bottom: 6px;
  background: rgba(243,241,234,.9);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.section-nav a {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-muted);
  padding: 6px 12px;
  border-radius: var(--radius-pill);
}
.section-nav a:hover { background: #fff; color: var(--ink); text-decoration: none; }
.section-nav a.active { background: var(--ink); color: #fff; }

/* ───────────────────────────── KPI tiles ───────────────────────────── */
.kpi-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
}
.kpi {
  background: var(--card);
  border: 1px solid var(--border-card);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 20px;
  position: relative;
  /* no overflow:hidden — it would clip the help tooltips */
}
.kpi::before {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 4px;
  background: var(--accent);
  border-radius: var(--radius-card) 0 0 var(--radius-card);
}
.kpi.k-mint  { --accent: var(--mint); }
.kpi.k-peri  { --accent: var(--periwinkle); }
.kpi.k-peach { --accent: var(--peach); }
.kpi.k-pink  { --accent: var(--pink); }
.kpi .kpi-val {
  font-family: var(--font-display);
  font-size: 30px;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.kpi .kpi-label {
  margin-top: 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.kpi .kpi-val.pos { color: var(--accent-green); }
.kpi .kpi-val.neg { color: var(--danger); }

/* ───────────────────────────── Pills (sub-tabs) ───────────────────────────── */
.pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 16px;
}
.pill {
  background: var(--cream);
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 7px 15px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-soft);
  transition: all var(--transition);
}
.pill:hover { border-color: var(--periwinkle); color: var(--primary-deep); }
.pill.active {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}

/* ───────────────────────────── Tables ───────────────────────────── */
.table-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.table-toolbar .spacer { flex: 1; }

/* Export dropdown */
.export-dd { position: relative; }
.export-btn::after { content: ' \25BE'; opacity: .7; }
.export-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 5px);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-pop);
  padding: 5px;
  min-width: 138px;
  z-index: 70;
  display: none;
}
.export-dd.open .export-menu { display: block; }
.export-menu button {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 7px 11px;
  border-radius: 6px;
  font-family: var(--font-body);
  font-size: 12.5px;
  color: var(--ink-soft);
}
.export-menu button:hover { background: var(--primary-tint); color: var(--primary-deep); }

.data-table-wrap {
  overflow: auto;
  max-height: 600px;
  border: 1px solid var(--border-card);
  border-radius: var(--radius-md);
}
.table-count {
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-muted);
  padding: 9px 4px 0;
  text-align: right;
}

/* Inline-SVG sparkline (ingredient growth-trend column) */
.spark { display: block; }
.spark-lbl {
  font-family: var(--font-body);
  font-size: 9px;
  font-weight: 600;
  fill: var(--ink-soft);
}
.spark-na { color: var(--ink-muted); }

/* Clickable drill-down term inside table cells (e.g. chemical categories) */
.clickable-term { color: var(--primary-deep); cursor: pointer; }
.clickable-term:hover { text-decoration: underline; }
table.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
table.data-table thead th {
  position: sticky;
  top: 0;
  background: #faf9f4;
  text-align: left;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding: 11px 14px;
  border-bottom: 1.5px solid var(--border);
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
}
table.data-table thead th:hover { color: var(--ink); }
table.data-table thead th .sort-ind { opacity: .35; font-size: 9px; margin-left: 3px; }
table.data-table thead th[data-dir="asc"] .sort-ind,
table.data-table thead th[data-dir="desc"] .sort-ind { opacity: 1; color: var(--primary-deep); }
table.data-table tbody td {
  padding: 11px 14px;
  border-bottom: 1px solid #f4f2e8;
  color: var(--ink-soft);
  vertical-align: middle;
}
table.data-table tbody tr:last-child td { border-bottom: none; }
table.data-table tbody tr:hover td { background: #faf9f3; }
table.data-table tbody img {
  max-height: 160px;
  max-width: 150px;
  border-radius: 8px;
  object-fit: contain;
  background: #fff;
}
table.data-table a { color: var(--primary-deep); }

/* OEM expandable rows.
   Two layout variants:
   (a) Leading-toggle-column variant — opt-in via `.has-toggle-col` on
       the <table>. The first <td> of every row is reserved for the
       ▶ toggle (34px wide, centered). Used by Brand Deep Dive
       (`#oemTable`, `#ingredientTable`) where the backend rows ARRIVE
       with a leading empty `<td></td>` placeholder.
   (b) Inline-toggle variant — DEFAULT, no opt-in needed. The ▶ toggle
       is prepended INSIDE the first data cell. No separate column =
       no risk of the empty leading column visually misaligning the
       header (the bug §14.22 originally tried to address by inserting
       a leading cell; turns out inlining is the cleaner fix). Used by
       OEM Deep Dive (`#brandTable`). */
.has-toggle-col tr.oem-row > td:first-child {
  width: 34px; text-align: center; cursor: pointer;
}
/* CRITICAL: the leading `<th></th>` must be sized to match the 34px
   body cell. Without this, browser auto-sizing gives the empty <th>
   the bare minimum width (~16px from padding) while the body cell is
   34px — the column widths disagree and the headers visually shift
   left of the data underneath. */
.has-toggle-col thead th:first-child {
  width: 34px;
  padding-left: 0;
  padding-right: 0;
}
.oem-toggle {
  display: inline-grid; place-items: center;
  width: 20px; height: 20px;
  border-radius: 5px;
  background: var(--primary-tint);
  color: var(--primary-deep);
  font-size: 10px;
  transition: transform var(--transition);
}
/* When inlined into a content cell, give the toggle a little right margin
   so it doesn't crash into the text it prefixes. */
tr.oem-row > td:first-child > .oem-toggle:first-child { margin-right: 8px; vertical-align: middle; }
tr.oem-row.open .oem-toggle { transform: rotate(90deg); }
/* Clickable cue on inline-toggle rows — the whole row is clickable
   when child rows exist, so a subtle hint that this isn't just static. */
.data-table:not(.has-toggle-col) tr.oem-row { cursor: pointer; }
.data-table:not(.has-toggle-col) tr.oem-row:hover td { background: var(--surface-soft, #faf9f3); }
tr.oem-child-row td { background: #faf9f3 !important; padding: 0 !important; }
.oem-child-inner {
  padding: 8px 14px 14px 48px;
  max-height: 400px;
  overflow-y: auto;
}
.oem-child-inner table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.oem-child-inner th {
  text-align: left; font-size: 10px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--ink-muted); padding: 6px 10px; border-bottom: 1px solid var(--border);
  position: sticky; top: 0; background: #faf9f3;
}
.oem-child-inner td { padding: 6px 10px; border-bottom: 1px solid #efede2; }

/* ─────────────────────── Prose / profile block ─────────────────── */
.brand-profile { font-size: 14px; line-height: 1.7; color: var(--ink); }
.brand-profile p { margin: 0 0 10px; }
.brand-profile p:last-child { margin-bottom: 0; }

/* ───────────────────────────── Charts ───────────────────────────── */
.chart { width: 100%; height: 380px; }
.chart.tall { height: 480px; }
.chart-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}

/* ───────────────────────────── Help tooltip ───────────────────────────── */
.help {
  display: inline-grid; place-items: center;
  width: 15px; height: 15px;
  border-radius: 50%;
  background: var(--cream-deep);
  color: var(--ink-muted);
  font-size: 10px;
  font-weight: 700;
  cursor: help;
  position: relative;
  vertical-align: middle;
  margin-left: 3px;
}
.help:hover { background: var(--periwinkle); color: #fff; }
.help:hover::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  width: 240px;
  background: var(--ink);
  color: #fff;
  font-size: 11.5px;
  font-weight: 400;
  line-height: 1.5;
  text-transform: none;
  letter-spacing: 0;
  padding: 9px 11px;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-pop);
  z-index: 100;
}
.help:hover::before {
  content: '';
  position: absolute;
  bottom: calc(100% + 2px);
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--ink);
  z-index: 100;
}
/* When a .help icon lives inside a scroll container (e.g. `.data-table-wrap`
   has `overflow: auto`), the CSS pseudo-tooltip gets clipped at the
   container edge — the user can't read it. The fix is a JS portal that
   re-renders the tooltip on document.body with `position: fixed`, so it
   escapes every ancestor's overflow. The JS marks the .help element with
   `data-portal="true"` which suppresses the pseudo-tooltip to prevent
   double-tooltip rendering. See §14.29 of the playbook for the helper. */
.help[data-portal="true"]:hover::after,
.help[data-portal="true"]:hover::before { display: none !important; }

.help-portal-tip {
  width: 240px;
  background: var(--ink);
  color: #fff;
  font-size: 11.5px;
  font-weight: 400;
  line-height: 1.5;
  text-transform: none;
  letter-spacing: 0;
  padding: 9px 11px;
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-pop);
  pointer-events: none;   /* don't intercept mouse — let the help icon keep hover */
}

/* ───────────────────────────── Inline empty / error per section ───────────────────────────── */
.inline-empty {
  text-align: center;
  padding: 38px 20px;
  color: var(--ink-muted);
  font-size: 13.5px;
}
.inline-empty .ie-mark { margin: 0 auto 12px; opacity: .8; }

/* ───────────────────────────── Skeleton loading ───────────────────────────── */
.skeleton {
  background: linear-gradient(100deg, #efede4 30%, #f7f6ef 50%, #efede4 70%);
  background-size: 220% 100%;
  animation: shimmer 1.3s linear infinite;
  border-radius: 6px;
}
@keyframes shimmer { to { background-position: -220% 0; } }
.sk-line { height: 13px; margin: 9px 0; }
.sk-chart { height: 320px; border-radius: var(--radius-md); }
.sk-row { display: flex; gap: 14px; }
.sk-row .skeleton { flex: 1; }

/* Reveal animation for results */
.reveal { animation: reveal .45s ease both; }
@keyframes reveal { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* ───────────────────────────── State visibility ───────────────────────────── */
#results { display: none; }
#onboarding { display: block; }
.section-nav { display: none; }

/* result sections appear only when data is ready —
   they stay hidden while idle AND while loading */
body[data-state="ready"] #onboarding { display: none; }
body[data-state="ready"] #results { display: block; }
body[data-state="ready"] .section-nav { display: flex; }

.sk-only { display: none; }

/* loading: the onboarding panel stays put but turns into a
   "running" indicator — chips/hint hidden, brand mark pulses */
body[data-state="loading"] .example-label,
body[data-state="loading"] .example-chips,
body[data-state="loading"] .onboard-hint { display: none; }
body[data-state="loading"] .onboard-mark span { animation: pulse 1.2s ease-in-out infinite; }
body[data-state="loading"] .onboard-mark .s-tri { animation-delay: .15s; }
body[data-state="loading"] .onboard-mark .s-cir { animation-delay: .3s; }
body[data-state="loading"] .onboard-mark .s-sq  { animation-delay: .45s; }

/* ───────────────────────────── Loader overlay ───────────────────────────── */
.loader-overlay {
  position: fixed;
  inset: 0;
  background: rgba(243,241,234,.82);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  display: none;
  place-items: center;
  z-index: 200;
}
.loader-overlay.show { display: grid; }
.loader-box { text-align: center; }
.loader-box .shape-cluster span { animation: pulse 1.2s ease-in-out infinite; }
.loader-box .shape-cluster .s-tri { animation-delay: .15s; }
.loader-box .shape-cluster .s-cir { animation-delay: .3s; }
.loader-box .shape-cluster .s-sq  { animation-delay: .45s; }
@keyframes pulse { 0%,100% { opacity: .35; transform: scale(.86); } 50% { opacity: 1; transform: scale(1); } }
.loader-box p {
  margin-top: 16px;
  font-family: var(--font-display);
  font-size: 16px;
  font-style: italic;
  color: var(--ink-soft);
}

/* ───────────────────────────── Modal (lightweight) ───────────────────────────── */
.modal-back {
  position: fixed; inset: 0;
  background: rgba(31,35,51,.4);
  display: none;
  place-items: center;
  z-index: 210;
}
.modal-back.show { display: grid; }
.modal-box {
  background: #fff;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-pop);
  width: min(420px, 92vw);
  padding: 26px 28px;
  text-align: center;
}
.modal-box h4 { font-family: var(--font-display); font-size: 19px; margin-bottom: 8px; }
.modal-box p { color: var(--ink-soft); font-size: 13.5px; }
.modal-box .btn { margin-top: 16px; }

/* Wide-modal variant — used for the date-range picker */
.modal-box.modal-wide {
  width: min(640px, 94vw);
  max-height: 92vh;
  overflow-y: auto;
  text-align: left;
  padding: 22px 26px;
}
.modal-box .modal-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 6px;
}
.modal-box .modal-close {
  background: none; border: 0; cursor: pointer;
  font-size: 22px; line-height: 1; color: var(--ink-muted);
  padding: 4px 8px; border-radius: 6px;
}
.modal-box .modal-close:hover { background: var(--primary-tint); color: var(--primary-deep); }
.modal-box .modal-actions {
  display: flex; gap: 10px; justify-content: flex-end;
  margin-top: 18px;
}
.modal-box .modal-actions .btn { margin-top: 0; }

/* Month grid used by the custom-date-range picker */
.month-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-top: 12px;
}
.month-btn {
  padding: 10px 12px;
  font-size: 13px;
  font-family: inherit;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--ink);
  cursor: pointer;
  transition: background var(--transition), color var(--transition), border-color var(--transition);
}
.month-btn:hover { background: var(--primary-tint); border-color: var(--primary); }
.month-btn.in-range {
  background: var(--primary-tint);
  border-color: var(--primary);
  color: var(--primary-deep);
}
.month-btn.selected-boundary {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
  font-weight: 600;
}

/* ───────────────────────────── Footer ───────────────────────────── */
.footer {
  margin-top: 40px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--ink-muted);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
}

/* ───────────────────────────── Data-source list ───────────────────────────── */
#data_source_text { font-size: 13px; line-height: 1.7; }
#data_source_text b, #data_source_text strong { color: var(--ink); }

/* ───────────────────────────── Tom Select overrides ───────────────────────────── */
.ts-wrapper { font-family: var(--font-body); }
.ts-control {
  border: 1px solid var(--border-input) !important;
  border-radius: var(--radius-sm) !important;
  background: #fff !important;
  padding: 6px 10px !important;
  min-height: 44px !important;
  box-shadow: none !important;
  font-size: 14px !important;
  gap: 4px !important;
}
.ts-wrapper.focus .ts-control {
  border-color: var(--periwinkle) !important;
  box-shadow: 0 0 0 3px var(--primary-tint) !important;
}
.ts-wrapper.is-valid .ts-control { border-color: var(--accent-green) !important; background: #f3fbf7 !important; }
.ts-wrapper.is-invalid .ts-control { border-color: var(--danger) !important; background: var(--danger-tint) !important; }
/* hide placeholder once one or more items are selected */
.ts-wrapper.has-items .ts-control input::placeholder { color: transparent !important; }
.ts-control .item {
  background: var(--primary-tint) !important;
  color: var(--primary-deep) !important;
  border-radius: var(--radius-pill) !important;
  padding: 3px 9px !important;
  font-size: 12px !important;
  font-weight: 600 !important;
  border: none !important;
}
.ts-control .item .remove { border: none !important; color: var(--primary-deep) !important; opacity: .6; }
.ts-control .item .remove:hover { opacity: 1; background: transparent !important; }
.ts-dropdown {
  border: 1px solid var(--border) !important;
  border-radius: var(--radius-md) !important;
  box-shadow: var(--shadow-pop) !important;
  font-size: 13px !important;
  margin-top: 5px !important;
  z-index: 150 !important;   /* above the sticky section nav + topbar */
}
.ts-dropdown .option { padding: 8px 13px !important; color: var(--ink-soft) !important; }
.ts-dropdown .option:hover,
.ts-dropdown .active { background: var(--primary-tint) !important; color: var(--primary-deep) !important; }

/* ───────────────────────────── Vanilla typeahead ───────────────────────────── */
.typeahead-wrap { position: relative; }
.ta-menu {
  position: absolute;
  left: 0; right: 0;
  top: calc(100% + 4px);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-pop);
  max-height: 260px;
  overflow-y: auto;
  z-index: 150;
  display: none;
}
.ta-menu.show { display: block; }
.ta-item { padding: 8px 13px; font-size: 13px; color: var(--ink-soft); cursor: pointer; }
.ta-item:hover, .ta-item.active { background: var(--primary-tint); color: var(--primary-deep); }
.ta-item b { color: var(--primary-deep); }

/* ─────────────────────── Product Deep Dive hero card ───────────────── */
.product-hero {
  display: grid;
  grid-template-columns: 240px 1fr;
  gap: 24px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 22px;
}
/* `min-width: 0` on grid children stops a wide image (or any wide
   inline content) from forcing the track to expand past its declared
   240px. Without this, the engine's inline `max-width: 280px` on the
   product photo could push the column out and the body column would
   shrink correspondingly. */
.product-hero > * { min-width: 0; }
.product-hero-photo { overflow: hidden; }
.product-hero-photo img {
  display: block;
  /* `!important` overrides the engine's inline `style="max-width:280px;
     cursor:pointer"` on `example_photo_snippet` (v1 Bootstrap leftover).
     Without this the image was 40px wider than its 240px grid column
     on deep-link loads, where there's no candidate-card pre-sizing. */
  max-width: 100% !important;
  max-height: 280px !important;
  width: auto !important;
  height: auto !important;
  margin: 0 auto;
  object-fit: contain;
  background: #fff;
  border-radius: 12px;
  cursor: default;
}
.product-hero-body .product-hero-brand {
  display: inline-block;
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--primary-deep);
  font-weight: 600;
}
.product-hero-body .product-hero-name {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1.2;
  margin: 4px 0 10px;
  color: var(--ink);
}
.product-hero-body .product-hero-desc {
  color: var(--ink-soft);
  font-size: 13.5px;
  line-height: 1.6;
  margin: 0;
}
.product-hero-meta {
  display: grid;
  /* Fixed 3-column layout so 6 meta items wrap predictably as 3 + 3 rather
     than the previous auto-fit version which could leave 2 items orphaned
     on a partial row when the viewport is wide. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px 24px;
  margin: 18px 0 0;
}
@media (max-width: 720px) {
  .product-hero-meta { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.product-hero-meta .meta-item dt {
  color: var(--ink-muted);
  margin: 0 0 2px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-size: 10.5px;
  font-weight: 600;
}
.product-hero-meta .meta-item dd {
  color: var(--ink);
  margin: 0;
  font-size: 13px;
  line-height: 1.4;
}
.product-hero-ingre {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
  font-size: 13px;
  line-height: 1.6;
  color: var(--ink-soft);
}
.product-hero-ingre h5 {
  font-family: var(--font-display);
  font-size: 14px;
  color: var(--ink);
  margin: 0 0 6px;
  font-weight: 600;
}
.product-hero-ingre a { color: var(--primary-deep); }
@media (max-width: 720px) {
  .product-hero { grid-template-columns: 1fr; }
  .product-hero-photo img { max-height: 220px; }
}

/* ─── Tom Select inline loading indicator ────────────────────────────── */
/* Added to a Tom Select wrapper while options are being fetched in the
   background (e.g. the Product Deep Dive "Step 2 · Product" picker waiting
   for `_1` to return the brand's product list). A small spinning dot in
   the right edge of the control gives a visible cue beyond the disabled
   state, which on its own is easy to miss. */
.ts-wrapper.ts-loading .ts-control { position: relative; }
.ts-wrapper.ts-loading .ts-control::after {
  content: '';
  position: absolute;
  right: 14px;
  top: 50%;
  width: 14px;
  height: 14px;
  margin-top: -7px;
  border: 2px solid var(--primary-tint);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ─────────────────── Candidate-variant picker (Product Deep Dive) ──── */
/* Used between the brand/product search and the main results — each card
   represents one formulation/variant returned by the `_1A` endpoint. */
.candidate-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px;
  margin-top: 8px;
}
.candidate-card {
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px;
  cursor: pointer;
  text-align: left;
  transition: box-shadow var(--transition), transform var(--transition), border-color var(--transition);
  font: inherit;
}
.candidate-card:hover {
  border-color: var(--primary);
  box-shadow: var(--shadow-pop);
  transform: translateY(-1px);
}
/* "Currently viewing" marker — the card the user last clicked the
   "Deep-dive into this variant" button on. Tinted background + thicker
   periwinkle border + a small "Currently viewing" pill in the corner
   so the user can scroll back up and see which variant the metrics
   below relate to. */
.candidate-card.selected {
  position: relative;
  border-color: var(--primary);
  border-width: 2px;
  padding: 11px;   /* compensate for the extra 1px border */
  background: linear-gradient(180deg, var(--primary-tint), #fff 28%);
}
.candidate-card.selected::after {
  content: '✓ Currently viewing';
  position: absolute;
  top: -10px; right: 12px;
  background: var(--primary);
  color: #fff;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 4px 9px;
  border-radius: 999px;
  box-shadow: var(--shadow-card);
}
.candidate-card-photo {
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #faf9f3;
  border-radius: 8px;
  overflow: hidden;
  margin-bottom: 10px;
}
.candidate-card-photo img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.candidate-card-name {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.35;
  margin: 0 0 4px;
}
.candidate-card-meta {
  font-size: 11.5px;
  color: var(--ink-muted);
  line-height: 1.4;
  margin: 0;
}
.candidate-card .pick-cta {
  margin-top: auto;
  padding-top: 10px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--primary-deep);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
/* "Show full details" expander inside a candidate card. Lets the user
   inspect the variant — every name, every country, every ingredient —
   before committing to the deep-dive. Collapsed by default. */
.candidate-card-details {
  margin: 8px 0 4px;
  font-size: 12px;
  color: var(--ink-soft);
  line-height: 1.4;
}
.candidate-card-details summary {
  cursor: pointer;
  color: var(--primary-deep);
  font-weight: 600;
  padding: 4px 0;
  list-style: none;
  font-size: 11.5px;
  letter-spacing: 0.02em;
}
.candidate-card-details summary::-webkit-details-marker { display: none; }
.candidate-card-details summary::before { content: '▸ '; font-size: 9px; }
.candidate-card-details[open] summary::before { content: '▾ '; }
.candidate-card-section {
  padding-top: 8px;
  margin-top: 8px;
  border-top: 1px dashed var(--border);
}
.candidate-card-section h6 {
  font-family: var(--font-display);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink);
  margin: 0 0 4px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.candidate-card-section p {
  margin: 0 0 4px;
  font-size: 12px;
  color: var(--ink-soft);
  word-break: break-word;
}
/* Explicit deep-dive button — replaces the previous "whole card is
   clickable" behaviour so users can browse + compare before committing. */
.candidate-card-deepdive {
  margin-top: 12px;
  width: 100%;
  font-size: 12.5px;
  padding: 9px 14px;
}

/* Brand → product loading banner — large, animated, hard to miss. */
.product-loading-banner {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 14px;
  padding: 14px 18px;
  background:
    linear-gradient(135deg, rgba(138,142,240,0.12), rgba(127,217,180,0.10) 70%, transparent 100%),
    #fbfaf3;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
}
.product-loading-banner .shape-cluster {
  width: 44px; height: 44px; flex: 0 0 44px;
}
.product-loading-banner .shape-cluster span {
  animation: pulse 1.2s ease-in-out infinite;
}
.product-loading-banner .shape-cluster .s-tri { animation-delay: .15s; }
.product-loading-banner .shape-cluster .s-cir { animation-delay: .3s;  }
.product-loading-banner .shape-cluster .s-sq  { animation-delay: .45s; }
.product-loading-banner .banner-title {
  font-family: var(--font-display);
  font-size: 16px;
  color: var(--ink);
  margin: 0 0 2px;
}
.product-loading-banner .banner-sub {
  margin: 0;
  font-size: 12.5px;
  color: var(--ink-soft);
}

/* Small helper text under a Tom Select / input (e.g. the product picker
   hint about pressing Enter to search by keyword). */
.field-help {
  font-size: 11.5px;
  color: var(--ink-muted);
  margin: 6px 2px 0;
  line-height: 1.4;
}
.field-help kbd {
  font-family: 'SF Mono', ui-monospace, Menlo, monospace;
  font-size: 10.5px;
  background: var(--primary-tint);
  color: var(--primary-deep);
  padding: 1px 6px;
  border-radius: 4px;
  font-weight: 600;
}

/* ─────────────────── World map (Product Deep Dive) ─────────────────── */
.map-card { padding: 12px; }
.map-container { height: 420px; width: 100%; }
/* jsvectormap regions: cream initial fill via the JS init's `regionStyle`
   (NOT a CSS rule — a CSS `fill` declaration would have higher specificity
   than the JS-applied inline fill on some browsers and silently revert
   our live/discontinued tints). The stroke + selected style are CSS-only. */
.jvm-region { stroke: #ddd9c8; }
.jvm-region.jvm-region-selected { fill: var(--primary); }
.jvm-tooltip {
  background: #fff;
  border: 1px solid var(--border);
  box-shadow: var(--shadow-pop);
  border-radius: 8px;
  padding: 8px 10px;
  font-family: var(--font-body);
  color: var(--ink);
  font-size: 12.5px;
}
.jvm-tooltip h6 { font-family: var(--font-display); font-size: 13px; margin: 0 0 4px; }
.jvm-tooltip p { margin: 0; color: var(--ink-soft); }

/* ─────────────────────── Image gallery (product grid) ───────────────── */
.image-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 16px;
  margin: 6px 0 10px;
}
/* Each backend-rendered card lands here as its own grid cell. The backend
   bundles cards 4-per-row inside <div class="row"> wrappers; the JS
   flattens them so each .thumbnail becomes one tile. */
.image-grid > * {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 12px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink-soft);
  transition: box-shadow var(--transition), transform var(--transition);
}
.image-grid > *:hover {
  box-shadow: var(--shadow-pop);
  transform: translateY(-1px);
}
.image-grid img { max-width: 100%; }
/* Whole card is wrapped in an <a> — reset link styling so the text colour
   comes from .caption rules below, not the default link colour. */
.image-grid a { color: inherit; text-decoration: none; display: block; }
.image-grid .caption { margin-top: 10px; }
.image-grid .caption p { margin: 0; }
/* Brand | Country — small uppercase eyebrow */
.image-grid .caption p.fw-bold {
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--ink-muted);
  margin-bottom: 4px;
}
/* Product name — prominent, dark */
.image-grid .caption p:not(.fw-bold) {
  font-size: 14px;
  line-height: 1.35;
  font-weight: 600;
  color: var(--ink);
}
.image-grid a:hover .caption p:not(.fw-bold) { color: var(--primary-deep); }
.image-grid-actions {
  display: flex;
  justify-content: center;
  margin-top: 8px;
}

/* ─────────────────────── Progress bar (AI analysis) ─────────────────── */
.progress-track {
  height: 10px;
  background: var(--primary-tint);
  border-radius: 5px;
  overflow: hidden;
  margin: 14px 0 4px;
}
.progress-fill {
  height: 100%;
  width: 0%;
  background: var(--primary);
  transition: width 320ms ease;
}
.progress-caption {
  font-size: 12px;
  color: var(--ink-muted);
  text-align: center;
}

/* AI-analysis trigger banner — visually distinct from result cards.
   Gradient cream/periwinkle background, brand shape cluster on the left,
   prominent button on the right. Reads as an action gate, not data. */
.ai-cta-banner {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 24px;
  align-items: center;
  padding: 22px 26px;
  background:
    linear-gradient(135deg, rgba(138,142,240,0.14), rgba(242,189,126,0.10) 70%, transparent 100%),
    #fbfaf3;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
}
.ai-cta-banner .ai-cta-text h3 {
  font-family: var(--font-display);
  font-size: 22px;
  color: var(--ink);
  margin: 0 0 4px;
}
.ai-cta-banner .ai-cta-text p {
  color: var(--ink-soft);
  font-size: 13.5px;
  margin: 0;
  max-width: 640px;
}
.ai-cta-banner .btn { margin-top: 0; }
@media (max-width: 720px) {
  .ai-cta-banner {
    grid-template-columns: 1fr;
    text-align: center;
  }
  .ai-cta-banner > .shape-cluster { margin: 0 auto; }
  .ai-cta-banner .ai-cta-text p { margin: 0 auto; }
}

/* "Running AI analysis…" loading panel — visually identical to the
   onboarding loading state, used to cover the area where the stage-2
   sections will appear so users don't see empty placeholder cards. */
.ai-loading-panel {
  text-align: center;
  padding: 56px 24px 40px;
}
.ai-loading-panel h2 {
  font-family: var(--font-display);
  font-size: 26px;
  color: var(--ink);
  margin: 18px 0 8px;
}
.ai-loading-panel .lead {
  color: var(--ink-soft);
  font-size: 14px;
  max-width: 480px;
  margin: 0 auto;
}
/* Pulse animation on the shape cluster inside the AI loader, matching
   what the onboarding loader does when data-state=loading. */
.ai-loading-panel .shape-cluster span { animation: pulse 1.2s ease-in-out infinite; }
.ai-loading-panel .shape-cluster .s-tri { animation-delay: .15s; }
.ai-loading-panel .shape-cluster .s-cir { animation-delay: .3s; }
.ai-loading-panel .shape-cluster .s-sq  { animation-delay: .45s; }

/* Section-nav links flagged data-ai-stage are hidden until the user has
   actually triggered the AI analysis AND the data is ready — otherwise
   the nav promises sections that don't exist yet. */
#sectionNav a[data-ai-stage] { display: none; }
body[data-ai-stage="ready"] #sectionNav a[data-ai-stage] { display: inline; }

/* Same gating for the Review-AI narrative anchor — hidden until the
   second-stage AI fetch (drivers of positive / negative reviews) has
   landed. */
#sectionNav a[data-review-ai-stage] { display: none; }
body[data-review-ai-stage="ready"] #sectionNav a[data-review-ai-stage] { display: inline; }

/* Consumer review AI narrative — readable serif paragraph styling that
   matches the rest of the page. Engine returns HTML with <p>/<strong>
   that we render inline. Heavily indented bullets etc. get reined in. */
.review-ai-narrative {
  margin-top: 14px;
  font-family: var(--font-serif);
  font-size: 16px;
  line-height: 1.7;
  color: var(--ink);
}
.review-ai-narrative p { margin: 0 0 12px; }
.review-ai-narrative p:last-child { margin-bottom: 0; }
.review-ai-narrative ul, .review-ai-narrative ol { margin: 0 0 12px 22px; padding: 0; }
.review-ai-narrative li { margin: 0 0 6px; }
.review-ai-narrative strong { color: var(--ink-strong, var(--ink)); }
/* Consumer-review AI empty-state — shown when both the positive and
   negative AI fetches return no data. Mirrors the layout of the loading
   panel (shape cluster on the left, message on the right) so users see
   the same "shape" of card transitioning from loading → empty. */
.review-ai-empty {
  display: flex;
  align-items: flex-start;
  gap: 22px;
  border-left: 4px solid var(--accent-peach, #f0c089);
}
.review-ai-empty .shape-cluster { flex-shrink: 0; }
.review-ai-empty-body { flex: 1; min-width: 0; }
.review-ai-empty-body h3 {
  margin: 0 0 8px;
  font-family: var(--font-serif);
  font-size: 22px;
  color: var(--ink, #2c2f43);
}
.review-ai-empty-body p {
  margin: 0 0 10px;
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: 1.6;
  color: var(--ink-soft, #4c5163);
}
.review-ai-empty-body .review-ai-empty-hints {
  margin-bottom: 4px;
  color: var(--ink, #2c2f43);
}
.review-ai-empty-body ul {
  margin: 4px 0 0 18px;
  padding: 0;
  font-family: var(--font-sans);
  font-size: 13.5px;
  line-height: 1.65;
  color: var(--ink-soft, #4c5163);
}
.review-ai-empty-body li { margin: 0 0 4px; }

/* Consumer-review samples — the engine returns flat <tr> rows with a
   broken first <a> tag (no closing </a>) that bleeds into the next
   column. We parse the rows in JS and render each as a card with proper
   visual hierarchy. The wrapper keeps the existing scroll behaviour
   (max-height 600 + overflow:auto from .data-table-wrap). */
.review-samples-wrap { background: var(--surface-soft, #faf7ec); }
.review-samples-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px;
}
.review-sample {
  background: #fff;
  border: 1px solid var(--border-card, #e6e3d7);
  border-radius: 12px;
  padding: 14px 16px;
  box-shadow: 0 1px 2px rgba(31,35,51,.04);
}
.review-sample-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 4px;
}
.review-sample-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  font-family: var(--font-sans);
  font-size: 12px;
  color: var(--ink-muted, #6f7185);
}
.review-sample-meta > span { white-space: nowrap; }
.review-sample-date {
  background: var(--primary-tint, #ecedfc);
  color: var(--primary-deep, #4d52c7);
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
}
.review-sample-retailer { font-weight: 600; color: var(--ink, #2c2f43); }
.review-sample-retailer::after {
  content: '·';
  display: inline-block;
  margin-left: 10px;
  color: var(--ink-muted);
}
.review-sample-brand { color: var(--ink-soft, #4c5163); }
.review-sample-rating {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-sans);
  font-size: 12.5px;
  color: var(--ink-soft, #4c5163);
}
.review-sample-stars {
  color: #e9a93b;
  letter-spacing: 1.2px;
  font-size: 14px;
  line-height: 1;
}
.review-sample-rating-num {
  background: var(--primary-tint, #ecedfc);
  color: var(--primary-deep, #4d52c7);
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
}
.review-sample-product {
  display: block;
  font-family: var(--font-sans);
  font-size: 12.5px;
  color: var(--primary-deep, #4d52c7);
  text-decoration: none;
  margin: 2px 0 6px;
}
.review-sample-product:hover { text-decoration: underline; }
.review-sample-headline {
  font-family: var(--font-serif);
  font-size: 16px;
  font-weight: 600;
  margin: 4px 0 4px;
  color: var(--ink, #2c2f43);
  line-height: 1.35;
}
.review-sample-text {
  font-family: var(--font-sans);
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--ink-soft, #4c5163);
  margin: 0;
}

/* Sections retired from a tool but kept in the DOM so existing JS keeps
   finding its element references. Always hidden — `!important` because
   normal JS state changes (e.g. setting `display:''` after a fetch) must
   not bring the section back. */
.feature-retired { display: none !important; }

/* ───────────────────────────── Responsive ───────────────────────────── */
.sidebar-scrim {
  position: fixed; inset: 0;
  background: rgba(31,35,51,.4);
  z-index: 55;
  display: none;
}

@media (max-width: 1024px) {
  .sidebar { transform: translateX(-100%); }
  body.nav-open .sidebar { transform: translateX(0); box-shadow: var(--shadow-pop); }
  body.nav-open .sidebar-scrim { display: block; }
  .main { margin-left: 0; }
  .kpi-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 620px) {
  .content { padding: 18px 14px 50px; }
  .search-panel { padding: 22px 18px 18px; }
  .search-head h1 { font-size: 25px; }
  .kpi-grid { grid-template-columns: 1fr 1fr; }
  .form-row > * { flex-basis: 100%; }
  .topbar-title { font-size: 16px; }
}
