/* ═══════════════════════════════════════════════════════════════
   kleon better publishing — zentrales Stylesheet
   Diese Datei gilt für ALLE Seiten. Änderungen hier wirken überall.
   ═══════════════════════════════════════════════════════════════ */

/* ─── Switzer, selbst gehostet ─────────────────────────────────
   Kein fontshare mehr: Damit geht bei keinem Seitenaufruf mehr eine
   IP-Adresse an einen Dritten — das war der DSGVO-Grund.
   Nur die vier Schnitte, die die Seite wirklich benutzt (400/500/600/700),
   keine Kursiven. **Wer eine neue Stärke einsetzt, muss sie hier ergänzen
   und die .woff2 nach assets/fonts/ legen** — sonst rechnet der Browser
   sie sich krumm.
   woff2 genügt; jeder Browser, der die anderen Regeln dieser Datei
   versteht (color-mix, clip-path), kann auch woff2. */
@font-face{font-family:"Switzer";src:url("../fonts/Switzer-Regular.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Switzer";src:url("../fonts/Switzer-Medium.woff2") format("woff2");
  font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"Switzer";src:url("../fonts/Switzer-Semibold.woff2") format("woff2");
  font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:"Switzer";src:url("../fonts/Switzer-Bold.woff2") format("woff2");
  font-weight:700;font-style:normal;font-display:swap}

/* ─── Markenfarben aus kleon_color_rgb.ase ─────────────────────
   Wenn sich eine Farbe ändert: nur hier anpassen.            */
:root{
  --forest:#17422D;
  --olive:#7B8863;
  --tea:#C9DEA6;
  --grey-1:#9A9999;
  --grey-2:#E6E4E7;
  --black:#000000;
  --white:#FFFFFF;

  --forest-dark:#0F2C1E;   /* abgedunkelt, nur für Hover */
  --text-soft:#4F6157;     /* gedeckter Fließtext */
  /* Olive um 10 % abgedunkelt, Farbton unverändert. **Nur für kleine Schrift
     auf hellem Grund** — dort erreicht das reine Olive nur 3,79:1 und damit
     nicht die geforderten 4,5:1; dieser Ton erreicht 4,56:1.
     Als Fläche, Linie, Punkt oder in großer Schrift bleibt --olive. */
  --olive-text:#6F7A59;

  --f:"Switzer","Inter",system-ui,-apple-system,sans-serif;

  --s--1:clamp(.72rem,.68rem + .2vw,.82rem);
  --s-0:clamp(1rem,.95rem + .25vw,1.13rem);
  --s-1:clamp(1.25rem,1.05rem + .8vw,1.65rem);
  --s-2:clamp(1.8rem,1.3rem + 2.2vw,3rem);
  --s-3:clamp(2.4rem,1.5rem + 4.4vw,5rem);
  --s-4:clamp(3.2rem,.6rem + 12.5vw,11.5rem);

  --gutter:clamp(1.25rem,5vw,5rem);
  --maxw:1500px;
  --cols:12;
  --colgap:clamp(1rem,1.6vw,2rem);
  --rule:1px solid color-mix(in srgb,var(--forest) 18%,transparent);
  --ease:cubic-bezier(.16,1,.3,1);

  /* Höhe der fixierten Kopfzeile. Alles, was unter dem Kopf beginnt,
     rechnet mit diesem Wert — nicht durch feste Werte ersetzen. */
  --headerh:4.5rem;
  /* Höhe des mitlaufenden Kontakt-Knopfes. Der Satzspiegel-Umschalter
     stapelt sich mobil darüber und rechnet mit diesem Wert. */
  --stickyh:3.2rem;
}

/* Mobil ist das Raster vierspaltig. Der Wert steht hier und nicht in
   einzelnen Bausteinen, weil Layouts und Satzspiegel-Overlay dieselbe
   Variable lesen müssen — genau darauf beruht, dass das Overlay stimmt.
   Die Grenze liegt bei 560 px, weil ab dort jeder Rasterbaustein ohnehin
   über die volle Breite läuft (`1/-1`). Darüber gilt bei `.card` noch
   `span 6`, was in vier Spalten überliefe.
   **Wer die Grenze nach oben verschiebt, muss die grid-column-Angaben von
   .card (560), .aud (620) und .quotes figure (660) mitziehen.** */
@media(max-width:560px){
  :root{--cols:4}
  /* Das Overlay bringt zwölf Streifen im HTML mit; bei vier Spalten
     brächen die übrigen acht in weitere Zeilen um. */
  #grid i:nth-child(n+5){display:none}
}

/* ─── Grundlagen ─────────────────────────────────────────────── */
*,*::before,*::after{box-sizing:border-box}
/* Sprungziele nicht unter die fixierte Kopfzeile scrollen lassen */
html{-webkit-text-size-adjust:100%;scroll-padding-top:calc(var(--headerh) + 1.2rem)}
/* Kein overflow-x:hidden auf body — das macht body zum Scroll-Container
   und bringt die klebende Kopfzeile auf iOS durcheinander. Der einzige
   Überstand kommt vom Masthead und wird dort beschnitten (.cover). */
body{margin:0;background:var(--white);color:var(--forest);font-family:var(--f);
  font-size:var(--s-0);line-height:1.62;-webkit-font-smoothing:antialiased}
body::after{content:"";position:fixed;inset:0;pointer-events:none;z-index:9990;opacity:.03;
  mix-blend-mode:multiply;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}

h1,h2,h3,h4{font-family:var(--f);font-weight:700;line-height:1.04;letter-spacing:-.034em;margin:0;text-wrap:balance}
p{margin:0 0 1.1em}
a{color:inherit}
/* height:auto gehoert zwingend zu den width/height-Attributen im HTML.
   Die Attribute geben dem Browser das Seitenverhaeltnis vor, damit er den
   Platz schon vor dem Laden freihaelt und die Seite beim Nachladen nicht
   springt. Ohne height:auto wirkt die Hoehe aber als feste Angabe und das
   Bild wird gestaucht, sobald max-width greift.
   Bausteine mit eigener Hoehe (.slide, .card, .quotes, .vergleich) stehen
   weiter unten und ueberschreiben das hier. */
img{max-width:100%;height:auto;display:block}
button{font-family:inherit}
:focus-visible{outline:3px solid var(--forest);outline-offset:4px;border-radius:3px}
/* Auf dunklem Grund muss der Fokusrahmen aufhellen. **Diese Liste muss zur
   Konstante DARK in kleon.js passen.** Vorher stand hier nur `.dark` —
   auf .cover, .sheet und .starter war der Rahmen dadurch Forest auf Forest
   und damit unsichtbar (1,00:1, nachgemessen an 22 Elementen: die vier
   Coverlines, neun Projektkacheln, neun Knöpfe im Projekt-Starter). */
.dark :focus-visible,.cover :focus-visible,.sheet :focus-visible,
.starter :focus-visible,.pagehead :focus-visible,
.projekt-hero :focus-visible,.kolophon :focus-visible{outline-color:var(--tea)}

.skip{position:absolute;left:-999px;top:0;z-index:10000;background:var(--forest);
  color:var(--white);padding:.9rem 1.4rem;font-size:var(--s--1)}
.skip:focus{left:.5rem;top:.5rem}

/* Nur für Screenreader — für Text, der als Zeichnung vorliegt */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;
  overflow:hidden;clip-path:inset(50%);white-space:nowrap}

.wrap{max-width:var(--maxw);margin-inline:auto;padding-inline:var(--gutter)}
/* 12-Spalten-Raster: identisch zum Satzspiegel-Overlay */
.raster{display:grid;grid-template-columns:repeat(var(--cols),minmax(0,1fr));
  column-gap:var(--colgap);row-gap:0}
section{padding-block:clamp(4rem,10vw,9rem);position:relative}
.dark{background:var(--forest);color:var(--white)}
.dark p{color:color-mix(in srgb,var(--white) 72%,transparent)}

.tag{font-size:var(--s--1);letter-spacing:.22em;text-transform:uppercase;font-weight:600;
  color:var(--forest);display:flex;align-items:center;gap:.75rem;margin:0}
.tag::before{content:"";width:1.7rem;height:2px;background:currentColor;flex:none}
/* **Liste muss zur Konstante DARK in kleon.js passen.** Vorher fehlten
   .sheet und .starter — „Selected work“ und „Let’s talk“ standen dadurch
   in Forest auf Forest, also unsichtbar (Kontrast 1,00:1, nachgemessen).
   Auch der Strich in .tag::before verschwand mit. */
.dark .tag,.sheet .tag,.starter .tag,.cover .tag,
.pagehead .tag,.projekt-hero .tag,.kolophon .tag{color:var(--tea)}

.page-no{position:absolute;top:clamp(1.5rem,4vw,3rem);right:var(--gutter);
  font-size:var(--s--1);letter-spacing:.2em;text-transform:uppercase;font-weight:600;color:var(--text-soft)}
/* Auf dunklem Grund wie .tag aufhellen — --text-soft läge sonst bei 1,7:1. */
.sheet .page-no,.dark .page-no{color:var(--tea)}

/* ─── Scroll-Fortschritt ─────────────────────────────────────── */
.colorbar{position:fixed;top:0;right:0;width:5px;height:100vh;z-index:60;
  background:var(--grey-2);display:flex;flex-direction:column}
.colorbar span{flex:1;transform:scaleY(0);transform-origin:top;transition:transform .1s linear}
.colorbar span:nth-child(1){background:var(--tea)}
.colorbar span:nth-child(2){background:var(--olive)}
.colorbar span:nth-child(3){background:var(--forest)}
.colorbar span:nth-child(4){background:var(--forest-dark)}

/* ─── Satzspiegel-Overlay ────────────────────────────────────── */
#grid{position:fixed;top:0;bottom:0;left:0;right:0;z-index:9980;pointer-events:none;opacity:0;
  transition:opacity .35s;display:grid;grid-template-columns:repeat(var(--cols),minmax(0,1fr));
  column-gap:var(--colgap);padding-inline:var(--gutter);max-width:var(--maxw);margin-inline:auto}
#grid.on{opacity:1}
#grid i{background:color-mix(in srgb,var(--olive) 16%,transparent);height:100%}
/* Der Umschalter steht im Markup in der Kopfzeile, schwebt am Schreibtisch
   aber weiterhin unten links als Textknopf — position:fixed nimmt ihn dort
   aus dem Fluss, die Kopfzeile merkt nichts davon. Das geht nur, solange
   der Kopf kein transform trägt (siehe Kommentar bei header). */
.gridbtn{position:fixed;left:1rem;bottom:1rem;z-index:9985;background:var(--white);
  border:1px solid var(--forest);color:var(--forest);font-size:.68rem;letter-spacing:.16em;
  text-transform:uppercase;font-weight:600;padding:.55rem .9rem;border-radius:99px;cursor:pointer;
  transition:background .3s,color .3s}
.gridbtn[aria-pressed="true"],.gridbtn:hover{background:var(--forest);color:var(--white)}
.gridbtn svg{display:none}

/* Ab hier wird daraus ein Zeichen in der Kopfzeile, neben dem Menüknopf —
   kein mitschwebender Knopf mehr. Strichstärke und Tippfläche sind dieselben
   wie beim Burger, damit beide als ein Paar lesbar sind.
   **Die Grenze ist bewusst 900 px, dieselbe wie beim Burger.** Bei 760 klaffte
   dazwischen eine Lücke: Auf Tablets (z. B. iPad Air, 820 px) gab es den
   Burger UND die schwebende Pille, und die war nur 34 px hoch. */
@media(max-width:900px){
  /* margin-left:auto schiebt beide Zeichen als Paar nach rechts. Ohne das
     verteilt justify-content:space-between sie über die halbe Kopfzeile. */
  .gridbtn{position:static;z-index:auto;
    width:2.75rem;height:2.75rem;padding:0;margin-left:auto;margin-right:-.35rem;
    display:inline-flex;align-items:center;justify-content:center;flex:none;
    background:none;border:0;border-radius:0;color:inherit}
  .gridbtn:hover,.gridbtn[aria-pressed="true"]{background:none;color:inherit}
  .gridbtn svg{display:block;width:1.35rem;height:1.35rem}
  .gb-txt{position:absolute;width:1px;height:1px;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap}
  /* Vier Striche = die vier Spalten, die das Overlay mobil zeichnet.
     Der Schrägstrich erscheint, sobald der Satzspiegel an ist: Das Zeichen
     sagt damit, was ein Tippen bewirkt — ausblenden. Dieselbe Logik wie
     Auge und durchgestrichenes Auge, nur auf ein Symbol angewandt.
     Den Zustand selbst meldet aria-pressed an Hilfstechnologien. */
  .gb-strich{opacity:0;transition:opacity .25s var(--ease)}
  .gridbtn[aria-pressed="true"] .gb-strich{opacity:1}
  .gridbtn[aria-pressed="true"] .gb-raster{opacity:.55}
}

/* ─── Kopfzeile ──────────────────────────────────────────────── */
/* sticky statt fixed: iOS Safari verschiebt fixierte Elemente, während die
   Adresszeile ein- und ausfährt — der Kopf sprang dabei über bzw. unter die
   Leiste. Ein klebendes Element gehört zum Scroll-Container und macht diesen
   Sprung nicht mit. Der negative Außenabstand nimmt die Höhe wieder aus dem
   Fluss, damit der Inhalt weiterhin ganz oben beginnt.
   Kein transform auf dem Kopf: das würde einen Bezugsrahmen für das
   position:fixed des Mobilmenüs aufspannen und das Overlay auf Kopfhöhe
   zusammenschrumpfen. Deshalb blendet der Kopf über die Deckkraft ein. */
header{position:sticky;top:0;z-index:9970;padding:0 var(--gutter);
  margin-bottom:calc(-1 * var(--headerh));height:var(--headerh);
  display:flex;justify-content:space-between;align-items:center;gap:1.5rem;
  color:var(--forest);
  opacity:0;visibility:hidden;
  transition:opacity .4s var(--ease),visibility 0s linear .4s,color .3s var(--ease)}
header.show,header.static,header.menu-open{opacity:1;visibility:visible;
  transition:opacity .4s var(--ease),visibility 0s linear 0s,color .3s var(--ease)}

/* Der Kopf hat keine eigene Fläche. Liegt ein dunkler Abschnitt dahinter,
   dreht kleon.js die Farbe um — Marke statt Blendmodus, damit Kontrast und
   Farbwerte in jeder Kombination stimmen. */
header.on-dark,header.menu-open{color:var(--white)}
header.on-dark .logo-txt,header.menu-open .logo-txt{color:color-mix(in srgb,var(--white) 78%,transparent)}
header.on-dark nav a::after,header.menu-open nav a::after{background:var(--white)}
header.on-dark .nav-cta{background:var(--white);color:var(--forest)}
header.on-dark .nav-cta:hover{background:var(--tea)}

.logo{display:flex;align-items:center;gap:.65rem;text-decoration:none;color:inherit;flex:none;
  position:relative;z-index:2}
/* aspect-ratio + flex:none: sonst rechnet Safari die Breite des Inline-SVG
   falsch aus und die Bögen von b und p werden rechts abgeschnitten.
   Das Verhältnis muss zur viewBox in den HTML-Dateien passen. */
.logo svg{height:32px;width:auto;display:block;flex:none;aspect-ratio:398.3/516.2;overflow:visible}
/* Im Kopf steht nur noch das Zeichen. Das Markup bleibt in den HTML-Dateien:
   Wer die Wortmarke zurückholen will, löscht allein das display:none. */
.logo-txt{display:none;
  font-size:var(--s--1);letter-spacing:.16em;text-transform:uppercase;
  font-weight:600;color:var(--text-soft)}
header nav ul{display:flex;gap:clamp(.8rem,1.8vw,1.8rem);list-style:none;margin:0;padding:0;align-items:center}
header nav a{font-size:var(--s--1);letter-spacing:.14em;text-transform:uppercase;font-weight:600;
  text-decoration:none;position:relative;padding-block:.3rem}
header nav a::after{content:"";position:absolute;left:0;bottom:0;width:100%;height:2px;background:var(--forest);
  transform:scaleX(0);transform-origin:right;transition:transform .35s}
header nav a:hover::after,header nav a:focus-visible::after,header nav a[aria-current="page"]::after{transform:scaleX(1);transform-origin:left}
.nav-cta{background:var(--forest);color:var(--white);padding:.55rem 1.1rem!important;border-radius:99px}
.nav-cta::after{display:none}
.nav-cta:hover{background:var(--olive)}

/* ─── Menüknopf ──────────────────────────────────────────────── */
.burger{display:none;position:relative;z-index:2;flex:none;
  width:2.75rem;height:2.75rem;margin-right:-.7rem;
  background:none;border:0;padding:0;cursor:pointer;color:inherit}
.burger i{position:absolute;left:.7rem;right:.7rem;height:2px;background:currentColor;
  transition:transform .45s var(--ease)}
.burger i:nth-of-type(1){transform:translateY(-4px)}
.burger i:nth-of-type(2){transform:translateY(4px)}
header.menu-open .burger i:nth-of-type(1){transform:rotate(45deg)}
header.menu-open .burger i:nth-of-type(2){transform:rotate(-45deg)}

/* ─── Mobilmenü ────────────────────────────────────────────────
   Alle Regeln hier hängen an `header nav`, nicht an `nav`. Ungebunden
   erwischten sie auch die <nav>-Spalten im Kolophon: Deren Listen wurden
   unter 900 px zu unsichtbaren Overlays, sichtbar blieben nur die
   Überschriften. **Nichts hier auf `nav` allein setzen.** */
@media(max-width:900px){
  .burger{display:block}
  /* nav bleibt als Flex-Element im Fluss, ist aber ohne Breite:
     dadurch sitzt das Logo links und der Menüknopf rechts. */
  header nav{flex:none}
  header nav ul{position:fixed;inset:0;z-index:1;
    flex-direction:column;justify-content:center;align-items:stretch;
    gap:0;padding:calc(var(--headerh) + 1rem) var(--gutter) 3rem;
    background:var(--forest);color:var(--white);counter-reset:m;
    overflow-y:auto;overscroll-behavior:contain;
    opacity:0;visibility:hidden;transform:translateY(-1.25rem);
    transition:opacity .4s var(--ease),transform .5s var(--ease),visibility 0s linear .4s}
  header.menu-open nav ul{opacity:1;visibility:visible;transform:none;
    transition:opacity .4s var(--ease),transform .5s var(--ease),visibility 0s linear 0s}
  header nav ul li{counter-increment:m;
    border-bottom:1px solid color-mix(in srgb,var(--white) 16%,transparent)}
  header nav ul a{display:flex;align-items:baseline;gap:1.1rem;padding:.85rem 0;
    font-size:clamp(1.4rem,1.1rem + 2.4vw,2.2rem);letter-spacing:-.02em;
    text-transform:none;font-weight:600;line-height:1.2}
  header nav ul a::before{content:counter(m,decimal-leading-zero);flex:none;min-width:2.4rem;
    font-size:var(--s--1);letter-spacing:.16em;font-weight:600;color:var(--tea)}
  header nav ul a::after{display:none}
  /* Der Handlungsaufruf bleibt eine Schaltfläche, nicht Teil der Liste. */
  header nav ul li:last-child{border-bottom:0;margin-top:1.8rem;align-self:flex-start}
  header nav ul li:last-child a::before{display:none}
  .nav-cta{display:inline-flex;background:var(--white);color:var(--forest);
    padding:.95rem 1.7rem!important;font-size:var(--s--1)!important;
    letter-spacing:.14em;text-transform:uppercase}
  .nav-cta:hover{background:var(--tea)}
}
/* Hintergrund festhalten, solange das Menü offen ist.
   Nur auf html sperren — auf body würde body zum Scroll-Container,
   und die klebende Kopfzeile klebte dann in dessen Box statt im
   Viewport und verschwände nach oben aus dem Bild. */
html.menu-lock{overflow:hidden}
/* Beide schweben über der Kopfzeile und lägen sonst auf dem Menü */
/* visibility, nicht nur opacity: Der Satzspiegel-Knopf sitzt jetzt in der
   Kopfzeile und bliebe sonst trotz Unsichtbarkeit in der Fokusfalle des
   offenen Menüs erreichbar. */
html.menu-lock .sticky-cta,html.menu-lock .gridbtn{opacity:0;visibility:hidden;pointer-events:none}

/* ─── Cover (Startseite) ─────────────────────────────────────── */
/* overflow-x:clip fängt die seitlich versetzten Registerebenen des
   Mastheads ab. clip statt hidden: erzeugt keinen Scroll-Container. */
.cover{min-height:100svh;background:var(--forest);color:var(--white);position:relative;
  overflow-x:clip;
  display:flex;flex-direction:column;justify-content:space-between;
  padding:clamp(1.2rem,3vw,2.2rem) var(--gutter)}
.cover::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 80% at 70% 0%,color-mix(in srgb,var(--olive) 45%,transparent),transparent 62%)}
.cover>*{position:relative;z-index:2}
.cover-top{display:flex;justify-content:space-between;align-items:flex-start;gap:2rem;
  font-size:var(--s--1);letter-spacing:.2em;text-transform:uppercase;font-weight:600;
  padding-bottom:1rem;border-bottom:1px solid color-mix(in srgb,var(--white) 28%,transparent);
  opacity:0;animation:fadeIn .8s 1.5s forwards}
.cover-top span:nth-child(2){color:var(--tea)}

/* Der Masthead ist eine Zeichnung, keine Schrift mehr — die Titelseite hängt
   damit nicht mehr davon ab, ob Switzer geladen hat.
   font-size bleibt var(--s-4), obwohl kein Text mehr darin steht: Der
   Registerversatz --dx/--dy rechnet in em, und kleon.js liest ihn beim
   Scrollen aus. **Wird font-size hier entfernt, bricht der Scroll-Effekt.**
   Die Maße sind von der früheren Schriftfassung übernommen, damit sich am
   Bild nichts ändert: Kastenhöhe .8em (die alte Zeilenhöhe), Zeichnung
   .736em hoch (die alte Tintenhöhe), .0436em unter der Kastenkante (wo die
   Buchstaben vorher saßen). */
.masthead{position:relative;margin:clamp(1rem,4vh,3rem) 0 0}
.masthead .ch{display:block;font-size:var(--s-4);height:.8em;position:relative;
  /* forwards: auf Wunsch zurück auf den ruhigen Zustand. Nebenwirkung —
     die füllende Animation hält den Endwert „kein Versatz" fest und steht
     in der Kaskade über den Inline-Stilen. Der Scroll-Versatz, den
     kleon.js weiterhin berechnet und schreibt, kommt dadurch nicht an.
     Wer den Registerversatz wieder sichtbar machen will: hier auf
     `backwards` stellen, sonst nichts. */
  mix-blend-mode:screen;transition:transform .5s var(--ease);animation:reg 1.5s var(--ease) forwards}
/* Jede Ebene ausser der ersten liegt absolut darueber. Geschwister-Selektor
   statt :first-child — sonst zaehlt der versteckte Textspan mit und alle
   vier Ebenen wuerden absolut, der Masthead fiele in sich zusammen. */
.masthead .ch ~ .ch{position:absolute;inset:0}
.masthead .ch svg{position:absolute;top:.0436em;left:0;
  height:.736em;width:auto;aspect-ratio:303.2/91.74;overflow:visible;display:block}
/* Vorlage für die vier Ebenen — nimmt keinen Platz ein */
.sprite{position:absolute;width:0;height:0;overflow:hidden}
.ch.a{color:var(--olive);--dx:-.08em;--dy:.05em}
.ch.b{color:var(--tea);--dx:.07em;--dy:-.04em}
.ch.c{color:var(--grey-2);--dx:.02em;--dy:.065em}
.ch.d{color:var(--white);mix-blend-mode:normal;--dx:0;--dy:0;animation-delay:.12s}
@keyframes reg{0%{transform:translate(calc(var(--dx)*7),calc(var(--dy)*7));opacity:0}
  38%{opacity:1}100%{transform:translate(0,0);opacity:1}}
@keyframes fadeIn{to{opacity:1}}
@keyframes up{from{opacity:0;transform:translateY(24px)}to{opacity:1;transform:none}}

.cover-sub{font-size:var(--s-1);font-weight:500;max-width:34ch;margin-top:1.4rem;
  color:color-mix(in srgb,var(--white) 78%,transparent);opacity:0;animation:up .9s 1.15s var(--ease) forwards}

.coverlines{list-style:none;margin:clamp(2rem,6vh,4rem) 0 0;padding:0;display:grid;gap:.1rem;max-width:min(100%,54ch)}
.coverlines li{opacity:0;animation:up .8s var(--ease) forwards}
.coverlines li:nth-child(1){animation-delay:1.3s}
.coverlines li:nth-child(2){animation-delay:1.42s}
.coverlines li:nth-child(3){animation-delay:1.54s}
.coverlines li:nth-child(4){animation-delay:1.66s}
.coverlines a{display:flex;align-items:baseline;gap:1rem;text-decoration:none;padding:.55rem 0;
  border-bottom:1px solid color-mix(in srgb,var(--white) 16%,transparent);
  transition:padding-left .4s var(--ease),color .3s}
.coverlines a:hover,.coverlines a:focus-visible{padding-left:.9rem;color:var(--tea)}
.coverlines em{font-style:normal;font-size:var(--s--1);letter-spacing:.16em;font-weight:600;
  color:var(--tea);flex:none;min-width:2.6rem}
.coverlines b{font-size:clamp(1.05rem,.9rem + .8vw,1.5rem);font-weight:600;letter-spacing:-.02em;line-height:1.2}
.coverlines a::after{content:"→";margin-left:auto;opacity:0;transform:translateX(-8px);
  transition:opacity .35s,transform .35s}
.coverlines a:hover::after,.coverlines a:focus-visible::after{opacity:1;transform:none}

.cover-bottom{display:flex;justify-content:space-between;align-items:flex-end;gap:2rem;
  margin-top:clamp(2rem,5vh,3rem);opacity:0;animation:fadeIn .8s 1.9s forwards}
.barcode{width:120px;height:44px;opacity:.8;background:repeating-linear-gradient(90deg,
  var(--white) 0 2px,transparent 2px 4px,var(--white) 4px 5px,transparent 5px 9px,
  var(--white) 9px 12px,transparent 12px 13px,var(--white) 13px 14px,transparent 14px 18px)}
.cover-bottom small{font-size:var(--s--1);letter-spacing:.18em;text-transform:uppercase;
  font-weight:600;color:color-mix(in srgb,var(--white) 62%,transparent);text-align:right}

/* ─── Innenseiten-Kopf (alle Seiten außer Startseite) ────────── */
.pagehead{background:var(--forest);color:var(--white);
  padding:calc(var(--headerh) + clamp(3.4rem,14vw - var(--headerh),7.4rem)) var(--gutter) clamp(3rem,7vw,5rem)}
.pagehead h1{font-size:var(--s-3);max-width:18ch;margin-top:1.3rem}
/* :not(.tag) ist nötig: Die Dachzeile ist ebenfalls ein <p>, und
   `.pagehead p` (0-1-1) ist spezifischer als `.tag` (0-1-0). Ohne den
   Ausschluss erbt sie die Vorspanngröße — 26,4 statt 13,1 px. */
.pagehead p:not(.tag){max-width:56ch;margin-top:1.4rem;font-size:var(--s-1);
  color:color-mix(in srgb,var(--white) 76%,transparent)}

/* ─── Rechtstexte ────────────────────────────────────────────── */
.legal{max-width:68ch}
.legal h2{font-size:var(--s-1);margin:2.8rem 0 .9rem;letter-spacing:-.02em}
.legal h2:first-child{margin-top:0}
.legal h3{font-size:var(--s-0);font-weight:700;margin:1.8rem 0 .5rem}
.legal p,.legal li{color:var(--text-soft)}
.legal ul{margin:0 0 1.1em;padding-left:1.2rem}
.legal li{margin-bottom:.4em}
.legal dl{margin:0 0 1.1em}
.legal dt{font-weight:600;color:var(--forest);margin-top:.9rem}
.legal dd{margin:0;color:var(--text-soft)}
.legal a{text-decoration:underline;text-underline-offset:.2em}
.legal .stand{margin-top:3rem;padding-top:1.2rem;border-top:var(--rule);
  font-size:var(--s--1);letter-spacing:.06em}

/* ─── Reveal beim Scrollen ───────────────────────────────────── */
/* Ohne die Klasse `js` am <html> bleibt alles sichtbar. Das Einblenden ist
   eine Zugabe des Skripts — fällt das Skript aus, wäre die Website sonst
   vollständig leer. Die Klasse setzt ein kurzes Skript im Dateikopf. */
.js .rv{opacity:0;transform:translateY(32px);transition:opacity .85s var(--ease),transform .85s var(--ease)}
.js .rv.in{opacity:1;transform:none}
/* Was beim Laden schon im Bild liegt, erscheint ohne Überblendung —
   sonst wirkt die Seite in der ersten Sekunde leer. */
.js .rv.sofort{transition:none}
.rv[data-d="1"]{transition-delay:.1s}
.rv[data-d="2"]{transition-delay:.2s}
.rv[data-d="3"]{transition-delay:.3s}

/* ─── Laufschrift ────────────────────────────────────────────── */
.statement{border-block:var(--rule);padding-block:clamp(2.5rem,6vw,4.5rem);overflow:hidden}
.ticker{--tick:clamp(2rem,6vw,4.4rem);
  display:flex;gap:2.5rem;width:max-content;animation:tick 34s linear infinite;align-items:center}
.ticker.stopped{animation-play-state:paused}
@keyframes tick{to{transform:translateX(calc(-50% - 1.25rem))}}
.ticker b{font-size:var(--tick);font-weight:700;letter-spacing:-.04em;white-space:nowrap}
/* Hier stand eine Regel, die jedes zweite Wort als Kontur setzen sollte. Sie
   hat nie gegriffen (Wort und Punkt wechseln sich ab, alle Wörter sitzen auf
   ungeraden Positionen) und ist nach Ansicht bewusst verworfen: alle Wörter
   bleiben gefüllt. Falls das Thema zurückkommt — der Weg wäre
   `.ticker b:nth-of-type(even){color:transparent;-webkit-text-stroke:1.5px var(--olive)}`. */
/* Trenner: echter Kreis wie der Punkt im kbp-Zeichen, kein Schriftzeichen —
   damit stimmt die Form exakt statt nur ungefähr. Der Durchmesser hängt an
   --tick, die Laufschrift bleibt also in einem Maß. Größer oder kleiner:
   allein den Faktor .22 ändern. */
.ticker s{flex:none;text-decoration:none;
  width:calc(var(--tick) * .22);height:calc(var(--tick) * .22);
  border-radius:50%;background:var(--olive)}

/* ─── Zielgruppen ────────────────────────────────────────────── */
.audience{display:grid;grid-template-columns:repeat(var(--cols),minmax(0,1fr));
  column-gap:var(--colgap);margin-top:3rem;border-top:var(--rule)}
.aud{grid-column:span 4}
@media(max-width:900px){.aud{grid-column:span 6}}
@media(max-width:620px){.aud{grid-column:1/-1}}
/* Beim Überfahren läuft die Fläche nach links über den Satzspiegel hinaus,
   statt den Text einzurücken — so wie ein Farbblock im Druck angeschnitten
   wird. Der Satz bleibt dadurch auf der Rasterkante stehen, bekommt aber
   optisch Luft. Stärke des Anschnitts: allein --aud-bleed ändern.
   Die Fläche fährt über clip-path herein und nicht mehr über translateY —
   sonst bräuchte .aud ein overflow:hidden, das den Anschnitt abschneidet. */
.aud{--aud-bleed:clamp(.75rem,1.4vw,1.2rem);
  padding:2.4rem 1.8rem 2.6rem 0;border-bottom:var(--rule);
  position:relative;transition:color .45s}
.aud::before{content:"";position:absolute;inset:0 0 0 calc(-1 * var(--aud-bleed));
  background:var(--forest);z-index:0;
  clip-path:inset(100% 0 0 0);transition:clip-path .5s var(--ease)}
.aud:hover::before{clip-path:inset(0 0 0 0)}
.aud:hover{color:var(--white)}
.aud:hover p,.aud:hover b{color:color-mix(in srgb,var(--white) 80%,transparent)}
.aud>*{position:relative;z-index:1}
.aud b{font-size:var(--s--1);letter-spacing:.2em;text-transform:uppercase;display:block;
  margin-bottom:1.3rem;font-weight:600;color:var(--olive-text);transition:color .45s}
.aud h3{font-size:var(--s-1);margin-bottom:.7rem}
.aud p{font-size:var(--s-0);color:var(--text-soft);margin:0;transition:color .45s}

/* ─── Leistungen ─────────────────────────────────────────────── */
.svc-intro{grid-column:1/8;margin-top:2.4rem}
@media(max-width:900px){.svc-intro{grid-column:1/-1}}
.svc-intro h2{font-size:var(--s-3);margin-bottom:1.4rem;text-wrap:balance}
.svc-list{margin-top:4.5rem;border-top:var(--rule)}
.svc{border-bottom:var(--rule);padding-block:2.6rem;display:grid;
  grid-template-columns:repeat(var(--cols),minmax(0,1fr));column-gap:var(--colgap);row-gap:1.6rem;
  align-items:start;transition:background .5s}
.svc:hover{background:linear-gradient(90deg,color-mix(in srgb,var(--tea) 40%,transparent),transparent 58%)}
.svc-h{grid-column:1/6;display:flex;align-items:baseline;gap:1.1rem;
  transition:transform .5s var(--ease)}
.svc:hover .svc-h{transform:translateX(.6rem)}
.svc>div:last-child{grid-column:7/13}
@media(max-width:900px){.svc-h,.svc>div:last-child{grid-column:1/-1}}
.svc-h em{font-style:normal;font-size:var(--s--1);color:var(--olive-text);letter-spacing:.16em;font-weight:600}
.svc h3{font-size:var(--s-2);position:relative;display:inline-block}
.svc h3::after{content:"";position:absolute;left:0;bottom:.02em;height:.07em;width:100%;background:var(--forest);
  transform:scaleX(0);transform-origin:left;transition:transform .55s var(--ease)}
.svc:hover h3::after{transform:scaleX(1)}
.svc p{color:var(--text-soft)}
.svc p:last-child{margin-bottom:0}

/* ─── Der Bogen: horizontale Projektstrecke ──────────────────── */
.sheet{background:var(--forest);color:var(--white);position:relative}
.sheet-head{padding:clamp(3.5rem,8vw,6rem) var(--gutter) 0;max-width:1500px;margin-inline:auto}
.sheet-head h2{font-size:var(--s-3);margin-top:1.3rem;max-width:16ch}
.hrail{height:340vh;position:relative}
.hstick{position:sticky;top:0;height:100svh;display:flex;align-items:center;overflow:hidden}
.htrack{display:flex;gap:clamp(1rem,2vw,2rem);padding-inline:var(--gutter);will-change:transform}
.slide{width:clamp(230px,26vw,380px);flex:none;position:relative}
.slide a{text-decoration:none;color:inherit;display:block}
.slide figure{margin:0;position:relative;aspect-ratio:3/4;overflow:hidden;
  background:color-mix(in srgb,var(--olive) 40%,var(--forest))}
.slide img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  filter:grayscale(1) contrast(1.1);transition:filter .7s,transform .9s var(--ease)}
/* Halbtonraster über den Kacheln. Punktradius und Deckkraft zusammen ergeben
   die Verdunklung: 34 % Radius deckten 36 % der Fläche, mal 0,85 Deckkraft
   ergab ~28 % Grün über dem Cover — die Titel waren kaum noch zu lesen.
   26 % Radius decken 21 %, mal 0,6 ergibt ~12 %. Raster bleibt sichtbar,
   das Bild darunter aber auch. */
.slide figure::after{content:"";position:absolute;inset:0;pointer-events:none;
  background-image:radial-gradient(color-mix(in srgb,var(--forest) 92%,transparent) 26%,transparent 28%);
  background-size:5px 5px;mix-blend-mode:multiply;opacity:.6;transition:opacity .6s}
.slide a:hover figure::after,.slide a:focus-visible figure::after{opacity:0}
.slide a:hover img,.slide a:focus-visible img{filter:none;transform:scale(1.04)}
.slide-meta{display:flex;justify-content:space-between;gap:1rem;align-items:baseline;margin-top:.9rem;
  padding-top:.7rem;border-top:1px solid color-mix(in srgb,var(--white) 24%,transparent)}
.slide-meta b{font-size:var(--s-0);font-weight:600;letter-spacing:-.015em}
.slide-meta span{font-size:var(--s--1);letter-spacing:.14em;text-transform:uppercase;
  font-weight:600;color:var(--tea);flex:none}
.hprog{position:absolute;left:var(--gutter);right:var(--gutter);bottom:clamp(1.5rem,4vh,3rem);
  height:2px;background:color-mix(in srgb,var(--white) 20%,transparent)}
.hprog i{display:block;height:100%;width:0;background:var(--tea)}
.hhint{position:absolute;left:var(--gutter);bottom:clamp(2.6rem,6vh,4.4rem);font-size:var(--s--1);
  letter-spacing:.2em;text-transform:uppercase;font-weight:600;
  color:color-mix(in srgb,var(--white) 55%,transparent)}
/* Der Knopf unter dem Bogen richtet sich an derselben Kante aus wie der
   Hinweis darüber. Der Bogen läuft randlos — nur `padding-inline`, keine
   Maximalbreite —, `.wrap` dagegen ist auf --maxw zentriert. Ab 1500 px
   Fensterbreite liefen die beiden um die halbe Differenz auseinander.
   **Nicht auf .wrap zurückstellen**, sonst kommt der Versatz wieder. */
.bogen-fuss{padding-inline:var(--gutter);padding-bottom:clamp(3rem,7vw,5rem)}

/* ─── Projektübersicht (Raster) ──────────────────────────────── */
.filterbar{display:flex;flex-wrap:wrap;gap:.55rem;margin-bottom:3rem}
.filterbar button{background:none;border:1px solid color-mix(in srgb,var(--forest) 30%,transparent);
  color:var(--forest);font-size:var(--s--1);letter-spacing:.14em;text-transform:uppercase;
  font-weight:600;padding:.6rem 1.2rem;border-radius:99px;cursor:pointer;transition:.3s}
.filterbar button:hover{border-color:var(--forest)}
.filterbar button[aria-pressed="true"]{background:var(--forest);color:var(--white);border-color:var(--forest)}

.grid{display:grid;grid-template-columns:repeat(var(--cols),minmax(0,1fr));
  column-gap:var(--colgap);row-gap:clamp(2rem,4vw,3.4rem)}
.card{grid-column:span 3}
@media(max-width:1200px){.card{grid-column:span 4}}
@media(max-width:900px){.card{grid-column:span 6}}
@media(max-width:560px){.card{grid-column:1/-1}}
.card a{text-decoration:none;color:inherit;display:block}
.card figure{margin:0;position:relative;aspect-ratio:3/4;overflow:hidden;background:var(--grey-2)}
.card img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transition:transform .8s var(--ease),filter .6s;filter:grayscale(1) contrast(1.04)}
.card a:hover img,.card a:focus-visible img{transform:scale(1.045);filter:none}
.card-meta{margin-top:1rem;padding-top:.8rem;border-top:var(--rule)}
.card-meta b{display:block;font-size:var(--s-1);font-weight:600;letter-spacing:-.025em;line-height:1.2}
.card-meta span{display:block;margin-top:.35rem;font-size:var(--s--1);letter-spacing:.14em;
  text-transform:uppercase;font-weight:600;color:var(--olive-text)}
.card-meta p{margin:.6rem 0 0;font-size:var(--s-0);color:var(--text-soft)}
.card[hidden]{display:none}

/* ─── Projekt-Detailseite ────────────────────────────────────── */
.projekt-hero{background:var(--forest);color:var(--white);
  padding:clamp(7rem,14vw,11rem) var(--gutter) clamp(3rem,7vw,5rem)}
.projekt-hero h1{font-size:var(--s-3);max-width:16ch;margin-top:1.2rem}
.projekt-hero .lead{font-size:var(--s-1);max-width:52ch;margin-top:1.4rem;
  color:color-mix(in srgb,var(--white) 78%,transparent)}
.projekt-facts{display:flex;flex-wrap:wrap;gap:1.6rem 3.5rem;margin-top:3rem;padding-top:1.4rem;
  border-top:1px solid color-mix(in srgb,var(--white) 26%,transparent)}
.projekt-facts div{min-width:8rem}
.projekt-facts dt{font-size:var(--s--1);letter-spacing:.18em;text-transform:uppercase;
  font-weight:600;color:var(--tea);margin-bottom:.35rem}
.projekt-facts dd{margin:0;font-size:var(--s-0);font-weight:500}

.case{display:grid;grid-template-columns:repeat(var(--cols),minmax(0,1fr));
  column-gap:var(--colgap);row-gap:1rem;padding-block:clamp(2.4rem,5vw,3.6rem);
  border-bottom:var(--rule);align-items:start}
.case h2{grid-column:1/5}
.case .case-body{grid-column:6/13}
@media(max-width:820px){.case h2,.case .case-body{grid-column:1/-1}}
.case:first-of-type{border-top:var(--rule)}
.case h2{font-size:var(--s-2)}
.case-body{color:var(--text-soft)}
.case-body p:last-child{margin-bottom:0}
/* Zwischenüberschriften und Aufzählungen im Projekttext. Die h3 steht eine
   Stufe unter der Spaltenüberschrift und in voller Textfarbe, damit sie sich
   vom weicheren Fließtext abhebt. */
/* line-height weicht bewusst von den 1.04 der Display-Überschriften ab: hier
   steht die h3 im Textblock und bricht auf schmalen Schirmen zweizeilig um. */
.case-body h3{font-size:var(--s-1);color:var(--forest);margin:2.2rem 0 .7rem;line-height:1.15}
.case-body h3:first-child{margin-top:0}
.case-body ul{margin:0 0 1.1em;padding-left:1.1rem}
.case-body li{margin-bottom:.4em}
.case-body li::marker{color:var(--olive-text)}
.case-body ul:last-child{margin-bottom:0}

.galerie{display:grid;gap:clamp(1rem,2.5vw,2rem);margin-top:clamp(2.5rem,6vw,4.5rem)}
.galerie img{width:100%;height:auto}
.galerie .breit{grid-column:1/-1}
@media(min-width:820px){.galerie{grid-template-columns:1fr 1fr}}

/* Raster statt gleichmäßiger Verteilung. Mit justify-content:space-between
   hing die Lage von „Alle Projekte" an der Länge der Nachbartitel — sie
   wanderte über rund 120 px und traf die Seitenmitte nie. Zwei gleich
   breite Außenspalten (1fr) rücken die Mittelspalte exakt in die Mitte.
   Der obere Abstand hält die Trennlinie von der letzten Abbildung frei;
   vorher stieß das Bild ohne Luft an die Linie. */
.projekt-nav{display:grid;grid-template-columns:1fr auto 1fr;
  align-items:baseline;gap:2rem;margin-top:clamp(2.5rem,6vw,4.5rem);
  padding-block:clamp(2.5rem,6vw,4rem);border-top:var(--rule)}
/* Folgt die Navigation direkt auf einen Textblock statt auf eine
   Bildstrecke, liegen zwei Linien übereinander: `.case` bringt eine
   Unterlinie mit, die Navigation ihre eigene Oberlinie. Betrifft derzeit
   nur SBZ — die einzige Projektseite, die mit Text endet. Dann übernimmt
   die Linie des Textblocks, und der Abstand entfällt mit. */
.case + .projekt-nav{border-top:none;margin-top:0}
.projekt-nav>:first-child{justify-self:start}
.projekt-nav>:nth-child(2){justify-self:center;text-align:center}
.projekt-nav>:last-child{justify-self:end;text-align:right}
/* Am Anfang und am Ende der Kette fehlt ein Nachbar; dort steht statt des
   Links ein leeres <span>. „Alle Projekte" blieb dann zwar mittig, aber
   die leere Hälfte daneben ließ es verloren wirken. Fehlt ein Nachbar,
   rückt es deshalb an dessen Platz: beim ersten Projekt nach links, beim
   letzten nach rechts. Der vorhandene Nachbar hält die Gegenseite. */
@media(min-width:701px){
  .projekt-nav:has(> span:first-child){grid-template-columns:auto 1fr}
  .projekt-nav:has(> span:first-child) > span:first-child{display:none}
  .projekt-nav:has(> span:first-child) > :nth-child(2){justify-self:start;text-align:left}

  .projekt-nav:has(> span:last-child){grid-template-columns:1fr auto}
  .projekt-nav:has(> span:last-child) > span:last-child{display:none}
  .projekt-nav:has(> span:last-child) > :nth-child(2){justify-self:end;text-align:right}
}

/* Schmale Schirme: vor und zurück nebeneinander, „Alle Projekte"
   darunter mittig — drei lange Titel nebeneinander werden sonst zu eng. */
@media(max-width:700px){
  .projekt-nav{grid-template-columns:1fr 1fr;row-gap:1.5rem}
  .projekt-nav>:first-child{grid-area:1/1}
  .projekt-nav>:last-child{grid-area:1/2}
  .projekt-nav>:nth-child(2){grid-area:2/1/3/-1;justify-self:center}
  /* Am Kettenanfang und -ende gibt es keine zweite Zeile zu füllen:
     „Alle Projekte" rückt neben den vorhandenen Nachbarn statt darunter. */
  .projekt-nav:has(> span:first-child),
  .projekt-nav:has(> span:last-child){grid-template-columns:1fr 1fr;row-gap:0}
  .projekt-nav:has(> span:first-child) > span:first-child,
  .projekt-nav:has(> span:last-child) > span:last-child{display:none}
  .projekt-nav:has(> span:first-child) > :nth-child(2){grid-area:1/1;
    justify-self:start;text-align:left}
  .projekt-nav:has(> span:last-child) > :nth-child(2){grid-area:1/2;
    justify-self:end;text-align:right}
  .projekt-nav:has(> span:last-child) > :first-child{grid-area:1/1}
}
.projekt-nav a{font-size:var(--s-1);font-weight:600;letter-spacing:-.02em;text-decoration:none;
  transition:color .3s}
.projekt-nav a:hover{color:var(--olive)}

/* ─── Gründerinnen ───────────────────────────────────────────── */
.founders{background:var(--tea);color:var(--forest)}
.founders .tag{color:var(--forest)}
/* Die Seitenzahl stand mit 62 % Deckung im HTML und erreichte auf Tea Green
   nur 3,20:1. 80 % ergeben 4,86:1 — geprüft. */
.founders .page-no{color:color-mix(in srgb,var(--forest) 80%,transparent)}
/* Im Ansprechpartnerin-Block füllt das Porträt seine Spalte. Mit den
   allgemeinen 17rem stand es mit 272 px in einer 415 px breiten Spalte
   und wirkte verloren. Mehr Abstand zur Schaltfläche, 24 px waren zu
   knapp. */
/* Der Ansprechpartnerin-Block mit Porträt ist anders gebaut als der auf
   der Startseite: dort stehen zwei Textspalten und der Knopf unten rechts,
   deshalb `align-items:end`. Hier steht das Bild allein in der rechten
   Spalte und soll oben mit dem Text abschließen — die Regel greift über
   `:has(.portraet)` nur in diesem Fall. */
.fgrid:has(.portraet){align-items:start}
/* Eine Spalte weiter links als sonst (8/12 statt 9/13): so rückt das Bild
   an den Text heran, ohne dabei größer zu werden. */
.fgrid:has(.portraet)>*:last-child{grid-column:8/12}
.founders .portraet{width:100%;margin-bottom:0}
.founders .btn{margin-top:2rem}
@media(max-width:820px){
  /* Gestapelt füllte das Bild die ganze Breite — auf dem Tablet ergab das
     rund 700 px. Die Deckelung greift erst dort: auf dem Smartphone ist die
     Spalte ohnehin schmaler als 22rem, dort ändert sich nichts. */
  .founders .portraet{max-width:22rem}
}
.founders h2{font-size:var(--s-3);max-width:16ch;margin-block:1.3rem 2rem}
.founders p{max-width:52ch;color:color-mix(in srgb,var(--forest) 88%,transparent)}
.fgrid{display:grid;grid-template-columns:repeat(var(--cols),minmax(0,1fr));
  column-gap:var(--colgap);row-gap:2.5rem;align-items:end}
.fgrid>*:first-child{grid-column:1/8}
.fgrid>*:last-child{grid-column:9/13}
@media(max-width:820px){.fgrid>*{grid-column:1/-1!important}}

.btn{display:inline-flex;align-items:center;gap:.7rem;background:var(--forest);color:var(--white);
  font-size:var(--s--1);letter-spacing:.16em;text-transform:uppercase;font-weight:600;
  padding:1rem 1.7rem;border-radius:99px;text-decoration:none;border:none;cursor:pointer;
  transition:transform .35s var(--ease),box-shadow .35s,background .3s}
.btn:hover{transform:translateY(-3px);box-shadow:0 14px 34px rgba(0,0,0,.18);background:var(--forest-dark)}
/* Auf dunklen Flächen dreht der Knopf um. **Diese Liste muss zur Konstante
   DARK in kleon.js passen.** Vorher fehlten .sheet und .projekt-hero —
   dadurch stand „Alle Projekte ansehen“ im Bogen als Forest auf Forest,
   sichtbar war nur die Schrift. Kommt eine dunkle Fläche dazu: hier mit
   eintragen. */
.dark .btn,.starter .btn,.sheet .btn,.cover .btn,.pagehead .btn,
.projekt-hero .btn,.kolophon .btn{background:var(--white);color:var(--forest)}
.dark .btn:hover,.starter .btn:hover,.sheet .btn:hover,.cover .btn:hover,
.pagehead .btn:hover,.projekt-hero .btn:hover,.kolophon .btn:hover{background:var(--tea)}

.paket{border-top:var(--rule);margin-top:3rem}
.paket-item{border-bottom:1px solid color-mix(in srgb,var(--forest) 22%,transparent);
  padding-block:1.8rem;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.4fr);gap:1rem 3rem}
.paket-item h3{font-size:var(--s-1)}
.paket-item p{margin:0}
@media(max-width:700px){.paket-item{grid-template-columns:1fr}}

/* ─── Kundenstimmen ──────────────────────────────────────────── */
.quotes{display:grid;grid-template-columns:repeat(var(--cols),minmax(0,1fr));
  column-gap:var(--colgap);margin-top:3rem;border-top:var(--rule)}
.quotes figure{grid-column:span 4}
@media(max-width:1000px){.quotes figure{grid-column:span 6}}
@media(max-width:660px){.quotes figure{grid-column:1/-1}}
.quotes figure{margin:0;padding:2.4rem 2rem 2.4rem 0;border-bottom:var(--rule)}
blockquote{margin:0 0 1.6rem;font-size:var(--s-1);line-height:1.34;font-weight:500;letter-spacing:-.018em}
blockquote::before{content:"„";font-size:1.5em;color:var(--olive);line-height:0;
  vertical-align:-.16em;font-weight:700}
.quotes figcaption{display:flex;gap:.9rem;align-items:center}
/* Alle fünf Vorlagen sind Hochformate mit dem Kopf zwischen 25 und 38 % der
   Bildhöhe. Der mittige Ausschnitt (Vorgabe 50 %) begann erst bei 17 % und
   schnitt die Köpfe an. 15 % lässt bei allen fünf Luft über dem Kopf. */
.quotes figcaption img{width:64px;height:64px;border-radius:50%;object-fit:cover;
  object-position:50% 15%;filter:grayscale(1);background:var(--tea);flex:none}
/* Bildnachweis unter dem Porträt, wo einer nötig ist */
.quotes figcaption small{display:block;margin-top:.3rem;font-size:.68rem;
  letter-spacing:.04em;color:var(--text-soft)}
/* Name und Position stehen dicht beieinander — ohne eigene Zeilenhöhe erben
   beide die 1.62 des Fließtexts und fallen beim Umbruch auseinander. */
.quotes figcaption b{display:block;font-size:var(--s-0);font-weight:700;
  letter-spacing:-.02em;line-height:1.2}
.quotes figcaption span span{display:block;font-size:.72rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--text-soft);font-weight:500;
  line-height:1.3;margin-top:.2rem}

/* ─── Studio ─────────────────────────────────────────────────── */
.team{display:grid;grid-template-columns:repeat(var(--cols),minmax(0,1fr));
  column-gap:var(--colgap);row-gap:3rem;margin-top:3.4rem}
.team article{grid-column:span 6}
@media(max-width:820px){.team article{grid-column:1/-1}}
/* Porträts. Die Datei liegt im nativen 2:3 vor, der Ausschnitt entsteht erst
   hier — so lässt er sich nachjustieren, ohne das Bild neu zu rechnen.
   object-position hält den Kopf oben, beschnitten wird unten. */
/* height:auto ist Pflicht — die Attribute width/height am <img> setzen sonst
   eine feste Höhe, gegen die aspect-ratio nicht ankommt. */
/* Ohne .team davor, weil dasselbe Porträt auch im Ansprechpartnerin-Block
   auf der Gründer:innen-Seite steht. Sonst stünde die Regel zweimal. */
.portraet{display:block;width:min(100%,17rem);height:auto;aspect-ratio:4/5;
  object-fit:cover;object-position:50% 10%;margin-bottom:1.5rem;background:var(--grey-2)}
.team h3{font-size:var(--s-2);margin-bottom:.4rem}
.team .role{font-size:var(--s--1);letter-spacing:.2em;text-transform:uppercase;font-weight:600;
  color:var(--olive-text);margin-bottom:1.5rem}
.team p{color:var(--text-soft)}

/* ─── Projekt-Starter ────────────────────────────────────────── */
.starter{background:var(--forest);color:var(--white)}
.starter h2{font-size:var(--s-3);margin-block:1.3rem 2.5rem;max-width:15ch}
.q{margin-bottom:2.2rem}
.q>p{font-size:var(--s--1);letter-spacing:.18em;text-transform:uppercase;font-weight:600;
  color:color-mix(in srgb,var(--white) 62%,transparent);margin-bottom:.9rem}
.opts{display:flex;flex-wrap:wrap;gap:.6rem}
.opt{background:none;border:1px solid color-mix(in srgb,var(--white) 38%,transparent);color:var(--white);
  font-size:var(--s-0);font-weight:500;padding:.7rem 1.3rem;border-radius:99px;cursor:pointer;
  transition:background .3s,color .3s,border-color .3s,transform .3s var(--ease)}
.opt:hover{transform:translateY(-2px);border-color:var(--tea)}
.opt[aria-pressed="true"]{background:var(--tea);color:var(--forest);border-color:var(--tea)}
.starter-out{margin-top:2.5rem;padding-top:2rem;
  border-top:1px solid color-mix(in srgb,var(--white) 22%,transparent);
  display:flex;flex-wrap:wrap;gap:1.5rem 2.5rem;align-items:center;justify-content:space-between}
#preview{font-size:var(--s-1);font-weight:600;letter-spacing:-.02em;max-width:44ch;line-height:1.3}
#preview u{text-decoration:none;color:var(--tea);border-bottom:2px solid var(--tea)}

/* ─── Kontakt & Fuß ──────────────────────────────────────────── */
.contact{border-top:var(--rule)}
.contact h2{font-size:var(--s-3);max-width:14ch;margin-block:1.3rem 2.4rem}
.clinks{display:flex;flex-wrap:wrap;gap:1rem 3rem;font-size:var(--s-1);font-weight:600;letter-spacing:-.02em}
.clinks a{text-decoration:none;border-bottom:3px solid var(--olive);transition:color .3s}
.clinks a:hover{color:var(--olive)}
/* ─── Kolophon ───────────────────────────────────────────────────
   Die Rückseite der Ausgabe: dunkler Block, Angaben in Spalten auf
   demselben Satzspiegel wie alles andere, unten der Strichcode als Echo
   der Titelseite. Der Block zählt zu den dunklen Flächen — er steht
   deshalb in der Konstante DARK in kleon.js, damit die Kopfzeile beim
   Herunterscrollen auf Weiß dreht. */
/* Unten so viel Platz, dass der schwebende Kontakt-Knopf über Fläche steht
   und nicht auf der Ausgabezeile — er bleibt hier sichtbar, seit er die
   Farbe des Untergrunds annimmt. Die Rechnung: Abstand vom Rand, Höhe des
   Knopfes, Luft. Ändert sich --stickyh, stimmt sie weiterhin. */
/* Der Abstand über dem Kolophon trennt hellen Inhalt vom dunklen Fuß.
   Endet die Seite aber schon auf einer Farbfläche — mit dem Abschlussblock
   „Ähnliches Vorhaben?" oder mit dem Ansprechpartnerin-Block —, riss er
   einen weißen Streifen zwischen zwei Farbflächen. Dann entfällt er, und
   eine feine Linie übernimmt die Trennung.
   **Diese Liste ergänzen, sobald eine Seite auf einer neuen Farbfläche
   endet** — sonst steht der weiße Streifen wieder da. */
main:has(> .starter:last-child) + footer.kolophon,
main:has(> .founders:last-child) + footer.kolophon{margin-top:0;
  border-top:1px solid color-mix(in srgb,var(--white) 20%,transparent)}

footer.kolophon{background:var(--forest);color:var(--white);
  padding-block:clamp(3.5rem,8vw,6rem) calc(1rem + var(--stickyh) + 1.5rem);
  margin-top:clamp(4rem,10vw,8rem)}
.kolophon .raster{row-gap:2.8rem}
.kolophon :focus-visible{outline-color:var(--tea)}

.kol-marke{grid-column:1/5}
.kol-marke svg{height:58px;width:auto;display:block;flex:none;
  aspect-ratio:398.3/516.2;overflow:visible}
.kol-marke p{margin:1.5rem 0 0;max-width:28ch;font-size:var(--s-0);line-height:1.55;
  color:color-mix(in srgb,var(--white) 74%,transparent)}

.kol-rubriken{grid-column:5/8}
.kol-kontakt{grid-column:8/11}
.kol-recht{grid-column:11/13}

.kolophon h2{font-size:var(--s--1);letter-spacing:.2em;text-transform:uppercase;
  font-weight:600;color:var(--tea);margin:0 0 1.2rem}
.kolophon ul{list-style:none;margin:0;padding:0;display:grid;gap:.6rem}
.kolophon a{text-decoration:none;color:color-mix(in srgb,var(--white) 82%,transparent);
  transition:color .3s}
.kolophon a:hover{color:var(--tea)}
/* WCAG 2.2 AA, 2.5.8 „Zielgrösse": Ein Bedienelement muss mindestens
   24x24 px gross sein. Diese Links sind inline — ihr anklickbarer Bereich
   ist damit nur so hoch wie die Schrift selbst; gemessen 20 px auf dem
   Telefon, 23 px am Rechner. inline-block macht die Zeilenhöhe zur Höhe
   des Bereichs. Am Bild ändert sich dadurch nichts, die Zeilen stehen wie
   vorher — nur die Trefferfläche wächst.
   Ausgenommen der Wortmarken-Link, der ist ohnehin gross genug und trägt
   eine eigene Auszeichnung. */
/* Die Icon-Knoepfe sind ausgenommen. Sie sind 44x44 gross, liegen also
   weit ueber der Anforderung — und sie brauchen ihr inline-flex, um das
   Icon zu zentrieren. Ohne diese Ausnahme gewann `display:inline-block`
   von hier (zwei Klassen plus Element) gegen `.social a` (eine Klasse
   plus Element): Das Icon rutschte in die linke obere Ecke, waehrend die
   runde Hoverflaeche 44x44 blieb — gemessen 12 px Versatz in beide
   Richtungen. */
.kolophon a:not(.kol-logo):not(.social a),.projekt-facts dd a,
.legal dd a,.legal address a{display:inline-block;min-height:24px}
.kolophon .social a{display:inline-flex}
/* Die Spalten stehen in <nav>-Elementen und erbten sonst die Versalien der
   Kopfnavigation. Hier lesen sie sich als Register, nicht als Menüleiste. */
.kolophon nav a{font-size:var(--s-0);letter-spacing:0;text-transform:none;
  font-weight:500;padding-block:0}
.kolophon nav a::after{display:none}
.kolophon address{font-style:normal;line-height:1.8;
  color:color-mix(in srgb,var(--white) 74%,transparent)}

.kol-fuss{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:1.4rem 2rem;margin-top:clamp(3rem,6vw,4.5rem);padding-top:1.6rem;
  border-top:1px solid color-mix(in srgb,var(--white) 20%,transparent);
  font-size:var(--s--1);letter-spacing:.06em;
  color:color-mix(in srgb,var(--white) 62%,transparent)}
.kol-ausgabe{letter-spacing:.2em;text-transform:uppercase;font-weight:600}
/* display:flex muss hier stehen: `.kolophon ul` setzt display:grid und
   würde die beiden Zeichen sonst untereinander stapeln. */
.kolophon .social{display:flex;flex:none;gap:.4rem}
.kolophon .social a{color:color-mix(in srgb,var(--white) 82%,transparent)}
.kolophon .social a:hover{color:var(--forest);background:var(--tea)}

@media(max-width:900px){
  .kol-marke{grid-column:1/7}
  .kol-rubriken{grid-column:8/13}
  .kol-kontakt{grid-column:1/7}
  .kol-recht{grid-column:8/13}
}
@media(max-width:560px){
  .kol-marke,.kol-rubriken,.kol-kontakt,.kol-recht{grid-column:1/-1}
  .kol-fuss{justify-content:flex-start}
}

/* Die Netzwerknamen stehen als Text im Markup und werden nur optisch
   ausgeblendet — Screenreader lesen sie, das Icon allein wäre stumm. */
.social{display:flex;gap:.4rem;list-style:none;margin:0;padding:0}
.social a{display:inline-flex;align-items:center;justify-content:center;
  width:2.75rem;height:2.75rem;border-radius:99px;color:var(--text-soft);
  transition:color .3s,background .3s}
.social a:hover{color:var(--forest);background:color-mix(in srgb,var(--olive) 16%,transparent)}
.social svg{width:1.25rem;height:1.25rem;display:block}
.social span{position:absolute;width:1px;height:1px;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap}

/* min-height macht --stickyh zur verbindlichen Größe: Solange sie gilt,
   stimmt der Abstand, mit dem der Satzspiegel-Umschalter darüber sitzt. */
.sticky-cta{position:fixed;right:1rem;bottom:1rem;z-index:9975;background:var(--forest);color:var(--white);
  min-height:var(--stickyh);display:inline-flex;align-items:center;
  font-size:var(--s--1);letter-spacing:.16em;text-transform:uppercase;font-weight:600;
  padding:.9rem 1.4rem;border-radius:99px;text-decoration:none;box-shadow:0 10px 30px rgba(0,0,0,.2);
  opacity:0;transform:translateY(20px);pointer-events:none;transition:.45s var(--ease)}
.sticky-cta.show{opacity:1;transform:none;pointer-events:auto}
.sticky-cta:hover{background:var(--olive)}
/* Wie die Kopfzeile: Liegt unter dem Knopf eine dunkle Fläche, dreht er um.
   kleon.js misst dafür auf seiner eigenen Höhe, nicht auf der des Kopfes. */
.sticky-cta.on-dark{background:var(--white);color:var(--forest)}
.sticky-cta.on-dark:hover{background:var(--tea)}


/* ─── Bewegung auf den Projektseiten ─────────────────────────────
   1. Bilder werden aufgedeckt statt eingeblendet: Die Maske fährt von
      unten hoch, das Bild fährt dabei aus einer leichten Vergrößerung
      zurück — wie ein Bogen, der aus der Maschine läuft. Der Blockfade
      von .rv wird dafür abgeschaltet, sonst überlagern sich zwei Effekte.
   2. Die Abschnittsüberschrift bleibt stehen, während der Text daneben
      weiterläuft. Nur am Schreibtisch — mobil liegen beide untereinander.
   Beides läuft über reine CSS-Übergänge; die Klasse .in setzt bereits
   der vorhandene Beobachter in kleon.js. Kein zusätzliches Skript. */
.galerie.rv{opacity:1;transform:none}
.galerie img{clip-path:inset(0 0 100% 0);transform:scale(1.05);
  transition:clip-path 1.1s var(--ease),transform 1.5s var(--ease)}
.galerie.in img{clip-path:inset(0 0 0 0);transform:none}
.galerie.in img:nth-child(2){transition-delay:.12s}
.galerie.in img:nth-child(3){transition-delay:.24s}
.galerie.in img:nth-child(4){transition-delay:.36s}

@media(min-width:820px){
  /* align-self:start ist nötig: Im Raster streckt sich das Element sonst
     über die volle Zeilenhöhe und hat nichts, woran es kleben könnte. */
  .case h2{position:sticky;top:calc(var(--headerh) + 2.5rem);align-self:start}
}


/* ─── Vorher/Nachher-Schieber ────────────────────────────────────
   Zwei deckungsgleiche Abbildungen übereinander; die obere wird über
   clip-path aufgezogen. Gesteuert von einem echten <input type="range">
   — damit ist der Vergleich von Haus aus mit der Tastatur bedienbar und
   braucht keine Fremdbibliothek. Ohne JavaScript bleibt er bei 50 %
   stehen und zeigt weiterhin beide Hälften.
   **Beide Bilder müssen dieselben Abmessungen haben**, sonst liegen sie
   nicht deckungsgleich. */
.vergleich{--pos:50%;margin-top:clamp(2.5rem,6vw,4.5rem)}
/* Der Bezugsrahmen umfasst nur die Bilder — läge die Bildunterschrift darin,
   zöge sich das obere Bild über sie hinweg und die beiden wären nicht mehr
   deckungsgleich. */
.vergleich-buehne{position:relative}
.vergleich img{width:100%;height:auto;display:block}
.vergleich img + img{position:absolute;inset:0;height:100%;object-fit:cover;
  clip-path:inset(0 0 0 var(--pos))}
.vergleich input[type=range]{position:absolute;inset:0;width:100%;height:100%;
  margin:0;appearance:none;background:none;cursor:ew-resize}
.vergleich input[type=range]::-webkit-slider-thumb{appearance:none;
  width:2.75rem;height:2.75rem;border-radius:99px;cursor:ew-resize;
  background:var(--white);border:2px solid var(--forest)}
.vergleich input[type=range]::-moz-range-thumb{width:2.75rem;height:2.75rem;
  border-radius:99px;cursor:ew-resize;background:var(--white);border:2px solid var(--forest)}
/* Die Trennlinie sitzt genau dort, wo die Maske ansetzt. */
.vergleich-buehne::after{content:"";position:absolute;top:0;bottom:0;left:var(--pos);
  width:2px;background:var(--white);pointer-events:none;
  box-shadow:0 0 0 1px color-mix(in srgb,var(--forest) 30%,transparent)}
.vergleich figcaption{display:flex;justify-content:space-between;
  margin-top:.9rem;font-size:var(--s--1);letter-spacing:.16em;
  text-transform:uppercase;font-weight:600;color:var(--olive-text)}

/* ─── Reduzierte Bewegung ────────────────────────────────────── */
/* ─── Abweichungen einzelner Blöcke ──────────────────────────────
   Diese Angaben standen als Inline-Stile in den HTML-Dateien, entgegen der
   Konvention. Sie sind **bewusste Abweichungen** von den Regeln weiter oben
   (`.starter h2`, `.svc-intro h2`), deshalb stehen sie hier am Dateiende:
   Bei gleicher Spezifität gewinnt die spätere Regel — dafür sind die
   Selektoren mit dem Element qualifiziert (`h2.klasse` statt `.klasse`).
   **Dieser Block muss am Ende bleiben.** Weiter oben verlieren die Klassen
   gegen die Kontextregeln, und die Überschriften springen auf deren Maße.
   Eigene Klassen statt Kontextselektoren, weil dieselben Bausteine auf
   anderen Seiten in der Standardgröße vorkommen. */
h2.h2-abschnitt{font-size:var(--s-3);margin-top:1.3rem;max-width:20ch}
/* Nur die Größe überschreiben — den unteren Abstand liefert weiterhin
   `.svc-intro h2`. Ein `margin-bottom:0` hier räumt ihn ab. */
h2.h2-mittel{font-size:var(--s-2)}
h2.h2-person{font-size:var(--s-2);margin-block:1.2rem}

/* Abschlussblock „Ähnliches Vorhaben?“ der Unterseiten — nicht zu
   verwechseln mit dem Projekt-Starter der Startseite, der im selben
   .starter-Abschnitt liegt, aber anders aufgebaut ist. */
h2.starter-h2{font-size:var(--s-3);margin-block:1.3rem 1.5rem;max-width:16ch}
p.starter-text{max-width:48ch;color:color-mix(in srgb,var(--white) 72%,transparent)}
p.starter-text + .btn{margin-top:1.5rem}

/* Ansprechpartnerin im Gründerinnen-Anreißer */
p.ansprech{font-size:var(--s--1);letter-spacing:.2em;text-transform:uppercase;font-weight:600}
p.ansprech strong{font-size:var(--s-1);letter-spacing:-.02em;text-transform:none;font-weight:700}

.quotes.einspaltig{grid-template-columns:1fr}

@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-duration:.01ms!important}
  .rv{opacity:1;transform:none}
  .galerie img{clip-path:none;transform:none}
  .cover-top,.cover-sub,.coverlines li,.cover-bottom{opacity:1}
  .ticker{animation:none;flex-wrap:wrap;width:auto}
  .hrail{height:auto}
  .hstick{position:static;height:auto;padding-block:3rem}
  .htrack{flex-wrap:wrap;gap:2rem;transform:none!important}
  .slide{width:min(100%,320px)}
  .hprog,.hhint{display:none}
  .slide figure::after{opacity:0}
}

/* ─── Abschlussblock hell ────────────────────────────────────────
   „Ähnliches Vorhaben?" auf Projektübersicht und Projektseiten. Vorher
   Waldgrün — damit stießen nach dem Schließen des weißen Zwischenraums
   zwei gleiche Grünflächen aneinander. Tee-Grün mit Waldgrün-Schrift ist
   dasselbe Muster wie der Gründer:innen-Block; gemessener Kontrast 8,0:1.

   **Nur der kurze Abschluss ist hell.** Der Frage-Baustein auf der
   Startseite („Worum geht es?") steckt ebenfalls in `.starter`, bleibt
   aber dunkel — seine Auswahlknöpfe sind auf dunklen Grund gerechnet.
   Deshalb die zusätzliche Klasse statt einer Änderung an `.starter`.

   **`DARK` in kleon.js musste mit**: dort steht jetzt
   `.starter:not(.starter-hell)`, sonst bliebe der Kopf über der hellen
   Fläche weiß auf hell. */
.starter-hell{background:var(--tea);color:var(--forest)}
.starter-hell .tag{color:var(--forest)}
.starter-hell :focus-visible{outline-color:var(--forest)}
.starter-hell .btn{background:var(--forest);color:var(--white)}
.starter-hell .btn:hover{background:var(--forest-dark);color:var(--white)}
.starter-hell h2.starter-h2{color:var(--forest)}
.starter-hell p.starter-text{color:color-mix(in srgb,var(--forest) 82%,transparent)}
