@font-face {
    font-family: "Inter";
    font-weight: 200;
    src:
        local("Inter"),
        url("../../files/fonts/Inter-ExtraLight.ttf") format("truetype");
}

@font-face {
    font-family: "Inter";
    font-weight: 400;
    src:
        local("Inter"),
        url("../../files/fonts/Inter-Regular.ttf") format("truetype");
}

@font-face {
    font-family: "Inter";
    font-weight: 900;
    src:
        local("Inter"),
        url("../../files/fonts/Inter-Black.ttf") format("truetype");
}
/* ==========================================================================
   VISIONARY Berlin – Design Tokens
   --------------------------------------------------------------------------
   Diese Datei enthaelt ausschliesslich Custom Properties und deren
   Registrierung. Kein Selektor ausser :root. Wer das Layout global
   aendern will, aendert es hier.

   Einbindung im Seitenlayout VOR style.css:
   fonts.css, tokens.css, style.css
   ========================================================================== */


/* ==========================================================================
   ELEMENTLOKALE EIGENSCHAFTEN
   --------------------------------------------------------------------------
   Custom Properties werden standardmaessig vererbt. Ohne diese
   Registrierung reicht ein --flow von einem Artikel bis in jede einzelne
   Kachel hinunter und setzt dort ungewollt Abstaende.

   inherits: false macht sie elementlokal.
   syntax: "*" ohne initial-value sorgt dafuer, dass var(--flow, X)
   weiterhin auf X zurueckfaellt, wenn nichts gesetzt ist.
   ========================================================================== */

@property --flow {
   syntax: "*";
   inherits: false;
}

@property --flow-end {
   syntax: "*";
   inherits: false;
}

@property --span {
   syntax: "*";
   inherits: false;
}

@property --span-h {
   syntax: "*";
   inherits: false;
}

@property --start {
   syntax: "*";
   inherits: false;
}

@property --cols {
   syntax: "*";
   inherits: false;
}

@property --tile-ratio {
   syntax: "*";
   inherits: false;
}

/* ==========================================================================
   REGISTRIERTE PROPERTIES
   --------------------------------------------------------------------------
   Custom Properties vererben sich standardmaessig. Fuer Steuer-Properties
   ist das falsch: setzt man --flow auf einem Artikel, erbt es jede Kachel
   darin und der Fallback in var(--flow, 0) greift nie mehr.

   inherits: false stoppt das. Ohne initial-value bleibt der Wert die
   "guaranteed-invalid value", solange niemand ihn setzt, deshalb
   funktionieren die Fallbacks in var() weiterhin wie gewohnt.

   Gilt nur fuer Properties, die ein Element fuer sich selbst setzt.
   Die Design-Tokens in :root sollen vererben und bleiben unregistriert.
   ========================================================================== */

@property --flow {
   syntax: "*";
   inherits: false;
}

@property --flow-end {
   syntax: "*";
   inherits: false;
}

@property --span {
   syntax: "*";
   inherits: false;
}

@property --span-h {
   syntax: "*";
   inherits: false;
}

@property --start {
   syntax: "*";
   inherits: false;
}

@property --cols {
   syntax: "*";
   inherits: false;
}

@property --tile-ratio {
   syntax: "*";
   inherits: false;
}


:root {

   /* ---------------------------------------------------------------
       FARBEN
       --------------------------------------------------------------- */

   --c-bg: #000;
   --c-fg: #fff;

   /* Abgestufte Textfarben statt opacity. opacity vererbt sich auf
       Kindelemente und macht Kontrastpruefungen unmoeglich. */
   --c-fg-muted: rgb(255 255 255 / 0.70);
   /* Footer, Meta, Captions */

   /* Heller Bereich, z. B. der Team-Block auf About */
   --c-surface: #fff;
   --c-on-surface: #000;

   --c-header-scrim: linear-gradient(180deg,
         rgb(0 0 0 / 0.55) 0%,
         rgb(0 0 0 / 0) 100%);

   --c-focus: #fff;


   /* ---------------------------------------------------------------
       SCHRIFT
       ---------------------------------------------------------------
       Alle Groessen fluid per clamp(). Referenzpunkte: 375px und 1920px
       Viewport. Dazwischen wird linear interpoliert, deshalb gibt es
       keine Typo-Breakpoints mehr.
       1rem = 16px (Browser-Default, nicht body-font-size).
       --------------------------------------------------------------- */

   --font-body: "Inter", "Helvetica Neue", Helvetica, Arial, sans-serif;

   /* Inter liefert aktuell nur 200 / 400 / 900.
       --fw-bold zeigt bewusst auf 900, damit der Browser kein
       Fake-Bold aus 400 synthetisiert. Sobald 700 als woff2 vorliegt,
       hier auf 700 umstellen. */
   --fw-light: 200;
   --fw-regular: 400;
   --fw-bold: 900;

   --fs-body: clamp(1.0625rem, 1.017rem + 0.19vw, 1.25rem);
   /*  17 →  20 */
   --fs-small: 0.8em;

   --fs-h1: clamp(3.125rem, 1.913rem + 5.18vw, 8.125rem);
   /*  50 → 130 */
   --fs-h2: clamp(2.5rem, 1.893rem + 2.59vw, 5rem);
   /*  40 →  80 */
   --fs-h3: clamp(1.875rem, 1.541rem + 1.42vw, 3.25rem);
   /*  30 →  52 */
   --fs-h4: clamp(1.25rem, 1.068rem + 0.78vw, 2rem);
   /*  20 →  32 */

   --fs-logo: clamp(1.875rem, 1.19rem + 2.92vw, 5rem);
   /*  30 →  80 */

   --lh-tight: 1;
   --lh-heading: 1.1;
   --lh-body: 1.5;

   /* Optischer Randausgleich fuer grosse Headlines. Relativ zur
       Schriftgroesse, skaliert deshalb automatisch mit. */
   --optical-align: -0.045em;


   /* ---------------------------------------------------------------
       ABSTAENDE
       ---------------------------------------------------------------
       Zwei getrennte Systeme:
       1. --space-*   fuer Abstaende INNERHALB von Bloecken
       2. --section-* fuer Abstaende ZWISCHEN inhaltlichen Gruppen
       --------------------------------------------------------------- */

   --space-2xs: 0.3125rem;
   /*  5px */
   --space-xs: 0.625rem;
   /* 10px */
   --space-s: 1.25rem;
   /* 20px */
   --space-m: 2.5rem;
   /* 40px */
   --space-l: 5rem;
   /* 80px */

   /* Aussenabstand zum Viewportrand und Grid-Gap. 20px → 40px */
   --gutter: clamp(1.25rem, 0.732rem + 2.21vw, 2.5rem);

   /* Sektionsabstand: 80px bei 640px Viewport, 320px ab 1920px.
       Das ist der Hauptregler fuer den vertikalen Rhythmus. */
   --section: clamp(5rem, -2.5rem + 18.75vw, 20rem);
   /*  80 → 320 */
   --section-m: calc(var(--section) * 0.5);
   /*  40 → 160 */
   --section-s: calc(var(--section) * 0.25);
   /*  20 →  80 */


   /* ---------------------------------------------------------------
       LAYOUT
       --------------------------------------------------------------- */

   --container: 120rem;
   /* 1920px */

   /* Lesebreite. 45rem entspricht bei 20px Schrift etwa 70 Zeichen
       pro Zeile und liegt damit im komfortablen Bereich. 960px waeren
       zwar exakt span-3 des Rasters, aber rund 95 Zeichen und damit
       zu lang fuer Fliesstext. Das Raster regelt Layout, die Lesebreite
       regelt Typografie. Die beiden muessen nicht dasselbe Mass haben. */
   --measure: 45rem;
   /*  720px, Impressum, Datenschutz, About */
   --measure-wide: 60rem;
   /*  960px, entspricht span-3 im Raster   */

   /* Hoehe des Headers im kompakten Zustand. Wird als Offset fuer
       Seiten ohne Hero und fuer Sprungmarken benutzt. */
   --header-h: clamp(4rem, 2rem + 4vw, 6.5rem);
   /*  64 → 104 */

   --grid-cols: 6;
   /* Inhalts-Raster, mobil auf 1 gesetzt */
   --list-cols: 3;
   /* Projekt- und Terminliste */
   --client-cols: 6;
   /* Logowand */

   /* --cols wird hier bewusst NICHT gesetzt. Es ist der Uebersteuerungs-
       Haken: wer ein einzelnes Raster abweichend braucht, setzt --cols
       direkt am Element, z. B. style="--cols: 4". */


   /* ---------------------------------------------------------------
       FORM UND BEWEGUNG
       --------------------------------------------------------------- */

   --radius: 1.25rem;
   /* 20px */
   --radius-pill: 62.4375rem;
   --border-w: 2px;

   --dur: 0.25s;
   --dur-slow: 0.5s;
   --ease: cubic-bezier(0.4, 0, 0.2, 1);
   --ease-back: cubic-bezier(0.68, -0.6, 0.32, 1.6);


   /* ---------------------------------------------------------------
       EBENEN
       --------------------------------------------------------------- */

   --z-behind: -1;
   --z-overlay: 10;
   --z-header: 100;
}


/* Die Logowand geht in Stufen herunter, die volle Zeilen ergeben:
   6 / 4 / 3 / 2. Bei einer durch 12 teilbaren Zahl von Logos bleibt
   damit auf jeder Breite die letzte Zeile vollstaendig gefuellt. */

@media (max-width: 1200px) {
   :root {
      --list-cols: 2;
      --client-cols: 4;
   }
}

/* Ab hier wird das Inhaltsraster einspaltig. Zwei Breakpoints reichen,
   weil Typografie und Abstaende fluid sind. */
@media (max-width: 900px) {
   :root {
      --grid-cols: 1;
      --list-cols: 1;
      --client-cols: 3;
   }
}

@media (max-width: 520px) {
   :root {
      --client-cols: 2;
   }
}
/* ==========================================================================
   VISIONARY Berlin – Stylesheet
   --------------------------------------------------------------------------
   Aufbau:
     1  @layer reset
     2  @layer base        Typografie, Links, Medien, Fokus
     3  @layer layout      Seitengeruest, Artikel-Stack, Raster
     4  @layer components  Buttons, Formulare, Header, Navigation, Bild, Hero
     5  @layer modules     Contao-Module und Seitenbausteine
     6  @layer utilities   Steuerklassen fuer das Backend

   Benoetigt tokens.css. Reihenfolge im Seitenlayout:
     fonts.css, tokens.css, style.css

   Wichtig zum Verstaendnis: bei Cascade Layers gewinnt immer der spaetere
   Layer, unabhaengig von der Spezifitaet. Deshalb steht jede Regel dort,
   wo sie hingehoert, und Sonderfaelle stehen NACH ihrem Standardfall.
   ========================================================================== */

@layer reset, base, layout, components, modules, utilities;


/* ==========================================================================
   1  RESET
   ========================================================================== */

@layer reset {

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

    html {
        scroll-behavior: smooth;
        /* Sprungmarken landen nicht unter dem fixen Header */
        scroll-padding-top: calc(var(--header-h) + var(--space-s));
        -webkit-text-size-adjust: 100%;
    }

    body {
        margin: 0;
        /* clip statt hidden: erzeugt keinen Scroll-Container,
           position: sticky funktioniert weiterhin */
        overflow-x: clip;
    }

    img,
    video,
    figure {
        display: block;
        max-width: 100%;
    }

    /* svg bewusst NICHT auf display: block. Fremdplayer und Icon-Sets
       zentrieren ihre Grafiken haeufig ueber text-align, was mit einem
       Blockelement nicht mehr funktioniert. */
    svg {
        max-width: 100%;
    }

    img,
    video {
        height: auto;
    }

    figure {
        margin: 0;
    }

    /* Raster- und Flex-Kinder duerfen schrumpfen. Ohne diese Zeile ist
       min-content die Untergrenze und Layouts laufen aus dem Viewport. */
    :where(.grid, .layout_full, .mod_newslist, .clients)>* {
        min-width: 0;
    }

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

    ul,
    ol {
        padding-left: 1.2em;
    }
}


/* ==========================================================================
   2  BASE
   ========================================================================== */

@layer base {

    body {
        background-color: var(--c-bg);
        color: var(--c-fg);
        font-family: var(--font-body);
        font-size: var(--fs-body);
        font-weight: var(--fw-regular);
        line-height: var(--lh-body);
        -webkit-font-smoothing: antialiased;
    }

    /* --- Ueberschriften ------------------------------------------------- */

    h1,
    h2,
    h3,
    h4 {
        margin: 0 0 var(--space-m) 0;
        font-weight: var(--fw-bold);
        text-wrap: balance;
    }

    h1 {
        font-size: var(--fs-h1);
        line-height: var(--lh-tight);
        /* optischer Randausgleich, skaliert mit der Schriftgroesse */
        margin-left: var(--optical-align);
    }

    h2 {
        font-size: var(--fs-h2);
        line-height: var(--lh-tight);
    }

    h3 {
        font-size: var(--fs-h3);
        line-height: var(--lh-heading);
    }

    h4 {
        font-size: var(--fs-h4);
        line-height: var(--lh-heading);
        margin-bottom: var(--space-s);
    }

    /* --- Fliesstext ----------------------------------------------------- */

    p {
        margin: 0 0 var(--space-s) 0;
        text-wrap: pretty;
    }

    li {
        margin: 0 0 var(--space-s) 0;
    }

    .rte> :last-child,
    .content-text> :last-child {
        margin-bottom: 0;
    }

    /* Kursiv wird in dieser Marke als Extra Light gesetzt.
       :not([class]) schuetzt Icon-Elemente wie <em class="fa-solid">. */
    .rte em:not([class]) {
        font-style: normal;
        font-weight: var(--fw-light);
    }

    strong {
        font-weight: var(--fw-bold);
    }

    a {
        color: inherit;
    }

    /* --- Fokus ---------------------------------------------------------- */

    :focus-visible {
        outline: var(--border-w) solid var(--c-focus);
        outline-offset: 3px;
        border-radius: 2px;
    }

    /* Screenreader-only. Contao vergibt diese Klasse an die Sprunglinks. */
    .invisible {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    .invisible:focus-visible {
        position: static;
        width: auto;
        height: auto;
        margin: 0;
        padding: var(--space-xs) var(--space-s);
        clip-path: none;
        background: var(--c-fg);
        color: var(--c-bg);
    }

    video::-webkit-media-controls {
        display: none;
    }
}


/* ==========================================================================
   3  LAYOUT
   ========================================================================== */

@layer layout {

    /* --- Artikel-Stack ---------------------------------------------------
       :where(#hero) statt #hero. :where() traegt nichts zur Spezifitaet
       bei, deshalb bleibt dieser Selektor bei (0,1,0) und wird von
       .grid nicht mehr ueberstimmt.
       -------------------------------------------------------------------- */

    .mod_article:not(:where(#hero)) {
        display: flex;
        flex-direction: column;
        width: min(100% - 2 * var(--gutter), var(--container));
        margin-inline: auto;
        /* var()-Fallbacks statt fester Werte: dadurch wirken die
           flow- und pad-Klassen auch auf dem Artikel selbst. */
        margin-block: var(--flow, var(--section)) var(--flow-end, var(--section));
    }

    /* Erster Artikel einer Seite haelt Abstand zum fixen Header,
       ebenfalls uebersteuerbar. */
    :where(#main > .inside)>.mod_article:not(:where(#hero)):first-child {
        margin-block-start: var(--flow, calc(var(--header-h) + var(--section-m)));
    }

    /* --- Vertikaler Rhythmus im Stack ------------------------------------
       Der Abstand liegt am Kind, nicht am Container. Dadurch ist jeder
       einzelne Abstand ueber --flow steuerbar.
       .grid ist ausgenommen, dort regelt gap den Grundabstand.
       -------------------------------------------------------------------- */

    .mod_article:not(:where(#hero, .grid))>*+* {
        margin-block-start: var(--flow, var(--section));
    }

    .content-text {
        width: 100%;
        margin-inline: auto;
    }

    /* --- Raster ----------------------------------------------------------
       Ein Regelwerk fuer alle Rasterkontexte. Die Kinder steuern ihre
       Lage ueber --span, --start und --span-h.
       -------------------------------------------------------------------- */

    .grid,
    .layout_full {
        display: grid;
        grid-template-columns: repeat(var(--cols, var(--grid-cols)), minmax(0, 1fr));
        gap: var(--gutter);
    }

    :where(.grid, .layout_full, .mod_newslist)>* {
        grid-column: var(--start, auto) / span var(--span, 1);
        grid-row: span var(--span-h, 1);
    }

    /* Rueckfallebene zur @property-Registrierung in tokens.css, fuer
       Browser ohne deren Unterstuetzung. Stellt sicher, dass ein --flow
       vom Artikel nicht in dessen Kinder durchschlaegt. Steht im
       layout-Layer, die flow-Klassen im utilities-Layer, dadurch
       gewinnen die Klassen immer. */
    .mod_article>*,
    :where(.grid, .layout_full, .mod_newslist)>* {
        --flow: initial;
        --flow-end: initial;
    }

    /* Zaesur innerhalb eines Rasters. Standardabstand ist der Gutter,
       eine flow- oder pad-Klasse hebt einzelne Zeilen heraus. Dieselben
       Klassen wirken im Stack und im Raster identisch. */
    :where(.grid, .layout_full, .mod_newslist)>* {
        margin-block-start: var(--flow, 0);
        margin-block-end: var(--flow-end, 0);
    }

    /* Ueberschriften spannen immer ueber die volle Breite, egal wie viele
       Spalten das Raster gerade hat. Bricht in keinem Breakpoint. */
    :where(.grid, .mod_newslist, .clients)> :is(h1, h2, h3, h4) {
        grid-column: 1 / -1;
        text-align: center;
        margin-bottom: var(--space-l);
    }

    .grid>.content-text {
        align-self: center;
    }

    /* --- Full Bleed ------------------------------------------------------
       Bricht aus dem zentrierten Container aus. Ein Ueberhang durch die
       Scrollbar wird von body { overflow-x: clip } gefangen.
       -------------------------------------------------------------------- */

    .full-bleed {
        width: 100vw;
        margin-inline: calc(50% - 50vw);
    }
}


/* ==========================================================================
   4  COMPONENTS
   ========================================================================== */

@layer components {

    /* --- Buttons ---------------------------------------------------------
       Icons liegen im Markup als <em class="fa-..."> vor dem Text.
       -------------------------------------------------------------------- */

    .primaryButton,
    .secondaryButton,
    button {
        display: inline-block;
        padding: 0.75em 1.25em;
        border: var(--border-w) solid var(--c-fg);
        border-radius: var(--radius-pill);
        font-size: 1rem;
        font-weight: var(--fw-bold);
        line-height: 1.2;
        text-decoration: none;
        cursor: pointer;
        transition:
            background-color var(--dur) var(--ease),
            color var(--dur) var(--ease);
    }

    .secondaryButton,
    button {
        background: transparent;
        color: var(--c-fg);
    }

    .primaryButton {
        background-color: var(--c-fg);
        color: var(--c-bg);
    }

    .secondaryButton:hover,
    button:hover {
        background-color: var(--c-fg);
        color: var(--c-bg);
    }

    .primaryButton:hover {
        background-color: transparent;
        color: var(--c-fg);
    }

    :is(.primaryButton, .secondaryButton)> :is(em, i) {
        display: inline-block;
        margin-right: 0.5em;
        color: inherit;
        transition: transform var(--dur) var(--ease);
    }

    :is(.primaryButton, .secondaryButton):hover> :is(em, i) {
        transform: translateX(0.25em);
    }

    .secondaryButton+.primaryButton {
        margin-left: var(--space-s);
    }

    /* --- Formulare -------------------------------------------------------- */

    input[type="text"],
    input[type="email"] {
        width: 100%;
        padding: 0.85em 1em;
        border: var(--border-w) solid transparent;
        border-radius: var(--radius-pill);
        background: var(--c-fg);
        color: var(--c-on-surface);
    }

    input::placeholder {
        color: rgb(0 0 0 / 0.55);
    }

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

    #header {
        position: fixed;
        inset: 0 0 auto 0;
        z-index: var(--z-header);
        background: var(--c-header-scrim);
    }

    /* Exakt dieselbe Breitenformel wie beim Artikel, damit Logo und
       Inhalt auf jeder Viewportbreite dieselbe linke Kante haben.
       Vorher lief das oberhalb von 2000px auseinander, weil der Header
       nur max-width hatte und der Artikel zusaetzlich den Gutter abzieht. */
    #header>.inside {
        display: flex;
        align-items: center;
        justify-content: space-between;
        width: min(100% - 2 * var(--gutter), var(--container));
        margin-inline: auto;
    }

    #logo {
        display: block;
        padding: var(--space-m);
        /* Das Padding bleibt als Klickflaeche, wird optisch aber
           herausgezogen. Dadurch sitzt die Schrift buendig. */
        margin-inline-start: calc(-1 * var(--space-m));
        font-size: var(--fs-logo);
        font-weight: var(--fw-bold);
        line-height: 1;
        text-decoration: none;
    }

    /* Gegenstueck auf der rechten Seite */
    #menu .level_1>li:last-child> :is(a, strong) {
        margin-inline-end: calc(-1 * var(--space-m));
    }

    #mobile_menu,
    #mobile_menu_logo {
        display: none;
    }

    /* Scrollgesteuerte Verdichtung. Nur als Verbesserung, nie als
       Voraussetzung: ohne Unterstuetzung bleibt der Verlauf. */
    @supports (animation-timeline: scroll()) {
        @media (prefers-reduced-motion: no-preference) and (min-width: 901px) {

            #header {
                animation: header-solid linear both;
                animation-timeline: scroll();
                animation-range: 0 250px;
            }

            #logo {
                animation: logo-compact linear both;
                animation-timeline: scroll();
                animation-range: 0 250px;
            }

            #menu .level_1>li> :is(a, strong) {
                animation: header-compact linear both;
                animation-timeline: scroll();
                animation-range: 0 250px;
            }
        }
    }

    @keyframes header-solid {
        from {
            background-color: rgb(0 0 0 / 0);
            backdrop-filter: blur(0);
        }

        to {
            background-color: rgb(0 0 0 / 1);
            backdrop-filter: blur(5px);
        }
    }

    @keyframes header-compact {
        from {
            padding-block: var(--space-m);
        }

        to {
            padding-block: var(--space-xs);
        }
    }

    @keyframes logo-compact {
        from {
            padding-block: var(--space-m);
            font-size: var(--fs-logo);
        }

        to {
            padding-block: var(--space-xs);
            font-size: calc(var(--fs-logo) * 0.75);
        }
    }

    /* --- Hauptnavigation ---------------------------------------------------- */

    #menu .level_1 {
        display: flex;
        margin: 0;
        padding: 0;
        list-style: none;
    }

    #menu li {
        position: relative;
        margin: 0;
    }

    #menu .level_1 :is(a, strong) {
        display: block;
        padding: var(--space-m);
        font-weight: var(--fw-bold);
        text-decoration: none;
    }

    /* Unterstrich: ein Pseudoelement, zwei Zustaende */
    #menu .level_1 :is(a, strong)::after {
        content: "";
        position: absolute;
        inset-inline: var(--space-m);
        top: calc(50% + 0.7em);
        height: 4px;
        background-color: var(--c-fg);
        transition: scale var(--dur) var(--ease);
        transform-origin: left center;
        scale: 0 1;
    }

    /* Der aktive und der uebergeordnete Punkt werden DURCHGESTRICHEN,
       nicht unterstrichen. Das ist Absicht und Teil der Markenfuehrung,
       kein Fehler. Bitte nicht auf die Hover-Position aendern.
       Der Balken sitzt deshalb auf der Textmitte statt darunter. */
    #menu .level_1 strong::after,
    #menu .level_1 a.trail::after {
        top: calc(50% - 1px);
        scale: 1 1;
    }

    #menu .level_1 a:hover::after,
    #menu .level_1 li:hover>a::after {
        scale: 1 1;
    }

    /* Untermenue */
    #menu li ul {
        position: absolute;
        display: block;
        padding: var(--space-2xs) 0;
        border-radius: var(--radius);
        background-color: var(--c-bg);
        visibility: hidden;
        opacity: 0;
        transition:
            opacity var(--dur-slow) var(--ease),
            visibility 0s linear var(--dur-slow);
    }

    #menu li:hover>ul,
    #menu li:focus-within>ul {
        visibility: visible;
        opacity: 1;
        transition-delay: 0s;
    }

    #menu li ul :is(a, strong) {
        padding: var(--space-s) var(--space-m);
    }

    #menu :is(a, strong).submenu::before {
        content: "\203A";
        position: absolute;
        left: calc(100% - 30px);
        transition: rotate var(--dur-slow) var(--ease);
        rotate: 90deg;
    }

    #menu li:hover> :is(a, strong).submenu::before {
        rotate: -90deg;
    }

    /* --- Mobile Navigation --------------------------------------------------- */

    @media (max-width: 900px) {

        #header>.inside {
            display: block;
            position: relative;
        }

        #menu,
        #menu_logo {
            display: none;
        }

        #mobile_menu_logo {
            display: block;
            padding: var(--space-s);
            margin-inline-start: calc(-1 * var(--space-s));
        }

        #mobile_menu_logo a {
            font-size: var(--fs-logo);
            font-weight: var(--fw-bold);
            line-height: 1;
            text-decoration: none;
        }

        #mobile_menu {
            display: block;
            position: absolute;
            inset: 0 0 auto 0;
        }

        #mobile_menu input[type="checkbox"] {
            position: absolute;
            opacity: 0;
            pointer-events: none;
        }

        /* dvh statt vh, sonst schneidet die iOS-Adressleiste ab.
           Kein festes li-Hoehenmass, mehrzeilige Menuepunkte sind
           dadurch unproblematisch. */
        #mobile_menu .level_1 {
            position: fixed;
            inset: 0;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            gap: var(--space-s);
            margin: 0;
            padding: var(--space-l) var(--gutter);
            list-style: none;
            background-color: var(--c-bg);
            font-size: var(--fs-h4);
            visibility: hidden;
            opacity: 0;
            transition:
                opacity var(--dur-slow) var(--ease),
                visibility 0s linear var(--dur-slow);
        }

        #mobile_menu input[type="checkbox"]:checked~.level_1 {
            visibility: visible;
            opacity: 1;
            transition-delay: 0s;
        }

        #mobile_menu li {
            margin: 0;
            opacity: 0;
            translate: 0 12px;
            transition:
                opacity var(--dur) var(--ease),
                translate var(--dur) var(--ease);
        }

        #mobile_menu input[type="checkbox"]:checked~.level_1 li {
            opacity: 1;
            translate: 0 0;
        }

        #mobile_menu :is(a, strong, label) {
            display: inline-block;
            padding: var(--space-xs) var(--space-s);
            font-weight: var(--fw-bold);
            text-decoration: none;
        }

        /* Contao setzt auf der aktiven Seite ein <label class="active">
           statt eines Links. */
        #mobile_menu :is(strong, label.active) {
            text-decoration: underline;
            text-decoration-thickness: 4px;
            text-underline-offset: 0.3em;
        }

        /* Hintergrund nicht mitscrollen lassen, ohne JavaScript */
        html:has(#hamburger:checked) {
            overflow: hidden;
        }

        /* Burger */
        #mobile_menu>label[for="hamburger"] {
            position: absolute;
            top: 0;
            right: 0;
            z-index: var(--z-overlay);
            display: flex;
            flex-direction: column;
            justify-content: center;
            gap: 6px;
            width: 70px;
            height: 70px;
            padding: var(--space-s);
            cursor: pointer;
        }

        #mobile_menu>label[for="hamburger"] span {
            height: 2px;
            border-radius: 10px;
            background: var(--c-fg);
            transition: all var(--dur) var(--ease-back);
        }

        #mobile_menu>label[for="hamburger"] span:nth-of-type(1) {
            width: 50%;
        }

        #mobile_menu>label[for="hamburger"] span:nth-of-type(2) {
            width: 100%;
        }

        #mobile_menu>label[for="hamburger"] span:nth-of-type(3) {
            width: 75%;
        }

        #mobile_menu input:checked~label span:nth-of-type(1) {
            width: 100%;
            translate: 0 8px;
            rotate: 45deg;
        }

        #mobile_menu input:checked~label span:nth-of-type(2) {
            opacity: 0;
        }

        #mobile_menu input:checked~label span:nth-of-type(3) {
            width: 100%;
            translate: 0 -8px;
            rotate: -45deg;
        }
    }

    /* --- Bilder -------------------------------------------------------------- */

    .content-image {
        position: relative;
        max-height: calc(100svh - var(--header-h));
        overflow: hidden;
        border-radius: var(--radius);
    }

    .content-image :is(figure, img) {
        width: 100%;
        height: 100%;
        object-fit: cover;
        object-position: center;
    }

    /* --- Text-Bild-Block ------------------------------------------------------
       Raster statt Flex. Dadurch keine 50%-plus-gap-Rechnung mehr, die
       frueher aus dem Container gelaufen ist.
       ------------------------------------------------------------------------ */

    .content-text.media {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--space-l);
        align-items: center;
    }

    .content-text.media>figure {
        grid-column: 1;
        grid-row: 1;
    }

    .content-text.media.media--right>figure {
        grid-column: 2;
    }

    .content-text.media.media--right>.rte {
        grid-column: 1;
        grid-row: 1;
    }

    /* Bild ueber Text, einspaltig */
    .content-text.media.media--above {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--space-s);
        align-items: start;
    }

    .content-text.media.media--above>figure {
        grid-column: 1;
        grid-row: 1;
    }

    .content-text.media img {
        max-height: 90svh;
        border-radius: var(--radius);
        object-fit: cover;
    }

    @media (max-width: 900px) {

        .content-text.media,
        .content-text.media.media--right {
            grid-template-columns: minmax(0, 1fr);
            gap: var(--space-s);
        }

        .content-text.media>figure,
        .content-text.media.media--right>figure {
            grid-column: 1;
            grid-row: 1;
        }

        .content-text.media.media--right>.rte {
            grid-column: 1;
            grid-row: 2;
        }

        .content-text.media img {
            max-height: 60svh;
        }
    }

    /* --- Hero -----------------------------------------------------------------
       Steht bewusst NACH .content-image, damit die Hintergrundregeln die
       Standardregeln des Bildelements ueberschreiben. Bei Cascade Layers
       entscheidet der Layer vor der Spezifitaet, deshalb muessen beide im
       selben Layer liegen.
       -------------------------------------------------------------------------- */

    #hero {
        position: relative;
        display: flex;
        align-items: flex-end;
        min-height: 100svh;
        padding: var(--header-h) var(--gutter) var(--section-s);
        overflow: hidden;
        isolation: isolate;
    }

    /* Nachfahren-Selektor, damit es auch greift, wenn Contao das Element
       in eine Gruppe legt. */
    #hero video,
    #hero .content-image {
        position: absolute;
        inset: 0;
        z-index: var(--z-behind);
        width: 100%;
        height: 100%;
        min-height: 100%;
        max-height: none;
        margin: 0;
        border-radius: 0;
        object-fit: cover;
    }

    #hero video {
        opacity: 0.8;
    }

    #hero .content-image {
        overflow: hidden;
        opacity: 0.5;
    }

    #hero .content-image :is(figure, img) {
        width: 100%;
        height: 100%;
        min-height: 100%;
        max-height: none;
        border-radius: 0;
        object-fit: cover;
        object-position: center;
    }

    #hero .content-text {
        position: relative;
        z-index: 0;
        max-width: var(--container);
        margin-inline: auto;
    }

    #hero .content-text :is(h1, h4, p) {
        margin-block: var(--space-s);
    }

    #hero .content-text>.rte> :last-child {
        margin-bottom: 0;
    }

    @media (max-width: 900px) {
        #hero {
            min-height: calc(100svh - var(--header-h));
        }
    }
}


/* ==========================================================================
   5  MODULES
   ========================================================================== */

@layer modules {

    /* --- Kundenlogos ----------------------------------------------------------
       Feste Spaltenstufen 6 / 4 / 3 / 2 statt auto-fit. Bei einer durch 12
       teilbaren Zahl von Logos bleibt jede Zeile voll besetzt.
       -------------------------------------------------------------------------- */

    .clients {
        display: grid;
        grid-template-columns: repeat(var(--client-cols), minmax(0, 1fr));
        gap: var(--section-s) var(--gutter);
        place-items: center;
    }

    .clients .content-image {
        display: grid;
        place-items: center;
        width: 100%;
        max-height: none;
        overflow: visible;
        border-radius: 0;
    }

    /* height: auto hebt die Standardregel des Bildelements auf. Ohne diese
       Zeile werden die Logos auf Zellenhoehe gezerrt und ueberlappen. */
    .clients .content-image :is(figure, img) {
        width: auto;
        height: auto;
        max-width: min(10rem, 100%);
        max-height: 4rem;
        object-fit: contain;
    }

    /* Setzt schwarze Logos auf weiss um. Funktioniert nur bei einfarbig
       schwarzen PNGs mit Transparenz. */
    .clients .content-image img {
        filter: invert(1);
    }

    /* --- Projektliste ----------------------------------------------------------- */

    .mod_newslist {
        display: grid;
        grid-template-columns: repeat(var(--cols, var(--list-cols)), minmax(0, 1fr));
        /* dense fuellt Luecken, die durch ueberspannende Kacheln entstehen,
           mit nachfolgenden 1x1-Kacheln auf. */
        grid-auto-flow: row dense;
        gap: var(--gutter);
        align-items: stretch;
    }

    /* Flex-Zentrierung statt text-align: laesst sich nicht durch eine
       geerbte Textausrichtung aushebeln und greift unabhaengig davon,
       welche Zusatzklassen Contao am Absatz vergibt. */
    /* Dreifach abgesichert: der Absatz spannt ueber alle Spalten,
       zentriert sich selbst in seiner Rasterflaeche und zentriert
       zusaetzlich seinen Inhalt. Damit ist es unabhaengig davon,
       welche Zusatzklassen Contao am Absatz vergibt. */
    .mod_newslist>.more {
        grid-column: 1 / -1;
        justify-self: center;
        display: flex;
        justify-content: center;
        margin-block: var(--section-s) 0;
        text-align: center;
    }

    /* --- Projektkachel -----------------------------------------------------------
       align-self: start ist hier zwingend. Ein Rasterelement mit
       aspect-ratio und der Standardausrichtung stretch bezieht seine Hoehe
       aus der Zeile statt aus dem Seitenverhaeltnis. Da der gesamte
       Kachelinhalt absolut positioniert ist, waere die Inhaltshoehe null
       und die Kachel wuerde zusammenfallen.
       ----------------------------------------------------------------------------- */

    .layout_latest {
        position: relative;
        display: block;
        align-self: start;
        aspect-ratio: var(--tile-ratio, 16 / 9);
        overflow: hidden;
        border-radius: var(--radius);
        text-decoration: none;
        cursor: pointer;
    }

    /* Ueberspannende Kacheln haben kein eigenes Seitenverhaeltnis, sondern
       die Hoehe der Zeilen, die sie belegen. Die Zeilenhoehe kommt von den
       16:9-Nachbarn, deshalb passt alles ohne calc() zusammen. */
    .layout_latest:where(.tile-wide, .tile-tall, .tile-big) {
        align-self: stretch;
        aspect-ratio: auto;
    }

    .layout_latest>.inside {
        position: absolute;
        inset: 0;
        background-size: cover;
        background-position: center;
        opacity: 0.8;
        transition:
            opacity var(--dur-slow) var(--ease),
            scale var(--dur-slow) var(--ease);
    }

    .layout_latest:hover>.inside,
    .layout_latest:focus-visible>.inside {
        opacity: 0.5;
        scale: 1.1;
    }

    .layout_latest video {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        scale: 1.01;
    }

    .layout_latest>.text {
        position: absolute;
        inset-inline: 0;
        top: 50%;
        translate: 0 -50%;
        padding: var(--space-s);
        text-align: center;
    }

    .layout_latest .text p {
        margin: 0;
        font-size: var(--fs-small);
        font-weight: var(--fw-bold);
    }

    .layout_latest .text :is(h3, h4) {
        margin: 0;
    }

    /* --- Projektdetail ------------------------------------------------------------
       Kein eigener Abstand mehr. Der Textblock verhaelt sich wie jedes
       andere Rasterelement und wird ueber flow- oder pad-Klassen gesteuert.
       ------------------------------------------------------------------------------ */

    .layout_full>.content-text {
        align-self: center;
    }

    .layout_full video {
        width: 100%;
        border-radius: var(--radius);
    }

    /* --- Team, heller Bereich ------------------------------------------------------ */

    .about {
        background-color: var(--c-surface);
        color: var(--c-on-surface);
    }

    .about>.inside {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
        gap: var(--section-s) var(--gutter);
        max-width: var(--container);
        margin-inline: auto;
        padding: var(--section-m) var(--gutter);
    }

    .about .team img {
        width: 100%;
        margin-bottom: var(--space-s);
        border-radius: var(--radius);
        object-fit: cover;
    }

    .about .team p:last-of-type {
        font-size: var(--fs-small);
    }

    /* --- Footer --------------------------------------------------------------------
       Kein opacity, sondern eine Textfarbe mit ausreichendem Kontrast.
       Zum Abdunkeln --c-fg-muted in tokens.css anpassen.
       -------------------------------------------------------------------------------- */

    #footer>.inside {
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        align-items: center;
        gap: var(--space-s);
        max-width: var(--container);
        margin-inline: auto;
        padding: var(--space-m) var(--gutter);
        color: var(--c-fg-muted);
        font-size: var(--fs-small);
    }

    #footer .social {
        text-align: center;
    }

    #footer .social a {
        display: inline-block;
        padding: var(--space-2xs) var(--space-xs);
    }

    #footer .language {
        text-align: right;
    }

    #footer .language ul {
        margin: 0;
        padding: 0;
        list-style: none;
    }

    #footer .language li {
        display: inline-block;
        margin: 0;
    }

    #footer :is(a, strong):hover {
        color: var(--c-fg);
    }

    @media (max-width: 900px) {

        #footer>.inside {
            grid-template-columns: 1fr;
            gap: var(--space-s);
            text-align: center;
        }

        #footer .language,
        #footer .legal {
            text-align: center;
        }
    }

    /* --- Tabellen ---------------------------------------------------------------------- */

    .content-table table {
        border-collapse: collapse;
    }

    .content-table :is(th, td) {
        padding-block-end: var(--space-s);
        vertical-align: top;
        text-align: left;
    }

    .content-table th {
        padding-inline-end: var(--space-m);
        font-weight: var(--fw-bold);
    }

    /* --- Eingebetteter Videoplayer -----------------------------------------------------
       Fuer Fremdplayer wie Clappr, der sein Markup selbst erzeugt.
       Wir setzen nur den Rahmen, alles Innere gehoert dem Player.
       ------------------------------------------------------------------------------------- */

    .herovideo .video,
    #player-wrapper {
        position: relative;
        overflow: hidden;
        border-radius: var(--radius);
    }

    #player-wrapper [data-player] {
        border-radius: var(--radius);
        overflow: hidden;
    }

    /* --- Credits-Ausklapper --------------------------------------------------------------
       Der aufklappende Teil liegt in einem eigenen Wrapper mit genau
       EINER Rasterzeile. Das ist der entscheidende Unterschied zur
       vorherigen Fassung: dort wurde eine Liste aus auto und 0fr
       interpoliert, und die auto-Zeile konnte sich waehrend des
       Uebergangs mitbewegen. Jetzt ist nur ein einziger Wert animiert,
       und der Button liegt komplett ausserhalb davon. Er kann sich
       dadurch gar nicht mehr bewegen.
       --------------------------------------------------------------------------------------- */

    .credits {
        display: flex;
        flex-direction: column;
        align-items: start;
    }

    /* order haelt den Button oben, unabhaengig davon, ob er im Template
       vor oder nach der Tabelle steht. */
    .credits-toggle {
        order: -1;
        padding: 0;
        border: 0;
        border-radius: 0;
        background: none;
        color: inherit;
        font: inherit;
        font-weight: var(--fw-bold);
        text-decoration: underline;
        text-underline-offset: 0.3em;
        cursor: pointer;
    }

    .credits-toggle:hover {
        background: none;
        color: var(--c-fg);
    }

    /* Das Vorzeichen gehoert zum Zustand, nicht zum Inhalt. Deshalb
       steht es im CSS und JavaScript muss keinen Text austauschen. */
    .credits-toggle::before {
        content: "+ ";
    }

    .credits.is-open .credits-toggle::before {
        content: "\2013 ";
    }

    .credits-panel {
        display: grid;
        grid-template-rows: 0fr;
        width: 100%;
        transition: grid-template-rows var(--dur-slow) var(--ease);
    }

    .credits.is-open .credits-panel {
        grid-template-rows: 1fr;
    }

    /* display: block ist hier entscheidend. overflow und min-block-size
       wirken nicht auf ein Element mit display: table, deshalb liesse
       sich die Tabelle sonst nicht auf null Hoehe klemmen. Als
       Blockcontainer greift beides, die Zeilen werden intern in eine
       anonyme Tabelle gewrappt und das Spaltenlayout bleibt erhalten.
       Der Innenabstand wird im geschlossenen Zustand mitgeklemmt,
       deshalb braucht es keine animierte Luecke. */
    .credits-panel>table {
        display: block;
        min-block-size: 0;
        min-inline-size: 0;
        padding-block-start: var(--space-s);
        overflow: hidden;
        opacity: 0;
        transition: opacity var(--dur-slow) var(--ease);
    }

    .credits.is-open .credits-panel>table {
        opacity: 1;
    }

    /* --- iPhone-Mockup ---------------------------------------------------------------------
       Breitengesteuert statt hoehengesteuert. Dadurch passt sich das
       Geraet der Rasterspalte an, statt aus ihr herauszulaufen.
       ---------------------------------------------------------------------------------------- */

    .iphone-container-wrapper {
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .iphone-container {
        position: relative;
        width: min(100%, 22.5rem);
        aspect-ratio: 1 / 2;
        background-image: url("../../files/media/projects/iphone.png");
        background-size: contain;
        background-repeat: no-repeat;
        background-position: center;
    }

    .iphone-container .video-container {
        position: absolute;
        top: 2.25%;
        inset-inline: 5.85%;
        height: 95.5%;
        overflow: hidden;
        /* 8% der Breite entspricht bei diesem Seitenverhaeltnis 4% der
           Hoehe, dadurch bleiben die Ecken rund statt oval. */
        border-radius: 8% / 4%;
        background-color: var(--c-bg);
        cursor: pointer;
    }

    .iphone-container video {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    .progress-indicator {
        position: absolute;
        top: 4%;
        inset-inline: 12%;
        display: flex;
        gap: 2px;
    }

    .progress-segment {
        flex: 1 1 0;
        height: 3px;
        border-radius: 5px;
        background-color: rgb(255 255 255 / 0.25);
        transition: background-color var(--dur) var(--ease);
    }

    .progress-segment.active {
        background-color: rgb(255 255 255 / 0.6);
    }

    .mute-button {
        position: absolute;
        right: 10%;
        bottom: 5%;
        width: 40px;
        padding: var(--space-2xs);
        color: var(--c-fg-muted);
        text-align: center;
        cursor: pointer;
    }

    /* --- Social-Icons im Fliesstext, Kontaktseite ------------------------------------ */

    p.social a {
        display: inline-block;
        position: relative;
        left: -0.35em;
        padding: var(--space-2xs) 0.35em;
    }
}


/* ==========================================================================
   6  UTILITIES
   --------------------------------------------------------------------------
   Diese Klassen traegst Du in Contao im Expertenbereich ein.
   Sie stehen im letzten Layer und gewinnen deshalb immer.
   ========================================================================== */

@layer utilities {

    /* --- Rasterlage ------------------------------------------------------------
       Setzen nur Custom Properties. Die eigentliche Regel steht im
       Layout-Layer, dadurch wirken sie in jedem Rasterkontext gleich.
       ---------------------------------------------------------------------------- */

    .span-2 {
        --span: 2;
    }

    .span-3 {
        --span: 3;
    }

    .span-4 {
        --span: 4;
    }

    .span-5 {
        --span: 5;
    }

    .span-6 {
        --span: 6;
    }

    .start-1 {
        --start: 1;
    }

    .start-2 {
        --start: 2;
    }

    .start-3 {
        --start: 3;
    }

    .start-4 {
        --start: 4;
    }

    .start-5 {
        --start: 5;
    }

    /* --- Projektkacheln ---------------------------------------------------------
       Ohne Klasse ist jede Kachel 1x1 im Format 16:9.
       Einzelfall: style="--tile-ratio: 4/5" fuer ein Hochformat.
       ---------------------------------------------------------------------------- */

    .tile-wide {
        --span: 2;
    }

    /* zwei Spalten, eine Zeile */
    .tile-tall {
        --span-h: 2;
    }

    /* eine Spalte, zwei Zeilen */
    .tile-big {
        --span: 2;
        --span-h: 2;
    }

    /* zwei mal zwei            */

    /* Generische Zeilenspanne. Passend zu span-2 bis span-6 fuer die
       Breite. Wird auf den Projektdetailseiten fuer hohe Bilder genutzt,
       .tile-tall ist der gleichwertige Name im Kachelraster. */
    .span-h-2 {
        --span-h: 2;
    }

    .span-h-3 {
        --span-h: 3;
    }

    /* Einspaltig: alle Spannweiten zuruecksetzen */
    @media (max-width: 900px) {
        :is(.grid, .layout_full, .mod_newslist)>* {
            --span: 1;
            --span-h: 1;
            --start: auto;
        }
    }

    /* --- Vertikaler Rhythmus -----------------------------------------------------
       --flow steuert den Abstand nach oben, --flow-end den nach unten.
       Die Klassen wirken im Artikel-Stack und im Raster identisch.
       Standard ist im Stack --section, im Raster der Gutter.
       ------------------------------------------------------------------------------ */

    .flow-l {
        --flow: var(--section);
    }

    /* 320px auf Desktop */
    .flow-m {
        --flow: var(--section-m);
    }

    /* 160px auf Desktop */
    .flow-s {
        --flow: var(--section-s);
    }

    /*  80px auf Desktop */
    .flow-0 {
        --flow: 0;
    }

    /* Abstand oben und unten */
    .pad-l {
        --flow: var(--section);
        --flow-end: var(--section);
    }

    .pad-m {
        --flow: var(--section-m);
        --flow-end: var(--section-m);
    }

    .pad-s {
        --flow: var(--section-s);
        --flow-end: var(--section-s);
    }

    /* Im Stack: verkuerzt den eigenen und den folgenden Abstand */
    .tight,
    .tight+* {
        --flow: var(--section-m);
    }

    .tighter,
    .tighter+* {
        --flow: var(--section-s);
    }

    /* Randfaelle im Raster: das erste und letzte Element bekommen keinen
       zusaetzlichen Aussenabstand, sonst addiert er sich zum Aussenabstand
       des Artikels. :is() liegt bei (0,2,0) und schlaegt damit die
       pad-Klassen bei (0,1,0), unabhaengig von der Reihenfolge.
       Bewusst uebersteuern per style="--flow: 320px" am Element. */
    :is(.grid, .layout_full, .mod_newslist)> :first-child {
        --flow: 0;
    }

    :is(.grid, .layout_full, .mod_newslist)> :last-child {
        --flow-end: 0;
    }

    /* --- Artikelraender ------------------------------------------------------------
       Gehoeren an den ARTIKEL, nicht an ein Inhaltselement.
       In Contao: Artikel bearbeiten, Experteneinstellungen, CSS-Klasse.
       -------------------------------------------------------------------------------- */

    .mod_article.flush-top {
        margin-block-start: calc(var(--header-h) + var(--space-m));
    }

    /* Schliesst buendig an den Footer an */
    .mod_article.flush-bottom {
        margin-block-end: 0;
    }

    .mod_article.flush {
        margin-block: calc(var(--header-h) + var(--space-m)) 0;
    }

    /* --- Breite ---------------------------------------------------------------------- */

    /* Lesebreite fuer zusammenhaengenden Fliesstext:
       Impressum, Datenschutz, AGB, Einleitungstexte. */
    .measure {
        max-width: var(--measure);
        margin-inline: auto;
    }

    /* Breitere Variante, entspricht span-3 im Sechserraster.
       Fuer Bloecke mit vielen Ueberschriften statt Fliesstext. */
    .measure-wide {
        max-width: var(--measure-wide);
        margin-inline: auto;
    }

    .text-small {
        font-size: var(--fs-small);
        color: var(--c-fg-muted);
    }

    /* --- Trenner -------------------------------------------------------------------------
       Leeres Element, das im Raster eine Zeile umbricht und optional
       Abstand erzeugt. Ohne Zusatzklasse nur der Umbruch.
       -------------------------------------------------------------------------------------- */

    .divider {
        grid-column: 1 / -1;
        block-size: 0;
        margin-block-start: var(--flow, var(--section-s));
    }

    /* --- Sichtbarkeit ---------------------------------------------------------------------- */

    .hidden {
        display: none;
    }

    /* --- Ausrichtung ----------------------------------------------------------------- */

    .center {
        text-align: center;
    }

    .vertical-center {
        align-self: center;
    }

    /* --- Einblenden beim Scrollen ------------------------------------------------------ */

    @supports (animation-timeline: view()) {
        @media (prefers-reduced-motion: no-preference) {
            .fade-in-section {
                animation: fade-in-up linear both;
                animation-timeline: view();
                animation-range: entry 0% cover 30%;
            }
        }
    }

    @keyframes fade-in-up {
        from {
            opacity: 0;
            translate: 0 40px;
        }

        to {
            opacity: 1;
            translate: 0 0;
        }
    }
}


/* ==========================================================================
   BEWEGUNG REDUZIEREN
   Ungelayert, damit es alles ueberstimmt.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {

    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
