/*
 * Lumen Layout - Raum-/Gebäudegrafik
 * (Belegungsplan Tool 66/5/34, Reservierungsformular, Raumgrafik "ein Raum über
 * mehrere Tage")
 *
 * Die Grafik ist eine Tabelle: erste Spalte = Raum (bzw. Tag), danach eine Spalte
 * je Stunde. Die Belegungen liegen als absolut positionierte <div class=
 * "raumgrafikTimeevent"> in der Stundenzelle, in der sie beginnen; left und width
 * kommen in Prozent einer Stundenspalte aus dem PHP (GebaeudeGrafik::getWidth und
 * Tabelleneintrag::getVarValue). Ohne "position: relative" an der Zelle und
 * "position: absolute" am Block wirken diese Angaben nicht - die Blöcke stünden
 * im normalen Textfluss.
 *
 * Diese Geometrie-Regeln standen bisher ausschließlich in
 * layout/css/style.css (Zeilen 1886-1899), und style.css wird im Lumen-Layout
 * nicht geladen. Sie sind deshalb hier nachgezogen.
 *
 * Die erste Spalte wird nicht mehr über den JS-Klon der ganzen Tabelle fixiert
 * (KuferTools.fixiereTabellenSpalten - genau dieser Klon war die doppelte
 * Raumtabelle im Lumen), sondern über "position: sticky". Der Aufruf ist in
 * layout/js/hm_raumbelegung.js für das Lumen-Layout abgeschaltet.
 */

/* ---------------------------------------------------------------------------
 * Steuerleiste
 *
 * Alles, was den Ausschnitt bestimmt (Tag, Zeitraum, Gebäude), steht ÜBER dem
 * Raster - im klassischen Layout liegt dasselbe Formular unter bis zu 70 Zeilen.
 * Die vier Blätterpfeile tragen die Klasse "submit_bei_blaettern" und senden das
 * Formular damit selbst ab (ausgewertet in layout/js/hm_raumbelegung.js); ohne
 * sie setzten sie nur das Datumsfeld und man musste zusätzlich absenden.
 * ------------------------------------------------------------------------- */
/* Zwei Zeilen, weil die beiden Hälften verschieden teuer sind: Der Tag und die
   Gebäudeauswahl bestimmen, was geladen wird (eine knappe Sekunde Wartezeit),
   Bedarfsfenster und Raumsuche nur, was davon zu sehen ist (sofort, ohne
   Serverrunde). Die Trennlinie zeigt den Unterschied, ohne ihn zu beschriften. */
.rr-steuerleiste {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0 0 10px;
  padding: 10px 12px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}

.rr-zeile-laden,
.rr-zeile-zeigen {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
}

.rr-zeile-zeigen {
  padding-top: 8px;
  border-top: 1px solid var(--line-2);
}

.rr-steuerleiste .rr-suchfeld {
  width: 13rem;
}

.rr-steuerleiste .rr-gruppe {
  display: flex;
  align-items: center;
  gap: 6px;
}

.rr-steuerleiste label {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--ink-2);
  white-space: nowrap;
}

/* Datumswahl als zusammenhängende Einheit: Pfeile und Feld ohne Fugen. */
.rr-datum {
  gap: 0;
  border: 1px solid var(--ink-3);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--card);
}

.rr-pfeil {
  border: 0;
  background: var(--card);
  color: var(--ink-2);
  padding: 7px 10px;
  font: inherit;
  line-height: 1;
  cursor: pointer;
}

.rr-pfeil:hover {
  background: var(--teal-soft);
  color: var(--ink);
}

.rr-steuerleiste .rr-datumfeld {
  width: 7.5rem;
  border: 0;
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
  border-radius: 0;
  text-align: center;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

.rr-steuerleiste .rr-zeitfeld {
  width: 4.75rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.rr-bis {
  color: var(--ink-3);
}

.rr-steuerleiste .rr-gebaeude select {
  width: auto;
  min-width: 11rem;
}

/* Das Bedarfsfeld ist der Hauptfilter und darf das auch aussehen. */
.rr-bedarf {
  border: 1px solid var(--ink-3);
  border-radius: var(--radius-sm);
  padding: 3px 4px 3px 10px;
}

.rr-bedarf.rr-hat-bedarf {
  border: 2px solid var(--teal-d);
  background: var(--teal-soft);
  padding: 2px 3px 2px 9px;
}

.rr-bedarf.rr-hat-bedarf label {
  color: var(--teal-d);
  font-weight: 500;
}

.rr-weg {
  border: 0;
  background: none;
  color: var(--teal-d);
  font-size: 1.125rem;
  line-height: 1;
  padding: 3px 7px;
  border-radius: 5px;
  cursor: pointer;
}

.rr-weg:hover {
  background: rgba(1, 112, 115, 0.12);
}

/* Ohne gesetztes Zeitfenster gibt es nichts aufzuheben. Das Attribut setzt zuerst
   das Template, danach raumsuche.js - nur eine Stelle entscheidet. */
.rr-weg[hidden] {
  display: none;
}

/* Zeilen, die die Raumsuche ausschließt. */
table.grafik_table tbody tr.rr-versteckt {
  display: none;
}

.rr-zeitraum {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
  margin: 0 2px 10px;
  font-size: 0.8125rem;
  color: var(--ink-2);
}

.rr-zeitraum .rr-ergebnis {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--ink);
}

.rr-zeitraum .rr-hinweis,
.rr-zeitraum .rr-suchhinweis {
  color: var(--ink-3);
  font-style: italic;
}

/* Leere Hinweise sollen keine Lücke in der Zeile hinterlassen. */
.rr-zeitraum .rr-hinweis:empty,
.rr-zeitraum .rr-suchhinweis:empty {
  display: none;
}

/* ---------------------------------------------------------------------------
 * Farblegende - direkt unter dem Raster statt neben dem Formular am Seitenende
 * ------------------------------------------------------------------------- */
.rr-legende {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 18px;
  margin: 0 2px 24px;
  padding: 0;
  list-style: none;
  font-size: 0.8125rem;
  color: var(--ink-2);
}

.rr-legende .rr-legende-titel {
  font-weight: 500;
  color: var(--ink);
}

/* Die Legendenmarke ist ein Balken im Kleinen - dieselben Custom Properties,
   dieselbe Form. */
.rr-legende i {
  display: inline-block;
  width: 16px;
  height: 12px;
  margin-right: 7px;
  vertical-align: -1px;
  border: 1px solid var(--rr-balken-rand, rgba(16, 40, 44, 0.25));
  border-left: 4px solid var(--rr-balken-kante, var(--ink-3));
  border-radius: 3px;
  background: var(--rr-balken-flaeche, var(--card));
}

/* ---------------------------------------------------------------------------
 * Scrollbereich statt endloser Seite
 *
 * Im klassischen Layout begrenzt style.css den tbody auf 400 px und macht ihn
 * per "display: block" scrollbar. Das ist hier nicht möglich: "display: block"
 * an thead/tbody nimmt den Zellen ihre Tabellensemantik, und "position: sticky"
 * greift dann nicht mehr. Stattdessen scrollt der Wrapper, die Tabelle bleibt
 * eine Tabelle.
 * ------------------------------------------------------------------------- */
.table-responsive.grafik_table,
.table-responsive.grafik_table_raumreservierung {
  max-height: 27rem;
  overflow: auto;
  overscroll-behavior: contain;
  /* Nur so breit wie das Raster, höchstens so breit wie der Platz. Zwang man die
     Tabelle stattdessen auf die volle Breite (min-width: 100%), blieben auf großen
     Bildschirmen alle Spalten bei ihrer festen Breite und der Überschuss sammelte
     sich als Lücke hinter der Raumspalte. */
  width: fit-content;
  max-width: 100%;
  margin: 16px 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--card);
  /* Eigener Stapelkontext: Die klebenden Zellen brauchen z-index 2 bis 4, sonst
     laufen die Belegungsblöcke über sie hinweg. Ohne diesen Kontext gälten diese
     Werte aber seitenweit - und der Datumswähler, dem jQuery UI z-index 1 inline
     zuweist (der Eingabe fehlt ein positionierter Vorfahre), verschwände hinter
     der ersten Spalte. Mit "position: relative; z-index: 0" bleiben die Werte
     innerhalb des Rasters, und die ganze Tabelle konkurriert nur noch als eine
     Ebene 0. */
  position: relative;
  z-index: 0;
}

/* Den Rahmen und die Fläche trägt der Scrollbereich, nicht die Tabelle. Ihr
   Hintergrund muss durchsichtig sein, damit die Auflagen unter dem Gitter (siehe
   Vergangenheitsschleier) überhaupt zu sehen sind. */
.table-responsive.grafik_table > table.table.grafik_table,
.table-responsive.grafik_table_raumreservierung > table.table.grafik_table {
  width: auto;
  border: 0;
  border-radius: 0;
  background: transparent;
}

/* ---------------------------------------------------------------------------
 * Klebender Kopf und klebende erste Spalte
 *
 * Reihenfolge der Ebenen: Kopf-Ecke (4) über Kopfzeile (3) über erster Spalte
 * (2) über den Belegungsblöcken (1). Die Blöcke müssen unter der ersten Spalte
 * durchlaufen, wenn waagrecht gescrollt wird.
 * ------------------------------------------------------------------------- */
table.grafik_table thead th {
  position: sticky;
  top: 0;
  z-index: 3;
  padding: 7px 6px;
  background: var(--card);
  box-shadow: inset 0 -1px 0 var(--line);
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-align: left;
}

table.grafik_table thead th:first-child,
table.grafik_table tbody td:first-child {
  position: sticky;
  left: 0;
  background: var(--card);
}

table.grafik_table thead th:first-child {
  z-index: 4;
  /* Zwei Schatten: Trennlinie nach unten (wie die Kopfzeile) und nach rechts. */
  box-shadow: inset 0 -1px 0 var(--line), 1px 0 0 var(--line);
}

table.grafik_table tbody td:first-child {
  z-index: 2;
  box-shadow: 1px 0 0 var(--line);
  width: 17rem;
  min-width: 17rem;
  padding: 6px 10px 6px 12px;
  vertical-align: middle;
  font-size: 0.8125rem;
  line-height: 1.3;
  /* Der Raumname darf umbrechen, die Spalte aber nicht wachsen. */
  white-space: normal;
  overflow-wrap: anywhere;
}

/* Raumzeile: Name, darunter eine Meta-Zeile mit Platzzahl und Gebäude.
   Die Platzzahl (kursorte.platz) liegt ohnehin im Kursort-Objekt jeder Zeile -
   sie anzuzeigen kostet keine zusätzliche Abfrage. Räume ohne hinterlegtes
   Gebäude bekommen bewusst KEINEN Ersatztext, die Zeile bleibt dann kürzer. */
/* Name und Knopf nebeneinander statt untereinander - das halbiert die Zeilenhöhe. */
.rr-raumzelle {
  display: flex;
  align-items: center;
  gap: 10px;
}

.rr-raumzelle > .rr-raumtext {
  flex: 1 1 auto;
  min-width: 0;
}

.rr-raumzelle > .raumreservierung_reservieren_formular_div {
  flex: 0 0 auto;
  margin: 0;
}

.rr-raumname {
  display: block;
  font-weight: 500;
  color: var(--ink);
}

.rr-raummeta {
  display: block;
  font-size: 0.75rem;
  color: var(--ink-3);
}

.rr-raummeta > span + span::before {
  content: " · ";
}

.rr-raummeta .rr-plaetze {
  font-weight: 500;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}

.rr-raummeta .rr-freitext {
  color: var(--amber-d);
  font-weight: 500;
}

/* ---------------------------------------------------------------------------
 * Gruppenzeilen (frei / fast passend / belegt)
 *
 * Die Zeile spannt über alle Spalten; die Regeln für die klebende erste Spalte
 * müssen dafür zurückgenommen werden - sonst wäre die Gruppenzelle 14,5 rem breit
 * und stünde als Block über der ersten Spalte.
 * ------------------------------------------------------------------------- */
table.grafik_table tbody tr.rr-gruppenzeile > td:first-child {
  position: static;
  width: auto;
  min-width: 0;
  box-shadow: none;
  padding: 5px 12px;
  background: var(--neutral-bg);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-2);
}

table.grafik_table tbody tr.rr-gruppe-frei > td {
  background: var(--green-bg);
  color: var(--green-d);
}

table.grafik_table tbody tr.rr-gruppe-fast > td {
  background: var(--amber-bg);
  color: var(--amber-d);
}

.rr-gruppenanzahl {
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--ink-3);
}

/* Belegte Räume bleiben lesbar, treten aber zurück. */
table.grafik_table tbody tr.rr-zeile-belegt > td:first-child {
  background: var(--neutral-bg);
}

/* ---------------------------------------------------------------------------
 * Markierung des gesuchten Zeitraums
 *
 * Ein Band über alle Zeilen. Es wird nicht je Zelle gezeichnet, sondern einmal
 * je Zeile im ersten Stundenfeld: Dessen ::before ist absolut positioniert und
 * darf über die Zellgrenze hinausragen (dieselbe Mechanik wie bei den
 * Belegungsblöcken). Die Werte kommen als Custom Properties vom Server, eine
 * Stundenspalte ist 68 px breit.
 * ------------------------------------------------------------------------- */
/* Hier steht nur das Aussehen. WO das Band liegt (welche Spalte, wie weit links,
   wie breit), entscheidet der erzeugte Regelblock <style id="rr-ausschnitt"> -
   er setzt "content" und left/width an genau einer Spalte. Ohne "content"
   erscheint ein Pseudoelement gar nicht, diese Regeln bleiben also folgenlos,
   solange kein Bedarf gesetzt ist. So bleibt die Farbgebung im Stilblatt und der
   erzeugte Block winzig.

   Das Band liegt auf ::after, der Vergangenheitsschleier auf ::before - in dieser
   Reihenfolge malt der Browser, das Band bleibt also obenauf.

   Nur im Tabellenrumpf: Die Kopfzellen kleben (position: sticky) und brauchen dafür
   einen deckenden Hintergrund - der übermalt jede Auflage, die aus einer früheren
   Spalte herüberragt. Im Kopf war das Band deshalb noch nie zu sehen. Statt dagegen
   anzukämpfen bleibt der Kopf, was er ist: eine Zeile mit Uhrzeiten. */
.grafik_table.rr-hat-bedarf table.grafik_table tbody td.timestep::after {
  position: absolute;
  top: 0;
  bottom: 0;
  /* Unter das Gitter: Eine Auflage über den Zellenrändern schluckt sie, weil die
     Ränder heller sind als jede sichtbare Tönung. Die Balken (z-index 1) bleiben
     darüber. */
  z-index: -1;
  pointer-events: none;
  background: rgba(1, 112, 115, 0.07);
  border-left: 1px dashed rgba(1, 112, 115, 0.55);
  border-right: 1px dashed rgba(1, 112, 115, 0.55);
}

/* In den freien Räumen ist das Band die eigentliche Antwort - dort etwas kräftiger. */
.grafik_table.rr-hat-bedarf table.grafik_table tbody tr.rr-zeile-frei td.timestep::after {
  background: rgba(22, 163, 74, 0.1);
}

/* ---------------------------------------------------------------------------
 * Vergangenheit und Jetzt-Linie
 *
 * Nur am heutigen Tag: Was vorbei ist, tritt zurück, und ein Strich zeigt, wo
 * "jetzt" liegt. An vergangenen Tagen wäre der Schleier flächendeckend und
 * verschlechterte nur die Lesbarkeit - dort sagen es die gesperrten Knöpfe.
 * Die Uhrzeit kommt vom Server (dieselbe Uhr, die beim Speichern entscheidet);
 * der Browser schiebt den Strich minütlich weiter.
 * ------------------------------------------------------------------------- */
/* Schraffur statt Fläche: Eine geschlossene Tönung, die kräftig genug ist, um
   aufzufallen, ist zugleich dunkler als die Zellenränder (--line-2) - das Raster
   verschwände darin. Zwischen den Strichen bleibt es sichtbar. */
.rr-raster table.grafik_table tbody td.timestep::before {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: -1;
  pointer-events: none;
  background: repeating-linear-gradient(
    -45deg,
    rgba(16, 40, 44, 0.075) 0 5px,
    rgba(16, 40, 44, 0) 5px 11px
  );
}

.rr-raster.rr-jetzt table.grafik_table tbody td.timestep::before {
  border-right: 2px solid var(--orange);
}

/* Belegungsplan der Tools 5 und 34: Uhrzeitmarke ja, Schleier nein.
   Dort ist die Vergangenheit eine Auskunft wie jede andere - anders als in der
   Raumsuche, wo "vorbei" zugleich "nicht mehr reservierbar" heißt. Die Auflage
   selbst bleibt bestehen, sie trägt die orangefarbene Kante an ihrem rechten
   Rand; nur die Schraffur fällt weg. */
.rr-raster.rr-ohne-schleier table.grafik_table tbody td.timestep::before {
  background: none;
}

/* ---------------------------------------------------------------------------
 * Stundenspalten und Belegungsblöcke
 * ------------------------------------------------------------------------- */
table.grafik_table .timestep {
  position: relative;
  width: 68px;
  min-width: 68px;
  padding: 0;
  border-left: 1px solid var(--line-2);
}

table.grafik_table tbody td {
  border-top: 1px solid var(--line-2);
}

table.grafik_table .raumgrafikTimeevent {
  position: absolute;
  /* Bahnen (Tools 5 und 34, siehe unten): Überschneiden sich Belegungen eines
     Raums, liegt jede in einer eigenen Bahn derselben Zeile. Die Zahlen setzt
     das PHP ins Stilattribut - so trägt eine Formel jede Bahnenzahl, statt für
     jede eine eigene Regel zu brauchen. Ohne Überschneidung (1 Bahn, Bahn 0)
     rechnen sich top und bottom auf die früheren 3 px zurück. */
  --rr-bahnen: 1;
  --rr-bahn: 0;
  --rr-bahn-hoehe: calc((100% - 6px - (var(--rr-bahnen) - 1) * 2px) / var(--rr-bahnen));
  top: calc(3px + var(--rr-bahn) * (var(--rr-bahn-hoehe) + 2px));
  bottom: calc(3px + (var(--rr-bahnen) - 1 - var(--rr-bahn)) * (var(--rr-bahn-hoehe) + 2px));
  z-index: 1;
  overflow: hidden;
  box-sizing: border-box;
  padding: 2px 6px;
  border: 1px solid var(--rr-balken-rand, rgba(16, 40, 44, 0.18));
  /* Kräftige Kante vorn, helle Fläche dahinter - dasselbe Muster wie die
     Statusmarken auf den übrigen Lumen-Seiten. Der Balken beginnt damit sichtbar
     dort, wo die Belegung beginnt, auch wenn er nur wenige Pixel breit ist. */
  border-left: 4px solid var(--rr-balken-kante, var(--ink-3));
  background: var(--rr-balken-flaeche, var(--card));
  color: var(--rr-balken-text, var(--ink));
  border-radius: 5px;
  font-size: 0.75rem;
  line-height: 1.25;
}

/* ---------------------------------------------------------------------------
 * Farbe nach ART der Belegung
 *
 * Im klassischen Layout bestimmen die Tool-Einstellungen farbe* die Fläche und
 * unterscheiden damit den STATUS eines Kurstags (normal, erster Kurstag,
 * durchgeführt). Für die Raumsuche ist das die falsche Auskunft: Wer einen Raum
 * sucht, will wissen, WAS ihn belegt. Die Klasse kommt aus Tabelleneintrag::$art,
 * die Legende aus derselben Quelle (GebauedeGrafik::getArtLegenden) - eine Farbe,
 * eine Beschriftung, ein Ursprung. Nur wenn PHP keine Flächenfarbe mehr mitgibt
 * (setFarbeAusArt), greifen diese Werte; in den Hausmeister- und
 * Mitarbeiter-Sichten bleibt die alte Färbung.
 * ------------------------------------------------------------------------- */
.rr-art-kurstag {
  --rr-balken-kante: var(--blue);
  --rr-balken-flaeche: var(--blue-bg);
  --rr-balken-text: var(--blue-d);
  --rr-balken-rand: #c7d7fa;
}

.rr-art-sperre {
  --rr-balken-kante: var(--red);
  --rr-balken-flaeche: var(--red-bg);
  --rr-balken-text: var(--red-d);
  --rr-balken-rand: #f5cccc;
}

.rr-art-reservierung {
  --rr-balken-kante: var(--amber);
  --rr-balken-flaeche: var(--amber-bg);
  --rr-balken-text: var(--amber-d);
  --rr-balken-rand: #f0dcb4;
}

/* Auf- und Abrüstung gehören zum Kurstag daneben und sollen ihn nicht überstimmen. */
.rr-art-ruest {
  --rr-balken-kante: var(--ink-3);
  --rr-balken-flaeche: var(--neutral-bg);
  --rr-balken-text: var(--ink-2);
  --rr-balken-rand: var(--line);
}

.rr-art-kursplanung {
  --rr-balken-kante: var(--teal);
  --rr-balken-flaeche: var(--teal-soft);
  --rr-balken-text: var(--teal-d);
  --rr-balken-rand: #b8e3e4;
}

/* Überschneiden sich Belegungen VERSCHIEDENER Art in einem Balken, wäre jede der
   beiden Farben eine Behauptung. Der Balken beschriftet sich ohnehin mit
   "N Raumbelegungen". */
.rr-art-mehrere {
  --rr-balken-kante: var(--ink-2);
  --rr-balken-flaeche: var(--neutral-bg);
  --rr-balken-text: var(--ink);
  --rr-balken-rand: var(--line);
}

/* Die Anzahl trägt die Aussage des zusammengefassten Balkens. */
table.grafik_table .raumgrafikTimeevent .grafik_anzahl {
  font-weight: 500;
}

/* Balken mit Angaben sind anklickbar - und sollen danach aussehen. */
table.grafik_table .raumgrafikTimeevent[data-detail] {
  cursor: pointer;
}

table.grafik_table .raumgrafikTimeevent[data-detail]:hover {
  border-color: var(--rr-balken-kante, var(--ink-3));
}

table.grafik_table .raumgrafikTimeevent[data-detail]:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 1px;
}

/* ---------------------------------------------------------------------------
 * Detailfenster einer Belegung
 *
 * Der Inhalt wird im Browser gebaut (components/belegungsdetails.js) und in einen
 * jQuery-UI-Dialog gegeben; Rahmen, Kopf und Fußzeile kommen aus jquery-ui.css.
 * Hier steht nur der Inhalt. Er wohnt in dieser Datei, weil sie ohnehin für jede
 * Seite geladen wird - eine zweite Stilvorlage für dieselbe Sache wäre eine
 * zusätzliche Anfrage für nichts.
 * ------------------------------------------------------------------------- */
.rr-detail-tag {
  margin: 0 0 12px;
  font-size: 0.8125rem;
  color: var(--ink-3);
}

.rr-detail-liste {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Dieselbe Kante wie am Balken, aus denselben Custom Properties (.rr-art-*).
   Wer den Balken angeklickt hat, erkennt ihn im Fenster wieder. */
.rr-detail-eintrag {
  padding: 10px 12px;
  border: 1px solid var(--rr-balken-rand, var(--line));
  border-left: 4px solid var(--rr-balken-kante, var(--ink-3));
  border-radius: var(--radius-sm);
  background: var(--rr-balken-flaeche, var(--card));
}

.rr-detail-kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  margin: 0 0 6px;
}

.rr-detail-zeit {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--rr-balken-text, var(--ink));
}

.rr-detail-art {
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* Bezeichnung und Wert nebeneinander, solange der Platz reicht. */
.rr-detail-felder {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 2px 12px;
  margin: 0;
}

.rr-detail-felder dt {
  font-size: 0.8125rem;
  font-weight: 400;
  color: var(--ink-3);
}

.rr-detail-felder dd {
  margin: 0;
  color: var(--ink);
  overflow-wrap: anywhere;
}

/* Der Weg zum Kurs - die Handlung des Fensters, und der einzige Ort, an dem es
   ihn gibt (der Balken selbst trägt keinen Link mehr). */
.rr-detail-kurs {
  display: inline-block;
  margin-top: 10px;
}

@media (max-width: 30rem) {
  .rr-detail-felder {
    grid-template-columns: 1fr;
    gap: 0 0;
  }

  .rr-detail-felder dd {
    margin-bottom: 6px;
  }
}

table.grafik_table .raumgrafikTimeevent .grafik_kursinhalt {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* ---------------------------------------------------------------------------
 * Tagesstreifen - dasselbe Raster als Liste (schmale Fenster, Telefon)
 *
 * Auf einem Telefon ist die Tabelle unbrauchbar: allein die Raumspalte ist
 * 17 rem breit, dahinter liegen 14 bis 24 Stundenspalten. Statt einer zweiten
 * Darstellung mit eigener Datenquelle wird hier nur UMGEBROCHEN - dieselben
 * Zeilen, dieselben Balken, dieselben Klassen. Aus der Tabellenzeile wird eine
 * Karte: oben Raumname, Platzzahl und "Reservieren", darunter der Tagesstreifen.
 *
 * Der Streifen ist nichts anderes als die Stundenzellen, gleich breit
 * nebeneinander (flex: 1 1 0). Weil left und width der Balken Prozentwerte EINER
 * Stundenzelle sind, stimmt die Geometrie ohne eine einzige neue Rechnung - und
 * mit ihr der Ausschnitt, der Vergangenheitsschleier, das Bedarfsband, die
 * Jetzt-Linie und das Detailfenster beim Antippen eines Balkens.
 *
 * Die Stundenbeschriftung steht nur noch EINMAL über der Liste (der Tabellenkopf,
 * unverändert) und bleibt beim Scrollen stehen. Beschriftet wird jede vierte
 * Spalte; weil Spalte 1 der Raum ist, trifft :nth-child(4n+2) genau die durch
 * vier teilbaren Stunden (0, 4, 8, 12, 16, 20) - unabhängig davon, wo der
 * Ausschnitt beginnt.
 * ------------------------------------------------------------------------- */

/* Ob die Liste gilt, entscheidet allein der Media-Query unten. components/
   tagesstreifen.js liest diesen Wert, statt die Breite ein zweites Mal zu
   kennen. */
.rr-raster {
  --rr-liste: 0;
}

/* ---------------------------------------------------------------------------
 * Dieselbe Grafik im Reservierungsformular
 *
 * Dort geht es um EINEN Raum an EINEM Tag - dieselbe Tabelle, eine Zeile
 * (siehe FormularGrafikUseCase). Die erste Spalte braucht dann keine 17 rem:
 * Sie trägt nur den Raumnamen, und der steht ohnehin schon in der Überschrift.
 * Die schmalere Spalte lässt dafür mehr Stunden ins Bild.
 * ------------------------------------------------------------------------- */
.rr-grafik-titel {
  margin: 18px 0 2px;
  font-size: 1.0625rem;
}

.rr-formulargrafik .rr-zeitraum {
  margin-bottom: 4px;
}

.rr-einzelraum table.grafik_table tbody td:first-child {
  width: 8rem;
  min-width: 8rem;
}

.rr-einzelraum table.grafik_table thead th:first-child {
  width: 8rem;
}

/* Die eine Zeile bekommt ihre Höhe sonst vom Raumnamen - eine Zeile Text, in die
   ein Balken mit Kursnummer UND Titel nicht hineinpasst. */
.rr-einzelraum table.grafik_table tbody td {
  height: 3rem;
}

/* Eine einzelne Zeile braucht keinen eigenen Rollbereich in der Höhe. */
.table-responsive.grafik_table.rr-einzelraum {
  max-height: none;
}

/* ---------------------------------------------------------------------------
 * Das Bedarfsband läuft hier auch durch die Kopfzeile
 *
 * Im Belegungsplan tragen siebzig Zeilen die Sichtbarkeit des Bandes: Liegt in
 * einem Raum eine Belegung darüber, sieht man es in den anderen. Hier gibt es
 * nur EINE Zeile - von ihren 48 Pixeln bleiben bei einer Kollision drei über und
 * drei unter dem Balken übrig. Die Kopfzeile übernimmt deshalb, was sonst die
 * Nachbarzeilen leisten, und sie tut es an der besten Stelle: direkt an den
 * Uhrzeiten, die man ohnehin abliest.
 *
 * Die Geometrie liegt bereits an - die erzeugte Ausschnitt-Regel trifft mit
 * "tr > *" auch die Kopfzellen. Im Weg stand nur ihr deckender Hintergrund: Eine
 * klebende Kopfzelle braucht ihn, um beim Scrollen alles zu überdecken, und er
 * übermalt jede Auflage, die aus einer früheren Spalte herüberragt. Mit einer
 * einzigen Zeile scrollt hier aber nichts senkrecht, der Hintergrund darf also
 * weg. NICHT bei der ersten Spalte: Die klebt waagrecht, und unter ihr müssen
 * die Stundenspalten weiterhin verschwinden.
 * ------------------------------------------------------------------------- */
/* Der unsichtbare Rand ist kein Schmuck: Die Stundenzelle im Rumpf hat einen
   1-px-Rand links, die Kopfzelle nicht - und left/width des Bandes sind Prozente
   des Kastens, gegen den sie rechnen. Ohne diesen Rand säße das Kopfband einen
   Pixel daneben und wäre zwei Pixel zu breit; die gestrichelten Kanten hätten
   einen sichtbaren Versatz zur Zeile darunter. */
.rr-einzelraum table.grafik_table thead th:not(:first-child) {
  background: transparent;
  border-left: 1px solid transparent;
}

.grafik_table.rr-einzelraum.rr-hat-bedarf table.grafik_table thead th::after {
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: -1;
  pointer-events: none;
  background: rgba(1, 112, 115, 0.07);
  border-left: 1px dashed rgba(1, 112, 115, 0.55);
  border-right: 1px dashed rgba(1, 112, 115, 0.55);
}

/* Skala und Auskunft gehören zum Streifen und hängen als zusätzliche Zellen an
   der Zeile. In der Tabelle wären sie zwei zusätzliche Spalten - dort bleiben
   sie aus. */
.rr-raster tbody td.rr-skala,
.rr-raster tbody td.rr-auskunft,
.rr-raster tbody td.rr-belegungen,
.rr-raster tbody .rr-belegungszahl {
  display: none;
}

/* ---------------------------------------------------------------------------
 * Überschneidende Raumbelegungen (Tools 5 und 34)
 *
 * Dort ist eine Überschneidung kein Darstellungsproblem, sondern ein Befund:
 * zwei Kurse im selben Raum zur selben Zeit muss jemand auflösen. Sie fällt
 * deshalb auf drei Ebenen auf - Meldung über der Tabelle, Warnzeichen in der
 * Raumzelle, getönter Streifen am Balken.
 *
 * Statt sie zusammenzufassen (so macht es die Raumsuche in Tool 66) bekommt
 * jede Belegung eine eigene BAHN. Die Geometrie steht oben in der Grundregel
 * des Balkens; die Zeilenhöhe kommt aus GebauedeGrafik::getHoeheForZeile und
 * hält jede Bahn auf den 24 px der WCAG-Zielfläche: bis zwei Bahnen konstante
 * 57 px für die ganze Tabelle (es wächst nicht die Zeile, es schrumpft der
 * Balken), ab drei wächst die betroffene Zeile mit (83 px bei drei Bahnen).
 * Der Vorteil gegenüber dem Zusammenfassen: Beide Kurstage behalten Text, Farbe
 * und vor allem ihren Link - und jede Balkenbreite stimmt weiterhin.
 * ------------------------------------------------------------------------- */

/* In einer Bahn ist nur eine Textzeile Platz - der zweite Eintrag würde sonst
   halb abgeschnitten hervorlugen. */
table.grafik_table .raumgrafikTimeevent:not(.rr-bahnen-1) {
  padding-top: 1px;
  padding-bottom: 1px;
}

table.grafik_table .raumgrafikTimeevent:not(.rr-bahnen-1) .grafik_kursinhalt + .grafik_kursinhalt {
  display: none;
}

/* Der überlagerte Bereich als kräftiger Streifen am UNTEREN Rand, nicht als
   Fläche: Eine Tönung über der ganzen Balkenfläche drückt den Text unter den
   Kontrastwert (gemessen 4,02:1 auf der Bernstein-Fläche, nötig sind 4,5:1).
   Die Geometrie kommt als Verlauf aus dem PHP (--rr-ovl), die Farbe steht hier. */
table.grafik_table .raumgrafikTimeevent.rr-ueberschneidet {
  background-image: var(--rr-ovl);
  background-size: 100% 4px;
  background-position: bottom left;
  background-repeat: no-repeat;
}

/* Treffer der Suche über die Raumbelegungen (Tools 5 und 34, siehe
   components/belegungssuche.js). Die Zeile bleibt stehen, weil IRGENDEINE ihrer
   Belegungen passt - der Ring sagt, welche. Als outline und nicht als Rahmen:
   Ein Rahmen verschöbe den Inhalt des Balkens um zwei Pixel, und bei einem
   halbstündigen Kurstag ist dafür kein Platz. */
table.grafik_table .raumgrafikTimeevent.rr-treffer {
  outline: 2px solid var(--focus-ring);
  outline-offset: -1px;
  z-index: 2;
}

/* ---------------------------------------------------------------------------
 * Raumgrafik (Tools 5 und 34): EIN Raum über MEHRERE Tage
 *
 * Dieselbe Tabelle wie der Belegungsplan, um 90 Grad gedreht - deshalb steht hier
 * nur, was sich unterscheidet: die Kopfzeile mit dem Raum, die Wahl des Zeitraums
 * und die schmalere erste Spalte (ein Datum braucht keine 17 rem).
 * ------------------------------------------------------------------------- */
.rr-raumkopf-meta {
  margin: -8px 2px 12px;
  color: var(--ink-2);
  font-size: 0.875rem;
}

.rr-steuerleiste a.rr-pfeil {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

/* Zwischen den Pfeilen steht der NAME des Zeitraums, kein Eingabefeld: Gezeigt
   wird immer eine ganze Woche oder ein ganzer Monat, und der hat einen Namen.
   Zugleich ist er der Auslöser für den Sprung zu einem Datum - dort sucht man
   ihn, weil es in Kalendern überall so ist.
   Die Mindestbreite hält die Pfeile ruhig, wenn der Name kürzer wird ("Mai"). */
.rr-steuerleiste .rr-zeitraumlabel {
  min-width: 12.5rem;
  padding: 3px 8px;
  border-radius: var(--radius-sm);
  text-align: center;
  font-size: 0.9375rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  cursor: pointer;
  list-style: none;
}

.rr-steuerleiste .rr-zeitraumlabel::-webkit-details-marker {
  display: none;
}

.rr-steuerleiste .rr-zeitraumlabel .fa-caret-down {
  margin-left: 4px;
  color: var(--ink-3);
}

.rr-steuerleiste .rr-zeitraumlabel:hover,
.rr-steuerleiste .rr-zeitraumwahl[open] > .rr-zeitraumlabel {
  background: var(--teal-soft);
}

.rr-steuerleiste .rr-zeitraumlabel:focus-visible {
  outline: 2px solid var(--teal-d);
  outline-offset: 1px;
}

/* Zurück zum heutigen Tag - erscheint nur, wenn er nicht ohnehin zu sehen ist.
   Bewusst ein stiller Link neben den Knöpfen, keiner davon. */
.rr-steuerleiste .rr-heute {
  align-self: center;
  color: var(--teal-d);
  font-size: 0.8125rem;
  text-decoration: none;
}

.rr-steuerleiste .rr-heute:hover,
.rr-steuerleiste .rr-heute:focus {
  text-decoration: underline;
}

.rr-steuerleiste .rr-spanne .btn.aktiv {
  border-color: var(--teal-d);
  background: var(--teal-soft);
  color: var(--teal-d);
  font-weight: 600;
}

/* Die Gruppe klippt sonst ihre Ecken (.rr-datum, overflow: hidden) - und mit
   ihnen das aufgeklappte Feld. Hier runden deshalb die Randkinder selbst ab. */
.rr-datum.rr-datum-klappbar {
  overflow: visible;
}

.rr-datum.rr-datum-klappbar > :first-child {
  border-top-left-radius: var(--radius-sm);
  border-bottom-left-radius: var(--radius-sm);
}

.rr-datum.rr-datum-klappbar > :last-child {
  border-top-right-radius: var(--radius-sm);
  border-bottom-right-radius: var(--radius-sm);
}

/* Das Sprungfeld hängt unter der Beschriftung, statt die Leiste auseinander zu
   schieben - sonst wanderten Pfeile und Knöpfe beim Aufklappen. */
.rr-zeitraumwahl {
  position: relative;
}

.rr-zeitraumwahl .rr-sprungfeld {
  position: absolute;
  z-index: 5;
  top: 100%;
  left: 50%;
  width: max-content;
  margin-top: 4px;
  padding: 10px;
  transform: translateX(-50%);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--card);
  box-shadow: var(--shadow);
}

.rr-waehler-kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}

.rr-waehler-titel {
  flex: 1 1 auto;
  text-align: center;
  font-size: 0.875rem;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

/* Monatsmodus: zwölf Monate, das Jahr über die Pfeile im Kopf. */
.rr-monatsraster {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}

.rr-monatsraster .rr-monat {
  position: relative;
  min-width: 4.25rem;
  padding: 9px 8px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--line-2);
  color: var(--ink);
  font-size: 0.875rem;
  text-align: center;
  text-decoration: none;
}

.rr-monatsraster .rr-monat:hover {
  background: var(--teal-soft);
}

/* Der laufende Monat bekommt einen Punkt - er ist eine Auskunft, keine Wahl. */
.rr-monatsraster .rr-monat.rr-jetzt::after {
  content: "";
  position: absolute;
  top: 6px;
  right: 6px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--teal);
}

.rr-monatsraster .rr-monat.rr-gewaehlt {
  border-color: var(--teal-d);
  background: var(--teal-soft);
  color: var(--teal-d);
  font-weight: 650;
}

/* Wochenmodus: die ZEILE ist das Ziel. Deshalb liegt in jeder Zelle derselbe
   Link - kein Tagesklick, der hinterher auf den Montag zurückgerechnet wird. */
.rr-wochentabelle {
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.rr-wochentabelle th {
  padding: 2px 6px 6px;
  color: var(--ink-3);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.rr-wochentabelle td {
  padding: 0;
  border-top: 1px solid transparent;
  border-bottom: 1px solid transparent;
}

.rr-wochentabelle .rr-zelle {
  display: block;
  min-width: 1.85rem;
  padding: 7px 2px;
  color: var(--ink);
  font-size: 0.8125rem;
  text-align: center;
  text-decoration: none;
}

.rr-wochentabelle .rr-zelle.rr-kw {
  min-width: 3rem;
  padding-right: 8px;
  color: var(--ink-3);
  font-size: 0.75rem;
  text-align: right;
}

.rr-wochentabelle .rr-zelle.rr-fremd {
  color: var(--ink-3);
}

.rr-wochenzeile:hover td {
  background: var(--teal-soft);
}

.rr-wochenzeile:hover td:first-child {
  border-radius: var(--radius-sm) 0 0 var(--radius-sm);
}

.rr-wochenzeile:hover td:last-child {
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}

.rr-wochenzeile.rr-gewaehlt td {
  border-top-color: var(--teal-d);
  border-bottom-color: var(--teal-d);
  background: var(--teal-soft);
}

.rr-wochenzeile.rr-gewaehlt .rr-zelle {
  color: var(--teal-d);
  font-weight: 650;
}

.rr-wochentabelle .rr-zelle.rr-heute {
  position: relative;
}

.rr-wochentabelle .rr-zelle.rr-heute::after {
  content: "";
  position: absolute;
  bottom: 2px;
  left: 50%;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  border-radius: 50%;
  background: var(--teal);
}

/* Ohne JavaScript bleibt das Formular - ein Feld, kein Bereich. */
.rr-sprungform {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.rr-sprungform label {
  font-size: 0.8125rem;
  color: var(--ink-2);
  white-space: nowrap;
}

/* Auf dieser Seite steht in der Zeile nur der Suchhinweis. Sie muss trotzdem
   immer im Dokument stehen - components/belegungssuche.js schreibt beim Tippen
   hinein -, soll ohne Begriff aber keine Lücke hinterlassen. Deshalb trägt der
   Hinweis den Abstand, nicht der Absatz. */
.rr-zeitraum.rr-nursuche {
  margin-bottom: 0;
}

.rr-zeitraum.rr-nursuche .rr-suchhinweis:not(:empty) {
  margin-bottom: 10px;
}

.rr-raumtage table.grafik_table tbody td:first-child,
.rr-raumtage table.grafik_table thead th:first-child {
  width: 8.5rem;
  min-width: 8.5rem;
}

.rr-raumtage .rr-tagzelle .rr-raumname {
  font-variant-numeric: tabular-nums;
}

/* Der heutige Tag ist die Zeile, die man zuerst sucht. Die Fläche liegt auf der
   Tagzelle, nicht auf der Zeile: Über den Stundenzellen läge sie vor der
   Uhrzeitmarke (td.timestep::before, z-index -1). */
.rr-raumtage tbody tr.rr-zeile-heute td:first-child {
  background: var(--teal-soft);
}

.rr-raumtage .rr-heute-marke {
  color: var(--teal-d);
  font-weight: 600;
}

/* Die betroffenen Räume in der Warnmeldung sind Sprungziele. Der Punkt dazwischen
   kommt aus dem Stilblatt: Im FOREACH gäbe es kein "zwischen", nur ein "vor
   jedem". */
.rr-warnung-raum {
  color: var(--amber-d);
  text-decoration: underline;
}

.rr-warnung-raum + .rr-warnung-raum::before {
  content: " · ";
  text-decoration: none;
  display: inline-block;
  margin: 0 2px;
}

.rr-warnung-raum:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

/* Angesprungene Zeile: Der klebende Tabellenkopf darf sie nicht verdecken. */
table.grafik_table tbody tr.rr-zeile {
  scroll-margin-top: 3rem;
}

.rr-raumname .rr-warnzeichen {
  margin-right: 5px;
  color: var(--amber-d);
}

.rr-warnung {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  margin: 0 2px 10px;
  padding: 7px 12px;
  border: 1px solid var(--amber-rand);
  border-radius: var(--radius-sm);
  background: var(--amber-bg-2);
  color: var(--amber-d);
  font-size: 0.8125rem;
}

.rr-warnung .rr-warnung-raeume {
  color: var(--ink-2);
}

/* Am Rechner ist die Tabelle da, und mit ihr der Tooltip am Balken. */
.rr-tipp {
  display: none;
  margin: 0 2px 8px;
  font-size: 0.8125rem;
  font-style: italic;
  color: var(--ink-3);
}

/* ---------------------------------------------------------------------------
 * Konfliktauskunft im Reservierungsformular
 *
 * Sie steht unter den beiden Uhrzeitfeldern - dort, wo die Änderung entsteht,
 * nicht oben bei der Grafik. Aufgebaut wird sie in components/formulargrafik.js;
 * das Template ist mit dem klassischen Layout geteilt und bleibt unberührt.
 *
 * Zwei Zustände, bewusst ungleich gewichtet (dasselbe Prinzip wie beim
 * Absendekasten in formstatus.css): "belegt" ist ein Kasten, "frei" nur eine
 * Zeile. Der gute Fall ist der häufige - er soll bestätigen, nicht auffallen.
 * ------------------------------------------------------------------------- */
.rr-konflikt {
  margin: 8px 0 0;
  font-size: 0.8125rem;
}

.rr-konflikt-satz {
  display: flex;
  align-items: baseline;
  gap: 7px;
  margin: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.rr-konflikt-frei {
  color: var(--green-d);
}

.rr-konflikt-belegt {
  padding: 8px 12px;
  border: 1px solid var(--amber-rand);
  border-radius: var(--radius-sm);
  background: var(--amber-bg-2);
  color: var(--amber-d);
}

.rr-konflikt-liste {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
}

/* Dieselbe Kante wie am Balken und im Detailfenster, aus denselben Custom
   Properties (.rr-art-*): Wer die Belegung im Raster gesehen hat, erkennt sie
   im Satz wieder. */
.rr-konflikt-eintrag {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 10px;
  padding: 5px 10px;
  border: 1px solid var(--rr-balken-rand, var(--line));
  border-left: 4px solid var(--rr-balken-kante, var(--ink-3));
  border-radius: var(--radius-sm);
  background: var(--rr-balken-flaeche, var(--card));
}

.rr-konflikt-zeit {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--rr-balken-text, var(--ink));
}

.rr-konflikt-was {
  font-weight: 400;
  color: var(--ink-2);
  overflow-wrap: anywhere;
}

@media (max-width: 47.9375em) {
  .rr-raster {
    --rr-liste: 1;
  }

  /* Kein eigener Scrollkasten mehr: Auf dem Telefon scrollt die Seite, sonst
     läge ein Rollbereich im anderen. */
  .table-responsive.grafik_table.rr-raster {
    max-height: none;
    overflow: visible;
    width: auto;
    margin: 12px 0 16px;
  }

  /* Durchgehend "table.grafik_table" im Selektor, obwohl ".rr-raster" allein
     eindeutig wäre: Die Regeln weiter oben in dieser Datei tragen alle diesen
     Klassennamen und wären sonst spezifischer - das Umbrechen liefe ins Leere.
     (Genau daran ist der erste Anlauf gescheitert: Die Achse behielt ihre
     Schriftgröße und beschriftete jede Stunde.) */
  .rr-raster > table.table.grafik_table,
  .rr-raster table.grafik_table tbody {
    display: block;
  }

  /* Der Tabellenkopf entfällt. Eine einzige Achse über der Liste hilft nur den
     obersten Karten: Wer beim zwanzigsten Raum angekommen ist, müsste einen
     Balken am unteren Bildrand mit einer Skala am oberen vergleichen. Jede Karte
     trägt deshalb ihre eigene Skala (td.rr-skala, gebaut in
     components/tagesstreifen.js) - so wie im Entwurf. */
  .rr-raster table.grafik_table thead {
    display: none;
  }

  /* Zeilen werden zu Karten. Bewusst OHNE eigenen Hintergrund: Schleier und
     Bedarfsband liegen auf z-index -1, also unter dem Gitter - und damit auch
     unter jedem Hintergrund, den ein Nachfahre der Tabelle setzt. Die weiße
     Fläche kommt vom Kasten ringsum. */
  .rr-raster table.grafik_table tbody td {
    border-top: 0;
  }

  /* Der Abstand nach unten ist knapp bemessen: Er gehört optisch noch zum Raum
     darüber. Die Hälfte davon steckt stattdessen im grauen Kopf der nächsten
     Karte (siehe unten) - dieselbe Gesamthöhe, aber die Grenze liegt weiter
     oben und wird dadurch deutlicher. */
  .rr-raster table.grafik_table tbody tr.rr-zeile {
    display: flex;
    flex-wrap: wrap;
    padding-bottom: 6px;
    border-top: 1px solid var(--line);
  }

  /* Sonst stünde die Linie direkt unter dem Rahmen des Kastens. */
  .rr-raster table.grafik_table tbody tr.rr-zeile:first-child {
    border-top: 0;
  }

  /* Unter der letzten Karte kommt keine weitere - dort wäre der knappe Abstand
     nur ein zu enger Rand zum Kasten. */
  .rr-raster table.grafik_table tbody tr.rr-zeile:last-child {
    padding-bottom: 12px;
  }

  .rr-raster table.grafik_table tbody tr.rr-gruppenzeile,
  .rr-raster table.grafik_table tbody tr.rr-gruppenzeile > td {
    display: block;
  }

  /* Der Kartenkopf: Name, Platzzahl, Gebäude und der Knopf - die erste Spalte
     der Tabelle, nur über die volle Breite.
     Er trägt als einziger eine Fläche: Ein Trennstrich allein beantwortete die
     Frage nicht, wo ein Raum aufhört und der nächste anfängt - Streifen, Skala
     und Belegungsliste stehen ja untereinander und sehen aus wie ein Block. Das
     graue Band markiert den Anfang jeder Karte.
     Die Fläche darf hier sein, weil der Vergangenheitsschleier und das
     Bedarfsband an den STUNDENZELLEN hängen (td.timestep::before, z-index -1) -
     dort bleibt der Hintergrund weiterhin durchsichtig. */
  .rr-raster table.grafik_table tbody tr.rr-zeile > td:first-child {
    position: static;
    z-index: auto;
    flex: 0 0 100%;
    width: auto;
    min-width: 0;
    padding: 9px 12px 8px;
    border-bottom: 1px solid var(--line);
    background: var(--bg);
    box-shadow: none;
  }

  /* Viel Luft ÜBER dem Raumnamen, wenig darunter (22 gegen 8 Pixel): Nähe
     gruppiert, und so gehört der Kopf sichtbar zu dem Streifen UNTER ihm statt
     zur Karte darüber. Der Abstand zwischen zwei Karten bleibt in der Summe
     derselbe (6 px weiß + 22 px grau) - er liegt nur zum größeren Teil in der
     grauen Fläche, die schon zur neuen Karte gehört. Die erste Karte braucht das
     nicht, über ihr steht der Rand des Kastens. */
  .rr-raster table.grafik_table tbody tr.rr-zeile:not(:first-child) > td:first-child {
    padding-top: 22px;
  }

  .rr-raster table.grafik_table tbody td.timestep {
    flex: 1 1 0;
    min-width: 0;
    height: 2.25rem;
    border-top: 1px solid var(--line-2);
    border-bottom: 1px solid var(--line-2);
  }

  .rr-raster table.grafik_table tbody td.timestep:nth-child(4n+2) {
    border-left-color: var(--line);
  }

  /* Auf 30 Pixel Spaltenbreite ist kein Text unterzubringen; die Angaben stehen
     im Fenster, das ein Antippen öffnet. Die Mindestbreite hält kurze
     Belegungen (Rüstzeiten!) sichtbar. */
  .rr-raster table.grafik_table tbody .raumgrafikTimeevent {
    top: 2px;
    bottom: 2px;
    min-width: 5px;
    padding: 0;
    border-left-width: 3px;
    border-radius: 3px;
  }

  .rr-raster table.grafik_table tbody .raumgrafikTimeevent .grafik_kursinhalt {
    display: none;
  }

  /* Die Skala unter dem Streifen. Die Marken liegen absolut in Prozent der
     Zeilenbreite - dieselbe Rechnung wie bei den Balken, deshalb stehen sie
     genau über den Stundenstrichen. Höhere Spezifität als die erzeugten
     Ausschnitt-Regeln (.rr-raster tr > *:nth-child(n+X){display:none}): Skala
     und Auskunft stehen als letzte Zellen der Zeile und fielen sonst mit den
     Stunden hinter dem Ausschnitt aus. */
  .rr-raster table.grafik_table tbody tr > td.rr-skala {
    display: block;
    position: relative;
    flex: 0 0 100%;
    height: 1.1rem;
    padding: 1px 0 0;
    border: 0;
    font-size: 0.625rem;
    line-height: 1;
    color: var(--ink-3);
    font-variant-numeric: tabular-nums;
  }

  .rr-raster table.grafik_table tbody td.rr-skala span {
    position: absolute;
    top: 2px;
    white-space: nowrap;
  }

  .rr-raster table.grafik_table tbody tr > td.rr-auskunft {
    display: block;
    flex: 0 0 100%;
    padding: 3px 12px 0;
    border: 0;
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
    color: var(--ink-2);
  }

  /* Die Raumbelegungen als Liste unter dem Streifen (Tools 5 und 34, gebaut in
     components/belegungsliste.js). Auf dem Telefon ist SIE die Auskunft: In den
     Balken steht dort kein Text mehr, und die Frage dieser Tabelle lautet, WAS
     den Raum belegt. Nebenbei löst die Liste jede Überschneidung auf - zwei
     einander überlappende Zeiten stehen hier untereinander. */
  .rr-raster table.grafik_table tbody tr > td.rr-belegungen {
    display: block;
    flex: 0 0 100%;
    padding: 4px 12px 0;
    border: 0;
  }

  .rr-raster table.grafik_table tbody td.rr-belegungen ul {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: 0;
    padding: 0;
    list-style: none;
  }

  /* Jede Zeile sieht aus wie ihr Balken: helle Fläche, kräftige Kante vorn, Text
     in der dunklen Tönung derselben Farbe (dieselben Wertepaare wie oben bei
     .rr-art-*, dort auf Kontrast geprüft). Die Farbe ist auf dem Telefon die
     einzige Auskunft über die Art - der Streifen darüber ist zu schmal für Text,
     und eine Legende steht weit oben auf der Seite. */
  .rr-raster table.grafik_table tbody td.rr-belegungen .rr-bel-knopf {
    display: flex;
    gap: 4px 10px;
    flex-wrap: wrap;
    width: 100%;
    /* 24 px Zielfläche (WCAG 2.2), dieselbe Vorgabe wie bei den Bahnen. */
    min-height: 24px;
    align-items: baseline;
    padding: 5px 10px;
    border: 1px solid var(--rr-balken-rand, var(--line));
    border-left: 3px solid var(--rr-balken-kante, var(--ink-3));
    border-radius: 5px;
    background: var(--rr-balken-flaeche, var(--card));
    font: inherit;
    font-size: 0.8125rem;
    color: var(--rr-balken-text, var(--ink));
    text-align: left;
    cursor: pointer;
  }

  .rr-raster table.grafik_table tbody td.rr-belegungen .rr-bel-knopf:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 1px;
  }

  .rr-raster table.grafik_table tbody td.rr-belegungen .rr-bel-zeit {
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
    font-weight: 500;
  }

  /* Eine Zeile je Raumbelegung: Was nicht hineinpasst, steht im Fenster, das ein
     Antippen öffnet. */
  .rr-raster table.grafik_table tbody td.rr-belegungen .rr-bel-text {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }

  .rr-raster table.grafik_table tbody td.rr-belegungen .rr-bel-versteckt {
    display: none;
  }

  .rr-raster table.grafik_table tbody td.rr-belegungen .rr-mehr {
    padding: 5px 0 3px 11px;
    border: 0;
    background: none;
    font: inherit;
    font-size: 0.8125rem;
    color: var(--focus-ring);
    text-decoration: underline;
    cursor: pointer;
  }

  /* Die Zahl im Kartenkopf - erst sie macht aus dem Streifen eine Auskunft, ohne
     dass man die Liste zählen muss. */
  .rr-raster table.grafik_table tbody .rr-belegungszahl {
    display: block;
    margin-top: 1px;
    font-size: 0.75rem;
    color: var(--ink-2);
  }

  .rr-raster table.grafik_table tbody .rr-belegungszahl-frei {
    color: var(--ink-3);
  }

  /* Der Hinweis auf das Antippen - nur dort, wo es etwas anzutippen gibt. */
  .rr-tipp {
    display: block;
  }

  /* Steuerleiste: Auswahl und Suchfeld nehmen die volle Zeile, statt sich auf
     375 Pixel in vier Fetzen zu teilen. */
  .rr-steuerleiste .rr-gebaeude,
  .rr-steuerleiste .rr-bedarf,
  .rr-steuerleiste .rr-suche {
    flex: 1 1 100%;
  }

  .rr-steuerleiste .rr-gebaeude select,
  .rr-steuerleiste .rr-suchfeld {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
  }
}
