/* ============================================================
   Palette roles. Values come from the design-system reference
   instance; the diverging red arm was generated to match the
   blue arm's OKLCH lightness exactly (0.763 / 0.623 / 0.480),
   so the two arms carry equal visual weight either side of parity.
   Dark steps are selected for the dark surface, not flipped.
   ============================================================ */
:root {
  color-scheme: light;

  --surface-1: #fcfcfb;
  --plane: #f9f9f7;
  --text-primary: #0b0b0b;
  --text-secondary: #52514e;
  --muted: #898781;
  --grid: #e1e0d9;
  --axis: #c3c2b7;
  --border: rgba(11, 11, 11, 0.10);
  --border-strong: rgba(11, 11, 11, 0.16);

  --series-1: #2a78d6;
  --series-2: #eb6834;
  --success: #006300;

  /* diverging: Russian-leaning <- parity -> Ukrainian-leaning */
  --dv-1: #b0081d;
  --dv-2: #e34948;
  --dv-3: #ff8c85;
  --dv-4: #f0efec;
  --dv-5: #86b6ef;
  --dv-6: #3987e5;
  --dv-7: #1c5cab;

  --no-data: #e4e3de;
  --radius: 12px;
  --sans: system-ui, -apple-system, "Segoe UI", sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) {
    color-scheme: dark;
    --surface-1: #1a1a19;
    --plane: #0d0d0d;
    --text-primary: #ffffff;
    --text-secondary: #c3c2b7;
    --muted: #898781;
    --grid: #2c2c2a;
    --axis: #383835;
    --border: rgba(255, 255, 255, 0.10);
    --border-strong: rgba(255, 255, 255, 0.18);
    --series-1: #3987e5;
    --series-2: #d95926;
    --success: #0ca30c;
    --dv-1: #ff8c85;
    --dv-2: #e34948;
    --dv-3: #b0081d;
    --dv-4: #383835;
    --dv-5: #1c5cab;
    --dv-6: #3987e5;
    --dv-7: #86b6ef;
    --no-data: #262625;
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --surface-1: #1a1a19;
  --plane: #0d0d0d;
  --text-primary: #ffffff;
  --text-secondary: #c3c2b7;
  --muted: #898781;
  --grid: #2c2c2a;
  --axis: #383835;
  --border: rgba(255, 255, 255, 0.10);
  --border-strong: rgba(255, 255, 255, 0.18);
  --series-1: #3987e5;
  --series-2: #d95926;
  --success: #0ca30c;
  --dv-1: #ff8c85;
  --dv-2: #e34948;
  --dv-3: #b0081d;
  --dv-4: #383835;
  --dv-5: #1c5cab;
  --dv-6: #3987e5;
  --dv-7: #86b6ef;
  --no-data: #262625;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--plane);
  color: var(--text-primary);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

.wrap { max-width: 800px; margin: 0 auto; padding: 0 20px; }

/* ── hero intro: the catchy headline that replaced the header bar ─ */
.hero-intro { padding: 56px 0 8px; }
.hero-intro h1 {
  margin: 0; font-size: clamp(2.4rem, 7vw, 3.6rem); font-weight: 700;
  letter-spacing: -0.025em; line-height: 1.04;
}
.kw-ua { color: var(--series-1); }
.kw-ru { color: var(--dv-2); }
.vs { color: var(--muted); font-weight: 400; }
.tagline {
  margin: 16px 0 0; color: var(--text-secondary); font-size: 1.08rem;
  line-height: 1.5; max-width: 54ch;
}

/* ── segmented controls ─────────────────────────────────── */
.seg { display: inline-flex; border: 1px solid var(--border-strong); border-radius: 8px; overflow: hidden; }
.seg button {
  appearance: none; border: 0; background: transparent; cursor: pointer;
  font: inherit; font-size: 0.8rem; padding: 6px 11px; color: var(--text-secondary);
  min-height: 32px;
}
.seg button + button { border-left: 1px solid var(--border); }
.seg button:hover { background: var(--plane); color: var(--text-primary); }
.seg button.on { background: var(--text-primary); color: var(--surface-1); }
button.ghost {
  appearance: none; background: transparent; border: 1px solid var(--border-strong);
  border-radius: 8px; font: inherit; font-size: 0.8rem; padding: 6px 12px;
  color: var(--text-secondary); cursor: pointer; min-height: 32px;
}
button.ghost:hover { background: var(--plane); color: var(--text-primary); }
:focus-visible { outline: 2px solid var(--series-1); outline-offset: 2px; }

/* ── hero: single column — split bar, then stats ──────────── */
.hero { padding: 36px 0 30px; }
/* Three fixed columns, always one row — each a target %, then its estimated
   month and year stacked, so the trio reads as a short timeline at a glance. */
.proj-row { display: flex; gap: 16px; margin: 24px 0 0; }
.proj-col { flex: 1 1 0; min-width: 0; }
.proj-col dd { margin: 2px 0 0; }
.proj-target { font-size: 0.78rem; color: var(--muted); margin: 0; }
.proj-month {
  display: block; font-size: 0.85rem; font-weight: 700; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--text-secondary);
}
.proj-year { display: block; font-size: 1.35rem; font-weight: 600; letter-spacing: -0.01em; }
.up { color: var(--success); }
.stat-note { margin: 10px 0 0; font-size: 0.78rem; color: var(--muted); }

/* ── hero split bar: a big version of the region-row bar ──── */
.split-bar { margin: 28px 0 0; }
.split-bar-labels { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 10px; }
.split-bar-stat { display: flex; flex-direction: column; }
.split-bar-stat.is-ru { align-items: flex-end; text-align: right; }
.split-bar-stat.is-ua { color: var(--series-1); }
.split-bar-stat.is-ru { color: var(--dv-2); }
.split-bar-lang { font-size: 0.85rem; font-weight: 600; }
.split-bar-pct { font-size: 1.6rem; font-weight: 700; letter-spacing: -0.01em; }
.split-bar-track { position: relative; display: flex; gap: 2px; height: 8px; }
.split-bar-track i { display: block; height: 100%; }
.split-bar-track .ua { background: var(--series-1); border-radius: 2px 0 0 2px; }
.split-bar-track .ru { background: var(--dv-2); border-radius: 0 2px 2px 0; }
/* Quarter marks at 25/50/75%, same convention as the trend chart's division
   gaps: a thin strip of the page background cut through the fill, rather than
   a painted line — correct in both themes by construction. */
.split-bar-tick {
  position: absolute; top: 0; bottom: 0; width: 2px; margin-left: -1px;
  background: var(--plane); pointer-events: none;
}
/* Axis labels under the bar, aligned to the same 0/25/50/75/100 positions as
   the ticks above — edge labels hug the bar's ends, the rest are centered. */
.split-bar-axis { position: relative; height: 14px; margin-top: 6px; }
.split-bar-axis span {
  position: absolute; top: 0; font-size: 0.72rem; color: var(--muted);
  transform: translateX(-50%);
}
.split-bar-axis span:first-child { transform: translateX(0); }
.split-bar-axis span:last-child { transform: translateX(-100%); }
.split-bar-axis span:nth-child(3) { color: var(--text-primary); font-weight: 700; }

/* ── sections ───────────────────────────────────────────── */
/* No card chrome: sections are divided by a hairline rule and generous
   vertical rhythm rather than a boxed background, so the page reads as one
   continuous document instead of a stack of panels. */
.section {
  padding: 44px 0; border-top: 1px solid var(--border);
}
.section-head { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.section h2 { margin: 0; font-size: 1.02rem; font-weight: 600; }
.section-sub { margin: 4px 0 0; color: var(--text-secondary); font-size: 0.85rem; max-width: 62ch; }
.filter-row { display: flex; align-items: center; gap: 12px; margin: 20px 0 4px; flex-wrap: wrap; }
.spacer { flex: 1 1 auto; }

/* ── charts: pinned axes + one shared horizontal scroller ─ */
.charts-wrap { display: flex; align-items: flex-start; margin-top: 20px; position: relative; }
.charts-axes { flex: none; width: 44px; }
.chart-axis svg { display: block; }
.charts-scroll {
  flex: 1 1 auto; min-width: 0; overflow-x: auto; overflow-y: hidden;
  overscroll-behavior-x: contain; /* don't hijack the page's back-gesture */
}
.charts-inner { display: block; }
.chart { position: relative; }
.chart svg { display: block; height: auto; }

/* Level-chart callouts: a sibling of .charts-scroll (not nested inside it), so
   `right: 0` resolves against .charts-wrap — which is exactly the visible
   viewport's width, since only .charts-scroll's content is widened past it —
   and pins there natively with no JS involved in the positioning itself.
   `top`/`height` line up with #chart-level's own box: 22px is the chart-label
   row above it (.label-spacer), 299px is LEVEL_HEIGHT from chart.js. Content
   (not position) is still updated on scroll, to track whichever week is
   currently at the right edge rather than always the newest one. */
.level-callouts { position: absolute; top: 22px; right: 0; height: 299px; pointer-events: none; }

/* Label height is duplicated as a spacer in the axis column so the two columns
   stay row-aligned; keep the two values equal. */
.charts-inner .chart-label {
  position: sticky; left: 0; z-index: 2;
  height: 22px; line-height: 22px; margin: 0;
  width: max-content; padding-right: 12px;
  background: var(--plane);
  font-size: 0.78rem; color: var(--text-secondary); font-weight: 500;
}
.label-spacer { height: 22px; }
.scroll-hint { margin: 20px 0 0; font-size: 0.78rem; color: var(--muted); }

/* thin, unobtrusive scrollbar */
.charts-scroll::-webkit-scrollbar { height: 10px; }
.charts-scroll::-webkit-scrollbar-track { background: transparent; }
.charts-scroll::-webkit-scrollbar-thumb {
  background: var(--axis); border-radius: 5px;
  border: 3px solid var(--plane); background-clip: padding-box;
}
.charts-scroll { scrollbar-width: thin; scrollbar-color: var(--axis) transparent; }

.grid-line { stroke: var(--grid); stroke-width: 1; }
.axis-line { stroke: var(--axis); stroke-width: 1; }
.parity-line { stroke: var(--axis); stroke-width: 1; }
.tick-text { fill: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.anno-line { stroke: var(--axis); stroke-width: 1; }
.anno-text { fill: var(--muted); font-size: 10.5px; }
.chart-label { margin: 0 0 4px; font-size: 0.78rem; color: var(--text-secondary); font-weight: 500; }

/* Reveals the page background through a thin gap at each quarter mark, rather
   than painting a fixed color over the bars — always correct in both themes
   because it's literally the surface showing through, not a color tuned to
   contrast against it. */
.division-gap { fill: var(--plane); pointer-events: none; }

/* Latest-value callouts, above and below the chart. HTML spans now (not SVG
   text) so they can live in the sticky overlay instead of the scrolling SVG.
   Since the callout now tracks whatever week is scrolled to (not always the
   fixed latest one), it can land next to any year tick or annotation label —
   a matte background (same trick as .chart-label) keeps it legible instead of
   overlapping whatever text happens to be underneath. */
.axis-callout {
  position: absolute; right: 4px; line-height: 1;
  font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums;
  white-space: nowrap; background: var(--plane); padding: 2px 4px;
  border-radius: 3px;
}
.callout-ua { top: 16px; color: var(--series-1); }
.callout-ru { bottom: 6px; color: var(--dv-2); }

/* Diverging weekly bars: blue when the week favors Ukrainian, red when it
   favors Russian. Same blue/red pair as the "купити"/"купить" heading. */
.pace-bar.up { fill: var(--series-1); }
.pace-bar.dn { fill: var(--dv-2); }
.pace-bar.low-conf { opacity: 0.35; }
.pace-dot { fill: var(--text-secondary); }
.pace-dot-up { fill: var(--series-1); }
.pace-dot-dn { fill: var(--dv-2); }

/* Stacked weekly bar: blue (UA) below the boundary, red (RU) above it — same
   pair used everywhere else for "купити"/"купить" (region bars, split bar,
   the heading itself), no new color introduced. */
.bar-ua { fill: var(--series-1); }
.bar-ru { fill: var(--dv-2); }

.series-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.s2 { stroke: var(--series-2); }
.s2-fill { fill: var(--series-2); }
.low-conf { opacity: 0.35; }
.end-dot { stroke: var(--surface-1); stroke-width: 2; }
.end-label { fill: var(--text-primary); font-size: 12px; font-weight: 600; }
.crosshair { stroke: var(--axis); stroke-width: 1; pointer-events: none; }
.hover-dot { stroke: var(--surface-1); stroke-width: 2; pointer-events: none; }

.chart-legend { display: flex; gap: 16px; flex-wrap: wrap; margin: 10px 0 0; font-size: 0.8rem; color: var(--text-secondary); }
.chart-legend span.key { display: inline-flex; align-items: center; gap: 6px; }
.chart-legend i { width: 14px; height: 2px; border-radius: 1px; display: inline-block; }
.chart-legend i.dashed { background: none; height: 0; border-top: 2px dashed var(--series-1); }
.chart-legend i.dotted {
  background: repeating-linear-gradient(to right, var(--muted) 0 2px, transparent 2px 4px); height: 2px;
}
.chart-legend i.dashdot {
  background: repeating-linear-gradient(to right, var(--muted) 0 6px, transparent 6px 9px); height: 2px;
}

/* ── forecast chart: denoised trend + linear projection ────── */
.forecast-label { margin: 24px 0 0; font-size: 0.78rem; color: var(--text-secondary); font-weight: 500; }
.forecast-line { stroke: var(--series-1); }
.forecast-line.projected { stroke-dasharray: 5 4; opacity: 0.55; }
.forecast-dot { fill: var(--series-1); stroke: var(--surface-1); stroke-width: 2; }
.forecast-branch-dot { fill: var(--muted); stroke: var(--surface-1); stroke-width: 1.5; }
.milestone-pct { font-weight: 700; fill: var(--text-primary); }

/* Counterfactual "what if the pace from before this event had just kept
   going" lines — muted and clearly distinct from the real actual/forecast
   line, differentiated from each other only by dash rhythm since they're the
   same kind of thing (a real historical pace extrapolated past where it
   actually stopped), not a second data series. */
.forecast-scenario { stroke: var(--muted); opacity: 0.85; }
.forecast-scenario.pace-pre-2014 { stroke-dasharray: 1.5 3; }
.forecast-scenario.pace-2014-2022 { stroke-dasharray: 6 3 1.5 3; }

/* ── map ────────────────────────────────────────────────── */
/* Always single column: map above, region list below — regardless of viewport
   width, not just on narrow screens. */
.map-layout { display: flex; flex-direction: column; gap: 24px; margin-top: 14px; }
.map-figure { margin: 0; min-width: 0; }
.map svg { display: block; width: 100%; height: auto; }
.region-shape { stroke: var(--surface-1); stroke-width: 1.4; cursor: pointer; transition: opacity .12s; }
.region-shape:hover { opacity: 0.82; }
.region-shape.selected { stroke: var(--text-primary); stroke-width: 2; }
.occupied-hatch { fill: url(#hatch); pointer-events: none; }

.slider-wrap { display: flex; align-items: center; gap: 10px; font-size: 0.8rem; color: var(--text-secondary); }
.slider-wrap input[type=range] { width: 220px; accent-color: var(--series-1); }
.period-out { font-variant-numeric: tabular-nums; font-weight: 600; color: var(--text-primary); min-width: 62px; }

/* No inner scroll: the list grows and scrolls with the page. */
.region-list { list-style: none; margin: 0; padding: 0; }
.region-list li {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 8px;
  padding: 4px 6px; border-radius: 6px; cursor: pointer; font-size: 0.82rem;
}
.region-list li:hover { background: var(--plane); }
.region-list li.selected { background: var(--plane); box-shadow: inset 0 0 0 1px var(--border-strong); }
.region-list .rname { display: flex; align-items: center; gap: 7px; min-width: 0; }
.region-list .rname span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.region-list .chip { width: 11px; height: 11px; border-radius: 2px; flex: none; }
.region-list .rval { font-variant-numeric: tabular-nums; font-weight: 600; }
/* Full-width UA/RU split. The 2px gap is the separator — never a stroke. */
.region-list .rbar { grid-column: 1 / -1; height: 4px; display: flex; gap: 2px; }
.region-list .rbar i { display: block; height: 100%; border-radius: 2px; }
.region-list .rbar .ua { background: var(--series-1); }
.region-list .rbar .ru { background: var(--dv-2); }
.region-list .rbar .nodata { background: var(--no-data); }

/* ── method ─────────────────────────────────────────────── */
.method h2 { margin-bottom: 10px; }
.method h3 { font-size: 0.88rem; margin: 18px 0 5px; }
.method p, .method li { color: var(--text-secondary); font-size: 0.86rem; max-width: 76ch; }
.method ul { padding-left: 18px; margin: 6px 0; }
.method code {
  font-size: 0.85em; background: var(--plane); padding: 1px 5px;
  border-radius: 4px; border: 1px solid var(--border);
}

/* ── tooltip ────────────────────────────────────────────── */
.tooltip {
  position: fixed; z-index: 50; pointer-events: none;
  background: var(--surface-1); color: var(--text-primary);
  border: 1px solid var(--border-strong); border-radius: 8px;
  padding: 8px 11px; font-size: 0.8rem; line-height: 1.45;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.13); max-width: 260px;
}
.tooltip .tt-title { font-weight: 600; margin-bottom: 3px; }
.tooltip .tt-row { display: flex; justify-content: space-between; gap: 14px; color: var(--text-secondary); }
.tooltip .tt-row b { color: var(--text-primary); font-variant-numeric: tabular-nums; }
.tooltip .tt-note { color: var(--muted); font-size: 0.92em; margin-top: 4px; }
.tooltip .tt-sep {
  margin-top: 6px; padding-top: 5px; border-top: 1px solid var(--border);
  font-weight: 600; font-size: 0.95em;
}

/* ── footer ─────────────────────────────────────────────── */
.page-foot { border-top: 1px solid var(--border); margin-top: 10px; padding: 24px 0 40px; }
.foot-controls { display: flex; gap: 8px; margin-bottom: 16px; }
.page-foot p { margin: 0 0 4px; font-size: 0.8rem; color: var(--text-secondary); }
.muted { color: var(--muted) !important; }

/* ── responsive ─────────────────────────────────────────── */
@media (max-width: 820px) {
  .hero { padding: 26px 0 22px; }
  .proj-row { gap: 12px; }
}
@media (max-width: 480px) {
  .wrap { padding: 0 14px; }
  .section { padding: 32px 0; }
  .hero-intro { padding: 36px 0 8px; }
  .slider-wrap input[type=range] { width: 150px; }
  .proj-month { font-size: 0.72rem; }
  .proj-year { font-size: 1.05rem; }
}

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

/* Forced colors: fall back to system colors and lean on the hatch channel. */
@media (forced-colors: active) {
  .region-shape { forced-color-adjust: none; stroke: CanvasText; }
}

/* ── release: status is part of the headline, scenarios are secondary ── */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.load-status {
  margin: 16px 0 0; padding: .75rem 1rem; border-radius: 8px;
  border: 1px solid var(--dv-2); color: var(--text-primary); background: var(--surface-1);
}
.headline-lede { margin: 0; font-size: 1.05rem; max-width: 62ch; }
.headline-lede b { font-size: 1.15em; }
.headline-change { margin: 14px 0 0; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.headline-change b { color: var(--text-primary); }
.headline-caveat { margin: 6px 0 0; font-size: 0.82rem; color: var(--text-secondary); max-width: 62ch; }
.stale-notice {
  margin: 16px 0 0; border-left: 3px solid var(--dv-2); padding: .6rem 1rem;
  font-size: .9rem; background: var(--surface-1); border-radius: 0 6px 6px 0;
}
.data-status {
  display: grid; grid-template-columns: max-content 1fr; gap: 4px 16px;
  margin: 20px 0 0; font-size: 0.8rem;
}
.data-status > div { display: contents; }
.data-status dt { color: var(--muted); }
.data-status dd { margin: 0; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.region-list li:focus-visible, .region-shape:focus-visible { outline: 2px solid var(--series-1); outline-offset: 3px; }
/* "<1" weeks: the bar is a floor, not a measurement, so it is drawn hatched. */
.region-list li.censored .rval { color: var(--text-secondary); font-style: italic; }
.region-list li.censored .rbar .ua { min-width: 2px; }
.region-list li.censored .rbar .ru {
  background: repeating-linear-gradient(135deg, var(--dv-2) 0 4px, var(--dv-3) 4px 6px);
}
.charts-scroll:focus-visible { outline-offset: 4px; }

.projections h2 { margin-bottom: 4px; }
.scenarios { margin-top: 16px; border: 1px solid var(--border-strong); border-radius: 8px; }
.scenarios > summary {
  cursor: pointer; padding: 10px 14px; font-size: 0.88rem; font-weight: 500;
  color: var(--text-secondary); min-height: 44px; display: flex; align-items: center;
}
.scenarios > summary:hover { color: var(--text-primary); }
.scenarios[open] > summary { border-bottom: 1px solid var(--border); }
.scenarios-body { padding: 4px 14px 16px; }
.scenario-warning {
  margin: 12px 0 0; font-size: 0.84rem; color: var(--text-secondary);
  border-left: 3px solid var(--muted); padding-left: 10px; max-width: 70ch;
}

.download-row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.download-row button.ghost { min-height: 44px; }
@media (max-width: 540px) { .proj-row { gap: .75rem; } .data-status { grid-template-columns: 1fr; gap: 0 0; } .data-status dd { margin-bottom: 6px; } }
@media (forced-colors: active) {
  .stale-notice, .load-status, .scenarios { border: 1px solid CanvasText; }
}
