/* ghadami.de — Cockpit und Fraktalwelt.
 *
 * Aufbau:
 *   1 Grundlagen und Farben
 *   2 Seitengerüst: Sichtfeld innerhalb des Rahmens
 *   3 Schilder — die Beschriftungen des Schwarms
 *   4 Cockpit: Rahmen, Kulisse, Konsole
 *   5 Burgermenü und Einstellungen
 *   6 Textseiten
 *   7 Zustände: Hochlauf, kein Signal, Bewegung aus
 *   8 Schmale Bildschirme
 *
 * Farbe gibt es nur an einer Stelle: in der Fraktalwelt. Das Cockpit ist
 * neutral schwarz und bleibt es auch, wenn die Welt im Einstellungsfeld zum
 * roten oder blauen Ende verschoben wird — siehe assets/scene/palette.js.
 */

/* ── 1 Grundlagen ─────────────────────────────────────────────────────── */

:root {
  /* Eine variable Schrift gehört hier selbst gehostet hinein. Bis dahin:
     Systemschriften, aber niemals in einem mageren Schnitt — vor bewegtem
     Hintergrund verschwindet der zuverlässig. */
  --schrift: ui-sans-serif, system-ui, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --schrift-technisch: ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo, Consolas, monospace;

  --rahmen-oben: 54px;
  --rahmen-unten: 104px;
  --rahmen-seite: 64px;
  /* Der Infobereich rechts. Er ersetzt den Deko-Holm auf dieser Seite und
     nimmt dem Sichtfeld Fläche weg — was der Bildrate zugutekommt: Der
     Raymarcher rechnet genau die Bildpunkte, die übrig bleiben. */
  --infobreite: 20rem;

  --uebergang: 480ms;

  /* Das Cockpit ist neutral schwarz, und zwar buchstäblich: R = G = B.
     Ein Rahmen mit eigener Farbe kämpft mit dem Bild in seiner Mitte und
     gewinnt — er ist größer, er steht still, und das Auge nimmt ihn als
     Weißabgleich. Die Farbe gehört in die Welt, nicht in den Rahmen.

     Die einzige Ausnahme ist das Alarmrot. Das ist ein Zustand und keine
     Dekoration: „kein Signal" muss auch dann noch als Störung lesbar sein,
     wenn man gerade woanders hinsieht. */
  --grund: #050505;
  --platte-1: #242424;
  --platte-2: #161616;
  --platte-3: #0b0b0b;
  --kante: #3a3a3a;
  --leuchte: #e8e8e8;
  --leuchte-matt: #6e6e6e;
  --signal: #d6d6d6;
  --alarm: #ff6f5e;
  --text: #ededed;
  --text-matt: #9b9b9b;
  --text-kontur: rgba(0, 0, 0, 0.94);
  --kulisse-strich: #303030;
  --kulisse-metall: #464646;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

html {
  background: var(--grund);
  color: var(--text);
  font-family: var(--schrift);
  font-weight: 500;
  transition: background var(--uebergang) ease;
}

body.flug {
  position: fixed;
  inset: 0;
  overflow: hidden;
  overscroll-behavior: none;
  background: var(--grund);
}

kbd {
  font-family: var(--schrift-technisch);
  font-size: 0.85em;
  font-weight: 600;
  border: 1px solid var(--kante);
  border-bottom-width: 2px;
  border-radius: 4px;
  padding: 0.05em 0.4em;
  background: var(--platte-2);
  color: var(--text);
}

:focus-visible {
  outline: 3px solid var(--leuchte);
  outline-offset: 2px;
  border-radius: 3px;
}

.sprung {
  position: absolute;
  left: 8px;
  top: -100px;
  z-index: 90;
  padding: 0.6rem 1rem;
  background: var(--platte-1);
  border: 1px solid var(--leuchte);
  border-radius: 6px;
  color: var(--text);
  font-weight: 600;
  text-decoration: none;
  transition: top 140ms ease;
}

.sprung:focus {
  top: 8px;
}

/* ── 2 Sichtfeld ──────────────────────────────────────────────────────── */

/* Die Zeichenfläche liegt innerhalb des Rahmens. Was das Cockpit verdeckt,
   wird nicht gerechnet — bei einem Fünftel Rahmen ist das ein Fünftel der
   teuersten Berechnung der ganzen Anwendung. Ein Rahmen, der bloß darüber
   schwebte, spart nichts. */
.sichtfeld {
  position: absolute;
  top: var(--rahmen-oben);
  bottom: var(--rahmen-unten);
  left: var(--rahmen-seite);
  right: var(--infobreite);
  background: #000;
  overflow: hidden;
  touch-action: none;
  cursor: grab;
}

.sichtfeld:active {
  cursor: grabbing;
}

.welt {
  display: block;
  width: 100%;
  height: 100%;
}

.sitename {
  position: absolute;
  left: calc(var(--rahmen-seite) + 12px);
  top: 12px;
  z-index: 12;
  margin: 0;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text);
  pointer-events: none;
}

.sitename span {
  display: block;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: var(--text-matt);
}

.flughinweis {
  position: absolute;
  z-index: 1;
  left: 50%;
  bottom: 10px;
  transform: translateX(-50%);
  margin: 0;
  padding: 0.35rem 0.8rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.42);
  color: var(--text-matt);
  font-size: 0.76rem;
  font-weight: 600;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 600ms ease;
}

html[data-status="flug"] .flughinweis {
  opacity: 1;
}

html[data-hinweis="aus"] .flughinweis {
  opacity: 0;
}

/* ── 3 Schilder ───────────────────────────────────────────────────────── */

/* Ein Element pro Menüpunkt — nie mehrere, auch wenn der Punkt mehrfach im
   Raum steht. Es ist Beschriftung, Klickfläche und der eine Tastaturweg zu
   diesem Punkt in einem. */
.schilder {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}

.schild {
  /* Für den Cluster-Fall ist das Schild ein <button> — der bringt eine
     Schaltflächen-Optik mit, die hier nichts zu suchen hat. */
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: 0;
  font: inherit;
  cursor: pointer;
  position: absolute;
  left: 0;
  top: 0;
  display: block;
  padding: 0.2rem 0.45rem;
  border-radius: 6px;
  text-align: center;
  text-decoration: none;
  color: var(--text);
  pointer-events: auto;
  will-change: transform, opacity;
  transition: opacity 220ms ease, filter 220ms ease;
}

/* Diese eine Zeile ist der Unterschied zwischen „das Schild verschwindet"
   und „das Schild verschwindet nicht". Die Szene blendet ein Schild aus,
   indem sie `el.hidden = true` setzt — und das Attribut wirkt über die
   Regel `[hidden] { display: none }` des Browsers. Die steht aber im
   Browser-Stylesheet, und `display: block` hier steht im Autoren-Stylesheet:
   Autor schlägt Browser, gleiche Spezifität hin oder her.

   Die Folge war nicht etwa ein Schild zu viel, sondern das genaue Gegenteil
   von allem, was die Szene entscheidet: Jedes Schild stand dauerhaft im
   Bild, eingefroren an der Stelle, an der es zuletzt gesetzt worden war —
   auch dann, wenn sein Diamant längst hinter Fels, hinter der Kamera oder
   ganz woanders war. Beschriftungen, die stehen bleiben, während die Welt
   sich dreht. */
.schild[hidden] {
  display: none;
}

.schild-name {
  display: block;
  max-width: 15rem;
  font-size: clamp(0.95rem, 1.7vw, 1.25rem);
  font-weight: 650;
  letter-spacing: 0.045em;
  line-height: 1.15;
  /* Vor einer farbwechselnden, bewegten Welt trägt keine feste Schriftfarbe.
     Kontur plus weicher Schatten trägt vor jedem Hintergrund und kostet
     nichts. */
  paint-order: stroke fill;
  -webkit-text-stroke: 3px var(--text-kontur);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.85), 0 0 18px rgba(0, 0, 0, 0.55);
}

/* Der Untertitel steht ausserhalb des Kastens, den das Schild aufspannt:
   absolut positioniert, unter dem Namen, um die Mitte gehaengt. Vorher stand
   er im Fluss — und weil er breiter ist als jeder Name, war JEDES Schild
   volle fuenfzehn Rem breit, auch das, dessen Untertitel gar nicht zu sehen
   war. Das Ausrichten am Bildrand rechnet mit der halben Schildbreite, also
   riss es jedes Schild in Randnaehe um bis zu 126 Bildpunkte zur Seite: eine
   Beschriftung, die neben ihrem Diamanten stand statt an ihm. */
.schild-unter {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  width: 15rem;
  margin-top: 0.15rem;
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--text-matt);
  paint-order: stroke fill;
  -webkit-text-stroke: 2.5px var(--text-kontur);
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  transition: opacity 200ms ease, max-height 200ms ease;
}

.schild[data-nah="ja"] .schild-unter,
.schild:hover .schild-unter,
.schild:focus-visible .schild-unter {
  opacity: 1;
  max-height: 3rem;
}

.schild:hover .schild-name,
.schild:focus-visible .schild-name {
  color: var(--leuchte);
}

/* ── 4 Cockpit ────────────────────────────────────────────────────────── */

.cockpit {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 10;
}

.cockpit > * {
  pointer-events: auto;
}

.deko-vorrat {
  position: absolute;
}

.rahmen {
  position: absolute;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
}

.rahmen-oben {
  top: 0;
  height: var(--rahmen-oben);
  gap: 1.2rem;
  padding: 0 0.9rem 0 calc(var(--rahmen-seite) + 9.5rem);
  justify-content: space-between;
}

.rahmen-unten {
  bottom: 0;
  height: var(--rahmen-unten);
  padding: 0 var(--rahmen-seite);
}

.deko {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.deko-holm {
  position: absolute;
  top: var(--rahmen-oben);
  bottom: var(--rahmen-unten);
  width: var(--rahmen-seite);
  height: auto;
  inset-inline: auto;
}

.deko-links { left: 0; }
.deko-rechts { right: 0; }

/* Kulisse: matt und unbeschriftet. Nichts hiervon ist anfassbar, nichts
   davon liegt im DOM-Fokus, nichts davon spricht Vorlesesoftware an. */
.platte-hell { stop-color: var(--platte-1); }
.platte-mitte { stop-color: var(--platte-2); }
.platte-dunkel { stop-color: var(--platte-3); }
.niete { fill: var(--kulisse-metall); opacity: 0.5; }
.niete-glanz { fill: var(--kante); opacity: 0.5; }
.riffel-linie { stroke: var(--kulisse-strich); stroke-width: 1.2; }
.kabelkanal { stroke: var(--kulisse-strich); stroke-width: 3; fill: none; }
.kabelkanal.duenn { stroke-width: 1.2; opacity: 0.8; }
.kabelstrang { fill: var(--kulisse-strich); }
.kabelstrang.duenn { opacity: 0.7; }
.plakette { fill: var(--kulisse-metall); opacity: 0.35; }
.plakette-zeile { stroke: var(--kulisse-strich); stroke-width: 1.4; fill: none; }
.skala-bogen { fill: none; stroke: var(--kulisse-metall); stroke-width: 1.6; }
.skala-strich { stroke: var(--kulisse-strich); stroke-width: 1.6; fill: none; }
.skala-achse { fill: var(--kulisse-metall); }
.skala-zeiger {
  stroke: var(--leuchte-matt);
  stroke-width: 1.8;
  fill: none;
  transform-origin: 22px 22px;
  animation: zeiger 7s ease-in-out infinite alternate;
}
.kipp-sockel { fill: var(--platte-3); stroke: var(--kulisse-strich); }
.kipp-hebel { fill: var(--kulisse-metall); }
.kipp-punkt { fill: var(--kulisse-strich); }
.knopf-deko { fill: var(--platte-3); stroke: var(--kulisse-strich); stroke-width: 1.5; }
.knopf-deko.innen { fill: var(--kulisse-metall); opacity: 0.4; stroke: none; }

.led { fill: var(--leuchte-matt); opacity: 0.35; animation: blinken 4s steps(1, end) infinite; }
.led-1 { animation-duration: 2.7s; animation-delay: 0.1s; }
.led-2 { animation-duration: 4.3s; animation-delay: 0.9s; }
.led-3 { animation-duration: 6.1s; animation-delay: 0.4s; }
.led-4 { animation-duration: 3.3s; animation-delay: 1.6s; }
.led-5 { animation-duration: 5.2s; animation-delay: 2.2s; fill: var(--signal); }
.led-6 { animation-duration: 7.7s; animation-delay: 0.6s; fill: var(--signal); }

@keyframes blinken {
  0%, 74% { opacity: 0.22; }
  75%, 82% { opacity: 0.85; }
  83%, 100% { opacity: 0.22; }
}

@keyframes zeiger {
  0% { transform: rotate(-11deg); }
  38% { transform: rotate(6deg); }
  61% { transform: rotate(-3deg); }
  100% { transform: rotate(14deg); }
}

/* Anzeigen: beleuchtet und beschriftet, also echt — auch wenn man sie nicht
   drückt. */
.anzeige {
  position: relative;
  z-index: 2;
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 0.55rem;
  font-family: var(--schrift-technisch);
  font-size: 0.78rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
}

.anzeige-name {
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-matt);
}

.position-pfad,
.status-text {
  color: var(--leuchte);
  text-overflow: ellipsis;
  overflow: hidden;
}

/* ── Der Infobereich ─────────────────────────────────────────────────────
   Eine Säule rechts, immer sichtbar, mit derselben Platte wie der Rahmen —
   sie gehört zum Cockpit und liegt nicht davor. Gescrollt wird nur die Liste
   darin: Kopf und Fuß sollen stehen bleiben, sonst ist der Zähler nach dem
   dritten Fund aus dem Bild. */
.infobereich {
  position: absolute;
  z-index: 3;
  top: var(--rahmen-oben);
  bottom: var(--rahmen-unten);
  right: 0;
  width: var(--infobreite);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.85rem 0.95rem 0.7rem;
  border-left: 1px solid var(--kante);
  overflow: hidden;
}

.deko-info {
  z-index: -1;
}

.infokopf {
  flex: none;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem;
}

.infotitel {
  margin: 0;
  font-family: var(--schrift-technisch);
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-matt);
}

.infozaehler {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  font-family: var(--schrift-technisch);
  font-size: 0.72rem;
}

.infozaehler-zahl {
  font-size: 0.92rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--leuchte-matt);
}

/* Sobald etwas in der Sammlung liegt, leuchtet der Zähler. Vorher wäre das
   eine Auszeichnung für nichts. */
html[data-funde="ja"] .infozaehler-zahl {
  color: var(--leuchte);
  text-shadow: 0 0 10px color-mix(in srgb, var(--leuchte) 55%, transparent);
}

.infozaehler-wort {
  font-size: 0.58rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-matt);
}

.infohinweis {
  flex: none;
  margin: 0;
  font-size: 0.74rem;
  line-height: 1.5;
  color: var(--text-matt);
}

.infohinweis[hidden] {
  display: none;
}

.fundliste {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  align-content: start;
  gap: 0.8rem;
}

.fundstueck {
  border-left: 2px solid var(--kante);
  padding-left: 0.65rem;
}

/* Was gerade dazugekommen ist, blitzt einmal auf. Ein Fund ohne Quittung
   fühlt sich an, als wäre nichts passiert. */
.fundstueck[data-neu="ja"] {
  border-left-color: var(--leuchte);
  animation: fundblitz 1.6s ease-out;
}

@keyframes fundblitz {
  0% { background: color-mix(in srgb, var(--leuchte) 22%, transparent); }
  100% { background: transparent; }
}

.fundstueck-name {
  font-family: var(--schrift-technisch);
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--leuchte);
}

.fundstueck-stand {
  margin-left: 0.4rem;
  font-family: var(--schrift-technisch);
  font-size: 0.66rem;
  font-variant-numeric: tabular-nums;
  color: var(--text-matt);
}

.fundstueck-info {
  margin: 0.3rem 0 0;
  font-size: 0.76rem;
  line-height: 1.5;
  color: var(--text-matt);
  /* Bei einem Lied ist der Zeilenumbruch der Text: Eine Strophe aus denselben
     Wörtern, aber als Fließabsatz gesetzt, ist kein Vers mehr. `pre-line`
     behält die Umbrüche und lässt die Einrückung der Quelle weg — an den
     Fragmenten der Projekte, die keine Umbrüche haben, ändert es nichts. */
  white-space: pre-line;
}

/* Der jüngste Text eines Ziels steht oben und heller als die älteren. */
.fundstueck-info:first-of-type {
  color: var(--text);
}

.funde-fuss {
  flex: none;
  padding-top: 0.2rem;
}

/* Nur für Vorlesesoftware. Nicht `display: none` — das nähme sie auch der
   Vorlesesoftware weg, und dann wäre der Fund für niemanden angesagt. */
.nur-vorlesen {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.status-lampe {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--alarm);
  box-shadow: 0 0 8px currentColor;
  align-self: center;
  flex: none;
}

html[data-status="hochlauf"] .status-lampe {
  background: var(--signal);
  animation: pulsen 900ms ease-in-out infinite alternate;
}

html[data-status="flug"] .status-lampe {
  background: var(--leuchte);
  animation: none;
}

@keyframes pulsen {
  from { opacity: 0.35; }
  to { opacity: 1; }
}

/* Konsole */
.konsole {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding-bottom: 0.5rem;
}

.schalter {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 46px;
  padding: 0.5rem 0.95rem;
  border: 1px solid var(--kante);
  border-radius: 8px;
  background: linear-gradient(var(--platte-1), var(--platte-3));
  color: var(--text);
  font: inherit;
  font-size: 0.84rem;
  font-weight: 650;
  letter-spacing: 0.02em;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 1px 0 rgba(0, 0, 0, 0.5);
  transition: border-color 160ms ease, color 160ms ease, background 160ms ease;
}

.schalter:hover:not(:disabled) {
  border-color: var(--leuchte);
  color: var(--leuchte);
}

.schalter:disabled {
  cursor: not-allowed;
  color: var(--text-matt);
  border-color: var(--kulisse-strich);
}

.schalter[aria-pressed="true"],
.schalter[aria-expanded="true"] {
  border-color: var(--leuchte);
  color: var(--grund);
  background: linear-gradient(var(--leuchte), var(--leuchte-matt));
}

.schalter-symbol svg {
  display: block;
  width: 18px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
}

.schalter-haupt {
  margin-right: auto;
}

/* Der Schubhebel: zwei Tasten, die gedrückt gehalten werden. */
.hebel {
  display: inline-flex;
  gap: 0.3rem;
}

.schalter-hebel[data-an="ja"] {
  border-color: var(--leuchte);
  color: var(--grund);
  background: linear-gradient(var(--leuchte), var(--leuchte-matt));
}

/* ── 5 Burgermenü und Einstellungen ───────────────────────────────────── */

.burger-panel,
.einstellungen {
  position: absolute;
  z-index: 20;
  max-height: calc(100% - var(--rahmen-oben) - var(--rahmen-unten) - 1.5rem);
  padding: 1.1rem 1.3rem 1.3rem;
  border: 1px solid var(--kante);
  border-radius: 10px;
  background: color-mix(in srgb, var(--platte-2) 96%, transparent);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(6px);
}

/* Nicht das Panel scrollt, sondern die Liste darin. Sonst wandern Kopf und
   Fuß mit hinaus — auf dem Telefon war Impressum nur nach einer vollen
   Menülänge Scrollen erreichbar, also praktisch nicht. */
.burger-panel {
  left: var(--rahmen-seite);
  bottom: calc(var(--rahmen-unten) + 0.6rem);
  width: min(26rem, calc(100% - 2 * var(--rahmen-seite)));
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.burger-fuss {
  flex: none;
}

.burger-panel > .menu-tiefe-0 {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Der Rand hält die Bildlaufleiste von den Einträgen fern, ohne dass die
     Einträge selbst schmaler werden. */
  margin-right: -0.5rem;
  padding-right: 0.5rem;
}

.einstellungen {
  overflow-y: auto;
  right: calc(var(--infobreite) + 0.6rem);
  bottom: calc(var(--rahmen-unten) + 0.6rem);
  width: min(23rem, calc(100% - var(--rahmen-seite) - var(--infobreite) - 1.2rem));
}

.burger-panel[hidden],
.einstellungen[hidden] {
  display: none;
}

.einstellungen-titel {
  margin: 0 0 0.8rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-matt);
}

/* Ein Schalter, der nicht in der Konsole steht, sondern in einem Panel:
   kleiner, damit er den Inhalt nicht überstimmt. */
.schalter-klein {
  min-height: 34px;
  padding: 0.25rem 0.7rem;
  font-size: 0.76rem;
}

.menu-liste {
  list-style: none;
  margin: 0;
  padding: 0;
}

.menu-tiefe-1 {
  margin-left: 0.9rem;
  padding-left: 0.9rem;
  border-left: 1px solid var(--kulisse-strich);
}

.menu-eintrag + .menu-eintrag {
  margin-top: 0.15rem;
}

.menu-ziel {
  display: block;
  padding: 0.5rem 0.6rem;
  border-radius: 7px;
  color: var(--text);
  text-decoration: none;
  border: 1px solid transparent;
}

.menu-ziel:hover,
.menu-ziel:focus-visible {
  border-color: var(--kante);
  background: var(--platte-1);
  color: var(--leuchte);
}

.menu-label {
  font-size: 1rem;
  font-weight: 650;
}

.menu-gruppe {
  display: block;
  margin: 0.7rem 0 0.1rem;
  padding: 0 0.6rem;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--leuchte-matt);
}

.menu-untertitel {
  display: block;
  padding: 0 0.6rem;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text-matt);
}

.menu-ziel .menu-untertitel {
  padding: 0;
}

.burger-fuss {
  display: flex;
  gap: 1.2rem;
  list-style: none;
  margin: 1rem 0 0;
  padding: 0.8rem 0.6rem 0;
  border-top: 1px solid var(--kulisse-strich);
  font-size: 0.82rem;
}

.burger-fuss a,
.einstellungen-fuss a {
  color: var(--text-matt);
}

.feld {
  margin: 0 0 1rem;
  padding: 0;
  border: 0;
}

.feld legend {
  padding: 0;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-matt);
}

.wahl {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin-top: 0.45rem;
}

.wahl label {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 40px;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--kante);
  border-radius: 7px;
  background: var(--platte-1);
  font-size: 0.82rem;
  font-weight: 600;
  cursor: pointer;
}

.wahl-breit {
  width: 100%;
  line-height: 1.35;
}

.wahl label:hover {
  border-color: var(--leuchte);
}

.wahl input {
  accent-color: var(--leuchte);
  margin: 0;
}

.wahl label:has(input:checked) {
  border-color: var(--leuchte);
  color: var(--leuchte);
}

/* Der Farbregler. Zwei Knöpfe, dazwischen der Stand — bewusst mit einer
   Ziffer und nicht bloß als Balken: Wer die Seite wieder öffnet, will
   ablesen können, wo er stehen geblieben ist. Der Knopf am Anschlag wird
   von cockpit.js abgeschaltet und sieht dann auch so aus. */
.farbregler {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.45rem;
}

.schalter-farbe {
  min-width: 6.5rem;
}

.farbe-wert {
  flex: 1;
  min-width: 5rem;
  padding: 0.3rem 0.6rem;
  border: 1px solid var(--kulisse-strich);
  border-radius: 7px;
  background: var(--platte-3);
  font-family: var(--schrift-technisch);
  font-size: 0.8rem;
  font-weight: 600;
  text-align: center;
  color: var(--leuchte);
}

.feld-hinweis {
  margin: 0.5rem 0 0;
  font-size: 0.76rem;
  line-height: 1.4;
  color: var(--text-matt);
}

.einstellungen-fuss {
  display: flex;
  gap: 1.2rem;
  list-style: none;
  margin: 0;
  padding: 0.8rem 0 0;
  border-top: 1px solid var(--kulisse-strich);
  font-size: 0.82rem;
}

/* Selbstauskunft unter /?diagnose */
.diagnose {
  position: absolute;
  inset: var(--rahmen-oben) 0.5rem var(--rahmen-unten);
  z-index: 40;
  overflow: auto;
  padding: 0.8rem 1rem 1.2rem;
  border: 1px solid var(--kante);
  border-radius: 10px;
  background: color-mix(in srgb, var(--platte-3) 97%, transparent);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.7);
}

.diagnose-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  position: sticky;
  top: -0.8rem;
  margin: -0.8rem -1rem 0.6rem;
  padding: 0.8rem 1rem 0.5rem;
  background: inherit;
}

.diagnose h2 {
  margin: 0;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-matt);
}

.diagnose pre {
  margin: 0;
  font-family: var(--schrift-technisch);
  font-size: 0.72rem;
  line-height: 1.5;
  color: var(--text);
  white-space: pre-wrap;
  word-break: break-word;
  user-select: text;
}

/* ── 6 Textseiten ─────────────────────────────────────────────────────── */

body.dokument {
  background: var(--grund);
}

.blatt {
  max-width: 44rem;
  margin: 0 auto;
  padding: 2.5rem 1.3rem 4rem;
  line-height: 1.65;
  color: var(--text);
}

.blatt h1 {
  font-size: clamp(1.6rem, 4vw, 2.2rem);
  letter-spacing: -0.01em;
}

.blatt h2 {
  margin-top: 2.2rem;
  font-size: 1.1rem;
  letter-spacing: 0.02em;
  color: var(--leuchte);
}

.blatt a {
  color: var(--leuchte);
}

.blatt address {
  font-style: normal;
  padding: 0.8rem 1rem;
  border-left: 2px solid var(--kante);
  background: var(--platte-2);
}

.blatt-zurueck {
  font-size: 0.85rem;
  font-weight: 600;
}

.blatt-zurueck a {
  color: var(--text-matt);
  text-decoration: none;
}

.blatt-stand {
  margin-top: 2.5rem;
  font-size: 0.8rem;
  color: var(--text-matt);
}

.blatt .code {
  font-family: var(--schrift-technisch);
  font-size: 3rem;
  font-weight: 700;
  color: var(--leuchte-matt);
  margin: 0;
}

/* Liedseiten. Der Liedtext ist der einzige Ort dieser Seite, an dem der
   Zeilenumbruch Bedeutung trägt — deshalb <pre>, und deshalb `pre-wrap`,
   damit eine zu lange Zeile auf dem Telefon umbricht, statt seitlich zu
   verschwinden. */
.lied-untertitel {
  font-size: 1.05rem;
  color: var(--text-matt);
}

.liedtext {
  margin: 2rem 0;
  padding: 1.2rem 1.2rem 1.2rem 1.4rem;
  border-left: 2px solid var(--kante);
  background: var(--platte-3);
  font-family: var(--schrift);
  font-size: 0.98rem;
  line-height: 1.7;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

.hoeren-knopf {
  display: inline-block;
  padding: 0.6rem 1.1rem;
  border: 1px solid var(--kante);
  background: var(--platte-2);
  color: var(--leuchte);
  font-weight: 600;
  text-decoration: none;
}

.hoeren-knopf:hover,
.hoeren-knopf:focus-visible {
  background: var(--platte-1);
}

/* ── 7 Zustände ───────────────────────────────────────────────────────── */

/* Kein Signal: schwarzer Hintergrund, kein Ersatzbild. Ein Raumschiff ohne
   Außenbild, bei dem nur die Konsole leuchtet. Deckt drei Fälle ab — kein
   WebGL2, misslungene Shader-Übersetzung, verlorener Grafikkontext. */
html[data-status="offline"] .welt,
html[data-status="offline"] .schilder,
html[data-status="offline"] .flughinweis {
  display: none;
}

html[data-status="offline"] .sichtfeld {
  background: #000;
  cursor: default;
}

html[data-status="offline"] .status-text {
  color: var(--alarm);
}

html[data-status="hochlauf"] .status-text {
  color: var(--signal);
}

/* Bewegung anhalten: der Schwarm friert ein, die Welt bleibt stehen. */
html[data-bewegung="aus"] .led,
html[data-bewegung="aus"] .skala-zeiger {
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  .led,
  .skala-zeiger,
  .status-lampe {
    animation: none !important;
  }
}

/* ── 8 Schmale Bildschirme ────────────────────────────────────────────── */

/* Die Dichte bleibt, der Rahmen wird schmaler. Reduziert wird Fläche, nicht
   Look. Die echten Schalter behalten eine treffbare Größe. */
@media (max-width: 860px) {
  :root {
    --rahmen-oben: 46px;
    --rahmen-unten: 92px;
    --rahmen-seite: 26px;
  }

  .rahmen-oben {
    padding-left: calc(var(--rahmen-seite) + 0.6rem);
    gap: 0.6rem;
  }

  .sitename {
    display: none;
  }

  .rahmen-unten {
    padding: 0 0.5rem;
  }

  .konsole {
    gap: 0.35rem;
  }

  .schalter {
    padding: 0.5rem 0.6rem;
    font-size: 0.78rem;
  }

  /* Nur wo ein Symbol steht, weicht die Beschriftung. Ein Schalter ohne
     Symbol — der Kopierknopf der Selbstauskunft — bliebe sonst eine leere
     Fläche. Die Regel „beschriftet heißt anfassbar" trägt hier die
     Vorlesebeschriftung. */
  .schalter-symbol + .schalter-text {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .schalter-symbol svg {
    width: 22px;
    height: 16px;
  }

  .burger-panel,
  .einstellungen {
    left: 0.5rem;
    right: 0.5rem;
    width: auto;
  }

  /* Auf schmalen Geräten wandert der Infobereich von der Seite nach unten:
     eine Leiste über der Konsole. Er bleibt sichtbar — das ist der Punkt —,
     nimmt aber Höhe statt Breite, weil Breite dort nicht da ist. */
  :root {
    --infobreite: 0px;
    --infohoehe: 8.5rem;
  }

  .sichtfeld {
    right: var(--rahmen-seite);
    bottom: calc(var(--rahmen-unten) + var(--infohoehe));
  }

  .infobereich {
    top: auto;
    bottom: var(--rahmen-unten);
    left: 0;
    right: 0;
    width: auto;
    height: var(--infohoehe);
    padding: 0.45rem 0.7rem 0.5rem;
    border-left: none;
    border-top: 1px solid var(--kante);
    gap: 0.3rem;
  }

  .infohinweis {
    font-size: 0.68rem;
    /* Zwei Zeilen, dann ist Schluss — die Leiste ist niedrig, und der Platz
       gehört den Funden und nicht der Erklärung. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  .einstellungen {
    right: 0.5rem;
    width: auto;
    bottom: calc(var(--rahmen-unten) + var(--infohoehe) + 0.5rem);
  }

  .burger-panel {
    bottom: calc(var(--rahmen-unten) + var(--infohoehe) + 0.5rem);
  }

  /* Der Zurücksetzen-Knopf braucht in der Leiste keinen eigenen Fuß. */
  .funde-fuss {
    position: absolute;
    top: 0.45rem;
    right: 0.7rem;
    padding: 0;
  }

  .funde-fuss .schalter-klein {
    min-height: 26px;
    padding: 0.15rem 0.5rem;
    font-size: 0.66rem;
  }

  .anzeige-name {
    display: none;
  }

  .flughinweis {
    font-size: 0.68rem;
    white-space: normal;
    max-width: 90%;
    text-align: center;
  }
}

@media (max-width: 520px) {
  :root {
    --rahmen-seite: 16px;
  }

  .deko-holm {
    opacity: 0.9;
  }
}
