/*
 * Orbitron, aus dem eigenen Verzeichnis.
 *
 * Bis zum 23.09.2026 kam die Schrift von `fonts.googleapis.com`, und damit ging
 * bei jedem Seitenaufruf die IP-Adresse des Besuchers an Google -- ohne
 * Einwilligung, bevor irgendein Banner etwas fragen konnte. Ein Cookie-Banner
 * haette daran nichts geaendert: Schriften laden, bevor jemand klicken kann.
 *
 * Nur ein Schnitt und nur der lateinische Bereich: die Wortmarke braucht
 * Orbitron 700, sonst nichts. 6,5 kB statt zweier Verbindungen zu einem
 * Drittanbieter.
 *
 * `font-display: swap` bleibt: bis die Datei da ist, steht die Wortmarke in der
 * Ersatzschrift, statt unsichtbar zu sein.
 */
@font-face {
  font-family: 'Orbitron';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('brand/fonts/orbitron-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}


  /* ============================================================
     POLARIS1 — dunkler Onepager
     Der Hero gibt die Sprache vor: Schwarz, Dither-Korridor,
     Mono-Versalien, eckige Kanten. Die ganze Seite folgt ihm jetzt -
     numerierte Bloecke mit Mock-UIs, technische Labels, duenne
     Linien statt Karten-Schatten. Akzent: Polaris1-Blau.
     ============================================================ */
  :root {
    /* Das O der Wortmarke. Eigenes Token, weil `--brand` auf dieser Seite das
       dunkle Knopf-Blau meint und nicht das Grün der App -- ein `var(--brand)`
       hier faerbte das O navy. Bewusst **nicht** in html.light ueberschrieben:
       die Marke soll auf hellem wie dunklem Grund dieselbe Farbe tragen. Auf
       Weiss steht sie damit bei rund 1,7:1; das ist eine Markenentscheidung,
       keine Unachtsamkeit, und gilt nur fuer dieses eine Zeichen. */
    --logo-o: #5ceda3;
    --bg: #05080f;
    --panel: #0a0e17;
    --panel2: #0e131e;
    --ink: #ffffff;
    --muted: rgba(255,255,255,.56);
    --faint: rgba(255,255,255,.34);
    --dim: rgba(255,255,255,.17);
    --line: rgba(255,255,255,.11);
    --accent: #6cb6ec;
    /* Gefuellte Buttons sind kleine dunkle Platten, in denen das
       Dither-Muster laeuft - das ist der Markenmoment, keine Farbe. */
    --brand: #0d1420;
    --brand-h: #16202f;
    --brand-ink: #ffffff;
    --brand-edge: rgba(255,255,255,.22);
    --brand-glow: transparent;
    --brand-glow-h: transparent;
    --green: #4fd493;
    --amber: #e7b04c;
    --red: #ff6b6b;
    --wide: 1240px;
    --e: cubic-bezier(.22, .7, .2, 1);
  }
  * { margin: 0; padding: 0; box-sizing: border-box; }
  html { background: var(--bg); scroll-behavior: smooth; }
  body {
    background: var(--bg); color: var(--ink);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
    font-size: 16px; line-height: 1.55;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
  }
  ::selection { background: rgba(108,182,236,.3); color: #fff; }
  a { color: var(--accent); }
  a:hover { color: #9ed2f5; }
  section[id] { scroll-margin-top: var(--hh, 76px); }
  .wide { max-width: var(--wide); margin: 0 auto; padding: 0 clamp(1.25rem, 4vw, 3rem); }
  .mono, .ulabel { font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace; }
  /* `.ubtn` stand bis zum 18.10.2026 in dieser Reihe. Mit Versalien und 0,1 em
     Sperrung las sich die Schreibmaschinenschrift als technisches Etikett, und
     genau das war gewollt. Seit der Knopf gemischt und halbfett gesetzt ist,
     traegt sie nicht mehr: Monospace in gemischter Schreibung sieht nach
     Eingabefeld aus, nicht nach Knopf. `.ulabel` bleibt, wo es war -- das ist
     weiterhin ein Etikett. */
  .ulabel {
    font-family: ui-monospace, Menlo, monospace;
    font-size: .68rem; letter-spacing: .2em; text-transform: uppercase; color: var(--faint);
  }
  /* ── Knopfform, 18.10.2026 ────────────────────────────────────────────────
   *
   * Vorher: 20 px Radius bei 46 px Hoehe, Versalien, 0,1 em gesperrt. Bei
   * 46 px waere eine Pille 23 px -- wir lagen also fast dort, und der Knopf
   * las sich als Etikett.
   *
   * Jetzt die Form von pipelime.ai, abgemessen an einem Bildschirmfoto:
   * 11 px Radius bei 40 px Hoehe, gemischte Schreibung, 14,5 px halbfett,
   * keine Sperrung. Der groessere Unterschied im Eindruck kommt nicht von den
   * neun Pixeln Rundung, sondern von den Versalien -- vorher ein Schalter,
   * jetzt ein Satz, den man anklickt.
   *
   * Die Beschriftungen standen im HTML laengst in gemischter Schreibung;
   * `text-transform` machte nur die Optik. Entfernen genuegte fuer alle
   * siebzig Knoepfe der Website, keine Seite musste angefasst werden.
   */
  .ubtn {
    display: inline-flex; align-items: center; gap: .62rem;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
    font-size: 14.5px; font-weight: 650; letter-spacing: -.005em;
    padding: .72rem 1.25rem; border-radius: 11px; text-decoration: none; white-space: nowrap;
    transition: background .2s var(--e), border-color .2s var(--e), color .2s var(--e),
                transform .15s var(--e), box-shadow .2s var(--e);
  }

  /* Der Pfeil als `::before` mit `order`, nicht als `::after`: `::after`
   * gehoert schon dem Schimmer im Abschluss-Knopf (`.ubtn.shimmer::after`).
   * Zwei Regeln auf demselben Pseudoelement waeren ein Fehler, der nur an
   * einem einzigen Knopf der Website auffiele -- also gar nicht.
   *
   * Im Flexbox-Kasten ist das Pseudoelement ein eigenes Element; `order: 1`
   * schiebt es hinter den Text, der als namenloses Element auf 0 bleibt.
   */
  .ubtn::before {
    content: '\2192'; order: 1; font-size: 1.02em; line-height: 1;
    transition: transform .2s var(--e);
  }
  .ubtn:hover::before { transform: translateX(2px); }
  .ubtn:active { transform: translateY(1px); }
  .ubtn.light, .ubtn.solid {
    position: relative; overflow: hidden; isolation: isolate;
    background: var(--brand); color: var(--brand-ink);
    border: 1px solid var(--brand-edge);
    box-shadow: 0 8px 26px var(--brand-glow, transparent);
  }
  .ubtn.light:hover, .ubtn.solid:hover {
    background: var(--brand-h); color: var(--brand-ink);
    box-shadow: 0 10px 32px var(--brand-glow-h, transparent);
  }
  /* Das laufende Raster liegt hinter der Schrift, nicht darueber */
  .btnpx {
    position: absolute; inset: 0; width: 100%; height: 100%; z-index: -1;
    pointer-events: none; image-rendering: pixelated; opacity: .9;
  }
  /* ── Schimmer im Abschluss-Knopf ──────────────────────────────────────────
   *
   * Ein Lichtstreifen, der schraeg ueber den Knopf laeuft, eine Pause macht und
   * von vorn anfaengt. Ohne die Pause waere es ein Lauflicht, kein Schimmern.
   *
   * Hier stand vorher ein Sternenfeld -- neun Punkte je Kachel, zweitonig,
   * damit sie auf der hellen gruenen Platte ueberhaupt zu sehen waren. Genau
   * das war das Problem: Punkte, die kraeftig genug sind, um auf Hellgruen zu
   * bestehen, sehen auf einem Knopf nicht nach Sternen aus, sondern nach
   * Flecken. Der Streifen allein macht dieselbe Bewegung, ohne die Flaeche zu
   * stoeren.
   *
   * `top/bottom: -60%` und die Drehung sorgen dafuer, dass der Streifen den
   * Knopf auch an den Ecken voll ueberstreicht; `overflow: hidden` am Knopf
   * schneidet den Rest ab.
   */
  .ubtn.shimmer::after {
    content: ''; position: absolute; z-index: -1; pointer-events: none;
    top: -60%; bottom: -60%; left: 0; width: 34%;
    background: linear-gradient(90deg,
      transparent 0%, rgba(255,255,255,.72) 50%, transparent 100%);
    animation: p1sweep 3.9s ease-in-out infinite;
  }
  @keyframes p1sweep {
    0%,  6%   { transform: translateX(-120%) rotate(16deg); }
    54%, 100% { transform: translateX(420%)  rotate(16deg); }
  }

  .ubtn.ghost { background: rgba(255,255,255,.03); border: 1px solid rgba(255,255,255,.3); color: #fff; }
  .ubtn.ghost:hover { background: rgba(255,255,255,.1); border-color: #fff; color: #fff; }

  /* ---------- Header ------------------------------------------- */
  /* Am Seitenanfang schwebt die Leiste mit Abstand; sobald sie opak wird,
     dockt sie oben an. `top` gehoert deshalb in die Uebergangsliste. */
  /*
   * `#hdr`, nicht `header`.
   *
   * Hier stand `header { position: fixed }` -- eine Elementregel fuer ein
   * globales Layoutverhalten. Das ging gut, solange jede Seite genau ein
   * `<header>` hatte: die Navigationsleiste.
   *
   * Am 30.09.2026 bekam die Startseite einen zweiten. Der Ablauf-Abschnitt
   * benutzt `<header class="p1-head">` fuer seinen Ueberschriftenblock --
   * voellig korrektes HTML -- und erbte damit `position: fixed; top: .9rem`.
   * Die Ueberschrift "What actually happens when you run a test." klebte
   * daraufhin am Seitenanfang und lag ueber dem Hero, waehrend der Rest des
   * Abschnitts 600 Pixel weiter unten stand.
   *
   * Der Fehler war nicht der neue Abschnitt, sondern die Reichweite dieser
   * Regel. Sie gilt jetzt fuer die Leiste, die gemeint ist.
   */
  #hdr {
    position: fixed; top: .9rem; left: 0; right: 0; z-index: 50;
    transition: transform .45s var(--e), background .3s, box-shadow .3s, top .3s var(--e);
  }
  /*
   * Beim Scrollen wird aus der Leiste eine schwebende Kapsel.
   *
   * Sie rueckt an den Seiten ein und rundet sich, statt bis an die Kanten zu
   * laufen -- dieselbe Bewegung, die iOS 26 fuer seine Leisten benutzt. Der
   * Radius ist derselbe wie bei den Knoepfen und der Insel; drei verschiedene
   * Rundungen in einer Leiste sehen nach Zufall aus.
   */
  header.solid {
    top: .55rem;
    /*
     * Die Kapsel endet dort, wo der Inhalt endet.
     *
     * `.hbar` ist auf 1440px begrenzt und zentriert; die Kapsel lief aber mit
     * einem festen Rand von rund einem Zentimeter bis an die Fensterkanten. Auf
     * einem breiten Bildschirm sah sie deshalb aus wie eine Leiste mit viel Luft
     * darin, statt wie ein Gegenstand.
     *
     * `calc(50vw - 720px)` ist die halbe Fensterbreite minus die halbe
     * Inhaltsbreite -- damit deckt sich die Kante der Kapsel mit dem Rand des
     * Inhalts. `max()` faengt schmale Fenster ab: dort bleibt 1rem Abstand,
     * sonst wuerde der Wert negativ und die Kapsel liefe ueber den Rand hinaus.
     */
    left: max(1rem, calc(50vw - 720px));
    right: max(1rem, calc(50vw - 720px));
    border-radius: 22px;
  }
  #hdr {
    transition: transform .45s var(--e), background .3s, box-shadow .3s,
                top .3s var(--e), left .3s var(--e), right .3s var(--e),
                border-radius .3s var(--e);
  }
  header.solid {
    background: rgba(10, 22, 50, .78); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    box-shadow: 0 1px 0 var(--line);
  }
  /*
   * Die Kopfzeile bricht bewusst aus `--wide` (1240px) aus: Logo und Handlungen
   * sollen weiter an den Raendern sitzen als der Inhalt darunter. Das ist keine
   * Unachtsamkeit -- eine Navigationsleiste, die den Textspalten folgt, wirkt
   * eingeschnuert.
   *
   * `position: relative` traegt die mittige Insel: sie wird absolut auf diese
   * Leiste zentriert, damit sie unabhaengig von der Breite links und rechts
   * genau in der Mitte steht. Sonst muesste das Markup dreier Spalten wegen in
   * dreizehn Designer-Dateien geaendert werden.
   */
  .hbar {
    position: relative;
    flex-wrap: nowrap;
    max-width: 1440px; margin: 0 auto;
    /* Senkrecht knapper: Die Hoehe der Leiste ist die Summe aus diesem Abstand
       und dem hoechsten Element darin -- das ist der Knopf rechts. Beide sind
       zusammen zurueckgenommen, sonst zieht der Knopf die Kapsel weiter auf,
       egal wie klein der Abstand wird. */
    padding: .5rem clamp(1rem, 2.5vw, 2rem);
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  }
  .logo {
    font-family: 'Orbitron', ui-monospace, monospace;
    font-weight: 700; font-size: 1.05rem; letter-spacing: .005em; line-height: 1;
    text-transform: uppercase; color: #fff; text-decoration: none;
    display: flex; align-items: baseline;
  }
  .logo:hover { color: #fff; }
  .logo .ostar { display: block; width: 1.28cap; height: 1cap; margin: 0 .09em; fill: var(--logo-o); }
  .hnav { display: flex; align-items: center; gap: 1.15rem; }

  /*
   * Die Seitenlinks liegen als eigene Flaeche in der Kopfzeile -- eine Insel.
   * `Log in` und `Start for free` stehen bewusst **ausserhalb**: sie sind
   * Handlungen, keine Navigation, und die Trennung soll man sehen, ohne sie
   * erklaert zu bekommen. Im Markup standen sie ohnehin schon neben
   * `.links`, nur sah man es nicht.
   *
   * Ab 1040px wandert die Zeile ins Overlay (`display: none` weiter unten),
   * die Insel verschwindet dort mit ihr.
   */
  /* Ohne eigenen Rahmen: Die Leiste ist seit dem Milchglas selbst eine Flaeche,
     und ein Kasten darin war ein zweiter Rahmen im ersten. Die Woerter stehen
     jetzt frei; ihre Form bekommen sie erst beim Ueberfahren. */
  .hnav .links {
    position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
    display: flex; align-items: center; gap: .3rem;
  }
  /* Innerhalb der Insel keine Versalien und kein Monospace: die Seitennamen
     sind Woerter, keine Systemzustaende. Draussen bleibt `Log in` wie es war. */
  .hnav .links a.plain {
    font-family: ui-monospace, Menlo, monospace;
    font-size: .78rem; letter-spacing: .01em; text-transform: none;
    padding: .38rem .8rem; border-radius: 16px;
    transition: background .18s var(--e), color .18s var(--e);
  }
  /* Blass in der Markenfarbe, nicht in Grau: Das O der Wortmarke traegt
     dasselbe Gruen, und der Hover verbindet beides. */
  .hnav .links a.plain:hover { background: rgba(92, 237, 163, .16); color: #fff; }

  /* `Log in` steht ausserhalb der Insel und hatte bisher gar keine Flaeche.
     Damit ein Hintergrund dort nicht wie ein Fehler aussieht, bekommt es
     dieselbe Form wie ein Inselwort. */
  .hnav > a.plain {
    padding: .38rem .8rem; border-radius: 16px;
    transition: background .18s var(--e), color .18s var(--e);
  }
  .hnav > a.plain:hover { background: rgba(92, 237, 163, .16); color: #fff; }
  .hnav a.plain {
    font-family: ui-monospace, Menlo, monospace;
    font-size: .68rem; letter-spacing: .13em; text-transform: uppercase;
    color: rgba(255,255,255,.62); text-decoration: none; white-space: nowrap;
  }
  .hnav a.plain:hover { color: #fff; }
  /* `Log in` steht als direktes Kind neben der Insel -- deshalb der
     Kindselektor: die Regel darf die Inselwoerter nicht noch einmal fassen. */
  .hnav > a.plain {
    font-family: ui-monospace, Menlo, monospace;
    font-size: .78rem; letter-spacing: .01em; text-transform: none;
  }
  .hnav .ubtn {
    /* Die Schreibmaschinenschrift stand hier bis zum 18.10.2026 eigens
       nochmal, obwohl `.ubtn` sie ohnehin hatte. Sie faellt mit weg: ein
       Knopf im Kopf und einer im Inhalt sollen dieselbe Schrift haben,
       sonst wirkt der eine wie ein Eingabefeld neben dem anderen.
       Der kleinere Radius ist kein zweiter Entwurf, sondern derselbe im
       Verhaeltnis -- 9 auf 35 Pixel entspricht 11 auf 40. */
    font-size: .82rem; letter-spacing: -.005em; text-transform: none;
    border-radius: 9px;
    /* .55rem ergibt rund 35px Hoehe. Tiefer gehe ich nicht: darunter wird der
       Knopf auf einem Touchscreen unangenehm klein zu treffen. */
    padding: .55rem 1.1rem;
  }
  /* Weiss, unabhaengig vom Zustand der Kopfzeile. Ueber dem Hero und auf der
     opaken Leiste galten bisher zwei verschiedene Regeln. */
  .hnav .ubtn.solid,
  html.light header .ubtn.solid,

  /*
   * Der umkreisende Schein am Haupt-Knopf.
   *
   * Ein Kegelverlauf dreht sich hinter dem Knopf; zwei uebereinandergelegte
   * Masken schneiden alles bis auf einen 1,5px-Ring heraus. Dadurch wandert ein
   * heller Bogen einmal aussen herum, statt dass die ganze Flaeche blinkt --
   * auffaellig genug, um den Blick zu holen, ruhig genug, um beim Lesen nicht
   * zu stoeren.
   *
   * Der Winkel laeuft ueber `@property`, weil CSS eine Custom Property sonst
   * nicht weich interpolieren kann. Kennt ein Browser das nicht, steht der
   * Bogen still -- der Knopf sieht dann aus wie zuvor, nur mit einem festen
   * Schimmer an einer Kante. Kein Rueckfall noetig.
   */
  @property --p1orbit {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: false;
  }
  /*
   * Zwei Ebenen, absichtlich.
   *
   * Der Ring unten braucht `@property` -- ohne das kann CSS einen Winkel in
   * einer Custom Property nicht weich interpolieren, und der Bogen stuende
   * still. Diese Pulsation hier braucht nichts als `box-shadow` und laeuft
   * seit jeher in jedem Browser. Sie ist die Zusicherung: **irgendein** Zeichen
   * von Leben ist immer da, auch wenn der Bogen ausfaellt.
   *
   * Beides im Ruhezustand, ohne `:hover` -- der Knopf soll den Blick holen,
   * bevor jemand ihn sucht.
   */
  .hnav .ubtn.solid {
    position: relative;
    animation: p1pulse 2.8s ease-in-out infinite;
  }
  @keyframes p1pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(92, 237, 163, .5); }
    55%      { box-shadow: 0 0 0 7px rgba(92, 237, 163, 0); }
  }
  /*
   * `::after` statt `::before`, und **ohne** negativen z-index: als
   * Nachkomme im Inhaltsfluss liegt es ohnehin ueber der Flaeche des Knopfes.
   * Der erste Versuch lag mit `z-index: -1` dahinter -- die fragilere Variante,
   * die von der Stapelreihenfolge des Elternelements abhaengt.
   */
  .hnav .ubtn.solid::after {
    content: ''; position: absolute; inset: -2px; border-radius: 22px;
    padding: 2px; pointer-events: none;
        /* Weiss, nicht `--logo-o`: der Knopf ist in der Aurora-Fassung selbst
       gruen (#5ceda3), ein gruener Bogen darauf war unsichtbar. Genau daran
       lag es, dass der Effekt zu fehlen schien -- er lief die ganze Zeit. */
    background: conic-gradient(from var(--p1orbit), transparent 0deg, #ffffff 45deg, transparent 100deg);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    animation: p1orbit 4s linear infinite;
  }
  @keyframes p1orbit { to { --p1orbit: 360deg; } }
  /* Wer Bewegung abbestellt hat, bekommt sie nicht. */
  @media (prefers-reduced-motion: reduce) {
    .hnav .ubtn.solid,
    .hnav .ubtn.solid::after { animation: none; }
    /* Wer Bewegung abbestellt hat, sieht keinen Streifen laufen. */
    .ubtn.shimmer::after { animation: none; display: none; }
  }
  /* Theme-Switch: zwei Felder, das aktive ist hell hinterlegt */
  /*
   * Der Hell/Dunkel-Umschalter ist aus der Kopfzeile genommen (01.09.2026):
   * die Website erscheint nur noch hell. Die Knoepfe bleiben im Markup, weil
   * sie in dreizehn Designer-Exporten stehen -- und weil `site.js` sie sucht.
   * Ausgeblendet statt entfernt ist hier also das Robustere.
   */
  .tsw {
    display: none; align-items: center; gap: 2px; flex: none;
    border: 1px solid var(--line); border-radius: 3px; padding: 2px;
    background: rgba(255,255,255,.04);
  }
  .tsw button {
    display: grid; place-items: center; width: 26px; height: 22px;
    background: none; border: 0; border-radius: 2px; cursor: pointer;
    color: var(--faint); transition: background .2s var(--e), color .2s var(--e);
  }
  .tsw button svg { width: 13px; height: 13px; display: block; }
  .tsw button:hover { color: var(--ink); }
  .tsw button[aria-pressed="true"] { background: rgba(255,255,255,.14); color: var(--ink); }
  html.light .tsw { background: rgba(12,21,36,.04); }
  html.light .tsw button[aria-pressed="true"] { background: rgba(12,21,36,.1); }

  /* ============================================================
     LIGHT MODE — gleiche Struktur, invertierte Werte.
     Der Hero bleibt schwarz (der Dither-Korridor lebt davon),
     alles darunter wird hell.
     ============================================================ */
  html.light {
    --bg: #ffffff;
    --panel: #fafbfc;
    --panel2: #f3f7fa;
    --ink: #0c1524;
    --muted: #55606d;
    --faint: #7c8794;
    --dim: rgba(12,21,36,.18);
    --line: #e5e9ee;
    --accent: #2f86c9;
    --brand: #0c1524;
    --brand-h: #16202f;
    --brand-ink: #ffffff;
    --brand-edge: rgba(255,255,255,.14);
    --green: #12864c;
    --amber: #a1690b;
    --red: #c2313b;
  }
  html.light body { background: var(--bg); color: var(--ink); }
  html.light ::selection { background: #cfe6f8; color: var(--ink); }
  html.light .ubtn.light, html.light .ubtn.solid { background: var(--brand); color: var(--brand-ink); }
  html.light .ubtn.light:hover, html.light .ubtn.solid:hover { background: var(--brand-h); color: var(--brand-ink); }
  html.light .ubtn.ghost { background: #fff; border-color: #cfd6df; color: var(--ink); }
  html.light .ubtn.ghost:hover { background: #f2f5f8; border-color: var(--ink); color: var(--ink); }
  /*
   * Dunkelblaues Milchglas mit gruenem Schimmer.
   *
   * Vorher war die Scheibe weiss. Weiss kann Neongruen nicht tragen -- der
   * Akzent verblasst darauf (1,7:1), und die Leiste stand als heller Block
   * ueber einer Seite, deren Hero tiefblau ausläuft. Auf dunklem Grund traegt
   * dasselbe Gruen bei 9:1 und wirkt wie Licht statt wie Farbe.
   *
   * Vier Ebenen, von hinten nach vorn:
   *
   *   1. `backdrop-filter` streut, was dahinter liegt -- 40px, damit Formen zu
   *      Flaechen werden, plus Saettigung gegen das Ausbleichen.
   *   2. Ein blauer Verlauf, oben dichter als unten. Das ist die Scheibe.
   *   3. Ein gruener Schein diagonal von oben links, sehr schwach (.10). Er
   *      soll erahnbar sein, nicht erkennbar -- ab etwa .18 kippt es von
   *      "Licht faellt darauf" zu "gruen eingefaerbt".
   *   4. Kanten: innen oben eine Lichtlinie, innen ein weiter gruener Schein,
   *      aussen ein feiner Ring.
   *
   * Der Schatten ist bewusst weit und schwach (50px, .32) statt eng und hart --
   * er soll die Leiste heben, nicht abschneiden.
   */
  /*
   * Die Kapsel liegt jetzt naeher am Fusszeilen-Blau (#0c1a3a), ohne es zu
   * erreichen -- Kopf und Fuss sollen als dieselbe Farbe lesbar sein, aber
   * nicht als dasselbe Element.
   *
   * Zwei Groessen bestimmen das: der Farbton (13,28,62 statt 17,33,60 -- eine
   * Spur tiefer und blauer) und vor allem die Deckkraft. .86 statt .64 macht
   * den Unterschied, den man sieht.
   *
   * Weiter hoch geht es nicht: `backdrop-filter` lebt davon, dass etwas
   * hindurchscheint. Ab etwa .9 ist die Kapsel eine Platte, und die Unschaerfe
   * dahinter arbeitet umsonst -- das Milchglas waere weg.
   */
  html.light header.solid {
    background:
      linear-gradient(135deg, rgba(92, 237, 163, .10) 0%, rgba(92, 237, 163, 0) 46%),
      linear-gradient(rgba(13, 28, 62, .86), rgba(10, 22, 50, .78));
    -webkit-backdrop-filter: blur(40px) saturate(190%);
            backdrop-filter: blur(40px) saturate(190%);
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, .16),
      inset 0 -1px 0 rgba(255, 255, 255, .05),
      inset 0 0 44px rgba(92, 237, 163, .06),
      0 0 0 1px rgba(255, 255, 255, .09),
      0 18px 50px rgba(4, 10, 22, .34);
  }
  /* Header liegt ueber dem schwarzen Hero: dort bleibt er hell,
     sobald er opak wird, kippt er auf dunkle Schrift */
  html.light header .logo, html.light header .hnav a.plain { color: rgba(255,255,255,.72); }
  html.light header .logo { color: #fff; }
  html.light header .links a.plain:hover,
  html.light header > .hbar > .hnav > a.plain:hover { background: rgba(92, 237, 163, .2); color: #fff; }
  /* Auf dunklem Glas genuegt weniger Gruen: .16 liest sich dort als Schein,
     waehrend .26 auf Weiss noetig war, um ueberhaupt sichtbar zu sein. */
  html.light header.solid .links a.plain:hover,
  html.light header.solid .hnav > a.plain:hover { background: rgba(92, 237, 163, .16); color: #fff; }
  html.light header .tsw { border-color: rgba(255,255,255,.2); background: rgba(255,255,255,.06); }
  html.light header .tsw button { color: rgba(255,255,255,.6); }
  html.light header .tsw button[aria-pressed="true"] { background: rgba(255,255,255,.16); color: #fff; }
  html.light header .ubtn.solid { background: var(--brand); color: var(--brand-ink); }
  html.light header.solid .logo { color: var(--ink); }
  /*
   * Auf dunklem Glas helle Schrift.
   *
   * Vorher stand hier `--ink` -- richtig, solange die Scheibe weiss war. Mit
   * der blauen Scheibe kehrt sich das um: Weiss bei .88 steht mit rund 11:1
   * darauf, unabhaengig davon, was gerade durchscheint.
   *
   * Die Schriftstaerke bleibt bei 500. Auf einer bewegten Flaeche traegt
   * Gewicht mehr zur Lesbarkeit bei als Farbe.
   */
  html.light header.solid .hnav a.plain { color: rgba(255, 255, 255, .88); font-weight: 500; }
  html.light header.solid .logo { color: #fff; }
  html.light header.solid .hnav a.plain:hover { color: #fff; }
  html.light header.solid .tsw { border-color: var(--line); background: rgba(12,21,36,.04); }
  html.light header.solid .tsw button { color: var(--faint); }
  html.light header.solid .tsw button[aria-pressed="true"] { background: rgba(12,21,36,.1); color: var(--ink); }
  html.light header.solid .ubtn.solid { background: var(--brand); color: var(--brand-ink); }
  /* Panels und Raster */
  html.light .mock { background: #fff; }
  html.light .card, html.light .stat, html.light .proc, html.light .plan { background: #fff; }
  html.light .plan.mid, html.light .oneplan { background: var(--panel2); }
  html.light .plan .chip { background: var(--ink); color: #fff; }
  html.light .card:hover { border-color: #c9d3de; }
  html.light .proc:hover { background: var(--panel2); }
  html.light .card .mock { background: var(--panel); }
  html.light .mock-body .dim { color: #9aa4b0; }
  html.light .mock-bar b, html.light .mock-body .k, html.light .mrow strong { color: var(--ink); }
  html.light .fcol a { color: var(--ink); }
  /* Der Hero bleibt in beiden Modi schwarz - sein Text also hell */
  html.light .hero { color: #fff; }
  html.light .hero h1 { color: #fff; }
  html.light .hero p.lede { color: rgba(255, 255, 255, .78); }
  html.light .hero .ubtn.light { background: var(--brand); color: var(--brand-ink); }
  html.light .hero .ubtn.light:hover { background: var(--brand-h); color: var(--brand-ink); }
  html.light .hero .ubtn.ghost { background: rgba(255,255,255,.03); border-color: rgba(255,255,255,.3); color: #fff; }
  html.light .hero .ubtn.ghost:hover { background: rgba(255,255,255,.1); border-color: #fff; color: #fff; }
  html.light .hpoints { color: rgba(255,255,255,.5); }   /* liegt im Hero */
  .menubtn {
    display: none; flex: none;
    font-family: ui-monospace, Menlo, monospace;
    font-size: .68rem; letter-spacing: .13em; text-transform: uppercase;
    color: var(--ink); background: none; border: 0; cursor: pointer;
    padding: .55rem .2rem;
  }
  html.light header:not(.solid):not(.overmenu) .menubtn { color: #fff; }
  /* Bei offenem Menue liegt der Header auf heller Flaeche */
  html.light body.menu-open header .logo,
  html.light body.menu-open header .menubtn { color: var(--ink); }
  html.light body.menu-open header .tsw { border-color: var(--line); background: rgba(12,21,36,.04); }
  html.light body.menu-open header .tsw button { color: var(--faint); }
  html.light body.menu-open header .tsw button[aria-pressed="true"] { background: rgba(12,21,36,.1); color: var(--ink); }
  html.light body.menu-open header .ubtn.solid { background: var(--brand); color: var(--brand-ink); }
  body.menu-open { overflow: hidden; }
  /* Ab hier ist kein Platz mehr fuer die Linkzeile: sie wandert ins
     Overlay, sichtbar bleibt Menu + Switch + CTA. */
  @media (max-width: 1040px) {
    .hnav .links { display: none; }
    .menubtn { display: block; }
  }
  @media (max-width: 560px) { .hnav .ubtn.solid { display: none; } }

  /* Vollbild-Menue */
  .menu {
    position: fixed; inset: 0; z-index: 49;
    background: color-mix(in oklab, var(--bg) 96%, transparent);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    /* Scroll-Container statt zentrierter Box: der Header-Streifen wird
       als Padding reserviert, bei zu kurzem Viewport scrollt das Menue
       statt zu clippen. */
    display: grid; justify-items: center; align-content: safe center;
    overflow-y: auto; overscroll-behavior: contain;
    padding: calc(var(--hh, 87px) + 1rem) 1rem 2.5rem; text-align: center;
    opacity: 0; visibility: hidden; transition: opacity .3s var(--e), visibility .3s;
  }
  body.menu-open .menu { opacity: 1; visibility: visible; }
  .menu a {
    display: block; padding: .5rem 1.5rem; text-decoration: none; color: var(--ink);
    font-size: clamp(1.6rem, 6vw, 2.4rem); font-weight: 620; letter-spacing: -.03em;
  }
  .menu a:hover { color: var(--accent); }
  .menu .ubtn { margin-top: 1.6rem; font-size: .8rem; }

  /* ---------- Hero: schwarze Buehne, Dither-Korridor ------------- */
  .hero {
    /* 100vh waren es, solange der Text mittig sass. Seit er oben steht, blieb
       darunter eine leere Flaeche von fast einem halben Bildschirm -- schoen
       animiert, aber der Besucher scrollt daran vorbei und sucht den Inhalt.
       Kuerzer heisst hier: derselbe Text an derselben Stelle, nur weniger
       Nichts darunter. */
    position: relative; min-height: 78vh; overflow: hidden;
    /* Unten war der Hero abgerundet, und durch die Rundung schien die
       Seitenfarbe -- im Hellmodus also Weiss. Solange darunter eine helle
       Flaeche kam, war das eine gewollte Kante. Seit dort der dunkle
       Ablauf-Streifen anschliesst, waren es zwei weisse Zipfel mitten in einem
       durchgehenden Verlauf. Kante raus, der Uebergang traegt jetzt allein. */
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    /* Der Inhalt ist senkrecht zentriert; der untere Abstand schiebt ihn nach
       oben. Ueber die Hoehe geregelt und nicht ueber `justify-content`, damit
       die Zentrierung erhalten bleibt und die Verschiebung auf kleinen wie
       grossen Bildschirmen mitwaechst. Nebeneffekt, der hier erwuenscht ist:
       der Text bleibt deutlich ueber dem 200px-Auslauf am unteren Rand. */
    text-align: center; padding: clamp(5rem, 10vh, 7rem) 1.25rem clamp(8rem, 18vh, 13rem);
    background: #000;
  }
  /* ---------- Unterseiten-Kopf ----------------------------------
     Nicht die schwarze Buehne der Startseite: helle Flaeche, und der
     Seitenname liegt als Dither-Raster im Hintergrund - gleiches
     Material (Pixel, Markenblau, Orbitron), andere Komposition. */
  .phero {
    position: relative; overflow: hidden; isolation: isolate;
    min-height: min(56vh, 540px);
    display: flex; flex-direction: column; justify-content: flex-end;
    padding: calc(var(--hh, 87px) + clamp(2.5rem, 7vh, 4.5rem)) 0 clamp(2.2rem, 5vh, 3.2rem);
    background: var(--bg);
  }
  /* Variante A: Farbfeld am rechten Rand */
  .pfield {
    position: absolute; top: calc(var(--hh, 87px) + .4rem); right: 0; bottom: 0; width: min(72%, 900px);
    z-index: 0; pointer-events: none; image-rendering: pixelated;
    /* zusaetzlich weich auslaufen lassen */
    mask-image: linear-gradient(180deg, transparent 0, #000 2.5rem);
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 2.5rem);
  }
  /* Variante B: schmales Spektrumband ueber dem Seitentitel */
  .phero.pb .ulabel { color: var(--accent); }
  .phero > .wide { position: relative; z-index: 2; width: 100%; }
  .phero .ulabel { display: block; margin-bottom: 1rem; }
  .phero h1 {
    margin: 0; max-width: 22em; text-wrap: balance;
    font-size: clamp(2rem, 4.2vw, 3.3rem); line-height: 1.06;
    font-weight: 640; letter-spacing: -.035em;
  }
  .phero h1 .hw {
    display: inline-block; opacity: 0; transform: translateY(.28em); filter: blur(8px);
    animation: wordin .9s cubic-bezier(.2,.7,.15,1) both;
  }
  .phero p.lede {
    margin: 1.2rem 0 0; max-width: 33em; color: var(--muted);
    font-size: 1rem; line-height: 1.65;
    opacity: 0; animation: fadein .9s var(--e) .5s both;
  }
  .phero .cta-row { justify-content: flex-start; margin-top: 2.1rem; }
  .phero .ubtn { font-size: .78rem; padding: .95rem 1.6rem; }
  .phero .pmeta { margin-top: clamp(2rem, 5vh, 3rem); }

  /*
   * Kontakt hat als einzige Unterseite keine Merkmalszeile unter den Knoepfen.
   *
   * `min-height: min(56vh, 540px)` haelt den Seitenkopf auf, damit er auf allen
   * Unterseiten gleich hoch beginnt. Ohne die Zeile darunter endet der Inhalt
   * aber schon nach den Knoepfen, und die Mindesthoehe haelt danach nur noch
   * eine leere Flaeche offen -- knapp zwei Handbreit bis zum naechsten
   * Abschnitt. Hier darf der Kopf so hoch sein wie das, was drinsteht.
   */
  body[data-page="contact"] .phero { min-height: 0; }
  .phero .hpoints,
  html.light .phero .hpoints { justify-content: flex-start; margin: 0; color: var(--faint); }
  @media (max-width: 720px) {
    .phero { min-height: min(62vh, 460px); }
    .phero h1 { font-size: clamp(1.9rem, 8vw, 2.4rem); }
  }

  .herobg { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
  .herobg video, .herobg canvas {
    position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
  }
  .herobg canvas { image-rendering: pixelated; }
  /* Aurora-Fassung: Nachthimmel statt Schwarz - oben fast schwarz mit
     Blaustich, nach unten tiefes Marineblau, dazu ein schwacher
     Horizontschein. Das Gruen des Polarlichts liegt darueber. */
  body.aurora .hero {
    background:
      radial-gradient(120% 62% at 50% 108%, rgba(28,74,132,.42) 0%, rgba(14,38,74,.2) 42%, transparent 74%),
      radial-gradient(90% 50% at 18% 96%, rgba(22,60,110,.24) 0%, transparent 70%),
      linear-gradient(180deg, #03060e 0%, #050b18 34%, #071227 66%, #0a1a33 100%);
  }
  body.aurora #aurora {
    image-rendering: auto;
    filter: blur(4px) saturate(1.12);
    transform: scale(1.05);
    transform-origin: 50% 60%;
  }
  .herobg video { display: none; }
  .herobg.has-video video { display: block; }
  .herobg.has-video canvas { display: none; }
  /*
   * Das eine hervorgehobene Wort in der Ueberschrift.
   *
   * Nur Farbe. Ein Zwischenstand hatte hier Orbitron und einen leuchtenden
   * Unterstrich -- beides zu laut: Die Schrift laeuft so viel breiter, dass ein
   * einzelnes Wort aus der Zeile faellt, und der Strich zog den Blick auf sich,
   * statt ihn weiterzufuehren. Die Markenfarbe allein reicht, um das Wort zu
   * setzen, das die Ueberschrift traegt.
   */
  .hero h1 .lk { font-style: normal; color: var(--logo-o); position: relative; }

  /*
   * Das hervorgehobene Wort in der Ueberschrift: nur Farbe.
   *
   * Vier Varianten standen hier nacheinander -- Orbitron, ein leuchtender
   * Unterstrich, ein gezeichneter Bogen, Monospace. Jede war eine zweite
   * Auszeichnung auf einem Wort, das mit der Markenfarbe bereits eine hatte,
   * und jede zog dadurch mehr Aufmerksamkeit auf sich als auf die Aussage.
   *
   * Geblieben ist die Farbe. Sie genuegt, weil sie im Hero sonst nirgends
   * vorkommt.
   */
  .hero h1 .lk { font-style: normal; color: var(--logo-o); }

  /*
   * Der Ausklang des Heros -- und der Grund, warum es ihn braucht.
   *
   * Unter dem Hero liegt der dunkle Streifen (`.p1hiw`, davor `.flband`), und
   * beide sind als *eine* Flaeche gedacht. Der Streifen beginnt mit `#0a1a33`,
   * der Farbe, auf die der Hero-Verlauf endet.
   *
   * Nur endet der Hero nicht auf diese Farbe. Ueber dem Verlauf liegt der
   * Aurora-Canvas, und der *animiert*: er wird in 250x132 gezeichnet, auf 551
   * Pixel hochskaliert und unten abgeschnitten. Welche Farbe seine letzte
   * sichtbare Zeile hat, haengt davon ab, wo die Welle gerade steht -- gemessen
   * zwischen `#0a1a31` und fast Schwarz. Mal passt die Naht, mal sieht man eine
   * Kante quer ueber die Seite, und zwar bei jedem Besucher zu einer anderen
   * Sekunde.
   *
   * Eine Farbe laesst sich gegen etwas Bewegtes nicht abstimmen. Deshalb wird
   * die Unterkante hier *festgelegt*: die letzten 150 Pixel blenden auf genau
   * `#0a1a33` aus, egal was der Canvas darunter tut. Danach ist die Naht
   * deterministisch statt zufaellig.
   *
   * `z-index: 2` -- ueber Canvas (0) und Maske (1), unter dem Text (3).
   */
  body.aurora .hero::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 150px;
    z-index: 2; pointer-events: none;
    background: linear-gradient(180deg, rgba(10, 26, 51, 0) 0%, rgba(10, 26, 51, .72) 58%, #0a1a33 100%);
  }

  .heromask {
    position: absolute; inset: 0; z-index: 1; pointer-events: none;
    background:
      radial-gradient(46% 58% at 50% 46%, #000 0%, #000 46%, rgba(0,0,0,.86) 66%, rgba(0,0,0,.35) 84%, transparent 100%),
      linear-gradient(180deg, rgba(0,0,0,.55), transparent 22%, rgba(0,0,0,.85));
  }
  /* Aurora-Fassung: der Himmel bleibt unten offen, der Text bekommt
     einen eigenen Schleier statt der Mitten-Vignette des Korridors. */
  /*
   * Der Auslauf zum Ablauf-Streifen.
   *
   * Drei Anlaeufe habe ich gebraucht, weil ich die Farbe treffen wollte, mit
   * der der Hero endet. Das kann nicht gelingen: sichtbar ist das **Canvas**,
   * darueber liegt `.heromask` mit 30 % Schwarz am unteren Rand, und beides
   * ist ueber die Breite verschieden. Jeder gleichmaessige Verlauf trifft das
   * an einer Stelle und daneben nicht.
   *
   * Also andersherum: Der Hero laeuft ueber seine letzten 200px in **genau die
   * Farbe** aus, mit der der Streifen beginnt (#0a1a33). Dann gibt es nichts
   * mehr zu treffen -- es ist dieselbe Farbe, per Konstruktion.
   *
   * z-index 2: ueber Canvas (0) und Maske (1), unter `.hero-core` (3), damit
   * Text und Knoepfe unberuehrt bleiben.
   */
  .hero::after {
    content: ''; position: absolute; left: 0; right: 0; bottom: 0;
    height: 200px; z-index: 2; pointer-events: none;
    background: linear-gradient(to bottom,
      rgba(10, 26, 51, 0) 0%,
      rgba(10, 26, 51, .45) 45%,
      rgba(10, 26, 51, .85) 78%,
      #0a1a33 100%);
  }

  body.aurora .heromask {
    background:
      radial-gradient(46% 36% at 50% 40%, rgba(0,0,0,.72) 0%, rgba(0,0,0,.5) 55%, rgba(0,0,0,.16) 82%, transparent 100%),
      linear-gradient(180deg, rgba(0,0,0,.6) 0%, rgba(0,0,0,.18) 30%, transparent 66%, rgba(0,0,0,.3) 100%);
  }
  .hero-core { position: relative; z-index: 3; width: 100%; max-width: 58rem; }
  .hero h1 {
    font-size: clamp(2.4rem, 5.4vw, 4.4rem);
    line-height: 1.08; font-weight: 620; letter-spacing: -.035em;
    text-wrap: balance; max-width: 20em; margin: 0 auto;
  }
  .hero h1 .hw {
    display: inline-block; opacity: 0; transform: translateY(.28em); filter: blur(8px);
    animation: wordin .9s cubic-bezier(.2,.7,.15,1) both;
  }
  @keyframes wordin { to { opacity: 1; transform: none; filter: blur(0); } }
  @keyframes fadein { to { opacity: 1; } }
  /*
   * Die Unterzeile wuchs nicht mit.
   *
   * `font-size: 1rem` ist fest -- waehrend die Ueberschrift ueber `clamp` bis
   * 4rem geht. Auf einem grossen Bildschirm stand also eine 64px-Zeile ueber
   * einer 16px-Zeile, und das Verhaeltnis kippte: Der Satz wirkte wie eine
   * Fussnote, nicht wie die Erklaerung der Ueberschrift.
   *
   * Jetzt waechst sie mit, und die Deckkraft steigt von .62 auf .78 -- auf dem
   * dunklen Hero war der Text sonst da, aber anstrengend.
   *
   * `max-width` in `em` bleibt: Die Zeilenlaenge soll sich nach der Schrift
   * richten, nicht nach dem Fenster. 34em sind rund 70 Zeichen.
   */
  .hero p.lede {
    margin: 1.6rem auto 0; max-width: 34em;
    font-size: clamp(1.06rem, 1.45vw, 1.32rem);
    line-height: 1.6; color: rgba(255, 255, 255, .78);
    opacity: 0; animation: fadein .9s var(--e) .75s both;
  }
  .cta-row {
    margin-top: 2.6rem; display: flex; gap: .7rem; justify-content: center; align-items: center;
    flex-wrap: wrap; opacity: 0; animation: fadein .9s var(--e) .9s both;
  }
  .hero .ubtn { font-size: .78rem; padding: .95rem 1.6rem; }
  .trusted {
    position: relative; z-index: 3; width: 100%; margin-top: clamp(3rem, 7vh, 5.5rem);
    opacity: 0; animation: fadein 1s var(--e) 1.05s both;
  }
  /* Bis Kundenlogos vorliegen: die vier Zusagen, die den Erstkontakt
     traegen - keine Platzhalter-Logos auf einer Live-Seite. */
  .hpoints {
    list-style: none; display: flex; flex-wrap: wrap; justify-content: center;
    gap: .55rem 1.6rem; max-width: 54rem; margin: 0 auto;
    font-family: ui-monospace, Menlo, monospace; font-size: .64rem;
    letter-spacing: .14em; text-transform: uppercase; color: rgba(255,255,255,.5);
  }
  .hpoints li { display: flex; align-items: center; gap: 1.6rem; }
  .hpoints li + li::before { content: ""; width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: .6; }

  /* ---------- Statement: erhellt sich beim Scrollen -------------- */
  /* ── Die Aussage ────────────────────────────────────────────────────────
   * Ueber die volle Breite und so gross, dass sie nicht mehr als Absatz
   * gelesen wird, sondern als Flaeche. Der Satz ist hier das Bild -- es ist
   * die einzige Stelle der Seite, an der nur ein Gedanke steht, und er darf
   * den Platz dafuer haben.
   *
   * Dahinter drei Lagen, von denen keine etwas darstellt:
   *
   *   · zwei weiche Scheine, die der Flaeche eine Richtung geben
   *   · ein Ring, groesser als der Abschnitt und halb ausserhalb
   *   · ein feines Raster, das zur Mitte hin ausblendet
   *
   * Zusammen ergibt das Tiefe ohne Motiv. Ein Bild waere hier eine
   * Behauptung -- eine Andeutung ist es nicht.
   */
  /* Ohne Hintergrund. Hier lagen nacheinander ein Raster, ein Ring und ein
     gruenes Farbfeld -- jedes davon zog Aufmerksamkeit auf sich, die dem Satz
     gehoerte. Der Satz ist gross genug, um allein zu stehen; die Lichtkante,
     die beim Scrollen durch ihn laeuft, ist Bewegung genug.

     Damit braucht der Abschnitt auch kein `position`, kein `isolation` und
     keine z-Ebene mehr -- es gibt nichts, was gestapelt werden muesste. */
  .statement { padding: clamp(7rem, 15vw, 12rem) 0; }

  .statement p {
    font-size: clamp(2.1rem, 5.6vw, 5rem);
    line-height: 1.08; font-weight: 600; letter-spacing: -.04em;
    text-wrap: balance;
  }
  .statement p + p { margin-top: 1.5em; }
  /* Der zweite Satz traegt die Begruendung, nicht die Aussage -- er muss
     leiser sein. Gleich gross waeren es zwei Ueberschriften nebeneinander,
     und der Leser wuesste nicht, welche gilt. Gross ist er trotzdem: er
     nimmt dieselbe Breite und faellt nur in Gewicht und Farbe zurueck. */
  .statement p.sub {
    margin-top: .95em;
    font-size: clamp(1.05rem, 1.95vw, 1.62rem); line-height: 1.5;
    font-weight: 400; letter-spacing: -.015em; color: var(--muted);
    text-wrap: pretty;
  }
  .w { color: color-mix(in oklab, var(--ink) calc(var(--l, 0) * 100%), var(--dim)); }
  @supports not (color: color-mix(in oklab, red, blue)) {
    .w { color: var(--dim); transition: color .3s linear; }
    .w.lit { color: var(--ink); }
  }
  em { font-style: normal; }
  em .w { color: color-mix(in oklab, var(--accent) calc(var(--l, 0) * 100%), var(--dim)); }
  em .w.lit { color: var(--accent); }
  s { text-decoration: none; }
  s .w { color: color-mix(in oklab, var(--red) calc(var(--l, 0) * 100%), var(--dim)); }
  s .w.lit { color: var(--red); }

  /* ---------- Section-Geruest ----------------------------------- */
  section.block { padding: clamp(5rem, 10vw, 8rem) 0; position: relative; }
  .bhead { max-width: 46rem; margin-bottom: clamp(2.5rem, 5vw, 4rem); }
  /* Der Abstand oben trennt die Ueberschrift vom Etikett darueber. Wo kein
     Etikett steht, trennt er nichts und schiebt den Abschnitt nur nach unten. */
  .bhead > h2:first-child { margin-top: 0; }
  .bhead h2 {
    margin-top: 1.2rem;
    font-size: clamp(1.9rem, 4.2vw, 3.1rem);
    line-height: 1.08; font-weight: 640; letter-spacing: -.035em; text-wrap: balance;
  }
  .bhead p { margin-top: 1.1rem; color: var(--muted); font-size: 1.02rem; line-height: 1.7; max-width: 38em; }

  /* ---------- Mock-Panels -------------------------------------- */
  .mock {
    min-width: 0; border: 1px solid var(--line); background: var(--panel);
    border-radius: 6px; overflow: hidden;
  }
  .mock-bar {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    padding: .7rem .95rem; border-bottom: 1px solid var(--line);
    font-family: ui-monospace, Menlo, monospace;
    font-size: .62rem; letter-spacing: .12em; text-transform: uppercase; color: var(--faint);
  }
  .mock-bar b { color: #fff; font-weight: 400; }
  .mock-bar .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); flex: none; }
  /* ── Produktansicht auf der Startseite
     Praefix `pf` (polaris finding), weil `.frow` auf dieser Seite bereits die
     Formularzeile des Kontaktformulars ist (site.css, Kontaktformular-Block).
     Die stand weiter unten und gewann -- aus drei Spalten wurden zwei, und die
     Fundliste war zerlegt. ──────────────────────────────────
     Ein Fund, so wie ihn die App zeigt. Bewusst als Markup und nicht als
     Bildschirmfoto: es bleibt in beiden Modi richtig, skaliert ohne Unschaerfe,
     ist durchsuchbar und veraltet nicht, sobald sich die Oberflaeche aendert. */
  .pfgrid {
    display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
    gap: clamp(1.5rem, 3vw, 2.75rem); align-items: start;
  }
  @media (max-width: 900px) { .pfgrid { grid-template-columns: 1fr; } }

  .pfshot { background: var(--bg); }
  .pfshot-count { text-transform: none; letter-spacing: .04em; }

  .pfrow {
    display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: .9rem;
    align-items: start; padding: .95rem 1rem;
    border-bottom: 1px solid var(--line); text-decoration: none; color: inherit;
  }
  .pfrow:hover { background: var(--panel); }
  .pfsev {
    flex: none; padding: .18rem .42rem; border: 1px solid currentColor; border-radius: 2px;
    font-family: ui-monospace, Menlo, monospace; font-size: .58rem; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase; white-space: nowrap;
  }
  .pfsev.crit { color: var(--red); }
  .pfsev.high { color: var(--amber); }
  .pfmain { display: grid; gap: .22rem; min-width: 0; }
  .pftitle { font-size: .96rem; font-weight: 600; letter-spacing: -.01em; color: var(--ink); }
  .pfctx { font-size: .86rem; line-height: 1.5; color: var(--muted); }
  .pfmeta { font-size: .73rem; color: var(--faint); }
  .pfmono, .pfref { font-family: ui-monospace, Menlo, monospace; }
  .pfref { flex: none; font-size: .68rem; color: var(--faint); }

  .pfproof { padding: 1rem; background: var(--panel); }
  .pfproof-head {
    font-family: ui-monospace, Menlo, monospace; font-size: .6rem;
    letter-spacing: .14em; text-transform: uppercase; color: var(--faint);
  }
  /* Beweise werden nicht umbrochen -- eine umgebrochene Anfrage ist eine
     andere Anfrage. Deshalb scrollt der Block, statt den Inhalt zu verfaelschen. */
  .pfproof-pre {
    margin: .6rem 0 0; padding: .8rem .9rem; overflow-x: auto; white-space: pre;
    border: 1px solid var(--line); border-radius: 5px; background: var(--bg);
    font-family: ui-monospace, Menlo, monospace; font-size: .74rem; line-height: 1.75;
    color: var(--ink2, var(--muted));
  }
  .pfproof-foot { margin-top: .7rem; font-size: .8rem; line-height: 1.55; color: var(--muted); }

  .pfpoints { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.15rem; }
  .pfpoints li {
    display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .65rem;
    align-items: baseline; font-size: .93rem; line-height: 1.6; color: var(--muted);
  }
  .pfpoints li::before {
    content: "+"; font-family: ui-monospace, Menlo, monospace; color: var(--green);
  }
  .pfpoints b { color: var(--ink); font-weight: 620; }

  .mock-body {
    padding: 1rem .95rem; font-family: ui-monospace, Menlo, monospace;
    font-size: .74rem; line-height: 1.95; color: var(--muted); overflow-x: auto;
  }
  .mock-body .k { color: #fff; }
  .mock-body .ok { color: var(--green); }
  .mock-body .warn { color: var(--amber); }
  .mock-body .bad { color: var(--red); }
  .mock-body .dim { color: var(--dim); }
  .mrow {
    display: flex; gap: .85rem; align-items: baseline;
    padding: .8rem .95rem; border-top: 1px solid var(--line);
  }
  .mrow:first-child { border-top: 0; }
  .mrow .tag {
    flex: none; font-family: ui-monospace, Menlo, monospace;
    font-size: .55rem; letter-spacing: .12em; text-transform: uppercase; font-weight: 700;
    padding: .22rem .5rem; border: 1px solid; border-radius: 2px;
  }
  .mrow .tag.hi { color: var(--red); border-color: rgba(255,107,107,.45); }
  .mrow .tag.md { color: var(--amber); border-color: rgba(231,176,76,.45); }
  .mrow .tag.lo { color: var(--green); border-color: rgba(79,212,147,.45); }
  .mrow strong { display: block; font-size: .88rem; font-weight: 600; }
  .mrow span { color: var(--muted); font-size: .82rem; }

  /* ---------- Drei Karten unter dem Hero ------------------------ */
  .cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1rem; }
  @media (max-width: 980px) { .cards { grid-template-columns: minmax(0, 1fr); } }
  .card {
    min-width: 0; border: 1px solid var(--line); background: var(--panel);
    border-radius: 8px; padding: 1.3rem 1.3rem 1.5rem;
    display: flex; flex-direction: column; gap: 1rem;
    opacity: 0; transform: translateY(16px);
    transition: opacity .7s var(--e), transform .7s var(--e), border-color .3s var(--e);
  }
  .cards.in .card { opacity: 1; transform: none; }
  /* Die Staffelung lief bis drei -- so lang war die laengste Reihe. Auf der
     Feature-Seite stehen jetzt sechs Karten in einem Raster, und die zweite
     Reihe erschien schlagartig, waehrend die erste noch einlief. */
  .cards.in .card:nth-child(2) { transition-delay: .1s; }
  .cards.in .card:nth-child(3) { transition-delay: .2s; }
  .cards.in .card:nth-child(4) { transition-delay: .3s; }
  .cards.in .card:nth-child(5) { transition-delay: .4s; }
  .cards.in .card:nth-child(6) { transition-delay: .5s; }
  .card:hover { border-color: rgba(255,255,255,.22); }
  .card .clabel {
    font-family: ui-monospace, Menlo, monospace; font-size: .6rem; letter-spacing: .16em;
    text-transform: uppercase; color: var(--accent);
  }
  .card h3 { font-size: 1.06rem; font-weight: 620; letter-spacing: -.015em; }
  .card p { color: var(--muted); font-size: .92rem; line-height: 1.6; }
  .card .mock { margin-top: auto; background: #06070a; }

  /* ---------- Numerierte Bloecke ------------------------------- */
  .feat {
    display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 4.5rem); align-items: center;
    padding: clamp(2.5rem, 5vw, 4rem) 0;
  }
  .feat + .feat { border-top: 1px solid var(--line); }
  .feat:nth-child(even) .fcopy { order: 2; }
  @media (max-width: 940px) {
    .feat { grid-template-columns: minmax(0, 1fr); }
    .feat:nth-child(even) .fcopy { order: 0; }
  }
  .feat .fnum {
    font-family: ui-monospace, Menlo, monospace; font-size: .68rem;
    letter-spacing: .18em; text-transform: uppercase; color: var(--accent);
  }
  .feat h3 { margin-top: .9rem; font-size: clamp(1.35rem, 2.4vw, 1.9rem); font-weight: 630; letter-spacing: -.025em; }
  .feat p.fdesc { margin-top: .8rem; color: var(--muted); font-size: .99rem; line-height: 1.65; max-width: 34em; }
  .feat ul { list-style: none; margin-top: 1.4rem; }
  .feat li {
    position: relative; padding: .6rem 0 .6rem 1.5rem;
    font-size: .94rem; border-top: 1px solid var(--line);
  }
  .feat li:last-child { border-bottom: 1px solid var(--line); }
  .feat li::before {
    content: "+"; position: absolute; left: 0; top: .6rem; color: var(--accent);
    font-family: ui-monospace, Menlo, monospace; font-size: .85em;
  }
  .feat .fcopy, .feat .mock { opacity: 0; transition: opacity .8s var(--e), transform .8s var(--e); }
  .feat .fcopy { transform: translateY(14px); }
  .feat .mock { transform: translateY(14px); transition-delay: .1s; }
  .feat.in .fcopy, .feat.in .mock { opacity: 1; transform: none; }

  .feat p.fmeta {
    margin-top: 1.3rem; padding-top: .9rem; border-top: 1px solid var(--line);
    font-family: ui-monospace, Menlo, monospace; font-size: .62rem;
    letter-spacing: .13em; text-transform: uppercase; color: var(--faint);
  }
  /* Schluessel/Wert-Zeilen in einem Mock */
  .mspecs { padding: .3rem 0; }
  .mspecs .mrow { justify-content: space-between; padding: .58rem .95rem; }
  .mspecs .mk {
    font-family: ui-monospace, Menlo, monospace; font-size: .66rem;
    letter-spacing: .11em; text-transform: uppercase; color: var(--faint);
  }
  .mspecs .mv { font-family: ui-monospace, Menlo, monospace; font-size: .75rem; color: #fff; text-align: right; }
  html.light .mspecs .mv { color: var(--ink); }

  /* ---------- Zahlenreihe -------------------------------------- */
  .stats {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 6px; overflow: hidden;
  }
  @media (max-width: 780px) { .stats { grid-template-columns: minmax(0, 1fr); } }
  .stat { background: var(--panel); padding: 1.6rem 1.5rem; }
  .stat b {
    display: block; font-size: clamp(1.7rem, 3vw, 2.3rem); font-weight: 650;
    letter-spacing: -.03em; font-variant-numeric: tabular-nums;
  }
  .stat p { margin-top: .5rem; color: var(--muted); font-size: .9rem; line-height: 1.6; }

  /* ---------- Signal-Trichter ----------------------------------
     Analogie von aikido.dev ("Security tools generate a lot of alerts.
     Only a few are worth acting on."), bei uns als Grafik: aus dem
     Rohrauschen bleiben am Ende drei bestaetigte Funde. */
  .funnel {
    margin-top: 1rem; border: 1px solid var(--line); border-radius: 6px;
    background: var(--panel); overflow: hidden;
  }
  .funnel .fhead {
    display: flex; align-items: baseline; justify-content: space-between; gap: 1rem;
    padding: 1.1rem 1.3rem; border-bottom: 1px solid var(--line);
    font-family: ui-monospace, Menlo, monospace; font-size: .62rem;
    letter-spacing: .16em; text-transform: uppercase; color: var(--faint);
  }
  .funnel .fhead b { color: var(--ink); font-weight: 400; }
  .fsteps { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
  @media (max-width: 820px) { .fsteps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  .fstep { padding: 1.4rem 1.3rem 1.6rem; border-left: 1px solid var(--line); }
  .fstep:first-child { border-left: 0; }
  .fstep .fs-label {
    font-family: ui-monospace, Menlo, monospace; font-size: .58rem;
    letter-spacing: .16em; text-transform: uppercase; color: var(--faint);
  }
  .fstep .fs-num {
    margin-top: .7rem; font-size: clamp(1.6rem, 3vw, 2.2rem); font-weight: 650;
    letter-spacing: -.03em; font-variant-numeric: tabular-nums; line-height: 1;
  }
  .fstep.keep .fs-num { color: var(--accent); }
  /* Balken zeigt, wie viel vom Rauschen uebrig bleibt */
  .fstep .fs-bar { margin-top: .9rem; height: 4px; background: var(--line); border-radius: 2px; overflow: hidden; }
  .fstep .fs-bar i {
    display: block; height: 100%; width: 0; background: var(--faint);
    transition: width 1s var(--e);
  }
  .fstep.keep .fs-bar i { background: var(--accent); }
  .funnel.in .fstep .fs-bar i { width: var(--w, 100%); }
  .fstep p { margin-top: .8rem; color: var(--muted); font-size: .88rem; line-height: 1.55; }
  .funnel .ffoot {
    padding: 1rem 1.3rem; border-top: 1px solid var(--line);
    font-family: ui-monospace, Menlo, monospace; font-size: .64rem;
    letter-spacing: .12em; text-transform: uppercase; color: var(--faint);
  }
  .funnel .ffoot b { color: var(--accent); font-weight: 400; }

  /* ---------- Vertrauenskette ----------------------------------
     Numerierte Schritte mit durchgehender Linie - so macht aikido.dev
     transparent, was sie mit Kundendaten tun. Bei uns: was wir
     anfassen und was garantiert nicht. */
  .chain { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0; }
  @media (max-width: 900px) { .chain { grid-template-columns: minmax(0, 1fr); } }
  .clink { position: relative; padding: 0 1.6rem 2rem 0; }
  .clink .cnum {
    display: grid; place-items: center; width: 26px; height: 26px; border-radius: 50%;
    border: 1px solid var(--line); background: var(--bg);
    font-family: ui-monospace, Menlo, monospace; font-size: .62rem; color: var(--accent);
    position: relative; z-index: 1;
  }
  /* Verbindungslinie zum naechsten Glied */
  .clink::before {
    content: ""; position: absolute; left: 13px; top: 13px; right: 0; height: 1px;
    background: var(--line);
  }
  .chain .clink:last-child::before { display: none; }
  @media (max-width: 900px) {
    .clink { padding: 0 0 1.8rem 2.4rem; }
    .clink .cnum { position: absolute; left: 0; top: 0; }
    .clink::before { left: 13px; top: 26px; right: auto; bottom: 0; width: 1px; height: auto; }
  }
  .clink h3 { margin-top: 1.1rem; font-size: 1rem; font-weight: 620; letter-spacing: -.01em; }
  .clink p { margin-top: .5rem; color: var(--muted); font-size: .9rem; line-height: 1.6; max-width: 26em; }
  @media (max-width: 900px) { .clink h3 { margin-top: 0; } }

  /* ---------- Garantie ----------------------------------------- */
  .guarantee {
    margin-top: 1rem; border: 1px solid var(--accent); border-radius: 6px;
    background: color-mix(in oklab, var(--accent) 8%, transparent);
    padding: 1.2rem 1.4rem;
    display: flex; align-items: baseline; justify-content: space-between; gap: 1.2rem; flex-wrap: wrap;
  }
  .guarantee b {
    font-family: ui-monospace, Menlo, monospace; font-size: .66rem;
    letter-spacing: .16em; text-transform: uppercase; color: var(--accent); font-weight: 600;
  }
  .guarantee span { color: var(--muted); font-size: .94rem; line-height: 1.6; max-width: 52em; }

  /* ── Der eine Preis ───────────────────────────────────────────────────────
   * Zwei Spalten statt drei Karten: links die Zahl und der Knopf, rechts was
   * dafuer geliefert wird. Eine einzelne Karte in einem Dreier-Raster saehe
   * aus, als fehlten zwei -- derselbe Eindruck, den leere Rasterzellen machen.
   */
  .oneplan {
    display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1fr);
    gap: clamp(1.5rem, 4vw, 3.5rem); align-items: start;
    border: 1px solid var(--line); border-radius: 10px;
    padding: clamp(1.8rem, 4vw, 2.8rem);
    /* Bezugsrahmen fuer die Lichtkante und den Schein, und die Kante, an der
       beide beschnitten werden. */
    position: relative; overflow: hidden;
  }
  @media (max-width: 820px) { .oneplan { grid-template-columns: minmax(0, 1fr); } }

  .oneplan .price { font-size: clamp(2.6rem, 6vw, 3.6rem); font-weight: 640; letter-spacing: -.04em; line-height: 1; }
  .oneplan .price span { font-size: .9rem; font-weight: 500; color: var(--muted); letter-spacing: 0; }
  .oneplan-head > p { margin-top: 1rem; color: var(--muted); font-size: .95rem; line-height: 1.6; }
  .oneplan-head .ubtn { margin-top: 1.5rem; }
  .oneplan-head .tnote {
    margin-top: .9rem; font-family: ui-monospace, Menlo, monospace;
    font-size: .62rem; letter-spacing: .12em; text-transform: uppercase; color: var(--faint);
  }

  .oneplan-list { list-style: none; display: grid; gap: 0; }
  .oneplan-list li {
    padding: .85rem 0; border-top: 1px solid var(--line);
    font-size: .95rem; line-height: 1.55; color: var(--ink2, var(--ink));
    display: grid; grid-template-columns: 1.1rem 1fr; gap: .7rem; align-items: baseline;
  }
  .oneplan-list li:first-child { border-top: 0; padding-top: 0; }
  .oneplan-list li::before { content: "+"; color: var(--accent); font-weight: 600; }

  /* ---------- Prozess ------------------------------------------ */
  /*
   * So viele Spalten wie Schritte -- nicht vier, komme was wolle.
   *
   * Das Raster stand fest auf `repeat(4, …)`, weil sein erster Nutzer (die
   * Regeln auf "Ueber uns") vier Karten hat. Die Preisseite hat drei, und die
   * vierte Spalte blieb als grauer Kasten stehen: die Trennlinien sind hier
   * kein `border`, sondern der Zwischenraum selbst (`gap: 1px` ueber einem
   * eingefaerbten Grund). Eine leere Zelle zeigt damit den Grund des Rasters,
   * und der ist die Linienfarbe.
   *
   * `grid-auto-flow: column` legt fuer jedes Kind genau eine Spalte an und
   * keine mehr. Das stimmt fuer drei, fuer vier und fuer jede spaetere Zahl,
   * ohne dass jemand daran denken muss.
   */
  .procgrid {
    display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr);
    border: 1px solid var(--line); border-radius: 6px; overflow: hidden;
  }
  /* Wie bei `.cgrid`: sonst bleibt bei zwei Spalten und drei Schritten auf
     Tablet-Breite wieder eine Zelle grau stehen. */
  .procgrid > * { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); margin: 0 -1px -1px 0; }
  /* Untereinander muss der Fluss zurueck auf Zeilen -- sonst legt das Raster
     weiter Spalten an und `grid-template-columns` bleibt wirkungslos. */
  /*
   * Auf Tablet-Breite eine Spalte -- ausser bei vier Schritten, dann zwei.
   *
   * Dieses Raster hat zwei Nutzer: die Preisseite mit drei Schritten und "Ueber
   * uns" mit vieren. Eine feste Zweispalten-Stufe strandet die drei zu 2 + 1,
   * und die leere Zelle daneben sieht aus wie ein Fehler. `:has()` fragt die
   * Zahl ab, statt sie zu raten: nur wo ein viertes Kind existiert, lohnen sich
   * zwei Spalten.
   */
  @media (max-width: 980px) {
    .procgrid { grid-auto-flow: row; grid-template-columns: minmax(0, 1fr); }
    .procgrid:has(> :nth-child(4)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  }
  @media (max-width: 620px) {
    .procgrid, .procgrid:has(> :nth-child(4)) { grid-auto-flow: row; grid-template-columns: minmax(0, 1fr); }
  }
  .proc {
    background: var(--panel); padding: 1.7rem 1.5rem 1.9rem; position: relative;
    transition: background .3s var(--e);
  }
  .proc:hover { background: var(--panel2); }
  .proc .pn { font-family: ui-monospace, Menlo, monospace; font-size: .62rem; letter-spacing: .16em; text-transform: uppercase; color: var(--accent); }
  .proc h3 { margin-top: 1rem; font-size: 1.02rem; font-weight: 620; letter-spacing: -.01em; }
  .proc p { margin-top: .55rem; color: var(--muted); font-size: .9rem; line-height: 1.6; }
  .proc .ptime {
    margin-top: 1.1rem; font-family: ui-monospace, Menlo, monospace;
    font-size: .6rem; letter-spacing: .14em; text-transform: uppercase; color: var(--faint);
  }

  /* ---------- Pricing ----------------------------------------- */
  .plans {
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 6px; overflow: hidden;
  }
  @media (max-width: 940px) { .plans { grid-template-columns: minmax(0, 1fr); } }
  .plan { background: var(--panel); padding: 2rem 1.7rem 2.1rem; display: flex; flex-direction: column; position: relative; }
  .plan.mid, .oneplan { background: var(--panel2); }
  .plan .chip {
    position: absolute; top: 0; right: 0;
    font-family: ui-monospace, Menlo, monospace; font-size: .55rem; letter-spacing: .14em;
    text-transform: uppercase; font-weight: 700; background: #fff; color: #000; padding: .3rem .6rem;
  }
  .plan h3 { font-family: ui-monospace, Menlo, monospace; font-size: .66rem; letter-spacing: .18em; text-transform: uppercase; color: var(--faint); font-weight: 600; }
  .plan .price { margin-top: 1.3rem; font-size: 2.1rem; font-weight: 650; letter-spacing: -.03em; font-variant-numeric: tabular-nums; }
  .plan .price span { font-size: .76rem; font-weight: 400; color: var(--faint); letter-spacing: 0; }
  .plan ul { list-style: none; margin: 1.3rem 0 1.8rem; flex: 1; }
  .plan li { position: relative; padding: .5rem 0 .5rem 1.4rem; font-size: .92rem; color: var(--muted); border-top: 1px solid var(--line); }
  .plan li::before { content: "+"; position: absolute; left: 0; color: var(--accent); font-family: ui-monospace, Menlo, monospace; }
  .plan .ubtn { align-self: flex-start; }

  /* ---------- FAQ --------------------------------------------- */
  .faqgrid { display: grid; grid-template-columns: .75fr 1.25fr; gap: clamp(2.5rem, 6vw, 5rem); align-items: start; }
  @media (max-width: 900px) { .faqgrid { grid-template-columns: minmax(0, 1fr); } }
  .accordion details { border-bottom: 1px solid var(--line); }
  .accordion details:first-child { border-top: 1px solid var(--line); }
  .accordion summary {
    cursor: pointer; list-style: none;
    display: flex; justify-content: space-between; align-items: center; gap: 1.5rem;
    padding: 1.25rem .1rem; font-size: 1rem; font-weight: 600; letter-spacing: -.01em;
  }
  .accordion summary::-webkit-details-marker { display: none; }
  .accordion summary::after {
    content: "+"; font-family: ui-monospace, Menlo, monospace; font-size: 1.1rem;
    color: var(--accent); flex: none; transition: transform .25s var(--e);
  }
  .accordion details[open] summary::after { transform: rotate(45deg); }
  .accordion details p { color: var(--muted); padding: 0 2.2rem 1.3rem .1rem; font-size: .94rem; line-height: 1.7; }
  .accordion details[open] p { animation: accopen .3s var(--e); }
  @keyframes accopen { from { opacity: 0; transform: translateY(-5px); } }

  /* ---------- Finale + Footer ---------------------------------- */
  .final { padding: clamp(7rem, 15vw, 12rem) 0; text-align: center; }
  /*
   * Wo ein Abschnitt direkt vor dem Abschluss endet, treffen zwei Innenmasse
   * aufeinander: die 8rem Unterkante des Abschnitts und die 12rem Oberkante des
   * Abschlusses -- zusammen ueber 300 Pixel Leere. Das faellt erst auf, wenn
   * eine Seite kurz wird; auf "Ueber uns" sind zwei Abschnitte entfallen, und
   * seitdem steht die Ueberschrift eine halbe Bildschirmhoehe zu tief.
   */
  .block + .final { padding-top: clamp(3rem, 6vw, 5rem); }
  .final h2 { font-size: clamp(2.2rem, 5.6vw, 4.4rem); font-weight: 640; letter-spacing: -.04em; line-height: 1.05; text-wrap: balance; }
  .final p { margin: 1.3rem auto 0; max-width: 34em; color: var(--muted); font-size: 1.02rem; line-height: 1.7; }
  .final .cta-row { margin-top: 2.4rem; opacity: 1; animation: none; }

  /* Im Abschluss steht der Kasten mittig und schmaler als auf der Preisseite,
     wo er die volle Spaltenbreite füllt. */
  .final .guarantee { margin: 2.2rem auto 0; max-width: 46em; text-align: left; }

  /* ── Fusszeile ──────────────────────────────────────────────────────────
   * Mitternachtsblau auf jeder Seite, in beiden Fassungen. Sie ist der einzige
   * Block, der ueberall gleich aussieht -- deshalb traegt sie die Farbe fest
   * und nicht ueber die Token, die zwischen hell und dunkel wechseln.
   *
   * Die oberen Ecken sind gerundet wie die Unterkante des dunklen Teils auf der
   * Startseite: derselbe Abschluss, einmal nach unten, einmal nach oben. Ohne
   * die Rundung waere es eine Farbfleche, die zufaellig unten anfaengt.
   */
  footer {
    margin-top: clamp(3rem, 6vw, 5rem);
    padding: clamp(3rem, 5vw, 4.5rem) 0 2.6rem;
    /* Mitternachtsblau oben, Schwarz unten. Vier Stufen statt zwei: ein
       Verlauf von Blau direkt nach Schwarz kippt in der Mitte ins Graue,
       weil der kuerzeste Weg zwischen beiden durch entsaettigte Toene
       fuehrt. Die Zwischenstufen halten ihn im Blau, bis er unten
       tatsaechlich ankommt. */
    background: linear-gradient(180deg,
      #0c1a3a 0%,
      #0a1530 34%,
      #060c1c 68%,
      #000000 100%);
    color: #fff;
    border-top-left-radius: clamp(1.25rem, 2.5vw, 2rem);
    border-top-right-radius: clamp(1.25rem, 2.5vw, 2rem);
  }
  /* Auf dunklem Grund gelten die hellen Werte -- auch in der hellen Fassung,
     wo `--muted` und `--faint` dunkle Graus sind und hier verschwinden wuerden. */
  footer .logo, html.light footer .logo { color: #fff; }
  footer .fbrand p { color: rgba(255,255,255,.6); }
  footer .fcol h4 { color: rgba(255,255,255,.38); }
  /* `html.light .fcol a` weiter unten ist spezifischer als `footer .fcol a`
     (zwei Klassen und zwei Typen gegen eine Klasse und zwei Typen) und faerbte
     die Links dunkel auf dem dunklen Grund. Deshalb hier dieselbe Klasse noch
     einmal mit `footer` davor. */
  footer .fcol a, html.light footer .fcol a { color: rgba(255,255,255,.72); }
  footer .fcol a:hover, html.light footer .fcol a:hover { color: #fff; }
  footer .fbottom { border-top-color: rgba(255,255,255,.12); color: rgba(255,255,255,.4); }

  /* Die beiden Marken stehen ganz unten, wo der Verlauf schon fast schwarz
     ist. Als Fliesstext in der Farbe der Zeile daneben (40 % Weiss) waeren
     sie das Unauffaelligste der Seite -- dabei sind sie das Einzige dort, das
     jemand sucht. Also als Plaketten: eigener Rand, eigener Grund, fast
     volles Weiss. */
  footer .fcerts { display: flex; gap: .5rem; flex-wrap: wrap; }
  footer .fcerts b {
    display: inline-flex; align-items: center;
    padding: .36rem .75rem; border-radius: 999px;
    border: 1px solid rgba(255,255,255,.24);
    background: rgba(255,255,255,.07);
    color: rgba(255,255,255,.94);
    font-family: ui-monospace, Menlo, monospace;
    font-size: .66rem; letter-spacing: .1em; text-transform: uppercase; font-weight: 500;
    white-space: nowrap;
  }
  .fgrid { display: grid; grid-template-columns: 1.6fr repeat(3, minmax(0, 1fr)); gap: 2.5rem; }
  @media (max-width: 860px) { .fgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  @media (max-width: 520px) { .fgrid { grid-template-columns: minmax(0, 1fr); } }
  .fbrand p { margin-top: 1rem; color: var(--muted); font-size: .88rem; line-height: 1.6; max-width: 24em; }
  .fcol h4 { font-family: ui-monospace, Menlo, monospace; font-size: .62rem; letter-spacing: .18em; text-transform: uppercase; color: var(--faint); font-weight: 400; margin-bottom: 1rem; }
  .fcol ul { list-style: none; }
  .fcol li { margin-bottom: .6rem; }
  .fcol a { font-family: ui-monospace, Menlo, monospace; font-size: .7rem; letter-spacing: .08em; text-transform: uppercase; color: rgba(255,255,255,.72); text-decoration: none; }
  .fcol a:hover { color: #fff; }
  .fbottom {
    margin-top: 3rem; padding-top: 1.4rem; border-top: 1px solid var(--line);
    display: flex; justify-content: space-between; flex-wrap: wrap; gap: 1rem;
    font-family: ui-monospace, Menlo, monospace; font-size: .62rem; letter-spacing: .13em;
    text-transform: uppercase; color: var(--faint);
  }

  /* ---------- Kontaktformular ---------------------------------- */
  .cform { margin: 2.6rem auto 0; max-width: 44rem; text-align: left; display: grid; gap: .9rem; }
  .frow { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .9rem; }
  @media (max-width: 640px) { .frow { grid-template-columns: minmax(0, 1fr); } }
  .cform label {
    display: grid; gap: .45rem;
    font-family: ui-monospace, Menlo, monospace; font-size: .6rem;
    letter-spacing: .16em; text-transform: uppercase; color: var(--faint);
  }
  .cform input, .cform select, .cform textarea {
    font-family: inherit; font-size: .95rem; color: var(--ink);
    background: var(--panel); border: 1px solid var(--line); border-radius: 4px;
    padding: .8rem .9rem; width: 100%;
    transition: border-color .2s var(--e), background .2s var(--e);
  }
  html.light .cform input, html.light .cform select, html.light .cform textarea { background: #fff; }
  .cform textarea { resize: vertical; min-height: 6.5rem; }
  .cform input::placeholder, .cform textarea::placeholder { color: var(--faint); }
  .cform input:focus, .cform select:focus, .cform textarea:focus {
    outline: none; border-color: var(--accent);
  }
  .cform .hp { position: absolute; left: -9999px; width: 1px; height: 1px; }
  .fsubmit { display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap; margin-top: .5rem; }
  .cform button { border: 0; cursor: pointer; font-family: ui-monospace, Menlo, monospace; }
  .cform button[disabled] { opacity: .5; cursor: default; }
  .fnote { font-size: .84rem; color: var(--muted); line-height: 1.5; max-width: 24em; }
  .fstatus {
    margin: 0; font-family: ui-monospace, Menlo, monospace; font-size: .68rem;
    letter-spacing: .1em; text-transform: uppercase; min-height: 1em;
  }
  .fstatus.ok { color: var(--green); }
  .fstatus.bad { color: var(--red); }
  .final .ulabel { display: block; margin-bottom: 1.2rem; }

  /* ---------- Unterseiten ---------------------------------------
     Kein dunkler Hero unter dem Header: von Anfang an dunkle Schrift,
     darunter ein ruhiger Seitenkopf statt der Buehne. */
  /*
   * Nur solange der Header **transparent** ist.
   *
   * Hier stand derselbe Satz Regeln zweimal: einmal ohne `:not(.solid)` und
   * direkt darunter noch einmal mit. Die ungeschuetzte Fassung galt auch fuer
   * die geglaste Kapsel und war spezifischer als deren eigene Farben -- auf
   * einer Unterseite blieb die Wortmarke deshalb beim Scrollen dunkel und
   * verschwand in der dunkelblauen Kapsel. Auf der Startseite trat das nie
   * auf, weil dort `body.sub` fehlt.
   *
   * Uebrig bleibt die geschuetzte Fassung. Damit verhaelt sich die Kopfzeile
   * auf allen Seiten gleich: dunkle Schrift ueber dem hellen Seitenkopf,
   * helle Schrift in der Kapsel.
   */
  .hnav a.plain.on { color: var(--ink); font-weight: 600; }
  html.light header:not(.solid):not(.overmenu) .hnav a.plain.on { color: #fff; }
  .menu nav a.on { color: var(--accent); }
  html.light body.sub header:not(.solid) .logo,
  html.light body.sub header:not(.solid) .menubtn { color: var(--ink); }
  html.light body.sub header:not(.solid) .hnav a.plain { color: var(--muted); }
  html.light body.sub header:not(.solid) .hnav a.plain:hover,
  html.light body.sub header:not(.solid) .hnav a.plain.on { color: var(--ink); }
  html.light body.sub header:not(.solid) .tsw { border-color: var(--line); background: rgba(12,21,36,.04); }
  html.light body.sub header:not(.solid) .tsw button { color: var(--faint); }
  html.light body.sub header:not(.solid) .tsw button[aria-pressed="true"] { background: rgba(12,21,36,.1); color: var(--ink); }
  html.light body.sub header:not(.solid) .ubtn.solid { background: var(--brand); color: var(--brand-ink); }

  .phead {
    padding: calc(var(--hh, 87px) + clamp(3rem, 8vw, 6rem)) 0 clamp(2.5rem, 6vw, 4.5rem);
  }
  .phead .wide { max-width: 62rem; }
  .phead h1 {
    margin-top: 1.2rem; font-size: clamp(2.2rem, 5.4vw, 3.7rem);
    line-height: 1.04; font-weight: 640; letter-spacing: -.04em; text-wrap: balance;
  }
  .phead p {
    margin-top: 1.3rem; max-width: 36em; color: var(--muted);
    font-size: clamp(1rem, 1.4vw, 1.12rem); line-height: 1.65;
  }

  .midlink {
    margin-top: 2rem; display: flex; align-items: baseline; gap: 1.2rem; flex-wrap: wrap;
    font-family: ui-monospace, Menlo, monospace; font-size: .66rem;
    letter-spacing: .14em; text-transform: uppercase;
  }
  .midlink a { text-decoration: none; }
  .midlink a:hover { text-decoration: underline; text-underline-offset: 4px; }

  /* Prosa-Bloecke auf About */
  .prose { max-width: 40em; }
  .prose p { margin-top: 1.1rem; color: var(--muted); font-size: 1.02rem; line-height: 1.75; }
  .prose p strong { color: var(--ink); font-weight: 600; }
  .prose p:first-child { margin-top: 0; }
  .todo {
    margin-top: 1.5rem; max-width: 40em; border: 1px dashed var(--red); border-radius: 6px;
    padding: 1.1rem 1.3rem; background: color-mix(in oklab, var(--red) 6%, transparent);
    font-size: .92rem; line-height: 1.6; color: var(--muted);
  }
  .todo b {
    display: block; margin-bottom: .4rem; color: var(--red);
    font-family: ui-monospace, Menlo, monospace; font-size: .62rem;
    letter-spacing: .16em; text-transform: uppercase;
  }

  /* Kontaktseite: Formular links, Fakten rechts */
  /* `.contactgrid` ist entfallen: das zweispaltige Raster hielt eine halbe
     Seitenbreite fuer eine Spalte frei, in der nur noch zwei Zeilen stehen.
     Eine Spalte, das Formular in seinen eigenen 44rem, mittig. */
  .cwrap { max-width: 44rem; margin: 0 auto; }
  /* Der Hinweis unter dem Formular, durch eine Haarlinie abgesetzt -- er gehoert
     dazu, ist aber kein Teil des Formulars mehr. */
  .callnote { margin-top: 2.4rem; padding-top: 1.7rem; border-top: 1px solid var(--line); }
  .facts { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 6px; overflow: hidden; }
  .fact { background: var(--panel); padding: 1.1rem 1.2rem; }
  html.light .fact { background: #fff; }
  .fact h4 {
    font-family: ui-monospace, Menlo, monospace; font-size: .58rem; font-weight: 400;
    letter-spacing: .16em; text-transform: uppercase; color: var(--faint);
  }
  .fact p { margin-top: .5rem; font-size: .94rem; line-height: 1.6; color: var(--muted); }
  .fact p a { text-decoration: none; }
  .fact p a:hover { text-decoration: underline; text-underline-offset: 3px; }
  .fact strong { color: var(--ink); font-weight: 600; }

  /* Derselbe Hinweis, ohne Kasten.
     Ein einzelner Eintrag in einem gerahmten Raster liest sich wie eine Liste,
     der die uebrigen Punkte fehlen -- der Rahmen verspricht Nachbarn. Die
     Typografie bleibt die der Kaesten, damit die Seite nicht zwei Tonlagen
     fuer dieselbe Art Randbemerkung hat. */
  .callnote h4 {
    font-family: ui-monospace, Menlo, monospace;
    font-size: .58rem; font-weight: 400; letter-spacing: .16em;
    text-transform: uppercase; color: var(--faint);
  }
  .callnote p { margin-top: .55rem; font-size: .94rem; line-height: 1.6; color: var(--muted); }

  .phead .cta-row { animation-delay: .2s; }
  .microline {
    margin-top: 1.4rem; display: flex; gap: .5rem 1.4rem; flex-wrap: wrap;
    font-family: ui-monospace, Menlo, monospace; font-size: .6rem;
    letter-spacing: .14em; text-transform: uppercase; color: var(--faint);
  }
  .pill {
    display: inline-flex; align-items: center; gap: .45rem; padding: .3rem .7rem;
    border: 1px solid var(--line); border-radius: 20px; background: var(--panel);
    font-family: ui-monospace, Menlo, monospace; font-size: .58rem;
    letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
  }
  .pill b { color: var(--green); font-weight: 400; }

  /* Reportliste (Features) */
  .rlist { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
  .rlist > div { background: var(--panel); padding: 1.1rem 1.3rem; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .9rem; }
  html.light .rlist > div { background: #fff; }
  .rlist .rmark { color: var(--green); font-family: ui-monospace, Menlo, monospace; font-size: .8rem; }
  .rlist h4 { font-size: .98rem; font-weight: 600; letter-spacing: -.015em; }
  .rlist p { margin-top: .35rem; color: var(--muted); font-size: .9rem; line-height: 1.6; }

  /* Tarifkarten: Kopf + Spezifikationszeilen */
  .tspec { margin-top: 1.2rem; display: grid; gap: 1px; background: var(--line); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
  .tspec > div { background: var(--panel); padding: .7rem 0; }
  html.light .tspec > div { background: transparent; }
  .tspec span {
    display: block; font-family: ui-monospace, Menlo, monospace; font-size: .54rem;
    letter-spacing: .16em; text-transform: uppercase; color: var(--faint);
  }
  .tspec b { display: block; margin-top: .3rem; font-size: .9rem; font-weight: 600; }
  .tnote {
    margin-top: 1rem; font-family: ui-monospace, Menlo, monospace; font-size: .58rem;
    letter-spacing: .12em; text-transform: uppercase; color: var(--green); text-align: center;
  }

  /* Vergleichstabelle */
  .cmp { width: 100%; border-collapse: collapse; font-size: .94rem; }
  .cmp th, .cmp td { padding: .95rem 1.1rem; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
  .cmp thead th {
    font-family: ui-monospace, Menlo, monospace; font-size: .56rem; font-weight: 400;
    letter-spacing: .16em; text-transform: uppercase; color: var(--faint); border-bottom: 1px solid var(--ink);
  }
  .cmp tbody th { font-weight: 500; color: var(--muted); width: 30%; }
  .cmp .us { color: var(--ink); font-weight: 600; }
  .cmp .them { color: var(--faint); }
  .cmpwrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 8px; padding: 0 .4rem; background: var(--panel); }
  html.light .cmpwrap { background: #fff; }

  /* ── Unsere Spalte, wie im Vergleich auf der Startseite ───────────────────
   * Dasselbe Blau (#0c1a3a) wie Kopfzeilen-Kapsel, Fusszeile und die
   * Vergleichstabelle dort, und derselbe zurueckhaltende gruene Schein.
   *
   * Anders als dort braucht es hier keinen Kunstgriff gegen Streifen: eine
   * Tabelle ist **ein** Raster, ihre Zellen stossen von sich aus aneinander.
   * `border-collapse: collapse` legt die senkrechten Kanten zusammen, sodass
   * links und rechts je eine durchgehende Linie steht.
   */
  .cmpwrap { overflow: hidden; }
  .cmp thead th:nth-child(2),
  .cmp .us {
    background:
      linear-gradient(90deg, rgba(92, 237, 163, .10) 0%, rgba(92, 237, 163, 0) 46%),
      #0c1a3a;
    color: #fff;
    border-left: 1px solid rgba(92, 237, 163, .28);
    border-right: 1px solid rgba(92, 237, 163, .28);
    border-bottom-color: rgba(92, 237, 163, .14);
  }
  /* Der Kopf eine Spur heller, und die schwarze Trennlinie darunter wuerde auf
     dem dunklen Grund verschwinden. */
  .cmp thead th:nth-child(2) {
    background:
      linear-gradient(90deg, rgba(92, 237, 163, .13) 0%, rgba(92, 237, 163, 0) 46%),
      #102547;
    border-bottom-color: rgba(92, 237, 163, .3);
  }
  /* Die Wortmarke traegt ihre eigene Schrift; die Versalien und die Sperrung
     des Tabellenkopfs gelten fuer sie nicht. */
  .cmp-logo { font-size: .95rem; letter-spacing: .005em; justify-content: center; }

  /* Kontaktkarten */
  /*
   * Die Trennlinien liegen auf den Karten, nicht unter ihnen.
   *
   * Vorher war der Grund des Rasters eingefaerbt und schien durch `gap: 1px`
   * durch -- elegant, solange jede Zelle belegt ist. Sechs Karten in vier
   * Spalten lassen zwei Zellen frei, und die zeigten den Grund: zwei graue
   * Kaesten unten rechts.
   *
   * Jetzt zieht jede Karte ihre eigene Linie nach rechts und nach unten. Eine
   * leere Zelle zeichnet nichts, weil es sie nicht gibt. Die negativen
   * Aussenmasse schieben die Linien der letzten Spalte und der letzten Zeile
   * unter den Rahmen des Rasters, sonst laege dort ein doppelter Strich.
   */
  /*
   * Drei Spalten, nicht `auto-fit`.
   *
   * `auto-fit` packte auf breiten Schirmen vier Karten nebeneinander. Bei sechs
   * Karten bleiben dann zwei Zellen leer -- und weil der Rahmen des Rasters ein
   * Rechteck ist, umschliesst er die leere Flaeche mit. Erst war sie grau, dann
   * war sie weiss und eingerahmt; beides sah aus wie ein Kasten, den jemand
   * vergessen hat.
   *
   * Sechs Karten gehen glatt auf in drei, in zwei und in einer Spalte. Damit
   * gibt es auf keiner Breite eine leere Zelle, und der Rahmen umschliesst nur
   * Inhalt. Die Karten werden dabei breiter und lesen sich besser als in vier
   * Spalten.
   */
  .cgrid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border: 1px solid var(--line); border-radius: 8px; overflow: hidden; }
  @media (max-width: 900px) { .cgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
  @media (max-width: 560px) { .cgrid { grid-template-columns: minmax(0, 1fr); } }
  .cgrid > * { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); margin: 0 -1px -1px 0; }
  .ccard { background: var(--panel); padding: 1.5rem 1.5rem 1.6rem; display: flex; flex-direction: column; }
  html.light .ccard { background: #fff; }
  .ccard h3 { font-size: 1.05rem; font-weight: 620; letter-spacing: -.02em; }
  .ccard p { margin-top: .5rem; color: var(--muted); font-size: .92rem; line-height: 1.6; flex: 1; }
  .ccard a.clk {
    margin-top: 1.1rem; align-self: flex-start; font-family: ui-monospace, Menlo, monospace;
    font-size: .62rem; letter-spacing: .14em; text-transform: uppercase; text-decoration: none;
  }
  .ccard a.clk:hover { text-decoration: underline; text-underline-offset: 4px; }

  /* Team / Buero */
  .people { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); gap: 1.4rem 1.2rem; }
  .person .pimg {
    aspect-ratio: 1; border: 1px solid var(--line); border-radius: 6px; background: var(--panel);
    display: grid; place-items: center; font-family: ui-monospace, Menlo, monospace;
    font-size: .55rem; letter-spacing: .14em; text-transform: uppercase; color: var(--faint); text-align: center; padding: 1rem;
  }
  .person h4 { margin-top: .8rem; font-size: .95rem; font-weight: 620; }
  .person p { margin-top: .2rem; font-family: ui-monospace, Menlo, monospace; font-size: .58rem; letter-spacing: .12em; text-transform: uppercase; color: var(--faint); }

  .reveal { opacity: 0; transform: translateY(16px); transition: opacity .75s var(--e), transform .75s var(--e); }
  .reveal.in { opacity: 1; transform: none; }

  @media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    .reveal, .card, .feat .fcopy, .feat .mock { opacity: 1 !important; transform: none !important; transition: none !important; }
    .hero h1 .hw, .hero p.lede, .phero h1 .hw, .phero p.lede, .cta-row, .trusted { animation: none; opacity: 1; transform: none; filter: none; }
    .w { color: var(--ink); transition: none; }
    em .w { color: var(--accent); }
    s .w { color: var(--red); }
    .herobg canvas { display: none; }
  }

  /* ---------- Aurora-Fassung: Buttons in Polarlichtgruen ---------
     Statt der Rasterplatte tragen gefuellte Buttons die Farbe des
     Polarlichts - eine Flaeche, dunkle Schrift. */
  body.aurora, html.light body.aurora {
    --brand: #5ceda3;
    --brand-h: #8af8c1;
    --brand-ink: #04180f;
    --brand-edge: rgba(4,24,15,.3);
    /* Der Schein unter dem Knopf, wie bei der Vorlage. Nur hier gesetzt:
       ausserhalb des Polarlichts ist der gefuellte Knopf eine dunkle Platte
       mit laufendem Raster, und ein Schein unter einer dunklen Platte auf
       dunklem Grund ist ein Fleck, kein Licht. */
    --brand-glow:   rgba(92,237,163,.22);
    --brand-glow-h: rgba(92,237,163,.32);
  }
  body.aurora .btnpx { display: none; }
  body.aurora .ubtn.solid, body.aurora .ubtn.light {
    background-image: linear-gradient(180deg, #7df3b8 0%, #4fe39a 100%);
    box-shadow: 0 0 0 rgba(92,237,163,0);
  }
  body.aurora .ubtn.solid:hover, body.aurora .ubtn.light:hover {
    background-image: linear-gradient(180deg, #9cfbcd 0%, #6bedae 100%);
    box-shadow: 0 0 22px rgba(92,237,163,.3);
  }

  /* Akzent folgt der Marke: Polarlichtgruen. Im Light-Mode abgedunkelt,
     damit Links und Marken auf Weiss lesbar bleiben. */
  body.aurora { --accent: #57e59d; }
  html.light body.aurora { --accent: #0d8a58; }

  /* ---------- Unterseiten in der Aurora-Fassung -------------------
     Kein Dither-Raster im Seitenkopf: das Material der Startseite ist
     weiches Licht, also liegt hier ein ruhiger Polarlichtschein statt
     Pixel. Das Spektrumband ueber dem Schluss-CTA fällt ebenso weg. */
  /* Die Lichtflaeche reicht unter die Sektion hinaus und klingt dort
     aus, damit der Uebergang zur naechsten Sektion fliessend ist. */
  body.aurora .phero { overflow: visible; background: none; }
  /* Das Licht liegt als feste Flaeche hinter der ganzen Seite und
     wandert beim Scrollen mit - kein Kopfbereich mehr, keine Kante. */
  /* ── Nebel auf `contact` ───────────────────────────────────────────────
   * Statt drei Verlaufsflecken auf dem Body: vier weiche Ballen auf einer
   * eigenen Ebene, alle zusammen 80px unscharf.
   *
   * Der Unterschied zwischen Fleck und Nebel liegt genau in diesem `blur`.
   * Ein Radialverlauf hat einen Mittelpunkt, den das Auge findet, auch wenn er
   * blass ist -- man sieht, wo die Farbe herkommt. Weichgezeichnet verlieren
   * die vier Ballen ihre Mitten, laufen ineinander und ergeben eine Flaeche
   * ohne Ursprung. Auf dem Body waere das nicht gegangen: `filter` wirkt auf
   * das Element, nicht auf seinen Hintergrund, und ein unscharfer Body waere
   * eine unscharfe Seite.
   *
   * `fixed`, weil Nebel nicht mitscrollt -- die Seite zieht hindurch. Und eine
   * sehr langsame Drift, damit er steht, aber nicht klebt.
   *
   * z-index -1: hinter dem Polarlicht-Canvas (0), das darueber seine Baender
   * zieht, und hinter allen Abschnitten (1).
   */
  /*
   * Das Polarlicht-Canvas ist auf dieser Seite abgeschaltet.
   *
   * Es malt senkrechte Baender, und die waren das, was man als "Akzente" sah --
   * nicht die Verlaeufe auf dem Body. Solange es laeuft, liegt jeder Nebel
   * unsichtbar dahinter, weil Baender eine Richtung haben und Nebel keine: das
   * Auge nimmt die Richtung.
   */
  /*
   * Das Polarlicht-Canvas ist auf **allen** Unterseiten abgeschaltet.
   *
   * Es malt senkrechte Baender. Solange sie gruen waren, las man sie als
   * Markenelement; im Blau sind es blasse Schlieren, die aussehen, als haette
   * der Bildschirm einen Fehler. Und ein Band hat eine Richtung -- neben ihm
   * ist jeder Nebel unsichtbar, weil das Auge die Richtung nimmt.
   */
  body.sub.aurora canvas.pfield { display: none; }

  body.sub.aurora::before {
    content: ''; position: fixed; inset: -20%; z-index: -1; pointer-events: none;
    /* Deckkraft dreimal so hoch wie im ersten Anlauf. Bei 8 % auf Weiss war der
       Nebel rechnerisch da und mit dem Auge nicht zu finden. */
    background:
      radial-gradient(38% 44% at 22% 26%, rgba(46,72,168,.30), transparent 70%),
      radial-gradient(34% 40% at 78% 16%, rgba(32,54,140,.24), transparent 72%),
      radial-gradient(46% 38% at 62% 72%, rgba(26,46,124,.27), transparent 74%),
      radial-gradient(30% 34% at 10% 78%, rgba(60,92,190,.22), transparent 72%);
    filter: blur(80px);
    /* Nur `transform` bewegt sich; die Unschaerfe bleibt konstant. Damit kann
       der Browser die weichgezeichnete Ebene einmal rechnen und danach nur noch
       verschieben, statt sie 64 Sekunden lang neu zu zeichnen. */
    will-change: transform;
    animation: p1fog 64s ease-in-out infinite alternate;
  }
  html:not(.light) body.sub.aurora::before {
    background:
      radial-gradient(38% 44% at 22% 26%, rgba(70,102,206,.34), transparent 70%),
      radial-gradient(34% 40% at 78% 16%, rgba(40,64,158,.28), transparent 72%),
      radial-gradient(46% 38% at 62% 72%, rgba(28,48,132,.30), transparent 74%),
      radial-gradient(30% 34% at 10% 78%, rgba(86,120,224,.24), transparent 72%);
  }
  @keyframes p1fog {
    from { transform: translate3d(0, 0, 0) scale(1); }
    to   { transform: translate3d(-2.5%, 1.5%, 0) scale(1.06); }
  }
  @media (prefers-reduced-motion: reduce) {
    body.sub.aurora::before { animation: none; }
  }

  body.aurora canvas.pfield {
    position: fixed; inset: 0; top: 0; right: 0; bottom: 0; left: 0;
    width: 100vw; height: 100vh; max-width: none;
    filter: blur(7px); z-index: 0; pointer-events: none;
    contain: strict; will-change: contents;
  }
  /* Inhalte liegen ueber der Lichtflaeche */
  body.aurora section, body.aurora footer,
  body.aurora .final { position: relative; z-index: 1; }
  body.aurora .phero > *:not(canvas) { position: relative; z-index: 1; }

  /* Panels lassen das Licht schwach durch, damit die Erscheinung ueber
     die ganze Seite laeuft und nicht an jeder Karte endet. */
  body.aurora .card, body.aurora .plan, body.aurora .proc, body.aurora .stat,
  body.aurora .mock, body.aurora .ccard, body.aurora .fact, body.aurora .funnel,
  body.aurora .rlist > div, body.aurora .cmpwrap, body.aurora .pill {
    background: color-mix(in srgb, var(--panel) 82%, transparent);
    backdrop-filter: blur(3px);
  }
  html.light body.aurora .card, html.light body.aurora .plan, html.light body.aurora .proc,
  html.light body.aurora .stat, html.light body.aurora .mock, html.light body.aurora .ccard,
  html.light body.aurora .fact, html.light body.aurora .funnel,
  html.light body.aurora .rlist > div, html.light body.aurora .cmpwrap, html.light body.aurora .pill {
    background: rgba(255,255,255,.84);
  }
  html.light body.aurora .plan.mid,
  html.light body.aurora .oneplan { background: color-mix(in srgb, var(--panel2) 82%, transparent); }

  /* ---------- Seitenhintergrund: ruhiger Verlauf ------------------
     Ein Verlauf ueber die gesamte Seitenhoehe (liegt auf dem Body,
     also nicht am Fenster festgeklebt): oben ein Schein in
     Mitternachtsblau, unten laeuft es dunkler aus. Pro Seite ein
     anderer Ausschnitt. Statisch - nichts wird gerechnet.

     Bis zum 02.09.2026 war der obere Schein markengruen. Auf einer
     Seite voller weisser, halbtransparenter Karten ergab das einen
     Stich, der nach Verfaerbung aussah statt nach Farbe -- deshalb
     traegt der Hintergrund jetzt Blau und das Gruen bleibt den
     Akzenten vorbehalten, wo es als Absicht lesbar ist. */
  /* `features` hat als einzige Unterseite keinen Verlauf: der gruene Schein
     lag dort hinter Karten, die selbst schon weiss und halbtransparent sind,
     und ergab einen Stich, der nach Verfaerbung aussah statt nach Farbe. */

  /* ---------- Nordlichter nur im Hero -----------------------------
     Unter dem Seitenkopf ist die Seite ruhiger Grund: die Lichtflaeche
     haengt nicht mehr am Fenster, sondern sitzt oben im Dokument und
     klingt nach unten aus. Panels sind wieder deckend. */
  body.aurora canvas.pfield {
    position: absolute; top: 0; left: 0; right: auto; bottom: auto;
    width: 100%; height: min(92vh, 860px); max-width: none;
    -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 54%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 0%, #000 54%, transparent 100%);
  }
  body.aurora .card, body.aurora .plan, body.aurora .proc, body.aurora .stat,
  body.aurora .mock, body.aurora .ccard, body.aurora .fact, body.aurora .funnel,
  body.aurora .rlist > div, body.aurora .cmpwrap, body.aurora .pill {
    background: var(--panel); backdrop-filter: none;
  }
  body.aurora .plan.mid, body.aurora .oneplan { background: var(--panel2); }
  html.light body.aurora .card, html.light body.aurora .plan, html.light body.aurora .proc,
  html.light body.aurora .stat, html.light body.aurora .mock, html.light body.aurora .ccard,
  html.light body.aurora .fact, html.light body.aurora .funnel,
  html.light body.aurora .rlist > div, html.light body.aurora .cmpwrap, html.light body.aurora .pill {
    background: var(--panel);
  }

  /* ---------- Preis-Sektion als helle Insel -----------------------
     Der Plan-Block liegt als weisse Flaeche mit runden Ecken im
     dunklen Grund. Tokens werden lokal gedreht, damit Karten, Text
     und Linien darin ohne Sonderregeln stimmen. */
  body.aurora #plans {
    --bg: #f6f8fa; --panel: #ffffff; --panel2: #eef2f7;
    --ink: #0c1524; --muted: #475364; --faint: #66717f; --dim: #8b95a4;
    --line: rgba(12,21,36,.13); --accent: #0d8a58;
    background: #f6f8fa; color: var(--ink);
    border-radius: clamp(20px, 2.4vw, 34px);
    margin: clamp(1rem, 3vw, 2.4rem) clamp(.6rem, 1.6vw, 1.4rem);
    padding-top: clamp(3rem, 6vw, 5.5rem);
    padding-bottom: clamp(3rem, 6vw, 5.5rem);
  }
  body.aurora #plans h2, body.aurora #plans h3, body.aurora #plans b { color: var(--ink); }
  body.aurora #plans p, body.aurora #plans li, body.aurora #plans span { color: var(--muted); }
  body.aurora #plans .ulabel { color: var(--faint); }
  body.aurora #plans .price { color: var(--ink); }
  body.aurora #plans .price span { color: var(--dim); }
  body.aurora #plans .plan { border-color: var(--line); }
  body.aurora #plans .ubtn.ghost { color: var(--ink); border-color: rgba(12,21,36,.28); }
  body.aurora #plans .ubtn.ghost:hover { background: rgba(12,21,36,.06); }
  body.aurora #plans .guarantee { border-color: var(--line); background: #ffffff; }
  body.aurora #plans a:not(.ubtn) { color: var(--accent); }

  /* Markenfarbe an den Kanten: ruhige, kuehl-gruene Haarlinien.
     Der meistgewaehlte Plan traegt oben eine Lichtkante in der
     Polarlicht-Palette, deren Schein weich in die Karte laeuft -
     kein Neonrahmen, sondern Licht, das ueber die Kante faellt. */
  body.aurora #plans .plan { border: 1px solid rgba(20,120,96,.24); }
  body.aurora #plans .plan:first-child { border-color: rgba(22,104,116,.2); }
  body.aurora #plans .plan:last-child { border-color: rgba(24,150,102,.26); }

  /* Der eine Preis traegt dieselbe Auszeichnung, die vorher die mittlere
     Karte hatte: gruene Kante, Lichtkante oben, Schein von der Oberkante her.
     Sie war nie ein Hinweis auf "die beliebteste Wahl" -- sie markierte, worum
     es auf der Seite geht, und das tut sie jetzt ohne Konkurrenz daneben. */
  body.aurora #plans .plan.mid {
    border-color: rgba(24,168,110,.42);
    overflow: hidden;
    box-shadow: 0 14px 44px -26px rgba(16,110,80,.5), 0 0 0 0 rgba(0,0,0,0);
  }
  /*
   * Beim einen Preis laeuft **keine** Lichtkante ueber die Oberkante.
   *
   * Bei drei Karten war sie ein Zeiger: eine davon ist gemeint. Bei einer
   * Karte zeigt sie auf nichts und macht nur eine von vier Kanten anders als
   * die drei uebrigen. Stattdessen traegt der Rand rundum etwas mehr Farbe --
   * derselbe Ton, gleichmaessig, an allen vier Seiten.
   */
  body.aurora #plans .oneplan {
    border-color: rgba(24,168,110,.5);
    overflow: hidden;
    box-shadow: 0 14px 44px -26px rgba(16,110,80,.42);
  }
  /* Lichtkante */
  body.aurora #plans .plan.mid::before {
    content: ""; position: absolute; left: 0; right: 0; top: 0; height: 2px; z-index: 3;
    background: linear-gradient(90deg,
      rgba(14,86,102,.5) 0%, rgba(24,168,110,.95) 18%, rgba(140,252,190,1) 33%,
      rgba(24,168,110,.9) 48%, rgba(16,120,120,.55) 68%, rgba(140,252,190,.95) 86%, rgba(24,168,110,.7) 100%);
    background-size: 220% 100%;
    animation: auroraEdge 13s linear infinite;
  }
  /* Schein, der von der Kante in die Karte faellt */
  body.aurora #plans .plan.mid::after,
  body.aurora #plans .oneplan::after {
    content: ""; position: absolute; left: -10%; right: -10%; top: -1px; height: 46%;
    z-index: 0; pointer-events: none;
    background:
      radial-gradient(42% 100% at 32% 0%, rgba(87,229,157,.22) 0%, transparent 72%),
      radial-gradient(38% 90% at 76% 0%, rgba(22,150,168,.15) 0%, transparent 74%);
    animation: planAurora 15s ease-in-out infinite;
  }
  body.aurora #plans .plan.mid > *:not(.chip),
  body.aurora #plans .oneplan > * { position: relative; z-index: 1; }
  body.aurora #plans .plan.mid .chip { z-index: 4; }
  @keyframes auroraEdge { from { background-position: 0% 50%; } to { background-position: 220% 50%; } }
  @keyframes planAurora {
    0%   { opacity: .7;  transform: translate3d(-14px, 0, 0); }
    50%  { opacity: 1;   transform: translate3d(14px, 0, 0); }
    100% { opacity: .7;  transform: translate3d(-14px, 0, 0); }
  }
  @media (prefers-reduced-motion: reduce) {
    body.aurora #plans .plan.mid::before,
    body.aurora #plans .plan.mid::after,
    body.aurora #plans .oneplan::after { animation: none; }
  }

  /* ═══════════════════════════════════════════════════════════════════════
     Der Ablauf-Streifen auf der Startseite.

     Sechs Bildschirme zum Durchklicken, die zeigen, was zwischen "Domain
     eintragen" und "Fix in der Hand" passiert. Er ersetzt zwei Abschnitte,
     die dasselbe in Prosa beschrieben.

     Praefix `fl`, weil `.fstep` auf dieser Seite bereits die Trichterstufe
     ist und `.stage`, `.canvas`, `.bar` viel zu allgemein waeren. Das
     Markup steht in index.html, die Inszenierung in site.js.
     ═══════════════════════════════════════════════════════════════════════ */
/* ── Schrittleiste ── */
  /* ── Die Abfolge ──────────────────────────────────────────────────────
     Sechs Zeilen an einer durchgehenden Linie. Bis zum 19.09.2026 standen
     hier Reiter und eine Buehne mit Browser-Attrappe; die Begruendung fuer
     den Umbau steht in site.js ueber dem Renderer. */
  .flsteps { list-style:none; margin:0; padding:0; display:grid; gap:0; }
  /* Drei Spalten: Ziffer, Text, Beweis.
     ─────────────────────────────────────────────────────────────────────────
     Einspaltig hing alles am linken Rand -- auf 1440px nutzte der Abschnitt
     rund 630 von 1240 verfuegbaren Pixeln und wurde dabei 2400px hoch. Sechs
     gleich gebaute Bloecke untereinander lasen sich dazu als Wiederholung,
     nicht als Abfolge. Nebeneinander halbiert sich die Hoehe, die Breite wird
     benutzt, und die Linie hat etwas, woran sie entlanglaeuft. */
  .flrow { display:grid; grid-template-columns:auto minmax(0,1fr) minmax(0,1.05fr);
         gap:0 2.2rem; position:relative; padding:0 0 3rem; align-items:start; }
  .flrow:last-child { padding-bottom:0; }
  @media (max-width:900px){
    .flrow { grid-template-columns:auto minmax(0,1fr); gap:0 1.4rem; }
    .flproof { grid-column:2; }
  }

  .flnum { position:relative; z-index:1; display:grid; place-items:center;
         width:2.4rem; height:2.4rem; border-radius:50%;
         border:1px solid var(--line); background:var(--bg);
         font:700 .7rem/1 ui-monospace,Menlo,monospace; letter-spacing:.06em;
         color:var(--faint); }
  /* Die Linie haengt an der **Zeile**, nicht an der Ziffer.
     An der Ziffer war `height:100%` deren eigene Hoehe -- 2.4rem -- und die
     Linie endete als Stummel kurz darunter, statt die naechste Ziffer zu
     erreichen. `bottom:0` auf der Zeile reicht bis an deren Unterkante, und
     die Polsterung darunter schliesst die Luecke. */
  .flrow:not(:last-child)::before { content:""; position:absolute; top:2.4rem;
         left:1.2rem; width:1px; bottom:0; background:var(--line);
         transform:translateX(-50%); }
  .flrow.seen .flnum { border-color:var(--green); color:var(--ink); }

  .flbody { min-width:0; padding-top:.25rem; }
  .flbody h3 { margin:0; font:640 1.28rem/1.3 system-ui; letter-spacing:-.028em;
             color:var(--ink); text-wrap:balance; }
  .flbody p { margin:.5rem 0 0; max-width:46rem; font-size:.97rem; line-height:1.62;
            color:var(--muted); }

  /* Der Beweis-Schnipsel: eine Karte, kein Fenster. Die drei Punkte und die
     Adresszeile behaupteten "Bildschirmfoto", wo handgebautes HTML steht. */
  .flproof { padding:1.15rem 1.25rem; border:1px solid var(--line);
           border-radius:10px; background:var(--bg); }
  @media (max-width:900px){ .flproof { margin-top:1.1rem; } }

  @media (max-width:640px){
    .flrow { gap:0 .9rem; padding-bottom:2.2rem; }
    .flnum { width:2rem; height:2rem; font-size:.62rem; }
    .flrow:not(:last-child)::before { top:2rem; left:1rem; }
    .flbody h3 { font-size:1.12rem; }
  }

  /* ── Bausteine in der Bühne ── */
  .flfld { display:grid; gap:.4rem; margin-bottom:.9rem; }
  .flfld span { font:400 .6rem/1 ui-monospace,Menlo,monospace; letter-spacing:.14em;
              text-transform:uppercase; color:var(--faint); }
  .flfld i { display:block; padding:.7rem .85rem; border:1px solid var(--line); border-radius:6px;
           background:var(--bg); font:400 .95rem/1 ui-monospace,Menlo,monospace;
           color:var(--ink); font-style:normal; }
  .fltxt { padding:.85rem .9rem; border:1px solid var(--line); border-radius:6px;
            background:var(--bg); font:400 .78rem/1.7 ui-monospace,Menlo,monospace;
            color:var(--muted); overflow-x:auto; white-space:pre; }
  .flres { display:flex; align-items:center; gap:.5rem; margin-top:.7rem;
         font:400 .78rem/1 ui-monospace,Menlo,monospace; color:var(--green); }
  .flph { display:grid; gap:.55rem; }
  .flphr { display:grid; grid-template-columns:7.5rem minmax(0,1fr) auto; gap:.8rem;
         align-items:center; font:400 .76rem/1 ui-monospace,Menlo,monospace; color:var(--muted); }
  .flbar { height:6px; border-radius:3px; background:var(--panel2); overflow:hidden; }
  .flbar u { display:block; height:100%; background:var(--green); border-radius:3px;
           transition:width .8s cubic-bezier(.4,0,.2,1); }
  .flphr.skip { color:var(--faint); }
  .flphr.skip .flbar u { background:var(--line); }
  .flsevgrid { display:grid; grid-template-columns:repeat(4,1fr); gap:.5rem; margin-bottom:1rem; }
  .flsevbox { padding:.75rem .7rem; border-radius:6px; }
  .flsevbox u { display:block; font:400 .58rem/1 ui-monospace,Menlo,monospace;
              letter-spacing:.14em; text-transform:uppercase; text-decoration:none; }
  .flsevbox b { display:block; margin-top:.4rem; font:650 1.5rem/1 system-ui; letter-spacing:-.03em; }
  .fllockrow { display:grid; grid-template-columns:auto 1fr auto; gap:.8rem; align-items:center;
             padding:.65rem 0; border-top:1px solid var(--line);
             font:400 .68rem/1 ui-monospace,Menlo,monospace; color:var(--faint); }
  .fllockbar { height:.55rem; border-radius:3px; background:var(--panel2); }

  /* Behebungsvorschlaege: nummerierte Schritte, kein Fliesstext. Wer einen
     Fund behebt, arbeitet eine Liste ab und liest keinen Absatz. */
  .flfixstep { display:grid; grid-template-columns:auto minmax(0,1fr); gap:.8rem;
             padding:.85rem 0; border-top:1px solid var(--line); align-items:start; }
  .flfixstep:first-child { border-top:0; padding-top:0; }
  .flfixstep u { display:grid; place-items:center; width:1.55rem; height:1.55rem; flex:none;
               border-radius:50%; background:var(--ink); color:#fff; text-decoration:none;
               font:700 .7rem/1 ui-monospace,Menlo,monospace; }
  .flfixstep b { display:block; font:620 .96rem/1.35 system-ui; letter-spacing:-.012em; color:var(--ink); }
  .flfixstep span { display:block; margin-top:.25rem; font-size:.87rem; line-height:1.55; color:var(--muted); }
  .flfixstep i { font-family:ui-monospace,Menlo,monospace; font-style:normal; font-size:.85em; color:var(--ink); }
  .flfixfoot { margin-top:1rem; padding-top:.9rem; border-top:1px solid var(--line);
             font-size:.84rem; line-height:1.55; color:var(--faint); }

  .flcaret { display:inline-block; width:.55ch; background:var(--ink); color:transparent;
           animation:blink 1s steps(1) infinite; }
  @keyframes blink { 50% { opacity:0 } }

  /* Sichtbar, solange niemand das Gegenteil sagt.
     ─────────────────────────────────────────────────────────────────────────
     Vorher stand `opacity:0` als Grundzustand, und erst JavaScript holte die
     Teile hervor. Das ist auf einer Startseite die falsche Richtung: faellt
     das Skript aus -- geblockt, Fehler weiter oben, ein Browser ohne
     IntersectionObserver -- stehen dort leere Karten, und niemand merkt es.

     Jetzt setzt das Skript beim Start `.willanim` auf jeden Schnipsel, den es
     zu animieren gedenkt. Nur was diese Klasse traegt, startet unsichtbar. */
  .willanim .flres { opacity:0; transform:translateX(-4px); }
  .flres { transition:opacity .3s, transform .3s; }
  .flres.on { opacity:1; transform:none; }
  .flres.pending { color:var(--faint); }

  .willanim .flphr { opacity:.35; }
  .flphr { transition:opacity .35s; }
  .flphr.on { opacity:1; }
  .willanim .flsevbox { opacity:0; transform:translateY(6px); }
  .flsevbox { transition:opacity .35s, transform .35s; }
  .flsevbox.on { opacity:1; transform:none; }
  .willanim .fllockrow { opacity:0; }
  .fllockrow { transition:opacity .4s; }
  .fllockrow.on { opacity:1; }
  .willanim .flfixstep { opacity:0; transform:translateY(5px); }
  .flfixstep { transition:opacity .35s, transform .35s; }
  .flfixstep.on { opacity:1; transform:none; }

  @media (prefers-reduced-motion: reduce) { .flcaret { animation:none; } }

  /* ── Der Abschnitt steht auf dunklem Grund ────────────────────────────────
     Vorher: helles Fenster auf heller Seite -- das Fenster verschwand im
     Hintergrund, und die Markenfarbe hatte nichts, wogegen sie leuchten
     konnte. Jetzt schwebt das helle App-Fenster auf Dunkel, so wie man ein
     Produktbild zeigt. Der Bildschirm selbst bleibt hell, denn hell ist die
     Anwendung wirklich -- was sich aendert, ist der Grund, nicht das Produkt. */
  /*
   * Die Naht zum Hero.
   *
   * Der Hero endet nicht mit *einer* Farbe: unter seinem Linearverlauf
   * (…#0a1a33) liegen zwei blaue Lichtscheine, der staerkste zentriert bei
   * `50% 108%`. Seine Unterkante ist deshalb in der Mitte rund #122e55 und an
   * den Raendern #0a1a33 -- sie **variiert ueber die Breite**. Jeder
   * gleichmaessige CSS-Verlauf trifft das an genau einer Stelle und daneben
   * nicht; das war die Kante, die drei Anlaeufe ueberlebt hat.
   *
   * Loesung: dieselben Scheine im Streifen fortsetzen. `::before` traegt sie,
   * an der Oberkante verankert und ueber 380px auslaufend. Darunter beginnt der
   * Grundverlauf bei genau der Farbe, mit der der Hero linear endet.
   */
  .flband {
    /* ── Dunkle Insel auf heller Seite: Tokens lokal drehen ────────────────
     *
     * Dieselbe Technik, die `#plans` als *helle* Insel im dunklen Grund
     * benutzt -- nur andersherum, und aus demselben Grund: "damit Karten,
     * Text und Linien darin ohne Sonderregeln stimmen".
     *
     * Ohne diesen Block war der Abschnitt halb umgestellt. `.flband` drehte
     * Ueberschriften, Fliesstext, Ziffern und die Zeitachse auf hell -- den
     * Kartengrund aber nicht. `.flproof` nimmt `var(--bg)`, und das ist auf
     * dieser Seite (`<html class="light">`) reines Weiss. In einem dunklen
     * Abschnitt standen damit sechs grellweisse Rechtecke, und alles darin
     * erbte die helle Palette mit: Eingabefelder, Code-Bloecke, Phasenbalken.
     *
     * Die Folge war nicht nur ein Bruch im Bild. Die Animationen dieses
     * Abschnitts -- Tippen, Phasenbalken, einlaufende DNS-Treffer -- spielen
     * in diesen Karten, und `--green` verliert auf Weiss seine Leuchtkraft.
     * Auf dunklem Grund traegt dieselbe Bewegung.
     *
     * Der Schatten unten (`0 30px 70px rgba(0,0,0,.5)`) war ohnehin fuer eine
     * dunkle Karte gedacht; unter einer weissen sah er nach Fehler aus.
     */
    --bg: #0a0e17;
    --panel: #0d1220;
    --panel2: rgba(255,255,255,.09);
    --line: rgba(255,255,255,.12);
    --ink: #ffffff;
    --muted: rgba(255,255,255,.62);
    --faint: rgba(255,255,255,.42);
    --dim: rgba(255,255,255,.34);

    position: relative;
    /*
     * Hier endet der dunkle Teil der Seite -- Hero und Streifen sind eine
     * einzige Flaeche, und das ist ihre Unterkante. Die Rundung sitzt deshalb
     * hier und nicht am Hero: der Hero hoert mittendrin auf, dieser Abschnitt
     * hoert wirklich auf.
     *
     * `overflow` braucht es nicht -- die Verlaeufe sind Hintergruende dieses
     * Elements und werden von der Rundung ohnehin beschnitten. Der Schatten
     * des Fensters darin bleibt damit sichtbar.
     */
    border-bottom-left-radius: clamp(1.25rem, 2.5vw, 2rem);
    border-bottom-right-radius: clamp(1.25rem, 2.5vw, 2rem);
    background:
      radial-gradient(90% 45% at 12% 58%, rgba(92,237,163,.09), transparent 62%),
      radial-gradient(80% 40% at 88% 92%, rgba(92,237,163,.06), transparent 66%),
      linear-gradient(#0a1a33 0%, #08142a 14%, #060e1e 38%, #050a14 68%, #04070e 100%);
    color:#fff;
  }
  .flband > .wide { position: relative; z-index: 1; }
  .flband .bhead h2 { color:#fff; }
  .flband .bhead p { color:rgba(255,255,255,.62); }
  .flband .ulabel { color:rgba(126,240,183,.75); }

  /* Die Abfolge auf Dunkel. Nur Ziffer, Linie und Text kippen -- der
     Beweis-Schnipsel bleibt eine helle Karte, die darauf schwebt. */
  .flband .flnum { background:transparent; border-color:rgba(255,255,255,.16);
                 color:rgba(255,255,255,.5); }
  .flband .flrow:not(:last-child)::before { background:rgba(255,255,255,.12); }
  .flband .flrow.seen .flnum { border-color:#5ceda3; color:#fff; }
  .flband .flbody h3 { color:#fff; }
  .flband .flbody p { color:rgba(255,255,255,.62); }
  .flband .flproof {
    border-color:rgba(255,255,255,.10);
    box-shadow:0 30px 70px rgba(0,0,0,.5), 0 0 0 1px rgba(255,255,255,.04);
    transition:box-shadow .6s var(--e), border-color .6s var(--e);
  }
  /* Die Karte bekommt eine Buehne. Beim Aktivwerden glimmt sie von innen auf,
     in derselben Farbe wie das Polarlicht im Hero -- dann hat die Bewegung
     einen Ort, statt auf einer Flaeche zu spielen, die sich nicht dafuer
     interessiert. `.seen` setzt die Zeile, wenn sie ins Bild kommt; dieselbe
     Klasse faerbt schon die Ziffer links gruen. */
  .flband .flrow.seen .flproof {
    border-color:rgba(92,237,163,.22);
    box-shadow:
      0 30px 70px rgba(0,0,0,.5),
      0 0 0 1px rgba(92,237,163,.10),
      0 0 46px -12px rgba(92,237,163,.30);
  }

  /* Gleich hohe Zeilen, damit die Zeitachse links eine Linie bleibt statt nach
     unten auszufransen. Die sechs Zeilen waren 166, 253, 259, 264, 288 und 385
     Pixel hoch -- die letzte mehr als doppelt so hoch wie die erste. */
  @media (min-width:901px) {
    .flband .flrow { align-items:start; min-height:15rem; }
    .flband .flproof { min-height:11rem; }
  }

  /* ── Preisvergleich (Abschnitt 02) ────────────────────────────────────────
     Praefix `pcmp`, weil `.cmp` auf dieser Seite bereits vergeben ist.

     Drei Spalten: Merkmal, das Uebliche, wir. Die eigene Spalte ist farblich
     abgesetzt, aber nicht lauter -- die Zahlen tragen den Vergleich, nicht die
     Gestaltung. Ein Vergleich, der optisch schreit, wirkt wie einer, der es
     inhaltlich noetig hat. */
  /* Ein einziges Raster statt acht kleiner.
     ─────────────────────────────────────────────────────────────────────────
     Vorher war jede Zeile ihr eigenes Grid. Das reichte, solange die Spalten
     nur Text trugen -- fuer einen durchgehenden Hintergrund reicht es nicht:
     acht getrennte Raster ergeben acht getrennte Flaechen mit sichtbaren
     Absaetzen dazwischen.

     Deshalb traegt jetzt `.pcmp` das Raster, und Kopf und Zeilen verschwinden
     per `display: contents` daraus. Die Zellen sind damit direkte Kinder
     derselben Spalte und stossen ohne Luecke aneinander. Innenmass und Linien
     wandern von der Zeile in die Zelle -- sonst haenge das Band an der
     falschen Kante. */
  .pcmp {
    display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, 1fr);
    border: 1px solid var(--line); border-radius: 10px; overflow: hidden;
    /* Zwei Schatten statt einem: der weite traegt die Tabelle von der Seite ab,
       der enge setzt die Kante. Einer allein ist entweder eine Wolke ohne Kante
       oder eine Kante ohne Tiefe. */
    box-shadow:
      0 26px 60px -20px rgba(12, 21, 36, .22),
      0 3px 10px -3px rgba(12, 21, 36, .08);
  }
  .pcmp-head, .pcmp-row { display: contents; }
  .pcmp > div > span {
    padding: .95rem 1.15rem; border-top: 1px solid var(--line);
    font-size: .95rem; line-height: 1.45; color: var(--muted);
  }
  .pcmp-head > span {
    border-top: 0; background: var(--panel); border-bottom: 1px solid var(--line);
    font-family: ui-monospace, Menlo, monospace; font-size: .62rem;
    letter-spacing: .14em; text-transform: uppercase; color: var(--faint);
  }
  .pcmp-head + .pcmp-row > span { border-top: 0; }
  .pcmp-row > span:first-child { color: var(--ink); font-weight: 560; }

  /* ── Unsere Spalte ────────────────────────────────────────────────────────
     Der dunkelblaue Grund der Marke, gruene Werte -- dieselbe Paarung wie im
     Ablauf-Streifen darueber, damit die Seite nicht zwei Vorstellungen davon
     hat, wie Polaris1 aussieht.

     Sie ist abgesetzt, nicht lauter: die Zahlen tragen den Vergleich. Ein
     Vergleich, der optisch schreit, wirkt wie einer, der es noetig hat. */
  .pcmp .pcmp-us {
    /* Der Verlauf laeuft **waagrecht**, und das ist der ganze Trick: jede Zelle
       traegt ihn einzeln, aber weil er sich von links nach rechts aufbaut und
       nicht von oben nach unten, sieht jede Zeile gleich aus. Uebereinander
       gestapelt ergibt das ein durchgehendes Band statt sichtbarer Streifen.

       Ein senkrechter Verlauf haette sich in jeder Zelle neu begonnen -- sechs
       Zeilen, sechs Ansaetze, und die Spalte saehe aus wie ein Zebra. */
    /* Dasselbe Blau wie die Kopfzeilen-Kapsel und die Fusszeile (#0c1a3a) und
       derselbe gruene Schein wie dort: 10 % am linken Rand, bis 46 % auf null.
       Vorher lag er bei 15 bis 24 % -- so viel Gruen auf Dunkelblau liest sich
       nicht mehr als Schein, sondern als Tuerkis, und die Spalte hatte eine
       eigene Farbe statt der Markenfarbe.

       Waagrecht, nicht diagonal wie im Kopf: die Kapsel ist ein Element, diese
       Spalte sind sieben Zellen untereinander. Ein Verlauf ueber 135 Grad
       begaenne in jeder neu. */
    background:
      linear-gradient(90deg, rgba(92, 237, 163, .10) 0%, rgba(92, 237, 163, 0) 46%),
      #0c1a3a;
    color: #fff; font-weight: 600;
    /* Die Kante stapelt sich Zelle fuer Zelle zu einer durchgehenden Linie. */
    border-left: 1px solid rgba(92, 237, 163, .28);
    border-top-color: rgba(92, 237, 163, .13);
  }
/* Die Steuerangabe neben dem eigenen Preis: kleiner, aber nicht versteckt.
   Der Preis ist brutto (DECISION-14, Weg B) -- ohne den Zusatz stuende eine
   Zahl da, die je nach Land eine andere Bedeutung hat. */
.pcmp-us small { font-size: .62em; font-weight: 500; opacity: .75; white-space: nowrap; }

  .pcmp-head .pcmp-us {
    /* Der Kopf eine Spur heller als die Zeilen darunter, sonst derselbe Aufbau. */
    background:
      linear-gradient(90deg, rgba(92, 237, 163, .13) 0%, rgba(92, 237, 163, 0) 46%),
      #102547;
    border-bottom-color: rgba(92, 237, 163, .26);
    /* Die gruene Lichtkante oben schliesst die Spalte nach aussen ab. */
    box-shadow: inset 0 1px 0 rgba(92, 237, 163, .38);
    /* Die Wortmarke braucht Luft, sonst klebt sie auf der Kante. */
    padding-top: .95rem; padding-bottom: .95rem;
  }
  /* Die Wortmarke im Kopf: dieselbe wie oben in der Leiste, nur groesser --
     sie ist hier die Spaltenueberschrift und muss die Zeile tragen.
     `.logo` bringt Orbitron, Versalien und das gruene O mit. */
  .pcmp-logo { font-size: 1.2rem; }

  .pcmp-note {
    margin: 1.6rem 0 0; max-width: 46em;
    font-size: .95rem; line-height: 1.65; color: var(--muted);
  }
  /* Untereinander gestapelt gibt es keine Spalte, durch die ein Band laufen
     koennte -- dort traegt nur die Schrift die Farbe. */
  @media (max-width: 680px) {
    .pcmp { display: block; }
    .pcmp-head { display: none; }
    .pcmp-row {
      display: grid; grid-template-columns: 1fr; gap: .2rem;
      padding: .9rem 1rem; border-top: 1px solid var(--line);
    }
    .pcmp-head + .pcmp-row { border-top: 0; }
    .pcmp > div > span { padding: 0; border-top: 0; }
    .pcmp .pcmp-us { background: none; color: var(--green); border-left: 0; }
    .pcmp-row > span:nth-child(2)::before { content: "Booked pentest: "; color: var(--faint); }
    .pcmp-row > span:nth-child(3)::before { content: "Polaris1: "; color: var(--faint); font-weight: 400; }
  }
