/* ==========================================================================
   Scheffczyk Veranstaltungen — motion.css
   Leitidee „Der rote Faden": Bewegung folgt dem Scrollen des Besuchers,
   ruhig, präzise, nie im Vordergrund. Lesetext bleibt stehen.

   Prinzip: Scroll-Effekte lesen alle die Variable --p (0 → 1).
   - Browser mit Scroll-Timelines (Chrome, Edge, Safari 26+) animieren --p
     nativ über animation-timeline — kein JS im Scroll-Pfad.
   - Alle anderen bekommen --p von motion.js (rAF, nur sichtbare Elemente).
   [data-p] legt fest, worauf sich der Fortschritt bezieht:
     page   = ganze Seite          hero  = erste Bildschirmhöhe
     read   = Element läuft von 85 % auf 35 % Bildschirmhöhe
     cover  = Element betritt bis verlässt den Bildschirm
     center = Oberkante bis Unterkante passiert die Bildschirmmitte

   Alles hier greift nur mit aktivem JS (html.js) und ohne
   „Bewegung reduzieren" — sonst gilt der statische Zustand aus style.css.
   ========================================================================== */

@property --p {
  syntax: '<number>';
  inherits: true;
  initial-value: 0;
}

@keyframes p-progress {
  from { --p: 0; }
  to   { --p: 1; }
}

@media (prefers-reduced-motion: no-preference) {

  html { scroll-behavior: smooth; }

  /* ---------- 0) Fortschritt nativ treiben ---------- */
  @supports (animation-timeline: scroll()) {
    html.js [data-p] { animation: p-progress linear both; }
    html.js [data-p="page"]   { animation-timeline: scroll(root block); }
    html.js [data-p="hero"]   { animation-timeline: scroll(root block); animation-range: 0 100vh; }
    html.js [data-p="read"]   { animation-timeline: view(block); animation-range: cover 15vh cover 65vh; }
    html.js [data-p="cover"]  { animation-timeline: view(block); animation-range: cover 0% cover 100%; }
    html.js [data-p="center"] { animation-timeline: view(block); animation-range: cover 50vh cover calc(100% - 50vh); }
  }

  /* ---------- 1) Einblenden, Redline, Headline-Masken ---------- */
  html.js .reveal {
    opacity: 0;
    transform: translateY(26px);
    transition: opacity .8s var(--ease), transform .8s var(--ease);
  }
  html.js .reveal.is-visible { opacity: 1; transform: none; }
  html.js .reveal[data-delay="1"] { transition-delay: .12s; }
  html.js .reveal[data-delay="2"] { transition-delay: .24s; }
  html.js .reveal[data-delay="3"] { transition-delay: .36s; }
  html.js .reveal[data-delay="4"] { transition-delay: .48s; }

  html.js .redline {
    transform: scaleX(0);
    transition: transform 1.1s var(--ease-out) .15s;
  }
  html.js .redline.is-visible { transform: scaleX(1); }

  /* Zeilen gleiten aus einer unsichtbaren Maske nach oben */
  html.js .split .line {
    overflow: clip;
    padding-bottom: .12em;
    margin-bottom: -.12em;
  }
  html.js .split .line > span {
    display: inline-block;
    transform: translateY(112%);
    transition: transform 1s var(--ease-out);
  }
  html.js .split .line:nth-child(2) > span { transition-delay: .1s; }
  html.js .split .line:nth-child(3) > span { transition-delay: .2s; }
  html.js .split.is-visible .line > span { transform: none; }

  /* ---------- 2) Header: Lesefortschritt als Redline ---------- */
  html.js .site-header::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: -1px;
    height: 2px;
    background: var(--red);
    transform: scaleX(var(--p));
    transform-origin: left center;
    pointer-events: none;
  }

  /* Mobile Navigation klappt auf statt zu springen */
  @media (max-width: 820px) {
    html.js .site-nav.is-open { animation: nav-in .45s var(--ease-out) both; }
    html.js .site-nav.is-open a { animation: nav-item .5s var(--ease-out) both; }
    html.js .site-nav.is-open a:nth-child(2) { animation-delay: .05s; }
    html.js .site-nav.is-open a:nth-child(3) { animation-delay: .1s; }
  }
  @keyframes nav-in   { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0); } }
  @keyframes nav-item { from { opacity: 0; transform: translateY(-8px); } }

  /* ---------- 3) Hero: drei Tiefenebenen ---------- */
  /* translate = Scroll-Parallax, transform = Zeiger-Parallax (motion.js);
     beide Eigenschaften addieren sich, ohne sich zu stören. */
  html.js .hero-depth > * { will-change: transform, translate; }
  html.js .hero-grid {
    translate: 0 calc(var(--p) * 240px);
    transform: translate3d(calc(var(--mx, 0) * -8px), calc(var(--my, 0) * -8px), 0);
  }
  html.js .hero-ghost {
    translate: 0 calc(var(--p) * 150px);
    transform: translate3d(calc(var(--mx, 0) * -18px), calc(var(--my, 0) * -12px), 0);
  }
  html.js .hero-mark {
    translate: 0 calc(var(--p) * 70px);
    transform: translate3d(calc(var(--mx, 0) * -30px), calc(var(--my, 0) * -20px), 0);
  }
  @media (max-width: 820px) {
    html.js .hero-grid  { translate: 0 calc(var(--p) * 120px); }
    html.js .hero-ghost { translate: 0 calc(var(--p) * 70px); }
    html.js .hero-mark  { translate: 0 calc(var(--p) * 40px); }
  }

  /* Monogramm zeichnet sich beim Laden — der rote Bogen zuletzt */
  html.js .hero-mark path,
  html.js .photo-slot .slot-mark path {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    animation: draw 2.6s var(--ease-out) forwards;
  }
  html.js .hero-mark path:nth-of-type(1) { animation-delay: .35s; }
  html.js .hero-mark path:nth-of-type(3) { animation-delay: .7s; }
  html.js .hero-mark path.r { animation-delay: 1.25s; animation-duration: 2.2s; }
  @keyframes draw { to { stroke-dashoffset: 0; } }

  /* Platzhalter: Kontur zeichnet sich, dann füllt sich die Fläche */
  html.js .photo-slot .slot-mark path {
    fill: transparent;
    stroke: #CFCFCF;
    stroke-width: .5;
    animation-play-state: paused;
    transition: fill 1.2s var(--ease) 1.6s;
  }
  html.js .photo-slot.is-visible .slot-mark path { animation-play-state: running; fill: #E6E6E6; }
  html.js .photo-slot .slot-mark path.r { animation-delay: .5s; }

  /* ---------- 4) Wertschöpfungskette (Startseite) ---------- */
  html.js .chain .tile:nth-child(1) { --i: 0; }
  html.js .chain .tile:nth-child(2) { --i: 1; }
  html.js .chain .tile:nth-child(3) { --i: 2; }
  html.js .chain .tile:nth-child(4) { --i: 3; }
  @media (min-width: 1100px) {
    html.js .chain::after { transform: scaleX(var(--p)); }
    /* Marker füllt sich rot, sobald die Linie ihn erreicht */
    html.js .chain .tile {
      --on: clamp(0, calc((var(--p) * 4 - var(--i) - .06) * 12), 1);
    }
    html.js .chain .tile::after {
      box-shadow: inset 0 0 0 calc(var(--on) * 5px) var(--red), inset 0 0 0 2px var(--black);
    }
    html.js .chain .big-num { opacity: calc(.25 + var(--on) * .75); }
  }

  /* ---------- 5) Prozess-Faden 01 → 04 (Leistungen) ---------- */
  html.js .services { padding-left: clamp(28px, 4vw, 48px); }
  html.js .services::before,
  html.js .services::after {
    content: '';
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 1px;
    background: var(--grey-line);
  }
  html.js .services::after {
    width: 2px;
    left: -.5px;
    background: var(--black);
    transform: scaleY(var(--p));
    transform-origin: top center;
  }
  html.js .service:nth-child(1) { --i: 0; }
  html.js .service:nth-child(2) { --i: 1; }
  html.js .service:nth-child(3) { --i: 2; }
  html.js .service:nth-child(4) { --i: 3; }
  html.js .service .big-num {
    opacity: clamp(.2, calc((var(--p) * 4 - var(--i)) * 3 + .2), 1);
    transform: translateX(calc((1 - clamp(0, (var(--p) * 4 - var(--i)) * 3, 1)) * -10px));
  }

  /* ---------- 6) Formate-Band: wandert mit dem Scrollen ---------- */
  html.js .formats-track {
    flex-wrap: nowrap;
    width: max-content;
    translate: calc(var(--p) * var(--shift, 0px) * -1) 0;
    will-change: translate;
  }
  /* zweite Zeile läuft gegenläufig */
  html.js .formats-track--reverse {
    translate: calc((var(--p) - 1) * var(--shift, 0px)) 0;
  }

  /* ---------- 7) Kennzahlen: Trennlinien wachsen mit ---------- */
  html.js .stat.reveal::before {
    transform: scaleY(0);
    transition: transform 1.3s var(--ease-out) .25s;
  }
  html.js .stat.reveal.is-visible::before { transform: scaleY(1); }

  /* ---------- 8) Statement: Wort für Wort ins Licht ---------- */
  html.js .illuminate .w {
    opacity: clamp(.18, calc(var(--p) * (var(--n) + 4) - var(--i)), 1);
  }

  /* ---------- 9) Foto-Flächen öffnen sich ---------- */
  html.js .photo-slot.reveal {
    opacity: 1;
    transform: none;
    clip-path: inset(100% 0 0 0);
    transition: clip-path 1.3s var(--ease-out);
  }
  html.js .photo-slot.reveal.is-visible { clip-path: inset(0); }
  html.js .photo-slot > img {
    scale: 1.08;
    transition: scale 1.8s var(--ease-out);
  }
  html.js .photo-slot.is-visible > img { scale: 1; }

  /* ---------- 10) Zeiger-Effekte (nur Maus/Trackpad) ---------- */
  @media (hover: hover) and (pointer: fine) {
    /* Lichtkante: Der Rahmen glimmt dort, wo der Zeiger ist */
    html.js .tile::before,
    html.js .value-card::before {
      content: '';
      position: absolute;
      inset: -1px;
      padding: 1px;
      background: radial-gradient(240px circle at var(--x) var(--y), var(--red), transparent 70%);
      -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
      -webkit-mask-composite: xor;
              mask-composite: exclude;
      opacity: 0;
      transition: opacity .4s var(--ease);
      pointer-events: none;
    }
    html.js .tile:hover::before,
    html.js .value-card:hover::before { opacity: 1; }
  }

  /* ---------- 11) Seitenwechsel (View Transitions, Cross-Document) ---------- */
  @view-transition { navigation: auto; }
  .site-header { view-transition-name: site-header; }
  ::view-transition-group(site-header) { animation: none; }
  ::view-transition-old(root) { animation: vt-out .28s var(--ease) both; }
  ::view-transition-new(root) { animation: vt-in .55s var(--ease-out) both; }
  @keyframes vt-out { to   { opacity: 0; transform: translateY(-10px); } }
  @keyframes vt-in  { from { opacity: 0; transform: translateY(14px); } }
}

/* ==========================================================================
   Tiefe: Ebenen, die übereinander gleiten
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {

  /* ---------- 12) Hero bleibt stehen, die Seite schiebt sich darüber ---------- */
  @media (min-height: 560px) {
    /* --stick-top setzt motion.js: Header-Höhe, oder negativ, falls der Hero
       höher als der Bildschirm ist (dann haftet er erst mit seiner Unterkante) */
    html.js .hero--stack {
      position: sticky;
      top: var(--stick-top, var(--header-h));
      z-index: 0;
    }
    /* der Inhalt weicht zurück, das Licht wird gedimmt */
    html.js .hero--stack > .wrap {
      scale: calc(1 - var(--p) * .06);
      translate: 0 calc(var(--p) * -30px);
      transform-origin: 30% 100%;
    }
    html.js .hero--stack::after {
      content: '';
      position: absolute;
      inset: 0;
      z-index: 1;
      background: var(--black);
      opacity: calc(var(--p) * .45);
      pointer-events: none;
    }
    /* im stehenden Hero bewegen sich nahe Ebenen schneller als ferne */
    html.js .hero--stack .hero-grid  { translate: 0 calc(var(--p) * -30px); }
    html.js .hero--stack .hero-ghost { translate: 0 calc(var(--p) * -90px); }
    html.js .hero--stack .hero-mark  { translate: 0 calc(var(--p) * -160px); }

    /* alles danach liegt eine Ebene höher und wirft einen Schatten nach oben */
    :where(html.js .hero--stack ~ *) {
      position: relative;
      z-index: 1;
      background-color: var(--white);
    }
    html.js .hero--stack + * { box-shadow: 0 -24px 60px rgba(0,0,0,.22); }
  }

  /* ---------- 13) Footer wird wie hinter einem Vorhang freigelegt ---------- */
  @media (min-height: 640px) {
    html.js main {
      position: relative;
      z-index: 1;
      background: var(--white);
      box-shadow: 0 30px 70px rgba(0,0,0,.6);
    }
    /* feine Lichtkante an der Unterseite der Inhaltsebene */
    html.js main::after {
      content: '';
      position: absolute;
      left: 0; right: 0; bottom: 0;
      height: 1px;
      background: rgba(255,255,255,.08);
      pointer-events: none;
    }
    html.js .site-footer {
      position: sticky;
      bottom: 0;
      z-index: 0;
    }
  }

  /* ---------- 14) Porträt: Rahmen und Bild auf zwei Tiefen ---------- */
  html.js .photo-wrap::before { translate: 0 calc((var(--p) - .5) * 70px); }
  html.js .photo-wrap .photo-slot { translate: 0 calc((var(--p) - .5) * -24px); }

  /* ---------- 15) Karten kippen leicht zum Zeiger, Inhalt schwebt darüber ---------- */
  @media (hover: hover) and (pointer: fine) {
    /* .is-visible erhöht die Spezifität über die Einblende-Regel (.reveal.is-visible) */
    html.js .tile.is-visible,
    html.js .value-card.is-visible {
      transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(var(--lift, 0px));
      transform-style: preserve-3d;
      transition: opacity .8s var(--ease), transform .6s var(--ease-out), box-shadow .45s var(--ease), border-color .35s var(--ease);
    }
    html.js .tile:not(.reveal),
    html.js .value-card:not(.reveal) { transform-style: preserve-3d; }
    html.js .tile.is-visible:hover,
    html.js .value-card.is-visible:hover {
      --lift: -6px;
      transform: perspective(1000px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(var(--lift));
    }
    html.js .tile .big-num,
    html.js .value-card .big-num { transform: translateZ(34px); }
    html.js .tile h3,
    html.js .value-card h3 { transform: translateZ(18px); }
  }
}
