:root {
  --bg: rgba(255, 255, 255, .93);
  --fg: #1c1f23;
  --dim: #6a7178;
  --line: rgba(0, 0, 0, .12);
  --accent: #2f6fb0;
  --shadow: 0 2px 14px rgba(0, 0, 0, .22);
  --radius: 10px;
}
@media (prefers-color-scheme: dark) {
  :root {
    --bg: rgba(28, 31, 35, .94);
    --fg: #e9edf1;
    --dim: #9aa3ab;
    --line: rgba(255, 255, 255, .15);
    --accent: #6fa8dc;
    --shadow: 0 2px 16px rgba(0, 0, 0, .5);
  }
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; overflow: hidden;
  font: 14px/1.4 system-ui, -apple-system, "Segoe UI", sans-serif; color: var(--fg); }
#map { position: absolute; inset: 0; z-index: 0; }

/* Die Schummerung liegt als eigene Kachelebene über der Grundkarte (beide
   bekommen in app.js ein `className`, Leaflet gibt jeder einen eigenen
   Container). `multiply` statt bloßer Deckkraft: Grau dunkelt ab, Weiß
   lässt stehen — dadurch bleibt die Beschriftung der Grundkarte scharf,
   statt unter einem grauen Schleier zu verblassen. Das Blenden bleibt auf
   den Kachel-Pane beschränkt, die Datenlayer darüber sind nicht betroffen. */
.basemap-shade { mix-blend-mode: multiply; }
@media (prefers-color-scheme: dark) {
  /* Im Dunkelmodus die ganze Grundlage zurücknehmen, damit die Farbskalen
     der Prognose leuchten. */
  .basemap-plain { filter: brightness(.78) saturate(.85); }
}

.dim { color: var(--dim); }
.small { font-size: 12px; }
.err { color: #c0392b; }
hr { border: 0; border-top: 1px solid var(--line); margin: 6px 0; }

#boot {
  position: absolute; inset: 0; z-index: 2000; display: grid; place-content: center;
  text-align: center; background: var(--bg); padding: 24px;
}
#boot code { background: rgba(127,127,127,.18); padding: 2px 6px; border-radius: 4px; }

/* ------------------------------------------------------------- Kopfzeile */
/* Die Kopfzeile trägt nur noch zwei Dinge: welche Ebene liegt auf der Karte,
   und wo will ich hin. Alles Weitere steckt im Ebenenpanel darunter — es
   gehört in dieselbe Spalte, damit es unter dem Knopf aufklappt, auch wenn
   die Leiste auf schmalen Anzeigen zweizeilig wird. */
/* Die Spalte reicht bis kurz über den Zeitregler. Das ist kein Selbstzweck:
   das Panel darunter bekommt damit eine echte Höhe zum Schrumpfen, statt
   dass eine geratene max-height auf schmalen Anzeigen in die Zeitleiste
   läuft. Die Fläche selbst nimmt keine Klicks an — die Karte bleibt
   überall greifbar, nur die Kinder fangen ab. */
#top {
  position: absolute; z-index: 1100; top: 10px; left: 10px; right: 68px; bottom: 116px;
  display: flex; flex-direction: column; gap: 6px; pointer-events: none;
}
#top > * { pointer-events: auto; }
/* Die Leiste selbst ist nur ein Behälter — zwischen Knopf, Suchfeld und
   Zählung soll die Karte weiter zu fassen sein. */
#top > .bar { pointer-events: none; }
.bar > * { pointer-events: auto; }
.bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.chips { display: flex; flex-wrap: wrap; gap: 5px; }

.layer-btn, .toggle, .control {
  border: 1px solid var(--line); background: var(--bg); color: var(--fg);
  padding: 6px 11px; border-radius: 999px; cursor: pointer;
  font-size: 13px; box-shadow: var(--shadow); white-space: nowrap;
}
.layer-btn.small { padding: 4px 9px; font-size: 12px; }
.layer-btn:hover, .toggle:hover, .control:hover { border-color: var(--accent); }
.layer-btn.active, .toggle.active {
  background: var(--accent); color: #fff; border-color: var(--accent); font-weight: 600;
}
.toggle:disabled { opacity: .5; cursor: default; border-color: var(--line); }

/* Ebenenknopf: trägt den Namen der Ebene, die gerade zu sehen ist. */
.control {
  display: inline-flex; align-items: center; gap: 7px; min-width: 0;
  max-width: min(280px, 60vw); font: inherit; font-size: 13px; padding: 6px 10px 6px 12px;
}
.control .ic { color: var(--accent); font-size: 12px; }
.control-label {
  font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.control .caret { color: var(--dim); font-size: 10px; transition: transform .15s; }
.control.open { border-color: var(--accent); }
.control.open .caret { transform: rotate(180deg); }

/* Zählung der bewerteten Startplätze — verschwindet, solange nichts dasteht. */
.pill {
  background: var(--bg); border: 1px solid var(--line); border-radius: 999px;
  padding: 4px 10px; box-shadow: var(--shadow); white-space: nowrap;
}
.pill:empty { display: none; }

/* ------------------------------------------------------------ Ebenenpanel */
#layer-panel {
  width: min(320px, 100%); align-self: flex-start;
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
  /* Schrumpft in den Platz, den die Kopfzeile übrig lässt (siehe #top) */
  flex: 0 1 auto; min-height: 0; max-height: 560px;
}
#layer-panel[hidden] { display: none; }   /* sonst setzt sich das flex durch */

.lp-head { display: flex; align-items: center; gap: 6px; padding: 8px 8px 6px; }
#layer-search {
  flex: 1; min-width: 0; border: 1px solid var(--line); background: transparent;
  color: var(--fg); border-radius: 8px; padding: 6px 10px; font: inherit; font-size: 13px;
}
#layer-search:focus { outline: none; border-color: var(--accent); }
#layer-search::placeholder { color: var(--dim); }
#layer-panel-close {
  border: 0; background: transparent; color: var(--dim);
  font-size: 21px; line-height: 1; cursor: pointer; padding: 0 4px;
}
#layer-panel-close:hover { color: var(--fg); }

/* Ebenenliste und Überlagerungen scrollen getrennt.
   Vorher teilten sie sich einen Scrollbereich, in dem der Fuß unten klebte.
   Das trug, solange der Fuß aus zwei Schaltern bestand — mit Windpfeilen,
   Vektorhöhen und Luftraumsteuerung ist er auf über 400 px gewachsen und
   nahm sich davon so viel, dass von der Ebenenliste zwei Zeilen sichtbar
   blieben. Die Ebenenwahl ist der Zweck des Panels und bekommt deshalb den
   Vorrang; der Fuß ist gedeckelt und scrollt selbst, wenn er nicht passt.
   Auf niedrigen Anzeigen (Telefon quer) bleiben so beide erreichbar. */
.lp-body {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column; overflow: hidden;
}
.lp-list {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  padding: 0 8px 6px;
}
.lp-group + .lp-group { margin-top: 6px; }
.lp-group[hidden] { display: none; }
.lp-group-title {
  font-size: 11px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--dim); padding: 6px 4px 3px;
  position: sticky; top: 0; background: var(--bg);
}

.lp-item {
  display: flex; align-items: baseline; gap: 8px; width: 100%;
  border: 0; background: transparent; color: var(--fg); font: inherit;
  text-align: left; padding: 7px 9px; border-radius: 8px; cursor: pointer;
  /* Platz für den Haken der aktiven Ebene, damit beim Wechsel nichts springt */
  border-left: 3px solid transparent;
}
.lp-item[hidden] { display: none; }
.lp-item:hover, .lp-item.cursor { background: rgba(127, 127, 127, .14); }
.lp-item.cursor { outline: 1px solid var(--accent); outline-offset: -1px; }
.lp-item.active {
  border-left-color: var(--accent); background: rgba(47, 111, 176, .13); font-weight: 600;
}
@media (prefers-color-scheme: dark) {
  .lp-item.active { background: rgba(111, 168, 220, .18); }
}
.lp-item .lp-name { flex: 1; min-width: 0; }
.lp-item .lp-unit { flex: none; }
.lp-empty { padding: 12px 9px; }
.lp-empty[hidden] { display: none; }

/* Überlagerungen: liegen nicht *statt* der Ebene auf der Karte, sondern
   zusätzlich — deshalb Schalter statt Auswahlliste, deutlich abgesetzt. */
.lp-foot {
  flex: 0 0 auto; max-height: 45%;
  overflow-y: auto; overscroll-behavior: contain;
  background: var(--bg);
  border-top: 1px solid var(--line); padding: 6px 8px 8px;
}
.lp-row {
  display: flex; align-items: center; gap: 10px; width: 100%;
  border: 0; background: transparent; color: var(--fg); font: inherit;
  text-align: left; padding: 6px 9px; border-radius: 8px; cursor: pointer;
}
.lp-row:hover { background: rgba(127, 127, 127, .14); }
.lp-row-text { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.lp-row-text .dim { line-height: 1.3; }
.lp-row .knob {
  flex: none; width: 34px; height: 20px; border-radius: 999px;
  background: rgba(127, 127, 127, .38); position: relative; transition: background .15s;
}
.lp-row .knob::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .35);
  transition: transform .15s;
}
.lp-row.active .knob { background: var(--accent); }
.lp-row.active .knob::after { transform: translateX(14px); }

#vectors { padding: 2px 9px 2px; }
/* Solange die Pfeile aus sind, sind die Höhen nur ein Angebot. Ein Klick
   darauf schaltet sie an (siehe app.js), deshalb bleiben sie bedienbar. */
#vectors.off { opacity: .55; }
/* Nicht jede Druckfläche führen beide Modelle: 975 hPa gibt es nur bis
   +48 h, 925 bis 775 hPa erst darüber. Zur jeweiligen Stunde leere Höhen
   stehen durchgestrichen da statt zu verschwinden — sonst spränge die Reihe
   bei jedem Schritt des Zeitreglers um. Bedienbar bleiben sie: ein Klick
   darauf und ein Schritt in den anderen Modellteil zeigt sie an. */
#vectors .layer-btn.unavailable { opacity: .4; text-decoration: line-through; }

/* Höhenfilter und Farbwahl der Lufträume — dieselbe Regel wie bei den
   Windhöhen: aus, aber bedienbar, denn ein Klick schaltet die Ebene mit ein. */
#airspace-controls.off { opacity: .55; }
/* Bei ausgeschalteter Ebene sagt die Legende nichts über die Karte aus. */
#airspace-controls.off .as-legend,
#airspace-controls.off .as-hint { display: none; }

/* Der Live-Verkehr trägt dieselben Reihen wie die Lufträume — es ist
   dieselbe Art Bedienung, und zwei Gestaltungen dafür wären eine zu viel. */
#ogn-controls.off { opacity: .55; }
#ogn-controls.off .as-legend,
#ogn-controls.off .as-hint { display: none; }
/* Rund statt Balken: die Punkte stehen für Luftfahrzeuge, nicht für
   Luftraumgrenzen. */
#ogn-legend .sw { width: 8px; height: 8px; border-radius: 50%; vertical-align: 0; }

.as-row { display: flex; align-items: center; gap: 7px; padding: 2px 9px; }
.as-label { flex: none; width: 38px; }

.as-legend { display: flex; flex-wrap: wrap; column-gap: 10px; row-gap: 2px;
  padding: 4px 9px 2px; line-height: 1.5; }
.as-legend .sw { display: inline-block; width: 11px; height: 4px;
  border-radius: 2px; margin-right: 4px; vertical-align: 2px; }
.as-hint { padding: 0 9px 4px; line-height: 1.35; }

/* Die Lufträume unter dem Zeiger stehen unter dem Messwert; sie dürfen die
   Anzeige nicht zur Textwand machen. */
.as-hit { display: block; margin-top: 3px; font-size: 12px; line-height: 1.35;
  border-top: 1px solid var(--line); padding-top: 3px; }

/* Der Verkehr unter dem Zeiger steht in derselben Anzeige. Der farbige Punkt
   davor ist die Verbindung zum Zeichen auf der Karte — ohne ihn müsste man
   raten, welches der drei Ziele gemeint ist. */
.ogn-hit { display: block; margin-top: 3px; font-size: 12px; line-height: 1.35;
  border-top: 1px solid var(--line); padding-top: 3px; }
.ogn-hit .sw { display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  margin-right: 5px; vertical-align: 1px; }
.ogn-hit .up { color: #2e9e4f; font-weight: 600; }

/* ----------------------------------------------------------- Platzsuche */
/* Wächst neben dem Ebenenknopf mit, bricht erst um, wenn darunter wirklich
   kein Platz mehr ist. */
#search-wrap { position: relative; flex: 1 1 170px; min-width: 0; max-width: 300px; }

#site-search {
  width: 100%; border: 1px solid var(--line); background: var(--bg);
  color: var(--fg); border-radius: 999px; padding: 7px 13px;
  font: inherit; font-size: 13px; box-shadow: var(--shadow);
}
#site-search:focus { outline: none; border-color: var(--accent); }
#site-search::placeholder { color: var(--dim); }

#site-results {
  position: absolute; top: calc(100% + 5px); left: 0; right: 0;
  margin: 0; padding: 4px; list-style: none;
  max-height: min(46vh, 340px); overflow-y: auto;
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
#site-results[hidden] { display: none; }
#site-results li {
  display: flex; flex-direction: column; gap: 1px;
  padding: 6px 9px; border-radius: 7px; cursor: pointer; line-height: 1.3;
}
#site-results li.active { background: var(--accent); color: #fff; }
#site-results li.active .dim { color: rgba(255, 255, 255, .8); }
#site-results li.msg { cursor: default; }
.hit-name { display: flex; align-items: baseline; gap: 6px; font-size: 13px; }
.hit-kind {
  font-size: 10px; text-transform: uppercase; letter-spacing: .04em;
  border: 1px solid var(--line); border-radius: 999px; padding: 0 5px;
  color: var(--dim);
}
#site-results li.active .hit-kind { color: #fff; border-color: rgba(255, 255, 255, .5); }
.hit-detail { font-size: 11px; }

/* Suchtreffer auf der Karte: gestrichelter Ring, damit er sich von den
   bewerteten Startplatzmarkern unterscheidet. */
.search-hit-label {
  background: var(--bg); color: var(--fg); border: 1px solid var(--accent);
  border-radius: 6px; box-shadow: var(--shadow); font-size: 12px;
  font-weight: 600; padding: 2px 6px;
}
.search-hit-label::before { display: none; }

/* -------------------------------------------------------------- Anzeigen */
#readout {
  position: absolute; z-index: 1000; right: 10px; top: 96px;
  background: var(--bg); border-radius: var(--radius); padding: 8px 11px;
  box-shadow: var(--shadow); min-width: 172px; font-size: 13px;
  /* Mit eingeschalteten Lufträumen stehen hier bis zu drei Namen — ohne
     Deckel wüchse der Kasten sonst quer über die Karte. */
  max-width: min(330px, 44vw);
}

#legend {
  position: absolute; z-index: 1000; left: 10px; bottom: 124px;
  width: 258px; background: var(--bg); border-radius: var(--radius);
  padding: 10px 12px; box-shadow: var(--shadow);
}
#legend-title { font-weight: 600; margin-bottom: 6px; }
#legend-bar { height: 13px; border-radius: 3px; border: 1px solid var(--line); }
.ticks { display: flex; justify-content: space-between; font-size: 11px;
  color: var(--dim); margin-top: 3px; }
#legend-note { margin-top: 6px; line-height: 1.35; }
.opacity { display: flex; align-items: center; gap: 8px; margin-top: 8px;
  font-size: 12px; color: var(--dim); }
.opacity input { flex: 1; }
#runinfo { margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--line); }

/* ----------------------------------------------------------- Zeitregler */
#timebar {
  position: absolute; z-index: 1000; left: 10px; right: 10px; bottom: 10px;
  display: flex; align-items: center; gap: 10px;
  background: var(--bg); border-radius: var(--radius);
  padding: 8px 12px; box-shadow: var(--shadow);
}
#play {
  width: 38px; height: 38px; flex: none; border-radius: 50%;
  border: 1px solid var(--line); background: transparent; color: var(--fg);
  font-size: 15px; cursor: pointer;
}
#play.active { background: var(--accent); color: #fff; border-color: var(--accent); }
.time-wrap { flex: 1; min-width: 0; }
.time-head { display: flex; align-items: center; gap: 9px; margin-bottom: 1px; }
#time-label { font-weight: 600; font-variant-numeric: tabular-nums; }
.badge { font-size: 11px; padding: 2px 8px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--dim); white-space: nowrap; }
.badge.fine { background: rgba(60, 150, 90, .18); color: #2e8b52; border-color: transparent; }
.badge.coarse { background: rgba(200, 140, 40, .2); color: #b57d20; border-color: transparent; }
/* Interpolierte Zwischenzeiten werden gekennzeichnet — sie sind kein
   eigener Modellzeitpunkt, und das soll man sehen können. */
.badge.interp { outline: 1px dashed var(--dim); outline-offset: 1px; }

#timeline-canvas {
  display: block; width: 100%; height: 62px;
  cursor: ew-resize; touch-action: none;
}

.sunkey { margin-left: auto; display: flex; align-items: center; gap: 4px; }
.sunkey i { display: inline-block; }
.sunkey .band { width: 13px; height: 9px; border-radius: 2px; margin-left: 6px; }
.sunkey .band.day { background: rgba(255, 205, 90, .55); }
.sunkey .band.twilight { background: rgba(240, 140, 70, .55); }
.sunkey .band.night { background: rgba(45, 60, 100, .55); }
.sunkey .dot { width: 7px; height: 7px; border-radius: 50%; margin-left: 6px; }
.sunkey .dot.rise { background: rgb(230, 175, 50); }
.sunkey .dot.set { background: rgb(205, 85, 55); }

/* ---------------------------------------------------------- Meteogramm */
/* So groß, wie der Bildschirm über der Zeitleiste hergibt: die Höhenachse
   reicht bis 6000 m und trägt fünf Druckflächen mit Windfahnen — je mehr
   Fläche das Diagramm bekommt, desto weiter liegen sie auseinander.
   Darum keine feste Größe, sondern aufgespannt zwischen Kopfzeile und
   Zeitleiste: das Canvas wächst über den ResizeObserver in app.js mit. */
#meteogram {
  position: absolute; z-index: 1200;
  left: 10px; right: 10px; top: 52px; bottom: 106px;
  background: var(--bg); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 10px 12px; display: none; flex-direction: column;
}
#meteogram.open { display: flex; }
.mg-head { display: flex; justify-content: space-between; align-items: center;
  font-weight: 600; margin-bottom: 4px; }
#meteogram-close { border: 0; background: transparent; color: var(--fg);
  font-size: 22px; line-height: 1; cursor: pointer; padding: 0 4px; }
/* flex-basis 0 statt auto: das Canvas hat über sein height-Attribut eine
   Intrinsic-Höhe (Breite × devicePixelRatio), die sonst als Basis zählt und
   die Legende aus dem Rahmen drückt. min-height: 0 erlaubt das Schrumpfen. */
#meteogram-canvas { flex: 1 1 0; min-height: 0; width: 100%; }

/* Platzinfo als Untermenue: eingeklappt steht nur die Zusammenfassung da
   (die freigegebenen Richtungen), aufgeklappt der Rest. Zugeklappt kostet
   das Diagramm damit eine Zeile statt dreien. */
.mg-site {
  flex: none; line-height: 1.5; margin: 1px 0 3px;
  border-bottom: 1px solid var(--line); padding-bottom: 4px;
}
.mg-site[hidden] { display: none; }
.mg-site > summary { cursor: pointer; }
.mg-site > summary::marker { color: var(--accent); }
.mg-site > summary:hover { color: var(--accent); }
.mg-site a { color: var(--accent); }
/* Auflagen koennen sehr lang sein — gekuerzt anzeigen, vollstaendig im Tooltip */
.mg-note { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.mg-days { flex: none; display: flex; gap: 4px; margin: 2px 0 4px; flex-wrap: wrap; }
.day-btn {
  border: 1px solid var(--line); background: transparent; color: var(--fg);
  border-radius: 7px; padding: 3px 9px; font-size: 12px; cursor: pointer;
  display: flex; gap: 4px; align-items: baseline;
}
.day-btn:hover { border-color: var(--accent); }
.day-btn.active {
  background: var(--accent); color: #fff; border-color: var(--accent); font-weight: 600;
}
.day-btn.active .dim { color: rgba(255, 255, 255, .75); }

.mg-probe {
  flex: none; min-height: 30px; line-height: 1.35;
  font-variant-numeric: tabular-nums; margin-top: 2px;
}
.mg-legend { flex: none; display: flex; flex-wrap: wrap;
  column-gap: 12px; row-gap: 2px; margin-top: 5px; }
.mg-legend .sw { display: inline-block; width: 11px; height: 11px;
  border-radius: 2px; margin-right: 4px; vertical-align: -1px; }
.mg-legend .sw.dash { border-top: 2px dashed #b00; height: 0; border-radius: 0; }

/* Der Rasterlayer soll beim Zoomen nicht weichgezeichnet werden — die
   Zellgrenzen sind echte Information, keine Artefakte. */
.grid-overlay { image-rendering: pixelated; }

/* Startplatzmarker. Nah am Gelände (Klasse am Container, gesetzt in app.js
   ab derselben Zoomstufe, ab der die Sektoren erscheinen) bekommen sie den
   kräftigen dunklen Ring: aus ihm geht der Fächer hervor, und der Punkt
   bleibt darin als Träger der Bewertung erkennbar. Über die Klasse statt
   über setStyle, weil sonst bei jedem Zoomschritt 2500 Marker einzeln
   umgestellt werden müssten. */
.leaflet-container.zoom-near .site-dot {
  stroke: #16191d;
  stroke-width: 3.2;
  stroke-opacity: .88;
}
@media (prefers-color-scheme: dark) {
  .leaflet-container.zoom-near .site-dot { stroke: #0b0d10; }
}

.leaflet-popup-content { font-size: 13px; line-height: 1.45; }
.leaflet-popup-content b { font-size: 14px; }

/* ------------------------------------------------------------- Mobilgeräte */
@media (max-width: 720px) {
  #top { right: 10px; }
  #legend { display: none; }
  #readout { top: auto; bottom: 165px; right: 10px; left: 10px; min-width: 0; }
  /* Die Leiste oben bricht auf schmalen Anzeigen zweizeilig um — dafür etwas
     mehr Luft lassen, damit Ebenenknopf und Suchfeld sichtbar bleiben. */
  #meteogram { top: 92px; bottom: 84px; }
  .layer-btn { font-size: 12px; padding: 5px 9px; }

  /* Ebenenknopf und Suchfeld teilen sich die erste Zeile; der Knopf gibt
     nach, damit das Suchfeld nicht auf Briefmarkengröße schrumpft. */
  .control { max-width: 46vw; padding: 7px 9px 7px 11px; }
  #search-wrap { flex: 1 1 130px; }
  #sites-summary { font-size: 11px; padding: 3px 9px; }

  /* Volle Breite; die Höhe ergibt sich aus der Kopfzeilenspalte (#top) */
  #layer-panel { width: 100%; }
  /* Fingerbreite Ziele statt Mausziele */
  .lp-item, .lp-row { padding-top: 10px; padding-bottom: 10px; }
  #layer-search { padding: 9px 11px; }
  #vectors .layer-btn { padding: 6px 11px; font-size: 12px; }
  /* Auf schmalen Anzeigen hat die Sonnenlegende keinen Platz — die Bänder
     erklären sich in der Leiste selbst. */
  .sunkey { display: none; }
  #timeline-canvas { height: 54px; }
}

/* ------------------------------------------------------------- Flugbuch */
/* Eine Spalte am linken Rand, nicht die ganze Breite wie das Meteogramm:
   der ausgewählte Flug liegt als Track auf der Karte, und ein Fenster, das
   ihn verdeckt, nähme dem Flugbuch seinen Sinn. Die Liste oben, der
   gewählte Flug darunter — in der Reihenfolge, in der man sie liest. */
#flightlog {
  position: absolute; z-index: 1250;
  left: 10px; top: 52px; bottom: 106px;
  width: min(420px, calc(100vw - 20px));
  background: var(--bg); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 10px 12px; display: flex; flex-direction: column; gap: 6px;
}
#flightlog[hidden] { display: none; }   /* sonst setzt sich das flex durch */

.fl-head { display: flex; align-items: center; gap: 8px;
  font-weight: 600; flex: none; }
#fl-device { font-weight: 400; }
#flightlog-close { border: 0; background: transparent; color: var(--fg);
  font-size: 22px; line-height: 1; cursor: pointer; padding: 0 4px;
  margin-left: auto; }

.fl-tabs { display: flex; gap: 6px; flex: none; }
.fl-tabs .toggle[aria-selected="true"] {
  border-color: var(--accent); color: var(--accent); }

.fl-form { display: flex; gap: 6px; flex: none; flex-wrap: wrap; }
.fl-form[hidden] { display: none; }
#fl-number {
  width: 140px; font: inherit; font-variant-numeric: tabular-nums;
  letter-spacing: .05em; text-transform: uppercase;
  padding: 6px 10px; border-radius: 8px; color: var(--fg);
  background: transparent; border: 1px solid var(--line);
}
#fl-number:focus { outline: none; border-color: var(--accent); }
.fl-status { flex: none; line-height: 1.4; min-height: 17px; }
.fl-status .ok { color: #2e8b52; }
.fl-live { color: #2e8b52; }

.fl-body { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column;
  gap: 8px; }
/* Die Liste bekommt höchstens die halbe Höhe: sie ist der Weg zum Flug,
   nicht das Ziel. Sind erst drei Flüge da, schrumpft sie auf deren Höhe. */
.fl-list { flex: 0 1 auto; max-height: 45%; min-height: 0;
  overflow-y: auto; display: flex; flex-direction: column; gap: 3px;
  border-bottom: 1px solid var(--line); padding-bottom: 6px; }
.fl-empty { padding: 10px 2px; }

.fl-row {
  display: flex; flex-direction: column; gap: 2px; text-align: left;
  border: 1px solid transparent; border-radius: 8px; padding: 6px 8px;
  background: transparent; color: var(--fg); font: inherit; cursor: pointer;
}
.fl-row:hover { background: rgba(127, 127, 127, .14); }
.fl-row.active { border-color: var(--accent); background: rgba(127, 127, 127, .1); }
.fl-when { display: flex; flex-direction: column; }
.fl-nums { display: flex; gap: 10px; font-variant-numeric: tabular-nums; }
.fl-nums span:first-child { min-width: 62px; }
/* Die eigene Nummer in der Österreich-Liste: derselbe Aufbau, nur
   hervorgehoben — sie ist der Grund, warum man die Liste aufmacht. */
.fl-row.mine { border-color: var(--accent); }
.fl-who { font-variant-numeric: tabular-nums; }
.fl-day { position: sticky; top: 0; z-index: 1; background: var(--bg);
  padding: 4px 2px 2px; font-size: 11px; color: var(--dim); }

.fl-detail { flex: 1 1 0; min-width: 0; min-height: 0; overflow-y: auto; }
.fl-detail:empty::before {
  content: 'Einen Flug in der Liste wählen — der Track erscheint auf der Karte.';
  color: var(--dim); font-size: 12px;
}
.fl-detail-head { display: flex; align-items: baseline; gap: 10px;
  margin-bottom: 4px; }
.fl-igc { color: var(--accent); font-size: 12px; margin-left: auto; }

/* Feste Höhe statt flex: das Barogramm steht in einer scrollenden Spalte
   und hätte dort keine Höhe, aus der es sich seine ableiten könnte. */
.fl-baro { width: 100%; height: 190px; display: block; touch-action: none; }
.fl-probe { min-height: 17px; font-variant-numeric: tabular-nums; margin: 2px 0 6px; }

.fl-stats { display: grid; grid-template-columns: auto 1fr; gap: 2px 12px;
  margin: 0 0 8px; font-variant-numeric: tabular-nums; }
.fl-stats dt { white-space: nowrap; }
.fl-stats dd { margin: 0; }

.fl-legend { display: flex; flex-wrap: wrap; column-gap: 10px; row-gap: 2px;
  margin-bottom: 6px; }
.fl-legend .sw { display: inline-block; width: 11px; height: 4px;
  border-radius: 2px; margin-right: 4px; vertical-align: 3px; }
.fl-note { line-height: 1.4; margin: 0; }

/* Auf dem Telefon steht das Flugbuch über der ganzen Breite — dort ist
   nebeneinander ohnehin kein Platz, und der Track lässt sich nach dem
   Schließen ansehen: er bleibt liegen. */
@media (max-width: 560px) {
  #flightlog { right: 10px; width: auto; }
  .fl-baro { height: 150px; }
}

/* --------------------------------------------------------- Wartungsmenue */
/* Versteckt (siehe admin.js): oeffnet mit Strg+Alt+A oder ueber #admin.
   Liegt ueber dem Meteogramm, damit es beim Nachsehen nicht verschwindet. */
#admin {
  position: absolute; z-index: 1300; right: 10px; bottom: 106px;
  width: min(360px, calc(100vw - 20px));
  background: var(--bg); border-radius: var(--radius); box-shadow: var(--shadow);
  padding: 10px 12px; display: flex; flex-direction: column; gap: 7px;
}
#admin[hidden] { display: none; }   /* sonst setzt sich das flex durch */

.admin-head { display: flex; justify-content: space-between; align-items: center;
  font-weight: 600; }
#admin-close { border: 0; background: transparent; color: var(--fg);
  font-size: 22px; line-height: 1; cursor: pointer; padding: 0 4px; }
.admin-actions { display: flex; gap: 6px; flex-wrap: wrap; }
#admin-state { line-height: 1.45; }

.admin-bar { height: 8px; border-radius: 4px; overflow: hidden;
  background: rgba(127, 127, 127, .22); }
.admin-bar > i { display: block; height: 100%; width: 0;
  background: var(--accent); transition: width .4s ease; }
.admin-bar.error > i { background: #c0392b; }

/* Solange die Gesamtzahl der Schritte nicht feststeht - vor dem ersten
   Zeitschritt und im Moment, in dem der ICON-EU-Teil dazukommt - zeigt der
   Balken Bewegung statt einer erfundenen Zahl. */
.admin-bar.indeterminate > i { width: 35%; animation: admin-sweep 1.4s ease-in-out infinite; }
@keyframes admin-sweep {
  from { transform: translateX(-110%); }
  to   { transform: translateX(300%); }
}
