Die Regie steht links neben dem Video, nicht nur unten

Filipe, 28.09.2026: "anstatt alles nur unten zu haben wieso nicht
rechts und links noch ausnutzen um mehr ueberblick zu haben."

ICH HATTE IHN ZWEIMAL FALSCH VERSTANDEN. Beim ersten Mal baute ich
zwei Spalten INNERHALB der unteren Leiste, beim zweiten Mal Kacheln
darin. Gemeint war der BILDSCHIRM: Die Regie klebte als 272 Pixel
hoher Streifen unten, waehrend darueber das ganze Bild frei war. Man
sah entweder das Video oder die Bedienung.

AUFGEKLAPPT steht sie jetzt LINKS neben dem Video, ueber die volle
Hoehe. Rechts der Chat, unten die Senderleiste und der Transport --
die Anordnung jedes Sendepults: Was man bedient, liegt neben dem, was
man dabei ansieht.

ZUGEKLAPPT bleibt alles wie vorher, eine schmale Leiste unten. Wer
die Regie zumacht, will das Bild gross; eine leere Spalte daneben
waere das Gegenteil.

WAS DAS NEBENBEI LOEST: Die Kacheln hatten unten 272 Pixel fuer sich
-- drei Felder untereinander passten nicht hinein, und die
Transportleiste verdeckte den Rest. In einer Spalte stehen rund 700
Pixel zur Verfuegung. Die Enge war nie eine Frage der Gestaltung,
sondern des Platzes.

DER TRANSPORT VERLAESST DAS REGISTER. Er lag in "Sendung" und war
damit weg, sobald jemand auf "Ton" oder "Spenden" ging. Jetzt ist er
eine eigene Zeile unter dem Saal -- und damit auch bei zugeklappter
Regie da. Der Play-Knopf ist der eine, den man mitten in einer
Sendung blind treffen muss.

`:has(.pult[data-auf="ja"])` UND KEINE KLASSE AM KOERPER: Der Zustand
steht schon am Pult; ein zweiter Merker waere die zweite Antwort auf
dieselbe Frage. Erst ab 1100 px -- darunter bleibt fuer das Video
keine Breite: 26rem Regie plus 23rem Chat sind 784 Pixel. Gerechnet,
nicht geraten.

=======================================================================
DREI BEFUNDE GEGEN DIE EIGENEN PRUEFUNGEN -- UND EINER IST ERNST

1. "GENAU EINE REGEL DARF DIE ZEILEN DES SAALS SETZEN" war die
   Faustregel zum Befund vom Nachmittag, aber nicht die Frage, um
   die es geht. Eine zweite FASSUNG (Handy, aufgeklappte Regie) ist
   richtig und noetig -- sie setzt die Zeilen neu UND verteilt die
   Kinder neu. Der Fehler war eine zweite ANGABE, die die Zeilenzahl
   VERKLEINERT und die Kinder stehen laesst. Geprueft wird jetzt
   genau das: Jede Fassung, deren Gegenstand der Saal IST, muss
   gleich viele Zeilen haben.

2. DER ERNSTE: Dieselbe Pruefung hatte einen BLINDFLECK. Ihr Muster
   liess den Regelrumpf ueber eine oeffnende Klammer hinweg laufen
   (`[^}]*` statt `[^{}]*`) -- damit fiel jede Regel INNERHALB eines
   `@media` heraus. Gemessen: Sie meldete "alle 1 Fassungen",
   obwohl zwei dastanden. Ein Fehler im Medienblock -- und genau
   dort steht die ganze Handyansicht -- waere unbemerkt
   durchgegangen. Die Gegenprobe beweist jetzt, dass eine Fassung
   mit weniger Zeilen wirklich auffaellt.

3. Auch beim Regieplatz zaehlte sie Fassungen statt Wirkung und
   schlug an, sobald eine dritte dazukam. Jetzt prueft sie, ob eine
   Fassung eine KACHEL VERGISST -- dann verschwindet die in genau
   dieser Ansicht, und gemerkt haette es niemand.

pruef-reaktion 374/0 - pruef-css-klassen ok - pruef-tippziele 11/0

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-09-28 20:45:34 +02:00
co-authored by Claude Opus 5
parent 6033d1b6f2
commit a6d55d939a
48 changed files with 895 additions and 749 deletions
+90 -31
View File
@@ -1651,27 +1651,61 @@ melde("=== 18. Die Regieleiste ===");
diese Pruefung -- sie war gruen und wertlos.
Jetzt zaehlt JEDE Regel, in deren Auswahl `.saal` vorkommt. */
const zeilen = [...css.matchAll(/\{|\}/g)].length >= 0
? [...css.replace(/\/\*[\s\S]*?\*\//g, " ")
.matchAll(/([^{}]*\.saal[^{}]*)\{([^}]*)\}/g)]
.filter((m) => /grid-template-rows/.test(m[2]))
: [];
ok(zeilen.length === 1,
zeilen.length === 1
? `genau eine Regel bestimmt die Zeilen des Saals (${zeilen[0][1].trim()})`
: `${zeilen.length} Regeln bestimmen die Zeilen des Saals -- `
+ `eine davon wird irgendwo ignoriert: `
+ zeilen.map((m) => m[1].trim()).join(" / "));
/* GEGENPROBE: Die Pruefung muss eine zweite Regel auch dann
finden, wenn sie nicht am Zeilenanfang steht -- genau daran ist
sie gescheitert. */
/* ==== NICHT „WIE VIELE", SONDERN „WIE VIELE ZEILEN" ==========
Diese Pruefung zaehlte Regeln: „genau eine darf die Zeilen des
Saals setzen." Das war die Faustregel zum Befund -- aber nicht
die Frage, um die es geht. Eine zweite FASSUNG (Handy,
aufgeklappte Regie) ist richtig und noetig; sie setzt die
Zeilen neu UND verteilt die Kinder neu. Der Fehler war eine
zweite ANGABE, die die Zeilenzahl VERKLEINERT und die Kinder
stehen laesst: Der Buehnenmodus gab dem Saal eine Zeile,
waehrend `#teil-live` auf Zeile 2 genagelt war -- Leinwand null
Pixel hoch.
Also: Jede Regel, deren Gegenstand der Saal IST, muss gleich
viele Zeilen setzen. Regeln, die nur zufaellig `.saal` im
Vorfahrenpfad haben (`.saal … .pult { … }`), zaehlen nicht --
sie beantworten eine andere Frage. */
/* `[^{}]*` FUER DEN RUMPF UND NICHT `[^}]*` -- der Unterschied
ist ein Blindfleck: Mit `[^}]*` verschluckt der Rumpf die
oeffnende Klammer eines `@media`, und jede Regel INNERHALB
eines Medienblocks faellt aus der Pruefung. Gemessen: Sie
meldete „alle 1 Fassungen", obwohl zwei dastanden. Ein Fehler
im Medienblock -- und genau dort steht die Handyansicht --
waere unbemerkt durchgegangen. */
const saalRegeln = (text) => [...text.replace(/\/\*[\s\S]*?\*\//g, " ")
.matchAll(/([^{}]+)\{([^{}]*)\}/g)]
.filter((m) => /grid-template-rows/.test(m[2]))
/* Der GEGENSTAND einer Auswahl ist ihr letzter Teil. Bei
`.saal .pult` ist das `.pult` -- und dessen Zeilen gehen den
Saal nichts an. */
.filter((m) => {
const teile = m[1].trim().split(/\s+|>/).filter(Boolean);
return /\.saal/.test(teile[teile.length - 1] || "");
})
.map((m) => ({
wahl: m[1].trim(),
zeilen: (m[2].match(/grid-template-rows:\s*([^;]+)/) || [, ""])[1]
.trim().split(/\s+(?![^(]*\))/).filter(Boolean).length,
}));
const saal = saalRegeln(css);
const zahlen = [...new Set(saal.map((x) => x.zeilen))];
ok(saal.length >= 1 && zahlen.length === 1,
zahlen.length === 1
? `alle ${saal.length} Fassungen des Saals haben ${zahlen[0]} Zeilen`
: `UNGLEICH VIELE ZEILEN: ` + saal.map((x) => `${x.wahl} → ${x.zeilen}`).join(" / "));
/* GEGENPROBE: Eine eingeschobene Fassung mit WENIGER Zeilen muss
auffallen -- genau die war der Buehnenmodus, und genau die hat
die alte Pruefung nicht gesehen. */
{
const erfunden = 'body[data-nur="probe"] .saal { grid-template-rows: 1fr; }';
const mit = [...(css + erfunden).replace(/\/\*[\s\S]*?\*\//g, " ")
.matchAll(/([^{}]*\.saal[^{}]*)\{([^}]*)\}/g)]
.filter((m) => /grid-template-rows/.test(m[2]));
ok(mit.length === 2,
`Gegenprobe: eine eingeschobene zweite Regel faellt auf (${mit.length})`);
const erfunden = 'body[data-nur="probe"] .saal { grid-template-rows: minmax(0, 1fr); }';
const mit = saalRegeln(css + erfunden);
ok([...new Set(mit.map((x) => x.zeilen))].length === 2,
`Gegenprobe: eine Fassung mit weniger Zeilen faellt auf `
+ `(${[...new Set(mit.map((x) => x.zeilen))].join(" und ")})`);
}
/* ---- UND SIE GEHOERT NUR DENEN, DIE SENDEN ---- */
@@ -1946,15 +1980,22 @@ melde("=== 20. Regieplatz und Bildschirm ===");
}
/* ---- LINKS, RECHTS UND EINE LEISTE UNTEN ---- */
ok(/laeuft sendung[\s\S]{0,60}laeuft bereit[\s\S]{0,60}leiste leiste/.test(regeln),
"der Regieplatz hat links, rechts und eine Leiste unten");
ok(/laeuft sendung[\s\S]{0,60}laeuft bereit/.test(regeln),
"der Regieplatz hat links und rechts eine Kachel");
/* ==== UND DIE REGIE STEHT LINKS NEBEN DEM VIDEO ==============
Filipe: „anstatt alles nur unten zu haben wieso nicht rechts
und links noch ausnutzen um mehr ueberblick zu haben." */
ok(/"pult kino"/.test(regeln) && /"transport transport"/.test(regeln),
"aufgeklappt steht die Regie links, das Video daneben, der Transport unten");
ok(/:has\(\.pult\[data-auf="ja"\]\)/.test(regeln),
"und zugeklappt bleibt sie die schmale Leiste von vorher");
/* ==== ES MUESSEN KACHELN SEIN UND KEINE SPALTEN ==============
Filipe hat die erste Fassung zerrissen: „ich wollte was hoch
professionelles wo rechts links und unten kacheln sind wo alles
drin ist." Zwei Spalten mit einer Trennlinie sind eine Teilung,
keine Gliederung -- und das sieht man einer CSS-Regel an:
Rahmen, eigener Grund, ein Kopf. */
const kachel = regeln.match(/\.regiekachel \{[^}]*\}/);
const kachel = regeln.match(/\.regiekachel \{[^{}]*\}/);
ok(!!kachel && /border:/.test(kachel[0]) && /background:/.test(kachel[0]),
"eine Regiekachel hat Rahmen und eigenen Grund");
ok((html.match(/class="regiekachel/g) || []).length >= 3,
@@ -1967,17 +2008,35 @@ melde("=== 20. Regieplatz und Bildschirm ===");
"die linke Kachel hat ein Vorschaubild");
ok(/laufbild-leer/.test(js) && /trag rechts eine YouTube-Adresse ein/.test(html),
"und ohne Video sagt sie, was zu tun ist");
const platz = [...regeln.matchAll(/([^{}]*\.regieplatz[^{}]*)\{([^}]*)\}/g)]
/* ==== JEDE FASSUNG BRAUCHT ALLE DREI KACHELN ================
Auch hier zaehlte die Pruefung Regeln -- und meldete einen
Fehler, sobald eine dritte Fassung dazukam (schmale Spalte
neben dem Video). Die Zahl der Fassungen ist aber nicht die
Frage. Die Frage ist, ob eine davon eine Kachel VERGISST: Dann
verschwindet sie in genau dieser Ansicht, und gemerkt haette
es niemand. */
const platz = [...regeln.matchAll(/([^{}]*\.regieplatz[^{}]*)\{([^{}]*)\}/g)]
.filter((m) => /grid-template-areas/.test(m[2]));
/* ZWEI REGELN FUER DIESELBE FRAGE SIND DIE GARANTIE, DASS EINE
FALSCH GEWINNT -- heute schon viermal passiert. Die Handyansicht
darf die Bereiche neu setzen; deshalb zwei, nicht eine. */
ok(platz.length === 2,
`${platz.length} Regeln ordnen den Regieplatz (Rechner und Handy)`);
ok(platz.length >= 2, `${platz.length} Fassungen ordnen den Regieplatz`);
const ohneKachel = platz.filter((m) => !["laeuft", "sendung", "bereit"]
.every((x) => m[2].includes(x)));
ok(ohneKachel.length === 0,
ohneKachel.length
? `EINE FASSUNG VERGISST EINE KACHEL: ${ohneKachel.map((m) => m[1].trim()).join(" / ")}`
: "und jede davon nennt alle drei Kacheln");
/* Die Leiste traegt den ganzen Transport -- und zwar in EINER. */
const iLeiste = html.indexOf('class="transport"');
const iEnde = html.indexOf("</section>", iLeiste);
/* ==== DER TRANSPORT LIEGT UNTER DEM SAAL, NICHT IM REGISTER
Er lag im Register „Sendung" und war damit weg, sobald jemand
auf „Ton" oder „Spenden" ging. Der Play-Knopf ist aber der
eine, den man mitten in einer Sendung blind treffen muss. */
const iPultEnde = html.indexOf('id="transport"');
ok(iPultEnde > html.indexOf('id="pult"'),
"der Transport steht hinter dem Pult");
ok(iPultEnde < html.indexOf("</main>"),
"und noch im Saal -- nicht in einem Register");
const iLeiste = html.indexOf('id="transport"');
const iEnde = html.indexOf("</main>", iLeiste);
const inLeiste = html.slice(iLeiste, iEnde);
for (const k of ["v-band", "v-zeit", "v-zurueck", "v-spiel", "v-vor", "v-naechstes", "tempo"]) {
ok(inLeiste.includes(`id="${k}"`), `„${k}" liegt in der Transportleiste`);