/* Ukraina – frontlinjen. Built on the House design tokens (shared/styles.css +
   brand-tokens). The control-zone palette is the only product-local colour set:
   a red→maroon occupation scale plus a quiet green for de-occupied land, tuned
   to read on both paper and dark. Layout mirrors Våldskartan: a map hero with a
   stats/chart side column. */

:root {
  --uk-container: 1600px;
  --dash-h: clamp(640px, 62vh, 760px);
  --uk-occupied:  #c0392b; /* occupied since 2022 (the live front) */
  --uk-pre2022:   #7d1128; /* occupied since 2014 (Crimea + ORDLO) */
  --uk-contested: #8d8881; /* grey zone / status unknown (warm neutral grey) */
  --uk-liberated: #3f8f5f; /* de-occupied, Ukraine-controlled again */
  --uk-ua: #3f8f5f;        /* event marker: Ukrainian action — the map's Ukraine-green (vs occupation red) */
}
:root.dark {
  --uk-occupied:  #e0584a;
  --uk-pre2022:   #c25563;
  --uk-contested: #a8a39a;
  --uk-liberated: #5fb585;
  --uk-ua: #5fb585;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }

html, body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
h1, h2, h3 {
  font-family: var(--font-serif);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-tight);
  margin: 0;
}
a { color: inherit; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

/* ---------- Header ---------- */
.tagline {
  margin: 0 0 var(--space-4);
  font-size: var(--text-sm);
  color: var(--ink-muted);
}
.live {
  width: 9px; height: 9px;
  border-radius: var(--radius-pill);
  background: var(--gold);
  box-shadow: 0 0 0 0 var(--gold-wash);
  animation: live-pulse 2.4s var(--ease) infinite;
}
@keyframes live-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(200,164,85,0.5); }
  70%  { box-shadow: 0 0 0 7px rgba(200,164,85,0); }
  100% { box-shadow: 0 0 0 0 rgba(200,164,85,0); }
}
@media (prefers-reduced-motion: reduce) { .live { animation: none; } }
.updated { color: var(--ink-faint); }

/* ---------- Layout ---------- */
.container { max-width: var(--uk-container); margin: 0 auto; padding: var(--space-5); }
.layout {
  display: grid;
  grid-template-columns: minmax(260px, 0.85fr) minmax(420px, 1.7fr) minmax(300px, 1fr);
  gap: var(--space-5);
  align-items: stretch;
}
.col { display: flex; flex-direction: column; gap: var(--space-5); }
/* Desktop order: stats | map | events. (Source order is map-first for mobile.) */
.col-left { order: 1; }
.col-center { order: 2; }
.col-right { order: 3; }

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-5);
}
.col-center > .panel, .col-left > .panel, .col-right > .panel { display: flex; flex-direction: column; min-height: 0; }

.panel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.panel-head h2 { font-size: var(--text-lg); }
.map-date {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink-muted);
}

/* Three equal-height columns at the map's height. The chart fills the left
   column and the events feed fills the right, each scrolling internally so the
   feed stays in view without scrolling the page. */
@media (min-width: 921px) {
  .col-left, .col-center, .col-right { height: var(--dash-h); }
  .col-center > .panel { flex: 1; }
  .col-center .map { flex: 1; height: auto; min-height: 0; }
  .col-left > .panel:last-child { flex: 1; }
  .col-left .chart { flex: 1; height: auto; min-height: 200px; }
  .col-right > .panel-events { flex: 1; }
  .panel-events .uk-ev-feed { flex: 1; }
}

/* ---------- Map ---------- */
.map {
  width: 100%;
  height: clamp(440px, 62vh, 660px);
  border-radius: var(--radius);
  border: 1px solid var(--line);
  background: var(--surface-sunken);
  overflow: hidden;
}
.leaflet-container { font-family: var(--font-sans); background: var(--surface-sunken); }
.leaflet-bar a { background: var(--surface); color: var(--ink); border-color: var(--line); }
.leaflet-bar a:hover { background: var(--surface-sunken); }
.leaflet-control-attribution {
  background: rgba(255,255,255,0.7); color: var(--ink-faint); font-size: 10px;
}
:root.dark .leaflet-control-attribution { background: rgba(28,29,34,0.7); }
.leaflet-control-attribution a { color: var(--ink-muted); }

/* ---------- Legend ---------- */
.legend {
  list-style: none;
  display: flex; flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin: var(--space-3) 0 0;
  padding: 0;
}
.legend li { display: inline-flex; }
.legend-btn {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font: inherit; font-size: var(--text-sm);
  color: var(--ink-muted);
  background: none; border: 0; padding: 2px 4px;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease), opacity var(--dur-fast) var(--ease);
}
.legend-btn:hover { color: var(--ink); }
.legend-btn.is-off { opacity: 0.4; text-decoration: line-through; }
.dot {
  width: 12px; height: 12px; border-radius: 3px; flex-shrink: 0;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.12);
}
/* Swatches composite the status colour at the SAME fill opacity the map draws
   (occupied .55, pre2022 .6, contested .45, liberated .28) over the surface, so
   the legend reads like the map rather than as fully saturated chips. */
.dot-occupied  { background: color-mix(in srgb, var(--uk-occupied) 55%, var(--surface)); }
.dot-pre2022   { background: color-mix(in srgb, var(--uk-pre2022) 60%, var(--surface)); }
.dot-contested { background: color-mix(in srgb, var(--uk-contested) 45%, var(--surface)); }
.dot-liberated { background: color-mix(in srgb, var(--uk-liberated) 28%, var(--surface)); }

/* ---------- Timeline ---------- */
.timeline {
  display: flex; align-items: center; gap: var(--space-3);
  margin-top: var(--space-4);
}
.play-btn {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  border: 1px solid var(--line);
  border-radius: var(--radius-pill);
  background: var(--surface-sunken);
  color: var(--ink);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.play-btn:hover { border-color: var(--ink-faint); background: var(--surface); }
.play-btn .ic-pause { display: none; }
.play-btn.is-playing .ic-play { display: none; }
.play-btn.is-playing .ic-pause { display: inline; }

.time-range {
  flex: 1;
  -webkit-appearance: none; appearance: none;
  height: 6px; border-radius: var(--radius-pill);
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  cursor: pointer;
}
.time-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--uk-occupied);
  border: 2px solid var(--surface);
  box-shadow: 0 1px 3px rgba(0,0,0,0.3);
  cursor: pointer;
}
.time-range::-moz-range-thumb {
  width: 18px; height: 18px; border: 2px solid var(--surface); border-radius: 50%;
  background: var(--uk-occupied); cursor: pointer;
}
/* ---------- Summary / KPIs ---------- */
.summary-bar {
  display: flex; flex-direction: column; gap: var(--space-3);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4) var(--space-5);
}
.sumbar-label { font-size: var(--text-sm); font-weight: 600; color: var(--ink-muted); }
.sumbar-label em { font-style: normal; font-weight: 400; color: var(--ink-faint); }
/* Stacked: the two 6-digit KPI cards don't fit side by side in the narrow left
   column, so the gråzon card sits under the occupied one. */
.kpis { display: grid; grid-template-columns: 1fr; gap: var(--space-3); }
.kpi {
  display: flex; flex-direction: column; gap: 3px;
  background: var(--surface-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--space-3) var(--space-4);
}
.kpi-top { display: flex; align-items: baseline; gap: var(--space-2); }
.kpi-top .dot { align-self: center; box-shadow: none; }
.kpi b {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;            /* never break "116 875" across lines */
  font-size: var(--text-2xl);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.kpi-unit { font-size: var(--text-sm); color: var(--ink-faint); }
.kpi-label { font-size: var(--text-sm); color: var(--ink-muted); }
/* Own line + tabular digits so the label never reflows or jitters as the
   percentage changes while scrubbing the slider. */
/* Reserve the line even when empty (early days show "–" with no percentage), so
   the card height — and the row both KPI cards share — never shifts while scrubbing. */
.kpi-pct { display: block; min-height: 1.35em; line-height: 1.35; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.stat-delta {
  margin-top: 2px;
  /* Always exactly one line: nowrap stops a long value wrapping to two lines,
     and min-height reserves the line even when empty (no 30-day reference near
     the timeline start) — so the card height, and the row it sets, never shift. */
  display: block;
  white-space: nowrap;
  line-height: 1.4;
  min-height: 1.4em;
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--ink-faint);
}
.stat-delta.is-up { color: var(--danger); }
.stat-delta.is-down { color: var(--positive); }

/* ---------- Chart ---------- */
.chart { width: 100%; height: 280px; }
.src {
  margin: var(--space-3) 0 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
  font-size: var(--text-xs);
  color: var(--ink-faint);
  line-height: var(--leading-snug);
}
.src a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

/* ---------- Events: strikes & battles ---------- */
/* Markers + synced feed over the front. Colour = who acted (Russia red / Ukraine
   blue); icon shape = type; a gold ring marks targets inside Russia/occupied
   Crimea; brand gold marks the focused event. A white rim keeps markers legible
   over the territory fills. */
.panel-events { min-height: 0; }
.ev-count { font-size: var(--text-sm); color: var(--ink-muted); white-space: nowrap; }
.ev-count b { font-variant-numeric: tabular-nums; color: var(--ink); }

.uk-ev-legend {
  list-style: none;
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4);
  margin: 0 0 var(--space-3); padding: 0 0 var(--space-3);
  border-bottom: 1px solid var(--line);
}
.uk-ev-key { display: inline-flex; align-items: center; gap: 6px; font-size: var(--text-xs); color: var(--ink-muted); }
.uk-ev-key svg { width: 14px; height: 14px; color: var(--ink-faint); }
.uk-ev-sw { width: 11px; height: 11px; border-radius: 50%; flex-shrink: 0; }
.uk-ev-sw.act-ru { background: var(--uk-occupied); }
.uk-ev-sw.act-ua { background: var(--uk-ua); }

.uk-ev-feed {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 1px;
  overflow-y: auto; min-height: 0;
}
.uk-ev-row {
  display: flex; align-items: flex-start; gap: var(--space-3);
  width: 100%; text-align: left; font: inherit;
  background: none; border: 0; border-radius: var(--radius);
  padding: var(--space-2) var(--space-3); cursor: pointer;
  transition: background var(--dur-fast) var(--ease);
}
.uk-ev-row:hover { background: var(--surface-sunken); }
.uk-ev-row.is-active { background: var(--gold-wash); }
.uk-ev-ic {
  flex: none; display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; margin-top: 1px;
  border-radius: 50%; color: #fff;
}
.uk-ev-ic svg { width: 14px; height: 14px; }
.uk-ev-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.uk-ev-name { font-size: var(--text-sm); font-weight: 600; color: var(--ink); line-height: var(--leading-snug); }
.uk-ev-meta { font-size: var(--text-xs); color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.uk-ev-empty { font-size: var(--text-sm); color: var(--ink-faint); padding: var(--space-3); }

/* Actor colour, shared by feed icons and map pins. */
.act-ru { background: var(--uk-occupied); }
.act-ua { background: var(--uk-ua); }
.act-oth { background: var(--uk-contested); }

/* Map markers (Leaflet divIcon). */
.uk-ev { background: none; border: 0; }
.uk-ev-pin {
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%;
  color: #fff; border: 2px solid var(--surface);
  box-shadow: 0 1px 4px rgba(0,0,0,0.35);
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}
.uk-ev-pin svg { width: 15px; height: 15px; }
.uk-ev-pin:hover { transform: scale(1.15); }
.uk-ev-pin.is-active {
  transform: scale(1.18);
  box-shadow: 0 0 0 4px var(--gold-wash), 0 0 0 2px var(--gold), 0 1px 4px rgba(0,0,0,0.35);
  border-color: var(--gold);
}
@media (prefers-reduced-motion: reduce) { .uk-ev-pin { transition: none; } .uk-ev-pin:hover, .uk-ev-pin.is-active { transform: none; } }

/* Marker popup, themed to match the House cards. */
.uk-ev-popup .leaflet-popup-content-wrapper {
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-md);
}
.uk-ev-popup .leaflet-popup-content { margin: var(--space-3) var(--space-4); max-width: 240px; }
.uk-ev-popup .leaflet-popup-tip { background: var(--surface); border: 1px solid var(--line); }
.uk-ev-pop { display: flex; flex-direction: column; gap: 4px; }
.uk-ev-pop b { font-size: var(--text-sm); color: var(--ink); }
.uk-ev-tag { display: inline-flex; align-items: center; gap: 5px; font-size: var(--text-xs); font-weight: 600; color: var(--ink-muted); }
.uk-ev-tag svg { width: 13px; height: 13px; }
.uk-ev-tag.act-ru { background: none; color: var(--uk-occupied); }
.uk-ev-tag.act-ua { background: none; color: var(--uk-ua); }
.uk-ev-tag.act-oth { background: none; color: var(--ink-muted); }
.uk-ev-pop-date { font-size: var(--text-xs); color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.uk-ev-ins { color: var(--gold); font-weight: 600; }
.uk-ev-pop-desc { font-size: var(--text-xs); color: var(--ink-muted); line-height: var(--leading-snug); margin-top: 2px; }

/* ---------- Page footer ---------- */
.page-foot {
  margin: var(--space-6) 0 0;
  padding-top: var(--space-4);
  border-top: 1px solid var(--line);
  font-size: var(--text-xs);
  color: var(--ink-faint);
  line-height: var(--leading-body);
}
.page-foot a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

/* ---------- Thumbnail mode (?thumb) ---------- */
/* Map-only view at the og:image size; everything else is hidden and the map
   fills the frame. Used by the headless thumbnail render, never in normal use. */
.thumb #sitenav, .thumb .topbar, .thumb .tagline, .thumb .col-left, .thumb .col-right,
.thumb .legend, .thumb .timeline, .thumb .panel-head, .thumb .page-foot { display: none !important; }
.thumb .container { max-width: none; padding: 0; margin: 0; }
.thumb .layout { display: block; }
.thumb .panel { border: 0; border-radius: 0; box-shadow: none; padding: 0; background: none; }
.thumb .map { height: 100vh !important; border: 0; border-radius: 0; }
.thumb .leaflet-control-container { display: none !important; }

/* ---------- Responsive ---------- */
@media (max-width: 920px) {
  .layout { grid-template-columns: 1fr; }
  /* Stack map first, then stats, then events. */
  .col-center { order: 1; }
  .col-left { order: 2; }
  .col-right { order: 3; }
  .map { height: clamp(380px, 56vh, 560px); }
  .uk-ev-feed { max-height: 60vh; }
}
@media (max-width: 560px) {
  .container { padding: var(--space-4); }
  .panel { padding: var(--space-4); }
  /* Stack the two KPI cards: side-by-side is too narrow for the 6-digit number
     on a phone (it would wrap "116 875" across two lines). */
  .kpis { grid-template-columns: 1fr; }
}
