/* --- Planung: Aufgaben und Ziele ------------------------------------------- */

.planZeile { display: flex; gap: 10px; }
.planZeile input { flex: 1; min-width: 0; background: var(--panel);
  border: 1px solid var(--linie); border-radius: var(--rundKlein); color: var(--text);
  font: inherit; font-size: 14px; padding: 11px 13px; }
.planZeile input:focus { outline: none; border-color: var(--gold); }

/* 20x20 waren es bis zum 23.08.2026 — unter dem Haus-Mindestmass von 32 für
   alles Antippbare. Die Liste wird ohnehin angefasst, also gilt die Regel hier
   ab jetzt (Regel 17 §6). Das Symbol bleibt klein, seine Fläche waechst. */
.planHaken { width: 32px; height: 32px; flex: none; border-radius: 8px; padding: 0;
  border: 1.5px solid var(--randStark); background: transparent; cursor: pointer;
  display: grid; place-items: center; color: #fff;
  transition: border-color .14s ease, background-color .14s ease; }
.planHaken:hover, .planHaken:focus-visible { border-color: var(--gold); outline: none; }
.planHaken[disabled] { opacity: 0.4; cursor: not-allowed; }
.planHaken.an { background: var(--gold); border-color: var(--gold); }
.planHaken .ikon { width: 13px; height: 13px; }
.planEintrag.fertig .tafelName { color: var(--dim); text-decoration: line-through; }

.planZiel .planLeise { font-size: 11.5px; color: var(--dim); white-space: nowrap; }
.planBalken { width: 84px; height: 6px; flex: none; border-radius: 99px;
  background: var(--zeile); overflow: hidden; }
.planBalken > span { display: block; height: 100%; border-radius: 99px;
  background: var(--gold); }

/* Aufgaben-Details: Erstblick bleibt eine Zeile, alles Weitere auf Klick. */
.planBlock { border-top: 1px solid var(--zeile); }
.planBlock:first-child { border-top: 0; }
.planBlock .tafelZeile { border-top: 0; }
/* 21 Pixel hoch war der Titel-Knopf bis zum 23.08.2026 — gemeldet vom
   Bild-Prüfer an der laufenden Oberflaeche, fuenfmal in einer Liste. Er ist
   der Weg ins Detail und damit ein Tippziel wie jedes andere. */
.planTitel { flex: 1; min-width: 0; text-align: left; background: transparent;
  border: 0; padding: 0; color: inherit; font: inherit; cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-height: 32px; display: flex; align-items: center; }
.planTitel:hover, .planTitel:focus-visible { color: var(--goldText); outline: none; }
.planEintrag.fertig .planTitel { color: var(--dim); text-decoration: line-through; }

.planDetail { display: none; padding: 0 18px 14px 47px; }
.planDetail.offen { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 14px; }
.planDetail label { display: flex; flex-direction: column; gap: 4px;
  font-size: 11.5px; color: var(--dim); }
/* Kein `select` mehr hier (Runde 4, Symbol-Liste 21): Status, Zuständig und
   Ziel sind jetzt eigene Bauteile mit eigenem Stil (siehe unten). */
.planDetail textarea, .planDetail input {
  background: var(--bg); border: 1px solid var(--linie); border-radius: 8px;
  color: var(--text); font: inherit; font-size: 13px; padding: 7px 9px; width: 100%; }
.planDetail textarea:focus, .planDetail input:focus {
  outline: none; border-color: var(--gold); }
.planDetail label:first-child { grid-column: 1 / -1; }
.planDetailFuss { grid-column: 1 / -1; display: flex; justify-content: flex-end; }

/* Runde 4 (K8d, Symbol-Liste 21): Status als Kreis-Umschalter statt
   `<select>`; Zuständig/Ziel nutzen die Bauteile aus app-abschluss.css
   (.abAvatarKnopf, .abZielKnopfChip, .abPopoverListe), hier nur die
   Zustands-Farben des Kreises. */
.planStatusUmschalter { width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--linie);
  background: var(--bg); display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0; }
.planStatusUmschalter .ikon { width: 15px; height: 15px; color: var(--dim); }
.planStatusUmschalter.in_arbeit { border-color: var(--gold); }
.planStatusUmschalter.in_arbeit .ikon { color: var(--goldText); }
.planStatusUmschalter.erledigt { background: var(--gruen); border-color: var(--gruen); }
.planStatusUmschalter.erledigt .ikon { color: var(--bg); }

.zielStatus { background: transparent; border: 1px solid var(--linie);
  border-radius: 999px; color: var(--dim); font: inherit; font-size: 11px;
  padding: 2px 10px; cursor: pointer; margin-left: auto; white-space: nowrap; }
.zielStatus:hover, .zielStatus:focus-visible { border-color: var(--gold);
  color: var(--goldText); outline: none; }

@media (max-width: 700px) {
  .planDetail.offen { grid-template-columns: 1fr; }
  .planDetail { padding-left: 18px; }
}

/* Ueberschrift und Handlung in einer Zeile — die Handlung als Symbol, ihr
   Wort steht im Hinweis (Haus-Regel „Symbole vor Text"). */
.tischKopf { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.tischKopf h2 { margin: 0; }

/* --- Der Riegel unter allem ------------------------------------------------
   `hidden` ist ein Attribut, keine Bitte: Jede eigene `display`-Regel schlaegt
   die Vorgabe des Browsers. Am 20.08.2026 ist dieselbe Falle dreimal in einer
   Stunde zugeschnappt — ein leerer Kasten unter einer vollen Liste, ein
   „Mehr laden" ohne Nachschub, ein Knopf ohne Recht. Deshalb steht die Regel
   hier ganz unten: huelle.css wird NACH app.css geladen (Shell).
   Die Verdopplung des Attributs ist Absicht und kein Vertipper: `button.aktion`
   waere sonst spezifischer und gewaenne trotz spaeterer Position. Das ist der
   Ausweg, den die Haus-Regel „Masse gehoeren ins Stylesheet" meint — hoehere
   Spezifitaet statt `!important`, das die naechste Regel ebenso aussticht wie
   die vorige. */
[hidden][hidden] { display: none; }

/* --- Telefonbreite, nachgezogen (20.08.2026) ---------------------------------
   Diese zwei Regeln stehen bewusst am DATEIENDE und nicht oben bei den
   Meetings: Ihre Grundregeln kommen weiter unten in dieser Datei, und bei
   gleicher Spezifitaet gewinnt die spaetere. Oben stehend haetten sie
   gegriffen, waeren aber wirkungslos geblieben — der Bild-Pruefer hat genau
   das gemeldet (55x32 statt 36). */
@media (max-width: 768px) {
  /* Die zwei Pflicht-Links im Fuss. */
  .rechtsZeile a { min-height: 36px; }
  /* Die Unterzeile ist ein Satz, kein Etikett: Auf schmalen Schirmen bricht sie
     um, statt sich abschneiden zu lassen. Auf 375 Pixeln wurde aus der Raum-
     Zeile sonst „Musterhaus-Brain · Verwalter · du darfst hier schr…", und ein
     Hover-Hinweis hilft am Telefon niemandem — man liest mit den Augen, nicht
     mit der Maus. */
  #raumZeile { white-space: normal; overflow: visible; text-overflow: clip; }
}


/* --- Planung: Gruppen nach Ziel, breites Anlege-Formular (23.08.2026) ------ */

/* Der Gruppenkopf trägt Symbol, Namen und den gerechneten Balken. Er erscheint
   nur unter „Alle" — unter „Meine" wäre er eine Überschrift über einer
   Liste, die ohnehin nur einer Person gehört. */
.planGruppe { display: flex; align-items: center; gap: 9px; padding: 11px 18px 7px;
  font-size: 12px; letter-spacing: .3px; text-transform: uppercase; color: var(--dim); }
.planGruppe .ikon { width: 15px; height: 15px; flex: none; }
.planGruppeName { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.planGruppe.ohneZiel { color: var(--dim); opacity: .75; }
.planGruppe + .planBlock { border-top: 0; }

/* Überfällig ist ein Zustand — Farbe UND Form (der Strich links), nicht ein
   weiteres Wort in einer Zeile, die schon drei trägt. */
.planEintrag.spaet { border-left: 3px solid var(--warn, #d98a3a); }
.planEintrag.spaet .tafelZeit { color: var(--warn, #d98a3a); }

.planZeileBreit { flex-wrap: wrap; }
.planZeileBreit #aufgabeTitel { flex: 3 1 220px; }
.planZeileBreit select, .planZeileBreit input[type="date"] {
  flex: 1 1 130px; min-width: 0; background: var(--panel);
  border: 1px solid var(--linie); border-radius: var(--rundKlein); color: var(--text);
  font: inherit; font-size: 13px; padding: 10px 11px; min-height: 32px; }
.planZeileBreit select:focus, .planZeileBreit input[type="date"]:focus {
  outline: none; border-color: var(--gold); }

@media (max-width: 768px) {
  .planHaken { width: 36px; height: 36px; }
  /* Auf dem Telefon wird umgebrochen statt abgeschnitten. Ein Aufgaben-Titel,
     der mitten im Wort endet, ist keine Aufgabe mehr — gemeldet vom
     Bild-Prüfer auf 390 Pixel, sechsmal in einer Liste. */
  .planTitel { min-height: 36px; white-space: normal; overflow: visible;
    text-overflow: clip; line-height: 1.3; padding: 4px 0; }
  .planGruppeName { white-space: normal; overflow: visible; text-overflow: clip; }
  .planEintrag { flex-wrap: wrap; }
  .planEintrag .tafelZeit { flex-basis: 100%; padding-left: 44px; }
  /* Vier Felder in vier Zeilen schieben die Liste aus dem Bild. Titel oben,
     die drei freiwilligen Angaben zu zweit daneben. */
  .planZeileBreit #aufgabeTitel { flex: 1 1 100%; }
  .planZeileBreit select, .planZeileBreit input[type="date"] { min-height: 36px;
    flex: 1 1 calc(50% - 5px); }
  .planZeileBreit .aktion { flex: 1 1 calc(50% - 5px); min-height: 36px; }
}


/* Der Reiter-Modus des Leibs. `data-spalte` entscheidet, ob links eine
   Dateiliste steht — ein leerer Streifen neben dem Inhalt wäre Fläche ohne
   Auskunft. Die Szene wird auch hier nur weggeschoben, nie ausgeblendet
   (derselbe Grund wie im Baum-Modus weiter oben). */
.kwLeib[data-art="reiter"] { grid-template-columns: 300px minmax(0, 1fr); }
.kwLeib[data-art="reiter"][data-spalte="keine"] { grid-template-columns: minmax(0, 1fr); }
.kwLeib[data-art="reiter"][data-spalte="keine"] .kwSpalte { display: none; }
/* Die Szene wird hier UNSICHTBAR geparkt, nicht zur Seite geschoben.
   Gemessen im Kontrollgang am 06.09.2026: Ein Rahmen bei `translateX(105%)`
   macht seinen Behälter 2107 statt 1028 Pixel breit. Beim ersten Klick auf
   einen Knopf am rechten Rand schob der Browser die halbe Ansicht aus dem
   Bild und den Bücherschrank daneben hinein — „bring das Fokus-Ziel ins
   Sichtfeld" rollt jeden Behälter, der rollen KANN.

   `overflow: hidden` reicht dagegen NICHT: Es verbirgt nur den Überlauf, der
   Behälter bleibt ein Roll-Behälter und lässt sich weiter aus dem Code rollen
   (nachgemessen: `scrollLeft` sprang trotz `hidden` auf 470). Erst ohne die
   Verschiebung gibt es nichts mehr zu rollen.

   `visibility: hidden` und nicht `display: none` — aus demselben Grund, der
   weiter oben beim Baum-Modus steht: ein `display:none`-Rahmen misst sich zu
   0x0 und baut die Szene beim Wiederkommen leer auf. Ein unsichtbarer Rahmen
   behält seinen Kasten. */
.kwLeib[data-art="reiter"] #kwSzene { position: absolute; inset: 0;
  transform: none; visibility: hidden; pointer-events: none; }

/* Kopfzeile eines Reiter-Inhalts: Titel links, Symbol-Knöpfe rechts. */
.prommKopf { display: flex; align-items: center; gap: 8px; margin-bottom: 14px;
  padding-bottom: 10px; border-bottom: 1px solid var(--linie); flex-wrap: wrap; }
/* Der Titel nimmt die erste Zeile ganz, sobald die Werkzeuge nicht mehr
   daneben passen — gemessen am 08.09.2026: dreizehn Knöpfe brauchen 515
   Pixel, ein Telefon hat 390. Ohne den Umbruch würden sie gequetscht oder
   liefen aus dem Bild; beides hätte der Betreiber beim ersten Blick gesehen
   und keine Testsuite je gemeldet. */
@media (max-width: 700px) {
  .prommKopfTitel { flex: 1 0 100%; margin-bottom: 4px; }
}
.prommKopfTitel { flex: 1; min-width: 0; font-size: 15px; font-weight: 600;
  color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prommKopf .zAktion { flex: none; }

/* Der Ehrlichkeits-Hinweis über dem Test-Knopf. Er steht VOR der Handlung und
   nicht als Fußnote darunter — wer fremden Code startet, soll vorher wissen,
   was ihn schützt und was nicht. */
.prommHinweis { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 14px;
  padding: 10px 12px; border-radius: var(--rundKlein, 8px); background: var(--zeile);
  color: var(--dim); font-size: 12.5px; line-height: 1.5; }
.prommHinweisMarke { flex: none; display: grid; place-items: center;
  width: 18px; height: 18px; color: var(--goldText); }
.prommHinweisMarke .ikon { width: 15px; height: 15px; }

/* Testlauf: Ausgang als Symbol, Zahlen daneben, Ausgabe darunter. */
.prommTestFeld { border: 1px solid var(--linie); border-radius: var(--rundKlein, 8px);
  padding: 12px 14px; font-size: 12.5px; color: var(--dim); }
.prommTestFeld[data-stand="gut"] { border-color: var(--gruen, #5fbf7f); }
.prommTestFeld[data-stand="schlecht"] { border-color: var(--warn, #e2725b); }
.prommTestKopf { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-bottom: 10px; color: var(--text); font-size: 13px; }
.prommTestMarke { flex: none; display: grid; place-items: center; width: 20px; height: 20px; }
.prommTestMarke .ikon { width: 17px; height: 17px; }
.prommTestFeld[data-stand="gut"] .prommTestMarke { color: var(--gruen, #5fbf7f); }
.prommTestFeld[data-stand="schlecht"] .prommTestMarke { color: var(--warn, #e2725b); }
.prommTestBefehl { margin-left: auto; padding: 2px 8px; border-radius: 6px;
  background: var(--zeile); color: var(--dim); font-size: 11.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
/* Der Ausgabe-Block scrollt in SICH — eine breite Testausgabe darf die Seite
   nicht waagerecht schieben (Bild-Prüfer: „waagerechter Überlauf"). */
.prommTestAusgabe { margin: 0; max-height: 320px; overflow: auto;
  padding: 10px 12px; border-radius: 6px; background: var(--zeile);
  color: var(--text); font-family: var(--schriftMono, ui-monospace, monospace);
  font-size: 11.5px; line-height: 1.5; white-space: pre; }
.prommTestGekappt { margin-top: 8px; color: var(--dim); font-size: 11.5px; }

/* --- Die Formen: Tafel ------------------------------------------------------
   Karten in Bahnen. Die Bahnen stehen am Schreibtisch nebeneinander und auf dem
   Telefon untereinander — dieselbe Form, nicht eine zweite Ansicht.
   Alle Maße stehen hier, keines im JavaScript (Haus-Regel 17 §6). */
.prommAbschnitt { display: flex; align-items: center; gap: 8px;
  margin: 22px 0 10px; font-size: 14px; font-weight: 600; color: var(--kopf); }
.prommAbschnitt:first-of-type { margin-top: 6px; }
/* Die Marke ist die Auskunft „hier fehlt eine Spalte" — Symbol mit Hover,
   kein Satz in der Fläche (Haus-Regel 17 §4). */
.prommMarke { display: inline-grid; place-items: center; width: 20px; height: 20px;
  color: var(--goldText); cursor: help; }
.prommMarke .ikon { width: 15px; height: 15px; }

.prommBahnen { display: grid; gap: 12px; align-items: start;
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr)); }
.prommBahn { display: flex; flex-direction: column; gap: 8px; min-width: 0;
  padding: 10px; border: 1px solid var(--linie); border-radius: var(--rund, 12px);
  background: color-mix(in srgb, var(--zeile) 40%, transparent); }
.prommBahnKopf { display: flex; align-items: center; gap: 8px; margin: 0 0 2px;
  font-size: 12px; font-weight: 600; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--dim); }
.prommBahnMarke { flex: none; display: grid; place-items: center; width: 16px; height: 16px; }
.prommBahnMarke .ikon { width: 14px; height: 14px; }
.prommBahn[data-rolle="fertig"] .prommBahnMarke { color: var(--gruenText); }
.prommBahn[data-rolle="jetzt"] .prommBahnMarke { color: var(--goldText); }
.prommBahn[data-rolle="weg"] .prommBahnMarke { color: var(--warnText); }
.prommBahnName { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prommBahnZahl { flex: none; margin-left: auto; padding: 1px 8px; border-radius: 999px;
  background: var(--zeile); color: var(--text); font-size: 11.5px; letter-spacing: 0; }
.prommBahn[data-rolle="fertig"] .prommBahnZahl { color: var(--gruenText); }
.prommBahn[data-rolle="jetzt"] .prommBahnZahl { color: var(--goldText); }

.prommRaster { display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(255px, 1fr)); }

.prommKarte { display: flex; flex-direction: column; gap: 6px; min-width: 0;
  padding: 10px 12px; border: 1px solid var(--linie); border-radius: var(--rundKlein, 9px);
  background: var(--panel); }
.prommKarte.offen { border-color: var(--gold); }
.prommKarteKopf { display: flex; align-items: flex-start; gap: 7px; min-width: 0; }
.prommKarteNummer { flex: none; padding: 1px 6px; border-radius: 5px;
  background: var(--zeile); color: var(--dim);
  font-family: var(--schriftMono, ui-monospace, monospace); font-size: 11px; line-height: 1.6; }
.prommKarteTitel { flex: 1; min-width: 0; font-size: 13px; line-height: 1.45; color: var(--text); }
/* Der Zustand ist Farbe UND Form: ein Symbol, dessen Wort im Hover steht.
   Farbe allein trägt ihn nicht — der Bild-Prüfer misst dafür den Kontrast. */
.prommKarteChip { flex: none; display: grid; place-items: center;
  width: 20px; height: 20px; color: var(--dim); cursor: help; }
.prommKarteChip .ikon { width: 15px; height: 15px; }
.prommKarte[data-rolle="fertig"] .prommKarteChip { color: var(--gruenText); }
.prommKarte[data-rolle="jetzt"] .prommKarteChip { color: var(--goldText); }
.prommKarte[data-rolle="weg"] .prommKarteChip { color: var(--warnText); }
.prommKarte[data-rolle="weg"] .prommKarteTitel { text-decoration: line-through; color: var(--dim); }
.prommKarteDatum { align-self: flex-start; color: var(--dim); font-size: 11px; }
.prommKarteDatum[data-naehe] { padding: 1px 8px; border-radius: 999px; font-weight: 600;
  background: color-mix(in srgb, var(--naeheFarbe) 18%, transparent); color: var(--naeheFarbe); }
.prommKarteDatum[data-naehe="spaeter"] { --naeheFarbe: var(--dim); }
.prommKarteDatum[data-naehe="bald"] { --naeheFarbe: #EF9F27; }
.prommKarteDatum[data-naehe="verpasst"] { --naeheFarbe: #E24B4A; }
.prommKarteDatum[data-naehe="fertig"] { --naeheFarbe: #1D9E75; }
.prommKarteWer { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--dim); }
.prommAvatar { display: inline-grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; flex: none;
  background: var(--avatarFarbe); color: #fff; font-size: 10px; font-weight: 700; letter-spacing: .02em; }
/* Woher die Zeile kommt, wenn eine Tafel mehrere Tabellen zusammenzieht. */
.prommKarteEtikett { align-self: flex-start; padding: 1px 7px; border-radius: 999px;
  background: var(--zeile); color: var(--dim); font-size: 10.5px; letter-spacing: 0.02em; }
.prommKarteUnter { margin: 0; font-size: 12px; line-height: 1.5; color: var(--dim); }
.prommKarteMehr { flex: none; display: grid; place-items: center;
  width: 32px; height: 32px; margin: -6px -6px -6px 0; padding: 0;
  background: transparent; border: 0; border-radius: 8px; color: var(--dim); cursor: pointer; }
.prommKarteMehr:hover, .prommKarteMehr:focus-visible { background: var(--zeile); color: var(--text); }
.prommKarteMehr[aria-expanded="true"] .ikon { transform: rotate(180deg); }
.prommKarteMehr .ikon { width: 15px; height: 15px; transition: transform .15s ease; }
.prommKarteRest { display: grid; grid-template-columns: auto 1fr; gap: 3px 10px;
  margin: 2px 0 0; padding-top: 8px; border-top: 1px solid var(--linie);
  font-size: 11.5px; line-height: 1.5; }
.prommKarteRest dt { color: var(--dim); }
.prommKarteRest dd { margin: 0; color: var(--text); min-width: 0; overflow-wrap: anywhere; }

/* --- Die Formen: Zeitstrahl -------------------------------------------------
   Eine senkrechte Linie, an der die Schritte hängen. Die Linie selbst ist ein
   Rahmen am Punkt, kein eigenes Element — so bleibt sie ohne Rechnerei genau so
   lang wie die Liste. */
.prommSumme { flex: none; margin-left: auto; padding: 1px 9px; border-radius: 999px;
  background: var(--zeile); color: var(--dim); font-size: 11.5px; font-weight: 400; }
.prommStrahl { list-style: none; margin: 0 0 22px; padding: 0; }
.prommSchritt { position: relative; display: flex; gap: 12px;
  padding: 0 0 14px 0; }
/* Der Faden zwischen den Punkten. Beim letzten Schritt hört er auf — sonst
   zeigte er ins Nichts. */
.prommSchritt::before { content: ""; position: absolute; left: 11px; top: 24px; bottom: 0;
  width: 2px; background: var(--linie); }
.prommSchritt:last-child::before { display: none; }
.prommPunkt { position: relative; z-index: 1; flex: none;
  display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%;
  border: 1px solid var(--linie); background: var(--panel); color: var(--dim); cursor: help; }
.prommPunkt .ikon { width: 13px; height: 13px; }
.prommSchritt[data-rolle="fertig"] .prommPunkt { border-color: var(--gruen); color: var(--gruenText); }
.prommSchritt[data-rolle="jetzt"] .prommPunkt { border-color: var(--gold); color: var(--goldText);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 22%, transparent); }
.prommSchritt[data-rolle="weg"] .prommPunkt { color: var(--warnText); }
.prommSchritt[data-rolle="weg"] .prommSchrittTitel { text-decoration: line-through; color: var(--dim); }
.prommSchrittLeib { flex: 1; min-width: 0; padding-top: 2px; }
.prommSchrittKopf { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.prommSchrittTitel { flex: 1 1 220px; min-width: 0; font-size: 13px; line-height: 1.45;
  color: var(--text); }
.prommSchrittDatum { flex: none; color: var(--dim); font-size: 11.5px; }
/* Der Balken zeigt die Dauer im Verhältnis zur längsten. Nur seine BREITE
   entsteht im JavaScript — sie ist ein Datenwert, kein Maß (Regel 17 §6). */
/* Der Balken misst, er füllt nicht: Über die halbe Bildschirmbreite gezogen
   liest er sich wie ein Fortschritt und nicht wie ein Verhältnis
   (Kontrollgang 07.09.2026, Reiter Gliederung). */
.prommBalken { display: flex; align-items: center; gap: 8px; margin-top: 6px;
  max-width: 320px; }
.prommBalkenBahn { flex: 1; min-width: 0; height: 6px; border-radius: 999px;
  background: var(--zeile); }
.prommBalkenBahn > span { display: block; height: 100%; min-width: 4px;
  border-radius: 999px; background: var(--gold); }
.prommBalkenWert { flex: none; color: var(--dim); font-size: 11px; }

/* --- Die Formen: Vortrag ----------------------------------------------------
   **Eine Folie hat eine feste Leinwand: 1280 x 720.** Alles darin rechnet in
   Pixeln dieser Leinwand, und der Behälter skaliert sie als GANZES.

   Der erste Versuch am 07.09.2026 ging anders: Schriftgrößen in `cqw` mit
   einem `clamp()`-Boden. Auf der Bühne sah das gut aus, in der Miniatur nicht:
   Bei 226 Pixeln Breite sind 2.6cqw noch 5,9 Pixel, also gewann der Boden von
   11 Pixeln — die Miniatur setzte den Text in fast voller Größe in einen
   Kasten von einem Fünftel der Fläche. Gemessen liefen ALLE sechs Miniaturen
   über, um 24 bis 139 Pixel bei 126 Pixeln Höhe, und `overflow: hidden`
   schnitt sie mitten im Wort ab. Ein Boden, der das Skalieren aushebelt, ist
   kein Schutz, sondern der Fehler.

   Jetzt: eine Leinwand, ein Maßstab. Miniatur und Bühne zeigen dasselbe Bild
   in verschiedener Größe — das ist auch die Zusage, die eine Vorschau geben
   muss. Der Maßstab ist eine MESSUNG (Behälterbreite geteilt durch 1280) und
   steht deshalb als Inline-Wert; er ist keine Gestaltung (Haus-Regel 17 §6). */
/* Die feste Palette der Folie. Eine Folie ist ein Dokument, kein Fenster —
   sie wechselt die Farbe nicht, wenn der Betreiber das Nachtlicht anmacht,
   und ein PDF, das je nach Thema anders aussieht, ist kein Export. Die fünf
   Werte stammen aus der Bildsprache des Präsentations-prommblumms; derselbe
   Satz liegt `folien-export.py` zugrunde, damit beide Wege dasselbe Bild
   zeigen. */
.folieRahmen, .folieBuehne {
  /* AN RENÉS ENTWURF GEMESSEN (08.09.2026), nicht aus einer Palette gewählt:
     Grund und Akzent stammen aus `image (1).png` — der Grund aus einer ruhigen
     Ecke unten links, der Akzent aus dem violetten Teil seiner Schlagzeile.
     Der Grund ist der Grund, aus dem seine Zeichen geschnitten sind; jede
     andere Farbe hier zeigt sie als Kasten auf der Folie. */
  /* Seit 25.09.2026 (Flow) kommt der Stil aus dem Reiter Stil des Projekts
     (`stil.json`, huelle-stil.js setzt `--stil-*` an der Wurzel). Die Werte
     hier sind das Thema „nacht" und gelten, solange ein Projekt keinen Stil hat. */
  --fo-grund: var(--stil-grund, #00020d);
  --fo-titel: var(--stil-titel, #ffffff);
  --fo-strich: var(--stil-strich, #d8dae6);
  --fo-akzent: var(--stil-akzent, #795af0);
  --fo-gegen: var(--stil-gegen, #f38ba8);
  --fo-leise: var(--stil-leise, #9aa0b4);
  --fo-linie: var(--stil-linie, #1c2036);
}
.folieRahmen { position: relative; container-type: inline-size; aspect-ratio: 16 / 9;
  overflow: hidden; border: 1px solid var(--linie); border-radius: var(--rund, 12px);
  background: var(--fo-grund); }
.folieRahmen:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
/* Die Leinwand: feste Größe, oben links verankert, als Ganzes skaliert. */
.folieBuehne { position: absolute; top: 0; left: 0; width: 1280px; height: 720px;
  transform-origin: top left; transform: scale(var(--folie-massstab, 1));
  display: flex; flex-direction: column; gap: 0.67em;
  padding: 2.13em 2.53em; overflow: hidden;
  font-size: var(--folie-schrift, 30px); line-height: 1.45;
  color: var(--fo-strich); font-family: var(--stil-schrift-text, inherit);
  /* FLACH. Der Schein hinter dem Gehirn und die Sternpunkte sind Teil von
     Renés Bild und kommen mit dem Bildschnitt — ein zweiter Verlauf im
     Stylesheet läge daneben und ergäbe zwei Lichtquellen. */
  background: var(--fo-grund); }
.folieBuehne h1 { margin: 0; font-size: 2.27em; line-height: 1.12; color: var(--fo-titel);
  font-family: var(--stil-schrift-titel, inherit); font-weight: var(--stil-gewicht-titel, 700);
  letter-spacing: -0.02em; }
/* Die zweifarbige Schlagzeile: `# Bau dir dein **zweites Gehirn**`. Der fette
   Teil bekommt eine eigene Zeile und die Akzentfarbe — das ist Renés Bauteil,
   und es kostet kein einziges neues Zeichen in der Grammatik. */
.folieBuehne h1 b { display: block; font-weight: inherit; color: var(--fo-akzent); }
/* Ein hervorgehobener Teil im Untertext bleibt in der Zeile, nimmt aber
   dieselbe Farbe an — sonst hätte die Folie zwei Sprachen für dieselbe Sache. */
.folieBuehne blockquote b, .folieBuehne li b { color: var(--fo-akzent); }

/* Bauteil 1 — die Kopfzeile: Nummer und Kapitel, klein und weit gesperrt.
   `background: none`, weil die Anwendung eine allgemeine Regel für `header`
   und `footer` hat — auf der Folie zeichnete sie einen dunklen Balken quer
   durchs Bild. Die Bauteile heißen `header`/`footer`, weil sie das SIND;
   sie sollen deshalb aus der Fensterrahmen-Regel ausdrücklich aussteigen. */
.folieKopf, .folieFuss { background: none; }
.folieKopf { display: flex; align-items: center; gap: 0.53em;
  font-size: 0.67em; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--fo-leise); }
/* Die Marke: Renés Logo mit Wortmarke, oben links vor der Nummer. Ihre Höhe
   steht in `em` wie alles auf der Folie, damit sie beim Verkleinern mitgeht. */
.folieMarke { flex: none; height: 1.4em; width: auto; margin-right: 0.4em; }
/* Auf einer Titelfolie steht oben NUR die Marke. Renés Entwurf trägt dort
   keine Nummer und kein Kapitel — eine Ordnungszahl neben dem Absender
   wäre eine Auskunft, die das Publikum nicht braucht. */
.folieBuehne:is([data-layout="titel"], [data-layout="frei"][data-basis="titel"])[data-bild="ja"] .folieKopfNummer,
.folieBuehne:is([data-layout="titel"], [data-layout="frei"][data-basis="titel"]) .folieKopfNummer,
.folieBuehne:is([data-layout="titel"], [data-layout="frei"][data-basis="titel"])[data-bild="ja"] .folieKopfKapitel,
.folieBuehne:is([data-layout="titel"], [data-layout="frei"][data-basis="titel"]) .folieKopfKapitel { display: none; }
.folieKopfNummer { color: var(--fo-akzent); font-variant-numeric: tabular-nums; }
.folieKopfKapitel { padding-left: 0.8em; border-left: 2px solid var(--fo-linie); }

/* Bauteil 5 — der Aussage-Kasten: der zweite Zitat-Block, gerahmt, am Fuß.
   Er trägt die Folgerung, nicht den Kernsatz — deshalb Fläche statt Balken. */
/* NUR der letzte Kasten schiebt sich nach unten. Trägt eine Folie zwei
   Aussage-Blöcke, hätten sonst beide `margin-top: auto` — und im Flexlauf
   landen sie exakt übereinander. Am 08.09.2026 an einer von Hand
   geschriebenen Folie gesehen: zwei Kästen, ein unlesbarer Stapel, und der
   Überlauf maß trotzdem 0. */
.folieBuehne blockquote.folieAussage { margin-top: 0; padding: 0.67em 0.89em;
  border: 2px solid var(--fo-akzent); border-left-width: 2px; border-radius: 0.39em;
  background: color-mix(in srgb, var(--fo-akzent) 12%, transparent);
  font-size: 1em; line-height: 1.3; color: var(--fo-strich); }

.folieBuehne blockquote.folieAussage:last-of-type { margin-top: auto; }

/* Die Fußzeile ist IMMER das letzte Element der Folie — auch wenn nach ihr
   noch etwas im Text steht, das die Grammatik nicht kennt. Ohne diese Zeile
   rutschte ein Absatz unter sie und stand halb ausserhalb der Leinwand. */
.folieBuehne > .folieFuss { order: 99; }
.folieBuehne > .folieKopf { order: -1; }

/* Bauteil 4 — die Symbol-Reihe: dieselben Zeilen, nebeneinander. */
/* Renés Bauform: das Zeichen LINKS, der Text rechts daneben, zweizeilig, und
   ein Haarstrich zwischen den Einträgen. Untereinander (Zeichen über Text)
   braucht dieselbe Aussage doppelt so viel Höhe. */
.folieBuehne ul.folieReihe { display: flex; gap: 0; padding: 0;
  list-style: none; align-items: stretch; }
.folieBuehne ul.folieReihe > li { display: flex; align-items: center; gap: 0.53em;
  flex: 1 1 0; margin: 0; min-width: 0; padding: 0 1.07em;
  font-size: 0.63em; line-height: 1.25; color: var(--fo-leise); }
.folieBuehne ul.folieReihe > li:first-child { padding-left: 0; }
.folieBuehne ul.folieReihe > li + li { border-left: 1px solid var(--fo-linie); }
.folieBuehne ul.folieReihe > li b { display: block; margin-bottom: 0.15em;
  font-size: 1em; font-weight: 600; color: var(--fo-titel); }
/* Die Hülle um den Zeilentext (siehe `folieBauteile`): sie hält Fett-Teil und
   Rest in EINEM Fach, damit sie untereinander stehen statt nebeneinander. */
.folieReiheText { min-width: 0; }
.folieReiheSymbol { flex: none; width: 2em; height: 2em; margin: 0;
  color: var(--fo-akzent); }
/* Ein Zeichen aus dem eigenen Entwurf: dieselbe Fläche wie ein Blatt-Zeichen,
   damit beide Sorten in einer Reihe nicht auseinanderfallen. */
.folieReiheBild { flex: none; width: 2em; height: 2em; margin: 0;
  object-fit: contain; }

/* Bauteil 6 — die Fußzeile: drei Felder, links, Mitte, rechts. Sie steht am
   unteren Rand der Leinwand, über einer Haarlinie. */
.folieFuss { display: flex; justify-content: space-between; gap: 0.8em;
  margin-top: auto; padding-top: 0.73em; border-top: 1px solid var(--fo-linie);
  font-size: 0.6em; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--fo-leise); }
.folieFuss > span:nth-child(2) { text-align: center; flex: 1; }
.folieFuss > span:first-child, .folieFuss > span:last-child { flex: none; }
.folieFuss > span:last-child { text-align: right; color: var(--fo-akzent); }
/* Beide Randleisten haben ihr `margin-top: auto` — hätten sie es beide in
   einer Folie, schöbe die erste die zweite nicht mehr nach unten. Der Kasten
   gibt es ab, sobald eine Fußzeile da ist. */
.folieBuehne:has(.folieFuss) blockquote.folieAussage { margin-top: 0; }
.folieBuehne h2, .folieBuehne h3 { margin: 0; font-size: 1.33em; color: var(--fo-titel); }
/* Der Kernsatz: ein Balken links, keine Anführungszeichen. Er ist der eine
   Satz, den das Publikum behält — nicht ein Zitat von jemand anderem. */
.folieBuehne blockquote { margin: 0; padding: 0 0 0 0.87em; border-left: 0.27em solid var(--fo-akzent);
  font-size: 1.2em; line-height: 1.35; color: var(--fo-strich); }
.folieBuehne ul, .folieBuehne ol { margin: 0; padding-left: 1.53em; }
.folieBuehne li { margin: 0.33em 0; }
.folieBuehne p { margin: 0; }
.folieBuehne table { border-collapse: collapse; font-size: 0.8em; }
.folieBuehne th, .folieBuehne td { padding: 0.2em 0.53em; border: 1px solid var(--fo-linie);
  text-align: left; }
.folieBuehne img.folieBild { align-self: center; max-width: 100%; min-height: 0;
  flex: 0 1 auto; object-fit: contain; max-height: 11.5em; }
/* Ein Bild MITTEN in einem Satz ist keine Bildzeile — die Grammatik kennt es
   nicht, und gross gezeigt zerreisst es den Satz um sich herum. Es bleibt in
   der Zeile und wird so hoch wie sie. */
.folieBuehne p img.folieBild:not(:only-child) { display: inline-block;
  max-height: 1.2em; vertical-align: text-bottom; }
/* Pixelkunst wird hart vergrößert, ein Foto weich. Die Klasse setzt der Baum
   nach einer MESSUNG der natürlichen Breite (`huelle.js`), nicht nach einer
   Vermutung über die Herkunft — `pixelated` auf einem 1672 Pixel breiten
   Entwurf macht aus sauberen Kanten eine Treppe.

   Die Größe steht hier und ist ein ganzzahliges Vielfaches des 64er-Rasters
   (5 x 64), wie die Bildsprache des promms es verlangt. Ohne sie blieb ein
   64-Pixel-Motiv auf einer 1280 Pixel breiten Leinwand genau 64 Pixel groß —
   ein Punkt, kein Bild. `flex: 0 0 auto`, damit die Bühne es nicht streckt. */
.folieBuehne img.folieBild.pixelbild { image-rendering: pixelated;
  flex: 0 0 auto; width: 8.53em; height: 8.53em; }

/* Bauform `standard` MIT Bild: zwei Spalten. Titel und Kernsatz spannen beide,
   die Zeilen stehen links, das Bild rechts daneben.

   Warum das kein Schönheitsthema ist: Untereinander addieren sich die Höhen
   von Text und Bild. Am 07.09.2026 lief die Präsentation dadurch um bis zu
   273 Pixel über die 720 der Leinwand, und `overflow: hidden` schnitt den
   Rest ab — der Betrachter sah einen halben Satz. Nebeneinander kostet das
   Bild keine Höhe mehr. */
.folieBuehne[data-layout="standard"][data-bild="ja"] { display: grid;
  grid-template-columns: minmax(0, 1fr) auto; column-gap: 1.87em;
  align-content: start; }
/* Die Ordnung einer Folie mit Bild — fünf Zeilen, feste Plätze:
     1 Kopfzeile · 2 Schlagzeile · 3 Untertext · 4 Zeilen · 5 Aussage · 6 Fuß
   und das Bild rechts daneben. Ohne diese Ordnung sucht sich jedes Bauteil
   selbst eine Zeile, das Bild bekommt eine eigene, und die Folie wird höher
   als ihre Leinwand — am 07.09.2026 um bis zu 365 Pixel.

   Fehlt ein Bauteil, bleibt seine Zeile leer und ist null hoch. */
.folieBuehne[data-bild="ja"]:not([data-layout="titel"]) {
  grid-template-rows: auto auto auto auto 1fr auto; }
.folieBuehne[data-bild="ja"] > * { grid-column: 1 / -1; }
.folieBuehne[data-bild="ja"] > .folieKopf { grid-row: 1; }
.folieBuehne[data-bild="ja"] > h1 { grid-row: 2; grid-column: 1; }
.folieBuehne[data-bild="ja"] > blockquote:not(.folieAussage) { grid-row: 3; grid-column: 1; }
.folieBuehne[data-bild="ja"] > ul:not(.folieReihe),
.folieBuehne[data-bild="ja"] > ol:not(.folieReihe) { grid-row: 4; grid-column: 1; }
/* Eine Symbol-Reihe steht unter dem Bild, nicht neben ihm — sie ist so breit
   wie die Folie, sonst quetschen sich vier Symbole in eine halbe Spalte. */
.folieBuehne[data-bild="ja"] > ul.folieReihe { grid-row: 4; grid-column: 1 / -1; }
.folieBuehne[data-bild="ja"] > blockquote.folieAussage { grid-row: 5; align-self: end; }
/* Alles, was die Grammatik nicht kennt (ein Absatz, ein drittes Zitat, eine
   zweite Überschrift), bekommt eine EIGENE Zeile unter der Ordnung. Ohne
   diese Regel teilen sich zwei solche Elemente eine Zeile und liegen
   übereinander — sichtbar kaputt, und der Überlauf misst trotzdem null. */
.folieBuehne[data-bild="ja"] > p:not(:has(img.folieBild)):not(:has(.folieLuecke)),
.folieBuehne[data-bild="ja"] > blockquote:not(.folieAussage) ~ blockquote:not(.folieAussage),
.folieBuehne[data-bild="ja"] > h2, .folieBuehne[data-bild="ja"] > h3 { grid-row: auto; }
.folieBuehne[data-bild="ja"] > .folieFuss { grid-row: 6; }
/* Wie weit das Bild reicht, hängt davon ab, was links darunter steht: neben
   einer Liste bis zu ihr hinunter, neben einer Reihe nur bis zum Untertext —
   die Reihe braucht die volle Breite. */
.folieBuehne[data-bild="ja"] > p:has(img.folieBild),
.folieBuehne[data-bild="ja"] > p:has(.folieLuecke) {
  grid-row: 2 / 5; grid-column: 2; align-self: stretch; justify-self: stretch;
  display: flex; align-items: center; justify-content: center; }
/* Das Bild FÜLLT seine Spalte, statt als Quadrat darin zu sitzen. Renés
   Folien geben dem Bild die halbe Fläche; ein 256er Kästchen daneben sah aus
   wie ein Platzhalter, nicht wie ein Bild. */
.folieBuehne[data-bild="ja"] img.folieBild { max-height: none; max-width: 100%;
  /* `width: 100%` statt `auto`: Ein Bild, das kleiner ist als seine Spalte,
     bliebe sonst in seiner natürlichen Größe stehen — bei Renés Zeichen also
     ein 512er Kästchen neben einer halben leeren Spalte. `contain` hält dabei
     das Seitenverhältnis. */
  width: 100%; height: auto; max-block-size: 100%; object-fit: contain; }
/* Und die Spalte selbst ist die Hälfte wert, nicht nur so breit wie ihr
   Inhalt. */
.folieBuehne[data-bild="ja"] { grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr); }
.folieBuehne[data-zeilen="reihe"][data-bild="ja"] > p:has(img.folieBild),
.folieBuehne[data-zeilen="reihe"][data-bild="ja"] > p:has(.folieLuecke) { grid-row: 2 / 4; }

/* Bauform `titel` — AN RENÉS FOLIE 01 GEMESSEN (08.09.2026).
   Die Werte stammen aus einem Helligkeits-Abtaster über seine 1672 x 941
   grosse Folie, umgerechnet auf die Leinwand 1280 x 720 (Faktor 0,7656).
   Nicht geschätzt, nicht nach Augenmass — jede Zahl unten ist die Tinte
   seiner Folie. Nachgemessen wurde gegen die laufende Oberfläche: Breiten
   über die Textkästen, Höhen über die GRUNDLINIE (ein inline-block der Höhe
   null sitzt genau auf ihr; die Versalhöhe aus dem Canvas ist dafür zu
   ungenau). Die Zielkästen, alle in Leinwand-Pixeln:

     Zeichen        x   52..102   y  54.. 96
     Wortmarke      x  118..292   Grundlinie  89
     Schlagzeile 1  x   62..517   Grundlinie 245
     Schlagzeile 2  x   60..673   Grundlinie 349
     Trennstrich    x   60..109   y 389..392
     Untertext 1    x   60..566   Grundlinie 438
     Untertext 2    x   60..502   Grundlinie 472
     Reihe Zeichen  x   58/267/477  y 539..581   43 x 43
     Reihe Text     x  116/325/530  zwei Zeilen, Sprung 22
     Trenner        x  242 und 452
     Fusslinie      x   52..1226  y 640
     Fuss links     x   52..162   Grundlinie 682
     Fuss Trenner   x  186..188
     Fuss Datum     x  211..371   in Akzentfarbe
     Fuss rechts    x  824..1226  in Akzentfarbe

   Der Doppel-Selektor ist Absicht: `[data-bild="ja"]` setzt weiter unten ein
   Grid, und bei gleicher Spezifität gewänne die spätere Regel. Dann bezöge
   sich `left` auf den Grid-Bereich statt auf die Leinwand — gemessen: das
   Bild sass bei 1363 statt 674.

   Toleranz +-4 px auf 1280. Wer das ändert, misst neu. */
.fB-titel, .folieBuehne:is([data-layout="titel"], [data-layout="frei"][data-basis="titel"]) { display: block; padding: 0;
  font-family: Helvetica, Arial, sans-serif; isolation: isolate; }
.fB-titel > *, .folieBuehne:is([data-layout="titel"], [data-layout="frei"][data-basis="titel"]) > * { position: absolute; margin: 0; }
