/* ── WELTKLIMA-EXPLORER — Kartenebenen & Bedienung ─────────────────────────
   Gehoert zu js/render/region-selector.js und den Ebenen, die es zusammensetzt:
     js/land-layer.js      Landmassen + Kuestenlinie
     js/koeppen-layer.js   Klimazonen-Flaechen
     js/terminator.js      Tag/Nacht-Grenze
     js/weather-layer.js   Niederschlag (NASA GIBS)
     js/wx-playback.js     24-h-Schleife
   AUS prototype.css AUSGELAGERT (800-Zeilen-Limit) — dieselbe Trennung wie bei
   css/sim-tab.css. prototype.css war mit diesem Block bei 822 Zeilen.
   Verlinkt in index.html NACH prototype.css. */

/* ── WELTKLIMA-EXPLORER (render/region-selector.js) ───────────────────────── */
.klima-card { margin-bottom: 0; }
.klima-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; margin-bottom: 16px; }
.klima-title { font-size: 15px; font-weight: 700; }
.klima-desc { font-size: 12px; color: var(--text-dim); margin-top: 3px; }
.klima-badge {
  flex-shrink: 0; font-size: 9px; font-weight: 700; font-family: var(--mono); text-transform: uppercase; letter-spacing: .05em;
  background: var(--sand-bg); color: var(--orange); border: 1px solid var(--sand-lt); border-radius: 999px; padding: 4px 10px; white-space: nowrap;
}
.klima-badge.pulse { animation: klimaPulse .9s ease; }
@keyframes klimaPulse { 50% { transform: scale(1.08); background: var(--sand); color: #fff; } }

/* 5 Regionen NEBENEINANDER */
.klima-chips { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; }
.klima-chip {
  display: flex; flex-direction: column; gap: 3px; text-align: left; cursor: pointer; font-family: var(--sans); color: var(--text);
  background: var(--surface2); border: 1px solid var(--border); border-radius: 12px; padding: 12px;
  transition: transform .18s ease, border-color .18s ease, background .18s ease;
}
.klima-chip:hover { transform: translateY(-2px); border-color: var(--sand); background: var(--sand-bg); }
.klima-chip.is-current { border-color: var(--green); background: var(--green-bg); }
/* Eingerastete Zone: bleibt sichtbar aktiv (per Klick ODER durch Stadtauswahl). */
.klima-chip.is-locked {
  border-color: var(--green); background: var(--green-bg);
  box-shadow: inset 0 0 0 2px var(--green), 0 4px 12px rgba(61,107,79,.18);
}
.klima-chip.is-locked::after {
  content: '🔒 eingerastet'; position: absolute; top: 6px; right: 8px;
  font-size: 8px; font-family: var(--mono); font-weight: 700; color: var(--green);
}
.klima-chip { position: relative; }
.klima-chip-top { display: flex; align-items: center; justify-content: space-between; }
.klima-chip-flag { font-size: 20px; }
.klima-chip-z { font-family: var(--mono); font-size: 10px; font-weight: 700; color: #fff; border-radius: 4px; padding: 1px 6px; }
.klima-chip-name { font-size: 13px; font-weight: 700; margin-top: 5px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.klima-chip-tag { font-size: 8px; text-transform: uppercase; letter-spacing: .04em; background: var(--green); color: #fff; border-radius: 3px; padding: 1px 5px; }
.klima-chip-sub { font-size: 11px; color: var(--text-dim); }
.klima-chip-stats { display: flex; gap: 10px; margin-top: 8px; font-family: var(--mono); font-size: 10px; color: var(--text-dim); }

/* Karten-Toggle */
.klima-map-toggle {
  width: 100%; margin-top: 14px; padding: 11px 14px; border-radius: 10px; cursor: pointer;
  border: 1px dashed var(--border); background: var(--surface); color: var(--text);
  font-family: var(--sans); font-size: 13px; font-weight: 700;
  display: flex; align-items: center; justify-content: center; gap: 8px; transition: all .18s ease;
}
.klima-map-toggle:hover { border-color: var(--green); color: var(--green); background: var(--green-bg); border-style: solid; }
.klima-map-toggle[aria-expanded="true"] { border-style: solid; border-color: var(--green); color: var(--green); background: var(--green-bg); }
.klima-caret { font-size: 10px; transition: transform .2s ease; }
.klima-map-toggle[aria-expanded="true"] .klima-caret { transform: rotate(180deg); }

/* Karte */
.klima-map { margin-top: 14px; }
.klima-map[hidden] { display: none; }
.klima-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 10px; }
.klima-toolbar-hint { font-size: 11px; color: var(--text-dim); }
.klima-weather-toggle { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 600; color: var(--text-dim); cursor: pointer; }

.klima-map-frame { position: relative; border: 1px solid var(--border); border-radius: 12px; overflow: hidden; background: #EAF0EC; }
/* ── MATT & SEPIA, EINHEITLICH (Nutzer-Wunsch) ─────────────────────────────
   EIN Farbfilter ueber die GESAMTE Kartengruppe (das ganze SVG), damit alles
   wie aus einem Guss wirkt: die fotografische NASA-Basemap, die knalligen
   Koeppen-Standardfarben und der Terminator werden GEMEINSAM in warme, matte
   Erdtoene gedaempft. Die HTML-Bedienelemente (Suche, Zeit, Legende, Ort-Info)
   liegen AUSSERHALB des SVG und bleiben bewusst neutral/scharf.
   Werte getunt: sepia waermt, saturate nimmt das Knallige, brightness/contrast
   halten es matt statt flau. Tag/Nacht-Lesbarkeit visuell gegengeprueft. */
.klima-svg {
  display: block; width: 100%; height: auto;
  filter: sepia(0.34) saturate(0.78) brightness(1.03) contrast(0.92);
  cursor: grab; touch-action: none;
}
.klima-svg:active { cursor: grabbing; }
/* Basemap-Bilder tragen keine Pointer-Events — Ziehen faellt auf sie durch,
   Pins darueber bleiben klickbar. */
.klima-basemap image { pointer-events: none; }
.klima-ocean { fill: #DCE7E4; }
.klima-grid line { stroke: rgba(28,43,30,.10); stroke-width: .6; }
.klima-grid .klima-eq { stroke: rgba(28,43,30,.28); stroke-width: 1; stroke-dasharray: 5 4; }

/* ── ECHTE LANDMASSEN (js/land-layer.js) ───────────────────────────────────
   Die unterste Landebene. Es gab sie vorher NICHT: `#coastPath` hatte `fill:
   none`, sichtbares "Land" entstand allein aus den Koeppen-Zonen darueber — wo
   der Zonen-Datensatz nichts kannte, lag blanker Ozean.

   FARBE: ein heller, warmer Erdton knapp neben --bg (#F5F2EC) und --border
   (#E0D9CE). Er muss zwei Dinge zugleich: sich vom kuehlen Ozean (#DCE7E4)
   absetzen UND unter den halbdurchsichtigen Koeppen-Zonen (opacity .74)
   verschwinden, ohne deren wissenschaftliche Farben zu kippen. Vorher lag dort
   der Ozeanton — die Zonen standen also ohnehin schon auf einem Untergrund;
   dieser hier ist nur der ehrlichere. */
/* Die frueher hier stehende `.klima-land path { fill:#E9E3D6 }` (Vektor-Landflaeche)
   ist ENTFERNT — das Kartenbild traegt jetzt die NASA-Basemap (js/basemap-layer.js).
   HIER LIEF KURZ `animation: landIn 1s ease-out backwards` (from{fill-opacity:0}).
   Sie ist RAUS — und zwar nicht aus Vorsicht, sondern nach einer Messung, die
   die Falle dieses Projekts ein drittes Mal gezeigt hat. Spur nach dem Öffnen:
       t=600 ms   is-drawn=false  fill-opacity=1  (keine Animation)
       t=1200 ms  is-drawn=true   fill-opacity=0  landIn:running@0
       t=2500 ms  is-drawn=true   fill-opacity=0  landIn:running@0   <- Uhr steht
       t=4000 ms  is-drawn=true   fill-opacity=1  (fertig)
   `running@0` über 1,3 s heißt: die Animationsuhr hängt am ersten Paint. Im
   sichtbaren Tab kostet das nur Verzögerung — in einem Tab, der NICHT zeichnet,
   startet sie nie, und `backwards` nagelt fill-opacity dauerhaft auf 0. Genau so
   sind hier schon die Klimazonen und der Wetter-Layer unsichtbar geworden.
   Die Landmasse ist die TRAGENDE Ebene der Karte — ohne sie ist die Welt leer.
   Sie hängt deshalb an keiner Animation. Leben bringen die Zonen (kzIn) und die
   Pins (pinIn); das Land erscheint, sobald es geladen ist (gemessen 1,6 s). */

/* Kuestenlinie = Aussenkante der Zonen, deshalb UEBER ihnen. fill bleibt none:
   die Flaeche traegt #landFill, hier ist nur die Kontur zuhause. */
.klima-coast path { fill: none; stroke: #1C2B1E; stroke-width: 1.1; stroke-opacity: .55; stroke-linejoin: round; }

/* ── LEBENDE KARTE: organisch + hightech (nur transform/opacity) ──────────── */
/* ── ECHTE KOEPPEN-ZONEN (js/koeppen-layer.js) ─────────────────────────────
   Ersetzt die frueheren Breitengrad-Baender (.klima-zone) und den Deko-Filter
   (.klima-wx/wxPulse). Die Fuellfarben sind der wissenschaftliche Standard
   (Peel et al. 2007) und werden NICHT umgefaerbt — ins Erdton-Design gebunden
   wird ueber die Deckkraft hier, damit die Karte gegen eine Publikation
   vergleichbar bleibt.

   DREI EBENEN, je EINE Zustaendigkeit. Grund: @keyframes schlagen in der Kaskade
   jede normale Deklaration. Lagen Atem-Animation und Fokus-Dimmer auf DEMSELBEN
   Element (so war es vorher), gewann immer die Animation — der data-focus-Dimmer
   der Zonen war dadurch wirkungslos. Getrennte Elemente multiplizieren ihre
   Opazitaeten sauber, statt sich zu ueberschreiben. */
.klima-zones { opacity: 1; transition: opacity .45s ease; }          /* An/Aus */
.klima-zones.is-off { opacity: 0; pointer-events: none; }
/* Deckkraft bewusst gesenkt (war .74): die echte NASA-Basemap soll UNTER den
   Zonen durchscheinen, damit "echte Kontinente" und Klimazonen zusammen matt und
   einheitlich wirken statt die Zonen die Fotografie zupflastern. */
.klima-zones-live { opacity: .62; animation: zoneBreath 11s ease-in-out infinite; } /* Atmen */
@keyframes zoneBreath { 0%,100% { opacity: .58; } 50% { opacity: .66; } }
.klima-kz { opacity: 1; transition: opacity .25s ease; }             /* Fokus/Dimmen */
.klima-kz path { stroke: none; }
/* ── kzIn ENTFERNT (die "Animationsfalle" — zum VIERTEN Mal dieselbe Klasse) ──
   HIER STAND:
     .klima-map.is-drawn .klima-kz path { animation: kzIn .9s ease-out backwards; }
     @keyframes kzIn { from { fill-opacity: 0; } }
   Dieselbe Falle wie zuvor bei landIn, wxIn und drawCoast: Einblende-Animation
   und der tragende Grundwert (fill-opacity:1, Default) liegen auf DEMSELBEN
   Element. `backwards` legt den from-Wert (fill-opacity:0) schon VOR dem Start
   an. `is-drawn` wird per requestAnimationFrame gesetzt — feuert der rAF nicht
   (Tab war beim Oeffnen nicht sichtbar / Uhr haengt am ersten Paint), startet die
   Animation nie und nagelt die Zonen DAUERHAFT auf fill-opacity 0 = unsichtbar,
   ohne Fehler. Genau so sind hier schon Land und Wetter verschwunden.
   Die Zonen sind eine TRAGENDE Ebene und haengen deshalb an keiner Animation
   mehr: sie erscheinen mit .klima-zones (opacity, Transition) sobald gerendert,
   und leben ueber zoneBreath (opacity, ohne `backwards` -> faellt hoechstens auf
   den Grundwert .74 zurueck, nie auf 0). Belegt: nach Tab-Wechsel + Rueckkehr
   bleibt fill-opacity/opacity > 0. */

/* Glimmende Küsten */
.klima-coast { animation: coastGlow 7s ease-in-out infinite; }
@keyframes coastGlow { 0%,100% { opacity: .75; } 50% { opacity: 1; } }

/* ── ECHTE TAG/NACHT-GRENZE (js/terminator.js) ────────────────────────────
   Ersetzt den frueheren Fake-Sweep (@keyframes sunSweep, 42 s von links nach
   rechts). Position kommt jetzt aus der Astronomie — DESHALB darf hier keine
   Animation mehr laufen: jede Verschiebung waere wieder gelogen.
   pointer-events:none haelt die Pins darunter anklickbar. */
.klima-daylight { pointer-events: none; }
/* Nacht = weicher Schatten (multiply), kein schwarzer Balken. */
.klima-night { fill: #16241C; opacity: .44; mix-blend-mode: multiply; }
/* Daemmerungssaum: warmer Rand genau auf der Grenze — leuchtet nur ueber der Nachtseite. */
.klima-term { fill: none; stroke: #F5D98B; stroke-width: 2.4; opacity: .55; }
.klima-sunglow circle { mix-blend-mode: soft-light; }

/* ── ECHTER WETTER-LAYER (js/weather-layer.js + js/wx-playback.js) ─────────
   NASA-GIBS-PNGs (1000x500 = die viewBox). Die Fuellfarben sind wieder der
   Standard der Quelle und werden NICHT umgefaerbt — eingebunden wird ueber
   Deckkraft, damit Zonen und Kuesten darunter lesbar bleiben.
   Hier laeuft KEINE Positions-Animation: das Bild sitzt auf echten Koordinaten,
   jede Verschiebung waere gelogen (gleiche Regel wie beim Terminator). Bewegung
   entsteht ausschliesslich durch den Frame-Wechsel an der Zeitachse.
   pointer-events:none haelt die Pins darunter anklickbar.

   DREI EBENEN, je EINE Zustaendigkeit — dieselbe Lehre wie bei den Koeppen-Zonen.

   HIER STAND `animation: wxIn .5s` (weiches Erscheinen beim Frame-Wechsel). Sie
   ist ersatzlos weg, aus ZWEI Gruenden:
   1. Ihre Aufgabe war es, den harten 30-min-Frame-Wechsel zu kaschieren. Genau
      das macht jetzt die echte Kreuzblende — und zwar richtig.
   2. Sie war eine LATENTE FALLE, live nachgemessen: liegt `opacity: .82` und
      `animation: wxIn` (from{opacity:0}) auf DEMSELBEN Element, ueberschattet der
      Startwert der Animation den Grundwert. Startet die Animation nie — und das
      tut sie nicht, wenn erst ein VORFAHRE von display:none auf sichtbar geht —,
      bleibt die Ebene dauerhaft auf opacity 0, also unsichtbar. Gemessen:
      mit Animation 0, ohne Animation 0.82, getAnimations() leer.
   Kurz: keine @keyframes auf ein Element, das auch einen tragenden Wert haelt. */
.klima-wx { pointer-events: none; }
/* Grunddeckkraft + Isolation. isolation/opacity sind hier PFLICHT, nicht Deko:
   sie sperren das plus-lighter der oberen Bildebene in diese Gruppe ein — sonst
   addierte die Blende sich in die Karte darunter und liesse sie ausbleichen. */
.klima-wx-stack { opacity: .82; isolation: isolate; }
/* Die Bilder tragen NUR die Blende, geschrieben aus wxPaintPair(). Keine
   Animation, keine Transition — beides wuerde die Blende ueberschreiben bzw.
   ihr hinterherhinken (die Blende IST schon die Animation, 25x/s aus der Uhr). */
#klima-wx-a, #klima-wx-b { will-change: opacity; }

/* Ladebalken am unteren Kartenrand: der Fortschritt gehoert IN die Karte, nicht
   in ein sechstes Bedienfeld. 3 px hoch — er soll die Karte begleiten, nicht
   sie moderieren. Die Stueckzahl steht im Badge, das ohnehin schon da ist. */
.klima-wx-load-bg { fill: #16241C; opacity: .12; }
.klima-wx-load-fill { fill: var(--sand); opacity: .95; }

/* Badge im Zeit-Chip: der kompakte Dauerzustand. Alles Weitere steht im Panel. */
.klima-wx-badge {
  font-size: 8px; font-weight: 700; letter-spacing: .04em; font-family: var(--mono);
  background: #3F3DD5; color: #fff; border-radius: 3px; padding: 1px 5px; white-space: nowrap;
}
.klima-wx-badge[hidden] { display: none; }
.klima-wx-badge.is-lag { background: var(--sand); color: #16241C; }
.klima-wx-badge.is-off { background: var(--surface2); color: var(--text-dim); }
.klima-wx-badge.is-load { background: var(--sand-lt); color: #16241C; animation: wxPulse 1.1s ease-in-out infinite; }
.klima-wx-badge.is-loop { background: var(--green); color: #fff; }
@keyframes wxPulse { 50% { opacity: .45; } }

/* Legende: sitzt im Zeit-Panel (der Frame-Zeitstempel IST eine Zeitangabe) und
   nimmt der Karte keine fuenfte Ecke weg. Zwei Skalen, weil der Datensatz zwei
   hat — blau ist SCHNEE, nicht Regen. */
.klima-wx-legend {
  display: flex; flex-direction: column; gap: 5px;
  border-top: 1px solid var(--surface2); padding-top: 7px;
}
.klima-wx-legend[hidden] { display: none; }
.klima-wx-legend.is-off .klima-wx-scale { opacity: .32; }  /* kein Bild -> Skala ist gerade gegenstandslos */
.klima-wx-frame { font-size: 10px; color: var(--text); font-family: var(--mono); line-height: 1.4; }
.klima-wx-scale { display: flex; align-items: center; gap: 6px; }
.klima-wx-scale span { font-size: 9px; color: var(--text-dim); width: 34px; flex-shrink: 0; }
.klima-wx-scale i { flex: 1; height: 7px; border-radius: 999px; box-shadow: inset 0 0 0 1px rgba(28,43,30,.18); }
.klima-wx-scale b { font-family: var(--mono); font-size: 8px; color: var(--text-dim); white-space: nowrap; }
.klima-wx-src { font-family: var(--mono); font-size: 8px; color: var(--text-dim); }

/* ── DEZENTE OZEAN-ANIMATION (js/basemap-layer.js: oceanShimmerSvg) ─────────
   Weiche, SEHR langsam driftende Lichtflaechen, per soft-light ueber die
   Bathymetrie der NASA-Basemap gelegt und per Maske (oceanMask) strikt auf
   Wasser beschraenkt. Rein CSS -> laeuft auch im nicht zeichnenden Tab (keine
   rAF-Falle). "ganz ganz leicht" (O-Ton Nutzer): geringe Deckkraft, 42-58 s
   Periode, kein Wellen-Kitsch. */
.klima-shimmer { mix-blend-mode: soft-light; }
.klima-shimmer ellipse { fill: #CFE4FF; opacity: .28; animation: shimmerDrift 42s ease-in-out infinite; }
.klima-shimmer ellipse:nth-child(2) { animation-duration: 52s; animation-delay: -12s; }
.klima-shimmer ellipse:nth-child(3) { animation-duration: 46s; animation-delay: -24s; }
.klima-shimmer ellipse:nth-child(4) { animation-duration: 58s; animation-delay: -36s; }
@keyframes shimmerDrift {
  0%,100% { transform: translate(0,0) scale(1); opacity: .16; }
  50% { transform: translate(20px,-9px) scale(1.05); opacity: .36; }
}

/* Ambient-Partikel */
.klima-mote { fill: #FFFFFF; opacity: .5; animation: moteDrift 12s ease-in-out infinite; }
@keyframes moteDrift {
  0%,100% { transform: translate(0,0); opacity: .15; }
  50% { transform: translate(6px,-9px); opacity: .6; }
}
/* Beim Reinzoomen wuerden die Partikel (mit der viewBox vergroessert) zu Klecksen —
   sie verblassen deshalb, sobald die Karte gezoomt ist. */
.klima-motes { transition: opacity .3s ease; }
.klima-svg[data-zoomed] .klima-motes { opacity: 0; }

/* ── ZOOM-BEDIENUNG (js/render/region-selector.js: #klima-zoom) ────────────
   Sparsam, am freien linken Mittelrand — die vier Ecken gehoeren Suche, Zeit,
   Legende und Ort-Info. Hauptweg bleibt Mausrad + Ziehen. */
.klima-zoom {
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; gap: 5px; z-index: 3;
  opacity: .55; transition: opacity .18s ease;
}
.klima-map-frame:hover .klima-zoom, .klima-zoom.is-zoomed { opacity: 1; }
.klima-zoom-btn {
  width: 30px; height: 30px; border-radius: 8px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--sans); font-size: 16px; font-weight: 700; line-height: 1; color: var(--text);
  background: rgba(255,255,255,.9); border: 1px solid var(--border);
  box-shadow: 0 4px 12px rgba(0,0,0,.14); backdrop-filter: blur(3px);
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.klima-zoom-btn:hover { border-color: var(--green); color: var(--green); background: var(--green-bg); }
.klima-zoom-home { font-size: 14px; }

/* Lebende Pins */
.klima-pin-dot { animation: pinBreath 4.5s ease-in-out infinite; }
@keyframes pinBreath { 0%,100% { opacity: .85; } 50% { opacity: 1; } }

/* Zonen-Fokus über Chip (Lock A–E): trifft jetzt die ECHTEN Polygone. Die 31
   Codes ordnen sich über data-main (= erster Buchstabe) den Hauptzonen zu. */
.klima-svg[data-focus] .klima-kz { opacity: .12; }
.klima-svg[data-focus="A"] .klima-kz[data-main="A"],
.klima-svg[data-focus="B"] .klima-kz[data-main="B"],
.klima-svg[data-focus="C"] .klima-kz[data-main="C"],
.klima-svg[data-focus="D"] .klima-kz[data-main="D"],
.klima-svg[data-focus="E"] .klima-kz[data-main="E"] { opacity: 1; }

/* Einzelzonen-Hover (Karte ODER Legende): hebt genau einen Code heraus.
   :not(.is-hot) ist nötig, damit dieser Block dieselbe Spezifität (0,4,0) hat
   wie der Lock-Block darüber und als späterer Block gewinnt — sonst bliebe die
   gelockte Hauptzone beim Hovern mit hell stehen. Der Lock wird dabei nur
   überlagert, nicht zurückgesetzt: nach dem Hover greift er wieder. */
.klima-svg[data-kz-hot] .klima-kz:not(.is-hot) { opacity: .14; }
.klima-svg[data-kz-hot] .klima-kz.is-hot { opacity: 1; }
.klima-kz.is-hot path { stroke: #16241C; stroke-width: .9; stroke-opacity: .5; stroke-linejoin: round; }

.klima-svg[data-focus] .klima-pin { opacity: .25; }
.klima-svg[data-focus="A"] .klima-pin[data-zone="A"],
.klima-svg[data-focus="B"] .klima-pin[data-zone="B"],
.klima-svg[data-focus="C"] .klima-pin[data-zone="C"],
.klima-svg[data-focus="D"] .klima-pin[data-zone="D"],
.klima-svg[data-focus="E"] .klima-pin[data-zone="E"] { opacity: 1; }

/* Einblenden beim Öffnen.
   HIER STAND die "Selbstmal"-Animation der Küste:
     .klima-map.is-drawn .klima-coast path { stroke-dasharray: 1400; ... }
     @keyframes drawCoast { from { stroke-dashoffset: 1400; } to { ... 0; } }
   Sie ist ersatzlos entfernt — sie war für einen kurzen Pfad gedacht und hat auf
   einer echten Küstenlinie die Kontinente ZERSTÖRT. Im Browser nachgemessen
   (land-110m): Pfadlänge 14.272,6 px, nicht 1.400. Der dasharray blieb nach dem
   Ablauf stehen und ließ 3.447,4 px = 24,2 % der Küste DAUERHAFT verschwinden.
   SVG startet das Strichmuster je Subpfad neu — betroffen waren daher exakt die
   3 Subpfade über 1.400 px, also Afrika+Eurasien (−1.400 px), Amerika (−1.233 px)
   und die Antarktis (−814 px), während alle 126 Inseln ganz blieben.
   Eingeblendet wird jetzt die LANDFLÄCHE über fill-opacity (landIn, s. o.); die
   Küste ist deren Kante und kommt damit mit. Die Regel ist bewusst NICHT durch
   "dasharray = getTotalLength()" ersetzt: der Nutzer wollte die sich selbst
   malende Linie nicht, und ein dauerhafter dasharray auf diesem Pfad ist genau
   die Falle, die hier zweimal zugeschlagen hat. */
.klima-map.is-drawn .klima-pin { animation: pinIn .5s cubic-bezier(0.16,1,0.3,1) backwards; }
@keyframes pinIn { from { opacity: 0; transform: translateY(-6px) scale(.4); } }

/* Pins */
.klima-pin { cursor: pointer; transition: opacity .25s ease; }
.klima-pin-halo { fill: currentColor; opacity: 0; }
.klima-pin-dot { stroke: #fff; stroke-width: 1.2; transition: r .18s ease; }
.klima-pin:hover .klima-pin-dot, .klima-pin.is-active .klima-pin-dot { r: 6; }
.klima-pin:hover .klima-pin-halo, .klima-pin.is-active .klima-pin-halo { fill: var(--green); opacity: .22; animation: haloPulse 1.4s ease-in-out infinite; }
@keyframes haloPulse { 50% { opacity: .06; } }

.klima-pin-info {
  position: absolute; left: 12px; bottom: 12px; background: rgba(22,36,28,.92); color: #EAF2EC;
  border-radius: 10px; padding: 9px 13px; display: flex; flex-direction: column; gap: 2px; max-width: 62%;
  box-shadow: 0 6px 18px rgba(0,0,0,.25); backdrop-filter: blur(2px);
}
.klima-pin-hint { font-size: 11px; color: rgba(234,242,236,.7); }
.klima-pin-name { font-size: 13px; font-weight: 700; display: flex; align-items: center; gap: 7px; }
.klima-pin-meta { font-size: 10px; color: rgba(234,242,236,.6); font-family: var(--mono); }
.klima-pin-stats { font-size: 11px; font-family: var(--mono); margin-top: 3px; }
.klima-pin-stats em { font-style: normal; color: rgba(234,242,236,.5); font-size: 9px; }

/* ── STADTSUCHE — sitzt IN der Karte ─────────────────────────────────────── */
.klima-layers { display: flex; gap: 14px; align-items: center; }
.klima-search { position: absolute; top: 12px; left: 12px; width: min(340px, 55%); z-index: 3; }
.klima-search-bar {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 10px;
  background: rgba(255,255,255,.94); border: 1px solid var(--border);
  box-shadow: 0 6px 18px rgba(0,0,0,.14); backdrop-filter: blur(3px);
}
.klima-search-bar:focus-within { border-color: var(--green); box-shadow: 0 6px 20px rgba(61,107,79,.28); }
.klima-search-ico { font-size: 13px; opacity: .6; }
#klima-q { flex: 1; border: none; outline: none; background: transparent; font-family: var(--sans); font-size: 13px; color: var(--text); min-width: 0; }
.klima-q-clear { border: none; background: transparent; color: var(--text-dim); cursor: pointer; font-size: 12px; padding: 2px 4px; border-radius: 4px; }
.klima-q-clear:hover { background: var(--surface2); color: var(--text); }
.klima-results {
  margin-top: 6px; background: rgba(255,255,255,.97); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 26px rgba(0,0,0,.18); overflow: hidden; max-height: 240px; overflow-y: auto;
}
.klima-res { display: flex; flex-direction: column; gap: 1px; width: 100%; text-align: left; cursor: pointer;
  background: transparent; border: none; border-bottom: 1px solid var(--surface2); padding: 8px 12px; font-family: var(--sans); }
.klima-res:last-child { border-bottom: none; }
.klima-res:hover { background: var(--green-bg); }
.klima-res-n { font-size: 12px; font-weight: 700; color: var(--text); }
.klima-res-m { font-size: 10px; color: var(--text-dim); }
.klima-res-info { padding: 10px 12px; font-size: 11px; color: var(--text-dim); font-family: var(--mono); }

/* ── ZEITACHSE — sitzt IN der Karte, gegenueber der Suche, eingeklappt ───── */
.klima-time { position: absolute; top: 12px; right: 12px; width: min(250px, 40%); z-index: 3; }
.klima-time-chip {
  width: 100%; display: flex; align-items: center; gap: 7px; padding: 8px 10px; border-radius: 10px;
  background: rgba(255,255,255,.94); border: 1px solid var(--border);
  box-shadow: 0 6px 18px rgba(0,0,0,.14); backdrop-filter: blur(3px);
  font-family: var(--sans); font-size: 12px; font-weight: 600; color: var(--text);
  cursor: pointer; transition: border-color .18s ease, box-shadow .18s ease;
}
.klima-time-chip:hover { border-color: var(--green); box-shadow: 0 6px 20px rgba(61,107,79,.28); }
.klima-time-chip[aria-expanded="true"] { border-color: var(--green); }
.klima-time-chip[aria-expanded="true"] .klima-caret { transform: rotate(180deg); }
.klima-time-ico { font-size: 12px; opacity: .6; }
.klima-time-now { flex: 1; text-align: left; font-family: var(--mono); font-size: 11px; white-space: nowrap; }
.klima-time-live {
  font-size: 8px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  background: var(--green); color: #fff; border-radius: 3px; padding: 1px 5px;
}

.klima-time-panel {
  margin-top: 6px; padding: 11px 12px 10px; display: flex; flex-direction: column; gap: 9px;
  background: rgba(255,255,255,.97); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 26px rgba(0,0,0,.18);
}
.klima-time-panel[hidden] { display: none; }
.klima-time-row { display: flex; align-items: center; gap: 9px; }
.klima-time-row label {
  font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-dim); width: 26px; flex-shrink: 0;
}
.klima-time-row input[type="range"] {
  flex: 1; min-width: 0; height: 16px; cursor: pointer; accent-color: var(--green); background: transparent;
}
.klima-time-val {
  font-family: var(--mono); font-size: 10px; font-weight: 700; color: var(--text);
  width: 62px; text-align: right; flex-shrink: 0;
}
.klima-time-actions { display: flex; gap: 7px; }
.klima-time-btn {
  flex: 1; padding: 6px 8px; border-radius: 7px; cursor: pointer;
  font-family: var(--sans); font-size: 11px; font-weight: 700;
  background: var(--surface2); color: var(--text); border: 1px solid var(--border);
  transition: all .16s ease;
}
.klima-time-btn:hover { border-color: var(--green); color: var(--green); background: var(--green-bg); }
.klima-time-btn.tone-play.is-on { background: var(--green); border-color: var(--green); color: #fff; }
.klima-time-read { font-size: 10px; color: var(--text-dim); font-family: var(--mono); line-height: 1.4; }
.klima-time-sun {
  font-size: 10px; color: var(--text); font-family: var(--mono);
  border-top: 1px solid var(--surface2); padding-top: 7px;
}

/* Enger: Suche und Zeitachse duerfen sich nicht ueberlappen */
@media (max-width: 620px) {
  .klima-search { width: min(200px, 48%); }
  .klima-time { width: min(180px, 44%); }
  .klima-time-now { font-size: 10px; }
}

/* Gesuchter Standort: hervorgehobener Pin */
.klima-selpin-ring, .klima-selpin-ring2 { fill: none; stroke: var(--green); }
.klima-selpin-ring { stroke-width: 1.5; opacity: .5; animation: selPulse 2s ease-out infinite; }
.klima-selpin-ring2 { stroke-width: 2; opacity: .85; }
.klima-selpin-dot { fill: var(--green); stroke: #fff; stroke-width: 2; }
@keyframes selPulse { 0% { r: 8; opacity: .7; } 100% { r: 20; opacity: 0; } }

.klima-loc-z { font-family: var(--mono); font-size: 9px; font-weight: 700; color: #fff; border-radius: 4px; padding: 2px 6px; flex-shrink: 0; }
.klima-src { font-size: 10px; color: var(--text-dim); margin-top: 10px; font-family: var(--mono); }
.klima-live { font-size: 8px; font-weight: 700; letter-spacing: .05em; background: var(--green); color: #fff; border-radius: 3px; padding: 1px 5px; }
.klima-pin-src { font-size: 9px; color: rgba(234,242,236,.5); font-family: var(--mono); margin-top: 2px; }
/* Datensatz (1976–2000) vs. Live-Formel (2014–2023) — erscheint NUR bei Abweichung. */
.klima-pin-drift {
  font-size: 9px; font-family: var(--mono); margin-top: 4px; padding-top: 4px;
  border-top: 1px dashed rgba(234,242,236,.2); color: rgba(245,217,139,.85);
}
.klima-pin-drift b { color: #F5D98B; }

/* ── ZONEN-LEGENDE — sitzt IN der Karte, gegenüber der Ort-Info ────────────
   31 Zonen wären als flache Liste eine Wand. Deshalb zwei Klapp-Ebenen und
   nicht mehr: Chip → Panel → 5 Hauptgruppen A–E, jede mit ihren Codes. */
.klima-kz-legend { position: absolute; right: 12px; bottom: 12px; width: min(268px, 46%); z-index: 3; }
.klima-kz-chip {
  width: 100%; display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-radius: 10px;
  background: rgba(255,255,255,.94); border: 1px solid var(--border);
  box-shadow: 0 6px 18px rgba(0,0,0,.14); backdrop-filter: blur(3px);
  font-family: var(--sans); font-size: 12px; font-weight: 600; color: var(--text);
  cursor: pointer; transition: border-color .18s ease, box-shadow .18s ease;
}
.klima-kz-chip:hover { border-color: var(--green); box-shadow: 0 6px 20px rgba(61,107,79,.28); }
.klima-kz-chip[aria-expanded="true"] { border-color: var(--green); }
.klima-kz-chip[aria-expanded="true"] .klima-caret { transform: rotate(180deg); }
/* Beim Zonen-Hover wird der Chip zur Anzeige — statt eines zweiten Feldes. */
.klima-kz-chip.is-reading { border-color: var(--sand); background: var(--sand-bg); }
.klima-kz-chip-t { flex: 1; text-align: left; font-size: 11px; line-height: 1.25; }
.klima-kz-chip.is-reading .klima-kz-chip-t { font-family: var(--mono); font-size: 10px; }
/* Farbband: die 31 Standardfarben als eine Leiste — Legende im Kleinstformat. */
.klima-kz-bar { display: flex; flex-shrink: 0; border-radius: 3px; overflow: hidden; box-shadow: inset 0 0 0 1px rgba(28,43,30,.18); }
.klima-kz-bar i { width: 3px; height: 14px; }
.klima-kz-chip.is-reading .klima-kz-bar { opacity: .45; }

.klima-kz-panel {
  position: absolute; right: 0; bottom: calc(100% + 6px); width: 100%;
  background: rgba(255,255,255,.97); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 10px 26px rgba(0,0,0,.18); overflow: hidden;
}
.klima-kz-panel[hidden] { display: none; }
.klima-kz-scroll { max-height: 232px; overflow-y: auto; }
.klima-kz-group { border-bottom: 1px solid var(--surface2); }
.klima-kz-group:last-child { border-bottom: none; }
.klima-kz-group-h {
  width: 100%; display: flex; align-items: center; gap: 6px; padding: 7px 10px; cursor: pointer;
  background: transparent; border: none; font-family: var(--sans); font-size: 11px; color: var(--text); text-align: left;
}
.klima-kz-group-h:hover { background: var(--green-bg); }
.klima-kz-group-h[aria-expanded="true"] { background: var(--surface2); }
.klima-kz-group-h[aria-expanded="true"] .klima-caret { transform: rotate(180deg); }
.klima-kz-group-ico { font-size: 12px; }
.klima-kz-group-h b { font-family: var(--mono); font-size: 10px; }
.klima-kz-group-h span:not(.klima-caret):not(.klima-kz-group-ico):not(.klima-kz-group-n) { flex: 1; color: var(--text-dim); }
.klima-kz-group-n { font-family: var(--mono); font-size: 9px; color: var(--text-dim); background: var(--surface2); border-radius: 3px; padding: 1px 5px; }
.klima-kz-group-h[aria-expanded="true"] .klima-kz-group-n { background: #fff; }
.klima-kz-items[hidden] { display: none; }

.klima-kz-item {
  width: 100%; display: flex; align-items: center; gap: 7px; padding: 5px 10px 5px 22px; cursor: pointer;
  background: transparent; border: none; font-family: var(--sans); text-align: left;
  transition: background .15s ease, padding-left .15s ease;
}
.klima-kz-item:hover, .klima-kz-item.is-hot { background: var(--sand-bg); padding-left: 26px; }
.klima-kz-item.is-hot { box-shadow: inset 2px 0 0 var(--sand); }
.klima-kz-sw { width: 11px; height: 11px; border-radius: 3px; flex-shrink: 0; box-shadow: inset 0 0 0 1px rgba(28,43,30,.25); }
.klima-kz-item b { font-family: var(--mono); font-size: 10px; color: var(--text); width: 26px; flex-shrink: 0; }
.klima-kz-item span { font-size: 10px; color: var(--text-dim); line-height: 1.2; }
.klima-kz-foot { padding: 6px 10px; font-family: var(--mono); font-size: 8px; color: var(--text-dim); background: var(--surface2); }
