/* ============================================================
   Centsible Clicks — design tokens
   Measured values from the site extraction; semantic corrections
   applied per spec (base surface is WHITE, not #000; inverse text
   is #FFF; secondary text bumped to #6b6b6b for AA 5.1:1).
   ============================================================ */
:root {
  /* color */
  --surface-base: #ffffff;
  --surface-muted: #f4f5f7;
  --text-primary: #4b4f58;
  --text-secondary: #6b6b6b;   /* 5.1:1 on white — AA for small text */
  --text-inverse: #ffffff;
  --brand: #4064d7;            /* 5.2:1 on white */
  --accent: #d81439;           /* rare: the one thing that matters on screen */
  --success: #1a7f4f;          /* 5.0:1 on white */
  --border: #e4e6ea;

  /* type — Varela Round ships ONE weight (400); hierarchy comes from
     size, color, and spacing, never weight */
  --font: 'Varela Round', ui-rounded, system-ui, sans-serif;
  --font-num: 'Varela Round', ui-monospace, monospace;
  --fs-xs: 12px;  --fs-sm: 14px;  --fs-md: 15px;  --fs-lg: 16px;
  --fs-xl: 18px;  --fs-2xl: 30px; --fs-3xl: 35px; --fs-4xl: 43px;
  --lh-body: 29.7px;

  /* spacing */
  --sp-1: 6px;  --sp-2: 10px; --sp-3: 15px;   --sp-4: 16px;
  --sp-5: 20px; --sp-6: 22px; --sp-7: 24px;   --sp-8: 28.8px;

  /* radius — 20 for cards, 50 for pill controls */
  --r-xs: 4px; --r-sm: 20px; --r-md: 30px; --r-lg: 50px;

  /* motion */
  --t-instant: 200ms;
  --t-fast: 300ms;
}

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

html {
  /* Varela Round has no bold. Fail loudly rather than let the browser
     synthesize a smeared faux-bold. */
  font-synthesis: none;
  /* Reserve the scrollbar track: content growing/shrinking (breakdown
     reloads, range changes) must never toggle the scrollbar and nudge the
     whole layout sideways. */
  scrollbar-gutter: stable;
}

body {
  margin: 0;
  font-family: var(--font);
  font-weight: 400;
  font-size: var(--fs-xl);
  line-height: var(--lh-body);
  color: var(--text-primary);
  background: var(--surface-muted);
}

h1, h2, h3, strong, b { font-weight: 400; } /* no bold exists; see html rule */
h1 { font-size: var(--fs-2xl); line-height: 1.25; margin: 0; }
h2 { font-size: var(--fs-lg); line-height: 1.3; margin: 0; color: var(--text-secondary);
     text-transform: uppercase; letter-spacing: 0.06em; }

a { color: var(--brand); }

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
}

/* keyboard-first: an unmistakable ring on EVERY interactive element */
:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}
.pill:focus-visible { border-radius: var(--r-lg); }

.skip-link {
  position: absolute; left: -9999px; top: 0;
  background: var(--brand); color: var(--text-inverse);
  padding: var(--sp-2) var(--sp-5); border-radius: 0 0 var(--r-xs) 0;
  z-index: 10;
}
.skip-link:focus { left: 0; }

/* numbers align in columns: Varela Round has no tabular figures, so
   numeric cells fall through to a monospace stack that does */
.num {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

[hidden] { display: none !important; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---- layout -------------------------------------------------- */
.page {
  max-width: 1200px;
  margin: 0 auto;
  padding: var(--sp-7) var(--sp-5) var(--sp-8);
  display: grid;
  gap: var(--sp-7);
}
/* Grid items default to min-width auto and refuse to shrink below their
   content, letting wide tables/canvases blow the layout out sideways.
   Constrain the whole chain. */
.page > *, #main > section, #main > div { min-width: 0; }

.site-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-5);
}
.logo {
  display: block;
  height: 34px;
  width: auto;
}
.logo-lg {
  height: 52px;
  margin: 0 auto var(--sp-1);
}
.site-header h1 { margin-right: auto; }

.card {
  background: var(--surface-base);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: var(--sp-7);
}

.card-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin-bottom: var(--sp-5);
}
.card-head h2 { margin-right: auto; }

/* ---- pills --------------------------------------------------- */
/* Pill groups must wrap on narrow screens, never overflow. flex-basis
   max-content + shrink lets a group claim its own full-width line beside a
   heading when space is tight, then wrap its pills inside that line. */
.pill-group { display: flex; flex-wrap: wrap; gap: var(--sp-1); min-width: 0; }
.site-header > .pill-group, .chart-controls { flex: 1 1 max-content; min-width: 0; }
.chart-controls { justify-content: flex-end; }

.pill {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface-base);
  color: var(--text-primary);
  font-size: var(--fs-sm);
  line-height: 1;
  padding: var(--sp-2) var(--sp-4);
  transition: background-color var(--t-instant), border-color var(--t-instant), color var(--t-instant);
}
.pill:hover { border-color: var(--brand); }
.pill[aria-pressed="true"], .pill[aria-selected="true"] {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--text-inverse);
}

.custom-range {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-1);
  font-size: var(--fs-sm);
  min-width: 0;
}
.custom-range input {
  font: inherit; color: inherit;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: calc(var(--sp-2) - 2px) var(--sp-3);
  background: var(--surface-base);
}

/* ---- scorecards ---------------------------------------------- */
/* Brand-tinted panel (option C) holding floating shadow cards (option D). */
.metrics-panel {
  background: rgba(64, 100, 215, 0.06);
  border-radius: var(--r-md);
  padding: var(--sp-6);
}
.metrics-panel .panel-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--sp-3);
  padding: 0 var(--sp-2) var(--sp-4);
}
.metrics-panel .panel-head h2 { margin: 0; }
.range-note { font-size: var(--fs-sm); color: var(--text-secondary); }
.metrics-panel .scorecard {
  border: 0;
  box-shadow: 0 1px 3px rgba(75, 79, 88, 0.08), 0 10px 28px rgba(64, 100, 215, 0.10);
  transition: transform var(--t-instant), box-shadow var(--t-instant);
}
.metrics-panel .scorecard:hover {
  transform: translateY(-2px);
  box-shadow: 0 2px 5px rgba(75, 79, 88, 0.08), 0 14px 34px rgba(64, 100, 215, 0.15);
}

.scorecards {
  display: grid;
  /* always 4 over 4 — collapses to 2x4 only on narrow screens */
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sp-4);
}
@media (max-width: 980px) {
  .scorecards { grid-template-columns: repeat(2, 1fr); }
}
.scorecard {
  padding: var(--sp-5) var(--sp-6);
  /* locked height + single-line value/delta: cards never resize or shift
     when the date range changes the magnitude of the numbers */
  min-height: 128px;
  min-width: 0; /* never let a long value blow the grid column open */
}
.scorecard .label {
  font-size: var(--fs-sm);
  color: var(--text-secondary);
  line-height: 1.4;
  white-space: nowrap;
}
.scorecard .value {
  font-size: var(--fs-2xl);
  line-height: 1.2;
  margin-top: var(--sp-1);
  text-align: left; /* .num sets right; scorecard values read left */
  white-space: nowrap;
}
.delta {
  display: inline-flex;
  align-items: baseline;
  gap: var(--sp-1);
  margin-top: var(--sp-1);
  font-size: var(--fs-sm);
  line-height: 1.4;
  white-space: nowrap;
  color: var(--text-secondary); /* neutral: cost, or no computable delta */
}
.delta--good { color: var(--success); }
.delta--bad  { color: var(--accent); }
.delta .vs { color: var(--text-secondary); }

/* ---- chart --------------------------------------------------- */
/* overflow: hidden breaks the canvas feedback loop: a stale oversized
   canvas would otherwise hold the container wide so Chart.js's resize
   observer never shrinks it back */
.chart-wrap { position: relative; height: 320px; overflow: hidden; }
.chart-controls { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; }

.chart-alt {
  font-size: var(--fs-md);
  color: var(--text-secondary);
  margin: var(--sp-3) 0 0;
}

.gap-note {
  font-size: var(--fs-xs);
  color: var(--text-secondary);
  text-align: right;
  margin: 0 0 var(--sp-1);
}

details.data-table summary {
  cursor: pointer;
  font-size: var(--fs-sm);
  color: var(--brand);
  margin-top: var(--sp-3);
}
details.data-table summary:hover { text-decoration: underline; }

/* ---- conversion breakdown ------------------------------------ */
.conv-rows { display: grid; gap: 0; }
.conv-row {
  display: grid;
  grid-template-columns: minmax(140px, 220px) 1fr 90px;
  gap: var(--sp-4);
  align-items: center;
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-lg);
}
.conv-row:last-child { border-bottom: 0; }
.conv-row .conv-label {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.conv-row.total { color: var(--text-primary); border-top: 1px solid var(--border); }
.conv-bar-track { background: var(--surface-muted); border-radius: var(--r-xs); height: 14px; }
.conv-bar {
  height: 100%;
  background: var(--brand);
  border-radius: var(--r-xs);
  min-width: 2px;
  transition: width var(--t-fast);
}

/* ---- tables -------------------------------------------------- */
.table-scroll { overflow-x: auto; }

/* Breakdown panel keeps its footprint while loading/swapping so the page
   height doesn't jump on every range change. Long tables (city breakdowns
   can run to 200 rows) cap at ~20 rows and scroll internally, with the
   header and totals row pinned. */
#bd-panel {
  min-height: 380px;
  max-height: 880px;
  overflow-y: auto;
}
#bd-panel table.metrics thead th {
  position: sticky;
  top: 0;
  background: var(--surface-base);
  z-index: 1;
  border-bottom: 0;
  box-shadow: 0 1px 0 var(--border); /* borders don't stick; shadows do */
}
#bd-panel table.metrics tfoot td {
  position: sticky;
  bottom: 0;
  background: var(--surface-base);
  border-top: 0;
  box-shadow: 0 -1px 0 var(--border);
}
/* The name column stays pinned while the metric columns scroll sideways —
   without it, a scrolled table is rows of numbers with no identity. */
#bd-panel table.metrics th:first-child,
#bd-panel table.metrics td:first-child {
  position: sticky;
  left: 0;
  background: var(--surface-base);
  z-index: 2;
  box-shadow: 1px 0 0 var(--border);
}
#bd-panel table.metrics thead th:first-child {
  z-index: 3;
  box-shadow: 1px 0 0 var(--border), 0 1px 0 var(--border);
}
#bd-panel table.metrics tfoot td:first-child {
  z-index: 3;
  box-shadow: 1px 0 0 var(--border), 0 -1px 0 var(--border);
}

table.metrics {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-md);
  line-height: 1.5;
}
table.metrics th, table.metrics td {
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--border);
  text-align: right;
  white-space: nowrap;
}
table.metrics th:first-child, table.metrics td:first-child {
  text-align: left;
  max-width: 320px;
  overflow: hidden; text-overflow: ellipsis;
}
table.metrics thead th {
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-secondary);
}
table.metrics thead th button {
  all: unset;
  cursor: pointer;
  display: inline-flex; gap: 4px; align-items: baseline;
}
table.metrics thead th button:hover { color: var(--text-primary); }
table.metrics thead th button:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; }
table.metrics tfoot td { border-top: 1px solid var(--border); border-bottom: 0; }
table.metrics td.num, table.metrics th.num { font-family: var(--font-num); font-variant-numeric: tabular-nums; }

.row-toggle {
  all: unset;
  cursor: pointer;
  display: inline-flex; align-items: center; gap: var(--sp-1);
  max-width: 100%;
}
.row-toggle:focus-visible { outline: 3px solid var(--brand); outline-offset: 2px; border-radius: var(--r-xs); }
.row-toggle .chev { transition: transform var(--t-instant); font-size: var(--fs-xs); color: var(--text-secondary); }
.row-toggle[aria-expanded="true"] .chev { transform: rotate(90deg); }
.row-toggle .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

tr.subrow td:first-child { padding-left: var(--sp-8); color: var(--text-secondary); }
tr.subrow-note td { color: var(--text-secondary); font-size: var(--fs-sm); }

/* ---- notices & states ---------------------------------------- */
.banner {
  border-radius: var(--r-sm);
  border: 1px solid var(--border);
  background: var(--surface-muted);
  padding: var(--sp-3) var(--sp-6);
  font-size: var(--fs-md);
}
.banner + .banner { margin-top: var(--sp-2); }

.state {
  text-align: center;
  color: var(--text-secondary);
  padding: var(--sp-8) var(--sp-5);
  font-size: var(--fs-lg);
}
.state .headline { font-size: var(--fs-xl); color: var(--text-primary); margin: 0 0 var(--sp-2); }
.state button { margin-top: var(--sp-3); }

.btn {
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--surface-base);
  font-size: var(--fs-sm);
  line-height: 1;
  padding: var(--sp-2) var(--sp-4);
  transition: border-color var(--t-instant);
}
.btn:hover { border-color: var(--brand); }
.btn-primary {
  background: var(--brand);
  border-color: var(--brand);
  color: var(--text-inverse);
  font-size: var(--fs-lg);
  padding: var(--sp-2) var(--sp-6);
}
.btn-primary:hover { border-color: var(--brand); filter: brightness(1.08); }

[aria-busy="true"] { opacity: 0.55; transition: opacity var(--t-instant); }

/* ---- login --------------------------------------------------- */
.login-wrap {
  min-height: 80vh;
  display: grid;
  place-items: center;
  padding: var(--sp-5);
}
.login-card {
  width: min(420px, 100%);
  display: grid;
  gap: var(--sp-4);
  text-align: center;
}
.login-card h1 { font-size: var(--fs-2xl); }
.login-card label {
  display: grid; gap: var(--sp-1);
  text-align: left; font-size: var(--fs-sm); color: var(--text-secondary);
}
.login-card input {
  font: inherit; color: var(--text-primary);
  font-size: var(--fs-lg);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-2) var(--sp-4);
}
.login-error { color: var(--accent); font-size: var(--fs-md); min-height: 1.5em; margin: 0; }

/* ---- small screens ------------------------------------------- */
@media (max-width: 640px) {
  .page { padding: var(--sp-4) var(--sp-3) var(--sp-7); gap: var(--sp-4); }
  .card { padding: var(--sp-5); }
  h1 { font-size: 24px; }
  .logo { height: 28px; }
  .chart-wrap { height: 240px; }

  /* scorecards: tighter cards, smaller values, delta keeps glyph + % only
     (the full "vs. prior period" context stays in the aria-label) */
  .metrics-panel { padding: var(--sp-4); }
  .scorecards { gap: var(--sp-2); }
  .scorecard { padding: var(--sp-3) var(--sp-4); min-height: 0; }
  .scorecard .value { font-size: 20px; }
  .delta .vs { display: none; }

  /* conversion rows: bar drops to its own full-width line instead of
     being squeezed to nothing between label and count */
  .conv-row {
    grid-template-areas: "label count" "bar bar";
    grid-template-columns: 1fr auto;
    gap: var(--sp-1) var(--sp-3);
  }
  .conv-label { grid-area: label; }
  .conv-bar-track { grid-area: bar; }
  .conv-row > .num { grid-area: count; }

  /* pinned name column earns its keep here — cap its width */
  table.metrics th:first-child, table.metrics td:first-child { max-width: 150px; }
  #bd-panel { max-height: 70vh; }
}

/* comfortable tap targets on touch devices */
@media (pointer: coarse) {
  .pill, .btn { padding-top: 12px; padding-bottom: 12px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
