/* ══════════════════════════════════════════════════════════════════════════
   MyDealDrop — shared styles.

   Redesigned on the Modernist system: flat, architectural, Archivo throughout,
   a single red accent on a bone ground, zero corner radius, strong 2px rules.
   Nothing floats; alignment and the strength of the dividers do the organising.

   Every class name from the previous stylesheet is preserved, so the existing
   pages and js/app.js keep working — only the look changed. New classes are
   grouped at the bottom under "Redesign additions".
   ══════════════════════════════════════════════════════════════════════ */

/* Archivo (SIL Open Font License), self-hosted. It used to come from Google
   Fonts via @import, which made every page wait on a third-party server before
   it could paint - and a slow response there stalled whole pages. One variable
   file per script subset covers every weight; the browser downloads only the
   subset a page actually uses (unicode-range). font-display: swap shows text
   immediately in the fallback font while it loads. */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 100%;
  font-display: swap;
  src: url('/fonts/archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* — Modernist tokens — */
  --bg: #f3f2f2;
  --surface: #eae9e9;
  --surface-2: #f8f4f4;
  --text: #201e1d;
  --text-dim: #605d5d;
  --divider: rgba(32, 30, 29, 0.4);
  --hairline: rgba(32, 30, 29, 0.18);

  --accent: #ec3013;
  --accent-100: #fff2ef;
  --accent-200: #ffe0d9;
  --accent-600: #dd2b0f;
  --accent-700: #ae1800;

  --neutral-100: #f8f4f4;
  --neutral-200: #eae7e7;
  --neutral-300: #d7d3d3;
  --neutral-400: #bab6b6;
  --neutral-500: #9b9797;
  --neutral-600: #7d7979;
  --neutral-700: #605d5d;
  --neutral-800: #444141;
  --neutral-900: #2d2b2b;

  /* Legacy aliases — old markup still references these. Mapped onto the
     Modernist palette so nothing renders off-system. */
  --border: var(--hairline);
  --brand: var(--accent);
  --brand-dark: var(--accent-600);
  --danger: var(--accent-700);
  --ok: var(--text);

  --font: "Archivo", system-ui, -apple-system, BlinkMacSystemFont, sans-serif;

  /* The score is mono: strong deals get a solid accent stamp, middling ones
     read as ink, weak ones drop to grey. Fill — not hue — carries the verdict,
     so it survives greyscale printing and colour-blind readers. */
  --score-exceptional: var(--accent);
  --score-excellent: var(--accent);
  --score-good: var(--text);
  --score-average: var(--neutral-600);
  --score-bad: var(--neutral-600);

  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --radius: 0px;
}

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  /* Safety net, not a fix in itself: a single element that's even slightly
     too wide (a long unbroken word, a table, an unguarded multi-column
     grid) used to drag the WHOLE page sideways on mobile - the page felt
     "broken" even when only one element was actually at fault. This
     doesn't excuse leaving something overflowing; it just stops one
     overflow from taking the rest of the page down with it.
     max-width: 100vw alongside overflow-x: hidden, not just the latter
     alone - iOS Safari has a well-documented quirk where a sticky/fixed
     positioned element (this site's nav is position:sticky) can still let
     the page be dragged sideways even with overflow-x:hidden set, because
     that element isn't fully contained by the ancestor's overflow clipping
     the same way in-flow content is. Capping the actual box width closes
     that gap regardless of which descendant caused the overflow. */
  overflow-x: hidden;
  max-width: 100vw;
}

img, svg { max-width: 100%; height: auto; }

/* Any inline multi-column grid that should simply stack into one column
   below the tablet breakpoint, rather than staying cramped - see
   context.md's 2026-09-18 mobile-audit entry for exactly which layouts
   needed this and why each was missed (mostly: added after the page's own
   responsive pass, so never got a breakpoint of its own). */
@media (max-width: 900px) {
  .stack-mobile { grid-template-columns: minmax(0,1fr) !important; }
  .pricing-founding-box { border-left: 0 !important; padding-left: 0 !important; border-top: 2px solid var(--divider); padding-top: 16px; margin-top: 4px; }
}

h1, h2, h3, h4, h5, h6 {
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.025em;
  margin: 0 0 8px;
}

a { color: inherit; text-decoration: none; }
a:hover { color: var(--accent); }

:focus { outline: none; }
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
::selection { background: var(--accent-200); }

.container {
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 24px;
}

/* ── Nav ─────────────────────────────────────────────────────────────── */
.nav {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--bg);
  color: var(--text);
  border-bottom: 2px solid var(--divider);
}
.nav-inner {
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  padding: 0 24px;
  max-width: 1240px;
  margin: 0 auto;
  gap: 24px;
  flex-wrap: wrap;
}
.brand {
  display: flex;
  align-items: center;
  font-weight: 800;
  font-size: 19px;
  letter-spacing: -0.02em;
  padding: 14px 0;
  margin-right: auto;
  white-space: nowrap;
}
.brand span { color: var(--accent); }
.nav-links {
  display: flex;
  gap: 2px;
  flex-wrap: wrap;
  align-items: stretch;
}
.nav-links a {
  display: flex;
  align-items: center;
  padding: 14px 12px;
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  border-bottom: 3px solid transparent;
  transition: color 150ms var(--ease-out), border-color 150ms var(--ease-out);
}
.nav-links a:hover { color: var(--accent); }
.nav-links a[aria-current="page"] {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.nav-cta {
  align-self: center;
  background: var(--accent);
  color: var(--bg) !important;
  padding: 9px 16px !important;
  border-bottom: 0 !important;
  font-size: 13px !important;
  font-weight: 800 !important;
}
.nav-cta:hover { background: var(--accent-600); color: var(--bg) !important; }

/* ── Buttons ─────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  white-space: nowrap;
  border: 1px solid transparent;
  border-radius: 0;
  padding: 9px 16px;
  font-family: var(--font);
  font-size: 14px;
  font-weight: 800;
  line-height: 1.2;
  color: var(--text);
  background: transparent;
  cursor: pointer;
  transition: background 140ms var(--ease-out), color 140ms var(--ease-out), border-color 140ms var(--ease-out);
}
.btn-primary { background: var(--accent); color: var(--bg); }
.btn-primary:hover { background: var(--accent-600); color: var(--bg); }
.btn-primary:active { background: var(--accent-700); }
.btn-secondary { border-color: var(--divider); color: var(--text); }
.btn-secondary:hover { background: rgba(32, 30, 29, 0.07); color: var(--text); }
.btn-secondary:active { background: rgba(32, 30, 29, 0.14); }
.btn-ghost { color: var(--accent); padding-inline: 4px; }
.btn-ghost:hover { background: rgba(236, 48, 19, 0.1); }
.btn-danger { border-color: var(--divider); color: var(--accent-700); }
.btn-danger:hover { background: var(--accent-100); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-block { width: 100%; }
.btn-lg { padding: 13px 22px; font-size: 15px; }

/* ── Surfaces ────────────────────────────────────────────────────────── */
.card {
  background: transparent;
  border: 2px solid var(--divider);
  border-radius: 0;
  padding: 20px;
}
.card-flat {
  background: var(--surface);
  border: 0;
  padding: 20px;
}

.hero { padding: 56px 0 32px; }
.hero h1 {
  font-size: clamp(40px, 6vw, 76px);
  line-height: 0.95;
  letter-spacing: -0.035em;
  margin: 0 0 20px;
  max-width: 15ch;
}
.hero p {
  color: var(--neutral-800);
  font-size: 17px;
  line-height: 1.5;
  margin: 0 0 28px;
  max-width: 52ch;
}

.section-title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin: 40px 0 16px;
}
.section-title h2 {
  font-size: 24px;
  margin: 0;
  letter-spacing: -0.02em;
}
.section-title a {
  color: var(--accent);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* ── Deal grid + cards ───────────────────────────────────────────────── */
/* The grid draws itself: cells are separated by the system's rules rather
   than by floating rounded boxes, so the structure is visible. */
.deal-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(264px, 1fr));
  gap: 0;
  border-top: 2px solid var(--divider);
  border-left: 2px solid var(--divider);
}
.deal-grid > p,
.deal-grid > .empty-state {
  grid-column: 1 / -1;
  border-right: 2px solid var(--divider);
  border-bottom: 2px solid var(--divider);
}

.deal-card {
  display: flex;
  flex-direction: column;
  background: transparent;
  border-right: 2px solid var(--divider);
  border-bottom: 2px solid var(--divider);
  color: var(--text);
  transition: background 140ms var(--ease-out);
  opacity: 0;
  animation: card-in 380ms var(--ease-out) both;
}
.deal-card:hover { background: var(--neutral-100); color: var(--text); }

@keyframes card-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .deal-card { animation-duration: 1ms; animation-delay: 0ms !important; }
}

.deal-card-media {
  position: relative;
  aspect-ratio: 16 / 10;
  background: var(--neutral-100);
  border-bottom: 1px solid var(--hairline);
  overflow: hidden;
}
.media-photo {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: var(--neutral-100);
  transition: transform 240ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .deal-card:hover .media-photo { transform: scale(1.04); }
}
.media-fallback {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--neutral-500);
}
.media-fallback svg { width: 30%; height: 30%; }
.stock-flag {
  position: absolute;
  top: 0;
  left: 0;
  background: var(--text);
  color: var(--bg);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 4px 9px;
}

.deal-card-body {
  padding: 14px 16px 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1 1 auto;
}
.deal-card-category {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--neutral-700);
}
.deal-card-name {
  font-size: 15px;
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: -0.01em;
}
.deal-card-retailer { font-size: 12px; color: var(--neutral-700); }
.deal-card-prices {
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.price-now {
  font-size: 22px;
  font-weight: 800;
  letter-spacing: -0.02em;
}
.price-was {
  font-size: 12px;
  color: var(--neutral-600);
  text-decoration: line-through;
}
.price-save {
  margin-left: auto;
  font-size: 12px;
  font-weight: 800;
  color: var(--accent-700);
}
.price-unavailable {
  font-size: 14px;
  font-weight: 700;
  color: var(--neutral-600);
}
.deal-card-footer {
  margin-top: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

/* ── The verdict stamp ───────────────────────────────────────────────── */
/* Replaces the old coloured emoji pill. A solid accent band means "buy";
   ink means "decent"; grey means "wait". Readable at a glance down a column
   without relying on hue. */
.verdict {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--hairline);
  background: transparent;
  color: var(--neutral-600);
}
.verdict-score {
  font-size: 28px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.03em;
}
.verdict-label {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.verdict-strong { background: var(--accent); color: var(--bg); }
.verdict-mid { background: transparent; color: var(--text); }
.verdict-weak { background: transparent; color: var(--neutral-600); }
/* A price nobody has re-confirmed recently: no score, no verdict colour - the
   stamp says so instead of grading an old number. */
.verdict-stale { background: var(--surface); color: var(--neutral-600); }
.stale-note { font-size: 11.5px; line-height: 1.4; color: var(--neutral-700); border-top: 1px solid var(--hairline); padding-top: 8px; margin-top: auto; }
.price-stale { color: var(--neutral-600); }
.notice { border: 2px solid var(--divider); background: var(--surface-2); padding: 12px 16px; font-size: 13px; line-height: 1.5; margin: 16px 0; }

/* The inline variant, for table cells and the product header. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.02em;
  padding: 3px 9px;
  border-radius: 0;
  white-space: nowrap;
  background: transparent;
  color: var(--text);
  border: 1px solid var(--divider);
}
.badge-exceptional,
.badge-excellent {
  background: var(--accent);
  color: var(--bg);
  border-color: var(--accent);
}
.badge-good { background: transparent; color: var(--text); border-color: var(--text); }
.badge-average,
.badge-bad { background: transparent; color: var(--neutral-600); border-color: var(--neutral-400); }

/* The evidence line — the whole product thesis, made visible on every card. */
.evidence {
  font-size: 11.5px;
  line-height: 1.4;
  color: var(--neutral-700);
  border-top: 1px solid var(--hairline);
  padding-top: 8px;
  margin-top: auto;
}

/* A 90-day price trace under the price. */
.sparkline { display: block; width: 100%; height: 26px; }

/* ── Filters ─────────────────────────────────────────────────────────── */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  align-items: center;
  padding: 14px 0;
  margin-bottom: 0;
  border-top: 2px solid var(--divider);
  border-bottom: 2px solid var(--divider);
}
.filter-group {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.filter-label {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--neutral-700);
}
/* Chips replace the old <select> menus: the options are visible without a
   click, which is what makes a filter bar scannable. */
.chip {
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  padding: 5px 11px;
  border: 1px solid var(--divider);
  background: transparent;
  color: var(--text);
  cursor: pointer;
  transition: border-color 140ms var(--ease-out), background 140ms var(--ease-out);
}
.chip:hover { border-color: var(--accent); }
.chip[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
}
.result-count {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 0;
  font-size: 12px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--neutral-700);
}
.filters select,
.filters input {
  border: 1px solid var(--divider);
  border-radius: 0;
  padding: 8px 10px;
  font-family: var(--font);
  font-size: 14px;
  background: var(--surface);
  color: var(--text);
}

/* ── Forms ───────────────────────────────────────────────────────────── */
.field { margin-bottom: 16px; }
.field label {
  display: block;
  font-size: 12px;
  font-weight: 600;
  margin-bottom: 5px;
  color: var(--neutral-700);
}
.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 42px;
  border: 1px solid var(--divider);
  border-radius: 0;
  padding: 10px 12px;
  font-family: var(--font);
  font-size: 14px;
  background: var(--surface);
  color: var(--text);
  caret-color: var(--accent);
  transition: border-color 140ms var(--ease-out);
}
.field textarea { min-height: 140px; resize: vertical; line-height: 1.5; }
.field input:hover,
.field select:hover,
.field textarea:hover { border-color: rgba(32, 30, 29, 0.45); }
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 0;
  border-color: var(--accent);
}

.form-card { max-width: 460px; margin: 48px auto; }

/* ── Tabs ────────────────────────────────────────────────────────────── */
.tabs {
  display: flex;
  gap: 0;
  margin-bottom: 20px;
  border-bottom: 2px solid var(--divider);
  flex-wrap: wrap;
}
.tab {
  padding: 10px 16px;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--neutral-600);
  cursor: pointer;
  border-bottom: 3px solid transparent;
  margin-bottom: -2px;
  transition: color 140ms var(--ease-out), border-color 140ms var(--ease-out);
}
.tab:first-child { padding-left: 0; }
.tab:hover { color: var(--text); }
.tab.active { color: var(--accent); border-bottom-color: var(--accent); }

/* ── Tables ──────────────────────────────────────────────────────────── */
table { width: 100%; border-collapse: collapse; font-size: 14px; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--hairline); }
th {
  color: var(--neutral-700);
  font-weight: 600;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  border-bottom: 2px solid var(--divider);
}
th:first-child, td:first-child { padding-left: 0; }
tbody tr:hover { background: rgba(32, 30, 29, 0.04); }
.table-name { font-weight: 800; font-size: 13.5px; }

.pill {
  display: inline-block;
  white-space: nowrap;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 3px 9px;
  border-radius: 0;
  background: var(--neutral-100);
  color: var(--neutral-800);
}
.pill-outline { background: transparent; border: 1px solid var(--accent); color: var(--accent); }
.pill-real { background: var(--accent); color: var(--bg); font-weight: 800; }
.pill-lowest { background: var(--text); color: var(--bg); font-weight: 800; letter-spacing: 0.04em; text-transform: uppercase; }
.pill-claimed { background: var(--neutral-100); color: var(--neutral-700); }
.pill-checking { background: var(--neutral-100); color: var(--neutral-700); font-style: italic; }
.verdict-pills { position: absolute; top: 0; right: 0; display: flex; flex-direction: column; align-items: flex-end; gap: 0; }
.verdict-pills .pill { border-radius: 0; }
.save-heart {
  position: absolute;
  bottom: 8px;
  right: 8px;
  width: 30px;
  height: 30px;
  padding: 6px;
  border: none;
  border-radius: 50%;
  background: rgba(255,255,255,0.9);
  color: var(--neutral-600);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.save-heart svg { width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.8; }
.save-heart:hover { color: var(--accent); }
.save-heart.saved { color: var(--accent); }
.save-heart.saved svg { fill: var(--accent); }

/* ── Utility ─────────────────────────────────────────────────────────── */
.muted { color: var(--neutral-700); }
.stack { display: flex; flex-direction: column; gap: 8px; }
.row { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
.grid-2 { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 0; }
@media (max-width: 860px) { .grid-2 { grid-template-columns: minmax(0,1fr); } }

.hr { height: 2px; border: 0; margin: 0; background: var(--divider); }
.kicker {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}

/* A measured bar — used for score components, weights and alert progress. */
.meter { width: 100%; height: 5px; background: var(--neutral-300); }
.meter > i { display: block; height: 100%; background: var(--accent); }
.meter-ink > i { background: var(--text); }
.meter-dim > i { background: var(--neutral-600); }

/* ── Product page ────────────────────────────────────────────────────── */
.product-hero {
  display: flex;
  gap: 28px;
  align-items: flex-start;
  flex-wrap: wrap;
  padding: 28px 32px 28px 0;
}
.product-media {
  position: relative;
  width: 150px;
  height: 150px;
  flex: none;
  border-radius: 0;
  overflow: hidden;
  background: var(--neutral-100);
}
.product-media .media-photo,
.product-media .media-fallback { position: absolute; inset: 0; }
.product-media .media-fallback svg { width: 42%; height: 42%; }
@media (max-width: 560px) {
  .product-media { width: 96px; height: 96px; }
}

/* The score panel: the one place red runs as a full field. */
.score-panel {
  background: var(--accent);
  color: var(--bg);
  padding: 28px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 18px;
}
/* The red field is earned, not automatic: only a strong verdict gets the
   full accent panel. A middling score reads as ink, a weak one as surface —
   otherwise the page shouts "buy" at a 45. */
.score-panel-mid { background: var(--text); color: var(--bg); }
.score-panel-weak { background: var(--surface); color: var(--text); }

.score-panel .score-number {
  font-size: 104px;
  font-weight: 800;
  line-height: 0.8;
  letter-spacing: -0.05em;
}

.score-breakdown { display: flex; flex-direction: column; border-top: 1px solid var(--hairline); }
.score-breakdown .item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 80px;
  gap: 16px;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid var(--hairline);
  background: transparent;
  border-radius: 0;
}
.score-breakdown .item .label {
  font-size: 14px;
  font-weight: 800;
  text-transform: none;
  letter-spacing: -0.01em;
  color: var(--text);
}
.score-breakdown .item .weight {
  font-size: 11px;
  letter-spacing: 0.06em;
  color: var(--neutral-600);
  margin-left: 6px;
  font-weight: 400;
}
.score-breakdown .item .note { font-size: 12.5px; color: var(--neutral-700); margin-top: 2px; }
.score-breakdown .item .value {
  font-size: 16px;
  font-weight: 800;
  text-align: right;
}
.score-breakdown .item .value-wrap {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 5px;
}

.chart-legend {
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
  font-size: 11.5px;
  color: var(--neutral-700);
  padding-top: 10px;
  margin-top: 8px;
  border-top: 1px solid var(--hairline);
}
.chart-legend span { display: flex; align-items: center; gap: 6px; }
.swatch-line { width: 18px; height: 2px; background: var(--accent); }
.swatch-dash { width: 18px; height: 0; border-top: 2px dashed var(--neutral-600); }
.swatch-low { width: 18px; height: 2px; background: var(--neutral-400); }

/* Alert targets — pick from real anchors instead of typing a number blind. */
.target-list { display: flex; flex-direction: column; border-top: 1px solid var(--hairline); }
.target {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  text-align: left;
  padding: 14px 4px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  font-family: var(--font);
  cursor: pointer;
  transition: background 140ms var(--ease-out);
}
.target:hover { background: var(--neutral-100); }
.target[aria-pressed="true"] { background: var(--accent-100); }
.target .dot {
  width: 16px;
  height: 16px;
  flex: none;
  border-radius: 50%;
  border: 1.5px solid var(--divider);
}
.target[aria-pressed="true"] .dot {
  border-color: var(--accent);
  background: var(--accent);
  box-shadow: inset 0 0 0 4px var(--bg);
}
.target .target-price { font-size: 19px; font-weight: 800; min-width: 96px; }
.target .target-note { font-size: 13px; color: var(--neutral-800); }
.target .target-odds {
  margin-left: auto;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--neutral-600);
}

/* ── Stats (admin, pricing) ──────────────────────────────────────────── */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 0;
  border-top: 2px solid var(--divider);
  border-left: 2px solid var(--divider);
  margin: 20px 0;
}
.stat-card {
  background: transparent;
  border: 0;
  border-right: 2px solid var(--divider);
  border-bottom: 2px solid var(--divider);
  border-radius: 0;
  padding: 18px 20px;
}
.stat-card .label {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--neutral-700);
}
.stat-card .value {
  font-size: 34px;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
  margin-top: 6px;
}
.stat-card .delta { font-size: 11.5px; color: var(--neutral-700); margin-top: 2px; }
.stat-card .value-accent { color: var(--accent); }

/* Admin table thumbnail */
.thumb {
  position: relative;
  width: 36px;
  height: 36px;
  border-radius: 0;
  overflow: hidden;
  background: var(--neutral-100);
}
.thumb .media-photo, .thumb .media-fallback { position: absolute; inset: 0; }
.thumb .media-fallback svg { width: 50%; height: 50%; }

/* ── Empty + loading states ──────────────────────────────────────────── */
/* An empty state is a layout with something to say, not centred grey text:
   it names what happened and offers the next move. */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  text-align: left;
  padding: 56px 32px;
  color: var(--text);
}
.empty-state h3 { margin: 0; font-size: 24px; letter-spacing: -0.02em; }
.empty-state p { margin: 0; max-width: 52ch; color: var(--neutral-800); font-size: 14px; }
.empty-state .empty-icon { width: 32px; color: var(--accent); }
.empty-state .row { margin-top: 8px; }

/* Skeletons, so a slow feed shows its shape rather than the word "Loading". */
.skeleton-card {
  border-right: 2px solid var(--divider);
  border-bottom: 2px solid var(--divider);
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.skeleton {
  background: var(--neutral-200);
  animation: pulse 1.4s ease-in-out infinite;
}
.skeleton-stamp { height: 32px; width: 56px; }
.skeleton-media { aspect-ratio: 16 / 10; }
.skeleton-line { height: 14px; }
.skeleton-price { height: 22px; width: 40%; background: var(--neutral-300); }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }

/* ── Toast ───────────────────────────────────────────────────────────── */
.toast {
  position: fixed;
  bottom: 0;
  right: 24px;
  background: var(--text);
  color: var(--bg);
  padding: 14px 18px;
  border-radius: 0;
  font-size: 14px;
  font-weight: 600;
  opacity: 0;
  transform: translateY(100%);
  transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out);
  pointer-events: none;
  z-index: 50;
}
.toast.show { opacity: 1; transform: translateY(0); }

/* ── Footer ──────────────────────────────────────────────────────────── */
footer {
  margin-top: 72px;
  border-top: 2px solid var(--divider);
  padding: 36px 0;
  color: var(--neutral-700);
  font-size: 12.5px;
}
.footer-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 28px;
}
.footer-title {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--neutral-600);
  margin-bottom: 10px;
}
.footer-links { display: flex; flex-direction: column; gap: 6px; }
.footer-links a { font-size: 13px; color: var(--neutral-800); }

@media (hover: hover) and (pointer: fine) {
  .clickable:hover { background: var(--neutral-100); }
}

/* Photographs print in black and white, per the system. Product shots are
   exempt on purpose — colour is information when you are buying a thing. */
.grayscale { filter: grayscale(1) contrast(1.08); }

@media (max-width: 640px) {
  .container { padding: 0 16px; }
  .nav-inner { padding: 0 16px; }
  .nav-links a { padding: 12px 8px; font-size: 12px; }
  .hero { padding: 36px 0 24px; }
  .product-hero { padding: 20px 0; gap: 18px; }
  .score-panel { padding: 20px; }
  /* The red field is earned, not automatic: only a strong verdict gets the
   full accent panel. A middling score reads as ink, a weak one as surface —
   otherwise the page shouts "buy" at a 45. */
.score-panel-mid { background: var(--text); color: var(--bg); }
.score-panel-weak { background: var(--surface); color: var(--text); }

.score-panel .score-number { font-size: 72px; }
  .filters { gap: 14px; }
  /* 44px minimum hit target on touch. */
  .btn { padding: 12px 16px; }
  .chip { padding: 9px 12px; }
}

/* ── Responsive: the new two-column shells collapse ──────────────────── */
@media (max-width: 900px) {
  /* minmax(0,1fr), never a bare 1fr: a plain "1fr" track's minimum width
     defaults to auto (content-based), not zero - a wide descendant (a
     table, a long unbroken string) forces the track past the viewport and
     the WHOLE PAGE ends up horizontally scrollable, since the overflow
     happens at the grid-sizing step, before any child's own overflow-x
     rule ever gets a chance to clip/scroll it locally. minmax(0,1fr) lets
     the track actually shrink to the viewport, so descendants' own
     overflow-x:auto wrappers (tables, etc.) do their job instead of being
     bypassed. Confirmed live via a real bug report ("still have to swipe
     right on mobile admin") - see context.md's 2026-09-18 entry. */
  .product-top { grid-template-columns: minmax(0,1fr) !important; }
  .product-top .product-hero { border-right: 0 !important; }
  .alert-block { grid-template-columns: minmax(0,1fr) !important; }
  .alert-block > div:first-child { border-right: 0 !important; border-bottom: 2px solid var(--divider); }
  .price-grid { grid-template-columns: minmax(0,1fr) !important; }
  #auth-split { grid-template-columns: minmax(0,1fr) !important; min-height: 0 !important; }
  #auth-split > div { padding: 40px 24px !important; }
  #admin-shell { grid-template-columns: minmax(0,1fr) !important; }
  #admin-rail { border-right: 0 !important; border-bottom: 2px solid var(--divider); padding: 16px 0; }
  #admin-tabs { display: flex; overflow-x: auto; }
  #admin-tabs .admin-tab {
    width: auto !important;
    border-left: 0 !important;
    border-bottom: 3px solid transparent;
  }
  #admin-tabs .admin-tab[aria-selected="true"] { border-bottom-color: var(--accent); }
  #admin-shell main { padding: 24px 16px 56px !important; }
  .grid-2 > div:first-child { border-right: 0 !important; border-bottom: 2px solid var(--divider); }
  .grid-2 > div { padding-left: 0 !important; padding-right: 0 !important; }
}

@media (max-width: 760px) {
  .hero { grid-template-columns: minmax(0,1fr) !important; gap: 28px !important; }
  .hero > div:last-child { border-left: 0 !important; border-top: 2px solid var(--divider); padding-left: 0 !important; padding-top: 20px; }
  .watch-head { display: none !important; }
  .watch-row { grid-template-columns: minmax(0,1fr) minmax(0,1fr) !important; gap: 12px !important; }
  .filters { position: static !important; }
  .filters .filter-group { width: 100%; }
  .filters .filter-group:last-child { margin-left: 0 !important; }
}

/* ── Confirmation dialog (siteDialog() in app.js) ───────────────────────
   In-page replacement for the browser's own confirm()/prompt() pop-ups,
   which look foreign, can't be styled and are sometimes suppressed. */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center;
  padding: 16px; background: rgba(32, 30, 29, 0.55);
}
.modal {
  width: 100%; max-width: 460px; max-height: calc(100vh - 32px); overflow-y: auto;
  padding: 26px; background: var(--surface-2); border: 2px solid var(--text);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28);
}
.modal h2 { margin: 0 0 10px; font-size: 22px; letter-spacing: -0.02em; }
.modal p { margin: 0 0 18px; font-size: 14px; line-height: 1.55; color: var(--neutral-700); }
.modal .field { margin-bottom: 20px; }
.modal-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; }
.modal-actions .btn[disabled] { opacity: 0.45; cursor: not-allowed; }
