/* =====================================================================
   REVOLUTION II – Abendzettel
   Die Plakate sind das Gesetz: eine Schrift, ein Schnitt, zwei Farben.

   Die Plakate sind in Folio Bold Condensed gesetzt (Bauer 1957) – eine
   kommerzielle Schrift, die nicht auf einen Webserver gehört. Aus dem Feld
   der frei lizenzierten Annäherungen sitzt Big Shoulders Display 900 am
   nächsten dran; gemessen an den Originalplakaten (300 dpi, Pixelanalyse):

     Merkmal                Plakat   Big Shoulders 900
     Versalbreite N/H       1,227    1,143
     x-Höhe / Versalhöhe    0,741    0,750
     Unterlänge / Versal    0,266    0,250
     Stammbreite / Versal   0,201    0,188   ← 6 % zu leicht
     „REVOLUTION“ in cap     5,61     5,77

   Die fehlende Strichstärke holt allein die Riesenzeile mit einer Kontur von
   1 Einheit (bei Schriftgrad 100) zurück, siehe .riese. Sonst gilt die Regel
   der Plakate: kein Tracking, keine zweite Familie, kein leichterer Schnitt –
   auch der Haftungsausschluss in 0,9 % Versalhöhe bleibt fett.

   Aufbau dieser Datei
     1  Marken (Custom Properties)
     2  Grundlage
     3  Papier und Raster
     4  Der Bogen (Seitengerüst: Absender, Bogenleiste, Haftung)
     5  Satz (Riesenzeilen, Zeilenblöcke, Fließtext)
     6  Bausteine (Stempel, Medaillon, Marquee, Graffito, Plakate)
     7  Programm
     8  Fragezettel
     9  Bewegung
   ===================================================================== */

/* 1 ── Marken ──────────────────────────────────────────────────────── */

:root {
  /* Zwei Farben, mehr hatten die Plakate nicht. Grau entsteht nur als
     Raster, nie als Fläche – deshalb gibt es hier kein Grau. */
  --tinte: #000;
  --papier: #fff;
  /* Gedrucktes bleibt gedruckt: Plakate und Fotos kippen im Dunkelmodus nicht
     mit, sonst hinge da ein Negativ an der Wand. */
  --druck-tinte: #000;
  --druck-papier: #fff;

  --schrift: "Big Shoulders Display", "Haettenschweiler", "Arial Narrow", sans-serif;
  /* Was das Publikum selbst schreibt, steht in seiner eigenen Schrift, nicht in
     der des Plakats. Das betrifft ausschließlich Eingabefelder und die in der
     Redaktion gelesenen Fragen – jeder Text, den das Blatt selbst sagt, steht
     in der Plakatschrift, bis hinunter zum Haftungsausschluss. */
  --hand: ui-sans-serif, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* Versalhöhe von Big Shoulders = 0,800 em. Die Stufen sind die Plakatstufen,
     umgerechnet: Schriftgrad = gewünschte Versalhöhe / 0,800 */
  /* Die Stufen des Absenderkopfs stehen einzeln, weil sie die Kopfhöhe
     bestimmen (siehe --kopf-absender) und weil das Plakat sie so setzt. */
  --t-absender-1: clamp(1.009rem, 3.114vw, 1.611rem);
  --t-absender-2: clamp(0.859rem, 2.523vw, 1.288rem);
  --t-absender-3: clamp(0.773rem, 2.147vw, 1.095rem);
  --t-reiter: clamp(0.752rem, 2.792vw, 1.074rem);
  --t-termin: clamp(1.127rem, 3.865vw, 1.933rem);
  --t-lauf: clamp(1.02rem, 3.221vw, 1.557rem);
  --t-lauftext: clamp(1.235rem, 1.095rem + 0.644vw, 1.611rem);
  --t-punkt: clamp(1.342rem, 4.724vw, 1.879rem);
  --t-nebensatz: 1rem;

  --t-gross: clamp(2.255rem, 9.127vw, 4.939rem);
  --t-mittel: clamp(1.45rem, 3.865vw, 2.255rem);
  --t-text: clamp(1.141rem, 1.031rem + 0.537vw, 1.396rem);
  --t-klein: clamp(0.94rem, 0.891rem + 0.215vw, 1.074rem);
  --t-winz: clamp(0.738rem, 0.709rem + 0.129vw, 0.872rem);

  /* Abstände: die Plakate kennen nur wenige, dafür klare Sprünge. */
  --luft-1: 0.35rem;
  --luft-2: 0.75rem;
  --luft-3: 1.5rem;
  --luft-4: 2.5rem;
  --luft-5: clamp(3rem, 8vw, 6rem);
  --rand: clamp(0.75rem, 3.5vw, 2.25rem);
  --breite: 62rem;

  --rund-lichtkasten: clamp(18px, 5vw, 42px);

  --strich: 3px;
  --strich-dick: 7px;

  /* Was über dem Umschlag steht, aus denselben clamp-Werten zurückgerechnet:
     Absenderkopf (Polster oben + unten + drei Zeilen à 1,06 + Trennstrich)
     und die Bogenleiste (Mindesthöhe + Trennstrich). JavaScript misst den
     Wert später exakt nach; ohne JavaScript stimmt diese Rechnung auf wenige
     Pixel genau. */
  --kopf-absender: calc(
    clamp(0.7rem, 2.2vw, 1.15rem) + clamp(0.55rem, 1.6vw, 0.9rem) + var(--strich)
    + 1.06 * (var(--t-absender-1) + var(--t-absender-2) + var(--t-absender-3)));
  --kopf-leiste: calc(3.1rem + var(--strich));
  --kopfhoehe: calc(var(--kopf-absender) + var(--kopf-leiste));

  color-scheme: light dark;
}

/* Im Halbdunkel des Foyers steht das Plakat als Negativ da – so, wie es
   aus dem Kopierer kommt, wenn man den Deckel offen lässt. */
@media (prefers-color-scheme: dark) {
  :root { --tinte: #fff; --papier: #000; }
}

@font-face {
  font-family: "Big Shoulders Display";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/bigshoulders-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Big Shoulders Display";
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("../fonts/bigshoulders-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* 2 ── Grundlage ───────────────────────────────────────────────────── */

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

html {
  -webkit-text-size-adjust: 100%;
  /* Sonst verdeckt die klebende Bogenleiste den Anfang des Sprungziels. */
  scroll-padding-top: 4.5rem;
}

body {
  margin: 0;
  background: var(--papier);
  color: var(--tinte);
  font-family: var(--schrift);
  font-size: var(--t-text);
  line-height: 1.42;
  font-weight: 900;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
}

img, svg { max-width: 100%; display: block; }
img { height: auto; }

a { color: inherit; text-underline-offset: 0.14em; text-decoration-thickness: 2px; }

:where(a, button, input, textarea, select, summary, [tabindex]):focus-visible {
  outline: var(--strich) solid var(--tinte);
  outline-offset: 3px;
}

/* Sprungmarke für die Tastatur – sieht aus wie ein aufgeklebter Zettel. */
.sprung {
  position: absolute; left: var(--rand); top: -100px; z-index: 50;
  background: var(--tinte); color: var(--papier);
  padding: 0.5rem 0.9rem; font-size: var(--t-klein);
  text-transform: uppercase; text-decoration: none;
  transition: top 0.12s;
}
.sprung:focus { top: 0.5rem; }

.nur-vorleser {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* 3 ── Papier und Raster ───────────────────────────────────────────── */

/* Kein Raster als Fläche. Die Vergrößerung der Plakate zeigt keinen
   regelmäßigen Punktraster, sondern einen stochastischen Diffusionsdither –
   und den bekommt CSS nicht ehrlich hin. Ein Ben-Day-Punktraster wäre das
   falsche Signal (Siebdruck statt Kopierer), also bleiben die Flächen satt.
   Grau gibt es hier weiterhin nicht: nur Tinte, Papier und Deckkraft. */

/* 4 ── Der Bogen ───────────────────────────────────────────────────── */

.bogen {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

/* Der Absenderkopf steht auf jedem Plakat und auf jedem Blatt: wer lädt,
   in welcher Eigenschaft, wozu. Er ist keine Zierzeile, sondern der Kopf
   eines Briefes – und rechtlich der Absender. */
.absender {
  text-align: center;
  padding: clamp(0.7rem, 2.2vw, 1.15rem) var(--rand) clamp(0.55rem, 1.6vw, 0.9rem);
  line-height: 1.06;
  text-transform: uppercase;
  border-bottom: var(--strich) solid var(--tinte);
}
.absender b {
  display: block;
  font-weight: 900;
  font-size: var(--t-absender-1);
  letter-spacing: 0.005em;
}
.absender span {
  display: block;
  font-size: var(--t-absender-2);
}
.absender em {
  display: block;
  font-style: normal;
  font-size: var(--t-absender-3);
  text-transform: none;
}
.absender a { text-decoration: none; }
.absender a:hover b { text-decoration: underline; }

/* Die Bogenleiste ist die Faltkante: fünf Felder, das aufgeschlagene
   steht im Negativ. Oben auf großen Schirmen, unten am Daumen auf dem
   Telefon – dort, wo im Foyer die Hand liegt. */
.bogenleiste {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  border-bottom: var(--strich) solid var(--tinte);
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--papier);
}
.bogenleiste a {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.05em;
  padding: 0.5rem 0.2rem 0.45rem;
  text-decoration: none;
  text-transform: uppercase;
  line-height: 1;
  border-right: var(--strich) solid var(--tinte);
  min-height: 3.1rem;
}
.bogenleiste a:last-child { border-right: 0; }
.bogenleiste a i {
  font-style: normal;
  font-size: var(--t-winz);
  opacity: 0.75;
}
.bogenleiste a b {
  font-weight: 900;
  font-size: var(--t-reiter);
}
.bogenleiste a[aria-current="page"] { background: var(--tinte); color: var(--papier); }
.bogenleiste a:hover:not([aria-current="page"]) { background: var(--tinte); color: var(--papier); }

@media (max-width: 47.99em) {
  .bogenleiste {
    position: fixed;
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    border-top: var(--strich-dick) solid var(--tinte);
    border-bottom: 0;
    padding-bottom: env(safe-area-inset-bottom);
  }
  body { padding-bottom: 3.6rem; }
  /* Unten am Daumen liegt die Leiste über dem Blatt, sie nimmt keinen Platz
     im Fluss – dafür verdeckt sie die untersten 3,6 rem. */
  :root { --kopfhoehe: calc(var(--kopf-absender) + 3.6rem); }
}

.blatt {
  flex: 1;
  width: 100%;
  max-width: var(--breite);
  margin: 0 auto;
  padding: 0 var(--rand);
}
.blatt-breit { max-width: none; }

/* Der Haftungsausschluss des Europäischen Parlaments. Er steht auf jedem
   Plakat im gleichen fetten Schnitt wie alles andere – genau so bleibt er. */
.haftung {
  border-top: var(--strich) solid var(--tinte);
  margin-top: var(--luft-5);
  padding: var(--luft-3) var(--rand) var(--luft-4);
  text-align: center;
  font-size: var(--t-winz);
  line-height: 1.35;
  text-transform: none;
}
.haftung p { margin: 0 auto; max-width: 46rem; }
.haftung .impressum { margin-top: var(--luft-2); }
.haftung .impressum a { text-decoration-thickness: 1px; }

/* Der Umschlag füllt das erste Fenster, so wie das Plakat die Litfaßsäule:
   Bildschirmhöhe minus alles, was darüber steht.

   Der Titel wird hier über die ZEILENHÖHE gesetzt, nicht über die Breite.
   Sonst gilt auf einem querformatigen Laptop entweder „von Kante zu Kante“
   oder „passt ins Fenster“, aber nie beides: das Plakat ist hochformatig,
   der Bildschirm nicht. `--hoehenbudget` ist der Platz geteilt durch die Zahl
   der Zeilen; daraus und aus --vmax ergibt sich die Breite des Titelblocks,
   und auf breiten Fenstern deckelt ihn die Seitenbreite – dann steht er
   wieder randbündig. */
.umschlag {
  /* Zwei Grenzen, die kleinere gewinnt:
     1. Wie viel Höhe im ersten Fenster übrig ist, geteilt durch die Zeilenzahl.
     2. Wie hoch eine Zeile sein darf, damit die breiteste noch auf die Seite
        passt – 100 % Breite geteilt durch deren Verhältnis von Breite zu Höhe
        (--vmax, kommt aus der Messung in build.mjs).
     Dadurch stehen ALLE Zeilen exakt gleich hoch, egal welche gerade an der
     Breite anschlägt. Genau das ging vorher schief. */
  --hoehenbudget: max(4.5rem, calc((100svh - var(--kopfhoehe) - 13.5rem) / 2));
  min-height: calc(100svh - var(--kopfhoehe));
  display: grid;
  grid-template-rows: 1fr auto auto;
  /* Notbremse: nichts auf dem Umschlag darf die Seite waagerecht aufziehen. */
  overflow-x: clip;
}
.umschlag > .riesenblock { align-self: center; padding-inline: var(--rand); }
/* Breiten stehen als Inline-Prozente an den Zeilen selbst (build.mjs). */
.umschlag .graffito { height: auto; }


/* Der Titelblock ist so breit wie seine breiteste Zeile. Begrenzt wird er
   allein über die Höhe, die im ersten Fenster noch frei ist: Zeilenhöhe mal
   Seitenverhältnis der breitesten Zeile (--vmax, steht als Inline-Wert am
   Element und kommt aus der Messung in build.mjs).

   Die Zeilen selbst tragen feste Prozentbreiten aus build.mjs. Es wird also
   nichts im Browser gerechnet, was schiefgehen könnte – gleiche Zeilenhöhe
   folgt aus der Geometrie, nicht aus einer Formel. */
.riesenblock .breit,
.riesenblock .schmal {
  max-width: calc(var(--hoehenbudget) * var(--vmax));
  flex-direction: column;
  /* Gleicher Abstand zwischen allen Zeilen. */
  gap: clamp(0.15rem, 0.7vw, 0.6rem);
}

@media (max-width: 47.99em) {
  /* Drei Zeilen statt zwei, dafür liegt unten die Leiste über dem Blatt. */
  /* Drei Titelzeilen plus die zwei Drittel hohe Zeile mit dem Gesprühten. */
  .umschlag { --hoehenbudget: max(3rem, calc((100svh - var(--kopfhoehe) - 9.5rem) / 3.75)); }
}

/* Auf breiten Schirmen läuft der Titel in einer Zeile, auf schmalen bricht
   er wie auf dem Betonplakat: REVO / LUTI / ON II. */
.riesenblock .schmal { display: none; }
.riesenblock .breit { display: flex; }
@media (max-width: 47.99em) {
  .riesenblock .schmal { display: flex; }
  .riesenblock .breit { display: none; }
}

/* 5 ── Satz ────────────────────────────────────────────────────────── */

h1, h2, h3, p, ul, ol, figure, blockquote { margin: 0; }

/* Die Riesenzeile. Als SVG gesetzt, damit sie wie auf dem Plakat exakt
   von Kante zu Kante läuft – die Buchstaben werden dabei nicht verzerrt,
   die Zeile skaliert als Ganzes. */
.riese {
  display: block;
  width: 100%;
  fill: currentColor;
  /* Big Shoulders ist 6 % leichter als die Plakatschrift. Bei Schriftgrad 100
     in der viewBox holt eine Kontur von 1 Einheit genau diese Differenz zurück,
     ohne die Buchstabenbreiten anzutasten. */
  stroke: currentColor;
  stroke-width: 1;
  paint-order: stroke fill;
}
.riese + .riese { margin-top: -0.04em; }

.riesenblock {
  display: block;
  padding: clamp(0.6rem, 2vw, 1.4rem) 0 clamp(0.7rem, 2.4vw, 1.6rem);
}
.riesenblock > svg { display: block; }
.riesenblock > svg + svg { margin-top: 0.5vw; }

/* Eine Zeile des Titels, die aus mehreren Teilen besteht: II neben dem
   gesprühten Motto, oder ON und II auseinandergezogen. Die Teile stehen auf
   einer Grundlinie, der Zwischenraum füllt den Rest der Zeilenbreite – so
   schließt die Zeile rechts bündig mit der ersten ab, ganz wie auf dem
   Betonplakat, wo zwischen ON und II eine ganze Versalhöhe Luft steht. */
.riesenblock .zeile {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: clamp(0.75rem, 3vw, 3rem);
  min-width: 0;
}
.riesenblock .zeile > svg { flex: 0 0 auto; }

/* Auf dem Telefon steht der Titel dreizeilig und füllt die Breite; neben LUTI
   bliebe für das Gesprühte nur ein Streifen von einem Sechstel der Seite.
   Statt es dort auf Briefmarkengröße zu quetschen, bekommt es eine eigene
   Zeile unter dem Titel – rechtsbündig, in der Höhe einer Titelzeile. */
.riesenblock .zeile-hand { display: none; }
@media (max-width: 47.99em) {
  .riesenblock .zeile-hand {
    display: flex;
    justify-content: flex-end;
    margin-top: 0.3rem;
  }
  /* Die Breite steht am Element selbst: gut zwei Drittel einer Titelzeile
     hoch – groß genug zum Lesen, klein genug fürs erste Fenster. */
}

/* Das Gesprühte gibt nach, bevor die Zeile über die Kante läuft. */
.riesenblock .zeile .graffito {
  flex: 0 1 auto;
  min-width: 0;
  object-fit: contain;
  object-position: right bottom;
}

/* Titelzeilen ohne SVG (Zwischenüberschriften) */
.titel {
  font-size: var(--t-gross);
  line-height: 0.88;
  text-transform: uppercase;
  margin: 0;
}
.zwischentitel {
  font-size: var(--t-mittel);
  line-height: 1;
  text-transform: uppercase;
  margin: var(--luft-5) 0 var(--luft-3);
  padding-bottom: var(--luft-1);
  border-bottom: var(--strich) solid var(--tinte);
}
.zwischentitel:first-child { margin-top: var(--luft-4); }

/* Kleinere Zwischenüberschrift innerhalb eines Abschnitts. */
.kleintitel {
  font-size: var(--t-klein);
  font-weight: 900;
  line-height: 1.1;
  text-transform: uppercase;
  margin: var(--luft-4) 0 var(--luft-2);
}

/* Aufzählung im Plakatton: kein Punkt, ein Strich. */
.strichliste {
  list-style: none;
  padding: 0;
  margin: 0;
  max-width: 44em;
}
.strichliste li {
  position: relative;
  padding-left: 1.4em;
  margin-bottom: 0.4em;
  line-height: 1.35;
}
.strichliste li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 0.9em;
  height: 3px;
  background: currentColor;
}
.strichliste b { font-weight: 900; }

/* Der Veranstaltungsblock: drei Zeilen, mittig, wie auf dem Plakat. */
.termin {
  text-align: center;
  text-transform: uppercase;
  line-height: 1.06;
  padding: var(--luft-2) 0 var(--luft-3);
}
.termin b { display: block; font-weight: 900; font-size: var(--t-termin); }
.termin span { display: block; font-size: var(--t-termin); }

/* Fließtext. Der einzige Ort, an dem das Plakat je einen Absatz hätte –
   kurze Zeilen, viel Durchschuss, damit die fette Schrift lesbar bleibt. */
.lauftext {
  max-width: 34em;
  font-size: var(--t-lauftext);
  line-height: 1.46;
}
.lauftext p + p { margin-top: 0.9em; }
.lauftext .stark {
  display: block;
  font-size: 1.28em;
  line-height: 1.16;
  text-transform: uppercase;
  margin-top: 0.7em;
}

.gross { font-size: var(--t-mittel); text-transform: uppercase; line-height: 1.1; }

/* Knopf: ein schwarzer Kasten, der beim Drücken kippt. */
.knopf {
  display: inline-block;
  background: var(--tinte);
  color: var(--papier);
  border: var(--strich) solid var(--tinte);
  padding: 0.5em 1.1em 0.45em;
  font-family: var(--schrift);
  font-weight: 900;
  font-size: var(--t-mittel);
  /* Zeilenhöhe 1 schneidet bei Big Shoulders die Versalien unten an. */
  line-height: 1.12;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.knopf:hover, .knopf:focus-visible { background: var(--papier); color: var(--tinte); }
.knopf[disabled] { opacity: 0.45; cursor: not-allowed; }
.knopf-leer { background: var(--papier); color: var(--tinte); }
.knopf-leer:hover, .knopf-leer:focus-visible { background: var(--tinte); color: var(--papier); }

.knopfreihe { display: flex; flex-wrap: wrap; gap: var(--luft-2); align-items: center; }

/* 6 ── Bausteine ───────────────────────────────────────────────────── */

/* Stempel: was noch nicht feststeht, wird gestempelt, nicht verschwiegen. */
.stempel {
  display: inline-block;
  border: var(--strich) solid var(--tinte);
  padding: 0.24em 0.6em 0.18em;
  font-size: var(--t-klein);
  line-height: 1.1;
  text-transform: uppercase;
  transform: rotate(-2.5deg);
}
.stempel-voll { background: var(--tinte); color: var(--papier); }

/* Laufband des Zustands: vorher, heute, vorbei. */
.lauf {
  border-top: var(--strich) solid var(--tinte);
  border-bottom: var(--strich) solid var(--tinte);
  text-align: center;
  text-transform: uppercase;
  font-size: var(--t-lauf);
  line-height: 1;
  padding: 0.5em var(--rand) 0.42em;
}
.lauf.jetzt { background: var(--tinte); color: var(--papier); }

/* Medaillon nach dem Porträtplakat: der Kreisausschnitt, ohne den Lorbeer –
   der bleibt dem Plakat vorbehalten. */
.medaillon {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
  border: var(--strich) solid var(--tinte);
  filter: grayscale(1) contrast(1.35);
  background: var(--druck-papier);
}
.medaillon img { width: 100%; height: 100%; object-fit: cover; }

/* Marquee-Rahmen nach Plakat 3: Lichtkasten mit Birnen, gerastert.
   Die Birnen sind echte Kreise auf einem gerasterten Band. */
.marquee {
  position: relative;
  padding: clamp(1.4rem, 5vw, 3rem);
  isolation: isolate;
}
.marquee::before {
  content: "";
  position: absolute;
  inset: 0;
  border: clamp(14px, 4.5vw, 34px) solid var(--tinte);
  border-radius: var(--rund-lichtkasten);
  z-index: -2;
}
.marquee::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--rund-lichtkasten);
  background:
    repeating-linear-gradient(to right, var(--papier) 0 12px, transparent 12px 40px) top / 100% clamp(14px, 4.5vw, 34px) no-repeat,
    repeating-linear-gradient(to right, var(--papier) 0 12px, transparent 12px 40px) bottom / 100% clamp(14px, 4.5vw, 34px) no-repeat,
    repeating-linear-gradient(to bottom, var(--papier) 0 12px, transparent 12px 40px) left / clamp(14px, 4.5vw, 34px) 100% no-repeat,
    repeating-linear-gradient(to bottom, var(--papier) 0 12px, transparent 12px 40px) right / clamp(14px, 4.5vw, 34px) 100% no-repeat;
  -webkit-mask: radial-gradient(circle at 50% 50%, #000 42%, transparent 43%) 0 0 / 26px 26px;
  mask: radial-gradient(circle at 50% 50%, #000 42%, transparent 43%) 0 0 / 26px 26px;
  z-index: -1;
  pointer-events: none;
}

/* Graffito: die einzige Handschrift auf den Plakaten. Keine Schriftart kann
   das nachmachen, also steht hier das Original – aus dem Betonplakat
   herausgeschnitten und so weit aufgehellt, dass vom Putz nur die Sprühspur
   übrig bleibt. Multiply blendet das restliche Weiß ins Papier; im Negativ
   wird invertiert und mit Screen aufgelegt. Der rechte Rand ist auf dem
   Plakat angeschnitten – das bleibt so. */
.graffito {
  display: block;
  width: clamp(6.5rem, 21vw, 15rem);
  height: auto;
  mix-blend-mode: multiply;
  /* Der letzte Rest Putzgrau muss auf reines Weiß, sonst zeichnet sich beim
     Multiplizieren der Rand des Ausschnitts als Kasten ab. */
  filter: brightness(1.12) contrast(1.15);
  transform: rotate(-1.5deg);
}
@media (prefers-color-scheme: dark) {
  .graffito { filter: brightness(1.12) contrast(1.15) invert(1); mix-blend-mode: screen; }
}

/* Der Aushang: die vier gedruckten Plakate. */
/* Die Anschlagwand. Die vier Plakate haengen als Papier davor – deshalb
   behalten sie ihre eigenen Farben, auch wenn die Seite im Negativ steht. */
.anschlagwand {
  background: var(--tinte);
  color: var(--papier);
  padding: var(--luft-4) var(--rand) var(--luft-5);
  margin-top: var(--luft-5);
}
.anschlagwand .zwischentitel {
  margin-top: 0;
  border-bottom-color: var(--papier);
}
.anschlagwand .lauftext { max-width: 38em; }

.aushang {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr));
  gap: clamp(0.75rem, 2.4vw, 1.75rem);
  margin: var(--luft-3) auto 0;
  max-width: 78rem;
}
.aushang figure { margin: 0; }
.aushang a {
  display: block;
  background: var(--druck-papier);
  color: var(--druck-tinte);
  text-decoration: none;
  box-shadow: 0 2px 0 rgba(0, 0, 0, 0.35);
}
.aushang a:hover, .aushang a:focus-visible { outline: var(--strich) solid var(--papier); outline-offset: 4px; }
.aushang img { width: 100%; }
.aushang figcaption {
  font-size: var(--t-klein);
  text-transform: uppercase;
  padding: 0.45em 0.6em 0.35em;
  border-top: var(--strich) solid var(--druck-tinte);
  line-height: 1.15;
}

/* Der Zwischenruf: einmal pro Seite darf das Plakat dazwischenschreien.
   Vollbreit, im Negativ, in der Lautstärke der Straße. */
.zwischenruf {
  background: var(--tinte);
  color: var(--papier);
  margin: var(--luft-5) 0;
  padding: clamp(1.5rem, 5vw, 3.5rem) var(--rand) clamp(1.2rem, 4vw, 2.6rem);
}
.zwischenruf .riese { fill: var(--papier); }
.zwischenruf .riese + .riese { margin-top: 0.6vw; }
.zwischenruf figcaption {
  margin-top: clamp(0.8rem, 2.5vw, 1.6rem);
  font-size: var(--t-klein);
  text-transform: uppercase;
  line-height: 1.2;
}

/* Der Aufruf: die einzige Handlung, die diese Seite verlangt. */
.aufruf {
  border-top: var(--strich-dick) solid var(--tinte);
  border-bottom: var(--strich-dick) solid var(--tinte);
  margin: var(--luft-5) 0;
  padding: var(--luft-3) 0;
}
.aufruf .gross { margin-bottom: var(--luft-2); }

/* Kleingedrucktes im Fließtext (Datenschutz, Lizenzen). Auf den Plakaten steht
   auch der Haftungsausschluss im selben fetten Schnitt – hier ebenso. */
.was-klein {
  font-size: var(--t-nebensatz);
  line-height: 1.5;
  max-width: 44em;
  margin-top: 1.2em;
}

/* Besetzung: die Gastgeber im Medaillon, darunter die offenen Plätze. */
.gastgeberreihe {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
  gap: var(--luft-4);
  margin-top: var(--luft-3);
}
.gastgeber { margin: 0; display: grid; grid-template-columns: minmax(5rem, 7.5rem) 1fr; gap: var(--luft-3); align-items: start; }
.gastgeber figcaption b {
  display: block;
  font-weight: 900;
  font-size: var(--t-mittel);
  line-height: 1;
  text-transform: uppercase;
  text-wrap: balance;
}
.gastgeber figcaption span {
  display: block;
  font-size: var(--t-klein);
  line-height: 1.2;
  margin-top: 0.35em;
  text-transform: uppercase;
}
.gastgeber figcaption p {
  font-size: var(--t-nebensatz);
  line-height: 1.45;
  margin-top: 0.7em;
}

.besetzungsliste { list-style: none; padding: 0; margin: var(--luft-3) 0 0; }
.besetzungsliste li {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4em var(--luft-3);
  align-items: baseline;
  justify-content: space-between;
  border-bottom: var(--strich) solid var(--tinte);
  padding: 0.55em 0 0.5em;
}
.besetzungsliste li:first-child { border-top: var(--strich) solid var(--tinte); }
.besetzungsliste .rolle { font-size: var(--t-mittel); line-height: 1; text-transform: uppercase; }
.besetzungsliste .platzhalter { font-size: var(--t-klein); text-transform: uppercase; opacity: 0.62; }

/* Der Programm-Reiter blinkt nicht, er kippt: am Abend steht er im Negativ. */
.bogenleiste a.laeuft-gerade:not([aria-current="page"]) {
  background: var(--tinte);
  color: var(--papier);
}

/* Im Dunkelmodus werden aus den schwarzen Feldern gerahmte Felder. Sonst
   leuchtet einem im Foyer mitten im Scrollen eine weiße Fläche entgegen –
   die Gliederung trägt dann der Rahmen, nicht die Füllung. */
@media (prefers-color-scheme: dark) {
  .zwischenruf,
  .anschlagwand {
    background: var(--papier);
    color: var(--tinte);
    border-top: var(--strich-dick) solid var(--tinte);
    border-bottom: var(--strich-dick) solid var(--tinte);
  }
  .zwischenruf .riese { fill: var(--tinte); }
  .anschlagwand .zwischentitel { border-bottom-color: var(--tinte); }
  .aushang a:hover, .aushang a:focus-visible { outline-color: var(--tinte); }
  .aushang a { box-shadow: none; }
}

/* 7 ── Programm ────────────────────────────────────────────────────── */

.programmkopf {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--luft-2);
  margin-top: var(--luft-4);
}

/* Der Filter ist die Antwort auf ein schmales Display. Im Raster ab 60em
   stehen ohnehin alle Räume nebeneinander – dort wäre er nur ein Knopf, der
   Löcher in den Stundenplan reißt. */
.raumfilter {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  margin: var(--luft-3) 0;
  border: var(--strich) solid var(--tinte);
}
.raumfilter button {
  flex: 1 1 auto;
  font-family: var(--schrift);
  font-size: var(--t-klein);
  text-transform: uppercase;
  line-height: 1;
  padding: 0.62em 0.7em 0.55em;
  background: var(--papier);
  color: var(--tinte);
  border: 0;
  border-right: var(--strich) solid var(--tinte);
  cursor: pointer;
}
.raumfilter button:last-child { border-right: 0; }
.raumfilter button[aria-pressed="true"] { background: var(--tinte); color: var(--papier); }

/* Zeitleiste: auf dem Telefon eine Liste nach Uhrzeit, ab Tablet ein Raster
   aus Zeit und Raum. Dieselben Elemente, nur anders gesetzt – die Stundenmarke
   ist in der Liste die Zwischenüberschrift und im Raster die linke Spalte. */
.zeitleiste { margin: var(--luft-3) 0 0; }

.zeitmarke {
  font-size: var(--t-mittel);
  font-weight: 900;
  line-height: 1;
  text-transform: uppercase;
  margin: var(--luft-4) 0 var(--luft-2);
  padding-top: var(--luft-1);
  border-top: var(--strich-dick) solid var(--tinte);
}
.zeitmarke:first-of-type { margin-top: var(--luft-3); }
.zeitmarke[hidden] { display: none; }

/* Die Spaltenköpfe gehören nur ins Raster; in der Liste sagt jeder
   Programmpunkt seinen Raum ohnehin selbst. */
.spaltenkopf { display: none; }
.spaltenkopf i { font-style: normal; opacity: 0.7; }

.punkt {
  display: block;
  border: var(--strich) solid var(--tinte);
  padding: 0.7rem 0.8rem 0.75rem;
  margin-bottom: var(--luft-2);
  background: var(--papier);
}
.punkt[hidden] { display: none; }
.punkt .kopfzeile {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5em;
  align-items: baseline;
  justify-content: space-between;
  font-size: var(--t-klein);
  text-transform: uppercase;
  line-height: 1.1;
}
.punkt .zeit { white-space: nowrap; }
.punkt .raum { border-bottom: 2px solid currentColor; }
.punkt h3 {
  font-weight: 900;
  font-size: var(--t-punkt);
  line-height: 1.02;
  text-transform: uppercase;
  margin: 0.3em 0 0;
}
.punkt .wer {
  font-size: var(--t-text);
  line-height: 1.2;
  margin-top: 0.25em;
}
.punkt .wer.offen { text-transform: uppercase; opacity: 0.66; }
.punkt .was {
  font-size: var(--t-nebensatz);
  line-height: 1.4;
  margin-top: 0.5em;
  max-width: 42em;
}
.punkt.laeuft {
  background: var(--tinte);
  color: var(--papier);
  border-color: var(--tinte);
}
/* 0,4 ergäbe 2,85:1 – nach 21 Uhr wäre der halbe Bogen unter der Grenze. */
.punkt.gewesen { opacity: 0.62; }

.jetztmarke {
  display: inline-block;
  font-size: var(--t-klein);
  text-transform: uppercase;
  border: 2px solid currentColor;
  padding: 0.1em 0.45em 0.05em;
  margin-left: 0.5em;
}

@media (min-width: 60em) {
  .raumfilter { display: none; }

  .zeitleiste.raster-ansicht {
    display: grid;
    grid-template-columns: 6.4rem repeat(var(--spalten, 4), 1fr);
    gap: 0;
    /* Rundum geschlossen: die Zellen zeichnen rechts und unten, der Rahmen
       oben und links – und rechts/unten noch einmal, damit die Kante auch
       dort steht, wo die letzte Spalte leer ausläuft. */
    border: var(--strich) solid var(--tinte);
  }
  .zeitleiste.raster-ansicht > * {
    border-right: var(--strich) solid var(--tinte);
    border-bottom: var(--strich) solid var(--tinte);
  }
  .zeitleiste.raster-ansicht .spaltenkopf {
    display: block;
    padding: 0.5rem 0.6rem;
    text-transform: uppercase;
    font-size: var(--t-klein);
    line-height: 1.1;
    position: sticky;
    top: 3.4rem;
    background: var(--papier);
    z-index: 5;
  }
  .zeitleiste.raster-ansicht .zeitmarke {
    margin: 0;
    padding: 0.5rem 0.6rem;
    white-space: nowrap;
    border-top: 0;
    font-size: var(--t-klein);
    text-transform: uppercase;
  }
  .zeitleiste.raster-ansicht .punkt {
    border: 0;
    margin: 0;
  }
  .zeitleiste.raster-ansicht .leerzelle { display: block; }
}

/* Leerzellen schließen das Raster: ohne sie stünden die Programmpunkte als
   einzelne Kästen im Nichts statt in einem Stundenplan. */
.leerzelle { display: none; }
.leerzelle[hidden] { display: none; }

.spaltenkopf .vorlaeufig {
  display: inline-block;
  border: 2px solid currentColor;
  padding: 0 0.3em;
  font-size: 0.8em;
  vertical-align: 0.1em;
}

/* 8 ── Fragezettel ─────────────────────────────────────────────────── */

.zettelfeld { max-width: 40rem; margin-top: var(--luft-3); }

.feld { display: block; margin-bottom: var(--luft-3); }
.feld > .marke {
  display: block;
  font-size: var(--t-klein);
  text-transform: uppercase;
  line-height: 1.1;
  margin-bottom: 0.3em;
}
.feld > .hinweis {
  display: block;
  font-size: var(--t-nebensatz);
  line-height: 1.35;
  margin-bottom: 0.45em;
  opacity: 0.75;
}

input[type="text"], textarea {
  width: 100%;
  font-family: var(--hand);
  font-size: 1.0625rem;
  line-height: 1.45;
  color: var(--tinte);
  background: var(--papier);
  border: var(--strich) solid var(--tinte);
  border-radius: 0;
  padding: 0.6rem 0.7rem;
  -webkit-appearance: none;
  appearance: none;
}
textarea { min-height: 8.5rem; resize: vertical; }
/* 0,5 ergäbe #808080 und damit nur 3,9:1 – zu wenig für Hilfetext im Feld. */
::placeholder { color: var(--tinte); opacity: 0.62; }

.wahl { display: flex; flex-wrap: wrap; border: var(--strich) solid var(--tinte); }
.wahl label {
  flex: 1 1 auto;
  position: relative;
  font-size: var(--t-klein);
  text-transform: uppercase;
  line-height: 1;
  padding: 0.62em 0.7em 0.55em;
  border-right: var(--strich) solid var(--tinte);
  cursor: pointer;
  text-align: center;
}
.wahl label:last-child { border-right: 0; }
.wahl input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.wahl label:has(input:checked) { background: var(--tinte); color: var(--papier); }
.wahl label:has(input:focus-visible) { outline: var(--strich) solid var(--tinte); outline-offset: 2px; }

.zaehlwerk { font-size: var(--t-klein); text-transform: uppercase; margin-top: 0.3em; }
.zaehlwerk.zuviel { background: var(--tinte); color: var(--papier); padding: 0 0.3em; }

/* Der Honigtopf. Menschen sehen ihn nicht, Maschinen füllen ihn aus. */
.honig {
  position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden;
}

.meldung {
  border: var(--strich) solid var(--tinte);
  padding: var(--luft-2) var(--luft-3);
  margin-top: var(--luft-3);
  font-size: var(--t-mittel);
  line-height: 1.15;
  text-transform: uppercase;
}
.meldung.schlecht { background: var(--tinte); color: var(--papier); }
.meldung[hidden] { display: none; }

/* Die Quittung steht im Lichtkasten vom Plakat „Shitshow Deutschland“:
   Wenn der Zettel angekommen ist, geht das Schild an. */
.quittung {
  margin-top: var(--luft-4);
  text-align: center;
}
.quittung .titel { margin-bottom: var(--luft-2); font-size: var(--t-gross); }
.quittung .lauftext { margin-inline: auto; }
.quittung .knopfreihe { justify-content: center; }

/* 9 ── Bewegung ────────────────────────────────────────────────────── */

/* Der eine gestaltete Moment: der Bogen wird umgeblättert. Kein Fade,
   kein Sliden – Papier klappt um seine Kante. */
@view-transition { navigation: auto; }

::view-transition-old(root) {
  animation: blatt-weg 0.26s cubic-bezier(0.22, 0.61, 0.36, 1) both;
  transform-origin: left center;
}
::view-transition-new(root) {
  animation: blatt-her 0.3s cubic-bezier(0.22, 0.61, 0.36, 1) both;
  transform-origin: left center;
}
@keyframes blatt-weg {
  to { transform: translateX(-1.2%); opacity: 0; }
}
@keyframes blatt-her {
  from { transform: translateX(1.6%); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .stempel, .graffito { transform: none; }
}

/* Druck: der Bogen soll sich ausdrucken lassen und im Foyer aushängen. */
@media print {
  :root { --tinte: #000; --papier: #fff; }
  .bogenleiste, .sprung, .raumfilter, .knopfreihe { display: none; }
  body { font-size: 11pt; padding-bottom: 0; }
  .punkt, .aushang a { break-inside: avoid; }
  .haftung { margin-top: 1.5rem; }
}
