*, *::before, *::after { box-sizing: border-box; }

/* Kill the default mobile tap-flash on every interactive element. The UA
   default is a rectangular translucent overlay (grey on iOS, light-grey on
   Android) painted over the element's bounding box — it IGNORES the
   element's border-radius, so on rounded / circular / oval buttons it
   reads as a sharp-cornered square flash that "cuts into" the visible
   shape. Setting it to transparent everywhere unifies the feel: buttons
   that define a `:active` rule give shape-aware feedback (background or
   transform change, inside the radius); buttons that don't stay silent
   (native-app convention). Applied to the interactive element list only,
   not `*`, so non-clickable text isn't touched. */
a, button, summary, label, [role="button"], [tabindex] {
  -webkit-tap-highlight-color: transparent;
}

/* Status palette — every error, warning, and success surface in the app
   (status line, GPS button, invalid inputs) reads from
   these tokens. Keeps the three ad-hoc reds that used to ship (#b0321d,
   #c1432c, #8c2413) from drifting apart. Contrast on the paired bg meets
   WCAG AA for body text at 12 px+.

   color-scheme: only light is the authoritative opt-out from browser-
   forced dark modes (Samsung Internet, Yandex, MIUI, Kiwi, Chrome's
   "Force Dark Mode for Web Contents" flag, Android 10+ system dark).
   Without this the panel and form inputs flip to near-black on those
   engines, even though every background colour is explicit: the UA
   inverts or overlays colours at its own layer. `only` is stricter
   than plain `light` and blocks the auto-invert pass entirely. */
:root {
  color-scheme: only light;
  --err-text:   #a1361f;
  --err-bg:     #fff1ee;
  --err-border: #f0c4bb;
  --warn-text:   #8a5a00;
  --warn-bg:     #fff8e1;
  --warn-border: #ebd39a;
  --ok-text:   #0f4d2a;
  --ok-bg:     #e9f5ee;
  --ok-border: #bdd9c4;
  --map-hud-edge: 18px;
  --map-hud-upper-lane: 72px;
}

html, body {
  height: 100%;
  margin: 0;
  /* Block the whole-document pull-to-refresh (Chrome Android) + rubber-
     band bounce (iOS Safari). Without this, a downward drag anywhere on
     the page — including on the Leaflet map — can temporarily lift the
     entire document by a few pixels, pushing the `position:fixed` bottom
     sheet (and its handle chevron) past the viewport bottom until the
     gesture releases. `none` stops both the gesture AND the visual
     glow/bounce; Leaflet handles its own map scroll so nothing is lost. */
  overscroll-behavior: none;
  overscroll-behavior-y: none;
}

/* Explicit background on the root element so browsers that paint the
   area outside `body` (e.g. during scroll over-fling on iOS, or when
   the layout temporarily fails to fill the viewport) don't reveal a
   system colour that flips dark under forced dark-mode overlays. */
html { background: #f5f7f3; }

body {
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  color: #152514;
  background: #f5f7f3;
  -webkit-font-smoothing: antialiased;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.shell {
  display: flex;
  flex-direction: column;
  /* 100vh is iOS Safari's "largest" viewport (address bar hidden). When the
     real visible area shrinks — soft keyboard open, address bar expanded,
     gesture chrome visible — content measured against 100vh becomes taller
     than what the user can see, and any flex item that can shrink gets
     squeezed. 100dvh tracks the *current* visible area on iOS 16+ / Android
     Chrome 108+ and is the right anchor for mobile. 100vh stays as a
     fallback for older browsers. */
  height: 100vh;
  height: 100dvh;
  min-height: 0;
  overflow: hidden;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  /* Baseline padding for every regular browser mode. Safe-area insets
     are applied in a `@media (display-mode: standalone)` block further
     down (only installed PWAs actually need to respect the device's
     safe zones; regular browsers handle their own chrome). This keeps
     Hola / Yandex / UC / Samsung Internet style chromium derivatives
     from pumping their custom toolbar's height into our env() reads. */
  padding: 14px 20px;
  background: #0f4d2a;
  color: #fff;
  box-shadow: 0 1px 0 rgba(0,0,0,0.12);
  /* Sit above the bottom sheet AND every Leaflet control so a full-snap
     sheet on short viewports can never cover the brand row. Positioned
     ancestor is required for z-index to take effect on a static element. */
  position: relative;
  z-index: 1500;
  /* Pin the bar so a keyboard-resized viewport can't flex-shrink it down
     to a thin green sliver (user-reported on both iOS + Android). Without
     this, the default flex-shrink:1 lets the parent compress the topbar
     when .shell's min-height briefly exceeds the visible area. min-height
     guarantees the brand row stays readable even if padding/content shift. */
  flex-shrink: 0;
  min-height: 54px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.brand-logo {
  flex-shrink: 0;
  display: block;
  border-radius: 8px;
}

.brand-text { min-width: 0; }

.brand-name {
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.2px;
}

.brand-caption {
  font-size: 12px;
  opacity: 0.85;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.top-actions {
  display: flex;
  align-items: center;
  gap: 14px;
}

.back-link {
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  color: #d9f0e1;
  text-decoration: none;
  border-radius: 8px;
  transition: background-color 0.14s ease, color 0.14s ease;
  -webkit-tap-highlight-color: transparent;
}

.back-link:hover {
  background-color: rgba(255, 255, 255, 0.12);
  color: #fff;
}

.back-link:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.back-link svg { display: block; }
.back-link:active { background-color: rgba(255, 255, 255, 0.2); }

.lang-switch {
  display: flex;
  gap: 4px;
  background: rgba(255,255,255,0.12);
  padding: 3px;
  border-radius: 8px;
}

.lang-btn {
  display: inline-grid;
  place-items: center;
  color: #fff;
  text-decoration: none;
  font-size: 12px;
  font-weight: 600;
  padding: 5px 10px;
  border-radius: 6px;
  letter-spacing: 0.4px;
}

.lang-btn:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.lang-btn:active { background: rgba(255, 255, 255, 0.2); }

.lang-btn.is-active {
  background: #fff;
  color: #0f4d2a;
}

.layout {
  flex: 1;
  position: relative;
  min-height: 0;
  overflow: hidden;
}

.panel { min-width: 0; }

.data-dialog {
  width: min(560px, calc(100vw - 32px));
  max-width: none;
  max-height: calc(100dvh - 32px);
  margin: auto;
  padding: 0;
  border: 0;
  overflow: visible;
  background: transparent;
  color: #18251c;
}

.data-dialog::backdrop {
  background: rgba(4, 18, 11, 0.58);
}

.data-dialog-card {
  display: flex;
  flex-direction: column;
  max-height: min(820px, calc(100dvh - 32px));
  overflow: hidden;
  border: 1px solid rgba(211, 224, 207, 0.96);
  border-radius: 18px;
  background: linear-gradient(180deg, #f8fbf7 0%, #f1f6ef 100%);
  box-shadow: 0 30px 90px rgba(3, 18, 10, 0.34);
  animation: data-dialog-in 180ms cubic-bezier(0.22, 0.78, 0.25, 1);
}

@keyframes data-dialog-in {
  from { opacity: 0; transform: translateY(10px) scale(0.985); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.data-dialog-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 18px;
  padding: 18px 20px 15px;
  border-bottom: 1px solid #dbe6d7;
  background: rgba(255, 255, 255, 0.88);
}

.data-dialog-eyebrow {
  margin: 0 0 4px;
  color: #2f714a;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.11em;
  line-height: 1.2;
  text-transform: uppercase;
}

.data-dialog-title {
  margin: 0;
  color: #173520;
  font-size: 20px;
  line-height: 1.18;
}

.data-dialog-title:focus {
  outline: none;
}

.data-dialog-subtitle {
  margin: 5px 0 0;
  color: #60705e;
  font-size: 12.5px;
  line-height: 1.4;
}

.data-dialog-close {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  padding: 0;
  border: 1px solid #cbd9c7;
  border-radius: 10px;
  background: #f8fbf6;
  color: #2b4932;
  font: inherit;
  font-size: 23px;
  line-height: 1;
  cursor: pointer;
}

.data-dialog-close:hover {
  background: #edf5e9;
}

.data-dialog-close:focus-visible {
  outline: 2px solid #0f4d2a;
  outline-offset: 2px;
}

.panel--controls {
  min-height: 0;
  padding: 16px 18px 20px;
  overflow-y: auto;
  overflow-x: hidden;
  background: transparent;
  scrollbar-width: thin;
  scrollbar-color: rgba(15, 77, 42, 0.24) transparent;
  overscroll-behavior: contain;
}

.panel--controls::-webkit-scrollbar { width: 6px; }
.panel--controls::-webkit-scrollbar-track { background: transparent; }
.panel--controls::-webkit-scrollbar-thumb {
  border-radius: 999px;
  background: rgba(15, 77, 42, 0.24);
}

@media (prefers-reduced-motion: reduce) {
  .data-dialog-card {
    animation: none;
  }
}


/* Zoom and geometry actions are rendered by the shared SmartMap toolbar.
   Hiding Leaflet's native chrome prevents visual and functional drift between
   street, satellite and globe modes while preserving Leaflet.Draw handlers. */
.leaflet-top.leaflet-right { display: none; }

/* ---- Map mode switcher (top-left) --------------------------------------
   One stable control surface switches between the optional globe and the
   established street/satellite field maps. It stays renderer-independent
   so users can always recover from a WebGL initialization failure. */
.map-mode-switch {
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: 1100;
  display: flex;
  border: 1px solid #c4d0bf;
  border-radius: 10px;
  overflow: hidden;
  background-color: #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
}

.map-mode-btn {
  width: 34px;
  height: 34px;
  padding: 0;
  background: #fff;
  color: #2f4431;
  border: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.14s ease, color 0.14s ease;
  -webkit-tap-highlight-color: transparent;
  border-right: 1px solid #eef2ea;
}

.map-mode-btn:last-child { border-right: none; }

.map-mode-btn svg {
  display: block;
  flex: none;
}

@media (hover: hover) {
  .map-mode-btn:hover:not([aria-pressed="true"]) {
    background: #f0f6ed;
    color: #0f4d2a;
  }
}

.map-mode-btn[aria-pressed="true"] {
  background: #0f4d2a;
  color: #fff;
}

.map-mode-btn:focus-visible {
  outline: 2px solid #0f4d2a;
  outline-offset: -2px;
  z-index: 1;
}

/* Mobile: keep the same 34 px cells as desktop — two finger-friendly bumps
   side-by-side made the pill dominate the map chrome. 34 px is still above
   the practical tap-target threshold for an isolated icon button. */

/* ---- Provider attribution ----------------------------------------------
   OSM and Esri both require visible on-map credit. Leaflet and MapLibre use
   one restrained, readable surface in the same lower-right workspace lane. */
.panel--map .leaflet-bottom.leaflet-right,
.globe-map .maplibregl-ctrl-bottom-right {
  right: 8px;
  bottom: 8px;
  z-index: 1050;
  max-width: calc(100% - 16px);
}

.leaflet-control-attribution,
.globe-map .maplibregl-ctrl-attrib {
  max-width: min(620px, calc(100vw - 32px));
  margin: 0 !important;
  padding: 3px 8px !important;
  border: 1px solid rgba(31, 77, 43, 0.14) !important;
  border-radius: 999px !important;
  background: rgba(246, 249, 245, 0.68) !important;
  box-shadow: 0 2px 10px rgba(8, 31, 16, 0.1);
  color: rgba(27, 55, 34, 0.84) !important;
  font-size: 10px !important;
  line-height: 1.35 !important;
  text-align: right;
  white-space: normal;
  backdrop-filter: blur(5px) saturate(0.82);
  -webkit-backdrop-filter: blur(5px) saturate(0.82);
  transition: background-color 0.16s ease, color 0.16s ease;
}

.leaflet-control-attribution a,
.globe-map .maplibregl-ctrl-attrib a {
  color: #214b2c !important;
  text-decoration: none;
}

.leaflet-control-attribution:hover,
.leaflet-control-attribution:focus-within,
.globe-map .maplibregl-ctrl-attrib:hover,
.globe-map .maplibregl-ctrl-attrib:focus-within {
  background: rgba(250, 252, 249, 0.9) !important;
  color: #17351f !important;
}

.leaflet-control-attribution:hover a,
.leaflet-control-attribution:focus-within a,
.globe-map .maplibregl-ctrl-attrib:hover a,
.globe-map .maplibregl-ctrl-attrib:focus-within a {
  color: #0f4d2a !important;
  text-decoration: underline;
}

/* Drawing guidance is presented by the shared renderer-neutral guide, so the
   Leaflet cursor tooltip is intentionally suppressed in flat map modes. */
.leaflet-draw-tooltip,
.leaflet-draw-tooltip-single,
.leaflet-tooltip {
  display: none !important;
}

/* Keep selection geometry and edit affordances visually identical between
   Leaflet's flat maps and the MapLibre globe overlay. */
.smartmap-selection-path {
  filter: drop-shadow(0 0 2px rgba(2, 14, 8, 0.9));
}

.leaflet-editing-icon {
  width: 12px !important;
  height: 12px !important;
  margin-left: -6px !important;
  margin-top: -6px !important;
  border: 2px solid #ffffff !important;
  border-radius: 50% !important;
  background: #0f4d2a !important;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.72);
}

.leaflet-editing-icon.is-polygon-close-target {
  border-color: #0f4d2a !important;
  background: #efffe9 !important;
  box-shadow: 0 0 0 3px rgba(239, 255, 233, 0.82), 0 1px 3px rgba(0, 0, 0, 0.72);
}

.control-section {
  padding: 14px;
  margin-bottom: 10px;
  border: 1px solid #d9e4d6;
  border-radius: 12px;
  background: linear-gradient(180deg, #fbfdfb 0%, #ffffff 36%);
  box-shadow: 0 3px 12px rgba(27, 62, 37, 0.055);
}

.control-section--date {
  background: linear-gradient(180deg, #f8fbf7 0%, #ffffff 36%);
}

.control-section--layer {
  background: linear-gradient(180deg, #f8fbf7 0%, #ffffff 36%);
}

.control-actions {
  margin-top: 8px;
}

.panel-title {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: #4a6048;
  margin: 18px 0 8px;
}

.panel-title:first-of-type { margin-top: 0; }

.control-section .panel-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 8px;
  color: #244d32;
}

.control-section .panel-title::before {
  content: "";
  width: 7px;
  height: 7px;
  flex: 0 0 auto;
  border-radius: 999px;
  background: #177044;
  box-shadow: 0 0 0 3px rgba(23, 112, 68, 0.1);
}

/* Hints are a whisper under the heading — dimmer and smaller than the
   title so the heading dominates the vertical rhythm. Default top margin
   leaves breathing room when the hint follows a form row (e.g. the date
   inputs); the `.panel-title + .hint` rule below pulls it closer only in
   the heading→hint→inputs case so the heading and its hint read as one unit. */
.hint {
  font-size: 11px;
  font-weight: 400;
  line-height: 1.35;
  color: #7a877a;
  margin: 8px 0 10px;
}

.panel-title + .hint {
  margin-top: -2px;
}

.data-draw-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin: 0 0 10px;
}

.data-draw-btn {
  min-height: 38px;
  padding: 8px 10px;
  border: 1px solid #bfd0ba;
  border-radius: 9px;
  background: #f6faf4;
  color: #244d32;
  font: inherit;
  font-size: 12px;
  font-weight: 750;
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  .data-draw-btn:hover {
    border-color: #84ac7d;
    background: #eaf4e6;
  }
}

.data-draw-btn:active {
  background: #deedd9;
}

.data-draw-btn:focus-visible {
  outline: 2px solid #0f4d2a;
  outline-offset: 2px;
}

.control-section .hint:last-child,
.control-section .bbox-readout:last-child,
.control-section .resolution-hint:last-child {
  margin-bottom: 0;
}

.search-box {
  display: flex;
  gap: 6px;
  margin-bottom: 8px;
}

.search-box input {
  flex: 1;
  /* Without min-width: 0 a flex item's min-width defaults to its intrinsic
     content width — for an input that's the placeholder ("City / district
     / address..." / "İl / ilçe / adres..."). On narrow phones (iPhone SE,
     320-375 px) that intrinsic width alone can exceed the available row
     width; the flex container then OVERFLOWS, and since .panel--controls
     has overflow-x: hidden, the last sibling ("Ara" button) is clipped off
     the right edge. Explicit 0 min-width lets the input shrink to fit. */
  min-width: 0;
  font: inherit;
  font-size: 13px;
  padding: 8px 10px;
  border: 1px solid #c4d0bf;
  border-radius: 8px;
  background: #fafcf8;
}

.search-box input:focus {
  outline: 2px solid #2d8a4f;
  outline-offset: -2px;
  border-color: transparent;
}

/* Scoped to the search submit only. Previously this selector ALSO styled
   the GPS icon button next to it — with dark-green fill, text-align inherit,
   and horizontal padding that squeezed the SVG to one edge of its square.
   :not(.gps-btn) keeps the GPS button on its own dedicated rules below. */
.search-box button:not(.gps-btn) {
  /* flex-shrink:0 pins the Ara/Search label at its natural width —
     otherwise under pressure from a narrow viewport the button would
     truncate the text or its padding would collapse before the input
     gave up any width. */
  flex-shrink: 0;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 8px 14px;
  border: none;
  border-radius: 8px;
  background: #0f4d2a;
  color: #fff;
  cursor: pointer;
}

.search-box button:not(.gps-btn):hover { background: #15683a; }
.search-box button:not(.gps-btn):disabled {
  cursor: wait;
  opacity: 0.68;
}

.geocode-results {
  border: 1px solid #dde4d8;
  border-radius: 8px;
  background: #fff;
  margin-bottom: 10px;
  max-height: 180px;
  overflow-y: auto;
}

.geocode-result {
  display: block;
  width: 100%;
  padding: 7px 10px;
  border: 0;
  font-size: 12px;
  font-family: inherit;
  line-height: 1.45;
  text-align: left;
  background: #fff;
  color: #2f4431;
  cursor: pointer;
  border-bottom: 1px solid #eef2ea;
}

.geocode-result:last-child { border-bottom: none; }
.geocode-result:hover { background: #f0f6ed; }
.geocode-result:focus-visible {
  position: relative;
  outline: 2px solid #0f4d2a;
  outline-offset: -2px;
}
.geocode-result:active { background: #e2eedc; }

.bbox-readout {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  font-size: 12px;
  padding: 8px 10px;
  background: #f5f7f3;
  border-radius: 8px;
  margin-bottom: 6px;
  color: #2f4431;
}

.bbox-label { color: #4a6048; font-weight: 600; }
.bbox-value { font-variant-numeric: tabular-nums; }

.clear-btn {
  margin-left: auto;
  font: inherit;
  font-size: 11px;
  padding: 3px 8px;
  border: 1px solid #c4d0bf;
  border-radius: 6px;
  background: #fff;
  cursor: pointer;
  color: #4a6048;
}

.clear-btn:hover { background: #f0f6ed; }

.date-row {
  display: grid;
  /* auto-fit + minmax is the only layout guaranteed never to overlap on
     *any* mobile engine. Fixed "1fr 1fr" trusted every browser to honour
     the grid's 8 px gap and to keep <input type="date"> rendered within
     its declared width; some iOS Safari + Chrome Android builds ignore
     this because the input's shadow DOM (calendar indicator, locale
     placeholder) enforces its own UA-level minimum width and bleeds
     into the neighbouring cell. With auto-fit, whenever the container
     can't fit two 130-px columns (≈ tiny phones under 280 px content
     width) the second column drops to a new row instead of overlapping.
     130 px minimum still comfortably shows "dd.mm.yyyy" + calendar icon
     at 14 px font. */
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 8px;
}

.date-row label,
.cloud-row label {
  display: flex;
  flex-direction: column;
  gap: 3px;
  font-size: 11px;
  font-weight: 600;
  color: #4a6048;
  /* Safety net: clip any native-rendered overflow inside the label wrap
     (calendar indicator shadow parts on older WebKit) so visual bleed
     can't escape into the adjacent grid cell even if the input itself
     misreports its width. */
  min-width: 0;
  overflow: hidden;
}

.cloud-row {
  margin-top: 8px;
}

.date-row input,
.cloud-row input {
  font: inherit;
  font-size: 13px;
  padding: 7px 8px;
  border: 1px solid #c4d0bf;
  border-radius: 8px;
  background: #fafcf8;
  /* Explicit text colour — some forced-dark implementations invert the
     value colour without touching the background, producing white-on-
     white unreadable dates. Also keeps the native date-picker popup
     rendering in light mode on Chrome/Edge where it inherits the
     element's color-scheme. */
  color: #1f2f22;
  /* width + max-width + min-width triple lock: the input always matches
     the grid cell, never wider (overflow from native glyph), never
     narrower (intrinsic content floor), never bleeds into neighbours. */
  width: 100%;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
}

.cloud-row input {
  max-width: 150px;
}

/* Input + select + textarea + button: native-rendered parts (date picker
   popups, scroll arrows, option lists) follow the element's color-scheme
   on Chromium/WebKit, not just the :root declaration. Scoping it here
   keeps the wheel pickers and calendar popups light-themed even when
   the user's OS is in dark mode but we're overriding to light. */
input, select, textarea, button { color-scheme: only light; }

.layer-chips {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  margin-bottom: 12px;
}

.layer-chip {
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 10px 8px;
  text-align: left;
  border: 1px solid #c4d0bf;
  border-radius: 8px;
  background: #fafcf8;
  color: #2f4431;
  cursor: pointer;
  transition: background-color 0.12s, border-color 0.12s, color 0.12s, transform 0.08s;
}

.layer-chip:hover { background: #f0f6ed; }
.layer-chip:active { transform: scale(0.98); }

.layer-chip:disabled {
  opacity: 0.62;
  cursor: wait;
  transform: none;
}

.layer-chip.is-active {
  background: #0f4d2a;
  color: #fff;
  border-color: #0f4d2a;
}

.resolution-hint {
  font-size: 11px;
  color: #6a7e68;
  margin: 4px 0 12px;
  min-height: 14px;
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
}

.resolution-hint strong {
  color: #2f4431;
  font-weight: 600;
}

.resolution-hint-note {
  color: #7a8d77;
  font-size: 10.5px;
  margin-top: 2px;
}

.primary-btn {
  width: 100%;
  font: inherit;
  font-size: 14px;
  font-weight: 700;
  padding: 12px;
  border: none;
  border-radius: 10px;
  background: #0f4d2a;
  color: #fff;
  cursor: pointer;
  letter-spacing: 0.3px;
  margin-top: 6px;
}

.primary-btn:hover:not(:disabled) { background: #15683a; }

.primary-btn:disabled {
  background: #b7c5b4;
  cursor: not-allowed;
}

.secondary-btn {
  width: 100%;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  padding: 9px 12px;
  border: 1px solid #c4d0bf;
  border-radius: 8px;
  background: #fafcf8;
  color: #2f4431;
  cursor: pointer;
  margin-top: 10px;
  letter-spacing: 0.2px;
}

.secondary-btn:hover { background: #f0f6ed; border-color: #a8b8a3; }
.secondary-btn:active { background: #e2ecdc; }

.status-line {
  font-size: 12px;
  color: #4a6048;
  min-height: 16px;
  margin: 10px 0 0;
}

.status-line.is-error   { color: var(--err-text); }
.status-line.is-warning { color: var(--warn-text); }
.status-line.is-success { color: var(--ok-text); }

.scene-info {
  margin-top: 14px;
  padding: 12px 14px;
  background: #f5f7f3;
  border: 1px solid #e3e9de;
  border-radius: 10px;
  font-size: 12px;
  color: #2f4431;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.scene-info-title {
  display: block;
  color: #0f4d2a;
  font-size: 11px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  font-weight: 700;
}

.scene-info-header {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.scene-info-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 2px 0;
}

.scene-info-row > span:first-child {
  color: #5e6e5c;
}

.scene-info-row > span:last-child {
  font-variant-numeric: tabular-nums;
  font-weight: 500;
  color: #1f2f22;
}

.scene-info-note {
  margin: 0;
  padding: 6px 10px;
  background: #ffffff;
  border-left: 2px solid #0f4d2a;
  border-radius: 4px;
  font-size: 11.5px;
  line-height: 1.4;
  color: #4a5a49;
}

.scene-info-list {
  margin: 0;
  border-top: 1px dashed #c8d2c0;
  padding-top: 8px;
}

.scene-info-list > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  padding: 2px 0;
  font-size: 11.5px;
  user-select: none;
  outline: none;
  border-radius: 4px;
}

.scene-info-list > summary::-webkit-details-marker {
  display: none;
}

.scene-info-list > summary:hover .scene-info-list-toggle,
.scene-info-list > summary:focus-visible .scene-info-list-toggle {
  color: #0a3a1f;
  text-decoration: underline;
}

.scene-info-list-count {
  color: #5e6e5c;
}

.scene-info-list-toggle {
  color: #0f4d2a;
  font-weight: 600;
  font-size: 11px;
}

.scene-info-list[open] .scene-info-list-items {
  margin-top: 6px;
}

.scene-info-list-items {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 176px;
  overflow-y: auto;
  border-radius: 6px;
  background: #ffffff;
  border: 1px solid #e3e9de;
}

.scene-info-list-items::-webkit-scrollbar {
  width: 6px;
}

.scene-info-list-items::-webkit-scrollbar-thumb {
  background: #c8d2c0;
  border-radius: 3px;
}

.scene-info-list-item {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 10px;
  padding: 6px 10px;
  font-size: 11.5px;
  border-bottom: 1px solid #eef2eb;
}

.scene-info-list-item:last-child {
  border-bottom: none;
}

.scene-info-list-item.is-chosen {
  background: #e6f0df;
}

.scene-info-list-item.is-skipped .scene-info-list-date,
.scene-info-list-item.is-skipped .scene-info-list-meta {
  color: #8b978a;
}

.scene-info-list-date {
  font-weight: 500;
  color: #1f2f22;
  font-variant-numeric: tabular-nums;
}

.scene-info-list-meta {
  color: #5e6e5c;
  font-variant-numeric: tabular-nums;
  font-size: 11px;
  min-width: 3ch;
  text-align: right;
}

.scene-info-list-tag {
  font-size: 10px;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 999px;
  white-space: nowrap;
}

.scene-info-list-tag.is-chosen {
  background: #0f4d2a;
  color: #ffffff;
}

.scene-info-list-tag.is-used {
  background: #dbe7d0;
  color: #0f4d2a;
}

.scene-info-list-tag.is-skipped {
  background: #edf0e9;
  color: #8b978a;
}

/* Clickable rows — the whole row behaves like a button so the larger touch
   target helps on mobile. Keyboard users get a crisp focus ring. */
.scene-info-list-item.is-clickable {
  cursor: pointer;
  transition: background-color 0.12s ease, transform 0.12s ease;
  -webkit-tap-highlight-color: transparent;
}

.scene-info-list-item.is-clickable:hover {
  background: #f0f6ed;
}

.scene-info-list-item.is-clickable.is-chosen:hover {
  /* Chosen row hover is a no-op action (re-renders the same scene), so we
     don't lift the background — it would hint at an action that isn't there. */
  background: #e6f0df;
}

.scene-info-list-item.is-clickable:active {
  transform: translateY(0.5px);
}

.scene-info-list-item.is-clickable:focus-visible {
  outline: 2px solid #0f4d2a;
  outline-offset: -2px;
  background: #f0f6ed;
}

.scene-info-list-hint {
  margin: 6px 2px 0;
  font-size: 10.5px;
  color: #8b978a;
  line-height: 1.4;
}

/* Manual-pick strategy note gets a subtle amber accent + inline reset link */
.scene-info-note.is-manual {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  border-left-color: #c48a17;
  background: #fdf6e3;
  color: #5a4711;
}

.scene-info-reset {
  appearance: none;
  background: none;
  border: none;
  padding: 2px 4px;
  margin: 0;
  color: #0f4d2a;
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  border-radius: 4px;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.scene-info-reset:hover {
  color: #0a3a1f;
  background: #e6f0df;
}

.scene-info-reset:focus-visible {
  outline: 2px solid #0f4d2a;
  outline-offset: 1px;
}

.timeline-panel {
  margin-top: 12px;
  padding: 12px 14px;
  background: #ffffff;
  border: 1px solid #dfe7d9;
  border-radius: 8px;
  color: #263a29;
}

.timeline-panel[hidden] {
  display: none;
}

.timeline-head,
.timeline-label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.timeline-title {
  color: #0f4d2a;
  font-size: 11px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  font-weight: 700;
}

.timeline-meta {
  color: #6d7a69;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

.timeline-label {
  margin-top: 8px;
  color: #5e6e5c;
  font-size: 11.5px;
}

.timeline-label strong {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: #1f2f22;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.scene-slider {
  width: 100%;
  margin: 10px 0 0;
  accent-color: #0f4d2a;
  cursor: pointer;
}

.scene-slider:disabled {
  cursor: default;
  opacity: 0.55;
}

.map-timeline {
  position: absolute;
  z-index: 650;
  width: min(328px, calc(100% - 24px));
  padding: 8px 12px 9px;
  border: 1px solid rgba(226, 255, 232, 0.2);
  border-radius: 14px;
  background:
    linear-gradient(135deg, rgba(3, 17, 12, 0.9), rgba(10, 58, 35, 0.84));
  box-shadow:
    0 14px 36px rgba(0, 0, 0, 0.3),
    inset 0 1px 0 rgba(255, 255, 255, 0.1);
  color: #f4fff5;
  backdrop-filter: blur(14px) saturate(125%);
  -webkit-backdrop-filter: blur(14px) saturate(125%);
  pointer-events: auto;
  box-sizing: border-box;
}

.map-timeline[hidden] {
  display: none;
}

.map-timeline-track {
  position: relative;
  padding-top: 22px;
}

.map-timeline-date {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  max-width: 100%;
  padding: 2px 9px;
  border: 1px solid rgba(231, 255, 235, 0.16);
  border-radius: 999px;
  background: rgba(231, 255, 235, 0.11);
  color: #f7fff8;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
  font-size: 10.5px;
  font-weight: 800;
  line-height: 1.35;
  letter-spacing: 0.015em;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.timeline-panel.is-loading .timeline-label strong::after,
.map-timeline.is-loading .map-timeline-date::after {
  content: "";
  width: 8px;
  height: 8px;
  flex: 0 0 8px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  opacity: 0.78;
  animation: timeline-loading-spin 0.7s linear infinite;
}

@keyframes timeline-loading-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .timeline-panel.is-loading .timeline-label strong::after,
  .map-timeline.is-loading .map-timeline-date::after {
    animation: none;
    border-right-color: currentColor;
  }
}

.map-scene-slider {
  --timeline-progress: 0%;
  appearance: none;
  -webkit-appearance: none;
  display: block;
  width: 100%;
  height: 28px;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: #8bd38a;
  cursor: pointer;
}

.map-scene-slider::-webkit-slider-runnable-track {
  height: 4px;
  border: 0;
  border-radius: 999px;
  background: linear-gradient(
    90deg,
    #8bd38a 0 var(--timeline-progress),
    rgba(239, 255, 241, 0.25) var(--timeline-progress) 100%
  );
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.28);
}

.map-scene-slider::-webkit-slider-thumb {
  appearance: none;
  -webkit-appearance: none;
  width: 17px;
  height: 17px;
  margin-top: -6.5px;
  border: 2px solid #17623e;
  border-radius: 50%;
  background: #f7fff7;
  box-shadow:
    0 0 0 2px rgba(139, 211, 138, 0.22),
    0 3px 9px rgba(0, 0, 0, 0.38);
}

.map-scene-slider::-moz-range-track {
  height: 4px;
  border: 0;
  border-radius: 999px;
  background: rgba(239, 255, 241, 0.25);
  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.28);
}

.map-scene-slider::-moz-range-progress {
  height: 4px;
  border-radius: 999px;
  background: #8bd38a;
}

.map-scene-slider::-moz-range-thumb {
  width: 13px;
  height: 13px;
  border: 2px solid #17623e;
  border-radius: 50%;
  background: #f7fff7;
  box-shadow:
    0 0 0 2px rgba(139, 211, 138, 0.22),
    0 3px 9px rgba(0, 0, 0, 0.38);
}

.map-scene-slider:focus-visible {
  outline: 2px solid #d9ffda;
  outline-offset: 2px;
  border-radius: 999px;
}

.map-scene-slider:active::-webkit-slider-thumb {
  border-color: #9be29a;
  background: #ffffff;
  transform: scale(1.06);
}

.map-scene-slider:active::-moz-range-thumb {
  border-color: #9be29a;
  background: #ffffff;
}

.map-scene-slider:disabled {
  cursor: default;
  opacity: 0.55;
}

.result-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}

.result-actions .secondary-btn {
  margin-top: 0;
  flex: 1 1 142px;
}

.data-workflow {
  position: fixed;
  right: 66px;
  bottom: 78px;
  z-index: 1700;
  display: flex;
  align-items: center;
  gap: 8px;
}

.data-workflow[hidden] {
  display: none;
}

.data-workflow-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 46px;
  min-width: 46px;
  padding: 0 14px;
  border: 1px solid rgba(25, 78, 43, 0.24);
  border-radius: 999px;
  background: rgba(249, 252, 248, 0.94);
  color: #174326;
  box-shadow: 0 11px 30px rgba(7, 34, 18, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.75);
  font: inherit;
  font-size: 12.5px;
  font-weight: 800;
  line-height: 1;
  cursor: pointer;
  transition: transform 0.16s ease, box-shadow 0.16s ease, background-color 0.16s ease;
}

.data-workflow-btn[hidden] {
  display: none;
}

.data-workflow-btn svg {
  display: block;
  flex: 0 0 auto;
}

.data-workflow-btn.is-compact {
  width: 46px;
  padding: 0;
}

.data-workflow-btn--download {
  width: 46px;
  padding: 0;
  border-color: rgba(255, 255, 255, 0.3);
  background: linear-gradient(135deg, #16603a, #0f4d2a);
  color: #ffffff;
}

.data-workflow-btn:disabled {
  cursor: wait;
  opacity: 0.62;
}

@media (hover: hover) and (pointer: fine) {
  .data-workflow-btn:hover:not(:disabled) {
    transform: translateY(-1px);
    background: #ffffff;
    box-shadow: 0 14px 36px rgba(7, 34, 18, 0.26), inset 0 1px 0 #ffffff;
  }

  .data-workflow-btn--download:hover:not(:disabled) {
    background: linear-gradient(135deg, #1b7046, #135c35);
  }
}

.data-workflow-btn:active:not(:disabled) {
  transform: translateY(1px);
}

.data-workflow-btn:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(15, 77, 42, 0.48);
}

.ai-analysis {
  position: fixed;
  right: 12px;
  bottom: 78px;
  z-index: 1700;
  display: grid;
  justify-items: end;
  gap: 10px;
  pointer-events: none;
  transition: opacity 0.16s ease, transform 0.16s ease;
}

.ai-analysis-toggle,
.ai-analysis-panel {
  pointer-events: auto;
}

.ai-analysis-toggle {
  display: inline-grid;
  place-items: center;
  width: 46px;
  height: 46px;
  min-height: 46px;
  padding: 6px;
  border: 1px solid rgba(20, 84, 52, 0.28);
  border-radius: 999px;
  background: linear-gradient(135deg, #0f4d2a 0%, #145c3d 58%, #1f7048 100%);
  color: #ffffff;
  box-shadow: 0 12px 32px rgba(11, 42, 24, 0.26), inset 0 1px 0 rgba(255,255,255,0.16);
  font: inherit;
  font-size: 13px;
  font-weight: 800;
  cursor: pointer;
  transition: transform 0.16s ease, box-shadow 0.16s ease, border-color 0.16s ease;
}

.ai-analysis-toggle:hover {
  border-color: rgba(246, 204, 92, 0.75);
  box-shadow: 0 14px 38px rgba(11, 42, 24, 0.32), inset 0 1px 0 rgba(255,255,255,0.2);
  transform: translateY(-1px);
}

.ai-analysis-toggle:active {
  transform: translateY(1px) scale(0.99);
}

.ai-analysis-toggle:focus-visible,
.ai-analysis-close:focus-visible,
.ai-analysis-refresh:focus-visible {
  outline: 2px solid #ffffff;
  outline-offset: 2px;
}

.ai-analysis-toggle-mark,
.ai-analysis-avatar {
  display: inline-grid;
  place-items: center;
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  background: #f9fff4;
  color: #0f4d2a;
  box-shadow: inset 0 0 0 1px rgba(15, 77, 42, 0.12), 0 0 0 3px rgba(255,255,255,0.08);
}

.ai-analysis-icon {
  width: 24px;
  height: 24px;
  display: block;
}

.ai-analysis-avatar {
  width: 34px;
  height: 34px;
  background: #eef8e8;
  box-shadow: inset 0 0 0 1px #c9ddbf;
}

.ai-analysis-avatar .ai-analysis-icon {
  width: 25px;
  height: 25px;
}

.ai-analysis-panel {
  width: min(390px, calc(100vw - 36px));
  max-height: min(560px, calc(100dvh - 96px));
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid rgba(205, 216, 198, 0.95);
  border-radius: 10px;
  background: #ffffff;
  color: #18251c;
  box-shadow: 0 24px 70px rgba(12, 23, 15, 0.26);
}

.ai-analysis-panel[hidden] {
  display: none;
}

.ai-analysis-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 12px 13px;
  border-bottom: 1px solid #dce6d6;
  background: #f7faf5;
}

.ai-analysis-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.ai-analysis-title {
  margin: 0;
  color: #17251b;
  font-size: 15px;
  line-height: 1.2;
}

.ai-analysis-status {
  margin: 2px 0 0;
  color: #667462;
  font-size: 11.5px;
  line-height: 1.3;
}

.ai-analysis-close {
  width: 32px;
  height: 32px;
  flex: 0 0 auto;
  border: 1px solid #cbd8c4;
  border-radius: 8px;
  background: #ffffff;
  color: #2f4431;
  font-size: 21px;
  line-height: 1;
  cursor: pointer;
}

.ai-analysis-body {
  min-height: 120px;
  overflow: auto;
  padding: 14px 15px;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: rgba(15, 77, 42, 0.25) transparent;
}

.ai-analysis-body p {
  margin: 0 0 10px;
  color: #253528;
  font-size: 13px;
  line-height: 1.55;
}

.ai-analysis-body p:last-child {
  margin-bottom: 0;
}

.ai-analysis-body[data-state="empty"] p,
.ai-analysis-body[data-state="ready"] p:first-child {
  color: #4f5f4d;
}

.ai-analysis-body[data-state="error"] p {
  color: var(--err-text);
}

.ai-analysis-loading {
  width: 34px;
  height: 34px;
  margin: 34px auto;
  border: 3px solid #dce8d6;
  border-top-color: #0f4d2a;
  border-radius: 999px;
  animation: ai-analysis-spin 0.8s linear infinite;
}

@keyframes ai-analysis-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .ai-analysis-toggle,
  .ai-analysis-loading {
    transition: none;
    animation: none;
  }
}

.ai-analysis-footer {
  display: flex;
  justify-content: flex-end;
  padding: 10px 13px 12px;
  border-top: 1px solid #edf2e9;
  background: #fbfdf9;
}

.ai-analysis-refresh {
  min-height: 34px;
  padding: 7px 12px;
  border: 1px solid #cbd8c4;
  border-radius: 8px;
  background: #f7faf4;
  color: #0f4d2a;
  font: inherit;
  font-size: 12px;
  font-weight: 800;
  cursor: pointer;
}

.ai-analysis-refresh:hover:not(:disabled) {
  background: #edf5e8;
}

.ai-analysis-refresh:disabled {
  cursor: default;
  opacity: 0.55;
}

.analysis-modal {
  position: fixed;
  inset: 0;
  z-index: 3100;
  display: grid;
  place-items: center;
  padding: 18px;
}

.analysis-modal[hidden] {
  display: none;
}

.analysis-backdrop {
  position: absolute;
  inset: 0;
  border: 0;
  background: rgba(15, 30, 20, 0.42);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
}

.analysis-card {
  position: relative;
  z-index: 1;
  width: min(940px, calc(100vw - 36px));
  max-height: min(780px, calc(100dvh - 36px));
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: #f7faf5;
  border: 1px solid rgba(205, 216, 198, 0.95);
  border-radius: 8px;
  box-shadow: 0 24px 80px rgba(12, 23, 15, 0.28);
}

.analysis-modal.is-loading .analysis-card {
  width: min(460px, calc(100vw - 36px));
}

.analysis-header {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 18px 13px;
  border-bottom: 1px solid #dce6d6;
  background: #ffffff;
}

.analysis-title {
  margin: 0;
  color: #18251c;
  font-size: 18px;
  line-height: 1.2;
}

.analysis-subtitle {
  margin: 5px 0 0;
  color: #5f6c5c;
  font-size: 12.5px;
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
}

.analysis-subtitle:empty {
  display: none;
}

.analysis-close {
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  border: 1px solid #cbd8c4;
  border-radius: 8px;
  background: #f7faf4;
  color: #2f4431;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}

.analysis-close:hover {
  background: #edf5e8;
}

.analysis-close:focus-visible,
#analysis-csv-btn:focus-visible {
  outline: 2px solid #0f4d2a;
  outline-offset: 2px;
}

.analysis-status {
  min-height: 18px;
  padding: 10px 20px 0;
  color: #455444;
  font-size: 13px;
}

.analysis-status:empty {
  display: none;
}

.analysis-status.is-error {
  color: var(--err-text);
}

.analysis-content {
  overflow: auto;
  padding: 16px 18px 18px;
  overscroll-behavior: contain;
}

.analysis-content[hidden] {
  display: none;
}

.analysis-summary {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 12px;
}

.analysis-summary-card {
  min-width: 0;
  padding: 10px 11px;
  border: 1px solid #dce5d7;
  border-left: 4px solid #9ca89a;
  border-radius: 8px;
  background: #ffffff;
}

.analysis-summary-card.is-normal {
  border-left-color: #177245;
}

.analysis-summary-card.is-watch {
  border-left-color: #c28a09;
}

.analysis-summary-card.is-stress {
  border-left-color: #c24124;
}

.analysis-summary-card.is-neutral {
  border-left-color: #6f7d6b;
}

.analysis-summary-label {
  display: block;
  color: #657462;
  font-size: 11px;
  line-height: 1.3;
}

.analysis-summary-value {
  display: block;
  margin-top: 4px;
  color: #18251c;
  font-size: 17px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.analysis-chart-wrap {
  border: 1px solid #dce5d7;
  border-radius: 8px;
  background: #ffffff;
  overflow: hidden;
}

.analysis-chart {
  display: block;
  width: 100%;
  height: auto;
  min-height: 400px;
}

.analysis-table-wrap {
  margin-top: 12px;
  max-height: 260px;
  overflow: auto;
  border: 1px solid #dce5d7;
  border-radius: 8px;
  background: #ffffff;
}

.analysis-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 11.5px;
}

.analysis-table th,
.analysis-table td {
  padding: 8px 9px;
  border-bottom: 1px solid #edf2e9;
  text-align: left;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.analysis-table th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: #f4f7f1;
  color: #43533f;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.35px;
}

.analysis-table tr:last-child td {
  border-bottom: 0;
}

.analysis-signal {
  display: inline-flex;
  align-items: center;
  min-height: 22px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
}

.analysis-metric-pill {
  display: inline-flex;
  justify-content: center;
  min-width: 44px;
  padding: 2px 7px;
  border-radius: 999px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.analysis-metric-pill.is-normal {
  background: #e8f3e4;
  color: #16603a;
}

.analysis-metric-pill.is-watch {
  background: #fff4c7;
  color: #6d5100;
}

.analysis-metric-pill.is-stress {
  background: #fde8e2;
  color: #8a2c18;
}

.analysis-metric-pill.is-neutral {
  background: #eef2ea;
  color: #52604f;
}

.analysis-signal.is-normal {
  background: #e7f2df;
  color: #0f4d2a;
}

.analysis-signal.is-watch {
  background: #fff2cc;
  color: #6a4a00;
}

.analysis-signal.is-stress {
  background: #fde4dc;
  color: #8a2c18;
}

.analysis-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 14px;
}

.analysis-actions .secondary-btn {
  margin-top: 0;
}

body.analysis-modal-open {
  overflow: hidden;
}

.panel--map {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 400px;
}

#map {
  position: absolute;
  inset: 0;
  /* Belt-and-suspenders: Leaflet already sets `touch-action: none` on
     .leaflet-container, but some mobile chromium derivatives still
     propagate the first downward drag to the document's overscroll
     behaviour before Leaflet's handler claims it. `contain` locks the
     scroll chain at the map boundary so pull-to-refresh never fires,
     even on that first pre-claim frame. */
  overscroll-behavior: contain;
}

/* The globe is a progressive-enhancement renderer. One compressed background
   layer adds depth without another canvas, WebGL context or JavaScript timer.
   Its transform-only drift is deliberately slow, pauses outside globe mode,
   and is disabled for people who request reduced motion. */
.panel--map > .globe-map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 2;
  overflow: hidden;
  background-color: #01040c;
  overscroll-behavior: contain;
  touch-action: none;
}

.panel--map::before {
  content: "";
  position: absolute;
  inset: -4%;
  z-index: 3;
  pointer-events: none;
  background-image:
    radial-gradient(ellipse at center, rgba(1, 4, 12, 0.02) 25%, rgba(1, 4, 12, 0.34) 100%),
    url("/sat/assets/deep-space-v2.webp");
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  mix-blend-mode: screen;
  opacity: 0.82;
  transform: translate3d(-0.45%, -0.3%, 0) scale(1.04);
  animation: smartmap-space-drift 54s ease-in-out infinite alternate;
}

.panel--map:not(.is-globe-mode)::before {
  animation-play-state: paused;
  visibility: hidden;
}

@keyframes smartmap-space-drift {
  to { transform: translate3d(0.55%, 0.35%, 0) scale(1.065); }
}

@media (max-width: 600px) {
  .panel--map > .globe-map {
    background-color: #01040c;
  }

  .panel--map::before {
    background-image:
      radial-gradient(ellipse at center, rgba(1, 4, 12, 0.02) 20%, rgba(1, 4, 12, 0.32) 100%),
      url("/sat/assets/deep-space-mobile-v2.webp");
  }
}

@media (prefers-reduced-motion: reduce) {
  .panel--map::before {
    animation: none;
    transform: scale(1.04);
  }
}

.panel--map > .globe-map[hidden] { display: none; }

.globe-data-overlay {
  position: absolute;
  inset: 0;
  z-index: 4;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.globe-data-overlay[hidden] { display: none; }

/* MapLibre's globe draping can place GeoJSON lines below a raster surface on
   some GPU/driver combinations. This lightweight projected SVG mirror keeps
   the field outline and edit handles crisp above every satellite tile while
   MapLibre remains the authoritative camera and coordinate transformer. */
.globe-selection-overlay {
  position: absolute;
  inset: 0;
  z-index: 5;
  width: 100%;
  height: 100%;
  overflow: hidden;
  pointer-events: none;
}

.globe-selection-overlay[hidden] { display: none; }

.globe-selection-fill {
  fill: rgba(110, 205, 91, 0.22);
  stroke: none;
}

.globe-selection-halo,
.globe-selection-line {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.globe-selection-halo {
  stroke: rgba(2, 14, 8, 0.78);
  stroke-width: 7;
}

.globe-selection-line {
  stroke: #efffe9;
  stroke-width: 3;
}

.globe-selection-guide {
  fill: none;
  stroke: rgba(239, 255, 233, 0.92);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-dasharray: 2 11;
  vector-effect: non-scaling-stroke;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.7));
}

.globe-selection-vertex {
  fill: #0f4d2a;
  stroke: #ffffff;
  stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.72));
}

.globe-selection-vertex.is-polygon-close-target {
  fill: #efffe9;
  stroke: #0f4d2a;
  stroke-width: 2.5;
  filter: drop-shadow(0 0 3px rgba(239, 255, 233, 0.9)) drop-shadow(0 1px 2px rgba(0, 0, 0, 0.72));
}

.panel--map.is-globe-mode #map {
  visibility: hidden;
  pointer-events: none;
}

.globe-map .maplibregl-canvas:focus-visible {
  outline: 3px solid #bfe6c4;
  outline-offset: -4px;
}

.globe-map.is-drawing .maplibregl-canvas { cursor: crosshair; }

.map-workspace-tools {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 1100;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.map-tool-group {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid #c4d0bf;
  border-radius: 10px;
  background: #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.22);
}

.map-tool-group[hidden] { display: none; }

.map-tool-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: none;
  border-bottom: 1px solid #eef2ea;
  background: #fff;
  color: #2f4431;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.map-tool-btn:last-child { border-bottom: none; }

.map-tool-btn[aria-pressed="true"] {
  background: #0f4d2a;
  color: #fff;
}

.map-tool-btn:disabled {
  background: #f5f7f3;
  color: #a9b6a6;
  cursor: not-allowed;
}

@media (hover: hover) {
  .map-tool-btn:hover:not(:disabled):not([aria-pressed="true"]) {
    background: #f0f6ed;
    color: #0f4d2a;
  }
}

.map-tool-btn:focus-visible {
  outline: 2px solid #0f4d2a;
  outline-offset: -2px;
  z-index: 1;
}

.legend {
  position: absolute;
  bottom: var(--map-hud-upper-lane);
  left: var(--map-hud-edge);
  z-index: 400;
  background: rgba(255,255,255,0.96);
  padding: 10px 12px;
  border-radius: 10px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.12);
  font-size: 11px;
  min-width: 180px;
}

.legend-title {
  font-weight: 700;
  color: #0f4d2a;
  margin-bottom: 6px;
}

.legend-gradient {
  height: 10px;
  border-radius: 4px;
  margin-bottom: 4px;
}

.legend-ticks {
  display: flex;
  justify-content: space-between;
  color: #4a6048;
  font-variant-numeric: tabular-nums;
}

/* ---- Inline GPS button inside the search-box ------------------------- */
/* Visible on all breakpoints, invaluable on mobile where drawing a precise
   rectangle with a finger is painful. One tap → center + auto-select a
   500m × 500m square at the user's location. */
.gps-btn {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid #c4d0bf;
  border-radius: 8px;
  background: #fafcf8;
  color: #2f4431;
  cursor: pointer;
  /* inline-flex + align/justify is robust across Safari/Chrome/Firefox
     and immune to inherited text-align from parents. grid+place-items has
     an older-Safari quirk on buttons where the SVG anchors to one edge. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 0;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
  -webkit-tap-highlight-color: transparent;
}

.gps-btn svg {
  display: block;
  flex: none;
}

.gps-btn:hover { background: #f0f6ed; border-color: #0f4d2a; color: #0f4d2a; }
.gps-btn:active { background: #e2ecdc; }
.gps-btn:focus-visible { outline: 2px solid #0f4d2a; outline-offset: 2px; }
/* Busy: the whole SVG spins around its concentric center dot — reads as
   "locating…" better than fading the glyph and works at any size. */
.gps-btn[data-state="busy"] { cursor: progress; color: #0f4d2a; }
.gps-btn[data-state="busy"] svg { animation: gps-spin 1s linear infinite; transform-origin: 50% 50%; }
.gps-btn[data-state="error"] {
  border-color: var(--err-border);
  color: var(--err-text);
  background: var(--err-bg);
}

@keyframes gps-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}


/* ---- Compact layout: modal data workflow ----------------------------- */
@media (max-width: 760px), (max-height: 500px) {
  .topbar {
    gap: 10px;
    padding: 10px 14px;
  }

  .top-actions { gap: 10px; }
  .back-link { width: 40px; height: 40px; }
  .lang-btn { min-height: 34px; padding: 5px 9px; }

  .layout {
    position: relative;
    overflow: hidden;
  }

  .panel--map {
    width: 100%;
    height: 100%;
    min-height: 0;
  }

  .data-dialog {
    position: fixed;
    inset: auto 8px 8px;
    width: auto;
    max-height: calc(100dvh - 72px);
    margin: 0;
  }

  .data-dialog-card {
    max-height: calc(100dvh - 72px);
    border-radius: 20px;
  }

  .data-dialog-header {
    padding: 15px 16px 13px;
  }

  .data-dialog-title {
    font-size: 18px;
  }

  .data-dialog-subtitle {
    font-size: 12px;
  }

  .panel--controls {
    padding: 14px 14px 18px;
  }

  .data-draw-btn {
    min-height: 44px;
  }

  .layer-chips { gap: 8px; }
  .layer-chip { padding: 12px 8px; }

  .date-row input,
  .cloud-row input { padding: 10px; font-size: 14px; }
  .cloud-row input { max-width: 100%; }
  .search-box input { padding: 11px 12px; font-size: 14px; }
  .gps-btn { width: 42px; height: 42px; }

  .timeline-panel {
    padding: 11px 12px;
  }

  .scene-slider {
    min-height: 32px;
  }

  .panel--map .leaflet-bottom.leaflet-right,
  .globe-map .maplibregl-ctrl-bottom-right {
    right: 8px;
    bottom: 8px;
    max-width: calc(100vw - 16px);
  }

  .leaflet-control-attribution,
  .globe-map .maplibregl-ctrl-attrib {
    max-width: calc(100vw - 16px);
    font-size: 9.5px !important;
  }

  .data-workflow {
    right: 66px;
    bottom: 52px;
    max-width: calc(100vw - 78px);
  }

  .ai-analysis {
    right: 12px;
    bottom: 52px;
    max-width: calc(100vw - 24px);
  }

  .ai-analysis-toggle {
    width: 46px;
    height: 46px;
    min-height: 44px;
    padding: 6px;
  }

  .ai-analysis-panel {
    width: min(360px, calc(100vw - 24px));
    max-height: min(440px, calc(100dvh - 120px));
  }

  .analysis-modal {
    align-items: end;
    padding: 0;
  }

  .analysis-card {
    width: 100%;
    max-height: calc(100dvh - 22px);
    border-radius: 14px 14px 0 0;
  }

  .analysis-modal.is-loading .analysis-card {
    width: min(420px, 100%);
  }

  .analysis-header {
    padding: 16px 16px 12px;
  }

  .analysis-content {
    padding: 12px 16px 18px;
  }

  .analysis-summary {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .analysis-chart {
    min-height: 360px;
  }

  .analysis-table th,
  .analysis-table td {
    padding: 8px;
  }
}



@media (max-width: 340px) {
  .brand-caption { display: none; }
}

/* ---- Service worker update banner ----------------------------------------
   Shown only inside an installed PWA when a newer worker is waiting while
   the current app still runs the previous build in memory. It belongs to the
   map panel's top-center lane, away from attribution, imagery legends and the
   persistent insight action. */
.update-banner {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1800;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px 10px 16px;
  background: #0f4d2a;
  color: #fff;
  border-radius: 999px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.28);
  font-size: 13px;
  font-weight: 500;
  max-width: calc(100% - 24px);
  animation: update-banner-in 0.22s ease-out;
}

.update-banner > span { white-space: nowrap; }

@media (max-width: 900px), (max-height: 500px) {
  html.has-sat-update .map-mode-switch,
  html.has-sat-update .map-workspace-tools {
    top: 76px;
  }
}

@keyframes update-banner-in {
  from { opacity: 0; transform: translate(-50%, 12px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

.update-banner-btn {
  appearance: none;
  border: none;
  background: #fff;
  color: #0f4d2a;
  font: inherit;
  font-weight: 700;
  padding: 6px 14px;
  border-radius: 999px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 0.14s ease;
}

.update-banner-btn:hover { background: #e9f5ee; }
.update-banner-btn:active { background: #dbe9d4; }
.update-banner-btn:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* ---- PWA standalone safe-area insets ----------------------------------
   env(safe-area-inset-*) is ONLY honored when the app is running in
   installed-PWA standalone/fullscreen mode. Regular browsers (Chrome,
   Safari, Firefox, Edge) do NOT need our layout to respect device
   insets — their own chrome already covers the device's unsafe zones.

   Quirky chromium derivatives (Hola, Yandex, UC, some Samsung Internet
   builds) report non-zero env() values in regular browser mode because
   they treat their own custom toolbar as "unsafe". Without this scoping
   the topbar balloons to 80+ px, Leaflet controls slide down, the
   legend shifts inward, and the sheet grows a huge bottom pad.

   By putting every env() consumer behind display-mode:standalone we
   keep the PWA experience pixel-correct on iOS home-screen installs
   and Android TWA/installed-PWAs, while every browser tab renders
   with the pristine fixed baselines above. */
@media (display-mode: standalone), (display-mode: fullscreen), (display-mode: minimal-ui) {
  .topbar {
    padding: max(14px, env(safe-area-inset-top, 0px))
             max(20px, env(safe-area-inset-right, 0px))
             14px
             max(20px, env(safe-area-inset-left, 0px));
  }
}

@media (display-mode: standalone) and (max-width: 760px),
       (display-mode: fullscreen) and (max-width: 760px),
       (display-mode: minimal-ui) and (max-width: 760px) {
  .map-mode-switch {
    top: max(12px, env(safe-area-inset-top, 0px));
    left: max(12px, env(safe-area-inset-left, 0px));
  }

  .map-workspace-tools {
    top: max(12px, env(safe-area-inset-top, 0px));
    right: max(12px, env(safe-area-inset-right, 0px));
  }

  .panel--controls {
    padding-bottom: max(18px, env(safe-area-inset-bottom, 0px));
  }

  .data-dialog {
    right: max(8px, env(safe-area-inset-right, 0px));
    bottom: max(8px, env(safe-area-inset-bottom, 0px));
    left: max(8px, env(safe-area-inset-left, 0px));
  }

  .legend {
    left: max(12px, env(safe-area-inset-left, 0px));
  }

  .ai-analysis {
    right: max(12px, env(safe-area-inset-right, 0px));
  }

  .data-workflow {
    right: max(66px, calc(env(safe-area-inset-right, 0px) + 54px));
  }
}
