/* ==========================================================================
   JARII · Akt 2 (Halm-Bühne) und Akt 3 (Clubs) · Agent C, Bühne
   überarbeitet 26.10.2026 (Agent H: Glas im Verhältnis, Striche, fünf Karten).
   Gehört zu src/partials/product.html, clubs.html und assets/js/straw.js.
   Nur Tokens aus tokens.css, keine neuen Hex-Werte, keine Verläufe.

   Zwei Zustände der Bühne:
   1. Grundzustand (ohne JavaScript, reduzierte Bewegung, GSAP fehlt):
      normale Sektion. Halm steht im Glas mit Fenster vorn, daneben zwei
      vergrößerte Fenster-Ausschnitte mit Chip, fünf Karten als Liste.
   2. html.has-stage (setzt early.js vor dem ersten Bild, Rücknahme durch
      straw.js oder main.js, wenn die Bühne nicht aufgebaut wird; Agent P): hohe Sektion (600vh, mobil 420vh)
      mit Sticky-Bühne 100svh (Muster 2, docs/21st-referenzen.md). Sticky
      statt GSAP-Pin: kein Pin-Spacer, ruhiger auf iOS und beim Drehen, und
      die Sektion davor (Agent B) kann ihre Höhe ändern, ohne dass hier
      etwas nachgerechnet werden muss.
   ========================================================================== */

/* --- Grundzustand ------------------------------------------------------- */
.product { position: relative; }

.stage__sticky {
  position: relative;
  padding-block: clamp(48px, 8vw, 96px) var(--space-12);
}

.stage__grid {
  display: grid;
  gap: var(--space-8);
  grid-template-areas: "head" "visual" "cards";
}
@media (min-width: 768px) {
  .stage__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
    grid-template-areas: "head head" "visual cards";
    align-items: start;
    gap: var(--space-12) var(--space-8);
  }
}

.stage__head { grid-area: head; }
.stage__visual { grid-area: visual; }
.stage__cards { grid-area: cards; }

/* H1: Wortmarke in display-xl, darunter die Unterzeile. Die Kapseln für
   „II“ baut assemble.mjs zentral (Klasse .wm, components.css, Agent W);
   hier keine eigene Färbung mehr, sonst gäbe es zwei Varianten der Marke. */
.stage__title {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.stage__wordmark { color: var(--navy); }
/* Unterzeile: mobil body-l (passt in eine Zeile und lässt dem Halm Platz),
   ab 768 px heading-2. Werte aus tokens.css übernommen, weil die Klasse
   nicht je Breite wechseln kann. */
.stage__sub {
  color: var(--ink);
  font-family: var(--font-text);
  font-size: 1.0625rem;
  line-height: 1.5556;
  font-weight: 500;
  letter-spacing: 0;
}
@media (min-width: 768px) {
  .stage__sub {
    font-family: var(--font-display);
    font-size: clamp(1.375rem, 2.6vw, 1.625rem);
    line-height: 1.1;
    font-weight: 700;
    letter-spacing: -0.025em;
  }
}

/* Hinweis „Scrollen“ hat nur mit Bühne einen Sinn */
.stage__hint {
  display: none;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
  color: var(--ink-muted);
  transition: opacity var(--dur) var(--ease);
}
.stage__hint .icon { width: 1.1em; height: 1.1em; }

/* Halm im Grundzustand: steht im Glas mit Fenster vorn (SVG-Attribute).
   Ab 768 px stehen die Fenster-Ausschnitte rechts daneben, darunter mobil. */
.stage__visual {
  position: relative;
  margin: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
}
/* flex-wrap: Bei 768–1100 px ist die linke Spalte nur rund 270–550 px breit;
   Halm (rund 200 px) und die zwei Ausschnitte (rund 330 px) passen dann nicht
   nebeneinander und ragten über Karte 02 und den linken Rand (gefunden beim
   Abschluss-Prüflauf 26.10.2026, Screenshot 768 px, reduzierte Bewegung).
   Jetzt rutschen die Ausschnitte unter den Halm, sobald der Platz fehlt. */
@media (min-width: 768px) {
  .stage__visual { flex-direction: row; flex-wrap: wrap; justify-content: center; }
  .straw__states { flex-wrap: wrap; }   /* schmale Spalte: Ausschnitte untereinander */
}
.straw {
  position: relative;
  height: min(60vh, 520px);
  aspect-ratio: 250 / 640;
}
/* overflow sichtbar: die Halmspitze darf beim Anheben kurz über den SVG-Rand */
.straw__svg { width: 100%; height: 100%; max-width: none; overflow: visible; }

/* SVG-Farben über Tokens. Strichstärken in Pixeln (non-scaling-stroke),
   damit Linien bei 390 px nicht unter 1 px fallen. */
.straw__tube { fill: var(--navy); }
.straw__bore { fill: var(--surface-100); }
.straw__window { fill: var(--surface-100); }
.straw__strip { fill: var(--surface-raised); }
/* Striche im Fenster: neutral dunkel, keine Signalfarbe (Reaktionsfarbe
   offen, docs/aenderungen-2026-10-26.md Abschnitt 4). Strichstärke bleibt
   Attribut: straw.js hebt sie auf kleinen Bildschirmen auf mindestens 2 px. */
.straw__marks { fill: none; stroke: var(--ink); stroke-linecap: butt; }
/* Tropfen: neutrale gefüllte Form, kein Gegenstand */
.straw__drop { fill: var(--navy); }
.straw__ring {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1px;
  vector-effect: non-scaling-stroke;
}
.straw__seam {
  stroke: var(--hairline);
  stroke-width: 1px;
  vector-effect: non-scaling-stroke;
}
.straw__mouthline {
  fill: none;
  stroke: var(--on-navy-accent);
  stroke-width: 1px;
  vector-effect: non-scaling-stroke;
}
.straw__maxring {
  fill: none;
  stroke: var(--lilac);
  stroke-width: 2.5px;
  vector-effect: non-scaling-stroke;
}
/* font-size bleibt Attribut: straw.js rechnet sie je Größe so, dass „MAX“
   immer etwa 12 px hat (eine CSS-Angabe würde das Attribut überschreiben). */
.straw__maxtext {
  fill: var(--ink-muted);
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: 0.22em;
}
.straw__liquid { fill: var(--lilac); }
.straw__glassline {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.5px;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
}
.straw__glassline--back { stroke: var(--ink-muted); stroke-width: 1px; }
.straw__glassline--thin { stroke: var(--ink-muted); stroke-width: 1px; }

/* Pause-Logo nur in der Bühne */
.straw__pause { display: none; }

/* Anzeige im Grundzustand: zwei Fenster-Ausschnitte nebeneinander, jeder
   mit seinem Chip darunter (links leer, rechts mit zwei Strichen). */
.straw__states {
  display: flex;
  justify-content: center;
  gap: var(--space-6);
  list-style: none;
}
.straw__state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
}
/* Ausschnitt: navy Rohrstück, Fenster in der Mitte, Kapselecken über
   clip-path (das Rohr füllt den viewBox ganz aus) */
.straw__zoom {
  display: block;
  width: 48px;
  height: 120px;
  clip-path: inset(0 round var(--radius-md));
}
.straw__chip { background-color: var(--surface-raised); white-space: nowrap; }

/* --- Karten -------------------------------------------------------------- */
.stage__cards {
  display: grid;
  gap: var(--space-4);
  list-style: none;
}
.stage-card {
  background-color: var(--surface-raised);
  color: var(--ink);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-6) var(--space-6);
}
@media (max-width: 767px) {
  .stage-card { padding: var(--space-4); }
}
.stage-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  color: var(--ink-muted);
}
.stage-card__num { color: var(--violet); }
.stage-card__head .icon { width: 20px; height: 20px; color: var(--navy); }
.stage-card__title { margin-top: var(--space-3); color: var(--ink); }
.stage-card__text { margin-top: var(--space-2); }
.stage-card__foot {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-4);
  color: var(--ink-muted);
}
.stage-card__ticks {
  display: flex;
  flex: 1;
  gap: var(--space-1);
}
.tick {
  flex: 1;
  height: 3px;
  overflow: hidden;
  border-radius: var(--radius-pill);
  background-color: var(--hairline);
}
.tick > span {
  display: block;
  height: 100%;
  background-color: var(--violet);
  transform-origin: left center;
}

.stage__progress { display: none; }

/* --- Unter der Bühne ---------------------------------------------------- */
.product__after {
  display: grid;
  gap: var(--space-6);
  padding-block: var(--space-12) clamp(48px, 8vw, 96px);
}
.product__notes { display: grid; gap: var(--space-2); }
.product__status {
  display: grid;
  gap: var(--space-1);
  padding-left: var(--space-4);
  border-left: 2px solid var(--lilac);
}
.product__status .label { color: var(--ink-muted); }
.product__cta { margin-top: var(--space-2); }

/* ==========================================================================
   Bühne (html.has-stage)
   ========================================================================== */
/* Fünf Phasen: 600vh (mobil 420vh), damit jede Phase rund 100vh (mobil
   rund 70vh) Scrollweg hat und nicht hetzt. */
html.has-stage .stage { height: 600vh; }
@media (max-width: 767px) {
  html.has-stage .stage { height: 420vh; }
}

html.has-stage .stage__sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  /* oben Platz für den fixierten Mini-Header, unten für die Fortschrittslinie */
  padding: calc(var(--head-h) + var(--space-4)) 0 var(--space-8);
}
html.has-stage .stage__grid {
  height: 100%;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: auto minmax(0, 1fr) auto;
  grid-template-areas: "head" "visual" "cards";
  gap: var(--space-4);
}

/* Mobil: unten Platz für die Bottom-Bar, Karten liegen nie darunter */
@media (max-width: 767px) {
  html.has-stage .stage__sticky {
    padding-bottom: calc(var(--bar-h) + env(safe-area-inset-bottom) + var(--space-3));
  }
  /* Hinweis rechts neben der Wortmarke statt darunter: spart eine Zeile */
  html.has-stage .stage__head { position: relative; }
  html.has-stage .stage__hint {
    position: absolute;
    top: var(--space-2);
    right: 0;
    margin-top: 0;
  }
}
/* Kleine Handys (z. B. 360×640): Glas und Halm bekämen sonst nur rund
   130 px Höhe. Gewonnen werden rund 60 px: Wortmarke etwas kleiner, engere
   Abstände, Ticks in der Karte weg (die Fortschrittslinie unten zeigt den
   Stand weiterhin). */
@media (max-width: 767px) and (max-height: 700px) {
  html.has-stage .stage__sticky { padding-top: calc(var(--head-h) + var(--space-2)); }
  html.has-stage .stage__grid { gap: var(--space-2); }
  html.has-stage .stage__wordmark { font-size: 2.75rem; }
  html.has-stage .stage__title { gap: var(--space-1); }
  html.has-stage .stage-card__foot { display: none; }
}

/* Ab 768 px: Karten unten rechts (max. 380 px), Halm in der linken Spalte */
@media (min-width: 768px) {
  html.has-stage .stage__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
    grid-template-rows: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "head   head"
      "visual ."
      "visual cards";
    gap: var(--space-4) var(--space-6);
  }
}
/* Ab 1280 px ist genug Platz: Halm in der Seitenmitte über die volle Höhe,
   Titel links oben und Karten rechts unten liegen daneben. */
@media (min-width: 1280px) {
  html.has-stage .stage__visual {
    grid-column: 1 / -1;
    grid-row: 1 / -1;
  }
  html.has-stage .stage__head,
  html.has-stage .stage__cards { position: relative; z-index: 2; }
}

html.has-stage .stage__hint { display: inline-flex; }
html.has-stage .stage.is-scrolled .stage__hint { opacity: 0; }

html.has-stage .stage__visual {
  display: block;
  min-height: 0;
  height: 100%;
}
/* Glas und Halm füllen zusammen rund 95 % der SVG-Höhe; bis 84svh bleiben
   Fenster und Striche am Desktop gut erkennbar, ohne an den Header zu stoßen. */
html.has-stage .straw {
  height: 100%;
  max-height: 84vh;
  max-height: 84svh;
  margin-inline: auto;
}
/* Mobil etwas links, damit die Chips rechts neben dem Fenster Platz haben */
@media (max-width: 767px) {
  html.has-stage .straw { max-height: 45svh; margin-left: 12%; }
}

/* Logo und Chips liegen über dem SVG. straw.js setzt nur transform und
   opacity; Ausgangspunkt ist die linke obere Ecke der Bühne. */
html.has-stage .straw__pause,
html.has-stage .straw__states {
  position: absolute;
  left: 0;
  top: 0;
}
html.has-stage .straw__pause {
  display: block;
  width: 40px;
  height: 40px;
  opacity: 0;
  will-change: transform, opacity;
}
/* Beide Chips in derselben Rasterzelle: in Phase 05 wechselt „Nichts
   erkannt“ an Ort und Stelle zu „Substanz erkannt“. Die Ausschnitte braucht
   die Bühne nicht, dort zeigt der Halm selbst die Striche. */
html.has-stage .straw__states { display: grid; gap: 0; will-change: transform; }
html.has-stage .straw__state {
  grid-area: 1 / 1;
  align-items: flex-start;
  opacity: 0;
  will-change: transform, opacity;
}
html.has-stage .straw__zoom { display: none; }

/* Großaufnahme und Führungslinie gibt es nur in der Bühne (der statische
   Zustand zeigt dafür die zwei Ausschnitte). */
.straw__lead,
.straw__loupe { display: none; }
/* Großaufnahme unter dem Chip: Kapsel (Grundform der Marke), schwebt.
   Mobil 52 × 128 px, ab 768 px 64 × 160 px. Damit sind die Striche darin
   mindestens rund 25 × 4 px (mobil) bzw. 32 × 5 px (Desktop). */
html.has-stage .straw__lead,
html.has-stage .straw__loupe {
  display: block;
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
  will-change: transform, opacity;
}
html.has-stage .straw__loupe {
  width: 52px;
  height: 128px;
  padding: var(--space-1);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  background-color: var(--surface-raised);
  box-shadow: var(--shadow-soft);
}
@media (min-width: 768px) {
  html.has-stage .straw__loupe { width: 64px; height: 160px; }
}
html.has-stage .straw__loupe svg {
  display: block;
  width: 100%;
  height: 100%;
  clip-path: inset(0 round var(--radius-pill));
}
/* Feine Führungslinie vom Fensterrand zum Chip (Breite = Luft minus Rand) */
html.has-stage .straw__lead {
  transform-origin: left center;
  width: 12px;
  height: 1px;
  background-color: var(--hairline);
}

/* Karten: alle in derselben Rasterzelle, unten bündig. Nur die aktive ist
   sichtbar; vorherige schieben nach oben weg, kommende warten unten. */
html.has-stage .stage__cards {
  grid-area: cards;
  align-self: end;
  gap: 0;
}
html.has-stage .stage-card {
  grid-area: 1 / 1;
  align-self: end;
  opacity: 0;
  transform: translateY(16px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
html.has-stage .stage-card.is-prev { transform: translateY(-16px); }
html.has-stage .stage-card.is-active {
  opacity: 1;
  transform: none;
  border-color: var(--violet);
  box-shadow: var(--shadow-soft);   /* die aktive Karte schwebt */
}
html.has-stage .tick > span { transform: scaleX(0); }

/* Anfangszustand, bevor straw.js die Bühne aufgebaut hat (Abschluss-Agent,
   26.10.2026). straw.js baut erst bei Annäherung auf; beim schnellen Scrollen
   (CPU 4×) stand die Bühne sonst rund 150 ms ohne Karte und mit dem Halm im
   Glas (Grundzustand ohne JS) da. Bis .stage die Klasse is-built trägt, zeigt
   CSS genau render(0): Karte 01 aktiv, Halm senkrecht ohne Glas, Fenster
   weggedreht (θ −120°), Kamera wie CAM_A in straw.js. CSS-transform und
   -opacity überschreiben die SVG-Attribute nur bis zum Aufbau; danach setzt
   straw.js die Attribute wie bisher. */
html.has-stage .stage:not(.is-built) .stage-card:first-child {
  opacity: 1;
  transform: none;
  border-color: var(--violet);
  box-shadow: var(--shadow-soft);
}
html.has-stage .stage:not(.is-built) .straw__camera {
  transform: translate(125px, 320px) scale(1.3) translate(-120px, -350px);
}
html.has-stage .stage:not(.is-built) .straw__body { transform: translate(120px, 560px); }
html.has-stage .stage:not(.is-built) .straw__glass { opacity: 0; }
html.has-stage .stage:not(.is-built) .straw__window,
html.has-stage .stage:not(.is-built) .straw__strip,
html.has-stage .stage:not(.is-built) .straw__seam { visibility: hidden; }

/* Fortschrittslinie über die volle Breite, unten an der Bühne */
html.has-stage .stage__progress {
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background-color: var(--hairline);
}
html.has-stage .stage__progress > span {
  display: block;
  height: 100%;
  background-color: var(--violet);
  transform: scaleX(0);
  transform-origin: left center;
}
@media (max-width: 767px) {
  html.has-stage .stage__progress { bottom: calc(var(--bar-h) + env(safe-area-inset-bottom)); }
}

/* ==========================================================================
   Akt 3 · Clubs (navy)
   ========================================================================== */
.clubs__intro { display: grid; gap: var(--space-6); }
.clubs__label { color: var(--on-navy-accent); }
.clubs__lead { color: var(--on-navy); }

.clubs__cards {
  display: grid;
  gap: var(--space-6);
  margin-top: var(--space-12);
  list-style: none;
}
@media (min-width: 900px) {
  .clubs__cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* Karten auf navy: Rand aus on-navy-accent mit geringer Deckung. color-mix
   statt neuem Hex-Wert; ältere Browser bekommen den vollen Token als Rand. */
.club-card {
  display: grid;
  align-content: start;
  gap: var(--space-3);
  padding: var(--space-6);
  border: 1px solid var(--on-navy-accent);
  border-color: color-mix(in srgb, var(--on-navy-accent) 28%, transparent);
  border-radius: var(--radius-lg);
  color: var(--on-navy);
}
@media (min-width: 768px) {
  .club-card { padding: var(--space-8); }
}
.clubs__cta { margin-top: var(--space-12); }

/* Einmaliges Einblenden (html.has-reveal setzt straw.js nur ohne reduzierte
   Bewegung). Ohne die Klasse ist alles sofort sichtbar. */
html.has-reveal .reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
html.has-reveal .reveal.is-in { opacity: 1; transform: none; }
html.has-reveal .clubs__cards .reveal:nth-child(2) { transition-delay: 0.08s; }
html.has-reveal .clubs__cards .reveal:nth-child(3) { transition-delay: 0.16s; }

@media (prefers-reduced-motion: reduce) {
  html.has-reveal .reveal { opacity: 1; transform: none; transition: none; }
}
