/* Colour tokens (27 Sep 2026). Light by default; dark follows the device
   (prefers-color-scheme) unless the header toggle picked one, which sets
   data-theme on <html> (inline script in index.html, theme.js). */
:root {
  color-scheme: light;
  --bg: #f7f8fa;
  --surface: #ffffff;
  --surface-2: #f8f9fa;
  --hover: #f2f5f8;
  --text: #1a1a1a;
  --text-2: #495057;
  --muted: #6c757d;
  --border: #dee2e6;
  --border-strong: #ced4da;
  --accent: #1c7ed6;
  --accent-soft: #e7f0fb;
  --accent-soft-hover: #d0e4f8;
  --accent-border: #c5dcf5;
  --accent-ink: #1c4f82;
  --track: #eeeeee;
  --good: #2f9e44;
  --good-bg: #d3f9d8;
  --bad: #e03131;
  --bad-bg: #ffe3e3;
  --bad-ink: #c92a2a;
  --mid: #f08c00;
  --warn-bg: #fff3bf;
  --warn-bg-2: #fff9db;
  --warn-border: #ffe066;
  --warn-ink: #7a5c00;
  --orange-bg: #ffe8cc;
  --demo-bg: #fffdf2;
  --test-bg: #f3f0ff;
  --test-bg-2: #e5dbff;
  --test-border: #d0bfff;
  --test-ink: #5f3dc4;
  --auto-ink: #9c36b5;
  --card-hover-border: #c7d6e5;
  --chart-line: #1c7ed6;
  --chart-ak: #e8590c;
  --chart-same: #868e96;
  --chart-area: rgba(28, 126, 214, 0.10);
  --chart-grid: #edf0f3;
  --chart-axis: #868e96;
  --chart-ref: #adb5bd;
  --chart-ref-text: #495057;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #0f141a;
    --surface: #1a2129;
    --surface-2: #212a33;
    --hover: #26303b;
    --text: #e6e9ec;
    --text-2: #c1c7cd;
    --muted: #98a2ad;
    --border: #2f3a45;
    --border-strong: #46535f;
    --accent: #4dabf7;
    --accent-soft: #1b3048;
    --accent-soft-hover: #22405f;
    --accent-border: #2b4f78;
    --accent-ink: #a5d8ff;
    --track: #2b3642;
    --good: #51cf66;
    --good-bg: #173d22;
    --bad: #ff6b6b;
    --bad-bg: #3d1c1c;
    --bad-ink: #ff8787;
    --mid: #ffa94d;
    --warn-bg: #3a3112;
    --warn-bg-2: #2e2710;
    --warn-border: #6b5a14;
    --warn-ink: #ffd866;
    --orange-bg: #3d2a12;
    --demo-bg: #242010;
    --test-bg: #241d38;
    --test-bg-2: #33285a;
    --test-border: #5f4b9a;
    --test-ink: #d0bfff;
    --auto-ink: #e599f7;
    --card-hover-border: #3d5a78;
    --chart-line: #4dabf7;
    --chart-ak: #ff922b;
    --chart-same: #adb5bd;
    --chart-area: rgba(77, 171, 247, 0.14);
    --chart-grid: #27313b;
    --chart-axis: #98a2ad;
    --chart-ref: #5c6b79;
    --chart-ref-text: #c1c7cd;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0f141a;
  --surface: #1a2129;
  --surface-2: #212a33;
  --hover: #26303b;
  --text: #e6e9ec;
  --text-2: #c1c7cd;
  --muted: #98a2ad;
  --border: #2f3a45;
  --border-strong: #46535f;
  --accent: #4dabf7;
  --accent-soft: #1b3048;
  --accent-soft-hover: #22405f;
  --accent-border: #2b4f78;
  --accent-ink: #a5d8ff;
  --track: #2b3642;
  --good: #51cf66;
  --good-bg: #173d22;
  --bad: #ff6b6b;
  --bad-bg: #3d1c1c;
  --bad-ink: #ff8787;
  --mid: #ffa94d;
  --warn-bg: #3a3112;
  --warn-bg-2: #2e2710;
  --warn-border: #6b5a14;
  --warn-ink: #ffd866;
  --orange-bg: #3d2a12;
  --demo-bg: #242010;
  --test-bg: #241d38;
  --test-bg-2: #33285a;
  --test-border: #5f4b9a;
  --test-ink: #d0bfff;
  --auto-ink: #e599f7;
  --card-hover-border: #3d5a78;
  --chart-line: #4dabf7;
    --chart-ak: #ff922b;
    --chart-same: #adb5bd;
  --chart-area: rgba(77, 171, 247, 0.14);
  --chart-grid: #27313b;
  --chart-axis: #98a2ad;
  --chart-ref: #5c6b79;
  --chart-ref-text: #c1c7cd;
}

* { box-sizing: border-box; }

body {
  font-family: -apple-system, Segoe UI, Roboto, sans-serif;
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
}

header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 20px;
  background: #12263a;
  color: white;
}

header h1 { font-size: 18px; margin: 0; }

header button {
  background: var(--accent);
  color: white;
  border: none;
  padding: 8px 14px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
}

#userLabel { margin-right: 10px; font-size: 14px; opacity: 0.85; }

main {
  max-width: 1400px;
  margin: 0 auto;
  padding: 16px 24px 40px;
}

/* Control panel: add-product form + bulk-action buttons, grouped into one
   card instead of stacking as loose, inconsistently-styled elements. */
#controlPanel {
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px 16px;
  margin-bottom: 16px;
}
#controlPanel[hidden] { display: none; }

.panel-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

#addForm { margin: 0; }

#addUrlInput {
  background: var(--surface);
  color: var(--text);
  flex: 1;
  min-width: 200px;
  padding: 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 14px;
}

#addForm button {
  padding: 8px 14px;
  border: none;
  border-radius: 6px;
  background: var(--accent);
  color: white;
  cursor: pointer;
}

.panel-actions { padding-top: 4px; border-top: 1px solid var(--border); margin-top: 2px; }

#discoverBtn,
#checkAllBtn,
#scrubBtn {
  padding: 7px 14px;
  border: 1px solid var(--accent);
  border-radius: 6px;
  background: var(--surface);
  color: var(--accent);
  cursor: pointer;
  font-size: 13px;
}
#discoverBtn:disabled,
#checkAllBtn:disabled,
#scrubBtn:disabled { opacity: 0.6; cursor: default; }

.panel-status { font-size: 13px; color: var(--text-2); min-height: 16px; }
.panel-status:empty { min-height: 0; }
.lbl-short { display: none; }

/* Control bar: store tabs + group-by toggle */
#controlBar {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 10px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}

/* Search: its own light panel directly above the product grid (so it reads
   as part of the list), sticky so it stays reachable while scrolling a long
   list. Colours are set explicitly -- with `color-scheme: light dark` a
   phone in dark mode otherwise gives the input a dark default background,
   which made it look disabled. */
#searchPanel {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--accent-soft);
  border: 1px solid var(--accent-border);
  border-radius: 10px;
  padding: 10px 14px;
  margin-bottom: 16px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.08);
}
#searchPanel .search-wrap { position: relative; }
#searchInput {
  width: 100%;
  box-sizing: border-box;
  padding: 11px 40px 11px 40px;
  border: 2px solid var(--border-strong);
  border-radius: 10px;
  background-color: var(--surface);
  /* Magnifying-glass icon, drawn inline so there's no extra file. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='%23495057' stroke-width='2.5' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='16.5' y1='16.5' x2='21' y2='21'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 13px center;
  color: var(--text);
  /* 16px stops iOS zooming the page when the box is focused. */
  font-size: 16px;
  color-scheme: light;
}
#searchInput::placeholder { color: var(--muted); }
/* Says what the box is for, under it -- the placeholder alone disappears
   as soon as you start typing. */
#searchHint {
  margin-top: 5px;
  font-size: 12px;
  color: var(--accent-ink);
}
#searchInput:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(28,126,214,0.2); }
/* Our own clear button instead of the browser's (inconsistent across phones). */
#searchInput::-webkit-search-cancel-button { display: none; }
#searchClear {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  border: none;
  background: none;
  color: var(--muted);
  font-size: 22px;
  line-height: 1;
  padding: 4px 8px;
  cursor: pointer;
}
#searchClear[hidden] { display: none; }

/* Wrap onto more lines rather than running off the side: on a phone the
   category row alone was 810px wide, which made the whole page wider than
   the screen -- sideways scrolling, and it broke the sticky search panel
   (it pinned to the oversized layout, off-screen). */
.tab-group { display: flex; gap: 4px; flex-wrap: wrap; min-width: 0; }

.tab {
  padding: 6px 14px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
  cursor: pointer;
}
.tab:hover { background: var(--hover); }
.tab-active { background: var(--accent-soft); color: var(--accent); }
.tab-sm { padding: 4px 10px; font-weight: 500; }

.control-sep { width: 1px; height: 20px; background: var(--border); }

/* Store / Group by / Sort rows. Inline across one line on a wide screen. */
#controlRows { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.control-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
/* Phone-only "Filter & sort" button; hidden on wide screens. */
#controlsToggle {
  display: none;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: var(--surface);
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}
#controlsToggle #controlsSummary {
  color: var(--accent);
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#controlsToggle .caret { color: var(--muted); transition: transform 0.15s; }
#controlsToggle.open .caret { transform: rotate(180deg); }

.group-label { font-size: 13px; color: var(--muted); }

#productCount { margin-left: auto; font-size: 12px; color: var(--muted); }

#categoryBar {
  /* A full-width row inside the Filter & sort panel, under a hairline. */
  flex: 1 0 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}
/* Same specificity trap as #detailOverlay above -- an ID's own display
   rule beats the browser's default [hidden] { display: none }. */
#categoryBar[hidden] { display: none; }
#categoryTabs[hidden] { display: none; }

#categoryToggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: var(--surface);
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
#categoryToggle #categoryCurrent { color: var(--accent); }
#categoryToggle .caret { color: var(--muted); transition: transform 0.15s; }
#categoryToggle.open .caret { transform: rotate(180deg); }
/* When open, the tabs take their own full line under the button. */
#categoryTabs { flex-basis: 100%; }

#freshnessBar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  margin-bottom: 16px;
}
#freshnessBar[hidden] { display: none; }

#freshnessTrack {
  flex-shrink: 0;
  width: 140px;
  height: 8px;
  background: var(--track);
  border-radius: 4px;
  overflow: hidden;
}
#freshnessFill {
  height: 100%;
  background: var(--mid); /* amber while some are stale/unchecked */
  border-radius: 4px;
  transition: width 0.3s ease;
}
#freshnessFill.all-fresh { background: var(--good); }

#freshnessLabel { font-size: 12px; color: var(--muted); }

.demo-badge {
  font-size: 9px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--warn-bg);
  color: var(--warn-ink);
}

/* Same amber-for-stale semantic as #freshnessFill, just per-card. */
.stale-badge {
  font-size: 9px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--orange-bg);
  color: var(--mid);
}

.dup-badge {
  font-size: 9px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--bad-bg);
  color: var(--bad);
}

.dup-heading { color: var(--bad); }

.demo-note {
  font-size: 12px;
  color: var(--warn-ink);
  background: var(--warn-bg-2);
  border: 1px solid var(--warn-border);
  border-radius: 6px;
  padding: 8px 10px;
  margin: 8px 0;
}

/* Card grid */
.grid-section { margin-bottom: 28px; }
.grid-section-heading {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  transition: box-shadow 0.15s, border-color 0.15s;
}
.card:hover { box-shadow: 0 2px 10px rgba(0,0,0,0.08); border-color: var(--card-hover-border); }

/* Must come after .card/.card:hover -- same specificity, so source order
   decides, and this needs to win to actually show the amber highlight.
   A tinted background + thicker border since this is now the only signal
   marking it out (no more surrounding "Live Demo" section/banner). */
.demo-card { position: relative; background: var(--demo-bg); border-width: 2px; border-color: #ffd43b; }
.demo-card:hover { border-color: #f5c400; box-shadow: 0 2px 10px rgba(245, 196, 0, 0.25); }

.live-demo-tag {
  position: absolute;
  bottom: 8px;
  right: 8px;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 3px 7px;
  border-radius: 4px;
  background: #ffd43b;
  color: #7a5c00; /* fixed: dark-on-yellow reads in both themes */
  pointer-events: none;
}

.card-image {
  width: 100%;
  height: 140px;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-bottom: 1px solid var(--border);
}
.card-image img { max-width: 88%; max-height: 88%; object-fit: contain; }
.card-image-placeholder { font-size: 11px; color: var(--muted); }

.card-body {
  padding: 10px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex-grow: 1;
}

.card-badges { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }

.card-name {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  min-height: 34px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card-price-row {
  margin-top: auto;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 8px;
}
.card-price-row .price { font-size: 18px; font-weight: 700; }
/* Cheapest-ever price, bottom right of each card -- a quick read of how the
   current price compares without opening the detail view. */
.card-price-row .lowest-price {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  font-size: 14px;
  font-weight: 700;
  color: var(--good);
  line-height: 1.1;
}
.card-price-row .lowest-when {
  font-size: 10px;
  font-weight: 500;
  color: var(--muted);
  margin-top: 1px;
}
.card-price-row .lowest-label {
  font-size: 9px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.8;
}

.store-badge {
  display: inline-block;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--accent-soft);
  color: var(--accent);
}

.auto-badge { font-size: 9px; font-weight: 700; padding: 2px 6px; border-radius: 4px; background: var(--test-bg); color: var(--auto-ink); }

.trend { display: inline-block; font-size: 11px; padding: 2px 6px; border-radius: 10px; background: var(--track); align-self: flex-start; }
.trend.good { background: var(--good-bg); color: var(--good); }
.trend.bad { background: var(--bad-bg); color: var(--bad); }
.trend.mid { background: var(--warn-bg); color: var(--mid); }

.oos, .err { display: inline-block; font-size: 11px; padding: 2px 6px; border-radius: 10px; background: var(--bad-bg); color: var(--bad); }

#emptyState { color: var(--muted); font-size: 14px; padding: 40px; text-align: center; }

/* Detail overlay (modal) */
#detailOverlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 10;
}
/* The ID rule above beats the browser's default [hidden] { display: none }
   (an ID selector always outranks a plain attribute selector), so without
   this the overlay stayed visually shown as an empty flex box even while
   its `hidden` attribute was correctly toggled off. */
#detailOverlay[hidden] { display: none; }

#detailPanel {
  position: relative;
  background: var(--surface);
  border-radius: 10px;
  padding: 24px;
  max-width: 680px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
}

#detailPanel h2 { margin: 0; font-size: 18px; }

/* "← Back" (was a small ×, hard to hit on a phone). Sticky so it stays
   reachable while scrolling a long product view. */
#detailCloseBtn {
  position: sticky;
  top: 0;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  margin: 0 0 10px;
  padding: 8px 16px;
  border: 1px solid var(--accent-border);
  border-radius: 8px;
  background: var(--accent-soft);
  color: var(--accent-ink);
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 1px 4px rgba(0,0,0,0.08);
}
#detailCloseBtn:hover { background: var(--accent-soft-hover); }

/* Product photo beside the name. */
.detail-head { display: flex; align-items: center; gap: 14px; margin-bottom: 6px; }
.detail-head h2 { margin: 0; }
.detail-image {
  width: 110px;
  height: 110px;
  flex: none;
  object-fit: contain;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.detail-stats { display: flex; gap: 24px; margin: 16px 0; }
.detail-stats .label { display: block; font-size: 12px; color: var(--muted); }
.detail-stats .value { display: block; font-size: 20px; font-weight: 700; }
.detail-updated { font-size: 12px; color: var(--muted); margin-bottom: 4px; }

/* Sized here, drawn at this size x device pixel ratio by drawPriceChart. */
#priceChart {
  display: block;
  width: 100%;
  height: 230px;
  margin-top: 10px;
  cursor: crosshair;
  /* Horizontal drags read prices; vertical still scrolls the page. */
  touch-action: pan-y;
}

#chartTooltip {
  position: fixed;
  z-index: 20;
  background: #1a1a1a;
  color: white;
  font-size: 12px;
  line-height: 1.4;
  padding: 6px 10px;
  border-radius: 6px;
  pointer-events: none;
  white-space: nowrap;
}
#chartTooltip[hidden] { display: none; }
.chart-note { font-size: 12px; color: var(--muted); }

.detail-actions { display: flex; gap: 8px; margin-top: 16px; }
.detail-actions button {
  font-size: 13px;
  padding: 6px 14px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--surface);
  color: var(--text);
  cursor: pointer;
}
#detailRemoveBtn { color: var(--bad); }

/* ---- Cheapest vendor (informational, understated on purpose) ---- */
.vendor-box {
  margin: 8px 0 4px;
  padding: 8px 12px;
  border-left: 3px solid var(--border-strong);
  background: var(--surface-2);
  color: var(--text);
  font-size: 13px;
  border-radius: 0 6px 6px 0;
}
.vendor-stock, .vendor-other, .vendor-note { color: var(--muted); }
.vendor-link { display: inline-block; margin: 3px 0; color: var(--accent); }
.vendor-other { font-size: 12px; }
.vendor-other a { color: var(--muted); }
.vendor-note { font-size: 11px; margin-top: 3px; }

/* ---- Test / Dev products (functions/testProducts.js) ---- */
.test-badge {
  font-size: 9px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--test-bg-2);
  color: var(--test-ink);
  text-transform: uppercase;
}
.test-card { border-style: dashed; }
.test-note {
  font-size: 12px;
  color: var(--test-ink);
  background: var(--test-bg);
  border: 1px solid var(--test-border);
  border-radius: 6px;
  padding: 8px 10px;
  margin: 8px 0;
}

/* ---- Price alerts (alerts-ui.js) ---- */
.watch-badge { font-size: 11px; line-height: 1; }

header .alerts-btn { background: transparent; border: 1px solid rgba(255,255,255,0.5); margin-right: 8px; }

.alert-box {
  margin-top: 16px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--text);
  font-size: 13px;
}
.alert-box-muted { color: var(--muted); }
.alert-box-title { font-weight: 700; margin-bottom: 8px; }
.alert-box .alert-on {
  font-size: 10px;
  font-weight: 700;
  color: white;
  background: var(--good);
  border-radius: 8px;
  padding: 1px 7px;
  margin-left: 4px;
  vertical-align: middle;
}
/* Trigger chips: one row, highlighted when ticked. */
.alert-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 11px;
  border: 1px solid var(--border-strong);
  border-radius: 18px;
  background: var(--surface);
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
  user-select: none;
}
.chip input[type="checkbox"] { margin: 0; accent-color: var(--accent); }
.chip:has(input[type="checkbox"]:checked) { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-ink); }
.alert-box input[type="number"] {
  width: 64px;
  padding: 2px 5px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: 14px;
  color: var(--text);
  background: var(--surface);
  color-scheme: light;
}
.alert-box-actions { display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.alert-box-actions button,
.alerts-actions button {
  font-size: 13px;
  padding: 6px 14px;
  border: none;
  border-radius: 6px;
  background: var(--accent);
  color: white;
  cursor: pointer;
}
.alert-box-actions .btn-secondary,
.alerts-actions .btn-secondary { background: var(--surface); color: var(--text); border: 1px solid var(--border); }
.alert-box-status { font-size: 12px; color: var(--text-2); }
.alert-box-oos { font-size: 12px; color: var(--bad-ink); margin-top: 6px; }
.alert-box-hint { font-size: 11px; color: var(--muted); margin-top: 8px; }

.replay-box { margin-top: 10px; font-size: 12px; color: var(--text); }
.replay-box summary { cursor: pointer; }
.replay-note { color: var(--muted); margin: 4px 0; }
/* Fold-out notes on the product view (test data / imported history). */
details.test-note summary, details.demo-note summary { cursor: pointer; }
.replay-list { margin: 4px 0 0; padding-left: 18px; color: var(--text-2); }
.replay-list span { display: inline-block; min-width: 52px; color: var(--muted); }
.replay-more { color: var(--muted); margin-top: 2px; }

#alertsPanel {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  z-index: 15;
}
#alertsPanel[hidden] { display: none; }
.alerts-card {
  position: relative;
  background: var(--surface);
  color: var(--text);
  border-radius: 10px;
  padding: 24px;
  max-width: 520px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  font-size: 14px;
}
.alerts-card h2 { margin: 0 24px 12px 0; font-size: 18px; }
.alerts-card h3 { font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); margin: 16px 0 6px; }
.alerts-close {
  position: absolute;
  top: 16px;
  right: 16px;
  border: none;
  background: none;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  color: var(--muted);
}
.alerts-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.alerts-state { margin: 0 0 8px; }
.alerts-status { font-size: 13px; color: var(--text-2); min-height: 1em; }
.alerts-hint { font-size: 12px; color: var(--muted); }
.alerts-list { margin: 0; padding-left: 18px; }
.alerts-list li { margin: 6px 0; }
.alerts-list span, .alerts-list small { color: var(--text-2); }

@media (max-width: 700px) {
  main { padding: 12px; }
  #controlBar { gap: 8px; padding: 10px 12px; }
  #productCount { width: 100%; margin-left: 0; order: 10; }
  /* Controls fold behind the "Filter & sort" button; when open, one
     labelled row each, options wrapping under a fixed-width label. */
  #controlsToggle { display: flex; }
  #controlRows { display: none; flex-direction: column; align-items: stretch; gap: 8px; width: 100%; }
  #controlBar.controls-open #controlRows { display: flex; }
  .control-sep { display: none; }
  .control-row { align-items: flex-start; }
  .control-row .group-label { flex: none; width: 66px; padding-top: 6px; }
  .control-row .tab-group { flex: 1; }
  /* Header on a phone (user, 27 Sep: "a desktop single line of buttons
     wrapped onto multiple lines"): the name on one line with the theme
     toggle at its right, then About / Alerts / Sign in as one even row. */
  header {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    align-items: center;
    gap: 10px 8px;
    padding: 10px 12px 12px;
  }
  header > div { display: contents; }
  header h1 { grid-column: 1 / 3; grid-row: 1; font-size: 17px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  header #themeBtn { grid-column: 3; grid-row: 1; justify-self: end; margin: 0; width: 40px; height: 36px; padding: 0; }
  header #aboutBtn, header #alertsBtn, header #signInBtn, header #signOutBtn {
    grid-row: 2; width: 100%; margin: 0; padding: 9px 4px; font-size: 14px; white-space: nowrap;
  }
  header #signOutBtn { background: transparent; border: 1px solid rgba(255,255,255,0.5); }
  #userLabel { display: none; }

  /* Long list, round 2 (27 Sep): two compact cards across on a phone
     instead of one big card per row -- roughly half the scrolling. */
  .card-grid { grid-template-columns: 1fr 1fr; gap: 8px; }
  .card-image { height: 96px; }
  .card-body { padding: 8px 9px 9px; gap: 4px; }
  .card-badges { gap: 4px; }
  .card-name { font-size: 12px; min-height: 31px; }
  .card-price-row { flex-direction: column; align-items: flex-start; gap: 2px; }
  .card-price-row .price { font-size: 16px; }
  .card-price-row .lowest-price { flex-direction: row; align-items: baseline; gap: 4px; font-size: 12px; }
  .card-price-row .lowest-when { display: none; } /* the month is on the product page */
  .card-price-row .lowest-label { white-space: nowrap; }

  /* Owner panel on a phone: search box full width, Paste / Add as an even
     pair, the three tools as one even row with short labels. */
  #addForm { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  #addUrlInput { grid-column: 1 / -1; min-width: 0; padding: 10px; font-size: 16px; }
  #addForm button { width: 100%; padding: 10px 6px; font-size: 14px; }
  .panel-actions { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; padding-top: 10px; }
  #discoverBtn, #checkAllBtn, #scrubBtn { width: 100%; padding: 9px 4px; font-size: 13px; white-space: nowrap; }
  .lbl-long { display: none; }
  .lbl-short { display: inline; }
  #searchPanel { padding: 8px 10px; }

  /* Product view: full screen on a phone instead of a floating card, with
     tighter spacing; the close button stays reachable while scrolling. */
  #detailOverlay { padding: 0; align-items: stretch; }
  #detailPanel {
    max-width: none;
    max-height: none;
    height: 100dvh;
    border-radius: 0;
    padding: 12px 14px 28px;
    box-sizing: border-box;
  }
  #detailCloseBtn { width: 100%; justify-content: flex-start; }
  #detailPanel h2 { font-size: 16px; margin: 0; }
  .detail-image { width: 88px; height: 88px; }
  #priceChart { height: 190px; }
  .detail-stats { gap: 14px; margin: 10px 0 4px; }
  .detail-stats .value { font-size: 17px; }
  .alert-box { margin-top: 10px; padding: 10px 12px; }
  .alert-box-actions button { flex: 1; }
}

/* ---- "The numbers" panel (wraps the cheapest-vendor lines) ---- */
.numbers-title { margin: 0 0 4px; font-size: 13px; font-weight: 700; letter-spacing: 0.02em; }
.numbers-facts { margin: 0 0 6px; padding-left: 18px; }
.numbers-facts li { margin: 2px 0; line-height: 1.4; }
.numbers-packs { margin-top: 6px; }
.numbers-packs a { color: var(--muted); }
.numbers-muted { color: var(--muted); font-size: 12px; list-style: none; margin-left: -18px; }

/* ---- Footer disclaimer ---- */
/* Full width, edge to edge, and the same on a phone: the text just
   reflows to whatever width the screen is (no max-width, no phone-only rule). */
.site-footer {
  width: 100%;
  box-sizing: border-box;
  padding: 16px clamp(16px, 3vw, 24px) 28px;
  border-top: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--muted);
  font-size: 12px;
  line-height: 1.5;
}
.site-footer p { margin: 0 0 6px; }
.site-footer b { color: var(--text-2); }

/* Coverage line (ACCC: up front, not fine print) */
.coverage-line { margin: 0 0 12px; color: var(--text-2); font-size: 13px; line-height: 1.4; }

/* ---- Old Mate: modals (About, Sign in), feedback card, the Shed (27 Sep) ---- */
.om-modal {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  z-index: 15;
}
.om-modal[hidden] { display: none; }
.om-card p { line-height: 1.5; }
.om-muted { color: var(--muted); font-size: 13px; }
.om-list { padding-left: 18px; margin: 0; }
.om-list li { margin: 6px 0; line-height: 1.45; }
.om-signoff { margin-top: 16px; }
.om-why { background: var(--surface-2); border-left: 3px solid var(--border-strong); padding: 8px 12px; margin: 0 0 14px; border-radius: 0 6px 6px 0; }
.om-why p { margin: 4px 0; font-size: 13px; }
.om-google { width: 100%; }
.om-or { text-align: center; color: var(--muted); font-size: 12px; margin: 14px 0 6px; position: relative; }
.om-or::before { content: ""; position: absolute; left: 0; right: 0; top: 50%; border-top: 1px solid var(--border); }
.om-or span { background: var(--surface); padding: 0 8px; position: relative; }
.om-banter { font-size: 13px; color: var(--text-2); margin: 6px 0 10px; }
.om-email-form { display: flex; gap: 8px; flex-wrap: wrap; }
.om-email-form input { flex: 1 1 200px; min-width: 0; padding: 8px 10px; border: 1px solid var(--border-strong); border-radius: 6px; font-size: 16px; color: var(--text); background: var(--surface); }
.link-btn { background: none; border: none; padding: 0; color: var(--accent); text-decoration: underline; cursor: pointer; font: inherit; }

#feedbackHome { margin: 24px 0 8px; }
.om-feedback {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  color: var(--text);
  max-width: 640px;
}
#detailFeedback .om-feedback { margin-top: 16px; }
.om-feedback h3 { margin: 0 0 4px; font-size: 16px; }
.om-choices { display: grid; gap: 6px; margin: 10px 0; }
.om-choice {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface); cursor: pointer; font-size: 14px;
}
.om-choice:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.om-choice input { margin: 0; accent-color: var(--accent); color-scheme: light; }
.om-icon { min-width: 3.6em; text-align: center; white-space: nowrap; }
.om-comment { width: 100%; box-sizing: border-box; padding: 8px 10px; border: 1px solid var(--border-strong); border-radius: 6px; font: inherit; font-size: 16px; color: var(--text); background: var(--surface); }
.om-hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.om-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 8px; }
.om-actions button:disabled { opacity: 0.5; cursor: default; }
.om-shout { font-weight: 600; color: var(--accent); }

#shed { margin: 0 0 16px; }
#shed[hidden] { display: none; }
#shed details { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 10px 14px; color: var(--text); }
#shed summary { cursor: pointer; font-weight: 700; }
#shed h4 { margin: 16px 0 6px; font-size: 13px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); }
.shed-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 8px; margin-top: 10px; }
.shed-tile { border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; }
.shed-value { font-size: 22px; font-weight: 700; }
.shed-label { font-size: 12px; color: var(--text-2); }
.shed-note { font-size: 11px; color: var(--muted); margin-top: 2px; }
.shed-chart { width: 100%; height: auto; max-width: 720px; display: block; }
.shed-axis { stroke: var(--border-strong); stroke-width: 1; }
.shed-tick { font-size: 14px; fill: var(--muted); }
.shed-fill { fill: var(--accent); }
.shed-hit { fill: transparent; }
.shed-bar:hover .shed-fill { fill: #1864ab; }
.shed-list { margin: 0; padding-left: 20px; }
.shed-list li { margin: 3px 0; }
.shed-feedback { list-style: none; padding: 0; margin: 0; }
.shed-feedback li { border-top: 1px solid var(--border); padding: 8px 0; }
.shed-fb-head { font-size: 13px; }
.shed-fb-comment { margin: 4px 0; white-space: pre-wrap; }
.om-card button:not(.alerts-close):not(.link-btn),
.om-feedback button,
#shed button,
.om-danger {
  padding: 8px 14px;
  border: none;
  border-radius: 6px;
  background: var(--accent);
  color: white;
  cursor: pointer;
  font-size: 14px;
}
#shed .btn-secondary { background: var(--surface); color: var(--accent); border: 1px solid var(--accent); }
.om-danger { background: var(--surface); color: var(--bad-ink); border: 1px solid var(--bad-ink); }
.om-unsub { margin-top: 20px; text-align: right; }
.om-unsub .link-btn { color: var(--muted); font-size: 12px; }

/* Theme toggle (header) */
header .theme-btn { background: transparent; border: 1px solid rgba(255,255,255,0.5); margin-right: 8px; padding: 8px 10px; }

/* Owner "Find a product to add" (27 Sep) */
#addForm .btn-paste { background: var(--surface); color: var(--accent); border: 1px solid var(--accent); }
.add-results { list-style: none; margin: 6px 0 0; padding: 0; border: 1px solid var(--border); border-radius: 8px; max-height: 50vh; overflow-y: auto; background: var(--surface); }
.add-results[hidden] { display: none; }
.add-results li { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-top: 1px solid var(--border); font-size: 13px; }
.add-results li:first-child { border-top: none; }
.add-name { flex: 1; min-width: 0; }
.add-price { color: var(--muted); white-space: nowrap; }
.add-results button { padding: 6px 12px; border: none; border-radius: 6px; background: var(--accent); color: white; cursor: pointer; font-size: 13px; }
.add-tracked { font-size: 12px; color: var(--good); white-space: nowrap; }

/* Long list: "Show all N" per group, and a back-to-top button (27 Sep) */
.show-all-btn {
  display: block;
  margin: 10px auto 4px;
  padding: 8px 18px;
  border: 1px solid var(--accent);
  border-radius: 18px;
  background: var(--surface);
  color: var(--accent);
  font-size: 14px;
  cursor: pointer;
}
.to-top {
  position: fixed;
  right: 16px;
  bottom: 20px;
  z-index: 10;
  padding: 10px 14px;
  border: none;
  border-radius: 22px;
  background: var(--accent);
  color: white;
  font-size: 14px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.25);
  cursor: pointer;
}
.to-top[hidden] { display: none; }

/* Notification summary card (27 Sep) */
.alert-summary h2 { font-size: 17px; margin-right: 0; }
.alert-summary-body { font-size: 15px; line-height: 1.5; margin: 6px 0 16px; }
.alert-summary-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.om-card .alert-summary-actions button.btn-secondary { background: var(--surface); color: var(--text); border: 1px solid var(--border-strong); }

/* Alerts panel: product links (27 Sep) */
.alert-links { font-size: 13px; }
.alert-links a { color: var(--accent); }

/* "Press Back again to leave" note (27 Sep) */
.leave-toast {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  z-index: 30;
  padding: 10px 16px;
  border-radius: 20px;
  background: #1a1a1a;
  color: white;
  font-size: 14px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.3);
  white-space: nowrap;
}
.leave-toast[hidden] { display: none; }

/* About -> feedback card: a brief highlight so it's obvious where you landed */
#feedbackHome.om-flash .om-feedback { box-shadow: 0 0 0 3px var(--accent); transition: box-shadow 0.3s; }
#feedbackHome { scroll-margin-top: 140px; } /* clear of the sticky search panel */

/* Whole-store search results + store product view (27 Sep) */
.list-cue { margin: 0 0 12px; font-size: 13px; color: var(--text-2); line-height: 1.45; }
#storeResults { margin: 0 0 16px; background: var(--surface); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
#storeResults[hidden] { display: none; }
.store-results-head { padding: 10px 14px; font-size: 13px; font-weight: 700; color: var(--text); border-bottom: 1px solid var(--border); }
.store-results-head .muted, .store-watch .muted { font-weight: 400; color: var(--muted); }
.store-results { list-style: none; margin: 0; padding: 0; max-height: 290px; overflow-y: auto; } /* about 5 rows; scroll for the rest (user, 27 Sep) */
.store-results li + li { border-top: 1px solid var(--border); }
.store-row { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%; padding: 10px 14px; border: none; background: none; text-align: left; cursor: pointer; color: var(--text); font: inherit; }
.store-row:hover { background: var(--hover); }
.store-row-name { font-size: 14px; }
.store-row-meta { font-size: 12px; color: var(--muted); }
.store-row-meta .on-list { color: var(--good); font-weight: 600; }
.store-watch { margin: 12px 0; padding: 12px 14px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface-2); }
.store-watch p { margin: 6px 0 0; font-size: 13px; }
.store-watch-btn { padding: 9px 16px; border: none; border-radius: 6px; background: var(--accent); color: white; font-size: 14px; cursor: pointer; }
.store-watch-btn:disabled { opacity: 0.6; cursor: default; }

/* Photos switched off from the Shed (siteConfig.showImages = false) */
.no-images .card-image,
.no-images .detail-image { display: none !important; }

/* "Lowest ever*" card badge (27 Sep) */
.lowest-ever { margin: 2px 0 4px; line-height: 1.3; }
.lowest-ever-tag { display: inline-block; padding: 1px 6px; border-radius: 4px; background: var(--good-bg); color: var(--good); border: 1px solid var(--good); font-size: 11px; font-weight: 700; letter-spacing: 0.02em; }
.lowest-ever-note { display: block; font-size: 11px; color: var(--muted); margin-top: 2px; }

/* Feedback folded behind a quiet toggle (27 Sep): product panel + footer */
.om-fold > summary { cursor: pointer; font-size: 14px; font-weight: 600; color: var(--text-2); padding: 6px 0; list-style-position: inside; }
.om-fold > summary .om-muted { font-weight: 400; }
.om-fold[open] > summary { margin-bottom: 6px; }
#feedbackHome { margin: 0 0 12px; text-align: left; }
.om-ps { font-size: 13px; color: var(--text-2); margin-top: 10px; }
.om-shout-msg { margin: 6px 0; font-size: 14px; }
.om-feedback .om-shout-btn:disabled { opacity: 0.6; cursor: default; }

/* Price history panel (27 Sep): heading, explainer, smaller chart, legend */
.chart-panel { margin: 12px 0; padding: 12px 14px; border: 1px solid var(--border); border-radius: 8px; background: var(--surface-2); }
.chart-title { margin: 0; font-size: 15px; }
.chart-explain { margin: 2px 0 0; font-size: 13px; color: var(--text-2); line-height: 1.4; }
.chart-panel #priceChart { height: 200px; }
.chart-legend { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 6px; font-size: 12px; color: var(--text-2); }
.chart-legend[hidden] { display: none; }
.chart-legend span { display: inline-flex; align-items: center; gap: 5px; }
.chart-legend .sw { display: inline-block; width: 14px; height: 4px; border-radius: 2px; }
.sw-4wd { background: var(--chart-line); }
.sw-ak { background: var(--chart-ak); }
.sw-same { background: var(--chart-same); }
.chart-today { margin: 6px 0 0; font-size: 14px; }
.chart-panel .chart-note { margin: 4px 0 0; }
@media (max-width: 700px) { .chart-panel #priceChart { height: 170px; } }

/* Shop names: full on desktop, short on a phone */
.nm-short { display: none; }
@media (max-width: 700px) { .nm-full { display: none; } .nm-short { display: inline; } }
