/* ==========================================================================
   Borneo Weather — app layer on the tanghoong design system (vendor/tanghoong-*).
   The first block is this app's own tokens: the map ground and the data scales.
   Everything below it uses tokens only.
   ========================================================================== */

:root {
  /* --- Map ground: neutral, built from the system surfaces ----------------- */
  --map-sea:          light-dark(#e4e8ee, #000000);
  --map-land:         light-dark(#f1f2f4, #0e0e10);
  --map-land-focus:   var(--bg-elevated);
  --map-border:       light-dark(#0000002e, #ffffff24);
  --map-border-focus: light-dark(#00000047, #ffffff3a);
  --map-province:     light-dark(#00000014, #ffffff12);
  --map-province-focus: light-dark(#00000024, #ffffff1f);

  /* --- Data scales -----------------------------------------------------------
     Same in both themes: these are measurements, and a colour that changed with
     the theme would stop matching the legend people remember. Text on them is
     always --on-data. */
  --aqi-1: #3ac47d;  /* 0-50 good */
  --aqi-2: #e8c547;  /* 51-100 moderate */
  --aqi-3: #ff8a3d;  /* 101-150 unhealthy for sensitive groups */
  --aqi-4: #ef4b4b;  /* 151-200 unhealthy */
  --aqi-5: #a45de0;  /* 201-300 very unhealthy */
  --aqi-6: #9b2f4b;  /* 301+ hazardous */
  --aqi-none: #86868b;
  --fire-1: #ffd166; /* FRP < 8 MW */
  --fire-2: #ff8a3d; /* 8-20 MW */
  --fire-3: #ff4d3d; /* >= 20 MW */
  --rain-1: #7cc4ff; /* 1-10 mm */
  --rain-2: #3f96ff; /* 10-30 mm */
  --rain-3: #2f62ea; /* 30-60 mm */
  --rain-4: #7b4dff; /* 60-100 mm */
  --rain-5: #d44dff; /* 100+ mm */
  --on-data: #111114;

  /* Theme-aware data inks */
  --fire-edge: light-dark(#ffffff, #000000);
  --quake: var(--info);
  --wind-ink: light-dark(#1b3a66, #dce9ff);

  /* One colour per map layer, for its toggle */
  --layer-fires: var(--fire-2);
  --layer-air: var(--aqi-1);
  --layer-rain: var(--rain-2);
  --layer-wind: var(--wind-ink);
  --layer-quakes: var(--quake);
  --layer-alerts: var(--danger);

  /* Ambient map motion (fire halos, quake ripples). Slower than any UI motion on
     purpose: it describes the data, it isn't feedback. Off with reduced motion. */
  --dur-breathe: 3.2s;
  --dur-ripple: 2.8s;
  --ease-breathe: cubic-bezier(0.45, 0, 0.55, 1);

  /* The system's smallest step is 13px; dense map labels need one below it. */
  --fs-2xs: 0.6875rem;  /* 11px */

  /* Layout of the map chrome */
  --bar-h: 44px;                                   /* layer toggle row */
  --chrome-top: calc(env(safe-area-inset-top, 0px) + var(--nav-h) + var(--bar-h) + var(--s-4));
  --panel-w: 384px;
}

/* ---------- page -------------------------------------------------------- */
html, body { height: 100%; overflow: hidden; }
body { font-size: var(--fs-sm); background: var(--map-sea); }

#map { position: fixed; inset: 0; background: var(--map-sea); }
.leaflet-container { background: var(--map-sea); font: inherit; }
/* base.css caps svg, img and canvas at 100% width. Leaflet only undoes that for its own panes;
   the custom panes here (basemap, quakes, fires, wind) draw larger than the view on purpose. */
.leaflet-container svg, .leaflet-container canvas, .leaflet-container img { max-width: none; max-height: none; }
.leaflet-control-attribution {
  background: color-mix(in srgb, var(--bg) 72%, transparent) !important;
  color: var(--text-3) !important;
  font-size: var(--fs-2xs);
}
.leaflet-control-attribution a { color: var(--text-2) !important; }

/* Inline icons sit on the text line (base.css makes every svg a block). */
svg.i { display: inline-block; inline-size: 1.15em; block-size: 1.15em; flex: none; vertical-align: -0.2em; }
.iconbtn svg.i { inline-size: 18px; block-size: 18px; vertical-align: 0; stroke-width: 1.8; }
.iconbtn:disabled { opacity: 0.4; cursor: default; }

/* ---------- header ------------------------------------------------------ */
.app-head {
  position: fixed; inset-block-start: 0; inset-inline: 0;
  z-index: var(--z-head);
  padding-block-start: env(safe-area-inset-top, 0px);
  background: var(--bg-glass);
  border-block-end: 1px solid var(--hairline-soft);
}
@supports (backdrop-filter: blur(1px)) {
  .app-head {
    background: color-mix(in srgb, var(--bg) 72%, transparent);
    backdrop-filter: saturate(180%) blur(20px);
  }
}
.app-head__in {
  display: flex; align-items: center; gap: var(--s-3);
  block-size: var(--nav-h);
  padding-inline: var(--s-4);
}
.brand { min-inline-size: 0; flex: 1; }
.brand__text { min-inline-size: 0; }
.brand__name { font-size: clamp(var(--fs-sm), 0.8rem + 1vw, var(--fs-body)); font-weight: 600; line-height: 1.2; letter-spacing: -0.02em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.brand__meta {
  font-size: var(--fs-2xs); font-weight: 400; line-height: 1.3; letter-spacing: 0;
  color: var(--text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.head-end { gap: var(--s-2); flex: none; }
.head-end .select { inline-size: auto; max-inline-size: clamp(5.5rem, 26vw, 7.5rem); min-height: 44px; }

/* ---------- layer toggles ----------------------------------------------- */
.layerbar {
  position: fixed; z-index: var(--z-head);
  inset-block-start: calc(env(safe-area-inset-top, 0px) + var(--nav-h) + var(--s-2));
  inset-inline: 0;
  display: flex; gap: var(--s-2);
  padding-inline: var(--s-4);
  overflow-x: auto; scrollbar-width: none;
}
.layerbar::-webkit-scrollbar { display: none; }
/* A toggle, not a .chip: chips in the system are passive labels. */
.toggle {
  flex: none;
  display: inline-flex; align-items: center; gap: var(--s-2);
  min-height: var(--bar-h);
  padding-inline: var(--s-4);
  border: 1px solid var(--hairline);
  border-radius: var(--r-chip);
  background: var(--bg-elevated);
  color: var(--text-3);
  font-size: var(--fs-sm); font-weight: 500;
  white-space: nowrap; cursor: pointer;
  box-shadow: var(--sh-sm);
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.toggle:hover { color: var(--text); }
.toggle:active { scale: 0.97; }
.toggle svg.i { inline-size: 16px; block-size: 16px; vertical-align: 0; stroke-width: 2; }
.toggle[aria-pressed="true"] {
  color: var(--text);
  border-color: color-mix(in oklab, var(--c) 55%, transparent);
  background: color-mix(in oklab, var(--c) 14%, var(--bg-elevated));
}
.toggle[aria-pressed="true"] svg.i { color: var(--c); }
/* Just switched on by opening a card: a brief tint confirms the map changed. */
.toggle.flash { background: color-mix(in oklab, var(--c) 32%, var(--bg-elevated)); }
.toggle__n { color: var(--text-3); font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }

.banner {
  position: fixed; z-index: var(--z-head);
  inset-block-start: var(--chrome-top);
  inset-inline: var(--s-4);
  font-size: var(--fs-xs);
  /* Over a busy map the translucent note wash is unreadable; lay it on a solid surface. */
  background: color-mix(in oklab, var(--warn) 14%, var(--bg-elevated));
  box-shadow: var(--sh-md);
}

/* ---------- map controls ------------------------------------------------ */
.map-ctl {
  position: fixed; z-index: var(--z-head);
  inset-inline-start: var(--s-4);
  inset-block-end: calc(var(--peek-h, 175px) + env(safe-area-inset-bottom, 0px) + var(--s-3));
  display: flex; flex-direction: column; gap: var(--s-2);
}
.map-ctl .iconbtn { box-shadow: var(--sh-sm); }
body[data-sheet="half"] .map-ctl, body[data-sheet="full"] .map-ctl { display: none; }

/* ---------- legend ------------------------------------------------------ */
.legend {
  position: fixed; z-index: var(--z-head);
  inset-inline-end: var(--s-4);
  inset-block-end: calc(var(--peek-h, 175px) + env(safe-area-inset-bottom, 0px) + var(--s-3));
  max-inline-size: 12rem;
  max-block-size: calc(100dvh - var(--chrome-top) - var(--peek-h, 175px) - var(--s-8));
  overflow-y: auto;
  padding: 0 var(--s-3) var(--s-2);
  border: 1px solid var(--hairline-soft);
  border-radius: var(--r-md);
  background: var(--bg-elevated);
  box-shadow: var(--sh-md);
  font-size: var(--fs-xs); color: var(--text-2);
}
.legend__toggle {
  display: flex; align-items: center; gap: var(--s-2);
  min-height: 44px; inline-size: 100%;
  padding: 0; border: 0; background: none; cursor: pointer;
  font-size: var(--fs-xs); font-weight: 600; color: var(--text-2);
}
.legend[data-open="false"] { padding-block-end: 0; }
.legend__group + .legend__group { margin-block-start: var(--s-3); }
.legend__h {
  display: flex; align-items: center; gap: var(--s-1);
  margin-block-end: var(--s-1);
  font-size: var(--fs-2xs); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-3);
}
.legend__row { display: flex; align-items: center; gap: var(--s-2); line-height: 1.7; }
.legend__note { color: var(--text-3); line-height: 1.4; }
.sw { inline-size: 10px; block-size: 10px; flex: none; border-radius: calc(var(--s-1) / 2); }
.sw--round { border-radius: 50%; }
.seg {
  display: inline-flex; margin-block: var(--s-1);
  border: 1px solid var(--hairline); border-radius: var(--r-chip); overflow: hidden;
}
.seg button {
  min-height: 36px; padding-inline: var(--s-3);
  border: 0; background: none; cursor: pointer;
  font-size: var(--fs-xs); font-variant-numeric: tabular-nums; color: var(--text-3);
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.seg button[aria-pressed="true"] { background: color-mix(in oklab, var(--layer-rain) 22%, transparent); color: var(--text); font-weight: 600; }

/* ---------- info panel (bottom sheet on phones, side panel from 900px) --- */
.sheet {
  position: fixed; z-index: var(--z-sheet);
  inset-inline: 0; inset-block-end: 0;
  display: flex; flex-direction: column;
  max-block-size: calc(100dvh - env(safe-area-inset-top, 0px) - var(--nav-h) - var(--s-2));
  padding-block-end: env(safe-area-inset-bottom, 0px);
  border: 1px solid var(--hairline-soft); border-block-end: 0;
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  background: var(--bg-elevated);
  box-shadow: var(--sh-lg);
  transform: translateY(calc(100% - var(--peek-h, 175px) - env(safe-area-inset-bottom, 0px)));
  transition: transform var(--dur-slow) var(--ease);
}
.sheet[data-state="half"] { transform: translateY(calc(100% - min(56dvh, 100%))); }
.sheet[data-state="full"] { transform: translateY(0); }
.sheet:focus { outline: none; }

.grabber {
  display: grid; place-items: center; flex: none;
  min-height: 28px; padding: var(--s-2) 0 var(--s-1);
  border: 0; background: none; cursor: grab; touch-action: none;
}
.grabber span { inline-size: 40px; block-size: 5px; border-radius: var(--r-chip); background: var(--hairline); }

/* Stat cards: the system's .stat__fig / __label / __note inside a tappable card. */
.statbar {
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: clamp(var(--s-1), 1.6vw, var(--s-2));
  padding: var(--s-1) clamp(var(--s-2), 3vw, var(--s-3)) var(--s-3);
  flex: none;
}
.statcard {
  display: flex; flex-direction: column; align-items: flex-start;
  min-inline-size: 0; min-height: 44px;
  padding: var(--s-2) clamp(var(--s-1), 1.8vw, var(--s-2));
  border: 1px solid var(--hairline-soft);
  border-radius: var(--r-md);
  background: var(--bg-sunken);
  color: var(--text);
  text-align: start; cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.statcard:hover { border-color: var(--hairline); }
.statcard:active { scale: 0.97; }
.statcard[aria-current="true"] { border-color: color-mix(in oklab, var(--accent) 50%, transparent); background: var(--accent-wash); }
.statcard .stat__label {
  display: flex; align-items: center; gap: 3px; max-inline-size: 100%;
  margin: 0; font-size: var(--fs-2xs); letter-spacing: clamp(0em, 0.5vw - 0.04em, 0.04em);
  overflow: hidden; white-space: nowrap;
}
.statcard .stat__label svg.i { inline-size: 12px; block-size: 12px; stroke-width: 2.4; }
.statcard .stat__fig { margin-block-start: var(--s-1); font-size: clamp(1.125rem, 0.95rem + 0.8vw, 1.375rem); }
.statcard .stat__fig small { margin-inline-start: 1px; font-size: var(--fs-2xs); font-weight: 500; color: var(--text-3); }
.statcard .stat__note {
  max-inline-size: 100%; margin: 0;
  font-size: var(--fs-2xs); line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dot { display: inline-block; inline-size: 7px; block-size: 7px; margin-inline-end: 3px; border-radius: 50%; vertical-align: 1px; }

/* Tabs: the system's .tabs, stacked icon over a short label so six fit on a phone. */
.sheet .tabs { flex: none; gap: 0; padding-inline: var(--s-2); overflow-x: auto; scrollbar-width: none; }
.sheet .tabs button {
  flex: 1 1 0; min-inline-size: 3.25rem; min-height: 48px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  padding: var(--s-2) var(--s-1);
  font-size: var(--fs-2xs); letter-spacing: 0.01em;
}
.sheet .tabs button svg.i { inline-size: 18px; block-size: 18px; stroke-width: 1.8; }

.sheet-body {
  flex: 1; min-block-size: 0;
  overflow-y: auto; overscroll-behavior: contain;
  padding: var(--s-4) var(--s-4) var(--s-8);
}
.sheet-body > * + * { margin-block-start: var(--s-4); }
.sec-title {
  display: flex; align-items: center; gap: var(--s-2);
  font-size: var(--fs-xs); font-weight: 600; line-height: 1.4;
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-3);
}
.sheet-body > .sec-title:not(:first-child) { margin-block-start: var(--s-6); }
.sheet-body p { font-size: var(--fs-sm); color: var(--text-2); }
.sheet-body .fine { font-size: var(--fs-xs); color: var(--text-3); }
.sheet-body .empty { padding: var(--s-10) var(--s-4); }

/* ---------- loading --------------------------------------------------------
   The markup ships skeletons built from the real components (stat cards, toggles,
   bar rows) with placeholder text in them, so each box is exactly as tall as what
   replaces it and nothing moves when the data lands. The sweep waits 300 ms:
   a fast load should never flash it. */
/* Inherit the line-height of the element it stands in for, so the box is the same height. */
.skel-inline { display: inline-block; max-inline-size: 100%; line-height: inherit; vertical-align: top; }
.skel::after { animation-delay: 300ms; }
.statcard--skel, .toggle--skel { cursor: default; pointer-events: none; }
.toggle--skel { box-shadow: none; }
/* Refreshing in place (another date): the old numbers stay readable and dim. */
#stats[aria-busy="true"] > .statcard:not(.statcard--skel),
#sheet-body[aria-busy="true"] > :not(.skel-view) {
  opacity: 0.45;
  transition: opacity var(--dur) var(--ease);
}

/* ---------- lists ------------------------------------------------------- */
.list { list-style: none; padding: 0; margin-block-start: var(--s-2); }
.list > li { margin: 0; }
.list > li + li { border-block-start: 1px solid var(--hairline-soft); }
.list__head {
  padding: var(--s-4) 0 var(--s-1);
  font-size: var(--fs-2xs); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-3);
}
.list > li + li.list__head { border: 0; }
.list__item {
  display: flex; align-items: center; gap: var(--s-3);
  inline-size: 100%; min-height: 56px;
  padding: var(--s-2) var(--s-1);
  border: 0; border-radius: var(--r-sm); background: none;
  color: var(--text); text-align: start; cursor: pointer;
  transition: background-color var(--dur-fast) var(--ease);
}
button.list__item:hover { background: color-mix(in oklab, var(--text) 4%, transparent); }
.list__main { display: block; flex: 1; min-inline-size: 0; }
.list__t { display: block; font-weight: 600; letter-spacing: -0.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list__t small { font-weight: 400; color: var(--text-3); font-size: var(--fs-xs); }
.list__d { display: block; font-size: var(--fs-xs); color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.list__r { flex: none; text-align: end; font-size: var(--fs-xs); color: var(--text-3); font-variant-numeric: tabular-nums; line-height: 1.5; }
.list__r svg.i { inline-size: 13px; block-size: 13px; }

.pill {
  display: inline-grid; place-items: center; flex: none;
  min-inline-size: 48px; min-height: 30px; padding-inline: var(--s-2);
  border-radius: var(--r-sm);
  color: var(--on-data); font-weight: 650; font-variant-numeric: tabular-nums;
}
.pill--line { background: none; color: var(--c); box-shadow: inset 0 0 0 1.5px var(--c); }
.pill--lg { min-inline-size: 64px; min-height: 48px; font-size: var(--fs-lead); }

/* Horizontal bars */
.bars { display: grid; gap: var(--s-1); margin-block-start: var(--s-2); }
.bar-row { display: grid; grid-template-columns: 8.5rem minmax(0, 1fr) 3.25rem; gap: var(--s-2); align-items: center; font-size: var(--fs-xs); }
.bar-row__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-row__n { text-align: end; color: var(--text-2); font-variant-numeric: tabular-nums; }
.track { block-size: 8px; border-radius: var(--r-chip); background: var(--bg-sunken); overflow: hidden; }
.track__fill { block-size: 100%; border-radius: inherit; background: var(--fire-2); }

/* ---------- detail card ------------------------------------------------- */
.detail {
  padding: var(--s-4);
  border: 1px solid var(--hairline-soft);
  border-radius: var(--r-lg);
  background: var(--bg-sunken);
}
.detail__head { display: flex; align-items: flex-start; gap: var(--s-3); }
.detail__title { flex: 1; min-inline-size: 0; font-size: var(--fs-body); font-weight: 600; line-height: 1.35; letter-spacing: -0.012em; }
.detail__title small { display: block; font-size: var(--fs-xs); font-weight: 400; color: var(--text-3); letter-spacing: 0; }
.detail__close { margin-block-start: calc(var(--s-2) * -1); margin-inline-end: calc(var(--s-2) * -1); }
.detail > * + * { margin-block-start: var(--s-3); }
.aqi-now { display: flex; align-items: center; gap: var(--s-3); }
.aqi-now__label { font-weight: 600; }
.aqi-now__meta { font-size: var(--fs-xs); color: var(--text-3); }
.facts--compact {
  grid-template-columns: max-content minmax(0, 1fr);
  gap: var(--s-1) var(--s-4);
  padding: 0; background: none; border-radius: 0;
}
.facts--compact dt { font-size: var(--fs-2xs); display: flex; align-items: center; gap: var(--s-1); }
.facts--compact dd { font-size: var(--fs-xs); font-variant-numeric: tabular-nums; }
.forecast { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s-2); }
.forecast__day {
  padding: var(--s-2) var(--s-1);
  border-radius: var(--r-sm); background: var(--bg-elevated);
  font-size: var(--fs-2xs); line-height: 1.5; text-align: center; color: var(--text-2);
}
.forecast__day b { display: block; font-size: var(--fs-xs); color: var(--text); }

/* ---------- charts ------------------------------------------------------ */
.chart { inline-size: 100%; block-size: 110px; }
.chart .grid line { stroke: var(--chart-grid); }
.chart text { fill: var(--text-3); font-size: 10px; }
.chart .hit { fill: transparent; cursor: pointer; }
.chart .bar { fill: var(--fire-2); }
.chart .bar--other { fill: color-mix(in oklab, var(--text-3) 45%, transparent); }
.chart .line { fill: none; stroke: var(--info); stroke-width: 2; stroke-linejoin: round; }
.chart .pt { fill: var(--info); stroke: var(--bg-elevated); stroke-width: 2; }
.chart .now { stroke: var(--text-3); stroke-dasharray: 3 3; }
.chart .xhair { stroke: var(--text-2); }
.chart-key { display: flex; gap: var(--s-4); font-size: var(--fs-xs); color: var(--text-2); }
.chart-key i { display: inline-block; inline-size: 10px; block-size: 10px; margin-inline-end: var(--s-1); border-radius: calc(var(--s-1) / 2); vertical-align: -1px; }
.tooltip {
  position: fixed; z-index: var(--z-toast); pointer-events: none;
  padding: var(--s-1) var(--s-2);
  border: 1px solid var(--hairline); border-radius: var(--r-sm);
  background: var(--bg-elevated); box-shadow: var(--sh-md);
  font-size: var(--fs-xs); white-space: nowrap;
}

/* ---------- about / credits --------------------------------------------- */
.sources .list__item { cursor: default; align-items: flex-start; }
.sources .list__d { white-space: normal; }
.credit {
  display: flex; align-items: center; gap: var(--s-3);
  padding-block-start: var(--s-4);
  border-block-start: 1px solid var(--hairline-soft);
  font-size: var(--fs-xs); color: var(--text-2);
}
.credit svg { inline-size: 32px; block-size: 32px; flex: none; }
.credit p { font-size: var(--fs-xs); }

/* ---------- map features ------------------------------------------------ */
/* Basemap paths are styled here, not in script, so they follow the theme. */
.leaflet-pane path.land { fill: var(--map-land); stroke: var(--map-border); fill-opacity: 1; }
.leaflet-pane path.land--focus { fill: var(--map-land-focus); stroke: var(--map-border-focus); }
.leaflet-pane path.prov { stroke: var(--map-province); }
.leaflet-pane path.prov--focus { stroke: var(--map-province-focus); }
.leaflet-pane path.prov.is-selected { stroke: var(--accent); stroke-width: 2px; }
.leaflet-pane path.quake-ring { stroke: var(--quake); fill: var(--quake); }

.fire-canvas, .fire-glow, .wind-canvas { position: absolute; inset-block-start: 0; inset-inline-start: 0; pointer-events: none; }
/* Fire halos breathe: opacity only, so the compositor animates the layer without redrawing it. */
.fire-glow { opacity: 0.5; filter: blur(3px); }
@keyframes fire-breathe { from { opacity: 0.2; } to { opacity: 0.85; } }
/* Quake ripples: a ring that spreads and fades (transform + opacity only). */
.quake-ripple span {
  display: block; inline-size: 100%; block-size: 100%;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1.5px var(--quake);
  opacity: 0;
}
@keyframes quake-ripple {
  from { transform: scale(1); opacity: 0.75; }
  to { transform: scale(2.6); opacity: 0; }
}
@media (prefers-reduced-motion: no-preference) {
  .fire-glow { animation: fire-breathe var(--dur-breathe) var(--ease-breathe) infinite alternate; will-change: opacity; }
  .quake-ripple span { animation: quake-ripple var(--dur-ripple) var(--ease) infinite; will-change: transform, opacity; }
}
/* Empty parts of an SVG layer let clicks through; only drawn shapes catch them. */
.leaflet-pane > svg { pointer-events: none; }
.leaflet-container.fire-hover, .fire-hover .leaflet-interactive { cursor: pointer; }
.grid-overlay {
  filter: blur(2px);
  mask-image: radial-gradient(ellipse 60% 62% at 50% 50%, #000 70%, transparent 100%);
}
.rain-overlay { filter: blur(1.5px); }

.city-marker { display: flex; flex-direction: column; align-items: center; }
.city-marker__aqi {
  display: grid; place-items: center;
  min-inline-size: 30px; block-size: 22px; padding-inline: 5px;
  border: 2px solid var(--map-sea); border-radius: var(--r-chip);
  color: var(--on-data); font-size: var(--fs-2xs); font-weight: 700; font-variant-numeric: tabular-nums;
}
.city-marker__name {
  display: none; margin-block-start: 2px;
  font-size: var(--fs-2xs); font-weight: 500; color: var(--text); white-space: nowrap;
  text-shadow: 0 0 3px var(--map-sea), 0 0 6px var(--map-sea);
}
.show-labels .city-marker__name { display: block; }
.event-marker {
  display: grid; place-items: center;
  inline-size: 30px; block-size: 30px;
  border: 2px solid var(--map-sea); border-radius: var(--r-sm);
  color: var(--accent-ink);
  transform: rotate(45deg);
}
.event-marker > span { display: grid; transform: rotate(-45deg); }
.event-marker svg.i { inline-size: 16px; block-size: 16px; stroke-width: 2.4; }
.event-marker--green { background: var(--ok); }
.event-marker--orange { background: var(--warn); }
.event-marker--red { background: var(--danger); }
.wind-arrow svg { overflow: visible; }
.wind-arrow path { fill: none; stroke: var(--wind-ink); stroke-opacity: 0.6; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.me-marker {
  inline-size: 16px; block-size: 16px; border-radius: 50%;
  background: var(--info); border: 3px solid var(--bg-elevated);
  box-shadow: 0 0 0 6px var(--info-wash);
}

/* ---------- wide screens: side panel ------------------------------------ */
@media (width >= 900px) {
  :root { --chrome-top: calc(env(safe-area-inset-top, 0px) + var(--nav-h) + var(--bar-h) + var(--s-4)); }
  .app-head__in { padding-inline: var(--s-5); }
  .brand__meta { font-size: var(--fs-xs); }
  .head-end .select { max-inline-size: 10rem; }
  .layerbar { inset-inline-start: calc(var(--panel-w) + var(--s-8)); padding-inline: 0 var(--s-4); }
  .banner { inset-inline-start: calc(var(--panel-w) + var(--s-8)); inset-inline-end: calc(var(--s-4) + 44px + var(--s-4)); }
  .sheet {
    inset-inline-start: var(--s-4); inset-inline-end: auto;
    inset-block-start: calc(env(safe-area-inset-top, 0px) + var(--nav-h) + var(--s-3));
    inset-block-end: var(--s-4);
    inline-size: var(--panel-w); max-block-size: none;
    border: 1px solid var(--hairline-soft); border-radius: var(--r-lg);
    transform: none !important;
  }
  .grabber { display: none; }
  .statbar { padding-block-start: var(--s-3); }
  .map-ctl, body[data-sheet] .map-ctl {
    display: flex;
    inset-inline-start: auto; inset-inline-end: var(--s-4);
    inset-block-end: auto; inset-block-start: var(--chrome-top);
  }
  .legend { inset-block-end: var(--s-8); max-block-size: calc(100dvh - var(--chrome-top) - 200px); }
}
