:root {
  --ink: #1e2442;
  --ink-rgb: 30, 36, 66;
  --muted: #6f789c;
  --content-max-width: 1060px;
  --layout-gap: 20px;
  --panel: linear-gradient(180deg, rgba(255, 255, 255, 0.94) 0%, rgba(239, 244, 255, 0.84) 100%);
  --panel-muted: linear-gradient(180deg, rgba(241, 245, 255, 0.92) 0%, rgba(232, 238, 255, 0.84) 100%);
  --stroke: rgba(72, 84, 141, 0.14);
  --accent: #5c68f6;
  --accent-deep: #3947ac;
  --sun: #8e79f6;
  --coral: #d95c84;
  --olive: #5ea496;
  --shadow: 0 22px 54px rgba(33, 42, 83, 0.16);
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  --page-background:
    radial-gradient(1180px 860px at 8% 10%, rgba(186, 168, 255, 0.52) 0%, rgba(186, 168, 255, 0) 60%),
    radial-gradient(980px 760px at 92% 10%, rgba(170, 201, 255, 0.58) 0%, rgba(170, 201, 255, 0) 58%),
    linear-gradient(180deg, #eef2ff 0%, #e6ebff 54%, #e2e8fb 100%);
}

* {
  box-sizing: border-box;
}

html {
  background: var(--page-background);
  background-color: #e7ecff;
  overflow-y: scroll;
  scrollbar-gutter: stable;
  overscroll-behavior-y: none;
  scrollbar-width: thin;
  scrollbar-color: rgba(92, 104, 246, 0.38) rgba(255, 255, 255, 0.18);
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100svh;
  font-family: "Inter", "Segoe UI", "Trebuchet MS", sans-serif;
  color: var(--ink);
  -webkit-tap-highlight-color: transparent;
}

html::-webkit-scrollbar {
  width: 12px;
}

html::-webkit-scrollbar-track {
  background: rgba(255, 255, 255, 0.16);
}

html::-webkit-scrollbar-thumb {
  background: rgba(92, 104, 246, 0.34);
  border: 3px solid transparent;
  border-radius: 999px;
  background-clip: content-box;
}

html::-webkit-scrollbar-thumb:hover {
  background: rgba(92, 104, 246, 0.46);
  border: 3px solid transparent;
  background-clip: content-box;
}

html::-webkit-scrollbar-corner {
  background: transparent;
}

.shell {
  max-width: 1240px;
  margin: 0 auto;
  padding:
    calc(40px + var(--safe-top))
    calc(24px + var(--safe-right))
    calc(72px + var(--safe-bottom))
    calc(24px + var(--safe-left));
  position: relative;
}

p {
  margin: 0;
  color: var(--muted);
  max-width: 700px;
  line-height: 1.6;
}

.status {
  padding: 10px 14px;
  border-radius: 12px;
  border: 1px solid var(--stroke);
  background: rgba(255, 255, 255, 0.74);
  font-size: 0.88rem;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 10px;
  box-shadow: 0 8px 20px rgba(33, 42, 83, 0.06);
  transition: background 0.3s ease, border-color 0.3s ease, color 0.3s ease;
}

.status::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  background: rgba(var(--ink-rgb), 0.36);
  transition: background 0.3s ease;
}

.status[data-tone="pending"] {
  background: rgba(142, 121, 246, 0.14);
  color: #5642af;
  border-color: rgba(142, 121, 246, 0.28);
}

.status[data-tone="pending"]::before {
  background: var(--sun);
  animation: pulse 1.4s ease-in-out infinite;
}

.status[data-tone="success"] {
  background: rgba(94, 164, 150, 0.14);
  color: #2f6d63;
  border-color: rgba(94, 164, 150, 0.28);
}

.status[data-tone="success"]::before {
  background: var(--olive);
}

.status[data-tone="error"] {
  background: rgba(217, 92, 132, 0.14);
  color: #873352;
  border-color: rgba(217, 92, 132, 0.28);
}

.status[data-tone="error"]::before {
  background: var(--coral);
}

.status.is-hidden {
  display: none;
}

.panel-status {
  margin-top: 14px;
}

.layout {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas:
    "map"
    "data"
    "chart";
  gap: var(--layout-gap);
  align-items: stretch;
}

.panel {
  position: relative;
  overflow: hidden;
  background: var(--panel);
  border-radius: 24px;
  padding: 24px;
  border: 1px solid var(--stroke);
  box-shadow: var(--shadow);
  animation: liftIn 0.75s ease both;
  animation-delay: var(--delay, 0s);
}

.panel::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: linear-gradient(90deg, rgba(92, 104, 246, 0.54), rgba(185, 200, 255, 0.34), rgba(185, 200, 255, 0));
  pointer-events: none;
}

.panel--location {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, rgba(237, 243, 255, 0.88) 100%);
  border: 1px solid rgba(92, 104, 246, 0.1);
  box-shadow:
    0 22px 54px rgba(33, 42, 83, 0.14),
    inset 0 1px 0 rgba(255, 255, 255, 0.9);
}

.panel--location::before {
  height: 3px;
  background: linear-gradient(90deg, rgba(92, 104, 246, 0.6), rgba(142, 121, 246, 0.4), rgba(185, 200, 255, 0.2), rgba(185, 200, 255, 0));
}

#panel-map {
  grid-area: map;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  gap: 18px;
  width: min(100%, var(--content-max-width));
  justify-self: center;
  min-height: clamp(400px, 52vh, 560px);
}

#panel-data {
  grid-area: data;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  gap: 18px;
  width: min(100%, var(--content-max-width));
  justify-self: center;
}

#panel-chart {
  grid-area: chart;
  width: min(100%, var(--content-max-width));
  justify-self: center;
}

#panel-map .panel-header {
  justify-items: center;
  text-align: center;
}

.panel-header {
  display: grid;
  gap: 4px;
}

.panel-title {
  margin: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  width: fit-content;
  max-width: 100%;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid rgba(92, 104, 246, 0.18);
  background: rgba(92, 104, 246, 0.08);
  color: var(--accent-deep);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
  transition: background 0.25s ease, border-color 0.25s ease;
}

.panel-title:hover {
  background: rgba(92, 104, 246, 0.12);
  border-color: rgba(92, 104, 246, 0.24);
}

/* Legacy `.panel-body`, `.panel-body--map`, `.map-card`, `.map-search-bar*`,
   `.map-search-icon` rules removed 2026-04-20 — the new floating search
   (`.cm-map-search`) lives in the .cm-* block and owns its own styling. */

.search-spinner {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid rgba(92, 104, 246, 0.15);
  border-top-color: var(--accent);
  animation: overlaySpinnerRotate 0.7s linear infinite;
  flex-shrink: 0;
}

/* ── Search dropdown ── */

.search-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 900;
  display: grid;
  gap: 2px;
  padding: 6px;
  margin-top: 2px;
  border-radius: 14px;
  border: 1px solid rgba(72, 84, 141, 0.1);
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(20px) saturate(1.3);
  -webkit-backdrop-filter: blur(20px) saturate(1.3);
  box-shadow:
    0 12px 40px rgba(30, 36, 66, 0.16),
    inset 0 1px 0 rgba(255, 255, 255, 0.8);
  max-height: 260px;
  overflow-y: auto;
  animation: dropdownSlideIn 0.2s ease both;
}

@keyframes dropdownSlideIn {
  from {
    opacity: 0;
    transform: translateY(-4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.search-dropdown-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid transparent !important;
  background: transparent !important;
  color: var(--ink);
  font-size: 0.86rem;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
  box-shadow: none !important;
}

.search-dropdown-item:hover {
  background: rgba(92, 104, 246, 0.06) !important;
  border-color: rgba(92, 104, 246, 0.1) !important;
}

.search-dropdown-item:active {
  background: rgba(92, 104, 246, 0.1) !important;
}

.search-result-icon {
  flex-shrink: 0;
  color: var(--accent);
  opacity: 0.5;
}

.search-result-text {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.search-result-primary {
  font-weight: 600;
  font-size: 0.86rem;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.search-result-secondary {
  font-weight: 400;
  font-size: 0.76rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.map {
  height: 100%;
  min-height: clamp(300px, 40vh, 440px);
  border-radius: 0 0 16px 16px;
  overflow: hidden;
  border: 1px solid var(--stroke);
  border-top: none;
}

.section-card {
  display: grid;
  gap: 14px;
  padding: 18px;
  border-radius: 18px;
  border: 1px solid rgba(27, 43, 50, 0.08);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, rgba(241, 245, 255, 0.9) 100%);
  box-shadow:
    0 16px 30px rgba(33, 42, 83, 0.08),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
  transition: box-shadow 0.3s ease, border-color 0.3s ease;
}

.section-card:hover {
  border-color: rgba(92, 104, 246, 0.14);
  box-shadow:
    0 20px 40px rgba(33, 42, 83, 0.1),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
}

.section-card--date {
  align-content: start;
}

/* ── Section card label ── */

.section-card-label {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  padding-bottom: 4px;
  border-bottom: 1px solid rgba(72, 84, 141, 0.06);
}

.section-card-label svg {
  opacity: 0.8;
  flex-shrink: 0;
}

.form-grid--vertical {
  grid-template-columns: 1fr;
}

.leaflet-control-attribution {
  display: none !important;
}

/* Legacy `.coords-bar`, `.coords-field`, `.coords-label`, `.coords-sep`,
   `.coords-input-group`, `.coords-step-btn` rules removed 2026-04-20.
   Current coords UI uses `.cm-coords-bar > .cm-coords-cell` (input-only,
   no stepper buttons) defined in the new .cm-* block. */

.search-dropdown-message {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 14px;
  font-size: 0.86rem;
  color: var(--muted);
  text-align: left;
  line-height: 1.4;
}

.search-dropdown--error .search-dropdown-message {
  color: #b14545;
}

.search-dropdown--searching .search-dropdown-message {
  color: var(--accent-deep);
  opacity: 0.8;
}

.map-search-bar.is-searching .map-search-icon {
  opacity: 1;
  color: var(--accent);
  animation: searchPulse 1s ease-in-out infinite;
}

@keyframes searchPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

label {
  display: grid;
  gap: 6px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--muted);
}

button,
input,
select {
  touch-action: manipulation;
}

input:not([type="checkbox"]):not([type="radio"]),
select {
  width: 100%;
  min-height: 44px;
  padding: 10px 14px;
  border-radius: 12px;
  border: 1px solid rgba(27, 43, 50, 0.16);
  background: rgba(255, 255, 255, 0.96);
  font-size: 0.95rem;
  color: var(--ink);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.65);
  transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
}

.field-stack {
  gap: 8px;
}

.field-label {
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: 0.01em;
}

input:not([type="checkbox"]):not([type="radio"]):hover,
select:hover {
  border-color: rgba(27, 43, 50, 0.24);
}

input:not([type="checkbox"]):not([type="radio"]):focus,
select:focus {
  outline: none;
  border-color: rgba(92, 104, 246, 0.48);
  box-shadow: 0 0 0 4px rgba(92, 104, 246, 0.12);
  background: #fff;
}

input:not([type="checkbox"]):not([type="radio"]):disabled,
select:disabled {
  cursor: not-allowed;
  color: rgba(27, 43, 50, 0.48);
  background: rgba(244, 247, 247, 0.92);
  border-color: rgba(27, 43, 50, 0.1);
  box-shadow: none;
}

select {
  appearance: none;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position:
    calc(100% - 20px) calc(50% - 3px),
    calc(100% - 14px) calc(50% - 3px);
  background-repeat: no-repeat;
  background-size: 6px 6px, 6px 6px;
}

/* Legacy `.input-field`, `.input-unit`, `.gdd-field .input-field input`,
   `.form-grid`, `.date-range-group`, `.date-range-connector`, `.period-gdd-group`
   rules removed 2026-04-20 — all dead after the sat-style form refactor. */

.date-field input[type="date"] {
  text-align: left;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
}

.chip-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

button.chip-action {
  width: auto;
  min-height: 0;
  padding: 9px 14px;
  border-radius: 999px;
  border: 1px solid rgba(72, 84, 141, 0.14);
  background: rgba(243, 246, 255, 0.96);
  color: var(--ink);
  font-weight: 700;
  font-size: 0.79rem;
  box-shadow: none;
}

button.chip-action:hover {
  border-color: rgba(92, 104, 246, 0.24);
  background: rgba(237, 241, 255, 1);
  box-shadow: none;
}

.chips {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 8px;
  max-height: clamp(260px, 38vh, 400px);
  overflow-y: auto;
  padding-right: 4px;
  scrollbar-width: thin;
  scrollbar-color: rgba(92, 104, 246, 0.26) transparent;
}

.chips::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.chips::-webkit-scrollbar-thumb {
  background: rgba(92, 104, 246, 0.26);
  border-radius: 999px;
}

.chips::-webkit-scrollbar-track {
  background: transparent;
}

.chip {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 12px;
  border: 1px solid rgba(27, 43, 50, 0.1);
  background: rgba(255, 255, 255, 0.88);
  color: var(--ink);
  font-size: 0.84rem;
  line-height: 1.4;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}

.chip span {
  flex: 1;
  min-width: 0;
}

.chip:hover {
  border-color: rgba(27, 43, 50, 0.2);
  background: rgba(255, 255, 255, 0.96);
  transform: translateY(-1px);
}

.chip:has(input:checked),
.chip.is-checked {
  border-color: rgba(92, 104, 246, 0.28);
  background: linear-gradient(180deg, rgba(242, 244, 255, 0.98) 0%, rgba(234, 239, 255, 0.94) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.85), 0 12px 22px rgba(66, 79, 154, 0.1);
}

.chip:has(input:checked):hover,
.chip.is-checked:hover {
  border-color: rgba(92, 104, 246, 0.4);
  background: linear-gradient(180deg, rgba(244, 246, 255, 1) 0%, rgba(237, 241, 255, 0.98) 100%);
}

.chip input {
  appearance: none;
  width: 18px;
  height: 18px;
  margin: 0;
  display: inline-grid;
  place-items: center;
  flex-shrink: 0;
  border-radius: 6px;
  border: 1.5px solid rgba(27, 43, 50, 0.2);
  background: rgba(255, 255, 255, 0.98);
  cursor: pointer;
  transition: border-color 0.18s ease, background 0.18s ease, box-shadow 0.18s ease, transform 0.18s ease;
}

.chip input::after {
  content: "";
  width: 10px;
  height: 6px;
  border-left: 3px solid #fff;
  border-bottom: 3px solid #fff;
  transform: translateY(-1px) rotate(-45deg) scale(0);
  transform-origin: center;
  transition: transform 0.16s ease;
}

.chip input:hover {
  border-color: rgba(92, 104, 246, 0.36);
}

.chip input:focus-visible {
  outline: none;
  box-shadow: 0 0 0 4px rgba(92, 104, 246, 0.12);
}

.chip input:checked {
  border-color: var(--accent);
  background: var(--accent);
}

.chip input:checked::after {
  transform: translateY(-1px) rotate(-45deg) scale(1);
}

.is-hidden {
  display: none !important;
}

.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* Primary button styling — applies to Fetch Data and other form CTAs.
   The blacklist excludes anything that already has its own visual identity:
   the pill toggles, the sidebar/sheet chevrons, the map-chrome icon buttons,
   the coord steppers, the GPS button, and the dialog close "×". If this
   catch-all paints a button it shouldn't, add the class here — don't
   !important-fight it downstream. */
button:not(.chip-action):not(.button-secondary):not(.coords-step-btn):not(.utility-action):not(.install-guide__close):not(.cm-panel-toggle):not(.sheet-handle):not(.cm-gps-btn):not(.cm-basemap-btn):not(.cm-coord-step) {
  margin: 0;
  width: 100%;
  min-height: 44px;
  padding: 12px 16px;
  border-radius: 14px;
  border: 1px solid transparent;
  background: linear-gradient(135deg, #5e6df6, #404eb6 88%);
  color: #fff;
  font-weight: 700;
  letter-spacing: 0.02em;
  font-size: 0.96rem;
  cursor: pointer;
  box-shadow: 0 16px 28px rgba(66, 79, 154, 0.22);
  transition: transform 0.2s ease, box-shadow 0.2s ease, filter 0.2s ease, border-color 0.2s ease;
}

button:not(.chip-action):not(.button-secondary):not(.coords-step-btn):not(.utility-action):not(.install-guide__close):not(.cm-panel-toggle):not(.sheet-handle):not(.cm-gps-btn):not(.cm-basemap-btn):not(.cm-coord-step):hover {
  transform: translateY(-1px);
  box-shadow: 0 20px 34px rgba(66, 79, 154, 0.28);
  filter: brightness(1.02);
}

button:not(.chip-action):not(.button-secondary):not(.coords-step-btn):not(.utility-action):not(.install-guide__close):not(.cm-panel-toggle):not(.sheet-handle):not(.cm-gps-btn):not(.cm-basemap-btn):not(.cm-coord-step):disabled {
  cursor: not-allowed;
  opacity: 0.68;
  transform: none;
  box-shadow: none;
  filter: none;
}

.action-row {
  display: flex;
  gap: 12px;
  align-self: end;
}

.action-row button {
  flex: 1;
}

button.button-secondary {
  margin: 0;
  width: 100%;
  min-height: 44px;
  padding: 12px 16px;
  border-radius: 14px;
  border: 1px solid rgba(92, 104, 246, 0.18);
  background: linear-gradient(135deg, rgba(236, 240, 255, 0.96) 0%, rgba(244, 247, 255, 0.92) 100%);
  color: var(--accent-deep);
  font-weight: 700;
  letter-spacing: 0.02em;
  font-size: 0.96rem;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(92, 104, 246, 0.08);
  transition: transform 0.2s ease, border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

button.button-secondary svg {
  flex-shrink: 0;
  opacity: 0.7;
}

button.button-secondary:hover {
  transform: translateY(-1px);
  border-color: rgba(92, 104, 246, 0.32);
  background: linear-gradient(135deg, rgba(228, 234, 255, 0.98) 0%, rgba(238, 242, 255, 0.96) 100%);
  box-shadow: 0 8px 20px rgba(92, 104, 246, 0.12);
}

button.button-secondary:disabled {
  cursor: not-allowed;
  opacity: 0.68;
  transform: none;
  box-shadow: none;
}

.chart-panel {
  display: grid;
  gap: 20px;
}

.chart-block {
  display: grid;
  gap: 10px;
}

.chart-grid {
  display: grid;
  gap: 16px;
}

.chart-item {
  display: grid;
  gap: 14px;
  padding: 20px;
  border-radius: 16px;
  border: 1px solid rgba(27, 43, 50, 0.07);
  background: #fff;
  box-shadow: 0 2px 12px rgba(33, 42, 83, 0.06);
}

.chart-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.chart-heading {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.chart-title {
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.35;
  letter-spacing: -0.01em;
}

.chart-subtitle {
  font-size: 0.8rem;
  color: var(--muted);
  line-height: 1.45;
  opacity: 0.8;
}

.chart-actions {
  display: flex;
  justify-content: flex-end;
  flex-shrink: 0;
}

.chart-actions button {
  width: auto;
  min-height: 0;
  padding: 9px 14px;
  font-size: 0.84rem;
  gap: 4px;
}

.chart-actions button svg {
  width: 13px;
  height: 13px;
}

.chart-wrap {
  position: relative;
  height: 340px;
  border-radius: 10px;
  background: #fafbfe;
  overflow: hidden;
}

.chart-notes {
  padding: 12px 16px;
  border-radius: 10px;
  border-left: 3px solid rgba(75, 93, 156, 0.2);
  background: rgba(248, 249, 253, 0.9);
  font-size: 0.78rem;
  color: #5a6577;
  line-height: 1.6;
}

.chart-notes-title {
  font-weight: 600;
  font-size: 0.8rem;
  color: #3d4a5c;
  margin-bottom: 8px;
  letter-spacing: 0.01em;
}

.chart-notes-list {
  margin: 0;
  padding-left: 16px;
  display: grid;
  gap: 5px;
}

.chart-notes-list li::marker {
  color: rgba(75, 93, 156, 0.35);
}

.note {
  margin-top: 12px;
  font-size: 0.85rem;
  color: var(--muted);
}

.leaflet-container {
  font-family: inherit;
  background: #e4eafe;
}

.leaflet-container .leaflet-tile {
  outline: 1px solid transparent;
}

/* ── Loading overlay ── */

.loading-overlay {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: grid;
  place-items: center;
  padding: 24px;
  background: rgba(30, 36, 66, 0.16);
  backdrop-filter: blur(16px) saturate(1.3);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.4s cubic-bezier(0.16, 1, 0.3, 1),
    visibility 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}

.loading-overlay.is-active {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

.loading-card {
  display: grid;
  gap: 22px;
  justify-items: center;
  padding: 44px 52px;
  border-radius: 28px;
  border: 1px solid rgba(255, 255, 255, 0.26);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.94) 0%, rgba(239, 244, 255, 0.88) 100%);
  box-shadow:
    0 32px 80px rgba(33, 42, 83, 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
  max-width: min(88vw, 380px);
  text-align: center;
  transform: translateY(12px) scale(0.96);
  opacity: 0;
  transition:
    transform 0.45s cubic-bezier(0.16, 1, 0.3, 1),
    opacity 0.35s ease;
}

.loading-overlay.is-active .loading-card {
  transform: translateY(0) scale(1);
  opacity: 1;
}

.loading-indicator {
  position: relative;
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
}

.loading-spinner {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: 3px solid rgba(92, 104, 246, 0.12);
  border-top-color: var(--accent);
  animation: overlaySpinnerRotate 0.85s linear infinite;
}

.loading-icon {
  position: absolute;
  width: 30px;
  height: 30px;
  opacity: 0;
  transform: scale(0.4);
  transition: opacity 0.35s ease, transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}

.loading-icon--success { color: #2f8a6d; }
.loading-icon--error   { color: #c04060; }

/* State: pending — spinner visible, icons hidden */
.loading-overlay[data-state="pending"] .loading-spinner { display: block; }
.loading-overlay[data-state="pending"] .loading-icon   { display: none; }

/* State: success — spinner hidden, checkmark visible */
.loading-overlay[data-state="success"] .loading-spinner,
.loading-overlay[data-state="error"]   .loading-spinner {
  display: none;
}

.loading-overlay[data-state="success"] .loading-icon--success,
.loading-overlay[data-state="error"]   .loading-icon--error {
  opacity: 1;
  transform: scale(1);
}

.loading-text {
  font-size: 0.94rem;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.55;
  max-width: 300px;
}

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

@keyframes liftIn {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.5; transform: scale(0.8); }
}

@media (max-width: 1080px) {
  #panel-map {
    min-height: auto;
    width: 100%;
  }

  #panel-data,
  #panel-chart {
    width: 100%;
    justify-self: stretch;
  }

  .panel-body--map {
    grid-template-columns: 1fr;
  }

  .map {
    min-height: clamp(260px, 42vh, 380px);
  }

  .chips {
    max-height: none;
  }

  .section-card--date {
    max-width: 100%;
  }
}

@media (max-width: 720px) {
  .shell {
    padding:
      calc(24px + var(--safe-top))
      calc(14px + var(--safe-right))
      calc(48px + var(--safe-bottom))
      calc(14px + var(--safe-left));
  }

  .panel {
    padding: 16px;
    border-radius: 20px;
  }

  .map {
    min-height: clamp(240px, 38vh, 340px);
  }

  .map-search-bar {
    border-radius: 12px 12px 0 0;
    height: 42px;
  }

  .coords-bar {
    gap: 8px;
    padding: 8px 10px;
    border-radius: 12px;
  }

  .coords-label {
    font-size: 0.58rem;
  }

  .coords-label > span {
    display: none;
  }

  .coords-label {
    gap: 0;
  }

  .coords-bar input[type="text"] {
    width: 64px;
    height: 30px;
    font-size: 0.82rem;
  }

  .coords-step-btn {
    width: 26px;
    height: 30px;
    font-size: 0.95rem;
  }

  .coords-sep {
    height: 22px;
  }

  .date-range-group {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  .date-range-connector {
    display: none;
  }

  .period-gdd-group {
    grid-template-columns: 1fr 1fr;
    gap: 10px;
  }

  .section-card {
    padding: 16px;
    border-radius: 18px;
  }

  .chips {
    grid-template-columns: 1fr;
  }

  .action-row {
    flex-direction: column;
  }

  .chart-header {
    flex-direction: column;
    align-items: stretch;
  }

  .chart-actions {
    justify-content: flex-start;
  }

  .chart-wrap {
    height: 260px;
  }

  .loading-card {
    padding: 36px 28px;
  }
}

/* ── Extra-small mobile (320px-390px) ── */

@media (max-width: 420px) {
  .shell {
    padding:
      calc(20px + var(--safe-top))
      calc(10px + var(--safe-right))
      calc(40px + var(--safe-bottom))
      calc(10px + var(--safe-left));
  }

  .panel {
    padding: 14px;
    border-radius: 18px;
  }

  .panel-title {
    font-size: 0.72rem;
    padding: 7px 12px;
  }

  .map {
    min-height: 220px;
  }

  .map-card {
    padding: 6px;
    border-radius: 16px;
  }

  .map-search-bar {
    height: 40px;
    padding: 0 10px;
    border-radius: 10px 10px 0 0;
  }

  .coords-bar {
    gap: 4px;
    padding: 6px;
    border-radius: 10px;
  }

  .coords-bar input[type="text"] {
    width: 58px;
    height: 28px;
    font-size: 0.78rem;
  }

  .coords-step-btn {
    width: 24px;
    height: 28px;
    font-size: 0.9rem;
  }

  .coords-sep {
    height: 20px;
  }

  .section-card {
    padding: 14px;
    border-radius: 16px;
  }

  .period-gdd-group {
    grid-template-columns: 1fr;
    gap: 10px;
  }

  .field-label {
    font-size: 0.78rem;
  }

  input:not([type="checkbox"]):not([type="radio"]),
  select {
    min-height: 48px;
    padding: 10px 14px;
    border-radius: 12px;
    font-size: 0.92rem;
  }
}

@media (hover: none) and (pointer: coarse) {
  input:not([type="checkbox"]):not([type="radio"]),
  select {
    font-size: 16px;
  }
}

/* Premium workspace overrides */

:root {
  --ink: #142033;
  --ink-rgb: 20, 32, 51;
  --muted: #61708a;
  --accent: #4c5fe8;
  --accent-deep: #3647b7;
  --panel: linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, rgba(249, 251, 255, 0.92) 100%);
  --panel-muted: linear-gradient(180deg, rgba(252, 253, 255, 0.96) 0%, rgba(244, 247, 252, 0.94) 100%);
  --stroke: rgba(72, 92, 138, 0.12);
  --shadow: 0 22px 48px rgba(17, 27, 54, 0.08), 0 8px 20px rgba(17, 27, 54, 0.04);
  --page-background:
    radial-gradient(880px 520px at 0% 0%, rgba(104, 121, 241, 0.1) 0%, rgba(104, 121, 241, 0) 62%),
    radial-gradient(920px 640px at 100% 0%, rgba(117, 152, 226, 0.12) 0%, rgba(117, 152, 226, 0) 58%),
    linear-gradient(180deg, #f3f6fb 0%, #eef2f8 52%, #edf1f7 100%);
}

html,
body {
  background: var(--page-background);
  background-color: #edf2f8;
}

body {
  color: var(--ink);
  font-family: "Inter", "Segoe UI", sans-serif;
}

/* Legacy `.shell { max-width }`, `.app-shell`, old `.topbar`, `.topbar-meta`,
   `.topbar-name`, `.topbar-actions`, `.panel--location`, `.panel--control`,
   `#panel-map`, `#panel-data` rules removed 2026-04-20. The outer layout
   now lives under `.cm-shell` / `.cm-topbar` / `.cm-layout` / `.cm-panel`.
   The `.panel` + `#panel-chart` rules below survive because `.chart-panel`
   still carries both classes on the result card. */

.panel {
  padding: 28px;
  border-radius: 28px;
  border: 1px solid rgba(70, 88, 142, 0.12);
  background: var(--panel);
  box-shadow: var(--shadow);
  overflow: hidden;
}

#panel-chart {
  border-color: rgba(70, 88, 142, 0.11);
  width: 100%;
}

.panel-header,
#panel-map .panel-header {
  justify-items: start;
  text-align: left;
}

.panel-heading {
  display: grid;
  gap: 10px;
  min-width: 0;
}

.panel-title,
.panel-title:hover {
  padding: 0;
  border: none;
  background: transparent;
  color: var(--accent-deep);
  font-family: "Manrope", "Inter", sans-serif;
  font-size: 0.74rem;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  box-shadow: none;
}

.panel-subtitle {
  margin: 0;
  max-width: 44ch;
  color: var(--muted);
  font-size: 0.94rem;
  line-height: 1.6;
}

.panel-body--map {
  display: block;
  min-height: 0;
}

.map-card {
  min-height: 100%;
  padding: 14px;
  border-radius: 24px;
  border: 1px solid rgba(71, 90, 138, 0.14);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(246, 249, 255, 0.92) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    0 14px 30px rgba(20, 32, 51, 0.06);
  overflow: hidden;
}

.map {
  min-height: 600px;
  border: 1px solid rgba(71, 90, 138, 0.1);
  border-top: none;
  border-radius: 0 0 18px 18px;
  background: #dfe7f3;
}

.leaflet-container {
  font-family: "Inter", "Segoe UI", sans-serif;
}

.leaflet-control-attribution {
  display: block !important;
  margin: 0 14px 14px 0 !important;
  padding: 6px 8px !important;
  border-radius: 10px;
  border: 1px solid rgba(71, 90, 138, 0.12);
  background: rgba(255, 255, 255, 0.92) !important;
  color: #5c6880 !important;
  box-shadow: 0 8px 18px rgba(20, 32, 51, 0.08);
}

.leaflet-control-attribution a {
  color: #4254d1 !important;
}

.leaflet-control-zoom {
  border: none !important;
  box-shadow: 0 16px 28px rgba(20, 32, 51, 0.12) !important;
}

.leaflet-touch .leaflet-bar,
.leaflet-touch .leaflet-control-layers {
  border: 1px solid rgba(71, 90, 138, 0.12);
  background: rgba(255, 255, 255, 0.96);
  border-radius: 16px;
  overflow: hidden;
}

.leaflet-touch .leaflet-bar a {
  width: 42px;
  height: 42px;
  line-height: 40px;
  border-bottom-color: rgba(71, 90, 138, 0.1);
  color: var(--ink);
  background: transparent;
}

.leaflet-touch .leaflet-bar a:hover {
  background: rgba(76, 95, 232, 0.06);
  color: var(--accent-deep);
}

.control-stack {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  gap: 18px;
  height: 100%;
  min-height: 0;
}

.section-card {
  gap: 16px;
  padding: 20px;
  border-radius: 22px;
  border: 1px solid rgba(71, 90, 138, 0.1);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, rgba(248, 250, 255, 0.94) 100%);
  box-shadow: 0 14px 28px rgba(20, 32, 51, 0.05);
}

.section-card:hover {
  border-color: rgba(76, 95, 232, 0.16);
  box-shadow: 0 16px 30px rgba(20, 32, 51, 0.06);
}

.section-card--date {
  background: linear-gradient(180deg, rgba(252, 253, 255, 0.98) 0%, rgba(244, 247, 255, 0.95) 100%);
}

.section-card--metrics {
  min-height: 0;
  display: grid;
  grid-template-rows: auto auto minmax(0, 1fr);
}

.section-card-head {
  display: grid;
  gap: 8px;
}

.section-card-label {
  gap: 8px;
  padding: 0;
  border: none;
  color: #5f6f8d;
  font-family: "Manrope", "Inter", sans-serif;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.14em;
}

.section-card-caption {
  margin: 0;
  color: var(--muted);
  font-size: 0.88rem;
  line-height: 1.55;
}

label {
  color: #4b5a74;
}

.field-stack {
  gap: 10px;
}

.field-label {
  color: #36435d;
  font-family: "Manrope", "Inter", sans-serif;
  font-size: 0.79rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

input:not([type="checkbox"]):not([type="radio"]),
select {
  min-height: 48px;
  padding: 12px 14px;
  border-radius: 14px;
  border: 1px solid rgba(71, 90, 138, 0.16);
  background: rgba(255, 255, 255, 0.98);
  color: var(--ink);
  font-family: "Inter", "Segoe UI", sans-serif;
  font-size: 0.95rem;
  font-weight: 600;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
}

input:not([type="checkbox"]):not([type="radio"]):hover,
select:hover {
  border-color: rgba(71, 90, 138, 0.24);
}

input:not([type="checkbox"]):not([type="radio"]):focus,
select:focus {
  border-color: rgba(76, 95, 232, 0.42);
  box-shadow:
    0 0 0 4px rgba(76, 95, 232, 0.11),
    0 10px 20px rgba(76, 95, 232, 0.06);
  background: #fff;
}

select {
  background-image:
    linear-gradient(45deg, transparent 50%, #77839b 50%),
    linear-gradient(135deg, #77839b 50%, transparent 50%);
  background-position:
    calc(100% - 22px) calc(50% - 3px),
    calc(100% - 16px) calc(50% - 3px);
  background-size: 6px 6px, 6px 6px;
}

.input-unit {
  right: 16px;
  color: #6c7892;
  font-family: "Manrope", "Inter", sans-serif;
}

.gdd-field .input-field input {
  padding-right: 54px;
}

.date-range-group {
  grid-template-columns: 1fr 28px 1fr;
  gap: 12px;
}

.date-range-connector {
  height: 48px;
  padding-top: 24px;
  color: #7e8aa2;
  opacity: 0.75;
}

.period-gdd-group {
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

.chip-actions {
  gap: 10px;
}

button.chip-action {
  min-height: 38px;
  padding: 0 14px;
  border-radius: 12px;
  border: 1px solid rgba(71, 90, 138, 0.12);
  background: rgba(245, 247, 252, 0.98);
  color: #33415d;
  font-family: "Manrope", "Inter", sans-serif;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

button.chip-action:hover {
  border-color: rgba(76, 95, 232, 0.18);
  background: rgba(238, 242, 251, 1);
}

.chips {
  grid-template-columns: 1fr;
  gap: 10px;
  max-height: none;
  min-height: 0;
  overflow-y: auto;
  padding-right: 4px;
}

.chip {
  gap: 12px;
  min-height: 52px;
  padding: 13px 14px;
  border-radius: 16px;
  border: 1px solid rgba(71, 90, 138, 0.1);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.98) 0%, rgba(247, 249, 253, 0.98) 100%);
  font-size: 0.88rem;
  line-height: 1.45;
  transition: border-color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
}

.chip:hover {
  transform: none;
  border-color: rgba(71, 90, 138, 0.16);
  background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(248, 250, 255, 1) 100%);
}

.chip:has(input:checked),
.chip.is-checked {
  border-color: rgba(76, 95, 232, 0.22);
  background: linear-gradient(180deg, rgba(242, 245, 255, 0.98) 0%, rgba(236, 241, 255, 0.98) 100%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
}

.chip input {
  width: 20px;
  height: 20px;
  border-radius: 7px;
  border-width: 1.5px;
}

.chip input:focus-visible {
  box-shadow: 0 0 0 4px rgba(76, 95, 232, 0.12);
}

.control-footer {
  display: grid;
  gap: 12px;
  align-self: end;
}

.action-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}

#fetch-btn,
button.button-secondary {
  min-height: 50px;
  border-radius: 16px;
  font-family: "Manrope", "Inter", sans-serif;
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

#fetch-btn {
  border: 1px solid rgba(62, 79, 194, 0.18);
  background: linear-gradient(180deg, #4f62eb 0%, #4254d1 100%);
  box-shadow: 0 16px 24px rgba(66, 84, 209, 0.22);
}

#fetch-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 18px 28px rgba(66, 84, 209, 0.26);
}

button.button-secondary {
  border: 1px solid rgba(71, 90, 138, 0.12);
  background: rgba(255, 255, 255, 0.98);
  color: #31405d;
  box-shadow: 0 10px 18px rgba(20, 32, 51, 0.06);
}

button.button-secondary:hover {
  transform: translateY(-1px);
  border-color: rgba(76, 95, 232, 0.18);
  background: rgba(248, 250, 255, 1);
  box-shadow: 0 14px 22px rgba(20, 32, 51, 0.08);
}

.status {
  min-height: 48px;
  padding: 12px 14px;
  border-radius: 16px;
  border-color: rgba(71, 90, 138, 0.12);
  background: rgba(246, 248, 252, 0.96);
  box-shadow: none;
  font-size: 0.87rem;
}

.panel-status {
  margin-top: 0;
}

.chart-panel {
  gap: 18px;
}

.chart-title {
  font-family: "Manrope", "Inter", sans-serif;
}

.chart-subtitle,
.note {
  color: var(--muted);
}

.map-marker-icon {
  background: transparent;
  border: none;
}

.map-marker {
  position: relative;
  display: block;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.22);
}

.map-marker::before {
  content: "";
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background: linear-gradient(180deg, #4f62eb 0%, #3d4fc4 100%);
  border: 2px solid rgba(255, 255, 255, 0.92);
  box-shadow:
    0 10px 18px rgba(61, 79, 196, 0.26),
    0 0 0 6px rgba(79, 98, 235, 0.16);
}

.map-marker::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #fff;
  transform: translate(-50%, -50%);
}

@media (max-width: 1180px) {
  #panel-map,
  #panel-data {
    min-height: auto;
  }

  .map {
    min-height: 480px;
  }

  .control-stack {
    grid-template-rows: auto auto auto;
  }

  .section-card--metrics .chips {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 900px) {
  .shell {
    padding:
      calc(20px + var(--safe-top))
      calc(16px + var(--safe-right))
      calc(36px + var(--safe-bottom))
      calc(16px + var(--safe-left));
  }

  .topbar {
    flex-direction: column;
    align-items: stretch;
  }

  .topbar-actions {
    justify-content: space-between;
  }

  .map {
    min-height: 420px;
  }
}

@media (max-width: 720px) {
  .panel {
    padding: 20px;
    border-radius: 24px;
  }

  .map-card {
    padding: 10px;
    border-radius: 20px;
  }

  .map {
    min-height: 360px;
  }

  .date-range-group {
    grid-template-columns: 1fr;
    gap: 10px;
  }

  .date-range-connector {
    display: none;
  }

  .period-gdd-group,
  .action-row {
    grid-template-columns: 1fr;
  }

  .section-card--metrics .chips {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 520px) {
  .shell {
    padding:
      calc(16px + var(--safe-top))
      calc(12px + var(--safe-right))
      calc(28px + var(--safe-bottom))
      calc(12px + var(--safe-left));
  }

  .topbar-actions {
    gap: 10px;
  }

  .panel {
    padding: 16px;
    border-radius: 20px;
  }

  .panel-subtitle,
  .section-card-caption {
    font-size: 0.84rem;
  }

  .map-search-bar {
    height: 48px;
    padding: 0 14px;
  }

  .map {
    min-height: 300px;
  }
}

/* Context alignment overrides */

:root {
  --ink: #1e2442;
  --ink-rgb: 30, 36, 66;
  --muted: #6f789c;
  --content-max-width: 1040px;
  --layout-gap: 20px;
  --panel: linear-gradient(180deg, rgba(255, 255, 255, 0.94) 0%, rgba(239, 244, 255, 0.84) 100%);
  --panel-muted: linear-gradient(180deg, rgba(241, 245, 255, 0.92) 0%, rgba(232, 238, 255, 0.84) 100%);
  --stroke: rgba(72, 84, 141, 0.14);
  --accent: #5c68f6;
  --accent-deep: #3947ac;
  --sun: #8e79f6;
  --coral: #d95c84;
  --olive: #5ea496;
  --shadow: 0 22px 54px rgba(33, 42, 83, 0.16);
  --page-background:
    radial-gradient(1180px 860px at 8% 10%, rgba(186, 168, 255, 0.52) 0%, rgba(186, 168, 255, 0) 60%),
    radial-gradient(980px 760px at 92% 10%, rgba(170, 201, 255, 0.58) 0%, rgba(170, 201, 255, 0) 58%),
    linear-gradient(180deg, #eef2ff 0%, #e6ebff 54%, #e2e8fb 100%);
}

body {
  font-family: "Inter", "Segoe UI", "Trebuchet MS", sans-serif;
  color: var(--ink);
}

.skip-link {
  position: absolute;
  left: 16px;
  top: 16px;
  z-index: 2000;
  padding: 10px 14px;
  border-radius: 12px;
  background: #fff;
  color: var(--ink);
  transform: translateY(-160%);
  transition: transform 0.2s ease;
  box-shadow: 0 12px 26px rgba(33, 42, 83, 0.12);
}

.skip-link:focus {
  transform: translateY(0);
}

.shell {
  max-width: 1160px;
  padding:
    calc(36px + var(--safe-top))
    calc(24px + var(--safe-right))
    calc(64px + var(--safe-bottom))
    calc(24px + var(--safe-left));
}

.app-shell {
  gap: 18px;
}

.app-shell::before {
  display: none;
}

#panel-map,
#panel-data,
#panel-chart {
  width: min(100%, var(--content-max-width));
  justify-self: center;
}

.topbar {
  width: min(100%, var(--content-max-width));
  margin-inline: auto;
  gap: 12px;
}

.topbar-name {
  font-size: 1.4rem;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.topbar-actions {
  gap: 10px;
}

.panel {
  padding: 24px;
  border-radius: 24px;
  border: 1px solid var(--stroke);
  background: var(--panel);
  box-shadow: var(--shadow);
}

.panel::before,
.panel--location::before,
.panel--control::before,
#panel-chart::before {
  height: 3px;
  background: linear-gradient(90deg, rgba(92, 104, 246, 0.54), rgba(185, 200, 255, 0.34), rgba(185, 200, 255, 0));
}

.panel--location {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, rgba(237, 243, 255, 0.88) 100%);
  border: 1px solid rgba(92, 104, 246, 0.1);
  box-shadow:
    0 22px 54px rgba(33, 42, 83, 0.14),
    inset 0 1px 0 rgba(255, 255, 255, 0.9);
}

.panel--location::before {
  background: linear-gradient(90deg, rgba(92, 104, 246, 0.6), rgba(142, 121, 246, 0.4), rgba(185, 200, 255, 0.2), rgba(185, 200, 255, 0));
}

#panel-map {
  min-height: clamp(400px, 52vh, 560px);
}

#panel-data {
  min-height: auto;
}

.panel-heading {
  gap: 8px;
}

.panel-title,
.panel-title:hover {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  width: fit-content;
  max-width: 100%;
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid rgba(92, 104, 246, 0.18);
  background: rgba(92, 104, 246, 0.08);
  color: var(--accent-deep);
  font-family: "Inter", "Segoe UI", "Trebuchet MS", sans-serif;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  box-shadow: none;
}

.panel-subtitle {
  max-width: 42ch;
  font-size: 0.88rem;
  font-weight: 400;
  line-height: 1.6;
  color: var(--muted);
}

.map-card {
  padding: 10px;
  border-radius: 20px;
  border: 1px solid rgba(27, 43, 50, 0.08);
  background: var(--panel-muted);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7);
}

.map {
  min-height: clamp(300px, 40vh, 440px);
  border-radius: 0 0 16px 16px;
  border: 1px solid var(--stroke);
  border-top: none;
}

.leaflet-control-attribution {
  display: none !important;
}

.section-card {
  gap: 14px;
  padding: 18px;
  border-radius: 18px;
  border: 1px solid rgba(27, 43, 50, 0.08);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, rgba(241, 245, 255, 0.9) 100%);
  box-shadow:
    0 16px 30px rgba(33, 42, 83, 0.08),
    inset 0 1px 0 rgba(255, 255, 255, 0.7);
}

.section-card--date {
  gap: 18px;
}

.section-card-label {
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.12em;
}

.section-card-caption {
  font-size: 0.8rem;
}

input:not([type="checkbox"]):not([type="radio"]),
select {
  min-height: 44px;
  padding: 10px 14px;
  border-radius: 12px;
  font-size: 0.95rem;
}

.field-label {
  font-size: 0.82rem;
  font-weight: 600;
}

.section-card--date .field-label {
  color: #33415d;
  font-family: "Manrope", "Inter", sans-serif;
  font-size: 0.84rem;
  font-weight: 700;
}

.section-card--date input:not([type="checkbox"]):not([type="radio"]),
.section-card--date select {
  min-height: 50px;
  padding: 0 16px;
  border-radius: 16px;
  border: 1px solid rgba(72, 84, 141, 0.16);
  background: rgba(255, 255, 255, 0.98);
  color: #24314d;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.92),
    0 1px 0 rgba(255, 255, 255, 0.7);
}

.section-card--date input:not([type="checkbox"]):not([type="radio"]):hover,
.section-card--date select:hover {
  border-color: rgba(72, 84, 141, 0.24);
}

.section-card--date input:not([type="checkbox"]):not([type="radio"]):focus,
.section-card--date select:focus {
  border-color: rgba(92, 104, 246, 0.4);
  box-shadow:
    0 0 0 4px rgba(92, 104, 246, 0.1),
    0 10px 18px rgba(63, 76, 160, 0.08);
}

.date-range-group {
  grid-template-columns: 1fr auto 1fr;
  gap: 8px;
}

.date-range-connector {
  height: 44px;
  padding-top: 20px;
  opacity: 0.4;
}

.chips {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.chip {
  min-height: 0;
  padding: 10px 12px;
  border-radius: 14px;
  font-size: 0.84rem;
}

.chip input {
  width: 18px;
  height: 18px;
  border-radius: 6px;
}

/* Legacy `.input-field`, `.input-glyph`, `.date-range-*`, `.period-gdd-group`
   rules removed 2026-04-20 — those classes are no longer in the HTML after
   the sat-style form refactor. */

.action-row {
  display: flex;
  gap: 12px;
}

.action-row button {
  flex: 1;
}

#fetch-btn,
button.button-secondary {
  min-height: 44px;
  padding: 12px 16px;
  border-radius: 14px;
  font-size: 0.92rem;
}

#fetch-btn {
  background: linear-gradient(135deg, #5e6df6, #404eb6 88%);
}

.status {
  border-radius: 12px;
  box-shadow: 0 8px 20px rgba(33, 42, 83, 0.06);
}

.map-marker::before {
  box-shadow: 0 10px 20px rgba(63, 76, 160, 0.24);
}


@media (max-width: 767px) {
  .shell {
    padding:
      calc(24px + var(--safe-top))
      calc(14px + var(--safe-right))
      calc(48px + var(--safe-bottom))
      calc(14px + var(--safe-left));
  }

  .panel {
    padding: 16px;
  }

  .chips {
    grid-template-columns: 1fr;
  }

  .date-range-group {
    grid-template-columns: 1fr;
  }

  .date-range-connector {
    display: none;
  }

  .action-row {
    flex-direction: column;
  }

}

@media (max-width: 420px) {
  .panel {
    padding: 16px;
    border-radius: 20px;
  }
}

.topbar-brand {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  min-width: 0;
}

.topbar-brand-icon {
  width: 52px;
  height: 52px;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid rgba(70, 88, 142, 0.12);
  background: #fff;
  box-shadow: 0 10px 22px rgba(20, 32, 51, 0.08);
}

.topbar-brand-icon img,
.topbar-brand-icon svg {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: contain;
}

.topbar-brand-copy {
  display: grid;
  gap: 4px;
  min-width: 0;
}

.topbar-caption {
  margin: 0;
  font-size: 0.88rem;
  color: #66739b;
  max-width: 38ch;
  line-height: 1.35;
}

.topbar-actions {
  gap: 12px;
}

button.utility-action {
  width: 40px;
  min-width: 40px;
  height: 40px;
  min-height: 40px;
  padding: 0;
  border-radius: 999px;
  border: 1px solid rgba(72, 84, 141, 0.14);
  background: rgba(255, 255, 255, 0.85);
  color: #4352bd;
  box-shadow: 0 6px 16px rgba(33, 42, 83, 0.06);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}

button.utility-action:hover {
  transform: translateY(-1px);
  border-color: rgba(92, 104, 246, 0.32);
  background: rgba(255, 255, 255, 0.96);
  box-shadow: 0 10px 20px rgba(33, 42, 83, 0.10);
}

button.utility-action:focus-visible,
button.install-guide__close:focus-visible {
  outline: 3px solid rgba(92, 104, 246, 0.32);
  outline-offset: 2px;
}

button.utility-action[hidden] {
  display: none !important;
}

.utility-action__icon {
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: inherit;
}

.utility-action__icon svg,
.install-guide__close svg {
  width: 18px;
  height: 18px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.1;
  stroke-linecap: round;
  stroke-linejoin: round;
}

button.utility-action--manual {
  color: #236c84;
}

button.utility-action--manual:hover {
  border-color: rgba(46, 127, 154, 0.32);
}

.install-guide-backdrop {
  position: fixed;
  inset: 0;
  z-index: 1200;
  background: rgba(23, 31, 62, 0.34);
  backdrop-filter: blur(8px);
}

.install-guide {
  position: fixed;
  top: max(20px, calc(var(--safe-top) + 14px));
  right: max(16px, calc(var(--safe-right) + 16px));
  z-index: 1201;
  width: min(420px, calc(100vw - 32px));
  display: grid;
  gap: 16px;
  padding: 20px;
  border-radius: 24px;
  border: 1px solid rgba(72, 84, 141, 0.14);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.96) 0%, rgba(239, 244, 255, 0.94) 100%);
  box-shadow: 0 28px 56px rgba(20, 28, 60, 0.22);
}

.install-guide__header {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px 12px;
  align-items: start;
}

.install-guide__eyebrow {
  grid-column: 1 / 2;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #5c6aa2;
}

.install-guide__title {
  margin: 0;
  grid-column: 1 / 2;
  font-size: 1.25rem;
  line-height: 1.2;
  color: #18214a;
}

button.install-guide__close {
  grid-column: 2 / 3;
  grid-row: 1 / span 2;
  width: 40px;
  height: 40px;
  min-width: 40px;
  min-height: 40px;
  padding: 0;
  border-radius: 999px;
  border: 1px solid rgba(72, 84, 141, 0.12);
  background: rgba(244, 247, 255, 0.92);
  color: #4f5c90;
  box-shadow: none;
}

button.install-guide__close:hover {
  transform: none;
  background: rgba(236, 241, 255, 0.98);
  border-color: rgba(92, 104, 246, 0.22);
  box-shadow: none;
}

.install-guide__summary {
  margin: 0;
  font-size: 0.94rem;
  line-height: 1.65;
  color: #53607f;
}

.install-guide__steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px;
}

.install-guide__step {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 12px;
  align-items: start;
  padding: 12px 14px;
  border-radius: 16px;
  border: 1px solid rgba(72, 84, 141, 0.1);
  background: rgba(255, 255, 255, 0.74);
}

.install-guide__step-badge {
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: rgba(92, 104, 246, 0.12);
  color: #4352bd;
  font-size: 0.82rem;
  font-weight: 800;
  line-height: 1;
}

.install-guide__step-text {
  font-size: 0.92rem;
  line-height: 1.55;
  color: #213054;
}

@media (max-width: 767px) {
  .topbar {
    align-items: stretch;
  }

  .topbar-actions {
    justify-content: space-between;
    width: 100%;
  }

  .topbar-caption {
    display: none;
  }

  .install-guide {
    top: auto;
    right: 16px;
    left: 16px;
    bottom: max(12px, calc(var(--safe-bottom) + 12px));
    width: auto;
    max-height: min(72vh, 560px);
    overflow-y: auto;
  }
}

@media (max-width: 540px) {
  .topbar-brand-icon {
    width: 44px;
    height: 44px;
    border-radius: 14px;
  }

  .topbar-brand-icon img,
  .topbar-brand-icon svg {
    width: 100%;
    height: 100%;
  }

  .topbar-name {
    font-size: 1.15rem;
  }
}

@media (prefers-contrast: more) {
  button.utility-action,
  button.install-guide__close,
  .chip,
  .panel,
  .section-card {
    border-color: rgba(27, 43, 50, 0.32);
  }

  .status {
    border-width: 2px;
  }
}

@media (forced-colors: active) {
  .install-guide-backdrop {
    background: rgba(0, 0, 0, 0.55);
  }

  button.utility-action,
  button.install-guide__close,
  .chip,
  .panel,
  .section-card,
  .status {
    forced-color-adjust: auto;
    border: 1px solid CanvasText;
    background: Canvas;
    color: CanvasText;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body.install-guide-open {
  overflow: hidden;
}

.chart-actions button,
button.chip-action {
  min-height: 44px;
}

.install-guide[data-mode="ios-manual"] {
  border-top: 4px solid #1f7a7b;
}

.install-guide[data-mode="mac-manual"] {
  border-top: 4px solid #4352bd;
}

.install-guide[data-mode="firefox-android-manual"] {
  border-top: 4px solid #b55b19;
}

.install-guide__summary {
  color: #32415f;
  font-weight: 600;
}

.install-guide__step {
  min-height: 68px;
}

.install-guide__step-badge {
  width: 32px;
  height: 32px;
  font-size: 0.88rem;
}

@media (max-width: 540px) {
  .topbar-actions {
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
  }
}

/* ============================================================================
   CLIMAP LAYOUT — nav + side-panel (desktop) / bottom-sheet (mobile) + map
   Added in step 1 of the sat-style refactor. `.cm-*` classes below are the
   new outer shell; existing `.section-card`, `.chip`, `.coords-*`, `.chart-*`
   rules still apply to the inner content and are intentionally left alone.
   ============================================================================ */

:root {
  color-scheme: only light;
}

html, body {
  height: 100%;
  margin: 0;
  /* iOS pull-to-refresh + Android overscroll bounce would otherwise lift the
     fixed bottom sheet past the viewport mid-drag. */
  overscroll-behavior: none;
  overscroll-behavior-y: none;
}

/* Native-rendered widgets (date pickers, <select> dropdown, scrollbars,
   calendar popups) inherit `color-scheme` FROM THE ELEMENT, not from :root,
   on Chromium and WebKit. Without this rule, the OS dark theme + Samsung
   Internet / Yandex / MIUI "force dark" would flip native widgets to a
   dark theme even though our surfaces are explicit light — producing
   white-on-white dates, invisible option text, unreadable scrollbar
   thumbs. Scoping color-scheme here keeps every native part of every
   input consistent with our app theme. Ported from /sat. */
input, select, textarea, button { color-scheme: only light; }

/* Explicit date-input text color — some forced-dark implementations invert
   the value color without touching the background, producing white-on-white
   unreadable dates. Also pins the native date-picker popup to light mode
   on Chromium/Edge. */
input[type="date"], input[type="number"], input[type="text"] { color: #1f2f22; }

html { background: #f5f7f3; }

.cm-shell {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
  gap: 0;
  padding: 0;
}

/* Override the old .app-shell/.topbar stack styling when .cm-shell wraps the
   app. The old rules cascaded gap/padding onto the shell that no longer
   applies after the refactor. */
.cm-shell .cm-topbar { width: 100%; }

.cm-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 20px;
  background: #0f4d2a;
  color: #fff;
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.12);
  position: relative;
  z-index: 1500;
  flex-shrink: 0;
  min-height: 58px;
}

.cm-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  flex: 1 1 auto;
}

.cm-brand-logo {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.08);
}

.cm-brand-logo img {
  display: block;
  width: 32px;
  height: 32px;
}

.cm-brand-text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  line-height: 1.15;
}

.cm-brand-name {
  font-family: "Manrope", "Inter", sans-serif;
  font-weight: 800;
  font-size: 19px;
  letter-spacing: 0.2px;
  color: #fff;
}

.cm-brand-caption {
  margin-top: 2px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.82);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cm-top-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  /* Explicit height so the nested items (back-link 32, lang-switch 32)
     share the exact vertical band and the topbar's `align-items: center`
     has a single anchor to centre against — no more top-bottom drift
     between the home icon and the TR/EN pills. */
  height: 32px;
}

.cm-back-link {
  display: inline-grid;
  place-items: center;
  /* 32 px matches the lang-switch pill height so both items in
     .cm-top-actions land at the identical vertical band — user flagged
     the 34-vs-28 px mismatch as "alt-üst mesafeler eşit değil". */
  width: 32px;
  height: 32px;
  color: #e3f4ea;
  text-decoration: none;
  border-radius: 9px;
  transition: background-color 0.14s ease, color 0.14s ease;
  -webkit-tap-highlight-color: transparent;
}

.cm-back-link:hover {
  background-color: rgba(255, 255, 255, 0.14);
  color: #fff;
}

.cm-back-link:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.cm-back-link svg { display: block; }

.cm-top-actions .cm-install-action {
  width: 32px;
  min-width: 32px;
  height: 32px;
  min-height: 32px;
  border-radius: 9px;
  border: 0;
  background: rgba(255, 255, 255, 0.14);
  color: #e3f4ea;
  box-shadow: none;
}

.cm-top-actions .cm-install-action:hover {
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
  box-shadow: none;
  transform: none;
}

.cm-top-actions .cm-install-action.utility-action--manual {
  color: #d7f3ff;
}

/* Language switch — ported 1:1 from /sat so the two apps share identical
   pills. <a class="lang-btn"> children directly inside .lang-switch. */
.cm-shell #language-switch.lang-switch,
.cm-shell .lang-switch {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 3px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.14);
  border: none;
  box-shadow: none;
  min-height: 0;
  min-width: 0;
  /* Fixed 32 px total so lang-switch height matches .cm-back-link. */
  height: 32px;
}

.cm-shell .lang-switch .lang-btn {
  color: #fff;
  text-decoration: none;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.4px;
  padding: 5px 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  box-shadow: none;
  cursor: pointer;
  line-height: 1;
  -webkit-tap-highlight-color: transparent;
  /* touch-action: manipulation kills iOS Safari's 350 ms double-tap-zoom
     delay on the anchor so tap → SPA switch feels instant — same speed
     profile desktop enjoys with a mouse click. */
  touch-action: manipulation;
  /* user-select + -webkit-user-select: none — long-press on mobile was
     selecting the "TR"/"EN" text as if it were document text, triggering
     the copy/share callout. That steals the tap. */
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  transition: background 0.14s ease, color 0.14s ease;
}

/* Hover ONLY on pointer-fine devices (desktop mouse). On touch screens
   `:hover` is sticky after a tap — the previously tapped lang-btn keeps
   its semi-transparent tint, which sits between the transparent base and
   the solid-white .is-active state. With the transition blending between
   the three, the active pill visibly "söngkleşiyor" for a moment after
   setLanguage runs. Gating :hover behind `@media (hover: hover)` means it
   simply doesn't exist on touch — tap feedback comes from :active alone,
   .is-active takes over on release, no intermediate tint. */
@media (hover: hover) {
  .cm-shell .lang-switch .lang-btn:hover {
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
  }
}

/* Tap-pressed feedback — fires on EVERY device (mouse + touch) and
   respects border-radius because it paints through the element itself. */
.cm-shell .lang-switch .lang-btn:active {
  background: rgba(255, 255, 255, 0.24);
  color: #fff;
  transition: background 0s;
}

.cm-shell .lang-switch .lang-btn.is-active {
  background: #fff;
  color: #0f4d2a;
  box-shadow: none;
}

.cm-shell .lang-switch .lang-btn.is-active:active {
  /* Press on the already-active pill should not flash — no state change
     happens, so giving feedback would be misleading. */
  background: #fff;
  color: #0f4d2a;
}

.cm-shell .lang-switch .lang-btn:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* ---- Main layout grid (desktop) -------------------------------------- */
/* The panel width is exposed as a custom property so the .cm-panel-toggle
   chevron can follow it without hardcoding pixel math. Min 380px keeps the
   controls readable; max 640px caps it so ultra-wide monitors don't waste
   real estate on what is, functionally, a form. On 1024px viewports the
   panel takes roughly half the screen — the "at least half" target the
   user asked for so charts aren't cramped after Fetch. */
.cm-layout {
  /* Dynamic sidebar width — reserve a fixed 480 px for the map (the
     floating search card, coords bar, basemap pill and zoom column all fit
     comfortably inside 480 px) and hand the rest of the viewport to the
     sidebar so form fields + charts never get squeezed. On very wide
     monitors (>1440 px) the sidebar caps at 960 px so the form doesn't
     stretch into empty whitespace; below that cap, the sidebar grows
     proportionally with the window:

        1280 px viewport → sidebar 800, map 480  (sidebar ~62 %, past centre)
        1440 px viewport → sidebar 920, map 520
        1680 px viewport → sidebar 960 (cap), map 720
        1920 px viewport → sidebar 960 (cap), map 960

     Neither side ever squeezes the other: the map holds a 480 px floor,
     and the sidebar holds a 380 px floor right before the mobile
     breakpoint takes over. */
  --cm-panel-w: clamp(380px, calc(100% - 480px), 960px);
  flex: 1;
  position: relative;
  display: grid;
  grid-template-columns: var(--cm-panel-w) 1fr;
  gap: 0;
  min-height: 0;
  transition: grid-template-columns 280ms cubic-bezier(0.4, 0, 0.2, 1);
}

.cm-layout.is-panel-collapsed {
  grid-template-columns: 0 1fr;
}

.cm-panel {
  min-width: 0;
  min-height: 0;
}

.cm-panel--controls {
  padding: 22px 22px 32px;
  background: #fff;
  border-right: 1px solid #dde4d8;
  overflow-y: auto;
  overflow-x: hidden;
  max-height: calc(100vh - 58px);
  max-height: calc(100dvh - 58px);
  transition: padding 280ms cubic-bezier(0.4, 0, 0.2, 1),
              border-right-color 280ms cubic-bezier(0.4, 0, 0.2, 1);
  /* Reset inherited padding/radius/shadow from the old .panel rules. */
  border-radius: 0;
  box-shadow: none;
}

.cm-layout.is-panel-collapsed .cm-panel--controls {
  padding-left: 0;
  padding-right: 0;
  border-right-color: transparent;
  pointer-events: none;
}

/* Kill the ::before gradient that the old .panel::before rule would render on
   .cm-panel (specificity: single class) — new panels don't want that seam. */
.cm-panel::before,
.cm-panel::after {
  content: none !important;
}

/* Inner stack inside the sidebar */
.cm-panel--controls .control-stack {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-height: 0;
  height: auto;
}

.cm-panel--controls .section-card {
  margin: 0;
}

/* ---- Panel collapse toggle (desktop chevron) ------------------------- */
.cm-panel-toggle {
  position: absolute;
  top: 50%;
  /* Follow the panel edge via the same custom property as the grid track. */
  left: calc(var(--cm-panel-w, 380px) - 19px);
  z-index: 600;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1.5px solid #fff;
  border-radius: 50%;
  background: #0f4d2a;
  color: #fff;
  cursor: pointer;
  display: grid;
  place-items: center;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.22);
  transform: translateY(-50%);
  transition: left 280ms cubic-bezier(0.4, 0, 0.2, 1),
              background-color 0.16s ease,
              box-shadow 0.16s ease;
  -webkit-tap-highlight-color: transparent;
}

.cm-panel-toggle:hover {
  background: #15683a;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.28);
}

.cm-panel-toggle:active { background: #0a3a1f; }

.cm-panel-toggle:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(15, 77, 42, 0.45);
}

.cm-panel-toggle svg {
  display: block;
  width: 16px;
  height: 16px;
  transition: transform 280ms cubic-bezier(0.4, 0, 0.2, 1);
}

.cm-layout.is-panel-collapsed .cm-panel-toggle { left: 0; }
.cm-layout.is-panel-collapsed .cm-panel-toggle svg { transform: rotate(180deg); }

/* ---- Map panel (main area) ------------------------------------------- */
.cm-panel--map {
  position: relative;
  min-height: 400px;
  background: #dfe7f3;
  overflow: hidden;
  border-radius: 0;
  box-shadow: none;
}

/* Override the old .map rule so it fills the panel edge-to-edge. */
.cm-panel--map #map.map,
.cm-panel--map #map {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  min-height: 0;
  border: 0;
  border-radius: 0;
  background: #dfe7f3;
  overscroll-behavior: contain;
}

/* Floating search — over the map, left-aligned so the full vertical column
   of map chrome (search → basemap → zoom) shares the same left edge.

   The stack math is driven by three CSS vars exposed on .cm-panel--map:
     --map-edge-pad   distance from map edge to first item
     --stack-gap      vertical gap between EVERY pair of items
     --search-h       explicit height of the search card
   so basemap/zoom padding-top can be a single calc() and the three rows
   share exactly one gap value — no drift between desktop and mobile. */
.cm-panel--map {
  --map-edge-pad: 14px;
  --stack-gap: 8px;
  --search-h: 44px;
}

.cm-map-search {
  position: absolute;
  top: var(--map-edge-pad);
  left: var(--map-edge-pad);
  z-index: 650;
  display: flex;
  align-items: center;
  gap: 8px;
  width: min(440px, calc(100% - 2 * var(--map-edge-pad)));
  height: var(--search-h);
  padding: 0 12px;
  box-sizing: border-box;
  background: rgba(255, 255, 255, 0.96);
  border: 1px solid rgba(15, 77, 42, 0.14);
  border-radius: 14px;
  box-shadow: 0 10px 28px rgba(15, 30, 20, 0.18);
  backdrop-filter: saturate(1.1) blur(4px);
  -webkit-backdrop-filter: saturate(1.1) blur(4px);
}

.cm-map-search:focus-within {
  border-color: #0f4d2a;
  box-shadow: 0 12px 30px rgba(15, 30, 20, 0.24);
}

.cm-map-search-icon {
  flex-shrink: 0;
  color: #3b5147;
}

.cm-map-search input[type="text"] {
  flex: 1 1 auto;
  min-width: 0;
  width: auto;
  min-height: 0;
  height: 26px;
  border: 0;
  outline: 0;
  background: transparent;
  box-shadow: none;
  font: inherit;
  /* 16px floor keeps iOS Safari from zooming the viewport on focus. */
  font-size: 16px;
  color: #152514;
  padding: 2px 0;
  border-radius: 0;
}

.cm-map-search input[type="text"]:hover,
.cm-map-search input[type="text"]:focus {
  border: 0;
  box-shadow: none;
  background: transparent;
}

.cm-map-search input[type="text"]::placeholder {
  color: #8a9a8f;
}

/* ---- GPS "use my location" — minimal icon-only button inside the search.
   No pill / border / background in the rest state: the search card already
   provides the surface. Hover tints the glyph only. A visible focus ring
   lands via :focus-visible for keyboard users. Sized to a 24 px tap target
   visually with a padded hit area so it still meets touch minimums. --- */
.cm-gps-btn {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  padding: 0;
  margin: 0;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: #4a6048;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 0;
  transition: color 0.12s ease, background 0.12s ease;
  -webkit-tap-highlight-color: transparent;
}

.cm-gps-btn svg { display: block; flex: none; width: 17px; height: 17px; }

.cm-gps-btn:hover { color: #0f4d2a; background: rgba(15, 77, 42, 0.08); }
.cm-gps-btn:active { background: rgba(15, 77, 42, 0.16); }
.cm-gps-btn:focus-visible { outline: 2px solid #0f4d2a; outline-offset: 2px; }

.cm-gps-btn[data-state="busy"] { cursor: progress; color: #0f4d2a; }
.cm-gps-btn[data-state="busy"] svg {
  animation: cm-gps-spin 1s linear infinite;
  transform-origin: 50% 50%;
}
.cm-gps-btn[data-state="error"] { color: #a1361f; }

@keyframes cm-gps-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* Floating coords — compact single-row pill at the bottom of the map.
   Two "cells" (Lat, Lon), each with a glyph + label + input.
   width:auto + left:50% + translateX(-50%) centers the pill symmetrically
   on every viewport; justify-content:center is belt-and-braces so the
   internal cells stay balanced if anything ever forces the pill wider
   than its natural width. max-width keeps it from poking past the map
   edges on small screens. */
.cm-coords-bar {
  position: absolute;
  left: 50%;
  bottom: 14px;
  transform: translateX(-50%);
  z-index: 650;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 6px 10px;
  width: auto;
  max-width: calc(100% - 28px);
  background: rgba(255, 255, 255, 0.96);
  border: 1px solid rgba(15, 77, 42, 0.14);
  border-radius: 12px;
  box-shadow: 0 10px 24px rgba(15, 30, 20, 0.18);
  backdrop-filter: saturate(1.1) blur(4px);
  -webkit-backdrop-filter: saturate(1.1) blur(4px);
}

.cm-coords-cell {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
}

.cm-coords-cell + .cm-coords-cell::before {
  content: "";
  width: 1px;
  height: 18px;
  margin-right: 6px;
  background: rgba(15, 77, 42, 0.14);
}

.cm-coords-k {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #4a6048;
  padding: 0 4px 0 2px;
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}

.cm-coords-icon {
  display: block;
  flex: none;
  opacity: 0.9;
}

.cm-coords-cell input[type="text"] {
  width: 72px;
  min-height: 0;
  height: 24px;
  padding: 2px 4px;
  border: 1px solid rgba(15, 77, 42, 0.18);
  border-radius: 6px;
  background: #fff;
  color: #152514;
  font: inherit;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  text-align: center;
  outline: 0;
  box-shadow: none;
}

.cm-coords-cell input[type="text"]:hover {
  border-color: #0f4d2a;
}

.cm-coords-cell input[type="text"]:focus {
  border-color: #0f4d2a;
  box-shadow: 0 0 0 2px rgba(15, 77, 42, 0.14);
  background: #fff;
}

/* ---- Leaflet zoom controls: keep top-right, same on mobile+desktop --- */
.cm-panel--map .leaflet-top.leaflet-right {
  top: 0;
  padding-top: 12px;
  padding-right: 12px;
}

/* Pixel-port of /sat's zoom pill — matches basemap pill visually. */
.cm-panel--map .leaflet-control-zoom {
  width: 34px;
  margin: 0 !important;
  border: 1px solid #c4d0bf !important;
  border-radius: 10px !important;
  overflow: hidden;
  background-color: #fff !important;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15) !important;
}

.cm-panel--map .leaflet-control-zoom a,
.cm-panel--map .leaflet-touch .leaflet-bar a {
  width: 34px !important;
  height: 34px !important;
  line-height: 34px !important;
  background-color: #fff !important;
  color: #2f4431 !important;
  border-bottom: 1px solid #eef2ea !important;
  font-size: 18px !important;
  font-weight: 500 !important;
  transition: background-color 0.14s ease, color 0.14s ease;
  -webkit-tap-highlight-color: transparent;
}

.cm-panel--map .leaflet-control-zoom a:last-child {
  border-bottom: none !important;
}

.cm-panel--map .leaflet-control-zoom a:hover {
  background-color: #f0f6ed !important;
  color: #0f4d2a !important;
}

.cm-panel--map .leaflet-control-zoom a.leaflet-disabled {
  background-color: #f5f7f3 !important;
  color: #b7c5b4 !important;
  cursor: not-allowed;
}

/* Attribution — ported 1:1 from /sat so the two apps match pixel-perfect.
   `!important` is necessary because the legacy `.leaflet-control-attribution
   { display: none !important }` rule earlier in this file still exists; we
   override the earlier !important with a more specific !important here. */
.cm-panel--map .leaflet-control-attribution {
  display: block !important;
  margin: 0 !important;
  background: rgba(255, 255, 255, 0.72) !important;
  padding: 1px 7px !important;
  border-radius: 4px 0 0 0 !important;
  font-size: 10px !important;
  line-height: 1.5 !important;
  color: #6b7363 !important;
  box-shadow: none;
  transition: background-color 0.16s ease, color 0.16s ease;
}

.cm-panel--map .leaflet-control-attribution a {
  color: #4a5a49 !important;
  text-decoration: none;
}

.cm-panel--map .leaflet-control-attribution:hover {
  background: rgba(255, 255, 255, 0.95) !important;
  color: #2f4431 !important;
}

.cm-panel--map .leaflet-control-attribution:hover a {
  color: #0f4d2a !important;
  text-decoration: underline;
}

/* Download button now visible — sits next to Fetch in the .action-row flex.
   2026-04-20: re-enabled after step 1 hiding. Both buttons share identical
   height/padding/radius via the .cm-panel--controls #fetch-btn /
   .button-secondary rule below. */

/* ---- Basemap + zoom live in the top-LEFT column, pushed down under the
   floating search card so search · basemap · zoom form a clean vertical
   column where EVERY gap equals --stack-gap. The three variables on
   .cm-panel--map drive the whole arithmetic:

     padding-top = edge-pad + search-h + stack-gap   (search → basemap gap)
     margin-bottom = stack-gap                        (basemap → zoom gap)

   Change --stack-gap in one place and both gaps track each other exactly
   on every viewport (desktop and mobile share the formula). */
.cm-panel--map .leaflet-top.leaflet-left {
  top: 0;
  padding-top: calc(var(--map-edge-pad) + var(--search-h) + var(--stack-gap));
  padding-left: var(--map-edge-pad);
}

.cm-panel--map .leaflet-top.leaflet-left .leaflet-control {
  margin: 0 0 var(--stack-gap) 0 !important;
}

.cm-panel--map .leaflet-top.leaflet-left .leaflet-control:last-child {
  margin-bottom: 0 !important;
}

/* Nothing lives in the top-right column any more — reset the legacy padding
   so Leaflet's default doesn't reserve empty space there. */
.cm-panel--map .leaflet-top.leaflet-right {
  padding: 0;
}

/* Pixel-port of /sat's basemap pill — same 34 px cell, same frame, same
   shadow, same hover/active tints. Keeps the two apps visually consistent
   so a user moving between them reads the control chrome as one system. */
.cm-basemap-switch {
  margin: 0 !important;
  display: flex;
  border: 1px solid #c4d0bf !important;
  border-radius: 10px !important;
  overflow: hidden;
  background-color: #fff !important;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15) !important;
}

.cm-basemap-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;
}

.cm-basemap-btn:last-child { border-right: none; }

.cm-basemap-btn svg { display: block; flex: none; }

.cm-basemap-btn:hover:not([aria-pressed="true"]) {
  background: #f0f6ed;
  color: #0f4d2a;
}

.cm-basemap-btn[aria-pressed="true"] {
  background: #0f4d2a;
  color: #fff;
}

.cm-basemap-btn:focus-visible {
  outline: 2px solid #0f4d2a;
  outline-offset: -2px;
  z-index: 1;
}

/* ---- Mobile sheet handle — hidden on desktop ------------------------- */
.sheet-handle { display: none; }

/* ---- Chart panel inside the controls sidebar ------------------------- */
.cm-panel--controls #panel-chart {
  padding: 16px 14px;
  border-radius: 16px;
  border: 1px solid rgba(15, 77, 42, 0.1);
  background: #fff;
  box-shadow: 0 6px 18px rgba(20, 32, 51, 0.05);
  margin-top: 8px;
}

.cm-panel--controls #panel-chart::before { content: none !important; }

.cm-panel--controls #panel-chart.is-hidden { display: none; }

/* ---- Mobile / short-viewport bottom sheet ---------------------------- */
@media (max-width: 820px), (max-height: 540px) {
  .cm-layout,
  .cm-layout.is-panel-collapsed {
    display: flex;
    flex-direction: column;
    position: relative;
    overflow: hidden;
    transition: none;
  }

  .cm-panel--map {
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
  }

  /* Desktop chevron hidden — the sheet handle is the mobile affordance. */
  .cm-panel-toggle { display: none; }

  .cm-panel--controls,
  .cm-layout.is-panel-collapsed .cm-panel--controls {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    top: auto;
    height: var(--sheet-h, 56px);
    max-height: calc(100vh - var(--topbar-h, 58px) - 8px);
    max-height: calc(100dvh - var(--topbar-h, 58px) - 8px);
    border: none;
    border-top: 1px solid #dde4d8;
    border-radius: 18px 18px 0 0;
    background: #fff;
    box-shadow: 0 -6px 24px rgba(10, 30, 20, 0.14),
                0 -1px 0 rgba(255, 255, 255, 0.9) inset;
    z-index: 1200;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding: 0 18px 18px;
    pointer-events: auto;
    transition: height 340ms cubic-bezier(0.32, 0.72, 0, 1);

    /* Hide the native scrollbar on the mobile bottom sheet — it otherwise
       renders OUTSIDE the 18 px top-radius corners on iOS Safari / Chrome
       Android, producing a visible vertical stripe poking past the rounded
       edge. The content is still fully scrollable via touch + the sticky
       sheet-handle at top acts as the visual affordance. */
    scrollbar-width: none;
  }

  .cm-panel--controls::-webkit-scrollbar,
  .cm-layout.is-panel-collapsed .cm-panel--controls::-webkit-scrollbar {
    display: none;
    width: 0;
    height: 0;
  }

  .cm-panel--controls[data-dragging="true"] {
    transition: none;
  }

  .sheet-handle {
    display: flex;
    align-items: center;
    justify-content: center;
    position: sticky;
    top: 0;
    left: -18px;
    right: -18px;
    width: calc(100% + 36px);
    margin: 0 -18px 4px;
    padding: 10px 0 8px;
    border: none;
    background: #fff;
    color: #4a6048;
    cursor: pointer;
    touch-action: none;
    -webkit-tap-highlight-color: transparent;
    z-index: 3;
    border-radius: 18px 18px 0 0;
    transition: color 0.15s ease;
  }

  .sheet-handle:hover,
  .sheet-handle:focus-visible { color: #0f4d2a; outline: none; }
  .sheet-handle:active { cursor: grabbing; }

  .sheet-handle-chevron {
    display: block;
    transition: transform 320ms cubic-bezier(0.32, 0.72, 0, 1);
  }

  .cm-panel--controls[data-snap="open"] .sheet-handle-chevron {
    transform: rotate(180deg);
  }

  /* When closed, everything except the handle is visually and functionally
     hidden so only the chevron bar peeks above the home indicator. */
  .cm-panel--controls[data-snap="closed"] > *:not(.sheet-handle) {
    visibility: hidden;
  }

  /* Search bar on mobile fills the top row; basemap + zoom sit in their own
     rows directly under it via .leaflet-top.leaflet-left padding-top that
     reads the same --map-edge-pad + --search-h + --stack-gap CSS vars, so
     the two gaps (search→basemap and basemap→zoom) stay identical. Only
     the var values shrink for the narrower mobile viewport. */
  .cm-panel--map {
    --map-edge-pad: 10px;
    --search-h: 40px;
  }

  .cm-map-search {
    width: calc(100% - 2 * var(--map-edge-pad));
    padding: 0 10px;
  }

  .cm-coords-bar {
    /* Lift above the sheet-closed handle (56px) + safe-area so it never
       hides under the sheet. Width stays `auto` (from the base rule) so the
       pill hugs its contents and is symmetrically centered by translateX,
       exactly like desktop — no forced full-width + left-aligned contents. */
    bottom: calc(64px + env(safe-area-inset-bottom, 0px));
    padding: 6px 10px;
    gap: 8px;
    max-width: calc(100% - 20px);
  }

  /* Stack padding is computed from the vars above — no manual px math. */
}


/* PWA standalone safe-area insets.

   env(safe-area-inset-*) is ONLY honoured when the app runs in installed
   standalone/fullscreen mode. Regular browsers (Chrome, Safari, Firefox,
   Edge) don't need our layout to respect device insets — their own
   chrome already covers the unsafe zones.

   Quirky chromium derivatives (Hola, Yandex, UC, some Samsung Internet
   builds) report non-zero env() values in regular-tab mode because they
   treat their own custom toolbar as "unsafe". WITHOUT scoping every
   env() consumer behind display-mode, the topbar visibly balloons to
   60-80 px on those browsers, Leaflet controls slide down, the pill
   stack drifts. That's the "nav bar changes shape between browsers"
   symptom — fixed by putting every env() behind display-mode:standalone.

   We also use max(px, env()) instead of calc(px + env()) so the top pad
   is the LARGER of the two, not the SUM. On a notched iPhone PWA that
   means 44 px (the notch inset), not 12 + 44 = 56 px — stable across
   devices, consistent with /sat. */
@media (display-mode: standalone), (display-mode: fullscreen), (display-mode: minimal-ui) {
  .cm-topbar {
    padding-top: max(12px, env(safe-area-inset-top, 0px));
    padding-left: max(20px, env(safe-area-inset-left, 0px));
    padding-right: max(20px, env(safe-area-inset-right, 0px));
  }
  .cm-panel--controls {
    padding-bottom: max(28px, env(safe-area-inset-bottom, 0px));
  }
}

@media (display-mode: standalone) and (max-width: 820px),
       (display-mode: fullscreen) and (max-width: 820px),
       (display-mode: minimal-ui) and (max-width: 820px) {
  .cm-panel--map .leaflet-top.leaflet-left {
    /* Notched iPhone PWA: inherit the same --map-edge-pad + --search-h +
       --stack-gap stack, but floor padding-top at env() so the stack
       never slips under the notch. */
    padding-top: max(
      calc(var(--map-edge-pad) + var(--search-h) + var(--stack-gap)),
      env(safe-area-inset-top, 0px)
    );
    padding-left: max(var(--map-edge-pad), env(safe-area-inset-left, 0px));
  }

  .cm-panel--controls,
  .cm-layout.is-panel-collapsed .cm-panel--controls {
    padding-left: max(18px, env(safe-area-inset-left, 0px));
    padding-right: max(18px, env(safe-area-inset-right, 0px));
    padding-bottom: max(18px, env(safe-area-inset-bottom, 0px));
  }

  .cm-coords-bar {
    bottom: max(64px, calc(56px + env(safe-area-inset-bottom, 0px)));
  }
}

/* Fetch / Download row — inside the sidebar, stretch full-width instead of
   the legacy right-aligned half-row. Primary CTA gets the whole row when
   Download is hidden (step 1); when both buttons are visible they split
   50/50 via flex. The legacy grid rule at line ~2030 was forcing two
   tracks regardless of visibility, so with Download hidden the Fetch
   button ended up in the left column of a grid that was itself pushed
   right by .control-footer's align-self:end. */
.cm-panel--controls .control-footer {
  align-self: stretch;
}

.cm-panel--controls .action-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-self: stretch;
}

.cm-panel--controls .action-row > button {
  flex: 1 1 0;
  min-width: 0;
  width: auto;
}

/* ---- Section headings + CTA scaled down (user flagged as too heavy).
       Earlier the section-card-label was 0.72rem + 800 weight +
       0.14em letter-spacing, plus an 18 px icon — which together read
       as a "shouty" all-caps badge taking up more visual weight than
       the form fields below. Same story for the 0.92rem / 50 px
       Fetch Data button. Trimmed to a calm label + standard-size CTA
       that doesn't dominate the panel. */
.cm-panel--controls .section-card-label {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: #6b7990;
  gap: 6px;
}

.cm-panel--controls .section-card-label svg {
  width: 13px;
  height: 13px;
  opacity: 0.75;
}

.cm-panel--controls #fetch-btn,
.cm-panel--controls .button-secondary {
  min-height: 40px;
  padding: 9px 14px;
  border-radius: 11px;
  font-family: "Manrope", "Inter", sans-serif;
  font-size: 0.82rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  box-shadow: 0 6px 14px rgba(66, 84, 209, 0.14);
}

.cm-panel--controls #fetch-btn:hover {
  box-shadow: 0 8px 18px rgba(66, 84, 209, 0.2);
}

/* "Tümünü Seç / Clear All" chip-action — trimmed so it sits as a
   supporting utility, in scale with the new smaller chips. */
.cm-panel--controls .chip-actions button.chip-action {
  font-size: 0.72rem;
  padding: 5px 11px;
  letter-spacing: 0.01em;
  min-height: 28px;
}

/* Dataset chips — shrunk a tick so they read as a dense selection list
   and visually harmonise with the smaller Fetch CTA + form inputs. */
.cm-panel--controls .chips .chip {
  padding: 7px 10px;
  font-size: 0.78rem;
  line-height: 1.35;
  gap: 8px;
  border-radius: 10px;
}

.cm-panel--controls .chips .chip input {
  width: 15px;
  height: 15px;
  border-radius: 5px;
  border-width: 1.5px;
}

.cm-panel--controls .chips .chip input::after {
  width: 8px;
  height: 5px;
  border-left-width: 2.5px;
  border-bottom-width: 2.5px;
}

/* Field labels inside the form — slightly toned so the heading↔field
   hierarchy still reads at the new lighter label weight. */
.cm-panel--controls .field-label {
  font-size: 0.76rem;
  font-weight: 600;
  color: #31405d;
}

/* ---- Date / Period / GDD form row — ported 1:1 from /sat's .date-row.
       Previous climate markup wrapped each input in .field-stack >
       .input-field with a decorative .input-glyph SVG and several
       variant classes (.input-field--date/select/number, .gdd-field);
       those legacy abstractions had drifted over time so every cell
       rendered a different size. The new markup is the sat shape:

           <div class="cm-date-row">
             <label>
               <span>label text</span>
               <input type="date">
             </label>
             ...
           </div>

       Two cells per row, identical styling, native OS widgets handle
       their own icons. 130 px auto-fit minmax means Start/End and
       Period/GDD stay side-by-side above ~280 px of inner width and
       drop to a new row below that — matches sat's behaviour. ---- */
.cm-panel--controls .cm-date-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 8px;
}

.cm-panel--controls .cm-date-row + .cm-date-row {
  margin-top: 10px;
}

.cm-panel--controls .cm-date-row label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  color: #4a6048;
  letter-spacing: 0;
  text-transform: none;
  min-width: 0;
  overflow: hidden;
  margin: 0;
}

.cm-panel--controls .cm-date-row input,
.cm-panel--controls .cm-date-row select {
  /* !important defeats the four generic `input:not([type=checkbox])` rules
     scattered across the legacy sheet that all set 0.95rem (~15.2 px) and
     would otherwise tie us on specificity and win on source order. */
  font-family: "Inter", "Segoe UI", sans-serif !important;
  font-size: 13px !important;
  font-weight: 500 !important;
  line-height: 1 !important;
  padding: 7px 8px !important;
  border: 1px solid #c4d0bf !important;
  border-radius: 8px !important;
  background: #fafcf8 !important;
  color: #1f2f22 !important;
  width: 100% !important;
  max-width: 100% !important;
  min-width: 0 !important;
  height: 34px !important;
  min-height: 0 !important;
  margin: 0 !important;
  box-sizing: border-box !important;
  box-shadow: none !important;
  font-variant-numeric: tabular-nums !important;
  text-align: left !important;
}

/* Chrome / Edge native date-picker sub-parts — the text of "01-Apr-2025"
   is rendered by an internal shadow DOM (::-webkit-datetime-edit and its
   children). Without this block the value renders at Chrome's internal
   system font (~15-16 px on Windows) regardless of what we set on the
   <input> itself — that's why Start/End looked huge while the neighbouring
   <select>'s "Daily" text respected our CSS. Style every segment (year,
   month, day, separators, wrapper) and the font sticks. */
.cm-panel--controls .cm-date-row input[type="date"]::-webkit-datetime-edit,
.cm-panel--controls .cm-date-row input[type="date"]::-webkit-datetime-edit-fields-wrapper,
.cm-panel--controls .cm-date-row input[type="date"]::-webkit-datetime-edit-text,
.cm-panel--controls .cm-date-row input[type="date"]::-webkit-datetime-edit-year-field,
.cm-panel--controls .cm-date-row input[type="date"]::-webkit-datetime-edit-month-field,
.cm-panel--controls .cm-date-row input[type="date"]::-webkit-datetime-edit-day-field,
.cm-panel--controls .cm-date-row input[type="date"]::-webkit-datetime-edit-hour-field,
.cm-panel--controls .cm-date-row input[type="date"]::-webkit-datetime-edit-minute-field {
  font-family: "Inter", "Segoe UI", sans-serif !important;
  font-size: 13px !important;
  font-weight: 500 !important;
  color: #1f2f22 !important;
  padding: 0 !important;
  line-height: 1 !important;
}

.cm-panel--controls .cm-date-row input:hover,
.cm-panel--controls .cm-date-row select:hover {
  border-color: #0f4d2a;
}

.cm-panel--controls .cm-date-row input:focus,
.cm-panel--controls .cm-date-row select:focus {
  border-color: #0f4d2a;
  box-shadow: 0 0 0 2px rgba(15, 77, 42, 0.14);
  outline: 0;
}

.cm-panel--controls .cm-date-row select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  padding-right: 22px;
  background-image:
    linear-gradient(45deg, transparent 50%, #6b7990 50%),
    linear-gradient(135deg, #6b7990 50%, transparent 50%);
  background-position:
    calc(100% - 11px) 50%,
    calc(100% - 7px) 50%;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
  cursor: pointer;
}

/* Native date indicator — visible icon at a consistent 13 px. */
.cm-panel--controls .cm-date-row input[type="date"]::-webkit-calendar-picker-indicator {
  width: 14px;
  height: 14px;
  padding: 0;
  margin-left: 4px;
  opacity: 0.55;
  cursor: pointer;
}

/* All legacy `.input-field` / `.field-stack` / `.input-glyph` / `.input-unit`
   / `.date-range-group` / `.period-gdd-group` / `.date-field` / `.gdd-field`
   / `.field-label` rules removed 2026-04-20: after porting the form markup
   to the sat-style `<div class="cm-date-row"><label><span>…</span><input></label>`
   shape, none of those classes appear in the HTML any more. The sole source
   of truth for the form now lives in the `.cm-date-row` block above. */

/* Respect reduced-motion preferences on all transitions. */
@media (prefers-reduced-motion: reduce) {
  .cm-layout,
  .cm-panel--controls,
  .cm-panel-toggle,
  .cm-panel-toggle svg,
  .sheet-handle-chevron {
    transition: none !important;
  }
}

/* ============================================================================
   Loading overlay — corporate / professional restrain. The legacy card was
   28 px radius, 44×52 padding, 56 px spinner, a heavy blue gradient body,
   a 32 px-blur shadow, and a scale+translate entrance. Too "loud" for a
   corporate dashboard. This block shrinks it to: white card, 14 px radius,
   brand-green spinner, subtle 12 px shadow, simple fade-in. Mobile and
   desktop share the same visual — no breakpoint diff. ========================= */
/* Loading overlay — corporate polish (2026-04-20).
   Previous card mixed fluffy scale-in + blue accent blur. Trimmed to a
   minimal enterprise pattern: crisp white sheet with a 2 px brand-green
   ribbon across the top edge, tighter proportions, Manrope label in
   brand green. Scrim slightly darker so the card reads as a focused
   modal, not a soft fog. */
.loading-overlay {
  background: rgba(12, 28, 20, 0.34) !important;
  backdrop-filter: blur(4px) saturate(1.05) !important;
  -webkit-backdrop-filter: blur(4px) saturate(1.05) !important;
  padding: 24px !important;
  transition: opacity 0.2s ease, visibility 0.2s ease !important;
}

.loading-overlay .loading-card {
  display: grid !important;
  gap: 12px !important;
  justify-items: center !important;
  padding: 20px 26px !important;
  border-radius: 10px !important;
  border: 1px solid rgba(15, 77, 42, 0.10) !important;
  background: #ffffff !important;
  box-shadow: 0 18px 44px rgba(15, 30, 20, 0.20),
              0 1px 0 rgba(15, 77, 42, 0.04) !important;
  max-width: min(86vw, 300px) !important;
  text-align: center !important;
  transform: translateY(4px) !important;
  opacity: 0 !important;
  transition: opacity 0.2s ease, transform 0.2s ease !important;
}

.loading-overlay.is-active .loading-card {
  transform: translateY(0) !important;
  opacity: 1 !important;
}

.loading-overlay .loading-indicator {
  width: 28px !important;
  height: 28px !important;
}

.loading-overlay .loading-spinner {
  width: 28px !important;
  height: 28px !important;
  border-width: 2px !important;
  border-color: rgba(15, 77, 42, 0.12) !important;
  border-top-color: #0f4d2a !important;
  animation-duration: 0.75s !important;
}

.loading-overlay .loading-icon {
  width: 22px !important;
  height: 22px !important;
}

.loading-overlay .loading-icon--success { color: #0f4d2a !important; }
.loading-overlay .loading-icon--error { color: #a1361f !important; }

.loading-overlay .loading-text {
  font-family: "Manrope", "Inter", "Segoe UI", sans-serif !important;
  font-size: 0.82rem !important;
  font-weight: 600 !important;
  color: #0f4d2a !important;
  letter-spacing: 0.01em !important;
  line-height: 1.4 !important;
  font-variant-numeric: tabular-nums !important;
}

@media (prefers-reduced-motion: reduce) {
  .loading-overlay,
  .loading-overlay .loading-card {
    transition: none !important;
  }
  .loading-overlay .loading-spinner {
    animation: none !important;
  }
}

/* ============================================================================
   Tap-highlight / focus-ring shape consistency (2026-04-20).

   Bug: on iOS Safari + some Android Chromium builds the default tap flash
   (`-webkit-tap-highlight-color`) is painted as a BOUNDING-BOX rectangle
   that ignores `border-radius` on certain element types — even when the
   button itself is a 999 px pill or a 10 px-radius chip. Also the default
   `:focus` outline is a thin rectangle that clashes with rounded corners
   when a user taps (some UAs fire :focus on touch). Both together produced
   the "şekli eğri ama flaşı dik köşeli" look the user reported.

   Fix (belt-and-braces):
   1. Zero the tap-highlight on every interactive surface, so the native
      flash never appears. Hover / :active CSS already covers the feedback
      and those DO respect border-radius because they paint through the
      element itself.
   2. Suppress the default focus ring on mouse/touch (still present for
      keyboard via :focus-visible).
   ============================================================================ */
a,
button,
label.chip,
input[type="checkbox"],
input[type="radio"],
select,
[role="button"],
[role="link"] {
  -webkit-tap-highlight-color: transparent;
}

/* Kill the rectangular outline that browsers draw on :focus when the focus
   was gained via pointer (not keyboard). :focus-visible is keyboard-only
   on modern browsers — it still fires for keyboard users, so accessibility
   is preserved. */
a:focus:not(:focus-visible),
button:focus:not(:focus-visible),
label.chip:focus:not(:focus-visible),
select:focus:not(:focus-visible),
[role="button"]:focus:not(:focus-visible) {
  outline: none;
}

/* Extend the touch-device hover-suppression to every remaining interactive
   element so :hover CSS never "sticks" post-tap on phones/tablets. */
@media (hover: none) and (pointer: coarse) {
  /* Note: .cm-shell .lang-switch .lang-btn is intentionally OMITTED here —
     its hover tint matches the :active tint so the effect is
     indistinguishable from the press feedback; keeping :hover active on
     touch gives the user a crisp on-tap visual confirmation. Removing it
     from the reset is what brought mobile TR/EN parity with desktop. */
  .chip:hover,
  .chip-action:hover,
  #fetch-btn:hover,
  .button-secondary:hover,
  .cm-coords-cell input:hover,
  .cm-panel--map .leaflet-control-zoom a:hover,
  .search-dropdown-item:hover {
    background: inherit;
    color: inherit;
    transform: none;
    box-shadow: none;
    filter: none;
    border-color: inherit;
  }
}

/* ============================================================================
   CROSS-BROWSER / MOBILE AUDIT (Step 4 — görsel kılcal polish)
   ============================================================================ */

/* BUG FIX — the legacy `.shell { max-width: 1360px; padding: ~50px }` rule
   was turning the whole app into a centred "card" on wide monitors,
   cropping the layout at ~1280 px usable width with blue gutters on the
   sides. The new app-shell layout fills the viewport — lift the cap and
   kill the outer padding so the map + sidebar use every pixel. */
.cm-shell {
  max-width: none;
  width: 100%;
  padding: 0;
  margin: 0;
}

/* Touch-device hover suppression — hover styles otherwise STICK after tap
   on phones/tablets (the last-tapped element keeps its hover bg until
   another element is tapped). Only apply hover transforms + colour
   shifts on devices that can actually hover. */
@media (hover: none) and (pointer: coarse) {
  .cm-panel-toggle:hover,
  .cm-basemap-btn:hover:not([aria-pressed="true"]),
  .cm-back-link:hover,
  .cm-gps-btn:hover,
  .cm-map-search:focus-within {
    /* Reset to base so the "sticky hover" never shows a hint the user
       didn't ask for. Taps still get :active feedback separately.
       .lang-btn is already gated behind @media (hover: hover), so it
       doesn't need resetting here. */
    background: inherit;
    box-shadow: none;
    transform: none;
  }

  /* Keep the basemap active (aria-pressed=true) state visible even on
     touch — that's state feedback, not hover. */
  .cm-basemap-btn[aria-pressed="true"] {
    background: #0f4d2a !important;
    color: #fff !important;
  }
}

/* Native widget consistency — number inputs render a pair of spinner
   buttons on Chromium/Edge/Firefox that look different on each browser
   and are nearly invisible at our small sizes. The spinner also catches
   touch events, producing an accidental +/- tap when a user scrolls
   through the form. Hide them globally inside the sidebar. */
.cm-panel--controls input[type="number"]::-webkit-outer-spin-button,
.cm-panel--controls input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.cm-panel--controls input[type="number"] { -moz-appearance: textfield; }

/* Placeholder colour — Firefox defaults to 0.54 opacity which reads as a
   broken/faded placeholder on our light background. Opacity:1 + explicit
   color keeps it consistent across Firefox / Chromium / WebKit. */
.cm-panel--controls input::placeholder,
.cm-map-search input::placeholder,
.cm-coords-bar input::placeholder {
  color: #8a9a8f;
  opacity: 1;
}

/* iOS momentum scrolling — without -webkit-overflow-scrolling, Safari
   iOS scrolls the sidebar with a jerky non-inertial feel. The new `touch`
   value restores the native flick-and-glide momentum. */
.cm-panel--controls {
  -webkit-overflow-scrolling: touch;
}

/* Tabular numerals on all numeric displays — date inputs, coords, any
   value that benefits from aligned digits. Prevents the widget width
   from jittering character-by-character as values change. */
.cm-coords-cell input,
#start-date,
#end-date,
#gdd-base {
  font-variant-numeric: tabular-nums;
}

/* Tap-target minimum on mobile — iOS HIG + Material both recommend 44×44
   for primary touch targets. The back link and GPS button stay icon-only
   (26-32 px visual) but their full button extent meets the floor via
   padding. */
@media (pointer: coarse) {
  .cm-back-link {
    min-width: 40px;
    min-height: 40px;
  }
  .cm-gps-btn {
    min-width: 34px;
    min-height: 34px;
  }
}

/* Windows High-Contrast / forced-colors mode — ensure the brand bar and
   active states still surface their meaning when the user's OS overrides
   colours. Without these, the green topbar becomes invisible against the
   forced-white background. */
@media (forced-colors: active) {
  .cm-topbar {
    border-bottom: 1px solid CanvasText;
  }
  .cm-basemap-btn[aria-pressed="true"] {
    forced-color-adjust: none;
    background: Highlight !important;
    color: HighlightText !important;
  }
  .cm-panel-toggle,
  .sheet-handle,
  .cm-gps-btn,
  .cm-back-link {
    forced-color-adjust: auto;
  }
}

/* Print — hide every map-chrome widget so a user printing a chart page
   doesn't waste ink on pills and the sheet handle. The sidebar + chart
   stack is what's worth printing. */
@media print {
  .cm-topbar,
  .cm-panel-toggle,
  .sheet-handle,
  .cm-map-search,
  .cm-coords-bar,
  .cm-panel--map .leaflet-top,
  .cm-panel--map .leaflet-bottom,
  #loading-overlay,
  #install-guide,
  #install-guide-backdrop {
    display: none !important;
  }
  .cm-layout {
    display: block !important;
  }
  .cm-panel--controls {
    overflow: visible !important;
    max-height: none !important;
    position: static !important;
    height: auto !important;
    border-right: 0;
    padding: 16px !important;
  }
  .cm-panel--map { display: none !important; }
}

/* z-index stack contract (documented once for sanity):
   - topbar:         1500
   - bottom sheet:   1200  (above Leaflet controls ~1000)
   - panel-toggle:    600
   - map overlays
     (search / coords / basemap / zoom): 650
   - loading overlay:  10000
   - install guide:    keeps its own internal z-index (5000+)
   No element in the app re-declares a z-index outside this contract. */

/* Chart container inside the sidebar — contain: layout keeps Chart.js
   canvas resize from triggering a full page reflow; that was noticeable
   during Fetch when the chart first appears and the sidebar scrollbar
   would briefly flash. */
.cm-panel--controls #panel-chart {
  contain: layout paint;
}

/* Reduced-motion — extend the block from earlier so Chart.js canvas
   transitions and hover effects also respect the preference. Chart.js
   itself obeys Chart.defaults.animation via our config, but the
   container-level CSS here catches any residual browser animations. */
@media (prefers-reduced-motion: reduce) {
  .cm-map-search,
  .cm-coords-bar,
  .cm-basemap-switch,
  .cm-gps-btn,
  .cm-gps-btn svg,
  .cm-back-link,
  .cm-shell .lang-switch .lang-btn,
  .loading-overlay,
  .loading-card,
  #panel-chart,
  #panel-chart.is-hidden {
    transition: none !important;
    animation: none !important;
  }
}
