/* ============================================================
   Casting Spells — die private Einladung

   Zwei Welten treffen sich hier. Der Kopf traegt das
   Kirchenfenster der Musikseite, der Rumpf das Papier von
   "Neu erzaehlt".

   ── Der Satzspiegel ──────────────────────────────────────

   Die Seite kennt drei Arten von Abschnitt, und sie wechseln
   einander ab. Ohne diesen Wechsel liest sich eine lange Seite
   als Liste, nicht als Text:

     KAPITEL  Ein grosser Satz, mittig, viel Luft darum. Traegt
              einen Gedanken.
     NOTIZ    Marke links, schmale Spalte rechts. Traegt eine
              Angabe. Kleiner gesetzt als ein Kapitel.
     TAFEL    Nur ein Bild, oder ein dunkles Feld. Keine Marke,
              keine Ueberschrift. Atempause.

   ── Schriftgroessen ──────────────────────────────────────

   Die Laufweite ist groessenabhaengig, nie ein Wert fuer alles:
   grosse Zeilen brauchen negative Laufweite, weil die Buchstaben
   beim Wachsen auseinanderfallen; kleine brauchen etwas positive,
   damit sie nicht verkleben. Der Zeilenabstand laeuft umgekehrt
   zur Groesse -- eng bei Ueberschriften, weit im Fliesstext.

   IM Fell English braucht dabei mehr Luft als eine Garamond.
   Ihre Kleinbuchstaben sind niedriger, ihre Konturen ahmen
   abgenutzte Lettern des 17. Jahrhunderts nach.

   ── iOS-Safari-Regeln, teuer gelernt ─────────────────────

   - background-clip:text nie zusammen mit filter am selben
     Element. Die Schrift verschwindet dann spurlos.
   - Der Schein liegt deshalb auf einer eigenen Ebene.
   ============================================================ */

/* ── Die Schriften, von dieser Seite ausgeliefert ─────────── */

@font-face {
  font-family: 'IM Fell English';
  font-style: normal; font-weight: 400; font-display: swap;
  src: url(../fonts/IMFellEnglish-400-latin.woff2) format('woff2');
}
@font-face {
  font-family: 'IM Fell English';
  font-style: italic; font-weight: 400; font-display: swap;
  src: url(../fonts/IMFellEnglish-400i-latin.woff2) format('woff2');
}
@font-face {
  font-family: 'IM Fell English SC';
  font-style: normal; font-weight: 400; font-display: swap;
  src: url(../fonts/IMFellEnglishSC-400-latin.woff2) format('woff2');
}
@font-face {
  font-family: 'EB Garamond';
  font-style: normal; font-weight: 400; font-display: swap;
  src: url(../fonts/EBGaramond-400-latin.woff2) format('woff2');
}
@font-face {
  font-family: 'EB Garamond';
  font-style: italic; font-weight: 400; font-display: swap;
  src: url(../fonts/EBGaramond-400i-latin.woff2) format('woff2');
}
@font-face {
  font-family: 'CCSBjork';
  src: url(../fonts/CCSBjork-Light.woff) format('woff');
  font-weight: 300; font-style: normal; font-display: swap;
}

/* ── Die Welt ─────────────────────────────────────────────── */

:root {
  /* Die Nacht der Musikseite. Dieselben Werte, damit Casting
     Spells kein Fremdkoerper neben /musik/ ist. */
  --grund:      #0a0810;
  --grund-tief: #060509;
  --grund-hoch: #15101c;
  --papier-warm: #120e18;       /* die ruhigen Felder */

  --text:       #f5f1e8;
  --text-weich: rgba(245, 241, 232, 0.80);
  --text-matt:  rgba(245, 241, 232, 0.58);
  --text-blass: rgba(245, 241, 232, 0.42);
  --linie:      rgba(212, 165, 116, 0.18);

  --akzent:      #d4a574;
  --akzent-hell: #e8c69e;
  --akzent-tief: #a8824f;
  --gold:        #c9a06a;
  --creme:       #f3ece0;

  /* Alte Namen, damit nichts unbemerkt bricht. */
  --papier:      var(--grund);
  --papier-tief: var(--grund-hoch);
  --tinte:       var(--text);
  --tinte-weich: var(--text-weich);
  --tinte-matt:  var(--text-matt);
  --tinte-blass: var(--text-blass);
  --ocker:       var(--akzent);
  --ocker-tief:  var(--akzent-hell);
  --nacht:       var(--grund);

  --fell:     'IM Fell English', 'EB Garamond', Georgia, serif;
  --fell-sc:  'IM Fell English SC', 'IM Fell English', Georgia, serif;
  --garamond: 'EB Garamond', Georgia, serif;

  /* Die Stufen. Jede traegt ihre eigene Laufweite und ihren
     eigenen Zeilenabstand -- das ist eine Entscheidung, nicht
     drei getrennte Regler. */
  --t-titel:    clamp(3.4rem, 12.5vw, 9rem);
  --t-kapitel:  clamp(1.95rem, 4.4vw, 3.3rem);
  --t-gross:    clamp(1.46rem, 2.5vw, 1.95rem);
  --t-satz:     clamp(1.4rem, 2.9vw, 2.2rem);
  --t-vorspann: clamp(1.18rem, 0.9vw + 1rem, 1.46rem);
  --t-text:     clamp(1.06rem, 0.52vw + 0.94rem, 1.2rem);
  --t-klein:    clamp(0.9rem, 0.3vw + 0.82rem, 0.98rem);
  --t-marke:    clamp(0.68rem, 0.3vw + 0.61rem, 0.78rem);

  /* Die Luft. Sieben Stufen, keine Zwischenwerte von Hand. */
  --luft-1: 0.5rem;
  --luft-2: 0.95rem;
  --luft-3: 1.5rem;
  --luft-4: 2.4rem;
  --luft-5: clamp(3rem, 6vw, 4.5rem);
  --luft-6: clamp(4.5rem, 10vw, 8rem);
  --luft-7: clamp(6rem, 15vw, 12rem);

  /* Die Satzbreiten. */
  --mass-eng:   34rem;
  --mass-lesen: 39rem;
  --mass-weit:  58rem;
  --mass-breit: 74rem;

  --rand: clamp(1.25rem, 5vw, 2.75rem);
  --aus:  cubic-bezier(0.23, 1, 0.32, 1);
}

:root { color-scheme: light; }

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--grund);
  color: var(--tinte);
  font-family: var(--fell);
  font-size: var(--t-text);
  line-height: 1.92;
  letter-spacing: 0.012em;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

/* ── Der Grund ────────────────────────────────────────────────
   Kein background-attachment: fixed -- das reisst in Safari auf
   iOS beim Ueberscrollen. Stattdessen eine eigene feste Ebene. */
.grund {
  position: fixed; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(ellipse 130% 70% at 50% 0%, #17121f 0%, transparent 62%),
    radial-gradient(ellipse 100% 60% at 50% 100%, #130f1a 0%, transparent 58%),
    linear-gradient(180deg, #0a0810 0%, #0d0a14 48%, #070510 100%);
}

/* ── Der Mond ─────────────────────────────────────────────────
   Dasselbe Video wie auf der Startseite. Es laeuft nicht, es wird
   gespult: Der Scrollfortschritt bestimmt die Mondphase. Die Bahn
   kommt aus schein.js; die -50 Prozent fuer die eigene Breite
   stecken in derselben transform-Angabe, sonst ueberschriebe das
   Skript sie. */
.mond {
  position: fixed;
  top: 7vh; left: 50%;
  z-index: -1;
  width: clamp(190px, 32vw, 440px);
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 50%;
  mix-blend-mode: screen;
  /* Er beginnt unsichtbar. schein.js laesst ihn erst auftreten,
     wenn der erste grosse Satz ins Bild kommt -- im Kopf soll nur
     das Fenster leuchten. */
  opacity: 0;
  pointer-events: none;
  /* Ein Hauch Saum, damit die Scheibe nicht ausgestanzt wirkt.
     Die inneren 86 Prozent bleiben voll. */
  -webkit-mask-image: radial-gradient(circle at 50% 50%,
    #000 0%, #000 86%, rgba(0,0,0,0.6) 95%, rgba(0,0,0,0) 100%);
          mask-image: radial-gradient(circle at 50% 50%,
    #000 0%, #000 86%, rgba(0,0,0,0.6) 95%, rgba(0,0,0,0) 100%);
  transform: translate3d(-50%, 0, 0);
  /* Der Uebergang gilt nur der Deckkraft. Die Lage kommt vom
     Scrollstand und darf nicht nachlaufen -- sonst schwimmt der
     Mond hinter dem Finger her. */
  transition: opacity 700ms var(--aus);
}
p { margin: 0; }
a { color: var(--ocker); }
a:hover { color: var(--ocker-tief); }

/* Rueckmeldung auf den Druck, nicht auf das Loslassen. */
a, button { -webkit-tap-highlight-color: transparent; }
a:active, button:active { transform: scale(0.985); transition: transform 100ms ease-out; }

.sprung {
  position: absolute; left: -9999px;
  background: var(--grund-hoch); color: var(--text);
  padding: 0.7rem 1.1rem; z-index: 99;
}
.sprung:focus { left: 1rem; top: 1rem; }

:focus-visible { outline: 2px solid var(--ocker); outline-offset: 3px; }

/* Die Spalten. */
.eng   { max-width: var(--mass-eng);   margin-inline: auto; padding-inline: var(--rand); }
.lesen { max-width: var(--mass-lesen); margin-inline: auto; padding-inline: var(--rand); }
.weit  { max-width: var(--mass-weit);  margin-inline: auto; padding-inline: var(--rand); }
.breit { max-width: var(--mass-breit); margin-inline: auto; padding-inline: var(--rand); }

/* ══════════════════════════════════════════════════════════
   DER KOPF
   ══════════════════════════════════════════════════════════ */

.kopf {
  position: relative;
  min-height: min(88svh, 760px);
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: clamp(5rem, 11vw, 8rem) var(--rand) clamp(5rem, 10vw, 7rem);
  /* Ein eigener, undurchsichtiger Grund. Dadurch bleibt der Mond
     hier unsichtbar -- er liegt mit negativem z-index darunter.
     Im Kopf soll nur das Fenster leuchten, sonst nichts. */
  background: var(--grund);
  overflow: hidden;
  text-align: center;
}

.glas {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: url('../musik/images/stained-glass.jpg');
  background-size: cover; background-position: center;
  mix-blend-mode: screen;
  opacity: 0.44;
  transition: opacity .45s ease;
  filter: blur(0.5px) saturate(1.6) brightness(1.15) contrast(1.05);
  /* Das Fenster leuchtet dort, wo der Zeiger steht. --mx und --my
     setzt schein.js; ohne Zeiger stehen sie in der Mitte. */
  -webkit-mask-image: radial-gradient(circle 380px at var(--mx, 50%) var(--my, 42%),
    rgba(0,0,0,1) 0%, rgba(0,0,0,0.82) 35%, rgba(0,0,0,0.32) 70%, rgba(0,0,0,0) 95%);
          mask-image: radial-gradient(circle 380px at var(--mx, 50%) var(--my, 42%),
    rgba(0,0,0,1) 0%, rgba(0,0,0,0.82) 35%, rgba(0,0,0,0.32) 70%, rgba(0,0,0,0) 95%);
}
.glas.wach { opacity: 0.72; }

@media (max-width: 700px) {
  .glas {
    -webkit-mask-image: radial-gradient(circle 240px at var(--mx, 50%) var(--my, 38%),
      rgba(0,0,0,1) 0%, rgba(0,0,0,0.8) 38%, rgba(0,0,0,0.3) 72%, rgba(0,0,0,0) 96%);
            mask-image: radial-gradient(circle 240px at var(--mx, 50%) var(--my, 38%),
      rgba(0,0,0,1) 0%, rgba(0,0,0,0.8) 38%, rgba(0,0,0,0.3) 72%, rgba(0,0,0,0) 96%);
  }
}

.laterne {
  position: absolute; z-index: 1; pointer-events: none;
  width: 320px; height: 320px; border-radius: 50%;
  left: 50%; top: 58%;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle,
    rgba(212,165,116,0.38) 0%, rgba(212,165,116,0.1) 40%, transparent 70%);
  mix-blend-mode: screen;
  opacity: 0.7;
  transition: opacity .4s ease;
}

/* Ein tieferer Grund hinter dem Titel. Das Glas ist an manchen
   Stellen so hell, dass die Buchstaben darin verschwinden. */
.titel-grund {
  position: absolute; z-index: 1; pointer-events: none;
  inset: 14% 0 24%;
  background: radial-gradient(ellipse 66% 58% at 50% 50%,
    rgba(5,3,9,0.86) 0%, rgba(5,3,9,0.68) 42%, rgba(5,3,9,0.3) 68%, transparent 84%);
}

/* Der Schein liegt auf einer eigenen Ebene, nicht auf dem Titel. */
.glas-schein {
  position: absolute; z-index: 0; pointer-events: none;
  inset: 26% 10% 38%;
  background: radial-gradient(ellipse at center,
    rgba(212,165,116,0.22) 0%, rgba(216,78,90,0.10) 35%, transparent 70%);
  filter: blur(28px);
  animation: scheinAtmen 7s ease-in-out 2s infinite alternate;
}
@keyframes scheinAtmen {
  0%   { opacity: 0.6; transform: scale(0.96); }
  100% { opacity: 1;   transform: scale(1.07); }
}

/* ── Der Kopf auf dem Telefon ─────────────────────────────────
   Dort gibt es keinen schwebenden Zeiger, also bewegt schein.js
   die Maske nicht mehr -- das Fenster leuchtet ruhig aus seiner
   Mitte. Zwei Dinge bleiben hier noch zu entlasten.

   Erstens der Atem hinter dem Titel: Ein Scale auf einer um 28
   Pixel unscharfen Flaeche zwingt das Geraet, die Unschaerfe in
   jedem Bild neu zu rechnen, und das mitten in der screen-Gruppe
   des Kopfes. Nur die Deckkraft zu atmen kostet nichts -- die
   unscharfe Flaeche darf gespeichert bleiben. Zu sehen ist der
   Unterschied auf dieser Groesse nicht.

   Zweitens die halbe Unschaerfe auf dem Glas: ein eigener
   Durchgang ueber die ganze Kopffläche, fuer einen halben Pixel,
   den auf einem Telefonschirm niemand findet. */
@media (hover: none), (pointer: coarse) {
  .glas {
    filter: saturate(1.6) brightness(1.15) contrast(1.05);
  }
  .glas-schein {
    animation-name: scheinAtmenRuhig;
  }
}
@keyframes scheinAtmenRuhig {
  0%   { opacity: 0.6; }
  100% { opacity: 1; }
}

.kopf-mitte {
  position: relative; z-index: 2;
  display: flex; flex-direction: column; align-items: center;
  gap: clamp(1.1rem, 2.6vw, 1.9rem);
  max-width: 46rem;
}

.kopf-kicker {
  font-family: var(--fell-sc);
  font-size: var(--t-marke);
  letter-spacing: 0.24em; text-transform: uppercase;
  color: rgba(243, 236, 224, 0.62);
  line-height: 1.8;
}

.glas-titel {
  margin: 0;
  font-family: 'CCSBjork', var(--fell), serif;
  font-weight: 300;
  font-size: var(--t-titel);
  /* 0.98 schnitt die Unterlaenge des g ab: die Zeilenbox war
     kuerzer als die Zeichen, und .kopf schneidet mit overflow
     ab. Mehr Zeilenhoehe plus etwas Polsterung unten. */
  line-height: 1.12;
  padding-bottom: 0.06em;
  letter-spacing: 0.02em;
  color: var(--creme);
  text-shadow: 0 2px 34px rgba(4, 3, 8, 0.95), 0 0 12px rgba(4, 3, 8, 0.8);
  animation: titelHerein 2.6s cubic-bezier(.22,.61,.36,1) .25s both;
}
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .glas-titel {
    background-image: linear-gradient(104deg,
      #f0c478 0%, #e0b584 16%, #e2646f 34%, #fdfaf4 50%,
      #5fb39c 66%, #5a86cc 83%, #a976c4 100%);
    background-size: 300% 100%;
    background-position: 0% 50%;
    -webkit-background-clip: text; background-clip: text;
    -webkit-text-fill-color: transparent; color: transparent;
    /* Kein filter hier. Siehe den Kopf dieser Datei. */
    animation: titelHerein 2.6s cubic-bezier(.22,.61,.36,1) .25s both,
               titelLicht 22s ease-in-out 2.9s infinite alternate;
  }
}
@keyframes titelHerein {
  from { opacity: 0; transform: translateY(26px); letter-spacing: 0.3em; }
  to   { opacity: 1; transform: translateY(0);    letter-spacing: 0.02em; }
}
@keyframes titelLicht {
  0%   { background-position:   0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position:  50% 50%; }
}

.gold-regel { width: clamp(150px, 26vw, 220px); height: auto; opacity: 0.9; }

.kopf-spruch {
  font-family: var(--garamond); font-style: italic;
  font-size: var(--t-vorspann);
  line-height: 1.72;
  letter-spacing: 0.004em;
  color: rgba(243, 236, 224, 0.8);
  max-width: 30ch;
}

/* ── Die Mondleiste ───────────────────────────────────────────
   Dieselbe wie auf der Startseite: echte Mondfotos, darueber ein
   dunkler Pfad fuer die Phase, der Name darunter. Jeder Mond
   treibt auf seiner eigenen Uhr -- gleich lange Atemzuege wuerden
   die Reihe im Gleichschritt pumpen lassen. */

.monde {
  position: relative; z-index: 2;
  display: flex; flex-wrap: wrap;
  justify-content: center; align-items: flex-start;
  gap: clamp(0.7rem, 2vw, 2rem);
  margin: clamp(1.8rem, 4vw, 3rem) auto 0;
  padding: 0.5rem 0;
}

.monde-ort {
  display: flex; flex-direction: column; align-items: center;
  gap: 0.7rem; padding: 0.4rem;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

.monde-scheibe {
  display: block;
  width: clamp(44px, 6.4vw, 72px);
  aspect-ratio: 1; border-radius: 50%;
  /* Der Schein ist das eigene Licht des Mondes auf der Nacht
     ringsum. Auf der Scheibe selbst, nicht auf dem Elternteil:
     sonst faengt ihn der Name mit ein. */
  filter: drop-shadow(0 0 14px rgba(212, 165, 116, 0.26));
  transition: filter 600ms var(--aus), transform 600ms var(--aus);
  animation: mondTrift 11s ease-in-out infinite alternate;
}
.monde-scheibe svg { width: 100%; height: 100%; display: block; }

.monde-ort:nth-child(1) .monde-scheibe { animation-duration: 11s;   animation-delay: 0s; }
.monde-ort:nth-child(2) .monde-scheibe { animation-duration: 13.5s; animation-delay: -3s; }
.monde-ort:nth-child(3) .monde-scheibe { animation-duration: 9.5s;  animation-delay: -6s; }
.monde-ort:nth-child(4) .monde-scheibe { animation-duration: 15s;   animation-delay: -1.5s; }
.monde-ort:nth-child(5) .monde-scheibe { animation-duration: 12.5s; animation-delay: -8s; }

@keyframes mondTrift {
  from { transform: translate3d(0, -5px, 0); }
  to   { transform: translate3d(0,  6px, 0); }
}

.monde-name {
  font-family: var(--fell-sc);
  font-size: clamp(0.62rem, 1.3vw, 0.78rem);
  letter-spacing: 0.14em; text-transform: uppercase;
  text-align: center; text-wrap: balance;
  color: rgba(245, 241, 232, 0.6);
  line-height: 1.35;
  /* Das laengste Wort gibt die Breite, nicht eine geratene Zahl
     in ch: bei 11ch und auch bei 13ch stand STARTSEITE ueber
     seinem Kasten hinaus und lief in den Nachbarn -- die Reihe
     brach dabei nicht um, weil sie rechnerisch passte. So bleibt
     jeder Name ganz, und "Casting Spells" faellt von selbst auf
     zwei Zeilen. */
  max-width: min-content;
  /* Zwei Zeilen Platz, auch wenn nur eine kommt: sonst steht
     "Casting Spells" tiefer als seine Nachbarn. */
  min-height: 2.7em;
  transition: color 400ms var(--aus);
}

@media (hover: hover) and (pointer: fine) {
  .monde-ort:hover .monde-scheibe {
    filter: drop-shadow(0 0 26px rgba(212, 165, 116, 0.58));
    transform: scale(1.07);
  }
  .monde-ort:hover .monde-name { color: var(--creme); }
}
.monde-ort:active .monde-scheibe { transform: scale(0.97); }
.monde-ort:focus-visible { outline: 2px solid var(--akzent); outline-offset: 4px; border-radius: 4px; }

.monde-ort[aria-current] .monde-name { color: var(--creme); }
.monde-ort--spell .monde-scheibe { filter: drop-shadow(0 0 20px rgba(186, 64, 34, 0.52)); }
.monde-ort--spell:hover .monde-scheibe { filter: drop-shadow(0 0 30px rgba(186, 64, 34, 0.75)); }

/* ══════════════════════════════════════════════════════════
   DIE MARKE UND DIE EINTRITTSKARTE
   ══════════════════════════════════════════════════════════ */

.marke {
  margin: 0;
  font-family: var(--fell-sc);
  font-size: var(--t-marke);
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--ocker);
  line-height: 1.8;
}

/* ── Die Karte ────────────────────────────────────────────────
   Vorher ein flacher Streifen aus fuenf Grossbuchstabenzeilen.
   Jetzt eine Eintrittskarte: Papier auf dem dunklen Tisch, wie
   die Galileo-Blaetter -- dasselbe Motiv, nicht ein zweites.

   Die Kerben an der Perforation sind aus der Karte ausmaskiert,
   nicht mit Kreisen in Hintergrundfarbe uebermalt. Der Grund
   dieser Seite ist ein Verlauf; uebermalte Kreise waeren dort
   als Flecken zu sehen.

   Kein drop-shadow: Der Schatten ist ein box-shadow auf einem
   unverschobenen Element, sonst rastert Safari auf iOS ihn zu
   einem milchigen Rechteck. */

.karte,
.zettel {
  --karte-papier: #ece5d4;
  --karte-tinte:  #2f2820;
  --karte-matt:   #6b5f52;
  --karte-ocker:  #995d27;
}

.karte {
  --riss: 66%;
  --kerbe: 10px;

  position: relative;
  max-width: 40rem;
  margin-inline: auto;
  display: flex;
  background: var(--karte-papier);
  color: var(--karte-tinte);
  box-shadow: 0 1px 2px rgba(0,0,0,.5), 0 20px 56px rgba(0,0,0,.45);

  -webkit-mask:
    radial-gradient(circle var(--kerbe) at var(--riss) 0,    transparent 98%, #000 100%) top    / 100% 50.5% no-repeat,
    radial-gradient(circle var(--kerbe) at var(--riss) 100%, transparent 98%, #000 100%) bottom / 100% 50.5% no-repeat;
          mask:
    radial-gradient(circle var(--kerbe) at var(--riss) 0,    transparent 98%, #000 100%) top    / 100% 50.5% no-repeat,
    radial-gradient(circle var(--kerbe) at var(--riss) 100%, transparent 98%, #000 100%) bottom / 100% 50.5% no-repeat;
}

/* Die doppelte Haarlinie oben und unten -- eine Konvention aus
   dem Buchdruck, die eine Karte sofort als Karte liest. */
.karte::before,
.karte::after {
  content: ''; position: absolute; left: 0; right: 0; height: 3px;
  pointer-events: none;
  background:
    linear-gradient(var(--karte-ocker), var(--karte-ocker)) top    / 100% 1px no-repeat,
    linear-gradient(rgba(47,40,32,.3), rgba(47,40,32,.3))   bottom / 100% 1px no-repeat;
  opacity: .55;
}
.karte::before { top: 6px; }
.karte::after  { bottom: 6px; transform: scaleY(-1); }

.karte-haupt {
  flex: 1 1 auto; min-width: 0;
  padding: clamp(1.3rem, 3.5vw, 1.9rem) clamp(1.2rem, 3.5vw, 2rem);
  text-align: left;
}
.karte-abriss {
  flex: 0 0 auto;
  display: flex; flex-direction: column; justify-content: center; gap: .55rem;
  padding: clamp(1.3rem, 3.5vw, 1.9rem) clamp(1rem, 3vw, 1.6rem);
  border-left: 1px dashed rgba(47,40,32,.38);
  background: rgba(47,40,32,.035);
  text-align: center;
}

.karte-marke {
  font-family: var(--fell-sc);
  font-size: .68rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--karte-ocker); line-height: 1.9;
}
.karte-titel {
  font-family: var(--garamond); font-style: italic;
  font-size: 1.04rem; line-height: 1.5;
  color: var(--karte-matt);
  margin-bottom: .9rem;
}

.karte-zeilen { display: flex; flex-direction: column; gap: .5rem; }
.karte-zeile  { display: flex; flex-wrap: wrap; gap: .1rem .8rem; align-items: baseline; }
.karte-was {
  flex: 0 0 4.4rem;
  font-family: var(--fell-sc);
  font-size: .64rem; letter-spacing: .17em; text-transform: uppercase;
  color: var(--karte-matt); line-height: 2.1;
}
.karte-wert {
  flex: 1 1 10rem; min-width: 0;
  font-family: var(--fell);
  font-size: 1.1rem; line-height: 1.5; letter-spacing: -.004em;
  color: var(--karte-tinte);
}
.karte-wert small {
  display: block;
  font-family: var(--garamond); font-size: .86rem;
  color: var(--karte-matt); line-height: 1.5;
}

.karte-eintritt {
  font-family: var(--fell);
  font-size: 1.5rem; line-height: 1.2; letter-spacing: -.01em;
}
.karte-stand {
  display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
  font-family: var(--fell-sc);
  font-size: .62rem; letter-spacing: .15em; text-transform: uppercase;
  color: var(--karte-matt); line-height: 1.7;
}
.punkt {
  display: inline-block; width: 6px; height: 6px; flex: none;
  border-radius: 50%; background: var(--karte-ocker);
}

/* Auf dem Telefon liegt der Abriss unten, und die Kerben
   wandern an die Seiten. */
@media (max-width: 560px) {
  .karte {
    flex-direction: column;
    --riss: 72%;
    -webkit-mask:
      radial-gradient(circle var(--kerbe) at 0    var(--riss), transparent 98%, #000 100%) left  / 50.5% 100% no-repeat,
      radial-gradient(circle var(--kerbe) at 100% var(--riss), transparent 98%, #000 100%) right / 50.5% 100% no-repeat;
            mask:
      radial-gradient(circle var(--kerbe) at 0    var(--riss), transparent 98%, #000 100%) left  / 50.5% 100% no-repeat,
      radial-gradient(circle var(--kerbe) at 100% var(--riss), transparent 98%, #000 100%) right / 50.5% 100% no-repeat;
  }
  .karte-abriss {
    border-left: 0;
    border-top: 1px dashed rgba(47,40,32,.38);
    flex-direction: row; justify-content: space-between; align-items: center;
    gap: 1rem; text-align: left;
  }
}

@media (prefers-contrast: more) {
  .karte { --karte-matt: #4b4136; }
  .karte-abriss { border-left-color: rgba(47,40,32,.7); }
}

/* ── Der Programmzettel ───────────────────────────────────────
   Dieselbe Karte, anderes Format. Die Eintrittskarte ist quer
   und hat einen Abriss; der Zettel steht hochkant und hat keinen.
   Deshalb auch keine Kerben: Zwei perforierte Papiere nebeneinander
   waeren zweimal dieselbe Geste.

   Die Nummern kommen aus einem CSS-Zaehler, nicht aus dem Markup.
   Eine Reihenfolge, die man an zwei Stellen pflegen muss, geht
   irgendwann auseinander. */

.zettel {
  position: relative;
  max-width: 26rem;
  margin: var(--luft-5) auto 0;
  padding: clamp(1.6rem, 5vw, 2.4rem) clamp(1.4rem, 5vw, 2.4rem) clamp(1.5rem, 4.5vw, 2.1rem);
  background: var(--karte-papier);
  color: var(--karte-tinte);
  text-align: center;
  box-shadow: 0 1px 2px rgba(0,0,0,.5), 0 20px 56px rgba(0,0,0,.45);
}

/* Dieselbe doppelte Haarlinie wie auf der Eintrittskarte -- daran
   erkennt man die beiden als ein Paar. */
.zettel::before,
.zettel::after {
  content: ''; position: absolute; left: 0; right: 0; height: 3px;
  pointer-events: none;
  background:
    linear-gradient(var(--karte-ocker), var(--karte-ocker)) top    / 100% 1px no-repeat,
    linear-gradient(rgba(47,40,32,.3), rgba(47,40,32,.3))   bottom / 100% 1px no-repeat;
  opacity: .55;
}
.zettel::before { top: 6px; }
.zettel::after  { bottom: 6px; transform: scaleY(-1); }

.zettel-marke {
  font-family: var(--fell-sc);
  font-size: .66rem; letter-spacing: .24em; text-transform: uppercase;
  color: var(--karte-ocker); line-height: 1.9;
}
.zettel-titel {
  font-family: var(--fell);
  font-size: clamp(1.5rem, 4.6vw, 1.9rem);
  line-height: 1.2; letter-spacing: -.012em;
  color: var(--karte-tinte);
  margin-top: .15rem;
}
.zettel-regel {
  display: block; width: clamp(140px, 44%, 200px); height: auto;
  margin: .7rem auto 1.3rem;
  color: var(--karte-ocker);
}

/* Das Vorspiel traegt keine Nummer: Es ist die Ouvertuere, nicht
   das erste Stueck. */
.zettel-vorspiel {
  font-family: var(--fell);
  font-size: 1.06rem; line-height: 1.5;
  padding-bottom: 1rem;
  border-bottom: 1px solid rgba(47,40,32,.22);
}
.zettel-vorspiel span {
  display: block;
  font-family: var(--fell-sc);
  font-size: .6rem; letter-spacing: .2em; text-transform: uppercase;
  color: var(--karte-matt); line-height: 2.2;
}

/* Die Liste steht linksbuendig, der Block aber mittig: max-content
   macht ihn so breit wie seine laengste Zeile, nicht so breit wie
   der Zettel. Sonst klebt er links, waehrend der Kopf mittig steht
   -- gemessen 371 Pixel Block bei 155 Pixel laengster Zeile.
   Kein fester Wert, damit ein laengerer Titel ihn mitwachsen
   laesst statt umzubrechen. */
.zettel-folge {
  counter-reset: stueck;
  list-style: none;
  width: max-content; max-width: 100%;
  margin: 1.1rem auto .4rem; padding: 0;
  text-align: left;
}
.zettel-folge li {
  counter-increment: stueck;
  display: grid;
  grid-template-columns: 2rem 1fr;
  align-items: baseline;
  gap: .1rem .5rem;
  padding-block: .3rem;
  font-family: var(--fell);
  font-size: 1.06rem; line-height: 1.5; letter-spacing: -.004em;
}
.zettel-folge li::before {
  content: counter(stueck) '.';
  font-family: var(--fell-sc);
  font-size: .76rem; letter-spacing: .06em;
  color: var(--karte-ocker);
  text-align: right;
}

@media (max-width: 420px) {
  .zettel-folge li { grid-template-columns: 1.6rem 1fr; font-size: 1rem; }
}

@media (prefers-contrast: more) {
  .zettel { --karte-matt: #4b4136; }
  .zettel-vorspiel { border-bottom-color: rgba(47,40,32,.7); }
}

/* ══════════════════════════════════════════════════════════
   KAPITEL — ein grosser Satz, mittig, viel Luft
   ══════════════════════════════════════════════════════════ */

/* overflow-x: clip, nicht hidden: clip macht keinen Scrollbereich
   auf und laesst sticky und fixed in Ruhe. Noetig, weil der Schein
   hinter den Ockerzeilen absichtlich breiter ist als sein Text --
   ohne diese Zeile wuchs das Dokument bei 390 Pixeln auf 457. Der
   Schein wird jetzt genau an der Bildschirmkante abgeschnitten,
   wo er ohnehin aufhoert, sichtbar zu sein. */
.kapitel {
  padding-block: var(--luft-7) 0;
  text-align: center;
  overflow-x: clip;
}
.kapitel .marke { margin-bottom: var(--luft-3); }

.kapitel h2 {
  margin: 0 auto var(--luft-5);
  font-family: var(--fell); font-weight: 400;
  font-size: var(--t-kapitel);
  line-height: 1.18;
  letter-spacing: -0.014em;
  max-width: 19ch;
  text-wrap: balance;
}

/* Mittig gesetzter Fliesstext liest sich schlecht -- das Auge
   findet den Zeilenanfang nicht. Der Rumpf steht linksbuendig
   in einer schmalen, mittigen Spalte. */
.kapitel-rumpf {
  text-align: left;
  display: flex; flex-direction: column; gap: var(--luft-3);
  max-width: var(--mass-lesen);
  margin-inline: auto;
  text-wrap: pretty;
}

/* Ein Satz, der allein steht. */
.satz {
  margin-block: var(--luft-5);
  font-family: var(--fell);
  font-size: var(--t-satz);
  line-height: 1.34; letter-spacing: -0.01em;
  color: var(--ocker);
  text-align: center;
  max-width: 22ch; margin-inline: auto;
  text-wrap: balance;
}

/* ══════════════════════════════════════════════════════════
   TAFELN — Bilder, die ihr Seitenverhaeltnis behalten
   ══════════════════════════════════════════════════════════ */

.tafel { margin-block: var(--luft-6) 0; }
.tafel figure { margin: 0 auto; }

/* Bilder werden nie gestreckt und nie ueber ihre eigene
   Aufloesung hinaus vergroessert -- beides macht sie unscharf.
   Jede Tafel traegt deshalb die Breite ihrer Datei als Grenze
   und das Seitenverhaeltnis der Aufnahme. */
.tafel img {
  width: 100%; height: auto;
  background: var(--grund-hoch);
}
/* Die Floeten stehen hochkant. Die Datei ist 844 breit, aber eine
   844 breite Saeule waere hier eine Wand: Das Bild ist ein Einwurf
   zwischen zwei Absaetzen, kein Kapitel fuer sich. */
.tafel--floete figure { max-width: 400px; }
.tafel--floete img { aspect-ratio: 844 / 1500; }

/* Das Wohnzimmer laeuft breit -- aber nie breiter als die Datei,
   sonst wird es unscharf. 960 ist ihre eigene Breite. */
.tafel--raum figure { max-width: 960px; }
.tafel--raum img { aspect-ratio: 16 / 9; }

/* ══════════════════════════════════════════════════════════
   DIE DIENSTE
   ══════════════════════════════════════════════════════════ */

.dienste { display: flex; flex-wrap: wrap; gap: var(--luft-2); justify-content: center; }
.dienst {
  display: inline-flex; align-items: center; gap: 0.7rem;
  min-height: 44px; padding: 0.75rem 1.25rem;
  border: 1px solid var(--linie);
  background: rgba(21, 16, 28, 0.5);
  color: var(--text); text-decoration: none;
  transition: border-color 400ms var(--aus), color 400ms var(--aus);
}
.dienst:hover { border-color: var(--ocker); color: var(--ocker); }
.dienst span { font-family: var(--fell-sc); font-size: 0.76rem; letter-spacing: 0.18em; text-transform: uppercase; }
.dienst em { font-family: var(--garamond); font-style: normal; font-size: 0.82rem; color: var(--tinte-blass); }

/* ══════════════════════════════════════════════════════════
   DER BRIEF
   ══════════════════════════════════════════════════════════ */

.brief {
  display: flex; flex-direction: column; align-items: center;
  gap: var(--luft-2);
  max-width: 30rem; margin-inline: auto; margin-top: var(--luft-4);
  background: rgba(21, 16, 28, 0.6);
  border: 1px solid var(--linie);
  padding: clamp(1.6rem, 4.5vw, 2.6rem);
  text-align: center;
}
.brief-marke {
  font-family: var(--fell-sc); font-size: 0.7rem;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--tinte-matt);
}
.brief-adresse {
  font-family: var(--fell);
  font-size: clamp(1.12rem, 2vw, 1.4rem);
  line-height: 1.4; letter-spacing: -0.004em;
  color: var(--ocker);
  text-decoration: none; word-break: break-word;
  border-bottom: 1px solid rgba(212, 165, 116, 0.35);
}
.brief-adresse:hover { border-bottom-color: var(--ocker); }
.knopf {
  margin-top: var(--luft-1);
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0.9rem 2rem;
  border: 1px solid var(--akzent); background: var(--akzent); color: #14100a;
  text-decoration: none;
  font-family: var(--fell-sc); font-size: 0.76rem;
  letter-spacing: 0.2em; text-transform: uppercase; cursor: pointer;
  transition: background 400ms var(--aus);
}
.knopf:hover { background: var(--akzent-hell); color: #14100a; }
.hinweis {
  width: 100%;
  font-family: var(--garamond); font-size: 0.84rem; line-height: 1.7;
  color: var(--tinte-matt);
  border-top: 1px solid var(--linie);
  padding-top: var(--luft-2); margin-top: var(--luft-1);
}

/* ══════════════════════════════════════════════════════════
   DER FUSS
   ══════════════════════════════════════════════════════════ */

footer { margin-top: var(--luft-7); border-top: 1px solid var(--linie); text-align: center; }
footer > div {
  display: flex; flex-wrap: wrap; gap: var(--luft-1) var(--luft-4);
  align-items: baseline; justify-content: center;
  padding-block: var(--luft-4) var(--luft-5);
  font-family: var(--garamond); font-size: 0.9rem; color: var(--tinte-matt);
}
footer a { color: var(--tinte-matt); }
footer a:hover { color: var(--ocker); }

/* ══════════════════════════════════════════════════════════
   WER ES RUHIGER, FESTER ODER DEUTLICHER BRAUCHT
   ══════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition-duration: 0.01ms !important; }
  .glas-titel { opacity: 1; letter-spacing: 0.02em; }
}

@media (prefers-reduced-transparency: reduce) {
  .glas { opacity: 0.3; }
}

@media (prefers-contrast: more) {
  :root {
    --tinte-weich: rgba(47, 40, 32, 0.96);
    --tinte-matt:  #463d33;
    --tinte-blass: #5a4e42;
    --linie:       rgba(47, 40, 32, 0.34);
  }
  .dienst, .brief { border-color: rgba(212, 165, 116, 0.5); }
  .monde-name { color: #f3ece0; }
}

/* ══════════════════════════════════════════════════════════
   DAS EDITORIAL

   Vier Dinge, die alle nach derselben Regel gebaut sind: Ohne
   Skript, im sparsamen Modus und bei prefers-reduced-motion
   steht die Seite vollstaendig und ruhig da. Nichts, was Sinn
   traegt, haengt an einer Animation.

   Die Klasse .js kommt aus einer Zeile im Kopf, noch vor dem
   ersten Bildaufbau. Ohne sie ist nichts verborgen.
   ══════════════════════════════════════════════════════════ */

/* ── Der Goldstaub ────────────────────────────────────────────
   Derselbe wie auf der Schwelle, aus derselben Datei: Koerner,
   die dem Finger ausweichen und danach an ihren Platz zurueck-
   treiben. Er liegt auf der Ebene des Mondes, also unter allem
   Text und ueber dem Grund. Im Kopf ist davon nichts zu sehen:
   Das Kirchenfenster hat einen eigenen, deckenden Grund, und
   das soll so bleiben.

   Er kommt nicht sofort, sondern geht auf -- wie alles andere
   auf dieser Seite. staub.js steigt im sparsamen Modus und bei
   prefers-reduced-motion von selbst aus; display: none ist nur
   der Riegel davor. */
.staub {
  position: fixed; inset: 0; z-index: -1;
  pointer-events: none;
  opacity: 0;
  animation: staubKommt 2.6s var(--aus) 0.6s forwards;
}
@keyframes staubKommt { to { opacity: 0.76; } }
html.low-power .staub { display: none; }
@media (prefers-reduced-motion: reduce) { .staub { display: none; } }

/* ══════════════════════════════════════════════════════════
   DIE SCHAU
   Die hochkanten Filme, dieselbe Schiene wie auf der Musik-
   seite. Das Skript dort zeichnet sie; hier stehen nur die
   Farben und Masze dieser Seite davor -- derselbe Ocker,
   dieselbe Kurve, dieselben Luftstufen.
   ══════════════════════════════════════════════════════════ */

.schau { padding-block: var(--luft-6) 0; }

.schau-zeile {
  margin: var(--luft-2) auto 0;
  max-width: var(--mass-eng);
  font-family: var(--garamond); font-style: italic;
  font-size: var(--t-klein);
  color: var(--text-matt);
}

.shorts-gallery {
  position: relative;
  margin-top: var(--luft-4);
}

/* Der Streifen wird gepolstert, nicht zentriert: justify-content
   auf einer scrollenden Reihe macht den linken Ueberhang in
   mehreren Browsern unerreichbar. Eine Polsterung von der halben
   Restbreite tut dasselbe und laesst jede Kachel in Reichweite.

   940 statt der 980, die vier Kacheln zusammen messen: So ragt
   die vierte auf jeder Breite ein Stueck ueber den Rand. Ein
   Streifen, der genau aufgeht, sieht aus wie eine fertige Reihe
   und laedt niemanden zum Schieben ein.

   Kein scroll-snap: Die Polsterung schiebt den Einrastpunkt der
   ersten Kachel weiter nach rechts, als ueberhaupt gescrollt
   werden kann -- der Browser landet dann beim Laden ganz rechts,
   und der Streifen beginnt am Ende. */
.shorts-rail {
  display: flex;
  gap: 20px;
  overflow-x: auto;
  padding: 0.6rem max(var(--rand), calc((100% - 940px) / 2)) 1.4rem;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.shorts-rail::-webkit-scrollbar { display: none; }
.shorts-rail:focus-visible { outline: 1px solid rgba(212, 165, 116, 0.5); outline-offset: -4px; }

.short {
  flex: 0 0 auto;
  width: clamp(148px, 42vw, 230px);
  aspect-ratio: 9 / 16;
  position: relative;
  display: block;
  padding: 0;
  border: 0;
  border-radius: 2px;
  overflow: hidden;
  cursor: pointer;
  background: #0c0a10;
  box-shadow:
    0 0 0 1px rgba(212, 165, 116, 0.18),
    0 16px 42px rgba(0, 0, 0, 0.58);
  transition: transform 550ms var(--aus), box-shadow 550ms var(--aus);
}
.short img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Auf einem grossen Schirm sitzen vier Kacheln zu 230 Pixeln
   verloren in der Mitte. Sie wachsen an denselben zwei Schwellen
   wie drueben. */
@media (min-width: 1500px) { .short { width: 268px; } }
@media (min-width: 2000px) { .short { width: 300px; } }
.short:hover, .short:focus-visible {
  transform: translateY(-5px);
  box-shadow:
    0 0 0 1px rgba(212, 165, 116, 0.42),
    0 24px 56px rgba(0, 0, 0, 0.66);
}

/* Das Zeichen sitzt tief und klein: Zuerst soll das Standbild
   gesehen werden, die Einladung danach. */
.short-play {
  position: absolute;
  left: 50%; bottom: 14px;
  transform: translateX(-50%);
  display: grid; place-items: center;
  width: 42px; height: 42px;
  border-radius: 50%;
  background: rgba(8, 7, 12, 0.62);
  color: var(--creme);
  box-shadow: inset 0 0 0 1px rgba(212, 165, 116, 0.38);
  transition: background 450ms var(--aus), color 450ms var(--aus);
}
.short-play svg { width: 20px; height: 20px; margin-left: 2px; }
.short:hover .short-play { background: rgba(212, 165, 116, 0.82); color: var(--nacht); }

/* Die Pfeile zeigen sich, wo es etwas zu schieben gibt -- fuer
   Finger wie fuer Maus. Ohne sie gibt ein Beruehrungsschirm kein
   Zeichen, dass die Reihe ueber den Rand weitergeht. */
.shorts-arrow {
  position: absolute;
  top: calc(50% - 10px);
  transform: translateY(-50%);
  display: grid; place-items: center;
  width: 46px; height: 46px;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  background: rgba(10, 8, 14, 0.72);
  color: rgba(245, 241, 232, 0.85);
  box-shadow: inset 0 0 0 1px rgba(212, 165, 116, 0.3);
  transition: opacity 400ms var(--aus), background 400ms var(--aus), color 400ms var(--aus);
}
.shorts-arrow svg { width: 22px; height: 22px; }
.shorts-arrow--prev { left: clamp(0.4rem, 2vw, 1.6rem); }
.shorts-arrow--next { right: clamp(0.4rem, 2vw, 1.6rem); }
.shorts-arrow:hover { background: rgba(212, 165, 116, 0.8); color: var(--nacht); }
.shorts-arrow:disabled { opacity: 0; pointer-events: none; }

/* Es passt schon alles: Es gibt nichts, wohin zu schieben waere. */
.shorts--static .shorts-arrow { display: none; }

/* Bis jemand die Reihe einmal geschoben hat, lehnt sich der
   vordere Pfeil alle paar Sekunden dorthin. Vier Pixel, langsam
   -- genug, um als Einladung gelesen zu werden, zu wenig, um zu
   draengeln. Bei der ersten Beruehrung hoert es auf. */
@keyframes schauWinkt {
  0%, 60%, 100% { transform: translateX(0); }
  72%           { transform: translateX(4px); }
  84%           { transform: translateX(0); }
}
.shorts--untouched .shorts-arrow--next:not(:disabled) svg {
  animation: schauWinkt 3.6s var(--aus) infinite;
}
html.low-power .shorts-arrow--next svg { animation: none !important; }

/* ── Das Fenster ──────────────────────────────────────────── */
.shorts-box {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center;
  padding: 1rem;
  background: rgba(4, 3, 7, 0.94);
  backdrop-filter: blur(6px);
}
.shorts-box[hidden] { display: none; }

.shorts-box-stage { display: grid; gap: 0.9rem; justify-items: center; }
/* Hochkant, und nie hoeher als der Schirm, auf dem es gezeigt
   wird. Die Breite folgt aus der Hoehe, damit der Film nie
   schwarze Balken bekommt. */
.shorts-box-frame {
  width: min(calc(100vw - 2rem), calc((100svh - 9rem) * 9 / 16), 430px);
  aspect-ratio: 9 / 16;
  border-radius: 3px;
  overflow: hidden;
  background: #000;
  box-shadow:
    0 0 0 1px rgba(212, 165, 116, 0.22),
    0 30px 80px rgba(0, 0, 0, 0.7);
}
.shorts-box-frame iframe { width: 100%; height: 100%; border: 0; display: block; }

.shorts-box-nav {
  display: flex; align-items: center; gap: 1.1rem;
  color: rgba(245, 241, 232, 0.7);
}
.shorts-box-step, .shorts-box-close {
  display: grid; place-items: center;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  background: rgba(245, 241, 232, 0.07);
  color: inherit;
  box-shadow: inset 0 0 0 1px rgba(212, 165, 116, 0.26);
  transition: background 400ms var(--aus), color 400ms var(--aus);
}
.shorts-box-step { width: 40px; height: 40px; }
.shorts-box-step svg { width: 20px; height: 20px; }
.shorts-box-step:hover, .shorts-box-close:hover {
  background: rgba(212, 165, 116, 0.8); color: var(--nacht);
}
.shorts-box-count {
  font-family: var(--fell-sc);
  font-size: 0.78rem;
  letter-spacing: 0.2em;
  font-variant-numeric: tabular-nums;
}
.shorts-box-close {
  position: absolute;
  top: clamp(0.6rem, 2vh, 1.6rem);
  right: clamp(0.6rem, 2vw, 1.6rem);
  width: 44px; height: 44px;
  color: rgba(245, 241, 232, 0.85);
}
.shorts-box-close svg { width: 22px; height: 22px; }

/* Fuer jemanden, der das Zeichen nicht sehen kann. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Das Skript drueben schreibt jede Beschriftung zweisprachig --
   die Musikseite hat einen Sprachschalter, diese nicht. Hier
   bleibt es bei einer Sprache. */
.lang-en { display: none; }

@media (prefers-reduced-motion: reduce) {
  .short, .short-play, .shorts-arrow,
  .shorts-box-step, .shorts-box-close { transition: none; }
  .shorts-arrow--next svg { animation: none !important; }
  .short:hover, .short:focus-visible { transform: none; }
  .shorts-rail { scroll-behavior: auto; }
}

/* ── Die Sternschnuppe ────────────────────────────────────────
   Einmal pro Besuch, leicht zu verpassen -- von der Startseite
   uebernommen, Wort fuer Wort dieselbe Bahn.

   box-shadow statt drop-shadow: iOS zeichnet einen drop-shadow
   auf einem bewegten, durchsichtigen Element als milchiges
   Rechteck nach. */
.sternschnuppe {
  position: fixed;
  top: 16%; left: -12%;
  width: clamp(80px, 10vw, 130px); height: 2px;
  z-index: -1;
  border-radius: 2px;
  background: linear-gradient(90deg, transparent, rgba(243, 236, 224, 0.9));
  box-shadow: 0 0 8px rgba(243, 236, 224, 0.5);
  transform: rotate(14deg);
  opacity: 0;
  pointer-events: none;
}
.sternschnuppe.los { animation: schnuppenFlug 1.7s var(--aus) forwards; }
@keyframes schnuppenFlug {
  0%   { opacity: 0;    transform: translate3d(0, 0, 0) rotate(14deg); }
  12%  { opacity: 0.85; }
  70%  { opacity: 0.5; }
  100% { opacity: 0;    transform: translate3d(88vw, 24vh, 0) rotate(14deg); }
}

/* ── Die Initiale ─────────────────────────────────────────────
   Der erste Buchstabe jedes Absatzes, der ueber zwei Zeilen
   laeuft, in der Schrift des Titels und in Gold.

   Ein echtes Element und nicht ::first-letter -- initials.js
   setzt es, weil erst nach dem Satz feststeht, wie viele Zeilen
   ein Absatz hat. Dieselbe Datei wie auf der Musikseite.

   Die enge Zeilenhoehe haelt den Kasten des Buchstabens klein
   genug, dass die erste Zeile nicht aufgeschoben wird. */
.initial {
  font-family: 'CCSBjork', var(--fell), serif;
  font-weight: 300;
  color: var(--akzent);
  font-size: 2.2em;
  line-height: 0.72;
  padding-right: 0.03em;
}

/* ── Das Auftauchen ───────────────────────────────────────────
   Marke, Ueberschrift, Rumpf und Ockerzeile steigen nacheinander
   aus der Tiefe. Nur transform und opacity -- beides laeuft im
   Compositor und zwingt den Browser zu keinem neuen Satz.

   Verstecken und Zeigen stehen auf derselben Liste, und das
   Skript setzt .da auf genau diese Elemente. Zwei Listen, die
   auseinanderlaufen koennen, waeren hier ein Fehler mit stiller
   Wirkung: Ein vergessenes Element bliebe fuer immer unsichtbar.

   Kein background-clip: text und kein filter auf diesen
   Elementen. Auf iOS verschwinden Ueberschriften, die beides
   tragen, vollstaendig -- teuer erkauftes Wissen. */
.js .kapitel .marke,
.js .kapitel h2,
.js .kapitel-rumpf,
.js .schau-zeile,
.js .shorts-gallery,
.js .satz,
.js .zettel,
.js .karte,
.js .brief,
.js .fund {
  opacity: 0;
  transform: translate3d(0, 20px, 0);
  transition: opacity 900ms var(--aus), transform 900ms var(--aus);
}

.js .kapitel .marke.da,
.js .kapitel h2.da,
.js .kapitel-rumpf.da,
.js .schau-zeile.da,
.js .shorts-gallery.da,
.js .satz.da,
.js .zettel.da,
.js .karte.da,
.js .brief.da,
.js .fund.da {
  opacity: 1;
  transform: none;
}

/* Die Staffelung. Die Marke ist zuerst da, dann die Zeile,
   dann der Text -- so liest sich ein Kapitelanfang, wie man
   ihn auch im Buch liest. */
.js .kapitel h2.da    { transition-delay: 110ms; }
.js .kapitel-rumpf.da { transition-delay: 210ms; }

/* ── Der Atem hinter der Ockerzeile ───────────────────────────
   Die Zitate pulsieren nicht selbst -- ein Text, der die
   Helligkeit wechselt, liest sich schlecht. Stattdessen atmet
   ein Schein dahinter, neun Sekunden hin, neun zurueck:
   langsam genug, dass man ihn eher spuert als sieht. Dieselbe
   Dauer wie der Schein im Unterrichtskasten auf der Musikseite.

   Der Schein liegt hinter dem Text, nicht darauf: sonst saenke
   der Kontrast mit jedem Atemzug. */
.satz { position: relative; }
.satz::before {
  content: '';
  position: absolute;
  inset: -45% -28%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(ellipse at 50% 50%,
    rgba(212, 165, 116, 0.13) 0%, transparent 68%);
  animation: satzAtem 9s ease-in-out infinite alternate;
}
@keyframes satzAtem {
  from { opacity: 0.45; transform: scale(0.94); }
  to   { opacity: 1;    transform: scale(1.06); }
}

/* ── Wer es ruhiger oder sparsamer braucht ───────────────────
   Der Atem hoert auf, die Sternschnuppe faellt aus, und alles,
   was sich einblendet, steht einfach da. Die Initiale bleibt:
   Sie ist Satz, keine Bewegung. */
html.low-power .satz::before,
html.low-power .sternschnuppe { display: none; }

html.low-power.js .kapitel h2,
html.low-power.js .satz { transition-duration: 400ms; }

@media (prefers-reduced-motion: reduce) {
  .satz::before { animation: none; opacity: 0.7; transform: none; }
  .sternschnuppe { display: none; }

  .js .kapitel .marke,
  .js .kapitel h2,
  .js .kapitel-rumpf,
  .js .schau-zeile,
  .js .shorts-gallery,
  .js .satz,
  .js .zettel,
  .js .karte,
  .js .brief,
  .js .fund {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ══════════════════════════════════════════════════════════
   DIE MONDSEQUENZ

   Drei Momente, drei Ausschnitte derselben Tafel aus Galileis
   Sidereus Nuncius von 1610. Die Zeichnung ist nicht bearbeitet:
   Die Ausschnitte sind an den gemessenen Zeilenbaendern der
   Tafel geschnitten, sonst nichts. Ein Weisspunkt-Eingriff haette
   die Dateien sogar groesser gemacht -- harte Kanten kosten mehr
   Bits als weiches Rauschen.

   Das Blatt bleibt hell. Auf der Nachtseite liest es sich dann
   als aufgeschlagenes Buch auf einem dunklen Tisch -- genau das
   Bild, um das es geht. Das Licht faellt darueber, nicht dahinter.

   Bewegung gibt es nur zwei: das Licht wandert beim Scrollen
   ueber das Papier, und jedes Blatt taucht beim Erreichen weich
   auf. Keine Choreografie, die abgespielt wird.

   iOS-Safari: Der Schatten des Papiers ist ein box-shadow auf
   einem unverschobenen Element. Ein drop-shadow-Filter wuerde
   dort zu einem milchigen Rechteck rastern.
   ══════════════════════════════════════════════════════════ */

.fund { text-align: center; }

.fund .marke { margin-bottom: var(--luft-3); }

/* Das Blatt ───────────────────────────────────────────────── */
.blatt {
  position: relative;
  margin-inline: auto;
  background: #f1eee5;
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.55),
    0 22px 70px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}
.blatt img { display: block; width: 100%; height: auto; }

/* Das einzige Galileo-Blatt der Seite, und deshalb groesser als
   damals, als es eins von dreien war. 640 statt 540 -- die Datei
   ist 760 breit, darueber wuerde sie unscharf. */
.blatt--tafel { max-width: 640px; }

/* Das Licht auf dem Papier. --lx und --ly setzt schein.js aus
   dem Scrollstand; ohne Skript steht der Fleck ruhig oben links. */
.blatt::before,
.blatt::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
}
/* Erst die Tiefe: das Papier ist nicht gleichmaessig hell. */
.blatt::before {
  background: radial-gradient(ellipse 120% 100% at var(--lx, 34%) var(--ly, 26%),
    rgba(255, 244, 222, 0) 0%, rgba(58, 44, 28, 0.1) 46%, rgba(40, 30, 18, 0.22) 100%);
  mix-blend-mode: multiply;
}
/* Dann der warme Fleck, als faele er durch ein Fenster. */
.blatt::after {
  background: radial-gradient(circle 42% at var(--lx, 34%) var(--ly, 26%),
    rgba(255, 221, 166, 0.6) 0%, rgba(255, 206, 142, 0.24) 40%, transparent 72%);
  mix-blend-mode: overlay;
}

/* Der Satz unter dem Blatt ────────────────────────────────── */
.fund-quelle {
  margin: var(--luft-3) auto 0;
  font-family: var(--garamond);
  font-size: 0.86rem; line-height: 1.7;
  letter-spacing: 0.02em;
  color: var(--text-blass);
  max-width: 42ch;
}
.fund-quelle em { font-style: italic; }

/* Das Blatt taucht langsamer auf als der Text: anderthalb
   Sekunden statt neun Zehnteln. Ein Bild, das so schnell
   erscheint wie eine Zeile, wirkt geschaltet. */
.js .fund    { transition-duration: 1.4s; }
