/* ===========================================================================
   Sektionssystem der Inhaltsseiten (T-10)

   Alle Werte kommen aus tokens.generated.css. Keine freien Hexwerte, keine
   eigenen Abstaende: DESIGN.md 4 und 5 sind die Vorgabe, tokens.json der Wert.

   Praefix epi- in kebab-case. Die Altseiten nutzen snake_case (hero_section,
   solutions_grid); die Trennung ist absichtlich, damit man am Klassennamen
   sieht, welchem System ein Baustein gehoert.
   =========================================================================== */

:root {
    /* Unter --content-size traegt der Rand die Seite, darueber die max-width. */
    --epi-gutter: clamp(1.25rem, 5vw, 2.5rem);
    /* Spaltengasse der Sektionsformen: 100 px bei 1200 Inhaltsbreite. */
    --epi-col-gap: clamp(2.5rem, 6vw, 6.25rem);
    /* Gasse der gleichspaltigen Raster (Module, Bento): 40 px. */
    --epi-grid-gap: var(--wp--preset--spacing--lg);
}

/* --- Seitenrahmen ---------------------------------------------------------
   Oberhalb von --wide-size steht die Seite still und wird zentriert
   (DESIGN.md 8, Verhalten > 1920px). Die Hero-Flaechen duerfen bis an den
   Viewportrand reichen; horizontaler Ueberlauf wird deshalb am Body und nicht
   an diesem Rahmen abgeschnitten. */

body {
    overflow-x: clip;
}

.epi-page {
    max-width: var(--wide-size);
    margin-inline: auto;
    overflow-x: visible;
}

/* --- Container ------------------------------------------------------------ */

.epi-container {
    width: 100%;
    /* Der Rand liegt ausserhalb der Inhaltsbreite: bei 1440 stehen exakt
       1200 px Inhalt, damit die Hero-Randflaeche an der Inhaltskante sitzt. */
    max-width: calc(var(--content-size) + 2 * var(--epi-gutter));
    margin-inline: auto;
    padding-inline: var(--epi-gutter);
}

/* Schmale Variante: der Inhalt steht als Block mittig, Text bleibt
   linksbuendig. Fuer Abschnitte mit einem Formular (52 rem wie .epi-formular). */
.epi-container--schmal {
    max-width: calc(52rem + 2 * var(--epi-gutter));
}

/* --- Textrhythmus ---------------------------------------------------------
   styles.spacing.blockGap ist 0, weil die Sektionsformen den Abstand selbst
   setzen. Fliesstext im Container braucht ihn trotzdem. Nur hier, damit die
   Altseiten unberuehrt bleiben. */

/* Der Traeger steht in :where(), damit die Regel nur Elementgewicht hat: jede
   Bausteinklasse (.epi-point__body, .epi-hero__text > *) schlaegt sie ohne
   !important und ohne Reihenfolgeabhaengigkeit. */

/* Die Klasse .wp-block-buttons steht in :where(): in :is() wuerde sie die
   Regel auf Klassengewicht heben und jede Bausteinklasse ueberstimmen. */

:where(.epi-container) :is(p, ul, ol, figure):where(:not(.epi-points)),
:where(.epi-container) :where(.wp-block-buttons) {
    margin-block: 0;
}

:where(.epi-container) :is(p, ul, ol, figure):where(:not(.epi-points))
    + :is(p, ul, ol, figure):where(:not(.epi-points)),
:where(.epi-container) :where(.wp-block-buttons) + *,
:where(.epi-container) * + :where(.wp-block-buttons) {
    margin-block-start: var(--wp--preset--spacing--md);
}

:where(.epi-container) :is(h2, h3, h4, h5, h6) {
    margin-block: 0;
}

:where(.epi-container) :is(h2, h3, h4, h5, h6) + * {
    margin-block-start: var(--wp--preset--spacing--md);
}

:where(.epi-container) * + :is(h3, h4, h5, h6) {
    margin-block-start: var(--wp--preset--spacing--lg);
}

/* Die Sektionsformen setzen ihre Gasse selbst; der Rhythmus darf die erste
   Zeile einer Spalte nicht nach unten schieben. */
:where(.epi-cols) > :first-child,
:where(.epi-cols) > * > :first-child {
    margin-block-start: 0;
}

/* --- Sektionen und Flaechen ----------------------------------------------
   Grundtakt ist der Wechsel Weiss/Creme. Akzentband und dunkle Zaesur
   stehen hoechstens einmal je Seite (DESIGN.md 4). */

.epi-section {
    padding-block: var(--section-spacing);
}

.epi-section--base {
    background-color: var(--color-base);
}

.epi-section--subtle {
    background-color: var(--color-primary-light);
}

.epi-section--band {
    background-color: var(--color-secondary-20);
}

.epi-section--dark {
    background-color: var(--color-dark);
    color: var(--color-base);
}

.epi-section--dark :is(h1, h2, h3, h4, h5, h6) {
    color: var(--color-base);
}

/* Auf das Band gehoert keine Trennlinie: border/default ist derselbe Wert
   wie die Flaeche und waere unsichtbar (DESIGN.md 2.4). */
.epi-section--band .epi-divider {
    border-color: var(--color-secondary);
}

/* Folgt eine Sektion derselben Farbe, entfaellt der doppelte Innenabstand. */
.epi-section + .epi-section--base:has(+ .epi-section--base) {
    padding-block-end: 0;
}

/* --- Sektionsformen -------------------------------------------------------
   Raster 460 + 100 + 640 = 1200. Die fr-Werte geben genau diese Breiten,
   weil die Gasse vorher abgezogen wird (DESIGN.md 4).
   Unter 1024 einspaltig: 460 px Titelspalte tragen dort keine Zeile mehr.
   Ableitung des Builds, in der Quelle nicht vorhanden. */

.epi-cols {
    display: grid;
    /* minmax(0, …): ein langes Wort in der Spalte weitet sonst das Raster
       ueber die Seite hinaus. */
    grid-template-columns: minmax(0, 1fr);
    gap: var(--epi-col-gap);
    /* Ohne das dehnt Grid-Standard "stretch" die kuerzere Spalte auf die
       Hoehe der laengeren. Bei Text-und-Punkte reisst das die Punkteliste
       sichtbar auseinander, weil sich die zusaetzliche Hoehe durch jede
       verschachtelte Grid-Ebene nach unten vererbt (.epi-points, .epi-point). */
    align-items: start;
}

@media screen and (min-width: 1024px) {
    /* Titel links, Text rechts */
    .epi-cols--title-left {
        grid-template-columns: 46fr 64fr;
    }

    /* Text links, Aufzaehlung rechts */
    .epi-cols--text-points {
        grid-template-columns: 64fr 46fr;
    }

    .epi-cols--even {
        grid-template-columns: 1fr 1fr;
    }

    /* Spiegelt die Spaltenreihenfolge (Bild links, Text rechts), Spaltenmasse
       bleiben wie in der Grundform. Zwei aufeinanderfolgende Text-und-Bild-
       Sektionen mit identischer Bildseite lesen sich als eine wiederholte
       Komponente statt als zwei eigene Abschnitte (Nutzer-Befund). */
    .epi-cols--reverse {
        direction: rtl;
    }

    .epi-cols--reverse > * {
        direction: ltr;
    }
}

/* --- Sektionsstapel ------------------------------------------------------
   Jede Sektion ist ein Stapel aus Ueberschrift, Intro und Inhalt mit 48 px
   Abstand. Der Wert kommt aus dem Auto-Layout der Sektionsrahmen in Figma
   (Knoten 104:179 und die uebrigen Sektionen der Produktseiten). */

.epi-stack {
    display: grid;
    gap: var(--wp--preset--spacing--xl);
}

/* Im Stapel setzt allein die Gasse den Abstand; der Fliesstext-Rhythmus
   (margin nach Ueberschriften) kaeme sonst obendrauf (68 statt 48 px). */
.epi-stack > * {
    margin-block: 0;
}

/* Die Sektionsueberschrift laeuft nie ueber 820 px. Zwei Zeilen H2 sind so
   gesetzt, nicht zufaellig (Figma: jedes H2 einer Sektion ist 820 breit). */
.epi-section :is(h2, .epi-stack > h2) {
    max-width: 820px;
}

/* In der Titelspalte begrenzt die Spalte selbst. */
.epi-cols h2 {
    max-width: none;
}

/* Lange deutsche Komposita („Dokumentenmanagement,") sind mobil breiter als
   die Spalte; Silbentrennung statt Ueberlauf. Die Hero-H1 trennt bewusst
   nicht automatisch (components.css .epi-hero h1). */
@media screen and (max-width: 767px) {
    .epi-section :is(h1, h2, h3) {
        hyphens: auto;
        overflow-wrap: break-word;
    }
}

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

/* Einspaltig bis 768px: ohne explizite Spalte waechst die implizite Spalte auf
   die Inhaltsbreite der Karten und erzeugt auf Mobil horizontales Scrollen.
   Drei Karten bleiben bis 1023 px einspaltig: zweispaltig stuende die dritte
   allein in einer Zeile. */
.epi-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--epi-grid-gap);
}

/* Zwei gleiche Spalten, 580 + 40 + 580 = 1200 (Figma 104:181). */
@media screen and (min-width: 1024px) {
    .epi-grid--2 {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media screen and (min-width: 1024px) {
    .epi-grid--3 {
        grid-template-columns: repeat(3, 1fr);
    }
}

@media screen and (min-width: 640px) {
    .epi-grid--4 {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media screen and (min-width: 1024px) {
    .epi-grid--4 {
        grid-template-columns: repeat(4, 1fr);
    }
}

/* --- Spaltentrenner ------------------------------------------------------
   Senkrechte Haarlinie in der Gasse eines zweispaltigen Rasters. Haengt an
   der Spalte, nicht an einem eigenen Element (tokens components.spaltentrenner).
   Faellt einspaltig weg, weil es dann keine Gasse gibt. */

.epi-colrule {
    position: relative;
}

@media screen and (min-width: 1024px) {
    .epi-colrule {
        grid-template-columns: 1fr 1fr;
    }

    .epi-colrule::before {
        content: "";
        position: absolute;
        inset-block: 0;
        left: 50%;
        width: 1px;
        translate: -50% 0;
        background-color: var(--color-secondary-20);
    }
}

/* --- Trennlinie ----------------------------------------------------------
   Plane 1-px-Linie, seit 2026-09-10 ohne Musterung (DESIGN.md 6). */

.epi-divider {
    border: 0;
    border-block-end: 1px solid var(--color-line);
    margin: 0;
}

.epi-divider--strong {
    border-block-end-color: var(--color-secondary);
}

/* --- Kaestchenraster -----------------------------------------------------
   Flaechentextur im Raster von --grid-mesh. Zwei Einsaetze (DESIGN.md 1.1):
   eng hinter einer Aussage auf eigener Flaeche (Zitat, Schluss-CTA) oder
   flaechig als Untergrund einer ganzen Sektion, dann ausgelaufen statt hart
   beschnitten. Nie auf dem Akzentband, nie zwei Sektionen hintereinander. */

.epi-paper {
    position: relative;
    --epi-paper-mesh:
        repeating-linear-gradient(to right, var(--color-secondary-20) 0 1px, transparent 1px var(--grid-mesh)),
        repeating-linear-gradient(to bottom, var(--color-secondary-20) 0 1px, transparent 1px var(--grid-mesh));
    background-image: var(--epi-paper-mesh);
}

.epi-section--dark .epi-paper,
.epi-paper--on-dark {
    --epi-paper-mesh:
        repeating-linear-gradient(to right, rgb(255 255 255 / 0.1) 0 1px, transparent 1px var(--grid-mesh)),
        repeating-linear-gradient(to bottom, rgb(255 255 255 / 0.1) 0 1px, transparent 1px var(--grid-mesh));
}

/* Sichtbare Kante: das Raster bricht hart ab, die Kante erklaert das Ende
   von selbst. Ohne Kante laeuft es weich aus, sonst sieht der Schnitt nach
   einem beschnittenen Bild aus (DESIGN.md 1.1, Vorgabe des Nutzers). */
.epi-paper--edge {
    border-radius: var(--radius-lg);
    overflow: hidden;
}

/* Waagerecht 10 Prozent, senkrecht 16 Prozent — die Prozentwerte der beiden
   Verlaufsrechtecke aus Figma (Knoten 313:199 und 313:200). Als Maske braucht
   der Auslauf keine Flaechenfarbe und liegt deshalb auf jedem Grund. */
/* Der Auslauf trifft nur das Karo: Es liegt in einem Pseudoelement mit der
   Maske. Auf dem Element selbst wuerde die Maske Text, Buttons und Bilder
   an den Raendern mit ausblenden. */
.epi-paper--fade {
    background-image: none;
    isolation: isolate;
}

.epi-paper--fade::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background-image: var(--epi-paper-mesh);
    pointer-events: none;
    -webkit-mask-image:
        linear-gradient(to right, transparent, black 10%, black 90%, transparent),
        linear-gradient(to bottom, transparent, black 16%, black 84%, transparent);
    -webkit-mask-composite: source-in;
    mask-image:
        linear-gradient(to right, transparent, black 10%, black 90%, transparent),
        linear-gradient(to bottom, transparent, black 16%, black 84%, transparent);
    mask-composite: intersect;
}

/* Raster als Untergrund einer ganzen Sektion statt als Flaeche unter einer
   einzelnen Aussage. Es liegt in einem Pseudoelement, nicht auf dem Element
   selbst: --fade ist eine Maske, und eine Maske trifft immer das ganze
   Element samt Text und Bildern darin — auf einer Sektion verblasst damit der
   Fliesstext an den Raendern mit. Im Pseudoelement laeuft nur das Raster aus.

   Links beginnt das Raster hart am Viewportrand — es kommt von aussen an die
   Seite heran. Nach rechts, oben und unten laeuft es aus: die Sektion traegt
   keine eigene Flaechenfarbe, ihre Kante ist also unsichtbar, und ohne Kante
   laeuft das Raster weich aus (DESIGN.md 1.1). */

.epi-paper--flaeche {
    background-image: none;
    isolation: isolate;
}

.epi-paper--flaeche::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image: var(--epi-paper-mesh);
    /* Waagerecht voll bis zur Bildkante bei 50 Prozent, aus bei 75: der Text
       beginnt kurz hinter dem Bild und bekommt nur noch den Anfang des
       Ausklangs ab, nicht die halbe Spalte. Senkrecht die 16 Prozent des
       Figma-Verlaufsrechtecks, wie bei --fade. */
    -webkit-mask-image:
        linear-gradient(to right, black 50%, transparent 75%),
        linear-gradient(to bottom, transparent, black 16%, black 84%, transparent);
    -webkit-mask-composite: source-in;
    mask-image:
        linear-gradient(to right, black 50%, transparent 75%),
        linear-gradient(to bottom, transparent, black 16%, black 84%, transparent);
    mask-composite: intersect;
}

/* --- Schwebende Flaeche --------------------------------------------------
   Eingeruecktes Panel statt Vollbreite. Die Sektion traegt nur den
   neutralen Seitenhintergrund als Rand (DESIGN.md 4). */

.epi-panel {
    max-width: var(--content-size);
    margin-inline: auto;
    margin-block: var(--wp--preset--spacing--xl);
    padding: var(--wp--preset--spacing--xl);
    border-radius: var(--radius-lg);
}

/* --- Eckmarke -----------------------------------------------------------
   Zwei Winkel, oben links und unten rechts. Vier waeren ein Rahmen, und ein
   Rahmen fasst ein statt auszurichten (tokens signatur.eckmarke). */

.epi-cornermark {
    position: relative;
}

.epi-cornermark::before,
.epi-cornermark::after {
    content: "";
    position: absolute;
    width: var(--epi-cornermark-leg, 20px);
    height: var(--epi-cornermark-leg, 20px);
    border: 0 solid var(--color-accent-dark-wcag);
    transition: width var(--motion-lift-duration) var(--motion-lift-easing),
                height var(--motion-lift-duration) var(--motion-lift-easing);
    pointer-events: none;
}

.epi-cornermark::before {
    top: var(--epi-cornermark-inset, 12px);
    left: var(--epi-cornermark-inset, 12px);
    border-block-start-width: var(--epi-cornermark-weight, 2px);
    border-inline-start-width: var(--epi-cornermark-weight, 2px);
}

.epi-cornermark::after {
    right: var(--epi-cornermark-inset, 12px);
    bottom: var(--epi-cornermark-inset, 12px);
    border-block-end-width: var(--epi-cornermark-weight, 2px);
    border-inline-end-width: var(--epi-cornermark-weight, 2px);
}

/* --- Bewegung -----------------------------------------------------------
   Vier Bewegungen sind erlaubt, weitere nicht (tokens motion). */

.epi-rise {
    animation: epi-rise var(--motion-entrance-duration) var(--motion-entrance-easing) both;
}

@keyframes epi-rise {
    from { opacity: 0; translate: 0 16px; }
    to   { opacity: 1; translate: 0 0; }
}

.epi-lift {
    transition: translate var(--motion-lift-duration) var(--motion-lift-easing);
}

.epi-lift:where(:hover, :focus-visible) {
    translate: 0 -2px;
}

/* Auftritt und Eckmarke fallen weg, Anhub und Zustandswechsel bleiben: ein
   Zustand ohne Rueckmeldung ist schlechter als eine kleine Bewegung
   (tokens motion.reducedMotion). */
@media (prefers-reduced-motion: reduce) {
    .epi-rise {
        animation: none;
    }

    .epi-cornermark::before,
    .epi-cornermark::after {
        transition: none;
    }
}

/* --- Sprungziele --------------------------------------------------------
   Die klebende Sprungleiste darf kein Ziel verdecken (Bauauftrag N32, C6). */

:where([id]) {
    scroll-margin-top: var(--epi-sticky-offset, 6rem);
}
