/*
 * Die Haustür. Das Aussehen ist auf florian/homelab#850 entschieden und wird
 * hier gebaut, nicht neu verhandelt:
 *
 *   Variante C — „Spalten“. Drei schräge senkrechte Spalten. Der Riss ist ein
 *   PROZENTUALER clip-path und niemals ein fester Winkel (#849: „ungefähr 30°“
 *   ist keine blickfeldunabhängige Angabe — 30° kosten auf einem 1440×900-
 *   Laptop 831 px gegen ein Budget von 300). Aufklappen verbreitert die Spalte
 *   und holt sie nach vorn. Der Grund ist `gerechnet`: ein Feld ohne eine
 *   einzige Bilddatei. Der Einstieg dahinter ist derselbe Riss eine Ebene
 *   tiefer — keine Karten, das Bild IST das Band.
 *
 * WAS HIER ANDERS IST ALS IM PROTOTYP, UND WARUM.
 *
 *   Der Prototyp rechnet die clip-paths in JavaScript, weil er zwischen drei
 *   Varianten und vier Gründen umschalten kann. Diese Seite kann das nicht und
 *   muss es nicht: es gibt genau drei Bereiche (die Karte: „Die Komposition
 *   bleibt drei“) und genau vier Zustände — nichts offen, oder einer von drei.
 *   Damit ist die gesamte Geometrie statisches CSS, und das ist keine
 *   Sparmaßnahme: eine Seite, deren Form von JavaScript abhängt, hat ohne
 *   JavaScript keine Form. So hat sie eine, und JavaScript fügt nur das Feld
 *   und das Umschalten hinzu.
 *
 * Reihenfolge: Marken, Grund, Spalten, Bänder, Kolophon, schmales Layout.
 */

/* ============================== die Marken ==============================
   Zurückhaltend, und das ist #850s Entscheidung, keine Vorsicht: „der Riss ist
   die Identität“. Drei Tönungen, ein Vordergrund, ein Fokusring — mehr Farben
   hat diese Seite nicht, weil jede weitere gegen den Riss anträte. */

:root {
  color-scheme: dark;

  --grund: #08090c;          /* die Seite unter allem */
  --feld: #070809;           /* was der Canvas als Erstes füllt */
  --schrift: #e8e6e1;
  --schrift-leise: rgba(232, 230, 225, 0.62);
  --schrift-still: rgba(232, 230, 225, 0.42);
  --fokus: #ff9a3d;

  /* Die halbe Steigung des Risses, in Prozent der BREITE der Bühne. #850:
     RISE_X = 8, also 4 je Seite. Prozent und nicht Grad — das ist die ganze
     Lehre aus #849, und sie steht deshalb in genau einer Zahl. */
  --R: 4%;

  /* Derselbe Riss eine Ebene tiefer, in Prozent der HÖHE des Einstiegs.
     #850: RISE_NEST = 9. */
  --RB: 4.5%;

  --schwung: 420ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Eine Tönung je Bereich. Sie liegt als Verlauf ÜBER dem Feld — das Feld ist
   eines für die ganze Bühne, und die Tönung ist das Einzige, was die drei
   Spalten voneinander unterscheidet. */
[data-bereich="community"] { --t1: #101c2b; --t2: #1d3f63; }
[data-bereich="tabletop"]  { --t1: #1a1220; --t2: #43214d; }
[data-bereich="games"]     { --t1: #12190f; --t2: #24401f; }

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

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  background: var(--grund);
  color: var(--schrift);
  /* Keine Webschrift. Alles, was diese Seite braucht, liefert sie mit, und eine
     Schriftdatei ist der einfachste Weg, sich versehentlich einen fremden Host
     einzuhandeln — hack/check-built-site.sh würde ihn abweisen, aber die Regel
     ist älter als die Prüfung. Der Charakter der Typografie kommt hier aus
     Größe, Gewicht und Laufweite, nicht aus einer eigenen Schrift: #850 hat den
     Riss zur Identität erklärt, und eine zweite auffällige Entscheidung daneben
     nähme ihm genau das. */
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* Nur für Bildschirmleser: die Seite trägt ihren Namen im <title>, und sichtbar
   wäre er eine vierte Sache neben drei Bereichen. Eine Überschriftenebene
   braucht sie trotzdem. */
.nur-vorlesen {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Sichtbar, überall, ohne Ausnahme. #849s Empfehlung ist eine echte
   Offenlegung, und eine echte Offenlegung muss erreichbar sein. */
:focus-visible {
  outline: 2px solid var(--fokus);
  outline-offset: 2px;
}

/* ============================== der Grund ==============================
   `gerechnet` (#850, Operator, 2026-08-15): ein Canvas-Feld ohne eine einzige
   Bilddatei, das langsam driftet und vom Zeiger geschoben wird. Es liegt HINTER
   den Spalten und scheint durch sie hindurch — deshalb ist es ein Geschwister
   der Bühne und nichts, was in einer Spalte steckt.

   Ohne Canvas — abgeschaltet, oder ein Leser, der keines hat — bleibt die
   Grundfarbe stehen. Die Seite verliert eine Bewegung und keine Aussage. */

#feld {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 0;
  background: var(--feld);
}

/* =============================== die Bühne =============================== */

#buehne {
  position: relative;
  z-index: 1;
  height: 100vh;
  overflow: hidden;
}

/* ============================== die Spalten ==============================
   Jede Spalte ist ein Kasten von der Größe der GANZEN BÜHNE; erst der
   clip-path macht eine Spalte daraus. Das ist nicht nebensächlich: weil der
   Kasten die Bühne ist, liegt der Einstieg darin ebenfalls über die volle
   Breite, und seine Bänder werden von der schrägen Kante der Spalte
   abgeschnitten. Genau dieser Schnitt ist der Grund, warum der Einstieg der
   gleiche Riss eine Ebene tiefer ist und nicht bloß so aussieht.

   --l und --r sind die NOMINELLEN Ränder der Spalte. Alles andere — die vier
   Ecken, der Textkasten, der linke Rand der Bänder — folgt daraus, sodass ein
   Zustand nur zwei Zahlen je Spalte setzt statt zwölf Koordinaten. */

.spalte {
  position: absolute;
  inset: 0;
  transition: clip-path var(--schwung);
  clip-path: polygon(
    calc(var(--l) + var(--R)) 0%,
    calc(var(--r) + var(--R)) 0%,
    calc(var(--r) - var(--R)) 100%,
    calc(var(--l) - var(--R)) 100%);
  z-index: 10;
}

/* Die äußeren beiden reichen bis an den Rand der Bühne und werden dort nicht
   angeschrägt — sonst stünde die Seite auf zwei Keilen. */
.spalte:first-of-type {
  clip-path: polygon(
    0% 0%,
    calc(var(--r) + var(--R)) 0%,
    calc(var(--r) - var(--R)) 100%,
    0% 100%);
}
.spalte:last-of-type {
  clip-path: polygon(
    calc(var(--l) + var(--R)) 0%,
    100% 0%,
    100% 100%,
    calc(var(--l) - var(--R)) 100%);
}

/* „Nach vorn holen“ ist wörtlich zu nehmen: die offene Spalte liegt über den
   anderen, nicht neben ihnen. */
.spalte[data-offen="true"] { z-index: 30; }

/* ========================= das Ruhebild (florian/homelab#1042) =========================
   Eine ruhende Bahn zeigte bis hierher nur Tönung über dem gerechneten Feld —
   „only showing the blank backdrop", so der Operator. Sie trägt nun die
   EIGENE Kunst: das erste Band dieser Bahn, das wirklich welche hat. Keine neue
   Datei, kein neues Byte; das Bild ist ohnehin im Image.

   (Das Wort dort oben heisst mit Absicht „nun". hack/check-gameserver.sh sucht
   die Beschriftung der laufenden Zeile als BLOSSES WORT mit `grep -rF` über das
   GANZE Bauergebnis — ein Kommentar in dieser Datei fällt darunter, und dieser
   hier ist beim ersten Bau genau so rot geworden. Deshalb steht das betroffene
   Wort in diesem Absatz nirgends ausgeschrieben: eine Erklärung, die ihre eigene
   Falle auslöst, wäre eine schlechte Erklärung.)

   Es liegt UNTER der Tönung und unter allem Text. Deshalb bekommt die Tönung
   hier eine Ebene zugewiesen — ohne sie stünde das Ruhebild als späteres Kind
   über dem ::before und die drei Tönungen, die die Bahnen unterscheiden, wären
   verdeckt.

   Es ist nie trefferbar. Das ist nicht Vorsicht, sondern #1032s Regel eine
   Ecke weiter: eine Fläche, die den ganzen Bahnkasten deckt, wäre der grösste
   denkbare Klickfänger, und sie hat nichts, wohin sie führen könnte. */
.ruhebild {
  position: absolute;
  inset: 0;
  z-index: 1;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  pointer-events: none;
  /* Beim Öffnen tritt es zurück: dann trägt der Einstieg die Kunst beschriftet,
     und zwei Bildebenen übereinander wären eine zu viel. Es verschwindet nicht
     — oben und unten schaut es weiter hervor und hält die Bahn zusammen. */
  opacity: 1;
  transition: opacity var(--schwung);
}
.spalte[data-offen="true"] .ruhebild { opacity: 0.22; }

/* Der Schleier über dem Ruhebild, und er ist keine Zierde: darüber stehen der
   Bereichsname und der Aufklapp-Knopf, und die standen bisher auf einem
   dunklen, gerechneten Grund. Auf Kunst ist Kontrast nichts, was sich von
   selbst einstellt — am gerenderten Bild gemessen, nicht geschätzt.
   Oben am dichtesten, weil dort der Text steht; nach unten hin gibt er die
   Kunst frei. */
.ruhebild::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    rgba(6, 7, 10, 0.92) 0%,
    rgba(6, 7, 10, 0.86) 22%,
    rgba(6, 7, 10, 0.55) 52%,
    rgba(6, 7, 10, 0.38) 100%);
}

/* Die Tönung. Sie liegt über dem Feld UND über dem Ruhebild, und unter dem
   Text — sie ist weiterhin das, was die drei Bahnen als drei liest. */
.spalte::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(160deg, var(--t1) 0%, var(--t2) 100%);
  opacity: 0.46;
  pointer-events: none;
}

/* Eine schräge Spalte ist nur zwischen ihrer oberen linken und ihrer unteren
   rechten Kante wirklich rechteckig. Der Text steht in genau diesem Rechteck —
   auf --l..--r gelegt fräst der clip-path die ersten beiden Buchstaben jeder
   Überschrift weg, und diese verlorene Breite ist der ehrliche Preis dafür, die
   Bereiche als Spalten zu lesen. */
.spalte-text {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--l) + var(--R));
  width: calc(var(--r) - var(--l) - 2 * var(--R));
  padding: clamp(20px, 4vh, 52px) 14px 0;
  transition: left var(--schwung), width var(--schwung);
  z-index: 20;
}

/* Kleiner als es eine ungeteilte Seite erlaubte, und das ist gemessen und nicht
   Geschmack: eine geschlossene Spalte ist rund ein Viertel der Bühnenbreite, in
   das ein Schaugrad von 62 px schlicht nicht passt. */
.bereich-name {
  font-size: clamp(18px, 2vw, 30px);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 0 0 8px;
  color: #fff;
}

/* ---------------------- die Offenlegung: die Zeile ----------------------
   #849 empfiehlt eine echte Offenlegung und nennt zwei Formen. Gewählt ist die
   Zeile: der eigene Satz des Bereichs IST der Knopf, unterstrichen, damit man
   ihm ansieht, dass er einer ist. Die andere Form — ein Chip nach APG — ist
   ebenso echt, kostet aber genau das, was #849 als ihren Preis benannt hat:
   drei sichtbare Bedienelemente auf einer Seite, deren ganze Idee drei saubere
   Risse sind.

   Ein <button> und kein <a>: er führt nirgendwohin, er klappt auf. */
.aufklappen {
  display: inline-block;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: clamp(13px, 1.35vw, 17px);
  line-height: 1.5;
  text-align: left;
  color: rgba(255, 255, 255, 0.86);
  cursor: pointer;
  /* 58ch und nicht 46: bei 46 lagen die deutschen Zeilen genau auf der Grenze,
     und der Winkel — per geschütztem Leerzeichen an das letzte Wort gebunden,
     damit er nicht verwaist — nahm die ganze Einheit in eine zweite Zeile. */
  max-width: 58ch;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 5px;
  text-decoration-color: rgba(255, 255, 255, 0.32);
}
.aufklappen .winkel {
  display: inline-block;
  font-size: 0.8em;
  opacity: 0.75;
  transition: transform 220ms ease;
}
.aufklappen[aria-expanded="true"] .winkel { transform: rotate(180deg); }
/* Der Winkel hängt am letzten Wort, nicht an der Zeile: passt das Paar nicht
   mehr, wandert es gemeinsam nach unten statt das Zeichen allein stehen zu
   lassen. Das leistet inzwischen das geschützte Leerzeichen im Markup selbst —
   der Prototyp brauchte dafür eine eigene Spanne um das letzte Wort, und die
   hätte die entschiedene Zeichenkette zerschnitten, die der Gate sucht. */

/* --------------------------- der Einstieg ---------------------------
   Sichtbarkeit statt [hidden], damit er sich in beide Richtungen bewegt und im
   geschlossenen Zustand trotzdem aus der Tabulatorfolge fällt.

   Über die volle Breite der Spalte, damit die Bänder bis an die schrägen Kanten
   laufen und dort vom clip-path der Spalte beendet werden. Oben lässt er die
   Überschrift stehen, unten das Kolophon. */
.einstieg {
  position: absolute;
  left: 0;
  right: 0;
  top: 24%;
  bottom: 7%;
  z-index: 20;
  opacity: 0;
  visibility: hidden;
  transition: opacity 260ms ease 110ms, visibility 0s linear 370ms;
}
.spalte[data-offen="true"] .einstieg {
  opacity: 1;
  visibility: visible;
  transition: opacity 260ms ease 110ms, visibility 0s;
}

/* ============================== die Bänder ==============================
   Keine Karten (#850, Operator): Kartenrahmen um die Welten waren eine zweite
   Bildsprache neben dem Riss. Das Bild IST das Band.

   --i und --n kommen aus den Daten, nicht aus dem Stylesheet. Deshalb steht
   hier auch keine Zahl 3: käme eine vierte Instanz dazu, stimmt die Geometrie
   weiter. Das ist dieselbe Naht, die die Manifeste offen halten — die Seite
   weiß nicht, wie viele Welten es gibt. */

.baender {
  position: relative;
  height: 100%;
}

.band {
  position: absolute;
  inset: 0;
  display: block;
  text-decoration: none;
  color: inherit;
  clip-path: polygon(
    0% calc(100% * var(--i) / var(--n) + var(--RB)),
    100% calc(100% * var(--i) / var(--n) - var(--RB)),
    100% calc(100% * (var(--i) + 1) / var(--n) - var(--RB)),
    0% calc(100% * (var(--i) + 1) / var(--n) + var(--RB)));
}
.band:first-child {
  clip-path: polygon(
    0% 0%,
    100% 0%,
    100% calc(100% * (var(--i) + 1) / var(--n) - var(--RB)),
    0% calc(100% * (var(--i) + 1) / var(--n) + var(--RB)));
}
.band:last-child {
  clip-path: polygon(
    0% calc(100% * var(--i) / var(--n) + var(--RB)),
    100% calc(100% * var(--i) / var(--n) - var(--RB)),
    100% 100%,
    0% 100%);
}

/* DAS BILD BEKOMMT SEIN EIGENES RECHTECK, und das ist eine Korrektur am
   Prototyp, kein Zusatz. Dort trägt das Band selbst den Hintergrund; das Band
   ist aber inset:0 des ganzen Einstiegs, also skaliert `cover` auf dessen Höhe
   und jedes Band zeigt nur einen waagerechten Streifen davon. `focus` — das
   Feld, ohne das hack/check-worlds.sh den Build rot macht, „sonst wäre der
   Ausschnitt Zufall“ — hätte dann fast nichts mehr zu entscheiden.
   Hier deckt das Bild genau das Rechteck seines eigenen Bandes ab, um --RB nach
   oben und unten verlängert, damit der Riss nie in eine Lücke schneidet. Erst
   dadurch ist `focus` das, wofür #850 es gehalten hat. */
.band-bild {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(100% * var(--i) / var(--n) - var(--RB));
  height: calc(100% / var(--n) + 2 * var(--RB));
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* WO KEIN BILD IST, ZEICHNET DAS RECHTECK DIE KANTE SELBST. Ohne dies sind
   zwei benachbarte bildlose Bänder exakt derselbe Ton, der Riss zwischen ihnen
   ist unsichtbar, und die Monatsrotation liest sich als frei schwebende Liste
   statt als Bänder. Ein Hauch Licht oben, ein Hauch Schatten unten: an jeder
   Risskante entsteht dadurch ein Tonsprung, und der Riss ist wieder da, ohne
   dass eine Linie gezogen oder eine Farbe erfunden werden müsste.
   Beim Ansehen der gebauten Seite gefunden, nicht beim Schreiben. */
.band[data-bild="false"] .band-bild {
  background-image: linear-gradient(180deg,
    rgba(255, 255, 255, 0.055) 0%,
    rgba(255, 255, 255, 0.014) 44%,
    rgba(0, 0, 0, 0.10) 100%);
}

/* Ein Schleier, keine Karte: gerade so viel Grund unter der Beschriftung, dass
   sie auf jedem Bild lesbar bleibt. Er läuft über das ganze Band und nicht erst
   ab --bandlinks — dort zu beginnen ließ im schrägen Rand der Spalte einen
   ungeschleierten Streifen stehen, der wie ein viertes, helleres Band aussah. */
.band-schleier {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    rgba(6, 7, 10, 0.84) 0%,
    rgba(6, 7, 10, 0.84) var(--bandlinks, 0%),
    rgba(6, 7, 10, 0.52) calc(var(--bandlinks, 0%) + 20%),
    rgba(6, 7, 10, 0) calc(var(--bandlinks, 0%) + 46%));
  transition: background var(--schwung);
}

/* Jedes Band ist ein Kasten voller Größe, den der clip-path nur FORMT — `bottom:
   0` wäre also der Boden des Einstiegs und stapelte alle Beschriftungen auf
   einen Punkt. Jede hängt an der höchsten Unterkante ihres eigenen Bandes, dem
   rechten Ende: die Beschriftung sitzt links, wo der steigende Riss bereits
   über der tiefen Ecke liegt. */
.band-text {
  position: absolute;
  left: var(--bandlinks, 0%);
  right: 0;
  bottom: calc(100% - 100% * (var(--i) + 1) / var(--n) + var(--RB));
  padding: 0 clamp(20px, 4vw, 56px) clamp(12px, 2vh, 22px);
  transition: left var(--schwung);
}
.band:last-child .band-text { bottom: 0; }

.band-titel {
  display: block;
  font-size: clamp(15px, 1.5vw, 21px);
  font-weight: 650;
  line-height: 1.25;
  color: #fff;
}
.band-unten {
  display: block;
  margin-top: 5px;
  font-size: 12px;
  color: var(--schrift-leise);
}

/* Der einzige Ort, an dem diese Seite eine Schreibmaschinenschrift benutzt, und
   dafür gibt es eine Regel statt eines Geschmacks: sie markiert das, was man
   eintippen kann. Das ist genau eine Zeichenkette — der Hostname des Chats.
   #856: die Apex war nie ein Weg zu ihm, „der Hostname ist der einzige Griff,
   den die Gruppe hat“, also steht er vollständig da und sieht aus wie das, was
   er ist. */
.hostname {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11.5px;
  letter-spacing: 0.01em;
}

/* Eine Instanz ohne aktive Welt behält ihr Band und verliert seinen Glanz. Sie
   ist keine Tür — verlinkt wird sie trotzdem, gleich wie die anderen (#982:
   eine leere Instanz ist ein Startfehler und kein Seitenzustand, den die Seite
   nachbilden soll). */
.band[data-leer="true"] .band-titel {
  font-weight: 500;
  font-style: italic;
  color: rgba(255, 255, 255, 0.72);
}
/* Ohne Bild gibt es nichts, wogegen der Text sich behaupten müsste — der volle
   Schleier machte aus dem Band dann ein Loch. */
.band[data-bild="false"] .band-schleier {
  background: linear-gradient(90deg, rgba(6, 7, 10, 0.42), rgba(6, 7, 10, 0.12));
}

/* ---------------------------- Zeit als Struktur ----------------------------
   Die Zeitangabe der Rotation steht links vor dem Spiel und ist bewusst leise:
   #949 hat gemessen, dass die Monate nicht mehr rekonstruierbar sind, und
   `vor 2026` ist eine wahre Aussage geringer Genauigkeit, wo `März 2019` eine
   falsche hoher Genauigkeit wäre. Kleingeschrieben und gesperrt, nicht
   versalisiert: die Unschärfe soll ruhig aussehen, nicht laut. */
.zeit {
  display: inline-block;
  letter-spacing: 0.08em;
  color: var(--schrift-still);
}

/* ============================== Zeigergesten ==============================
   HOVER IST AUSSCHLIESSLICH ZIERDE, und deshalb steht jede :hover-Regel in
   `@media (hover: hover)`. Das ist kein Widerspruch zu #849, sondern seine
   Anwendung: die Medienabfrage darf keine FUNKTION schalten, und hier schaltet
   sie keine — der Knopf klappt auf, mit und ohne Zeiger, in jedem Modus.

   Sie steht aus einem gemessenen Grund da: iOS Safari verschluckt den ersten
   Tipp auf jedes Element, dessen :hover-Regel die Darstellung ändert, nach
   Apples eigener mousemove-Regel. Ohne diese Klammer entstünde die
   Zwei-Tipp-Bedienung, die #849 als Falle benannt hat — aus Versehen. */
@media (hover: hover) {
  .spalte:hover .band-bild,
  .spalte:hover::before { filter: brightness(1.1); }
  .aufklappen:hover { color: #fff; text-decoration-color: rgba(255, 255, 255, 0.7); }
  a.band:hover .band-titel { color: #fff; }
  a.band:hover .band-schleier {
    background: linear-gradient(90deg,
      rgba(6, 7, 10, 0.9) 0%,
      rgba(6, 7, 10, 0.9) var(--bandlinks, 0%),
      rgba(6, 7, 10, 0.58) calc(var(--bandlinks, 0%) + 24%),
      rgba(6, 7, 10, 0.06) calc(var(--bandlinks, 0%) + 54%));
  }
}
/* Bewusst KEIN Rahmen und KEIN Anheben beim Überfahren: das Band ist die
   Fläche, nicht ein Bedienelement, das auf einer sitzt. */
a.band:focus-visible { outline: 2px solid var(--fokus); outline-offset: -4px; }

/* ============================= die vier Zustände =============================
   Nichts offen, oder einer von dreien. #850: OPEN_SHARE = 0.50, der Rest teilt
   sich den Rest. Mehr Zustände kann diese Seite nicht haben, und deshalb steht
   die Geometrie hier und nicht in einem Skript. */

#buehne .spalte:nth-of-type(1) { --l: 0%;      --r: 33.333%; }
#buehne .spalte:nth-of-type(2) { --l: 33.333%; --r: 66.667%; }
#buehne .spalte:nth-of-type(3) { --l: 66.667%; --r: 100%; }

#buehne[data-offen="community"] .spalte:nth-of-type(1) { --l: 0%;   --r: 50%; }
#buehne[data-offen="community"] .spalte:nth-of-type(2) { --l: 50%;  --r: 75%; }
#buehne[data-offen="community"] .spalte:nth-of-type(3) { --l: 75%;  --r: 100%; }

#buehne[data-offen="tabletop"] .spalte:nth-of-type(1) { --l: 0%;   --r: 25%; }
#buehne[data-offen="tabletop"] .spalte:nth-of-type(2) { --l: 25%;  --r: 75%; }
#buehne[data-offen="tabletop"] .spalte:nth-of-type(3) { --l: 75%;  --r: 100%; }

#buehne[data-offen="games"] .spalte:nth-of-type(1) { --l: 0%;   --r: 25%; }
#buehne[data-offen="games"] .spalte:nth-of-type(2) { --l: 25%;  --r: 50%; }
#buehne[data-offen="games"] .spalte:nth-of-type(3) { --l: 50%;  --r: 100%; }

/* Der linke Rand der Bänder ist eine Tatsache über die Spalte, gemessen an
   ihrer schmalsten Stelle — der oberen linken Ecke —, und keine Polsterung. */
.spalte { --bandlinks: calc(var(--l) + var(--R)); }

/* ============================== das Kolophon ==============================
   Leise, und es bleibt leise. Die drei Bereiche sind ein reiner Absprung; wer
   die Geschichte dahinter sucht, findet sie hier, und die Gruppe stolpert nie
   darüber. <details> und kein Skript: es klappt ohne JavaScript auf, ist über
   die Tastatur erreichbar und heißt in jedem Bildschirmleser richtig. */

.kolophon {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  padding: 10px 16px;
  font-size: 11px;
  color: var(--schrift-still);
}
.kolophon summary {
  display: inline-block;
  cursor: pointer;
  list-style: none;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: rgba(232, 230, 225, 0.25);
}
.kolophon summary::-webkit-details-marker { display: none; }
.kolophon details[open] summary { color: var(--schrift-leise); }
.kolophon p {
  max-width: 56ch;
  margin: 10px 0 0;
  font-size: 13px;
  line-height: 1.6;
  color: rgba(232, 230, 225, 0.8);
}
.kolophon details[open] {
  background: rgba(8, 9, 12, 0.94);
  border-top: 1px solid rgba(232, 230, 225, 0.14);
  margin: -10px -16px;
  padding: 14px 16px 18px;
}

/* ========================= das schmale Layout =========================
   Eine echte Medienabfrage, und sie hängt AN DER BREITE UND SONST NICHTS. Sie
   darf nie mit prefers-reduced-motion verschmolzen werden: das gäbe einem
   Mausleser mit reduzierter Bewegung das Telefonlayout auf einem 27-Zoll-
   Schirm, und kein Test fängt das (#849).

   `.ohne-js` nimmt dasselbe Layout bei jeder Breite. Ohne Skript gibt es kein
   Aufklappen — also wird nichts weggeklappt, und alle drei Einstiege stehen
   offen untereinander. Die Seite ist dann keine Geste mehr, aber sie ist
   vollständig: jede Tür, die sie hat, ist erreichbar. */

@media (max-width: 760px) {
  html.mit-js #buehne { height: auto; overflow: visible; padding-bottom: 72px; }
  html.mit-js .spalte {
    position: relative;
    inset: auto;
    clip-path: none !important;
    height: auto;
  }
  /* `relative` und NICHT `static`, und das ist der ganze Unterschied zwischen
     einer beschrifteten und einer unbeschrifteten Haustuer: `z-index: 20`
     (oben, an .spalte-text) wirkt AUSSCHLIESSLICH auf positionierte Elemente.
     Mit `static` faellt es weg, und das absolut gesetzte `.ruhebild`
     (z-index: 1) gewinnt die Malreihenfolge — mitsamt seinem Schleier, der
     ausdruecklich DARUNTER liegen soll. Auf 390 px stand hier deshalb ein
     Bild und kein Wort: kein Bereichsname, kein Satz, kein Winkel.
     florian/homelab#1048, am echten Chrome nachgestellt.
     `top`/`bottom`/`left` gehen auf `auto`, damit `relative` nichts
     verschiebt — es stellt nur die Reihenfolge wieder her. */
  html.mit-js .spalte-text {
    position: relative;
    top: auto;
    bottom: auto;
    left: auto;
    width: auto !important;
    padding: 24px 20px;
  }
  html.mit-js .einstieg { position: static; }
  html.mit-js .spalte[data-offen="false"] .einstieg { display: none; }
  html.mit-js .einstieg { transition: none; }
  html.mit-js .baender { height: auto; }
  html.mit-js .band {
    position: relative;
    inset: auto;
    height: 148px;
    clip-path: none !important;
  }
  html.mit-js .band + .band { margin-top: 3px; }
  html.mit-js .band-bild { position: absolute; inset: 0; top: 0; height: 100%; }
  html.mit-js .band-text { left: 0 !important; bottom: 0 !important; padding: 0 20px 12px; }
  html.mit-js .band-schleier {
    background: linear-gradient(0deg,
      rgba(6, 7, 10, 0.88) 0%, rgba(6, 7, 10, 0.5) 44%, rgba(6, 7, 10, 0.1) 100%) !important;
  }
  html.mit-js .kolophon { position: static; }
  html.mit-js .kolophon details[open] { margin: 0; }
}

/* Ohne Skript: dasselbe gestapelte Layout, bei jeder Breite, und alles offen. */
html.ohne-js #buehne { height: auto; overflow: visible; padding-bottom: 72px; }
html.ohne-js .spalte {
  position: relative;
  inset: auto;
  clip-path: none !important;
  height: auto;
}
/* Der zweite Fundort derselben Sache, und er gilt bei JEDER Breite: ohne
   Skript stand die Haustuer auch auf dem Schreibtisch unbeschriftet da.
   florian/homelab#856s Zusage war „faellt es aus, steht die Seite gestapelt
   mit jeder Tuer erreichbar" — erreichbar blieb sie, benannt nicht mehr, und
   eine Treffbarkeitspruefung sieht genau das nicht. Begruendung wie oben:
   florian/homelab#1048. */
html.ohne-js .spalte-text { position: relative; top: auto; bottom: auto; left: auto; width: auto !important; padding: 24px 20px; }
html.ohne-js .aufklappen { text-decoration: none; cursor: default; }
html.ohne-js .aufklappen .winkel { display: none; }
html.ohne-js .einstieg {
  position: static;
  opacity: 1;
  visibility: visible;
  transition: none;
}
html.ohne-js .baender { height: auto; }
html.ohne-js .band {
  position: relative;
  inset: auto;
  height: 148px;
  clip-path: none !important;
}
html.ohne-js .band + .band { margin-top: 3px; }
html.ohne-js .band-bild { position: absolute; inset: 0; top: 0; height: 100%; }
html.ohne-js .band-text { left: 0 !important; bottom: 0 !important; padding: 0 20px 12px; }
html.ohne-js .band-schleier {
  background: linear-gradient(0deg,
    rgba(6, 7, 10, 0.88) 0%, rgba(6, 7, 10, 0.5) 44%, rgba(6, 7, 10, 0.1) 100%) !important;
}
html.ohne-js .kolophon { position: static; }
html.ohne-js #feld { display: none; }

/* ============== die Bänder sind tot, bis sie zu sehen sind ==============
   florian/homelab#1032. `data-scharf` setzt tuer.js, und zwar erst, wenn das
   Aufblenden fertig ist — beim beiläufigen Öffnen durch den Zeiger sogar erst,
   nachdem der Zeiger sich einmal bewegt hat, während das Band schon zu sehen
   war. Die Begründung und die Messwerte stehen in tuer.js.

   Gemessen war der Zustand davor: der Anker ab t=2 ms trefferbar, bis ~150 ms
   bei opacity 0, voll da erst ab ~397 ms; 54 von 72 Rasterpunkten der Bahn
   sprangen von inert auf „ist ein Link“.

   DIESE ZWEI REGELN SIND DIE ZUSICHERUNG, die hack/check-built-site.sh hält:
   jede Regel, die ein Band trefferbar macht, trägt die Wache
   [data-scharf="true"]. Wer hier eine dritte hinzufügt, macht den Gate rot,
   und das ist der Zweck. */
.einstieg .band { pointer-events: none; }
.einstieg[data-scharf="true"] .band { pointer-events: auto; }

/* Ohne Skript gibt es keine Geste, keinen Zeiger-Zustand und nichts zu
   entschärfen: dort steht alles offen, und JEDE TÜR MUSS ERREICHBAR BLEIBEN
   (#856). Ohne diese Regel wäre die skriptlose Seite eine Liste toter Bänder —
   der Gate kennt sie deshalb als erlaubte Ausnahme. */
html.ohne-js .einstieg .band { pointer-events: auto; }

/* ========================= reduzierte Bewegung =========================
   #849s Befund, von Tag eins statt nachgerüstet. Das Feld verschwindet NICHT —
   es hört auf, sich zu bewegen (tuer.js zeichnet dann genau ein Bild). Es
   auszublenden wäre ein anderes Design, keine Einstellung. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    /* Die VERZOEGERUNG muss mit, nicht nur die Dauer. Der Einstieg schaltet
       seine `visibility` mit `0s linear 370ms` — die Verzoegerung wartet das
       Ausblenden ab, damit er sich in beide Richtungen bewegt. Bleibt sie unter
       reduzierter Bewegung stehen, dauert das Aufklappen dort 370 ms laenger
       als ueberall sonst, und zwar sichtbar: der Bereich ist offen und leer.
       Beim Nachmessen im Kopfloser-Browser gefunden. */
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }
}
