/* Pandaloop Admin Plane — Blueprint-Grau, Raster, Rot als Wuerze.
   Variablennamen wie in pandaloop.de/assets/styles.css. */

@font-face { font-family: 'Mozilla Headline'; src: url('/static/fonts/Mozilla_Headline_VF.woff2') format('woff2-variations');
             font-weight: 200 700; font-display: swap; }
@font-face { font-family: 'Geist'; src: url('/static/fonts/Geist_VF.woff2') format('woff2-variations');
             font-weight: 100 900; font-display: swap; }
@font-face { font-family: 'Geist Mono'; src: url('/static/fonts/Geist_Mono_VF.woff2') format('woff2-variations');
             font-weight: 100 900; font-display: swap; }

:root {
  --white:       #e4e4e4;
  --grey:        #959595;
  --black:       #222222;
  --red:         #e94b27;
  --orange:      #e66100;
  --lightgrey:   #bbb;
  --lightergrey: #ddd;
  /* --grey auf dem Kachelgrund ergibt 2,2:1 -- unter der Haelfte dessen,
     was lesbar heisst. Betroffen war nicht Beiwerk, sondern die ganze
     Erklaerlogik: jeder .hint, jede UUID, jedes Gruppenband im Menue.
     Also ein zweiter Ton fuer Text; --grey bleibt fuer Striche. */
  --grey-text:   #6a6a6a;

  --sp:  min(95vw, 2500px);
  --px:  calc(1 / 1600 * var(--sp));
  --gap: calc(12 * var(--px));
  --s1: calc((var(--sp) - 7 * var(--gap)) / 8);
  --s2: calc(2 * var(--s1) + var(--gap));
  --s4: calc(4 * var(--s1) + 3 * var(--gap));
  --s6: calc(6 * var(--s1) + 5 * var(--gap));

  --border-solid:  1px solid var(--black);
  --border-dashed: 1px dashed var(--black);
  --radius: calc(5 * var(--px));

  --ls-headline: calc(-1 / 40);
  --ls-mono:     calc(-1 / 15);
  --ls-body:     calc(-1 / 30);
}

/* Bis hierher zog '--px' die gesamte Typografie mit der Fensterbreite: auf
   einem Telefon mit 390 px ergab die Grundschrift 3,9 px und der Hinweistext
   2,8 px. Rechnerisch schluessig, praktisch unlesbar -- und eine Control
   Plane macht man gerade unterwegs auf, um zu sehen, ob ein Deploy durch
   ist. Unterhalb von 900 px bekommt '--px' deshalb einen festen Wert; das
   Raster rechnet weiter in '--px', hoert aber auf zu schrumpfen. */
@media (max-width: 900px) {
  :root {
    --sp: calc(100vw - 8vw);
    --px: 0.92px;
    --gap: 4vw;
  }
}

@media (max-width: 800px) { :root { --gap: 5vw; } }

* { box-sizing: border-box; }

html {
  font-family: 'Geist', system-ui, sans-serif;
  font-size: calc(17 * var(--px));
  letter-spacing: calc(var(--ls-body) * 1em);
  color: var(--black);
  background: var(--white);
}
body { margin: 0; min-height: 100vh; }

/* Hintergrund-Spaltenraster, liegt fest hinter allem. */
.bggrid {
  position: fixed; inset: 0; z-index: -2;
  display: flex; gap: var(--gap);
  width: var(--sp); margin: 0 auto;
  pointer-events: none;
}
.bggrid .cell { flex: 1; border-left: 1px dashed var(--lightgrey); }
.bggrid .cell:last-child { border-right: 1px dashed var(--lightgrey); }

/* Registerkreuze an den Rasterkanten — Passermarken aus dem Druck. */
.crosses { position: fixed; inset: 0; z-index: -1; pointer-events: none; }
.crosses span {
  position: absolute; width: calc(14 * var(--px)); height: calc(14 * var(--px));
  background: url('/static/cross.svg') no-repeat center / contain; opacity: .5;
}

.wrap { width: var(--sp); margin: 0 auto; padding: calc(28 * var(--px)) 0 calc(60 * var(--px)); }

/* -- Kopf ------------------------------------------------------------- */

header.top {
  display: flex; align-items: center; gap: var(--gap);
  padding-bottom: calc(14 * var(--px)); border-bottom: var(--border-solid);
}
header.top img.mark { height: calc(34 * var(--px)); width: auto; }
header.top .wordmark {
  font-family: 'Mozilla Headline', 'Geist', sans-serif; font-weight: 600;
  font-size: calc(26 * var(--px)); letter-spacing: calc(var(--ls-headline) * 1em);
  line-height: 1;
}
header.top nav { margin-left: auto; display: flex; gap: calc(6 * var(--px)); align-items: center; }

.navlink {
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: calc(13 * var(--px)); text-transform: uppercase;
  letter-spacing: calc(var(--ls-mono) * 1em);
  padding: calc(6 * var(--px)) calc(11 * var(--px));
  background: #aeaeaea1; backdrop-filter: blur(10px);
  border-radius: var(--radius); color: var(--black); text-decoration: none;
  border: none; cursor: pointer; transition: background 150ms;
}
.navlink:hover { background: #e94b27a1; }

/* -- Abschnittslabel: roter Slash, Mono-Versalien, Haarlinie ---------- */

.section-label {
  display: flex; align-items: baseline; gap: calc(8 * var(--px));
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: calc(15 * var(--px)); text-transform: uppercase;
  letter-spacing: calc(var(--ls-mono) * 1em);
  margin: calc(38 * var(--px)) 0 calc(14 * var(--px));
  border-bottom: var(--border-solid); padding-bottom: calc(6 * var(--px));
}
.section-label .slash { color: var(--red); }
.section-label .count { margin-left: auto; color: var(--grey-text); }

h1 {
  font-family: 'Mozilla Headline', 'Geist', sans-serif;
  font-size: calc(75 * var(--px)); font-weight: 700; line-height: .8;
  letter-spacing: calc(var(--ls-headline) * 1em);
  margin: calc(24 * var(--px)) 0 calc(8 * var(--px));
}
h2 {
  font-family: 'Mozilla Headline', 'Geist', sans-serif;
  font-size: calc(36 * var(--px)); font-weight: 600; line-height: .9;
  letter-spacing: calc(var(--ls-headline) * 1em); margin: 0;
}

.mono { font-family: 'Geist Mono', ui-monospace, monospace; letter-spacing: calc(var(--ls-mono) * 1em); }
.caps { text-transform: uppercase; }
.dim  { color: var(--grey-text); }
.num  { color: var(--black); }
.num::before { content: '['; color: var(--red); }
.num::after  { content: ']'; color: var(--red); }

/* -- Instanzkarte als Terminalfenster --------------------------------- */

/* flex-start statt des voreingestellten stretch: sonst zieht die hoechste
   Kachel einer Zeile alle anderen auf ihre Hoehe, und wer eine aufklappt,
   laesst ihre Nachbarn mitwachsen, ohne dass dort etwas zu sehen waere. */
.grid { display: flex; flex-wrap: wrap; gap: var(--gap); align-items: flex-start; }

.product-window {
  width: var(--s2); min-width: calc(260 * var(--px));
  border: var(--border-solid); background: var(--lightergrey);
  display: flex; flex-direction: column;
}
.product-window .head {
  display: flex; align-items: center; gap: calc(8 * var(--px));
  padding: calc(8 * var(--px)) calc(10 * var(--px));
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: calc(13 * var(--px)); text-transform: uppercase;
  letter-spacing: calc(var(--ls-mono) * 1em);
}
.product-window .head img { width: calc(14 * var(--px)); height: calc(14 * var(--px)); }
.product-window .head .n { margin: 0 auto; }
.product-window hr { border: none; border-top: var(--border-dashed); margin: 0; }
.product-window .body { padding: calc(12 * var(--px)) calc(10 * var(--px)); flex: 1; }
.product-window .body .name {
  font-family: 'Mozilla Headline', 'Geist', sans-serif; font-weight: 600;
  font-size: calc(28 * var(--px)); line-height: 1;
  letter-spacing: calc(var(--ls-headline) * 1em);
  word-break: break-word;
}
.product-window dl { margin: calc(12 * var(--px)) 0 0; font-size: calc(14 * var(--px)); }
.product-window dl div { display: flex; gap: calc(8 * var(--px)); padding: calc(3 * var(--px)) 0; }
.product-window dt {
  font-family: 'Geist Mono', ui-monospace, monospace; text-transform: uppercase;
  font-size: calc(12 * var(--px)); color: var(--grey-text); min-width: calc(74 * var(--px));
  letter-spacing: calc(var(--ls-mono) * 1em);
}
/* 'break-all' bricht immer mitten im Wort, auch wenn eine Leerstelle in
   Reichweite ist. Fuer einen Imagenamen ohne Leerzeichen war das richtig,
   fuer einen Satz zerhackt es die Woerter. 'anywhere' bricht am Wortende,
   solange es eines gibt, und erst im Notfall mittendrin — beides also
   richtig. 'min-width: 0', weil das dd ein Flex-Kind ist: ohne das schrumpft
   es nicht unter seine Inhaltsbreite und laeuft aus der Kachel heraus. */
.product-window dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.product-window dd ul { margin: calc(3 * var(--px)) 0 0; padding-left: 1.1em; }
.product-window dd li { margin-bottom: calc(2 * var(--px)); }
.product-window .foot {
  display: flex; gap: calc(6 * var(--px)); padding: calc(10 * var(--px));
  border-top: var(--border-dashed);
}

/* Verwaltete Instanzen sind der Normalfall: ruhige Flaeche, fester Rahmen.
   Fremde fallen auf — gestrichelter Rahmen und Punktraster, wie eine
   Flaeche in einer technischen Zeichnung, die nicht zum Bauteil gehoert. */
.product-window.unmanaged {
  border: var(--border-dashed);
  background-image: radial-gradient(var(--lightgrey) calc(1 * var(--px)), transparent calc(1 * var(--px)));
  background-size: calc(9 * var(--px)) calc(9 * var(--px));
}
.product-window.unmanaged .name { color: var(--grey-text); }
.product-window.unmanaged .head { color: var(--grey-text); }

.taglabel {
  display: inline-block;
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: calc(12 * var(--px)); text-transform: uppercase;
  letter-spacing: calc(var(--ls-mono) * 1em);
  padding: calc(2 * var(--px)) calc(7 * var(--px));
  border: 2px dotted var(--grey); border-radius: calc(3 * var(--px));
  background: linear-gradient(#ececec, #dcdcdc);
  transition: background 150ms, border-color 150ms;
}
.taglabel.hot { border-style: solid; border-color: var(--black); font-weight: 700; }

/* -- Formular ---------------------------------------------------------- */

form.panel { width: var(--s4); min-width: calc(300 * var(--px)); }
.field { margin-bottom: calc(14 * var(--px)); }
.field label, .field .feldkopf {
  display: block; font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: calc(12 * var(--px)); text-transform: uppercase; color: var(--grey-text);
  letter-spacing: calc(var(--ls-mono) * 1em); margin-bottom: calc(4 * var(--px));
}
.field input, .field select, .field textarea {
  width: 100%; font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: calc(15 * var(--px)); letter-spacing: calc(var(--ls-mono) * 1em);
  padding: calc(8 * var(--px)) calc(10 * var(--px));
  border: var(--border-solid); border-radius: 0;
  background: var(--lightergrey); color: var(--black);
}
/* Die Regel darueber meint Textfelder. Auf ein Ankreuzfeld angewandt zieht
   sie das Kaestchen ueber die ganze Zeile — es steht dann mittig, und der
   Text daneben rutscht darunter. Ein Kaestchen ist so breit, wie es ist. */
.field input[type="checkbox"], .field input[type="radio"] {
  width: auto; padding: 0; margin: 0 calc(8 * var(--px)) 0 0;
  vertical-align: baseline;
}
/* Und die Zeile um ein Kaestchen ist Fliesstext, keine Feldbeschriftung.
   Getroffen wird sie ueber ihren Inhalt, nicht ueber ein fehlendes 'for':
   Beschriftungen ohne 'for' gibt es auch anderswo, und die sollen
   Beschriftungen bleiben. */
.field label:has(> input[type="checkbox"]),
.field label:has(> input[type="radio"]) {
  display: block; text-transform: none; color: var(--black);
  font-family: inherit; font-size: calc(14 * var(--px));
  letter-spacing: normal; margin-bottom: calc(6 * var(--px));
}
.field textarea { min-height: calc(90 * var(--px)); resize: vertical; }
/* Ein Hinweis erklaert, er behauptet nicht. Bisher galt das nur innerhalb
   eines Formularfelds — ein '<p class="hint">' auf der Seite bekam gar keinen
   Stil und stand in voller Textgroesse da wie Fliesstext. Die laengsten waren
   damit 400 Zeichen Prosa in Erzaehlgroesse; sie sind jetzt das, was sie sein
   sollten: eine Nebenbemerkung. Die Breite deckelt mit, weil eine graue Zeile
   ueber die ganze Seite niemand liest. */
.hint {
  font-size: calc(13 * var(--px));
  color: var(--grey-text);
  line-height: 1.45;
  max-width: 72ch;
}
.field .hint { font-size: calc(12 * var(--px)); color: var(--grey-text); margin-top: calc(4 * var(--px)); }

/* Das lange Warum hinter einem Aufklapper: die Seite liest sich kurz, das
   Wissen bleibt einen Klick entfernt. */
details.warum { max-width: 72ch; margin: calc(6 * var(--px)) 0 calc(12 * var(--px)); }
details.warum > summary {
  font-size: calc(12 * var(--px)); color: var(--grey-text);
  text-transform: uppercase; letter-spacing: calc(var(--ls-mono) * 1em);
  cursor: pointer; list-style: none;
}
details.warum > summary::-webkit-details-marker { display: none; }
details.warum > summary::before { content: "+ "; color: var(--red); }
details.warum[open] > summary::before { content: "- "; }
details.warum > summary:hover { color: var(--black); }
details.warum > p { font-size: calc(13 * var(--px)); color: var(--grey-text); line-height: 1.45; }

.action {
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: calc(14 * var(--px)); text-transform: uppercase;
  letter-spacing: calc(var(--ls-mono) * 1em);
  padding: calc(8 * var(--px)) calc(14 * var(--px));
  border: var(--border-solid); border-radius: 0;
  background: var(--white); color: var(--black); cursor: pointer;
  transition: background 150ms, color 150ms;
  /* Auch fuer ein <a>: die Regel hing am Elementnamen, und fuenf Seiten
     stellten ihre Hauptaktion als Fliesstextlink dar -- bei den
     Einstellungen ausgerechnet den einzigen Weg, die Coolify-Verbindung zu
     pruefen. Die Unterstreichung kommt hier aus border-bottom, deshalb wird
     die mit abgeraeumt und nicht text-decoration. */
  display: inline-block; text-decoration: none; border-bottom: var(--border-solid);
}
.action:hover { background: var(--red); color: var(--white); }
.action.quiet:hover { background: var(--black); }

/* -- Meldungen --------------------------------------------------------- */

.note { border: var(--border-solid); padding: calc(12 * var(--px)); margin: calc(16 * var(--px)) 0; background: var(--lightergrey); }
.note.bad { border-left: calc(4 * var(--px)) solid var(--red); }
.note.good { border-left: calc(4 * var(--px)) solid var(--black); }
.note .k { font-family: 'Geist Mono', ui-monospace, monospace; text-transform: uppercase; font-size: calc(12 * var(--px)); color: var(--grey-text); }

/* -- Anmeldung --------------------------------------------------------- */

.login-shell { display: flex; align-items: center; justify-content: center; min-height: 100vh; }
.login-box { width: var(--s2); min-width: calc(320 * var(--px)); border: var(--border-solid); background: var(--lightergrey); }
.login-box .head { display: flex; align-items: center; gap: calc(8 * var(--px)); padding: calc(9 * var(--px)) calc(11 * var(--px)); font-family: 'Geist Mono', ui-monospace, monospace; font-size: calc(13 * var(--px)); text-transform: uppercase; letter-spacing: calc(var(--ls-mono) * 1em); }
.login-box .head img { width: calc(14 * var(--px)); height: calc(14 * var(--px)); }
.login-box .body { padding: calc(16 * var(--px)); }

/* Randannotation in Mono, wie die Koordinaten am Hero-Rand. */
.annotation {
  position: fixed; bottom: calc(12 * var(--px)); left: calc(14 * var(--px));
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: calc(11 * var(--px)); color: var(--grey-text);
  letter-spacing: calc(var(--ls-mono) * 1em); text-transform: uppercase;
}

/* -- Navigation: Logo als Heimweg, aktiver Punkt ---------------------- */

header.top .home {
  display: flex; align-items: center; gap: var(--gap);
  text-decoration: none; color: var(--black);
}
header.top .home img.mark { transition: transform 150ms; }
header.top .home:hover img.mark { transform: rotate(-4deg); }
.navlink.on { background: #e94b27a1; }

/* -- Tabelle: Zeilen als Raster, kein Kasten -------------------------- */

table.listing {
  width: 100%; border-collapse: collapse;
  margin-top: calc(4 * var(--px));
}
table.listing th {
  text-align: left;
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: calc(12 * var(--px)); text-transform: uppercase;
  letter-spacing: calc(var(--ls-mono) * 1em);
  color: var(--grey-text); font-weight: 400;
  padding: calc(6 * var(--px)) calc(8 * var(--px));
  border-bottom: var(--border-solid);
}
table.listing td {
  padding: calc(9 * var(--px)) calc(8 * var(--px));
  border-bottom: var(--border-dashed);
  font-size: calc(15 * var(--px)); vertical-align: top;
}
table.listing tr:hover td { background: var(--lightergrey); }

/* Kacheln des Dashboards duerfen schmaler stehen als Produktfenster. */
.grid .product-window { min-width: calc(220 * var(--px)); }

/* -- Filterzeile ------------------------------------------------------ */

.filters {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: calc(6 * var(--px));
  margin: calc(10 * var(--px)) 0 calc(4 * var(--px));
}
.filters a.taglabel { text-decoration: none; color: var(--black); }
.filters a.taglabel:hover { background: var(--red); color: var(--white); border-color: var(--black); }
.filters a.taglabel.hot { background: var(--black); color: var(--white); border-color: var(--black); }
.filters a.taglabel.hot .dim { color: var(--lightgrey); }
.filters .sep { color: var(--grey-text); margin: 0 calc(4 * var(--px)); }

/* -- Links: kein Browser-Blau, roter Marker beim Überfahren ------------ */

a { color: var(--black); text-decoration: none; }
/* '.nurikon' ausgenommen: ein Zeichen ist keine Textstelle, die man
   unterstreicht. Und weil diese Regel nur auf 'a' greift, bekamen Stift und
   Papier eine Linie, Duplizieren (summary) und Entfernen (button) keine -
   was aussah, als staenden die Zeichen auf verschiedenen Hoehen. */
.wrap p a:not(.blank), .wrap dd a:not(.blank),
td a:not(.navlink):not(.action):not(.nurikon):not(.blank) {
  border-bottom: 1px solid var(--grey);
  transition: border-color 150ms, color 150ms;
}
.wrap p a:not(.blank):hover, .wrap dd a:not(.blank):hover,
td a:not(.navlink):not(.action):not(.nurikon):not(.blank):hover {
  border-bottom-color: var(--red);
}
/* Trennzeichen in Linkzeilen bleibt grau, der Slash rot — wie im Fußzeilen-
   Muster "Seite 1 / 3". */
.linkline { display: flex; gap: calc(8 * var(--px)); align-items: baseline; }
.linkline .sep { color: var(--red); }

/* -- Kachelfuß: Mono-Labels statt Knöpfe ------------------------------- */

.product-window .foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: calc(10 * var(--px));
  padding: calc(8 * var(--px)) calc(10 * var(--px));
  border-top: var(--border-dashed);
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: calc(12 * var(--px)); text-transform: uppercase;
  letter-spacing: calc(var(--ls-mono) * 1em);
}
.product-window .foot form { display: inline; }
.act {
  background: none; border: none; padding: 0; cursor: pointer;
  font: inherit; letter-spacing: inherit; text-transform: inherit;
  color: var(--black); border-bottom: 1px solid var(--grey);
  transition: color 150ms, border-color 150ms;
}
.act:hover { color: var(--red); border-bottom-color: var(--red); }
/* "Nach aussen oeffnen" trug die Klasse und sah trotzdem aus wie jeder
   andere Knopf -- eine Regel dafuer gab es nicht. Der Knopf oeffnet eine
   Kopie echter Kundendaten nach draussen; er darf nicht grau sein. */
.act.gefahr { color: var(--red); border-bottom-color: var(--red); }
.act.gefahr:hover { background: var(--red); color: var(--white); }
.act.danger { color: var(--grey-text); }
.act.danger:hover { color: var(--red); border-bottom-color: var(--red); }
.product-window .foot .right { margin-left: auto; }

/* Zugeklappt ist ein Ausklapper nur sein Wort und steht in der Reihe.
   Aufgeklappt ist das Formular breiter als der Platz daneben — also nimmt
   es eine eigene Zeile ueber die volle Kachelbreite, statt rechts
   herauszuragen. */
.product-window .foot > * { min-width: 0; max-width: 100%; }
.product-window details.remove > summary { list-style: none; cursor: pointer; }
.product-window details.remove > summary::-webkit-details-marker { display: none; }
.product-window .foot > details[open] {
  flex-basis: 100%; width: 100%; margin-left: 0;
  padding-top: calc(8 * var(--px));
}
/* Das Menue: eine Spalte, kein Feld nebeneinander. Wer hier ist, sucht eine
   Handlung und keine Anordnung. */
.product-window .menu > summary { list-style: none; cursor: pointer; }
.product-window .menu > summary::-webkit-details-marker { display: none; }
.product-window .menu-panel {
  display: grid; gap: calc(10 * var(--px));
  padding-top: calc(10 * var(--px));
}
.product-window .menu-panel > form { display: block; }
.product-window .menu-panel details[open] { padding-bottom: calc(4 * var(--px)); }
/* Innerhalb des Menues sind es Zeilen, keine Woerter in einer Reihe. */
.product-window .menu-panel .act { display: inline-block; }

/* Gruppen im Menue.
   Acht Eintraege untereinander sind eine Liste, keine Ordnung: alles gleich
   laut, Haeufiges neben Seltenem, und das Loeschen mittendrin. Eine
   Ueberschrift je Gruppe kostet eine Zeile und beantwortet die Frage, in
   welcher Gegend man sucht -- dieselbe Geste wie '/ SYNOPSIS' im Web, nur
   kleiner. */
/* Die Gruppe ist eine Ueberschrift, kein Aufklapper mehr.
   Sie war einer, und damit lagen drei Ebenen uebereinander: Mehr, dann die
   Gruppe, dann die Aktion. Loeschen kostete drei Aufklapper, und die
   mittlere Ebene trug ausgerechnet die kleinste Schrift der Seite und nach
   eigenem Entschluss kein Auf-Zu-Zeichen -- ein Klickziel, das nicht
   aussah wie eines, auf halbem Weg zum Ziel.
   Die Ordnung bleibt, der Klick faellt weg. */
.menu-gruppe {
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: calc(11 * var(--px)); text-transform: uppercase;
  letter-spacing: calc(var(--ls-mono) * 1em);
  color: var(--black);
  margin-top: calc(12 * var(--px));
  border-bottom: var(--border-dashed);
  padding-bottom: calc(5 * var(--px));
}
.menu-gruppe:first-child { margin-top: 0; }
/* Die Linie liegt unter der Ueberschrift, nicht neben ihr: ein Strich links
   nimmt die Ueberschrift mit und ruecht sie aus der Spalte der anderen. Nur
   der Inhalt ruecht ein. */
.menu-gruppe ~ :not(.menu-gruppe) { margin-left: calc(10 * var(--px)); }
.menu-gruppe .slash { color: var(--red); margin-right: calc(4 * var(--px)); }
/* Der gefaehrliche Teil steht unten und hinter einer Linie -- man kommt
   dort nicht aus Versehen vorbei. */
.menu-gruppe.gefahr { border-top: var(--border-dashed); padding-top: calc(8 * var(--px)); }
/* Das Kreuz in der Kopfleiste ist jetzt ein Knopf und soll trotzdem
   aussehen wie vorher. */
.product-window .chrome-x {
  background: none; border: 0; padding: 0; margin: 0; line-height: 0;
  cursor: pointer; opacity: 0.75; transition: opacity 150ms;
}
.product-window .chrome-x:hover { opacity: 1; }

/* -- QR-Code: auf heller Flaeche, sonst lesen ihn manche Kameras nicht -- */

.qr {
  display: inline-block;
  background: #fff; padding: calc(8 * var(--px));
  border: var(--border-solid);
  margin: calc(8 * var(--px)) 0;
}
.qr svg { display: block; width: calc(190 * var(--px)); height: auto; }

/* Aktueller Punkt der Unternavigation: sichtbar der Ort - und trotzdem ein
   Link, weil man von jeder Unterseite dorthin zurueck will. */
.linkline .hier { color: var(--black); border-bottom: 1px solid var(--black); }

/* Link ohne Unterstreichung: auf den Kacheln traegt schon die Umgebung die
   Bedeutung, eine Linie waere nur eine weitere Kante zwischen vielen. Beim
   Ueberfahren wird sie sichtbar — dann, wenn die Frage aufkommt. */
/* '.wrap dd a' zeichnet Links mit einem grauen border-bottom, nicht mit
   text-decoration — ein 'text-decoration: none' lief deshalb ins Leere und
   die Domain stand unterstrichen da. Hier wird die Kante genommen und beim
   Ueberfahren in Rot zurueckgegeben, wie im uebrigen Haus. */
.wrap dd a.blank, .wrap p a.blank, a.blank {
  color: inherit; text-decoration: none; border-bottom: none;
}
.wrap dd a.blank:hover, .wrap p a.blank:hover, a.blank:hover,
a.blank:focus-visible { border-bottom: 1px solid var(--red); }
a.blank:focus-visible { outline: 1px solid var(--red); outline-offset: 2px; }

/* Aktionssymbole — Register 1 der Icon-Regeln: das Icon ist Text. Groesse in
   em, Farbe geerbt, keine Kachel, kein Rahmen, keine eigene Farbe. Das
   vertical-align setzt es auf die Grundlinie, wie Odoo es fuer seine
   Glyphen tut. */
.icon { vertical-align: -0.14em; flex: none; }
a.act .icon, button.act .icon { pointer-events: none; }
.act.nurikon {
  display: inline-flex; align-items: center; justify-content: center;
  width: calc(26 * var(--px)); height: calc(26 * var(--px));
  padding: 0; border: 1px solid transparent; border-bottom: 1px solid transparent;
  vertical-align: top;
}
.act.nurikon:hover, .act.nurikon:focus-visible {
  border-color: var(--black); background: var(--white);
}
.act.nurikon.gefahr:hover, .act.nurikon.gefahr:focus-visible {
  border-color: var(--red); color: var(--red);
}
/* Eine Zeile Aktionszeichen: gleiche Groesse, gleicher Abstand, nichts
   umbricht mitten in einer Gruppe. */
.ikonzeile { display: flex; align-items: center; gap: calc(7 * var(--px)); flex-wrap: wrap; }
.ikonzeile details > summary { list-style: none; }
.ikonzeile details > summary::-webkit-details-marker { display: none; }
/* Die Hauptaktion einer Zeile traegt ihr Wort: ein Zeichen allein muss man
   raten, und gerade diese Handlung baut ein Image und schiebt es hinaus. */
.act.mitikon { display: inline-flex; align-items: center; gap: calc(5 * var(--px)); }
/* Das Loeschen bekommt etwas Luft: direkt neben der Hauptaktion zu stehen
   laedt zu dem einen Klick ein, den niemand zuruecknehmen kann. */
.ikonzeile .gefahr { margin-left: calc(8 * var(--px)); }


/* Der Hinweis, wenn sich etwas geaendert hat, waehrend jemand tippt. Unten
   rechts, weil er nichts verdecken soll, was gerade bearbeitet wird. */
#puls-balken {
  position: fixed; right: calc(16 * var(--px)); bottom: calc(16 * var(--px));
  z-index: 50;
  background: var(--lightergrey); border: var(--border-solid);
  padding: calc(8 * var(--px)) calc(12 * var(--px));
  font-size: calc(13 * var(--px));
}
#puls-balken a { color: var(--red); }

/* Nur-Lese-Betrieb (PANGU_NUR_LESEN, Rust only): a parallel Pangu that must
   not be mistaken for the real one. Sticky on top of every page. */
.nur-lesen {
  position: sticky; top: 0; z-index: 60;
  background: var(--orange); color: var(--black);
  padding: calc(6 * var(--px)) calc(12 * var(--px));
  font-size: calc(14 * var(--px)); font-weight: 600; text-align: center;
}


/* --- Reiter -------------------------------------------------------------
   Zwei Wege zum selben Ziel nebeneinander zu stellen heisst, dass man beide
   liest, um zu merken, dass man nur einen braucht. Der Reiter zeigt einen
   und nennt den anderen.

   Radiogruppe statt Skript: die Auswahl ueberlebt ein Neuladen nicht, aber
   sie funktioniert ohne JavaScript, und der Browser fuehrt die Tastatur
   richtig (Pfeiltasten wandern durch die Gruppe). */
.reiter { margin: calc(10 * var(--px)) 0 0; }
.reiter > input[type="radio"] { position: absolute; opacity: 0; pointer-events: none; }
.reiter-leiste { display: flex; gap: calc(6 * var(--px)); border-bottom: var(--border-solid); }
.reiter-leiste label {
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: calc(12 * var(--px)); text-transform: uppercase;
  letter-spacing: calc(var(--ls-mono) * 1em);
  padding: calc(6 * var(--px)) calc(10 * var(--px));
  border: var(--border-solid); border-bottom: none;
  margin-bottom: -1px; background: transparent; color: var(--grey-text);
  cursor: pointer;
}
.reiter-leiste label:hover { color: var(--black); }
/* '~' statt '+': die beiden Radios stehen vor der Leiste, nur das zweite
   grenzt unmittelbar an sie. Mit '+' bekam der erste gar keine Fokusanzeige
   und der zweite liess beide Beschriftungen leuchten — bei Radios, die
   'opacity: 0' tragen, ist das die einzige Anzeige, die es gibt. */
.reiter > input:nth-of-type(1):focus-visible ~ .reiter-leiste label[for$="-1"],
.reiter > input:nth-of-type(2):focus-visible ~ .reiter-leiste label[for$="-2"] {
  outline: 2px solid var(--red); outline-offset: 2px;
}
.reiter-blatt { display: none; padding-top: calc(12 * var(--px)); }

/* Der gewaehlte Reiter sitzt auf der Linie, statt davor zu stehen. */
.reiter > input:nth-of-type(1):checked ~ .reiter-leiste label[for$="-1"],
.reiter > input:nth-of-type(2):checked ~ .reiter-leiste label[for$="-2"] {
  background: var(--white); color: var(--black); border-bottom: 1px solid var(--white);
}

/* Die Blaetter bekommen eigene Klassen statt ':nth-of-type'. Das zaehlt
   Geschwister derselben *Elementart*, und die Reiterleiste ist selbst ein
   div: ':nth-of-type(1)' meinte also die Leiste, nicht das erste Blatt.
   Folge war ein Reiter, unter dem gar nichts stand. */
.reiter > input:nth-of-type(1):checked ~ .blatt-1,
.reiter > input:nth-of-type(2):checked ~ .blatt-2 { display: block; }

/* --- Infozeichen --------------------------------------------------------
   Ein Erklaertext gehoert nicht neben jedes Feld, sondern dahinter. Die
   Seite liest sich kurz, das Wissen ist einen Klick entfernt.

   <details>/<summary>, kein Skript und kein Schwebefenster: es laesst sich
   mit der Tastatur oeffnen, es steht beim Ausdruck mit im Text, und auf
   einem Zeigegeraet ohne Mauszeiger funktioniert es ebenso. */
details.info { display: inline; }
details.info > summary {
  display: inline; list-style: none; cursor: help;
  color: var(--grey-text); vertical-align: baseline;
}
details.info > summary::-webkit-details-marker { display: none; }
details.info > summary:hover { color: var(--red); }
details.info > summary svg { width: 1em; height: 1em; vertical-align: -0.12em; }
details.info[open] > summary { color: var(--red); }
details.info > .info-text {
  display: block;
  font-size: calc(13 * var(--px)); color: var(--grey-text); line-height: 1.45;
  max-width: 72ch;
  margin: calc(4 * var(--px)) 0 calc(6 * var(--px));
  padding-left: calc(10 * var(--px));
  border-left: 1px solid var(--grey);
}



/* Das Duplizieren-Formular steckt in der Aktionsspalte und bekam deren
   Breite — zwei Felder, jedes einzeln umgebrochen. Eine Mindestbreite
   genuegt: die Zelle waechst beim Aufklappen, statt dass das Formular
   ueber die Zeilen darueber schwebt und sie verdeckt. */
.ikonzeile details[open] > form { min-width: calc(260 * var(--px)); text-align: left; }

.nur-bei-auffrischen[hidden] { display: none; }

/* Ein verstecktes Element mit eigener Anzeigeart braucht die Ausnahme --
   sonst gewinnt die Klasse gegen '[hidden]'. Dasselbe Muster wie bei
   '.nur-bei-auffrischen', und derselbe Fehler waere sonst wieder da. */
.kopie-form button[hidden], .kopie-hinweis[hidden] { display: none; }

/* Ein Fehlversuch im Protokoll. Rot als Zeichen, nicht als Flaeche: die
   Zeile bleibt lesbar, aber das Auge findet sie beim Ueberfliegen. Ohne
   Markierung stuenden Gelungenes und Gescheitertes in derselben grauen
   Spalte, und das Aufzeichnen haette wenig genutzt. */
tr.fehlversuch td:nth-child(3) { color: var(--red); }
tr.fehlversuch td:nth-child(3)::before { content: "! "; color: var(--red); }
