/*
  Code IT Solutions — site.css

  Brand tokens (hart, aus CODE-IT-SOLUTIONS/CLAUDE.md + references/voice-profile.md §6):
  Hintergrund #0D0D0D, Akzent #7C5CFF, Sekundärfläche #1B1B1B, Text #F5F5F5.
  Diese Datei überschreibt NUR die :root-Tokens von cool-website.css und ergänzt
  eigene Klassen. .cw-stage, .cw-copy und jedes [data-cw-*]-Selektor bleiben
  unangetastet (siehe references/template.html).
*/

:root {
  --cw-canvas:     #0D0D0D;
  --cw-surface:    #1B1B1B;
  --cw-ink:        #F5F5F5;
  --cw-ink-soft:   #9a9ba1;
  --cw-accent:     #7C5CFF;
  --cw-accent-ink: #0D0D0D;
  --cw-font-display: "Space Grotesk", system-ui, sans-serif;
  --cw-font-text:    "Inter", system-ui, sans-serif;

  /* 2026-09-30: Kontrast-Fix für gefüllte Akzent-Buttons (.site-bar__cta,
     .btn-primary, .close .cta). Dunkler Ink (#0D0D0D) auf dem harten
     Akzent-Ton (#7C5CFF) liegt bei nur ~4,5:1 Kontrast — rechnerisch knapp
     WCAG-AA, in der Praxis (Screenshot-Kompression, Sub-Pixel-Rendering)
     wirkt die Schrift dadurch fast unsichtbar ("der Button sieht komisch
     aus"-Feedback). --cw-accent (der harte Marken-Token) bleibt unverändert
     für Links, Borders, Tags etc. Dieser zusätzliche, nur für gefüllte
     Buttons genutzte Ton ist eine ~15% aufgehellte Variante von --cw-accent
     und hebt den Kontrast auf ~5,7:1 an, ohne den Marken-Akzent selbst
     anzutasten. */
  --cw-accent-btn: #9074FF;
}

/* Einmalige, zentrale Font-Einbindung für die ganze Seite (behebt Audit-Punkt
   "doppelte Google-Fonts-Deklaration" — self-hosted wäre performanter und
   DSGVO-sauberer, aber ein einziger @import statt mehrfacher <link>-Tags
   reicht als Zwischenlösung). */
@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=Inter:wght@400;500;600&display=swap");

/* Grain minimal anheben — Engine-Default (0.045) wirkt auf großen, sehr
   flachen Schwarzflächen kaum wahrnehmbar. Bleibt weit unter jeder
   "Textur als Deko"-Schwelle, macht die Fläche aber weniger steril. */
.cw-grain::before { opacity: .075; }

/* ---------- Site-Bar ---------- */
.site-bar {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.1rem clamp(1.25rem, 4vw, 2.5rem);
  background: linear-gradient(to bottom, rgba(13,13,13,.86), rgba(13,13,13,0));
  pointer-events: none;
}
.site-bar__mark,
.site-bar__cta,
.site-bar__nav,
.site-bar__burger {
  pointer-events: auto;
}
.site-bar__mark {
  display: flex;
  align-items: center;
  gap: .6rem;
  text-decoration: none;
  color: var(--cw-ink);
}
.site-bar__mark img { height: 22px; width: auto; display: block; }
.site-bar__nav {
  display: flex;
  gap: clamp(1rem, 2.4vw, 2rem);
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--cw-font-text);
  font-size: .92rem;
}
.site-bar__nav a {
  color: var(--cw-ink-soft);
  text-decoration: none;
  transition: color .2s ease;
}
.site-bar__nav a:hover,
.site-bar__nav a[aria-current="page"] { color: var(--cw-ink); }
.site-bar__cta {
  font-family: var(--cw-font-text);
  font-weight: 600;
  font-size: .88rem;
  color: var(--cw-accent-ink);
  background: var(--cw-accent-btn); /* Kontrast-Fix, siehe :root-Kommentar */
  border-radius: 999px;
  padding: .6rem 1.15rem;
  text-decoration: none;
  white-space: nowrap;
}
/* 2026-09-30: echtes Mobile-Menü. Vorher wurde .site-bar__nav unter 720px
   einfach ausgeblendet, ohne Ersatz — Leistungen/Portfolio/Über mich/Kontakt
   waren auf dem Handy nur noch über den Footer erreichbar. .site-bar__burger
   existierte bereits als toter, unsichtbarer Klassen-Hook ohne Markup; jetzt
   mit echtem Button + Toggle-Panel verbunden (siehe assets/site-nav.js). */
.site-bar__burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid rgba(245,245,245,.18);
  border-radius: 10px;
  background: rgba(27,27,27,.7);
  cursor: pointer;
}
.site-bar__burger span {
  display: block;
  width: 18px;
  height: 2px;
  background: var(--cw-ink);
  border-radius: 1px;
  transition: transform .25s var(--cw-ease-out), opacity .25s var(--cw-ease-out);
}
.site-bar__burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.site-bar__burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.site-bar__burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 720px) {
  /* 2026-09-30: Logo + CTA + Burger nebeneinander wurde auf schmalen
     Viewports eng — "Projekt anfragen" quetschte sich direkt neben den
     Burger. Grid statt Flex: Burger bleibt oben rechts neben dem Logo,
     CTA wandert in die Zeile darunter, rechtsbündig unter den Burger. */
  .site-bar {
    display: grid;
    grid-template-columns: 1fr auto;
    row-gap: .6rem;
  }
  .site-bar__mark { grid-column: 1; grid-row: 1; }
  .site-bar__burger { grid-column: 2; grid-row: 1; justify-self: end; display: flex; }
  .site-bar__cta { grid-column: 2; grid-row: 2; justify-self: end; }
  .site-bar__nav {
    position: fixed;
    inset: 0 0 auto 0;
    flex-direction: column;
    gap: 1.1rem;
    margin: 0;
    padding: 5.4rem 1.5rem 2rem;
    background: rgba(13,13,13,.98);
    border-bottom: 1px solid rgba(245,245,245,.09);
    font-size: 1.1rem;
    transform: translateY(-100%);
    opacity: 0;
    visibility: hidden;
    transition: transform .3s var(--cw-ease-out), opacity .3s var(--cw-ease-out), visibility .3s;
  }
  .site-bar__nav.is-open {
    transform: translateY(0);
    opacity: 1;
    visibility: visible;
  }
  .site-bar__nav a { display: block; padding: .5rem 0; }
}

/* ---------- Footer ---------- */
.site-foot {
  border-top: 1px solid rgba(245,245,245,.09);
  padding: 2.4rem clamp(1.25rem, 4vw, 2.5rem) 2.8rem;
  font-family: var(--cw-font-text);
  color: var(--cw-ink-soft);
  font-size: .88rem;
  display: flex;
  flex-wrap: wrap;
  gap: 1.4rem 2.4rem;
  align-items: flex-start;
  justify-content: space-between;
}
.site-foot__mark { display: flex; align-items: center; gap: .55rem; color: var(--cw-ink); }
.site-foot__mark img { height: 18px; width: auto; }
.site-foot__legal { display: flex; gap: 1.4rem; flex-wrap: wrap; }
.site-foot__legal a { color: var(--cw-ink-soft); text-decoration: none; }
.site-foot__legal a:hover { color: var(--cw-ink); }
.site-foot__contact { display: flex; flex-direction: column; gap: .25rem; }
.site-foot__contact a { color: var(--cw-ink-soft); text-decoration: none; }
.site-foot__contact a:hover { color: var(--cw-ink); }

/* ---------- Editorial page shell (kurze Seiten ohne Acts: Kontakt,
   Impressum, Datenschutz) ---------- */
.editorial {
  max-width: 760px;
  margin: 0 auto;
  padding: clamp(7rem, 16vh, 9rem) clamp(1.25rem, 6vw, 2rem) 4rem;
}
.editorial h1 {
  font-family: var(--cw-font-display);
  font-size: clamp(2rem, 5vw, 2.8rem);
  line-height: 1.08;
  margin: 0 0 1.6rem;
}
.editorial h2 {
  font-family: var(--cw-font-display);
  font-size: 1.25rem;
  margin: 2.4rem 0 .8rem;
  color: var(--cw-ink);
}
.editorial p, .editorial li {
  font-family: var(--cw-font-text);
  color: var(--cw-ink-soft);
  line-height: 1.65;
  font-size: 1.02rem;
}
.editorial a { color: var(--cw-accent); }
/* 2026-09-30: ".editorial a" (Element+Klasse) ist spezifischer als ".btn-primary"
   (nur Klasse) und überschreibt dort dessen Textfarbe — Button-Text wurde dadurch
   in Kontexten wie kontakt.html praktisch unsichtbar (Akzent-Text auf
   Akzent-Hintergrund). Fix erhöht die Spezifität gezielt für Buttons innerhalb
   von .editorial, ohne die generelle Link-Farbe anzutasten. */
.editorial .btn-primary { color: var(--cw-accent-ink); }
.editorial table { width: 100%; border-collapse: collapse; margin: 1.2rem 0 2rem; }
.editorial table td, .editorial table th {
  text-align: left;
  padding: .55rem .8rem .55rem 0;
  border-bottom: 1px solid rgba(245,245,245,.08);
  font-family: var(--cw-font-text);
  font-size: .95rem;
  color: var(--cw-ink-soft);
  vertical-align: top;
}
.editorial table th { color: var(--cw-ink); font-weight: 600; width: 40%; }
.editorial .lede {
  font-size: 1.12rem;
  color: var(--cw-ink);
}

/* ---------- shared content-page building blocks (flow/reveal pages:
   Leistungen, Portfolio, Über mich) ---------- */
.cw-wrap {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 clamp(1.25rem, 6vw, 2.5rem);
}
.cw-eyebrow {
  font-family: var(--cw-font-text);
  font-size: .8rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--cw-accent);
  margin: 0 0 .8rem;
}
.cw-stack { display: flex; flex-direction: column; gap: 1rem; }
.cw-lead-block {
  position: relative;
  max-width: 680px;
  padding: clamp(7rem, 18vh, 9rem) 0 3rem;
}
.cw-lead-block .lede {
  font-size: 1.12rem;
  color: var(--cw-ink);
}
/* Sehr dezenter, akzentgetönter Radial-Wash hinter jedem Seiten-Hero —
   kein neues Bild, weit unter der Glow-Schwelle (7% Mix), gibt dem
   Seitenanfang etwas Atmosphäre statt reinem Flachschwarz. */
.cw-lead-block::before {
  content: "";
  position: absolute;
  inset: -4rem -50vw auto -50vw;
  height: 26rem;
  background: radial-gradient(ellipse 60% 100% at 50% 0%,
    color-mix(in oklab, var(--cw-accent) 7%, transparent), transparent 70%);
  pointer-events: none;
  z-index: -1;
}

/* Section-Banding: bricht die durchgängig flache Schwarzfläche auf
   Leistungen/Portfolio/Über-mich in ruhige, alternierende Bahnen auf. */
.cw-section--tint {
  background: color-mix(in oklab, var(--cw-surface) 45%, var(--cw-canvas));
}

/* Home Akt 4 (Signature-Moment) folgt direkt auf die gepinnte Portfolio-Rail
   (Akt 3) — die Standard-Section-Polsterung (bis zu 11rem oben) lässt die
   Überschrift beim Scrollen unnötig weit unten im Viewport erscheinen.
   Nur das Top-Padding wird gekappt, das Bottom-Padding bleibt Standard. */
.cw-section--flush-top {
  padding-top: clamp(2.5rem, 5vw, 4.5rem);
}

.cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.4rem;
  margin: 2rem 0;
}
.card {
  background: var(--cw-surface);
  border: 1px solid rgba(245,245,245,.06);
  border-radius: 18px;
  padding: 1.6rem 1.5rem;
  box-shadow: var(--cw-e2), var(--cw-edge);
  transition: transform .25s var(--cw-ease-out), box-shadow .25s var(--cw-ease-out);
}
.card:hover {
  transform: translateY(-3px);
  box-shadow: var(--cw-e3), var(--cw-edge);
}
@media (prefers-reduced-motion: reduce) {
  .card { transition: none; }
  .card:hover { transform: none; }
}
.card h3 {
  font-family: var(--cw-font-display);
  font-size: 1.12rem;
  margin: 0 0 .55rem;
}
.card p { margin: 0; color: var(--cw-ink-soft); font-size: .96rem; line-height: 1.55; }

/* Nicht-Grid-Alternativen zu .cards-grid (Design-Spec §4.3): ruhige Liste
   bzw. nummerierter Ablauf statt eines vierten/dritten identischen
   Karten-Sets auf leistungen.html. */
.problem-list {
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
  margin: 2rem 0;
  max-width: 760px;
}
.problem-list__item {
  padding-left: 1.2rem;
  border-left: 2px solid rgba(245,245,245,.14);
}
.problem-list__item h3 {
  font-family: var(--cw-font-display);
  font-size: 1.08rem;
  margin: 0 0 .4rem;
  color: var(--cw-ink);
}
.problem-list__item p {
  margin: 0;
  color: var(--cw-ink-soft);
  font-size: .96rem;
  line-height: 1.6;
}

.process-flow {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0 1.6rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.process-flow__step {
  position: relative;
  padding-top: 1.2rem;
  border-top: 2px solid rgba(245,245,245,.14);
}
/* Pfeil sitzt in der Lücke über dem :not(:last-child)-Rand, auf Höhe der
   .process-flow__num-Zeile (nicht am Step selbst verankert) — rein
   dekorativ, daher als Pseudo-Element und nicht per aria-hidden-Span
   aus dem Accessibility-Tree entfernbar; bei Änderung von h2-Abstand
   oder padding-top hier gegenprüfen. */
.process-flow__step:not(:last-child)::after {
  content: "→";
  position: absolute;
  top: -1.05rem;
  right: -.9rem;
  color: var(--cw-ink-soft);
  font-size: .9rem;
}
.process-flow__num {
  display: block;
  margin-bottom: .4rem;
  font-family: var(--cw-font-display);
  font-size: .82rem;
  letter-spacing: .06em;
  color: var(--cw-accent);
}
.process-flow__step h3 {
  font-family: var(--cw-font-display);
  font-size: 1.08rem;
  margin: 0 0 .5rem;
  color: var(--cw-ink);
}
.process-flow__step p {
  margin: 0;
  color: var(--cw-ink-soft);
  font-size: .92rem;
  line-height: 1.55;
}
@media (max-width: 720px) {
  .process-flow { grid-template-columns: 1fr; gap: 1.6rem; }
  .process-flow__step:not(:last-child)::after { display: none; }
}

/* Kontakt-Karte: erbt Elevation/Kantenlicht von .card, aber ohne Hover-Lift —
   sie ist ein ruhiger Anker, kein interaktives Grid-Element. */
.contact-card {
  padding: 2rem 2.2rem;
  max-width: 480px;
}
.contact-card:hover { transform: none; box-shadow: var(--cw-e2), var(--cw-edge); }

.tag-row { display: flex; flex-wrap: wrap; gap: .5rem; margin: .9rem 0 0; }
.tag {
  font-family: var(--cw-font-text);
  font-size: .78rem;
  color: var(--cw-ink-soft);
  background: color-mix(in oklab, var(--cw-ink) 6%, transparent);
  border: 1px solid rgba(245,245,245,.14);
  border-radius: 999px;
  padding: .3rem .7rem;
}

.claim-note {
  font-family: var(--cw-font-text);
  font-size: .82rem;
  color: var(--cw-ink-soft);
  border-left: 2px solid var(--cw-accent);
  padding-left: .8rem;
  max-width: 46ch;
}

/* Stat-Row: dieselben bereits freigegebenen Erfahrungswerte (60% / 85–95% /
   15–30h), nur als greifbare Zahlen statt einer Fußnoten-Zeile. Analog zum
   .count-block-Pattern, aber dreispaltig für den Home-Haltungs-Block. */
.stat-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(140px, 1fr));
  gap: 1.6rem 2rem;
  margin: 2.2rem 0 0;
  padding-top: 1.6rem;
  border-top: 1px solid rgba(245,245,245,.08);
}
.stat-row__item { display: flex; flex-direction: column; gap: .3rem; }
.stat-row__num {
  font-family: var(--cw-font-display);
  font-size: clamp(1.9rem, 4vw, 2.6rem);
  font-weight: 600;
  color: var(--cw-accent);
  line-height: 1;
}
.stat-row__label {
  font-family: var(--cw-font-text);
  font-size: .82rem;
  color: var(--cw-ink-soft);
  line-height: 1.45;
}
@media (max-width: 620px) {
  .stat-row { grid-template-columns: 1fr; gap: 1.2rem; }
}

.btn-primary {
  display: inline-block;
  font-family: var(--cw-font-text);
  font-weight: 600;
  color: var(--cw-accent-ink);
  background: var(--cw-accent-btn); /* Kontrast-Fix, siehe :root-Kommentar */
  border-radius: 999px;
  padding: .8rem 1.5rem;
  text-decoration: none;
}
.btn-ghost {
  display: inline-block;
  font-family: var(--cw-font-text);
  font-weight: 600;
  color: var(--cw-ink);
  border: 1px solid rgba(245,245,245,.22);
  border-radius: 999px;
  padding: .78rem 1.45rem;
  text-decoration: none;
}
/* Mehrere Buttons nebeneinander (z. B. Kontaktseite "E-Mail schreiben" /
   "Anrufen" / "LinkedIn"): gleiche Wrap-Logik wie .tag-row, damit ein
   umbrechender Button auf schmalen Handy-Viewports nicht ohne Abstand an
   der Zeile darüber klebt. */
.btn-row { display: flex; flex-wrap: wrap; align-items: center; gap: .7rem 1rem; }

/* ---------- Über-mich: Bio-Header, Erfahrungs-Einträge, Zwei-Spalten-Block ---------- */
.bio {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: clamp(1.6rem, 4vw, 3rem);
  /* Bild vertikal zum (höheren) Textblock zentrieren statt oben ausgerichtet —
     auf der Originalseite sitzt das Porträt mittig zur Textspalte, nicht am
     oberen Rand des Grids. */
  align-items: center;
  max-width: 920px;
}
.bio__photo img {
  /* Natürliches Seitenverhältnis des Portraits (704x1385, ein Ganzkörperfoto)
     statt erzwungenem 3:4-Crop — sonst wird der Großteil des Bildes
     abgeschnitten und wirkt bei kleiner Breite gequetscht/winzig. */
  width: 100%;
  height: auto;
  aspect-ratio: 704 / 1385;
  object-fit: cover;
  border-radius: 18px;
  border: 1px solid rgba(245,245,245,.1);
  display: block;
}
.bio h1 {
  font-family: var(--cw-font-display);
  font-size: clamp(2rem, 4.4vw, 2.6rem);
  margin: 0 0 1rem;
}
.bio p { font-family: var(--cw-font-text); color: var(--cw-ink-soft); line-height: 1.65; margin: 0 0 .9rem; }
.bio .lede { color: var(--cw-ink); font-size: 1.08rem; }
@media (max-width: 640px) {
  .bio { grid-template-columns: 1fr; }
  /* Ganzkörperfoto braucht auf einer Spalte mehr Breite, sonst wirkt es
     bei 220px winzig — 280px zeigt es in angemessener, lesbarer Größe. */
  .bio__photo { max-width: 280px; margin-inline: auto; }
}

.exp-item h3 {
  font-family: var(--cw-font-display);
  font-size: 1.1rem;
  color: var(--cw-ink);
  margin: 0 0 .25rem;
}
.exp-item__meta {
  font-family: var(--cw-font-text);
  font-size: .82rem;
  color: var(--cw-accent);
  margin: 0 0 .7rem;
}
.exp-item ul {
  margin: 0 0 2rem;
  padding-left: 1.1rem;
  font-family: var(--cw-font-text);
  color: var(--cw-ink-soft);
  line-height: 1.6;
  font-size: .96rem;
}
.exp-item:last-child ul { margin-bottom: 0; }

.two-col {
  display: grid;
  grid-template-columns: repeat(2, minmax(220px, 1fr));
  gap: 2rem 3rem;
}
.two-col ul {
  margin: 0;
  padding-left: 1.1rem;
  font-family: var(--cw-font-text);
  color: var(--cw-ink-soft);
  line-height: 1.7;
  font-size: .96rem;
}
@media (max-width: 560px) {
  .two-col { grid-template-columns: 1fr; }
}

/* Kernkompetenzen (Design-Spec §4.3): gruppierte Tag-Rows statt Karten-Grid —
   nutzt .tag-row/.tag unverändert weiter (siehe "Technologien im Überblick"
   weiter unten auf dieser Seite). */
.skill-groups {
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
  margin: 2rem 0;
  max-width: 820px;
}
.skill-groups__item h3 {
  font-family: var(--cw-font-display);
  font-size: 1rem;
  /* kein margin-bottom: der sichtbare Abstand kommt von .tag-row's eigenem
     margin-top (.9rem), das per Margin-Collapsing durchschlägt — ein
     zusätzlicher Wert hier wäre wirkungslos und irreführend. */
  margin: 0;
  color: var(--cw-ink);
}

/* ---------- Portfolio: Case-Artikel, Ergebnis-Zeile, Signature-Count ---------- */
.case {
  max-width: 820px;
  padding-bottom: 2.6rem;
  border-bottom: 1px solid rgba(245,245,245,.08);
}
.case:last-of-type { border-bottom: none; padding-bottom: 0; }
.case h2 {
  font-family: var(--cw-font-display);
  font-size: clamp(1.5rem, 3.2vw, 2rem);
  margin: 0 0 1.4rem;
}
.case h3 {
  font-family: var(--cw-font-text);
  font-size: .82rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--cw-ink);
  margin: 1.4rem 0 .5rem;
}
.case h3:first-of-type { margin-top: 0; }
.case p {
  font-family: var(--cw-font-text);
  color: var(--cw-ink-soft);
  line-height: 1.65;
  font-size: .98rem;
  margin: 0;
}
.case__result {
  margin-top: 1.2rem !important;
  color: var(--cw-ink) !important;
}
.case__result strong { color: var(--cw-accent); }

.count-block {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: .6rem 1rem;
  margin-top: 1.6rem;
  padding-top: 1.4rem;
  border-top: 1px solid rgba(245,245,245,.08);
}
.count-block__num {
  font-family: var(--cw-font-display);
  font-size: clamp(2.4rem, 6vw, 3.6rem);
  font-weight: 600;
  color: var(--cw-accent);
  line-height: 1;
}
.count-block__unit {
  font-family: var(--cw-font-text);
  font-size: 1rem;
  color: var(--cw-ink-soft);
}
.count-block__label {
  flex-basis: 100%;
  font-family: var(--cw-font-text);
  font-size: .85rem;
  color: var(--cw-ink-soft);
}

/* ---------- Home: Video-Akt-1 Kapitelmarker-Tags (Akt 1, scrub) ---------- */
/* Ersetzt die vorherige Split-Stage (siehe Git-Historie vor
   docs/superpowers/specs/2026-09-30-code-it-solutions-video-akt1-design.md). Drei
   kurze Tags (ERP/Hallenboden/Systeme) flogen scroll-synchron über data-cw-cue
   pro Videosegment ein/aus — reiner Text, keine Spalten-/Seam-Mechanik mehr nötig.
   2026-09-30: Nicht mehr im Markup referenziert — durch volle Satzzeilen ersetzt
   (siehe .cw-copy__line unten), da das neue Wan-3.0-Video keine eingebrannten
   Untertitel mehr trägt. Regel bewusst nicht gelöscht (totes CSS, kein aktives
   Element), falls die kurzen Tags an anderer Stelle wieder gebraucht werden. */
.split__tag {
  margin: 0;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--cw-ink-soft);
}

/* ---------- Home: Video-Akt-1 sequenzielle Satzzeilen (Akt 1, scrub) ---------- */
/* 2026-09-30: Vier volle Sätze lösen sich nacheinander an DERSELBEN Stelle über
   dem Video ab (siehe index.html-Kommentar am Akt-1-<section>). [data-cw-cue]
   aus assets/cool-website.css setzt nur opacity:0 — ohne eigene Positionierung
   würden mehrere Geschwister-<p> im normalen Blockfluss untereinander aufgereiht
   werden (eine unsichtbare Box beansprucht trotzdem ihre Höhe). Deshalb hier
   position:absolute auf jede Zeile, alle exakt übereinandergelegt; .cw-copy--lead
   (unverändert aus der Engine) bleibt der positionierende Elternrahmen.
   Scope bewusst eng auf .cw-copy--lead .cw-copy__line gehalten — .cw-copy--lead
   kommt aktuell nur genau einmal im ganzen Projekt vor (Akt 1).
   2026-09-30 (Nachschlag): Nutzer fand die Sätze zu klein/unauffällig und wollte
   eine "premium" Position etwas höher. Schriftgröße auf display-Font + große
   clamp() angehoben (Größenordnung an .count-block__num / Sektions-Headlines
   angelehnt statt der bisherigen sehr kleinen Fließtext-Größe), engere
   Zeilenhöhe für Headline-Charakter. Position: .cw-copy--lead selbst kommt aus
   der Engine-CSS (assets/cool-website.css, bottom: clamp(3rem,12vh,9rem)) — hier
   bewusst NICHT die Engine-Datei angefasst, sondern in site.css (das lädt danach
   und darf Engine-Defaults überschreiben, wie an anderer Stelle in dieser Datei
   bereits mit !important gehandhabt) einen höheren bottom-Wert erzwungen. Sicher,
   da .cw-copy--lead projektweit nur an dieser einen Stelle verwendet wird. */
.cw-copy--lead {
  bottom: clamp(7rem, 24vh, 16rem) !important;
}
.cw-copy--lead .cw-copy__line {
  position: absolute;
  inset-inline: 0;
  bottom: 0;
  margin: 0;
  font-family: var(--cw-font-display);
  font-weight: 600;
  font-size: clamp(1.7rem, 4vw, 2.9rem);
  line-height: 1.22;
  letter-spacing: -0.01em;
  color: var(--cw-ink);
  max-width: 34ch;
}

/* ---------- Home: Portfolio-Rail (Akt 3, pan) ---------- */
/* min-width guarantees .rail's natural content width always exceeds the
   viewport (over = scrollWidth - vw > 0 in cool-website.js), so the pan
   transform activates on any monitor size — fixed-width flex children
   (flex: 0 0 auto) mean any shortfall becomes automatic trailing runway
   instead of collapsing the pan on wide/fullscreen screens. */
.rail {
  align-items: center;
  gap: clamp(1.4rem, 3vw, 2.4rem);
  height: 100%;
  padding-inline: var(--cw-gutter);
  min-width: 130vw;
}
.rail__lead { flex: 0 0 auto; max-width: 20rem; }
.rail__lead h2 {
  font-family: var(--cw-font-display);
  font-size: clamp(1.5rem, 3.2vw, 2.1rem);
  margin: .8rem 0;
}
.rail__lead p { margin: 0; color: var(--cw-ink-soft); font-size: .96rem; line-height: 1.55; }
.rail .item {
  position: relative;
  flex: 0 0 auto;
  width: clamp(270px, 24vw, 460px);
  background: var(--cw-surface);
  border: 1px solid rgba(245,245,245,.07);
  border-radius: 18px;
  padding: 1.7rem 1.5rem;
  box-shadow: var(--cw-e2), var(--cw-edge);
  transition: transform .25s var(--cw-ease-out), box-shadow .25s var(--cw-ease-out);
}
.rail .item:hover {
  transform: translateY(-3px);
  box-shadow: var(--cw-e3), var(--cw-edge);
}
@media (prefers-reduced-motion: reduce) {
  .rail .item { transition: none; }
  .rail .item:hover { transform: none; }
}
.rail .item h3 {
  font-family: var(--cw-font-display);
  font-size: 1.08rem;
  margin: .5rem 0;
  color: var(--cw-ink);
}
.rail .item p { margin: 0; color: var(--cw-ink-soft); font-size: .92rem; line-height: 1.5; }
.rail .item .tag-row { margin-top: .9rem; }

/* Shine-Border: rein additive Lichtspur, die einmal pro Zyklus um den
   Kartenrand läuft — zusätzliche Ebene über dem bestehenden 1px-Border,
   verändert weder :hover-Transform noch :hover-Shadow oben. --cw-border-angle
   wird via @property registriert, damit nur der Gradient-Winkel animiert
   (nicht das Element selbst rotiert) — so bleibt der Lichtring exakt an den
   abgerundeten Ecken der Card ausgerichtet, egal bei welchem Winkel. */
@property --cw-border-angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}
:root { --cw-border-angle: 0deg; } /* Fallback für Browser ohne @property-Support: statischer Ring statt Animation */

.rail .item::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  padding: 1px;
  background: conic-gradient(
    from var(--cw-border-angle),
    transparent 0%,
    transparent 80%,
    color-mix(in oklab, var(--cw-accent) 55%, transparent) 86%,
    #C08AFF 90%,
    #F5A35C 94%,
    transparent 100%
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  pointer-events: none;
  animation: cw-shine-rotate 7s linear infinite;
}
.rail .item > * { position: relative; z-index: 1; }
@keyframes cw-shine-rotate {
  to { --cw-border-angle: 360deg; }
}
@media (prefers-reduced-motion: reduce) {
  .rail .item::before {
    animation: none;
    background: color-mix(in oklab, var(--cw-accent) 18%, transparent);
  }
}

/* 2026-09-30: Touch-Gate, analog zu [data-cw-tilt]/[data-cw-magnet]/
   [data-cw-spotlight] in cool-website.css, die bereits auf
   (hover: hover) and (pointer: fine) beschränkt sind. Diese Animation
   rotiert einen @property-Winkel innerhalb eines conic-gradient — das kann
   der Browser nicht compositen, jeder Frame ist ein echtes Repaint von 4
   Elementen. Ohne dieses Gate lief sie unconditional ab dem ersten Paint,
   auch während Akt 1 (Video-Scrub, bereits der teuerste Akt der Seite) —
   das war der Hauptgrund für das gemeldete "ruckelt auf dem Handy, auch
   die ersten Seiten". Gleicher Fallback wie im reduced-motion-Block oben. */
@media (hover: none), (pointer: coarse) {
  .rail .item::before {
    animation: none;
    background: color-mix(in oklab, var(--cw-accent) 18%, transparent);
  }

  /* Akt 1 (Home, scrub-Sektion): auf dem Handy soll ein Swipe maximal einen
     der 4 Sätze weiterbewegen, nicht mehrere auf einmal überspringen. Die
     Engine (cool-website.js) bleibt unangetastet — sie liest ohnehin nur
     scrollY pro Frame, egal wodurch der Scroll entsteht. Stattdessen: vier
     unsichtbare 1px-Marker (.cw-snap-mark, siehe index.html) an der
     Scroll-Position jedes Satz-Plateaus, plus natives CSS scroll-snap.
     scroll-snap-stop: always ist hier der entscheidende Teil — ohne das
     würde ein harter Fling trotzdem zwei Marker auf einmal überspringen und
     beim nächstgelegenen landen; mit "always" MUSS der Browser an jedem
     Marker nacheinander anhalten. Nur Touch/coarse-Pointer, damit Maus/
     Trackpad-Scrollen auf Desktop exakt wie bisher frei durchläuft.
     2026-09-30 (Nachschlag): "mandatory" hat nach dem letzten Marker (Satz 4)
     zum bekannten Scroll-Snap-Trap-Verhalten geführt — der Browser wollte
     die Scroll-Endposition IMMER exakt auf den nächstgelegenen Marker
     zwingen, und da nach Satz 4 kein weiterer Marker kommt, blieb er dort
     hängen statt in Akt 2 weiterzuscrollen. "proximity" snapt nur, wenn die
     Ruheposition ohnehin schon nah an einem Marker liegt, erzwingt es aber
     nie — der "kein Überspringen"-Effekt bleibt trotzdem erhalten, weil
     scroll-snap-stop:always unabhängig vom Container-Typ wirkt. Zusätzlich
     bekommt der letzte Marker (Satz 4) gar kein "always" mehr, damit danach
     garantiert nichts mehr blockiert.
     2026-09-30 (Nachschlag 2): Trotzdem gemeldet: "extrem ruckelig, stopt
     nicht sauber". Ursache: html hat global scroll-behavior:smooth (siehe
     cool-website.css), und scroll-snap-type + scroll-behavior:smooth auf
     demselben Container heißt, der Browser animiert das Einrasten am Marker
     NOCH EINMAL per CSS obendrauf auf die bereits laufende native Touch-
     Momentum-Bewegung — zwei überlagerte Bewegungssysteme statt eines, was
     sich als Nachruckeln statt einem glatten Stopp zeigt (trifft am Ende
     trotzdem den richtigen Satz, siehe scroll-snap-align/-stop oben, nur
     über einen wackligen Zwischenschritt). Fix: scroll-behavior auf Touch
     zurück auf "auto" — exakt dasselbe Muster, das cool-website.css bereits
     für prefers-reduced-motion nutzt, hier nur für die Touch-Bedingung.
     Geprüft: keine In-Page-#anchor-Links im Projekt, und die einzige
     scrollIntoView-Nutzung (cool-website.js, Fokus-Handling) erzwingt
     bereits explizit behavior:'instant' — unabhängig von dieser Property.
     2026-10-01 (Nachschlag 3): Auf einem zweiten Testgerät gemeldet: "stoppt
     der nicht mal" bei einem kräftigen Flick, Scrollen wirkt sehr schnell —
     anders als das Ruckel-Problem oben betrifft das NICHT das Video, sondern
     den nativen Snap selbst. scroll-snap-stop:always soll laut Spec auch bei
     proximity jeden Marker zwingend anhalten, aber WebKit/Safari-Mobile hat
     dafür bekannte Inkonsistenzen, vor allem bei sehr kleiner Snap-Area (der
     Marker war bislang 1x1px). Gegenmaßnahme, nur CSS, kein Engine-Edit:
     Snap-Area pro Marker vergrößern (8vh statt 1px), damit der Browser mehr
     Fläche hat, um den Snap überhaupt als "nah genug" zu erkennen. Bewusst
     KEIN scroll-padding auf html gesetzt — das würde den tatsächlichen
     Snap-Landepunkt relativ zum Viewport verschieben und damit die bereits
     bestätigt korrekte Satz-Landeposition (top-Werte der Marker) verändern;
     scroll-snap-align:start bleibt unverändert am oberen Rand des Markers
     verankert, die zusätzliche Höhe erweitert nur den "Einzugsbereich" nach
     unten, zwischen diesem und dem nächsten Marker liegen weiterhin 15vh+
     Luft (siehe top-Werte unten), also keine Überlappung. */
  html { scroll-snap-type: y proximity; scroll-behavior: auto; }

  .cw-snap-mark {
    position: absolute;
    left: 0;
    width: 1px;
    height: 8vh;
    pointer-events: none;
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }
  .cw-snap-mark--last { scroll-snap-stop: normal; }
}

/* ---------- Home: pinned Signature-Moment (Akt 4) ---------- */
/* Analog zu .close (Akt 5): Text + Count-Block bleiben während des gesamten
   Pins vertikal zentriert und unbewegt — nur die Zahl selbst ändert sich.
   Kein eigenes height hier: das Element trägt bereits .cw-stage (JS-gesetzt),
   das height:100vh/100svh vorgibt. Ein height:100% hier würde das dank
   gleicher Selector-Spezifität und späterem Stylesheet-Load überschreiben
   und den Sticky-Pin sprengen — die Stage wurde dadurch so hoch wie die
   gesamte Pin-Spanne (180vh statt 100vh), der Text saß erst weit unten im
   riesigen Flex-Container und erschien nur schemenhaft nach mehrfachem
   Scrollen. Gilt für jede .cw-stage-Sektion mit data-cw-act="pin" (z.B. auch .close). */
.signature {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.2rem;
  text-align: center;
  padding-inline: var(--cw-gutter);
}
.signature .lede { margin: 0; max-width: 46ch; }
.signature .count-block {
  justify-content: center;
  margin-top: .2rem;
}

/* ---------- Home: pinned Closing-CTA (Akt 5) ---------- */
/* Kein eigenes height hier — derselbe Grund wie bei .signature:
   .cw-stage (JS-gesetzt) gibt bereits height:100vh/100svh vor, ein
   height:100% hier würde das überschreiben und den Sticky-Pin sprengen.
   .close__inner füllt via flex:1 trotzdem die volle Stage-Höhe. */
.close {
  display: flex;
  flex-direction: column;
}
.close__inner {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.4rem;
  text-align: center;
  padding-inline: var(--cw-gutter);
}
.close__inner h2 {
  font-family: var(--cw-font-display);
  font-size: clamp(2rem, 5vw, 3.2rem);
  line-height: 1.12;
  margin: 0;
  max-width: 20ch;
  color: var(--cw-ink);
}
.close__inner .lede { margin: 0; max-width: 46ch; }
.close .cta {
  display: inline-block;
  font-family: var(--cw-font-text);
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--cw-accent-ink);
  background: var(--cw-accent-btn); /* Kontrast-Fix, siehe :root-Kommentar */
  border-radius: 999px;
  padding: .95rem 2.1rem;
  text-decoration: none;
}

/* ---------- Home: Closing-CTA Trace-Faden (Akt 5) ---------- */
/* Fasst die drei in Akt 2 (.stat-row) bereits gezeigten Erfahrungswerte am
   Schluss noch einmal leise zusammen — keine neuen Zahlen, keine Konkurrenz
   zur Headline. Sitzt oberhalb von .close__inner, daher eigenes
   padding-inline statt Vererbung von .close__inner. Die Engine faded
   [data-cw-cue] nur über opacity (kein height-Collapse, siehe cool-website.js),
   d.h. der reservierte Platz bleibt nach dem Ausblenden bestehen und
   .close__inner rückt für den Rest des Pins nicht nach — bewusst in Kauf
   genommen statt eigenem JS-Hook nur für dieses Detail. */
.close__trace {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .5rem .9rem;
  padding-inline: var(--cw-gutter);
  margin-bottom: 1.6rem;
  font-family: var(--cw-font-text);
  font-size: .78rem;
  letter-spacing: .02em;
  color: var(--cw-ink-soft);
}
.close__trace-sep {
  opacity: .4;
}
