/* ============================================================
   TOLEVIA — Bewegung
   Alles hier ist an die Klasse .js gebunden: Ohne JavaScript ist
   die Seite vollständig sichtbar, nur eben ohne Animation.
   ============================================================ */

/* ---------- Weiche Seitenwechsel ----------
   Nativ im Browser, ohne Bibliothek. Wo es nicht unterstützt wird,
   verhält sich die Seite wie bisher — es geht nichts kaputt. */

@view-transition{navigation:auto}

::view-transition-old(root),
::view-transition-new(root){
  animation-duration:.42s;
  animation-timing-function:cubic-bezier(.23, 1, .32, 1);
}
/* Die kleine Wortmarke oben bleibt beim Wechsel stehen, statt mitzublenden */
.site-head .brand{view-transition-name:brand}

@media (prefers-reduced-motion: reduce){
  @view-transition{navigation:none}
}

/* ---------- Auftakt der Wortmarke ----------
   Die Buchstaben entstehen aus Unschärfe und Federgewicht. */

@keyframes mark-in{
  0%{
    opacity:0;
    filter:blur(18px);
    font-variation-settings:'wght' 400;
    transform:scale(1.06);
  }
  55%{opacity:1}
  100%{
    opacity:1;
    filter:blur(0);
    font-variation-settings:'wght' var(--mark-wght);
    transform:none;
  }
}

.js .mark .letter{
  opacity:0;
  animation:mark-in 1.2s var(--ease-out) both;
  animation-delay:calc(.2s + var(--i) * .07s);
}
/* Sobald das Script den Licht-Lauf übernimmt, muss die Auftakt-
   Animation weg — sonst hält ihr fill-mode das Gewicht fest. */
.js .mark.mark-done .letter{animation:none;opacity:1}

/* ---------- Der Satz ----------
   Die Worte erscheinen einzeln, während das Licht darüber läuft. */

.js .tagline .word{
  opacity:0;
  font-variation-settings:'wght' 400;
  transition:opacity .7s var(--ease-out), font-variation-settings .7s var(--ease-out);
}
.js .tagline .word.is-lit{
  opacity:1;
  font-variation-settings:'wght' 440;
}

/* Der Pinselstrich kommt zuletzt: ein einziger, zügiger Zug von links nach
   rechts, nachdem der Satz steht. Schnell ansetzen, sanft auslaufen —
   so bewegt sich eine Hand, die einen Strich zieht. */
.js .tagline .stroke{
  -webkit-clip-path:inset(0 100% 0 0);
  clip-path:inset(0 100% 0 0);
  transition:-webkit-clip-path .5s cubic-bezier(.2,.75,.25,1), clip-path .5s cubic-bezier(.2,.75,.25,1);
}
.js .tagline .stroke.is-lit{
  -webkit-clip-path:inset(0 -2% 0 0);
  clip-path:inset(0 -2% 0 0);
}

/* ---------- Große Aussagen ----------
   Die Worte gewinnen einzeln an Gewicht — dieselbe Sprache wie oben.
   Nichts rutscht, alles wird schwerer. */

.js .words .w{
  display:inline-block;
  opacity:0;
  font-variation-settings:'wght' 400;
  transition:opacity .9s var(--ease-out), font-variation-settings .9s var(--ease-out);
  transition-delay:calc(var(--i) * .05s);
}
.js .words.is-in .w{
  opacity:1;
  font-variation-settings:'wght' 500;
}

/* ---------- Fortschritt beim Scrollen ---------- */

.progress{
  position:fixed;
  top:0;left:0;
  height:2px;
  width:0;
  background:var(--ink);
  z-index:25;
  transition:width .12s linear;
  pointer-events:none;
}

/* ---------- Feines Korn ----------
   Nimmt der Fläche das Sterile. Als Filter eingebettet, keine Bilddatei. */

body::after{
  content:'';
  position:fixed;
  inset:0;
  z-index:4;
  pointer-events:none;
  opacity:.04;
  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='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- Einblenden beim Scrollen ---------- */

.js .reveal{
  opacity:0;
  transform:translateY(18px);
  transition:opacity .65s var(--ease-out), transform .65s var(--ease-out);
  transition-delay:var(--d, 0s);
}
.js .reveal.is-in{opacity:1;transform:none}

/* ---------- „Entgegenkommen" ----------
   Für einzelne Zeilen, die Gewicht haben sollen: Sie treten aus der Tiefe
   heran und werden dabei schwerer. Langsam und klein gehalten. */

.js .arrive{
  opacity:0;
  transform:scale(.965) translateY(12px);
  font-variation-settings:'wght' 400;
  transition:opacity 1s var(--ease-out), transform 1s var(--ease-out), font-variation-settings 1s var(--ease-out);
  transition-delay:var(--d, 0s);
}
.js .arrive.is-in{
  opacity:1;
  transform:none;
  font-variation-settings:'wght' 500;
}

/* ---------- Auftakt der übrigen Hero-Teile ---------- */

.js .intro{
  opacity:0;
  transform:translateY(14px);
  transition:opacity .7s var(--ease-out), transform .7s var(--ease-out);
  transition-delay:var(--d, 0s);
}
.js body.is-loaded .intro{opacity:1;transform:none}

/* ---------- Notbremse ----------
   Falls ein Script nicht lädt, wird nach 6 Sekunden alles sichtbar. */

.js.anim-fallback .tagline .word{opacity:1;font-variation-settings:'wght' 440}
.js.anim-fallback .reveal{opacity:1;transform:none}
.js.anim-fallback .arrive{opacity:1;transform:none;font-variation-settings:'wght' 500}
.js.anim-fallback .intro{opacity:1;transform:none}
.js.anim-fallback .mark .letter{opacity:1}
.js.anim-fallback .words .w{opacity:1;font-variation-settings:'wght' 500}
.js.anim-fallback .tagline .stroke{-webkit-clip-path:none;clip-path:none}

/* ---------- Bewegung reduziert ---------- */

@media (prefers-reduced-motion: reduce){
  .js .mark .letter{opacity:1 !important;animation:none !important;filter:none !important}
  .js .tagline .word{opacity:1 !important;font-variation-settings:'wght' 440 !important;transition:none !important}
  .js .tagline .stroke{-webkit-clip-path:none !important;clip-path:none !important;transition:none !important}
  .js .reveal,.js .intro,.js .arrive{opacity:1 !important;transform:none !important;transition:none !important}
  .js .arrive{font-variation-settings:'wght' 500 !important}
  .js .words .w{opacity:1 !important;font-variation-settings:'wght' 500 !important;transition:none !important}
  .mark{transform:none !important}
  .progress{display:none}
  body::after{display:none}
}
