/* ======================================================================
   Погода — светлый «небесный» интерфейс
   Живой фон, управляемый текущей погодой; данные плотные и читаемые.
   ====================================================================== */

:root {
  color-scheme: light;

  /* Base palette — calm paper-slate (deliberately de-blued: less "gismeteo") */
  --bg-0: oklch(97.8% 0.005 255);
  --bg-1: oklch(99.3% 0.003 255);
  --ink: oklch(24% 0.03 264);
  --muted: oklch(45% 0.024 262);
  --soft: oklch(56% 0.02 262);
  --faint: oklch(67% 0.018 262);

  /* Glass surfaces (white translucency on a soft sky) */
  --glass: oklch(100% 0 0 / 0.58);
  --glass-2: oklch(100% 0 0 / 0.8);
  --glass-strong: oklch(100% 0 0 / 0.74);
  --line: oklch(48% 0.025 262 / 0.12);
  --line-strong: oklch(42% 0.035 262 / 0.2);

  /* Accents — confident indigo (not bright sky-blue) + warm amber counterpoint */
  --accent: oklch(51% 0.16 264);
  --accent-warm: oklch(67% 0.14 52);
  --accent-soft: oklch(51% 0.16 264 / 0.11);

  --ok: oklch(56% 0.13 162);
  --warn: oklch(68% 0.14 64);
  --danger: oklch(56% 0.18 25);

  /* Weather icon colors (work on light surfaces) */
  --ico-sun: oklch(72% 0.16 70);
  --ico-moon: oklch(62% 0.05 255);
  --ico-cloud: oklch(74% 0.03 250);
  --ico-cloud-dark: oklch(58% 0.04 252);
  --ico-rain: oklch(60% 0.14 240);
  --ico-snow: oklch(72% 0.1 235);
  --ico-bolt: oklch(70% 0.16 75);

  /* Precipitation intensity ramp — shared by the hourly chart bars and legend */
  --rain-light: oklch(77% 0.075 236);
  --rain-mod: oklch(62% 0.13 240);
  --rain-heavy: oklch(50% 0.16 250);

  /* Dynamic sky — overwritten per-condition by JS via body[data-sky] */
  --sky-top: oklch(88% 0.06 235);
  --sky-bottom: oklch(98% 0.012 235);
  --sky-glow: oklch(90% 0.09 95 / 0.55);
  --sky-glow-2: oklch(85% 0.08 230 / 0.45);

  --shadow-lift: 0 20px 45px -28px oklch(45% 0.06 255 / 0.45);
  --radius: 16px;
  --radius-sm: 11px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  --font-display: "Fraunces", ui-serif, Georgia, serif;
  --font-body: "Hanken Grotesk", ui-sans-serif, system-ui, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, "SF Mono", monospace;

  font-family: var(--font-body);
}

/* Condition-driven sky tints (set on <body data-sky data-daytime>) */
body[data-sky="clear"][data-daytime="day"] {
  --sky-top: oklch(82% 0.1 230);
  --sky-glow: oklch(92% 0.1 95 / 0.7);
}
body[data-sky="partly"] { --sky-top: oklch(86% 0.06 232); }
body[data-sky="cloudy"],
body[data-sky="fog"] {
  --sky-top: oklch(88% 0.02 250);
  --sky-glow: oklch(90% 0.02 250 / 0.4);
  --sky-glow-2: oklch(85% 0.02 250 / 0.3);
}
body[data-sky="rain"],
body[data-sky="drizzle"],
body[data-sky="thunder"] {
  --sky-top: oklch(80% 0.04 245);
  --sky-glow: oklch(82% 0.05 240 / 0.45);
  --sky-glow-2: oklch(78% 0.05 250 / 0.4);
}
body[data-sky="snow"],
body[data-sky="sleet"] {
  --sky-top: oklch(90% 0.02 235);
  --sky-glow: oklch(96% 0.02 235 / 0.6);
}
body[data-daytime="night"] {
  --sky-top: oklch(58% 0.07 262);
  --sky-bottom: oklch(90% 0.02 250);
  --sky-glow: oklch(70% 0.07 280 / 0.4);
  --sky-glow-2: oklch(72% 0.06 230 / 0.35);
}

* {
  box-sizing: border-box;
}

html {
  background: var(--bg-0);
}

body {
  min-width: 320px;
  margin: 0;
  color: var(--ink);
  background: var(--bg-0);
  font-size: 14.5px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ---------------------------------------------------------------- Sky */
.sky {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background: linear-gradient(180deg, var(--sky-top), var(--sky-bottom) 70%);
  transition: background 1200ms var(--ease);
}

.sky__mesh,
.sky__aurora {
  position: absolute;
  inset: -20%;
  transition: opacity 1200ms var(--ease);
}

.sky__mesh {
  background:
    radial-gradient(40% 50% at 18% 12%, var(--sky-glow), transparent 70%),
    radial-gradient(45% 55% at 85% 8%, var(--sky-glow-2), transparent 72%),
    radial-gradient(60% 60% at 60% 100%, oklch(40% 0.06 250 / 0.5), transparent 70%);
  filter: blur(8px);
  animation: drift 28s ease-in-out infinite alternate;
}

.sky__aurora {
  background:
    conic-gradient(from 120deg at 30% 30%, transparent, var(--sky-glow) 25%, transparent 50%),
    conic-gradient(from 300deg at 75% 20%, transparent, var(--sky-glow-2) 30%, transparent 55%);
  opacity: 0.6;
  filter: blur(40px);
  animation: drift 36s ease-in-out infinite alternate-reverse;
}

.sky__grain {
  position: absolute;
  inset: 0;
  opacity: 0.4;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}

@keyframes drift {
  from { transform: translate3d(-2%, -1%, 0) scale(1.02); }
  to { transform: translate3d(3%, 2%, 0) scale(1.08); }
}

@media (prefers-reduced-motion: reduce) {
  .sky__mesh,
  .sky__aurora { animation: none; }
}

/* Live precipitation overlay (drops/flakes injected by JS) */
.sky__precip {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.sky__precip i {
  position: absolute;
  top: -8%;
  display: block;
  will-change: transform;
}

.sky__precip i.drop {
  width: 1.5px;
  height: 18px;
  background: linear-gradient(transparent, oklch(85% 0.05 220 / 0.55));
  animation: fall linear infinite;
}

.sky__precip i.flake {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: oklch(96% 0.01 240 / 0.7);
  animation: flutter linear infinite;
}

@keyframes fall {
  to { transform: translateY(112vh); }
}

@keyframes flutter {
  to { transform: translateY(112vh) translateX(22px); }
}

/* ------------------------------------------------------------- Layout */
.app-shell {
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: min(1020px, calc(100% - 36px));
  margin: 0 auto;
  padding: 0 0 28px; /* top breathing room now lives in .app-header */
}
/* Consistent vertical rhythm comes from the flex gap above — drop ad-hoc margins. */
.app-shell > .overview-card,
.app-shell > .status-bar,
.app-shell > .api-panel { margin-top: 0; margin-bottom: 0; }
.app-shell > .app-foot { margin-top: 4px; }

/* Tab panels reuse the shell's vertical rhythm for the sections they hold. */
.tabpanel {
  display: flex;
  flex-direction: column;
  gap: 16px;
  animation: tabFade 280ms var(--ease, ease) both;
}
.tabpanel[hidden] { display: none; }
@keyframes tabFade {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .tabpanel { animation: none; }
}

button,
input {
  font: inherit;
}

button {
  cursor: pointer;
}

h1, h2, p {
  margin: 0;
}

h1 {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: 1.34rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.05;
}

h2 {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: 1.18rem;
  font-weight: 560;
  line-height: 1.15;
}

code {
  font-family: var(--font-mono);
  font-size: 0.85em;
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--glass);
}

/* ----------------------------------------------------- Sticky header */
/* Topbar + tabbar travel together as one sticky unit. A page-coloured backing
   that fades out just below the tab bar masks the content scrolling underneath,
   so nothing bleeds through the translucent cards (the old bug came from two
   separate sticky bars overlapping each other). */
.app-header {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 12px;
  padding-bottom: 10px;
  margin-bottom: -10px; /* keep the shell's 16px rhythm to the next panel */
  background: linear-gradient(
    var(--bg-0) 0%,
    var(--bg-0) 68%,
    color-mix(in oklch, var(--bg-0), transparent 100%) 100%
  );
}

/* ------------------------------------------------------------- Topbar */
.topbar {
  position: relative;
  z-index: 3; /* lift above the sibling .tabbar so the location popup isn't trapped behind it */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 52px;
  padding: 8px 10px 8px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--glass-strong);
  backdrop-filter: blur(18px) saturate(1.4);
  box-shadow: var(--shadow-lift);
}

.product-title {
  display: flex;
  min-width: 0;
  align-items: center;
  gap: 10px;
}

.app-mark {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: radial-gradient(circle at 35% 30%, var(--accent-soft), transparent 70%), var(--glass);
  border: 1px solid var(--line-strong);
}

.app-mark svg {
  width: 22px;
  height: 22px;
}

.app-mark__ring {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.5;
  opacity: 0.5;
}

.app-mark__needle {
  fill: var(--accent);
  transform-origin: 16px 16px;
  animation: needle 9s ease-in-out infinite;
}

.app-mark__hub {
  fill: var(--ink);
}

@keyframes needle {
  0%, 100% { transform: rotate(-18deg); }
  50% { transform: rotate(22deg); }
}

.product-title__text { min-width: 0; }

.eyebrow {
  display: block;
  margin: 0 0 3px;
  color: var(--soft);
  font-family: var(--font-mono);
  font-size: 0.64rem;
  font-weight: 500;
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.section-kicker,
.status-label {
  display: block;
  margin: 0 0 6px;
  color: var(--soft);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
}

.hero-actions {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 7px;
}

.icon-button,
.text-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 36px;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  color: var(--ink);
  background: var(--glass);
  transition: border-color 200ms var(--ease), background-color 200ms var(--ease),
    color 200ms var(--ease), transform 160ms var(--ease);
}

.icon-button { width: 36px; padding: 0; }
.icon-button.small { min-height: 34px; width: 34px; }
.text-button { padding: 0 10px 0 11px; font-weight: 650; }
.text-button__icon { width: 17px; height: 17px; }
/* Chevron hints the location trigger opens a picker; muted so the pin leads. */
.text-button__chev { width: 14px; height: 14px; margin-left: -2px; color: var(--soft); }
.location-trigger { gap: 6px; }
.location-trigger[aria-expanded="true"] .text-button__chev { transform: rotate(180deg); }
.text-button__chev { transition: transform 200ms var(--ease); }

.icon-button svg,
.text-button svg {
  stroke: currentColor;
  stroke-width: 2;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* All icon-button glyphs share one size so the gear/close/refresh match. */
.icon-button svg { width: 18px; height: 18px; }
.icon-button.small svg { width: 16px; height: 16px; }
.icon-refresh { width: 18px; height: 18px; }

.text-button.primary {
  color: oklch(18% 0.03 252);
  background: var(--accent);
  border-color: transparent;
  font-weight: 750;
}

.icon-button:hover,
.text-button:hover {
  background: var(--glass-2);
  border-color: color-mix(in oklch, var(--accent), transparent 55%);
  transform: translateY(-1px);
}

.text-button.primary:hover {
  color: oklch(18% 0.03 252);
  background: color-mix(in oklch, var(--accent), white 12%);
}

.icon-button:active,
.text-button:active { transform: translateY(0); }

.is-loading .icon-refresh { animation: spin 0.8s linear infinite; }

@keyframes spin { to { transform: rotate(360deg); } }

/* ------------------------------------------------------------ Overview */
.overview-card {
  display: grid;
  grid-template-columns: minmax(0, 1.18fr) minmax(270px, 0.82fr);
  gap: 1px;
  margin-top: 10px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--line);
  box-shadow: var(--shadow-lift);
}

.overview-main,
.advice-panel {
  min-width: 0;
  padding: 18px 20px;
  background: var(--glass-strong);
  backdrop-filter: blur(16px);
}

.overview-main {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas:
    "kicker icon"
    "temp icon"
    "summary summary";
  align-content: start;
  align-items: center;
  gap: 11px 18px;
  background:
    radial-gradient(105% 90% at 0% 0%, var(--accent-soft), transparent 56%),
    var(--glass-strong);
}

.now-head {
  display: contents;
}

.now-head .section-kicker {
  grid-area: kicker;
  margin: 0;
}

.temperature-row {
  grid-area: temp;
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-end;
  gap: 15px;
  min-width: 0;
}

.temperature {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-variant-numeric: tabular-nums lining-nums;
  font-size: 5.35rem;
  font-weight: 440;
  letter-spacing: -0.025em;
  line-height: 0.82;
  color: var(--ink);
}

.temperature-side {
  display: grid;
  gap: 5px;
  min-width: 130px;
  padding-bottom: 4px;
}

.weather-chip {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  min-height: 28px;
  padding: 0 10px;
  border: 1px solid color-mix(in oklch, var(--accent), transparent 60%);
  border-radius: 999px;
  color: var(--accent);
  background: var(--accent-soft);
  font-size: 0.86rem;
  font-weight: 650;
}

.feels-line {
  color: var(--muted);
  font-size: 0.88rem;
  font-weight: 500;
}

.range-line {
  display: inline-flex;
  gap: 12px;
  font-variant-numeric: tabular-nums;
  font-size: 0.88rem;
  font-weight: 600;
}

.range-lo { color: var(--accent); }
.range-hi { color: var(--accent-warm); }

.summary {
  grid-area: summary;
  max-width: 70ch;
  color: var(--muted);
  font-size: 0.9rem;
  line-height: 1.42;
}
.summary[hidden] { display: none; }

/* Hero weather icon */
.weather-icon { display: inline-block; line-height: 0; }
.weather-icon--hero {
  grid-area: icon;
  display: grid;
  place-items: center;
  width: 96px;
  height: 96px;
  border-radius: 20px;
  background:
    radial-gradient(72% 72% at 50% 38%, color-mix(in oklch, var(--accent), transparent 86%), transparent 72%),
    var(--glass);
  border: 1px solid var(--line);
}
.weather-icon--hero svg { width: 76px; height: 76px; }

/* Advice + gauge */
.advice-panel {
  display: grid;
  align-content: center;
  gap: 14px;
}

.advice-body {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  align-items: center;
  gap: 14px;
}

.advice-text { min-width: 0; }
.advice-text h2 {
  margin-bottom: 5px;
  font-size: 1.08rem;
  line-height: 1.16;
}
.advice-text p {
  color: var(--muted);
  font-size: 0.86rem;
  line-height: 1.38;
}

/* Severity meter: an honest three-level instrument (calm / watch / caution)
   that replaced the abstract 0–100 "риск" dial. Bars fill cumulatively and the
   word + colour carry the level — no false-precision number. */
.risk-meter {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  width: 100%;
}

.risk-meter__bars {
  display: flex;
  align-items: flex-end;
  gap: 5px;
  height: 40px;
}

.risk-meter__bars i {
  width: 9px;
  border-radius: 3px;
  background: var(--glass-2);
  transition: background 500ms var(--ease);
}
.risk-meter__bars i:nth-child(1) { height: 16px; }
.risk-meter__bars i:nth-child(2) { height: 28px; }
.risk-meter__bars i:nth-child(3) { height: 40px; }

/* Active bars light up to the current level in its semantic colour. */
.risk-meter[data-level="calm"] .risk-meter__bars i:nth-child(1),
.risk-meter[data-level="watch"] .risk-meter__bars i:nth-child(-n + 2),
.risk-meter[data-level="caution"] .risk-meter__bars i {
  background: var(--risk-color, var(--ok));
  box-shadow: 0 0 8px color-mix(in oklch, var(--risk-color, var(--ok)), transparent 55%);
}

.risk-meter__word {
  font-size: 0.66rem;
  font-weight: 750;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--risk-color, var(--soft));
}

/* ----------------------------------------------------------- Statusbar */
.status-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  margin: 0;
}

.status-cell {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  min-width: 0;
  min-height: 26px;
  padding: 4px 8px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--glass);
}

.status-cell strong {
  display: inline-flex;
  align-items: center;
  overflow: hidden;
  font-size: 0.72rem;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.status-cell .status-label {
  margin: 0;
  font-size: 0.62rem;
  letter-spacing: 0.05em;
}

.confidence {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.confidence__dot {
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--soft);
  box-shadow: 0 0 0 0 currentColor;
}

.confidence[data-tone="ok"] { color: var(--ok); }
.confidence[data-tone="warn"] { color: var(--warn); }
.confidence[data-tone="danger"] { color: var(--danger); }
.confidence[data-tone] .confidence__dot {
  background: currentColor;
  animation: pulse 2.4s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in oklch, currentColor, transparent 40%); }
  50% { box-shadow: 0 0 0 5px transparent; }
}

/* ------------------------------------------------------------- Content */
.content-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 10px;
  min-width: 0;
}

.left-column,
.right-column {
  display: grid;
  align-content: start;
  gap: 10px;
  min-width: 0;
}

.panel {
  min-width: 0;
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--glass-strong);
  backdrop-filter: blur(14px);
  box-shadow: var(--shadow-lift);
}

.panel-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin-bottom: 14px;
}

.source-pill {
  display: inline-flex;
  align-items: center;
  min-height: 26px;
  padding: 0 11px;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  color: var(--muted);
  background: var(--glass);
  font-family: var(--font-mono);
  font-size: 0.74rem;
  font-weight: 500;
  max-width: 100%;
}

/* Hourly combined chart (temperature line + precipitation bars + cards) */
#forecastPanel {
  container: forecast / inline-size;
}

/* Hourly chart — single SVG: temperature spline + area, precip bars,
   icon overlay, time axis. Scrolls horizontally as one unit. */
.hchart {
  width: 100%;
  margin-bottom: 6px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
}
.hchart::-webkit-scrollbar { height: 7px; }
.hchart::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 99px; }

.hchart-inner { position: relative; }
.hchart-svg { display: block; }

.hchart-icons { position: absolute; inset: 0; pointer-events: none; }
.hchart-ico {
  position: absolute;
  top: 8px;
  transform: translateX(-50%);
  line-height: 0;
}
.hchart-ico svg { width: 100%; height: 100%; }

/* SVG primitives */
.hchart-axis { stroke: var(--line); stroke-width: 1; }
/* Лёгкие разделители между часами. */
.hchart-div { stroke: var(--line); stroke-width: 1; opacity: 0.5; }
/* «Ощущается» — пунктирная линия по той же шкале, что и температура. */
.hchart-feels {
  fill: none;
  stroke: var(--accent-warm, oklch(72% 0.14 50));
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 4 4;
  opacity: 0.85;
}
.hchart-feels-val {
  fill: var(--accent-warm, oklch(64% 0.14 50));
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.hchart-now {
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-dasharray: 2 4;
  opacity: 0.4;
}
.hchart-line {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.hchart-dot {
  fill: var(--bg-1);
  stroke: var(--accent);
  stroke-width: 2;
}
.hchart-dot.is-now { fill: var(--accent); }
.hchart-temp {
  fill: var(--ink);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 760;
  font-variant-numeric: tabular-nums;
}
.hchart-temp.is-now { fill: var(--accent); }
.hchart-bar rect {
  fill: var(--rain-light);
  transform-box: fill-box;
  transform-origin: bottom;
}
.hchart-bar[data-i="mod"] rect { fill: var(--rain-mod); }
.hchart-bar[data-i="heavy"] rect { fill: var(--rain-heavy); }
.hchart-bar-val {
  fill: var(--soft);
  font-family: var(--font-body);
  font-size: 10.5px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.hchart-time {
  fill: var(--muted);
  font-family: var(--font-mono);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.hchart-time.is-now { fill: var(--accent); font-weight: 600; }


.forecast-brief {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  overflow: hidden;
  margin: 0 0 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--glass);
}

.forecast-stat {
  min-width: 0;
  padding: 10px 12px;
  border-left: 1px solid var(--line);
}

.forecast-stat:first-child { border-left: 0; }

.forecast-stat__label {
  display: block;
  color: var(--soft);
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.forecast-stat__value {
  display: block;
  margin-top: 3px;
  overflow: hidden;
  color: var(--ink);
  font-size: 0.98rem;
  font-weight: 760;
  font-variant-numeric: tabular-nums;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.forecast-stat__sub {
  display: block;
  margin-top: 2px;
  overflow: hidden;
  color: var(--muted);
  font-size: 0.74rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@container forecast (max-width: 720px) {
  #forecastPanel .panel-heading {
    align-items: stretch;
  }

  #forecastPanel .segmented {
    width: 100%;
  }
  #forecastPanel .segmented button {
    min-height: 38px;
    font-size: 0.9rem;
  }

  .chart-legend {
    gap: 6px 10px;
    margin-bottom: 10px;
  }

  .chart-legend__sep {
    display: none;
  }
}

/* Chart legend — makes the line/precip encoding self-explanatory. */
.chart-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px 10px;
  margin: -5px 2px 10px;
  font-size: 0.68rem;
  color: var(--muted);
}
.chart-legend__item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}
.chart-legend__item::before {
  content: "";
  flex: 0 0 auto;
}
.chart-legend__item--line::before {
  width: 16px;
  height: 0;
  border-top: 2.5px solid var(--accent);
  border-radius: 2px;
}
.chart-legend__item--dash::before {
  width: 16px;
  height: 0;
  border-top: 2px dashed var(--accent-warm);
}
.chart-legend__item--bar::before {
  width: 8px;
  height: 10px;
  border-radius: 3px 3px 1px 1px;
}
.chart-legend__item--bar[data-i="light"]::before { background: var(--rain-light); }
.chart-legend__item--bar[data-i="mod"]::before { background: var(--rain-mod); }
.chart-legend__item--bar[data-i="heavy"]::before { background: var(--rain-heavy); }
.chart-legend__unit {
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--soft);
}
.chart-legend__sep {
  width: 1px;
  align-self: stretch;
  min-height: 14px;
  background: var(--line);
}
@media (max-width: 620px) {
  .chart-legend__sep { display: none; }
}


/* Daily — shared-scale temperature range bars (7-day) */
.daily-list { display: grid; gap: 4px; }

.daily-item {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) 2.4em minmax(96px, 1.4fr) 2.4em auto;
  align-items: center;
  gap: 14px;
  min-height: 52px;
  padding: 9px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--glass);
  transition: border-color 200ms var(--ease), background 200ms var(--ease);
}

.daily-item:hover { border-color: var(--line-strong); background: var(--glass-2); }

.daily-item.is-today {
  border-color: color-mix(in oklch, var(--accent), transparent 72%);
  background: var(--accent-soft);
}

.daily-day {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.daily-day .weather-icon svg { width: 40px; height: 40px; flex: 0 0 auto; }

.daily-day-text { min-width: 0; }
.daily-day-text b {
  display: block;
  overflow: hidden;
  font-weight: 700;
  text-transform: capitalize;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.daily-day-sub {
  display: block;
  overflow: hidden;
  color: var(--soft);
  font-size: 0.78rem;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.daily-day-date { color: var(--soft); }
.daily-day-desc { color: var(--faint); }

.daily-temp {
  font-size: 0.96rem;
  font-weight: 760;
  font-variant-numeric: tabular-nums;
  text-align: center;
  white-space: nowrap;
}
.daily-temp--lo { color: var(--soft); }
.daily-temp--hi { color: var(--ink); }

/* shared-scale range track: gradient anchored to the whole scale, clipped
   to each day's min–max segment so colour reads as absolute temperature. */
.dchart-track {
  position: relative;
  height: 8px;
  border-radius: 99px;
  background: color-mix(in oklch, var(--ink), transparent 91%);
}
.dchart-track__freeze {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 1px;
  background: color-mix(in oklch, var(--rain-mod), transparent 30%);
  transform: translateX(-50%);
  z-index: 1;
}
.dchart-track__fill {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    oklch(58% 0.16 250),
    oklch(72% 0.13 200),
    oklch(82% 0.11 130),
    oklch(67% 0.14 52));
}

@container forecast (max-width: 720px) {
  /* Narrow panel: day + temps on the first row, the range bar gets its own
     full-width row, meta below. Day names never fight the bar for space. */
  .daily-item {
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    column-gap: 10px;
    row-gap: 7px;
    padding: 10px 14px;
  }
  .daily-day { grid-column: 1 / 3; grid-row: 1; }
  .daily-temp--lo { grid-column: 3; grid-row: 1; }
  .daily-temp--hi { grid-column: 4; grid-row: 1; }
  .dchart-track { grid-column: 1 / -1; grid-row: 2; }
  .daily-meta { grid-column: 1 / -1; grid-row: 3; }
  .daily-temp { font-size: 0.92rem; }
  .daily-day .weather-icon svg { width: 36px; height: 36px; }
  /* The icon already conveys conditions; drop the wordy description so the
     date never truncates in the narrow day column. */
  .daily-day-desc { display: none; }
}

/* Daily meta: precip + UV + wind chips */
.daily-meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 5px 10px;
}
.daily-meta .rain,
.daily-meta .wind {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.daily-meta .meta-ico {
  width: 13px;
  height: 13px;
  stroke: currentColor;
  stroke-width: 1.9;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.7;
}
.daily-meta .rain { color: var(--rain-light); font-weight: 650; }
.daily-meta .rain[data-i="mod"] { color: var(--rain-mod); }
.daily-meta .rain[data-i="heavy"] { color: var(--rain-heavy); }
.daily-meta .rain[data-i="dry"] { color: var(--soft); }
.daily-meta .wind { color: var(--soft); }

.uv-pill {
  --uv: var(--ok);
  display: inline-flex;
  align-items: center;
  padding: 1px 7px;
  border-radius: 999px;
  color: var(--uv);
  background: color-mix(in oklch, var(--uv), transparent 86%);
  font-size: 0.72rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.uv-pill[data-lvl="low"] { --uv: var(--ok); }
.uv-pill[data-lvl="mod"] { --uv: var(--warn); }
.uv-pill[data-lvl="high"] { --uv: oklch(64% 0.17 45); }
.uv-pill[data-lvl="vhigh"] { --uv: var(--danger); }
.uv-pill[data-lvl="extreme"] { --uv: oklch(52% 0.2 320); }

@container forecast (max-width: 720px) {
  .forecast-brief {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .forecast-stat:nth-child(odd) {
    border-left: 0;
  }

  .forecast-stat:nth-child(n + 3) {
    border-top: 1px solid var(--line);
  }
}

/* ------------------------------------------------------- Details panel */
.details-panel {
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--glass-strong);
  backdrop-filter: blur(14px);
  box-shadow: var(--shadow-lift);
  overflow: hidden;
}

.details-panel > summary {
  display: flex;
  min-height: 50px;
  align-items: center;
  padding: 0 16px;
  color: var(--ink);
  cursor: pointer;
  font-weight: 650;
  list-style: none;
}

.details-panel > summary::-webkit-details-marker { display: none; }
.details-panel > summary span { display: flex; align-items: center; gap: 10px; }

.summary__icon {
  width: 17px;
  height: 17px;
  stroke: var(--accent);
  stroke-width: 2.4;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 240ms var(--ease);
}

.details-panel[open] .summary__icon { transform: rotate(90deg); }
.details-panel[open] > summary { border-bottom: 1px solid var(--line); }

.details-panel > .panel {
  margin: 12px;
  box-shadow: none;
  background: var(--glass);
}

/* Facts grid */
.fact-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 9px;
}

.fact-item {
  position: relative;
  display: grid;
  gap: 4px;
  min-height: 78px;
  align-content: start;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--glass);
}

.fact-item[data-has-tip] { cursor: help; }
.fact-item[data-has-tip]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.fact-head {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--soft);
  font-size: 0.76rem;
  font-weight: 600;
}

.fact-label { flex: 1 1 auto; min-width: 0; }

.fact-head svg {
  width: 18px;
  height: 18px;
  stroke: currentColor;
  stroke-width: 1.8;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.8;
  flex: 0 0 auto;
}

.fact-val {
  display: flex;
  align-items: baseline;
  gap: 2px;
  font-size: 1.4rem;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.fact-sub {
  color: var(--soft);
  font-size: 0.76rem;
  font-weight: 500;
}

.fact-item .wind-arrow {
  display: inline-block;
  margin-left: 4px;
  font-size: 1rem;
  color: var(--accent);
  transition: transform 400ms var(--ease);
}

.fact-trend {
  margin-left: 4px;
  font-size: 1rem;
  font-weight: 800;
}
.fact-trend[data-dir="up"] { color: var(--ok); }
.fact-trend[data-dir="down"] { color: var(--danger); }
.fact-trend[data-dir="steady"] { color: var(--soft); }

/* Compact wind rose in the wind tile */
.wind-rose { display: inline-flex; width: 26px; height: 26px; margin-left: 7px; align-self: center; }
.wind-rose svg { width: 26px; height: 26px; overflow: visible; }
.wind-rose__ring { fill: color-mix(in oklch, var(--accent), transparent 92%); stroke: var(--line-strong); stroke-width: 1.1; }
.wind-rose__n { fill: var(--soft); font-size: 6.5px; font-weight: 800; text-anchor: middle; font-family: inherit; }
.wind-rose__needle { transform-origin: 14px 14px; transition: transform 500ms var(--ease); }
.wind-rose__needle path { fill: var(--accent); }

/* UV color scale with a marker at the current index */
.uv-bar {
  position: relative;
  display: block;
  height: 6px;
  margin-top: 7px;
  border-radius: 99px;
  background: linear-gradient(90deg,
    oklch(80% 0.16 145), oklch(85% 0.17 95) 38%, oklch(75% 0.17 60) 62%,
    oklch(63% 0.22 25) 83%, oklch(55% 0.2 310));
}
.uv-bar__marker {
  position: absolute;
  top: 50%;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--ink);
  transform: translate(-50%, -50%);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}

/* Cross-source agreement badge — the core "N/8" signal on every tile */
.agree-badge {
  flex: 0 0 auto;
  font-size: 0.7rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  padding: 2px 6px;
  border-radius: 99px;
  border: 1px solid var(--line-strong);
  color: var(--soft);
  background: var(--glass-2);
  line-height: 1;
}
.agree-badge[data-tone="ok"] { color: var(--ok); border-color: color-mix(in oklch, var(--ok), transparent 55%); background: color-mix(in oklch, var(--ok), transparent 88%); }
.agree-badge[data-tone="warn"] { color: var(--warn); border-color: color-mix(in oklch, var(--warn), transparent 55%); background: color-mix(in oklch, var(--warn), transparent 88%); }
.agree-badge[data-tone="danger"] { color: var(--danger); border-color: color-mix(in oklch, var(--danger), transparent 55%); background: color-mix(in oklch, var(--danger), transparent 88%); }

/* Rich per-tile tooltip: what it means + source spread */
.fact-tip {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%);
  --tip-shift: 0px;
  z-index: 30;
  width: max-content;
  max-width: 240px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--tooltip-bg, #1b2330);
  color: #eef2f8;
  border: 1px solid color-mix(in oklch, #ffffff, transparent 86%);
  box-shadow: 0 12px 30px rgba(8, 12, 20, 0.35);
  pointer-events: none;
  /* display:none (not visibility:hidden) so an off-screen hidden tip never
     expands the document and causes horizontal overflow on mobile. */
  display: none;
  gap: 6px;
}
.fact-item:hover .fact-tip,
.fact-item:focus-within .fact-tip,
.fact-item:focus-visible .fact-tip {
  display: grid;
  animation: tipFade 150ms var(--ease, ease) both;
}
@keyframes tipFade { from { opacity: 0; } to { opacity: 1; } }
.fact-tip::after {
  content: "";
  position: absolute;
  top: 100%;
  left: calc(50% + var(--tip-shift));
  margin-left: -6px;
  border: 6px solid transparent;
  border-top-color: var(--tooltip-bg, #1b2330);
}
.fact-tip strong { font-size: 0.84rem; font-weight: 700; }
.fact-tip__what { font-size: 0.78rem; color: #c7d0de; line-height: 1.35; }
.fact-tip__range { font-size: 0.74rem; color: #aab6c8; }
.fact-tip__srcs { display: grid; gap: 2px; }
.fact-tip__src {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 0.74rem;
  font-variant-numeric: tabular-nums;
}
.fact-tip__src span { color: #aeb9ca; }
.fact-tip__src b { font-weight: 700; }
.fact-tip__agree { font-size: 0.74rem; font-weight: 700; }
.fact-tip__agree[data-tone="ok"] { color: #8fe3a9; }
.fact-tip__agree[data-tone="warn"] { color: #f3c87a; }
.fact-tip__agree[data-tone="danger"] { color: #f29b9b; }

@media (hover: none) {
  /* On touch, the tip would clip at screen edges; keep tap-to-focus but cap width */
  .fact-tip { max-width: min(240px, 70vw); }
}

/* Compare list — dot plots */
.compare-list { display: grid; gap: 4px; }

.compare-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 10px 13px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--glass);
}

.compare-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.compare-head b { font-weight: 650; }

.compare-dots {
  position: relative;
  height: 18px;
  margin-top: 7px;
  border-radius: 99px;
  background: linear-gradient(90deg, var(--glass-2), transparent 40%, transparent 60%, var(--glass-2));
}

.compare-dots .axis {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--line-strong);
}

.compare-dots .dot {
  position: absolute;
  top: 50%;
  width: 9px;
  height: 9px;
  margin: -4.5px 0 0 -4.5px;
  border-radius: 50%;
  background: var(--accent);
  border: 1.5px solid var(--bg-1);
  box-shadow: 0 0 0 1px var(--line-strong);
}

.compare-dots .dot.median {
  width: 12px; height: 12px; margin: -6px 0 0 -6px;
  background: var(--ink);
  z-index: 2;
}

.compare-dots .dot.outlier { background: var(--danger); }

.compare-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-variant-numeric: tabular-nums;
  font-size: 0.82rem;
  font-weight: 650;
  white-space: nowrap;
  text-align: right;
}

.compare-status[data-status="high"] { color: var(--ok); }
.compare-status[data-status="medium"] { color: var(--muted); }
.compare-status[data-status="watch"] { color: var(--warn); }
.compare-status[data-status="low"] { color: var(--danger); }
.compare-status[data-status="single"] { color: var(--faint); }

.compare-outlier {
  margin-top: 4px;
  color: var(--danger);
  font-size: 0.74rem;
}

/* Map */
.map-frame {
  overflow: hidden;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
}

.map-panel iframe {
  display: block;
  width: 100%;
  height: 240px;
  border: 0;
  filter: grayscale(0.3) brightness(0.85) contrast(1.05);
}

.map-caption {
  color: var(--soft);
  font-size: 0.86rem;
  line-height: 1.5;
}

.map-caption { margin-top: 12px; }

label {
  display: grid;
  gap: 8px;
  color: var(--muted);
  font-weight: 600;
}

input {
  min-height: 42px;
  width: 100%;
  padding: 0 13px;
  color: var(--ink);
  background: var(--glass);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  transition: border-color 180ms var(--ease), background 180ms var(--ease);
}

input::placeholder { color: var(--faint); }

input:focus,
button:focus-visible {
  outline: 2px solid color-mix(in oklch, var(--accent), transparent 35%);
  outline-offset: 2px;
}

input:focus { border-color: var(--accent); background: var(--glass-2); }

/* -------------------------------------------------------------- Errors */
.error-box {
  display: flex;
  gap: 12px;
  padding: 14px;
  border: 1px solid color-mix(in oklch, var(--danger), transparent 55%);
  border-radius: var(--radius-sm);
  background: color-mix(in oklch, var(--danger), transparent 88%);
}

.error-box__icon {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 1px;
  stroke: var(--danger);
  stroke-width: 2;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.error-box strong { color: color-mix(in oklch, var(--danger), white 18%); }
.error-box p { margin-top: 4px; color: var(--muted); font-size: 0.88rem; }

/* --------------------------------------------------------------- Foot */
.app-foot {
  display: grid;
  justify-items: center;
  gap: 8px;
  margin-top: 18px;
  padding: 0 4px;
  color: var(--faint);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  text-align: center;
}

/* ----------------------------------------------------- Loading / boot */
.is-loading { cursor: progress; }

.is-loading .overview-card,
.is-loading .status-bar,
.is-loading .content-layout {
  opacity: 0.78;
  transition: opacity 300ms var(--ease);
}

.skeleton {
  color: transparent !important;
  border-radius: 6px;
  background: linear-gradient(100deg, var(--glass) 30%, var(--glass-2) 50%, var(--glass) 70%);
  background-size: 200% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
}

@keyframes shimmer {
  to { background-position: -200% 0; }
}

/* Staggered reveal on load */
.reveal {
  opacity: 0;
  transform: translateY(14px);
}

body:not(.is-booting) .reveal {
  animation: rise 620ms var(--ease) forwards;
  animation-delay: calc(var(--d, 0) * 80ms);
}

@keyframes rise {
  to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; animation: none; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ------------------------------------------------------- Responsive */
@media (max-width: 920px) {
  .overview-card { grid-template-columns: 1fr; }
}

@media (max-width: 620px) {
  body { font-size: 13.5px; }

  .app-shell { width: min(100% - 18px, 1240px); }
  .app-header {
    gap: 8px;
    padding-top: 8px;
  }

  .topbar {
    gap: 8px;
    padding: 8px;
  }

  .product-title {
    flex: 1 1 auto;
    min-width: 0;
    gap: 8px;
  }

  .app-mark {
    width: 32px;
    height: 32px;
  }

  .eyebrow { max-width: 100%; }

  h1 {
    font-size: 1.18rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* The H1 already names the city, so the location control collapses to an
     icon-only trigger: no duplicated name, no wrapping, title stays one line. */
  .hero-actions {
    flex: 0 0 auto;
    justify-content: flex-end;
    gap: 6px;
  }
  .location-search { flex: 0 0 auto; min-width: 0; }
  .text-button {
    width: 36px;
    padding: 0;
    gap: 0;
  }
  .text-button > span { display: none; }
  .location-trigger .text-button__chev { display: none; }

  .overview-main,
  .advice-panel,
  .panel { padding: 16px; }

  /* Narrow screens: drop the grid and stack vertically. The header row holds
     the "Сейчас" kicker (left) and the condition icon (right); the big
     temperature + details sit on the next line — compact, no floating gaps. */
  .overview-main {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  .now-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
  }
  .now-head .section-kicker { margin: 0; }

  .temperature-row {
    gap: 14px;
    align-items: center;
  }

  .temperature { font-size: 4.2rem; }

  .temperature-side {
    min-width: 0;
    padding-bottom: 0;
  }

  .weather-icon--hero {
    width: 64px;
    height: 64px;
    border-radius: 16px;
  }

  .weather-icon--hero svg {
    width: 48px;
    height: 48px;
  }

  .fact-list { grid-template-columns: 1fr 1fr; }

  .advice-body {
    grid-template-columns: 64px minmax(0, 1fr);
    gap: 14px;
  }
  .risk-meter__bars { height: 34px; gap: 4px; }
  .risk-meter__bars i { width: 8px; }
  .risk-meter__bars i:nth-child(3) { height: 34px; }
  .risk-meter__bars i:nth-child(2) { height: 24px; }
  /* Daily mobile layout is owned by the forecast container query above. */
}

/* ======================================================================
   Minutely nowcast banner
   ====================================================================== */
.nowcast {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 14px;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
}
.nowcast[data-tone="warn"] { background: color-mix(in oklch, var(--warn), transparent 88%); }
.nowcast[data-tone="danger"] { background: color-mix(in oklch, var(--danger), transparent 88%); }
.nowcast-text { display: flex; align-items: center; gap: 10px; font-weight: 650; }
.nowcast-icon { width: 18px; height: 18px; flex: 0 0 auto; stroke: var(--accent); stroke-width: 1.8; fill: none; }
.nowcast[data-tone="warn"] .nowcast-icon { stroke: var(--warn); }
.nowcast[data-tone="danger"] .nowcast-icon { stroke: var(--danger); }
.nowcast-bars {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 30px;
  flex: 0 0 auto;
}
.nowcast-bar {
  width: 7px;
  border-radius: 3px;
  background: color-mix(in oklch, var(--accent), transparent 55%);
  min-height: 3px;
}
.nowcast-bar.kind-rain { background: var(--ico-rain); }
.nowcast-bar.kind-snow { background: var(--ico-snow); }
.nowcast-bar.kind-dry { background: var(--line-strong); }

/* ======================================================================
   Air quality + astronomy panel
   ====================================================================== */
.air-grid {
  display: grid;
  grid-template-columns: minmax(220px, 0.9fr) minmax(0, 1.5fr);
  gap: 14px;
}
.aqi-card {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--glass);
}
.aqi-dial {
  flex: 0 0 auto;
  display: grid;
  place-content: center;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  text-align: center;
  line-height: 1;
  color: var(--soft);
  background: var(--glass-2);
  border: 3px solid var(--line-strong);
}
.aqi-dial[data-tone="ok"] { border-color: var(--ok); color: var(--ok); }
.aqi-dial[data-tone="warn"] { border-color: var(--warn); color: var(--warn); }
.aqi-dial[data-tone="danger"] { border-color: var(--danger); color: var(--danger); }
.aqi-dial strong { font-family: var(--font-display); font-size: 1.6rem; font-weight: 560; font-variant-numeric: tabular-nums; }
.aqi-dial span { display: block; margin-top: 2px; font-size: 0.6rem; font-weight: 700; letter-spacing: 0.1em; }
.aqi-info { min-width: 0; }
.aqi-info strong { font-size: 1rem; font-weight: 700; }
.aqi-info strong[data-tone="ok"] { color: var(--ok); }
.aqi-info strong[data-tone="warn"] { color: var(--warn); }
.aqi-info strong[data-tone="danger"] { color: var(--danger); }
.aqi-info p { margin-top: 4px; color: var(--muted); font-size: 0.86rem; line-height: 1.4; }
.aqi-detail { color: var(--soft) !important; font-size: 0.8rem !important; }

.astro-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px;
  align-content: start;
}
.astro-tile {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--glass);
}
.astro-body { display: grid; gap: 2px; min-width: 0; }
.astro-label { color: var(--soft); font-size: 0.72rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; }
.astro-tile strong { font-size: 1rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.astro-sub { color: var(--soft); font-size: 0.78rem; }

.astro-ico { flex: 0 0 auto; display: grid; place-items: center; width: 34px; height: 34px; border-radius: 10px; background: color-mix(in oklch, var(--accent), transparent 90%); }
.astro-ico svg { width: 20px; height: 20px; stroke: var(--accent); stroke-width: 1.8; fill: none; stroke-linecap: round; stroke-linejoin: round; }

/* The moon gets a large illustrative visual spanning the row */
.astro-tile--moon { grid-column: 1 / -1; gap: 14px; }
.astro-visual { flex: 0 0 auto; line-height: 0; }
.astro-visual svg { width: 64px; height: 64px; }
.astro-tile--moon strong { font-size: 1.06rem; }

.insight-narrative {
  display: grid;
  gap: 0;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--glass);
}
.narrative-row {
  display: grid;
  grid-template-columns: 30px minmax(112px, 0.22fr) minmax(0, 1fr);
  gap: 9px 12px;
  align-items: center;
  padding: 9px 11px;
  border-top: 1px solid var(--line);
}
.narrative-row:first-child { border-top: 0; }
.narrative-icon {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: color-mix(in oklch, var(--accent), transparent 91%);
}
.narrative-icon svg {
  width: 24px;
  height: 24px;
}
.narrative-label {
  color: var(--accent);
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  line-height: 1.3;
}
.narrative-text {
  color: var(--ink);
  font-size: 0.84rem;
  line-height: 1.36;
}
@media (max-width: 560px) {
  .narrative-row {
    grid-template-columns: 30px minmax(0, 1fr);
    gap: 3px 9px;
  }
  .narrative-label,
  .narrative-text {
    grid-column: 2;
  }
}

@media (max-width: 720px) {
  .air-grid { grid-template-columns: 1fr; }
}

/* ======================================================================
   Chip navigation
   ====================================================================== */
/* Tab bar — horizontally scrollable on narrow screens. Stickiness is handled
   by the .app-header wrapper so the topbar and tabs move as one unit. */
.tabbar {
  position: relative;
}
.tabbar__inner {
  display: flex;
  gap: 4px;
  padding: 4px;
  overflow-x: auto;
  scrollbar-width: none;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--glass-strong);
  backdrop-filter: blur(12px);
}
.tabbar__inner::-webkit-scrollbar { display: none; }
.tab {
  flex: 1 0 auto;
  padding: 7px 14px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font-size: 0.84rem;
  font-weight: 650;
  white-space: nowrap;
  cursor: pointer;
  transition: color 180ms var(--ease), background 180ms var(--ease);
}
.tab:hover { color: var(--accent); }
.tab[aria-selected="true"] {
  color: var(--accent-ink, #fff);
  background: var(--accent);
  box-shadow: 0 3px 10px color-mix(in oklch, var(--accent), transparent 70%);
}
.tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Section heading inside the forecast detailed lists */
.detail-kicker {
  margin: 18px 0 8px;
  color: var(--soft);
  font-size: 0.74rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.panel-intro {
  margin: -4px 0 14px;
  color: var(--soft);
  font-size: 0.86rem;
  line-height: 1.5;
}

.compare-consensus {
  margin-left: 8px;
  color: var(--accent);
  font-size: 0.76rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ======================================================================
   Animated weather-icon parts
   ====================================================================== */
.ico-spin { animation: ico-spin 22s linear infinite; }
.ico-pulse { animation: ico-pulse 4s ease-in-out infinite; }
.ico-bob { animation: ico-bob 5s ease-in-out infinite; }
.ico-rain { animation: ico-rain 1.1s linear infinite; }
.ico-snow { animation: ico-snow 3.2s ease-in-out infinite; }
.ico-bolt { animation: ico-flash 2.6s steps(1, end) infinite; transform-origin: center; }
.ico-fog { animation: ico-fog 3.4s ease-in-out infinite alternate; }
.ico-twinkle { animation: ico-twinkle 2.6s ease-in-out infinite; }

@keyframes ico-spin { to { transform: rotate(360deg); } }
@keyframes ico-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.06); } }
@keyframes ico-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-1.5px); } }
@keyframes ico-rain {
  0% { transform: translateY(-4px); opacity: 0; }
  30% { opacity: 1; }
  100% { transform: translateY(6px); opacity: 0; }
}
@keyframes ico-snow {
  0% { transform: translateY(-3px) translateX(0); opacity: 0; }
  30% { opacity: 1; }
  100% { transform: translateY(7px) translateX(2px); opacity: 0; }
}
@keyframes ico-flash {
  0%, 92%, 100% { opacity: 1; }
  94% { opacity: 0.15; }
  96% { opacity: 1; }
}
@keyframes ico-fog { from { transform: translateX(-2px); } to { transform: translateX(3px); } }
@keyframes ico-twinkle { 0%, 100% { opacity: 0.3; } 50% { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .ico-spin, .ico-pulse, .ico-bob, .ico-rain, .ico-snow, .ico-bolt, .ico-fog, .ico-twinkle {
    animation: none;
  }
}

/* ======================================================================
   Location search
   ====================================================================== */
.location-search {
  position: relative;
}

.location-pop {
  /* JS (positionLocationPop) computes the exact viewport coordinates and writes
     them as CSS custom properties. We use position:fixed here so the popup
     escapes the topbar's backdrop-filter stacking context and sits at the
     correct viewport position below the full app-header (incl. tabbar). */
  position: fixed;
  top: var(--location-pop-top, 140px);
  left: var(--location-pop-left, auto);
  right: auto;
  z-index: 80;
  width: var(--location-pop-width, min(320px, calc(100vw - 24px)));
  padding: 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-1);
  box-shadow: 0 22px 50px -24px oklch(45% 0.06 255 / 0.5);
}

/* Search field with leading magnifier icon. */
.location-field {
  position: relative;
  margin-bottom: 8px;
}
.location-field__icon {
  position: absolute;
  left: 12px;
  top: 50%;
  transform: translateY(-50%);
  width: 17px;
  height: 17px;
  stroke: var(--faint);
  stroke-width: 2;
  fill: none;
  stroke-linecap: round;
  pointer-events: none;
}
.location-field input { padding-left: 38px; }
.location-field:focus-within .location-field__icon { stroke: var(--accent); }

.location-results {
  display: grid;
  gap: 2px;
  max-height: 260px;
  overflow-y: auto;
}

.location-result {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 11px;
  border: 0;
  width: 100%;
  border-radius: 9px;
  background: transparent;
  color: var(--ink);
  text-align: left;
  font-weight: 600;
}

.location-result:hover { background: var(--accent-soft); }
.location-result span { color: var(--soft); font-size: 0.8rem; font-weight: 500; }
.location-hint { padding: 6px 4px; color: var(--soft); font-size: 0.82rem; }

.location-geo {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 10px 11px;
  margin-bottom: 8px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--glass);
  color: var(--accent);
  font-weight: 650;
  text-align: left;
}
.location-geo:hover { background: var(--accent-soft); border-color: color-mix(in oklch, var(--accent), transparent 55%); }
.location-geo svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2; fill: none; stroke-linecap: round; }

/* City chips — favorites + "add current" laid out as wrapping pills. */
.location-favorites {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
}
.location-favorites:empty { display: none; }

.location-fav-label {
  flex: 0 0 100%;
  margin: 0 2px;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--soft);
}

.location-chip {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--glass);
  transition: border-color 160ms var(--ease), background 160ms var(--ease);
}
.location-chip:hover { border-color: var(--line-strong); }
.location-chip__pick {
  min-width: 0;
  padding: 6px 6px 6px 13px;
  border: 0;
  background: transparent;
  color: var(--ink);
  text-align: left;
  font-weight: 600;
  font-size: 0.85rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.location-chip__pick:hover { color: var(--accent); }
.location-chip__del {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 26px;
  height: 30px;
  padding: 0;
  margin-right: 3px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--faint);
  font-size: 0.95rem;
  line-height: 1;
}
.location-chip__del:hover { color: var(--danger); }

/* "Add current city" reads as a dashed, accent-tinted call to action. */
.location-chip--add {
  border-style: dashed;
  border-color: color-mix(in oklch, var(--accent), transparent 55%);
  background: transparent;
}
.location-chip--add .location-chip__pick { padding-right: 13px; color: var(--accent); }
.location-chip--add:hover { background: var(--accent-soft); border-color: var(--accent); }

.location-results { border-top: 1px solid var(--line); padding-top: 8px; }

/* ======================================================================
   Segmented toggle (hourly / daily, etc.)
   ====================================================================== */
.segmented {
  position: relative;
  display: inline-grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr; /* равные колонки → одинаковая ширина кнопок */
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--glass);
  isolation: isolate;
}

/* Скользящий индикатор активного сегмента (для 2 кнопок). */
.segmented::before {
  content: "";
  position: absolute;
  z-index: 0;
  top: 3px;
  bottom: 3px;
  left: 3px;
  width: calc((100% - 6px) / 2);
  border-radius: 999px;
  background: var(--accent);
  box-shadow: 0 4px 12px -4px color-mix(in oklch, var(--accent), transparent 40%);
  transform: translateX(0);
  transition: transform 300ms var(--ease);
}
.segmented[data-active="daily"]::before { transform: translateX(100%); }

.segmented button {
  position: relative;
  z-index: 1;
  min-height: 30px;
  padding: 0 14px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font-weight: 650;
  font-size: 0.85rem;
  cursor: pointer;
  transition: color 200ms var(--ease);
}

.segmented button.is-active { color: oklch(99% 0 0); }

@media (prefers-reduced-motion: reduce) {
  .segmented::before { transition: none; }
}

/* ======================================================================
   Source-trust / verification panel
   ====================================================================== */
.verify-consensus {
  --tone: var(--ok);
  display: grid;
  gap: 4px;
  margin-bottom: 14px;
  padding: 10px 12px;
  border: 1px solid color-mix(in oklch, var(--tone), var(--line) 60%);
  border-left: 3px solid var(--tone);
  border-radius: 12px;
  background: color-mix(in oklch, var(--tone), transparent 92%);
  font-variant-numeric: tabular-nums lining-nums;
}
.verify-consensus[data-tone="ok"] { --tone: var(--ok); }
.verify-consensus[data-tone="warn"] { --tone: var(--warn); }
.verify-consensus[data-tone="danger"] { --tone: var(--danger); }

.verify-consensus__row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.verify-consensus__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--tone);
  flex: none;
}
.verify-consensus__label {
  font-weight: 600;
  font-size: 0.94rem;
  color: var(--ink);
}
.verify-consensus__disputes {
  font-size: 0.86rem;
  color: var(--muted);
}

.trust-list { display: grid; gap: 8px; }

.trust-item {
  --tone: var(--ok);
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 14px;
  padding: 13px 15px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--glass);
  transition: border-color 200ms var(--ease);
}
.trust-item[data-tone="ok"] { --tone: var(--ok); }
.trust-item[data-tone="warn"] { --tone: var(--warn); }
.trust-item[data-tone="danger"] { --tone: var(--danger); }
.trust-item:hover { border-color: color-mix(in oklch, var(--tone), transparent 62%); }

/* Reliability donut */
.trust-ring {
  position: relative;
  display: grid;
  place-items: center;
  width: 50px;
  height: 50px;
}
.trust-ring__svg { width: 50px; height: 50px; transform: rotate(-90deg); }
.trust-ring__track { fill: none; stroke: var(--glass-2); stroke-width: 5; }
.trust-ring__val {
  fill: none;
  stroke: var(--tone);
  stroke-width: 5;
  stroke-linecap: round;
  transition: stroke-dashoffset 800ms var(--ease);
}
.trust-ring__num {
  position: absolute;
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 1rem;
  font-weight: 560;
  color: var(--ink);
}

.trust-main { display: grid; gap: 7px; min-width: 0; }
.trust-row { display: flex; align-items: center; gap: 9px; min-width: 0; }
.trust-name { font-weight: 700; }
.trust-anchor {
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.trust-verdict {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  padding: 3px 10px;
  border-radius: 999px;
  color: var(--tone);
  background: color-mix(in oklch, var(--tone), transparent 88%);
  font-weight: 700;
  font-size: 0.8rem;
  white-space: nowrap;
}
.trust-verdict .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }

.trust-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  color: var(--soft);
  font-size: 0.76rem;
  font-variant-numeric: tabular-nums;
}
.trust-meta b { color: var(--muted); font-weight: 700; }

/* Per-source bias vs METAR observations (forecast-vs-fact history) */
.trust-bias {
  margin-top: 6px;
  font-size: 0.76rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  color: var(--ok);
}
.trust-bias::before { content: "↔ "; opacity: 0.7; }
.trust-bias[data-tone="warn"] { color: var(--warn); }
.verify-flag.obs::before { content: "📡"; }

.verify-flags {
  display: grid;
  gap: 6px;
  margin-top: 12px;
}
.verify-flag {
  display: flex;
  gap: 9px;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid color-mix(in oklch, var(--warn), transparent 60%);
  background: color-mix(in oklch, var(--warn), transparent 90%);
  color: var(--ink);
  font-size: 0.85rem;
  line-height: 1.4;
}
.verify-flag::before { content: "⚠"; color: var(--warn); }
.verify-flag.ai {
  border-color: color-mix(in oklch, var(--accent), transparent 55%);
  background: var(--accent-soft);
}
.verify-flag.ai::before { content: "✦"; color: var(--accent); }

/* ======================================================================
   Radar map control panel (classes from map.js)
   ====================================================================== */
.radar-shell {
  position: relative;
  height: 400px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--glass-2);
}
.radar-shell .leaflet-container { background: var(--glass-2); font-family: var(--font-body); }

/* Controls are split: a layer segment floats top-center, the timeline + legend
   sit in a thin bar along the bottom, leaving the map center unobstructed. */
.radar-ctrl {
  position: absolute;
  z-index: 1100; /* above Leaflet marker pane (600) so the grid sits behind controls */
  border: 1px solid var(--line-strong);
  background: var(--glass-strong);
  backdrop-filter: blur(12px);
  box-shadow: var(--shadow-lift);
}
.radar-ctrl--top {
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  gap: 3px;
  padding: 3px;
  border-radius: 999px;
}
.radar-ctrl--bottom {
  left: 50%;
  transform: translateX(-50%);
  bottom: 12px;
  width: min(480px, calc(100% - 20px));
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 5px 10px;
  padding: 7px 11px;
  border-radius: 13px;
}

.radar-tab {
  padding: 5px 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--muted);
  font-size: 0.76rem;
  font-weight: 650;
  cursor: pointer;
  transition: color 160ms var(--ease), background 160ms var(--ease);
}
.radar-tab:hover { color: var(--accent); }
.radar-tab.is-active { background: var(--accent); color: oklch(99% 0 0); }
.radar-tab[disabled] { opacity: 0.4; cursor: not-allowed; }

.radar-tabs { display: flex; gap: 3px; }

.radar-player { display: flex; align-items: center; gap: 10px; flex: 1 1 220px; min-width: 160px; }
.radar-player[hidden] { display: none; }
.radar-slider { flex: 1; accent-color: var(--accent); cursor: pointer; }
.radar-time {
  flex: 0 0 auto;
  min-width: 44px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 0.82rem;
  color: var(--ink);
}
.radar-time[data-future="1"] { color: var(--accent); }

/* Кнопка Play/Pause — гоняет таймлайн (кадры-предсказания или часы прогноза). */
.radar-play {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: oklch(99% 0 0);
  cursor: pointer;
  transition: background 160ms var(--ease), transform 120ms var(--ease), opacity 160ms var(--ease);
}
.radar-play:hover { transform: scale(1.06); }
.radar-play:disabled { opacity: 0.4; cursor: not-allowed; }
.radar-play svg { width: 15px; height: 15px; fill: currentColor; }
.radar-play.is-playing { background: oklch(58% 0.16 25); }

/* Predictive grid markers (Open-Meteo): temperature pills, wind arrows,
   cloud-cover discs placed at grid points over the map. */
.mapgrid-icon { background: transparent; border: 0; }
.mapgrid-temp {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 30px;
  height: 22px;
  padding: 0 7px;
  border-radius: 999px;
  background: var(--c);
  color: oklch(99% 0 0);
  font: 800 12px/1 var(--font-body);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 1px 2px oklch(22% 0.05 250 / 0.55);
  box-shadow: 0 1px 5px oklch(30% 0.05 250 / 0.35), 0 0 0 1px oklch(100% 0 0 / 0.35) inset;
  white-space: nowrap;
}
.mapgrid-wind {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}
.mapgrid-wind svg {
  width: 24px;
  height: 24px;
  fill: currentColor;
  filter: drop-shadow(0 1px 2px oklch(25% 0.04 250 / 0.4));
}
.mapgrid-wind b {
  padding: 1px 4px;
  border-radius: 5px;
  background: var(--glass-2);
  color: var(--ink);
  font: 700 10px/1 var(--font-mono);
  box-shadow: 0 1px 3px oklch(30% 0.05 250 / 0.25);
}
/* Clouds: numeric percent chip over the real satellite / cloud-field layer. */
.mapgrid-cloudnum {
  display: inline-flex;
  align-items: baseline;
  justify-content: center;
  min-width: 30px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background: oklch(100% 0 0 / 0.82);
  color: oklch(38% 0.02 250);
  font: 800 11px/1 var(--font-body);
  font-variant-numeric: tabular-nums;
  box-shadow: 0 1px 4px oklch(30% 0.05 250 / 0.3), 0 0 0 1px oklch(40% 0.02 250 / 0.12) inset;
  white-space: nowrap;
}
.mapgrid-cloudnum i { font-size: 0.7em; font-style: normal; margin-left: 1px; opacity: 0.7; }
.mapgrid-cloudnum[data-d="hi"] { background: oklch(34% 0.02 250 / 0.86); color: oklch(98% 0 0); }
.mapgrid-cloudnum[data-d="mid"] { background: oklch(72% 0.02 250 / 0.84); color: oklch(24% 0.02 250); }

/* Smooth interpolated field (temperature / cloud cover) painted under the digits. */
.mapgrid-heat { will-change: transform; }

/* Precipitation drops — colour by intensity; dry points shown as faint dots. */
.mapgrid-precip {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
}
.mapgrid-precip svg {
  width: 22px;
  height: 22px;
  fill: currentColor;
  filter: drop-shadow(0 1px 2px oklch(25% 0.06 250 / 0.4));
}
.mapgrid-precip[data-i="light"] { color: oklch(80% 0.08 230); }
.mapgrid-precip[data-i="rain"] { color: oklch(62% 0.16 230); }
.mapgrid-precip[data-i="heavy"] { color: oklch(70% 0.17 145); }
.mapgrid-precip[data-i="storm"] { color: oklch(60% 0.2 25); }
.mapgrid-precip b {
  padding: 1px 4px;
  border-radius: 5px;
  background: var(--glass-2);
  color: var(--ink);
  font: 700 10px/1 var(--font-mono);
  box-shadow: 0 1px 3px oklch(30% 0.05 250 / 0.25);
}
.mapgrid-dry {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: oklch(55% 0.02 250 / 0.32);
}
/* Mode description is redundant with the tabs + the caption below the map. */
.radar-status { display: none; }

/* Per-mode color legend — its own row in the bottom bar. */
.radar-legend {
  flex: 1 1 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 5px 12px;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--muted);
}
.radar-legend[hidden] { display: none; }
.radar-legend__item { display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; }
.radar-legend__item i {
  width: 11px;
  height: 11px;
  border-radius: 3px;
  border: 1px solid var(--line);
}
.radar-legend__bar {
  width: 100%;
  height: 9px;
  border-radius: 99px;
  border: 1px solid var(--line);
}
.radar-legend__scale {
  display: flex;
  justify-content: space-between;
  width: 100%;
  margin-top: -2px;
  color: var(--soft);
  font-variant-numeric: tabular-nums;
}

/* Hourly/daily switch lives in the panel heading */
.panel-heading .segmented { flex: 0 0 auto; }

@media (max-width: 620px) {
  .trust-row { flex-wrap: wrap; }
  .trust-verdict { margin-left: 0; }
  /* Taller, portrait-oriented map on phones. */
  .radar-shell { height: min(72vh, 600px); min-height: 440px; }
}

/* ======================================================================
   Insights / smart recommendations
   ====================================================================== */
/* Tone channel — one variable drives icon + tint per element. */
.insight-lead,
.insight-card,
.window-chip {
  --tone: var(--accent);
  cursor: default;
}
[data-tone="ok"] { --tone: var(--ok); }
[data-tone="warn"] { --tone: var(--warn); }
[data-tone="danger"] { --tone: var(--danger); }
[data-tone="info"] { --tone: var(--accent); }

/* Panel rhythm — four groups stacked with a single consistent gap, hairline
   separators between them so the panel reads as one considered block. */
#insightsPanel > .insight-lead,
#insightsPanel > .insight-cards,
#insightsPanel > .insight-group { margin: 0; }
#insightsPanel {
  container: insights / inline-size;
  padding: 14px 16px 16px;
  scroll-margin-top: 156px;
}
#insightsPanel .panel-heading {
  align-items: flex-start;
  margin-bottom: 10px;
}
#insightsPanel .panel-heading h2 {
  font-family: var(--font-body);
  font-size: 1.08rem;
  font-weight: 760;
  line-height: 1.15;
  letter-spacing: 0;
}
#insightsPanel > .insight-lead + .insight-cards {
  margin-top: 12px;
}
#insightsPanel > .insight-cards + .insight-group,
#insightsPanel > .insight-group + .insight-group {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.insight-subhead {
  margin: 0 0 7px;
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--soft);
}

/* Lead — the single most important thing right now. */
.insight-lead {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr);
  gap: 10px;
  align-items: center;
  padding: 10px 12px;
  border: 1px solid color-mix(in oklch, var(--tone), transparent 72%);
  border-radius: var(--radius-sm);
  background:
    linear-gradient(color-mix(in oklch, var(--tone), transparent 94%), color-mix(in oklch, var(--tone), transparent 94%)),
    var(--glass);
}
.insight-lead__icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  color: var(--tone);
  background: color-mix(in oklch, var(--tone), transparent 90%);
}
.insight-lead__icon svg { width: 21px; height: 21px; }
.insight-lead__icon svg [fill="none"],
.insight-lead__icon svg path,
.insight-lead__icon svg circle {
  stroke: currentColor;
  stroke-width: 1.9;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.insight-lead__text {
  min-width: 0;
}
.insight-lead__text strong {
  display: block;
  font-size: 0.96rem;
  font-weight: 720;
  line-height: 1.2;
}
.insight-lead__text p {
  margin-top: 2px;
  max-width: 68ch;
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.34;
}
.insight-trust svg {
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  stroke: var(--accent);
  stroke-width: 1.8;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Recommendation cards — a clean, even grid; tone reads through a subtle tint
   plus the coloured icon chip, never a side stripe. */
.insight-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 8px;
}
.insight-card {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  gap: 9px;
  align-items: center;
  min-height: 58px;
  padding: 9px 11px;
  cursor: default;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background:
    linear-gradient(color-mix(in oklch, var(--tone), transparent 97%), color-mix(in oklch, var(--tone), transparent 97%)),
    var(--glass);
  transition: none;
}
.insight-card:hover {
  box-shadow: none;
}
.insight-card__icon {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  color: var(--tone);
  background: color-mix(in oklch, var(--tone), transparent 91%);
}
.insight-card__icon svg { width: 18px; height: 18px; }
.insight-card__icon svg path,
.insight-card__icon svg circle {
  stroke: currentColor;
  stroke-width: 1.9;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.insight-card__body { min-width: 0; }
.insight-card__body h3 {
  margin: 0;
  font-size: 0.84rem;
  font-weight: 700;
  line-height: 1.18;
}
.insight-card__body p {
  margin: 2px 0 0;
  color: var(--muted);
  font-size: 0.76rem;
  line-height: 1.3;
}

/* Best / worst outdoor windows — two chips side by side. */
.insight-windows {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
.window-chip {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--glass);
}
.window-chip[data-kind="best"] { --tone: var(--ok); }
.window-chip[data-kind="worst"] { --tone: var(--warn); }
.window-chip svg {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  color: var(--tone);
  stroke: currentColor;
  stroke-width: 2;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.window-chip__text { display: grid; min-width: 0; line-height: 1.25; }
.window-chip__label {
  color: var(--soft);
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.window-chip__text strong {
  font-variant-numeric: tabular-nums;
  font-size: 0.88rem;
  font-weight: 700;
}
.window-chip__reason { color: var(--muted); font-size: 0.74rem; }

@media (max-width: 560px) {
  .insight-cards,
  .insight-windows {
    grid-template-columns: 1fr;
  }
  #insightsPanel {
    padding: 14px;
    scroll-margin-top: 206px;
  }
  .insight-lead {
    align-items: center;
    padding: 10px 11px;
  }
  .insight-card {
    min-height: 0;
    padding: 9px 10px;
  }
}

@container insights (max-width: 720px) {
  .insight-cards,
  .insight-windows {
    grid-template-columns: 1fr;
  }

  .narrative-row {
    grid-template-columns: 30px minmax(0, 1fr);
    gap: 3px 9px;
  }

  .narrative-label,
  .narrative-text {
    grid-column: 2;
  }
}

/* ===== MAP-LEGEND-BLOCK START (subagent) ===== */
/* Слой-зависимая легенда карты: одна легенда на активный слой.
   Осадки/Ветер — дискретные ячейки; Облака/Температура — непрерывная
   градиентная шкала с делениями; Ветер дополнительно несёт индикатор
   направления (стрелка «куда дует» + румб). */

/* Подпись над легендой — что именно показывает шкала. */
.radar-legend__caption {
  flex: 1 1 100%;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--soft);
}

/* Строка «скорость + направление» для слоя ветра. */
.radar-legend__row {
  flex: 1 1 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
}

/* Градиентная шкала (облака/температура): полоса + деления под ней. */
.radar-legend--bar { gap: 3px 12px; }
.radar-legend--bar .radar-legend__bar {
  width: 100%;
  height: 10px;
  border-radius: 99px;
  border: 1px solid var(--line);
}
.radar-legend__ticks {
  position: relative;
  width: 100%;
  height: 0.95rem;
  font-size: 0.66rem;
  font-variant-numeric: tabular-nums;
  color: var(--soft);
}
.radar-legend__tick {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  white-space: nowrap;
}
/* Крайние деления держим в пределах полосы (не уезжают за край). */
.radar-legend__tick:first-child { transform: translateX(0); }
.radar-legend__tick:last-child { transform: translateX(-100%); }
.radar-legend__unit {
  flex: 0 0 auto;
  margin-left: auto;
  font-size: 0.66rem;
  font-weight: 700;
  color: var(--soft);
  font-variant-numeric: tabular-nums;
}

/* Индикатор направления ветра: компасная стрелка + румб. */
.radar-wind-arrow {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  padding: 2px 8px 2px 4px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--glass);
}
.radar-wind-arrow__svg {
  width: 17px;
  height: 17px;
  fill: var(--accent);
  transition: transform 320ms var(--ease);
  transform-origin: 50% 50%;
}
.radar-wind-arrow__label {
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
}
/* ===== MAP-LEGEND-BLOCK END ===== */

/* Cookie consent banner (informational model) */
.cookie-banner {
  position: fixed;
  left: 50%;
  bottom: 16px;
  transform: translateX(-50%);
  z-index: 1000;
  display: flex;
  align-items: center;
  gap: 12px;
  width: min(680px, calc(100vw - 24px));
  padding: 12px 14px;
  border-radius: 14px;
  background: var(--surface, oklch(99% 0.005 250));
  border: 1px solid var(--hairline, oklch(90% 0.01 250));
  box-shadow: 0 10px 30px oklch(40% 0.05 264 / 0.18);
  font-size: 13px;
  line-height: 1.4;
}
.cookie-banner__text { margin: 0; flex: 1 1 auto; color: var(--ink, oklch(30% 0.02 264)); }
.cookie-banner__text a { color: var(--accent, oklch(51% 0.16 264)); }
.cookie-banner__btn {
  flex: 0 0 auto;
  padding: 8px 16px;
  border: none;
  border-radius: 10px;
  background: var(--accent, oklch(51% 0.16 264));
  color: #fff;
  font-weight: 600;
  cursor: pointer;
}
.cookie-banner__btn:hover { filter: brightness(1.05); }
@media (max-width: 520px) {
  .cookie-banner { flex-direction: column; align-items: stretch; text-align: left; }
  .cookie-banner__btn { width: 100%; }
}

/* ===== PWA install prompt ===== */
@keyframes pwa-slide-up {
  from { opacity: 0; transform: translateX(-50%) translateY(24px); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0); }
}
@keyframes pwa-icon-pop {
  0%   { transform: scale(0.72); }
  65%  { transform: scale(1.08); }
  100% { transform: scale(1); }
}

.pwa-install {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%) translateY(24px);
  z-index: 1010;
  width: min(440px, calc(100vw - 24px));
  padding: 16px 16px 14px;
  border-radius: 18px;
  background: var(--surface, oklch(99.3% 0.003 255));
  border: 1px solid var(--hairline, oklch(91% 0.008 255));
  box-shadow:
    0 2px 6px oklch(40% 0.05 264 / 0.06),
    0 8px 24px oklch(40% 0.07 264 / 0.12),
    0 28px 52px -12px oklch(38% 0.08 264 / 0.16);
  opacity: 0;
  pointer-events: none;
  transition: none;
}
.pwa-install--visible {
  pointer-events: auto;
  animation: pwa-slide-up 0.38s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
}
@media (prefers-reduced-motion: reduce) {
  .pwa-install--visible {
    animation: none;
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}

.pwa-install__inner {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}
.pwa-install__icon-wrap {
  flex: 0 0 auto;
  width: 52px;
  height: 52px;
  border-radius: 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(
    135deg,
    oklch(88% 0.08 240 / 0.55),
    oklch(94% 0.05 200 / 0.35)
  );
  box-shadow:
    0 0 0 1.5px oklch(72% 0.12 240 / 0.22),
    inset 0 1px 0 oklch(100% 0 0 / 0.45);
}
.pwa-install--visible .pwa-install__icon {
  animation: pwa-icon-pop 0.55s cubic-bezier(0.22, 0.61, 0.36, 1) 0.18s both;
}
@media (prefers-reduced-motion: reduce) {
  .pwa-install--visible .pwa-install__icon {
    animation: none;
  }
}
.pwa-install__icon {
  width: 40px;
  height: 40px;
  border-radius: 10px;
  display: block;
}
.pwa-install__body {
  flex: 1 1 auto;
  min-width: 0;
  padding-top: 2px;
}
.pwa-install__title {
  margin: 0 0 3px;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink, oklch(24% 0.03 264));
  line-height: 1.2;
}
.pwa-install__sub {
  margin: 0;
  font-size: 13px;
  color: var(--muted, oklch(45% 0.024 262));
  line-height: 1.45;
}
.pwa-install__close {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 50%;
  background: color-mix(in oklch, var(--ink, oklch(24% 0.03 264)), transparent 88%);
  color: var(--muted, oklch(45% 0.024 262));
  cursor: pointer;
  transition: background 0.15s;
  padding: 0;
}
.pwa-install__close:hover {
  background: color-mix(in oklch, var(--ink, oklch(24% 0.03 264)), transparent 82%);
}

.pwa-install__actions {
  display: flex;
  gap: 8px;
  margin-top: 14px;
}
.pwa-install__btn {
  flex: 1 1 auto;
  padding: 9px 14px;
  border: none;
  border-radius: 11px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: filter 0.15s, transform 0.1s;
}
.pwa-install__btn:active {
  transform: scale(0.97);
}
.pwa-install__btn--primary {
  background: linear-gradient(
    135deg,
    var(--accent, oklch(51% 0.16 264)),
    oklch(46% 0.18 280)
  );
  color: #fff;
  box-shadow: 0 2px 10px oklch(51% 0.16 264 / 0.32);
}
.pwa-install__btn--primary:hover {
  filter: brightness(1.07);
}
.pwa-install__btn--dismiss {
  background: color-mix(in oklch, var(--ink, oklch(24% 0.03 264)), transparent 92%);
  color: var(--muted, oklch(45% 0.024 262));
}
.pwa-install__btn--dismiss:hover {
  filter: brightness(0.95);
}

/* Mobile: full-width sheet, safe-area bottom inset */
@media (max-width: 480px) {
  .pwa-install {
    left: 0;
    right: 0;
    bottom: 0;
    transform: translateY(100%);
    width: 100%;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  }
  .pwa-install--visible {
    animation: none;
    opacity: 1;
    transform: translateY(0);
  }
  @media (prefers-reduced-motion: no-preference) {
    .pwa-install--visible {
      animation: pwa-sheet-up 0.38s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
    }
  }
}
@keyframes pwa-sheet-up {
  from { opacity: 0; transform: translateY(100%); }
  to   { opacity: 1; transform: translateY(0); }
}
/* ===== PWA install prompt END ===== */

/* ======================================================================
   Legal pages (privacy policy, cookies section)
   Matches the app's card-based light theme — same tokens, no new colours.
   ====================================================================== */

.legal-page {
  background: var(--bg-0);
  min-height: 100dvh;
}

.legal-shell {
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: min(720px, calc(100% - 36px));
  margin: 0 auto;
  padding: 16px 0 56px;
}

/* Top bar — mirrors the app's .topbar look */
.legal-topbar {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 56px;
  padding: 10px 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--glass-strong);
  backdrop-filter: blur(18px) saturate(1.4);
  box-shadow: var(--shadow-lift);
  position: sticky;
  top: 12px;
  z-index: 20;
}

.legal-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  min-height: 34px;
  padding: 0 12px 0 8px;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: var(--glass);
  color: var(--accent);
  font-size: 0.84rem;
  font-weight: 650;
  text-decoration: none;
  transition: background 180ms var(--ease), border-color 180ms var(--ease), transform 160ms var(--ease);
}
.legal-back:hover {
  background: var(--glass-2);
  border-color: color-mix(in oklch, var(--accent), transparent 55%);
  transform: translateY(-1px);
}
.legal-back:active { transform: translateY(0); }
.legal-back svg {
  width: 16px;
  height: 16px;
  stroke: currentColor;
  stroke-width: 2.2;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.legal-topbar__title {
  min-width: 0;
}

.legal-topbar__title .section-kicker {
  margin-bottom: 3px;
}

.legal-topbar__title h1 {
  font-size: 1.15rem;
  font-weight: 600;
  line-height: 1.1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Revision date */
.legal-rev {
  padding: 0 2px;
  color: var(--soft);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  margin: 0;
}

/* Section cards — same as .panel */
.legal-card {
  padding: 18px 20px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--glass-strong);
  backdrop-filter: blur(14px);
  box-shadow: var(--shadow-lift);
  line-height: 1.65;
}

.legal-card .section-kicker {
  margin-bottom: 4px;
}

.legal-card h2 {
  font-size: 1.08rem;
  font-weight: 600;
  margin: 0 0 10px;
  color: var(--ink);
}

.legal-card p {
  color: var(--ink);
  margin: 0 0 10px;
}
.legal-card p:last-child { margin-bottom: 0; }

.legal-card ul {
  margin: 8px 0 0;
  padding-left: 1.4em;
  color: var(--ink);
}
.legal-card ul li {
  margin-bottom: 5px;
  line-height: 1.55;
}
.legal-card ul li:last-child { margin-bottom: 0; }

/* Cookies section — subtly highlighted with an accent left-border */
.legal-card--accent {
  border-left: 3px solid var(--accent);
  background:
    linear-gradient(color-mix(in oklch, var(--accent), transparent 95%),
                    color-mix(in oklch, var(--accent), transparent 95%)),
    var(--glass-strong);
  scroll-margin-top: 80px;
}

/* Links inside cards */
.legal-card a {
  color: var(--accent);
  text-decoration: none;
}
.legal-card a:hover { text-decoration: underline; }

/* Page footer */
.legal-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px 0 0;
  border-top: 1px solid var(--line);
  color: var(--faint);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  text-align: center;
}
.legal-foot a {
  color: var(--muted);
  text-decoration: none;
}
.legal-foot a:hover {
  color: var(--accent);
  text-decoration: underline;
}

/* Responsive: collapse topbar on mobile */
@media (max-width: 520px) {
  .legal-shell {
    width: min(100% - 18px, 720px);
    padding-top: 10px;
    gap: 10px;
  }

  .legal-topbar {
    gap: 10px;
    padding: 8px 12px;
    top: 8px;
    flex-wrap: nowrap;
  }

  .legal-topbar__title h1 {
    font-size: 1rem;
  }

  .legal-card {
    padding: 16px;
  }
}

/* Footer legal row */
.app-foot__legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--hairline, oklch(90% 0.01 250));
  font-size: 12px;
  color: var(--muted, oklch(55% 0.02 264));
}
.app-foot__legal a { color: var(--muted, oklch(55% 0.02 264)); text-decoration: none; }
.app-foot__legal a:hover { color: var(--accent, oklch(51% 0.16 264)); text-decoration: underline; }
