@charset "UTF-8";
/* =============================================================================
   FM-SQUARED GMBH — DESIGN-SYSTEM
   Eine Datei für die ganze Webseite. Stand 30.07.2026.

   Aufbau
     01  Schriften
     02  Farben, hell und dunkel
     03  Übrige Marken (Typografie, Abstände, Radien, Schatten, Bewegung, Layout)
     04  Zurücksetzen
     05  Basis-Elemente
     06  Layout
     07  Typografie-Bausteine
     08  Bausteine
     09  Effekte, auch die dreidimensionalen
     10  Hilfsklassen
     11  Bildschirmbreiten

   WICHTIG: Neue Regeln immer VOR Abschnitt 11 einfügen. Alles, was nach den
   Breakpoints steht, überschreibt sie und bricht das Responsive-Verhalten.
   ========================================================================== */


/* =============================================================================
   01  SCHRIFTEN
   Space Grotesk für Überschriften, Inter für Text. Beide lokal, beide als
   Variable Font: eine Datei deckt alle Schnitte von 400 bis 700 ab.
   ========================================================================== */

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/space-grotesk-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;
}
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/space-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/inter-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;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* =============================================================================
   02  FARBEN

   Grundsatz: die Werte stehen genau einmal (--h-* für hell, --d-* für dunkel).
   Darunter wird zugeordnet, welcher Satz gerade gilt. Die Zuordnung steht
   zweimal — einmal für „Gerät entscheidet", einmal für die Handauswahl.
   Beide Blöcke müssen gleich bleiben.

   Kontraste: alle Textfarben sind gegen ihre Flächen gerechnet und erreichen
   mindestens 4,5:1, Rahmen von Eingabefeldern mindestens 3:1.

   ACHTUNG Markenfarbe: #00C2FF erreicht auf Weiß nur 2,07:1. Auf hellen
   Flächen darf das Cyan deshalb NIE Text tragen und keine bedeutungstragende
   dünne Linie sein — nur Verläufe, Ringe, Schimmer. Für Text und Knöpfe auf
   Hell gibt es --akzent-text und --akzent-voll.
   ========================================================================== */

/*
   HELL IST DER STANDARD, seit 06.08.2026 auch dann, wenn das Gerät auf dunkel
   steht. Dunkel erscheint ausschließlich nach einem Tippen auf den Umschalter.

   Vorher folgte die Seite der Geräteeinstellung. Dafür gab es acht Blöcke
   `@media (prefers-color-scheme: dark)`, jeweils mit dem Selektor
   `:root:not([data-theme='light'])`. Zu jedem dieser acht Blöcke existierte
   schon ein wortgleicher Zwilling unter `:root[data-theme='dark']`, der die
   Handauswahl bediente. Vor dem Löschen wurden beide Reihen Angabe für Angabe
   verglichen: Die Handauswahl enthielt alles aus den Geräte-Blöcken und
   zusätzlich `color-scheme: dark`. Es ging also nichts verloren, es fielen nur
   54 doppelte Zeilen weg.

   `color-scheme: light` statt `light dark` gehört dazu. Sonst zeichnete der
   Browser auf einem dunkel gestellten Gerät weiterhin Rollbalken, Auswahlfelder
   und Datumsauswahl in Dunkel, während die Seite ringsum hell war.
*/
:root {
  color-scheme: light;

  /* --- Markenfarbe, in beiden Modi gleich --- */
  --marke:            #00C2FF;
  --marke-2:          #1E88E5;   /* Sekundärblau aus dem bisherigen Auftritt */
  --marke-dunkelblau: #04141C;   /* Textfarbe auf Cyan-Flächen, 9,06:1 */

  /* --- HELL: Werte --- */
  --h-bg:            #FFFFFF;
  --h-bg-abgesetzt:  #F4F7FA;
  --h-bg-karte:      #FFFFFF;
  --h-bg-invers:     #0D1520;
  --h-bg-schleier:   rgba(255, 255, 255, 0.82);
  --h-text:          #0D1520;
  --h-text-neben:    #4A5A6E;
  --h-text-fein:     #5C6C82;
  --h-text-invers:   #FFFFFF;
  --h-rahmen:        #E3E9F0;
  --h-rahmen-stark:  #7F8D9E;
  --h-akzent-text:   #00668F;
  --h-akzent-voll:   #005E85;
  --h-akzent-voll-h: #004E6E;
  --h-akzent-sanft:  #E6F6FD;
  --h-erfolg:        #0B7A55;
  --h-warnung:       #8A5200;
  --h-gefahr:        #B4231D;
  --h-schatten:      220 40% 22%;
  --h-schimmer:      rgba(0, 194, 255, 0.22);
  --h-objekt:        #0096CC;   /* 3D-Objekte auf hellem Grund, sichtbarer als das reine Cyan */

  /* --- DUNKEL: Werte --- */
  --d-bg:            #0B0F14;
  --d-bg-abgesetzt:  #06090D;
  --d-bg-karte:      #121924;
  --d-bg-invers:     #E9F1F9;
  --d-bg-schleier:   rgba(11, 15, 20, 0.82);
  --d-text:          #E9F1F9;
  --d-text-neben:    #A3B2C4;
  --d-text-fein:     #8493A6;
  --d-text-invers:   #0B0F14;
  --d-rahmen:        #1D2733;
  --d-rahmen-stark:  #5D7183;
  --d-akzent-text:   #4DD0FF;
  --d-akzent-voll:   #00C2FF;
  --d-akzent-voll-h: #33CFFF;
  --d-akzent-sanft:  #0C2430;
  --d-erfolg:        #3ED9A0;
  --d-warnung:       #F5B93C;
  --d-gefahr:        #FF8A80;
  --d-schatten:      220 60% 2%;
  --d-schimmer:      rgba(0, 194, 255, 0.32);
  --d-objekt:        #00C2FF;

  /* --- Zuordnung, Standard hell --- */
  --bg:            var(--h-bg);
  --bg-abgesetzt:  var(--h-bg-abgesetzt);
  --bg-karte:      var(--h-bg-karte);
  --bg-invers:     var(--h-bg-invers);
  --bg-schleier:   var(--h-bg-schleier);
  --text:          var(--h-text);
  --text-neben:    var(--h-text-neben);
  --text-fein:     var(--h-text-fein);
  --text-invers:   var(--h-text-invers);
  --rahmen:        var(--h-rahmen);
  --rahmen-stark:  var(--h-rahmen-stark);
  --akzent-text:   var(--h-akzent-text);
  --akzent-voll:   var(--h-akzent-voll);
  --akzent-voll-h: var(--h-akzent-voll-h);
  --akzent-sanft:  var(--h-akzent-sanft);
  --erfolg:        var(--h-erfolg);
  --warnung:       var(--h-warnung);
  --gefahr:        var(--h-gefahr);
  --schatten-hsl:  var(--h-schatten);
  --schimmer:      var(--h-schimmer);
  --objekt:        var(--h-objekt);
}

/* Gerät auf dunkel gestellt und keine Handauswahl getroffen */

/* Handauswahl dunkel — gleicher Inhalt wie oben, bitte synchron halten */
:root[data-theme='dark'] {
  color-scheme: dark;
  --bg:            var(--d-bg);
  --bg-abgesetzt:  var(--d-bg-abgesetzt);
  --bg-karte:      var(--d-bg-karte);
  --bg-invers:     var(--d-bg-invers);
  --bg-schleier:   var(--d-bg-schleier);
  --text:          var(--d-text);
  --text-neben:    var(--d-text-neben);
  --text-fein:     var(--d-text-fein);
  --text-invers:   var(--d-text-invers);
  --rahmen:        var(--d-rahmen);
  --rahmen-stark:  var(--d-rahmen-stark);
  --akzent-text:   var(--d-akzent-text);
  --akzent-voll:   var(--d-akzent-voll);
  --akzent-voll-h: var(--d-akzent-voll-h);
  --akzent-sanft:  var(--d-akzent-sanft);
  --erfolg:        var(--d-erfolg);
  --warnung:       var(--d-warnung);
  --gefahr:        var(--d-gefahr);
  --schatten-hsl:  var(--d-schatten);
  --schimmer:      var(--d-schimmer);
  --objekt:        var(--d-objekt);
}

:root[data-theme='light'] { color-scheme: light; }


/* =============================================================================
   03  ÜBRIGE MARKEN
   ========================================================================== */

:root {
  /* --- Schriftfamilien --- */
  --schrift-ueberschrift: 'Space Grotesk', 'Segoe UI', system-ui, sans-serif;
  --schrift-text: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --schrift-mono: ui-monospace, 'SFMono-Regular', 'Cascadia Mono', Menlo, monospace;

  /* --- Schriftgrößen, fließend zwischen 320px und 1600px --- */
  --gr--2: 0.75rem;
  --gr--1: 0.875rem;
  --gr-0:  clamp(1rem,     0.98rem + 0.10vw, 1.0625rem);
  --gr-1:  clamp(1.125rem, 1.08rem + 0.22vw, 1.25rem);
  --gr-2:  clamp(1.3rem,   1.21rem + 0.45vw, 1.5rem);
  --gr-3:  clamp(1.5rem,   1.32rem + 0.90vw, 2rem);
  --gr-4:  clamp(1.8rem,   1.45rem + 1.70vw, 2.75rem);
  --gr-5:  clamp(2.1rem,   1.50rem + 3.00vw, 3.5rem);
  --gr-6:  clamp(2.4rem,   1.45rem + 4.75vw, 4.5rem);

  /* --- Abstände, ebenfalls fließend --- */
  --ab-3xs: clamp(0.25rem, 0.24rem + 0.05vw, 0.3rem);
  --ab-2xs: clamp(0.5rem,  0.48rem + 0.10vw, 0.6rem);
  --ab-xs:  clamp(0.75rem, 0.71rem + 0.20vw, 0.9rem);
  --ab-s:   clamp(1rem,    0.95rem + 0.25vw, 1.2rem);
  --ab-m:   clamp(1.5rem,  1.43rem + 0.35vw, 1.8rem);
  --ab-l:   clamp(2rem,    1.83rem + 0.85vw, 2.6rem);
  --ab-xl:  clamp(3rem,    2.66rem + 1.70vw, 4.2rem);
  --ab-2xl: clamp(4rem,    3.32rem + 3.40vw, 6.4rem);
  --ab-3xl: clamp(5rem,    3.64rem + 6.80vw, 9rem);

  /* --- Rundungen --- */
  --rund-xs: 6px;
  --rund-s:  10px;
  --rund-m:  14px;
  --rund-l:  20px;
  --rund-xl: 28px;
  --rund-voll: 999px;

  /* --- Schatten, aus einem Farbton abgeleitet --- */
  --schatten-s: 0 1px 2px hsl(var(--schatten-hsl) / 0.06),
                0 2px 6px hsl(var(--schatten-hsl) / 0.05);
  --schatten-m: 0 2px 4px hsl(var(--schatten-hsl) / 0.06),
                0 8px 20px hsl(var(--schatten-hsl) / 0.08);
  --schatten-l: 0 4px 8px hsl(var(--schatten-hsl) / 0.07),
                0 20px 44px hsl(var(--schatten-hsl) / 0.12);
  --schatten-xl: 0 8px 16px hsl(var(--schatten-hsl) / 0.08),
                 0 36px 80px hsl(var(--schatten-hsl) / 0.18);

  /* --- Bewegung --- */
  --zeit-kurz: 140ms;
  --zeit-mittel: 260ms;
  --zeit-lang: 480ms;
  --kurve: cubic-bezier(0.22, 0.61, 0.36, 1);
  --kurve-aus: cubic-bezier(0.16, 1, 0.3, 1);

  /* --- Layout --- */
  --breite-text: 68ch;
  --breite-inhalt: 1200px;
  --breite-weit: 1440px;
  --kopf-hoehe: 64px;
  --rand: var(--ab-s);

  /* --- Umrisse bei Tastaturbedienung --- */
  --fokus-breite: 3px;
  --fokus-abstand: 2px;
}


/* =============================================================================
   04  ZURÜCKSETZEN
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

* { margin: 0; }

/*
   Das hidden-Attribut muss auch wirklich verbergen.

   Der Browser bringt dafür `[hidden] { display: none }` mit, aber das steht in
   seinem eigenen Stylesheet, und JEDE Autorenregel schlägt das, unabhängig von
   der Spezifität. Sobald ein Baustein also `display: flex` oder `display: grid`
   trägt, bleibt er trotz gesetztem hidden sichtbar.

   Genau das ist am 03.08.2026 auf /referenzen aufgefallen: Der Filter setzte
   hidden korrekt auf acht von neun Karten, die Meldung sagte wahrheitsgemäß
   "1 Projekt wird angezeigt", und der Browser zeichnete trotzdem alle neun,
   weil `.fm-refkarte` auf `display: flex` steht. Alle vier Filter waren
   betroffen, in jedem Browser, nicht nur in Safari.

   Vorher wurde das zweimal einzeln geflickt, bei `.fm-reiter__inhalt` und bei
   `.fm-meldung`. Zwei Flicken für dieselbe Ursache sind ein Zeichen, dass die
   Regel an die Wurzel gehört und nicht ans Blatt.

   Das !important ist hier keine Nachlässigkeit, sondern der Zweck der Sache:
   Ein Element, das ausdrücklich als verborgen ausgezeichnet ist, darf von
   keiner Layoutregel wieder sichtbar gemacht werden. Wer etwas ausblenden
   will, ohne es aus dem Fluss zu nehmen, benutzt nicht hidden, sondern
   `.fm-nur-vorlesen` oder eine eigene Klasse.
*/
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--kopf-hoehe) + var(--ab-m));
  hanging-punctuation: first last;
  /*
     Verhindert seitliches Scrollen, auch wenn ein Schimmer oder ein Motiv
     bewusst über den Rand hinausragt. Bewusst clip und nicht hidden: clip
     erzeugt keinen Scrollbereich, dadurch bleibt position: sticky im Kopf
     weiter funktionsfähig.
  */
  overflow-x: clip;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  min-height: 100svh;
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--schrift-text);
  font-size: var(--gr-0);
  line-height: 1.65;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
  transition: background-color var(--zeit-mittel) var(--kurve),
              color var(--zeit-mittel) var(--kurve);
}

img, picture, svg, video, canvas {
  display: block;
  max-width: 100%;
}

img, video { height: auto; }

input, button, textarea, select { font: inherit; color: inherit; }

button { background: none; border: none; padding: 0; cursor: pointer; }

ul, ol { padding: 0; }

p, li, figcaption { text-wrap: pretty; }

h1, h2, h3, h4, h5, h6 { text-wrap: balance; }

:target { scroll-margin-top: calc(var(--kopf-hoehe) + var(--ab-l)); }


/* =============================================================================
   05  BASIS-ELEMENTE
   ========================================================================== */

h1, h2, h3, h4 {
  font-family: var(--schrift-ueberschrift);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  /*
     Deutsche Komposita sind lang. „Geschäftsbedingungen" ist bei 35 Pixel
     Schriftgröße 391 Pixel breit und passt damit auf keinen Handybildschirm.
     Weil der Rumpf overflow-x: clip trägt, läuft die Schrift nicht sichtbar
     über den Rand, sondern wird abgeschnitten. Eine Prüfung über scrollWidth
     bemerkt das nicht, im iOS-Simulator sieht man es sofort.

     hyphens: auto trennt richtig, weil das Dokument lang="de" führt.
     overflow-wrap ist der Rückfall für Wörter ohne Trennstelle.
  */
  hyphens: auto;
  /*
     Nur lange Wörter trennen. Ohne diese Grenze trennte die Überschrift auf
     /zusammenarbeit „wofür" zu „wo-für", was in einer Schlagzeile albern
     aussieht. Die Zahlen heißen: mindestens acht Zeichen im Wort, mindestens
     vier davor, mindestens drei danach. „Geschäftsbedingungen" wird damit
     weiterhin getrennt, „wofür" nicht mehr.

     ABER: Mobile Safari beachtet die Grenze am 02.08.2026 nicht, dort steht in
     der Überschrift auf /zusammenarbeit weiterhin „wo-für". CSS.supports meldet
     Unterstützung, und in Chromium greift die Regel. Das ist hingenommen und
     nicht umgangen: die Trennung ist orthografisch richtig, nur unschön, und
     der Text dafür umzubauen wäre der schlechtere Tausch.
  */
  /*
     Dritter Wert am 06.08.2026 von 3 auf 4 erhöht. Anlass: Die neue Überschrift
     auf /ueber-uns lautet „Zwei, die selbst mitbauen, was sie verkaufen." und
     wurde bei 458 Pixeln Textbreite zu „mitbau-" und „en," getrennt.

     Gemessen wurde, welcher Wert das abstellt, statt geraten. Zwei Proben, beide
     mit text-wrap: balance wie im Ernstfall:

       Grenze   Überschrift bei 458 px      „Geschäftsbedingungen" bei 300 px
       8 4 3    getrennt (85 px, 2 Zeilen)  getrennt
       9 4 3    getrennt                    getrennt
       8 4 4    NICHT getrennt (128 px)     getrennt
       10 4 3   nicht getrennt              getrennt
       8 5 4    nicht getrennt              getrennt

     Ausschlaggebend ist also der dritte Wert, nicht die Mindestlänge des Wortes.
     8 4 4 ist die kleinste Änderung, die wirkt, und lässt die lange Zusammen-
     setzung unangetastet.

     Wichtig für das Verständnis: Bei einem ALLEIN stehenden Wort verhinderte
     schon 8 4 3 die Trennung. Erst im vollen Satz trennte der Browser trotzdem.
     Wer das nachmisst, muss also den ganzen Satz prüfen, nicht das Wort.
  */
  hyphenate-limit-chars: 8 4 4;
  overflow-wrap: break-word;
}

h1 { font-size: var(--gr-6); }
h2 { font-size: var(--gr-4); }
h3 { font-size: var(--gr-3); }
h4 { font-size: var(--gr-2); line-height: 1.25; }
h5 { font-size: var(--gr-1); font-family: var(--schrift-ueberschrift); font-weight: 600; }

a {
  color: var(--akzent-text);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  transition: color var(--zeit-kurz) var(--kurve);
}
a:hover { color: var(--text); }

strong, b { font-weight: 650; }

code, kbd, samp, pre {
  font-family: var(--schrift-mono);
  font-size: 0.9em;
}

code {
  padding: 0.15em 0.4em;
  border-radius: var(--rund-xs);
  background: var(--bg-abgesetzt);
  border: 1px solid var(--rahmen);
}

pre {
  overflow-x: auto;
  padding: var(--ab-s);
  border-radius: var(--rund-m);
  background: var(--bg-abgesetzt);
  border: 1px solid var(--rahmen);
  line-height: 1.5;
}
pre code { padding: 0; background: none; border: none; }

hr {
  height: 1px;
  margin-block: var(--ab-l);
  border: none;
  background: var(--rahmen);
}

::selection {
  background: var(--marke);
  color: var(--marke-dunkelblau);
}

/* Tastaturbedienung sichtbar machen, Mausklicks nicht störend umranden */
:focus-visible {
  outline: var(--fokus-breite) solid var(--akzent-text);
  outline-offset: var(--fokus-abstand);
  border-radius: var(--rund-xs);
}

/* Sprungmarke zum Inhalt, erscheint erst bei Tastaturbedienung */
.fm-sprung {
  position: fixed;
  top: var(--ab-2xs);
  left: var(--ab-2xs);
  z-index: 200;
  padding: var(--ab-2xs) var(--ab-s);
  border-radius: var(--rund-s);
  background: var(--akzent-voll);
  color: #FFFFFF;
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-160%);
  transition: transform var(--zeit-kurz) var(--kurve);
}
.fm-sprung:focus-visible {
  transform: translateY(0);
  color: #FFFFFF;
}


/* =============================================================================
   05b  SCHRUMPFENDE RASTER- UND FLEXKINDER

   Kinder eines Rasters oder einer Flexbox haben von sich aus min-width: auto.
   Sie schrumpfen deshalb NIE unter die Breite ihres längsten Inhalts, und wenn
   der Behälter schmaler wird, ragen sie heraus statt umzubrechen. Das ist die
   häufigste Ursache für waagerechten Überlauf überhaupt, und sie ist besonders
   tückisch, weil sie nur bei bestimmten Breiten sichtbar wird.

   Gemessen am 02.08.2026 über alle elf Bildschirmbreiten:

     /ki-pipelines        Datenliste ragt bei 600 Pixeln um 76 Pixel heraus
     /zusammenarbeit      Ratentext läuft ab 600 Pixeln über, bei JEDER Breite
     /referenzen/lbbw     Karte ragt bei 320 Pixeln um 70 Pixel heraus
     /ueber-uns           Textblock ragt bei 320 Pixeln um 17 Pixel heraus

   Deshalb hier einmal für die eigenen Layoutbausteine, statt es einzeln zu
   jagen. min-width: 0 ändert nichts, solange der Inhalt passt. Es greift genau
   dann, wenn er es nicht tut.
   ========================================================================== */

.fm-raster > *,
.fm-zweispalt > *,
.fm-stapel > *,
.fm-reihe > *,
.fm-karte > *,
.fm-daten__zeile > *,
.fm-refkarte__text > *,
.fm-profil > * { min-width: 0; }

/* Lange Wörter in diesen Bausteinen dürfen zusätzlich brechen. */
.fm-daten__wert,
.fm-karte__text { overflow-wrap: break-word; }

/* E-Mail-Adressen und lange Namen in schmalen Spalten. Auf /kontakt ragte die
   Adresse eines Geschäftsführers bei 600 Pixeln um 101 Pixel heraus, der Name
   lief bei 900 Pixeln über seinen Kasten. anywhere bricht notfalls im Wort,
   was bei einer Adresse richtig ist und bei einem Namen selten nötig wird. */
.fm-gruender__name,
.fm-gruender__rolle,
.fm-profil a[href^="mailto:"],
.fm-kontaktkarte a[href^="mailto:"] { overflow-wrap: anywhere; }


/* =============================================================================
   06  LAYOUT
   ========================================================================== */

.fm-huelle { width: 100%; overflow-x: clip; }

.fm-breite {
  width: 100%;
  max-width: var(--breite-inhalt);
  margin-inline: auto;
  padding-inline: var(--rand);
}
.fm-breite--weit { max-width: var(--breite-weit); }
.fm-breite--schmal { max-width: 820px; }

.fm-abschnitt {
  padding-block: var(--ab-2xl);
  position: relative;
}
.fm-abschnitt--knapp { padding-block: var(--ab-xl); }
.fm-abschnitt--weit  { padding-block: var(--ab-3xl); }
.fm-abschnitt--abgesetzt { background: var(--bg-abgesetzt); }
.fm-abschnitt--invers {
  background: var(--bg-invers);
  color: var(--text-invers);
}
.fm-abschnitt--invers h1,
.fm-abschnitt--invers h2,
.fm-abschnitt--invers h3,
.fm-abschnitt--invers h4 { color: var(--text-invers); }

/* Stapel: senkrechte Abstände über eine Regel, nicht über Margins am Kind */
.fm-stapel { display: flex; flex-direction: column; gap: var(--ab-s); }
.fm-stapel--eng  { gap: var(--ab-2xs); }
.fm-stapel--weit { gap: var(--ab-m); }
.fm-stapel--sehr-weit { gap: var(--ab-l); }

/* Reihe: nebeneinander, bricht von selbst um */
.fm-reihe {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ab-xs);
  align-items: center;
}
.fm-reihe--mitte { justify-content: center; }
.fm-reihe--verteilt { justify-content: space-between; }
/* Engere Reihe für Kleinteile, die zusammengehören, etwa Mailadresse und
   LinkedIn-Verweis unter einem Portrait. Der normale Abstand lässt die beiden
   wie zwei getrennte Angaben wirken. */
.fm-reihe--eng { gap: var(--ab-2xs) var(--ab-s); }

/*
   Verweis auf ein LinkedIn-Profil.

   Steht unter jedem Portrait der beiden Geschäftsführer. Die Klickfläche ist
   über den senkrechten Innenabstand auf 44 Pixel Höhe gebracht, wie bei den
   Brotkrumen: „LinkedIn" ist ein kurzes Wort und wäre sonst zu klein für einen
   Finger. Der negative Außenabstand nimmt den Platz wieder heraus, damit die
   Zeile optisch nicht auseinandergeht.
*/
.fm-linkedin {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 44px;
  margin-block: -0.7rem;
  font-size: var(--gr--1);
  color: var(--akzent-text);
  text-decoration: none;
}
.fm-linkedin:hover { text-decoration: underline; }
.fm-linkedin .fm-icon { flex: none; }

/*
   Raster mit gleichmäßigem Umbruch.
   Absichtlich KEIN auto-fit: das erzeugt Umbrüche wie 3+1. Stattdessen feste
   Spaltenzahlen je Bildschirmbreite, gesteuert über data-spalten. Die Stufen
   stehen in Abschnitt 11.
*/
.fm-raster {
  display: grid;
  gap: var(--ab-m);
  grid-template-columns: 1fr;
}

/* Zwei Spalten mit ungleicher Breite, z. B. Text und Bild */
.fm-zweispalt {
  display: grid;
  gap: var(--ab-l);
  grid-template-columns: 1fr;
  align-items: center;
}

.fm-mitte { text-align: center; margin-inline: auto; }
.fm-mitte .fm-lede { margin-inline: auto; }


/* =============================================================================
   07  TYPOGRAFIE-BAUSTEINE
   ========================================================================== */

.fm-augenbraue {
  display: inline-flex;
  align-items: center;
  gap: var(--ab-2xs);
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr--1);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--akzent-text);
}
.fm-augenbraue::before {
  content: '';
  width: 1.75rem;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--marke), transparent);
}

.fm-schlagzeile { font-size: var(--gr-5); }

.fm-lede {
  max-width: var(--breite-text);
  font-size: var(--gr-1);
  line-height: 1.6;
  color: var(--text-neben);
}

.fm-klein { font-size: var(--gr--1); color: var(--text-fein); }
.fm-neben { color: var(--text-neben); }
.fm-fein  { color: var(--text-fein); }

/* Farbverlauf im Text. Nur für Überschriften, nie für Fließtext. */
.fm-verlauf {
  background: linear-gradient(100deg, var(--akzent-text) 0%, var(--marke-2) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
/* Im Dunkelmodus ein helleres Verlaufspaar. */
:root[data-theme='dark'] .fm-verlauf {
  background: linear-gradient(100deg, var(--marke) 0%, #7FB3FF 100%);
  -webkit-background-clip: text;
  background-clip: text;
}

.fm-textblock { max-width: var(--breite-text); }
.fm-textblock > * + * { margin-top: var(--ab-s); }
.fm-textblock h2 { margin-top: var(--ab-l); }
.fm-textblock h3 { margin-top: var(--ab-m); }
.fm-textblock ul,
.fm-textblock ol { padding-left: 1.25em; }
.fm-textblock li + li { margin-top: var(--ab-3xs); }

/* Aufzählung mit Haken statt Punkt */
.fm-haken { list-style: none; padding-left: 0; }
.fm-haken li {
  display: grid;
  grid-template-columns: 1.5rem 1fr;
  gap: var(--ab-2xs);
  align-items: start;
}
.fm-haken li + li { margin-top: var(--ab-2xs); }
.fm-haken .fm-icon { color: var(--akzent-text); margin-top: 0.25em; }


/* =============================================================================
   08  BAUSTEINE
   ========================================================================== */

/* ------------------------------------------------------------------ Knöpfe */

.fm-knopf {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ab-2xs);
  min-height: 44px;                /* Klickfläche für Finger */
  padding: 0.7rem 1.4rem;
  border: 1px solid transparent;
  border-radius: var(--rund-s);
  font-family: var(--schrift-text);
  font-size: var(--gr-0);
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--zeit-kurz) var(--kurve),
              border-color var(--zeit-kurz) var(--kurve),
              color var(--zeit-kurz) var(--kurve),
              transform var(--zeit-kurz) var(--kurve),
              box-shadow var(--zeit-mittel) var(--kurve);
}
.fm-knopf:active { transform: translateY(1px); }
.fm-knopf .fm-icon { flex: none; }

.fm-knopf--haupt {
  background: var(--akzent-voll);
  color: #FFFFFF;
  box-shadow: 0 1px 2px hsl(var(--schatten-hsl) / 0.16);
}
.fm-knopf--haupt:hover {
  background: var(--akzent-voll-h);
  color: #FFFFFF;
  box-shadow: 0 6px 20px var(--schimmer);
}
/* Im Dunkelmodus ist die Flaeche das helle Cyan, dort muss die Schrift dunkel sein. */
:root[data-theme='dark'] .fm-knopf--haupt,
:root[data-theme='dark'] .fm-knopf--haupt:hover { color: var(--marke-dunkelblau); }

.fm-knopf--rand {
  background: transparent;
  border-color: var(--rahmen-stark);
  color: var(--text);
}
.fm-knopf--rand:hover {
  border-color: var(--akzent-text);
  color: var(--akzent-text);
  background: var(--akzent-sanft);
}

.fm-knopf--leise {
  background: var(--bg-abgesetzt);
  border-color: var(--rahmen);
  color: var(--text);
}
.fm-knopf--leise:hover { background: var(--akzent-sanft); border-color: var(--akzent-text); }

/* Auf /referenzen/lbbw steht eine vollständige Adresse als Verweistext.
   Die ist 328 Pixel breit und stand in einem 246 Pixel breiten Kasten.
   anywhere bricht auch mitten im Wort, was bei einer Adresse richtig ist. */
.fm-knopf--text { overflow-wrap: anywhere; }

/* Steht ein Textverweis ALLEIN in einem Kartenfuß, ist er dort die einzige
   Schaltfläche und braucht die volle Klickfläche. Gemessen waren 199 mal 29
   Pixel. Inline mitten im Satz bleibt es beim reinen Textverweis, dort wäre
   ein 44 Pixel hoher Kasten nur störender Leerraum. */
.fm-karte__fuss > .fm-knopf--text,
.fm-refkarte__fuss > .fm-knopf--text { min-height: 44px; align-items: center; }
.fm-knopf--text {
  min-height: 0;
  padding: 0.25rem 0;
  color: var(--akzent-text);
  border-radius: var(--rund-xs);
}
.fm-knopf--text:hover { color: var(--text); }
.fm-knopf--text .fm-icon { transition: transform var(--zeit-kurz) var(--kurve); }
.fm-knopf--text:hover .fm-icon { transform: translateX(3px); }

.fm-knopf--gross { padding: 0.95rem 1.9rem; font-size: var(--gr-1); }
.fm-knopf--breit { width: 100%; }


/* ------------------------------------------------------------------ Karten */

.fm-karte {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--ab-xs);
  padding: var(--ab-m);
  background: var(--bg-karte);
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-l);
  box-shadow: var(--schatten-s);
  transition: border-color var(--zeit-mittel) var(--kurve),
              box-shadow var(--zeit-mittel) var(--kurve),
              transform var(--zeit-mittel) var(--kurve);
}
.fm-karte--hebt:hover {
  border-color: color-mix(in srgb, var(--akzent-text) 40%, var(--rahmen));
  box-shadow: var(--schatten-l);
  transform: translateY(-4px);
}
.fm-karte__kopf { display: flex; align-items: center; gap: var(--ab-xs); }
.fm-karte__titel { font-family: var(--schrift-ueberschrift); font-size: var(--gr-2); font-weight: 600; }
.fm-karte__text { color: var(--text-neben); }
.fm-karte__fuss { margin-top: auto; padding-top: var(--ab-xs); }

/* Ganze Karte klickbar, ohne verschachtelte Links */
.fm-karte--klick { cursor: pointer; }
.fm-karte--klick .fm-karte__link::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

/* Icon-Plättchen in Karten */
.fm-plaettchen {
  display: grid;
  place-items: center;
  flex: none;
  width: 3rem;
  height: 3rem;
  border-radius: var(--rund-m);
  background: var(--akzent-sanft);
  color: var(--akzent-text);
  border: 1px solid color-mix(in srgb, var(--akzent-text) 18%, transparent);
}
.fm-plaettchen--voll {
  background: linear-gradient(135deg, var(--marke), var(--marke-2));
  color: var(--marke-dunkelblau);
  border-color: transparent;
}
.fm-plaettchen--gross { width: 3.75rem; height: 3.75rem; }


/* ------------------------------------------------------------------ Chips */

.fm-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-voll);
  background: var(--bg-abgesetzt);
  color: var(--text-neben);
  font-size: var(--gr--1);
  font-weight: 500;
  /*
     KEIN white-space: nowrap.

     Nicht umbrechen ist bei kurzen Schlagwörtern wie „Webseite" richtig und
     schadet dort nicht, weil sie ohnehin in eine Zeile passen. Bei ganzen
     Sätzen ist es falsch: In einem Chip auf /leistungen steht „Erster Entwurf
     in 48 Stunden möglich", der brauchte 295 Pixel in einem 268 Pixel breiten
     Kasten, und zwar nicht nur auf dem Handy, sondern noch bei 1280 Pixeln
     Fensterbreite. Gemessen am 02.08.2026.

     Eine Regel je Bildschirmbreite wäre der falsche Weg gewesen: der Kasten
     hängt an der Kartenbreite, nicht an der Fensterbreite.
  */
  text-decoration: none;
}
.fm-chip--akzent {
  background: var(--akzent-sanft);
  border-color: color-mix(in srgb, var(--akzent-text) 25%, transparent);
  color: var(--akzent-text);
}
.fm-chip--erfolg { color: var(--erfolg); border-color: color-mix(in srgb, var(--erfolg) 30%, transparent); background: color-mix(in srgb, var(--erfolg) 8%, transparent); }
.fm-chip--warnung { color: var(--warnung); border-color: color-mix(in srgb, var(--warnung) 30%, transparent); background: color-mix(in srgb, var(--warnung) 8%, transparent); }

/* Chip als Knopf, z. B. für Filter */
button.fm-chip { cursor: pointer; transition: all var(--zeit-kurz) var(--kurve); }
button.fm-chip:hover { border-color: var(--akzent-text); color: var(--akzent-text); }
button.fm-chip[aria-pressed='true'] {
  background: var(--akzent-voll);
  border-color: var(--akzent-voll);
  color: #FFFFFF;
}
:root[data-theme='dark'] button.fm-chip[aria-pressed='true'] { color: var(--marke-dunkelblau); }


/* ------------------------------------------------------------------ Abzeichen */

.fm-abzeichen {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.2rem 0.6rem;
  border-radius: var(--rund-xs);
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr--2);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  background: var(--akzent-sanft);
  color: var(--akzent-text);
}
.fm-abzeichen--live {
  background: color-mix(in srgb, var(--erfolg) 12%, transparent);
  color: var(--erfolg);
}
.fm-abzeichen--bald {
  background: color-mix(in srgb, var(--warnung) 12%, transparent);
  color: var(--warnung);
}
.fm-abzeichen__punkt {
  width: 0.5em;
  height: 0.5em;
  border-radius: 50%;
  background: currentColor;
}
.fm-abzeichen--live .fm-abzeichen__punkt { animation: fm-pulsen 2.4s ease-in-out infinite; }

@keyframes fm-pulsen {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.4; transform: scale(0.75); }
}


/* ------------------------------------------------------------------ Zitat */

.fm-zitat {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--ab-s);
  padding: var(--ab-m);
  padding-left: calc(var(--ab-m) + 0.5rem);
  background: var(--bg-karte);
  border: 1px solid var(--rahmen);
  border-left: 4px solid var(--marke);
  border-radius: var(--rund-m);
}
.fm-zitat__marke { color: var(--marke); opacity: 0.5; }
.fm-zitat__text { font-size: var(--gr-1); line-height: 1.6; }
.fm-zitat__quelle {
  display: flex;
  align-items: center;
  gap: var(--ab-xs);
  font-size: var(--gr--1);
  color: var(--text-fein);
}
.fm-zitat__quelle img {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  object-fit: cover;
}
.fm-zitat__name { font-weight: 600; color: var(--text); display: block; }


/* ------------------------------------------------------------------ Kennzahlen */

.fm-kennzahl { display: flex; flex-direction: column; gap: var(--ab-3xs); }
.fm-kennzahl__wert {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-4);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--akzent-text);
  font-variant-numeric: tabular-nums;
}
.fm-kennzahl__text { font-size: var(--gr--1); color: var(--text-neben); }


/* ------------------------------------------------------------------ Logoleiste */

.fm-logoleiste { display: flex; flex-direction: column; gap: var(--ab-xs); }
.fm-logoleiste__titel {
  font-size: var(--gr--2);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-fein);
}
/*
   Raster statt Flexbox: so sind alle Kacheln zwangsläufig gleich breit und die
   Reihe kann nicht umbrechen, weil eine Kachel ein paar Pixel zu breit ist.
   auto-fit legt je Bildschirmbreite so viele Spalten an, wie hineinpassen, und
   verteilt die Breite gleichmäßig.
*/
.fm-logoleiste__reihe {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(6.25rem, 1fr));
  gap: var(--ab-2xs);
  align-items: stretch;
}

/*
   Jedes Logo sitzt in einer eigenen weißen Kachel gleicher Größe.

   Warum nicht einfach freigestellt in die Reihe legen: die Marken sind völlig
   verschieden gebaut. Eine ist eine breite dunkle Wortmarke, eine ein fast
   quadratisches Wappen, eine schwarz auf durchsichtig, eine rot, eine ein
   App-Icon mit eigenem dunklem Hintergrund. Frei in der Reihe sehen die
   unterschiedlich groß und unterschiedlich schwer aus, und im Dunkelmodus
   verschwinden die dunklen ganz.

   Der frühere Versuch, dunkle Logos per Filter umzukehren, hat zusätzlich Farben
   verfälscht: aus einem kräftigen Grün wurde Lila. Auf einer hellen Kachel
   behält jede Marke ihre eigene Farbe, alle sind gleich groß und in beiden Modi
   gleich gut lesbar.

   Kundennamen stehen hier bewusst nicht mehr. Diese Datei wird an jeden Browser
   ausgeliefert, ihre Kommentare sind also öffentlich lesbar. Wer ein Projekt
   zurückstellt, muss diese Datei mitprüfen: Ein PHP-Kommentar bleibt auf dem
   Server, ein CSS-Kommentar nicht.
*/
/*
   Alle Logodateien sind von tools/kundenlogos-aufbereiten.py auf dieselbe Fläche
   von 900 mal 300 Pixeln gebracht, freigestellt und auf gleiche optische Größe
   skaliert. Deshalb genügt hier eine einzige Regel und es braucht keine
   Sonderfälle je Marke mehr.
*/
.fm-logoleiste__kachel {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.55rem 0.75rem;
  border-radius: var(--rund-m);
  background: #FFFFFF;
  border: 1px solid var(--rahmen);
  box-shadow: var(--schatten-s);
  transition: transform var(--zeit-kurz) var(--kurve), box-shadow var(--zeit-mittel) var(--kurve);
}
.fm-logoleiste__kachel:hover {
  transform: translateY(-2px);
  box-shadow: var(--schatten-m);
}
/*
   Kooperationspartner, eigene Zeile unter den Projektlogos.

   Die Reihe darüber ist ein auto-fit-Raster und würde ein einzelnes Logo über
   die ganze Breite ziehen. Deshalb bekommt die Partnerzeile eine feste
   Höchstbreite, sonst stünde eine Kachel da, die viermal so groß ist wie die
   darüber, und das läse sich, als sei der Partner das Wichtigste auf der Seite.
*/
.fm-logoleiste__partner {
  display: flex;
  flex-direction: column;
  gap: var(--ab-xs);
  margin-top: var(--ab-xs);
}
.fm-logoleiste__partner .fm-logoleiste__reihe {
  grid-template-columns: repeat(auto-fit, minmax(6.25rem, 0));
  justify-content: start;
}
/* Die Kachel ist ein Verweis. Der Rahmen des Tastaturfokus darf deshalb nicht
   von der Kachel verschluckt werden. */
.fm-logoleiste__kachel--verweis:focus-visible {
  outline: 3px solid var(--akzent-voll);
  outline-offset: 3px;
}

/* Im Dunkelmodus bleibt die Kachel hell, damit die Markenfarben stimmen. */
:root[data-theme='dark'] .fm-logoleiste__kachel { border-color: transparent; }

.fm-logoleiste__logo {
  width: 100%;
  height: auto;
}


/* ------------------------------------------------------------------ Reiter */

.fm-reiter { display: flex; flex-direction: column; gap: var(--ab-m); }
.fm-reiter__leiste {
  display: flex;
  gap: var(--ab-3xs);
  padding: 4px;
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-voll);
  background: var(--bg-abgesetzt);
  overflow-x: auto;
  scrollbar-width: none;
}
.fm-reiter__leiste::-webkit-scrollbar { display: none; }
.fm-reiter__knopf {
  flex: 1 0 auto;
  min-height: 40px;
  padding: 0.5rem 1.1rem;
  border-radius: var(--rund-voll);
  font-weight: 600;
  font-size: var(--gr-0);
  color: var(--text-neben);
  white-space: nowrap;
  transition: background-color var(--zeit-kurz) var(--kurve), color var(--zeit-kurz) var(--kurve);
}
.fm-reiter__knopf:hover { color: var(--text); }
.fm-reiter__knopf[aria-selected='true'] {
  background: var(--bg-karte);
  color: var(--text);
  box-shadow: var(--schatten-s);
}
.fm-reiter__inhalt[hidden] { display: none; }


/* ------------------------------------------------------------------ Akkordeon */

.fm-akkordeon { display: flex; flex-direction: column; gap: var(--ab-2xs); }
.fm-akkordeon__punkt {
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-m);
  background: var(--bg-karte);
  overflow: hidden;
}
.fm-akkordeon__punkt[open] { border-color: color-mix(in srgb, var(--akzent-text) 35%, var(--rahmen)); }
.fm-akkordeon__kopf {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ab-xs);
  min-height: 52px;
  padding: var(--ab-xs) var(--ab-s);
  font-family: var(--schrift-ueberschrift);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}
.fm-akkordeon__kopf::-webkit-details-marker { display: none; }
.fm-akkordeon__kopf:hover { color: var(--akzent-text); }
.fm-akkordeon__kopf .fm-icon { flex: none; transition: transform var(--zeit-mittel) var(--kurve); }
.fm-akkordeon__punkt[open] .fm-akkordeon__kopf .fm-icon { transform: rotate(180deg); }
.fm-akkordeon__koerper {
  padding: 0 var(--ab-s) var(--ab-s);
  color: var(--text-neben);
}


/* ------------------------------------------------------------------ Tabelle */

/*
   Sichtbare Tabellenbeschriftung, als Absatz VOR der scrollbaren Hülle.

   Als <caption> innerhalb der Hülle erbt sie die Breite der Tabelle statt die
   des Fensters. Bei 320 Pixeln maß sie dadurch 512 Pixel in einem 296 Pixel
   breiten Ausschnitt und lief nach rechts aus dem Bild. Eine Beschriftung, zu
   der man erst scrollen muss, erfüllt ihren Zweck nicht. Als Absatz davor
   bricht sie am Fenster um; die Zuordnung zur Tabelle läuft über
   aria-labelledby.
*/
.fm-tabelle__beschriftung {
  color: var(--text-neben);
  font-size: var(--gr--1);
  line-height: 1.5;
}

.fm-tabelle-huelle {
  overflow-x: auto;
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-m);
  background: var(--bg-karte);
}
.fm-tabelle {
  width: 100%;
  min-width: 32rem;
  border-collapse: collapse;
  font-size: var(--gr-0);
}
.fm-tabelle th,
.fm-tabelle td {
  padding: var(--ab-xs) var(--ab-s);
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--rahmen);
}
.fm-tabelle thead th {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr--1);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-fein);
  background: var(--bg-abgesetzt);
  position: sticky;
  top: 0;
}
.fm-tabelle tbody tr:last-child td { border-bottom: none; }
.fm-tabelle tbody tr:hover { background: var(--bg-abgesetzt); }
.fm-tabelle__zahl { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }


/* ------------------------------------------------------------------ Formular */

.fm-feld { display: flex; flex-direction: column; gap: var(--ab-3xs); }
.fm-feld__label { font-weight: 600; font-size: var(--gr-0); }
.fm-feld__pflicht { color: var(--gefahr); }
.fm-feld__hinweis { font-size: var(--gr--1); color: var(--text-fein); }
.fm-feld__fehler { font-size: var(--gr--1); color: var(--gefahr); font-weight: 500; }

.fm-eingabe {
  width: 100%;
  min-height: 46px;
  padding: 0.6rem 0.85rem;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--rahmen-stark);
  border-radius: var(--rund-s);
  transition: border-color var(--zeit-kurz) var(--kurve), box-shadow var(--zeit-kurz) var(--kurve);
}
.fm-eingabe::placeholder { color: var(--text-fein); opacity: 1; }
.fm-eingabe:hover { border-color: var(--akzent-text); }
.fm-eingabe:focus-visible {
  outline: none;
  border-color: var(--akzent-text);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--akzent-text) 25%, transparent);
}
.fm-eingabe[aria-invalid='true'] { border-color: var(--gefahr); }
textarea.fm-eingabe { min-height: 8rem; resize: vertical; }

select.fm-eingabe {
  appearance: none;
  padding-right: 2.4rem;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 1.15rem) 1.25rem, calc(100% - 0.8rem) 1.25rem;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}

/*
   Rückmeldung nach dem Absenden.

   Es gibt genau drei Zustände: läuft, hat geklappt, hat nicht geklappt. Der
   Kasten trägt role="status" beziehungsweise role="alert", damit auch ein
   Screenreader die Rückmeldung bekommt, ohne dass die Seite wechselt.

   Die Farbe allein trägt die Aussage nicht, jeder Zustand hat zusätzlich ein
   eigenes Zeichen. Wer Rot und Grün nicht unterscheidet, sieht trotzdem, was
   los ist.
*/
.fm-meldung {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--ab-2xs) var(--ab-xs);
  align-items: start;
  padding: var(--ab-xs) var(--ab-s);
  border: 1px solid var(--rahmen);
  border-left: 3px solid var(--rahmen-stark);
  border-radius: var(--rund-s);
  background: var(--bg-abgesetzt);
  font-size: var(--gr-0);
}
.fm-meldung[hidden] { display: none; }
.fm-meldung__text { grid-column: 2; margin: 0; }
.fm-meldung__titel {
  grid-column: 2;
  font-family: var(--schrift-ueberschrift);
  font-weight: 600;
}
.fm-meldung .fm-icon { grid-row: 1 / span 2; margin-top: 0.15rem; }

.fm-meldung--laeuft { border-left-color: var(--akzent-voll); }
.fm-meldung--laeuft .fm-icon { color: var(--akzent-text); }
.fm-meldung--gut {
  border-left-color: var(--erfolg);
  background: color-mix(in srgb, var(--erfolg) 8%, transparent);
}
.fm-meldung--gut .fm-icon { color: var(--erfolg); }
.fm-meldung--schlecht {
  border-left-color: var(--gefahr);
  background: color-mix(in srgb, var(--gefahr) 8%, transparent);
}
.fm-meldung--schlecht .fm-icon { color: var(--gefahr); }

/* Liste der Felder, die noch nicht stimmen. Steht im Fehlerkasten. */
.fm-meldung__liste { grid-column: 2; margin: 0; padding-left: 1.1rem; font-size: var(--gr--1); }
.fm-meldung__liste a { color: inherit; }

/* Knopf während des Sendens: gesperrt, aber sichtbar beschäftigt. */
.fm-knopf[aria-busy='true'] { cursor: progress; opacity: 0.75; }
.fm-knopf[aria-busy='true'] .fm-icon { animation: fm-puls 1s ease-in-out infinite; }
@keyframes fm-puls { 50% { opacity: 0.35; } }
@media (prefers-reduced-motion: reduce) {
  .fm-knopf[aria-busy='true'] .fm-icon { animation: none; }
}

.fm-kaestchen {
  display: grid;
  grid-template-columns: 1.25rem 1fr;
  gap: var(--ab-2xs);
  align-items: start;
  cursor: pointer;
}
.fm-kaestchen input {
  width: 1.25rem;
  height: 1.25rem;
  margin: 0.2em 0 0;
  accent-color: var(--akzent-voll);
}
.fm-kaestchen span { font-size: var(--gr--1); color: var(--text-neben); }

/* Honigtopf gegen Formularroboter: für Menschen unsichtbar, aber nicht
   display:none, weil manche Roboter das erkennen. */
.fm-honigtopf {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}


/* ------------------------------------------------------------------ Slideshow */

.fm-schau { display: flex; flex-direction: column; gap: var(--ab-xs); }
.fm-schau__buehne {
  position: relative;
  overflow: hidden;
  border-radius: var(--rund-l);
  border: 1px solid var(--rahmen);
  background: var(--bg-abgesetzt);
  box-shadow: var(--schatten-m);
}
.fm-schau__spur {
  display: flex;
  transition: transform var(--zeit-lang) var(--kurve-aus);
}
/*
   Feste Bühnenhöhe über ein festes Seitenverhältnis von 16 zu 10.

   Grund: die Aufnahmen kommen aus ganz verschiedenen Quellen. Ein Großteil ist
   16:10, Präsentationsfolien sind 16:9, Instagram-Vorlagen sind quadratisch,
   PDF-Seiten sind hochkant und einzelne Bildschirmaufnahmen ganzer Seiten waren
   1600 mal 11176 Pixel. Ohne feste Höhe springt jeder Block auf eine andere
   Größe und die Seite wirkt unruhig.

   Bewusst „contain“ und nicht „cover“: cover würde bei den breiten und den
   hochkanten Bildern Inhalt abschneiden, und genau der Inhalt ist hier der
   Beweis. Die verbleibenden Ränder tragen die abgesetzte Fläche und sehen
   dadurch wie ein Betrachter aus, nicht wie ein Fehler.
*/
.fm-schau__bild {
  position: relative;
  flex: 0 0 100%;
  min-width: 0;
  aspect-ratio: 16 / 10;
  background: var(--bg-abgesetzt);
  overflow: hidden;
}
.fm-schau__bild picture { display: contents; }
/*
   Das Bild wird absolut auf die Bühne gelegt und der Inhalt mit object-fit
   eingepasst.

   Warum nicht max-width und max-height mit 100 Prozent: bei einem Bild mit
   Maßangaben im HTML zieht der Browser das Eigenverhältnis vor und setzt die
   Höhe danach. Ein quadratisches Bild wurde dadurch auf die Bühnenbreite
   skaliert, war damit höher als die Bühne und unten abgeschnitten. Mit
   position: absolute und inset: 0 hat das Bild eine feste Box, und object-fit
   verkleinert den Inhalt darin, ohne etwas wegzuschneiden.
*/
.fm-schau__bild img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.fm-schau__unterschrift {
  padding: var(--ab-2xs) var(--ab-xs);
  font-size: var(--gr--1);
  color: var(--text-fein);
  background: var(--bg-karte);
  border-top: 1px solid var(--rahmen);
}
.fm-schau__steuerung {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ab-xs);
}
/*
   Die Punkte der Bilderschau.

   Bis Phase 7 war der Knopf so groß wie der sichtbare Punkt, also 9,6 Pixel,
   und eine Vergrößerung über ::before mit inset -10px brachte ihn auf knapp 30.
   Das eigene Projektziel sind 44. Nachgemessen bei 390 Pixeln Breite: 10 mal 10.

   Jetzt ist der KNOPF 44 mal 44 groß und damit die Klickfläche, der sichtbare
   Punkt entsteht als ::after in der Mitte. Der Weg über ein Pseudoelement mit
   negativem inset war der falsche: bei 6,4 Pixeln Abstand hätten sich die
   Flächen benachbarter Punkte überlappt, und ein Tipp wäre beim falschen Bild
   gelandet. So stoßen sie höchstens aneinander.
*/
/*
   Klickflächen, gesammelt.

   Das Projektziel sind 44 mal 44 Pixel für alles, was man antippen kann. Bei
   der Messung am 02.08.2026 bei 390 Pixeln Breite lagen mehrere Bauteile knapp
   darunter, jedes für sich unauffällig: der Filterknopf bei 41, die Pfeile in
   den Referenzkarten bei 36, die Sprungmarke bei 43, das Markenzeichen im Kopf
   bei 40. Knapp daneben ist bei einer Fingerkuppe genauso daneben.

   Ausgenommen bleibt .fm-knopf--text. Das ist bewusst kein Knopf, sondern ein
   Verweis in Textform mitten im Satz, und für solche gilt die Regel nicht.
*/
.fm-sprung { min-height: 44px; display: inline-flex; align-items: center; }

/*
   Sprungleiste der Startseite. Stand bis Phase 7 als style-Attribut im HTML,
   und die Verweise darin waren 31 Pixel hoch. Jetzt hier, mit 44.
*/
.fm-sprungleiste {
  position: sticky;
  top: var(--kopf-hoehe);
  z-index: 8;
  padding-block: var(--ab-2xs);
}
.fm-sprungleiste__leiste {
  display: flex;
  gap: 0.3rem;
  overflow-x: auto;
  padding: var(--ab-2xs);
  background: var(--bg-schleier);
  backdrop-filter: blur(12px);
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-voll);
  scrollbar-width: none;
}
.fm-sprungleiste__leiste::-webkit-scrollbar { display: none; }
.fm-sprungleiste__leiste a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 0.8rem;
  border-radius: var(--rund-voll);
  font-size: var(--gr--2);
  font-weight: 600;
  white-space: nowrap;
  color: var(--text-neben);
  text-decoration: none;
}
.fm-sprungleiste__leiste a:hover,
.fm-sprungleiste__leiste a:focus-visible { color: var(--akzent-text); }
.fm-kopf__marke { min-height: 44px; display: inline-flex; align-items: center; }

.fm-schau__punkte { display: flex; gap: 0; flex-wrap: wrap; }
.fm-schau__punkt {
  position: relative;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
}
.fm-schau__punkt::after {
  content: '';
  position: absolute;
  inset: 50% auto auto 50%;
  width: 0.6rem;
  height: 0.6rem;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  border: 1px solid var(--rahmen-stark);
  background: transparent;
  transition: background var(--zeit-kurz) var(--kurve),
              border-color var(--zeit-kurz) var(--kurve),
              transform var(--zeit-kurz) var(--kurve);
}
.fm-schau__punkt[aria-current='true']::after {
  background: var(--akzent-voll);
  border-color: var(--akzent-voll);
  transform: translate(-50%, -50%) scale(1.35);
}

.fm-schau__pfeile { display: flex; gap: var(--ab-3xs); }
.fm-schau__pfeil {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--rahmen-stark);
  border-radius: var(--rund-s);
  color: var(--text-neben);
  transition: all var(--zeit-kurz) var(--kurve);
}
.fm-schau__pfeil:hover { border-color: var(--akzent-text); color: var(--akzent-text); background: var(--akzent-sanft); }
.fm-schau__pfeil[disabled] { opacity: 0.4; cursor: default; }


/* ------------------------------------------------------------------ Countdown */

.fm-countdown { display: flex; flex-direction: column; gap: var(--ab-2xs); }
.fm-countdown__titel { font-size: var(--gr--1); color: var(--text-fein); }
.fm-countdown__uhr { display: flex; gap: var(--ab-2xs); }
.fm-countdown__teil {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  min-width: 3.6rem;
  padding: var(--ab-2xs) var(--ab-xs);
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-s);
  background: var(--bg-karte);
}
.fm-countdown__zahl {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-2);
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  /* Feste Breite, damit beim Zählen nichts springt */
  font-feature-settings: 'tnum';
  color: var(--akzent-text);
}
.fm-countdown__einheit {
  font-size: var(--gr--2);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-fein);
}
.fm-countdown[data-abgelaufen='ja'] .fm-countdown__uhr { display: none; }
.fm-countdown__abgelaufen { display: none; }
.fm-countdown[data-abgelaufen='ja'] .fm-countdown__abgelaufen { display: block; }


/* ------------------------------------------------------------------ Kopfzeile */

.fm-kopf {
  position: sticky;
  top: 0;
  z-index: 100;
  height: var(--kopf-hoehe);
  background: var(--bg-schleier);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  border-bottom: 1px solid var(--rahmen);
}
.fm-kopf__innen {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--ab-s);
  height: 100%;
}
.fm-kopf__marke {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  flex: none;
  text-decoration: none;
  color: var(--text);
}
/* Im Kopf steht allein das FM²-Zeichen, ohne Schriftzug daneben. */
.fm-kopf__marke img {
  height: 2.5rem;
  width: auto;
  transition: transform var(--zeit-mittel) var(--kurve);
}
.fm-kopf__marke:hover img { transform: scale(1.06); }
.fm-kopf__nav { display: none; }
.fm-kopf__rechts { display: flex; align-items: center; gap: var(--ab-2xs); }

/*
   Der Kopf auf sehr schmalen Geräten.

   Gemessen am 02.08.2026: bei 320 Pixeln Breite war der rechte Block 291 Pixel
   breit, sein rechter Rand lag bei 368, also 48 Pixel außerhalb des Fensters.
   Weil der Rumpf overflow-x: clip trägt, verschwand der Menüknopf einfach, und
   damit war auf einem iPhone SE der ersten Bauart die gesamte Navigation
   unerreichbar. Bei 360 Pixeln waren es noch 26 Pixel.

   Lösung: Unter 400 Pixeln zeigt der Aufrufknopf nur sein Symbol. Der Text
   steht dann im Menü, und der Knopf behält seine 44 Pixel Klickfläche.
   Weggelassen wird nichts, nur die Beschriftung wandert.
*/
@media (max-width: 399px) {
  .fm-kopf__rechts .fm-knopf--haupt span { display: none; }
  .fm-kopf__rechts .fm-knopf--haupt {
    padding-inline: 0.9rem;
    min-width: 44px;
    justify-content: center;
  }
}

.fm-nav__link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  /* 44 Pixel, wie überall. Gemessen waren es 37, und zwar auf jeder Seite
     ab 1100 Pixeln Fensterbreite. */
  min-height: 44px;
  padding: 0.45rem 0.7rem;
  border-radius: var(--rund-s);
  color: var(--text-neben);
  font-size: var(--gr--1);
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--zeit-kurz) var(--kurve), background-color var(--zeit-kurz) var(--kurve);
}
.fm-nav__link:hover { color: var(--text); background: var(--bg-abgesetzt); }
.fm-nav__link[aria-current='page'] { color: var(--akzent-text); font-weight: 600; }

/* Ausklappmenü für Leistungen */
.fm-nav__gruppe { position: relative; }
.fm-nav__klappe {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  min-width: 15rem;
  padding: var(--ab-2xs);
  background: var(--bg-karte);
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-m);
  box-shadow: var(--schatten-l);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: opacity var(--zeit-kurz) var(--kurve),
              transform var(--zeit-kurz) var(--kurve),
              visibility var(--zeit-kurz);
}
.fm-nav__gruppe:hover > .fm-nav__klappe,
.fm-nav__gruppe:focus-within > .fm-nav__klappe {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.fm-nav__klappe a {
  display: flex;
  align-items: center;
  gap: var(--ab-2xs);
  padding: 0.55rem 0.7rem;
  border-radius: var(--rund-s);
  color: var(--text);
  text-decoration: none;
  font-size: var(--gr-0);
}
.fm-nav__klappe a:hover { background: var(--akzent-sanft); color: var(--akzent-text); }
.fm-nav__klappe .fm-icon { color: var(--akzent-text); }

/* Umschalter Hell/Dunkel */
.fm-modus {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-s);
  color: var(--text-neben);
  transition: all var(--zeit-kurz) var(--kurve);
}
.fm-modus:hover { color: var(--akzent-text); border-color: var(--akzent-text); background: var(--akzent-sanft); }
.fm-modus__sonne, .fm-modus__mond { grid-area: 1 / 1; transition: opacity var(--zeit-mittel) var(--kurve), transform var(--zeit-mittel) var(--kurve); }
/* Hell aktiv: Mond anzeigen (was passiert beim Klick) */
.fm-modus__sonne { opacity: 0; transform: rotate(-90deg) scale(0.6); }
.fm-modus__mond  { opacity: 1; transform: none; }
:root[data-theme='dark'] .fm-modus__sonne { opacity: 1; transform: none; }
:root[data-theme='dark'] .fm-modus__mond  { opacity: 0; transform: rotate(90deg) scale(0.6); }

/* Menüknopf, nur auf schmalen Bildschirmen */
.fm-menue-knopf {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-s);
  color: var(--text);
}
.fm-menue-knopf:hover { border-color: var(--akzent-text); color: var(--akzent-text); }


/* ------------------------------------------------------------------ Menütafel (schmal) */

.fm-tafel-schleier {
  position: fixed;
  inset: 0;
  z-index: 110;
  background: hsl(var(--schatten-hsl) / 0.5);
  backdrop-filter: blur(3px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--zeit-mittel) var(--kurve), visibility var(--zeit-mittel);
}
.fm-tafel-schleier[data-offen='ja'] { opacity: 1; visibility: visible; }

.fm-tafel {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 120;
  max-height: 88svh;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--ab-s) var(--ab-s) var(--ab-l);
  background: var(--bg-karte);
  border-top: 1px solid var(--rahmen);
  border-radius: var(--rund-xl) var(--rund-xl) 0 0;
  box-shadow: var(--schatten-xl);
  transform: translateY(100%);
  /*
     visibility: hidden ist hier kein Zierrat, sondern der Kern.

     Bis Phase 7 war die geschlossene Tafel nur nach unten geschoben:
     display block, visibility visible, opacity 1. Für das Auge war sie weg,
     für alles andere nicht. Gemessen am 02.08.2026: zwölf antabbare Elemente
     standen im Zugänglichkeitsbaum. Ein Screenreader las auf JEDER Seite das
     komplette Menü ein zweites Mal vor, und wer mit der Tabulatortaste
     navigierte, landete in zwölf unsichtbaren Verweisen und verlor den Fokus
     aus dem Bild.

     visibility: hidden nimmt den Zweig aus dem Baum UND aus der Tabreihenfolge.
     Es wird mitanimiert, weil es in der transition steht: beim Öffnen sofort
     sichtbar, beim Schließen erst am Ende der Bewegung.
  */
  visibility: hidden;
  transition: transform var(--zeit-lang) var(--kurve-aus),
              visibility 0s linear var(--zeit-lang);
}
.fm-tafel[data-offen='ja'] {
  transform: translateY(0);
  visibility: visible;
  transition: transform var(--zeit-lang) var(--kurve-aus),
              visibility 0s linear 0s;
}
.fm-tafel__griff {
  width: 3rem;
  height: 4px;
  margin: 0 auto var(--ab-s);
  border-radius: 2px;
  background: var(--rahmen-stark);
}
.fm-tafel__titel {
  font-size: var(--gr--2);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-fein);
  margin-bottom: var(--ab-2xs);
}
.fm-tafel__liste { list-style: none; display: flex; flex-direction: column; gap: 2px; }
.fm-tafel__liste a {
  display: flex;
  align-items: center;
  gap: var(--ab-xs);
  min-height: 48px;
  padding: 0.6rem 0.7rem;
  border-radius: var(--rund-s);
  color: var(--text);
  text-decoration: none;
  font-weight: 500;
}
.fm-tafel__liste a:hover { background: var(--akzent-sanft); color: var(--akzent-text); }
.fm-tafel__liste a[aria-current='page'] { color: var(--akzent-text); background: var(--akzent-sanft); }
.fm-tafel__liste .fm-icon { color: var(--akzent-text); flex: none; }
.fm-tafel__unter a { padding-left: 2.2rem; font-size: var(--gr--1); }


/* ------------------------------------------------------------------ Fußzeile */

.fm-fuss {
  padding-block: var(--ab-xl) var(--ab-m);
  background: var(--bg-abgesetzt);
  border-top: 1px solid var(--rahmen);
  font-size: var(--gr--1);
}
.fm-fuss__raster {
  display: grid;
  gap: var(--ab-l);
  grid-template-columns: 1fr;
}
.fm-fuss__titel {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr--1);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-fein);
  margin-bottom: var(--ab-2xs);
}
.fm-fuss__liste { list-style: none; display: flex; flex-direction: column; gap: 0.35rem; }
.fm-fuss__liste a { color: var(--text-neben); text-decoration: none; }
.fm-fuss__liste a:hover { color: var(--akzent-text); text-decoration: underline; }
.fm-fuss__abschluss {
  margin-top: var(--ab-l);
  padding-top: var(--ab-s);
  border-top: 1px solid var(--rahmen);
  display: flex;
  flex-wrap: wrap;
  gap: var(--ab-xs) var(--ab-m);
  justify-content: space-between;
  color: var(--text-fein);
}


/* =============================================================================
   09  EFFEKTE
   Alles ohne fremde Bibliothek. Jeder Effekt schaltet sich bei
   prefers-reduced-motion selbst ab.
   ========================================================================== */

/* ------------------------------------------------------------------ Ringe (Marke) */

/*
   Die Umlaufzeiten und Richtungen sind genau die der ursprünglichen
   AILYSTA-Animation. Der Nullpunkt der viewBox liegt in der Mitte, deshalb
   genügt transform-origin: 0 0.
*/
.fm-ringe { color: var(--objekt); }
.fm-ringe--dreht .fm-ringe__ring {
  transform-origin: 0 0;
  animation: fm-drehen linear infinite;
}
.fm-ringe--dreht .fm-ringe__ring--b  { animation-duration: 20s; }
.fm-ringe--dreht .fm-ringe__ring--c  { animation-duration: 30s; animation-direction: reverse; }
.fm-ringe--dreht .fm-ringe__ring--ec { animation-duration: 35s; animation-direction: reverse; }
.fm-ringe--dreht .fm-ringe__ring--d  { animation-duration: 40s; }
.fm-ringe--dreht .fm-ringe__ring--e  { animation-duration: 50s; animation-direction: reverse; }

@keyframes fm-drehen { to { transform: rotate(360deg); } }

/* ------------------------------------------------------------------ Kugel in 3D */
/*
   Das Markenmotiv als echtes räumliches Objekt: mehrere Ringe, im Raum gekippt,
   in einer Perspektive gedreht. Reines CSS, dadurch günstig und überall lauffähig.
   Die Zeigerbewegung kippt die ganze Bühne (siehe fm2-3d.js).
*/
/*
   Die beiden Zahnräder als flacher Rückfall, wenn WebGL fehlt.

   Gedreht wird über CSS und nicht über SMIL, damit sich die Drehung bei
   „wenig Bewegung" abschalten lässt, genau wie beim Zeichen. Die Umlaufzeiten
   verhalten sich wie die Zähnezahlen, 30 zu 18 Sekunden bei zehn zu sechs
   Zähnen, sonst liefe die Verzahnung sichtbar auseinander. Die Räder drehen
   gegenläufig, weil zwei kämmende Räder das immer tun.
*/
.fm-zahnraeder {
  --zahnraeder-groesse: clamp(14rem, 34vw, 26rem);
  width: var(--zahnraeder-groesse);
  pointer-events: none;
  color: var(--objekt, var(--marke));
}
.fm-zahnraeder svg { width: 100%; height: auto; display: block; }

.fm-zahnrad { transform-box: fill-box; transform-origin: center; }
/* Das translate muss VOR der Drehung stehen, sonst kreist das Rad um die
   Bildmitte statt sich an seinem Platz zu drehen. Dieselbe Reihenfolge wie
   im 3D-Motiv.

   --mitte kommt aus dem style-Attribut, das zahnraeder_flach() schreibt, und
   steht deshalb nirgends im Stylesheet. Der Ersatzwert 0px ist nicht Zierde:
   Ohne ihn wäre die ganze transform-Eigenschaft ungültig, sobald das Attribut
   einmal fehlt, und beide Räder lägen übereinander in der Bildmitte. Genau
   diese Zeile hat tools/css-regeln-pruefen.php am 05.08.2026 angemahnt. */
.fm-zahnrad--gross { animation: fm-zahnrad-mit   30s linear infinite; }
/* 30 s mal 8/12: Die Umlaufzeiten verhalten sich wie die Zähnezahlen, sonst
   liefe die Verzahnung nach wenigen Umdrehungen auseinander. */
.fm-zahnrad--klein { animation: fm-zahnrad-gegen 20s linear infinite; }

/* Der Nabenring ist etwas dunkler als der Körper. Im 3D-Motiv entsteht der Ton
   durch Abdunkeln der Objektfarbe, hier über eine eigene Farbe. --marke-2 ist
   das Sekundärblau der Marke, also kein erfundener Ton. */
.fm-zahnrad__nabe { stroke: var(--marke-2); }

/* =============================================================================
   DER KREISEL AUF /leistungen

   Drei 3D-Motive, die um eine gemeinsame Mitte laufen. Die Bahn steckt im CSS,
   nicht im 3D-Modell: Jeder Platz füllt den ganzen Behälter und dreht sich um
   dessen Mitte, das Motiv sitzt oben am Rand und wird durch eine gegenläufige
   Drehung wieder aufgerichtet. Ohne diese Gegendrehung stünde der Bildschirm
   nach einer Vierteldrehung auf dem Kopf.

   MASSE: Das Motiv ist 43 Prozent des Behälters breit, seine Mitte liegt damit
   21,5 Prozent vom Rand und der Bahnradius bei 28,5 Prozent. Der Abstand zweier
   Nachbarn beträgt 2 mal 28,5 mal sin(60 Grad) = 49,4 Prozent bei 43 Prozent
   Breite, es bleiben also 6,4 Prozent Luft.
   ========================================================================== */
.fm-kreisel {
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  max-width: 34rem;
  margin-inline: auto;
}
/* Das gemeinsame Staubfeld liegt hinter allen dreien und füllt den ganzen
   Behälter. Es trägt als einziges den weichen Schein. */
.fm-kreisel__feld {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.fm-kreisel__feld .fm-gl { max-width: none; }

/* Die drei Motive selbst bekommen keinen eigenen Schein mehr. Drei Scheine
   nebeneinander sahen aus wie drei aufgeklebte Kacheln, aufgefallen am
   06.08.2026 an einem Bildschirmabzug des Kunden. */
.fm-kreisel__motiv .fm-gl::before { content: none; }

.fm-kreisel__platz {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  animation: fm-kreisel-bahn 42s linear infinite;
  animation-delay: calc(var(--platz, 0) * -14s);
}
.fm-kreisel__motiv {
  width: 43%;
  animation: fm-kreisel-auf 42s linear infinite;
  animation-delay: calc(var(--platz, 0) * -14s);
}
@keyframes fm-kreisel-bahn {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@keyframes fm-kreisel-auf {
  from { transform: rotate(0deg); }
  to   { transform: rotate(-360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .fm-kreisel__platz { animation: none; transform: rotate(calc(var(--platz, 0) * 120deg)); }
  .fm-kreisel__motiv { animation: none; transform: rotate(calc(var(--platz, 0) * -120deg)); }
}


@keyframes fm-zahnrad-mit {
  from { transform: translateX(var(--mitte, 0px)) rotate(0deg); }
  to   { transform: translateX(var(--mitte, 0px)) rotate(360deg); }
}
@keyframes fm-zahnrad-gegen {
  from { transform: translateX(var(--mitte, 0px)) rotate(0deg); }
  to   { transform: translateX(var(--mitte, 0px)) rotate(-360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .fm-zahnrad--gross,
  .fm-zahnrad--klein { animation: none; transform: translateX(var(--mitte, 0px)); }
}

.fm-kugel {
  --kugel-groesse: clamp(14rem, 34vw, 26rem);
  position: relative;
  width: var(--kugel-groesse);
  height: var(--kugel-groesse);
  perspective: 900px;
  perspective-origin: 50% 50%;
  pointer-events: none;
}
.fm-kugel__buehne {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: rotateX(var(--kipp-x, 66deg)) rotateZ(var(--kipp-z, 0deg));
  transition: transform var(--zeit-lang) var(--kurve-aus);
  animation: fm-kugel-atmen 18s ease-in-out infinite;
}
/*
   Ringgrößen und Umlaufzeiten sind die des Originals:
   E 565, D 442, EC 350, C 258, B 177, Mittelpunkt 64. Prozente daher
   442/565 = 78,2 %, 350/565 = 61,9 %, 258/565 = 45,7 %, 177/565 = 31,3 %.
*/
.fm-kugel__ring {
  position: absolute;
  inset: 0;
  margin: auto;
  border-radius: 50%;
  border: 2.5px solid var(--objekt);
  transform-style: preserve-3d;
  animation: fm-kugel-drehen linear infinite;
}
.fm-kugel__ring--e  { width: 100%;   height: 100%;   opacity: 1;    animation-duration: 50s; animation-direction: reverse; }
.fm-kugel__ring--d  { width: 78.2%;  height: 78.2%;  opacity: 0.88; animation-duration: 40s; transform: rotateY(22deg); }
.fm-kugel__ring--ec { width: 61.9%;  height: 61.9%;  opacity: 0.8;  animation-duration: 35s; animation-direction: reverse; transform: rotateY(-26deg); }
.fm-kugel__ring--c  { width: 45.7%;  height: 45.7%;  opacity: 0.72; animation-duration: 30s; animation-direction: reverse; transform: rotateX(26deg); }
.fm-kugel__ring--b  { width: 31.3%;  height: 31.3%;  opacity: 0.66; animation-duration: 20s; transform: rotateX(-30deg); }

.fm-kugel__kern {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 11.3%;
  height: 11.3%;
  border-radius: 50%;
  background: var(--objekt);
  box-shadow: 0 0 3rem 0.5rem var(--schimmer);
}
/* Einer der beiden Endpunkte des äußersten Rings, läuft mit ihm um */
.fm-kugel__punkt {
  position: absolute;
  top: -7px;
  left: calc(50% - 7px);
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--objekt);
  box-shadow: 0 0 1.2rem var(--schimmer);
}
@keyframes fm-kugel-drehen { to { transform: rotateZ(360deg); } }
@keyframes fm-kugel-atmen {
  0%, 100% { transform: rotateX(var(--kipp-x, 66deg)) rotateZ(var(--kipp-z, 0deg)) scale(1); }
  50%      { transform: rotateX(calc(var(--kipp-x, 66deg) - 8deg)) rotateZ(calc(var(--kipp-z, 0deg) + 6deg)) scale(1.03); }
}

/* ------------------------------------------------------------------ WebGL-Objekt */
/*
   Für Stellen, an denen ein richtiges 3D-Objekt gezeigt werden soll. Zeichnet
   ein Drahtgeflecht aus Ringbahnen. Ohne WebGL bleibt die CSS-Kugel sichtbar,
   die als Rückfall im selben Behälter liegt.
*/
.fm-gl {
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  max-width: 30rem;
  margin-inline: auto;
  isolation: isolate;
}
/* Weicher Schein hinter dem Objekt, damit es auf beiden Untergründen Tiefe bekommt */
.fm-gl::before {
  content: '';
  position: absolute;
  inset: -12%;
  z-index: -1;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle, var(--schimmer) 0%, transparent 62%);
  filter: blur(14px);
}
.fm-gl canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* Das Modell lässt sich mit der Maus oder dem Finger drehen. pan-y sorgt
     dafür, dass senkrechtes Wischen weiter die Seite scrollt. */
  cursor: grab;
  touch-action: pan-y;
}
.fm-gl canvas:active { cursor: grabbing; }
.fm-gl__rueckfall { position: absolute; inset: 0; display: grid; place-items: center; }
.fm-gl[data-gl='ja'] .fm-gl__rueckfall { display: none; }

/* ------------------------------------------------------------------ Karten kippen */

.fm-kipp {
  transform-style: preserve-3d;
  will-change: transform;
  transition: transform var(--zeit-mittel) var(--kurve-aus);
}
.fm-kipp[data-kippt='ja'] {
  transform: perspective(1000px)
             rotateX(var(--kipp-rx, 0deg))
             rotateY(var(--kipp-ry, 0deg))
             translateZ(6px);
  transition: transform 90ms linear;
}
/* Inhalt etwas nach vorne holen, damit die Räumlichkeit wirkt */
.fm-kipp > * { transform: translateZ(18px); }

/* ------------------------------------------------------------------ Schimmer unter dem Zeiger */

.fm-aura { position: relative; overflow: hidden; isolation: isolate; }
.fm-aura::before {
  content: '';
  position: absolute;
  inset: -1px;
  z-index: -1;
  border-radius: inherit;
  background: radial-gradient(
    18rem circle at var(--zeiger-x, 50%) var(--zeiger-y, 50%),
    var(--schimmer),
    transparent 62%
  );
  opacity: 0;
  transition: opacity var(--zeit-mittel) var(--kurve);
}
.fm-aura:hover::before { opacity: 1; }

/* ------------------------------------------------------------------ Beim Scrollen einblenden */

.fm-zeig {
  opacity: 0;
  transform: translateY(1.4rem);
  transition: opacity var(--zeit-lang) var(--kurve-aus),
              transform var(--zeit-lang) var(--kurve-aus);
}
.fm-zeig[data-sichtbar='ja'] { opacity: 1; transform: none; }
/* Gestaffelt, wenn mehrere Kinder nacheinander erscheinen sollen */
.fm-zeig-reihe > * {
  opacity: 0;
  transform: translateY(1.2rem);
  transition: opacity var(--zeit-lang) var(--kurve-aus),
              transform var(--zeit-lang) var(--kurve-aus);
}
.fm-zeig-reihe[data-sichtbar='ja'] > * { opacity: 1; transform: none; }
.fm-zeig-reihe[data-sichtbar='ja'] > :nth-child(2) { transition-delay: 70ms; }
.fm-zeig-reihe[data-sichtbar='ja'] > :nth-child(3) { transition-delay: 140ms; }
.fm-zeig-reihe[data-sichtbar='ja'] > :nth-child(4) { transition-delay: 210ms; }
.fm-zeig-reihe[data-sichtbar='ja'] > :nth-child(5) { transition-delay: 280ms; }
.fm-zeig-reihe[data-sichtbar='ja'] > :nth-child(6) { transition-delay: 350ms; }

/* ------------------------------------------------------------------ Tiefenebenen */

.fm-tiefe { position: relative; }
.fm-tiefe__ebene {
  position: absolute;
  will-change: transform;
  pointer-events: none;
}

/* ------------------------------------------------------------------ Hintergrundmotive */

/* Feines Punktmuster, sehr zurückhaltend */
.fm-muster-punkte::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: radial-gradient(currentColor 1px, transparent 1px);
  background-size: 28px 28px;
  color: var(--text-fein);
  opacity: 0.11;
  mask-image: radial-gradient(60% 60% at 50% 40%, #000 20%, transparent 100%);
}
/* Rasterlinien */
.fm-muster-raster::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    linear-gradient(to right, currentColor 1px, transparent 1px),
    linear-gradient(to bottom, currentColor 1px, transparent 1px);
  background-size: 72px 72px;
  color: var(--text-fein);
  opacity: 0.08;
  mask-image: linear-gradient(180deg, #000, transparent 85%);
}
.fm-muster-punkte > *,
.fm-muster-raster > * { position: relative; z-index: 1; }

/* Weicher Farbschimmer als Lichtquelle hinter Inhalten */
.fm-glanz { position: relative; }
.fm-glanz::after {
  content: '';
  position: absolute;
  z-index: 0;
  width: 42rem;
  height: 42rem;
  top: var(--glanz-oben, -18rem);
  left: var(--glanz-links, 50%);
  translate: -50% 0;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle, var(--schimmer), transparent 66%);
  filter: blur(20px);
  opacity: 0.75;
}
.fm-glanz > * { position: relative; z-index: 1; }

/* ------------------------------------------------------------------ Bewegung aus */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .fm-zeig,
  .fm-zeig-reihe > * { opacity: 1; transform: none; }
  .fm-kugel__buehne { animation: none; }
  .fm-kipp[data-kippt='ja'] { transform: none; }
}


/* =============================================================================
   09b  ABSCHNITTE DER STARTSEITE
   ========================================================================== */

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

.fm-hero { padding-block: var(--ab-xl) var(--ab-l); }
.fm-hero__oben {
  display: grid;
  gap: var(--ab-l);
  grid-template-columns: 1fr;
  align-items: center;
}
.fm-hero__text { display: flex; flex-direction: column; gap: var(--ab-s); }
/* Im Hero eine Stufe kleiner als die reine Schlagzeile: so bleibt oben Platz
   für Vorlauftext, Knöpfe und die Vertrauensleiste, ohne dass gescrollt
   werden muss. */
.fm-hero__text h1 { font-size: var(--gr-5); margin-bottom: 0; }

/* Das Teamfoto. Rahmen und leichter Schimmer, damit es nicht wie ein
   ausgeschnittenes Bild wirkt, sondern wie ein Teil der Seite. */
.fm-hero__bild {
  position: relative;
  border-radius: var(--rund-xl);
  overflow: hidden;
  border: 1px solid var(--rahmen);
  box-shadow: var(--schatten-l);
  isolation: isolate;
}
.fm-hero__bild img,
.fm-hero__bild picture { width: 100%; display: block; }
.fm-hero__marke {
  position: absolute;
  right: var(--ab-xs);
  bottom: var(--ab-xs);
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.75rem;
  border-radius: var(--rund-voll);
  background: var(--bg-schleier);
  backdrop-filter: blur(10px);
  border: 1px solid var(--rahmen);
  font-size: var(--gr--2);
  font-weight: 600;
  color: var(--text);
}

/* Die Vertrauensleiste unter dem Hero, noch im ersten Bildschirm */
.fm-hero__vertrauen {
  margin-top: var(--ab-l);
  padding-top: var(--ab-m);
  border-top: 1px solid var(--rahmen);
  display: flex;
  flex-direction: column;
  gap: var(--ab-s);
}
.fm-hero__zaehler {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  font-size: var(--gr--1);
  color: var(--text-fein);
}
.fm-hero__zaehler strong {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-1);
  font-weight: 700;
  color: var(--akzent-text);
}

/* ------------------------------------------------------------------ Referenzblock */

.fm-referenzen { display: flex; flex-direction: column; gap: var(--ab-2xl); }

.fm-referenz {
  display: grid;
  gap: var(--ab-m);
  grid-template-columns: 1fr;
  align-items: center;
}
.fm-referenz__text { display: flex; flex-direction: column; gap: var(--ab-xs); }
.fm-referenz__kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ab-2xs);
}
.fm-referenz__nummer {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr--1);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--text-fein);
  font-variant-numeric: tabular-nums;
}
/*
   Auch hier eine helle Kachel statt eines Farbfilters. Der frühere Filter
   invert() hat aus einem kräftigen Grün ein Lila gemacht, weil invert die Farbe
   umkehrt und nicht nur die Helligkeit.

   Hier stand bis zum 06.08.2026 der Name des Kunden, dessen Logo grün ist. Die
   Regel dagegen steht seit Langem weiter oben in dieser Datei, sie wurde an
   dieser Stelle nur nicht befolgt. Genau dafür prüft tools/css-regeln-pruefen.php
   jetzt eigens.
*/
.fm-referenz__logo-kachel {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 6.5rem;
  padding: 0.3rem 0.45rem;
  background: #FFFFFF;
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-s);
}
:root[data-theme='dark'] .fm-referenz__logo-kachel { border-color: transparent; }
.fm-referenz__logo {
  width: 100%;
  height: auto;
}
/* Kompakte Marken statt Wortmarken.

   Die Kachel ist auf Wortmarken ausgelegt, die auf einer Fläche von 900 zu 300
   liegen. Das FM²-Logo ist 324 zu 264, also fast quadratisch, und wird im Kopf
   und in der Fußzeile in dieser Fassung gebraucht. Über die Kachelbreite
   gestreckt wäre es 5,3rem hoch, also gut dreimal so groß wie die
   AILYSTA-Wortmarke daneben.

   Die 2,5rem sind nicht geschätzt, sondern gerechnet: gleiche sichtbare
   FLÄCHE, nicht gleiche Höhe, das ist dasselbe Maß, nach dem auch
   tools/kundenlogos-aufbereiten.py die Kundenlogos angleicht. Gemessen wurden
   die Pixel mit Alpha über der Schwelle: AILYSTA 43345 von 900x300, FM²
   18908 von 324x264, also 22,1 Prozent der Datei. Daraus folgt eine Höhe von
   2,49rem für gleiche Tintenfläche. */
.fm-referenz__logo--hoch {
  width: auto;
  height: 2.5rem;
}
.fm-referenz__titel { margin-bottom: 0; }
.fm-referenz__untertitel {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-1);
  font-weight: 500;
  color: var(--akzent-text);
}
.fm-referenz__kunde { font-size: var(--gr--1); color: var(--text-fein); }
.fm-referenz__zahlen {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ab-m);
  padding-top: var(--ab-2xs);
}
.fm-referenz__hinweis {
  padding: var(--ab-2xs) var(--ab-xs);
  border-left: 3px solid var(--warnung);
  background: color-mix(in srgb, var(--warnung) 8%, transparent);
  border-radius: var(--rund-xs);
  font-size: var(--gr--1);
  color: var(--text-neben);
}

/* ------------------------------------------------------------------ Referenzkarte */

/* Kompakte Fassung eines Referenzprojekts, für die Leistungsseiten und die
   Übersicht. Der große, abwechselnd gespiegelte Block bleibt der Startseite
   vorbehalten. */
.fm-refkarte {
  display: flex;
  flex-direction: column;
  background: var(--bg-karte);
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-l);
  overflow: hidden;
  box-shadow: var(--schatten-s);
  transition: border-color var(--zeit-mittel) var(--kurve),
              box-shadow var(--zeit-mittel) var(--kurve);
}
.fm-refkarte:hover {
  border-color: color-mix(in srgb, var(--akzent-text) 40%, var(--rahmen));
  box-shadow: var(--schatten-m);
}
/* Die Schau sitzt oben in der Karte, deshalb keine eigene Rundung und kein
   eigener Rahmen. */
.fm-refkarte .fm-schau { gap: 0; }
.fm-refkarte .fm-schau__buehne {
  border: none;
  border-radius: 0;
  box-shadow: none;
  border-bottom: 1px solid var(--rahmen);
}
.fm-refkarte .fm-schau__steuerung {
  padding: var(--ab-2xs) var(--ab-xs) 0;
}
.fm-refkarte .fm-schau__pfeil { width: 44px; height: 44px; }
.fm-refkarte .fm-schau__unterschrift {
  border-top: none;
  background: transparent;
  padding: var(--ab-3xs) var(--ab-xs) 0;
}
.fm-refkarte__text {
  display: flex;
  flex-direction: column;
  gap: var(--ab-3xs);
  padding: var(--ab-xs) var(--ab-s) var(--ab-s);
  flex: 1;
}
.fm-refkarte__kopf {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--ab-2xs);
  margin-bottom: var(--ab-3xs);
}
.fm-refkarte__titel {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-2);
  font-weight: 700;
  line-height: 1.2;
}
.fm-refkarte__untertitel {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-0);
  font-weight: 500;
  color: var(--akzent-text);
}
.fm-refkarte__fuss {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ab-xs);
  margin-top: auto;
  padding-top: var(--ab-xs);
}

/* ------------------------------------------------------------------ Kundenstimmen */

/* Ein einzelnes Zitat, das nicht in einem Raster steht.

   Am 03.08.2026 entfiel der gestrichelte Platzhalter „hier kommen noch zwei
   Stimmen hin", weil es bei der einen LBBW-Stimme bleibt. Ohne Nachbarn im
   Zweierraster lief das Zitat sonst über die volle Seitenbreite und stand
   linksbündig da wie ein vergessener Rest. Begrenzte Breite und mittig gesetzt
   liest sich das als Entscheidung. */
.fm-zitat--allein {
  max-width: 42rem;
  margin-inline: auto;
}

/* ------------------------------------------------------------------ Ablauf */

.fm-schritt { display: flex; flex-direction: column; gap: var(--ab-2xs); }
.fm-schritt__nummer {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-3);
  font-weight: 700;
  line-height: 1;
  color: var(--akzent-text);
  font-variant-numeric: tabular-nums;
}
/* „Entwicklungsvertrag" passte bei 1100 Pixeln nicht in seine Spalte.
   Silbentrennung wie bei den Überschriften, siehe Abschnitt 05. */
.fm-schritt__titel {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-1);
  font-weight: 600;
  hyphens: auto;
  overflow-wrap: break-word;
}
.fm-schritt__text { font-size: var(--gr-0); color: var(--text-neben); }

/* ------------------------------------------------------------------ Preisversprechen */

.fm-versprechen {
  display: grid;
  gap: var(--ab-s);
  padding: var(--ab-m);
  border-radius: var(--rund-l);
  background: var(--bg-invers);
  color: var(--text-invers);
  border: 1px solid transparent;
}
.fm-versprechen h3 { color: var(--text-invers); }
.fm-versprechen p { color: color-mix(in srgb, var(--text-invers) 78%, transparent); }
.fm-versprechen .fm-knopf--haupt {
  background: var(--marke);
  color: var(--marke-dunkelblau);
}
.fm-versprechen .fm-knopf--haupt:hover { background: #33CFFF; color: var(--marke-dunkelblau); }

/* ------------------------------------------------------------------ Gründerkarte */

.fm-gruender { display: flex; flex-direction: column; gap: var(--ab-s); }
.fm-gruender__bild {
  width: 100%;
  max-width: 13rem;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--rund-l);
  border: 1px solid var(--rahmen);
}
.fm-gruender__name { font-family: var(--schrift-ueberschrift); font-size: var(--gr-2); font-weight: 700; }
.fm-gruender__rolle { font-size: var(--gr--1); font-weight: 600; color: var(--akzent-text); }

/* ------------------------------------------------------------------ Meilensteine */

.fm-meilensteine {
  display: grid;
  gap: var(--ab-m);
  grid-template-columns: 1fr;
  counter-reset: meilenstein;
}
.fm-meilenstein {
  position: relative;
  padding-left: var(--ab-m);
  border-left: 2px solid var(--rahmen);
}
.fm-meilenstein::before {
  content: '';
  position: absolute;
  left: -7px;
  top: 0.4rem;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--bg);
  border: 2px solid var(--akzent-text);
}
.fm-meilenstein__jahr {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr--1);
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--akzent-text);
}
.fm-meilenstein__text { color: var(--text-neben); }


/* =============================================================================
   10  HILFSKLASSEN
   ========================================================================== */

.fm-nur-vorlesen {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.fm-kein-umbruch { white-space: nowrap; }
.fm-voll { width: 100%; }
.fm-oben-null { margin-top: 0; }

/*
   Icons.

   Der Zurücksetzer stellt svg auf display:block, damit einzeln stehende Grafiken
   keine Lücke unter der Grundlinie erzeugen. Für Icons ist das falsch: steht ein
   Icon mitten in einem Absatz, drückt block den folgenden Text in die nächste
   Zeile. Deshalb hier inline-block, leicht unter die Grundlinie gesetzt.

   In Flex- und Grid-Behältern (Knöpfe, Plättchen, Hakenlisten) ändert das
   nichts: dort werden Kinder ohnehin zu Blöcken.
*/
.fm-icon {
  flex: none;
  display: inline-block;
  vertical-align: -0.15em;
}
.fm-icon-fehlt {
  display: inline-grid;
  place-items: center;
  width: 1.5em;
  height: 1.5em;
  border: 1px dashed var(--gefahr);
  border-radius: 4px;
  color: var(--gefahr);
  font-size: 0.8em;
}
.fm-runden-l { border-radius: var(--rund-l); }
.fm-schatten-m { box-shadow: var(--schatten-m); }
.fm-schatten-l { box-shadow: var(--schatten-l); }

/* Bildrahmen, der wie ein Browserfenster wirkt */
.fm-fenster {
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-m);
  overflow: hidden;
  background: var(--bg-karte);
  box-shadow: var(--schatten-l);
}
.fm-fenster__leiste {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.55rem var(--ab-xs);
  background: var(--bg-abgesetzt);
  border-bottom: 1px solid var(--rahmen);
}
.fm-fenster__punkt { width: 0.65rem; height: 0.65rem; border-radius: 50%; background: var(--rahmen-stark); opacity: 0.7; }
.fm-fenster__adresse {
  flex: 1;
  min-width: 0;
  margin-left: 0.4rem;
  padding: 0.15rem 0.6rem;
  border-radius: var(--rund-voll);
  background: var(--bg);
  border: 1px solid var(--rahmen);
  font-size: var(--gr--2);
  color: var(--text-fein);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Rahmen, der wie ein Telefon wirkt */
.fm-telefon {
  max-width: 20rem;
  margin-inline: auto;
  padding: 0.55rem;
  border: 1px solid var(--rahmen-stark);
  border-radius: 2.2rem;
  background: var(--bg-karte);
  box-shadow: var(--schatten-l);
}
.fm-telefon > * { border-radius: 1.75rem; overflow: hidden; }

/* Druckausgabe */
@media print {
  .fm-kopf, .fm-tafel, .fm-tafel-schleier, .fm-modus, .fm-menue-knopf,
  .fm-schau__steuerung, .fm-sprung { display: none !important; }
  body { background: #FFFFFF; color: #000000; }
  a { color: #000000; text-decoration: underline; }
  .fm-abschnitt { padding-block: 1.5rem; }
}


/* =============================================================================
   10b  REFERENZSEITEN

   Bausteine, die nur auf der Referenzübersicht und den zehn Projektseiten
   vorkommen. Die zugehörigen Umbrüche stehen in Abschnitt 11.
   ========================================================================== */

/* ------------------------------------------------------------- Brotkrumen */

.fm-brotkrumen { font-size: var(--gr--1); }
.fm-brotkrumen ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.3rem 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.fm-brotkrumen li { display: flex; align-items: center; gap: 0.5rem; }
.fm-brotkrumen li + li::before {
  content: '/';
  color: var(--rahmen-stark);
}
/* Die Verweise bekommen eine eigene Klickfläche.

   „Start" ist ein kurzes Wort und war dadurch nur 32 mal 23 Pixel groß. Das
   liegt unter den 24 mal 24, die WCAG 2.5.8 als Mindestmaß nennt, und deutlich
   unter den 44, die Apple empfiehlt. Der senkrechte Innenabstand bringt die
   Fläche auf 44 Pixel Höhe, ohne die Zeile optisch zu verändern: der negative
   Außenabstand nimmt den zusätzlichen Platz wieder heraus, und weil die Liste
   ein Flexverbund mit `align-items: center` ist, bleibt die Grundlinie stehen.
   Gefunden bei der Breitenprüfung am 03.08.2026, auf allen zehn
   Referenzseiten und in jeder Breite. */
.fm-brotkrumen a {
  color: var(--text-neben);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  margin-block: -0.7rem;
}
.fm-brotkrumen a:hover { color: var(--akzent-text); text-decoration: underline; }
.fm-brotkrumen [aria-current='page'] { color: var(--text); font-weight: 500; }

/* --------------------------------------------------------------- Belegband */

/* Kennzahlen und Countdown in einem Band. Auf schmalen Schirmen untereinander,
   ab 900px nebeneinander, siehe Abschnitt 11. */
.fm-belege { display: grid; gap: var(--ab-m); align-items: center; }
.fm-belege .fm-referenz__zahlen { padding-top: 0; gap: var(--ab-l); }

/* ------------------------------------------------------------ Technikliste */

/*
   Zweispaltige Beschreibungsliste. Absichtlich keine Tabelle: es sind Paare aus
   Begriff und Wert, keine Daten mit Kopfzeile. Auf dem Handy stehen Begriff und
   Wert untereinander, ab 600px nebeneinander.
*/
.fm-daten {
  display: grid;
  margin: 0;
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-m);
  background: var(--bg-karte);
  overflow: hidden;
  /* Die Zeilen darunter fragen die Breite DIESER Liste ab, nicht die des
     Fensters. Grund: fm-daten steht mal seitenbreit (/ueber-uns), mal in
     halbbreiten Karten (/ki-pipelines). Eine Fensterregel machte bei 600px
     Fensterbreite aus der 208px-Karte zwei Spalten, und der Wert stand mit
     14px Breite ein Buchstabe je Zeile da. inline-size ist hier gefahrlos,
     die Breite der Liste kommt immer vom Elternelement, nie vom Inhalt. */
  container-type: inline-size;
}
.fm-daten__zeile {
  display: grid;
  gap: 0.15rem var(--ab-m);
  padding: var(--ab-xs) var(--ab-s);
  border-top: 1px solid var(--rahmen);
}
.fm-daten__zeile:first-child { border-top: 0; }
/* Streifen über color-mix, damit sie in beiden Modi gleich stark wirken. */
.fm-daten__zeile:nth-child(even) {
  background: color-mix(in srgb, var(--text) 4%, transparent);
}
.fm-daten__bereich {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-0);
  font-weight: 600;
  color: var(--text);
}
.fm-daten__wert {
  margin: 0;
  font-size: var(--gr-0);
  color: var(--text-neben);
}

/* Begriff und Wert nebeneinander, sobald die LISTE breit genug ist.
   26rem = 8.5rem Etikett + Wert in ordentlicher Lesebreite. Darunter stapeln
   die Paare, egal wie breit das Fenster ist. Bis zum 03.08.2026 hing diese
   Regel an @media (min-width: 600px), siehe den Vermerk bei .fm-daten. */
@container (min-width: 26rem) {
  .fm-daten__zeile {
    grid-template-columns: minmax(8.5rem, 0.34fr) 1fr;
    align-items: baseline;
  }
}

/* --------------------------------------------------------------- Blättern */

.fm-blaettern { display: grid; gap: var(--ab-xs); }
.fm-blaettern__glied {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: var(--ab-s) var(--ab-m);
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-m);
  background: var(--bg-karte);
  text-decoration: none;
  transition: border-color var(--zeit-kurz) var(--kurve),
              transform var(--zeit-kurz) var(--kurve),
              box-shadow var(--zeit-mittel) var(--kurve);
}
a.fm-blaettern__glied:hover {
  border-color: var(--akzent-voll);
  transform: translateY(-2px);
  box-shadow: var(--schatten-m);
}
.fm-blaettern__glied--leer { border-style: dashed; }
.fm-blaettern__glied--mitte { align-items: center; text-align: center; }
.fm-blaettern__glied--rechts { align-items: flex-end; text-align: right; }
.fm-blaettern__marke {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: var(--gr--1);
  color: var(--text-fein);
}
.fm-blaettern__titel {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-1);
  font-weight: 600;
  line-height: 1.25;
  color: var(--text);
}
.fm-blaettern__glied--leer .fm-blaettern__titel { color: var(--text-fein); }

/* ------------------------------------------------------------- Zeitleiste */

/*
   Erzählende Zeitleiste für „Über uns". Anders als .fm-meilensteine, das eine
   knappe Übersicht in Spalten ist: hier steht ein Strang von oben nach unten mit
   Jahr, Überschrift und Absatz, weil die Reihenfolge selbst die Aussage ist.

   Der Strang ist ein Rahmen am Listenelement, nicht ein eigenes Element. Damit
   endet die Linie automatisch beim letzten Eintrag und muss nicht gerechnet
   werden.
*/
/* --------------------------------------------------------------- Markenbaum */

/*
   Der Baum auf /ueber-uns: eine Wurzel, zwei Äste, darunter die Namen.

   Kästen und Linien aus CSS statt eines SVG. Ein SVG müsste den Text in fester
   Größe mitzeichnen und bräuchte für schmale Schirme eine zweite Fassung. So
   ist es dieselbe Auszeichnung in jeder Breite, mit echtem Text darin.

   Die Linien sind Pseudoelemente und tragen keine Bedeutung. Was der Baum
   aussagt, steht als Text in den Kästen, deshalb geht einem Screenreader nichts
   verloren, wenn er die Linien nicht kennt.
*/
.fm-baum {
  display: grid;
  justify-items: center;
  gap: 0;
}

/* Wurzel */
.fm-baum__wurzel {
  display: grid;
  justify-items: center;
  gap: var(--ab-2xs);
  padding: var(--ab-s) var(--ab-m);
  text-align: center;
  background: var(--bg-karte);
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-l);
  box-shadow: var(--schatten-m);
  position: relative;
  z-index: 1;
}
.fm-baum__name {
  margin: 0;
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-1);
  font-weight: 700;
}
.fm-baum__rolle { margin: 0; font-size: var(--gr--1); color: var(--text-neben); }

/* Stamm: senkrechte Linie von der Wurzel nach unten.

   Die drei zusätzlichen Pixel schließen eine sichtbare Lücke. Die Karten haben
   einen Rahmen von 1 Pixel, und ein absolut gesetztes Pseudoelement richtet
   sich am Innenrand seines Bezugselements aus, nicht am Außenrand. Gemessen am
   05.08.2026 blieben dadurch 2 Pixel Hintergrund zwischen Stammende und
   Kartenoberkante stehen, in der gestapelten Ansicht bei jeder Breite.

   Lieber ein Überstand von wenigen Pixeln in derselben Farbe, der unsichtbar
   ist, als eine Lücke, die man sieht. */
.fm-baum__wurzel::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  width: 2px;
  height: calc(var(--ab-m) + 3px);
  background: var(--rahmen-stark);
  transform: translateX(-50%);
}

.fm-baum__aeste {
  display: grid;
  gap: var(--ab-m);
  width: 100%;
  /*
     Gestapelte Ansicht: Zwischen Wurzel und erster Karte liegt nur EINE
     Strecke, der Stamm. Der Abstand ist deshalb genau so hoch wie der Stamm,
     sonst endet er im Leeren. Ab 900 Pixeln kommt die Querlinie dazu, dort
     wird der Abstand verdoppelt.
  */
  margin-top: var(--ab-m);
  position: relative;
}

.fm-baum__ast {
  display: grid;
  gap: var(--ab-2xs);
  align-content: start;
  padding: var(--ab-s) var(--ab-m);
  background: var(--bg-karte);
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-l);
  position: relative;
}
.fm-baum__kopf { display: flex; align-items: center; gap: var(--ab-2xs); }
.fm-baum__astname {
  margin: 0;
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-0);
  font-weight: 700;
}
.fm-baum__asttext { margin: 0; font-size: var(--gr--1); color: var(--text-neben); }

.fm-baum__blaetter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ab-2xs);
  margin: var(--ab-2xs) 0 0;
  padding: 0;
  list-style: none;
}
/*
   Jedes Blatt ist ein Verweis: die eigenen Produkte auf ihre Projektseite, die
   Leistungen auf ihre Leistungsseite. Deshalb 44 Pixel Höhe, sonst wäre ein
   kurzes Wort wie „Design" zu klein für einen Finger. Dieselbe Rechnung wie bei
   den Brotkrumen und dem LinkedIn-Verweis.
*/
.fm-baum__blatt {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 44px;
  padding: 0.3rem 0.8rem;
  font-size: var(--gr--1);
  font-weight: 600;
  color: var(--akzent-text);
  background: var(--akzent-sanft);
  border-radius: var(--rund-voll);
  text-decoration: none;
  transition: background var(--zeit-kurz) var(--kurve),
              transform var(--zeit-kurz) var(--kurve);
}
.fm-baum__blatt:hover {
  background: color-mix(in srgb, var(--akzent-text) 16%, transparent);
  transform: translateY(-1px);
}
.fm-baum__blatt:focus-visible {
  outline: 3px solid var(--akzent-voll);
  outline-offset: 2px;
}

/*
   Das Logo im Blatt sitzt in derselben weißen Kachel wie überall sonst, nur
   kleiner. Ohne die Kachel verschwänden die dunklen Marken im Dunkelmodus, das
   war schon in der Logoleiste der Grund für die Kachel. Die Breite ist über die
   Kachel begrenzt, nicht über das Bild, sonst zöge eine breite Wortmarke wie
   AILYSTA das ganze Blatt auseinander.
*/
.fm-baum__logo { display: inline-flex; flex: none; }
.fm-baum__logo .fm-referenz__logo-kachel {
  width: 3.4rem;
  padding: 0.2rem 0.3rem;
  border-radius: var(--rund-xs);
  box-shadow: none;
}

/*
   Steht das Logo ohne den Namen daneben, muss es größer sein.

   Gemessen am 06.08.2026: Mit 3,4rem Kachel kam das Wortbild auf 43 mal 14
   Pixel. Solange „Wegvio" als Text danebenstand, reichte das als Beiwerk. Als
   alleiniger Träger der Aussage reicht es nicht, „finde-deine-partei.ai" ist
   bei 43 Pixel Breite nicht mehr zu entziffern.

   6rem ist die Breite, bei der alle drei Wortbilder lesbar werden, ohne dass
   die Blätter in der Karte eine Zeile mehr brauchen.
*/
.fm-baum__blatt--nurlogo .fm-referenz__logo-kachel {
  width: 6rem;
  padding: 0.25rem 0.4rem;
}

/*
   Unter 900px stehen die Äste untereinander. Dann ist die verbindende Linie
   senkrecht und läuft von einem Ast zum nächsten, sonst zeigte der Stamm ins
   Leere.
*/
.fm-baum__ast + .fm-baum__ast::before {
  content: '';
  position: absolute;
  bottom: 100%;
  left: 50%;
  width: 2px;
  height: var(--ab-m);
  background: var(--rahmen-stark);
  transform: translateX(-50%);
}

.fm-zeitleiste { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
.fm-zeitleiste__punkt {
  position: relative;
  display: grid;
  gap: var(--ab-3xs) var(--ab-m);
  padding: 0 0 var(--ab-l) var(--ab-m);
  border-left: 2px solid var(--rahmen);
}
.fm-zeitleiste__punkt:last-child { padding-bottom: 0; border-left-color: transparent; }
.fm-zeitleiste__punkt::before {
  content: '';
  position: absolute;
  left: -8px;
  top: 0.45rem;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--bg);
  border: 3px solid var(--akzent-voll);
}
/* Der jüngste Eintrag ist der wichtigste, deshalb gefüllt statt hohl. */
.fm-zeitleiste__punkt--jetzt::before {
  background: var(--akzent-voll);
  box-shadow: 0 0 0 5px var(--akzent-sanft);
}
.fm-zeitleiste__jahr {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-0);
  font-weight: 700;
  color: var(--akzent-text);
  font-variant-numeric: tabular-nums;
}
.fm-zeitleiste__titel {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-1);
  font-weight: 600;
  line-height: 1.3;
}
.fm-zeitleiste__text { margin: 0; color: var(--text-neben); }
.fm-zeitleiste__marke {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: var(--gr--1);
  color: var(--text-fein);
}

/* ------------------------------------------------------------ Zahlungsplan */

/*
   Die drei Raten als Band. Die Breite jedes Abschnitts entspricht dem Anteil,
   der darin steht, damit man 40/30/30 sieht und nicht nur liest. Der Anteil
   kommt über --anteil aus dem HTML, weil er zum Inhalt gehört und nicht zum
   Aussehen.
*/
/* Der Ratenbaustein ist am 03.08.2026 entfallen, mit dem Zahlungsplan auf
   /zusammenarbeit. Rund 40 Zeilen Stil für einen Baustein, den keine Seite mehr
   benutzt, wurden hier entfernt. Wer den Zahlungsplan zurückholen will, holt sie
   aus der Versionsgeschichte, nicht aus der Erinnerung. */

/* --------------------------------------------------- Architekturdiagramm */

/*
   Zwei Darstellungen desselben Ablaufs, siehe inc/pipelinebild.php.
   Unter 900 Pixel die Liste, darüber das SVG. Umgeschaltet wird in Abschnitt 11.

   Die Liste bleibt oberhalb von 900 Pixel im Dokument und wird nur optisch
   verborgen, nicht mit display:none. Sonst wäre der Ablauf für Screenreader auf
   großen Schirmen nicht vorhanden, denn das SVG trägt aria-hidden.
*/
.fm-pipeline {
  display: grid;
  gap: var(--ab-m);
  padding: var(--ab-s);
  background: var(--bg-karte);
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-l);
}
.fm-pipeline__bild { display: none; }

.fm-pipeline__gruppe {
  display: flex;
  align-items: center;
  gap: var(--ab-2xs);
  font-size: var(--gr-1);
  margin-top: var(--ab-xs);
}
.fm-pipeline__gruppe .fm-icon { color: var(--akzent-text); }

.fm-ablaufliste { display: grid; gap: var(--ab-xs); margin: 0; padding: 0; list-style: none; }
.fm-ablaufliste__punkt {
  display: grid;
  gap: 0.2rem;
  padding: var(--ab-xs) var(--ab-s);
  background: var(--bg-karte);
  border: 1px solid var(--rahmen);
  border-left: 3px solid var(--akzent-voll);
  border-radius: var(--rund-s);
}
.fm-ablaufliste--kern .fm-ablaufliste__punkt { border-left-color: var(--marke-2, var(--akzent-voll)); }
.fm-ablaufliste__punkt--gut { border-left-color: var(--erfolg); }
.fm-ablaufliste__punkt--neutral { border-left-color: var(--rahmen-stark); }
.fm-ablaufliste__titel {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-0);
  font-weight: 600;
}
.fm-ablaufliste__text { font-size: var(--gr--1); color: var(--text-neben); }
.fm-ablaufliste__marke {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: var(--gr--1);
  font-weight: 600;
  color: var(--akzent-text);
}
.fm-ablaufliste__unter {
  margin: 0.2rem 0 0;
  padding-left: 1.1rem;
  font-size: var(--gr--1);
  color: var(--text-neben);
}

/* Farben und Schriften des Diagramms. Alles über Design-System-Variablen,
   damit Hell und Dunkel ohne zweite Fassung stimmen. */
.fm-pipeline__kasten rect,
rect.fm-pipeline__kasten {
  fill: var(--bg-karte);
  stroke: var(--akzent-voll);
  stroke-width: 1.5;
}
/* Zwei Schreibweisen, weil die große Zeichnung die Klasse an eine Gruppe hängt
   und die kompakte direkt an das Rechteck. Ohne die zweite Form blieben die
   Quellkästen im Kopf der Seite ungefüllt, und zwar stumm: Eine Regel, die
   nichts trifft, meldet sich nicht. Gemessen am 05.08.2026. */
.fm-pipeline__kasten--quelle rect,
rect.fm-pipeline__kasten--quelle { fill: var(--akzent-sanft); }
rect.fm-pipeline__kasten--gut { stroke: var(--erfolg); }
rect.fm-pipeline__kasten--neutral {
  fill: var(--bg-abgesetzt);
  stroke: var(--rahmen-stark);
}
.fm-pipeline__rahmen {
  fill: none;
  stroke: var(--akzent-voll);
  stroke-width: 1.5;
  stroke-dasharray: 8 6;
}
.fm-pipeline__titel text,
text.fm-pipeline__titel {
  fill: var(--text);
  font-family: var(--schrift-ueberschrift);
  font-size: 16px;
  font-weight: 700;
}
.fm-pipeline__unter text,
text.fm-pipeline__unter {
  fill: var(--text-neben);
  font-family: var(--schrift-text);
  font-size: 13px;
}
.fm-pipeline__punkt text {
  fill: var(--text-neben);
  font-family: var(--schrift-text);
  font-size: 13px;
}
.fm-pipeline__marke text {
  fill: var(--akzent-text);
  font-family: var(--schrift-text);
  font-size: 12px;
  font-weight: 600;
}
.fm-pipeline__rahmenname {
  fill: var(--akzent-text);
  font-family: var(--schrift-ueberschrift);
  font-size: 14px;
  font-weight: 700;
}
/*
   Halo hinter den Beschriftungen. Zwei von ihnen liegen zwangsläufig auf einer
   Verbindungslinie, weil die Linie an dieser Stelle durchmuss. paint-order
   zeichnet zuerst die Kontur in der Kartenfarbe und dann den Buchstaben, die
   Linie verschwindet also hinter dem Text statt quer durch ihn zu laufen.
*/
.fm-pipeline__marke text,
.fm-pipeline__rahmenname,
text.fm-pipeline__notiz {
  paint-order: stroke fill;
  stroke: var(--bg-karte);
  stroke-width: 5px;
  stroke-linejoin: round;
}
text.fm-pipeline__notiz {
  fill: var(--text-fein);
  font-family: var(--schrift-text);
  font-size: 12px;
  font-style: italic;
}
/* Die kompakte Fassung im Seitenkopf. Sie benutzt dieselben Klassen und damit
   dieselben Farben, Rahmen und Strichstärken wie die große Zeichnung. Anders
   sind nur die Schriftgrößen: Das viewBox ist hier 340 statt 900 Einheiten
   breit, eine Einheit ist also größer. Ohne diese Werte stünden 16er Titel in
   einem 340er Bild und die Kästen liefen über. */
.fm-pipeline-kompakt {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--ab-xs);
}
.fm-pipeline-kompakt__bild {
  display: block;
  width: 100%;
  height: auto;
}
.fm-pipeline-kompakt text.fm-pipeline__titel { font-size: 14px; }
.fm-pipeline-kompakt text.fm-pipeline__unter { font-size: 11px; }
.fm-pipeline-kompakt .fm-pipeline__marke text { font-size: 10.5px; }
.fm-pipeline-kompakt .fm-pipeline__rahmenname { font-size: 12px; }
.fm-pipeline-kompakt text.fm-pipeline__notiz { font-size: 10.5px; }
/* Der Halo hinter den Beschriftungen ist in der großen Zeichnung 5 Einheiten
   breit. Bei diesem kleineren viewBox wäre das anteilig zu viel und fräse
   Löcher in die Nachbarschaft. */
.fm-pipeline-kompakt .fm-pipeline__marke text,
.fm-pipeline-kompakt .fm-pipeline__rahmenname,
.fm-pipeline-kompakt text.fm-pipeline__notiz { stroke-width: 3.5px; }

.fm-pipeline-kompakt__unterschrift {
  font-size: var(--gr--1);
  color: var(--text-neben);
  text-align: center;
  text-wrap: balance;
}
.fm-pipeline-kompakt__unterschrift .fm-augenbraue {
  display: block;
  margin-bottom: 0.2rem;
}

.fm-pipeline__linie path {
  fill: none;
  stroke: var(--text-neben);
  stroke-width: 1.5;
}

/* ------------------------------------------------- Leistungsaufstellung */

/*
   Die Beispielaufstellung auf „Zusammenarbeit" ist eine Tabelle, in deren
   Leistungsspalte ein Kurztitel und darunter eine Aufzählung steht. Genau so
   sind unsere echten Angebote aufgebaut, deshalb bleibt es eine Tabelle und wird
   nicht in Karten aufgelöst.
*/
/*
   Unter 900 Pixel wird aus jeder Zeile ein Block, sonst müsste auf dem Handy
   seitlich gescrollt werden, und genau das wollen wir nicht. Ab 900 Pixel ist es
   wieder eine echte Tabelle, siehe Abschnitt 11.

   Die Tabellensemantik bleibt in beiden Fällen erhalten, weil im HTML die Rollen
   ausdrücklich gesetzt sind. Ohne diese Rollen würde display:block die Tabelle
   für Screenreader in eine Ansammlung von Absätzen verwandeln.
*/
.fm-tabelle--aufstellung { min-width: 0; display: block; }
.fm-tabelle--aufstellung thead { display: none; }
.fm-tabelle--aufstellung tbody { display: block; }
.fm-tabelle--aufstellung tr {
  display: block;
  padding: var(--ab-s) var(--ab-s) var(--ab-xs);
  border-top: 1px solid var(--rahmen);
}
.fm-tabelle--aufstellung tbody tr:first-child { border-top: 0; }
.fm-tabelle--aufstellung td {
  display: block;
  width: auto;
  padding: 0 0 var(--ab-2xs);
  border: 0;
}
.fm-tabelle--aufstellung td:empty { display: none; }
/* Beschriftung, die in der Tabellenansicht der Spaltenkopf wäre */
.fm-tabelle--aufstellung td[data-vor]::before {
  content: attr(data-vor) ': ';
  font-size: var(--gr--1);
  font-weight: 600;
  color: var(--text-fein);
}
.fm-tabelle--aufstellung td[data-vor='Position'] {
  text-align: left;
  font-family: var(--schrift-ueberschrift);
  font-weight: 700;
  color: var(--akzent-text);
}
.fm-aufstellung__titel {
  display: block;
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-0);
  font-weight: 600;
  margin-bottom: 0.3rem;
}
.fm-aufstellung__liste {
  margin: 0;
  padding-left: 1.1rem;
  font-size: var(--gr--1);
  color: var(--text-neben);
}
.fm-aufstellung__liste li + li { margin-top: 0.15rem; }

/* ---------------------------------------------------------- Großes Profil */

/*
   Gründerprofil auf „Über uns". Größer als .fm-gruender auf der Startseite:
   Bild links, Text rechts, mit Aufgabenliste. Unter 600px steht das Bild oben.
*/
.fm-profil {
  display: grid;
  gap: var(--ab-m);
  align-items: start;
}
.fm-profil__bild {
  width: 100%;
  max-width: 15rem;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: var(--rund-l);
  border: 1px solid var(--rahmen);
}
.fm-profil__name {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr-3);
  font-weight: 700;
  line-height: 1.1;
}
.fm-profil__rolle {
  font-size: var(--gr-0);
  font-weight: 600;
  color: var(--akzent-text);
}

/* ------------------------------------------------------------ Filterleiste */

.fm-filter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ab-2xs);
  align-items: center;
}
.fm-filter__knopf {
  /* inline-flex und nowrap, sonst rutscht das Icon auf eine eigene Zeile und der
     Knopf ist doppelt so hoch wie die daneben. */
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  white-space: nowrap;
  min-height: 44px;   /* Projektziel für Klickflächen, siehe Abschnitt 10c */
  padding: 0.5rem 1.05rem;
  border: 1px solid var(--rahmen-stark);
  border-radius: var(--rund-voll);
  background: transparent;
  font-family: var(--schrift-text);
  font-size: var(--gr--1);
  font-weight: 600;
  color: var(--text-neben);
  cursor: pointer;
  transition: background-color var(--zeit-kurz) var(--kurve),
              border-color var(--zeit-kurz) var(--kurve),
              color var(--zeit-kurz) var(--kurve);
}
.fm-filter__knopf:hover {
  border-color: var(--akzent-voll);
  color: var(--akzent-text);
}
.fm-filter__knopf[aria-pressed='true'] {
  background: var(--akzent-voll);
  border-color: var(--akzent-voll);
  color: #FFFFFF;
}
/* Im Dunkelmodus ist die Fläche das helle Cyan, dort muss die Schrift dunkel sein. */
[data-theme='dark'] .fm-filter__knopf[aria-pressed='true'] {
  color: var(--marke-dunkelblau);
}
/* Auf dem Handy eine eigene Zeile unter den Knöpfen, ab 900px rechts daneben.
   Siehe Abschnitt 11. */
.fm-filter__anzahl {
  flex-basis: 100%;
  font-size: var(--gr--1);
  color: var(--text-fein);
}


/* =============================================================================
   10c  RECHTSSEITEN

   AGB, Datenschutz, Impressum. Drei Seiten, die niemand freiwillig liest und
   die deshalb umso leichter benutzbar sein müssen: kurze Zeilen, sichtbare
   Gliederung, ein Verzeichnis, das ab 1100 Pixel mitläuft.

   Die zugehörigen Umbrüche stehen in Abschnitt 11.
   ========================================================================== */

.fm-recht {
  display: grid;
  gap: var(--ab-l);
  grid-template-columns: 1fr;
}

/* -------------------------------------------------------- Inhaltsverzeichnis */

.fm-recht__verzeichnis {
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-m);
  background: var(--bg-karte);
  padding: var(--ab-s);
}
.fm-recht__verzeichnis-titel {
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr--1);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-fein);
  margin-bottom: var(--ab-xs);
}
.fm-recht__verzeichnis-liste {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--ab-3xs);
  font-size: var(--gr--1);
}
.fm-recht__verzeichnis-liste a {
  display: block;
  padding: 0.35rem 0.5rem;
  border-radius: var(--rund-s);
  color: var(--text-neben);
  text-decoration: none;
  line-height: 1.35;
}
.fm-recht__verzeichnis-liste a:hover,
.fm-recht__verzeichnis-liste a:focus-visible {
  background: var(--bg-abgesetzt);
  color: var(--akzent-text);
}
/*
   Die Gruppenzeile ist eine reine Sehhilfe. Für Screenreader ist sie
   ausgeblendet, weil die Gruppe im Text selbst als Überschrift vorkommt und
   eine zweite Nennung im Verzeichnis nur Lärm wäre.
*/
.fm-recht__verzeichnis-gruppe {
  margin-top: var(--ab-xs);
  padding: 0 0.5rem;
  font-family: var(--schrift-ueberschrift);
  font-size: var(--gr--1);
  font-weight: 600;
  color: var(--text-fein);
}
.fm-recht__verzeichnis-gruppe:first-child { margin-top: 0; }

/* -------------------------------------------------------------------- Inhalt */

.fm-recht__inhalt {
  display: flex;
  flex-direction: column;
  gap: var(--ab-l);
  min-width: 0;
}

.fm-recht__gruppe {
  border-top: 2px solid var(--akzent-voll);
  padding-top: var(--ab-m);
  margin-top: var(--ab-m);
}
.fm-recht__inhalt > .fm-recht__gruppe:first-child { margin-top: 0; }
.fm-recht__gruppe-titel { font-size: var(--gr-3); }
.fm-recht__gruppe-text {
  margin-top: var(--ab-2xs);
  max-width: var(--breite-text);
  color: var(--text-neben);
}

.fm-recht__abschnitt { scroll-margin-top: calc(var(--kopf-hoehe) + var(--ab-l)); }
.fm-recht__titel {
  font-size: var(--gr-1);
  margin-bottom: var(--ab-2xs);
}

/*
   Der Einstiegssatz ist die Übersetzung des Paragrafen in Alltagssprache.
   Er steht optisch abgesetzt, damit niemand ihn für den Rechtstext hält.
*/
.fm-recht__einstieg {
  border-left: 3px solid var(--akzent-voll);
  padding-left: var(--ab-xs);
  margin-bottom: var(--ab-s);
  max-width: var(--breite-text);
  color: var(--text-neben);
  font-size: var(--gr-0);
}

.fm-recht__text {
  display: flex;
  flex-direction: column;
  gap: var(--ab-xs);
  max-width: var(--breite-text);
}
.fm-recht__text p { line-height: 1.65; }

.fm-recht__liste {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: var(--ab-2xs);
}
.fm-recht__liste li {
  position: relative;
  padding-left: 1.35rem;
  line-height: 1.6;
}
.fm-recht__liste li::before {
  content: '';
  position: absolute;
  left: 0.25rem;
  top: 0.65em;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--akzent-voll);
}

/*
   Merkmal und Wert je Verarbeitung: Zweck, Rechtsgrundlage, Empfänger, Dauer.

   Das Merkmal bekommt eine feste Spalte, damit die vier Begriffe über alle
   Abschnitte hinweg untereinander stehen und der Leser die Zeile findet, die
   ihn interessiert, ohne zu lesen. minmax(0, 1fr) für den Wert, sonst sprengt
   eine lange Rechtsgrundlage die Spalte nach rechts.

   Unter 620 Pixeln stapelt das Paar. Der Boden von 7.5rem für das Merkmal ist
   die Breite von "Rechtsgrundlage", dem längsten der vier Begriffe.
*/
.fm-recht__merkmale {
  display: flex;
  flex-direction: column;
  gap: 1px;
  border: 1px solid var(--rahmen);
  border-radius: var(--rund-m);
  background: var(--rahmen);
  overflow: hidden;
}
.fm-recht__merkmal {
  display: grid;
  gap: 0.15rem;
  padding: 0.7rem var(--ab-s);
  background: var(--bg-karte);
}
.fm-recht__merkmal dt {
  font-weight: 600;
  /* --text-neben, nicht --text-fein: dieselbe Rolle wie .fm-baum__rolle, ein
     ruhigeres Etikett, das trotzdem voll lesbar bleibt. --text-fein ist für
     Feldhinweise und wäre hier zu leise. */
  color: var(--text-neben);
  font-size: 0.9rem;
}
.fm-recht__merkmal dd { line-height: 1.6; }

@media (min-width: 620px) {
  .fm-recht__merkmal {
    grid-template-columns: 7.5rem minmax(0, 1fr);
    gap: var(--ab-xs);
    align-items: baseline;
  }
  .fm-recht__merkmal dt { font-size: 1rem; }
}

/* Hervorgehobener Kasten innerhalb eines Paragrafen */
.fm-recht__hinweis,
.fm-recht__vorspann {
  display: flex;
  gap: var(--ab-xs);
  align-items: flex-start;
  border: 1px solid color-mix(in srgb, var(--akzent-voll) 35%, var(--rahmen));
  border-radius: var(--rund-m);
  background: color-mix(in srgb, var(--akzent-voll) 6%, var(--bg-karte));
  padding: var(--ab-s);
}
.fm-recht__hinweis .fm-icon,
.fm-recht__vorspann .fm-icon {
  flex: none;
  margin-top: 0.15em;
  color: var(--akzent-text);
}
.fm-recht__hinweis p { line-height: 1.6; }

/* Der Kasten über dem Verzeichnis, z. B. der Hinweis zur anwaltlichen Prüfung */
.fm-recht__vorspann {
  max-width: var(--breite-inhalt);
  margin-bottom: var(--ab-m);
}
.fm-recht__vorspann-titel {
  font-family: var(--schrift-ueberschrift);
  font-weight: 600;
  margin-bottom: 0.2rem;
}

/*
   Tabellen in Rechtstexten stapeln unter 900 Pixel, sonst stehen dort drei
   Spalten à sechs Zeichen. Oberhalb bleiben sie echte Tabellen.
   Die Rollen im HTML sind kein Zierrat: display:block löscht die
   Tabellensemantik, und ohne sie liest ein Screenreader nur eine Textwüste.
*/
.fm-tabelle--gestapelt { min-width: 0; display: block; }
.fm-tabelle--gestapelt thead { display: none; }
.fm-tabelle--gestapelt tbody { display: block; }
.fm-tabelle--gestapelt tr {
  display: block;
  border-top: 1px solid var(--rahmen);
  padding: var(--ab-xs) 0;
}
.fm-tabelle--gestapelt tbody tr:first-child { border-top: 0; }
.fm-tabelle--gestapelt tbody tr:hover { background: transparent; }
.fm-tabelle--gestapelt td {
  display: block;
  border: 0;
  padding: 0.15rem 0;
}
.fm-tabelle--gestapelt td[data-vor]::before {
  content: attr(data-vor) ': ';
  font-weight: 600;
  color: var(--text-fein);
}


/* =============================================================================
   11  BILDSCHIRMBREITEN
   Vier Stufen, von schmal nach breit. Mehrspaltige Bereiche brechen gleichmäßig
   um: 1, dann 2, dann 3 oder 4. Nie 3+1, nie 4+1.

   NEUE REGELN GEHÖREN OBERHALB DIESES BLOCKS.
   ========================================================================== */

/* ---------------------------------------------------- ab 600px (großes Handy) */
@media (min-width: 600px) {
  :root { --rand: var(--ab-m); }

  .fm-raster[data-spalten='2'],
  .fm-raster[data-spalten='4'],
  .fm-raster[data-spalten='6'] { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .fm-fuss__raster { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fm-schau__bild { flex-basis: 100%; }

  /* Die Zweispaltenregel für .fm-daten__zeile stand bis zum 03.08.2026 HIER,
     also am Fenster. Das war der Fehler: Auf /ki-pipelines liegen fm-daten
     in halbbreiten Karten, und bei 600 Pixeln Fensterbreite ist so eine Karte
     nur 208 Pixel breit. Das Etikett behielt seinen 8.5rem-Boden, der Wert
     bekam die restlichen 14 Pixel und stand mit einem Buchstaben je Zeile da,
     gemessen bis zu 92 Zeilen hoch. Eine Überlaufprüfung findet das nie, die
     Seite läuft nirgends über. Die Regel schaltet jetzt nach der Breite des
     Behälters, siehe die @container-Regel bei .fm-daten. */

  /* Gründerprofil: Bild links, Text rechts.

     Zwei Fehler stecken in dieser einen Zeile, beide nacheinander behoben.

     Erst stand hier `15rem 1fr`. Eine feste Spaltenbreite schrumpft nicht, und
     die Kontaktseite ragte dadurch bei 600 Pixeln um 155 Pixel heraus.

     Dann stand hier `minmax(0, 15rem) 1fr`. Der Überlauf war weg, aber dafür
     brach die Textspalte zusammen: auf /kontakt stehen zwei Profile
     nebeneinander, jede Karte hat dort bei 744 Punkten nur etwa 288 Punkte,
     das Bild nimmt sich davon 15rem, und für den Text blieben rund 24 Punkte.
     Zusammen mit `overflow-wrap: anywhere` auf dem Namen stand „Finn Mattes
     Leßmann" dann senkrecht, ein Buchstabe je Zeile. Gefunden auf einem
     echten iPad mini, nicht in der Breitenprüfung: die misst Überlauf, und
     ein zusammengefallener Text ragt nirgends heraus.

     Jetzt hat die TEXTSPALTE den festen Boden und das BILD gibt nach. Grid
     verteilt den Platz zuerst an die Mindestbreiten, und weil die Bildspalte
     als Mindestmaß 0 hat, schrumpft sie, statt den Text zu erdrücken. Beide
     Fehler sind damit ausgeschlossen: nichts ragt heraus, nichts fällt
     zusammen. */
  .fm-profil { grid-template-columns: minmax(0, 15rem) minmax(11rem, 1fr); }

  /* Anteil links, Beschreibung rechts. */
}

/* ---------------------------------------------------- ab 900px (Tablet) */
@media (min-width: 900px) {

  /* Markenbaum: zwei Äste nebeneinander, verbunden über eine waagerechte
     Linie. Sie beginnt und endet in der Mitte des jeweiligen Astes, damit die
     senkrechten Abzweige genau darauf treffen.

     Der Weg von oben nach unten, drei Strecken, die sich berühren müssen:

       Wurzel  ──┐  Stamm,    .fm-baum__wurzel::after,  Höhe --ab-m
                 │
         ┌───────┴───────┐   Querlinie, .fm-baum__aeste::before
         │               │
         ▼               ▼   Abzweige,  .fm-baum__ast::before,  Höhe --ab-m
       Karte           Karte

     Die Querlinie sitzt deshalb eine --ab-m ÜBER der Kartenoberkante, nicht
     darauf. Stand sie darauf, liefen die Abzweige von der Karte nach oben und
     zeigten ins Leere, statt von der Linie nach unten auf die Karte. */
  .fm-baum__aeste {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    /* Doppelter Abstand: hier liegen Stamm UND Abzweige übereinander, in der
       gestapelten Ansicht nur der Stamm. Bis zum 05.08.2026 galt überall der
       einfache Abstand; die Querlinie lag dadurch auf der Kartenoberkante und
       die Abzweige liefen von dort nach OBEN ins Leere neben dem Stamm.
       Gemessen bei 1280 Pixeln: Querlinie auf y=7289, Abzweige von 7290 hinauf
       bis 7263, während die Karten bei 7290 begannen. */
    margin-top: calc(var(--ab-m) * 2);
  }
  .fm-baum__aeste::before {
    content: '';
    position: absolute;
    bottom: calc(100% + var(--ab-m));
    /* Nicht 25 Prozent, sondern 25 Prozent minus ein Viertel des
       Spaltenabstands. Grund: bei zwei gleich breiten Spalten mit Abstand g
       liegt die Mitte einer Spalte nicht bei 25 Prozent, sondern um g/4 weiter
       innen. Gemessen bei 1280 Pixeln: Astmitten bei 353 und 927, die
       25-Prozent-Marken bei 360 und 920, also 7 Pixel daneben bei einem
       Spaltenabstand von 27,36 Pixeln. Ohne diese Korrektur enden die
       senkrechten Stummel neben der waagerechten Linie statt darauf. */
    left: calc(25% - var(--ab-m) / 4);
    right: calc(25% - var(--ab-m) / 4);
    height: 2px;
    background: var(--rahmen-stark);
  }
  /* Abzweige: von der Querlinie nach unten auf jede Karte. Die drei
     zusätzlichen Pixel aus demselben Grund wie beim Stamm, siehe dort. */
  .fm-baum__ast::before,
  .fm-baum__ast + .fm-baum__ast::before {
    content: '';
    position: absolute;
    bottom: 100%;
    left: 50%;
    width: 2px;
    height: calc(var(--ab-m) + 3px);
    background: var(--rahmen-stark);
    transform: translateX(-50%);
  }
  :root { --kopf-hoehe: 72px; --rand: var(--ab-l); }

  .fm-raster[data-spalten='3'],
  .fm-raster[data-spalten='6'] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .fm-raster[data-spalten='4'] { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .fm-zweispalt { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fm-zweispalt--text-breit { grid-template-columns: 1.15fr 0.85fr; }
  .fm-zweispalt--bild-breit { grid-template-columns: 0.85fr 1.15fr; }

  .fm-fuss__raster { grid-template-columns: 1.4fr 1fr 1fr 1fr; }

  /* Hero: Text links, Foto rechts. Ab hier passt das Querformat. */
  .fm-hero__oben { grid-template-columns: 1.05fr 0.95fr; }
  /* Die Logokacheln brauchen die ganze Breite, damit sie in eine Reihe passen.
     Der Zähler steht deshalb darüber und nicht daneben. */
  .fm-hero__zaehler { flex-direction: row; align-items: baseline; gap: 0.6rem; }

  /*
     Referenzen: das Bild bekommt die breitere Spalte, der Text die schmalere.
     Bei jedem zweiten Block werden die Seiten getauscht. Dafür genügt es NICHT,
     nur die Reihenfolge zu ändern — dann läge der Text in der breiten Spalte.
     Die Spaltenbreiten müssen mitgetauscht werden.
  */
  .fm-referenz { grid-template-columns: 0.82fr 1.18fr; gap: var(--ab-l); }
  .fm-referenz--gespiegelt { grid-template-columns: 1.18fr 0.82fr; }
  .fm-referenz--gespiegelt .fm-referenz__text { order: 2; }

  .fm-meilensteine { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* Kennzahlen links, Countdown rechts. Ist nur eines von beiden da, füllt es
     die erste Spalte und die zweite bleibt ohne Breite. */
  .fm-belege { grid-template-columns: 1fr auto; gap: var(--ab-l); }

  /*
     Ab hier ist die Leistungsaufstellung wieder eine echte Tabelle. Feste
     Spaltenbreiten, sonst verteilt der Browser die Breite nach Textmenge und die
     Positionsspalte wird so breit wie die Leistungsspalte.
  */
  .fm-tabelle--aufstellung { display: table; table-layout: fixed; }
  .fm-tabelle--aufstellung thead { display: table-header-group; }
  .fm-tabelle--aufstellung tbody { display: table-row-group; }
  .fm-tabelle--aufstellung tr { display: table-row; padding: 0; border-top: 0; }
  .fm-tabelle--aufstellung td {
    display: table-cell;
    padding: var(--ab-xs) var(--ab-s);
    border-bottom: 1px solid var(--rahmen);
  }
  .fm-tabelle--aufstellung td:empty { display: table-cell; }
  /* Ab 900 Pixel sind wieder echte Tabellen möglich, die Stapelung entfällt. */
  .fm-tabelle--gestapelt { display: table; }
  .fm-tabelle--gestapelt thead { display: table-header-group; }
  .fm-tabelle--gestapelt tbody { display: table-row-group; }
  .fm-tabelle--gestapelt tr { display: table-row; border-top: 0; padding: 0; }
  .fm-tabelle--gestapelt td {
    display: table-cell;
    border-bottom: 1px solid var(--rahmen);
    padding: var(--ab-xs) var(--ab-s);
  }
  .fm-tabelle--gestapelt td[data-vor]::before { content: none; }
  .fm-tabelle--gestapelt tbody tr:hover { background: var(--bg-abgesetzt); }

  .fm-tabelle--aufstellung td[data-vor]::before { content: none; }
  .fm-tabelle--aufstellung td[data-vor='Position'] {
    text-align: right;
    font-family: var(--schrift-text);
    font-weight: 400;
    color: var(--text);
  }
  .fm-tabelle--aufstellung th:first-child,
  .fm-tabelle--aufstellung td:first-child { width: 4.5rem; }
  .fm-tabelle--aufstellung th:last-child,
  .fm-tabelle--aufstellung td:last-child { width: 13rem; }

  /* Zurück, Übersicht, Weiter in einer Reihe. Die Mitte darf schmaler sein. */
  .fm-blaettern { grid-template-columns: 1fr 0.8fr 1fr; }

  /* Ab hier passen alle Filterknöpfe in eine Reihe, die Zahl darf rechts daneben. */
  .fm-filter__anzahl { flex-basis: auto; margin-left: auto; }

  /*
     Ab 900 Pixel das gezeichnete Diagramm statt der Liste. Die Liste bleibt für
     Screenreader im Dokument, wird aber optisch entfernt. Kein display:none,
     sonst wäre sie auch für Hilfsmittel weg.
  */
  /* Begrenzt, weil das Diagramm für 900 Pixel gezeichnet ist. Ohne Deckel würde
     die Schrift auf großen Schirmen mitwachsen und größer als die Fließtexte. */
  .fm-pipeline__bild {
    display: block;
    width: 100%;
    max-width: 64rem;
    height: auto;
    margin-inline: auto;
  }
  .fm-pipeline__liste {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }


  /* Zeitleiste: Jahr in eigener Spalte links, damit die Jahre untereinander
     stehen und der Strang lesbar bleibt. */
  .fm-zeitleiste__punkt {
    grid-template-columns: 5.5rem 1fr;
    padding-left: var(--ab-l);
  }
  .fm-zeitleiste__jahr { grid-row: 1 / span 3; padding-top: 0.15rem; }
}

/* ---------------------------------------------------- ab 1100px (Notebook) */
@media (min-width: 1100px) {
  /* Ab hier passt die Navigation waagerecht, die Menütafel wird nicht gebraucht */
  .fm-kopf__nav { display: flex; align-items: center; gap: 2px; }
  .fm-menue-knopf { display: none; }

  .fm-raster[data-spalten='4'] { grid-template-columns: repeat(4, minmax(0, 1fr)); }

  .fm-kennzahl__wert { font-size: var(--gr-3); }

  .fm-meilensteine { grid-template-columns: repeat(4, minmax(0, 1fr)); }

  /*
     Rechtsseiten: erst ab hier steht das Verzeichnis neben dem Text und läuft
     beim Blättern mit. Darunter wäre die Spalte zu schmal, dann steht es als
     ganz normaler Kasten über dem Text.
  */
  .fm-recht { grid-template-columns: 17rem minmax(0, 1fr); gap: var(--ab-xl); }
  /* Ohne align-self zieht das Raster den Kasten auf die volle Zeilenhöhe, und
     der Rahmen läuft dann bis ans Ende des Textes. */
  .fm-recht__verzeichnis {
    align-self: start;
    position: sticky;
    top: calc(var(--kopf-hoehe) + var(--ab-s));
    max-height: calc(100vh - var(--kopf-hoehe) - var(--ab-l));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
}

/* ---------------------------------------------------- ab 1440px (großer Schirm) */
@media (min-width: 1440px) {
  :root { --breite-inhalt: 1240px; }
}

/* ---------------------------------------------------- sehr schmal (unter 360px) */
@media (max-width: 359px) {
  :root { --rand: var(--ab-xs); }
  .fm-knopf { padding-inline: 1rem; }
  .fm-countdown__teil { min-width: 3.1rem; }
}

/* ---------------------------------------------------- Zeiger ohne Feinsteuerung */
/* Auf Touchgeräten keine Hover- und Kipp-Effekte, die dort hängen bleiben */
@media (hover: none) {
  .fm-karte--hebt:hover { transform: none; box-shadow: var(--schatten-s); }
  .fm-aura:hover::before { opacity: 0; }
  .fm-nav__gruppe:hover > .fm-nav__klappe { opacity: 0; visibility: hidden; }
}
