/* ==========================================================================
   DMN · d-m-n.de
   Prinzip: JavaScript schreibt pro Szene nur eine Zahl --p (0…1, Scrollfortschritt).
   Alle Bewegungen rechnet CSS daraus selbst — clamp() schneidet Teilbereiche aus:
   --t: clamp(0, (var(--p) - START) / DAUER, 1)
   Ohne JS gilt --p: 1, alles steht im Endzustand und bleibt lesbar.
   ========================================================================== */

:root {
  --bg: #07090c;
  --ink: #eef1ec;
  --mute: #8b948e;
  --kupfer: #d9844a;
  --kupfer-hell: #f3c08e;
  --gruen: #3fbf5a;
  --gruen-hell: #8fe39f;
  --glas: rgba(255, 255, 255, 0.055);
  --glas-rand: rgba(255, 255, 255, 0.12);
  --schrift: "Segoe UI Variable Display", "Segoe UI", system-ui, -apple-system, "SF Pro Display", Roboto, sans-serif;
  --radius: 22px;
  --rand: clamp(16px, 4vw, 48px);
}

*, *::before, *::after { box-sizing: border-box; }
/* clip statt hidden: schneidet Überstand ab, ohne einen Scroll-Container zu bilden (sticky bleibt intakt).
   Nur an html — stünde es auch an body, würde body zum Scroll-Container und sticky bräche. */
html { scroll-behavior: smooth; overflow-x: clip; overflow-anchor: none; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--schrift);
  font-size: 1.05rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-anchor: none;
}
h1, h2, h3 { margin: 0; line-height: 1.02; letter-spacing: -0.035em; font-weight: 800; }
h2 { font-size: clamp(2.2rem, 6vw, 4.8rem); }
h2 em { font-style: normal; color: var(--kupfer); }
p { margin: 0; }
a { color: inherit; }
img { max-width: 100%; display: block; }
.nur-lesbar { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.ueber {
  font-size: 0.78rem; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--mute); margin-bottom: 1rem;
}

@keyframes wort-rein { from { opacity: 0; filter: blur(12px); transform: translateY(18px) scale(.96); } }
@keyframes blinken { 50% { opacity: 0; } }

/* ---------- Rahmen ---------- */
.grain {
  position: fixed; inset: 0; z-index: 90; pointer-events: none; opacity: 0.07;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.fortschritt { position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 100; }
.fortschritt i {
  display: block; height: 100%;
  background: linear-gradient(90deg, var(--kupfer), var(--gruen));
  transform-origin: left; transform: scaleX(var(--seite, 0));
}
.kopf {
  position: fixed; top: 14px; left: 16px; right: 16px; z-index: 80;
  display: flex; justify-content: space-between; align-items: center; pointer-events: none;
}
.kopf > * { pointer-events: auto; }
.marke, .kopf nav {
  background: rgba(10, 12, 15, .55); border: 1px solid var(--glas-rand);
  backdrop-filter: blur(14px) saturate(160%); -webkit-backdrop-filter: blur(14px) saturate(160%);
  border-radius: 999px;
}
.marke { font-weight: 900; letter-spacing: -0.04em; font-size: 1.25rem; text-decoration: none; padding: 8px 14px; }
.kopf nav { display: flex; gap: 4px; padding: 5px; }
.kopf nav a { text-decoration: none; font-size: 0.9rem; padding: 7px 14px; border-radius: 999px; color: #b7beb9; transition: color .2s, background .2s; }
.kopf nav a:hover { color: var(--ink); background: rgba(255,255,255,.08); }
.kopf nav a.knopf-klein { color: #1a0d05; background: var(--kupfer); font-weight: 600; }
@media (max-width: 640px) { .kopf nav a:not(.knopf-klein) { display: none; } }

/* ---------- Szenen-Grundgerüst ---------- */
.szene { position: relative; height: var(--hoehe, 300vh); --p: 1; }
html.js .szene { --p: 0; }
.buehne { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; }

/* ==========================================================================
   1 · BLASEN — flüssige Kugeln, aus DMN wird Dream · Make · Next
   ========================================================================== */
/* Die Blasen liegen eng beieinander: Nur wenn sie sich berühren, zieht der goo-Filter
   die „Brücken" zwischen ihnen — das ist der flüssige Eindruck. */
.fluid {
  --lage: translate(-50%, -50%);
  position: absolute; left: 50%; top: 50%; width: min(92vmin, 880px); aspect-ratio: 1;
  transform: var(--lage); filter: url(#goo); pointer-events: none;
}
.blob {
  position: absolute; border-radius: 50%; aspect-ratio: 1;
  background: radial-gradient(circle at 35% 30%, #ffd9b3, var(--kupfer) 50%, #a4532a);
  animation: schweben 14s ease-in-out infinite alternate;
}
.blob.b1 { width: 42%; left: 12%; top: 18%; }
.blob.b2 { width: 32%; left: 50%; top: 20%; animation-duration: 11s; animation-delay: -3s; background: radial-gradient(circle at 35% 30%, #c9f5d2, var(--gruen) 50%, #1f7a36); }
.blob.b3 { width: 26%; left: 36%; top: 54%; animation-duration: 17s; animation-delay: -6s; }
.blob.b4 { width: 21%; left: 62%; top: 56%; animation-duration: 13s; animation-delay: -2s; background: radial-gradient(circle at 35% 30%, #d6efff, #4a9be0 50%, #1f4f82); }
.blob.b5 { width: 15%; left: 24%; top: 58%; animation-duration: 9s; }
@keyframes schweben {
  0%   { transform: translate(0, 0) scale(1); }
  33%  { transform: translate(9%, -7%) scale(1.12); }
  66%  { transform: translate(-8%, 6%) scale(.9); }
  100% { transform: translate(5%, 9%) scale(1.05); }
}

.hero .buehne {
  --s: clamp(0, (var(--p) - 0.02) / 0.22, 1);     /* Buchstaben schrumpfen zuerst … */
  --t: clamp(0, (var(--p) - 0.12) / 0.32, 1);     /* … dann wachsen die Wörter heraus */
  --aus: clamp(0, (var(--p) - 0.62) / 0.3, 1);
  display: grid; place-content: center; text-align: center;
  background: radial-gradient(ellipse at 50% 60%, #111820 0%, var(--bg) 70%);
}
.hero .fluid {
  opacity: calc(0.62 - var(--t) * 0.32);
  transform: var(--lage) scale(calc(1 + var(--p) * 0.9)) rotate(calc(var(--p) * 40deg));
}
.hero .dmn-wort {
  position: relative; transform: translateY(calc(var(--aus) * -18vh)); opacity: calc(1 - var(--aus));
}
.dmn-wort {
  font-size: calc(clamp(5rem, 24vw, 21rem) * (1 - var(--s) * 0.64));
  display: flex; justify-content: center; align-items: baseline; gap: calc(var(--t) * 0.28em);
  font-weight: 900; letter-spacing: -0.06em; line-height: .9; text-shadow: 0 10px 60px rgba(0,0,0,.35);
}
.dmn-wort .w { display: inline-flex; align-items: baseline; }
.dmn-wort b { background: linear-gradient(180deg, #fff 20%, #9aa39d); -webkit-background-clip: text; background-clip: text; color: transparent; }
.dmn-wort i {
  font-style: normal; display: inline-block; overflow: hidden; white-space: nowrap;
  max-width: calc(var(--t) * var(--len, 2.4em)); opacity: var(--t);
  background: linear-gradient(180deg, var(--kupfer-hell), var(--kupfer)); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.scroll-hinweis { position: absolute; bottom: 5vh; left: 50%; translate: -50% 0; opacity: calc(1 - var(--p) * 6); }
.scroll-hinweis span { display: block; width: 22px; height: 36px; border: 2px solid var(--mute); border-radius: 12px; position: relative; }
.scroll-hinweis span::after {
  content: ""; position: absolute; left: 50%; top: 7px; width: 4px; height: 8px; margin-left: -2px;
  border-radius: 2px; background: var(--kupfer); animation: maus 1.8s ease-in-out infinite;
}
@keyframes maus { 0% { opacity: 0; transform: translateY(-3px); } 40% { opacity: 1; } 100% { opacity: 0; transform: translateY(10px); } }

/* ==========================================================================
   2 · DMN — der Kopf entsteht beim Scrollen in drei Schritten, und jeder Schritt gehört zu einer
   der drei Bedeutungen und trägt ihre Farbe. Die Reihenfolge erzählt, wie eine Idee entsteht:
   erst der Traum, dann wandern die Gedanken frei herein, zuletzt werden sie geordnet.
     Dream · Make · Next             kupfer  der Umriss zeichnet sich           (--a)
     Default · Mode · Network        grün    die Gedanken fliegen frei hinein   (--b)
     Decision · Model · Notation     blau    das Netz ordnet und verbindet sie  (--c)
   Die Wörter wechseln in main.js genau dort, wo ihr Schritt beginnt (p = 0,33 und 0,63).
   ========================================================================== */
.dmn .buehne {
  --ph: 0; --farbe: var(--farbe-1);
  --farbe-1: var(--kupfer); --farbe-2: #4fd86c; --farbe-3: #6fc3ff;
  --a: clamp(0, var(--p) / .28, 1);
  --b: clamp(0, (var(--p) - .33) / .27, 1);
  --c: clamp(0, (var(--p) - .63) / .25, 1);
  display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 3vh;
  text-align: center; padding: 72px 0 24px;
  background: radial-gradient(circle at 50% 42%, color-mix(in srgb, var(--farbe) 16%, transparent), transparent 55%), var(--bg);
  transition: background .6s;
}
.dmn .buehne[data-phase="1"] { --ph: 1; --farbe: var(--farbe-2); }
.dmn .buehne[data-phase="2"] { --ph: 2; --farbe: var(--farbe-3); }

/* Nie breiter als der Bildschirm — sonst schieben manche Handy-Browser das Bild zur Seite.
   Keine Schatten-Filter auf den Linien: Die müssten bei jedem Scroll-Schritt neu gerechnet werden
   und ließen das Bild auf dem Handy ruckeln. */
.gehirn { display: block; width: min(92vw, 52vh, 520px); flex: none; overflow: visible; }
.huelle path {
  fill: none; stroke: var(--farbe-1); stroke-width: 2.4; stroke-linecap: round;
  stroke-dasharray: 1; stroke-dashoffset: calc(1 - var(--a));
}
.huelle path:first-child { fill: rgba(217,132,74,calc(var(--a) * .08)); }
.erinnerung {
  --z: clamp(0, (var(--b) - var(--v) * 2.4) / .4, 1);
  fill: none; stroke: var(--farbe-2); stroke-width: 1.8; stroke-linejoin: round;
  transform: translate(calc(var(--sx) * (1 - var(--z)) * 1px), calc(var(--sy) * (1 - var(--z)) * 1px)) scale(calc(.6 + var(--z) * .4));
  transform-box: fill-box; transform-origin: center;
  opacity: var(--z);
}
.netz path {
  fill: none; stroke: var(--farbe-3); stroke-width: 1.8; stroke-linecap: round; stroke-dasharray: 1;
  stroke-dashoffset: calc(1 - var(--c));
}
/* Erst wenn das Netz steht, „denkt" der Kopf */
.dmn .buehne[data-phase="2"] .netz { animation: denken 2.4s ease-in-out infinite; }
@keyframes denken { 50% { opacity: .5; } }

/* Der Block steht mittig, innen bleiben D·M·N bündig untereinander. Seine Breite ergibt sich aus dem
   längsten Wort je Zeile (alle drei liegen in der Rolle) — so springt er beim Wechsel nicht. */
.slots { position: relative; text-align: left; font-size: clamp(2.4rem, min(9vw, 9vh), 7rem); font-weight: 900; letter-spacing: -0.05em; line-height: 1; }
.slot { display: flex; align-items: flex-end; height: 1.02em; }
.slot b { color: var(--farbe); transition: color .6s; width: .78em; }
.rolle { display: inline-block; height: 1.02em; overflow: hidden; }
.rolle i { display: block; font-style: normal; height: 1.02em; transform: translateY(calc(var(--ph) * -100%)); transition: transform .8s cubic-bezier(.7, 0, .2, 1); }
.slot:nth-child(2) .rolle i { transition-delay: .07s; }
.slot:nth-child(3) .rolle i { transition-delay: .14s; }

/* ==========================================================================
   3 · WURZELN — erst wächst der Baum, dann geht der Blick unter die Erde
   ========================================================================== */
.wurzeln .buehne {
  --wachs: clamp(0, var(--p) / 0.22, 1);
  --k: clamp(0, (var(--p) - 0.24) / 0.62, 1);
  --fest: clamp(0, (var(--k) - .95) / .04, 1);   /* Lichtpunkte werden zu klarer Schrift */
  background: #07090c;
}
/* Die „Welt" ist 250vh hoch und fährt beim Scrollen nach oben: Himmel → Boden → tief in die Erde.
   Wie weit, rechnet wurzeln.js aus (--ende), damit der Satz am Ende sicher im Bild steht. */
.welt { position: absolute; left: 0; right: 0; top: 0; height: 250vh; will-change: transform; transform: translateY(calc(var(--k) * var(--ende, 128vh) * -1)); }
.baum-oben { position: absolute; left: 50%; top: 12vh; height: 58vh; width: min(96vw, 87vh); translate: -50% 0; overflow: visible; }
.baum-oben [pathLength] { fill: none; stroke-linecap: round; stroke-dasharray: 1; stroke: #7a5534; }
.baum-oben .stamm { stroke-width: 16; stroke-dashoffset: calc(1 - clamp(0, var(--wachs) / .45, 1)); }
.baum-oben .ast { stroke-width: 7; stroke-dashoffset: calc(1 - clamp(0, (var(--wachs) - .35) / .35, 1)); }
.baum-oben .ast.fein { stroke-width: 4; stroke-dashoffset: calc(1 - clamp(0, (var(--wachs) - .5) / .3, 1)); }
.baum-oben .krone { fill: rgba(63,191,90,.3); transform-box: fill-box; transform-origin: center; transform: scale(clamp(0, (var(--wachs) - .6) / .4, 1)); }
.boden-linie { position: absolute; left: 0; right: 0; top: 70vh; height: 2px; background: linear-gradient(90deg, transparent, #4a3a28 20%, #4a3a28 80%, transparent); }
.erde {
  position: absolute; left: 0; right: 0; top: 70vh; height: 180vh;
  background:
    radial-gradient(ellipse 60% 30% at 50% 0%, rgba(122,85,52,.18), transparent 70%),
    linear-gradient(180deg, #19120c, #110c08 45%, #07090c);
}
.wurzelwerk { position: absolute; left: 50%; top: 0; height: 170vh; width: min(100vw, 113vh); translate: -50% 0; overflow: visible; }
.wurzelwerk path { fill: none; stroke-linecap: round; stroke-dasharray: 1; }
/* Wachstum je Gruppe; die Linien erben stroke-dashoffset */
.wurzelwerk .stufe { stroke-dashoffset: calc(1 - clamp(0, (var(--k) - var(--t0)) / .1, 1)); }
.wurzelwerk .spitze { fill: var(--kupfer-hell); }
.wurzelwerk .spitzen { opacity: clamp(0, (var(--k) - var(--t0)) / .08, 1); }
/* Die Lichtpunkte werden erst berechnet, wenn der Satz in Reichweite ist */
.satz-licht { display: none; }
.wurzelwerk.nah .satz-licht { display: inline; }
.wurzelwerk .stein { fill: #1c150f; }
/* Der Satz aus Licht: Punkte wandern von den Wurzelspitzen an ihren Platz */
.satz-licht circle {
  --z: clamp(0, (var(--k) - .84 - var(--s)) / .1, 1);
  fill: var(--kupfer-hell);
  opacity: calc(var(--z) * .95 * (1 - var(--fest)));
  transform: translate(calc(var(--dx) * (1 - var(--z)) * 1px), calc(var(--dy) * (1 - var(--z)) * 1px));
}
.satz-fest {
  fill: var(--kupfer-hell); font-family: var(--schrift); font-weight: 700; letter-spacing: -.01em;
  opacity: var(--fest);
}
/* Leuchten erst, wenn der Satz steht — vorher würde es unsichtbar, aber teuer mitgerechnet */
.wurzelwerk.lebt .satz-fest { filter: drop-shadow(0 0 5px rgba(243, 192, 142, .45)); }
/* Ganz unten angekommen: die Spitzen leben — wie ein Netz, das feuert. Es pulsieren die fünf Gruppen,
   nicht 400 einzelne Punkte: sieht gleich aus, kostet einen Bruchteil. */
.wurzelwerk.lebt .spitzen { animation: puls 2.6s ease-in-out infinite; }
.wurzelwerk.lebt .spitzen:nth-of-type(2n) { animation-delay: -.9s; }
.wurzelwerk.lebt .spitzen:nth-of-type(3n) { animation-delay: -1.7s; }
@keyframes puls { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
/* Die Werte stehen in der Zeichnung selbst — dunkler Rand, damit sie über den Wurzeln lesbar bleiben */
.wert-svg {
  fill: var(--kupfer-hell); font-family: var(--schrift); font-weight: 700; letter-spacing: 0;
  /* Dunkler Rand hinter der Schrift, schmal genug, dass er auf dem Handy keine Buchstaben anfrisst */
  paint-order: stroke; stroke: rgba(17, 12, 8, .85); stroke-width: 3.5px; stroke-linejoin: round;
  opacity: clamp(0, (var(--k) - var(--ab)) / .08, 1);
}

/* ==========================================================================
   4 · KONTAKT — zwei Tropfen fallen in die Lücken von D·M·N
   ========================================================================== */
.finale .buehne {
  --fall: clamp(0, (var(--p) - 0.04) / 0.3, 1);
  --auf:  clamp(0, (var(--p) - 0.36) / 0.12, 1);
  --txt:  clamp(0, (var(--p) - 0.52) / 0.12, 1);
  --kn:   clamp(0, (var(--p) - 0.62) / 0.1, 1);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6vh;
  padding: 80px 16px 60px; background: radial-gradient(ellipse at 50% 45%, #111820, var(--bg) 70%);
}
.fluid.leise { opacity: .22; }
.name {
  position: relative; z-index: 2; display: flex; align-items: flex-end;
  font-size: clamp(4.5rem, 19vw, 15rem); font-weight: 900; letter-spacing: -0.06em; line-height: .9;
  text-shadow: 0 10px 60px rgba(0,0,0,.35);
}
.name .bs { background: linear-gradient(180deg, #fff 20%, #9aa39d); -webkit-background-clip: text; background-clip: text; color: transparent; }
.vokal { position: relative; display: inline-block; }
.vokal.zwei { --fall: clamp(0, (var(--p) - 0.1) / 0.3, 1); }
.vokal b {
  display: inline-block; overflow: hidden; vertical-align: bottom; max-width: calc(var(--auf) * .9em);
  background: linear-gradient(180deg, var(--kupfer-hell), var(--kupfer)); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.tropfen {
  position: absolute; left: 50%; top: 55%; width: .42em; height: .42em; margin: -.21em 0 0 -.21em; border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #ffd9b3, var(--kupfer) 55%, #a4532a);
  transform: translateY(calc((1 - var(--fall)) * -80vh)) scale(calc(1 - var(--auf) * .85));
  opacity: calc(1 - var(--auf));
}
.kontakt-text { position: relative; z-index: 2; text-align: center; }
.kontakt-text h2 { font-size: clamp(1.8rem, 4.4vw, 3.2rem); opacity: var(--txt); transform: translateY(calc((1 - var(--txt)) * 16px)); }
.knoepfe { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin-top: 1.6rem; opacity: var(--kn); transform: translateY(calc((1 - var(--kn)) * 16px)); }
.knopf {
  display: inline-block; text-decoration: none; font-weight: 700; padding: 15px 28px; border-radius: 999px;
  color: #1a0d05; background: linear-gradient(135deg, var(--kupfer-hell), var(--kupfer));
  box-shadow: 0 10px 30px rgba(217,132,74,.3); transition: transform .2s, box-shadow .2s;
}
.knopf:hover { transform: translateY(-2px); box-shadow: 0 16px 40px rgba(217,132,74,.5); }
.fuss {
  position: absolute; bottom: 18px; left: 16px; right: 16px; z-index: 4;
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; font-size: .85rem; color: var(--mute);
}
.fuss a { text-decoration: none; }
.fuss a:hover { color: var(--ink); }

/* ---------- Leistung ---------- */
/* Was nicht zu sehen ist, steht still: Szenen außerhalb des Bildes */
html.js .szene:not(.sichtbar) * { animation-play-state: paused !important; }
/* Auf dem Handy kostet der Glas-Effekt der Kopfleiste über bewegten Bildern spürbar Leistung */
@media (max-width: 700px) {
  .marke, .kopf nav { backdrop-filter: none; -webkit-backdrop-filter: none; background: rgba(10, 12, 15, .82); }
  .grain { display: none; }
}

/* ---------- Weniger Bewegung gewünscht ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .blob, .scroll-hinweis span::after, .dmn .buehne .netz, .wurzelwerk.lebt .spitzen { animation: none !important; }
  .rolle i { transition: none !important; }
}
