/* =========================================================================
   Joel Sidler — Home
   Ergänzt css/style.css. Layout, dazu zwei Blöcke, die es nur hier gibt:
   die Drei-Akt-Grafik »Mein Weg« (.weg, Abschnitt 2) und die
   Schwerpunkte-Karten (.tafeln, Abschnitt 3). Beide bleiben seitenlokal —
   keiner von beiden wandert ins Fundament, solange er auf genau einer Seite
   steht.
   Der Hero selbst (.hero, .hero__media, .hero__inner,
   .hero__actions) ist eine Komponente aus style.css (Abschnitt 4.13)
   und wird hier nicht neu definiert.
   ========================================================================= */

/* ---------- 1. Hero — Layout-Detail, das style.css offen lässt ------------ */

/* Pill-Label dient hier als Kampagnen-Kicker: hidden im Markup, wird erst
   per JS befüllt und sichtbar (siehe js/main.js). */
.hero__inner .pill[hidden] { display: none; }

/* Grid-Items bekommen ohne min-inline-size: 0 eine automatische
   Mindestbreite in Höhe ihres min-content — zur Sicherheit gegen die
   langen Wörter im h1 (»UNTERSTÜTZEN«) auf schmalen Viewports. */
.hero__inner > * {
  min-inline-size: 0;
}

/* ---------- 2. Mein Weg — Kartenreise »Vom Ort zur Idee« -------------------
   Ersetzt die Drei-Akt-Grafik auf der Schiene. Dieselben drei Akte, dieselben
   Stationen, neue Inszenierung: links (auf dem Telefon oben) bleibt eine
   Karte stehen, rechts laufen die Akte an ihr vorbei, und die Karte zoomt
   mit jedem Akt eine Ebene heraus — Affoltern am Albis, Knonaueramt,
   Kanton Zürich.

   ZWEI FASSUNGEN, und das ist der Kern dieses Abschnitts:

     kompakt   Was hier in Abschnitt 2 steht. Karte oben, Akte darunter,
               normale Höhen, kein Kleben, kein Zoom. Das sieht jeder
               Browser ohne Scroll-Timelines und jeder, der weniger Bewegung
               eingestellt hat. Die Karte steht dann auf der Kantonsansicht
               mit hervorgehobenem Bezirk — dem Endbild der Reise.
     Reise     Abschnitt 2b. Erst dort werden die Akte bildschirmhoch, erst
               dort klebt die Bühne, erst dort zoomt die Karte. Die grossen
               Höhen stehen bewusst NICHT hier: eine Sektion, die vier
               Bildschirme hoch ist, aber nichts animiert, wäre nur lang.

   Die Karte selbst ist Beiwerk (aria-hidden im Markup) — alles, was sie
   zeigt, steht daneben als Text. Kartengrundlage: OpenStreetMap, ODbL,
   siehe Kommentar in index.html und Impressum.
   ------------------------------------------------------------------------ */

.weg__intro { max-inline-size: var(--measure); margin-block-end: var(--space-l); }

.weg {
  --marke-y: 0.8rem;
  position: relative;
  display: grid;
  gap: var(--space-l);
  margin-block-end: var(--space-l);
}

/* ---- Die Bühne mit der Karte ----
   Ohne Grund und ohne Unterkante: die Karte schwebt frei auf der Seite.
   Ein weisser Grund mit Linie las sich auf dem Telefon als Block, der den
   Text hart abschnitt. Dass der Text dort nicht durch die Karte läuft,
   regelt jetzt die Reise-Fassung (Abschnitt 2b, akt-aufloesen). */

/* Quadratisches Kartenfenster. Vorher hatte es das Seitenverhältnis der
   Kantons-Bounding-Box, also hochkant — darin verhungerte die querliegende
   Schweiz auf halber Höhe. Im Quadrat füllt der Kanton die Höhe und die
   Schweiz die Breite, beide bis auf 6 % Rand.
   Breitengetrieben (inline-size: 100%, Höhe aus aspect-ratio), damit das
   Fenster nie breiter wird als seine Spalte. Kein overflow: visible: die
   Karte ist ein Kartenfenster, und unter dem Zoom malte sie sonst über die
   Seite hinaus und zog eine waagrechte Bildlaufleiste auf. */
.karte {
  display: block;
  inline-size: 100%;
  aspect-ratio: 1;
}

/* Kartenebenen. Alle Striche mit vector-effect: non-scaling-stroke — sonst
   würde eine 4.5-fach gezoomte Grenze zum Balken. */
.karte__schweiz, .karte__kanton, .karte__bezirk {
  vector-effect: non-scaling-stroke;
}
.karte__schweiz, .karte__kanton, .karte__bezirk {
  fill: var(--cyan-soft);
  stroke: var(--cyan);
  stroke-width: 2;
  stroke-linejoin: round;
}
/* Der Ort: ein Punkt, kein Umriss. Die Gruppe darum skaliert gegen den
   Zoom (siehe Abschnitt 2b), der Punkt bleibt darum auf jeder Stufe gleich
   gross. */
.karte__marke { fill: var(--blue-deep); stroke: var(--paper); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
/* Der Pulsring gehört zur Bewegung und existiert nur in der Reise-Fassung. */
.karte__puls { display: none; }

/* ---- Die Akte an der senkrechten Spur ---- */

.weg__akte {
  position: relative;
  list-style: none; margin: 0; padding: 0;
  padding-inline-start: calc(var(--space-m) + 2px);
  display: grid; gap: var(--space-l);
}
/* Die Spur: graue Linie über die ganze Höhe der Akte. In der Reise-Fassung
   bekommt sie darüber eine cyane Füllung (::after), die mit dem Scrollen
   wächst. */
.weg__akte::before {
  content: "";
  position: absolute;
  inset-block: var(--marke-y) 0;
  inset-inline-start: 5px;
  inline-size: 2px;
  background: var(--line);
}

.akt { position: relative; }

/* Die Marke sitzt auf der Spur, auf Höhe der ersten Textzeile. */
.akt::before {
  content: "";
  position: absolute;
  inset-block-start: calc(var(--marke-y) - 6px);
  inset-inline-start: calc((var(--space-m) + 2px) * -1);
  inline-size: 12px; block-size: 12px;
  background: var(--blue-deep);
  outline: 4px solid var(--paper);
}
.akt--jetzt::before { background: var(--cyan); }

.akt__ort {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--step-2);
  line-height: 1.05;
  letter-spacing: -0.015em;
  color: var(--blue-deep);
  hyphens: auto; overflow-wrap: break-word;
}
.akt__satz {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-0);
  margin-block-start: 0.2em;
}
.akt__text {
  color: var(--ink-mute);
  margin-block-start: 0.4em;
}
/* Die globale Regel gibt jedem p die Satzbreite --measure. Im Akt bestimmt
   die Spalte die Breite, nicht der Text. */
.akt p { max-inline-size: none; }

.akt__stationen {
  list-style: none; margin: var(--space-s) 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--space-s);
}
/* Chip: die konkrete Station als kleiner Beleg unter dem Akt. Kante statt
   Fläche — die Akte tragen die Farbe, die Stationen sind die Fussnote. */
.akt__station {
  display: inline-flex; align-items: baseline; gap: 0.5em;
  padding: 0.35em 0.7em;
  border: 1px solid var(--line);
  background: var(--paper);
  font-size: var(--step--1);
  color: var(--ink-mute);
}
.akt__jahr {
  font-family: var(--font-display); font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
  color: var(--blue-deep);
}

.weg__ziel {
  /* Das Ziel ist ein p und erbt sonst die globale Satzbreite --measure. */
  max-inline-size: none;
  /* #weg hat absichtlich keinen Bodenabstand (Abschnitt 6: die Cyan-Fläche
     der Schwerpunkte soll direkt anschliessen). Der Knopf ist das letzte
     Element davor und lag dadurch auf der Naht — er trägt seinen Abstand
     darum selbst. Nicht durch padding an #weg ersetzen, das bringt die
     doppelte --space-xl-Naht zurück. */
  margin-block-end: var(--space-l);
}

/* Ab 820 px steht die Karte neben den Akten statt über ihnen. */
@media (min-width: 820px) {
  .weg {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-xl);
    align-items: start;
  }
  /* Die Karte bekommt die halbe Breite statt 0.85 Teile: quadratisch
     ist sie höher als vorher, und die Akte brauchen keine 1.15. */
  .karte { max-block-size: 68vh; }
  .weg__ziel { display: flex; justify-content: flex-end; }
}

/* ---------- 2b. Die Reise — Karte, Kleben, Zoom ----------------------------
   Hier erst wird aus dem kompakten Abschnitt die Reise. Alles in diesem
   Block — auch die Layout-Teile — steht in @supports UND in
   prefers-reduced-motion: no-preference. Das ist Absicht und keine
   Schlamperei: die bildschirmhohen Akte und die klebende Bühne existieren
   nur, um den Zoom zu tragen. Wo der Zoom nicht läuft, wären sie bloss ein
   Abschnitt, durch den man vier Bildschirme lang scrollt, ohne dass etwas
   passiert. Ohne Scroll-Timelines und bei reduzierter Bewegung bleibt darum
   die kompakte Fassung aus Abschnitt 2 stehen.

   DIE DREI EBENEN, an den Scrollfortschritt gekoppelt:

     0–14 %    Knonaueramt. Der Bezirk formatfüllend, Affoltern am Albis
               als Punkt darauf, ein ruhiger Puls darum.
     14–44 %   Fahrt hinaus. Das Knonaueramt blendet weg, der Kanton auf.
     44–56 %   Kanton Zürich.
     56–86 %   Fahrt hinaus. Der Kanton blendet weg, das Land auf.
     86–100 %  Schweiz.

   Die Fahrten haben je 30 % der Strecke, die Plateaus 14/12/14. Vorher
   waren es 20 % Fahrt auf 20 % Plateau — das war zu hastig, die Karte
   sprang eher um, als dass sie fuhr.

   DIE PLATEAUS SIND DER PUNKT, nicht Bequemlichkeit beim Schreiben der
   Keyframes. Eine durchlaufende Fahrt trifft jede Stufe nur für einen
   Augenblick — wer bei »Kanton Zürich« ankommt, sieht dann schon wieder
   etwas dazwischen. Jede Stufe hat darum ein Fünftel der Strecke, auf dem
   sich gar nichts bewegt, und die liegen dort, wo der zugehörige Akt in
   der Fenstermitte steht (bei contain 0 %, 50 % und 100 %). Wer die
   Zeitpunkte verschiebt, verschiebt beide Listen mit: karte-zoomen und
   ort-gegenhalten teilen sie sich.

   Der dritte Akt bekommt bewusst KEINE eigene Kartenebene: der Sitz der
   Arclumina AG ist hier nicht hinterlegt, und Erfinden ist bei einem
   Lebenslauf keine gestalterische Freiheit. Stattdessen tritt die Karte
   zurück (sie blendet auf ein Drittel ab), und der Akt übernimmt allein.
   Das ist auch die stärkere Lesart: die ersten zwei Schritte sind Orte, der
   dritte ist ein Entscheid.

   TIMELINE: benannte View-Timeline --reise auf .weg, Bereich »contain«.
   contain ist bei einem Element, das höher ist als das Fenster, genau die
   Strecke, auf der es das Fenster vollständig füllt — also exakt die Zeit,
   in der die Bühne klebt. entry/exit wären hier falsch: die liegen vor und
   nach dem Kleben.

   Die Akte takten sich dagegen jeder für sich über view() — jeder Akt weiss
   selbst, wo er im Fenster steht, und blendet auf, wenn er in die Lesezone
   kommt. Das ist robuster, als drei feste Abschnitte einer gemeinsamen
   Timeline zuzuteilen, und hält auf jeder Fensterhöhe.
   -------------------------------------------------------------------------- */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {

    .weg { view-timeline-name: --reise; }

    /* Die Bühne klebt unter der Navigationsleiste. */
    .weg__buehne {
      position: sticky;
      inset-block-start: calc(var(--nav-h) + var(--space-s));
      z-index: 1;
    }

    /* Jeder Akt bekommt eine Bildschirmhöhe und steht mittig darin: so ist
       immer genau einer in der Lesezone, und die Karte hat Strecke zum
       Zoomen. */
    .akt {
      min-block-size: 78vh;
      display: flex;
      flex-direction: column;
      justify-content: center;
    }
    /* Die Marke rutscht mit dem Text in die Mitte des hohen Kastens. */
    .akt::before { inset-block-start: calc(50% - 6px); }

    /* ---- Die Karte ---- */

    /* Weiche Fensterkante. Während der Fahrt ist die nächste Ebene grösser
       als das Kartenfenster, und das SVG schnitt ihre Fläche als hartes
       Quadrat ab — ein hellblauer Block, wo die Bühne keinen mehr hat. Die
       Maske blendet die äusseren 6 % aus — aber NUR WÄHREND DER FAHRT. Auf
       den Plateaus füllen die Ebenen das Fenster bis auf 2 % und würden
       von einer festen Blende angeschnitten (so war es zuerst: der
       Bezirk verblasste oben und unten). karte-rand zieht die Maske darum
       auf den Plateaus auf 130 % auf, ihr Verlauf liegt dann ausserhalb
       des Fensters und wirkt nicht. */
    .karte {
      mask-image:
        linear-gradient(to right, transparent, #000 6%, #000 94%, transparent),
        linear-gradient(to bottom, transparent, #000 6%, #000 94%, transparent);
      mask-composite: intersect;
      mask-position: center;
      mask-repeat: no-repeat;
      animation-name: karte-rand;
      animation-timing-function: linear;
      animation-fill-mode: both;
      animation-timeline: --reise;
      animation-range: contain 0% contain 100%;
    }
    @keyframes karte-rand {
      0%,  14%, 44%, 56%, 86%, 100% { mask-size: 130% 100%, 100% 130%; }
      22%, 38%, 64%, 80%            { mask-size: 100% 100%, 100% 100%; }
    }

    .karte__zoom {
      will-change: transform;
      transform-box: view-box;
      transform-origin: 0 0;
      animation-name: karte-zoomen;
      /* Beidseitig weich (ease-in-out), nicht var(--ease): das ist eine
         Ease-out-Kurve und riss die Fahrt vom Plateau weg los. Die Fahrt
         beginnt und endet im Stillstand, also muss sie beides weich tun.
         ACHTUNG: ort-gegenhalten fährt dieselbe Kurve und dieselben
         Zeitpunkte — sonst driftet der Punkt mitten in der Fahrt. */
      animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
      animation-fill-mode: both;
      animation-timeline: --reise;
      animation-range: contain 0% contain 100%;
    }
    @keyframes karte-zoomen {
      /* Jede Ebene füllt das Fenster bis auf 2 % Rand — auf den Plateaus
         blendet die Fensterkante nichts aus (karte-rand), der Platz gehört
         also den Formen. Werte aus getBBox(): Mitte der Box auf 500/500,
         längste Seite auf 960 Einheiten. */
      0%, 14%   { transform: translate(-62.5px, -2209.8px) scale(2.7858); }
      /* Der Kanton steht etwas tiefer als geometrisch mittig: seine Masse
         liegt im breiten Norden, der schmale Süden zieht den optischen
         Schwerpunkt nach oben. 10 Einheiten nach unten gleichen das aus,
         mehr lässt der knappe Rand nicht zu (daher 950 statt 960). */
      44%, 56%  { transform: translate(123.1px, 34.8px) scale(0.7538); }
      86%, 100% { transform: translate(528.3px, 224.4px) scale(0.1327); }
    }

    /* EINE UMRUNDUNG ZUR ZEIT. Jede Stufe hat genau ein Gebiet um den
       Punkt, das vorherige ist dann weg: Knonaueramt, dann Kanton, dann
       Land. Sie lösen sich während der Fahrt gegenseitig ab, und genau in
       diesem Moment sind beide halb da — das ist das Bild vom Kreis, der
       grösser wird. Drei gestapelte Umrisse gleichzeitig wären wieder eine
       Karte mit Ebenen, und die Frage »wo bin ich gerade« beantwortet sich
       dann nicht mehr von selbst.

       JE EIN DURCHGEHENDER VERLAUF ÜBER DIE GANZE STRECKE, nicht zwei
       kurze Animationen pro Element. Der Kanton hatte hier eine Zeit lang
       »auf« und »ab« als zwei Einträge mit eigenen Bereichen — und war
       dadurch von Anfang an sichtbar: bei animation-fill-mode: both hält
       auch die zweite Animation ausserhalb ihres Bereichs ihren
       Startwert (opacity: 1), und die spätere gewinnt. Zwei Animationen
       auf derselben Eigenschaft überschreiben sich, sie addieren sich
       nicht. Ein Keyframe-Satz mit Halteplateaus löst das ohne Sonderfall.

       Die Zeitpunkte spiegeln sich: erste Ablösung 12–46 %, zweite
       56–90 %. Beide Übergänge sehen damit gleich aus.

       Die Blenden sind absichtlich LÄNGER als die Fahrt (20–40 % bzw.
       60–80 %) und laufen ins Plateau hinein nach: die neue Umrundung
       kommt noch an, während die Karte schon steht. Kurze Blenden genau
       auf der Fahrt lasen sich als Schnitt mitten in der Bewegung — zwei
       Ereignisse gleichzeitig. So ist es eine durchgehende Bewegung mit
       einem ruhigen Ausklang.

       DIE WELLE AUS AFFOLTERN. Kanton und Land blenden nicht nur auf, sie
       breiten sich als Kreis vom Ortspunkt aus (clip-path: circle) — das
       Bild vom Kreis, der grösser wird, wörtlich genommen, und das Echo des
       Pulses. Die Welle fährt dieselbe Kurve und dieselben Zeitpunkte wie
       karte-zoomen; die Blende darüber macht die Kreiskante weich.
       Koordinaten: bei SVG-Elementen ist die Referenzbox die fill-box, der
       Mittelpunkt steht darum relativ zur Bounding Box des Pfads
       (Ort 150.6/980.6 minus bbox-Ursprung). Der Endradius ist die grösste
       Distanz vom Ort zum Umriss, ausgemessen per getPointAtLength, plus
       etwas Rand für den Strich. Wer die Pfade austauscht, misst neu. */
    .karte__bezirk, .karte__kanton, .karte__schweiz {
      animation-timing-function: linear;
      animation-fill-mode: both;
      animation-timeline: --reise;
      animation-range: contain 0% contain 100%;
    }
    .karte__bezirk  { animation-name: ebene-knonaueramt; }
    .karte__kanton  { animation-name: ebene-kanton, welle-kanton; }
    .karte__schweiz { animation-name: ebene-schweiz, welle-schweiz; }
    .karte__kanton, .karte__schweiz {
      animation-timing-function: linear, cubic-bezier(0.65, 0, 0.35, 1);
    }
    @keyframes welle-kanton {
      0%, 14%   { clip-path: circle(0px at 150.6px 980.3px); }
      44%, 100% { clip-path: circle(1080px at 150.6px 980.3px); }
    }
    @keyframes welle-schweiz {
      0%, 56%   { clip-path: circle(0px at 3979.6px 1249.6px); }
      86%, 100% { clip-path: circle(4820px at 3979.6px 1249.6px); }
    }
    @keyframes ebene-knonaueramt {
      0%,  12%  { opacity: 1; }
      42%, 100% { opacity: 0; }
    }
    @keyframes ebene-kanton {
      0%,  18%  { opacity: 0; }
      46%, 58%  { opacity: 1; }
      88%, 100% { opacity: 0; }
    }
    @keyframes ebene-schweiz {
      0%,  56%  { opacity: 0; }
      90%, 100% { opacity: 1; }
    }

    /* Gegenskalierung des Ortspunkts. Ohne sie wäre der Punkt auf der
       ersten Stufe ein Fleck und auf der Landesansicht unsichtbar: er
       sitzt ja im selben Koordinatensystem wie die Grenzen. Die Werte sind
       die Kehrwerte der drei Zoomstufen, zu denselben Zeitpunkten wie
       karte-zoomen — wer die eine Liste verschiebt, verschiebt die andere
       mit. */
    .karte__ort {
      transform-box: fill-box;
      transform-origin: center;
      animation-name: ort-gegenhalten;
      animation-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
      animation-fill-mode: both;
      animation-timeline: --reise;
      animation-range: contain 0% contain 100%;
    }
    @keyframes ort-gegenhalten {
      0%, 14%   { scale: 0.359; }
      44%, 56%  { scale: 1.327; }
      86%, 100% { scale: 7.533; }
    }

    /* Der Puls auf Affoltern: zeitgesteuert, nicht scrollgesteuert. Er ist
       kein Schritt der Reise, sondern das Zeichen »hier fängt sie an«.
       transform-box: fill-box, damit die Mitte des Kreises der Drehpunkt
       ist und nicht die Ecke des Koordinatensystems. */
    .karte__puls {
      display: block;
      fill: none;
      stroke: var(--cyan);
      stroke-width: 2;
      vector-effect: non-scaling-stroke;
      transform-box: fill-box;
      transform-origin: center;
      animation: karte-puls 3.2s var(--ease) infinite;
    }
    @keyframes karte-puls {
      0%        { opacity: 0.7; scale: 1; }
      70%, 100% { opacity: 0;   scale: 3.4; }
    }

    /* ---- Die Spur und die Akte ---- */

    /* Die cyane Füllung wächst über der grauen Spur mit dem Fortschritt. */
    .weg__akte::after {
      content: "";
      position: absolute;
      inset-block: var(--marke-y) 0;
      inset-inline-start: 5px;
      inline-size: 2px;
      background: var(--cyan);
      transform-origin: center top;
      animation-name: spur-fuellen;
      animation-timing-function: linear;
      animation-fill-mode: both;
      animation-timeline: --reise;
      animation-range: contain 0% contain 100%;
    }
    @keyframes spur-fuellen {
      from { scale: 1 0; }
      to   { scale: 1 1; }
    }

    /* Fokus: der Akt in der Lesezone steht gross und kontrastreich, die
       anderen treten zurück. Jeder Akt taktet sich über seine eigene
       view()-Timeline — er ist in der Lesezone, wenn er in der Fenstermitte
       steht, und das gilt auf jeder Fensterhöhe. Die gedimmten Akte sind
       nie die, die man gerade liest: sie stehen am oberen oder unteren
       Rand, und Scrollen stellt sie voll her. */
    .akt {
      animation-name: akt-fokus;
      animation-timing-function: var(--ease-out);
      animation-fill-mode: both;
      animation-timeline: view();
      animation-range: cover 8% cover 92%;
      /* Ursprung links auf der Spur, nicht in der Mitte: sonst wanderte der
         Text beim Verkleinern von der Spur weg. */
      transform-origin: left center;
    }
    @keyframes akt-fokus {
      0%       { opacity: 0.32; scale: 0.96; }
      36%, 64% { opacity: 1;    scale: 1; }
      100%     { opacity: 0.32; scale: 0.96; }
    }
    /* Die Marke schaltet mit: grau, wenn der Akt noch kommt, cyan in der
       Lesezone, dunkelblau danach. Der dritte Akt bleibt cyan — er ist das
       Jetzt und hört nicht auf, es zu sein. */
    .akt::before {
      animation-name: marke-erledigen;
      animation-timing-function: var(--ease-out);
      animation-fill-mode: both;
      animation-timeline: view();
      animation-range: cover 8% cover 92%;
    }
    .akt--jetzt::before { animation-name: marke-jetzt; }
    @keyframes marke-erledigen {
      0%       { background-color: var(--line); }
      36%, 64% { background-color: var(--cyan); }
      100%     { background-color: var(--blue-deep); }
    }
    @keyframes marke-jetzt {
      from { background-color: var(--line); }
      to   { background-color: var(--cyan); }
    }

    /* ---- Telefon: Karte über den Akten statt daneben ----
       Auf dem Desktop stehen Karte und Akte nebeneinander, und die Plateaus
       treffen die Akte von selbst. Auf dem Telefon steht die Bühne ÜBER den
       Akten und klebt dort — mit voller Breite nahm sie das halbe Fenster,
       die Akte liefen unter ihr durch, und der Zoom lief am Text vorbei:
       die Fahrt hinaus fand statt, während gar kein Akt zu sehen war.

       Darum hier drei Dinge, die zusammengehören:
         1. Die Karte wird kleiner (--karte-m) und steht mittig.
         2. Jeder Akt ist genau so hoch wie der Streifen UNTER der Bühne.
            Dann füllt Akt 1 den Streifen, wenn die Bühne zu kleben beginnt,
            Akt 3, wenn die Strecke endet — und Akt 2 liegt exakt bei 50 %.
            Das sind die Plateaus aus karte-zoomen, ohne neue Keyframes.
         3. Die Timeline zählt erst ab der Klebekante (view-timeline-inset),
            nicht ab der Fensteroberkante. Sonst begänne die Strecke, bevor
            die Bühne steht.
       svh statt vh: der Streifen soll auch bei eingeblendeter
       Browserleiste ganz sichtbar sein.

       DER TEXT LÖST SICH VOR DER KARTE AUF. Die Bühne hat keinen Grund
       mehr (Abschnitt 2), der Text liefe sonst durch die Karte. Jede Zeile
       und jeder Chip hat darum eine eigene Timeline auf den Streifen unter
       der Bühne und ist genau dann weg, wenn die eigene Oberkante die Karte
       erreicht — pro Element und nicht pro Akt, weil die Akte verschieden
       hoch sind. akt-fokus ist hier aus: eine Deckkraft-Regel reicht.
       Spur und Marken fallen weg: ohne Grund liefe die senkrechte Linie
       hinter der Karte bis zur Navigation hoch. Den Fortschritt zeigt auf
       dem Telefon die Karte selbst. */
    @media (max-width: 819px) {
      .weg {
        --karte-m: min(40svh, 100vw - 2 * var(--gutter));
        --kleben: calc(var(--nav-h) + var(--space-s));
        --buehne-unten: calc(var(--kleben) + var(--karte-m));
        view-timeline-inset: var(--kleben) 0;
        gap: 0;
      }
      .karte {
        inline-size: var(--karte-m);
        max-inline-size: 100%;
        margin-inline: auto;
        animation-name: karte-rand, karte-weiten;
        animation-timing-function: linear, cubic-bezier(0.65, 0, 0.35, 1);
      }
      /* Die Schweiz liegt quer und hat im quadratischen Fenster nur dessen
         Breite — auf dem Telefon oft deutlich weniger als die Spalte. Auf
         der letzten Fahrt wird das Fenster darum bis zur Spaltenbreite
         breiter (höchstens das 1.5-Fache), und die Schweiz wächst mit.
         Die negativen Ränder halten die Bühne dabei auf --karte-m Höhe:
         nichts darunter verschiebt sich, und --buehne-unten stimmt weiter.
         Oben und unten ragt nur leeres, durchsichtiges Fenster über; die
         Schweiz selbst ist 0.62 × Breite hoch und passt bis zum 1.5-Fachen
         in die Bühne. Gleiche Kurve und Zeitpunkte wie karte-zoomen. */
      @keyframes karte-weiten {
        0%, 56% { inline-size: var(--karte-m); margin-block: 0; }
        86%, 100% {
          inline-size: min(100%, var(--karte-m) * 1.5);
          margin-block: calc((var(--karte-m) - min(100%, var(--karte-m) * 1.5)) / 2);
        }
      }
      .weg__akte { gap: 0; padding-inline-start: 0; }
      .weg__akte::before, .weg__akte::after, .akt::before { display: none; }
      .akt {
        min-block-size: calc(100svh - var(--buehne-unten));
        animation-name: none;
      }
      .akt__ort, .akt__satz, .akt__text, .akt__station {
        animation: akt-aufloesen linear both;
        animation-timeline: view(block var(--buehne-unten) 0);
        /* Feste 2rem vor der Karte, kein Anteil der Strecke: der Streifen
           ist je nach Telefon verschieden hoch, und ein Prozentwert liess
           auf kurzen Schirmen den Titel des hohen zweiten Akts schon auf
           seinem Plateau verwischen. */
        animation-range: contain calc(100% - 2rem) contain 100%;
      }
      @keyframes akt-aufloesen {
        from { opacity: 1; translate: 0 0; filter: blur(0); }
        to   { opacity: 0; translate: 0 -0.5rem; filter: blur(4px); }
      }
    }
  }
}

/* ---------- 3. Meine Schwerpunkte — drei ruhige Karten --------------------
   Drei gleich breite Karten nebeneinander, ohne Hover-Abhängigkeit und ohne
   Auf- und Zuklappen. Seit der ersten Feedbackrunde trägt die Karte nur noch
   die Position: Thema, Zuspitzung, ein Satz Haltung, der Erfahrungsanker.
   Belege gibt es auf der Startseite keine mehr — .tafel__zahl (bis 4rem),
   .tafel__fakt und die Quellenangabe in .tafel__fuss sind ersatzlos
   entfernt, die Zahlen stehen nur noch auf /themen in .nachweis. Die
   Karte ist dadurch ruhiger; der gewonnene Platz geht in Weissraum und
   Schriftgrad, nicht in neuen Inhalt.

   .tafeln statt .cards-grid, damit kein alter Selektor (auch nicht mehr
   vorhandener JS-Module) versehentlich wieder greift. .card kommt aus
   style.css (Abschnitt 4.3) für Grund, Kante und Innenabstand. Die Karte ist
   hier ein li statt eines a, weil sie mehr als nur einen Link enthält;
   a.card:hover aus style.css greift deshalb nicht und wird unten für .tafel
   nachgebaut.
   ----------------------------------------------------------------------- */

/* Flache Fläche statt Verlauf: ein weicher Cyan-Wash hinter den Karten war
   reine Deko und trug keine Information — genau die "gradient wash as
   decoration" aus dem SaaS-Card-Baukasten. Die Seite selbst ist hartkantig
   (--radius: 0, Balken statt Flächen), ein Verlauf passt nicht zu ihrer
   Sprache. Eine flache Fläche tut denselben Job — die Sektion von Weiss
   absetzen — als bewusster Schnitt statt als Weichzeichnung, und genau das
   braucht die Naht zu #weg: dessen Bodenabstand ist null (siehe Abschnitt 6),
   die Flächen stossen also direkt aneinander. Ein Verlauf liesse diese Kante
   verschwimmen, die Flatfarbe macht sie zum sauberen Schnitt. */
#schwerpunkte {
  background: var(--cyan-soft);
  /* Eigener, kleinerer Bodenabstand statt --space-xl: sonst folgt auf die
     helle Flaeche noch einmal der volle Sektionsabstand, bevor #stimmen mit
     eigenem --space-xl beginnt — zwei gleich grosse Polster hintereinander,
     nur durch den Farbwechsel getrennt. So bleibt die Cyan-Flaeche knapper um
     ihren Inhalt geschnitten, der Rhythmus der Seite variiert. */
  padding-block-end: var(--space-l);
}

.schwerpunkte__intro { max-inline-size: var(--measure); margin-block-end: var(--space-l); }

.tafeln {
  list-style: none;
  padding: 0;
  margin-block-end: var(--space-l);
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-m);
}

/* Der Akzent wandert von der linken Kante nach oben — dieselbe Sprache wie
   die Stimmen-Karte (.quote, style.css 4.4), und oben trägt er die Kopfzeile
   mit Thema und Signet. Jedes Thema bekommt seinen eigenen Ton; Magenta
   bleibt aussen vor, das gehört den Call-to-Actions. */
.tafel {
  --akzent: var(--cyan);
  position: relative; /* Anker für den gestreckten Link (.tafel__link::after) */
  border-inline-start: 1px solid var(--line);
  border-block-start: 6px solid var(--akzent);
}
.tafel:nth-child(2) { --akzent: var(--blue-deep); }
.tafel:nth-child(3) { --akzent: color-mix(in srgb, var(--cyan) 45%, var(--blue-deep)); }

/* Der Themenname steht über einer Haarlinie — sie gibt der Karte einen
   Anfang, seit Belege, Erfahrungsanker und Signet alle weg sind. */
.tafel .eyebrow {
  padding-block-end: var(--space-s);
  border-block-end: 1px solid var(--line);
}

/* Die Zuspitzung trägt die Karte, seit die Kennzahl weg ist — eine Stufe
   grösser als zuvor (war --step-1). */
.tafel__titel { font-size: var(--step-2); line-height: 1.15; }
/* Die Zuspitzung liest sich als Überschrift, nicht als blauer Link — die
   Fläche macht schon die ganze Karte klickbar. */
.tafel__link { color: inherit; text-decoration: none; }
.tafel__link::after { content: ""; position: absolute; inset: 0; }
/* Der Ring sitzt auf der ganzen Karte, nicht auf dem Link selbst: ein Ring
   um die unsichtbare Linkzeile fiele kaum auf. */
.tafel__link:focus-visible { outline: none; }
.tafel:has(.tafel__link:focus-visible) {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
}

/* Die globale Regel gibt jedem p die Satzbreite --measure. In der Karte
   bestimmt die Spalte die Breite, nicht der Text. */
.tafel p { max-inline-size: none; }

/* Der Haltungssatz ist die einzige inhaltliche Aussage der Karte und trägt
   sie allein. Er steht darum über dem Lauftextgrad und mit ruhiger Zeile.
   Hier lagen früher die grosse Kennzahl (.tafel__zahl, bis 4rem), ein
   Pinselstrich dahinter und der Statistiksatz; alles entfernt — Joel wollte
   die Belege auf der Startseite ganz weg. Der gewonnene Platz geht in
   Weissraum und Zeilenabstand, nicht in neuen Inhalt — und nicht in einen
   Schriftgrad, der mit der Zuspitzung darüber konkurriert. */
.tafel__haltung {
  font-size: var(--step-0);
  line-height: 1.5;
  margin-block-start: var(--space-s);
}


/* »Mehr erfahren« schliesst die Karte ab und sitzt über einer Trennlinie:
   Die Zeile ist kein eigener Button, sondern die Beschriftung des gestreckten
   Links in der h3 — eine zweite Buttonsorte gibt es auf der Seite nicht.
   Der Pfeil (.btn__arrow) ist an .tafel__mehr ohnehin unsichtbar — die
   Klasse zeigt ihn nur an .btn--primary, siehe style.css 4.1 —, das Markup
   führt darum nur noch den Text. */
.tafel__mehr {
  align-self: end;
  margin-block-start: var(--space-m);
  padding-block-start: var(--space-m);
  border-block-start: 1px solid var(--line);
  inline-size: 100%;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step--1);
  color: var(--ink);
  transition: color 0.2s var(--ease), border-color 0.2s var(--ease);
}
/* Rückmeldung beim Überfahren sitzt hier statt an der ganzen Karte: die
   Tafel ist über die gestreckte h3 verlinkt, aber die Karte selbst
   anzuheben war dieselbe Standardgeste wie an .card und .btn — beide sind
   dafür bereits aus style.css entfernt (siehe dortige Kommentare). Genau die
   Zeile, an der man ohnehin prüft, ob etwas klickbar ist, färbt sich um —
   das ist spezifisch, nicht die ganze Fläche. */
.tafel:hover .tafel__mehr,
.tafel:has(.tafel__link:focus-visible) .tafel__mehr {
  color: var(--magenta-dark);
  border-block-start-color: var(--magenta);
}

/* ---------- 3.1 Ab 900 px — drei Spalten -----------------------------------
   Die drei Karten stehen nebeneinander. Damit Kopf, Zuspitzung, Haltung
   und »Mehr erfahren« über alle drei Karten auf derselben Linie
   stehen, bekommt jede Karte per Subgrid Zugriff auf vier gemeinsame
   Zeilenspuren der äusseren Liste: .tafeln definiert sie (eine pro
   Kind-Element, vier Kinder je Karte), jede .tafel spannt sie mit
   grid-row: span 4 auf und übernimmt sie als eigenes Zeilenraster. So
   richtet sich jede Zeile an der höchsten ihrer drei Ausprägungen aus, ohne
   dass irgendwo eine Höhe geraten werden müsste. */
@media (min-width: 900px) {
  .tafeln {
    /* minmax(0, 1fr) statt 1fr: die Vorgabe 1fr ist minmax(auto, 1fr), und
       auto laesst eine Spalte wachsen, sobald ihr laengstes Wort breiter ist
       als der gleiche Anteil — »Grundkompetenzen« machte die erste Karte
       rund 30 px breiter als die beiden anderen. Die 0-Untergrenze bindet
       die Spalte an den Anteil, nicht an ihren Inhalt. */
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: auto;
    column-gap: var(--space-m);
  }
  .tafel {
    grid-row: span 4;
    display: grid;
    grid-template-rows: subgrid;
    row-gap: var(--space-s);
  }
}

/* ---------- 4. Stimmen -------------------------------------------
   Sektion, Karte, Raster und Einladung sind Komponenten in style.css (4.4),
   weil dieselben Bausteine auch auf /unterstuetzen stehen. Hier bleibt
   nichts übrig, was nur die Home betrifft.
   -------------------------------------------------------------------------- */

/* ---------- 5. Schluss-Band ------------------------------------------------ */

.band .stack { max-inline-size: 46ch; align-items: center; display: flex; flex-direction: column; }

/* ---------- 6. Nahtstellen — kein doppeltes --space-xl ---------------------
   .section bringt padding-block: var(--space-xl) oben UND unten mit. Stehen
   zwei helle .section-Blöcke hintereinander, stapelt sich sonst 2× --space-xl
   am Übergang. Der Bodenabstand des oberen Blocks entfällt, der Kopfabstand
   des unteren bleibt — die Naht ist dann genau 1× --space-xl breit.

   Das gilt nur für Mein Weg → Schwerpunkte: die Cyan-Fläche von
   #schwerpunkte beginnt direkt am Ende von #weg, ein doppeltes Polster hätte
   dort wie eine Lücke zwischen zwei Flächen gewirkt statt wie ein Schnitt.
   #stimmen liegt auf eigener Fläche (.section--alt) und braucht oben wie
   unten den vollen Abstand — kein Grund, ihn zu kürzen. Der Bodenabstand von
   #schwerpunkte selbst ist knapper als --space-xl (siehe Abschnitt 3): die
   Fläche endet dadurch näher an ihrem Inhalt, statt denselben Rhythmus wie
   jede andere Sektion zu wiederholen. */
#weg {
  padding-block-end: 0;
}
