/* =========================================================================
   Schriften
   =========================================================================

   Selbst ausgeliefert, nicht von einem fremden Server (RIC-17). Vorher kam
   die Schrift von fonts.bunny.net - kein Tracking und EU-gehostet, aber
   trotzdem ein Dritter, der die IP jedes Besuchers zu sehen bekommt. Auf der
   Startseite steht, dass wir keine Daten an Dritte weitergeben; das muss
   auch fuer das Laden einer Schriftdatei gelten.

   Die Dateien liegen unter public/fonts, Herkunft und Lizenz stehen in
   public/fonts/SCHRIFTEN.md.

   'font-display: swap' ist Absicht: Lieber sofort in der Systemschrift lesen
   als eine Sekunde auf ein leeres Blatt sehen.

   Je Schnitt zwei Dateien, latin und latin-ext. Die zweite laedt der Browser
   nur, wenn ein Zeichen daraus vorkommt - deutsche Umlaute stecken bereits
   in latin, ein Name mit ł oder ő zieht latin-ext nach.
   ========================================================================= */

/* Dancing Script 700, latin */
@font-face {
  font-family: 'Dancing Script';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/dancing-script-latin-700-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* Dancing Script 700, latin-ext */
@font-face {
  font-family: 'Dancing Script';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/dancing-script-latin-ext-700-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* IBM Plex Mono 400, latin */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-latin-400-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* IBM Plex Mono 400, latin-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-latin-ext-400-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* IBM Plex Mono 500, latin */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-latin-500-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* IBM Plex Mono 500, latin-ext */
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/ibm-plex-mono-latin-ext-500-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* IBM Plex Sans 400, latin */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/ibm-plex-sans-latin-400-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* IBM Plex Sans 400, latin-ext */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/ibm-plex-sans-latin-ext-400-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* IBM Plex Sans 500, latin */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/ibm-plex-sans-latin-500-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* IBM Plex Sans 500, latin-ext */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/ibm-plex-sans-latin-ext-500-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* IBM Plex Sans 600, latin */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/ibm-plex-sans-latin-600-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* IBM Plex Sans 600, latin-ext */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/ibm-plex-sans-latin-ext-600-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/* IBM Plex Sans 700, latin */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/ibm-plex-sans-latin-700-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

/* IBM Plex Sans 700, latin-ext */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/ibm-plex-sans-latin-ext-700-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}

/*
 * Oeffentliche Seite der Adventsaktion.
 *
 * Enthaelt bewusst KEINEN einzigen Farbwert. Alle Farben kommen als
 * CSS-Variablen aus config/design.php und werden vom Layout in den
 * :root-Block geschrieben. Wer eine Farbe aendern will, aendert sie dort -
 * einmal, fuer die oeffentliche Seite und das Backend gemeinsam.
 *
 * Gestaltung folgt der Designvorlage unter design/: warmes Papierweiss,
 * Tannengruen als einziger Akzent, IBM Plex Sans/Mono.
 */

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

html {
  -webkit-text-size-adjust: 100%;
  color-scheme: light;
}

.buch-weg {
  position: relative;
}

/* Die Funken beim Umblaettern fliegen ueber den Buchrand hinaus - rueckwaerts
   nach rechts aus dem Bildschirm. Die Seite wurde dadurch kurz breiter als
   das Handy, und der Browser schob alles seitlich: Der Hintergrund waberte
   (RIC-91). "clip" statt "hidden", damit nichts zum Scrollbereich wird.
   Nicht auf grossen Bildschirmen: Dort stehen die Pfeile neben dem Buch. */
@media (max-width: 71.999rem) {
  .buch-weg {
    overflow-x: clip;
    /* Luft fuer den Buchschatten - so weit, wie das Buch vom
       Bildschirmrand entfernt steht. */
    overflow-clip-margin: 0.5rem;
  }
}

/* Ein einziger weicher Haltepunkt (RIC-88): Wer in die Naehe des Buchs
   scrollt, bleibt mittig darauf stehen - am Handy wie am Rechner (Nils).
   "proximity" haelt nur in der Naehe - wer zuegig weiterscrollt, kommt
   vorbei. Nicht wieder eine Kette von Rastpunkten: Die kaempften am iPhone
   gegen den Schwung.
   Kopfzeile und Dank-Hinweis stehen fest und verdecken oben und unten ein
   Stueck - gerastet und gesprungen wird deshalb in den Bereich dazwischen. */
html:has(.buch--blaettern) {
  scroll-snap-type: y proximity;
  scroll-padding-top: var(--buch-kopf, 0px);
  scroll-padding-bottom: var(--buch-fuss, 0px);
}

.buch-weg:has(.buch--blaettern) {
  scroll-snap-align: center;
}

body {
  margin: 0;
  background: var(--papier);
  color: var(--text);
  font-family: 'IBM Plex Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* ---------- Grundelemente ---------- */

h1,
h2,
h3 {
  line-height: 1.25;
  letter-spacing: -0.02em;
  margin: 0 0 0.5em;
  font-weight: 600;
}

h1 {
  font-size: clamp(1.75rem, 1.3rem + 2.2vw, 2.6rem);
}

h2 {
  font-size: clamp(1.25rem, 1.1rem + 0.9vw, 1.6rem);
}

h3 {
  font-size: 1.05rem;
}

p {
  margin: 0 0 1em;
}

p:last-child {
  margin-bottom: 0;
}

a {
  color: var(--akzent);
  text-underline-offset: 0.2em;
}

a:hover {
  color: var(--akzent-dunkel);
}

small {
  font-size: 0.85rem;
}

.mono {
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, monospace;
  font-variant-numeric: tabular-nums;
}

/* ---------- Seitenaufbau ---------- */

.seite {
  max-width: 46rem;
  margin: 0 auto;
  padding: 0 1.25rem;
}

/*
 * Der Seitenkopf.
 *
 * Er klebt oben und sieht auf jeder Seite gleich aus. Vorher hatte er drei
 * Zustaende: eine schwarze Leiste auf den Formularen, einen abdunkelnden
 * Verlauf ueber einem Kopfbereich mit Motiv, und gar nichts ueber dem
 * hellen. Derselbe Kopf sah dreimal anders aus, je nachdem wo man stand.
 *
 * Statt eines Verlaufs eine getoente Scheibe: hell, halbdurchsichtig, mit
 * Weichzeichner dahinter. Sie steht auf jedem Untergrund lesbar - ueber
 * einem dunklen Foto wie ueber Papier - und laesst das Motiv durchscheinen,
 * statt es unter einem grauen Balken zu begraben.
 *
 * Ohne JavaScript, und das ist Absicht: Diese Seite kommt bisher ganz ohne
 * aus. Ein Kopf, der beim Scrollen sein Aussehen wechselt, waere das erste
 * Skript hier - fuer einen Effekt, den 'sticky' und der Weichzeichner
 * zusammen schon leisten.
 */
/*
 * Die Vorlage des Elfen steht als unsichtbares <svg> vor dem Kopf und darf
 * keinen Platz kosten (RIC-46).
 *
 * width="0" height="0" macht sie unsichtbar, nicht aber platzlos: Ein <svg>
 * ist ein Inline-Element, und ein Inline-Element zieht eine Zeilenbox nach
 * sich - bei line-height 1.6 auf 1rem sind das 25,6 Pixel. Genau so viel
 * Luft stand ueber dem Kopf, solange die Seite oben war; sobald er beim
 * Scrollen oben ankleben musste, fiel sie weg. Der Kopf schien dadurch zu
 * schrumpfen, obwohl seine Hoehe sich nie geaendert hat.
 *
 * Absolut statt display:none, weil <use> sich seine Vorlage aus einem
 * ausgeblendeten Baum in aelteren Browsern nicht zuverlaessig holt.
 */
.elf__vorlage {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.kopf {
  position: sticky;
  top: 0;
  z-index: 20;
  /*
   * Fast deckend, nicht halbdurchsichtig. Bei 82% schien das dunkle Motiv
   * durch und die Leiste wurde grau - genau der graue Balken, den sie
   * ersetzen sollte. Der Weichzeichner bleibt: Er nimmt dem Rest die harte
   * Kante, wenn Inhalt darunter durchlaeuft.
   */
  background: color-mix(in srgb, var(--papier) 94%, transparent);
  backdrop-filter: blur(16px) saturate(1.2);
  -webkit-backdrop-filter: blur(16px) saturate(1.2);
  border-bottom: 1px solid color-mix(in srgb, var(--linie) 70%, transparent);
  color: var(--text);
}

/*
 * Am Telefon ohne Weichzeichner und ganz deckend (RIC-67). Bei 94 Prozent
 * Deckkraft sieht man vom Weichzeichnen kaum etwas, das Telefon muss es
 * aber bei jedem Bild neu rechnen, sobald darunter Schnee faellt - und
 * das liess den Kopfbereich stocken.
 */
@media (max-width: 48rem) {
  .kopf {
    background: var(--papier);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

/*
 * Kann der Browser den Weichzeichner nicht, wird die Scheibe deckend -
 * sonst staende die Schrift halbdurchsichtig auf einem Foto.
 */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .kopf {
    background: var(--papier);
  }
}


/* Sprungmarke fuer Tastatur und Screenreader - sichtbar erst bei Fokus. */
.sprungmarke {
  position: absolute;
  left: 50%;
  translate: -50% -150%;
  z-index: 10;
  background: var(--akzent);
  color: var(--auf-akzent);
  padding: 0.7rem 1.2rem;
  border-radius: 0 0 8px 8px;
  text-decoration: none;
  transition: translate 0.15s ease;
}

.sprungmarke:focus {
  translate: -50% 0;
  color: var(--auf-akzent);
}

/* Breiter als das schmale Blatt, aber nicht bis an den Bildschirmrand
   (RIC-53). Der Name steht links, der Kontakt rechts. */
.kopf__inhalt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  max-width: 74rem;
  margin-inline: auto;
  padding: 0.7rem 1.25rem;
}

.kopf__marke {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  min-width: 0;
  text-decoration: none;
  color: inherit;
}

.kopf__kontakt {
  flex: none;
  display: flex;
  align-items: center;
  text-decoration: none;
  color: var(--text-leise);
}

.kopf__kontakt-text {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
}

.kopf__kontakt-name {
  font-size: 0.8rem;
  line-height: 1.3;
  color: var(--text-still);
}

.kopf__kontakt-mail {
  font-size: 0.9rem;
  font-weight: 500;
  line-height: 1.3;
}

.kopf__kontakt:hover .kopf__kontakt-mail {
  color: var(--akzent);
}

/* Das Briefsymbol gibt es nur am Handy - dort ersetzt es Name und Adresse. */
.kopf__kontakt-symbol {
  display: none;
  width: 1.5rem;
  height: 1.5rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

@media (max-width: 40rem) {
  .kopf__kontakt-text {
    display: none;
  }

  .kopf__kontakt {
    /* Gross genug zum Treffen mit dem Daumen. */
    width: 2.75rem;
    height: 2.75rem;
    justify-content: center;
    border-radius: 50%;
  }

  .kopf__kontakt-symbol {
    display: block;
  }

  .kopf__kontakt:hover {
    color: var(--akzent);
  }
}

.kopf__logo {
  flex: none;
  width: 2.5rem;
  height: 2.5rem;
  object-fit: contain;
}

/* Name und Traeger untereinander statt nebeneinander: Nebeneinander riss die
   Zeile am Handy um, und der Traeger stand dann allein darunter - dasselbe
   Bild, nur unbeabsichtigt. */
.kopf__namen {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.kopf__name {
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.2;
}

.kopf__traeger {
  color: var(--text-still);
  font-size: 0.8rem;
  line-height: 1.3;
  /* Am Handy zaehlt die Hoehe des Kopfes mehr als der Untertitel. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Logo und Name sind der Weg zurueck, nicht nur der Name. */
.kopf__marke:hover .kopf__name {
  color: var(--akzent);
}

/*
 * Der Inhalt liegt als Blatt auf der Landschaft: eigener Papiergrund, an den
 * Seiten schmaler als der Bildschirm, damit links und rechts das Winterbild
 * stehen bleibt. Am Handy verliert das Blatt seine Raender und nimmt die
 * volle Breite - dort ist fuer beides kein Platz, und der Text hat Vorrang.
 */
main {
  position: relative;
  padding-block: clamp(2rem, 1rem + 5vw, 3.5rem) 3rem;
  background: var(--papier);
}

/*
 * Das Blatt behaelt auf jeder Breite einen Rand.
 *
 * Zuerst lief es am Telefon randlos ueber die volle Breite - und damit war
 * vom Hintergrund dort ueberhaupt nichts mehr zu sehen, also genau bei den
 * meisten Besuchern. Ein schmaler Streifen reicht, um zu zeigen, dass die
 * Seite auf etwas liegt; der Text verliert dabei kaum Platz, weil der
 * Innenabstand entsprechend kleiner wird.
 */
body:has(.landschaft) main,
body:has(.werkstatt) main {
  max-width: 58rem;
  margin-inline: auto;
  margin-block: 0.9rem 1.4rem;
  border-radius: 0.6rem;
  box-shadow: 0 0 2.5rem color-mix(in srgb, var(--schleier) 22%, transparent);
}

@media (max-width: 63.999rem) {
  body:has(.landschaft) main,
  body:has(.werkstatt) main {
    margin-inline: 1rem;
    /* Deutlich mehr Luft ueber und unter dem Blatt als am Schreibtisch: Am
       Telefon sind diese Baender die einzige Flaeche, auf der der
       Hintergrund gross genug ist, um erkannt zu werden. Ein 12-Pixel-
       Streifen am Rand zeigt nur Farbflecken. */
    margin-block: 2.5rem 3rem;
  }

  /* Der Innenabstand der Seite und der Rand des Blattes summieren sich
     sonst zu einer sehr schmalen Textspalte. */
  body:has(.landschaft) main > .seite,
  body:has(.werkstatt) main > .seite {
    padding-inline: 0.9rem;
  }

  /* Auch der Fuss rueckt ab, damit die Seite im Hintergrund ausklingt. */
  body:has(.landschaft) .fuss,
  body:has(.werkstatt) .fuss {
    padding-block: 2.5rem 3rem;
  }
}

/*
 * Der Countdown.
 *
 * Ein schmaler dunkler Streifen unter dem Kopfbereich. Dunkel, weil direkt
 * darunter der getoente Dank-Streifen liegt: zwei helle Baender uebereinander
 * verschwimmen zu einem breiten Rand, in dem beide Botschaften untergehen.
 *
 * Die Zahl traegt Gold und die Monospace-Schrift. Gold liegt hier auf
 * dunklem Grund und ist damit lesbar - auf dem hellen Papier waere es das
 * nicht, deshalb steht der Streifen dunkel und nicht der Rest der Seite.
 */
.countdown {
  /* Ueber der Landschaft, wie Hero und Fuss - ohne das laege der
     Hintergrund vor dem eigenen Grund. */
  position: relative;
  background: var(--akzent-tief);
  color: var(--text-hell);
  /* Zwei goldene Haarlinien statt einer. Unter einem dunklen Kopfbereich -
     die Zuordnungsphase hat einen - liegt Schwarz auf Schwarz, und ohne die
     obere Linie franst der Streifen nach oben aus, statt einer zu sein. */
  border-block: 1px solid color-mix(in srgb, var(--gold) 30%, transparent);
  padding-block: 0.7rem;
}

.countdown__reihe {
  /* Nicht "margin: 0": Das Element traegt auch .seite, deren "margin: 0 auto"
     es in der Spalte haelt - so wie beim Dank darunter. */
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 0.3rem 1.5rem;
}

.countdown__punkt {
  margin-block: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.45rem;
  font-size: 0.82rem;
  /* Die geplanten Aktionen stehen leiser als die laufende: Sie sind ein
     Ausblick, keine Frist. */
  color: color-mix(in srgb, var(--text-hell) 72%, transparent);
}

.countdown__punkt--haupt {
  font-size: 0.9rem;
  color: var(--text-hell);
}

.countdown__zeit {
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, monospace;
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--gold-hell);
}

.countdown__datum {
  font-size: 0.76rem;
  color: color-mix(in srgb, var(--text-hell) 48%, transparent);
}

.countdown__anlass a {
  color: inherit;
  text-underline-offset: 0.2em;
}

.countdown__anlass a:hover {
  color: var(--gold-hell);
}

/* Am Handy steht jede Aktion in ihrer eigenen Zeile und das Datum darf
   fehlen - drei Angaben je Zeile ergeben sonst einen Absatz aus Umbruechen. */
@media (max-width: 40rem) {
  .countdown__reihe {
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
  }

  .countdown__punkt:not(.countdown__punkt--haupt) .countdown__datum {
    display: none;
  }
}


/*
 * Der Dank.
 *
 * Ein schmaler Streifen unter dem Kopfbereich. Er soll gelesen werden, aber
 * nichts vom Weg abhalten: getoenter Grund statt Karte, kleine Schrift, eine
 * Zeile Hoehe, wo es geht. Wer sich anmelden will, scrollt daran vorbei;
 * wer wissen will, wer dahintersteht, bleibt haengen.
 */
/* Der Dank-Streifen unter dem Kopfbereich.

   Eine Zeile, mehr nicht - und genau das war diese Stelle immer. Der
   ausfuehrliche Dank stand hier eine Zeit lang selbst und war dann der
   laengste Block der Seite, an der Stelle, an der jemand wissen will, wie
   die Aktion funktioniert. Er steht jetzt am Ende; hier bleibt der Verweis
   darauf. */
.dankbanner {
  position: relative;
  background: color-mix(in srgb, var(--akzent-tint) 60%, var(--papier));
  border-bottom: 1px solid var(--linie);
  padding-block: 0.85rem;
}

.dankbanner__wort {
  /* Nicht "margin: 0": Das Element traegt auch .seite, und deren
     "margin: 0 auto" haelt es in der Spalte. Ohne das auto klebte der
     Streifen am linken Bildschirmrand, waehrend der Rest der Seite mittig
     stand. */
  margin-block: 0;
  margin-inline: auto;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--text-leise);
  text-align: center;
  text-wrap: balance;
}

.dankbanner__wort a {
  color: var(--akzent-dunkel);
  text-underline-offset: 0.2em;
}

.dankbanner__wort a:hover {
  color: var(--akzent);
}

/* Der Verweis nach unten. Eine Spur ruhiger als der Link in der Zeile
   selbst: Er ist ein Wegweiser, kein zweiter Gedanke. */
.dankbanner__mehr {
  margin-inline-start: 0.35rem;
  white-space: nowrap;
}

/* Der Dank.

   War einmal ein schmaler Streifen fuer einen Satz. Geliefert wurde ein
   Grusswort ueber vier Absaetze - und das ist keine Panne, sondern der
   Zweck: Es sind die Worte der Aktion, und sie sollen stehen bleiben
   duerfen. Also traegt die Form den Text, statt ihn zu quetschen.

   Drei Dinge sind deshalb anders als beim Streifen: linksbuendig statt
   zentriert (bei dreizehn Zeilen findet das Auge sonst den Zeilenanfang
   nicht wieder), Lesegroesse statt Kleingedrucktem, und echte Absaetze mit
   Abstand.

   Er steht jetzt am Seitenende, direkt vor dem Fuss - deshalb oben eine
   Linie statt unten: Er schliesst den Inhalt ab, statt etwas einzuleiten. */
.dank {
  position: relative;
  background: color-mix(in srgb, var(--akzent-tint) 60%, var(--papier));
  border-top: 1px solid var(--linie);
  padding-block: clamp(2rem, 5vw, 3.25rem);
  /* Unten mehr: Dort haengt das Lesebaendchen aus dem Buch. */
  padding-block-end: clamp(3.75rem, 6vw, 4.75rem);
  /* Damit der Sprung aus dem Streifen nicht unter dem klebenden Kopf
     landet. */
  scroll-margin-top: 5rem;
}

/* --- Das Wichtelbuch (RIC-61) --------------------------------------------
   Der Dank steht in einem aufgeschlagenen Buch: roter Einband mit goldener
   Naht, zwei Seiten mit Falz dazwischen, ein Lesebaendchen haengt unten
   heraus. Am Handy liegt nur eine Seite - zwei Spalten auf 400 Pixeln
   waeren zwei Zeilen mit je drei Woertern.

   Die Schrift ist dieselbe Schreibschrift wie die grosse Ueberschrift. Es
   gibt sie nur fett - deshalb groesser gesetzt und mit mehr Zeilenabstand,
   damit vier Absaetze lesbar bleiben. */
.dank__buch {
  /* Nicht "margin: 0": Das Element traegt auch .seite, und deren
     "margin: 0 auto" haelt es in der Spalte. */
  --buch-seite: color-mix(in srgb, var(--karte) 90%, var(--gold));
  --buch-falz: color-mix(in srgb, var(--buch-seite) 80%, var(--text));
  --buch-einband: color-mix(in srgb, var(--akzent) 70%, var(--akzent-tief));
  position: relative;
  margin-inline: auto;
  /* Breiter als die Textspalte der Seite: Ein aufgeschlagenes Buch liegt
     quer. In der schmalen Spalte stand es hochkant wie ein Notizblock. */
  width: min(100% - 1.5rem, 64rem);
  max-width: none;
  padding: clamp(0.5rem, 1.4vw, 0.9rem);
  background: var(--buch-einband);
  border-radius: 0.7rem;
  box-shadow:
    0 1.2rem 2.4rem -0.6rem color-mix(in srgb, var(--text) 30%, transparent),
    0 0.3rem 0.6rem color-mix(in srgb, var(--text) 12%, transparent);
}

/* Die Ziernaht auf dem Einband: eine gestrichelte Goldlinie rundherum. */
.dank__buch::before {
  content: '';
  position: absolute;
  inset: 0.22rem;
  border: 1px dashed color-mix(in srgb, var(--gold-hell) 75%, transparent);
  border-radius: 0.55rem;
  pointer-events: none;
}

.dank__inhalt {
  position: relative;
  padding: clamp(1.5rem, 5vw, 3rem) clamp(1.25rem, 5vw, 3.25rem);
  background: var(--buch-seite);
  border-radius: 0.3rem;
  /* Die Seitenkanten unten: drei Blaetter, jedes eine Spur dunkler. */
  box-shadow:
    0 2px 0 -0.5px color-mix(in srgb, var(--buch-seite) 92%, var(--text)),
    0 4px 0 -1px color-mix(in srgb, var(--buch-seite) 86%, var(--text)),
    0 6px 0 -1.5px color-mix(in srgb, var(--buch-seite) 80%, var(--text));
  font-family: 'Dancing Script', 'Segoe Script', cursive;
  font-weight: 700;
}

/* Das Lesebaendchen: steckt oben im Buch und haengt unten mit
   eingekerbtem Ende heraus. Gruen gegen den roten Einband. */
.dank__lesezeichen {
  position: absolute;
  z-index: 1;
  right: 14%;
  top: calc(100% - 0.6rem);
  width: 1.3rem;
  height: 3.2rem;
  background: var(--tanne);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 78%, 0 100%);
  filter: drop-shadow(0 2px 2px color-mix(in srgb, var(--text) 25%, transparent));
}

/* Ab Tablettbreite liegt das Buch offen: zwei Spalten, dazwischen der
   Falz. Der Falz ist ein Verlauf auf dem Papier und kein Element - so
   sitzt er immer genau in der Mitte, auch wenn die Spalten wandern. */
@media (min-width: 48rem) {
  .dank__inhalt {
    columns: 2;
    column-gap: clamp(4rem, 7vw, 6rem);
    background: linear-gradient(to right,
      var(--buch-seite) 0%,
      color-mix(in srgb, var(--buch-seite) 94%, var(--text)) 3%,
      var(--buch-seite) 10%,
      var(--buch-seite) 44%,
      color-mix(in srgb, var(--buch-seite) 88%, var(--text)) 49.2%,
      var(--buch-falz) 50%,
      color-mix(in srgb, var(--buch-seite) 88%, var(--text)) 50.8%,
      var(--buch-seite) 56%,
      var(--buch-seite) 90%,
      color-mix(in srgb, var(--buch-seite) 94%, var(--text)) 97%,
      var(--buch-seite) 100%);
  }

  .dank__titel,
  .dank__unterschrift {
    break-inside: avoid;
  }
}

.dank__titel {
  margin-block: 0 0.75rem;
  font-family: inherit;
  font-weight: 700;
  font-size: clamp(1.9rem, 1.5rem + 1.6vw, 2.5rem);
  line-height: 1.15;
  color: var(--akzent-dunkel);
  text-wrap: balance;
}

.dank__wort {
  color: var(--text);
  font-size: clamp(1.25rem, 1.15rem + 0.4vw, 1.4rem);
}

/* Die Absaetze selbst. Der Abstand steht zwischen ihnen und nicht aussen
   herum, damit der erste nicht vom Titel abrueckt und der letzte nicht von
   der Unterschrift. */
.dank__wort p {
  margin-block: 0;
  line-height: 1.5;
  /* Kein text-wrap: balance. Das wirkt bis etwa sechs Zeilen, danach
     steigen die Browser ohnehin aus - hier kostet es nur Rechenzeit. */
  text-wrap: pretty;
}

.dank__wort p + p,
.dank__wort:not(:empty) + .dank__schluss {
  margin-block-start: 0.9rem;
}

.dank__wort a {
  color: var(--akzent-dunkel);
  text-underline-offset: 0.2em;
}

.dank__wort a:hover {
  color: var(--akzent);
}

/* Die Unterschrift. Sie macht aus dem Abschnitt ein Wort von jemandem -
   und erst dadurch darf er so lang sein. */
/* Rechtsbuendig wie unter einem Brief und in der Farbe der Unterschrift
   im Kopfbereich (RIC-61) - ohne Gedankenstrich, eine Unterschrift von
   Hand hat keinen. */
.dank__unterschrift {
  margin-block: 1.5rem 0;
  text-align: right;
  font-size: clamp(1.9rem, 1.5rem + 1.6vw, 2.6rem);
  line-height: 1.1;
  color: var(--akzent);
}

/* =========================================================================
   Das Wichtelbuch als Seite (RIC-84)
   =========================================================================

   Der ganze Inhalt der Startseite steht in einem Buch mit gleich grossen
   Seiten. Es bleibt beim Scrollen in der Stube stehen und blaettert um;
   der Text bricht sich dabei selbst auf Seiten um (siehe
   components/buch.blade.php und public/js/buch.js).

   Die Seiten sind Spalten: .buch__text hat genau die Hoehe einer Seite,
   und was nicht hineinpasst, fliesst in weitere Spalten rechts daneben.
   Das Fenster zeigt davon zwei (Schreibtisch) oder eine (Handy) und
   schneidet den Rest ab; umgeblaettert wird, indem der Text um eine
   Fensterbreite nach links rueckt. Damit das aufgeht, ist der Spalten-
   abstand genau doppelt so breit wie der Seitenrand - dann ist eine
   Doppelseite exakt eine Fensterbreite.

   Ohne Skript (oder bei reduzierter Bewegung) fehlt .buch--blaettern: Dann
   steht das Buch lang untereinander, Kapitel fuer Kapitel.

   Die Erklaertexte stehen in der Grundschrift, wie gedruckt. Nur
   Ueberschriften und der Dank sind handgeschrieben. */

/* Das Blatt Papier, auf dem der Inhalt sonst liegt, faellt weg: Das Buch
   ist selbst das Papier. */
main.inhalt--buch {
  background: transparent;
}

main.inhalt--buch > .seite {
  max-width: 66rem;
}

body:has(.werkstatt) main.inhalt--buch {
  max-width: none;
  box-shadow: none;
  border-radius: 0;
}

@media (max-width: 63.999rem) {
  body:has(.werkstatt) main.inhalt--buch {
    margin-inline: 0.5rem;
  }

  body:has(.werkstatt) main.inhalt--buch > .seite {
    padding-inline: 0;
  }
}

.buch {
  --buch-seite: color-mix(in srgb, var(--karte) 90%, var(--gold));
  --buch-falz: color-mix(in srgb, var(--buch-seite) 80%, var(--text));
  --buch-einband: color-mix(in srgb, var(--akzent) 70%, var(--akzent-tief));
  --buch-rand: clamp(1.25rem, 4vw, 2.75rem);
  position: relative;
  margin-inline: auto;
  max-width: 64rem;
  padding: clamp(0.45rem, 1.4vw, 0.9rem);
  background: var(--buch-einband);
  border-radius: 0.7rem;
  box-shadow:
    0 1.2rem 2.4rem -0.6rem color-mix(in srgb, var(--text) 30%, transparent),
    0 0.3rem 0.6rem color-mix(in srgb, var(--text) 12%, transparent);
}

/* Die Ziernaht auf dem Einband, wie am Dank-Buch. */
.buch::before {
  content: '';
  position: absolute;
  inset: 0.22rem;
  border: 1px dashed color-mix(in srgb, var(--gold-hell) 75%, transparent);
  border-radius: 0.55rem;
  pointer-events: none;
}

/* Das Fenster auf die aufgeschlagenen Seiten. Am Handy der Bundsteg links
   als Schatten, am Schreibtisch der Falz in der Mitte. */
.buch__fenster {
  position: relative;
  overflow: clip;
  border-radius: 0.3rem;
  background: linear-gradient(to right,
    var(--buch-falz) 0%,
    color-mix(in srgb, var(--buch-seite) 90%, var(--text)) 1.5%,
    var(--buch-seite) 7%);
  /* Die Seite der Blaetter, die umschlagen - siehe unten. */
  --blatt-vorn: linear-gradient(to right,
    color-mix(in srgb, var(--buch-seite) 84%, var(--text)) 0%,
    var(--buch-seite) 8%);
  --blatt-hinten: linear-gradient(to left,
    color-mix(in srgb, var(--buch-seite) 84%, var(--text)) 0%,
    var(--buch-seite) 8%);
}

.buch__text {
  position: relative;
  padding: clamp(1.25rem, 3vw, 2rem) var(--buch-rand) 2.75rem;
}

/* Die Seiten sind zentriert gesetzt wie in einem Geschenkbuch: Ueberschrift,
   Zierlinie, Text auf der Mittelachse jeder Seite. */
.buch__kapitel {
  text-align: center;
}

.buch__auge {
  margin: 0 0 0.35rem;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--akzent);
}

.buch__titel {
  margin-block: 0 0.75rem;
  font-family: 'Dancing Script', 'Segoe Script', cursive;
  font-weight: 700;
  font-size: clamp(1.9rem, 1.5rem + 1.6vw, 2.5rem);
  line-height: 1.15;
  color: var(--akzent-dunkel);
  text-wrap: balance;
  break-after: avoid;
}

/* Unter jeder Kapitelueberschrift eine goldene Zierlinie mit einem Punkt
   in der Mitte. */
.buch__titel::after {
  content: '';
  display: block;
  width: 7rem;
  height: 0.6rem;
  margin: 0.7rem auto 0;
  background:
    radial-gradient(circle, var(--gold) 0 0.18rem, transparent 0.22rem) center / 0.6rem 0.6rem no-repeat,
    linear-gradient(var(--gold), var(--gold)) left center / 42% 1px no-repeat,
    linear-gradient(var(--gold), var(--gold)) right center / 42% 1px no-repeat;
}

.buch__auge {
  break-after: avoid;
}

/* Im Buch stehen die Schritte untereinander, das Zeichen mittig ueber
   seinem Text. */
.buch .schritte {
  display: block;
}

.buch .schritt {
  grid-template-columns: 1fr;
  justify-items: center;
  gap: 0.25rem;
  break-inside: avoid;
  margin-bottom: 0.8rem;
}

/* Etwas kleinere Zeichen als auf der Seite sonst: Alle vier Schritte
   sollen auf die erste Seite passen. */
.buch .schritt__symbol,
.buch .schritt:not(.schritt--mit-symbol)::before {
  width: 2rem;
  height: 2rem;
}

.buch .schritt__symbol svg {
  width: 1.15rem;
  height: 1.15rem;
}

.buch .punkte {
  display: block;
}

/* Ein Punkt darf ueber den Seitenumbruch laufen wie ein Absatz im Druck.
   Ganz zusammengehalten liess er unten Luecken, und der Datenschutz passte
   nicht mehr auf eine Doppelseite.
   Der Punkt steht zentriert ueber jedem Absatz statt links davor - links
   haengend passt er nicht zu zentriertem Text. Er sitzt im Innenabstand
   oben und nicht als eigener Block darueber: Einen Block durfte der
   Browser vom Text trennen, dann hing der Punkt unten auf der einen Seite
   und der Absatz begann auf der naechsten - und die Seiten liessen sich
   nicht mehr senkrecht mittig setzen (RIC-88). */
.buch .punkte li {
  padding-left: 0;
  padding-top: 0.85rem;
}

/* Nur fuer das Element selbst, das das Skript mittig gesetzt hat - erbte
   die Variable, rueckten beim mittig gesetzten Kapitel alle Punkte darin
   mit in den Text. */
@property --zentriert {
  syntax: '<length>';
  inherits: false;
  initial-value: 0px;
}

.buch .punkte li::before {
  left: 50%;
  /* Rueckt mit, wenn das Skript den Punkt senkrecht mittig setzt. Der
     Wert kommt ausdruecklich vom eigenen Punkt, nicht vom Kapitel. */
  --zentriert: inherit;
  top: var(--zentriert, 0px);
  margin-left: -0.225rem;
}

.buch .punkte li + li {
  margin-top: 0.7rem;
}

.buch .vertrauen__schluss {
  break-inside: avoid;
  margin-top: 0.7rem;
  padding-top: 0.6rem;
}

/* Der Fliesstext eine Spur kleiner als auf der Seite sonst: Der
   Datenschutz soll auf eine Doppelseite passen, auch zwischen Countdown
   und Dank-Hinweis. */
.buch__kapitel:not(.buch__kapitel--hand) {
  font-size: 0.95rem;
}

/* Am Schreibtisch haengt die Seitenhoehe am Bildschirm. Auf einem
   niedrigen Laptop (768-800 Pixel) wird die Schrift deshalb etwas kleiner,
   damit der Datenschutz auf seiner Doppelseite bleibt, statt einen
   einzelnen Satz auf die naechste zu schieben. */
@media (min-width: 48rem) {
  .buch__kapitel:not(.buch__kapitel--hand) {
    font-size: clamp(0.8rem, 1.45vh + 0.15rem, 0.95rem);
  }
}

.buch .punkte li + li {
  margin-top: 0.55rem;
}

/* Der Dank ist handgeschrieben, wie im Dank-Buch. */
.buch__kapitel--hand {
  font-family: 'Dancing Script', 'Segoe Script', cursive;
  font-weight: 700;
}

.buch__kapitel--hand .dank__unterschrift {
  break-inside: avoid;
  text-align: center;
}

/* Am Handy haben der letzte Absatz und die Unterschrift zusammen eine
   eigene Seite - sonst stand die Unterschrift allein auf der letzten und
   wirkte verloren (RIC-88). Nur wenn davor noch Text steht: Sonst bliebe
   die Ueberschrift allein zurueck. */
@media (max-width: 47.999rem) {
  .buch--blaettern .dank__schluss {
    break-inside: avoid;
  }

  /* Ohne Abstand oben: An einem erzwungenen Umbruch bliebe er stehen, und
     die Seite liesse sich nicht mehr mittig setzen. */
  .buch--blaettern .dank__wort:not(:empty) + .dank__schluss {
    break-before: column;
    margin-block-start: 0;
  }
}

/* Die Schlussseiten: Wichtel und Familien, jede endet mit ihrem Knopf. */
.buch__seite {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.9rem;
  break-inside: avoid;
}

.buch__seite p {
  margin: 0;
  color: var(--text-leise);
}

.buch__seite--familie .buch__titel {
  color: var(--empfaenger-dunkel);
}

.buch__fuss {
  margin-top: 0.5rem;
  color: var(--text-still);
}

.buch__leerseite,
.buch__zahl {
  display: none;
}

/* Das Lesebaendchen haengt unten aus dem Buch. */
.buch__lesezeichen {
  position: absolute;
  z-index: 1;
  right: 14%;
  top: calc(100% - 0.6rem);
  width: 1.3rem;
  height: 3.2rem;
  background: var(--tanne);
  clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 78%, 0 100%);
}

/* --- Ohne Umblaettern: das Buch lang untereinander ----------------------- */

.buch:not(.buch--blaettern) .buch__kapitel + .buch__kapitel,
.buch:not(.buch--blaettern) .buch__leerseite + .buch__kapitel {
  margin-top: 2.5rem;
  padding-top: 2.5rem;
  border-top: 1px dashed color-mix(in srgb, var(--buch-seite) 70%, var(--text));
}

.buch:not(.buch--blaettern) .buch__seite + .buch__seite {
  margin-top: 2rem;
}

@media (min-width: 48rem) {
  .buch:not(.buch--blaettern) .buch__kapitel {
    columns: 2;
    column-gap: calc(var(--buch-rand) * 2);
  }

  .buch:not(.buch--blaettern) .buch__kapitel--schluss {
    columns: auto;
    display: grid;
    grid-template-columns: 1fr 1fr;
    column-gap: calc(var(--buch-rand) * 2);
  }

  .buch:not(.buch--blaettern) .buch__seite + .buch__seite {
    margin-top: 0;
  }
}

/* --- Mit Umblaettern ----------------------------------------------------- */

/* Die Hoehe setzt das Skript - sie haengt an der Bildschirmhoehe.
   Senkrecht gehoert der Finger dem Browser, die Seite scrollt also wie
   immer; waagerecht wischt er im Buch (RIC-88). */
.buch--blaettern .buch__fenster {
  height: var(--buch-hoehe, 36rem);
  perspective: 2600px;
  touch-action: pan-y pinch-zoom;
}

.buch--blaettern .buch__text {
  box-sizing: border-box;
  height: 100%;
  /* Am Handy eine Seite breit - als Spaltenbreite, nicht als
     "column-count: 1": Eine einzelne Spalte setzt Safari (und damit jeder
     Browser am iPhone) nicht als Spaltensatz, der Text lief dort einfach
     nach unten weiter, und es gab nichts umzublaettern (RIC-91). Die
     Breite misst das Skript. */
  column-count: auto;
  column-width: var(--buch-spalte, 18rem);
  column-gap: calc(var(--buch-rand) * 2);
  column-fill: auto;
}

@media (min-width: 48rem) {
  .buch__fenster {
    background: linear-gradient(to right,
      var(--buch-seite) 0%,
      color-mix(in srgb, var(--buch-seite) 94%, var(--text)) 3%,
      var(--buch-seite) 10%,
      var(--buch-seite) 44%,
      color-mix(in srgb, var(--buch-seite) 88%, var(--text)) 49.2%,
      var(--buch-falz) 50%,
      color-mix(in srgb, var(--buch-seite) 88%, var(--text)) 50.8%,
      var(--buch-seite) 56%,
      var(--buch-seite) 90%,
      color-mix(in srgb, var(--buch-seite) 94%, var(--text)) 97%,
      var(--buch-seite) 100%);
    --blatt-vorn: linear-gradient(to right,
      color-mix(in srgb, var(--buch-seite) 88%, var(--text)) 0%,
      var(--buch-seite) 12%,
      var(--buch-seite) 80%,
      color-mix(in srgb, var(--buch-seite) 94%, var(--text)) 94%,
      var(--buch-seite) 100%);
    --blatt-hinten: linear-gradient(to left,
      color-mix(in srgb, var(--buch-seite) 88%, var(--text)) 0%,
      var(--buch-seite) 12%,
      var(--buch-seite) 80%,
      color-mix(in srgb, var(--buch-seite) 94%, var(--text)) 94%,
      var(--buch-seite) 100%);
  }

  .buch--blaettern .buch__text {
    column-count: 2;
    column-width: auto;
  }
}

/* Jedes Kapitel beginnt auf einer neuen Seite, die Familien auf der
   rechten neben den Wichteln (am Handy auf der naechsten). */
.buch--blaettern .buch__kapitel + .buch__kapitel,
.buch--blaettern .buch__leerseite + .buch__kapitel,
.buch--blaettern .buch__seite--familie {
  break-before: column;
}

/* Die leere Seite vor dem Schluss traegt einen kleinen Stern, damit sie
   nicht aussieht wie vergessen. */
.buch--blaettern .buch__leerseite.ist-an {
  display: grid;
  place-items: center;
  break-before: column;
  break-inside: avoid;
  height: calc(var(--buch-hoehe, 36rem) - 6.5rem);
}

.buch__vorsatz {
  display: none;
}

@media (min-width: 48rem) {
  .buch--blaettern .buch__vorsatz {
    display: grid;
    place-items: center;
    break-inside: avoid;
    height: calc(var(--buch-hoehe, 36rem) - 6.5rem);
  }

  .buch--blaettern .buch__vorsatz + .buch__kapitel {
    break-before: column;
  }
}

/* Mit Inhaltsverzeichnis (RIC-93) steht die Deckelinnenseite auch am Handy
   - als erste Seite. Das Verzeichnis oben, der Stern darunter. */
.buch--blaettern .buch__vorsatz:has(.buch__inhalt) {
  display: grid;
  place-items: center;
  align-content: center;
  gap: 1.6rem;
  break-inside: avoid;
  height: calc(var(--buch-hoehe, 36rem) - 6.5rem);
}

.buch--blaettern .buch__vorsatz:has(.buch__inhalt) + .buch__kapitel {
  break-before: column;
}

.buch__inhalt {
  width: min(100%, 22rem);
  text-align: center;
}

.buch__inhalt-titel {
  margin: 0 0 1.1rem;
  font-family: 'Dancing Script', 'Segoe Script', cursive;
  font-weight: 700;
  font-size: clamp(1.9rem, 1.5rem + 1.6vw, 2.5rem);
  line-height: 1.15;
  color: var(--akzent-dunkel);
}

/* Dieselbe goldene Zierlinie wie unter den Kapitelueberschriften. */
.buch__inhalt-titel::after {
  content: '';
  display: block;
  width: 7rem;
  height: 0.6rem;
  margin: 0.7rem auto 0;
  background:
    radial-gradient(circle, var(--gold) 0 0.18rem, transparent 0.22rem) center / 0.6rem 0.6rem no-repeat,
    linear-gradient(var(--gold), var(--gold)) left center / 42% 1px no-repeat,
    linear-gradient(var(--gold), var(--gold)) right center / 42% 1px no-repeat;
}

.buch__inhalt-liste {
  margin: 0;
  padding: 0;
  list-style: none;
  text-align: left;
}

.buch__inhalt-liste li + li {
  margin-top: 0.35rem;
}

/* Titel, gepunktete Linie, Seitenzahl - wie im gedruckten Buch. */
.buch__inhalt-liste a {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.3rem 0.2rem;
  border-radius: 0.3rem;
  color: var(--text);
  text-decoration: none;
}

.buch__inhalt-liste a::after {
  content: '';
  order: 1;
  flex: 1;
  min-width: 1.5rem;
  border-bottom: 2px dotted color-mix(in srgb, var(--gold) 70%, transparent);
  transform: translateY(-0.25em);
}

.buch__inhalt-seite {
  order: 2;
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, monospace;
  font-size: 0.85rem;
  color: var(--akzent-dunkel);
}

.buch__inhalt-liste a:hover,
.buch__inhalt-liste a:focus-visible {
  color: var(--akzent);
  background: color-mix(in srgb, var(--gold) 12%, transparent);
}

.buch__vorsatz::after,
.buch__leerseite.ist-an::after {
  content: '';
  width: 2.2rem;
  height: 2.2rem;
  background: color-mix(in srgb, var(--gold) 60%, var(--buch-seite));
  clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}

.buch--blaettern .buch__zahl {
  display: block;
  position: absolute;
  z-index: 1;
  bottom: 1rem;
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, monospace;
  font-size: 0.75rem;
  color: var(--text-still);
}

/* Mittig unter der Seite, mit Strichen, wie gedruckt. Leer bleibt leer. */
.buch__zahl--links,
.buch__zahl--rechts {
  left: 0;
  right: 0;
  text-align: center;
}

.buch__zahl:not(:empty)::before { content: '– '; }
.buch__zahl:not(:empty)::after  { content: ' –'; }

@media (min-width: 48rem) {
  .buch__zahl--links  { right: 50%; }
  .buch__zahl--rechts { left: 50%; }
}

/* --- Die Pfeile unter dem Buch (RIC-88) ----------------------------------- */

.buch__steuer {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.75rem;
  /* Unter dem Lesebaendchen durch, das aus dem Buch haengt. */
  margin-top: 2.8rem;
}

.buch__steuer[hidden] {
  display: none;
}

.buch__pfeil {
  display: grid;
  place-items: center;
  width: 2.9rem;
  height: 2.9rem;
  padding: 0;
  border: 1px solid color-mix(in srgb, var(--gold) 55%, transparent);
  border-radius: 50%;
  background: color-mix(in srgb, var(--karte) 90%, var(--gold));
  color: var(--tanne);
  cursor: pointer;
  box-shadow: 0 2px 6px rgb(0 0 0 / 0.18);
  transition: opacity 0.2s, transform 0.15s;
}

.buch__pfeil svg {
  width: 1.3rem;
  height: 1.3rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.buch__pfeil:hover:not(:disabled) {
  transform: scale(1.06);
}

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

.buch__pfeil:disabled {
  opacity: 0.35;
  cursor: default;
  box-shadow: none;
}

.buch__mitte {
  display: grid;
  justify-items: center;
  gap: 0.55rem;
}

.buch__punkte {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem;
}

.buch__punkt {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: color-mix(in srgb, var(--karte) 80%, transparent);
  box-shadow: 0 1px 2px rgb(0 0 0 / 0.25);
  transition: background 0.3s, scale 0.3s;
}

.buch__punkt.ist-an {
  background: var(--gold);
  scale: 1.35;
}

.buch__hinweis {
  margin: 0;
  padding: 0.35rem 0.9rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--karte) 90%, var(--gold));
  box-shadow: 0 2px 6px rgb(0 0 0 / 0.18);
  text-align: center;
  font-size: 0.85rem;
  line-height: 1.3;
  color: var(--text);
}

/* Solange das Buch zu ist, steht der Hinweis auf dem Deckel; beim
   Aufschlagen rutscht er hinunter zwischen die Pfeile. Den Abstand nach
   oben misst das Skript. */
.buch__hinweis {
  position: relative;
  z-index: 4;
  transition: transform 0.7s cubic-bezier(0.45, 0.05, 0.3, 1);
}

.buch__steuer.ist-auf-deckel .buch__hinweis {
  transform: translateY(var(--hinweis-hoch, 0px));
  animation: buch-hinweis-puls 2.4s ease-in-out infinite;
}

/* Pfeile links und rechts am Hinweis - es geht zur Seite. */
.buch__hinweis::before { content: '‹'; margin-right: 0.5em; font-weight: 700; }
.buch__hinweis::after  { content: '›'; margin-left: 0.5em; font-weight: 700; }

@keyframes buch-hinweis-puls {
  0%, 70%, 100% { scale: 1; }
  80% { scale: 1.07; }
  90% { scale: 1; }
}

/* Die wischende Hand auf dem Deckel: Sie setzt rechts auf, zieht nach
   links und hebt ab - immer wieder, solange das Buch zu ist. Nur auf dem
   echten Deckel, nicht auf dem Blatt, das beim Aufschlagen umdreht. */
.buch__wisch-hand {
  display: none;
}

@media (pointer: coarse) {
  .buch__zu .buch__wisch-hand {
    display: block;
    position: absolute;
    left: 50%;
    top: 61%;
    width: 4.2rem;
    margin-left: -2.1rem;
    fill: var(--schnee-weiss);
    filter: drop-shadow(0 3px 5px rgb(0 0 0 / 0.35));
    pointer-events: none;
    animation: buch-hand-wischt 2.6s ease-in-out infinite;
  }
}

@keyframes buch-hand-wischt {
  0%   { opacity: 0; translate: 4.5rem 0; rotate: 8deg; }
  15%  { opacity: 1; translate: 4.5rem 0; rotate: 8deg; }
  60%  { opacity: 1; translate: -4.5rem 0; rotate: -12deg; }
  75%  { opacity: 0; translate: -4.5rem 0; rotate: -12deg; }
  100% { opacity: 0; translate: -4.5rem 0; }
}

/* Solange das Buch zu ist, ruft der Weiter-Pfeil - am Rechner der
   naheliegende Weg hinein. Der Deckel selbst ist ebenfalls anklickbar. */
.buch__zu {
  cursor: pointer;
}

.buch__steuer.ist-auf-deckel .buch__pfeil--weiter {
  animation: buch-pfeil-ruft 1.8s ease-in-out infinite;
}

@keyframes buch-pfeil-ruft {
  0%, 100% { box-shadow: 0 2px 6px rgb(0 0 0 / 0.18), 0 0 0 0 color-mix(in srgb, var(--gold) 70%, transparent); }
  50%      { box-shadow: 0 2px 6px rgb(0 0 0 / 0.18), 0 0 0 0.6rem color-mix(in srgb, var(--gold) 0%, transparent); scale: 1.08; }
}

/* Der Deckel hebt sich kurz an, wenn das Buch ins Bild kommt. */
.buch__zu {
  transform-origin: left center;
}

.buch__zu.wackelt {
  animation: buch-deckel-anheben 1.1s cubic-bezier(0.45, 0.05, 0.3, 1);
}

@keyframes buch-deckel-anheben {
  0%, 100% { transform: rotateY(0); }
  35% { transform: rotateY(-22deg); }
  60% { transform: rotateY(-8deg); }
  75% { transform: rotateY(-14deg); }
}

/* Am Handy wird gewischt, am Rechner geklickt. Ausgegangen wird vom
   Rechner; nur ein Geraet mit grobem Zeiger (Finger) bekommt den Wisch-Text. */
.buch__hinweis-touch {
  display: none;
}

@media (pointer: coarse) {
  .buch__hinweis-touch {
    display: inline;
  }

  .buch__hinweis-maus {
    display: none;
  }
}

/* Mit der Maus ueber dem Deckel hebt er sich ein wenig - er geht auf. */
@media (hover: hover) {
  .buch__zu {
    transition: transform 0.35s cubic-bezier(0.45, 0.05, 0.3, 1);
  }

  .buch__zu:hover {
    transform: rotateY(-10deg);
  }
}

/*
 * Wichtelzauber am Rechner (RIC-88): Auf dem Deckel steht der Hinweis oben
 * ueber dem Titel, groesser, mit Goldrand, einem Schimmer, der darueber
 * laeuft, und Funken rundherum. Aufgeschlagen ist der Zauber vorbei.
 */
.buch__funken {
  display: none;
}

@media not (pointer: coarse) {
  .buch__hinweis {
    --hinweis-ziel: 0.13;
  }

  .buch__steuer.ist-auf-deckel .buch__hinweis {
    padding: 0.55rem 1.3rem;
    font-size: 1.02rem;
    font-weight: 600;
    color: var(--akzent-tief);
    border: 1.5px solid var(--gold);
    background:
      linear-gradient(110deg,
        transparent 35%,
        color-mix(in srgb, var(--gold-hell) 70%, transparent) 50%,
        transparent 65%) 0 0 / 250% 100% no-repeat,
      color-mix(in srgb, var(--karte) 90%, var(--gold));
    box-shadow:
      0 3px 10px rgb(0 0 0 / 0.25),
      0 0 18px color-mix(in srgb, var(--gold) 55%, transparent);
    animation:
      buch-hinweis-puls 2.4s ease-in-out infinite,
      buch-hinweis-schimmer 3.2s ease-in-out infinite;
  }

  .buch__hinweis::before,
  .buch__hinweis::after {
    content: '✦';
    color: var(--gold);
  }

  /* Aufgeschlagen ist man schon drin - dann braucht es kein "Schau rein". */
  .buch__steuer:not(.ist-auf-deckel):not(.ist-ende) .buch__hinweis {
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.4s, visibility 0s 0.4s;
  }

  .buch__steuer.ist-auf-deckel .buch__funken {
    display: block;
    position: absolute;
    inset: -1.1rem -1.6rem;
    pointer-events: none;
  }

  .buch__funken i {
    position: absolute;
    width: 1rem;
    height: 1rem;
    background: var(--gold-hell);
    clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%);
    filter: drop-shadow(0 0 3px var(--gold));
    opacity: 0;
    animation: buch-funkeln 2.2s ease-in-out infinite;
  }

  .buch__funken i:nth-child(1) { left: 2%;  top: 8%;  animation-delay: 0s; }
  .buch__funken i:nth-child(2) { left: 30%; top: -4%; animation-delay: 0.7s; scale: 0.7; }
  .buch__funken i:nth-child(3) { left: 66%; top: 0;   animation-delay: 1.3s; }
  .buch__funken i:nth-child(4) { right: 1%; top: 30%; animation-delay: 0.35s; scale: 0.8; }
  .buch__funken i:nth-child(5) { left: 48%; bottom: -6%; animation-delay: 1s; scale: 0.6; }
  .buch__funken i:nth-child(6) { left: 10%; bottom: 0; animation-delay: 1.7s; scale: 0.75; }
}

/* Die Funken, die beim Umblaettern hinter der Blattkante herziehen. Das
   Skript setzt Ort, Flugweg und Groesse je Funke. */
.buch__funke {
  position: absolute;
  z-index: 6;
  width: 1.2rem;
  height: 1.2rem;
  margin: -0.6rem 0 0 -0.6rem;
  /* Sattes Gold, damit die Funken auch auf den hellen Seiten leuchten. */
  background: var(--gold);
  clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%);
  filter: drop-shadow(0 0 5px var(--gold-hell)) drop-shadow(0 0 2px var(--gold));
  pointer-events: none;
  opacity: 0;
  animation: buch-funke-stiebt 1.1s ease-out both;
}

.buch__funke:nth-child(3n) {
  background: var(--gold-hell);
}

@keyframes buch-funke-stiebt {
  0%   { opacity: 0; transform: translate(0, 0) scale(0) rotate(0deg); }
  20%  { opacity: 1; transform: translate(calc(var(--dx) * 0.2), calc(var(--dy) * 0.2)) scale(var(--gross)) rotate(40deg); }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(0.2) rotate(160deg); }
}

@keyframes buch-hinweis-schimmer {
  0%, 30%  { background-position: 120% 0, 0 0; }
  80%, 100% { background-position: -120% 0, 0 0; }
}

@keyframes buch-funkeln {
  0%, 100% { opacity: 0; transform: scale(0.3) rotate(0deg); }
  45%      { opacity: 1; transform: scale(1.15) rotate(45deg); }
  70%      { opacity: 0; transform: scale(0.5) rotate(90deg); }
}

/* --- Letzte Seite: weiter geht es nach unten (RIC-88) --------------------- */

.buch__hinweis-ende {
  display: none;
}

.buch__steuer.ist-ende .buch__hinweis-touch,
.buch__steuer.ist-ende .buch__hinweis-maus {
  display: none;
}

.buch__steuer.ist-ende .buch__hinweis-ende {
  display: inline;
}

.buch__steuer.ist-ende .buch__hinweis::before,
.buch__steuer.ist-ende .buch__hinweis::after {
  content: '↓';
  color: var(--akzent);
}

.buch__steuer.ist-ende .buch__pfeil--weiter {
  animation: buch-pfeil-ruft 1.8s ease-in-out infinite;
}

.buch__steuer.ist-ende .buch__pfeil--weiter svg {
  rotate: 90deg;
  animation: wippt-runter 1.4s ease-in-out infinite;
}

/* --- Die Erinnerung ans Weiterscrollen (RIC-88) -------------------------- */

.scroll-erinnerung {
  position: fixed;
  z-index: 15;
  left: 50%;
  bottom: var(--erinnerung-unten, 1rem);
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.4rem 1rem 0.4rem 0.75rem;
  border: 1px solid color-mix(in srgb, var(--gold) 55%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--karte) 94%, var(--gold));
  box-shadow: 0 3px 10px rgb(0 0 0 / 0.2);
  color: var(--text);
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
  opacity: 0;
  translate: -50% 0.75rem;
  pointer-events: none;
  transition: opacity 0.45s, translate 0.45s;
}

.scroll-erinnerung[hidden] {
  display: none;
}

.scroll-erinnerung.ist-da {
  opacity: 1;
  translate: -50% 0;
  pointer-events: auto;
}

.scroll-erinnerung svg {
  width: 1.1rem;
  height: 1.1rem;
  fill: none;
  stroke: var(--akzent);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  animation: wippt-runter 1.4s ease-in-out infinite;
}

.scroll-erinnerung:focus-visible {
  outline: 3px solid var(--gold);
  outline-offset: 2px;
}

@keyframes wippt-runter {
  0%, 100% { translate: 0 -2px; }
  50%      { translate: 0 3px; }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-erinnerung svg {
    animation: none;
  }
}

/* Auf schmalen Handys eine Spur kleiner, damit der Hinweis in eine Zeile
   passt und die Pfeile am Rand nicht verdraengt. */
@media (max-width: 26rem) {
  .buch__hinweis {
    padding-inline: 0.7rem;
    font-size: 0.78rem;
    white-space: nowrap;
  }

  .buch__steuer {
    gap: 0.4rem;
  }
}

/* Auf grossen Bildschirmen ist neben dem Buch Platz: Dort stehen die
   Pfeile links und rechts auf halber Hoehe, wo man sie beim Lesen sieht. */
@media (min-width: 72rem) {
  .buch__steuer {
    position: absolute;
    inset: 0 -4.5rem;
    margin: 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    pointer-events: none;
  }

  .buch__pfeil {
    pointer-events: auto;
  }

  /* Der Hinweis steht nur auf dem Deckel; aufgeschlagen stehen die Pfeile
     daneben, und Seitenpunkte gaebe es hier keinen guten Platz. */
  .buch__mitte {
    pointer-events: none;
  }

  .buch__punkte {
    display: none;
  }

  /* Der Hinweis stuende hier mitten auf der Seite - der Pfeil nach unten
     neben dem Buch sagt es allein. */
  .buch__steuer.ist-ende .buch__hinweis {
    display: none;
  }
}

/*
 * Das Blatt, das umschlaegt. Das Skript legt es fuer die Dauer eines
 * Umblaetterns an: Es liegt am Bundsteg angeschlagen ueber der rechten
 * Seite (am Handy ueber der ganzen) und traegt vorn und hinten je eine
 * Abschrift des Textes, so verschoben, dass genau die richtige Seite zu
 * sehen ist. Gedreht wird ein fertiges Bild - das rechnet die Grafikkarte.
 */
.buch__blatt {
  position: absolute;
  z-index: 3;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  transform-origin: left center;
  transform-style: preserve-3d;
  transition: transform 0.75s cubic-bezier(0.45, 0.05, 0.3, 1);
  pointer-events: none;
}

.buch__blatt-seite,
.buch__unterlage {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--blatt-vorn);
}

.buch__blatt-seite {
  backface-visibility: hidden;
}

.buch__blatt-seite--hinten {
  transform: rotateY(180deg);
  background: var(--blatt-hinten);
}

/* Ein Hauch Schatten auf dem Blatt, solange es steht. */
.buch__blatt-seite::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to right, color-mix(in srgb, var(--text) 14%, transparent), transparent 35%);
  pointer-events: none;
}

/* Zwischen zwei Umblaetterungen liegen Blatt und Unterlage unsichtbar
   bereit - gesetzt, damit das naechste Umblaettern sofort losgehen kann. */
.buch__blatt.ist-still,
.buch__unterlage.ist-still {
  visibility: hidden;
}

/* Auf einer Flaeche liegt der Deckel (oder seine Innenseite) nur, wenn sie
   gerade ihn zeigt - sonst die Textseite darunter. */
.buch__blatt-seite > .buch__deckel,
.buch__blatt-seite > .buch__deckel-innen,
.buch__unterlage > .buch__deckel,
.buch__unterlage > .buch__deckel-innen {
  display: none;
}

.zeigt-deckel > .buch__deckel,
.zeigt-innen > .buch__deckel-innen {
  display: grid;
}

/* Die Abschriften des Textes auf Blatt und Unterlage. */
.buch__blatt-seite > .buch__text,
.buch__unterlage > .buch__text {
  position: absolute;
  top: 0;
}

.buch__unterlage {
  z-index: 2;
  pointer-events: none;
}

@media (min-width: 48rem) {
  .buch__blatt {
    left: 50%;
  }

  .buch__unterlage {
    right: auto;
    width: 50%;
    background: var(--blatt-hinten);
  }

  .buch__unterlage--rechts {
    left: 50%;
    background: var(--blatt-vorn);
  }
}

/* Das zugeklappte Buch und der Deckel: rot, mit Goldnaht, dem Titel in
   goldener Schreibschrift und einem Stern. Die Innenseite des Deckels ist
   schlichter - nur Einband. */
.buch__deckel,
.buch__deckel-innen,
.buch__zu {
  position: absolute;
  inset: 0;
  background: var(--buch-einband);
}

.buch__deckel {
  outline: 1px dashed color-mix(in srgb, var(--gold-hell) 75%, transparent);
  outline-offset: -0.6rem;
}

.buch__deckel {
  display: grid;
  place-items: center;
  align-content: center;
  gap: 1.5rem;
  padding: 2rem;
}

/* Der Titel in derselben Schreibschrift wie die Ueberschrift im
   Kopfbereich und der Dank. */
.buch__deckel-titel {
  font-family: 'Dancing Script', 'Segoe Script', cursive;
  font-weight: 700;
  font-size: clamp(2.2rem, 1.6rem + 2.4vw, 3.4rem);
  line-height: 1.1;
  text-align: center;
  text-wrap: balance;
  color: var(--gold-hell);
}

.buch__deckel::after {
  content: '';
  width: 3.5rem;
  height: 3.5rem;
  background: var(--gold-hell);
  clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}

.buch__deckel-innen {
  background: color-mix(in srgb, var(--buch-einband) 88%, var(--text));
}

.buch__zu {
  z-index: 3;
}

/*
 * Zugeklappt ist das Buch am Schreibtisch nur eine Seite breit: Die linke
 * Haelfte wird abgeschnitten, und das Buch rueckt um eine Viertelbreite
 * nach links, damit es mittig liegt. Beim Aufschlagen waechst es zurueck,
 * waehrend der Deckel dreht. Der Beschnitt reicht rundherum ueber das Buch
 * hinaus, sonst verloere es Schatten und Lesebaendchen.
 */
@media (min-width: 48rem) {
  .buch--blaettern {
    clip-path: inset(-3rem -3rem -5rem -3rem);
    transition:
      clip-path 0.75s cubic-bezier(0.45, 0.05, 0.3, 1),
      translate 0.75s cubic-bezier(0.45, 0.05, 0.3, 1);
  }

  .buch--blaettern.buch--zu {
    clip-path: inset(-3rem -3rem -5rem 50%);
    translate: -25% 0;
  }

  .buch__zu {
    left: 50%;
  }
}

/* Hero und Fuss stehen ebenfalls ueber der Landschaft - ohne
   position: relative laege die -1 der Landschaft vor ihrem Hintergrund.

   Der Kopf steht hier NICHT mehr dabei: Er ist 'sticky', und diese Regel
   kommt spaeter in der Datei - sie hat das Kleben stillschweigend wieder
   abgeschaltet. Ueber der Landschaft liegt er trotzdem, denn 'sticky' bildet
   genauso einen eigenen Stapelkontext wie 'relative'. */
.hero,
.fuss {
  position: relative;
}

/* Der Fuss laesst die Landschaft durchscheinen: Er traegt nur wenig Text,
   und so endet die Seite im Bild statt an einer Kante. */
body:has(.landschaft) .fuss,
body:has(.werkstatt) .fuss {
  border-top: 0;
  color: var(--text-leise);
}

/* Sonst legt sich die Leiste als weisser Riegel quer ueber die Landschaft.
   Durchsichtig mit Milchglas bleibt sie lesbar und laesst den Winter durch. */
body:has(.landschaft) .nd-signatur {
  background: color-mix(in srgb, var(--karte) 72%, transparent);
  backdrop-filter: blur(6px);
  border-top: 1px solid color-mix(in srgb, var(--karte) 45%, transparent);
}

.fuss {
  border-top: 1px solid var(--linie);
  color: var(--text-still);
  font-size: 0.875rem;
  padding-block: 1.5rem 2.5rem;
}

/* Der Zusagentext links, die Links rechts - nebeneinander, solange Platz
   ist. Darunter untereinander, mit den Links zuerst: Wer im Fussbereich
   sucht, sucht meistens das Impressum. */
.fuss__inhalt {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem 2rem;
}

.fuss__wort {
  max-width: 34rem;
}

.fuss__wort p {
  margin: 0 0 0.35rem;
}

.fuss__wort p:last-child {
  margin-bottom: 0;
}

.fuss__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
}

.fuss__wort a,
.fuss__links a {
  color: var(--text-leise);
}

.fuss__wort a:hover,
.fuss__links a:hover {
  color: var(--akzent);
}

@media (max-width: 40rem) {
  .fuss__inhalt {
    flex-direction: column-reverse;
    align-items: stretch;
  }
}

/* Ein Rechtstext ist kein Fliesstext einer Startseite: Er wird gelesen, um
   eine bestimmte Stelle zu finden. Deshalb schmaler Satz und deutlich
   abgesetzte Zwischenueberschriften. */
.rechtstext {
  max-width: 40rem;
}

.rechtstext h2 {
  margin: 2rem 0 0.6rem;
  font-size: 1.15rem;
}

.rechtstext h2:first-child {
  margin-top: 0;
}

.rechtstext p {
  margin: 0 0 0.9rem;
  color: var(--text-leise);
}

/* ---------- Bausteine ---------- */

.einleitung {
  color: var(--text-leise);
  font-size: 1.075rem;
  max-width: 34rem;
}

.abschnitt {
  margin-top: 2.5rem;
}

.karte {
  background: var(--karte);
  border: 1px solid var(--linie);
  border-radius: 10px;
  padding: 1.25rem;
}

/* Eine Flaeche in Akzentfarbe - fuer Abschnitte, die zusammengehoeren. */
.karte--getoent {
  background: var(--akzent-tint);
  border-color: var(--akzent-spur);
  padding: 1.4rem 1.5rem;
}

.karte--getoent h2 {
  color: var(--akzent-dunkel);
  margin-top: 0;
}

.karte--getoent .punkte {
  color: var(--text-leise);
}

/* Datenschutz-Abschnitt: Einleitung und Schlusssatz rahmen die Punkte ein,
   damit der Abschnitt nicht nur aus einer Aufzaehlung besteht. */
.vertrauen__einleitung {
  margin: 0 0 1rem;
  font-weight: 500;
}

.vertrauen__schluss {
  margin: 1.1rem 0 0;
  padding-top: 0.9rem;
  border-top: 1px solid var(--akzent-spur);
  font-weight: 600;
  color: var(--akzent-dunkel);
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  padding: 0.15rem 0.5rem;
  border-radius: 5px;
  background: var(--akzent-tint);
  color: var(--akzent);
  white-space: nowrap;
}

.knopf {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  background: var(--akzent);
  color: var(--auf-akzent);
  border: 1px solid var(--akzent);
  border-radius: 7px;
  padding: 0.7rem 1.15rem;
  font: inherit;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}

.knopf:hover {
  background: var(--akzent-dunkel);
  border-color: var(--akzent-dunkel);
  color: var(--auf-akzent);
}

.knopf--leise {
  background: var(--karte);
  color: var(--akzent);
  border-color: var(--linie-stark);
  font-weight: 500;
}

.knopf--leise:hover {
  background: var(--akzent-tint);
  border-color: var(--akzent-spur);
  color: var(--akzent-dunkel);
}

/* Die beiden Hauptknoepfe im Kopfbereich: gleich gross, gleich wichtig.
   Wer etwas verschenkt und wer etwas braucht, steht auf dieser Seite
   nebeneinander - deshalb unterscheiden sie sich in der Farbe, nicht in
   der Groesse. */
.knopf--gross {
  padding: 0.85rem 1.5rem;
  font-size: 1.02rem;
}

/* Alles, was zu den Familien fuehrt, ist gruen - wie Wald und Kranz am
   gezeichneten Haus. Spender rot, Familien gruen: So findet jede Seite ihren
   Weg schon an der Farbe (RIC-57).

   Nur --empfaenger kommt aus config/design.php; die Stufen daraus werden
   hier gemischt, damit ein Farbwechsel genau eine Zeile ist. */
:root {
  --empfaenger-dunkel: color-mix(in srgb, var(--empfaenger) 78%, var(--text));
  --empfaenger-tint: color-mix(in srgb, var(--empfaenger) 10%, var(--karte));
}

.knopf--familie {
  background: var(--empfaenger);
  border-color: var(--empfaenger);
  color: var(--auf-akzent);
}

.knopf--familie:hover {
  background: var(--empfaenger-dunkel);
  border-color: var(--empfaenger-dunkel);
  color: var(--auf-akzent);
}

/*
 * Der Ablauf.
 *
 * Als Reihe nebeneinander statt als Liste untereinander: Vier Schritte sind
 * ein Weg, keine Aufzaehlung. Nebeneinander sieht man auf einen Blick, dass
 * es vier sind - untereinander liest man sie einzeln und weiss beim dritten
 * nicht mehr, wie viele noch kommen.
 *
 * Am Handy kippt es zurueck in die Liste: Vier Spalten auf 400 Pixeln waeren
 * vier zu schmale Spalten.
 */
.schritte {
  counter-reset: schritt;
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1.75rem 2rem;
  /*
   * Zwei Spalten und nicht vier. Der Satzspiegel der Seite ist 46rem breit -
   * vier Schritte nebeneinander waeren vier Spalten von je zehn Zeichen, und
   * "im Dezember ist der Kalender da." braeche viermal um. Mit auto-fit
   * ergaben sich ausserdem drei Spalten und ein einzelner Schritt darunter.
   */
  grid-template-columns: repeat(2, 1fr);
}

.schritt {
  counter-increment: schritt;
  display: grid;
  gap: 0.6rem;
  align-content: start;
}

/* Symbol und Nummer sitzen in derselben runden Flaeche, damit die Reihe
   gleich aussieht, auch wenn nur einzelne Schritte ein Zeichen tragen. */
.schritt__symbol,
.schritt:not(.schritt--mit-symbol)::before {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: var(--akzent-tint);
  color: var(--akzent);
}

.schritt:not(.schritt--mit-symbol)::before {
  content: counter(schritt);
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, monospace;
  font-size: 0.9rem;
  font-weight: 600;
}

.schritt__symbol svg {
  width: 1.4rem;
  height: 1.4rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.schritt__wort b {
  display: block;
  font-weight: 600;
  color: var(--text);
  margin-bottom: 0.15rem;
}

.schritt__text {
  color: var(--text-leise);
  font-size: 0.925rem;
  line-height: 1.5;
}

/* Luft zwischen dem letzten Schritt und den beiden Karten: Der Ablauf
   erklaert, die Karten fordern auf - das sind zwei Gedanken, und sie sollen
   nicht ineinanderlaufen. */
.ablauf + .wahl {
  margin-top: 2.5rem;
}

@media (max-width: 34rem) {
  .schritte {
    grid-template-columns: 1fr;
    gap: 0.9rem;
  }

  .schritt {
    grid-template-columns: 2.5rem 1fr;
    gap: 0.75rem;
    align-items: start;
  }

  .schritt__symbol,
  .schritt:not(.schritt--mit-symbol)::before {
    width: 2.25rem;
    height: 2.25rem;
  }
}

.punkte {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
  color: var(--text-leise);
}

.punkte li {
  padding-left: 1.4rem;
  position: relative;
}

.punkte li::before {
  content: '';
  position: absolute;
  left: 0.3rem;
  top: 0.55em;
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 999px;
  background: var(--akzent);
}

/* Zahlen aus campaign_statistics - anonym, ohne Personenbezug. */
.zahlen {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  gap: 1px;
  background: var(--linie);
  border: 1px solid var(--linie);
  border-radius: 10px;
  overflow: hidden;
  margin: 0;
}

.zahlen div {
  background: var(--karte);
  padding: 1rem;
}

.zahlen dt {
  color: var(--text-still);
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.zahlen dd {
  margin: 0.2rem 0 0;
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, monospace;
  font-variant-numeric: tabular-nums;
  font-size: 1.7rem;
  font-weight: 500;
  line-height: 1.05;
  color: var(--akzent);
}

/* ---------- Adventsgesteck ----------
   Steht vom ersten Advent bis zum zweiten Weihnachtstag ueber dem Inhalt.
   Gezeichnet und nicht fotografiert, damit es sich mit der Palette umfaerbt.

   Laenglich und von vorn statt rund und von schraeg oben: Ein Ring braucht
   Perspektive, und die sah nach drei Anlaeufen immer noch aufgeklebt aus.
   ------------------------------------ */

.kranz {
  margin: 0 0 2.2rem;
  text-align: center;
}

.kranz__bild {
  display: block;
  width: 100%;
  /* Gross genug, um festlich zu wirken - aber kein Plakat. */
  max-width: 27rem;
  height: auto;
  margin: 0 auto;
  overflow: visible;
}

/* Der Koerper des Gestecks - er haelt die Zweige zusammen. */
.gesteck__bett {
  fill: var(--tanne);
}

.gesteck__zweig {
  fill: none;
  stroke-linecap: round;
  stroke: var(--tanne);
}

/* Die hinteren Zweige dunkler und duenner, die vorderen heller und
   kraeftiger - daraus entsteht Tiefe ohne einen einzigen Verlauf. */
.gesteck__zweig--hinten {
  stroke-width: 2.6;
  opacity: 0.85;
}

.gesteck__zweig--vorn {
  stroke: color-mix(in srgb, var(--tanne) 82%, var(--gold-spur));
  stroke-width: 2.8;
}

.schmuck--beere {
  fill: var(--akzent-dunkel);
}

.schmuck--kugel {
  fill: var(--gold);
}

.kerze__koerper {
  fill: var(--akzent);
}

.kerze__docht {
  fill: var(--text);
}

/* Heller Streifen und Schatten - flach gezeichnet, aber nicht platt. */
.kerze__licht {
  fill: var(--auf-akzent);
  opacity: 0.26;
}

.kerze__schatten {
  fill: var(--akzent-tief);
  opacity: 0.22;
}

.kerze__flamme {
  fill: var(--gold);
}

/* Der helle Kern sitzt in der Flamme und macht sie erst zu Feuer. */
.kerze__kern {
  fill: var(--gold-spur);
}

.kerze__schein {
  fill: url(#kerzenschein);
}

/*
   Die Flamme wiegt sich um ihren Fuss, nicht um ihre Mitte - eine Flamme,
   die um die Mitte kippt, sieht aus wie ein Wackelpudding.

   Der Takt ist je Kerze versetzt (--takt kommt aus dem Markup): Vier
   gleichzeitig zuckende Flammen waeren ein Blinklicht.
*/
.kerze--brennt .kerze__flamme,
.kerze--brennt .kerze__kern {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: flamme-wiegen 2.6s ease-in-out infinite;
  animation-delay: calc(var(--takt, 0) * -0.7s);
}

/* Der Kern wiegt sich eine Spur schneller - sonst wirken beide wie ein
   einziger starrer Koerper. */
.kerze--brennt .kerze__kern {
  animation-duration: 2.1s;
}

.kerze--brennt .kerze__schein {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: schein-atmen 3.7s ease-in-out infinite;
  animation-delay: calc(var(--takt, 0) * -0.9s);
}

@keyframes flamme-wiegen {
  0%, 100% { transform: rotate(-4deg) scaleY(1); }
  35%      { transform: rotate(3deg) scaleY(1.09); }
  70%      { transform: rotate(-2deg) scaleY(0.95); }
}

@keyframes schein-atmen {
  0%, 100% { opacity: 0.7; transform: scale(0.92); }
  50%      { opacity: 1; transform: scale(1.08); }
}

.kranz__wort {
  margin: 0.7rem 0 0;
  color: var(--text-leise);
  font-size: 0.95rem;
}

/* ---------- Adventskalender ---------- */

.kalender {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(5.5rem, 1fr));
  gap: 0.6rem;
  margin-top: 2rem;
  padding: 0;
  list-style: none;
}

.kalender > li {
  display: grid;
}

/*
 * Ein geoeffnetes Tuerchen sprengt das Raster und nimmt die volle Breite.
 * Die Regel muss am <li> haengen - das ist das Rasterfeld, nicht das
 * <details> darin.
 */
.kalender > li:has(> .tuerchen--offen[open]) {
  grid-column: 1 / -1;
}

.tuerchen {
  border-radius: 10px;
  min-height: 5.5rem;
}

/* Was noch zu ist, bleibt farblos - der Akzent gehoert dem Offenen. */
.tuerchen--zu {
  background: var(--papier);
  border: 1px dashed var(--linie-stark);
  color: var(--text-still);
  display: grid;
  place-items: center;
  text-align: center;
  padding: 0.5rem;
}

.tuerchen--offen {
  background: var(--akzent-tint);
  border: 1px solid var(--akzent-spur);
}

.tuerchen--offen > summary {
  cursor: pointer;
  list-style: none;
  min-height: 5.5rem;
  display: grid;
  place-items: center;
  padding: 0.5rem;
  text-align: center;
}

.tuerchen--offen > summary::-webkit-details-marker {
  display: none;
}

.tuerchen--offen:hover {
  border-color: var(--akzent);
}

.tuerchen--offen[open] {
  background: var(--karte);
}

.tuerchen__tag {
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, monospace;
  font-size: 1.5rem;
  font-weight: 500;
}

.tuerchen--offen .tuerchen__tag {
  color: var(--akzent);
}

.tuerchen--zu .tuerchen__tag {
  color: var(--text-still);
}

.tuerchen__hinweis,
.tuerchen__oeffnen {
  font-size: 0.7rem;
  display: block;
}

.tuerchen__oeffnen {
  color: var(--akzent);
  font-weight: 500;
}

/* Steht das Tuerchen offen, ist der Hinweis erledigt. */
.tuerchen--offen[open] .tuerchen__oeffnen {
  visibility: hidden;
}

.tuerchen__inhalt {
  border-top: 1px solid var(--akzent-spur);
  padding: 1rem 1.1rem 1.2rem;
  text-align: left;
}

.tuerchen__inhalt h3 {
  margin-top: 0;
  color: var(--akzent-dunkel);
}

/* ---------- Verlosung im Tuerchen (RIC-40) ----------

   Sie steht unter dem Spruch und soll ihn nicht verdraengen: abgesetzt
   durch eine Linie und einen getoenten Grund, aber ohne eigene Ueberschrift
   in Grossbuchstaben. Wer nur den Spruch lesen will, ueberblaettert sie.

   Das Gold statt des Rots: Der Spruch darueber traegt schon die Akzentfarbe
   in seiner Ueberschrift, und zwei rote Bloecke uebereinander lassen keinen
   mehr hervortreten. */

.verlosung {
  margin-top: 1.1rem;
  padding: 0.9rem 1rem 1rem;
  border-top: 1px dashed var(--gold-hell);
  background: color-mix(in srgb, var(--gold-spur) 45%, transparent);
  border-radius: 0 0 0.4rem 0.4rem;
}

.verlosung__auge {
  margin: 0 0 0.4rem;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--warnung);
}

.verlosung p {
  margin: 0 0 0.6rem;
  font-size: 0.95rem;
  line-height: 1.55;
}

.verlosung__preis {
  font-weight: 600;
  color: var(--text);
}

.verlosung__vorbei {
  margin: 0;
  font-size: 0.95rem;
  color: var(--text-still);
}

.verlosung__form {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 0.8rem;
}

/* Der Knopf nimmt hier nicht die volle Breite: Er ist eine Einladung, keine
   Aufforderung - der Kalender ist die Hauptsache. */
.verlosung__form .knopf {
  align-self: start;
}

.verlosung__klein {
  font-size: 0.82rem;
  color: var(--text-still);
}

.verlosung__klein p {
  margin: 0;
  font-size: inherit;
}

/* ---------- Hinweise ---------- */

.hinweis {
  border: 1px solid var(--akzent-spur);
  border-left: 3px solid var(--akzent);
  background: var(--akzent-tint);
  border-radius: 10px;
  padding: 0.9rem 1.1rem;
  font-size: 0.925rem;
}

.hinweis--warnung {
  background: var(--warnung-tint);
  border-color: var(--warnung-tint);
  border-left-color: var(--warnung);
  color: var(--warnung);
}

.hinweis--fehler {
  background: var(--fehler-tint);
  border-color: var(--fehler-tint);
  border-left-color: var(--fehler);
  color: var(--fehler);
}

/*
 * Vorschau-Balken: nur fuer angemeldete Backend-Nutzer sichtbar. Bewusst
 * auffaellig und in der Warnfarbe, damit niemand eine Vorschau fuer den
 * Live-Stand haelt.
 */
.vorschaubalken {
  background: var(--warnung);
  color: var(--auf-akzent);
  font-size: 0.85rem;
  padding: 0.55rem 0;
}

.vorschaubalken a {
  color: var(--auf-akzent);
}

.vorschaubalken__inhalt {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: center;
  justify-content: space-between;
}

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

.formular {
  display: grid;
  gap: 1.25rem;
  max-width: 34rem;
}

.feld {
  display: grid;
  gap: 0.3rem;
}

.feld > label,
.feldgruppe__titel {
  font-weight: 500;
  font-size: 0.925rem;
}

.feld__hinweis {
  color: var(--text-still);
  font-size: 0.85rem;
}

/*
 * Ein Hinweis, der zwischen den Feldern steht und nicht zu einem gehoert -
 * etwa die moegliche Aufteilung einer Spende auf zwei Familien. Auffaellig
 * genug, um vor dem Absenden gelesen zu werden, ohne wie eine Fehlermeldung
 * auszusehen.
 */
.hinweisbox {
  margin: 0;
  padding: 0.85rem 1rem;
  border-left: 3px solid var(--gold);
  border-radius: 0 var(--radius-klein, 4px) var(--radius-klein, 4px) 0;
  background: var(--warnung-tint);
  color: var(--text-leise);
  font-size: 0.9rem;
  line-height: 1.55;
}

/* Gruen statt Gold, wo der Hinweis beruhigen soll statt warnen (RIC-65).
   Tanne, nicht --empfaenger: Das Gruen der Familien gehoert auf ihre Seite. */
.hinweisbox--gruen {
  border-left-color: var(--tanne);
  background: color-mix(in srgb, var(--tanne) 9%, var(--karte));
  color: color-mix(in srgb, var(--tanne) 80%, var(--text));
}

.hinweisbox--gruen a {
  color: inherit;
}

input[type='text'],
input[type='email'],
input[type='tel'],
input[type='number'],
select,
textarea {
  font: inherit;
  color: inherit;
  background: var(--karte);
  border: 1px solid var(--linie-stark);
  border-radius: 7px;
  padding: 0.6rem 0.7rem;
  width: 100%;
}

input:hover,
textarea:hover {
  border-color: var(--akzent-spur);
}

input:focus-visible,
select:focus-visible,
textarea:focus-visible,
.knopf:focus-visible,
summary:focus-visible,
a:focus-visible {
  outline: 2px solid var(--akzent);
  outline-offset: 2px;
}

.feld--fehler input,
.feld--fehler select,
.feld--fehler textarea {
  border-color: var(--fehler);
  background: var(--fehler-tint);
}

.fehlertext {
  color: var(--fehler);
  font-size: 0.85rem;
}

.feldgruppe {
  border: 1px solid var(--linie);
  border-radius: 10px;
  padding: 1rem;
  margin: 0;
  background: var(--karte);
  display: grid;
  gap: 0.75rem;
}

.feldgruppe__titel {
  color: var(--akzent-dunkel);
}

.auswahl {
  display: grid;
  gap: 0.6rem;
}

.auswahl label {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.6rem;
  align-items: start;
  cursor: pointer;
}

.auswahl input {
  margin-top: 0.35rem;
  accent-color: var(--akzent);
}

.auswahl span small {
  display: block;
  color: var(--text-still);
}

/*
 * Zwei Felder nebeneinander. Welches der beiden schmal ist, haengt vom
 * Inhalt ab - eine Hausnummer braucht weniger Platz als eine Strasse,
 * beim Alter eines Kindes ist es umgekehrt.
 */
.zeile {
  display: grid;
  gap: 0.6rem;
  align-items: start;
  grid-template-columns: 1fr 1fr;
}

.zeile--strasse {
  grid-template-columns: 1fr 6rem;
}

.zeile--ort {
  grid-template-columns: 6rem 1fr;
}

/*
   Ein Feld fuer eine einstellige Zahl. Ueber die volle Breite sieht es aus,
   als erwarte es einen Satz - und die Anzahl der Kinder ist selten
   zweistellig.
*/
.feld--zahl input {
  max-width: 6rem;
}

/* Auf schmalen Geraeten untereinander - zwei Felder nebeneinander sind
 * auf einem Telefon nicht mehr zu treffen. */
@media (max-width: 26rem) {
  .zeile,
  .zeile--strasse,
  .zeile--ort {
    grid-template-columns: 1fr;
  }
}

/* Sichtbar nur fuer Screenreader: die Beschriftung wiederholt sich in
 * jeder Kinderzeile, ist aber optisch nach der ersten ueberfluessig. */
.nur-vorlesen {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Honigtopf gegen Bots. Nicht display:none - das ueberspringen viele. */
.honigtopf {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.zurueck {
  display: inline-block;
  margin-bottom: 1.5rem;
  font-size: 0.9rem;
  color: var(--text-still);
  text-decoration: none;
}

.zurueck:hover {
  color: var(--akzent);
}

.knopfzeile {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
}


/* =========================================================================
   Kopfbereich mit Motiv
   =========================================================================

   Ein Onepager: dieser Bereich steht in jeder Phase, darunter wird nur die
   Sektion getauscht. Motiv, Bewegung und Bildausschnitt kommen aus
   config/hero.php, die Texte aus config/seiteninhalte.php.
   ========================================================================= */

.hero {
  position: relative;
  isolation: isolate;
  display: grid;
  align-items: end;
  /*
   * Gut vier Fuenftel der Bildschirmhoehe, und zwar svh: Das ist die Hoehe
   * ohne die Adressleiste des Handybrowsers. Mit vh waere der Kopfbereich
   * dort genau um diese Leiste zu hoch, und es ragte immer ein Streifen
   * unter den Rand - sichtbar erst beim Scrollen, wenn die Leiste
   * einfaehrt.
   *
   * Nicht die volle Hoehe: Unten soll noch ein Streifen der Werkstatt und
   * der Anfang des Blattes zu sehen sein. Ein Kopfbereich, der exakt den
   * Bildschirm fuellt, sieht aus wie das Ende der Seite - und niemand
   * scrollt weiter, wenn nichts danach angedeutet ist.
   */
  min-height: 62svh;
  padding-block: 8rem 3.5rem;
  overflow: hidden;
  background: var(--akzent-tief);
  color: var(--auf-akzent);
}

/*
 * Bewusst z-index 0 und nicht -1: .hero setzt mit isolation einen eigenen
 * Stapelkontext, und ein Kind mit negativem z-index landet darin HINTER
 * dem Hintergrund des Elternteils - das Motiv war damit unsichtbar.
 */
.hero__medium {
  position: absolute;
  inset: 0;
  z-index: 0;
}

.hero__bild,
.hero__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.hero__video {
  position: absolute;
  inset: 0;
}

/*
 * Der Schleier ueber dem Motiv. Ohne ihn haengt die Lesbarkeit der
 * Ueberschrift davon ab, welches Foto gerade eingetragen ist - mit ihm ist
 * sie eine Einstellung (config/hero.php, 'schleier').
 */
.hero__schleier {
  position: absolute;
  inset: 0;
  background:
    /*
     * Von links: die Schrift steht dort. Rechts bleibt das Motiv fast
     * unangetastet - so traegt das Bild, ohne dass die Lesbarkeit davon
     * abhaengt, wie hell das gerade eingetragene Foto an dieser Stelle ist.
     */
    linear-gradient(
      to right,
      color-mix(in srgb, var(--schleier) 82%, transparent) 0%,
      color-mix(in srgb, var(--schleier) 55%, transparent) 42%,
      transparent 78%
    ),
    linear-gradient(
      to top,
      color-mix(in srgb, var(--schleier) 82%, transparent) 0%,
      color-mix(in srgb, var(--schleier) 30%, transparent) 55%,
      color-mix(in srgb, var(--schleier) 5%, transparent) 100%
    ),
    color-mix(in srgb, var(--schleier) calc(var(--hero-schleier, 0.55) * 100%), transparent);
}

.hero__inhalt {
  position: relative;
  z-index: 1;
  width: 100%;
}

/* --- Motiv und Schrift im Kopfbereich ------------------------------------ */

.hero__bild,
.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Das Motiv faehrt ueber Minuten unmerklich heran und wieder zurueck. Kein
   Effekt, den jemand bemerken soll - er nimmt dem Standbild nur die Starre. */
.hero__bild {
  animation: heranfahren 28s ease-in-out infinite alternate;
}

@keyframes heranfahren {
  from { transform: scale(1); }
  to   { transform: scale(1.07); }
}

/* Liegt ueber dem Bild: Das Video deckt es ab, sobald es laeuft. */
.hero__video {
  z-index: 1;
}

.hero__auge {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 1rem;
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-hell);
}

/* Der kurze Strich vor der Zeile. */
.hero__auge::before {
  content: '';
  width: 1.75rem;
  height: 2px;
  background: var(--auf-akzent);
  flex: none;
}

.hero__titel {
  margin: 0 0 1.25rem;
  max-width: 20ch;
  font-size: clamp(2.1rem, 1.2rem + 3.4vw, 3.6rem);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -0.02em;
}

.hero__text {
  max-width: 34rem;
  color: var(--text-hell);
}

.hero__text p {
  margin: 0 0 0.85rem;
}

/* Die beiden Wege stehen nebeneinander und sind exakt gleich breit (RIC-42).

   Vorher waren sie ein Flex-Container: Jeder Knopf wuchs mit seiner
   Aufschrift, und "Weihnachtsfreude erhalten (Empfaenger)" geriet damit
   breiter als "Weihnachtswichtel werden (Spender)". Auf einer Seite, die
   Geben und Annehmen gleichrangig nebeneinanderstellt, ist ein Knopf, der
   groesser ausfaellt als der andere, keine Kleinigkeit - er sieht aus wie
   der eigentlich gemeinte.

   Zwei gleiche Spalten sorgen dafuer, dass die laengere Aufschrift die
   Breite beider bestimmt. width: fit-content haelt das Paar dabei so
   schmal wie noetig: Ohne das liefen die Knoepfe ueber die volle Breite des
   Kopfbereichs und saehen aus wie zwei Balken. Und weil die Aufschriften
   aus dem Backend kommen, gilt das auch fuer die naechste Formulierung -
   hier steht keine Breite, die jemand nachpflegen muesste. */
.hero__aktionen {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  max-width: 34rem;
  gap: 0.75rem;
  margin-top: 1.75rem;
}

/* minmax(0, 1fr) statt 1fr: Eine 1fr-Spalte wird nie schmaler als ihr
   Inhalt, und "Weihnachtsfreude erhalten (Empfaenger)" ist ein breiter
   Inhalt. Auf einem schmalen Schirm sprengte das Raster damit den
   Kopfbereich - und riss Ueberschrift und Einleitung gleich mit heraus,
   weil alle im selben Container stehen. Mit der 0 als Untergrenze duerfen
   die Spalten schrumpfen und der Text darin umbrechen.

   Die 34rem sind dieselbe Breite wie beim Kurzablauf darueber: Beide
   Bloecke enden damit auf einer Linie. */

@media (max-width: 34rem) {
  /* Nebeneinander sind zwei Knoepfe hier nur noch schmale Streifen mit
     dreizeiliger Aufschrift. Untereinander bleiben sie gleich breit und
     gut zu treffen. */
  .hero__aktionen {
    grid-template-columns: 1fr;
  }
}

/* Der Live-Ticker (RIC-114): eine helle Plakette unter den Knoepfen.
   Eigener Kartengrund statt durchscheinend, damit sie auf dem Foto der
   Vollbild-Form genauso lesbar bleibt wie auf dem Papier der Hausform.
   Am Handy rutscht der zweite Wert unter den ersten, der Trenner faellt weg. */
.ticker {
  display: flex;
  width: fit-content;
  max-width: 100%;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem 0.9rem;
  margin: 1.25rem 0 0;
  padding: 0.55rem 1.1rem 0.55rem 0.7rem;
  border: 1px solid color-mix(in srgb, var(--text) 10%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--karte) 92%, transparent);
  box-shadow: 0 6px 18px -12px color-mix(in srgb, var(--text) 45%, transparent);
  color: var(--text-leise);
  font-size: 0.92rem;
  line-height: 1.3;
}

.ticker__marke {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.2rem 0.6rem 0.2rem 0.5rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tanne) 12%, var(--karte));
  color: var(--tanne);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.ticker__punkt {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--tanne);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--tanne) 55%, transparent);
  animation: ticker-puls 2s ease-out infinite;
}

.ticker__wert b {
  display: inline-block;
  min-width: 2.5ch;
  color: var(--akzent);
  font-size: 1.15rem;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.ticker__trenner {
  width: 1px;
  height: 1.1rem;
  background: color-mix(in srgb, var(--text) 18%, transparent);
}

/* Eine neue Anmeldung waehrend man hinsieht: Die Zahl hebt sich kurz. */
.ticker__neu {
  animation: ticker-neu 0.9s ease-out;
}

@keyframes ticker-puls {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tanne) 55%, transparent); }
  70%  { box-shadow: 0 0 0 0.45rem transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

@keyframes ticker-neu {
  30% { transform: scale(1.18); }
}

/* Am Handy so breit wie die Knoepfe darueber, zwei grosse Zahlen
   nebeneinander und die Beschriftung darunter. Als Pille brach der zweite
   Wert allein in eine neue Zeile, untereinander stand ein schmales Kaestchen
   verloren unter zwei breiten Knoepfen. */
@media (max-width: 34rem) {
  .ticker {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: start;
    width: 100%;
    gap: 0.5rem 0.75rem;
    padding: 0.8rem 1rem 0.9rem;
    border-radius: 0.9rem;
  }

  .ticker__marke {
    grid-column: 1 / -1;
    justify-self: start;
  }

  .ticker__wert {
    display: flex;
    flex-direction: column;
    font-size: 0.82rem;
    line-height: 1.25;
  }

  .ticker__wert b {
    font-size: 1.75rem;
    line-height: 1.1;
  }

  .ticker__trenner {
    align-self: stretch;
    height: auto;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ticker__punkt,
  .ticker__neu {
    animation: none;
  }
}

/* Der Hinweis, dass es unterhalb weitergeht. Zurueckhaltend - er soll den
   Weg zeigen, nicht um Aufmerksamkeit bitten. */
.hero__weiter {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 2.5rem;
  font-size: 0.85rem;
  color: var(--text-hell);
  text-decoration: none;
  opacity: 0.75;
}

.hero__weiter:hover {
  opacity: 1;
}

.hero__weiter svg {
  animation: hero-winken 2.4s ease-in-out infinite;
}

@keyframes hero-winken {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(0.25rem); }
}

/* Die Zeilen des Kopfbereichs tauchen nacheinander auf, von oben nach unten.
   Einmal beim Laden, nicht in Schleife. */
.hero__auge,
.hero__titel,
.hero__text,
.hero__aktionen,
.ticker,
.hero__weiter {
  animation: auftauchen 0.9s cubic-bezier(0.2, 0.7, 0.3, 1) backwards;
}

.hero__auge     { animation-delay: 0.1s; }
.hero__titel    { animation-delay: 0.22s; }
.hero__text     { animation-delay: 0.36s; }
.hero__aktionen { animation-delay: 0.62s; }
.ticker         { animation-delay: 0.72s; }
.hero__weiter   { animation-delay: 0.8s; }

@keyframes auftauchen {
  from { opacity: 0; transform: translateY(0.75rem); }
  to   { opacity: 1; transform: none; }
}

/* =========================================================================
   Hero, geteilte Bauform: Text links, Bild rechts
   =========================================================================

   Fuer Motive, die man sehen soll. In der Vollbild-Form liegt die Schrift
   auf dem Bild, was nur mit dunklen, in der Mitte leeren Motiven aufgeht -
   ein Weihnachtsmann waere dort halb von einem Absatz verdeckt.

   Umgesetzt als zweispaltiges Raster. Beide Bauformen teilen sich dieselbe
   Struktur; nur hier wird .hero__medium aus der absoluten Lage geholt und
   bekommt eine eigene Spalte.
   ========================================================================= */

.hero--geteilt {
  align-items: center;
  min-height: 62svh;
  padding-block: 7rem 3rem;
  /*
   * Hell statt dunkel. In der Vollbild-Form muss der Kopfbereich dunkel
   * sein, weil die Schrift auf dem Motiv liegt - hier liegt sie daneben,
   * und die Farbe ist frei. Ein warmes Creme mit rotem Titel wirkt
   * einladend; die dunkle Variante wirkte an dieser Stelle streng.
   */
  background:
    linear-gradient(to bottom,
      var(--akzent-tint) 0%,
      var(--papier) 62%);
  color: var(--text);
}

/* Die grosse Ueberschrift geschwungen - nur hier, nur einmal auf der Seite.
   Script-Schriften sind bei langen Zeilen anstrengend zu lesen, deshalb
   bleibt alles andere bei der Grundschrift. */
.hero--geteilt .hero__titel {
  font-family: 'Dancing Script', 'Segoe Script', cursive;
  font-weight: 700;
  font-size: clamp(2.6rem, 1.4rem + 4.4vw, 4.6rem);
  line-height: 1.02;
  letter-spacing: 0;
  max-width: 16ch;
  color: var(--akzent);
}

.hero--geteilt .hero__auge {
  color: var(--akzent-dunkel);
}

.hero--geteilt .hero__auge::before {
  background: var(--akzent);
}

.hero--geteilt .hero__text {
  color: var(--text-leise);
}

/* Die Unterschrift unter der Einleitung (RIC-49), in derselben Schrift wie
   die Ueberschrift. Das ist die zweite geschwungene Zeile auf der Seite -
   aber nur ein Name, und eine Unterschrift in Grundschrift liest sich wie
   eine Fusszeile.

   Rechtsbuendig wie unter einem Brief (RIC-55): Sie schliesst den Text ab,
   statt wie eine weitere Zeile darunter anzufangen. */
.hero__text .hero__unterschrift {
  margin: 0.4rem 0 0;
  text-align: right;
  font-family: 'Dancing Script', 'Segoe Script', cursive;
  font-weight: 700;
  font-size: clamp(1.7rem, 1.3rem + 1.4vw, 2.3rem);
  line-height: 1.1;
  color: var(--text-hell);
}

.hero--geteilt .hero__text .hero__unterschrift {
  color: var(--akzent);
}

.hero--geteilt .hero__weiter {
  color: var(--text-leise);
}

@media (min-width: 56rem) {
  /*
   * Ein echtes Zweispalten-Raster statt eines verschobenen Bildes.
   *
   * Der erste Versuch schob nur .hero__medium auf die rechte Haelfte. Das
   * ging schief, weil .hero__inhalt von .seite ein "margin: 0 auto" erbt:
   * Mit max-width 50 % wurde der Textblock ueber die volle Breite zentriert
   * und ragte ins Bild. Im Raster liegt jede Spalte fest, und die Frage
   * stellt sich nicht mehr.
   */
  .hero--geteilt {
    grid-template-columns: 1fr 1fr;
    padding-block: 7rem 3rem;
  }

  /*
   * grid-row muss bei beiden stehen, nicht nur grid-column. Das Bild kommt
   * im Markup zuerst und belegt Spalte 2; danach kann die automatische
   * Platzierung nicht mehr nach links zurueck und setzt den Text in eine
   * zweite Zeile - Bild oben, Text darunter. Mit fester Zeile stehen beide
   * nebeneinander, und die Reihenfolge im Markup bleibt frei.
   */
  .hero--geteilt .hero__medium {
    position: relative;
    inset: auto;
    grid-column: 2;
    grid-row: 1;
    align-self: stretch;
    min-height: 26rem;
  }

  .hero--geteilt .hero__inhalt {
    grid-column: 1;
    grid-row: 1;
    padding-right: 2.5rem;
  }

  /* Weiche Kante statt harter Schnittlinie: Das Motiv laeuft nach links in
     die dunkle Flaeche aus, damit es angesetzt wirkt und nicht angeklebt. */
  .hero--geteilt .hero__medium::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(to right,
      var(--papier) 0%,
      color-mix(in srgb, var(--papier) 55%, transparent) 15%,
      transparent 40%);
  }
}

/*
 * Unter 56rem gibt es keine zwei Spalten mehr: Das Bild rueckt unter den
 * Text, in fester Hoehe. Ein Motiv, das oben als Hintergrund durchlaeuft,
 * waere hier wieder das, was die geteilte Form vermeiden soll.
 */
@media (max-width: 55.999rem) {
  .hero--geteilt {
    align-items: stretch;
    min-height: 0;
    padding-block: 6.5rem 0;
  }

  .hero--geteilt .hero__medium {
    position: relative;
    inset: auto;
    order: 2;
    height: clamp(14rem, 52vw, 22rem);
    margin-top: 2rem;
  }

  .hero--geteilt .hero__inhalt {
    order: 1;
  }
}

/* =========================================================================
   Landschaft und Stimmung
   =========================================================================

   Drei Schichten, von hinten nach vorn:

     .landschaft  (fixed, -1)  das Winterbild, bleibt beim Scrollen stehen
     Inhalt       (relativ, 0) Kopf, Hero, main, Fuss - zieht darueber
     .stimmung    (fixed, 40)  Schnee, Lichter

   Die Stimmung liegt bewusst ueber dem Inhalt und nicht dahinter: Am Handy
   nimmt das Blatt die volle Breite ein, dahinter waere nichts mehr zu sehen -
   und "es schneit auf der Seite" hiesse dann "es schneit ueberall ausser da,
   wo man hinschaut". Damit sie trotzdem nicht stoert, ist sie durchsichtig
   genug zum Hindurchlesen und faengt keine Klicks ab.
   ========================================================================= */

.landschaft {
  position: fixed;
  inset: 0;
  z-index: -1;
  background-image: var(--landschaft-bild);
  background-size: cover;
  background-position: center;
  pointer-events: none;
}

/* Das Bild bleibt im Hintergrund, wo es hingehoert: aufgehellt und leicht
   entsaettigt, damit die Raender neben dem Blatt ruhig wirken und nicht mit
   dem Inhalt um Aufmerksamkeit streiten. */
.landschaft::after {
  content: '';
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--papier) 38%, transparent);
  backdrop-filter: saturate(0.85);
}

.stimmung {
  /*
   * Liegt im Kopfbereich, nicht mehr fest ueber dem Bildschirm (RIC-54).
   * Die Sektion ist der Bezugsrahmen, und als Groessencontainer gibt sie
   * ihre Hoehe als cqh an die Fallstrecken weiter: Eine Flocke faellt von
   * der Ober- bis zur Unterkante des Kopfbereichs, wie hoch der auch ist.
   */
  position: absolute;
  inset: 0;
  z-index: 40;
  container-type: size;
  overflow: hidden;
  pointer-events: none;
}

/* --- Die Wichtelwerkstatt (RIC-67) ---------------------------------------
   Das Innere des Hauses aus dem Kopfbereich, fest hinter der Seite. Liegt
   auf derselben Schicht wie .landschaft und schliesst sie aus - es gibt
   entweder ein Foto oder die Zeichnung, nie beides.

   Anders als die erste Fassung ist die Stube nicht blass: Sie hat dieselben
   satten Farben wie das Haus oben, damit man sie als dessen Inneres
   erkennt. Ruhig wird sie durch wenig und langsame Bewegung, nicht durch
   Ausbleichen. Alle Farben kommen aus der Palette. */

.werkstatt {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  background: var(--w-wand);

  --w-wand: color-mix(in srgb, var(--gold) 30%, var(--akzent-tint));
  --w-holz: color-mix(in srgb, var(--akzent-tief) 55%, var(--gold));
  --w-holz-dunkel: color-mix(in srgb, var(--w-holz) 68%, var(--text));
  --w-rot: var(--akzent);
  --w-gruen: var(--tanne);
  --w-weiss: var(--schnee-weiss);

  /* Die Wichtel hier sind so satt wie der im Giebelfenster - die blassen
     Figuren der ersten Fassung verschwanden vor der Holzwand. */
  /* Rot-gruene Muetzen (RIC-82): Die weisse Krempe und der weisse Bommel
     verschwanden vor dem verschneiten Fenster, und die Muetze hing ohne
     Rand in der Luft. Gruen auf Rot bleibt vor Schnee wie vor Holz
     sichtbar. */
  --elf-muetze: var(--akzent);
  --elf-krempe: color-mix(in srgb, var(--tanne) 85%, var(--karte));
  --elf-bommel: color-mix(in srgb, var(--tanne) 85%, var(--karte));
  --elf-haut: color-mix(in srgb, var(--gold) 28%, var(--karte));
  --elf-kittel: color-mix(in srgb, var(--tanne) 88%, var(--text));
  --elf-guertel: color-mix(in srgb, var(--akzent-tief) 70%, var(--text));
  --elf-bein: color-mix(in srgb, var(--akzent) 80%, var(--akzent-tief));
  --elf-schuh: color-mix(in srgb, var(--akzent-tief) 70%, var(--text));
  --elf-hand: color-mix(in srgb, var(--akzent) 85%, var(--akzent-tief));
  --elf-zug: color-mix(in srgb, var(--akzent-tief) 80%, var(--text));
  --elf-wange: color-mix(in srgb, var(--akzent) 45%, var(--karte));
}

/* Stube und Nacht liegen uebereinander, die Nacht unten: Sie ist nur
   durch das Fenster der Stube zu sehen (RIC-81). */
.werkstatt__stube,
.werkstatt__draussen {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/*
 * Wohin die Stube faehrt: auf die Mitte der Fensterscheibe (800, 420). Die
 * Zeichnung ist 1600 x 900 und mit "slice" eingepasst - waagerecht liegt
 * das Fenster also immer in der Mitte, senkrecht 30 Einheiten ueber der
 * Mitte, umgerechnet mit dem Massstab, den "slice" gerade nimmt.
 */
.werkstatt__stube {
  transform-origin: 50% calc(50% - max(100vw * 30 / 1600, 100vh * 30 / 900));
}

/*
 * Der Sog ins Haus: Beim Scrollen rueckt die Stube langsam naeher und wird
 * heller - oben sieht man sie durch den Tuerspalt aus der Ferne, am Ende
 * steht man darin. Laeuft an der Scrollposition, nicht an der Zeit. Wo der
 * Browser das nicht kann, steht die Stube einfach still da.
 */
@supports (animation-timeline: scroll()) {
  .werkstatt__stube {
    /* Beide Eigenschaften, die hier bewegt werden: transform (der Sog) und
       scale (die Fahrt durchs Fenster am Seitenende). Mit nur "transform"
       zeichnete der Browser die Stube bei der Fahrt in jedem Bild neu, bis
       zehnfach vergroessert - das frass den Grafikspeicher, und danach
       standen Stube und Buch still, bis man einmal ganz oben war (RIC-89).
       So schiebt er ein fertiges Bild; unscharf wird es erst, wenn man
       ohnehin schon hindurchfliegt. */
    will-change: transform, scale, opacity;
    animation: w-naeher linear both;
    animation-timeline: scroll(root);
  }
}

/* Nur eine Vergroesserung, kein Aufhellen: Ein Filter auf der ganzen
   Stube muesste bei jedem Scrollschritt neu gerechnet werden, eine
   Vergroesserung schiebt nur ein fertiges Bild. */
@keyframes w-naeher {
  from { transform: scale(1.14); }
  to   { transform: scale(1); }
}

/* Raum */
.w-wand { fill: var(--w-wand); }
.w-bretter line {
  stroke: color-mix(in srgb, var(--w-holz) 30%, transparent);
  stroke-width: 3;
}
.w-daemmer-oben  { stop-color: color-mix(in srgb, var(--akzent-tief) 26%, transparent); }
.w-daemmer-unten { stop-color: transparent; }
.w-boden   { fill: color-mix(in srgb, var(--w-holz) 72%, var(--gold)); }
.w-dielen line {
  stroke: color-mix(in srgb, var(--w-holz-dunkel) 45%, transparent);
  stroke-width: 3;
}
.w-leiste  { fill: var(--w-holz-dunkel); }
.w-balken  { fill: var(--w-holz-dunkel); }
.w-teppich { fill: color-mix(in srgb, var(--akzent) 88%, var(--akzent-tief)); }
.w-teppich-rand {
  fill: none;
  stroke: var(--gold-hell);
  stroke-width: 4;
  stroke-dasharray: 14 10;
}

/* Fenster */
/* Die Scheibe: ein Hauch Weiss, damit man Glas sieht und kein Loch. */
.w-glas { fill: color-mix(in srgb, var(--w-weiss) 12%, transparent); }

/* Die Fluegel sind an ihrer Aussenkante angeschlagen und gehen nach
   draussen auf - wie die Haustuer als Stauchung zur Angel hin. */
.w-fluegel { transform-box: fill-box; }
.w-fluegel--links  { transform-origin: left center; }
.w-fluegel--rechts { transform-origin: right center; }

/* Der Elf auf der Fensterbank hebt die Hand an den Fluegel. */
.elf--fenster {
  --elf-arm-vorn: -70deg;
}

.w-sprosse,
.w-rahmen {
  fill: none;
  stroke: var(--w-weiss);
  stroke-linejoin: round;
}
.w-sprosse { stroke-width: 9; }
.w-rahmen  { stroke-width: 16; }
.w-fensterbank { fill: var(--w-weiss); }
.w-vorhang { fill: color-mix(in srgb, var(--akzent) 90%, var(--akzent-tief)); }
/* Zuckerstangen in der Stube (RIC-90), gezeichnet wie die am Haus: ein
   weisser Grund, darauf rote Abschnitte mit geraden Enden. */
.w-zuckerstange path {
  fill: none;
  stroke-width: 9;
}

.w-zucker-grund {
  stroke: var(--schnee-weiss);
  stroke-width: 10;
  stroke-linecap: round;
}

.w-zucker-streifen {
  stroke: var(--akzent);
  stroke-linecap: butt;
  stroke-dasharray: 6 6;
}

.w-zuckerstange--klein path {
  stroke-width: 5;
}

.w-zuckerstange--klein .w-zucker-grund {
  stroke-width: 6;
}

.w-zuckerstange--klein .w-zucker-streifen {
  stroke-dasharray: 3.5 3.5;
}

.w-vorhangstange {
  stroke: var(--gold);
  stroke-width: 8;
  stroke-linecap: round;
}

/* Lichterkette */
.w-girlande {
  fill: none;
  stroke: color-mix(in srgb, var(--tanne) 90%, var(--text));
  stroke-width: 16;
  stroke-linecap: round;
  stroke-dasharray: 7 4;
}
.w-birne { animation: w-glimmen 3.6s ease-in-out infinite; }
.w-birne--0 { fill: var(--gold-hell); }
.w-birne--1 { fill: color-mix(in srgb, var(--akzent) 80%, var(--gold-hell)); }
.w-birne--2 { fill: color-mix(in srgb, var(--tanne) 45%, var(--gold-hell)); }
.w-takt--1 { animation-delay: 0.9s; }
.w-takt--2 { animation-delay: 1.8s; }
.w-takt--3 { animation-delay: 2.7s; }

.w-haengestern line {
  stroke: color-mix(in srgb, var(--w-holz-dunkel) 60%, transparent);
  stroke-width: 2;
}
.w-haengestern use { fill: var(--gold); }
.w-haengestern {
  animation: w-pendeln 7s ease-in-out infinite;
}
.w-haengestern--2 { animation-duration: 8.5s; animation-delay: -3s; }

@keyframes w-pendeln {
  0%, 100% { transform: rotate(-4deg); }
  50%      { transform: rotate(4deg); }
}

/* Kamin */
.w-schein-innen { stop-color: color-mix(in srgb, var(--gold-hell) 55%, transparent); }
.w-schein-aussen { stop-color: transparent; }
.w-kamin-mauer { fill: color-mix(in srgb, var(--akzent) 42%, var(--gold-spur)); }
.w-kamin-steine rect { fill: color-mix(in srgb, var(--akzent) 26%, var(--gold-spur)); }
.w-kamin-loch  { fill: color-mix(in srgb, var(--akzent-tief) 45%, var(--text)); }
.w-kaminsims   { fill: var(--w-holz-dunkel); }
/* Holz: die Rinde im Holzton der Stube, die Schnittflaeche hell, der
   Jahresring als feiner Strich (RIC-79). */
.w-scheit rect,
.w-stapel-scheit {
  fill: var(--w-holz);
  stroke: var(--w-holz-dunkel);
  stroke-width: 1.5;
}
/* Die gekreuzten Scheite oben liegen im Licht der Flammen - heller als der
   untere, sonst verschwimmen alle drei vor dem dunklen Loch zu einem. */
.w-scheit--oben rect { fill: color-mix(in srgb, var(--w-holz) 75%, var(--gold-hell)); }
.w-hirnholz      { fill: color-mix(in srgb, var(--gold-hell) 55%, var(--w-holz)); }
.w-jahresring {
  fill: none;
  stroke: var(--w-holz);
  stroke-width: 1.4;
}
.w-rinde {
  stroke: var(--w-holz-dunkel);
  stroke-width: 1.6;
  stroke-linecap: round;
}
.w-rost rect { fill: color-mix(in srgb, var(--text) 85%, var(--akzent-tief)); }

/* Der Schein an der Rueckwand der Feuerstelle und im Raum atmet mit dem
   Feuer - nur die Deckkraft, das kostet beim Zeichnen fast nichts. */
.w-glutschein {
  animation: w-glimmern 2.3s ease-in-out infinite;
}
.w-feuerschein {
  animation: w-schein-atmen 3.1s ease-in-out infinite;
}

@keyframes w-schein-atmen {
  0%, 100% { opacity: 1; }
  40%      { opacity: 0.8; }
  70%      { opacity: 0.93; }
}

@keyframes w-glimmern {
  0%, 100% { opacity: 0.75; }
  35%      { opacity: 1; }
  55%      { opacity: 0.6; }
  80%      { opacity: 0.9; }
}

.w-glut circle {
  fill: var(--gold-hell);
  animation: w-gluehen 1.9s ease-in-out infinite;
}
.w-glut .w-glut--2 { animation-duration: 2.6s; animation-delay: -0.8s; }
.w-glut .w-glut--3 { animation-duration: 1.5s; animation-delay: -0.3s; }

@keyframes w-gluehen {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}

/* Jede Zunge flackert in eigenem Takt und neigt sich dabei leicht - die
   krummen Laufzeiten sorgen dafuer, dass sich das Muster nie sichtbar
   wiederholt. */
.w-flamme {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: w-flackern 1.6s ease-in-out infinite;
}
.w-flamme--aussen  { fill: color-mix(in srgb, var(--akzent) 70%, var(--gold)); }
.w-flamme--links   { animation-duration: 1.3s; animation-delay: -0.7s; }
.w-flamme--rechts  { animation-duration: 1.45s; animation-delay: -0.2s; animation-direction: reverse; }
.w-flamme--mitte   { fill: var(--gold); animation-duration: 1.15s; animation-delay: -0.4s; }
.w-flamme--innen   { fill: var(--gold-hell); animation-duration: 0.85s; }

@keyframes w-flackern {
  0%, 100% { transform: scale(1, 1) rotate(0deg); }
  20%      { transform: scale(0.95, 1.07) rotate(-2.5deg); }
  45%      { transform: scale(1.03, 0.94) rotate(1.5deg); }
  70%      { transform: scale(0.97, 1.1) rotate(2.5deg); }
  85%      { transform: scale(1.02, 0.97) rotate(-1deg); }
}

/* Funken steigen auf und verloeschen, bevor sie den Bogen erreichen. */
.w-funke {
  fill: var(--gold-hell);
  opacity: 0;
  animation: w-funkenflug 2.8s ease-out infinite;
}
.w-funke--2 { animation-duration: 3.4s; animation-delay: -1.2s; }
.w-funke--3 { animation-duration: 2.3s; animation-delay: -2s; }

@keyframes w-funkenflug {
  0%   { opacity: 0;   transform: translate(0, 0); }
  10%  { opacity: 1; }
  100% { opacity: 0;   transform: translate(8px, -80px); }
}

.w-strumpf path { fill: var(--akzent); }
.w-strumpf--gruen path { fill: var(--tanne); }
.w-strumpf-rand { fill: var(--w-weiss); }

.w-kranz-reif {
  fill: none;
  stroke: color-mix(in srgb, var(--tanne) 90%, var(--text));
  stroke-width: 18;
  stroke-dasharray: 6 3;
}
.w-beere   { fill: var(--akzent); }
.w-schleife { fill: var(--akzent); }

.w-tasse rect { fill: var(--w-weiss); }
.w-tasse .w-henkel {
  fill: none;
  stroke: var(--w-weiss);
  stroke-width: 4;
}
.w-dampf path {
  fill: none;
  stroke: color-mix(in srgb, var(--w-weiss) 80%, transparent);
  stroke-width: 3;
  stroke-linecap: round;
  animation: w-dampf-steigen 3.2s ease-in-out infinite;
}
.w-dampf path:last-child { animation-delay: 1.6s; }

@keyframes w-dampf-steigen {
  0%   { opacity: 0; transform: translateY(6px); }
  35%  { opacity: 0.8; }
  100% { opacity: 0; transform: translateY(-18px); }
}

/* Werkbank */
.w-bank-platte   { fill: var(--w-holz); }
.w-bank-schuerze { fill: color-mix(in srgb, var(--w-holz) 70%, var(--w-holz-dunkel)); }
.w-bank-bein     { fill: var(--w-holz-dunkel); }
.w-rolle rect    { fill: var(--tanne); }
.w-rolle circle  { fill: var(--gold-hell); }

.w-gabe rect      { fill: var(--akzent); }
.w-gabe--gruen rect { fill: var(--tanne); }
.w-gabe--gold rect  { fill: var(--gold); }
.w-gabe .w-band     { fill: var(--gold-hell); }
.w-gabe--gold .w-band { fill: var(--akzent); }

.w-schleife-hopst {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: w-hopsen 2.4s ease-in-out infinite;
}

@keyframes w-hopsen {
  0%, 60%, 100% { transform: translateY(0) scale(1); }
  72%           { transform: translateY(-5px) scale(1.08); }
  84%           { transform: translateY(0) scale(0.96, 1.02); }
}

.w-kalender-dach { fill: var(--akzent); }
.w-kalender-haus { fill: var(--w-holz); }
.w-tuerchen      { fill: color-mix(in srgb, var(--gold-spur) 80%, var(--w-holz)); }
.w-tuerchen--offen {
  fill: var(--gold-hell);
  animation: w-glimmen 5s ease-in-out infinite;
}

/* Tannenbaum */
.w-baum path   { fill: color-mix(in srgb, var(--tanne) 92%, var(--text)); }
.w-baum .w-stamm { fill: var(--w-holz-dunkel); }
.w-baum-schnur {
  fill: none;
  stroke: var(--gold-hell);
  stroke-width: 3;
  stroke-dasharray: 2 7;
  stroke-linecap: round;
}
.w-kugel { animation: w-glimmen 4s ease-in-out infinite; }
.w-kugel--0 { fill: var(--akzent); }
.w-kugel--1 { fill: var(--gold-hell); }
.w-kugel--2 { fill: var(--w-weiss); }
.w-baumstern {
  fill: var(--gold-hell);
  filter: drop-shadow(0 0 8px color-mix(in srgb, var(--gold-hell) 80%, transparent));
}

/* Regal, Leiter, Spielzeug */
.w-regal rect { fill: var(--w-holz-dunkel); }
.w-teddy circle,
.w-teddy ellipse { fill: color-mix(in srgb, var(--akzent-tief) 40%, var(--gold)); }
.w-teddy .w-teddy-schnauze { fill: var(--gold-spur); }
.w-trommel rect { fill: var(--akzent); }
.w-trommel-zacken {
  fill: none;
  stroke: var(--gold-hell);
  stroke-width: 3;
  stroke-linejoin: round;
}
.w-leiter path,
.w-leiter line {
  fill: none;
  stroke: var(--w-holz);
  stroke-width: 9;
  stroke-linecap: round;
}
.w-leiter line { stroke-width: 6; }

.w-pferd {
  transform-origin: 1350px 790px;
  animation: w-schaukeln 3.4s ease-in-out infinite;
}
.w-kufe,
.w-pferd-bein {
  fill: none;
  stroke: var(--w-holz-dunkel);
  stroke-width: 8;
  stroke-linecap: round;
}
.w-pferd-leib    { fill: var(--w-weiss); }
.w-pferd-maehne  { fill: var(--akzent); }
.w-pferd-sattel  { fill: var(--tanne); }
.w-pferd-auge    { fill: var(--w-holz-dunkel); }

@keyframes w-schaukeln {
  0%, 100% { transform: rotate(-5deg); }
  50%      { transform: rotate(5deg); }
}

/* Die Wichtel */

/* Jeder zweite traegt die Muetze andersherum: gruen mit rotem Rand. Das
   Gruen ist heller als der Kittel, sonst verschmoelzen Muetze und Koerper. */
.elf--packer,
.elf--fenster {
  --elf-muetze: color-mix(in srgb, var(--tanne) 80%, var(--karte));
  --elf-krempe: var(--akzent);
  --elf-bommel: var(--akzent);
}

.elf-last rect { fill: var(--akzent); }
.elf-last .w-band {
  stroke: var(--gold-hell);
  stroke-width: 4;
}
.w-schleife-klein { fill: var(--gold-hell); }

/* Der Traeger geht ein paar Schritte zwischen Kamin und Werkbank. */
.elf--traeger {
  animation: elf-gehen 16s ease-in-out infinite alternate;
}

@keyframes elf-gehen {
  from { transform: translateX(0); }
  to   { transform: translateX(-26px); }
}

/* Der Packwichtel nickt ueber seinem Geschenk, im Takt der Schleife. */
.elf--packer {
  transform-origin: 737px 658px;
  animation: elf-packen 2.4s ease-in-out infinite;
}

@keyframes elf-packen {
  0%, 60%, 100% { transform: rotate(0deg); }
  72%           { transform: rotate(6deg); }
}

/* Der auf der Leiter reckt sich zum obersten Fach und sinkt zurueck. */
.elf--leiter {
  animation: elf-recken 4.2s ease-in-out infinite;
}

@keyframes elf-recken {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-8px); }
}

/* --- Eingang und Ausgang (RIC-67) ----------------------------------------
   Zwei freie Abschnitte: unter dem Kopfbereich geht man durch die Haustuer
   in die Stube, nach dem Wichtelbuch durch die Tuer wieder hinaus. Die
   Buehne klebt am Bildschirm, der Abschnitt laeuft darunter durch; seine
   Hoehe ist die Laenge des Weges.

   Ohne Scroll-Animationen im Browser (Firefox) gibt es weder Tuer noch
   Wand: Der Eingang ist dann ein freier Blick in die Stube, der Ausgang
   ein Blick in die Nacht. */

.werkstatt-gang {
  position: relative;
  height: 70svh;
}

.werkstatt-gang__buehne {
  position: sticky;
  top: 0;
  height: 100svh;
  max-height: 100%;
  overflow: hidden;
  display: grid;
  place-items: center;
}

.werkstatt-gang__tor {
  display: none;
}

/* Der Ausgang: Rahmen um Buehne, Weg, Fusszeile und Signatur. Die Buehne
   klebt darin bis zum Seitenende; alles danach schiebt sich darueber. */
.werkstatt-schluss {
  position: relative;
}

.werkstatt-schluss__weg {
  position: relative;
  height: 0;
}

/* Fusszeile und Signatur liegen ueber der klebenden Nacht - ohne eigene
   Position malte der Browser die Signatur darunter. */
.werkstatt-schluss .fuss,
.werkstatt-schluss .nd-signatur {
  position: relative;
}

.werkstatt-schluss .fuss {
  border-radius: 1.2rem 1.2rem 0 0;
  box-shadow: 0 -0.6rem 2rem color-mix(in srgb, var(--text) 12%, transparent);
}

.werkstatt-gang__text {
  position: relative;
  margin: 0 1.25rem;
  padding: 0.6rem 1.4rem 0.8rem;
  max-width: 34rem;
  text-align: center;
  font-family: 'Dancing Script', 'Segoe Script', cursive;
  font-weight: 700;
  font-size: clamp(1.7rem, 1.2rem + 2vw, 2.6rem);
  line-height: 1.2;
  color: var(--akzent-dunkel);
  text-wrap: balance;
  /* Papier hinter der Schrift, damit sie vor Stube und Nacht lesbar
     bleibt. Deckend statt Milchglas: Ein Weichzeichner hinter Text kostet
     am Telefon bei jedem Bild, und hier bewegt sich darunter alles. */
  background: color-mix(in srgb, var(--karte) 90%, transparent);
  border-radius: 1rem;
  box-shadow: 0 0.4rem 1.6rem color-mix(in srgb, var(--text) 14%, transparent);
}

/* Vor der Haustuer steht der Satz oben an der Wand, ueber dem Kranz. */
.werkstatt-gang--eingang .werkstatt-gang__buehne {
  place-items: start center;
}

.werkstatt-gang--eingang .werkstatt-gang__text {
  margin-top: 14svh;
}

/* Draussen steht er oben am Himmel, gleich unter der Kopfzeile: Unten
   schiebt sich am Ende die Fusszeile auf den Schnee, dazwischen fliegt der
   Schlitten. */
.werkstatt-schluss__buehne {
  place-items: start center;
}

.werkstatt-schluss .werkstatt-gang__text {
  margin-top: calc(4.5rem + 2svh);
}

/* Draussen */
.draussen__himmel-oben  { stop-color: color-mix(in srgb, var(--tanne) 45%, var(--text)); }
.draussen__himmel-unten { stop-color: color-mix(in srgb, var(--tanne) 55%, var(--karte)); }
.draussen__mond   { fill: var(--gold-hell); }
.draussen__sterne { fill: var(--gold-hell); }
/* Die Tannen: Farbe und Schneeton kommen als Variablen vom <use>. */
.tanne__gruen  { fill: var(--tanne-gruen); }
.tanne__schnee { fill: var(--tanne-schnee); }
.tanne__stamm  { fill: color-mix(in srgb, color-mix(in srgb, var(--akzent-tief) 55%, var(--gold)) 75%, var(--text)); }

.draussen__wald-fern {
  --tanne-gruen: color-mix(in srgb, var(--tanne) 55%, color-mix(in srgb, var(--karte) 50%, var(--text)));
  --tanne-schnee: color-mix(in srgb, var(--schnee-weiss) 85%, var(--tanne));
}

.draussen__wald-nah {
  --tanne-gruen: color-mix(in srgb, var(--tanne) 88%, var(--text));
  --tanne-schnee: var(--schnee-weiss);
}

.draussen__huegel-fern { fill: color-mix(in srgb, var(--schnee-weiss) 88%, var(--tanne)); }
.draussen__huegel { fill: var(--schnee-weiss); }
.draussen__mulde  { fill: color-mix(in srgb, var(--schnee-weiss) 90%, var(--tanne)); }
.draussen__spuren { fill: color-mix(in srgb, var(--schnee-weiss) 66%, var(--tanne)); }
.draussen__glitzer circle {
  fill: var(--gold-hell);
  animation: w-glimmen 3.2s ease-in-out infinite;
}
.draussen__glitzer circle:nth-child(2n) { animation-delay: 1.1s; }
.draussen__glitzer circle:nth-child(3n) { animation-delay: 2.2s; }

.draussen__schein-innen  { stop-color: color-mix(in srgb, var(--gold-hell) 60%, transparent); }
.draussen__schein-aussen { stop-color: transparent; }
.laterne__pfahl,
.laterne__dach   { fill: color-mix(in srgb, color-mix(in srgb, var(--akzent-tief) 55%, var(--gold)) 60%, var(--text)); }
.laterne__glas   {
  fill: var(--gold-hell);
  filter: drop-shadow(0 0 6px color-mix(in srgb, var(--gold-hell) 80%, transparent));
}
.laterne__schnee { fill: var(--schnee-weiss); }
.draussen__schnee { fill: var(--schnee-weiss); opacity: 0.85; }

/* Der Weihnachtsmann huscht vorbei: gut fuenf Sekunden quer ueber den
   Himmel, dann eine Pause ausserhalb des Bildes. Die Bahn liegt tief
   (y 460 bis 660): Am Schreibtisch schneidet der Ausschnitt den Himmel
   oben bis etwa y 300 ab, und darueber steht der Satz. Er haengt an der Zeit und
   nicht am Scrollen - wer draussen stehen bleibt, sieht ihn wiederkommen. */
.draussen__schlitten {
  animation: schlitten-fliegen 12s linear 0.6s infinite both;
}

/* Mit Skript wartet er, bis man draussen ankommt, und startet dann sofort
   - siehe werkstatt-ausgang.blade.php. */
.mit-ankunft .draussen__schlitten {
  animation: none;
  visibility: hidden;
}

.mit-ankunft.ist-draussen .draussen__schlitten {
  visibility: visible;
  animation: schlitten-fliegen 12s linear 0.3s infinite both;
}

/* 97 Prozent des Weges: Erst dort ist die Wand ganz aus dem Bild.
   Bei 87,5 Prozent stand man am Schreibtisch noch im Tuerrahmen - der
   Schlitten flog hinter der Wand vorbei und war nur mit Glueck zu sehen.
   Am Telefon fiel das nicht auf, weil der schmale Ausschnitt ihn erst
   spaeter zeigt. */
.werkstatt-gang__ankunft {
  position: absolute;
  left: 0;
  top: 97%;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

.schlitten__schweben {
  animation: schlitten-schweben 1.1s ease-in-out infinite alternate;
}

@keyframes schlitten-fliegen {
  0%        { transform: translate(-60px, 660px) rotate(-8deg); }
  22%       { transform: translate(520px, 580px) rotate(-6deg); }
  44%       { transform: translate(1320px, 460px) rotate(-5deg); }
  44.1%, 100% { transform: translate(1320px, 460px); visibility: hidden; }
}

/* Am Telefon zeigt der Ausschnitt den ganzen Himmel, aber nur die Mitte
   der Breite - dort liegt die Bahn hoeher, zwischen Satz und Fusszeile. */
@media (max-width: 48rem) {
  .draussen__schlitten {
    animation-name: schlitten-fliegen-schmal;
  }

  .mit-ankunft .draussen__schlitten {
    animation-name: none;
  }

  .mit-ankunft.ist-draussen .draussen__schlitten {
    animation-name: schlitten-fliegen-schmal;
  }
}

@keyframes schlitten-fliegen-schmal {
  0%        { transform: translate(-60px, 480px) rotate(-8deg); }
  22%       { transform: translate(520px, 420px) rotate(-6deg); }
  44%       { transform: translate(1320px, 330px) rotate(-5deg); }
  44.1%, 100% { transform: translate(1320px, 330px); visibility: hidden; }
}

@keyframes schlitten-schweben {
  from { transform: translateY(-3px); }
  to   { transform: translateY(3px); }
}

.schlitten__glitzer { fill: var(--gold-hell); }
.schlitten__glitzer circle:nth-child(2) { opacity: 0.75; }
.schlitten__glitzer circle:nth-child(3) { opacity: 0.5; }
.schlitten__glitzer circle:nth-child(4) { opacity: 0.3; }
.schlitten__zuegel {
  fill: none;
  stroke: var(--gold-hell);
  stroke-width: 1.5;
}
.rentier__leib   { fill: color-mix(in srgb, var(--akzent-tief) 45%, var(--gold)); }
.rentier__beine,
.rentier__geweih {
  fill: none;
  stroke: color-mix(in srgb, var(--akzent-tief) 55%, var(--gold));
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.rentier__geweih { stroke: var(--gold-spur); stroke-width: 2.2; }
.rentier__geschirr {
  stroke: var(--akzent);
  stroke-width: 3;
  stroke-linecap: round;
}
.rentier__nase   { fill: var(--akzent); }
.schlitten__sack { fill: color-mix(in srgb, var(--akzent-tief) 40%, var(--gold)); }
.santa__mantel,
.santa__muetze   { fill: var(--akzent); }
.santa__gesicht  { fill: color-mix(in srgb, var(--gold) 28%, var(--karte)); }
.santa__bart,
.santa__bommel,
.santa__krempe   { fill: var(--schnee-weiss); }
.schlitten__kasten { fill: color-mix(in srgb, var(--akzent) 85%, var(--akzent-tief)); }
.schlitten__kufe {
  fill: none;
  stroke: var(--gold);
  stroke-width: 3.5;
  stroke-linecap: round;
}

@supports (animation-timeline: view()) {
  /* Etwa eine Bildschirmhoehe Weg: ein Schritt, kein Warten. */
  .werkstatt-gang {
    height: 200svh;
    view-timeline: --gang block;
  }

  .werkstatt-gang__tor {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
  }

  /* Vor der Tuer steht der Satz schon da und verblasst beim Eintreten.
     Draussen erscheint er erst, wenn man angekommen ist. */
  .werkstatt-gang--eingang .werkstatt-gang__text {
    animation: gang-satz-weg linear both;
    animation-timeline: --gang;
    animation-range: contain 5% contain 35%;
  }

  /*
   * Der Ausgang misst am Weg unter der Buehne, nicht an einem Abschnitt:
   * "entry" laeuft, waehrend der Weg von unten ins Bild kommt - also genau
   * die Bildschirmhoehe, die man zum Fenster hinausfaehrt.
   */
  .werkstatt-schluss__weg {
    height: 100svh;
    view-timeline: --hinaus block;
  }

  .werkstatt-schluss .werkstatt-gang__text {
    animation: gang-satz-her linear both;
    animation-timeline: --hinaus;
    animation-range: entry 75% entry 100%;
  }

}

@keyframes gang-satz-weg {
  from { opacity: 1; }
  to   { opacity: 0; transform: translateY(-1.2rem); }
}

/* --- Der Eingang als Haus aus dem Kopfbereich (RIC-80) -------------------
   Die Zeichnung ist dieselbe wie oben (haus-zeichnung.blade.php), nur
   vergroessert. Ablauf beim Scrollen, alles an der Scrollposition:
     1. Ein Elf zieht die Tuer auf - zur Angel rechts hin, wie oben.
     2. Er tritt nach links beiseite, das warme Licht in der Tuer verblasst,
        und dahinter liegt die Stube.
     3. Man geht hindurch: Das Haus waechst um die Tuer herum, bis die
        Oeffnung den Bildschirm fuellt.
   Der Zoom sitzt in der Tuermitte (500, 844). Faktor 22 reicht, damit die
   Oeffnung auch an der Rundung oben Bildschirm und Handy ganz fuellt. */

/* Oben stehen die Fenster in einem Lichthof aus drop-shadow. Beim Zoomen
   muesste der in jedem Bild neu gerechnet werden - hier ohne. */
.eingang-haus .h-fenster,
.eingang-haus .h-mond,
.eingang-haus .h-turmstern {
  filter: none;
}

@supports (animation-timeline: view()) {
  .eingang-tor {
    transform-origin: 500px 844px;
    animation: eingang-eintreten linear both;
    animation-timeline: --gang;
    animation-range: contain 34% contain 95%;
  }

  .eingang-tuer__blatt {
    transform-box: fill-box;
    transform-origin: right center;
    animation: eingang-aufziehen linear both;
    animation-timeline: --gang;
    animation-range: contain 2% contain 24%;
  }

  .eingang-tuer__elf {
    animation: eingang-beiseite linear both;
    animation-timeline: --gang;
    animation-range: contain 22% contain 36%;
  }

  .eingang-tuer__licht {
    animation: eingang-licht linear both;
    animation-timeline: --gang;
    animation-range: contain 20% contain 40%;
  }
}

@keyframes eingang-aufziehen {
  from { transform: scaleX(1); }
  to   { transform: scaleX(0.1); }
}

/* Ein kurzer Schritt nach links, raus aus der Oeffnung - der Beschnitt
   der Tuer laesst ihn hinter der Wand verschwinden. */
@keyframes eingang-beiseite {
  from { transform: translateX(0); }
  to   { transform: translateX(-34px); }
}

@keyframes eingang-licht {
  from { opacity: 1; }
  to   { opacity: 0; }
}

@keyframes eingang-eintreten {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.8); }
  100% { transform: scale(22); }
}

/* --- Das Haus als Kopfbereich (RIC-86) ----------------------------------
   Der Eingang ist selbst der Kopfbereich: Zu Beginn liegen Ueberschrift,
   Text und Knoepfe auf der Hausszene, dann scrollen sie weg, "Pssst ..."
   erscheint, der Elf oeffnet die Tuer, und man geht hinein. Der Weg ist
   dafuer laenger als beim Eingang allein, und alle Bewegungen setzen
   spaeter ein - erst muss der Text aus dem Bild sein.

   Der Kopfbereich uebernimmt die Farben der geteilten Bauform (roter
   Titel in Schreibschrift), aber nicht ihr Raster und ihren Grund. */
.hero--eingang {
  display: block;
  min-height: 0;
  padding: 0;
  overflow: visible;
  background: none;
}

.werkstatt-gang__strecke {
  height: 0;
}

.werkstatt-gang__kopf {
  position: relative;
  z-index: 2;
  margin-top: -100svh;
  min-height: 100svh;
  display: grid;
  align-content: center;
  gap: 0.75rem;
  padding: 4.75rem 0.75rem 1.5rem;
}

/* Der Text liegt auf einer Karte aus Papier: Hinter ihm stehen Wald,
   Himmel und Schnee, und darauf waere Kleingedrucktes nicht zu lesen. */
.werkstatt-gang__kopf .hero__inhalt {
  /* Die geteilte Bauform stellt den Text am Handy per order hinter das
     Bild und gibt ihm am Schreibtisch eine feste Rasterzelle - beides
     gilt hier nicht. */
  order: 0;
  grid-column: auto;
  grid-row: auto;
  width: auto;
  max-width: 40rem;
  margin: 0;
  padding: clamp(1.1rem, 2.4vw, 1.9rem) clamp(1.25rem, 3vw, 2.25rem);
  background: color-mix(in srgb, var(--karte) 88%, transparent);
  border-radius: 1rem;
  box-shadow: 0 0.6rem 2rem color-mix(in srgb, var(--text) 14%, transparent);
}

/* Etwas kleiner als im geteilten Kopfbereich: Karte, Knoepfe und Hinweise
   sollen am Schreibtisch zusammen auf den ersten Bildschirm passen. */
.werkstatt-gang__kopf .hero__titel {
  font-size: clamp(2.3rem, 1.3rem + 3vw, 3.6rem);
  max-width: none;
}

/* Countdown und Dank-Hinweis stehen fest, solange man auf der Seite ist:
   der Countdown als Schild unter der Kopfzeile (er haengt an ihr und
   klebt mit ihr), der Dank als schmale Zeile am unteren Rand. Draussen am
   Seitenende blenden beide aus - dort stehen Abschiedssatz und Fusszeile. */
.kopf__leiste {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  padding-inline: 0.75rem;
  pointer-events: none;
  transition: opacity 0.4s;
}

.fussleiste {
  position: fixed;
  z-index: 45;
  left: 0;
  right: 0;
  bottom: 0.6rem;
  display: flex;
  justify-content: center;
  padding-inline: 0.75rem;
  pointer-events: none;
  transition: opacity 0.4s;
}

.kopf__leiste > *,
.fussleiste > * {
  pointer-events: auto;
}

.fussleiste .dankbanner {
  padding: 0.45rem 1.1rem;
  border: 1px solid var(--linie);
  border-radius: 999px;
  background: color-mix(in srgb, var(--karte) 92%, transparent);
  box-shadow: 0 0.3rem 1.2rem color-mix(in srgb, var(--text) 14%, transparent);
}

.fussleiste .dankbanner__wort {
  font-size: 0.8rem;
}

body.ist-draussen .kopf__leiste,
body.ist-draussen .fussleiste {
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: opacity 0.4s, visibility 0s 0.4s;
}

/* Die Karte rueckt unter dem Countdown-Schild ein Stueck nach unten. */
.werkstatt-gang__kopf {
  padding-top: 7rem;
  padding-bottom: 4rem;
}

/* Am Handy ist fuer zwei feste Leisten kein Platz: Das Schild steht dort
   einzeilig ohne Datum, und beide blenden aus, sobald man ins Haus scrollt
   (ist-unterwegs, siehe layout.blade.php). Das Buch bekommt dann die ganze
   Hoehe. */
@media (max-width: 39.999rem) {
  .kopf__leiste .countdown__datum {
    display: none;
  }

  .kopf__leiste .countdown {
    padding: 0.35rem 1.1rem;
  }

  /* Nicht nur durchsichtig, sondern weg: Die Kinder der Leisten nehmen
     Klicks ausdruecklich an (pointer-events: auto), und das unsichtbare
     "Zum ganzen Dank" fing dann den Tipp auf die Scroll-Erinnerung ab,
     die genau dort steht - das Buch sprang zum Dank. visibility greift
     auch fuer die Kinder, und erst nach dem Ausblenden. */
  body.ist-unterwegs .kopf__leiste,
  body.ist-unterwegs .fussleiste {
    opacity: 0;
    pointer-events: none;
    visibility: hidden;
    transition: opacity 0.4s, visibility 0s 0.4s;
  }
}

/* Am Schreibtisch steht der Text links im Wald, und das Haus rueckt dafuer
   nach rechts. Gerechnet in Zeichnungseinheiten: Die Tuer bleibt auch beim
   Hineinzoomen der feste Punkt, um den alles waechst. */
@media (min-width: 64rem) {
  .werkstatt-gang__kopf {
    justify-items: start;
    padding-inline: 5vw;
  }

  .werkstatt-gang--kopf .eingang-lage {
    transform: translate(190px, 0);
  }
}

@supports (animation-timeline: view()) {
  /*
   * Der Weg ist die Karte plus die Strecke dahinter, und alles haengt an
   * der Strecke (--tuer). Gemessen mit "cover": 0 %, wenn die Strecke von
   * unten ins Bild kommt (die Karte endet am unteren Rand), 28,6 %, wenn
   * die Karte oben hinaus ist, 71,4 %, wenn die Buehne sich loest. Die
   * Strecke ist 250svh lang, der ganze Messweg damit 350svh.
   */
  .werkstatt-gang--kopf {
    height: auto;
    timeline-scope: --tuer;
  }

  .werkstatt-gang__strecke {
    height: 250svh;
    view-timeline: --tuer block;
  }

  .werkstatt-gang--kopf .eingang-tuer__blatt {
    animation-timeline: --tuer;
    animation-range: cover 34% cover 46%;
  }

  .werkstatt-gang--kopf .eingang-tuer__elf {
    animation-timeline: --tuer;
    animation-range: cover 45% cover 52%;
  }

  .werkstatt-gang--kopf .eingang-tuer__licht {
    animation-timeline: --tuer;
    animation-range: cover 44% cover 54%;
  }

  .werkstatt-gang--kopf .eingang-tor {
    animation-timeline: --tuer;
    animation-range: cover 50% cover 71%;
  }

  /* "Pssst ..." erscheint, waehrend die Karte hinausrollt, und steht, bis
     die Tuer aufgeht. */
  .werkstatt-gang--kopf .werkstatt-gang__text {
    animation: gang-satz-her linear both;
    animation-timeline: --tuer;
    animation-range: cover 22% cover 30%;
  }

  .werkstatt-gang--kopf .werkstatt-gang__satz {
    animation: gang-huelle-weg linear both;
    animation-timeline: --tuer;
    animation-range: cover 43% cover 49%;
  }
}

/*
 * Die Sprechblase des Elfen (RIC-92): Im Kopfbereich steht "Pssst ..." nicht
 * mehr oben an der Wand, sondern als Blase ueber dem Elf, der die Tuer
 * aufzieht. Wo sein Kopf ist, rechnet das Skript in
 * werkstatt-eingang.blade.php aus. Sie erscheint, wenn die Tuer aufgeht, und
 * verblasst, wenn er beiseitetritt.
 */
.werkstatt-gang--kopf .werkstatt-gang__satz.ist-blase {
  position: absolute;
  left: var(--blase-links);
  bottom: var(--blase-unten);
  width: max-content;
  max-width: min(17rem, calc(100vw - 24px));
  margin: 0;
}

.werkstatt-gang--kopf .ist-blase .werkstatt-gang__text {
  margin: 0;
  padding: 0.55rem 1.1rem 0.7rem;
  max-width: none;
  font-size: clamp(1.25rem, 1rem + 1vw, 1.7rem);
  line-height: 1.15;
  background: var(--karte);
  border-radius: 1.3rem;
}

/* Der Zipfel zeigt nach unten auf den Kopf des Elfen. */
.werkstatt-gang--kopf .ist-blase .werkstatt-gang__text::after {
  content: '';
  position: absolute;
  top: calc(100% - 1px);
  left: calc(var(--zipfel) - 0.7rem);
  width: 1.1rem;
  height: 1rem;
  background: var(--karte);
  clip-path: polygon(0 0, 100% 0, 25% 100%);
}

@supports (animation-timeline: view()) {
  /* Erst, wenn die Tuer aufgeht und der Elf zu sehen ist ... */
  .werkstatt-gang--kopf .ist-blase .werkstatt-gang__text {
    transform-origin: var(--zipfel) 100%;
    animation: gang-blase-her linear both;
    animation-timeline: --tuer;
    animation-range: cover 38% cover 42%;
  }

  /* ... und weg, wenn er beiseitetritt. */
  .werkstatt-gang--kopf .werkstatt-gang__satz.ist-blase {
    animation-range: cover 47% cover 51%;
  }
}

@keyframes gang-blase-her {
  from { opacity: 0; transform: scale(0.6) translateY(0.6rem); }
  to   { opacity: 1; transform: none; }
}

/* Am Handy ist die Textkarte laenger als der Bildschirm und rollt spaet
   hinaus. Der Satz steht dort deshalb tiefer, ueber dem Dach, und kommt
   erst, wenn die Karte ihn freigegeben hat - oben lag sie noch darueber. */
@media (max-width: 39.999rem) {
  /* Zusammen mit den 14svh des Satzes selbst steht er bei 46svh. */
  .werkstatt-gang--kopf .werkstatt-gang__satz {
    margin-top: 32svh;
  }
}

/* Als Blase steht der Satz beim Elf, nicht tiefer an der Wand. */
@media (max-width: 39.999rem) {
  .werkstatt-gang--kopf .werkstatt-gang__satz.ist-blase {
    margin-top: 0;
  }
}

@keyframes gang-huelle-weg {
  from { opacity: 1; }
  to   { opacity: 0; transform: translateY(-1.2rem); }
}

@keyframes gang-satz-kommt-geht {
  0%        { opacity: 0; transform: translateY(1.2rem); }
  30%, 70%  { opacity: 1; transform: none; }
  100%      { opacity: 0; transform: translateY(-1.2rem); }
}

/* --- Der Ausgang durchs Fenster (RIC-81) ---------------------------------
   Am Seitenende, an der Zeitleiste --hinaus (der Weg unter der Buehne):
     1. Der Elf auf der Fensterbank drueckt beide Fluegel nach draussen auf.
     2. Er tritt nach links hinter den Vorhang.
     3. Die Stube faehrt auf die Scheibe zu und loest sich dabei in die
        Nacht dahinter auf (seit RIC-89 hoechstens 2,4-fach statt 10-fach,
        siehe w-hinaus). Die Nacht rueckt nur wenig naeher - sie ist weit
        weg.
   Braucht beides, Scroll-Zeitleisten und timeline-scope - fehlt eins, bleibt
   man in der Stube und sieht die Nacht durch das geschlossene Fenster. */
@supports (animation-timeline: view()) and (timeline-scope: --a) {
  .werkstatt__stube {
    animation: w-naeher linear both, w-hinaus linear both;
    animation-timeline: scroll(root), --hinaus;
    animation-range: normal, entry 36% entry 100%;
  }

  .w-fluegel {
    animation: w-fluegel-auf linear both;
    animation-timeline: --hinaus;
    animation-range: entry 4% entry 26%;
  }

  .w-fensterelf {
    animation: w-elf-beiseite linear both;
    animation-timeline: --hinaus;
    animation-range: entry 22% entry 38%;
  }

  .werkstatt__draussen {
    transform-origin: 50% 60%;
    will-change: transform;
    animation: w-draussen-naeher linear both;
    animation-timeline: --hinaus;
    animation-range: entry 36% entry 100%;
  }
}

/* Mit "scale" statt "transform": So legt sich die Fahrt ueber den
   langsamen Sog w-naeher, statt ihn zu ersetzen. Erst langsam, dann mit
   Schwung - wie beim Eingang. */
/*
 * Die Stube faehrt aufs Fenster zu und loest sich dabei in die Nacht
 * dahinter auf (RIC-89). Frueher fuhr sie zehnfach vergroessert ganz durch
 * die Scheibe: Hinaus ging das, der Browser schob ein fertiges Bild. Beim
 * Zurueckscrollen tauchte sie aber zehnfach gross wieder auf und musste so
 * neu gezeichnet werden - am Schreibtisch rund 15000 x 7500 Pixel. Die
 * Seite blieb dann leer oder zeigte Bruchstuecke, bis man ganz oben war.
 * Hoechstens 2,4-fach, und das Aufloesen erledigt den Rest.
 */
@keyframes w-hinaus {
  0%     { scale: 1;   opacity: 1; }
  45%    { scale: 1.5; opacity: 1; }
  99.9%  { scale: 2.4; opacity: 0; visibility: visible; }
  100%   { scale: 2.4; opacity: 0; visibility: hidden; }
}

/* Waehrend der Fahrt durchs Fenster stehen Feuer, Wichtel und Lichter in
   der Stube still: Jede Bewegung darin liesse die riesig vergroesserte
   Stube in jedem Bild neu zeichnen. Beim Durchfahren merkt das niemand.
   Die Klasse setzt werkstatt-ausgang.blade.php. */
body.ist-am-ende .werkstatt__stube * {
  animation-play-state: paused !important;
}

/* Ganz draussen ist die Stube nicht nur unsichtbar, sondern weg - siehe
   werkstatt-ausgang.blade.php (RIC-89). */
body.ist-ganz-draussen .werkstatt__stube {
  display: none;
}

@keyframes w-fluegel-auf {
  from { transform: scaleX(1); }
  to   { transform: scaleX(0.1); }
}

@keyframes w-elf-beiseite {
  0%   { transform: translateX(0); opacity: 1; }
  80%  { opacity: 1; }
  100% { transform: translateX(-58px); opacity: 0; }
}

@keyframes w-draussen-naeher {
  from { scale: 1; }
  to   { scale: 1.12; }
}

/* Am Schreibtisch steht der Satz links neben dem Haus, im Wald - oben
   laege er genau auf dem Giebelfenster mit dem winkenden Elf. */
@media (min-width: 64rem) {
  .werkstatt-gang--eingang .werkstatt-gang__buehne {
    place-items: center start;
  }

  .werkstatt-gang--eingang .werkstatt-gang__text {
    margin: 0 0 0 5vw;
    max-width: min(26rem, 30vw);
  }
}

@keyframes gang-satz-her {
  from { opacity: 0; transform: translateY(1.2rem); }
  to   { opacity: 1; transform: none; }
}

/*
 * Solange der Kopfbereich im Bild ist, wird die Stube gar nicht gezeichnet.
 * Sie liegt dort ohnehin hinter dem Haus und dem Papier, liefe aber mit
 * all ihren Bewegungen mit - am Telefon war das der Grund, warum der
 * Kopfbereich stockte. Gemessen wird am Kopfbereich selbst: Die Seite
 * macht seine Zeitleiste fuer alle sichtbar, die Stube schaltet sich
 * daran unsichtbar, solange er zu sehen ist.
 */
@supports (timeline-scope: --kopf) {
  /* --hinaus ist der Weg am Seitenende (werkstatt-ausgang.blade.php). Die
     Stube liegt ausserhalb von ihm und muss ihn trotzdem sehen: Sie faehrt
     an ihm zum Fenster hinaus (RIC-81). */
  body:has(.werkstatt) {
    timeline-scope: --kopf, --hinaus;
  }

  body:has(.werkstatt) .hero {
    view-timeline: --kopf block;
  }

  /* Ist der Eingang der Kopfbereich (RIC-86), misst nur sein Text: Die
     Stube muss sichtbar sein, sobald die Tuer aufgeht - und die gehoert
     hier mit zum Kopfbereich. */
  body:has(.werkstatt) .hero--eingang {
    view-timeline: none;
  }

  body:has(.werkstatt) .werkstatt-gang__kopf {
    view-timeline: --kopf block;
  }

  .werkstatt {
    animation: w-verborgen linear;
    animation-timeline: --kopf;
    animation-range: cover 0% exit 100%;
  }
}

@keyframes w-verborgen {
  from, to { visibility: hidden; }
}

/* Die Fusszeile folgt auf die Nacht draussen. Durchsichtig wie auf einer
   ruhigen Landschaft waere ihr Kleingedrucktes dort nicht zu lesen - also
   bekommt sie hier wieder Papier. */
body:has(.werkstatt) .fuss {
  background: var(--papier);
}

/* Auf der Werkstatt liegt das Wichtelbuch frei, ohne eigenen Grund: Es
   liegt in der Stube und nicht auf einem Streifen Papier davor. */
body:has(.werkstatt) .dank {
  background: transparent;
  border-top: 0;
}

/* =========================================================================
   Das Elfenhaeuschen in der rechten Spalte
   =========================================================================

   Bauform 'haus'. Der Aufbau des Kopfbereichs bleibt der geteilte: Text
   links auf hellem Papier, rechts das Motiv. Das Motiv ist ein
   gezeichnetes Maerchenhaus - steiles Dach, vorgesetzter Giebel mit der
   Tuer, vier warm erleuchtete Fenster, schiefer Schornstein, Schnee auf
   allem, und in einem Fenster ein winkender Elf.

   Gezeichnet als SVG, nicht aus Kaesten: Kaesten haben gerade Kanten und
   rechte Winkel, und damit wurde aus dem Haus eine Bauzeichnung. Hier
   steht deshalb fast nur Farbe - die Formen stehen in der Vorlage.

   Die Tueroeffnung ist im SVG ausgestanzt, und der Kopfbereich hat
   dahinter keinen eigenen Hintergrund: Was man durch den Spalt sieht, ist
   die Elfenwerkstatt, die ohnehin hinter der ganzen Seite laeuft. Der
   Schein im Spalt ist deshalb halbdurchsichtig - deckend waere er ein
   gelbes Feld und kein Blick.
   ========================================================================= */

.hero--haus {
  /*
   * Der Hausblock: am Telefon ein Kasten unter dem Text, am Schreibtisch
   * die rechte Spalte ueber die volle Hoehe. Sein Seitenverhaeltnis liegt
   * nah an dem der Zeichnung - das Bild sitzt mit "slice" darin und
   * verliert sonst zu viel an den Raendern.
   *
   * Die Breite steht in vw und nicht in Prozent, weil dieselbe Zahl weiter
   * unten in eine Hoehe und in die Ecken des Papierzuschnitts eingeht.
   */
  --haus-breite: 100%;
  /*
   * Die Hoehe des Hausbandes am Telefon. Sie haengt nicht am Geschmack,
   * sondern am Seitenverhaeltnis der Zeichnung: Das Bild sitzt mit "slice"
   * in seinem Kasten, fuellt ihn also immer ganz und wird dafuer
   * beschnitten. Ist das Band zu flach, faellt der Dachfirst weg.
   *
   * Seit das Haus hochkant steht (RIC-54), haengt die Hoehe an der Breite.
   * 128vw statt der knapp 111vw, bei denen die Zeichnung genau passt: Der
   * Kunde wollte das Haus hoeher, und was dafuer an den Seiten wegfaellt,
   * ist Wald. Die 76svh sind die Grenze fuer Tablets im Hochformat - sonst
   * stuende dort ein Haus so hoch wie der Bildschirm und der Text faenge
   * unter der Falz an.
   */
  --haus-hoehe: min(128vw, 76svh);

  /* Wie weit die Tuer aufsteht, als Anteil ihrer Breite. Klein halten:
     Eine weit offene Tuer ist eine Einladung hineinzugehen, ein Spalt eine
     Einladung hineinzusehen. */
  --spalt: 0.36;

  background: none;
}

/*
 * Das Papier des Kopfbereichs. Es liegt nicht auf der Sektion selbst,
 * sondern auf dieser Flaeche - und die endet dort, wo das Haus anfaengt.
 * Der Grund ist der Tuerspalt: Durch ihn soll die Werkstatt zu sehen sein,
 * und ein Hintergrund auf der Sektion laege davor.
 *
 * Am Telefon steht das Haus oben und der Text darunter - also faengt das
 * Papier unter dem Haus an. Umgekehrt, Text zuerst, lag das Haus unter der
 * Falz: Man haette erst scrollen muessen, um es ueberhaupt zu sehen.
 */
.hero--haus::before {
  content: '';
  position: absolute;
  inset: var(--haus-hoehe) 0 0 0;
  background: linear-gradient(to bottom,
    var(--akzent-tint) 0%,
    var(--papier) 62%);
}

/* Die weiche Kante der geteilten Bauform gilt hier nicht: Das Haus bringt
   seinen eigenen Himmel mit, und der geht nahtlos in das Papier ueber. */
.hero--haus .hero__medium::after {
  content: none;
}

.hero--haus {
  /* Oben das Haus, darunter der Text - der Innenabstand der geteilten
     Bauform wuerde davor einen Streifen Creme setzen. */
  padding-block: 0 2.5rem;
  align-items: start;
}

.hero--haus .hero__medium {
  order: 1;
  width: 100%;
  height: var(--haus-hoehe);
  margin: 0;
}

.hero--haus .hero__inhalt {
  order: 2;
  padding-top: 1.6rem;
}

/*
 * Schon ab Tablettbreite steht das Haus in der Spalte neben dem Text und
 * nicht mehr als Band darueber - frueher als bei der geteilten Bauform
 * sonst. Grund ist wieder der Zuschnitt: Ein Band ueber 700 Pixel Breite
 * und 240 Pixel Hoehe zeigt vom Haus nur noch einen waagerechten Streifen
 * mit den Fenstern.
 */
@media (min-width: 48rem) {
  .hero--haus {
    --haus-breite: 42%;
    padding-block: 7rem 3rem;
    align-items: center;
    /*
     * Das eigene Raster, und zwar schon hier: Die geteilte Bauform macht
     * ihre zwei Spalten erst ab 56rem auf. Ohne diese Zeile stuende der
     * Text zwischen 48 und 56rem ueber die volle Breite - und das Haus,
     * das absolut ueber der rechten Spalte liegt, mitten darin.
     */
    grid-template-columns: 1fr var(--haus-breite);
  }

  .hero--haus::before {
    inset: 0 var(--haus-breite) 0 0;
  }

  .hero--haus .hero__inhalt {
    grid-column: 1;
    grid-row: 1;
    order: 0;
    padding-top: 0;
    padding-right: 2.5rem;
  }

  /*
   * Das Haus aus dem Raster nehmen und ueber die Spalte legen. Im Raster
   * reichte es nur bis an den Innenabstand des Kopfbereichs - oben blieb
   * ein Streifen Papier ueber dem Dach stehen. Die Rasterangaben muessen
   * dafuer zurueck auf auto, sonst waere die Rasterzelle sein Bezugsrahmen
   * und der Innenabstand wieder da.
   */
  .hero--haus .hero__medium {
    position: absolute;
    grid-column: auto;
    grid-row: auto;
    order: 0;
    inset: 0 0 0 auto;
    width: var(--haus-breite);
    height: auto;
    min-height: 0;
    margin: 0;
  }
}

.haus {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* --- Himmel, Wald, Schnee ------------------------------------------------ */

.h-himmel-oben  { stop-color: var(--akzent-tint); }
.h-himmel-unten { stop-color: var(--papier); }

/* Der Wald hinter dem Haus ist blasser als alles davor: Was weiter weg
   ist, hat weniger Farbe. Ohne diesen Abstand klebt der Wald am Dach. */
.h-wald path {
  /* Etwas satter als frueher (RIC-90), damit die Lichter darauf leuchten -
     immer noch heller als das Haus, die Tannen stehen weiter hinten. */
  fill: color-mix(in srgb, var(--tanne) 52%, var(--papier));
}

/* Der Schmuck der Tannen (RIC-90). */
.h-girlande {
  fill: none;
  stroke: color-mix(in srgb, var(--gold) 75%, var(--papier));
  stroke-width: 0.9;
}

.h-licht {
  stroke-width: 2.2;
  animation: h-licht-funkelt 2.6s ease-in-out infinite alternate;
}

/* Der Schein um jedes Licht ist ein breiter, halb durchsichtiger Rand -
   billiger als ein Weichzeichner. */
.h-licht--0 {
  fill: var(--gold-hell);
  stroke: color-mix(in srgb, var(--gold-hell) 40%, transparent);
}

.h-licht--1 {
  fill: var(--akzent);
  stroke: color-mix(in srgb, var(--akzent) 30%, transparent);
  animation-delay: -0.9s;
}

.h-licht--2 {
  fill: var(--schnee-weiss);
  stroke: color-mix(in srgb, var(--schnee-weiss) 45%, transparent);
  animation-delay: -1.7s;
}

@keyframes h-licht-funkelt {
  0%, 40% { opacity: 1; }
  100%    { opacity: 0.35; }
}

.h-baumstern {
  fill: var(--gold);
  stroke: color-mix(in srgb, var(--gold-hell) 50%, transparent);
  stroke-width: 1.5;
}

.h-zuckerstange.h-zuckerstange--liegend path {
  stroke-width: 3.6;
}

.h-zuckerstange--liegend .h-zucker-grund {
  stroke-width: 4;
}

.h-zuckerstange.h-zuckerstange--liegend .h-zucker-streifen {
  stroke-dasharray: 2.8 2.8;
}

/* Fussspuren: kleine Mulden im Schnee, einen Hauch dunkler als er. */
.h-spur ellipse {
  fill: color-mix(in srgb, var(--linie) 90%, var(--text-still));
  opacity: 0.75;
}

@media (prefers-reduced-motion: reduce) {
  .h-licht {
    animation: none;
  }
}

.h-boden {
  fill: color-mix(in srgb, var(--karte) 95%, var(--gold-spur));
}

/* --- Wand und Fachwerk --------------------------------------------------- */

.h-wand {
  fill: color-mix(in srgb, var(--gold-spur) 78%, var(--karte));
}

/* Der Vorbau steht vor dem Hauptbau und faengt mehr Licht - eine Spur
   heller, sonst verschmelzen die beiden zu einer Flaeche. */
.h-wand--vorbau {
  fill: color-mix(in srgb, var(--gold-spur) 55%, var(--karte));
}

/* --- Daecher und Schnee -------------------------------------------------- */

.h-dach {
  fill: color-mix(in srgb, var(--akzent) 74%, var(--akzent-tief));
}

.h-dach--vorbau {
  fill: color-mix(in srgb, var(--akzent) 86%, var(--akzent-tief));
}

/* Der Schnee liegt als dicker Strich auf den Schraegen. Als eigene Flaeche
   gezeichnet waere es dieselbe Form ein zweites Mal - und beim naechsten
   Dach ein drittes. */
.h-dachschnee {
  fill: none;
  stroke: var(--schnee-weiss);
  stroke-width: 13;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.h-dachschnee--vorbau {
  stroke-width: 11;
}

/* Auf der Traufe liegt weniger als auf den Schraegen: Dort rutscht er
   nach. */
.h-dachschnee--traufe {
  stroke-width: 9;
}

/* Ein paar Haufen an der Traufe: Eine gleichmaessige Kante saehe aus wie
   ein Bauteil und nicht wie Schnee. */
.h-schneehaufen circle {
  fill: var(--schnee-weiss);
}

.h-eis path {
  fill: color-mix(in srgb, var(--schnee-weiss) 82%, var(--akzent-spur));
}

/* --- Schornstein und Rauch ----------------------------------------------- */

.h-schornstein .h-stein {
  fill: color-mix(in srgb, var(--akzent) 30%, var(--akzent-tief));
}

.h-schornstein .h-schnee {
  fill: var(--schnee-weiss);
}

/* --- Maerchenzeug (RIC-54) -----------------------------------------------
   Mond, Sterne, Turm, Laeden mit Herz, Zuckerstange, Schneemann. Nichts
   davon braucht das Haus - es macht aus einem Haus eines, in dem der
   Weihnachtsmann Kaffee trinken wuerde. */
.h-mond {
  fill: color-mix(in srgb, var(--gold-hell) 70%, var(--karte));
  filter: drop-shadow(0 0 10px color-mix(in srgb, var(--gold-hell) 70%, transparent));
}

/* Der Schneemann wippt, als haette er Musik im Ohr. Gedreht wird um die
   untere Kugel - er steht fest im Schnee und schaukelt nur oben. */
.h-schneemann__wippen {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: h-wippen 5.5s ease-in-out infinite;
}

@keyframes h-wippen {
  0%, 100% { transform: rotate(-3deg); }
  50%      { transform: rotate(3deg); }
}

.h-stern {
  fill: color-mix(in srgb, var(--gold) 80%, var(--karte));
  animation: h-funkeln 4.2s ease-in-out infinite;
}

.h-stern--1 { animation-delay: 1.4s; }
.h-stern--2 { animation-delay: 2.8s; }

@keyframes h-funkeln {
  0%, 100% { opacity: 0.35; }
  50%      { opacity: 1; }
}

.h-turmwand {
  fill: color-mix(in srgb, var(--gold-spur) 90%, var(--akzent-tint));
}

.h-dach--turm {
  fill: color-mix(in srgb, var(--tanne) 82%, var(--akzent-tief));
}

/* Der Stern auf der Turmspitze leuchtet und pulsiert langsamer als die am
   Himmel - er ist der eine, dem man folgt. */
.h-turmstern {
  fill: var(--gold-hell);
  filter: drop-shadow(0 0 4px color-mix(in srgb, var(--gold-hell) 80%, transparent));
  animation: w-glimmen 5s ease-in-out infinite;
}

.h-rahmen--fein {
  stroke-width: 2.6;
}

.h-gesims {
  fill: none;
  stroke: color-mix(in srgb, var(--gold-spur) 45%, var(--akzent-tief));
  stroke-opacity: 0.35;
  stroke-width: 3;
  stroke-linecap: round;
}

.h-laeden path {
  fill: color-mix(in srgb, var(--tanne) 80%, var(--papier));
}

.h-herzen path {
  fill: color-mix(in srgb, var(--gold-hell) 85%, var(--karte));
}

.h-zuckerstange path {
  fill: none;
  stroke-width: 5;
  stroke-linecap: round;
}

.h-zucker-grund {
  stroke: var(--schnee-weiss);
  stroke-width: 5.5;
}

/* Gerade Enden fuer die Streifen (RIC-90): Mit runden ragte jeder rote
   Abschnitt um eine halbe Strichbreite ueber, bei 5 Breite und 4er-Luecken
   schloss sich damit jede Luecke - der Stock war ganz rot. */
.h-zuckerstange .h-zucker-streifen {
  stroke: var(--akzent);
  stroke-linecap: butt;
  stroke-dasharray: 3.5 3.5;
}

/* Die Fuellung steht als Attribut im Blade: Die Zeichnung gibt es zweimal
   auf der Seite, jede mit eigenem Verlauf (RIC-80). */
.h-schneekugel {
  stroke: color-mix(in srgb, var(--linie) 60%, transparent);
  stroke-width: 0.8;
}

.h-kugel-hell {
  stop-color: var(--schnee-weiss);
}

.h-kugel-schatten {
  stop-color: color-mix(in srgb, var(--schnee-weiss) 78%, var(--tanne));
}

.h-ast {
  fill: none;
  stroke: color-mix(in srgb, var(--akzent-tief) 45%, var(--text));
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.h-schal,
.h-muetze {
  fill: var(--akzent);
}

.h-schalstreifen {
  fill: none;
  stroke: var(--tanne);
  stroke-width: 2;
}

.h-fransen {
  fill: none;
  stroke: var(--akzent);
  stroke-width: 1.2;
  stroke-linecap: round;
}

.h-muetzenrand,
.h-bommel {
  fill: var(--schnee-weiss);
  stroke: color-mix(in srgb, var(--linie) 60%, transparent);
  stroke-width: 0.6;
}

.h-wange {
  fill: color-mix(in srgb, var(--akzent) 45%, var(--schnee-weiss));
  opacity: 0.7;
}

.h-knopf {
  fill: color-mix(in srgb, var(--akzent-tief) 60%, var(--text));
}

.h-nase {
  fill: color-mix(in srgb, var(--gold) 65%, var(--akzent));
}

/* Drei Woelkchen, weit auseinander getaktet - eine dichte Fahne waere das
   Einzige, worauf das Auge auf der ganzen Seite noch schaut. */
.rauch {
  fill: color-mix(in srgb, var(--papier) 60%, transparent);
  opacity: 0;
  animation: rauch-steigen 9s ease-out infinite;
}

.rauch--2 { animation-delay: 3s; }
.rauch--3 { animation-delay: 6s; }

@keyframes rauch-steigen {
  0%   { opacity: 0; transform: translate(0, 0) scale(0.4); }
  15%  { opacity: 0.7; }
  100% { opacity: 0; transform: translate(14px, -60px) scale(2); }
}

/* --- Die Fenster ---------------------------------------------------------
   Rundbogen und Rundfenster, warmes Licht dahinter. Der Bogen ist der halbe
   Unterschied zwischen einem Haus und einem Buerogebaeude. */

.h-stube-hell { stop-color: color-mix(in srgb, var(--gold-hell) 88%, var(--karte)); }
.h-stube-warm { stop-color: var(--gold-hell); }
.h-stube-tief { stop-color: color-mix(in srgb, var(--gold) 72%, var(--akzent)); }

.h-fenster {
  /* Das Licht faellt aus dem Fenster auf die Wand. */
  filter: drop-shadow(0 0 7px color-mix(in srgb, var(--gold-hell) 65%, transparent));
}

.h-rahmen {
  fill: none;
  stroke: color-mix(in srgb, var(--karte) 92%, var(--gold-spur));
  stroke-width: 4;
}

.h-sprosse {
  fill: none;
  stroke: color-mix(in srgb, var(--karte) 92%, var(--gold-spur));
  stroke-width: 2.6;
}

.h-sims {
  fill: color-mix(in srgb, var(--karte) 92%, var(--gold-spur));
}

/*
 * Der Elf steht vor dem hellen Licht der Stube, und die Farben der
 * Werkstattelfen sind fuer hellen Grund gemacht - unveraendert waere er
 * dort ein blasser Fleck. Also dieselbe Figur, nur satter, und mit
 * erhobener Hand: Er schaut nicht nur heraus, er winkt auch.
 */
.h-elf {
  --elf-muetze: color-mix(in srgb, var(--akzent) 88%, var(--akzent-tief));
  --elf-kittel: color-mix(in srgb, var(--tanne) 82%, var(--akzent-tief));
  --elf-bein: color-mix(in srgb, var(--akzent-leise) 92%, var(--akzent-tief));
  --elf-schuh: color-mix(in srgb, var(--akzent) 78%, var(--akzent-tief));
  --elf-hand: color-mix(in srgb, var(--akzent) 72%, var(--akzent-tief));
  --elf-arm-vorn: -86deg;
  --elf-winkt: elf-winken;
}

/* Der Elf in der Haustuer laesst die Arme unten und winkt nicht: Der im
   Giebelfenster tut das schon. Zwei winkende Figuren auf einem Bild sehen
   aus wie eine Animation, die nicht weiss, wohin sie will. */
.h-elf--tuer {
  --elf-arm-vorn: -12deg;
  --elf-winkt: none;
}

/* --- Lichterkette, Kranz, Laterne ---------------------------------------- */

.h-schnur {
  fill: none;
  stroke: color-mix(in srgb, var(--tanne) 78%, var(--papier));
  stroke-width: 4;
  stroke-linecap: round;
  /* Aus dem Strich werden Zweige. */
  stroke-dasharray: 5 3;
}

.h-licht {
  fill: var(--gold-hell);
  animation: w-glimmen 3.4s ease-in-out infinite;
}

/* Drei Farben im Wechsel. Eine einfarbige Kette waere eine Perlenschnur;
   bunt wird sie erst durch den Wechsel, und mehr als drei Farben hat die
   Seite nicht. */
.h-licht--1 {
  fill: color-mix(in srgb, var(--akzent) 72%, var(--gold-hell));
  animation-delay: 1.1s;
}

.h-licht--2 {
  fill: color-mix(in srgb, var(--tanne) 55%, var(--gold-hell));
  animation-delay: 2.2s;
}

.h-kranz .h-reif {
  fill: none;
  stroke: color-mix(in srgb, var(--tanne) 80%, var(--papier));
  stroke-width: 5;
  stroke-linecap: round;
  /* Aus dem Strich werden Zweige. */
  stroke-dasharray: 4 2.4;
}

.h-kranz .h-beere { fill: var(--gold-hell); }
.h-kranz .h-schleife { fill: var(--gold); }

.h-kranz .h-band {
  fill: none;
  stroke: color-mix(in srgb, var(--gold) 70%, var(--akzent-tief));
  stroke-width: 2;
  stroke-linecap: round;
}

/* Der Schein auf dem Schnee vor der Tuer. */
.h-schein {
  fill: color-mix(in srgb, var(--gold-hell) 40%, transparent);
  animation: tuer-schein 2.4s ease-out 0.9s backwards;
}

@keyframes tuer-schein {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* --- Die Tuer ------------------------------------------------------------
   Der Spalt ist halbdurchsichtig: Was man dort sieht, soll die Werkstatt
   sein und nicht die Farbe, mit der wir sie uebermalen. */

.h-spalt-oben  { stop-color: color-mix(in srgb, color-mix(in srgb, var(--akzent-tief) 70%, var(--gold)) 62%, transparent); }
.h-spalt-mitte { stop-color: color-mix(in srgb, var(--gold-hell) 68%, transparent); }
.h-spalt-unten { stop-color: color-mix(in srgb, var(--gold) 66%, transparent); }

/* Ohne Werkstatt dahinter ist die Tueroeffnung kein Loch, sondern Wand: Der
   Lichtspalt liegt dann darauf statt darueber und muss deckend sein - sonst
   scheint die Hauswand durch das Licht, und die Tuer wirkt aufgemalt. */
.haus--tuer-ohne-blick .h-spalt-oben  { stop-color: color-mix(in srgb, var(--akzent-tief) 78%, var(--gold)); }
.haus--tuer-ohne-blick .h-spalt-mitte { stop-color: var(--gold-hell); }
.haus--tuer-ohne-blick .h-spalt-unten { stop-color: var(--gold); }

.tuer__schwelle {
  fill: color-mix(in srgb, var(--akzent-tief) 72%, var(--gold));
}

/*
 * Das Blatt wird zur Angel am rechten Rand hin zusammengezogen. Was es
 * dabei freigibt, ist der Spalt.
 *
 * transform-box: fill-box rechnet den Ursprung gegen die eigene Flaeche -
 * ohne das liegt er im Nullpunkt der Zeichenflaeche, und das Blatt
 * verschwindet nach links aus dem Bild.
 */
.tuer__blatt {
  transform-box: fill-box;
  transform-origin: right center;
  transform: scaleX(calc(1 - var(--spalt)));
  animation: tuer-aufklappen 2.2s cubic-bezier(0.32, 0.8, 0.28, 1) 0.5s backwards;
}

@keyframes tuer-aufklappen {
  from { transform: scaleX(1); }
  to   { transform: scaleX(calc(1 - var(--spalt))); }
}

.tuer__flaeche {
  fill: color-mix(in srgb, var(--akzent) 76%, var(--akzent-tief));
}

/* Die Kassetten mit feiner Goldlinie. Sie sind der Unterschied zwischen
   einer roten Flaeche und einer Tuer, hinter der Weihnachten stattfindet. */
.tuer__fuellung {
  fill: color-mix(in srgb, var(--akzent) 62%, var(--akzent-tief));
  stroke: color-mix(in srgb, var(--gold) 55%, transparent);
  stroke-width: 1.4;
}

.tuer__knauf { fill: var(--gold-hell); }

/* Die Schmalseite des Blattes an der offenen Kante. Sie macht aus der
   Flaeche eine Tuer, die im Raum steht - aber nur, wenn sie nach Holz im
   Schatten aussieht und nicht nach einem schwarzen Balken. */
.tuer__kante {
  fill: color-mix(in srgb, var(--akzent-tief) 55%, var(--akzent));
}

.tuer__zarge {
  fill: none;
  stroke: color-mix(in srgb, var(--karte) 88%, var(--gold-spur));
  stroke-width: 7;
  stroke-linejoin: round;
}

/* --- Die Elfen ----------------------------------------------------------
   Rot, Gold und ein Gruen wie der Rest der Szene, der Kopf hell.

   Die Farben stehen als Variablen und nicht direkt an den Formen, und das
   hat einen zwingenden Grund: Ein <use> holt die Figur in einen
   Schattenbaum, und in den reicht kein Nachfahren-Selektor hinein -
   ".fenster__elf .elf-kittel" trifft schlicht nichts, die Regel sieht im
   Stylesheet aber voellig richtig aus. Vererbte Eigenschaften kommen
   dagegen an, und Variablen werden vererbt. Wer eine einzelne Figur
   umfaerben will, setzt also die Variablen an ihrem <svg> - siehe der Elf
   an der Tuer.

   Die Figur im Hintergrund ist klein: Alles, was hier steht, muss auch bei
   60 Pixel Hoehe noch als Flaeche funktionieren. Deshalb keine Umrisse,
   keine Verlaeufe, keine halben Deckkraefte. */

.haus,
.eingang-haus {
  --elf-muetze: color-mix(in srgb, var(--akzent) 72%, var(--papier));
  --elf-krempe: color-mix(in srgb, var(--papier) 92%, var(--gold));
  --elf-bommel: var(--gold);
  --elf-haut: color-mix(in srgb, var(--gold) 26%, var(--papier));
  --elf-kittel: color-mix(in srgb, var(--tanne) 48%, var(--papier));
  --elf-guertel: color-mix(in srgb, var(--akzent-leise) 90%, var(--papier));
  --elf-bein: color-mix(in srgb, var(--akzent-leise) 75%, var(--papier));
  --elf-schuh: color-mix(in srgb, var(--akzent) 60%, var(--papier));
  --elf-hand: color-mix(in srgb, var(--akzent) 55%, var(--papier));
  /* Die Zuege im Gesicht. Kein Schwarz: Zwei schwarze Punkte auf einer
     hellen Flaeche starren, ein warmes Dunkelbraun schaut. */
  --elf-zug: color-mix(in srgb, var(--akzent-tief) 78%, var(--gold));
  --elf-wange: color-mix(in srgb, var(--akzent) 42%, var(--papier));
  /* Wie weit der vordere Arm gehoben ist. Eine Variable, weil auch sie
     durch das <use> hindurch muss. */
  --elf-arm-vorn: 0deg;
}

.elf-muetze  { fill: var(--elf-muetze); }
.elf-krempe  { fill: var(--elf-krempe); }
.elf-bommel  { fill: var(--elf-bommel); }
.elf-kopf,
.elf-ohr     { fill: var(--elf-haut); }
.elf-kittel  { fill: var(--elf-kittel); }
.elf-guertel { fill: var(--elf-guertel); }
.elf-bein    { fill: var(--elf-bein); }
.elf-schuh   { fill: var(--elf-schuh); }
.elf-hand    { fill: var(--elf-hand); }

.elf-auge    { fill: var(--elf-zug); }
.elf-wange   { fill: var(--elf-wange); }

.elf-mund {
  fill: none;
  stroke: var(--elf-zug);
  stroke-width: 1.6;
  stroke-linecap: round;
}

.elf-arm path {
  fill: none;
  stroke: var(--elf-kittel);
  stroke-width: 7;
  stroke-linecap: round;
}

/*
 * Der vordere Arm dreht um die Schulter. transform-box: fill-box rechnet
 * die Prozente gegen die eigene Flaeche - ohne das liegt der Drehpunkt
 * irgendwo in der viewBox und der Arm fliegt davon.
 *
 * Das Winken kommt als Name einer Bewegung durch eine Variable herein, und
 * zwar aus demselben Grund, aus dem auch die Farben Variablen sind: Die
 * Klasse .elf-arm--vorn trifft jede Figur im Dokument gleichzeitig, weil
 * jedes <use> dieselbe Vorlage einsetzt. Ohne die Variable winken alle vier
 * Elfen im Gleichtakt - der an der Werkbank auch, mit dem Hammer in der
 * Hand. Wer nicht winkt, bekommt 'none' und steht still.
 */
.elf-arm--vorn {
  transform-box: fill-box;
  transform-origin: 22% 18%;
  transform: rotate(var(--elf-arm-vorn));
  /* Die Verzoegerung wartet ab, bis die Tuer offen ist - vorher sieht das
     Winken niemand, weil das Tuerblatt noch davor liegt. */
  animation: var(--elf-winkt, none) 2.2s ease-in-out 2.9s infinite;
}

/*
 * Der Arm schwingt um die Ruhelage herum, nicht von ihr weg: Faengt die
 * Bewegung an einem anderen Winkel an, springt der Arm in dem Moment, in
 * dem sie einsetzt.
 */
@keyframes elf-winken {
  0%, 100% { transform: rotate(-86deg); }
  28%      { transform: rotate(-102deg); }
  70%      { transform: rotate(-70deg); }
}

@keyframes w-glimmen {
  0%, 100% { opacity: 0.35; }
  50%      { opacity: 1; }
}

/* --- Lichter: Advent und Abschluss ---------------------------------------
   Warme Punkte, die langsam steigen und dabei pulsieren. Gedacht als
   Nachhall der Lichterkette auf dem Foto, nicht als eigener Effekt. */

.funke {
  position: absolute;
  bottom: -2.5rem;
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 999px;
  background: var(--gold);
  filter: blur(1px);
  opacity: 0;
  animation: funke-steigen linear infinite;
}

@keyframes funke-steigen {
  0% { opacity: 0; transform: translateY(0) scale(0.6); }
  12% { opacity: 0.75; }
  70% { opacity: 0.5; }
  100% { opacity: 0; transform: translateY(-104cqh) scale(1.15); }
}

.funke--1  { left:  4%; animation-duration: 15s; animation-delay:  0s;   }
.funke--2  { left: 12%; animation-duration: 19s; animation-delay: 2.4s;  }
.funke--3  { left: 19%; animation-duration: 13s; animation-delay: 5.1s;  }
.funke--4  { left: 27%; animation-duration: 21s; animation-delay: 1.2s;  }
.funke--5  { left: 34%; animation-duration: 16s; animation-delay: 7.3s;  }
.funke--6  { left: 41%; animation-duration: 18s; animation-delay: 3.6s;  }
.funke--7  { left: 48%; animation-duration: 14s; animation-delay: 9.2s;  }
.funke--8  { left: 56%; animation-duration: 20s; animation-delay: 0.8s;  }
.funke--9  { left: 63%; animation-duration: 17s; animation-delay: 6.5s;  }
.funke--10 { left: 71%; animation-duration: 15s; animation-delay: 4.1s;  }
.funke--11 { left: 78%; animation-duration: 22s; animation-delay: 8.4s;  }
.funke--12 { left: 85%; animation-duration: 16s; animation-delay: 2.9s;  }
.funke--13 { left: 92%; animation-duration: 19s; animation-delay: 10.6s; }
.funke--14 { left: 97%; animation-duration: 14s; animation-delay: 5.8s;  }

/* --- Schnee: Zuordnung ---------------------------------------------------
   Bewusst wenige, langsame, weiche Flocken. Ein dichtes Schneetreiben
   macht die Schrift darunter unruhig und den Rechner laut. */

.flocke__vorlage {
  position: absolute;
}

.flocke {
  position: absolute;
  top: -2.5rem;
  width: var(--groesse);
  opacity: 0;
  animation: flocke-fallen linear infinite;
}

/*
 * Der Fall steckt aussen im <span>, das Wiegen innen im <svg>. Beides in
 * einer Animation hiesse, dieselbe transform-Kette zweimal zu schreiben -
 * getrennt laufen sie in eigenem Takt, und genau davon lebt Schnee: Keine
 * zwei Flocken taumeln gleich.
 */
.flocke svg {
  display: block;
  width: 100%;
  height: auto;
  fill: none;
  /*
   * Weiss allein reicht nicht, seit der Schnee ueber der ganzen Seite
   * faellt: Auf dem hellen Blatt waeren weisse Flocken unsichtbar. Der
   * weiche Schatten gibt dem Kristall auf Papier eine Kante und faellt
   * ueber dem dunklen Hero nicht auf - eine Flocke, die auf beiden
   * Gruenden funktioniert.
   */
  stroke: var(--auf-akzent);
  stroke-width: 2;
  stroke-linecap: round;
  /*
   * Ein kraeftigerer Schatten als zuerst (RIC-54): Mit dem alten verschwand
   * die Flocke auf dem rosa Papier des Kopfbereichs fast ganz - der Kunde
   * hat sie nicht gesehen und nach Schnee gefragt, der schon fiel. Zwei
   * Schatten uebereinander sahen noch besser aus, liessen den Kopfbereich
   * am Telefon aber stocken (RIC-67).
   */
  filter: drop-shadow(0 0.5px 1.5px color-mix(in srgb, var(--schleier) 50%, transparent));
  animation: flocke-wiegen var(--wiegen) ease-in-out infinite;
}

@keyframes flocke-fallen {
  0% { opacity: 0; transform: translate(0, 0); }
  10% { opacity: 0.75; }
  90% { opacity: 0.5; }
  100% { opacity: 0; transform: translate(3.5rem, 106cqh); }
}

/* Das Taumeln: seitliches Pendeln mit einer leichten Drehung. Eine Flocke,
   die senkrecht und ungedreht faellt, ist ein fallender Punkt. */
@keyframes flocke-wiegen {
  0%, 100% { transform: translateX(-0.5rem) rotate(-30deg); }
  50%      { transform: translateX(0.5rem) rotate(28deg); }
}

/* Negative Verzoegerungen: Jede Flocke ist beim Laden schon unterwegs.
   Mit positiven fiel in den ersten Sekunden fast nichts, und genau dann
   schaut man hin. */
.flocke--1  { left:   2.4%; animation-duration: 23s; animation-delay:   -8.6s; --groesse:  0.85rem; --wiegen:  7.7s; }
.flocke--2  { left:   9.5%; animation-duration: 28s; animation-delay:   -2.5s; --groesse:  0.75rem; --wiegen:  7.9s; }
.flocke--3  { left:  16.2%; animation-duration: 20s; animation-delay:   -0.3s; --groesse:  1.15rem; --wiegen:  8.0s; }
.flocke--4  { left:  23.1%; animation-duration: 26s; animation-delay:  -23.3s; --groesse:  1.05rem; --wiegen:  6.1s; }
.flocke--5  { left:  32.3%; animation-duration: 28s; animation-delay:  -13.0s; --groesse:  0.85rem; --wiegen:  9.6s; }
.flocke--6  { left:  37.6%; animation-duration: 23s; animation-delay:  -21.1s; --groesse:   1.3rem; --wiegen:  5.8s; }
.flocke--7  { left:  48.2%; animation-duration: 20s; animation-delay:  -13.2s; --groesse:  0.95rem; --wiegen:  6.4s; }
.flocke--8  { left:  52.4%; animation-duration: 21s; animation-delay:  -16.1s; --groesse:  0.75rem; --wiegen:  5.9s; }
.flocke--9  { left:  61.3%; animation-duration: 25s; animation-delay:  -12.7s; --groesse:  0.75rem; --wiegen:  8.0s; }
.flocke--10 { left:  67.3%; animation-duration: 21s; animation-delay:   -2.8s; --groesse:  0.75rem; --wiegen:  8.2s; }
.flocke--11 { left:  74.7%; animation-duration: 27s; animation-delay:  -14.9s; --groesse:  1.15rem; --wiegen:  9.3s; }
.flocke--12 { left:  81.5%; animation-duration: 21s; animation-delay:  -19.2s; --groesse:  1.15rem; --wiegen:  7.1s; }
.flocke--13 { left:  88.2%; animation-duration: 28s; animation-delay:  -25.2s; --groesse:  0.85rem; --wiegen:  5.4s; }
.flocke--14 { left:  96.3%; animation-duration: 18s; animation-delay:   -8.2s; --groesse:  0.75rem; --wiegen:  7.1s; }

/* --- Herbstlaub ----------------------------------------------------------
   Blaetter statt Flocken, solange draussen noch Herbst ist. Welche von
   beiden faellt, entscheidet der Kalender - siehe App\Content\Jahreszeit.

   Gegenueber dem Schnee drei Unterschiede, und alle drei kommen daher, dass
   ein Blatt schwerer ist als eine Flocke: Es faellt langsamer, es driftet
   weiter zur Seite, und es ueberschlaegt sich dabei, statt nur zu pendeln.
   ------------------------------------------------------------------------- */

.blatt {
  position: absolute;
  top: -3rem;

  /*
     Die Groesse ist hier eine Schriftgroesse, kein width: Ein Emoji ist ein
     Zeichen. Der Stapel nennt die Emoji-Schriften der drei Systeme - ohne
     ihn faellt manches Linux auf eine schwarzweisse Fassung zurueck.
  */
  font-size: var(--groesse);
  line-height: 1;
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;

  opacity: 0;
  animation: blatt-fallen linear infinite;
}

/*
   Der Fall steckt aussen, das Ueberschlagen innen - wie bei der Flocke.
   Beides auf einem Element hiesse, zweimal dieselbe transform-Kette zu
   schreiben; die zweite gewaenne, und das Blatt fiele ohne zu taumeln.
*/
.blatt > span {
  display: block;

  /*
     Der Schatten gibt dem Blatt auf hellem Papier eine Kante. Ueber dem
     dunklen Hero faellt er nicht auf - ein Blatt, das auf beiden Gruenden
     funktioniert.
  */
  filter: drop-shadow(0 1px 2px color-mix(in srgb, var(--schleier) 35%, transparent));
  animation: blatt-taumeln var(--wiegen) linear infinite;
}

@keyframes blatt-fallen {
  0%   { opacity: 0;    transform: translate(0, 0); }
  8%   { opacity: 0.50; }
  88%  { opacity: 0.36; }
  100% { opacity: 0;    transform: translate(var(--drift), 106cqh); }
}

/*
   Das Ueberschlagen. Die Drehung um die Hochachse laeuft einmal ganz durch,
   damit die Schleife ohne Sprung schliesst - dabei steht das Blatt zweimal
   fast auf der Kante und wird kurz zu einem Strich. Genau das tut ein Blatt
   im Fallen auch.
*/
@keyframes blatt-taumeln {
  0%   { transform: rotateZ(-16deg) rotateY(0deg); }
  25%  { transform: rotateZ(10deg)  rotateY(90deg); }
  50%  { transform: rotateZ(16deg)  rotateY(180deg); }
  75%  { transform: rotateZ(-10deg) rotateY(270deg); }
  100% { transform: rotateZ(-16deg) rotateY(360deg); }
}

/*
   Neun Blaetter, und alle an den Raendern: nichts zwischen 30% und 72%.

   Dort steht der Text. Die Schicht liegt ueber dem Inhalt und kann das
   nicht aendern - am Handy waere hinter dem Textblatt sonst gar nichts
   mehr zu sehen (siehe den Hinweis beim Stapel weiter oben). Also weicht
   sie dem Text aus, statt sich so blass zu machen, dass die Jahreszeit
   verschwindet. Der Rand ist ohnehin die richtige Stelle: Die Stimmung ist
   Beiwerk, kein Inhalt.

   Der Drift ist dafuer klein. Weht ein Blatt zu weit, landet es doch
   wieder in der Lesespalte.
*/
.blatt--1 { left:   2%; animation-duration: 24s; animation-delay:   0.0s; --groesse:   1.0rem; --wiegen:  7.5s; --drift:    3rem; }
.blatt--2 { left:   8%; animation-duration: 31s; animation-delay:   4.1s; --groesse:  1.24rem; --wiegen: 11.2s; --drift:   -2rem; }
.blatt--3 { left:  15%; animation-duration: 21s; animation-delay:   8.6s; --groesse:   0.8rem; --wiegen:  6.3s; --drift:    4rem; }
.blatt--4 { left:  22%; animation-duration: 28s; animation-delay:   1.9s; --groesse:  1.04rem; --wiegen:  9.4s; --drift:   -3rem; }
.blatt--5 { left:  28%; animation-duration: 23s; animation-delay:  12.4s; --groesse:  0.88rem; --wiegen:  8.1s; --drift:   -5rem; }
.blatt--6 { left:  73%; animation-duration: 34s; animation-delay:   6.2s; --groesse:  1.28rem; --wiegen: 12.6s; --drift:    5rem; }
.blatt--7 { left:  80%; animation-duration: 26s; animation-delay:   2.7s; --groesse:  1.04rem; --wiegen:  7.9s; --drift:   -3rem; }
.blatt--8 { left:  88%; animation-duration: 20s; animation-delay:  15.1s; --groesse:  0.76rem; --wiegen:  5.8s; --drift:    4rem; }
.blatt--9 { left:  95%; animation-duration: 30s; animation-delay:   9.8s; --groesse:  1.16rem; --wiegen: 10.7s; --drift:    2rem; }

/* --- Bluetenflug -----------------------------------------------------------
   Der Fruehling. Zu sehen ist er nur in der Ruhephase zwischen zwei
   Aktionen - siehe config/hero.php.

   Gegenueber dem Laub noch einmal leichter: kleiner, langsamer, weiter
   treibend und ohne das Ueberschlagen. Eine Bluete faellt nicht, sie treibt.
   ------------------------------------------------------------------------- */

.bluete {
  position: absolute;
  top: -3rem;
  font-size: var(--groesse);
  line-height: 1;
  font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
  opacity: 0;
  animation: bluete-treiben linear infinite;
}

.bluete > span {
  display: block;
  filter: drop-shadow(0 1px 2px color-mix(in srgb, var(--schleier) 30%, transparent));
  animation: bluete-wenden var(--wiegen) ease-in-out infinite;
}

@keyframes bluete-treiben {
  0%   { opacity: 0;    transform: translate(0, 0); }
  10%  { opacity: 0.46; }
  85%  { opacity: 0.34; }
  100% { opacity: 0;    transform: translate(var(--drift), 106cqh); }
}

/*
   Kein Ueberschlag wie beim Blatt, sondern ein Wenden: Die Bluete kippt zur
   Seite und zurueck. Sie ist flach und leicht - sie dreht sich nicht um
   sich selbst, sie schaukelt.
*/
@keyframes bluete-wenden {
  0%, 100% { transform: rotateZ(-24deg) rotateY(-35deg); }
  50%      { transform: rotateZ(24deg)  rotateY(35deg); }
}

/*
   Elf Blueten gegen neun Blaetter: Die Kirschbluete ist kleiner und
   blasser als ein Ahornblatt, ein paar mehr vertraegt sie deshalb. Die
   Lesespalte bleibt frei wie beim Laub.
*/
.bluete--1  { left:   3%; animation-duration: 30s; animation-delay:   0.0s; --groesse:  0.84rem; --wiegen:  9.2s; --drift:    4rem; }
.bluete--2  { left:   9%; animation-duration: 38s; animation-delay:   5.3s; --groesse:  0.64rem; --wiegen: 12.4s; --drift:   -3rem; }
.bluete--3  { left:  15%; animation-duration: 26s; animation-delay:  10.1s; --groesse:  0.96rem; --wiegen:  7.6s; --drift:    5rem; }
.bluete--4  { left:  21%; animation-duration: 34s; animation-delay:   2.4s; --groesse:  0.72rem; --wiegen: 10.8s; --drift:   -4rem; }
.bluete--5  { left:  27%; animation-duration: 29s; animation-delay:  14.7s; --groesse:  0.88rem; --wiegen:  8.9s; --drift:   -6rem; }
.bluete--6  { left:  72%; animation-duration: 41s; animation-delay:   7.1s; --groesse:  0.68rem; --wiegen: 13.7s; --drift:    6rem; }
.bluete--7  { left:  78%; animation-duration: 27s; animation-delay:   3.6s; --groesse:   1.0rem; --wiegen:  8.2s; --drift:   -3rem; }
.bluete--8  { left:  84%; animation-duration: 36s; animation-delay:  17.9s; --groesse:  0.76rem; --wiegen: 11.5s; --drift:    4rem; }
.bluete--9  { left:  89%; animation-duration: 31s; animation-delay:  11.4s; --groesse:  0.92rem; --wiegen:  9.7s; --drift:   -2rem; }
.bluete--10 { left:  94%; animation-duration: 39s; animation-delay:   6.0s; --groesse:  0.64rem; --wiegen: 12.9s; --drift:    3rem; }
.bluete--11 { left:  98%; animation-duration: 28s; animation-delay:  13.2s; --groesse:  1.04rem; --wiegen:  7.9s; --drift:   -4rem; }

/*
   Am Handy gibt es keine Raender mehr. '.seite' ist dann nur noch durch
   1,25rem Polster vom Bildschirmrand getrennt - der freie Streifen, in den
   das Laub oben ausweicht, ist hier keine zwei Zeichen breit.

   Also bleiben weniger Teilchen, sie ruecken ganz nach aussen, und der
   Drift wird klein: Er misst in rem und wuerde auf einem schmalen Schirm
   quer ueber die halbe Breite tragen. Sechs Blaetter am Rand sind mehr
   Herbst als neun mitten im Absatz.
*/
@media (max-width: 48rem) {
  .blatt--3,
  .blatt--4,
  .blatt--7 {
    display: none;
  }

  .blatt--1 { left:  0%; --drift:  1rem; }
  .blatt--2 { left:  5%; --drift: -1rem; }
  .blatt--5 { left: 10%; --drift:  1rem; }
  .blatt--6 { left: 86%; --drift: -1rem; }
  .blatt--8 { left: 91%; --drift:  1rem; }
  .blatt--9 { left: 96%; --drift: -1rem; }

  .bluete--3,
  .bluete--4,
  .bluete--7,
  .bluete--10 {
    display: none;
  }

  .bluete--1  { left:  0%; --drift:  1rem; }
  .bluete--2  { left:  5%; --drift: -1rem; }
  .bluete--5  { left: 10%; --drift:  1rem; }
  .bluete--6  { left: 85%; --drift: -1rem; }
  .bluete--8  { left: 90%; --drift:  1rem; }
  .bluete--9  { left: 95%; --drift: -1rem; }
  .bluete--11 { left: 98%; --drift: -1rem; }
}

/* =========================================================================
   Nils-Digital-Signatur
   =========================================================================

   Ein schmaler Streifen unter dem Fuss. Der Fuss gehoert dem Verein - was
   darunter steht, ist die Signatur des Handwerkers. Der hellere Grund macht
   die Kante sichtbar, an der die Seite des Vereins aufhoert.
   ========================================================================= */

.nd-signatur {
  position: relative;
  background: var(--karte);
  border-top: 1px solid var(--linie);
  padding-block: 1.1rem;
  font-size: 0.85rem;
}

.nd-signatur__inhalt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.7rem 1.6rem;
  flex-wrap: wrap;
}

.nd-signatur__marke {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: var(--text-still);
  text-decoration: none;
}

.nd-signatur__marke:hover {
  color: var(--text);
}

.nd-signatur__marke strong {
  color: var(--akzent);
  font-weight: 600;
}

.nd-signatur__zeichen {
  width: 26px;
  height: auto;
  flex-shrink: 0;
}

.nd-signatur__mehr {
  color: var(--text-still);
  text-decoration: none;
  white-space: nowrap;
}

.nd-signatur__mehr:hover {
  color: var(--akzent);
}

/* Unter ~520 px stehen die beiden Teile untereinander statt an den Raendern
   auseinandergezogen - "space-between" bei zwei umgebrochenen Zeilen sieht
   aus, als waere etwas verrutscht. */
@media (max-width: 32.5rem) {
  .nd-signatur__inhalt {
    flex-direction: column;
    align-items: flex-start;
  }
}

.abschnitt-eng {
  margin-top: 1rem;
}

/* Das Weiss des Schnees steht einmal fuer die ganze Seite: Haus, Daecher
   und Schneemann sollen denselben Ton haben.

   Frueher wuchs hier ausserdem eine Schneedecke am unteren Bildschirmrand
   an. Auf Wunsch der Kundin (RIC-54) bleibt der Schnee nicht mehr liegen -
   er faellt dezent durchs Bild und ist dann weg. */
:where(body) {
  --schnee-weiss: color-mix(in srgb, var(--karte) 95%, var(--gold-spur));
}

/* =========================================================================
   Reduzierte Bewegung
   =========================================================================

   Wer das im Betriebssystem einstellt, hat oft einen handfesten Grund -
   Schwindel, Migraene, Reizempfindlichkeit. Deshalb wird hier nicht
   gebremst, sondern abgeschaltet: kein Heranfahren, keine Teilchen, kein
   Video. Der Kopfbereich sieht dann aus wie ein Standbild, und das ist die
   richtige Antwort.
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
  /* Eingang und Ausgang entfallen als Gang: keine Tuer, kein Zoom. Man
     sieht Stube und Nacht gleich, und die Saetze stehen einfach da. */
  .werkstatt-gang {
    height: 70svh !important;
  }

  .werkstatt-schluss__weg {
    height: 0 !important;
  }

  .werkstatt-gang__tor {
    display: none !important;
  }

  /* Wer keine Bewegung will, bekommt auch keinen vorbeifliegenden
     Schlitten - ein stehender mitten im Himmel saehe festgeklebt aus. */
  .draussen__schlitten {
    display: none;
  }

  .hero__bild,
  .hero__video,
  .hero__auge,
  .hero__titel,
  .hero__text,
  .hero__aktionen,
  .hero__weiter,
  .hero__weiter svg {
    animation: none !important;
  }

  .stimmung,
  .hero__video {
    display: none;
  }

  /*
     Der Kranz bleibt stehen, nur seine Flammen hoeren auf zu flackern. Er
     sagt etwas aus - den wievielten Advent wir haben -, und das darf nicht
     an der Bewegung haengen.
  */
  .kerze__flamme,
  .kerze__kern,
  .kerze__schein {
    animation: none !important;
  }

  /* Die Werkstatt bleibt stehen - sie ist der Seitenhintergrund und kein
     Effekt. Nur ihre Bewegung hoert auf. */
  .werkstatt *,
  .werkstatt-gang__text,
  .h-stern,
  .h-turmstern,
  .h-schneemann__wippen,
  .elf-arm--vorn,
  .rauch {
    animation: none !important;
  }

  /* Die Tuer steht dann von Anfang an einen Spalt offen, statt
     aufzuklappen. Der Elf steht dabei schon dort, wo er hingehoert -
     deshalb muss seine Verschiebung von Hand nachgezogen werden, sonst
     schiebt ihn die abgeschaltete Animation aus dem Spalt. */
  .tuer__blatt {
    animation: none !important;
  }

  /* Ohne Bewegung bliebe vom Rauch nur ein Fleck ueber dem Schornstein
     stehen - dann lieber gar keiner. */
  .rauch {
    display: none;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
  }
}

/* --------------------------------------------------------------------------
   Auftakt der Anmeldestrecken

   Die Startseite empfaengt mit einem grossen Kopfbereich; die Formulare
   fingen darunter einfach an, und dieselbe Aktion sah aus wie zwei
   verschiedene Seiten. Derselbe getoente Verlauf und dieselbe geschwungene
   Ueberschrift stellen den Zusammenhang her.

   Schmaler als der Hero und ohne Bewegung: Wer hier ankommt, hat sich schon
   entschieden und will das Formular sehen.
   -------------------------------------------------------------------------- */
.anmeldekopf {
  background:
    linear-gradient(to bottom,
      var(--akzent-tint) 0%,
      var(--papier) 100%);
  padding: 2.25rem 0 2.5rem;
  border-bottom: 1px solid var(--linie);
}

.anmeldekopf__zurueck {
  display: inline-block;
  margin-bottom: 1.25rem;
  font-size: 0.9rem;
  color: var(--text-leise);
  text-decoration: none;
}
.anmeldekopf__zurueck:hover {
  color: var(--akzent);
}

.anmeldekopf__auge {
  margin: 0 0 0.5rem;
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--akzent-dunkel);
}

/* Dieselbe Schrift wie die Ueberschrift der Startseite. Die Regel dort - nur
   eine geschwungene Zeile je Seite - bleibt damit gewahrt: Diese Seite hat
   genau diese eine. Alles Weitere, gerade im Formular, bleibt bei der
   Grundschrift; Script-Schriften sind bei langen Zeilen anstrengend. */
.anmeldekopf__titel {
  margin: 0;
  font-family: 'Dancing Script', 'Segoe Script', cursive;
  font-weight: 700;
  font-size: clamp(2.2rem, 1.4rem + 3vw, 3.4rem);
  line-height: 1.05;
  letter-spacing: 0;
  max-width: 18ch;
  color: var(--akzent);
}

/* Die Familien-Anmeldung in Gruen, passend zu ihrem Knopf (RIC-57). */
.anmeldekopf--familie {
  background:
    linear-gradient(to bottom,
      var(--empfaenger-tint) 0%,
      var(--papier) 100%);
}

.anmeldekopf--familie .anmeldekopf__auge {
  color: var(--empfaenger-dunkel);
}

.anmeldekopf--familie .anmeldekopf__titel {
  color: var(--empfaenger);
}

.anmeldekopf__text {
  margin-top: 0.75rem;
  max-width: 34rem;
  color: var(--text-leise);
  font-size: 1.075rem;
}
.anmeldekopf__text p {
  margin: 0 0 0.5rem;
}
.anmeldekopf__text p:last-child {
  margin-bottom: 0;
}

/* Der Weg zum jeweils anderen Formular. Steht mit Abstand unter der
   Einleitung und faellt durch den Rahmen auf, ohne wie ein Knopf zu wirken:
   Er ist ein Ausweg fuer die Falschabgebogenen, keine zweite Einladung. */
.anmeldekopf__wechsel {
  margin: 1.25rem 0 0;
  font-size: 0.95rem;
}
/* Der Knopf traegt die Farbe der Seite, zu der er fuehrt: vom Spender-
   formular gruen zu den Familien, von dort rot zurueck (RIC-64). */
.anmeldekopf__wechsel a {
  display: inline-block;
  padding: 0.45rem 0.9rem;
  border: 1px solid var(--akzent);
  border-radius: 999px;
  background: var(--akzent-tint);
  color: var(--akzent);
  text-decoration: none;
}
.anmeldekopf__wechsel a:hover,
.anmeldekopf__wechsel a:focus-visible {
  background: var(--akzent);
  color: var(--auf-akzent);
}
.anmeldekopf__wechsel--zu-familien a {
  border-color: var(--empfaenger);
  background: var(--empfaenger-tint);
  color: var(--empfaenger-dunkel);
}
.anmeldekopf__wechsel--zu-familien a:hover,
.anmeldekopf__wechsel--zu-familien a:focus-visible {
  background: var(--empfaenger);
  color: var(--auf-akzent);
}

/* Das Formular beginnt danach ohne den doppelten Abstand, den .inhalt sonst
   oben setzt - der Auftakt hat seinen eigenen schon. Mit ~ statt +: Zwischen
   Auftakt und Inhalt steht der Countdown, und mit + griff die Regel nie. */
.anmeldekopf ~ .inhalt > .seite > .formular:first-child,
.anmeldekopf ~ .inhalt > .seite > .hinweis:first-child {
  margin-top: 0;
}

/*
 * Die Formulare in der Werkstatt (RIC-77).
 *
 * Seit RIC-77 steht die Stube auch hinter den beiden Anmeldeformularen.
 * Auftakt und Formular liegen dann wie auf der Startseite als Blaetter
 * darauf, und zwar schmaler als dort: Ein Formular ist eine Spalte, und auf
 * dem breiten Blatt der Startseite stand rechts daneben nur leeres Papier.
 * So bleibt links und rechts mehr von der Stube zu sehen.
 */
body:has(.werkstatt) .anmeldekopf,
body:has(.werkstatt):has(.anmeldekopf) main {
  max-width: 42rem;
  margin-inline: auto;
  border-radius: 0.6rem;
  box-shadow: 0 0 2.5rem color-mix(in srgb, var(--schleier) 22%, transparent);
}

body:has(.werkstatt) .anmeldekopf {
  position: relative;
  margin-block: 1.75rem;
  border-bottom: 0;
}

body:has(.werkstatt):has(.anmeldekopf) main {
  margin-block: 1.75rem 2.5rem;
}

body:has(.werkstatt) .anmeldekopf > .seite,
body:has(.werkstatt):has(.anmeldekopf) main > .seite {
  padding-inline: 2.5rem;
}

/*
 * Der Countdown zwischen den beiden Blaettern (RIC-78).
 *
 * Als schwarzer Streifen quer ueber den ganzen Bildschirm schnitt er die
 * Stube am Desktop mitten durch. Hier wird er zu einem hellen Schild, so
 * breit wie sein Text, das zwischen Auftakt und Formular haengt. Gold waere
 * auf hellem Grund nicht lesbar - die Zahl traegt deshalb die Farbe der
 * Strecke: rot fuer die Wichtel, gruen fuer die Familien.
 */
:is(body:has(.werkstatt):has(.anmeldekopf), .kopf__leiste) .countdown {
  width: fit-content;
  max-width: calc(100% - 2rem);
  margin-inline: auto;
  padding: 0.55rem 1.4rem;
  border: 1px solid var(--linie);
  border-radius: 1.4rem;
  background: var(--karte);
  box-shadow: 0 0 1.5rem color-mix(in srgb, var(--schleier) 18%, transparent);
  --countdown-farbe: var(--akzent);
}

body:has(.werkstatt):has(.anmeldekopf--familie) .countdown {
  --countdown-farbe: var(--empfaenger);
}

:is(body:has(.werkstatt):has(.anmeldekopf), .kopf__leiste) .countdown__reihe {
  padding: 0;
}

:is(body:has(.werkstatt):has(.anmeldekopf), .kopf__leiste) .countdown__punkt {
  justify-content: center;
  color: var(--text-still);
}

:is(body:has(.werkstatt):has(.anmeldekopf), .kopf__leiste) .countdown__punkt--haupt {
  color: var(--text-leise);
}

:is(body:has(.werkstatt):has(.anmeldekopf), .kopf__leiste) .countdown__zeit,
:is(body:has(.werkstatt):has(.anmeldekopf), .kopf__leiste) .countdown__anlass a:hover {
  color: var(--countdown-farbe);
  font-weight: 600;
}

:is(body:has(.werkstatt):has(.anmeldekopf), .kopf__leiste) .countdown__datum {
  color: var(--text-still);
}

/* Das Schild ersetzt den Abstand zwischen den Blaettern, statt ihn zu
   verdoppeln. */
body:has(.werkstatt):has(.anmeldekopf) .anmeldekopf {
  margin-bottom: 1.1rem;
}

:is(body:has(.werkstatt):has(.anmeldekopf), .kopf__leiste) .countdown + main {
  margin-top: 1.1rem;
}

@media (max-width: 63.999rem) {
  body:has(.werkstatt) .anmeldekopf,
  body:has(.werkstatt):has(.anmeldekopf) main {
    margin-inline: 1rem;
  }

  body:has(.werkstatt) .anmeldekopf {
    margin-block: 1.25rem 1.75rem;
  }

  body:has(.werkstatt):has(.anmeldekopf) main {
    margin-block: 1.75rem 2.5rem;
  }

  body:has(.werkstatt) .anmeldekopf > .seite,
  body:has(.werkstatt):has(.anmeldekopf) main > .seite {
    padding-inline: 1.1rem;
  }
}

/* =========================================================================
   Die Anmeldestrecke als aufgeschlagenes Wichtelbuch (RIC-87)
   =========================================================================

   Formulare und Folgeseiten (Danke, Bestaetigt, Ruecknahme) liegen im
   selben Buch wie die Startseite - Einband, Papier, Falz, Lesebaendchen
   (siehe components/buch-offen.blade.php). Am Schreibtisch eine
   Doppelseite, am Handy eine Seite. Die Formulare verteilt ein Skript auf
   Buchseiten - die Regeln dazu stehen weiter unten unter "Das Formular
   blaettert"; ohne JavaScript waechst das Buch mit seinem Inhalt.

   Die Regeln fuer Auftakt und Formular als Blaetter in der Stube (RIC-77)
   gelten hier nicht mehr; die folgenden sind deshalb bewusst etwas
   spezifischer als jene.
   ------------------------------------------------------------------------- */

html body:has(.buch-offen) main.inhalt--buch {
  max-width: none;
  margin: 1.1rem auto 2.5rem;
  background: transparent;
  box-shadow: none;
  border-radius: 0;
}

html body:has(.buch-offen) main.inhalt--buch > .seite {
  max-width: 62rem;
  padding-inline: 1rem;
}

.buch-offen {
  max-width: 62rem;
}

.buch-offen__fenster {
  display: grid;
}

.buch-offen__seite {
  position: relative;
  padding: clamp(1.6rem, 3.5vw, 2.6rem) var(--buch-rand) 3.4rem;
}

/* Die Seitenzahl unten mittig, wie im Wichtelbuch. */
.buch-offen__zahl {
  position: absolute;
  bottom: 1.1rem;
  left: 0;
  right: 0;
  text-align: center;
  font-family: 'IBM Plex Mono', ui-monospace, SFMono-Regular, monospace;
  font-size: 0.75rem;
  color: var(--text-still);
}

.buch-offen__zahl::before { content: '– '; }
.buch-offen__zahl::after  { content: ' –'; }

/* Am Handy eine Seite: der Auftakt oben, eine goldene Zierlinie, darunter
   das Formular. Eine Schmuckseite faellt ganz weg. */
@media (max-width: 47.999rem) {
  .buch-offen__seite--links {
    padding-bottom: 0;
  }

  /* Nur eine Seite - eine einzelne "2" saehe verloren aus. */
  .buch-offen__zahl {
    display: none;
  }

  .buch-offen__seite--rechts {
    padding-bottom: 2.2rem;
  }

  .buch-offen__seite--links::after {
    content: '';
    display: block;
    width: 7rem;
    height: 0.6rem;
    margin: 1.8rem auto 0;
    background:
      radial-gradient(circle, var(--gold) 0 0.18rem, transparent 0.22rem) center / 0.6rem 0.6rem no-repeat,
      linear-gradient(var(--gold), var(--gold)) left center / 42% 1px no-repeat,
      linear-gradient(var(--gold), var(--gold)) right center / 42% 1px no-repeat;
  }

  .buch-offen--schmuck .buch-offen__seite--links {
    display: none;
  }
}

/* Am Schreibtisch die Doppelseite. Der Falz in der Mitte kommt vom Fenster
   des Wichtelbuchs. */
@media (min-width: 48rem) {
  .buch-offen__fenster {
    grid-template-columns: 1fr 1fr;
    min-height: 34rem;
  }
}

/*
 * Das Buch liegt fest (RIC-87): Es fuellt den Bildschirm unter Kopfzeile
 * und Countdown, und gescrollt wird in den Seiten, nicht die Seite mit dem
 * Buch. Die Hoehe misst das Skript in buch-offen.blade.php. Oben und unten
 * laufen die Seiten weich ins Papier aus - so sieht man, dass es weitergeht.
 *
 * Nur bei genug Hoehe: Auf einem quergehaltenen Handy waere ein festes
 * Buch zu niedrig zum Ausfuellen, dort waechst es wie bisher mit.
 */
@media (min-height: 34rem) {
  .buch-offen.ist-fest {
    height: var(--buch-offen-hoehe);
  }

  .buch-offen.ist-fest .buch-offen__fenster {
    height: 100%;
    min-height: 0;
  }

  /* Jede Seite scrollt fuer sich; Seitenzahl und Raender bleiben stehen. */
  .buch-offen.ist-fest .buch-offen__seite {
    display: flex;
    flex-direction: column;
    min-height: 0;
  }

  .buch-offen.ist-fest .buch-offen__inhalt {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--gold) 55%, transparent) transparent;
    /* Platz fuer Fokusrahmen und Schatten, die sonst am Rand abgeschnitten
       wuerden. */
    padding: 0.6rem;
    margin: -0.6rem;
    mask-image: linear-gradient(to bottom,
      transparent 0, black 1.2rem, black calc(100% - 1.8rem), transparent 100%);
  }
}

/* Am Handy ist es eine einzige Seite: Dort scrollt das ganze Fenster. */
@media (min-height: 34rem) and (max-width: 47.999rem) {
  /* Ein Block statt Raster: Im Raster mit fester Hoehe schoben sich die
     beiden Teile uebereinander. Ausgeblendet wird nur unten, oben bleibt
     der Buchrand sauber. */
  .buch-offen.ist-fest .buch-offen__fenster {
    display: block;
    overflow-y: auto;
    overscroll-behavior: contain;
    mask-image: linear-gradient(to bottom, black calc(100% - 1.8rem), transparent 100%);
  }

  .buch-offen.ist-fest .buch-offen__seite {
    display: block;
  }

  .buch-offen.ist-fest .buch-offen__inhalt {
    overflow: visible;
    mask-image: none;
  }
}

.buch-offen__inhalt > :first-child {
  margin-top: 0;
}

.buch-offen__inhalt > :last-child {
  margin-bottom: 0;
}

/* --- Der Auftakt als Kapitelanfang ---------------------------------------- */

.buch.buch-offen .anmeldekopf.anmeldekopf {
  position: static;
  max-width: none;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  text-align: center;
}

.buch.buch-offen .anmeldekopf > .seite.seite {
  max-width: none;
  padding: 0;
}

.buch-offen .anmeldekopf__titel {
  /* Eine Spur kleiner als frueher im Auftakt: Die Seite ist fest, und der
     Weg zum anderen Formular soll ohne Scrollen zu sehen sein. */
  font-size: clamp(2rem, 1.4rem + 1.8vw, 2.7rem);
  max-width: none;
  margin-inline: auto;
  text-wrap: balance;
}

/* Dieselbe goldene Zierlinie wie unter den Kapiteln im Wichtelbuch. */
.buch-offen .anmeldekopf__titel::after {
  content: '';
  display: block;
  width: 7rem;
  height: 0.6rem;
  margin: 0.9rem auto 0;
  background:
    radial-gradient(circle, var(--gold) 0 0.18rem, transparent 0.22rem) center / 0.6rem 0.6rem no-repeat,
    linear-gradient(var(--gold), var(--gold)) left center / 42% 1px no-repeat,
    linear-gradient(var(--gold), var(--gold)) right center / 42% 1px no-repeat;
}

.buch-offen .anmeldekopf__text {
  max-width: 30rem;
  margin: 1rem auto 0;
  font-size: 0.95rem;
}

.buch-offen .anmeldekopf__zurueck {
  margin-bottom: 1rem;
}

/* --- Das Formular auf dem Papier ------------------------------------------ */

.buch-offen .formular {
  max-width: none;
  margin-top: 0;
}

.buch-offen .formular input:not([type='checkbox']):not([type='radio']),
.buch-offen .formular textarea,
.buch-offen .formular select {
  background: color-mix(in srgb, var(--karte) 70%, var(--schnee-weiss));
}

.buch-offen .hinweis {
  margin-top: 0;
}

/* --- Folgeseiten: links Zier, rechts der Text mittig ---------------------- */

.buch-offen--schmuck .buch-offen__seite--rechts .buch-offen__inhalt {
  display: grid;
  align-content: center;
  justify-items: center;
  min-height: 100%;
  text-align: center;
}

.buch-offen--schmuck .buch-offen__seite--rechts .abschnitt {
  margin-block: 1.2rem 0;
}

.buch-offen--schmuck .knopfzeile {
  justify-content: center;
}

.buch-schmuck {
  display: grid;
  place-items: center;
  align-content: center;
  gap: 1.6rem;
  min-height: 26rem;
  height: 100%;
}

.buch-schmuck__stern {
  width: 4.5rem;
  height: 4.5rem;
  background: color-mix(in srgb, var(--gold) 70%, var(--buch-seite));
  clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}

.buch-schmuck__elf {
  /* Dieselben satten Farben wie die Wichtel in der Werkstatt - ohne sie
     stuende der Elf als schwarzer Schattenriss auf dem Papier. */
  --elf-muetze: var(--akzent);
  --elf-krempe: color-mix(in srgb, var(--tanne) 85%, var(--karte));
  --elf-bommel: color-mix(in srgb, var(--tanne) 85%, var(--karte));
  --elf-haut: color-mix(in srgb, var(--gold) 28%, var(--karte));
  --elf-kittel: color-mix(in srgb, var(--tanne) 88%, var(--text));
  --elf-guertel: color-mix(in srgb, var(--akzent-tief) 70%, var(--text));
  --elf-bein: color-mix(in srgb, var(--akzent) 80%, var(--akzent-tief));
  --elf-schuh: color-mix(in srgb, var(--akzent-tief) 70%, var(--text));
  --elf-hand: color-mix(in srgb, var(--akzent) 85%, var(--akzent-tief));
  --elf-zug: color-mix(in srgb, var(--akzent-tief) 80%, var(--text));
  --elf-wange: color-mix(in srgb, var(--akzent) 45%, var(--karte));
  width: 5.5rem;
  height: auto;
  overflow: visible;
}

@media (min-width: 48rem) {
  .buch-offen--schmuck .buch-offen__seite--links .buch-offen__inhalt {
    height: 100%;
  }
}

/* Die Feldgruppen liegen auf dem Papier, statt als weisse Kaesten darauf
   zu kleben - nur ein feiner Goldrand fasst sie ein. */
.buch-offen .feldgruppe {
  background: transparent;
  border-color: color-mix(in srgb, var(--gold) 45%, transparent);
}

.buch-offen .feldgruppe__titel {
  padding-inline: 0.35rem;
}

.buch-offen--familie .feldgruppe__titel {
  color: var(--empfaenger-dunkel);
}

.buch-offen .knopfzeile {
  margin-top: 1.4rem;
}

/* Der Weg zum anderen Formular steht im Buch direkt unter dem Titel und
   nicht unter dem langen Text: Die Seite ist fest, und wer falsch
   abgebogen ist, soll es ohne Scrollen sehen (RIC-43). */
.buch.buch-offen .anmeldekopf > .seite.seite {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.buch-offen .anmeldekopf__text {
  order: 2;
}

.buch-offen .anmeldekopf__wechsel {
  order: 1;
  margin-top: 1rem;
}

/* Die Marke am Textende des Wichtelbuchs, an der das Skript abliest, wie
   viele Seiten es sind (RIC-91). Ein Block ohne Hoehe: Er steht in der
   Spalte, in der der Text aufhoert. */
.buch__ende-marke {
  display: block;
  height: 0;
}

/*
 * Die Frist als magisches Band (RIC-94): Auf der Anmeldestrecke haengt der
 * Countdown als rotes Satinband mit goldenen Kanten oben am Wichtelbuch und
 * ueberlappt dessen Oberkante - Schwalbenschwanz-Enden, ein goldener
 * Schimmer laeuft darueber. Die Regeln fuer das helle Schild (RIC-78) sind
 * spezifischer gebaut; die gedoppelten Klassen hier stechen sie aus.
 */
html .countdown.countdown--band.countdown--band.countdown--band {
  position: relative;
  z-index: 2;
  width: fit-content;
  max-width: calc(100% - 3.5rem);
  margin: 0.2rem auto -0.9rem;
  padding: 0.45rem 1.8rem;
  border: 0;
  border-block: 2px solid var(--gold);
  border-radius: 0.2rem;
  background:
    linear-gradient(110deg,
      transparent 35%,
      color-mix(in srgb, var(--gold-hell) 45%, transparent) 50%,
      transparent 65%) 0 0 / 250% 100% no-repeat,
    linear-gradient(180deg,
      color-mix(in srgb, var(--akzent) 80%, var(--karte)) 0%,
      var(--akzent) 45%,
      var(--akzent-dunkel) 100%);
  box-shadow:
    0 0.35rem 0.8rem color-mix(in srgb, var(--text) 30%, transparent),
    0 0 1.2rem color-mix(in srgb, var(--gold) 35%, transparent);
  animation: band-schimmer 4.5s ease-in-out infinite;
}

/* Die Enden, hinter dem Band nach unten gefaltet. */
html .countdown.countdown--band.countdown--band.countdown--band::before,
html .countdown.countdown--band.countdown--band.countdown--band::after {
  content: '';
  position: absolute;
  z-index: -1;
  top: 0.45rem;
  width: 1.7rem;
  height: 100%;
  background: color-mix(in srgb, var(--akzent-dunkel) 85%, var(--text));
  border-block: 2px solid color-mix(in srgb, var(--gold) 80%, var(--text));
}

html .countdown.countdown--band.countdown--band.countdown--band::before {
  left: -1.3rem;
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%, 38% 50%);
}

html .countdown.countdown--band.countdown--band.countdown--band::after {
  right: -1.3rem;
  clip-path: polygon(0 0, 100% 0, 62% 50%, 100% 100%, 0 100%);
}

html .countdown--band.countdown--band.countdown--band .countdown__reihe {
  padding: 0;
}

html .countdown--band.countdown--band.countdown--band .countdown__punkt,
html .countdown--band.countdown--band.countdown--band .countdown__punkt--haupt,
html .countdown--band.countdown--band.countdown--band .countdown__anlass a {
  justify-content: center;
  color: var(--auf-akzent);
}

html .countdown--band.countdown--band.countdown--band .countdown__zeit {
  color: var(--gold-hell);
  font-weight: 700;
}

html .countdown--band.countdown--band.countdown--band .countdown__datum {
  color: color-mix(in srgb, var(--auf-akzent) 75%, transparent);
}

@keyframes band-schimmer {
  0%, 35%   { background-position: 120% 0, 0 0; }
  85%, 100% { background-position: -120% 0, 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  html .countdown.countdown--band.countdown--band.countdown--band {
    animation: none;
  }
}

/* Am Handy einzeilig ohne Datum, wie in der Kopfleiste der Startseite. Das
   Lesebaendchen haengt dort am unteren Buchrand in die Seite hinein und
   faellt weg. */
@media (max-width: 39.999rem) {
  html .countdown--band.countdown--band.countdown--band .countdown__datum {
    display: none;
  }

  html .countdown.countdown--band.countdown--band.countdown--band {
    padding: 0.35rem 1.2rem;
    font-size: 0.9rem;
  }
}

@media (max-width: 47.999rem) {
  .buch-offen .buch__lesezeichen {
    display: none;
  }
}

/*
 * Am Schreibtisch steht die Anmeldestrecke fest, sofern es passt (Nils):
 * Nur das Buch scrollt, die Seite nicht - das verwirrte. Die Fusszeile
 * rueckt dafuer kompakt unter das Buch; die Hoehe rechnet das Skript in
 * buch-offen.blade.php, und es setzt die Klasse nur, wenn das Buch dann noch
 * hoch genug zum Ausfuellen bleibt.
 */
html:has(body.ist-buch-fest) {
  overflow: hidden;
}

html body.ist-buch-fest main.inhalt--buch {
  margin-bottom: 0;
  padding-block: 1.2rem 0.9rem;
}

body.ist-buch-fest .fuss {
  padding-block: 0.55rem 0.6rem;
  font-size: 0.78rem;
  line-height: 1.45;
}

body.ist-buch-fest .nd-signatur {
  padding-block: 0.45rem;
  font-size: 0.75rem;
}

/* Das Lesebaendchen hinge dort in die Fusszeile. */
body.ist-buch-fest .buch-offen .buch__lesezeichen {
  display: none;
}

/* Auf der Startseite haengt das Band direkt an der Kopfzeile (RIC-94): Es
   schliesst oben buendig an, statt als Schild darunter zu schweben. */
.kopf__leiste.kopf__leiste--band {
  top: 100%;
}

.kopf__leiste--band .countdown.countdown--band.countdown--band.countdown--band {
  margin: 0 auto;
  border-top-width: 0;
  border-radius: 0 0 0.25rem 0.25rem;
}

/* Die Enden haengen von der Unterkante der Kopfzeile herab. */
.kopf__leiste--band .countdown.countdown--band.countdown--band.countdown--band::before,
.kopf__leiste--band .countdown.countdown--band.countdown--band.countdown--band::after {
  top: 0.35rem;
}

/* =========================================================================
   Nach dem Absenden: draussen in der Winternacht (RIC-95)
   =========================================================================
   Die Danke-Seite zeigt die Nacht vom Ende der Startseite - ohne Stube,
   man hat das Haus ja verlassen. Der Schlitten fliegt nach der Uhr (ohne
   die Klasse mit-ankunft, die nur die Startseite setzt), also gleich nach
   dem Laden und dann alle zwoelf Sekunden. Der Text steht auf einem
   Papierschild oben am Himmel, wie der Abschiedssatz dort.
   ------------------------------------------------------------------------- */
body.ist-nacht .werkstatt__stube {
  display: none;
}

html body.ist-nacht main.inhalt--nacht {
  background: transparent;
  box-shadow: none;
  max-width: none;
  /* Unten Platz fuer Himmel, Schlitten und Schnee. */
  padding-block: 1.1rem 42svh;
}

html body.ist-nacht main.inhalt--nacht > .seite {
  max-width: 40rem;
}

.nacht-karte {
  position: relative;
  z-index: 1;
  margin-top: 0.4rem;
  padding: 1.6rem clamp(1.1rem, 4vw, 2.2rem) 1.4rem;
  text-align: center;
  background: color-mix(in srgb, var(--karte) 93%, transparent);
  border-radius: 1rem;
  box-shadow: 0 0.6rem 2rem color-mix(in srgb, var(--text) 25%, transparent);
}

.nacht-karte .anmeldekopf.anmeldekopf {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
  max-width: none;
}

.nacht-karte .anmeldekopf > .seite.seite {
  max-width: none;
  padding: 0;
}

.nacht-karte .anmeldekopf__titel {
  max-width: none;
  margin-inline: auto;
  text-wrap: balance;
}

.nacht-karte .anmeldekopf__titel::after {
  content: '';
  display: block;
  width: 7rem;
  height: 0.6rem;
  margin: 0.8rem auto 0;
  background:
    radial-gradient(circle, var(--gold) 0 0.18rem, transparent 0.22rem) center / 0.6rem 0.6rem no-repeat,
    linear-gradient(var(--gold), var(--gold)) left center / 42% 1px no-repeat,
    linear-gradient(var(--gold), var(--gold)) right center / 42% 1px no-repeat;
}

.nacht-karte .anmeldekopf__text {
  margin: 0.9rem auto 0;
}

.nacht-karte .abschnitt {
  margin-block: 1.1rem 0;
}

/* Das Band haengt ueber dem Schild und ueberlappt es ein Stueck. */
.inhalt--nacht .countdown--band + .nacht-karte {
  padding-top: 2rem;
}

/* Das Band bleibt einzeilig - umgebrochen sieht es aus wie zwei Baender. */
html .countdown--band.countdown--band.countdown--band .countdown__punkt {
  flex-wrap: nowrap;
  white-space: nowrap;
}

/* Am Schreibtisch ein schmaleres Schild: Links und rechts bleibt Himmel fuer
   den Schlitten. */
@media (min-width: 64rem) {
  html body.ist-nacht main.inhalt--nacht > .seite {
    max-width: 34rem;
  }
}

/* -------------------------------------------------------------------------
   Das Formular blaettert

   Im Buch stehen die Abschnitte des Formulars auf eigenen Seiten, damit
   niemand in einer Buchseite scrollen muss. Das Skript dazu liegt in
   anmeldung/teile/blaettern.blade.php; ohne es stehen die Abschnitte
   untereinander wie zuvor.
   ------------------------------------------------------------------------- */

.formular__blatt {
  display: grid;
  gap: 1.25rem;
}

.formular__blatt[hidden],
.blaettern [hidden],
.blaettern[hidden],
.buch-offen__seite[hidden] {
  display: none !important;
}

/* Die neue Seite kommt kurz von rechts herein - ein Blatt, kein Sprung. */
.ist-geblaettert .formular__blatt {
  animation: blatt-herein 0.35s ease-out;
}

@keyframes blatt-herein {
  from { opacity: 0; translate: 0.8rem 0; }
  to   { opacity: 1; translate: 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ist-geblaettert .formular__blatt {
    animation: none;
  }
}

/* Zurueck links, Weiter oder Absenden rechts, die Seitenpunkte dazwischen. */
.ist-geblaettert .blaettern {
  justify-content: space-between;
  flex-wrap: nowrap;
}

.blaettern__punkte {
  display: flex;
  gap: 0.4rem;
  margin-inline: auto;
}

.blaettern__punkt {
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: color-mix(in srgb, var(--gold) 30%, transparent);
  transition: background 0.3s, scale 0.3s;
}

.blaettern__punkt.ist-an {
  background: var(--gold);
  scale: 1.35;
}

/* Der Weiter-Knopf unter dem Auftakt, nur am Handy. Die Zierlinie darunter
   trennte Auftakt und Formular - auf getrennten Seiten braucht es sie nicht. */
.blaettern--auftakt {
  justify-content: center;
  margin-top: 1.4rem;
}

/* Ist der Auftakt laenger als die Seite, bleibt der Knopf trotzdem im Bild:
   Er haftet unten, der Text laeuft dahinter ins Papier aus. */
.ist-geblaettert.ist-fest .blaettern--auftakt {
  position: sticky;
  bottom: 0;
  margin-top: 0;
  padding-block: 1.6rem 0.4rem;
  background: linear-gradient(to bottom, transparent, var(--buch-seite) 1.4rem);
}

@media (max-width: 47.999rem) {
  .ist-geblaettert .buch-offen__seite--links {
    padding-bottom: 2.2rem;
  }

  .ist-geblaettert .buch-offen__seite--links::after {
    display: none;
  }
}

.ist-geblaettert .blaettern.blaettern--auftakt {
  justify-content: center;
}

/*
 * Ist ein einzelnes Feld hoeher als die Seite, scrollt sie doch - die
 * Knopfzeile bleibt dann unten stehen, statt mit hinauszurutschen. Das
 * weiche Auslaufen ins Papier entfaellt dafuer: Es sagte "hier geht es
 * weiter", und das sagen jetzt die Knoepfe. Halb verblasste Knoepfe saehen
 * nur kaputt aus.
 */
.ist-geblaettert.ist-fest .formular .blaettern {
  position: sticky;
  bottom: 0;
  margin-top: 0;
  padding-block: 0.7rem 0.2rem;
  background: linear-gradient(to bottom, transparent, var(--buch-seite) 0.7rem);
}

@media (min-height: 34rem) and (min-width: 48rem) {
  .buch-offen.ist-geblaettert.ist-fest .buch-offen__seite--rechts .buch-offen__inhalt {
    mask-image: none;
  }
}

/*
 * Mittig auf der Buchseite (Nils): Die Seiten sind seit dem Blaettern kurz,
 * und oben klebende Felder ueber einer leeren unteren Haelfte saehen aus wie
 * ein halb beschriebenes Blatt. Die Felder stehen deshalb mittig im Platz
 * ueber der Knopfzeile - die Knoepfe selbst bleiben unten, damit sie beim
 * Umblaettern nicht springen. Der Auftakt links steht genauso mittig.
 *
 * `ist-messend` setzt das Skript kurz, waehrend es den Platz ausmisst.
 */
.ist-geblaettert.ist-fest:not(.ist-messend) .buch-offen__inhalt {
  display: flex;
  flex-direction: column;
}

.ist-geblaettert.ist-fest:not(.ist-messend) .formular {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
}

.ist-geblaettert.ist-fest:not(.ist-messend) .formular__blatt,
.buch.buch-offen.ist-geblaettert.ist-fest:not(.ist-messend) .anmeldekopf.anmeldekopf {
  margin-block: auto;
}

/* Am Handy scrollt das Fenster, nicht die Seite - dort reicht die Kette
   eine Stufe weiter hinauf. */
@media (min-height: 34rem) and (max-width: 47.999rem) {
  .buch-offen.ist-geblaettert.ist-fest:not(.ist-messend) .buch-offen__fenster {
    display: flex;
    flex-direction: column;
  }

  .buch-offen.ist-geblaettert.ist-fest:not(.ist-messend) .buch-offen__seite {
    flex: 1 0 auto;
    display: flex;
    flex-direction: column;
  }

  .buch-offen.ist-geblaettert.ist-fest:not(.ist-messend) .buch-offen__inhalt {
    flex: 1 0 auto;
  }
}

/* Und die Schrift mittig, wie ueberall im Wichtelbuch. Die Haken bleiben
   linksbuendig: Ein Kaestchen mit mittig umbrochenem Text daneben liest
   sich schlecht. */
.buch-offen .formular .feld > label,
.buch-offen .formular .feld__hinweis,
.buch-offen .formular .fehlertext {
  text-align: center;
}

.buch-offen .formular .feldgruppe__titel {
  margin-inline: auto;
}

.buch-offen .formular .feld--zahl input {
  justify-self: center;
}

.buch-offen .hinweis {
  text-align: center;
}

/*
 * Am Handy darf die Seite hinter dem Buch scrollen. Solange das Buch selbst
 * scrollte, hielt es den Wisch bei sich fest (overscroll-behavior: contain) -
 * seit die Felder auf eine Seite passen, scrollte damit gar nichts mehr, und
 * unter der aufgeklappten Tastatur kam niemand ans naechste Feld (Nils).
 */
@media (max-width: 47.999rem) {
  .buch-offen.ist-geblaettert.ist-fest .buch-offen__fenster {
    overscroll-behavior: auto;
  }
}
