/* =========================================================
   Mond-Landingpage — Sternenhimmel als Scroll-Menü
   Art-Direction: ruhige Asymmetrie, alternierender Rhythmus,
   Sterne entfalten sich beim Näherkommen
   ========================================================= */

/* --------- Custom Fonts --------- */

@font-face {
  font-family: "CCSBjork";
  src: url("fonts/CCSBjork-Light.woff") format("woff");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "CCSBjork";
  src: url("fonts/CCSBjork.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "CCSBjork";
  src: url("fonts/CCSBjork-Bold.woff") format("woff");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Hermissoul";
  src: url("fonts/Hermissoul-Regular.woff") format("woff");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Off-Black statt pures #000 — pures Schwarz wirkt klinisch-flach
     und ist eines der häufigsten AI-Slop-Tells. Off-Black hat einen
     ganz leichten warmen Stich, der mit den Bernstein-Akzenten
     harmoniert ohne sie zu kippen. */
  --bg: #0a0a0a;
  /* Etwas wärmere Grundtöne — Pergament statt Mondsilber */
  --fg: #f5f1e8;
  --fg-muted: rgba(232, 215, 178, 0.7);
  --amber: rgba(212, 165, 116, 0.92);
  --amber-soft: rgba(224, 186, 140, 0.78);
  --moon-glow: rgba(212, 165, 116, 0.14);

  /* Display-Fonts nur für Überschriften / Begriffe — distinktive
     Custom-Faces, keine generischen Standards (Inter / Times BANNED). */
  --font-display: "CCSBjork", "Cormorant Garamond", serif;
  --font-hero:    "CCSBjork", "Cormorant Garamond", serif;
  /* Der Untertitel traegt Hermissoul -- genauso wie .hero-claim auf
     der Musikseite. Eigene Variable, damit die Namen sagen, wofuer
     die Schrift da ist, statt welche es zufaellig war. */
  --font-claim:   "Hermissoul", "CCSBjork", "Cormorant Garamond", serif;
  /* Lese-Font für Fließtexte: EB Garamond — klassisch, akademisch.
     Fallback bewusst NICHT Georgia (zu generisch) sondern Cormorant
     Garamond (distinktiver Web-Fallback). */
  --font-body:    "EB Garamond", "Cormorant Garamond", serif;
  /* UI bleibt für Mikro-Editorial-Labels bei CCSBjork */
  --font-ui:      "CCSBjork", system-ui, -apple-system, sans-serif;

  --moon-size: clamp(220px, 34vmin, 460px);

  /* Custom Easing Curves (Emil Kowalski) — die Built-in CSS-Easings sind
     zu schwach; diese Curves geben UI-Animationen Definition.
     --ease-out: stark abklingend, perfekt für Hover/Press-Feedback und
                 Element-Eintritte (startet schnell → fühlt sich responsiv an).
     --ease-in-out: für Bewegung auf dem Bildschirm (Modal-Panel etc.). */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);

  /* Bernstein-Fokus-Ring für Tastatur-Navigation. Wird via :focus-visible
     auf allen interaktiven Elementen genutzt — passt zum Look der Seite,
     statt der hässlichen blauen Standard-Outline. */
  --focus-ring: 0 0 0 2px rgba(212, 165, 116, 0.7),
                0 0 14px rgba(212, 165, 116, 0.35);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--fg);
  /* Default: lesbarer Body-Font. Display-Fonts werden lokal pro Headline gesetzt. */
  font-family: var(--font-body);
  font-weight: 400;
  letter-spacing: 0.005em;
  -webkit-font-smoothing: antialiased;
}

html { scroll-behavior: smooth; }

body {
  /* Off-Black aus :root — pures #000 bewusst vermieden, dunkler Rand
     des Mondes verschmilzt visuell trotzdem mit dem Hintergrund.
     min-height: 100dvh statt 100vh, damit auf iOS Safari beim
     Scrollen kein Seitensprung entsteht (vh = statisch, dvh = dynamic). */
  background: var(--bg);
  min-height: 100dvh;
  overflow-x: hidden;
}

/* --------- Reaktive Vernetzung (Sternbild zum aktiven Begriff) --------- */

.connection {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  /* Hinter den Sternen (12) und Mond (10), über dem Hintergrundsternenfeld */
  z-index: 5;
  overflow: visible;
  opacity: 1;
}

/* Linien (zwei Schichten pro Verbindung): weicher Halo (soft) und
   scharfer Kern (core). Beide zeichnen sich gestaffelt; nach dem
   Reveal pulsieren sie leise wie ein lebendiges Sternbild. */
.conn-line {
  --length: 1000;
  --delay: 0ms;
  fill: none;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: var(--length);
  stroke-dashoffset: var(--length);
  /* Längere Reveal-Dauer (2.2 s) → ruhiger und prozesshafter.
     stroke-Farbe bekommt eine eigene weiche Transition, damit
     Active-Wechsel ohne Flackern funktionieren. */
  transition:
    stroke-dashoffset 2.2s cubic-bezier(0.22, 0.61, 0.36, 1) var(--delay),
    stroke 1.1s ease var(--delay),
    stroke-width 1.1s ease,
    opacity 0.8s ease var(--delay);
  opacity: 0;
}
.connection.is-drawn .conn-line {
  stroke-dashoffset: 0;
  opacity: 1;
  /* Nach dem Reveal: sanftes Glanz-Atmen, jede Linie in eigener Phase */
  animation: conn-shimmer 5.5s ease-in-out infinite;
  animation-delay: calc(var(--delay) + 1.6s);
}

/* Sanftes Pulsieren — die Linien wirken nicht statisch, sondern leben.
   Glanz-Variation über opacity, leicht versetzt durch --delay. */
@keyframes conn-shimmer {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(1.4); }
}

/* Halo-Layer (soft) — breiter, weicher Schein für den Glanz */
.conn-line.is-soft {
  stroke-width: 2.2;
}

/* Kern-Layer (core) — schmal, hell, klare Linie */
.conn-line.is-core {
  stroke-width: 0.7;
}

/* Primäre Kanten (berühren den aktiven Stern) — leuchten klar */
.conn-line.is-primary {
  /* Strichstärke + Animation bleiben wie oben — die Helligkeit kommt aus dem Stroke-Wert */
}

/* Sekundäre Kanten (Hintergrund-Geflecht zwischen nicht-aktiven Sternen) —
   feiner, ruhiger, fast wie Spinnenseide. Bilden das neuronale Netz. */
.conn-line.is-secondary.is-soft {
  stroke-width: 1.4;
}
.conn-line.is-secondary.is-core {
  stroke-width: 0.4;
}
.connection.is-drawn .conn-line.is-secondary {
  /* Sanfteres, langsameres Atmen — Hintergrund-Geflecht */
  animation: conn-shimmer-soft 8.5s ease-in-out infinite;
  animation-delay: calc(var(--delay) + 1.6s);
}

@keyframes conn-shimmer-soft {
  0%, 100% { filter: brightness(0.85); }
  50%      { filter: brightness(1.15); }
}

@media (prefers-reduced-motion: reduce) {
  .conn-line { transition: none; animation: none; }
}

/* --------- Hintergrundsterne (Canvas, hinter allem) --------- */

.sky-stars {
  position: fixed;
  inset: 0;
  pointer-events: none;
  /* Sehr früh im Stack: hinter Mond, Sternen und Hero, vor dem Body-Schwarz */
  z-index: 1;
  width: 100%;
  height: 100%;
  /* Sehr leichtes opacity-mute, damit die Vignette sie zum Rand abdämpft */
  opacity: 0.92;
}

/* --------- Overlays: Körnung + Vignette --------- */

.grain {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 50;
  opacity: 0.08;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 0.6 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
  animation: grain-shift 1.2s steps(4) infinite;
}
@keyframes grain-shift {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(-3%, 2%); }
  50%  { transform: translate(2%, -3%); }
  75%  { transform: translate(-2%, -2%); }
  100% { transform: translate(0, 0); }
}

.vignette {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 40;
  background: radial-gradient(
    ellipse at 50% 50%,
    rgba(0, 0, 0, 0) 45%,
    rgba(0, 0, 0, 0.55) 90%,
    rgba(0, 0, 0, 0.85) 100%
  );
}

/* --------- Hero-Name — immer sichtbar, Buntglas-Farben --------- */

.hero-name {
  /* --moon-bright (0..1) wird per JS aus dem Mondvideo gesampelt.
     Mapped auf einen Effekt-Faktor 0.18..1 — bei Neumond glimmt der
     Name nur, bei Vollmond floresziert er bernsteinfarben. */
  --moon-bright: 0.55;
  --bright: calc(0.18 + 0.82 * var(--moon-bright));

  position: fixed;
  left: 0;
  right: 0;
  /* Hero so hoch wie sinnvoll — die obere Sternbild-Linie verläuft bei
     ~22-26 vh und soll deutlich UNTER dem Slogan liegen.
     clamp mit Pixel-Min, vh-Mid, Pixel-Max: minimal 12 px Polster zur
     Oberkante, skaliert mit Höhe, max 32 px auf großen Desktops.
     Mobile-Override unten setzt eigene Werte. */
  top: clamp(12px, 2.5vh, 32px);
  z-index: 35;
  margin: 0;
  padding: 0.35em 24px 0.45em;
  /* Page-Load-Choreografie: Hero erscheint nach 1.2 s, sanft eingeblendet */
  opacity: 0;
  animation: hero-name-emerge 1.6s var(--ease-out) 1.2s forwards;
  /* Stack: Hero-Link oben, Slogan direkt darunter — gleiche Box,
     fest verbunden, egal wie groß die Hero-Schrift wird. */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.05em;
  pointer-events: none;
  font-family: var(--font-hero);
  font-weight: 400;
  /* Größe skaliert mit vmin (engere Achse), Maximum bewusst niedrig
     gehalten (78 px), damit der Hero auf großen Desktop-Viewports
     nicht so weit nach unten ragt, dass der Slogan in den Bereich
     der oberen Sternbild-Linien (~22-26 vh) gerät. */
  /* Untergrenze wieder bei 26px. Sie war kurzzeitig auf 23 gesenkt,
     solange der Name in Hermissoul stand: die setzt 13,34 Pixel Breite
     je Pixel Schriftgröße und brauchte damit 347px, mehr als ein 320px
     breites Gerät hergibt. In CCSBjork sind es 9,32 — bei 26px also
     242px, was überall Platz hat. Umbrechen darf er wegen nowrap nach
     wie vor nicht. */
  font-size: clamp(26px, 6.8vmin, 78px);
  letter-spacing: 0.02em;
  line-height: 1.2;
  overflow: visible;
  /* „Mika Maria Mausshammer" muss IMMER in einer Zeile bleiben — sonst frisst
     der Wrap das ganze Hero-Layout und kollidiert mit den oberen
     Stern-Labels (besonders auf iPhone SE / kleinen Android-Geräten). */
  white-space: nowrap;
}

/* Hero-Link: klickbar, derselbe Look wie der h1, kein Underline.
   Trägt zugleich den Halo-Filter (zwei drop-shadow-Schichten mit
   moderatem Blur) — die Schrift bleibt scharf, nur der Halo atmet
   mit der Mondphase mit. */
.hero-link {
  display: inline-block;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  pointer-events: auto;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  filter:
    drop-shadow(0 0 calc(4px + 16px * var(--bright))
                rgba(245, 200, 130, calc(0.10 + 0.55 * var(--bright))))
    drop-shadow(0 0 calc(14px + 50px * var(--bright))
                rgba(210, 155, 80, calc(0.04 + 0.30 * var(--bright))));
  transition:
    filter 0.6s ease,
    transform 220ms var(--ease-out);
}
/* Hover-Effekte nur auf Geräten mit echtem Pointer (nicht Touch) — sonst
   triggert hover beim Tap und bleibt bis zum nächsten Tap stehen. */
@media (hover: hover) and (pointer: fine) {
  .hero-link:hover .hero-name span,
  .hero-link:focus-visible .hero-name span {
    filter: brightness(1.04);
  }
  .hero-link:hover,
  .hero-link:focus-visible {
    transform: scale(1.015);
  }
}
/* Press-Feedback: subtle Scale-Down beim Drücken — bestätigt, dass
   die UI den Klick „gehört" hat. */
.hero-link:active {
  transform: scale(0.985);
  transition: transform 140ms var(--ease-out);
}
/* Tastatur-Fokus: Bernstein-Ring um den Hero-Namen */
.hero-link:focus-visible {
  outline: none;
  border-radius: 4px;
  box-shadow: var(--focus-ring);
}

/* Pergament: eine einzige neutrale, warmweiße Farbe — wie eine
   lateinische Inschrift, wie altes Papier in einer Bibliothek.
   Kein Gradient, keine Goldstiche, keine Bewegung der Farbe selbst. */
.hero-name span {
  display: inline-block;
  /* Helligkeit wandert deutlich mit der Mondphase — von dunkler Bronze
     bei Neumond (28% lightness) zu strahlendem Bernstein bei Vollmond
     (90% lightness). Hue minimal verschoben. Schrift bleibt SCHARF —
     keine Blur-Layer auf der Schrift selber. */
  color: hsl(
    calc(32 + 8 * var(--bright)),
    calc(25% + 60% * var(--bright)),
    calc(28% + 62% * var(--bright))
  );

  /* Nur zwei scharfe Schatten ohne Blur — definieren Kontur ohne zu
     verwischen. Versatz und Härte variieren mit der Mondphase. */
  --dark: calc(1 - var(--bright));
  text-shadow:
    /* Heller Reflex oben (scharf, kein Blur) */
    0 calc(-1px - 1px * var(--bright)) 0
      rgba(255, 235, 195, calc(0.0 + 0.45 * var(--bright))),
    /* Harter Schlagschatten unten/rechts (scharf) */
    calc(1px + 2px * var(--dark))
    calc(1px + 3px * var(--dark)) 0
      rgba(20, 12, 4, calc(0.5 + 0.4 * var(--dark)));

  transition:
    color 0.6s ease,
    text-shadow 0.6s ease,
    filter 0.5s ease;
  /* Wichtig: alle Reste eines früheren Gradient-Fills neutralisieren */
  background: none !important;
  -webkit-background-clip: initial;
          background-clip: initial;
  -webkit-text-fill-color: currentColor;
  /* Sichtbares, aber sehr ruhiges Atmen — Helligkeit pulsiert weich */
  animation: hero-breathe 8s ease-in-out infinite;
}

@keyframes hero-breathe {
  0%, 100% { opacity: 0.78; }
  50%      { opacity: 1.00; }
}

/* Hero-Initial-Emerge: aus dem Schwarzen, leicht von unten, mit
   sanftem Blur-Klar-Übergang. Setzt nach 1.2 s ein, dauert 1.6 s. */
@keyframes hero-name-emerge {
  0% {
    opacity: 0;
    transform: translateY(8px);
    filter: blur(3px);
  }
  60% {
    opacity: 0.92;
    filter: blur(0);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}

/* Slogan direkt unter dem Hero-Namen, gleicher h1-Container.
   Eigene, viel kleinere Schrift — eigener feiner Glow. */
.hero-claim {
  display: block;
  margin: 0.15em 0 0;
  font-family: var(--font-claim);
  font-style: normal;
  font-weight: 400;
  /* Deutlich kleiner als Hero — wirkt wie eine handgesetzte Inschrift.
     Skalierung über vw (nicht vmin), damit auf engen Phones nicht zu
     groß. Letter-Spacing entsprechend kleiner gehalten. */
  font-size: clamp(11px, 2.4vw, 22px);
  letter-spacing: 0.14em;
  line-height: 1;
  color: rgba(212, 165, 116, 0.85);
  text-shadow:
    0 0 10px rgba(212, 165, 116, 0.20),
    0 0 26px rgba(180, 130, 70, 0.10);
  /* Eleganter Emerge: erst aufsteigt aus Unsichtbarkeit mit weiterem
     Letter-Spacing, beruhigt sich dann. Danach geht das ruhige Atmen.
     Setzt 1.8 s nach Page-Load ein — kommt also NACH dem Hero-Namen,
     wie bei einer langsam erwachenden Inschrift. */
  opacity: 0;
  animation:
    claim-emerge 2.4s cubic-bezier(0.22, 0.61, 0.36, 1) 1.8s both,
    claim-breathe 9s ease-in-out 4.4s infinite;
  will-change: opacity, transform, letter-spacing;
}

/* Eleganter Initial-Fade: aus dem Unsichtbaren steigend, mit
   leichtem Aufweiten des Letter-Spacings — wie das Erscheinen
   einer leisen Inschrift. */
@keyframes claim-emerge {
  0% {
    opacity: 0;
    transform: translateY(8px);
    letter-spacing: 0.40em;
    filter: blur(2px);
  }
  60% {
    opacity: 0.7;
    filter: blur(0);
  }
  100% {
    opacity: 0.85;
    transform: translateY(0);
    letter-spacing: 0.18em;
    filter: blur(0);
  }
}

@keyframes claim-breathe {
  0%, 100% { opacity: 0.78; }
  50%      { opacity: 1.00; }
}

@media (prefers-reduced-motion: reduce) {
  .hero-claim {
    animation: none;
    opacity: 0.85;
    transform: none;
  }
}

/* --------- Kopf & Fuß --------- */

.site-footer {
  position: fixed;
  left: 0;
  right: 0;
  z-index: 30;
  display: flex;
  justify-content: center;
  pointer-events: none;
  bottom: 22px;
  padding: 0 32px;
  /* Drei Spalten: Track-Hinweis links, Copyright mittig, Legal rechts */
  justify-content: space-between;
  align-items: center;
  gap: 18px;
  font-family: var(--font-display);
  font-size: 12.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  /* Bernsteinfarben — wärmer und lesbar */
  color: var(--amber-soft);
}

.footer-cell {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  pointer-events: auto;
}
.footer-legal { gap: 10px; }
.legal-link {
  background: none;
  border: 0;
  margin: 0;
  padding: 4px 2px;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition:
    color 180ms var(--ease-out),
    transform 140ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .legal-link:hover {
    color: var(--amber);
  }
}
.legal-link:focus-visible {
  outline: none;
  color: var(--amber);
  /* Bernstein-Ring für Tastatur-Fokus */
  border-radius: 3px;
  box-shadow: var(--focus-ring);
}
.legal-link:active {
  transform: scale(0.97);
  transition: transform 120ms var(--ease-out);
}
.footer-divider { opacity: 0.55; color: var(--amber-soft); }

/* Schmale Desktops + Tablets (≤ 720 px, dieselbe Schwelle an der die
   Label-Anker auf Mobile umschalten): Padding leicht reduziert. Das
   Copyright war hier früher ausgeblendet, weil der Werkhinweis links
   den Platz brauchte — der ist fort, also steht es wieder da. */
@media (max-width: 720px) {
  .site-footer {
    padding: 0 24px;
    gap: 14px;
  }
}
/* Sehr schmale Mobile-Viewports: Zeilen stapeln. */
@media (max-width: 480px) {
  .site-footer {
    flex-direction: column;
    gap: 6px;
    bottom: 14px;
    text-align: center;
    padding: 0 24px;
  }
}

/* --------- Mond-Bühne (sticky im Viewport) --------- */

.stage {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  z-index: 10;
  pointer-events: none;
  transition: transform 0.9s cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: transform;
}

.moon-wrap {
  position: relative;
  width: var(--moon-size);
  height: var(--moon-size);
  display: grid;
  place-items: center;
  pointer-events: auto;
  /* Sterne im Orbit dürfen den Mond-Rahmen verlassen */
  overflow: visible;
}

/* Mond-Glow: zarte warme Aureole AUSSERHALB des Monds. Bewusst sehr
   subtil — der Mond soll nicht in einer leuchtenden Halo-Wolke sitzen,
   sondern fast unsichtbar mit dem Body verschmelzen. Die Gradient-
   Stops gehen sanft vom warmen Glow zum Off-Black des Bodys, sodass
   am Mondrand keine Helligkeits-Diskontinuität entsteht (das wäre der
   sichtbare „Ring"). */
.moon-glow {
  position: absolute;
  inset: -25%;
  border-radius: 50%;
  background: radial-gradient(
    circle at center,
    rgba(212, 165, 116, 0.06) 30%,
    rgba(212, 165, 116, 0.025) 55%,
    rgba(0, 0, 0, 0) 80%
  );
  filter: blur(28px);
  transition: opacity 0.8s ease, transform 0.8s ease;
  opacity: 0.7;
}

.moon {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  overflow: hidden;
  cursor: pointer;
  /* Senkrecht scrollt die Seite weiter, waagerecht dreht die Scheibe
     ihre Phasen. Mit "manipulation" hätte der Browser beide Richtungen
     für sich behalten, und auf dem Handy käme nie eine waagerechte
     Bewegung bei uns an. */
  touch-action: pan-y;
  -webkit-tap-highlight-color: transparent;
  /* Background ist explizit der Body-Off-Black — wichtig für mix-blend-
     mode: screen auf dem Video. Ohne definierten Hintergrund würde der
     Blend-Mode transparente Pixel als reines Schwarz interpretieren und
     der dunkle Rand bliebe sichtbar. Mit identischem --bg verschwinden
     die schwarzen Video-Pixel optisch komplett im Body-Hintergrund. */
  background: var(--bg);
  /* Kein box-shadow mehr — der bisherige kühl-bläuliche Halo erzeugte
     außerhalb des Monds eine winzige Helligkeits-Diskontinuität gegen
     den warmen .moon-glow, was als sichtbarer Rand perzipiert wurde.
     Die warme Glow-Aureole übernimmt das Atmen alleine. */
  transition:
    filter 0.8s ease,
    transform 200ms var(--ease-out);
}
/* Subtle Press-Feedback — der Mond ist auch ein Button. Der Scale-Wert
   ist sehr klein (0.985), weil der Mond groß ist; trotzdem reicht es,
   den Klick spürbar zu bestätigen. */
.moon:active {
  transform: scale(0.985);
  transition: transform 140ms var(--ease-out);
}
/* Tastatur-Fokus-Ring rund um den Mond — Bernstein, leicht abgesetzt */
.moon:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring),
              0 0 0 4px rgba(7, 7, 10, 0.95);
}

.moon-media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
  user-select: none;
  pointer-events: none;
}
/* Initial-Reveal: Mond startet unsichtbar — der kurze Init-Play-Moment
   (auf iOS nötig, damit ein Frame im Compositor liegt) findet hinter
   einem Schwarz-Schleier statt. Erst wenn die Phase des aktiven Sterns
   eingestellt ist, wird der Mond sanft sichtbar.
   Wichtig: :not(.moon-fallback) — sonst würde der Gradient-Fallback
   beim is-ready ebenfalls sichtbar (er trägt die Klasse moon-media).

   mix-blend-mode: screen löscht alle schwarzen Pixel des Videos optisch
   aus — pure-schwarze Pixel (= Hintergrund des Mondvideos, der dunkle
   Übergang am Mondrand) werden vollständig unsichtbar gegen den
   Off-Black-Body. Der Mond schwebt frei, kein sichtbarer Rand mehr.
   Helle Pixel (Mondoberfläche) bleiben unverändert; dunkelgrau wird
   minimal aufgehellt (~1 % gegen #07070a) — visuell kein Unterschied. */
.moon .moon-media:not(.moon-fallback) {
  opacity: 0;
  /* Sanfter Page-Load-Reveal: Verzögerung ~0.4 s nach is-ready,
     damit der Mond NACH dem Sternenfeld aufdämmert (Choreografie:
     Sterne sofort → Mond bei ~0.4 s → Hero bei 1.2 s → ...). */
  transition: opacity 1.6s ease 0.4s;
  mix-blend-mode: screen;
}
.moon.is-ready .moon-media:not(.moon-fallback) {
  opacity: 1;
}
/* Fallback: reiner CSS-Mond aus radialen Gradienten — kein 404, kein Bild.
   Standardmäßig UNSICHTBAR. Wird NUR sichtbar, wenn das Video gar nicht
   geladen werden kann (.no-video). Sonst sieht man den Fallback-Gradient
   nicht — wir zeigen ausschließlich das echte Mondvideo, sobald die
   Phase des aktiven Sterns sauber gestellt ist. */
.moon-fallback {
  z-index: 0;
  opacity: 0;
  background:
    radial-gradient(circle at 38% 36%,
      rgba(245, 240, 225, 0.95) 0%,
      rgba(220, 210, 190, 0.85) 18%,
      rgba(150, 145, 135, 0.7) 45%,
      rgba(60, 60, 65, 0.6) 70%,
      rgba(20, 20, 24, 0.95) 100%),
    radial-gradient(circle at 70% 65%,
      rgba(40, 40, 45, 0.5) 0%,
      rgba(0, 0, 0, 0) 50%);
  filter: blur(0.5px);
}
.moon.no-video .moon-fallback { opacity: 1; }
.moon.no-video .moon-media:not(.moon-fallback) { display: none; }

.stage.is-scrubbing .moon {
  filter: brightness(1.1) saturate(1.03);
  transition: filter 0.25s ease;
}
.stage.is-scrubbing .moon-glow {
  opacity: 1;
  transform: scale(1.05);
}

/* Scroll-Spacer — zwei Zyklen (2 × 4 Sterne × 100 vh) Platz, damit das
   JS unsichtbar zwischen den Zyklen wrappen kann und der Scroll endlos
   wirkt. Ein Zyklus = 4 Viewport-Höhen, Spacer = 800 vh. */
.scroll-spacer {
  width: 1px;
  height: 800vh;
  pointer-events: none;
  visibility: hidden;
}

/* --------- Orbit: räumlich-frei verteilte Begriffe --------- */

.orbit {
  position: fixed;
  inset: 0;
  margin: 0;
  padding: 0;
  pointer-events: none;
  z-index: 12;
  overflow: visible;
  /* Page-Load-Choreografie: Orbit-Sterne sind beim Laden zunächst
     unsichtbar und dämmern nach Hero/Slogan auf (ab 2.4 s). Innerhalb
     des Orbits sind die einzelnen Sterne nochmal gestaffelt. */
  opacity: 0;
  animation: orbit-emerge 1.8s var(--ease-out) 2.4s forwards;
}

@keyframes orbit-emerge {
  0%   { opacity: 0; }
  100% { opacity: 1; }
}

/* Ein Stern: feste Position im Viewport, eigene Tiefe (--depth).
   Beim Scrollen wird der dem Scroll-Index entsprechende Stern aktiv
   (--active gleitet weich von 0 → 1 per JS), zoomt nach vorne. */
.orbit-star {
  --depth:  0.5;   /* statisch im HTML, definiert Grundgröße/Helligkeit */
  --hover:  0;     /* 0..1 — vom JS bei Pointer-Hover gesetzt */
  --active: 0;     /* 0..1 — vom JS gesetzt, wenn Scroll diesen Stern wählt */

  /* Effektiver Boost: Hover und Aktiv addieren sich, max 1 */
  --boost:  min(1, calc(var(--hover) + var(--active)));
  --depth-scale:  calc(0.55 + 0.7 * var(--depth));   /* 0.55 .. 1.25 */
  --total-scale:  calc(var(--depth-scale) + 0.85 * var(--boost));

  position: fixed;
  left: var(--pos-x);
  top:  var(--pos-y);
  width: 0;
  height: 0;
  text-decoration: none;
  color: var(--fg);
  /* iOS Safari interpretiert zwei schnelle Taps sonst als Double-Tap-
     Zoom und unterdrückt den zweiten click-Event — dadurch öffnete
     sich die verlinkte Seite nie. touch-action: manipulation erlaubt
     Pan/Pinch-Zoom auf der Seite, aber NICHT auf dem Stern selbst,
     sodass Doppelklicks zuverlässig ankommen.
     -webkit-tap-highlight-color: transparent entfernt das graue
     Tap-Flackern auf iOS. */
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  pointer-events: auto;
  cursor: pointer;
  /* Aktiv/hover: Stern-Element skaliert moderat (1.0 → 1.4) UND wandert
     deutlich in --out-Richtung (vom Mond weg). Bewusst weniger Skalierung
     als zuvor (1.7 war zu viel) — die Labels wuchsen sonst zoom-bedingt
     in den Mondbereich hinein und wurden unleserlich vor der hellen
     Mondscheibe. Stattdessen: weniger Wachstum, mehr räumliche Distanz.
     Visuelle Wirkung („dieser Stern ist gewählt") kommt durch Halo + Pulse
     des Punkts, nicht primär durch Größe des Labels. */
  transform:
    translate(
      calc(var(--out-x, 0) * var(--boost) * 22px),
      calc(var(--out-y, 0) * var(--boost) * 22px)
    )
    scale(calc(1 + 0.4 * var(--boost)));
  transform-origin: 0 0;
  z-index: calc(10 + var(--boost) * 5);
  transition: transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Großzügige Klickfläche, deckt auch das Label ab */
.orbit-star::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 96px;
  height: 96px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  /* Fokus-Ring vorerst unsichtbar */
  border: 1px solid transparent;
  transition: border-color 200ms var(--ease-out),
              box-shadow 200ms var(--ease-out);
}
/* Tastatur-Fokus auf einem Stern: Bernstein-Ring um die Klickfläche */
.orbit-star:focus-visible {
  outline: none;
}
.orbit-star:focus-visible::before {
  border-color: rgba(212, 165, 116, 0.7);
  box-shadow: 0 0 18px rgba(212, 165, 116, 0.35);
}

/* Leuchtpunkt — Tiefe und Boost steuern Größe / Glow / Helligkeit.
   Beim Aktivieren (boost ≈ 1) wandern die Glow-Farben deutlich ins
   Bernsteinfarbene: aus kühl-cream wird warm-goldlich. */
.orbit-star .dot {
  display: block;
  position: absolute;
  left: 0;
  top: 0;
  transform: translate(-50%, -50%);
  width:  calc(11px * var(--total-scale));
  height: calc(11px * var(--total-scale));
  border-radius: 50%;
  background: rgba(
    calc(252 - 3  * var(--boost)),
    calc(248 - 28 * var(--boost)),
    calc(228 - 80 * var(--boost)),
    calc(0.55 + 0.3 * var(--depth) + 0.2 * var(--boost))
  );
  filter: brightness(calc(0.7 + 0.4 * var(--depth) + 0.5 * var(--boost)))
          saturate(calc(1 + 0.4 * var(--boost)));
  box-shadow:
    /* Innerer Kern — wechselt von Cremeweiß zu warmem Gold */
    0 0 calc(8px  + 10px * var(--depth) + 24px * var(--boost))
        rgba(
          calc(255 - 0  * var(--boost)),
          calc(244 - 30 * var(--boost)),
          calc(218 - 78 * var(--boost)),
          calc(0.4 + 0.35 * var(--depth) + 0.4 * var(--boost))
        ),
    /* Mittlere Aureole — Bernstein-Tönung bei aktiv */
    0 0 calc(22px + 28px * var(--depth) + 52px * var(--boost))
        rgba(
          calc(252 - 12 * var(--boost)),
          calc(225 - 40 * var(--boost)),
          calc(180 - 70 * var(--boost)),
          calc(0.18 + 0.3 * var(--depth) + 0.45 * var(--boost))
        ),
    /* Weiter Halo — bei boost=0 leicht kühl, bei boost=1 satt bernstein */
    0 0 calc(48px + 50px * var(--depth) + 90px * var(--boost))
        rgba(
          calc(210 + 25 * var(--boost)),
          calc(205 - 30 * var(--boost)),
          calc(195 - 90 * var(--boost)),
          calc(0.06 + 0.18 * var(--depth) + 0.4 * var(--boost))
        );

  animation: orbit-twinkle 4.5s ease-in-out infinite;
  animation-delay: var(--twinkle-delay, 0s);
  transition:
    width 0.6s cubic-bezier(0.22, 0.61, 0.36, 1),
    height 0.6s cubic-bezier(0.22, 0.61, 0.36, 1),
    background 0.6s ease,
    filter 0.6s ease,
    box-shadow 0.6s ease;
}

@keyframes orbit-twinkle {
  0%, 100% { filter: brightness(calc(0.7 + 0.4 * var(--depth) + 0.45 * var(--boost))); }
  50%      { filter: brightness(calc(1.0 + 0.4 * var(--depth) + 0.45 * var(--boost))); }
}

/* Aktiver Stern (--active === 1): kräftiges Pulsieren */
.orbit-star.is-active .dot {
  animation: orbit-pulse 2.6s ease-in-out infinite;
}
@keyframes orbit-pulse {
  0%, 100% {
    transform: translate(-50%, -50%) scale(1);
    filter: brightness(calc(1.0 + 0.4 * var(--depth) + 0.45 * var(--boost))) saturate(1.05);
  }
  50% {
    transform: translate(-50%, -50%) scale(1.2);
    filter: brightness(calc(1.45 + 0.4 * var(--depth) + 0.45 * var(--boost))) saturate(1.18);
  }
}

/* Label — Position über data-anchor in 8 Himmelsrichtungen (n, ne, e,
   se, s, sw, w, nw). So ist immer eine Seite gewählt, an der das Label
   vom Stern weg in den freien Raum zeigt. */
.orbit-label {
  position: absolute;
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 400;
  /* Font-Wachstum bei Boost reduziert (5px → 3px), damit Labels im
     aktiven Zustand nicht in den Mondbereich hineinwachsen. Das primäre
     visuelle Feedback liefert der Halo + Pulse des Punkts. */
  font-size: calc(17px + 6px * var(--depth) + 3px * var(--boost));
  letter-spacing: 0.08em;
  line-height: 1.05;
  white-space: nowrap;
  /* Wandert von kühlem Pergament zu warmem Bernstein bei aktiv */
  color: rgba(
    calc(251 - 8  * var(--boost)),
    calc(244 - 28 * var(--boost)),
    calc(220 - 75 * var(--boost)),
    calc(0.55 + 0.3 * var(--depth) + 0.2 * var(--boost))
  );
  text-shadow:
    0 0 calc(6px  + 14px * var(--boost))
        rgba(
          255,
          calc(245 - 30 * var(--boost)),
          calc(220 - 80 * var(--boost)),
          calc(0.15 + 0.5 * var(--boost))
        ),
    0 0 calc(22px + 28px * var(--boost))
        rgba(
          calc(245 - 20 * var(--boost)),
          calc(215 - 35 * var(--boost)),
          calc(165 - 60 * var(--boost)),
          calc(0.08 + 0.4 * var(--boost))
        );
  /* Klickbar, damit Hover über das Label auch den Stern triggert */
  pointer-events: auto;
  user-select: none;
  transition:
    font-size 0.55s cubic-bezier(0.22, 0.61, 0.36, 1),
    color 0.55s ease,
    text-shadow 0.55s ease;
}

/* Anchor-Logik: das Label wird relativ zum Punkt versetzt, in der
   Richtung weg vom Mond. --gap wächst leicht mit Tiefe und Boost. */
.orbit-star { --gap: calc(16px + 5px * var(--depth) + 8px * var(--boost)); }

/* Nord (oben) */
.orbit-star[data-anchor="n"] .orbit-label {
  left: 0;
  bottom: calc(var(--gap) + 6px);
  transform: translateX(-50%);
}
/* Nordost (oben rechts) */
.orbit-star[data-anchor="ne"] .orbit-label {
  left: var(--gap);
  bottom: var(--gap);
}
/* Ost (rechts) */
.orbit-star[data-anchor="e"] .orbit-label {
  left: var(--gap);
  top: 0;
  transform: translateY(-50%);
}
/* Südost (unten rechts) */
.orbit-star[data-anchor="se"] .orbit-label {
  left: var(--gap);
  top: var(--gap);
}
/* Süd (unten) */
.orbit-star[data-anchor="s"] .orbit-label {
  left: 0;
  top: calc(var(--gap) + 6px);
  transform: translateX(-50%);
}
/* Südwest (unten links) */
.orbit-star[data-anchor="sw"] .orbit-label {
  right: var(--gap);
  top: var(--gap);
}
/* West (links) */
.orbit-star[data-anchor="w"] .orbit-label {
  right: var(--gap);
  top: 0;
  transform: translateY(-50%);
}
/* Nordwest (oben links) */
.orbit-star[data-anchor="nw"] .orbit-label {
  right: var(--gap);
  bottom: var(--gap);
}

/* Tablet-Breiten: die Seite trägt die seitlichen Beschriftungen noch,
   aber knapp. „Veröffentlichungen" ist das längste Wort und lief unten
   links über den Rand hinaus — beide Spalten rücken deshalb ein Stück
   zur Mitte. */
@media (min-width: 721px) and (max-width: 1023px) {
  .orbit-star[data-anchor="nw"],
  .orbit-star[data-anchor="sw"] { left: 25vw; }
  .orbit-star[data-anchor="ne"],
  .orbit-star[data-anchor="se"] { left: 75vw; }
}

/* Mobile: enge Viewports brauchen ein anderes Layout — Sterne näher
   zur Mitte, Labels VERTIKAL (über/unter dem Stern) statt seitlich,
   damit nichts über den Bildschirmrand wandert. */
@media (max-width: 720px) {
  .orbit-star {
    /* Mobile-Positionen aus --pos-x-m / --pos-y-m, sonst Desktop-Fallback */
    left: var(--pos-x-m, var(--pos-x));
    top:  var(--pos-y-m, var(--pos-y));
  }

  /* Label kompakter und nur über/unter dem Stern (data-mobile-anchor).
     Boost-Font-Wachstum reduziert (5 → 3 px), damit Labels nicht in den
     Mondbereich hineinwachsen — Mobile hat besonders wenig Platz. */
  .orbit-label {
    font-size: calc(12px + 4px * var(--depth) + 3px * var(--boost));
    letter-spacing: 0.06em;
  }

  .orbit-star[data-mobile-anchor="s"] .orbit-label {
    /* Label UNTER dem Punkt, horizontal zentriert */
    left: 0; right: auto;
    top: calc(var(--gap) + 4px); bottom: auto;
    transform: translateX(-50%);
  }
  .orbit-star[data-mobile-anchor="n"] .orbit-label {
    /* Label ÜBER dem Punkt, horizontal zentriert */
    left: 0; right: auto;
    bottom: calc(var(--gap) + 4px); top: auto;
    transform: translateX(-50%);
  }

  /* Mobile: deutliche Out-Drift (22 px), moderate Skalierung (1.0 → 1.2).
     Wesentliches Ziel: Labels bleiben kompakt und drücken sich beim
     Aktivieren spürbar VOM Mond weg statt in seinen Bereich hinein —
     vor allem bei Hexenwerk und Funkenfangen, die nahe am unteren
     Mondrand sitzen.
     Zusätzlich --gap-Multiplikator hier hochgedreht (8 → 16 px), damit
     Labels noch klarer Abstand zum Dot halten, wenn der Stern aktiv ist.
     --out-x-m/--out-y-m überschreiben die Desktop-Werte für Sterne, die
     auf Mobile auf der ANDEREN Seite des Monds liegen (z.B. „Über mich"
     ist Desktop rechts, Mobile links). Fallback: Desktop-Werte. */
  .orbit-star {
    --gap: calc(14px + 4px * var(--depth) + 16px * var(--boost));
    transform:
      translate(
        calc(var(--out-x-m, var(--out-x, 0)) * var(--boost) * 22px),
        calc(var(--out-y-m, var(--out-y, 0)) * var(--boost) * 22px)
      )
      scale(calc(1 + 0.2 * var(--boost)));
  }
}

/* --------- Legal-Modal (Impressum & Datenschutz) --------- */

.legal-modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: 24px;
  opacity: 0;
  pointer-events: none;
  /* Exit fast (180ms), Entry mittel (280ms) — beim Schließen will der
     User raus, nicht warten. Custom ease-out gibt Definition statt Watte. */
  transition: opacity 180ms var(--ease-out);
}
.legal-modal[hidden] {
  display: none;
}
.legal-modal.is-open {
  opacity: 1;
  pointer-events: auto;
  transition: opacity 280ms var(--ease-out);
}

.legal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.78);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.legal-panel {
  position: relative;
  width: min(640px, 100%);
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  padding: 56px 48px 44px;
  background: #0a0a0d;
  border: 1px solid rgba(233, 230, 223, 0.08);
  border-radius: 2px;
  /* Lesefreundliche Serif für Fließtext — Headlines unten überschreiben */
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  color: rgba(233, 230, 223, 0.82);
  letter-spacing: 0.005em;
  /* Sehr leichter Schein nach außen — wie bei einer Buchseite */
  box-shadow:
    0 30px 80px rgba(0, 0, 0, 0.6),
    0 0 0 1px rgba(233, 230, 223, 0.04);
  /* Entry-State: leicht skaliert + leicht versetzt + transparent. Nichts in
     der echten Welt erscheint aus dem Nichts — eine winzige Anfangsskala
     + Opacity macht den Eintritt natürlich. */
  transform: translateY(8px) scale(0.985);
  opacity: 0;
  transition:
    transform 180ms var(--ease-out),
    opacity 180ms var(--ease-out);
}
.legal-modal.is-open .legal-panel {
  transform: translateY(0) scale(1);
  opacity: 1;
  transition:
    transform 320ms var(--ease-out),
    opacity 280ms var(--ease-out);
}

.legal-close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  background: transparent;
  border: 1px solid rgba(233, 230, 223, 0.12);
  border-radius: 50%;
  color: var(--fg-muted);
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition:
    color 180ms var(--ease-out),
    border-color 180ms var(--ease-out),
    transform 160ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .legal-close:hover {
    color: var(--fg);
    border-color: rgba(233, 230, 223, 0.35);
  }
}
.legal-close:focus-visible {
  outline: none;
  color: var(--fg);
  border-color: rgba(212, 165, 116, 0.7);
  box-shadow: var(--focus-ring);
}
.legal-close:active {
  transform: scale(0.92);
  transition: transform 120ms var(--ease-out);
}

.legal-tabs {
  display: flex;
  gap: 18px;
  margin-bottom: 28px;
  border-bottom: 1px solid rgba(233, 230, 223, 0.08);
  padding-bottom: 12px;
}
.legal-tab {
  background: none;
  border: 0;
  padding: 6px 0;
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--fg-muted);
  cursor: pointer;
  position: relative;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transition:
    color 180ms var(--ease-out),
    transform 140ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .legal-tab:hover { color: rgba(233, 230, 223, 0.85); }
}
.legal-tab:focus-visible {
  outline: none;
  color: var(--fg);
  border-radius: 3px;
  box-shadow: var(--focus-ring);
}
.legal-tab:active {
  transform: scale(0.97);
  transition: transform 120ms var(--ease-out);
}
.legal-tab.active {
  color: var(--fg);
}
.legal-tab.active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -13px;
  height: 1px;
  background: rgba(233, 230, 223, 0.4);
}

.legal-title {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(28px, 4vmin, 42px);
  letter-spacing: 0.01em;
  color: #ede9de;
  margin: 0 0 24px;
  line-height: 1;
}

.legal-content { display: none; }
.legal-content.active { display: block; }
.legal-content h3 {
  /* Sub-Headings: hell und klar, deutlich kontrastreicher als der Fließtext.
     Tragen die Hierarchie sichtbar — Pergament-Weiß statt gedämpft. */
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 13px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #ede9de;
  margin: 32px 0 10px;
}
.legal-content h3:first-of-type { margin-top: 6px; }
.legal-content p {
  /* Fließtexte in EB Garamond — lesbar, klassisch */
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.65;
  letter-spacing: 0.005em;
  margin: 0 0 8px;
}
.legal-content a {
  color: rgba(233, 230, 223, 0.95);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 0.5px;
  text-decoration-color: rgba(233, 230, 223, 0.3);
  transition: text-decoration-color 200ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .legal-content a:hover {
    text-decoration-color: rgba(233, 230, 223, 0.75);
  }
}

@media (max-width: 600px) {
  .legal-panel {
    padding: 56px 28px 36px;
    font-size: 13px;
  }
  .legal-title {
    font-size: 26px;
  }
}

/* --------- Mondzyklus: 16 s Atem für die ganze Konstellation ---------- */
/* Klick auf den Mond → zweimal zu- und abnehmen, innerhalb des
   beleuchteten Bandes, zurück zur Phase des aktiven Sterns (gesamte
   Geste ~16 s). Während dieser Zeit:
     - der Mond ATMET rhythmisch (4 Atemzüge à 4 s, scale 1.0 ↔ 1.04)
     - alle Sterne pulsieren synchron heller (2 Spitzen, eine pro Zyklus)
     - Konstellations-Linien glühen mit (2 Glanz-Wellen)
   Die Animationen liegen alle bei 16 s ease-in-out, sodass Anfang und
   Ende der Geste so sanft sind wie ihre Mitte intensiv. */

/* Mond-Atem: rhythmisches An- und Abschwellen während des Zyklus.
   moon-wrap statt .moon, weil .moon eigene transform-Transitions hat. */
body.is-moon-cycle .moon-wrap {
  animation: moon-cycle-breathe 4s ease-in-out 4;
}
@keyframes moon-cycle-breathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.04); }
}

/* Sternen-Punkte pulsieren mit zwei Höhepunkten (einer pro Vollmond
   im Doppel-Zyklus) und sanften Tälern dazwischen. */
body.is-moon-cycle .orbit-star .dot {
  animation: moon-cycle-dot 16s ease-in-out 1 !important;
}
body.is-moon-cycle .orbit-star.is-active .dot {
  animation: moon-cycle-dot-active 16s ease-in-out 1 !important;
}
@keyframes moon-cycle-dot {
  0%, 100% {
    filter: brightness(1) saturate(1);
    transform: translate(-50%, -50%) scale(1);
  }
  25% {
    filter: brightness(2.2) saturate(1.5);
    transform: translate(-50%, -50%) scale(1.14);
  }
  50% {
    filter: brightness(1.2) saturate(1.05);
    transform: translate(-50%, -50%) scale(1.02);
  }
  75% {
    filter: brightness(2.2) saturate(1.5);
    transform: translate(-50%, -50%) scale(1.14);
  }
}
@keyframes moon-cycle-dot-active {
  0%, 100% {
    filter: brightness(1.2) saturate(1.1);
    transform: translate(-50%, -50%) scale(1);
  }
  25%, 75% {
    filter: brightness(2.8) saturate(1.65);
    transform: translate(-50%, -50%) scale(1.22);
  }
  50% {
    filter: brightness(1.4) saturate(1.15);
    transform: translate(-50%, -50%) scale(1.04);
  }
}

/* Konstellations-Linien glühen mit zwei Spitzen. */
body.is-moon-cycle .conn-line {
  animation: moon-cycle-line 16s ease-in-out 1 !important;
}
@keyframes moon-cycle-line {
  0%, 100% { filter: brightness(1); opacity: 0.85; }
  25%      { filter: brightness(1.9); opacity: 1; }
  50%      { filter: brightness(1.05); opacity: 0.9; }
  75%      { filter: brightness(1.9); opacity: 1; }
}

/* Während des Zyklus zeigt der Mond Default-Cursor — andere Elemente
   bleiben interaktiv, die Sterne lassen sich weiterhin anwählen. */
body.is-moon-cycle .moon {
  cursor: default;
}

/* --------- Klick-Übergang: reiner Fade, kein Zoom --------- */

body.is-leaving .stage,
body.is-leaving .site-footer,
body.is-leaving .hero-name,
body.is-leaving .connection {
  opacity: 0;
  transition: opacity 0.8s ease;
}
/* Die übrigen Sterne verblassen, der gewählte bleibt. Er ist das
   letzte, was von dieser Seite zu sehen ist, bevor die nächste
   übernimmt. */
body.is-leaving .orbit-star {
  opacity: 0;
  transition: opacity 0.55s ease;
}
body.is-leaving .orbit-star.is-chosen {
  opacity: 1;
  transition: opacity 0.55s ease 0.35s;
}
body.is-leaving .grain,
body.is-leaving .vignette {
  opacity: 0;
  transition: opacity 0.9s ease;
}
body.is-leaving .moon {
  filter: brightness(1.18);
  transition: filter 0.8s ease, opacity 0.8s ease 0.15s;
}
body.is-leaving {
  pointer-events: none;
  cursor: progress;
}

/* --------- Responsive --------- */

@media (max-width: 720px) {
  :root {
    --moon-size: clamp(180px, 48vmin, 300px);
  }
  /* Hero auf Mobile höher setzen — Abstand zu den oberen
     Sternbild-Linien (Musik ↔ Forschung) erhalten. */
  .hero-name {
    top: clamp(3vh, 4.5vh, 7vh);
    /* Padding seitlich kleiner, damit der Name auf engen Phones
       wirklich Platz hat. */
    padding: 0.35em 14px 0.45em;
  }
}

/* Mobile bis 720 px: Hero soll auf Hochformat-Phones nicht über vmin
   skalieren (zu groß, weil vmin = Breite × 1.x ist). vw ist hier
   zuverlässiger. */
@media (max-width: 720px) {
  .hero-name {
    font-size: clamp(26px, 7.2vw, 56px);
  }
}

/* Sehr enge Smartphones (≤ 380 px): Mond, Stern-Labels und
   Konstellations-Layout müssen noch vorsichtiger werden, sonst
   verzerrt sich alles und Labels überlappen sich oder den Mond. */
@media (max-width: 380px) {
  :root {
    --moon-size: clamp(160px, 50vmin, 220px);
  }
  .orbit-label {
    font-size: calc(11px + 3px * var(--depth) + 2px * var(--boost));
    letter-spacing: 0.04em;
  }
  .hero-name {
    font-size: clamp(22px, 7vw, 32px);
  }
  .hero-claim {
    font-size: clamp(10px, 2.6vw, 14px);
    letter-spacing: 0.10em;
  }
}

/* Reduced motion: scrollverhalten + Korn-Animation deaktivieren.
   Pulsieren der Sterne ebenfalls aus. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .grain { animation: none !important; }
  .orbit-star.is-active .dot { animation: none !important; }
  .hero-name span { animation: none !important; }
  .moon { transition: none !important; }
}
