/* =========================================================
   MOTION – wie die Seite entsteht

   Eine einzige Idee, konsequent: DIE LINIEN ZEICHNEN SICH.
   Nichts fliegt ein, nichts skaliert auf, kein Textblock blendet
   von unten herein. Der Grund steht im Entwurf selbst – das Logo
   ist eine Strichzeichnung der Villa, eine 1px-Vertikale hält die
   ganze Seite zusammen, jede Karte endet auf einer Linie, jeder
   Button ist eine Kontur. Bewegt sich nur das, ist die Seite in
   Bewegung, ohne unruhig zu werden: 1px trägt keine Lautstärke.

   Hover-Effekte stehen NICHT hier, sondern beim jeweiligen
   Bauteil (components.css) – dort gehören sie hin. Hier steht
   ausschließlich, was beim Laden und beim Scrollen passiert.

   Ohne JavaScript passiert nichts davon: die Ausgangszustände
   hängen an .js-reveal, das ein Einzeiler im <head> setzt. Fällt
   das Skript aus, steht die Seite fertig da statt leer.
   ========================================================= */

/* =========================================================
   1. LADEN – die Bühne baut sich auf
   Die Spine zieht sich durch den Hero, dann folgen Headline,
   Unterzeile und Buttons. Sie blenden nur auf, sie verschieben
   sich nicht: eine Titelzeile, die von unten hereinrutscht,
   ist die Geste jeder beliebigen Website, keine dieser.
   ========================================================= */
.js-reveal .rule--hero {
  transform: scaleY(0);
  transform-origin: 50% 0;
}
.js-reveal .hero__title,
.js-reveal .hero__sub,
.js-reveal .hero__actions { opacity: 0; }

.is-loaded .rule--hero {
  transform: scaleY(1);
  transition: transform var(--t-draw) var(--ease);
}
.is-loaded .hero__title,
.is-loaded .hero__sub,
.is-loaded .hero__actions {
  opacity: 1;
  transition: opacity var(--t-slow) var(--ease);
}
/* Der Versatz ist die Reihenfolge, in der man liest. */
.is-loaded .hero__title   { transition-delay: .25s; }
.is-loaded .hero__sub     { transition-delay: .45s; }
.is-loaded .hero__actions { transition-delay: .65s; }

/* =========================================================
   2. SCROLLEN – jede Linie zeichnet sich, wenn sie ins Bild kommt
   Das Skript setzt .is-in, sobald ein Abschnitt den unteren
   Rand des Fensters erreicht.
   ========================================================= */

/* Senkrechte Abschnitte der Spine: von oben nach unten, in der
   Richtung, in der man scrollt. Die langen Abschnitte laufen
   länger – sonst schießt die Linie dem Blick davon. */
.js-reveal .rule--lead,
.js-reveal .rule--grid,
.js-reveal .rule--exp,
.js-reveal .intro__text::before {
  transform: scaleY(0);
  transform-origin: 50% 0;
}
.rule--lead.is-in,
.rule--grid.is-in,
.rule--exp.is-in,
.intro__text.is-in::before {
  transform: scaleY(1);
  transition: transform var(--t-draw) var(--ease);
}
/* Der kurze Anlauf über der Headline ist nur 112 lang – er
   braucht die lange Dauer nicht. */
.rule--lead.is-in { transition-duration: var(--t-slow); }

/* Waagerechte über dem Ärztebild: von der Seitenkante her, also
   aus derselben Richtung, aus der sie im Entwurf kommt. */
.js-reveal .exp__edge {
  transform: scaleX(0);
  transform-origin: 0 50%;
}
.exp__edge.is-in {
  transform: scaleX(1);
  transition: transform var(--t-draw) var(--ease);
}

/* Kartenlinien: von links, Spalte für Spalte. Der Versatz ist
   klein genug, dass man ihn nicht zählt, aber groß genug, dass
   die Reihe als Reihe gelesen wird. clip-path statt transform –
   die Linie trägt im ::after schon die Hover-Füllung, ein
   transform am Elternteil würde sie mitverzerren. */
.js-reveal .card__line { clip-path: inset(0 100% 0 0); }
.card__line.is-in {
  clip-path: inset(0);
  transition: clip-path var(--t-slow) var(--ease);
}
/* Spalte für Spalte, links nach rechts. Achtung: der .rule--grid-Span
   ist das ERSTE Grid-Kind, die Karten sind also die Kinder 2..10 –
   Spalte 1 = 3n+2 (kein Versatz), Spalte 2 = 3n, Spalte 3 = 3n+1. */
.focus__grid .card:nth-child(3n)   .card__line.is-in { transition-delay: .09s; }
.focus__grid .card:nth-child(3n+1) .card__line.is-in { transition-delay: .18s; }

/* Unter 1100px liegt die Trennlinie des Intros waagerecht über
   dem Text (siehe responsive.css) – sie zeichnet sich dann auch
   waagerecht, sonst blitzt sie nur auf. */
@media (max-width: 1100px) {
  .js-reveal .intro__text::before {
    transform: scaleX(0);
    transform-origin: 0 50%;
  }
  .intro__text.is-in::before { transform: scaleX(1); }
}

/* =========================================================
   3. WER NICHT ANIMIERT WERDEN WILL
   base.css kürzt bereits alle Dauern auf ~0. Damit die Elemente
   dann nicht in ihrem Ausgangszustand einfrieren, werden die
   Ausgangszustände hier ganz aufgehoben.
   ========================================================= */
@media (prefers-reduced-motion: reduce) {
  .js-reveal .rule--hero,
  .js-reveal .rule--lead,
  .js-reveal .rule--grid,
  .js-reveal .rule--exp,
  .js-reveal .intro__text::before,
  .js-reveal .exp__edge { transform: none; }
  .js-reveal .card__line { clip-path: none; }
  .js-reveal .hero__title,
  .js-reveal .hero__sub,
  .js-reveal .hero__actions { opacity: 1; }
}
