/* Werkstatt - Oberflaeche.

   Vorgabe von Kevin: soll aussehen wie CONSTRUCT. Die Anmutung dort steckt
   nicht in der Farbe, sondern in der Bauweise: alles steht in Panels mit
   1px-Kante, Monospace durchgehend, kleine Schrift, wenig Luft zwischen den
   Zeilen, viel Information pro Flaeche. Danach ist hier gebaut.

   Die drei Regeln, an denen es kippt:

   1. Der Zeichenregen liegt HINTER der Buehne und ist ausserhalb von ihr
      sichtbar - nie hinter Text. Deshalb ist die Buehne deckend, hat feste
      Kanten und der Regen darf kraeftiger sein als vorher.
   2. Flaechen, auf denen Bilder liegen, bleiben ruhig und dunkel: kein
      Gruenstich, kein Overlay, kein Filter. Ein Foto bleibt ein Foto.
   3. Kein Kasten ohne Inhalt. Fehlt ein Bild, tritt ein Schild aus dem Titel
      an seine Stelle (.plakat) - keine leere Flaeche mit Schraffur. */

:root {
  /* Flaechen und Schrift - CONSTRUCT-Matrix, gemessene Kontraste im Kommentar */
  --grund: #000600;        /* CONSTRUCT --bg */
  --flaeche: #05120a;      /* Panelgrund, deckend */
  --flaeche-hoch: #0b1c11; /* eine Stufe heller: Kopf, aktive Zeilen */
  --rand: #16351f;         /* Deko-Trennlinien */
  --rand-stark: #00a82b;   /* CONSTRUCT --green-dim, 6.5:1 auf --grund (WCAG 1.4.11) */
  --schrift: #c8f5d4;      /* 17.0:1 - Fliesstext. Reines #00ff41 waere als
                              Textmasse zu grell, das bleibt der Signalfarbe. */
  --schrift-leise: #7dd398; /* CONSTRUCT --soft, 11.3:1 */
  --signal: #00ff41;       /* CONSTRUCT --green, 15.0:1 */
  --auf-signal: #001b06;   /* Schrift auf Signalflaeche, 13.3:1 */
  --gefahr: #ff5f57;       /* CONSTRUCT-Thema "blut", 6.9:1 auf --grund */

  /* rgba() kann keine Hex-Variable mit Deckkraft mischen - darum die Zahlen. */
  --signal-rgb: 0, 255, 65;

  /* Terminal heisst Monospace, auch im Fliesstext. Bewusst kein Webfont:
     die Werkstatt soll ohne Netz genauso aussehen. */
  --schriftfamilie: ui-monospace, "JetBrains Mono", "Fira Code", "DejaVu Sans Mono", Consolas, monospace;
  --mono: var(--schriftfamilie);

  /* Abstandsskala - jeder Abstand auf der Seite kommt aus dieser Liste */
  --r1: 0.25rem;
  --r2: 0.5rem;
  --r3: 0.75rem;
  --r4: 1rem;
  --r5: 1.5rem;
  --r6: 2rem;
  --r7: 3rem;
  --r8: 4.5rem;

  --buehne: 1180px;        /* die Flaeche, auf der alles steht */
  --lesebreite: 68ch;

  /* Damit Scrollbalken, Zahlenfeld-Pfeile, Dateidialog und aufgeklappte
     Selects vom Browser dunkel gezeichnet werden. */
  color-scheme: dark;
}

* { box-sizing: border-box; }

/* Der Grundton haengt am <html>, nicht am <body>: nur so liegt der
   Regen-Canvas (z-index:-1) sicher darueber statt darunter. */
html {
  background: var(--grund);
  color-scheme: dark;
  accent-color: var(--signal);
}

body {
  margin: 0;
  background: transparent;
  color: var(--schrift);
  font-family: var(--schriftfamilie);
  /* Kleiner als der Browser-Standard: Monospace baut breiter, und die Dichte
     ist genau das, was die Terminal-Anmutung ausmacht. */
  font-size: 0.95rem;
  line-height: 1.5;
  -webkit-text-size-adjust: 100%;
  /* Kein eingetippter Text sprengt die Flaeche, in der er steht - auch nicht
     ein aus Versehen eingefuegter Block ohne ein einziges Leerzeichen. */
  overflow-wrap: break-word;
}

/* Titel stehen in Flex- und Rasterzellen: dort reicht break-word nicht, weil
   die Zelle sonst so breit wird wie das laengste Wort. anywhere laesst sie
   schrumpfen. */
.kachel__titel,
.kachel__material,
.werkliste__titel,
.stueck__titel,
.werk__titel,
.werk__material,
.medium__name,
.rueckfrage__titel,
.brotkrume__hier { overflow-wrap: anywhere; }

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

a { color: var(--signal); }
a:hover { text-decoration: none; }

h1, h2, h3 { line-height: 1.2; text-wrap: balance; }

h1 { text-shadow: 0 0 12px rgba(var(--signal-rgb), 0.25); }

/* Sichtbarer Fokus auf allem Bedienbaren. Der Versatz laesst den dunklen
   Grund durchscheinen, dadurch traegt der Ring auch auf hellen Bildern. */
:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

/* Auf gruener Flaeche waere ein gruener Ring unsichtbar. */
.knopf--haupt:focus-visible,
.sprungmarke:focus-visible {
  outline-color: var(--schrift);
}

/* --- Buehne ---------------------------------------------------------------
   Der deckende Streifen in der Mitte, auf dem die ganze Seite steht. Er ist
   der Grund, warum der Regen nie hinter Text geraet: daneben laeuft er, hier
   drin nicht. Die Kanten sind sichtbar - sie machen aus dem Effekt Absicht. */

.buehne {
  max-width: var(--buehne);
  min-height: 100vh;
  margin: 0 auto;
  background: var(--grund);
  border-left: 1px solid var(--rand);
  border-right: 1px solid var(--rand);
  /* Trennt Buehne und Regen auch dort, wo der Rand auf dunklen Regen trifft. */
  box-shadow: 0 0 40px rgba(0, 0, 0, 0.9);
  position: relative;
  z-index: 1;
  /* Kopf, Inhalt, Fuss untereinander; der Inhalt nimmt den Rest. Sonst
     haengt der Fuss auf kurzen Seiten (ein Musikstueck mit nur einem
     Notenblatt, die Fehlerseite) in der Mitte der Buehne. */
  display: flex;
  flex-direction: column;
}

.inhalt { flex: 1 0 auto; }

/* --- Zeichenregen ---------------------------------------------------------
   Deko und sonst nichts: hinter allem, ohne Klicks zu fangen, und nur in den
   Raendern neben der Buehne zu sehen. Der Umschalter sitzt im Kopf, der Wunsch
   haengt als Attribut am <html> - dort ueberlebt er den Seitenwechsel ohne
   Neuladen. Das Canvas steht ausserhalb von <main> und wird nie angefasst,
   der Regen laeuft also durch wie die Musik. */

.regen {
  position: fixed;
  inset: 0;
  width: 100%;   /* ein <canvas> nimmt sonst seine Bitmapgroesse, nicht inset */
  height: 100%;
  z-index: 0;
  /* Kraeftiger als vorher (0.07): er liegt jetzt nachweislich neben dem Text
     statt dahinter, also darf man ihn auch sehen. */
  opacity: 0.5;
  pointer-events: none;
  /* Nach oben und unten ausblenden, damit der Streifen nicht wie ein
     abgeschnittenes Video endet. */
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent);
}

html[data-regen="aus"] .regen { display: none; }

/* Ist kein Rand mehr da, waere der Regen komplett von der Buehne verdeckt -
   dann kostet er nur Rechenzeit. */
@media (max-width: 1240px) {
  .regen { display: none; }
}

/* Nur mit JS sichtbar: ein Umschalter ohne Wirkung waere schlimmer als keiner. */
.regenschalter[hidden] { display: none; }

.regenschalter {
  font: inherit;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  padding: var(--r1) var(--r2);
  min-height: 1.75rem;   /* Inline-Bedienelement im Kopf, Ziel bleibt >= 24px */
  display: inline-flex;
  align-items: center;
  gap: var(--r2);
  background: transparent;
  border: 1px solid var(--rand-stark);   /* 6.5:1, siehe WCAG 1.4.11 */
  color: var(--schrift-leise);
  cursor: pointer;
  transition: color 140ms ease, border-color 140ms ease, background-color 140ms ease;
}

.regenschalter:hover {
  border-color: var(--signal);
  color: var(--schrift);
  background: rgba(var(--signal-rgb), 0.07);
}

/* Zustand nicht allein an der Farbe (WCAG 1.4.1): der Punkt wechselt die
   Form mit, ausgefuellt heisst an, hohl heisst aus. */
.regenschalter__punkt { color: var(--signal); font-size: 0.6em; }
.regenschalter__punkt::before { content: "\25CF"; }
html[data-regen="aus"] .regenschalter__punkt { color: var(--schrift-leise); }
html[data-regen="aus"] .regenschalter__punkt::before { content: "\25CB"; }

/* Nur fuer Screenreader */
.nur-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Sprungmarke: erstes fokussierbares Element, sichtbar sobald fokussiert. */
.sprungmarke {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 30;
  padding: var(--r3) var(--r4);
  background: var(--signal);
  color: var(--auf-signal);
  font-weight: 600;
  text-decoration: none;
}

.sprungmarke:not(:focus) {
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- Kopf und Fuss --------------------------------------------------------
   Der Kopf ist eine Terminalleiste: schmal, deckend, klebt oben. */

.kopf {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--r4);
  flex-wrap: wrap;
  padding: var(--r2) var(--r5);
  background: var(--flaeche-hoch);
  border-bottom: 1px solid var(--rand-stark);
}

/* Der Prompt macht aus der Marke eine Eingabezeile, ohne dass im HTML ein
   Zeichen ohne Bedeutung steht. Die Leer-Alternative nach dem Schraegstrich
   haelt das ">" aus der Vorlesereihenfolge heraus. */
.kopf__marke {
  font-weight: 700;
  font-size: 0.9rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--signal);
  text-shadow: 0 0 10px rgba(var(--signal-rgb), 0.35);
  padding: var(--r1) 0;
}

.kopf__marke::before {
  content: "> " / "";
  color: var(--rand-stark);
}

.kopf__marke:hover { text-decoration: underline; text-underline-offset: 4px; }

.kopf__werkzeuge,
.kopf__navigation {
  display: flex;
  align-items: center;
  gap: var(--r3);
  flex-wrap: wrap;
}

.kopf__link {
  color: var(--schrift);
  text-decoration: none;
  font-size: 0.8rem;
  letter-spacing: 0.04em;
  padding: var(--r1) var(--r2);
  border: 1px solid transparent;
}

.kopf__link:hover { color: var(--signal); border-color: var(--rand-stark); }

.kopf__abmelden { margin: 0; }

.inhalt {
  padding: var(--r6) var(--r5) var(--r8);
  outline: none; /* Ziel der Sprungmarke, aber kein eigener Fokusring */
}

.fuss {
  display: flex;
  justify-content: space-between;
  gap: var(--r4);
  flex-wrap: wrap;
  padding: var(--r3) var(--r5);
  border-top: 1px solid var(--rand);
  background: var(--flaeche);
  color: var(--schrift-leise);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
}

.fuss__zeile,
.fuss__ort { margin: 0; }

/* Der Prompt auch am Fuss - schliesst die Seite, wie der Kopf sie aufmacht.
   Leer-Alternative, damit der Screenreader das Zeichen nicht mitliest. */
.fuss__zeile::before {
  content: "$ " / "";
  color: var(--rand-stark);
}

.fuss__ort { opacity: 0.7; }

/* --- Startseite: Kopfbereich ---------------------------------------------- */

.einleitung {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--r5);
  margin: 0 0 var(--r5);
  padding-bottom: var(--r4);
  border-bottom: 1px solid var(--rand);
}

.einleitung__pfad {
  margin: 0 0 var(--r2);
  font-size: 0.75rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--rand-stark);
}

.einleitung__titel {
  margin: 0 0 var(--r2);
  font-size: clamp(1.8rem, 4vw, 2.4rem);
  letter-spacing: 0.02em;
}

.einleitung__text {
  margin: 0;
  max-width: var(--lesebreite);
  color: var(--schrift-leise);
}

/* Bestandskasten - sagt in drei Zeilen, was hier liegt, und haelt zugleich
   die rechte Haelfte des Kopfes besetzt. */
.bestand {
  margin: 0;
  min-width: 13rem;
  border: 1px solid var(--rand);
  background: var(--flaeche);
}

.bestand__posten {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--r4);
  padding: var(--r2) var(--r3);
}

.bestand__posten + .bestand__posten { border-top: 1px solid var(--rand); }

.bestand__zahl {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--signal);
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

.bestand__label {
  margin: 0;
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--schrift-leise);
}

.bestand__posten--leise .bestand__zahl { font-size: 0.8rem; font-weight: 400; }

/* --- Filterleiste --------------------------------------------------------- */

.typfilter {
  display: flex;
  gap: var(--r2);
  margin: 0 0 var(--r6);
  flex-wrap: wrap;
}

/* Rand statt nur Farbe, damit "aktiv" nicht allein an der Farbe haengt
   (WCAG 1.4.1). Padding sorgt zugleich fuer >= 24px Zielgroesse (2.5.8). */
.typfilter__eintrag {
  text-decoration: none;
  color: var(--schrift-leise);
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: var(--r2) var(--r3);
  min-height: 1.9rem;
  display: inline-flex;
  align-items: center;
  /* --rand waere hier zu schwach: der Kasten weist den Filtereintrag als
     bedienbar aus, und der braucht 3:1 (WCAG 1.4.11). */
  border: 1px solid var(--rand-stark);
  background: var(--flaeche);
  transition: color 120ms ease, border-color 120ms ease, background-color 120ms ease;
}

.typfilter__eintrag:hover {
  color: var(--signal);
  background: rgba(var(--signal-rgb), 0.08);
}

.typfilter__eintrag--aktiv,
.typfilter__eintrag--aktiv:hover {
  color: var(--auf-signal);
  border-color: var(--signal);
  background: var(--signal);
  font-weight: 700;
}

/* --- Sparten -------------------------------------------------------------- */

.sparte { margin: 0 0 var(--r7); }

.sparte__titel {
  display: flex;
  align-items: center;
  gap: var(--r2);
  margin: 0 0 var(--r4);
  padding-bottom: var(--r2);
  border-bottom: 1px solid var(--rand);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--schrift);
}

.sparte__marke { color: var(--rand-stark); }

.sparte__zahl {
  margin-left: auto;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  color: var(--schrift-leise);
  border: 1px solid var(--rand);
  padding: 0 var(--r2);
}

/* --- Kachelwand ----------------------------------------------------------- */

.kachelwand {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* min() haelt die Wand bei 320px Breite und bei 200% Zoom einspaltig. */
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
  gap: var(--r4);
}

.kachel { min-width: 0; }

/* Ein oder zwei Werke in einer Sparte - bei 3D-Druck ist das auf absehbare
   Zeit der Normalfall - lassen im Dreierraster eine halbe Reihe leer stehen.
   Das sieht nach abgebrochen aus, nicht nach wenig. Deshalb legen sich die
   Kacheln dann quer und nehmen die volle Breite: Bild links, Text rechts,
   untereinander wie ein Regal. Ab drei setzt das Template die Klasse nicht
   mehr und das Raster greift wieder. */
.kachelwand--quer { grid-template-columns: minmax(0, 1fr); }

.kachelwand--quer .kachel__link {
  flex-direction: row;
  align-items: stretch;
}

.kachelwand--quer .kachel__bild {
  flex: 0 0 34%;
  display: flex;
}

/* Hoehe kommt aus der Kachel, nicht aus dem Bild: sonst bestimmt das
   Seitenverhaeltnis der Datei, wie hoch die Zeile wird, und zwei Eintraege
   nebeneinander haben zwei verschiedene Hoehen. Ausschnitt oben, weil Kevins
   Renderings ihre Beschriftung am oberen Rand tragen. */
.kachelwand--quer .kachel__foto,
.kachelwand--quer .plakat {
  aspect-ratio: auto;
  width: 100%;
  height: 100%;
  min-height: 13rem;
  object-position: 50% 0;
  border-bottom: 0;
  border-right: 1px solid var(--rand);
}

.kachelwand--quer .kachel__text {
  justify-content: center;
  padding: var(--r4) var(--r5);
}

/* Im Raster hat die Kachel dafuer keinen Platz - dort wuerde der Anriss die
   Kachel in die Laenge ziehen und die Wand aus dem Takt bringen. */
.kachel__anriss { display: none; }

.kachelwand--quer .kachel__anriss {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  margin: var(--r3) 0 0;
  max-width: var(--lesebreite);
  color: var(--schrift);
  font-size: 0.85rem;
  line-height: 1.55;
}

/* Der Schein liegt als box-shadow AUSSEN am Rand - bewusst kein inset und
   kein Overlay: sonst bekaeme das Titelbild bei jedem Ueberfahren einen
   Gruenstich. Die Kachel darf leuchten, das Foto nicht. */
.kachel__link {
  display: flex;
  flex-direction: column;
  height: 100%;
  text-decoration: none;
  color: inherit;
  background: var(--flaeche);
  border: 1px solid var(--rand);
  transition: border-color 140ms ease, box-shadow 140ms ease, background-color 140ms ease;
}

.kachel__link:hover,
.kachel__link:focus-visible {
  border-color: var(--signal);
  background: var(--flaeche-hoch);
  box-shadow: 0 0 14px rgba(var(--signal-rgb), 0.18);
}

.kachel__link:hover .kachel__titel { color: var(--signal); }

.kachel__bild { margin: 0; }

/* cover statt contain: Letterbox-Balken um jedes Bild lassen die Wand
   ausfransen. Der Ausschnitt sitzt oben - Kevins Renderings und Screenshots
   tragen ihre Beschriftung am oberen Rand. */
.kachel__foto {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  object-position: 50% 20%;
  background: var(--grund);
  border-bottom: 1px solid var(--rand);
}

/* Hochkant-Bilder sind Motive, keine Screenshots (CrazyFamily, 9:16): der
   Ausschnitt sitzt in der Mitte, sonst zeigt die Kachel nur die Zimmerdecke.
   Das Merkmal setzt werkstatt.js, sobald es die Bildmasse kennt. */
.kachel__foto[data-hochkant],
.kachelwand--quer .kachel__foto[data-hochkant] { object-position: 50% 45%; }

.kachel__text {
  padding: var(--r3) var(--r4) var(--r4);
  display: flex;
  flex-direction: column;
  gap: var(--r1);
  flex: 1;
}

/* Kein Glimmen: als Ueberschrift zwar ein h3, in der Wirkung aber ein
   Listeneintrag - zwanzigmal untereinander wuerde es flimmern. */
.kachel__titel {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.01em;
  text-shadow: none;
  transition: color 140ms ease;
  /* Drei Zeilen reichen fuer jeden echten Titel. Was laenger ist, war ein
     Versehen und darf die Kachelwand nicht auseinanderziehen. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}

.kachel__zeile {
  margin: 0;
  display: flex;
  gap: var(--r2);
  color: var(--schrift-leise);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.kachel__zeile > * + *::before {
  content: "·";
  margin-right: var(--r2);
}

/* Die Materialzeile macht aus einer Kachel mit zwei Wortpaaren einen Eintrag,
   den man auch ohne Klick einordnen kann. Zwei Zeilen, dann Schluss. */
.kachel__material {
  margin: var(--r1) 0 0;
  color: var(--schrift-leise);
  font-size: 0.78rem;
  line-height: 1.45;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

/* --- Das Schild, wenn kein Bild da ist ------------------------------------
   PairPay, Memorium und Lerndex haben keins und bekommen auch keins. Statt
   einer leeren Flaeche steht hier ein Schild aus dem Titel: Initial gross,
   Name gesperrt darunter, feines Raster dahinter. */

.plakat {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--r2);
  aspect-ratio: 16 / 10;
  padding: var(--r4);
  border-bottom: 1px solid var(--rand);
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(var(--signal-rgb), 0.09), transparent 70%),
    repeating-linear-gradient(0deg, transparent 0 15px, rgba(var(--signal-rgb), 0.055) 15px 16px),
    repeating-linear-gradient(90deg, transparent 0 15px, rgba(var(--signal-rgb), 0.055) 15px 16px),
    var(--grund);
  overflow: hidden;
}

/* Bewusst ohne Kasten: die Kachel hat schon einen Rand, ein zweiter darin
   sieht nach Platzhalter aus. Der Buchstabe traegt allein. */
.plakat__initial {
  font-size: clamp(3rem, 9vw, 4.5rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--signal);
  text-shadow: 0 0 26px rgba(var(--signal-rgb), 0.5);
}

/* Dieselbe Idee im Kleinformat: als Miniatur in der Stueckliste. */
.plakat--klein {
  aspect-ratio: 1;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 1px solid var(--rand);
}

.plakat--klein .plakat__initial {
  font-size: 1.1rem;
  text-shadow: 0 0 12px rgba(var(--signal-rgb), 0.5);
}

/* Im Miniaturformat der Werkstattliste - gleiche Masse wie .werkliste__foto,
   damit die Zeilen dieselbe Kante haben. */
.plakat--liste {
  width: 128px;
  height: 80px;
  aspect-ratio: auto;
  flex: 0 0 auto;
  padding: 0;
  border: 1px solid var(--rand);
}

.plakat--liste .plakat__initial {
  font-size: 1.6rem;
  text-shadow: 0 0 14px rgba(var(--signal-rgb), 0.45);
}

.plakat__wort {
  font-size: 0.72rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--schrift-leise);
  text-align: center;
  max-width: 100%;
  overflow-wrap: anywhere;
  /* Sonst druecken ueberlange Titel das Schild in die Hoehe und reissen die
     ganze Kachelreihe mit - das Seitenverhaeltnis waere hin. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
}

/* --- Musik: eine Liste, keine Kachelwand ---------------------------------- */

.stuecke {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: stueck;
  border: 1px solid var(--rand);
  background: var(--flaeche);
}

.stueck {
  counter-increment: stueck;
  display: grid;
  /* Nummer, Bild, Knopf, Titel, Marken, Dauer */
  grid-template-columns: auto auto auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: var(--r3) var(--r4);
  padding: var(--r3) var(--r4);
  transition: background-color 140ms ease;
}

.stueck + .stueck { border-top: 1px solid var(--rand); }

.stueck:hover { background: var(--flaeche-hoch); }

/* Die Nummer steht als erste Spalte - ohne JS ist der Spielknopf nicht da,
   und die Liste soll trotzdem eine Liste bleiben. */
.stueck::before {
  content: counter(stueck, decimal-leading-zero);
  font-size: 0.8rem;
  color: var(--rand-stark);
  font-variant-numeric: tabular-nums;
}

/* Das Bild ist hier Beiwerk, nicht Hauptsache: quadratisch, klein, damit die
   Zeile eine Zeile bleibt. */
.stueck__bild {
  grid-column: 2;
  margin: 0;
  width: 3.25rem;
  height: 3.25rem;
}

.stueck__foto {
  width: 100%;
  height: 100%;
  object-fit: cover;
  background: var(--grund);
  border: 1px solid var(--rand);
}

.stueck__spielen {
  grid-column: 3;
  width: 2.5rem;
  height: 2.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  font: inherit;
  border: 1px solid var(--rand-stark);
  background: transparent;
  color: var(--signal);
  cursor: pointer;
  transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease;
}

.stueck__spielen[hidden] { display: none; }

.stueck__spielen:hover {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--auf-signal);
}

.stueck__symbol { font-size: 0.85rem; line-height: 1; }

/* Die grosse Ausfuehrung: nur auf der Musikseite, wo die Liste allein steht. */
.stuecke--gross .stueck { padding: var(--r4) var(--r5); gap: var(--r3) var(--r5); }
.stuecke--gross .stueck__bild { width: 4.5rem; height: 4.5rem; }
.stuecke--gross .stueck__titel { font-size: 1.15rem; }
.stuecke--gross .stueck__dauer { font-size: 1rem; }
.stuecke--gross .plakat--klein .plakat__initial { font-size: 1.6rem; }

/* Laeuft dieses Stueck gerade, ist das an der Zeile zu sehen - nicht nur am
   Abspieler unten. */
.stueck.medium--aktiv { background: var(--flaeche-hoch); }
.stueck.medium--aktiv .stueck__spielen {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--auf-signal);
}
.stueck.medium--aktiv .stueck__titel { color: var(--signal); }

.stueck__text { grid-column: 4; min-width: 0; }

/* Stehen spielbare und stumme Stuecke (nur Noten) in einer Liste, sitzt bei
   den stummen kein Knopf in Spalte 3 - der Titel ruckte nach links. Sobald
   irgendwo ein Knopf sichtbar ist, bekommen die stummen Zeilen seinen Platz. */
.stuecke:has(.stueck__spielen:not([hidden])) .stueck:not(.stueck--spielbar) .stueck__text {
  padding-left: 2.5rem;   /* Knopfbreite; die beiden Spaltenluecken sind ohnehin da */
}

.stueck__titel {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  text-shadow: none;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

.stueck__link { color: inherit; text-decoration: none; }
.stueck__link:hover { color: var(--signal); text-decoration: underline; text-underline-offset: 3px; }

.stueck__meta {
  margin: var(--r1) 0 0;
  color: var(--schrift-leise);
  font-size: 0.78rem;
  line-height: 1.4;
}

.stueck__marken {
  grid-column: 5;
  margin: 0;
  display: flex;
  align-items: center;
  gap: var(--r3);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--schrift-leise);
}

.marke {
  border: 1px solid var(--rand-stark);
  padding: 0 var(--r2);
  color: var(--schrift-leise);
}

.stueck__dauer {
  grid-column: 6;
  margin: 0;
  font-size: 0.85rem;
  color: var(--schrift-leise);
  font-variant-numeric: tabular-nums;
}

/* --- Leerzustand der ganzen Seite ----------------------------------------- */

.leerzustand {
  border: 1px dashed var(--rand-stark);
  background: var(--flaeche);
  padding: var(--r7) var(--r5);
  text-align: center;
}

.leerzustand__zeichen {
  margin: 0 0 var(--r3);
  font-size: 2.5rem;
  letter-spacing: 0.2em;
  color: var(--rand-stark);
  line-height: 1;
}

.leerzustand__titel { margin: 0 0 var(--r2); font-size: 1.2rem; }

.leerzustand__text {
  margin: 0 auto;
  max-width: 42ch;
  color: var(--schrift-leise);
}

/* --- Werk-Detail ---------------------------------------------------------- */

.brotkrume {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--r2);
  margin: 0 0 var(--r4);
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--schrift-leise);
}

.brotkrume__link { color: var(--schrift-leise); text-decoration: none; }
.brotkrume__link:hover { color: var(--signal); text-decoration: underline; text-underline-offset: 3px; }
.brotkrume__trenner { color: var(--rand-stark); }
/* Eine Zeile, dann Schluss: der Titel steht gleich darunter gross - in der
   Krume ist er nur die Ortsangabe. */
.brotkrume__hier {
  color: var(--schrift);
  min-width: 0;
  max-height: 1.5em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.werk__kopf {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--r5);
  align-items: start;
  margin: 0 0 var(--r6);
  padding-bottom: var(--r5);
  border-bottom: 1px solid var(--rand);
}

.werk__titelblock { max-width: var(--lesebreite); }

.werk__einordnung {
  margin: 0 0 var(--r2);
  display: flex;
  gap: var(--r2);
  color: var(--schrift-leise);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.werk__einordnung > * + *::before {
  content: "·";
  margin-right: var(--r2);
}

.werk__titel {
  margin: 0;
  font-size: clamp(1.7rem, 4vw, 2.4rem);
  letter-spacing: 0.01em;
}

/* Der Signalstrich macht die Materialzeile zum eigenen Element, ohne dass sie
   sich wie ein Kasten aufdraengt. Signal auf --grund: 6.0:1 - lesbar. Deshalb
   ausdruecklich KEINE Flaeche darunter: auf --flaeche waeren es nur 3.0:1. */
.werk__material {
  margin: var(--r4) 0 0;
  padding: var(--r1) 0 var(--r1) var(--r3);
  border-left: 2px solid var(--signal);
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--signal);
}

/* Steckbrief rechts im Kopf: haelt die Zeile besetzt, wenn der Text kurz ist. */
.werk__fakten {
  margin: 0;
  min-width: 12rem;
  border: 1px solid var(--rand);
  background: var(--flaeche);
}

.werk__faktum {
  display: flex;
  justify-content: space-between;
  gap: var(--r4);
  padding: var(--r2) var(--r3);
  font-size: 0.75rem;
}

.werk__faktum + .werk__faktum { border-top: 1px solid var(--rand); }

.werk__faktum-name {
  margin: 0;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--schrift-leise);
}

.werk__faktum-wert { margin: 0; color: var(--schrift); font-weight: 700; }

.werk__beschreibung {
  max-width: var(--lesebreite);
  margin: 0 0 var(--r6);
  font-size: 1rem;
  line-height: 1.65;
}

.werk__beschreibung p { margin: 0 0 var(--r4); }
.werk__beschreibung p:last-child { margin-bottom: 0; }

.werk__abschnitt {
  margin: 0 0 var(--r3);
  padding-bottom: var(--r2);
  border-bottom: 1px solid var(--rand);
  font-size: 0.8rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--schrift-leise);
}

/* --- Medien --------------------------------------------------------------- */

.medien { margin: 0 0 var(--r6); }

.medium { margin: 0 0 var(--r5); }

/* Die Buehne deckelt die Hoehe: ein 9:16-Video auf Spaltenbreite waere sonst
   eine Bildschirmhoehe schwarze Flaeche. Der Rahmen macht aus dem Rest der
   Zeile eine Fassung statt eines Lochs. */
.medium__buehne {
  display: flex;
  justify-content: center;
  align-items: center;
  /* Gedeckelt: neben einem 9:16-Video wuerde die Fassung sonst mehr Flaeche
     einnehmen als das Bild selbst. */
  max-width: 860px;
  /* Feste Hoehe: das Standbild (poster) ist querformat, das Video hochformat.
     Ohne sie wuerde die Seite in dem Moment springen, in dem der Browser die
     Videomasse kennt. */
  min-height: min(66vh, 620px);
  padding: var(--r4);
  border: 1px solid var(--rand);
  background:
    repeating-linear-gradient(90deg, transparent 0 15px, rgba(var(--signal-rgb), 0.04) 15px 16px),
    var(--grund);
}

.medium__video {
  display: block;
  max-height: min(66vh, 620px);
  max-width: 100%;
  width: auto;
  background: #000;
  border: 1px solid var(--rand);
}

.medium__audio { width: 100%; }

.medium__rahmen {
  position: relative;
  aspect-ratio: 16 / 9;
  border: 1px solid var(--rand);
  background: var(--grund);
}

.medium__einbettung {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.medium__unterschrift {
  display: flex;
  align-items: center;
  gap: var(--r3);
  flex-wrap: wrap;
  margin-top: var(--r2);
  font-size: 0.8rem;
  color: var(--schrift-leise);
}

.medium__name { color: var(--schrift); font-weight: 700; }

.medium__dauer { font-variant-numeric: tabular-nums; }

.medium__dauer::before { content: "· "; color: var(--rand-stark); }

.medium__uebernehmen { margin-left: auto; }

.medium--aktiv .medium__name { color: var(--signal); }

/* --- Bildergalerie -------------------------------------------------------- */

/* Zwei Spalten, sobald der Platz reicht: ein einzelnes Bild bekommt die
   ganze Breite, zwanzig Bilder werden nicht zur Endlosrolle. Die Breite ist
   gedeckelt - ein heller Screenshot ueber 1180px ist auf schwarzem Grund ein
   Scheinwerfer. */
.galerie {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
  align-items: start;
  gap: var(--r4);
  max-width: 1000px;
  margin: 0 0 var(--r6);
}

/* Auf der Musikseite fluchtet der Bilderteil mit der Videobuehne darueber -
   sonst steht das eine verbliebene Standbild breiter da als das Video, zu dem
   es gehoert. */
.werk--musik .werk__bilder,
.werk--musik .galerie { max-width: 860px; }

.galerie__bild { margin: 0; }

/* Ruhigste Flaeche der Seite: hier liegen die Fotos. Kein Schein, kein
   Filter - nur ein Rand und Dunkelheit dahinter. */
.galerie__foto {
  width: 100%;
  background: var(--grund);
  border: 1px solid var(--rand);
}

.galerie__unterschrift {
  margin-top: var(--r2);
  max-width: var(--lesebreite);
  color: var(--schrift-leise);
  font-size: 0.78rem;
}

/* --- Dokumente: Noten, Texte, Blaetter -------------------------------------
   Eine Zeile je Datei im selben Panel wie die Stueckliste: Kuerzel links,
   Titel und Groesse, rechts der Hinweis. Die ganze Zeile ist der Link
   (::after ueber der Zeile), der Fokusring sitzt auf dem Titel. */

.werk__dokumente { margin: 0 0 var(--r6); max-width: var(--lesebreite); }

.dokumente {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--rand);
  background: var(--flaeche);
}

.dokument { transition: background-color 140ms ease; }

.dokument + .dokument { border-top: 1px solid var(--rand); }

.dokument:hover { background: var(--flaeche-hoch); }

.dokument__zeile {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--r4);
  padding: var(--r3) var(--r4);
}

.dokument__art {
  width: 3.25rem;
  height: 3.25rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--rand-stark);
  background: var(--grund);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--signal);
}

.dokument__text { min-width: 0; display: grid; gap: var(--r1); }

.dokument__link {
  font-weight: 700;
  color: var(--schrift);
  text-decoration: none;
  overflow-wrap: anywhere;
}

.dokument__link:hover { color: var(--signal); text-decoration: underline; text-underline-offset: 3px; }

.dokument__meta { font-size: 0.78rem; color: var(--schrift-leise); }

.dokument__aktionen { display: flex; gap: var(--r2); white-space: nowrap; }

/* Aufgeklappte Anzeige: der Browser rendert die PDF selbst. Hoch genug fuer
   eine ganze Notenseite, aber nie hoeher als der Bildschirm. */
.dokument__ansicht {
  padding: 0 var(--r4) var(--r4);
}

.dokument__rahmen {
  display: block;
  width: 100%;
  height: min(80vh, 1100px);
  border: 1px solid var(--rand-stark);
  background: #fff;   /* PDF-Seiten sind weiss; ohne Grund blitzt beim Laden Schwarz */
}

/* --- Links und Zurueck ---------------------------------------------------- */

.werk__links { margin: 0 0 var(--r6); max-width: var(--lesebreite); }

.linkliste { list-style: none; margin: 0; padding: 0; }
.linkliste__eintrag { margin-bottom: var(--r2); }

.linkliste__link { font-size: 0.9rem; }

.linkliste__link::before { content: "→ "; color: var(--rand-stark); }

.zurueck { font-size: 0.85rem; }

.werk__zurueck {
  margin: 0;
  padding-top: var(--r4);
  border-top: 1px solid var(--rand);
}

/* --- Formulare ------------------------------------------------------------ */

.formular { max-width: 46rem; }

.feld {
  display: flex;
  flex-direction: column;
  gap: var(--r1);
  margin: 0 0 var(--r5);
}

.feld__label {
  font-size: 0.8rem;
  color: var(--schrift-leise);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.feld__eingabe {
  background: var(--grund);
  color: var(--schrift);
  caret-color: var(--signal);
  border: 1px solid var(--rand-stark);
  padding: var(--r2) var(--r3);
  font: inherit;
  width: 100%;
  min-height: 2.4rem;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}

.feld__eingabe::placeholder { color: var(--schrift-leise); opacity: 1; }

.feld__eingabe:hover { border-color: var(--signal); }

.feld__eingabe:focus-visible {
  border-color: var(--signal);
  outline: 2px solid var(--signal);
  outline-offset: 1px;
}

.feld__eingabe--kurz { max-width: 10rem; }
.feld__eingabe--mono { font-family: var(--mono); }

.feld__eingabe--gross {
  min-height: 9rem;
  resize: vertical;
  line-height: 1.5;
}

.feld__eingabe--datei {
  padding: var(--r2);
  font-size: 0.85rem;
  cursor: pointer;
}

.feld__eingabe--datei::file-selector-button {
  font: inherit;
  margin-right: var(--r3);
  padding: var(--r1) var(--r3);
  border: 1px solid var(--rand-stark);
  background: var(--flaeche);
  color: var(--schrift);
  cursor: pointer;
}

.feld__eingabe--datei:hover::file-selector-button { border-color: var(--signal); }

textarea.feld__eingabe { line-height: 1.5; }

.feld__hinweis {
  font-size: 0.8rem;
  color: var(--schrift-leise);
}

.formular__aktionen {
  display: flex;
  align-items: center;
  gap: var(--r3);
  flex-wrap: wrap;
  margin: var(--r5) 0 0;
}

/* --- Knoepfe -------------------------------------------------------------- */

.knopf {
  font: inherit;
  font-size: 0.85rem;
  letter-spacing: 0.06em;
  padding: var(--r2) var(--r4);
  min-height: 2.4rem;      /* >= 24px Zielgroesse mit Reserve (WCAG 2.5.8) */
  min-width: 2.4rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--rand-stark);
  background: var(--flaeche);
  color: var(--schrift);
  cursor: pointer;
  text-decoration: none;
  /* 140ms: kurz genug, dass der Knopf beim Ueberfahren nicht hinterherhinkt,
     lang genug, dass der Wechsel als Bewegung gelesen wird statt als Sprung. */
  transition: color 140ms ease, border-color 140ms ease,
              background-color 140ms ease, box-shadow 140ms ease;
}

.knopf:hover {
  border-color: var(--signal);
  color: var(--signal);
  background: rgba(var(--signal-rgb), 0.07);
  box-shadow: 0 0 10px rgba(var(--signal-rgb), 0.2);
}

.knopf:active { background: rgba(var(--signal-rgb), 0.14); }

/* Kleine Ausfuehrung fuer Kopfzeile und Unterschriften - bleibt ueber
   24px hoch. */
.knopf--klein {
  font-size: 0.75rem;
  padding: var(--r1) var(--r3);
  min-height: 1.75rem;
}

.knopf--haupt {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--auf-signal);
  font-weight: 700;
}

.knopf--haupt:hover {
  background: var(--grund);
  color: var(--signal);
  border-color: var(--signal);
  box-shadow: 0 0 14px rgba(var(--signal-rgb), 0.35);
}

.knopf--haupt:active { background: var(--flaeche); }

.knopf--schlicht { background: transparent; }

.knopf--gefahr {
  color: var(--gefahr);
  border-color: var(--gefahr);
  background: transparent;
}

.knopf--gefahr:hover {
  background: var(--gefahr);
  border-color: var(--gefahr);
  color: var(--grund);
}

.knopf[disabled],
.knopf[disabled]:hover {
  color: var(--schrift-leise);
  border-color: var(--rand);
  background: var(--flaeche);
  opacity: 0.55;
  cursor: default;
  box-shadow: none;
}

/* --- Werkstatt: Uebersicht ------------------------------------------------ */

.werkstatt__kopf,
/* Sprungleiste im Werk-Formular: die drei Upload-Bereiche liegen unter dem
   Textformular, auf dem Handy also weit unten. */
.sprungleiste {
  display: flex;
  flex-wrap: wrap;
  gap: var(--r2);
  margin: 0 0 var(--r4);
}

.sprungleiste__link {
  padding: var(--r1) var(--r3);
  border: 1px solid var(--rand-stark);
  font-size: 0.8rem;
  text-decoration: none;
  color: var(--signal);
}

.sprungleiste__link:hover { background: rgba(var(--signal-rgb), 0.07); border-color: var(--signal); }

.bilderpflege, .medienpflege { scroll-margin-top: 4rem; }

.werkform__kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--r4);
  flex-wrap: wrap;
  margin: 0 0 var(--r5);
  padding-bottom: var(--r3);
  border-bottom: 1px solid var(--rand);
}

.werkstatt__titel,
.werkform__titel {
  margin: 0;
  font-size: clamp(1.4rem, 3vw, 1.8rem);
}

.pflege__kopf {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--r4);
  flex-wrap: wrap;
  margin: 0 0 var(--r6);
  padding-bottom: var(--r3);
  border-bottom: 1px solid var(--rand);
}

.pflege__titelblock { min-width: 0; }

.pflege__titel {
  margin: 0 0 var(--r2);
  font-size: clamp(1.4rem, 3vw, 1.8rem);
}

.pflege__hinweis {
  margin: 0;
  max-width: var(--lesebreite);
  font-size: 0.8rem;
  color: var(--schrift-leise);
}

/* --- Werkstatt: die drei Bereiche -----------------------------------------
   Dieselbe Gliederung wie draussen auf der Startseite: Ueberschrift, Anzahl
   rechts, darunter der Bestand. Wer die Seite kennt, findet sich hier sofort
   zurecht. */

.bereich { margin: 0 0 var(--r7); }

.bereich__titel {
  display: flex;
  align-items: center;
  gap: var(--r2);
  margin: 0 0 var(--r3);
  padding-bottom: var(--r2);
  border-bottom: 1px solid var(--rand);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--schrift);
}

.bereich__marke { color: var(--rand-stark); }

.bereich__zahl {
  margin-left: auto;
  padding: 0 var(--r2);
  border: 1px solid var(--rand);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  color: var(--schrift-leise);
}

/* Der Zusatz "Eintraege" ist nur fuer Screenreader da - ohne diese Zeile
   erbt er das uppercase der Ueberschrift, und manche Vorlesesoftware
   buchstabiert Grossbuchstaben dann einzeln. */
.bereich__zahl .nur-sr { text-transform: none; }

.bereich__leerlink { margin-left: var(--r2); }

.werkliste,
.bilderliste,
.medienliste { list-style: none; margin: 0; padding: 0; }

.werkliste__eintrag,
.bilderliste__eintrag,
.medienliste__eintrag {
  display: flex;
  align-items: center;
  gap: var(--r4);
  padding: var(--r3);
  border: 1px solid var(--rand);
  background: var(--flaeche);
  margin-bottom: var(--r2);
  flex-wrap: wrap;
}

.werkliste__vorschau,
.bilderliste__vorschau { margin: 0; flex: 0 0 auto; }

/* contain, nicht cover: diese Miniaturen dienen dem Wiedererkennen. Ein
   Ausschnitt aus der Bildmitte sagt bei Renderings fast nichts. */
.werkliste__foto,
.bilderliste__foto {
  width: 128px;
  height: 80px;
  object-fit: contain;
  background: var(--grund);
  border: 1px solid var(--rand);
}

.werkliste__text,
.bilderliste__felder,
.medienliste__felder {
  flex: 1 1 16rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--r1);
}

/* line-height so, dass der Link auch als Ziel 24px hoch bleibt (WCAG 2.5.8) -
   er ist hier kein Wort im Fliesstext, sondern der Griff der ganzen Zeile. */
.werkliste__titel {
  font-weight: 700;
  font-size: 0.95rem;
  line-height: 1.7;
  color: var(--schrift);
  text-decoration: underline;
  text-underline-offset: 3px;
  /* Zwei Zeilen, dann Schluss: eine Liste, in der ein einziger Eintrag
     zwanzig Zeilen hoch wird, kann man nicht mehr ueberfliegen. Der volle
     Titel steht im Formular dahinter. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
}

.werkliste__titel:hover { color: var(--signal); }

.werkliste__meta {
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  color: var(--schrift-leise);
}

.werkliste__aktionen,
.bilderliste__aktionen,
.medienliste__aktionen {
  display: flex;
  gap: var(--r2);
  align-items: center;
  flex-wrap: wrap;
}

.werkliste__loeschen { margin: 0; }

/* Die Uebersichtsliste steht als ein Kasten je Bereich: elf einzeln gerahmte
   Zeilen waren Unruhe ohne Nutzen. Getrennt wird mit einer Linie, gefunden
   wird ueber die Bereichsueberschrift darueber. Steht bewusst nach den
   gemeinsamen Regeln oben - die gelten weiter fuer Bild- und Medienpflege. */

.werkliste {
  border: 1px solid var(--rand);
  background: var(--flaeche);
}

.werkliste__eintrag {
  margin: 0;
  border: 0;
  padding: var(--r3) var(--r4);
  background: transparent;
}

.werkliste__eintrag + .werkliste__eintrag { border-top: 1px solid var(--rand); }

.werkliste__eintrag:hover,
.werkliste__eintrag:focus-within { background: var(--flaeche-hoch); }

.werkliste__foto { width: 104px; height: 64px; }

.werkliste__vorschau .plakat--liste { width: 104px; height: 64px; }

.werkliste__text { flex: 1 1 14rem; }

/* Das Jahr steht vorn in der Metazeile und heller als der Rest: als eigene
   Spalte rechts riss es eine handbreite Luecke in jede Zeile. Tabellarische
   Ziffern halten es trotzdem untereinander. */
.werkliste__jahr {
  color: var(--schrift);
  font-variant-numeric: tabular-nums;
}

.werkliste__jahr::after {
  content: " ·";
  color: var(--rand-stark);
}

/* --- Werkstatt: Bildpflege ------------------------------------------------ */

.bilderpflege,
.medienpflege,
.werkform__entfernen {
  /* Bewusst breiter als .formular: so bleibt eine Bildzeile einzeilig
     (Nummer, Miniatur, Beschreibung, Knoepfe). */
  max-width: 64rem;
  margin-top: var(--r6);
  border-top: 1px solid var(--rand);
  padding-top: var(--r5);
}

.bilderliste { margin-top: var(--r5); }

.bilderpflege__titel,
.medienpflege__titel,
.werkform__entfernen-titel {
  margin: 0 0 var(--r3);
  font-size: 1.1rem;
}

.bilderpflege__hinweis,
.werkform__entfernen-hinweis {
  margin: 0 0 var(--r4);
  max-width: var(--lesebreite);
  color: var(--schrift-leise);
  font-size: 0.85rem;
}

/* Sichtbare Nummern: ohne sie ist nach dem Verschieben nicht zu erkennen,
   an welcher Stelle ein Bild jetzt steht. */
.bilderliste { counter-reset: bild; }

.bilderliste__eintrag { counter-increment: bild; }

.bilderliste__eintrag::before,
.medienliste__eintrag::before {
  flex: 0 0 auto;
  align-self: flex-start;
  min-width: 1.9rem;
  padding: var(--r1) var(--r2);
  border: 1px solid var(--rand-stark);
  font-size: 0.75rem;
  text-align: center;
  color: var(--schrift-leise);
}

.bilderliste__eintrag::before { content: counter(bild); }

.bilderliste__eintrag:first-child::before,
.medienliste__eintrag:first-child::before {
  color: var(--signal);
  border-color: var(--signal);
}

.bilderliste__marke {
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--signal);
  margin-top: var(--r1);
}

/* Verschieben-Pfeile: quadratisch, damit sie als Paar ruhig wirken. */
.bilderliste__aktionen .knopf--schlicht,
.medienliste__aktionen .knopf--schlicht {
  padding: var(--r2);
  min-width: 2.6rem;
  font-size: 1rem;
  line-height: 1;
}

/* Loeschen bewusst abgesetzt: direkt neben dem Abwaerts-Pfeil ist ein
   Fehlgriff zu leicht. */
.bilderliste__aktionen .knopf--gefahr,
.medienliste__aktionen .knopf--gefahr { margin-left: var(--r4); }

/* --- Werkstatt: Musik und Video ------------------------------------------- */

.medienliste { margin-top: var(--r5); counter-reset: medium; }

.medienliste__eintrag { counter-increment: medium; }

.medienliste__eintrag::before { content: counter(medium); }

/* Steht an der Stelle, an der bei den Bildern die Miniatur sitzt - eine
   Vorschau gibt es fuer Ton nicht, die Gattung ist hier die Miniatur. */
.medienliste__art {
  flex: 0 0 9rem;
  margin: 0;
  align-self: flex-start;
  padding-top: var(--r1);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--signal);
}

/* Eingebettete Adressen sind lang und haben keine Leerzeichen zum Umbrechen. */
.feld__hinweis--mono {
  font-size: 0.72rem;
  overflow-wrap: anywhere;
}

/* --- Vorschau vor dem Hochladen ------------------------------------------- */

.vorschau:empty { display: none; }

.vorschau__liste {
  list-style: none;
  margin: var(--r4) 0 0;
  padding: 0;
  display: flex;
  gap: var(--r3);
  flex-wrap: wrap;
  counter-reset: vorschau;
}

.vorschau__eintrag {
  counter-increment: vorschau;
  width: 180px;   /* breit genug, dass ein Dateiname in eine Zeile passt */
  padding: var(--r2);
  border: 1px solid var(--rand);
  background: var(--flaeche);
  font-size: 0.72rem;
  color: var(--schrift-leise);
  overflow-wrap: anywhere;
}

/* Reihenfolge sichtbar machen - das erste Bild wird das Titelbild. */
.vorschau__eintrag::before {
  content: counter(vorschau);
  display: block;
  width: fit-content;
  min-width: 1.5rem;
  margin-bottom: var(--r2);
  padding: 0 var(--r1);
  background: var(--grund);
  border: 1px solid var(--rand-stark);
  text-align: center;
  color: var(--schrift);
}

.vorschau__eintrag:first-child::before {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--auf-signal);
  font-weight: 700;
}

.vorschau__foto {
  width: 100%;
  height: 120px;
  object-fit: contain;
  background: var(--grund);
  margin-bottom: var(--r2);
}

.vorschau__name {
  display: block;
  font-size: 0.7rem;
  line-height: 1.4;
}

.vorschau__warnung {
  display: block;
  margin-top: var(--r1);
  padding-left: var(--r2);
  border-left: 2px solid var(--gefahr);
  color: var(--gefahr);
}

/* --- Meldungen ------------------------------------------------------------ */

.meldungen { list-style: none; margin: 0 0 var(--r5); padding: 0; }

.meldung {
  padding: var(--r2) var(--r3);
  border: 1px solid var(--rand);
  border-left: 3px solid var(--rand-stark);
  background: var(--flaeche);
  margin-bottom: var(--r2);
  font-size: 0.85rem;
}

.meldung--erfolg { border-left-color: var(--signal); }
.meldung--fehler { border-left-color: var(--gefahr); }

/* --- Anmeldung, Fehlerseite, Kleinkram ------------------------------------ */

.anmeldung {
  max-width: 24rem;
  margin: var(--r8) auto;
  padding: var(--r5);
  border: 1px solid var(--rand);
  background: var(--flaeche);
}

.anmeldung__titel {
  margin: 0 0 var(--r1);
  font-size: 1.3rem;
}

/* Der Strich sitzt unter dem Untertitel, damit Ueberschrift und Ortsangabe
   als ein Block stehen. */
.anmeldung__unter {
  margin: 0 0 var(--r5);
  padding-bottom: var(--r3);
  border-bottom: 2px solid var(--signal);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  color: var(--schrift-leise);
}

.anmeldung .meldung { margin-bottom: var(--r5); }

/* --- Rueckfrage vor dem Loeschen ------------------------------------------
   Natives <dialog>, von werkstatt.js einmal gebaut und wiederverwendet. Die
   rote Kante sagt, worum es geht, bevor man den Text liest. */

.rueckfrage {
  width: min(34rem, calc(100% - 2rem));
  padding: 0;
  border: 1px solid var(--gefahr);
  background: var(--flaeche);
  color: var(--schrift);
  box-shadow: 0 0 60px rgba(0, 0, 0, 0.9);
}

.rueckfrage::backdrop { background: rgba(0, 6, 0, 0.82); }

.rueckfrage__inhalt { margin: 0; padding: var(--r5); }

.rueckfrage__titel {
  margin: 0 0 var(--r3);
  font-size: 1.05rem;
  color: var(--gefahr);
}

.rueckfrage__text {
  margin: 0 0 var(--r5);
  max-width: var(--lesebreite);
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--schrift);
}

.rueckfrage__aktionen {
  display: flex;
  gap: var(--r3);
  justify-content: flex-end;
}

/* Leerstellen sind kein Fehler, sondern eine Einladung: gestrichelt statt
   durchgezogen, damit man den Unterschied zu einem Kasten mit Inhalt sieht -
   und der naechste Handgriff steht gleich mit drin. */
.leerhinweis,
.bereich__leer {
  margin: 0;
  padding: var(--r4) var(--r5);
  border: 1px dashed var(--rand);
  background: var(--flaeche);
  color: var(--schrift-leise);
  font-size: 0.85rem;
}

.fehlerseite { padding: var(--r7) 0; }

.fehlerseite__code {
  font-size: clamp(3rem, 12vw, 5rem);
  color: var(--signal);
  margin: 0 0 var(--r2);
  line-height: 1;
}

.fehlerseite__text { margin: 0 0 var(--r5); font-size: 1rem; }

/* --- Schmale Fenster ------------------------------------------------------ */

@media (max-width: 900px) {
  /* Der Bestandskasten rutscht unter den Titel und wird zur Zeile. */
  .einleitung { grid-template-columns: minmax(0, 1fr); gap: var(--r4); }
  .bestand { display: flex; flex-wrap: wrap; min-width: 0; }
  .bestand__posten { flex: 1 1 7rem; flex-direction: column; align-items: flex-start; gap: 0; }
  .bestand__posten + .bestand__posten { border-top: 0; border-left: 1px solid var(--rand); }

  /* Der Steckbrief rutscht unter den Titel und wird zur Zeile. */
  .werk__kopf { grid-template-columns: minmax(0, 1fr); gap: var(--r4); }
  .werk__fakten { display: flex; flex-wrap: wrap; min-width: 0; }
  .werk__faktum { flex: 1 1 8rem; }
  .werk__faktum + .werk__faktum { border-top: 0; border-left: 1px solid var(--rand); }
}

@media (max-width: 640px) {
  /* Schmal klebt der Kopf nicht: mit Marke, vier Links und dem Regenschalter
     wird er drei Zeilen hoch und naehme dem Bildschirm ein Viertel. Marke und
     Schalter teilen sich die erste Zeile, die Navigation bekommt die zweite. */
  .kopf {
    position: static;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    row-gap: var(--r2);
    padding-left: var(--r4);
    padding-right: var(--r4);
  }
  .kopf__werkzeuge { display: contents; }
  .kopf__navigation { grid-column: 1 / -1; gap: var(--r1) var(--r2); }
  .regenschalter { grid-row: 1; grid-column: 2; justify-self: end; }
  .inhalt { padding: var(--r5) var(--r4) var(--r7); }
  .fuss { padding-left: var(--r4); padding-right: var(--r4); }

  .buehne { border-left: 0; border-right: 0; }

  /* Drei gleich breite Felder in einer Zeile - umgebrochen sieht der Kasten
     aus, als waere ihm der Platz ausgegangen. */
  .bestand__posten { flex: 1 1 0; min-width: 0; padding: var(--r2); }
  .bestand__label { font-size: 0.65rem; letter-spacing: 0.06em; }
  .bestand__zahl { font-size: 1rem; }

  .kachelwand { gap: var(--r3); }

  /* Quer gelegte Kacheln wieder stapeln - nebeneinander bleibt hier von
     beidem zu wenig uebrig. */
  .kachelwand--quer .kachel__link { flex-direction: column; }
  .kachelwand--quer .kachel__bild { flex: none; }
  .kachelwand--quer .kachel__text { padding: var(--r3) var(--r4) var(--r4); }
  .kachelwand--quer .kachel__foto,
  .kachelwand--quer .plakat {
    aspect-ratio: 16 / 10;
    min-height: 0;
    border-right: 0;
    border-bottom: 1px solid var(--rand);
  }

  .galerie { gap: var(--r4); }

  /* Die Stueckzeile wird zweizeilig: Bild, Knopf und Titel oben, Marken und
     Dauer darunter. Nebeneinander wird es hier zu eng zum Treffen. Die
     Nummer entfaellt - sie ist Deko, der Platz nicht. */
  .stueck {
    /* Bild, Knopf, Text, Dauer - Marken und Dauer in einer zweiten Zeile
       unter dem Titel, jede in ihrer eigenen Spalte: in einer gemeinsamen
       Spalte lief "VIDEO 2026" in die "2:15" hinein. */
    grid-template-columns: auto auto minmax(0, 1fr) auto;
    gap: var(--r2) var(--r3);
    align-items: start;
  }
  .stueck::before { display: none; }
  .stueck__bild { grid-column: 1; }
  .stueck__spielen { grid-column: 2; }
  .stueck__text { grid-column: 3 / 5; }
  .stueck__marken { grid-column: 3; grid-row: 2; justify-content: flex-start; flex-wrap: wrap; }
  .stueck__dauer { grid-column: 4; grid-row: 2; }
  .stuecke:has(.stueck__spielen:not([hidden])) .stueck:not(.stueck--spielbar) .stueck__marken {
    padding-left: 2.5rem;   /* zweite Zeile buendig mit dem Titel */
  }
  /* Die grosse Liste (Musik-Filter) hat hier keinen Platz fuer grosse Luecken. */
  .stuecke--gross .stueck { padding: var(--r3) var(--r4); gap: var(--r2) var(--r3); }
  .stuecke--gross .stueck__bild { width: 3.25rem; height: 3.25rem; }
  .stuecke--gross .plakat--klein .plakat__initial { font-size: 1.1rem; }

  .medium__buehne { padding: var(--r2); }

  .dokument__zeile { grid-template-columns: auto minmax(0, 1fr); }
  .dokument__aktionen { grid-column: 2; }
  .dokument__rahmen { height: 70vh; }

  /* Bildpflege stapeln: nebeneinander wird es hier zu eng zum Treffen. */
  .werkliste__eintrag,
  .bilderliste__eintrag,
  .medienliste__eintrag { align-items: stretch; }

  .medienliste__art { flex: 1 1 100%; }
  .medienliste__aktionen { flex: 1 1 100%; }

  .werkliste__foto,
  .bilderliste__foto,
  .plakat--liste { width: 100%; height: 140px; }

  .werkliste__vorschau,
  .bilderliste__vorschau { flex: 1 1 100%; }

  .werkliste__aktionen,
  .bilderliste__aktionen { flex: 1 1 100%; }

  /* Die Uebersicht bleibt auch schmal eine Zeile: hier zaehlt der Ueberblick
     ueber elf Eintraege, nicht die Groesse der Miniatur. Nur die Knoepfe
     rutschen darunter, damit sie treffbar bleiben. */
  .werkliste__eintrag { align-items: center; gap: var(--r3); padding: var(--r3); }
  .werkliste__vorschau { flex: 0 0 auto; }
  .werkliste__foto,
  .werkliste__vorschau .plakat--liste { width: 72px; height: 48px; }
  .werkliste__text { flex: 1 1 8rem; }
  .werkliste__aktionen { flex: 1 1 100%; }
  /* Loeschen rutscht ans rechte Ende, statt allein in einer dritten Zeile
     anzufangen - und steht damit weiter weg von den harmlosen Knoepfen. */
  .werkliste__loeschen { margin-left: auto; }

  .vorschau__eintrag { width: calc(50% - var(--r2)); }

  .anmeldung { margin-top: var(--r6); }

  .rueckfrage__aktionen { flex-wrap: wrap; }
}

/* --- Wer keine Bewegung will, bekommt keine -------------------------------
   Nicht auf 0 gesetzt, sondern auf einen Wimpernschlag: ein transitionend,
   das nie kommt, haengt sonst JS auf, das darauf wartet. Der Regen laeuft
   hier gar nicht erst an - regen.js liest dieselbe Abfrage und laesst ihn
   aus, solange niemand den Schalter selbst betaetigt hat. */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- Kleinkram ------------------------------------------------------------ */

::selection {
  background: var(--signal);
  color: var(--auf-signal);
  text-shadow: none;
}
