/* Token Partners — One-Pager
   Werte 1:1 aus dem Design (Claude Design, "Token Partners v4").
   Farben: Grund #FFFFFF, Text #0B0B0C, Absatz #4A4A52, leise #7A7A83 / #8C8C94 /
   #A6A6AC, Haarlinie #ECECEF, Rahmen #DEDEE3, Akzent #2D6BFF, Hover #1B4FD1. */

:root {
  --ink: #0B0B0C;
  --ink-2: #4A4A52;
  --ink-3: #7A7A83;
  --mono: #8C8C94;
  --quiet: #A6A6AC;
  --hair: #ECECEF;
  --line: #DEDEE3;
  --blue: #2D6BFF;
  --blue-dark: #1B4FD1;
  --ease: cubic-bezier(.22, .61, .36, 1);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  /* kein Hintergrund auf dem Wurzelelement: das Spine-Canvas liegt auf z-index:-1 */
  background: #FFFFFF;
  color: var(--ink);
  font-family: 'Space Grotesk', system-ui, -apple-system, 'Segoe UI', sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* Browser setzen bei textarea und Co. eigene Schriften, textarea sogar Monospace. */
input, textarea, button, select { font-family: inherit; font-size: inherit; }

a { color: var(--blue); text-decoration: none; }
a:hover { color: var(--blue-dark); }
::selection { background: var(--blue); color: #fff; }
:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; }

.page { width: 100%; overflow-x: hidden; }

/* ---------- Raster ---------- */

.wrap { max-width: 1200px; margin: 0 auto; padding: 0 clamp(20px, 5vw, 48px); }
.sec { border-bottom: 1px solid var(--hair); }
.sec-pad { padding-top: clamp(64px, 7.7vw, 94px); padding-bottom: clamp(64px, 7.7vw, 94px); }

/* Umbrechendes Flex statt Grid: Grid bricht die Textspalte auf schmalen Viewports. */
.row {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(32px, 4vw, 64px);
  align-items: flex-start;
}
.row--mid { align-items: center; }
.col { flex: 1 1 420px; min-width: 0; }

.lbl {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--mono);
}
.lbl--side { flex: 0 0 220px; padding-top: 12px; }
.lbl--side-tight { flex: 0 0 220px; padding-top: 10px; }

/* ---------- Typografie ---------- */

h1, h2, h3 { margin: 0; font-weight: 400; }

.h1 {
  font-size: clamp(40px, 6vw, 80px);
  line-height: 1.02;
  font-weight: 300;
  letter-spacing: -0.038em;
  text-wrap: balance;
}
.h2 {
  font-size: clamp(32px, 4.6vw, 54px);
  line-height: 1.07;
  font-weight: 300;
  letter-spacing: -0.032em;
}
.h2--contact {
  font-size: clamp(38px, 5.6vw, 70px);
  line-height: 1.03;
  font-weight: 300;
  letter-spacing: -0.035em;
  text-wrap: balance;
}
.h2--name {
  font-size: clamp(30px, 3.4vw, 40px);
  line-height: 1.1;
  font-weight: 400;
  letter-spacing: -0.03em;
}
.blue { color: var(--blue); }

.lead, .body {
  color: var(--ink-2);
  text-wrap: pretty;
}
.lead { font-size: 19px; line-height: 1.6; }
.body { font-size: 18px; line-height: 1.65; }

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  border-radius: 2px;
  font-weight: 500;
  transition: background 180ms ease, border-color 180ms ease,
              transform 180ms ease, box-shadow 180ms ease;
}
.btn--primary { background: var(--blue); color: #FFFFFF; }
.btn--primary:hover { background: var(--blue-dark); color: #FFFFFF; }
.btn--ghost { color: var(--ink); border: 1px solid var(--line); font-weight: 400; }
.btn--ghost:hover { color: var(--ink); border-color: var(--ink); transform: translateY(-2px); }

/* nowrap: auf 375px brechen Schriftzug und Button sonst je zweizeilig um */
.btn--nav { height: 42px; padding: 0 22px; font-size: 14px; white-space: nowrap; }
.btn--nav:hover { transform: translateY(-1px); }
.btn--hero { height: 54px; padding: 0 32px; font-size: 15px; }
.btn--hero.btn--primary:hover { transform: translateY(-2px); box-shadow: 0 10px 30px rgba(45, 107, 255, 0.24); }
.btn--hero.btn--ghost { padding: 0 26px; }
.btn--contact { height: 56px; padding: 0 34px; font-size: 16px; }
.btn--contact:hover { transform: translateY(-2px); box-shadow: 0 12px 34px rgba(45, 107, 255, 0.26); }

/* ---------- Header ---------- */

.header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: rgba(255, 255, 255, 0.86);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--hair);
}
.header .wrap {
  padding-top: 20px;
  padding-bottom: 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
/* Der Schriftzug ist die Marke, es gibt kein Logo. */
.wordmark { font-size: 19px; letter-spacing: -0.01em; color: var(--ink); white-space: nowrap; }
.wordmark:hover { color: var(--ink); }
.wordmark b { font-weight: 700; }
.wordmark span { font-weight: 400; }

/* ---------- Hero ---------- */

.hero { position: relative; border-bottom: 1px solid var(--hair); overflow: hidden; }
.hero .wrap {
  position: relative;
  padding-top: clamp(64px, 7.7vw, 114px);
  padding-bottom: clamp(56px, 6.9vw, 94px);
  display: flex;
  flex-wrap: wrap;
  gap: clamp(32px, 4vw, 56px);
  align-items: center;
}
.hero__text { flex: 1 1 460px; min-width: 0; }
.hero__art { flex: 1 1 380px; min-width: 0; }
.hero__kicker { letter-spacing: 0.16em; }
.hero .h1 { margin-top: 32px; }
.hero .lead { margin-top: 36px; max-width: 520px; }
.hero__cta { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 44px; }
.hero__stage { position: relative; height: clamp(300px, 36vw, 480px); }

canvas.fill { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
#tp-net { pointer-events: none; }
#tp-mesh { cursor: crosshair; }
#tp-spine { position: fixed; inset: 0; width: 100%; height: 100%; display: block; pointer-events: none; z-index: -1; }

.glow {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 500ms ease;
}
#tp-glow {
  width: 440px; height: 440px; margin: -220px 0 0 -220px;
  background: radial-gradient(circle, rgba(45,107,255,0.055) 0%, rgba(45,107,255,0.028) 40%, rgba(45,107,255,0) 72%);
}
#tp-glow2 {
  width: 400px; height: 400px; margin: -200px 0 0 -200px;
  background: radial-gradient(circle, rgba(45,107,255,0.05) 0%, rgba(45,107,255,0.025) 42%, rgba(45,107,255,0) 74%);
}

/* ---------- Laufband ---------- */

.ticker { border-bottom: 1px solid var(--hair); overflow: hidden; padding: 16px 0; }
.ticker__track {
  display: flex;
  width: max-content;
  animation: tp-marquee 46s linear infinite;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--quiet);
}
.ticker__set { display: flex; gap: 56px; padding-right: 56px; }

/* ---------- Kartengitter ----------
   Die Haarlinien kommen aus Rahmen je Karte, nicht aus einer grauen Containerflaeche
   mit Luecken: leere Zellen wuerden sonst als graue Bloecke stehenbleiben. */

.grid {
  display: grid;
  gap: 0;
  border-top: 1px solid var(--hair);
  border-left: 1px solid var(--hair);
}
.grid--do {
  margin-top: clamp(42px, 5.2vw, 68px);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
}
.grid--steps {
  margin-top: clamp(38px, 5.2vw, 62px);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr));
}

.card {
  background: #FFFFFF;
  border-right: 1px solid var(--hair);
  border-bottom: 1px solid var(--hair);
  transition: transform 260ms var(--ease), box-shadow 260ms ease;
}
.card:hover { position: relative; z-index: 2; }
.card--do { padding: 44px 40px 50px; }
.card--do:hover { transform: translateY(-6px); box-shadow: 0 18px 44px rgba(11, 11, 12, 0.07); }
.card--step {
  padding: 34px 30px 40px;
  min-height: 180px;
  display: flex;
  flex-direction: column;
}
.card--step:hover { transform: translateY(-5px); box-shadow: 0 16px 40px rgba(11, 11, 12, 0.06); }

.card__num {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.1em;
  color: var(--blue);
}
.card--do h3 { margin-top: 22px; font-size: 24px; line-height: 1.2; font-weight: 500; letter-spacing: -0.02em; }
.card--do p { margin: 14px 0 0; font-size: 16px; line-height: 1.6; color: var(--ink-2); text-wrap: pretty; }
.card--step h3 { margin-top: 20px; font-size: 20px; line-height: 1.22; font-weight: 500; letter-spacing: -0.015em; }
.card--step p { margin: 12px 0 0; font-size: 15px; line-height: 1.55; color: var(--ink-3); text-wrap: pretty; }

/* ---------- Bildband ---------- */

.band { position: relative; width: 100%; height: clamp(300px, 42vw, 520px); }
.band img {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  /* etwas hoeher als mittig, damit Leinwand und Louis im Anschnitt bleiben */
  object-position: 50% 38%;
}
.band__caption {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--quiet);
  padding-top: 18px;
  padding-bottom: 26px;
}

/* ---------- Oekosystem-Karte ---------- */

.map { width: 100%; height: auto; display: block; overflow: visible; }

/* ---------- Netzwerk ---------- */

.network { position: relative; border-bottom: 1px solid var(--hair); overflow: hidden; }
.network .wrap { position: relative; }

.bubbles {
  position: relative;
  width: 100%;
  max-width: 1040px;
  margin: clamp(30px, 5.2vw, 66px) auto 0;
  height: clamp(640px, 78vw, 860px);
}
#tp-bubble-net { pointer-events: none; }

.hub {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: clamp(146px, 16vw, 180px);
  height: clamp(146px, 16vw, 180px);
  border-radius: 50%;
  background: var(--blue);
  color: #FFFFFF;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 16px;
  box-shadow: 0 18px 46px rgba(45, 107, 255, 0.24);
}
.hub__name { font-size: clamp(15px, 1.6vw, 18px); line-height: 1.2; font-weight: 500; letter-spacing: -0.01em; }
.hub__sub {
  margin-top: 8px;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 9.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  opacity: 0.75;
}

/* Die Ringposition steht im CSS, nicht im JavaScript: laeuft die Animation nicht,
   sitzt das Netzwerk trotzdem richtig. --l/--t/--s kommen pro Bubble aus dem Markup. */
.tp-bubble {
  position: absolute;
  left: var(--l);
  top: var(--t);
  width: var(--s);
  height: var(--s);
  transform: translate(-50%, -50%);
  will-change: transform;
}
.tp-bubble-dot {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: #FFFFFF;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 14px;
  font-size: clamp(12.5px, 1.25vw, 14.5px);
  line-height: 1.25;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
  transition: border-color 240ms ease, box-shadow 240ms ease, transform 240ms var(--ease);
  cursor: default;
}
.tp-bubble-note {
  position: absolute;
  left: 50%;
  top: calc(100% + 10px);
  transform: translateX(-50%);
  width: min(216px, 44vw);
  padding: 10px 14px;
  background: #FFFFFF;
  border: 1px solid var(--hair);
  border-radius: 2px;
  box-shadow: 0 12px 32px rgba(11, 11, 12, 0.10);
  text-align: center;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--ink-2);
  opacity: 0;
  transition: opacity 200ms ease;
  pointer-events: none;
  text-wrap: pretty;
}

/* Schmale Viewports: der Ring passt nicht. Bei 375px Breite ueberlappen die
   Kreise den Hub, die Beschreibungen liegen uebereinander und eine Bubble wird
   vom Rand beschnitten. Darunter wird derselbe Inhalt gestapelt gezeigt, in der
   Formensprache der Kartengitter (Haarlinien, 2px Radius, keine Schatten). */
@media (max-width: 760px) {
  .bubbles {
    height: auto;
    margin-top: clamp(30px, 7vw, 56px);
    border-top: 1px solid var(--hair);
  }
  #tp-bubble-net { display: none; }

  .hub {
    position: static;
    width: 100%;
    height: auto;
    border-radius: 2px;
    transform: none;
    padding: 26px 20px;
    box-shadow: none;
    margin-bottom: 8px;
  }

  .tp-bubble {
    position: static;
    width: auto;
    height: auto;
    transform: none;
  }
  .tp-bubble-dot {
    height: auto;
    border: 0;
    border-bottom: 1px solid var(--hair);
    border-radius: 0;
    display: block;
    text-align: left;
    padding: 22px 0 0;
    font-size: 17px;
    line-height: 1.3;
    transform: none;
  }
  .tp-bubble-note {
    position: static;
    width: auto;
    opacity: 1;
    padding: 8px 0 22px;
    border: 0;
    border-bottom: 1px solid var(--hair);
    border-radius: 0;
    box-shadow: none;
    text-align: left;
    transform: none;
    font-size: 15px;
  }
  /* der Name traegt schon die Trennlinie zur Beschreibung nicht mehr */
  .tp-bubble-dot { border-bottom: 0; }
}

/* ---------- Ueber Louis ---------- */

.about__inner {
  flex: 1 1 420px;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  gap: clamp(28px, 3.5vw, 56px);
  align-items: flex-start;
  max-width: 900px;
}
/* Portraet als eingebettetes Foto im 300x380-Feld des Designs, kein Radius.
   Dezent angehoben: der Schatten nimmt die Werte des Hub-Schattens auf, damit die
   Hebung im System bleibt und nicht als Fremdkoerper wirkt. Das Bild ist beim
   Aufbereiten schon auf 300:380 geschnitten, cover fangt nur Rundungen ab. */
.portrait {
  position: relative;
  flex: 0 0 300px;
  width: 300px;
  height: 380px;
  max-width: 100%;
  overflow: hidden;
  background: var(--hair);
  box-shadow: 0 18px 46px rgba(11, 11, 12, 0.13);
  transition: transform 260ms var(--ease), box-shadow 260ms ease;
}
.portrait:hover {
  transform: translateY(-4px);
  box-shadow: 0 26px 60px rgba(11, 11, 12, 0.17);
}
.portrait img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Schmale Viewports: das Foto nimmt die volle Spaltenbreite. Bei 375px bleiben
   neben den festen 300px sonst ein paar Pixel frei und es wirkt danebengerutscht.
   Diese Regel muss nach der .portrait-Definition stehen, sonst gewinnt deren
   feste Breite bei gleicher Spezifitaet. */
@media (max-width: 760px) {
  .portrait {
    flex: 1 1 auto;
    width: 100%;
    height: auto;
    aspect-ratio: 300 / 380;
  }
}
.about__text { flex: 1 1 340px; min-width: 0; }
.about__text .body { margin-top: 26px; }
.about__links {
  display: flex;
  gap: 28px;
  margin-top: 30px;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 12px;
  letter-spacing: 0.06em;
}

/* ---------- Kontakt ---------- */

.contact .wrap {
  padding-top: clamp(70px, 8.6vw, 112px);
  padding-bottom: clamp(70px, 8.6vw, 112px);
}
.contact__row {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(40px, 6vw, 88px);
  align-items: flex-start;
}
.contact__left { flex: 1 1 420px; min-width: 0; }
.contact .h2--contact { margin-top: 30px; }
.contact__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 26px; margin-top: 40px; }
.contact__phone { font-size: 17px; color: var(--ink); }
.contact__phone:hover { color: var(--blue); }

/* ---------- Mehrstufige Anfrage ----------
   Ein Klick beantwortet und geht weiter. Der Einstieg ist absichtlich eine
   Frage, die niemand nachdenken muss, die Kontaktdaten kommen erst zuletzt.
   Ohne JavaScript sind alle vier Schritte sichtbar, das Formular bleibt nutzbar. */

.quiz { flex: 1 1 380px; min-width: 0; max-width: 460px; }

.quiz__head { margin-bottom: 26px; }
.quiz__count {
  display: block;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--mono);
  padding-bottom: 12px;
}
.quiz__bar { height: 2px; background: var(--hair); }
.quiz__bar > span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--blue);
  transition: width 320ms var(--ease);
}

.quiz__panel { border: 0; margin: 0; padding: 0; min-width: 0; }
.quiz__panel[hidden] { display: none; }
/* Greift nur ohne JavaScript, wenn alle Schritte untereinander stehen. Mit
   JavaScript ist immer genau ein Schritt sichtbar. */
.quiz__panel + .quiz__panel { margin-top: 40px; }
.quiz__panel:focus { outline: none; }
.quiz__q {
  padding: 0;
  font-size: 21px;
  line-height: 1.3;
  font-weight: 400;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-wrap: pretty;
}

.quiz__opts { display: flex; flex-direction: column; gap: 10px; margin-top: 24px; }

/* Antwort als Fläche, nicht als Radiobutton: das echte Eingabefeld bleibt für
   Tastatur und Screenreader erhalten und wird nur visuell ersetzt. */
.opt { position: relative; display: block; cursor: pointer; }
.opt input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  margin: 0;
}
.opt span {
  display: block;
  padding: 15px 18px;
  border: 1px solid var(--line);
  border-radius: 2px;
  background: #FFFFFF;
  font-size: 16px;
  line-height: 1.35;
  color: var(--ink);
  transition: border-color 180ms ease, color 180ms ease,
              background 180ms ease, transform 180ms ease;
}
.opt:hover span { border-color: var(--ink); transform: translateY(-1px); }
.opt input:focus-visible + span { outline: 2px solid var(--blue); outline-offset: 3px; }
.opt input:checked + span {
  border-color: var(--blue);
  color: var(--blue-dark);
  background: rgba(45, 107, 255, 0.06);
}

.quiz__fields { display: flex; flex-direction: column; margin-top: 26px; }
.quiz__fields input,
.quiz__fields textarea {
  border: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  font-size: 16px;
  color: var(--ink);
  border-radius: 0;
  outline: none;
  margin-bottom: 22px;
  transition: border-color 180ms ease;
}
.quiz__fields input { height: 46px; }
.quiz__fields textarea { padding: 10px 0; line-height: 1.5; resize: vertical; }
.quiz__fields input:focus,
.quiz__fields textarea:focus { border-bottom-color: var(--blue); }
.quiz__fields input::placeholder,
.quiz__fields textarea::placeholder { color: var(--quiet); }
/* Rot waere ein zweiter Akzent, den die Marke nicht hat: Fehler markiert der Rahmen. */
.quiz__fields input[aria-invalid="true"] { border-bottom-color: var(--ink); }

.quiz__send {
  align-self: flex-start;
  height: 50px;
  padding: 0 28px;
  margin-top: 4px;
  border: 1px solid var(--ink);
  background: var(--ink);
  color: #FFFFFF;
  font-size: 15px;
  font-weight: 500;
  border-radius: 2px;
  cursor: pointer;
  transition: background 180ms ease, border-color 180ms ease, transform 180ms ease;
}
.quiz__send:hover { background: var(--blue); border-color: var(--blue); transform: translateY(-2px); }
.quiz__send[disabled] {
  background: var(--line);
  border-color: var(--line);
  color: #FFFFFF;
  cursor: default;
  transform: none;
}

.quiz__note {
  margin: 14px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--quiet);
  text-wrap: pretty;
}
.quiz__status {
  margin: 14px 0 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  text-wrap: pretty;
}
.quiz__status:empty { margin: 0; }

.quiz__back {
  margin-top: 20px;
  padding: 0;
  border: 0;
  background: none;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mono);
  cursor: pointer;
  transition: color 180ms ease;
}
.quiz__back:hover { color: var(--blue); }

/* Honeypot: fuer Menschen unsichtbar, aber nicht per display:none, sonst
   erkennen Automaten die Falle. Aus dem Tabfluss ist es ueber tabindex. */
.quiz__falle {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---------- Erfolg ----------
   Wird erst gezeigt, wenn der Server die Anfrage bestaetigt hat. Der Haken
   zeichnet sich, statt einfach da zu sein: das quittiert die Handlung. */

.quiz__ok { padding: 4px 0 0; }
.quiz__ok:focus { outline: none; }

.quiz__haken { width: 56px; height: 56px; display: block; }
.quiz__haken-kreis {
  stroke: var(--blue);
  stroke-width: 2;
  stroke-dasharray: 152;
  stroke-dashoffset: 152;
  animation: tp-kreis 520ms var(--ease) forwards;
}
.quiz__haken-strich {
  stroke: var(--blue);
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 44;
  stroke-dashoffset: 44;
  animation: tp-haken 340ms var(--ease) 380ms forwards;
}
@keyframes tp-kreis { to { stroke-dashoffset: 0; } }
@keyframes tp-haken { to { stroke-dashoffset: 0; } }

.quiz__ok-titel {
  margin: 26px 0 0;
  font-size: 21px;
  line-height: 1.3;
  font-weight: 400;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-wrap: pretty;
}
.quiz__ok-text {
  margin: 10px 0 0;
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink-2);
  text-wrap: pretty;
}

/* Bewegung reduzieren: der Haken ist sofort da, ohne sich zu zeichnen. */
@media (prefers-reduced-motion: reduce) {
  .quiz__haken-kreis, .quiz__haken-strich { stroke-dashoffset: 0; }
}

/* ---------- Footer ---------- */

.footer .wrap {
  padding-top: 52px;
  padding-bottom: 52px;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 32px;
}
.footer__claim { margin: 10px 0 0; font-size: 15px; color: var(--ink-3); }
.footer__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 26px;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--ink-3);
}
.footer__meta a { color: var(--ink-3); }
.footer__meta a:hover { color: var(--blue); }

/* ---------- Rechtstexte ---------- */

.legal main { padding-top: clamp(56px, 7.7vw, 94px); padding-bottom: clamp(64px, 8.6vw, 112px); }
.legal h1 { font-size: clamp(34px, 5vw, 52px); line-height: 1.08; font-weight: 300; letter-spacing: -0.03em; }
.legal h2 { margin-top: 44px; font-size: 15px; font-weight: 500; letter-spacing: -0.005em; }
.legal h2:first-of-type { margin-top: 56px; }
.legal p { margin: 12px 0 0; font-size: 17px; line-height: 1.7; color: var(--ink-2); text-wrap: pretty; }
.legal__body { max-width: 660px; }
.legal__note {
  margin-top: 56px;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 12px;
  line-height: 1.6;
  color: var(--quiet);
}
.legal__back {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 12px;
  letter-spacing: 0.06em;
  color: var(--ink-3);
}
.legal__back:hover { color: var(--blue); }
/* Platzhalter, die vor der Veroeffentlichung ersetzt werden muessen */
.todo {
  background: rgba(45, 107, 255, 0.08);
  border-bottom: 1px solid var(--blue);
  color: var(--blue-dark);
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 13px;
  padding: 1px 4px;
}

/* ---------- Keyframes ---------- */

@keyframes tp-marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes tp-flow { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -160; } }
@keyframes tp-pulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
@keyframes tp-ring { 0% { opacity: .5; transform: scale(.4); } 100% { opacity: 0; transform: scale(1); } }

/* ---------- Bewegung reduzieren ----------
   Hover bleibt nutzbar, die Bubbles stehen still auf ihrem Ring. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation: none !important;
    transition-duration: 1ms !important;
  }
  #tp-spine, #tp-net, #tp-mesh { display: none; }
}


/* ===========================================================================
   Aufklappbare Karten mit Akzentlinie
   Gilt fuer beide Reihen: "Was wir tun" und die Kick-off-Schritte.
   Der Kopf ist ein echter Button, damit Tastatur und Screenreader ihn finden.
   Das Aufklappen laeuft ueber grid-template-rows von 0fr auf 1fr, dadurch
   animiert die Hoehe weich, ohne dass JavaScript sie ausmessen muss.
   =========================================================================== */

/* Karte und Kopf sind Flex-Spalten, damit die Zeile "Mehr dazu" unten sitzt und
   in einer Reihe auf gleicher Hoehe steht, auch wenn die Einleitungstexte
   unterschiedlich lang sind. */
.card--do,
.card--step {
  position: relative;
  padding: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  transition: transform 260ms var(--ease), box-shadow 260ms ease;
}

/* Akzentlinie, waechst bei Hover und im offenen Zustand von oben herunter. */
.card--do::before,
.card--step::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--blue);
  transform: scaleY(0);
  transform-origin: top;
  transition: transform 320ms var(--ease);
}
.card--do:hover::before,
.card--do.card--offen::before,
.card--step:hover::before,
.card--step.card--offen::before { transform: scaleY(1); }

.card__kopf {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  width: 100%;
  margin: 0;
  padding: 44px 40px 26px;
  border: 0;
  background: none;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.card__kopf:focus-visible { outline: 2px solid var(--blue); outline-offset: -4px; }

.card--do .card__num { display: block; font-size: 13px; letter-spacing: 0.14em; }
.card--step .card__num { display: block; font-size: 12px; letter-spacing: 0.13em; }
.card--do .card__kopf h3 { margin: 22px 0 0; }
.card--do .card__kopf p { margin: 14px 0 0; }

.card--step .card__kopf { padding: 34px 30px 24px; min-height: 180px; }
.card--step .card__kopf h3 { margin: 20px 0 0; }
.card--step .card__kopf p { margin: 12px 0 0; }

/* Aufforderung zum Aufklappen */
.card__mehr {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  gap: 10px;
  margin-top: auto;
  padding-top: 22px;
  font-family: 'Space Mono', ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--mono);
  transition: color 180ms ease;
}
.card--step .card__mehr { padding-top: 18px; font-size: 10px; }
.card__kopf:hover .card__mehr { color: var(--blue); }

/* Plus, das sich beim Aufklappen zum Minus dreht */
.card__kreuz { position: relative; width: 11px; height: 11px; flex: 0 0 11px; }
.card__kreuz::before,
.card__kreuz::after {
  content: "";
  position: absolute;
  left: 0;
  top: 5px;
  width: 11px;
  height: 1px;
  background: currentColor;
  transition: transform 300ms var(--ease);
}
.card__kreuz::after { transform: rotate(90deg); }
.card--offen .card__kreuz::after { transform: rotate(0deg); }

.card__panel {
  flex: 0 0 auto;
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 420ms var(--ease);
}
.card--offen .card__panel { grid-template-rows: 1fr; }
.card__panel-innen { overflow: hidden; }
.card__panel-innen p {
  margin: 0;
  padding: 0 40px 44px;
  font-size: 16px;
  line-height: 1.65;
  color: var(--ink-2);
  text-wrap: pretty;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 300ms ease 120ms, transform 300ms var(--ease) 120ms;
}
.card--step .card__panel-innen p { padding: 0 30px 34px; font-size: 15px; line-height: 1.6; }
.card--offen .card__panel-innen p { opacity: 1; transform: none; }

/* Eine offene Karte hebt sich nicht zusaetzlich an, das wirkt sonst wacklig. */
.card--do.card--offen:hover,
.card--step.card--offen:hover { transform: none; }
.card--do.card--offen,
.card--step.card--offen { box-shadow: 0 18px 44px rgba(11, 11, 12, 0.07); z-index: 2; }

/* Zusammengehalten, sonst bricht der Browser nach dem Bindestrich um und "KI-"
   steht allein am Ende der ersten Zeile. */
.nichttrennen { white-space: nowrap; }

/* ===========================================================================
   "Was wir tun" hervorheben, ohne Farbflaeche
   Der Hintergrund bleibt weiss. Der Highlight greift die Linien-Sprache auf,
   die ohnehin ueber die Seite laeuft (Spine, Punktkarte, Netzwerk): eine duenne
   blaue Linie zeichnet sich beim Scrollen um die Karten herum, an den Ecken
   sitzen Knotenpunkte. --fortschritt kommt aus karten.js und haengt an der
   Scroll-Position, nicht an einem einmaligen Ausloeser.
   =========================================================================== */

.grid--do { position: relative; }

.tp-rahmen { position: absolute; inset: -24px; pointer-events: none; }

/* Vier einzelne Kanten statt eines SVG-Pfads: ein gestrecktes SVG rechnet die
   Strichlaenge je Seite anders, dadurch riss die Linie in Segmente auf. Jede
   Kante bekommt ein Viertel des Fortschritts, clamp() schneidet ab. */
.tp-kante { position: absolute; background: var(--blue); opacity: 0.45; }
.tp-kante--o {
  left: 0; top: 0; width: 100%; height: 1px;
  transform-origin: left center;
  transform: scaleX(clamp(0, var(--fortschritt, 0) / 0.25, 1));
}
.tp-kante--r {
  right: 0; top: 0; width: 1px; height: 100%;
  transform-origin: center top;
  transform: scaleY(clamp(0, (var(--fortschritt, 0) - 0.25) / 0.25, 1));
}
.tp-kante--u {
  left: 0; bottom: 0; width: 100%; height: 1px;
  transform-origin: right center;
  transform: scaleX(clamp(0, (var(--fortschritt, 0) - 0.5) / 0.25, 1));
}
.tp-kante--l {
  left: 0; top: 0; width: 1px; height: 100%;
  transform-origin: center bottom;
  transform: scaleY(clamp(0, (var(--fortschritt, 0) - 0.75) / 0.25, 1));
}

/* Knotenpunkte an den Ecken, wie die Punkte auf der Rhein-Ruhr-Karte. */
.tp-punkt {
  position: absolute;
  width: 7px;
  height: 7px;
  margin: -3.5px 0 0 -3.5px;
  border-radius: 50%;
  background: var(--blue);
  opacity: 0;
  transform: scale(0.2);
  transition: opacity 320ms ease, transform 420ms var(--ease);
}
.tp-punkt--lo { left: 0; top: 0; }
.tp-punkt--ro { left: 100%; top: 0; }
.tp-punkt--ru { left: 100%; top: 100%; }
.tp-punkt--lu { left: 0; top: 100%; }
.tp-punkt.ist-an { opacity: 1; transform: scale(1); }
.tp-punkt.ist-an::after {
  content: "";
  position: absolute;
  inset: -7px;
  border-radius: 50%;
  background: rgba(45, 107, 255, 0.14);
  animation: tp-knoten 2.6s ease-out infinite;
}
@keyframes tp-knoten {
  0% { transform: scale(0.5); opacity: 0.7; }
  70%, 100% { transform: scale(1.5); opacity: 0; }
}

/* Blauer Strich unter dem Mono-Label, waechst mit demselben Fortschritt. */
#leistung .lbl--side-tight { position: relative; }
#leistung .lbl--side-tight::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -12px;
  height: 2px;
  width: calc(64px * var(--fortschritt, 0));
  background: var(--blue);
}

/* Auftritt der vier Karten, versetzt. Das Rahmen-Element ist das erste Kind
   des Gitters, deshalb beginnen die Karten bei nth-child(2). */
#leistung .grid--do .card {
  opacity: 0;
  transform: translateY(26px) scale(0.985);
  transition: opacity 620ms var(--ease), transform 620ms var(--ease);
}
#leistung .grid--do.ist-da .card { opacity: 1; transform: none; }
#leistung .grid--do.ist-da .card:nth-child(2) { transition-delay: 0ms; }
#leistung .grid--do.ist-da .card:nth-child(3) { transition-delay: 110ms; }
#leistung .grid--do.ist-da .card:nth-child(4) { transition-delay: 220ms; }
#leistung .grid--do.ist-da .card:nth-child(5) { transition-delay: 330ms; }

@media (prefers-reduced-motion: reduce) {
  #leistung .grid--do .card { opacity: 1; transform: none; }
  .tp-punkt { opacity: 1; transform: none; }
  .tp-punkt.ist-an::after { animation: none; }
}

@media (max-width: 760px) {
  .card__kopf { padding: 34px 26px 22px; }
  .card__panel-innen p { padding: 0 26px 34px; }
  .card--step .card__kopf { padding: 34px 26px 22px; }
  .card--step .card__panel-innen p { padding: 0 26px 34px; }
  .tp-rahmen { inset: -16px; }
}
