/* ==================================================================
   Papps Hausmeisterservice — Stylesheet
   Umsetzung der verbindlichen Designrichtung.
   Aufbau:
     1. Schriften (lokal, DSGVO)
     2. Design-Tokens (Light)
     3. Dark Mode
     4. Reset und Grundlagen
     5. Utilities
     6. Layout: Container, Sektionen
     7. Header und Navigation
     8. Buttons
     9. Hero, Vertrauensband
    10. Leistungs-Karten
    11. Warum Papps
    12. Ablauf
    13. FAQ
    14. Kontakt und Formular
    15. Footer
    16. Rechtsseiten, Danke, 404
    17. Motion / prefers-reduced-motion / prefers-contrast
   ================================================================== */


/* ------------------------------------------------------------------
   1. Schriften — lokal selbst gehostet.
   KEIN Google-Fonts-Link, KEIN @import (DSGVO, LG München I 3 O 17493/20).
   ------------------------------------------------------------------ */
@font-face {
    font-family: "Source Sans 3";
    src: url("../fonts/source-sans-3-v19-latin-400.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+20AC, U+2122, U+2212;
}
@font-face {
    font-family: "Source Sans 3";
    src: url("../fonts/source-sans-3-v19-latin-600.woff2") format("woff2");
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Source Sans 3";
    src: url("../fonts/source-sans-3-v19-latin-700.woff2") format("woff2");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}


/* ------------------------------------------------------------------
   2. Design-Tokens — Light Mode
   ------------------------------------------------------------------ */
/* LOGO-ABGLEICH — Primär, Akzent und Flächenton sind exakt die drei
   Farben der Wortmarke (aus dem Original gemessen). Die abgeleiteten
   Töne wurden um denselben HSL-Betrag mitgezogen, damit die Palette
   geschlossen bleibt.
   Nachgerechnete Kontraste (WCAG 2.x, vorher -> nachher):
     weiße Schrift auf --color-primary   7,72 -> 7,69 : 1  (AA ab 4,5)
     --color-primary  auf --color-surface 7,72 -> 7,69 : 1
     --color-primary  auf --color-bg      7,03 -> 6,94 : 1
     --color-accent   auf --color-surface 6,25 -> 5,93 : 1
     --color-accent   auf --color-bg      5,69 -> 5,35 : 1
     --color-ink      auf --color-bg     15,47 -> 15,34 : 1
   Kein Paar verschlechtert sich um mehr als 0,34; alle bleiben
   deutlich über AA. Der Dunkelmodus bleibt unverändert — er ist
   bereits abgestimmt und leitet sich nicht aus dem Logo ab. */
:root {
    /* Primär — Betriebsgrün, exakt das Grün der Wortmarke */
    --color-primary:            #1D5E41;
    --color-primary-hover:      #164731;
    --color-primary-active:     #104F30;
    --color-primary-soft:       #E6EFEA;

    /* Akzent — Werkstatt-Ocker, exakt das Ocker des Logo-Dachs */
    --color-accent:             #9F4D11;
    --color-accent-soft:        #FCF0E5;

    /* Neutraltöne */
    --color-ink:                #1A1D1B;
    --color-ink-muted:          #4A524D;
    /* ACHTUNG, K8: Dieser Wert steht ein zweites Mal als Literal im
       Data-URI des Auswahlmenue-Pfeils (Abschnitt 14, .field__select).
       Ein Data-URI kann keine CSS-Variable lesen. Wird der Ton hier
       geaendert, ist er dort mitzuziehen. */
    --color-surface:            #FFFFFF;
    --color-bg:                 #F5F3EF;   /* Creme des Logo-Hintergrunds */
    --color-bg-alt:             #EBE9E3;

    /* Linien */
    --color-line:               #D5DAD6;   /* NUR dekorativ */
    --color-border-input:       #6E7671;   /* Bedienelemente, ≥3:1 */

    /* Feedback */
    --color-success:            #16653C;
    --color-error:              #B3261E;
    --color-disabled-bg:        #DCE0DC;

    /* Fokus */
    --color-focus:              #1A1D1B;

    /* Bild-Scrim */
    --scrim:                    rgba(13, 19, 16, 0.82);

    /* Unterzeile der Wortmarke ("HAUSMEISTERSERVICE").
       Eigenes Token, weil sie als einziger Teil des Logos den Grund
       wechselt: Im Hellmodus steht sie auf Weiß (Kopf) bzw. auf dem
       Cremeton (Fuß) und bleibt grün; im Dunkelmodus stünde dasselbe
       Grün mit 2,07 : 1 praktisch unsichtbar auf dem dunklen Kopf. */
    --color-logo-unterzeile:    var(--color-primary);

    /* Textfarben auf Vollflächen */
    --color-on-primary:         #FFFFFF;
    --color-on-accent:          #FFFFFF;
    --color-on-error:           #FFFFFF;

    /* --- Farbschema ---
       W4 — Ohne diese Zeile haelt der Browser die Seite fuer hell und
       zeichnet Checkbox, aufgeklappte <select>-Liste, Bildlaufleisten
       und Autofill-Felder im Dunkelmodus weiterhin hell. Der Wert
       steht in BEIDEN CSS-Dateien, damit er schon aus dem inline
       eingebetteten critical.css greift und nicht erst, wenn
       style.css nachgeladen ist. */
    color-scheme: light dark;

    /* --- Typografie --- */
    --font-sans: "Source Sans 3", -apple-system, BlinkMacSystemFont, "Segoe UI",
                 Roboto, "Helvetica Neue", Arial, sans-serif;

    --fs-h1:    clamp(2rem,      1.45rem + 2.60vw, 3.25rem);
    --fs-h2:    clamp(1.625rem,  1.35rem + 1.30vw, 2.25rem);
    --fs-h3:    clamp(1.3125rem, 1.19rem + 0.60vw, 1.5rem);
    --fs-h4:    clamp(1.125rem,  1.08rem + 0.22vw, 1.25rem);
    --fs-lead:  clamp(1.1875rem, 1.09rem + 0.42vw, 1.375rem);
    --fs-body:  clamp(1.0625rem, 1.01rem + 0.28vw, 1.1875rem);
    --fs-small: clamp(0.9375rem, 0.92rem + 0.10vw, 1rem);
    --fs-eyebrow: 0.9375rem;
    --fs-btn:   clamp(1.0625rem, 1.01rem + 0.28vw, 1.1875rem);
    --fs-ordinal: clamp(2.5rem,  2rem + 2.2vw, 3.75rem);

    --lh-tight: 1.15;
    --lh-snug:  1.28;
    --lh-body:  1.65;
    --lh-ui:    1.35;

    --fw-regular:  400;
    --fw-semibold: 600;
    --fw-bold:     700;

    --ls-h1: -0.015em;
    --ls-h2: -0.010em;
    --ls-eyebrow: 0.08em;
    --ls-normal: 0;

    /* --- Spacing --- */
    --space-3xs: 0.25rem;
    --space-2xs: 0.5rem;
    --space-xs:  0.75rem;
    --space-sm:  1rem;
    --space-md:  1.5rem;
    --space-lg:  2rem;
    --space-xl:  3rem;
    --space-2xl: 4rem;
    --space-3xl: 5.5rem;

    --section-py:    clamp(3rem, 2rem + 5vw, 5.5rem);
    --section-py-lg: clamp(4rem, 2.5rem + 7.5vw, 7rem);
    --gutter:        clamp(1rem, 0.55rem + 2.25vw, 2rem);

    /* --- Radien --- */
    --radius-sm:   4px;
    --radius-md:   8px;
    --radius-lg:   14px;
    --radius-pill: 999px;

    /* --- Rahmenstärken --- */
    --bw-hair:  1px;
    --bw-input: 2px;
    --bw-error: 3px;
    --bw-edge:  6px;
    --bw-focus: 3px;

    /* --- Schatten --- */
    --shadow-sm: 0 1px 2px rgba(26, 29, 27, 0.08);
    --shadow-md: 0 1px 2px rgba(26, 29, 27, 0.06),
                 0 6px 14px rgba(26, 29, 27, 0.08);
    --shadow-lg: 0 2px 4px rgba(26, 29, 27, 0.06),
                 0 12px 28px rgba(26, 29, 27, 0.12);
    --shadow-header: 0 2px 8px rgba(26, 29, 27, 0.10);

    /* --- Container --- */
    --container-max:  1180px;
    --container-wide: 1360px;
    --container-text: 68ch;

    /* --- Motion --- */
    --dur-fast:   120ms;
    --dur-base:   180ms;
    --dur-slow:   280ms;
    --dur-reveal: 320ms;
    --ease-out:    cubic-bezier(0.22, 0.61, 0.36, 1);
    --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
}


/* ------------------------------------------------------------------
   3. Dark Mode
   ------------------------------------------------------------------ */
@media (prefers-color-scheme: dark) {
    :root {
        --color-primary:        #5FBE8B;
        --color-primary-hover:  #7ACFA1;
        --color-primary-active: #4FAE7C;
        --color-primary-soft:   #1B2E23;

        --color-accent:         #E2924F;
        --color-accent-soft:    #2E2318;

        --color-ink:            #F1F0EA;
        --color-ink-muted:      #B6BEB6;   /* K8: auch im Pfeil-Data-URI, siehe oben */
        --color-surface:        #1F231D;
        --color-bg:             #161915;
        --color-bg-alt:         #282D26;

        --color-line:           #3B423A;
        --color-border-input:   #7C857C;

        --color-success:        #62C98D;
        --color-error:          #F4A29B;
        --color-disabled-bg:    #2A2F28;

        --color-focus:          #F1F0EA;

        --scrim:                rgba(8, 11, 9, 0.86);

        /* Umkehr der Button-Logik: heller Grund, dunkle Schrift */
        /* Weiß für die Logo-Unterzeile — bewusst --color-ink und nicht
           reines #FFFFFF: Der Ton sitzt neben Navigation und Rufnummer,
           die ebenfalls in --color-ink stehen, und wirkt daneben nicht
           kälter. 13,97 : 1 auf --color-surface, 12,31 : 1 auf
           --color-bg-alt (Fuß) — beides weit über AA. */
        --color-logo-unterzeile: var(--color-ink);

        --color-on-primary:     #0D1310;
        --color-on-accent:      #0D1310;
        --color-on-error:       #0D1310;

        /* Schatten funktionieren auf dunklem Grund nicht. */
        --shadow-sm: none;
        --shadow-md: none;
        --shadow-lg: none;
        --shadow-header: 0 2px 8px rgba(0, 0, 0, 0.5);
    }
}


/* ------------------------------------------------------------------
   4. Reset und Grundlagen
   ------------------------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }

html {
    font-size: 100%;                 /* Zoom-Einstellung respektieren */
    scroll-behavior: smooth;
    /* W6 — Bezugsgröße ist der KOMPAKTE Kopf, nicht der aufgeklappte:
       Nach jedem Ankersprung ist .is-scrolled gesetzt. Kompakt misst er
       73 px (unter 900 px) bzw. 77 px (ab 900 px); plus 7 px Luft ergibt
       5rem bzw. 5.25rem. Nachgemessen landen alle fünf Abschnitte damit
       6,8 bis 7,3 px unter der Kopfunterkante. Dass der Kopf beim Sprung
       vom Seitenanfang aus überhaupt erst schrumpft, fängt main.js ab
       (Abschnitt 3 dort) — sonst hälfe hier kein Wert. */
    scroll-padding-top: 5rem;
    -webkit-text-size-adjust: 100%;
}
@media (min-width: 900px) {
    html { scroll-padding-top: 5.25rem; }
}

/* AUSNAHME FUER DEN SEITENANFANG
   ------------------------------------------------------------------
   scroll-padding-top haelt Ankerziele frei vom klebenden Kopf. Fuer
   #start ist dieser Versatz aber falsch: Das Ziel ist der Seitenanfang
   selbst. Ohne diese Regel landet ein Klick auf "Start" (und auf das
   Logo, das ebenfalls auf #start zeigt) bei einem Scrollwert oberhalb
   der 8 px, ab denen main.js .is-scrolled setzt — der Kopf bliebe in
   der kompakten Stufe und die volle Wortmarke kaeme nie wieder.
   scroll-margin-top vergroessert den Scroll-Bereich des Ziels nach
   oben; ist der Wert groesser als der Abstand des Hero vom
   Seitenanfang, ergaebe sich eine negative Zielposition, die der
   Browser auf 0 klemmt — die Seite faehrt also exakt an den Anfang.
   100vh statt eines festen Wertes, weil der Abstand veraenderlich ist:
   Der Stagingstreifen (rund 40 px) steht nur im Testbetrieb ueber dem
   Kopf, und der Kopf selbst ist aufgeklappt 93 px (mobil) bis 121 px
   (ab 900 px) hoch. Eine Viewporthoehe liegt immer sicher darueber.
   Gilt NUR fuer #start — alle anderen Ankerziele rasten weiterhin
   sauber unter dem Kopf ein. */
#start { scroll-margin-top: 100vh; }

body {
    margin: 0;
    background: var(--color-bg);
    color: var(--color-ink);
    font-family: var(--font-sans);
    font-size: var(--fs-body);
    line-height: var(--lh-body);
    font-weight: var(--fw-regular);
    -webkit-hyphens: auto;
    hyphens: auto;
    text-align: left;
}

body.is-locked { overflow: hidden; }

h1, h2, h3, h4 {
    overflow-wrap: break-word;
    -webkit-hyphens: auto;
    hyphens: auto;
    margin: 0 0 var(--space-sm);
}
h1 {
    font-size: var(--fs-h1);
    line-height: var(--lh-tight);
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-h1);
    text-wrap: balance;
}
h2 {
    font-size: var(--fs-h2);
    line-height: var(--lh-tight);
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-h2);
}
h3 { font-size: var(--fs-h3); line-height: var(--lh-snug); font-weight: var(--fw-semibold); }
h4 { font-size: var(--fs-h4); line-height: var(--lh-snug); font-weight: var(--fw-semibold); }

p { margin: 0 0 var(--space-sm); max-width: var(--container-text); }
p:last-child { margin-bottom: 0; }

ul, ol { margin: 0 0 var(--space-sm); padding-left: 1.25em; }
li { margin-bottom: var(--space-2xs); }

a { color: var(--color-primary); }
a:hover { color: var(--color-primary-hover); }

/* Links im Fließtext sind immer unterstrichen — Farbe allein reicht nicht. */
main p a,
main li a,
.faq__a a,
.legal a {
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 2px;
}

img { max-width: 100%; height: auto; display: block; }

strong, b { font-weight: var(--fw-semibold); }

address { font-style: normal; }

.icon { flex: none; }

/* Fokus — Ring immer AUSSERHALB des Elements (siehe Designdoku §11) */
:focus { outline: none; }
:focus-visible {
    outline: var(--bw-focus) solid var(--color-focus);
    outline-offset: 3px;
    border-radius: var(--radius-sm);
}

::selection { background: var(--color-primary-soft); color: var(--color-ink); }

main:focus { outline: none; }


/* ------------------------------------------------------------------
   5. Utilities
   ------------------------------------------------------------------ */
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 200;
    background: var(--color-primary);
    color: var(--color-on-primary);
    padding: var(--space-xs) var(--space-md);
    font-weight: var(--fw-semibold);
    text-decoration: none;
    border-radius: 0 0 var(--radius-md) 0;
}
.skip-link:focus {
    left: 0;
    color: var(--color-on-primary);
    outline: var(--bw-focus) solid var(--color-focus);
    outline-offset: 3px;
}

.media {
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--color-bg-alt);
    margin: 0;
}
.media img { width: 100%; height: 100%; object-fit: cover; }
@media (prefers-color-scheme: dark) {
    .media img { filter: brightness(0.92); }
}



/* ------------------------------------------------------------------
   6. Layout: Container und Sektionen
   ------------------------------------------------------------------ */
.container {
    width: 100%;
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--gutter);
    min-width: 0;
}
.container--wide { max-width: var(--container-wide); }
.container--text { max-width: var(--container-text); }
.container--faq  { max-width: 800px; }

.section { padding-block: var(--section-py); }
.section--hero { padding-block: var(--section-py-lg); background: var(--color-bg); }
.section--alt  { background: var(--color-bg-alt); }
.section--card { background: var(--color-surface); }
.section--contact { background: var(--color-primary-soft); }

.section__head {
    margin-bottom: var(--space-lg);
    max-width: 46ch;
}
.section__eyebrow {
    font-size: var(--fs-eyebrow);
    line-height: 1.3;
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-eyebrow);
    text-transform: uppercase;
    color: var(--color-accent);
    margin: 0 0 var(--space-2xs);
}
/* Nur im Hero groesser: Dort traegt die Zeile die Region und ist die
   erste Aussage der Seite. Bewusst NICHT ueber --fs-eyebrow geloest -
   das Token gilt fuer saemtliche Abschnitts-Eyebrows.
   Versalien, Laufweite und Ocker bleiben, damit sie nicht wie eine
   zweite Ueberschrift wirkt; sie bleibt klar unter .lead. */
.section--hero .section__eyebrow {
    font-size: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
    margin-bottom: var(--space-xs);
}
.section__title {
    font-size: var(--fs-h2);
    line-height: var(--lh-tight);
    font-weight: var(--fw-bold);
    margin: 0;
}
.section__title::after {
    content: "";
    display: block;
    width: 3rem;
    height: var(--bw-edge);
    background: var(--color-primary);
    margin-top: var(--space-sm);
}
.section__intro {
    margin-top: var(--space-md);
    font-size: var(--fs-lead);
    line-height: 1.5;
    color: var(--color-ink-muted);
    max-width: 46ch;
}


/* ------------------------------------------------------------------
   7. Header und Navigation
   ------------------------------------------------------------------ */
.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
    background: var(--color-surface);
    border-bottom: var(--bw-hair) solid var(--color-line);
    transition: box-shadow var(--dur-base) var(--ease-out);
}
.site-header.is-scrolled { box-shadow: var(--shadow-header); }

/* Dreizonen-Raster: Logo | Navigation | Telefon + Menüknopf.
   ------------------------------------------------------------------
   Warum Grid und nicht Flex mit `margin-inline: auto` am <nav>:
   Bei Flex verteilt sich der Restplatz gleichmäßig LINKS UND RECHTS
   vom Menü — die Navigation stünde also mittig zwischen Logo und
   Rufnummer nur so lange, wie beide gleich breit sind. Sie sind es
   nicht (Logo ~140 px, Rufnummer ~190 px), das Menü liefe sichtbar
   aus der Mitte. Mit `auto 1fr auto` ist die mittlere Spalte der
   gesamte Zwischenraum, und `justify-self: center` setzt das Menü
   exakt in dessen Mitte — unabhängig davon, wie breit die beiden
   Randzonen werden.
   `column-gap: var(--space-lg)` ist das Sicherheitsnetz: Auch wenn der
   Platz eng wird, bleiben 2rem zwischen Menü und Rufnummer stehen; das
   Menü weicht dann nach links aus, statt sie zu berühren.
   min-height ist eine Untergrenze, keine Obergrenze — der Kopf wächst
   im aufgeklappten Zustand mit dem großen Logo mit (siehe unten). */
.site-header__inner {
    max-width: var(--container-max);
    margin-inline: auto;
    padding: var(--space-xs) var(--gutter);
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    column-gap: var(--space-lg);
    min-height: 4rem;
    position: relative;
}
.site-header__inner > .brand { grid-column: 1; }
/* Spalte 3 auch dann, wenn das <nav> als Drawer ausgeklappt und damit
   aus dem Fluss genommen ist — sonst rutschte der rechte Block in die
   mittlere Spalte. */
.site-header__inner > .site-header__actions { grid-column: 3; justify-self: end; }
@media (min-width: 900px) {
    .site-header__inner { min-height: 4.75rem; }
}

.brand {
    display: flex;
    flex-direction: column;
    /* Ohne flex-start würde das einzelne <svg> als Flex-Kind quer über
       die volle Breite gedehnt. */
    align-items: flex-start;
    justify-content: center;
    text-decoration: none;
    color: var(--color-ink);
    line-height: 1.1;
    min-width: 0;
}

/* --- Wortmarke als Inline-SVG (includes/config.php: papps_logo()) ---
   Höhe wird vorgegeben, Breite folgt der viewBox. Bewusst KEIN festes
   Seitenverhältnis und keine width/height im Markup: die Datei wird
   künftig ersetzt, ihre Maße dürfen sich dabei ändern, ohne dass hier
   etwas verzerrt.
   Die feste Höhe verhindert zugleich den Layoutsprung — der Kopf steht
   schon vor dem Laden des SVG in seiner Endhöhe. */
.logo-papps {
    display: block;
    width: auto;
    max-width: 100%;
    height: 3rem;
    /* .brand ist ein Flex-Container mit fester Hoehe. Ohne flex: none
       staucht flex-shrink das SVG auf genau diese Hoehe zurueck - die
       Ueberhoehung fuer den Zuschnitt der kompakten Stufe waere damit
       wirkungslos. */
    flex: none;
}

/* ZWEI AUSBAUSTUFEN DERSELBEN MARKE IM KOPF
   ------------------------------------------------------------------
   Ganz oben steht die volle Wortmarke (Dach, "Papps", Unterzeile),
   nach dem Scrollen die kompakte ohne Unterzeile.

   WARUM: Die Unterzeile "HAUSMEISTERSERVICE" belegt in der viewBox nur
   109,87 bis 119,99 von 120 Einheiten — als gesperrte Versalschrift ist
   ihre Versalhöhe also rund 8,6 % der Logohöhe. Bei 48 px Logo sind das
   4,1 px: unlesbar. Bequem lesbar wird sie erst ab etwa 8 px, also bei
   rund 96 px Logohöhe. Statt sie unlesbar mitzuschleppen, wird sie in
   der kompakten Stufe abgeschaltet — dann darf die Marke klein sein,
   denn "Papps" allein misst rund die Hälfte der kompakten Höhe.

   KEINE zweite SVG-Datei: Das SVG wird inline eingebettet (~28 KB);
   eine zweite Fassung im selben Dokument würde das HTML unnötig
   aufblähen. Die Stufen sind reines CSS auf denselben drei Gruppen.

   DER FREIE RAUM UNTEN: Die viewBox bleibt 120 Einheiten hoch, auch
   ohne Unterzeile. Gezeichnet ist dann nur noch bis y = 103,05, also
   103,05 / 120 = 0,85875 der Höhe. Ohne Gegenmaßnahme stünde die Marke
   deshalb zu hoch in ihrer Box. Lösung: .brand bekommt die SICHTBARE
   Höhe und overflow: hidden, das SVG wird um den Kehrwert des Anteils
   größer skaliert — der gezeichnete Teil füllt die Box dann exakt aus,
   der leere Rest wird unten abgeschnitten.
   Der Anteil steht als Variable an EINER Stelle; ändert sich das SVG,
   ist nur diese Zeile nachzuziehen. */
.site-header {
    /* Sichtbarer Anteil der Marke, wenn die Unterzeile abgeschaltet ist:
       Unterkante von "Papps" liegt bei y = 103,05 von 120 Einheiten.
       Aus den Pfaddaten des SVG gemessen. Aendert sich die Datei, ist
       NUR diese Zeile nachzuziehen. */
    --logo-anteil-ohne-unterzeile: 0.85875;   /* 103,05 / 120 */
    /* Bei 0,85875 wird buendig an der Tinte geschnitten - die
       p-Unterlaengen enden exakt auf der Kante. In einer Zeile mit
       Rufnummer und Menueknopf wirkt das zu tief sitzend, deshalb
       bleiben unten zwei Pixel Luft. */
    --logo-luft-unten: 2px;
    --logo-hoehe: 4.25rem;                    /* 68 px, Unterzeile 5,8 px */
}
.site-header.is-scrolled { --logo-hoehe: 3rem; }   /* 48 px, kompakt */
@media (min-width: 900px) {
    /* 96 px — ab hier ist die Unterzeile mit 8,2 px bequem lesbar.
       Der Kopf ist oben damit 120 px hoch und geht beim Scrollen auf
       die gewohnten 76 px zurück. */
    .site-header { --logo-hoehe: 6rem; }
}

/* Der Link ist die sichtbare Box; das SVG darf darüber hinausragen. */
.site-header__inner > .brand {
    height: var(--logo-hoehe);
    overflow: hidden;
    /* Oben bündig, damit unten abgeschnitten wird und nicht mittig. */
    justify-content: flex-start;
    transition: height var(--dur-base) var(--ease-out);
}
.logo-papps--header {
    height: var(--logo-hoehe);
    transition: height var(--dur-base) var(--ease-out);
}
.site-header.is-scrolled .logo-papps--header {
    height: calc((var(--logo-hoehe) - var(--logo-luft-unten)) / var(--logo-anteil-ohne-unterzeile));
}
/* Nur im Kopf — im Fuß bleibt die volle Wortmarke stehen. */
.site-header.is-scrolled .logo-papps__unterzeile { display: none; }

/* W6 — Beim Ankersprung schrumpft der Kopf OHNE Animation, damit der
   Browser das Sprungziel bereits mit der kompakten Kopfhoehe berechnet.
   main.js setzt die Klasse nur fuer einen Frame; Begruendung dort. */
.site-header.is-snapping,
.site-header.is-snapping .brand,
.site-header.is-snapping .logo-papps--header { transition: none; }

/* Im Fuß darf die Marke größer stehen — dort ist sie Absenderangabe
   und konkurriert mit keiner Bedienleiste.
   W7 — 4rem (64 px) ließen der Unterzeile nur 5,40 px Höhe, weniger
   als der bekannte Grenzfall im Kopf auf dem Handy (5,76 px). Die
   Unterzeile ist 8,6 % der Logohöhe, für lesbare 8 px braucht es also
   rund 96 px. 6rem = 96 px, Breite 142 px — die schmalste Fußspalte
   ist 232 px breit, es bleibt also Platz. */
.logo-papps--footer { height: 6rem; }

/* KEIN PENDELN AN DER SCROLLSCHWELLE
   ------------------------------------------------------------------
   main.js setzt .is-scrolled ab scrollY > 8. Schrumpft der Kopf dabei
   um rund 45 px, rückt aller Inhalt darunter nach oben — und Chromes
   Scroll-Anchoring gleicht das aus, indem es scrollTop um denselben
   Betrag VERRINGERT. Aus scrollY = 9 wird dadurch 0, die Klasse fällt
   wieder weg, der Kopf wächst: Das Logo pendelte sichtbar zwischen
   groß und klein. Nachgemessen: ohne diese Zeile sprang der Kopf im
   Bereich scrollY 9 bis 28 hin und her.
   Die saubere Lösung wäre eine Hysterese in der JS — die ist hier
   tabu, und Scroll-Anchoring abzuschalten ist der korrekte CSS-Weg:
   Die Seite reserviert für alle Bilder über width/height bzw.
   aspect-ratio ohnehin festen Platz, es gibt also keine nachladenden
   Inhalte, gegen die verankert werden müsste. */
body { overflow-anchor: none; }

/* Farben kommen aus den Tokens, NICHT aus den fill-Attributen im SVG.
   Ein Präsentationsattribut hat die niedrigste Priorität, jede
   Klassenregel schlägt es — dadurch trägt der Dunkelmodus automatisch
   (dort ist --color-primary #5FBE8B, --color-accent #E2924F).
   Nachgerechnet auf --color-surface im Dunkelmodus (#1F231D):
   Grün 7,01 : 1, Ocker 6,43 : 1 — beide weit über den 3 : 1, die für
   grafische Objekte gefordert sind. Eigene Dunkelmodus-Werte für das
   Logo sind deshalb nicht nötig. */
.logo-papps__wort { fill: var(--color-primary); }
.logo-papps__dach { fill: var(--color-accent); }
/* Eigene Farbe, siehe --color-logo-unterzeile in Abschnitt 2. Gilt für
   Kopf UND Fuß — beide Gründe wechseln mit dem Farbschema. */
.logo-papps__unterzeile { fill: var(--color-logo-unterzeile); }

/* Rückfall-Wortmarke: greift nur, wenn assets/img/logo-papps.svg fehlt
   oder unlesbar ist (siehe papps_logo() in includes/config.php).
   Die Regeln bleiben deshalb erhalten, obwohl im Normalfall das SVG
   ausgeliefert wird. */
.brand__name {
    font-size: var(--fs-h4);
    font-weight: var(--fw-bold);
    color: var(--color-ink);
}
.brand__sub {
    font-size: var(--fs-small);
    font-weight: var(--fw-regular);
    color: var(--color-ink-muted);
}
.brand--footer { display: flex; margin: 0 0 var(--space-sm); }

.site-header__actions {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
}

/* Telefon-Button — auf Mobil immer sichtbar, nie hinter dem Menü */
.phone-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2xs);
    min-width: 3rem;
    min-height: 3rem;
    padding: 0 var(--space-xs);
    border-radius: var(--radius-md);
    background: var(--color-primary);
    color: var(--color-on-primary);
    text-decoration: none;
    font-weight: var(--fw-bold);
    font-size: var(--fs-h4);
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
    transition: background-color var(--dur-fast) var(--ease-out);
}
.phone-btn:hover { background: var(--color-primary-hover); color: var(--color-on-primary); }
/* M7 — Die Rufnummer ist ab 900 px LESBARER TEXT, nicht nur ein Icon.
   Designrichtung §6.4 verlangt sie dort ausdrücklich; für die
   Zielgruppe 50+ ist die abtippbare Nummer der wichtigste Weg. */
.phone-btn__text { display: none; }
@media (min-width: 900px) {
    .phone-btn__text { display: inline; }
}

/* Burger */
.nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    padding: 0;
    background: transparent;
    border: var(--bw-input) solid transparent;
    border-radius: var(--radius-md);
    color: var(--color-ink);
    cursor: pointer;
}
.nav-toggle:hover { background: var(--color-primary-soft); }
.nav-toggle__bars { display: block; width: 24px; height: 18px; position: relative; }
.nav-toggle__bars span {
    position: absolute;
    left: 0;
    width: 24px;
    height: 2px;
    background: currentColor;
    border-radius: 2px;
    transition: transform var(--dur-base) var(--ease-out),
                opacity var(--dur-fast) var(--ease-out);
}
.nav-toggle__bars span:nth-child(1) { top: 0; }
.nav-toggle__bars span:nth-child(2) { top: 8px; }
.nav-toggle__bars span:nth-child(3) { top: 16px; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(1) { transform: translateY(8px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars span:nth-child(3) { transform: translateY(-8px) rotate(-45deg); }

/* Mobil-Drawer: Full-Width direkt unter dem Header.
   Ohne JavaScript ist das <nav> sichtbar (kein display:none per Default). */
.site-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--color-surface);
    border-top: var(--bw-hair) solid var(--color-line);
    box-shadow: var(--shadow-lg);
    /* Symmetrisch, seit unter dem letzten Menuepunkt kein CTA-Button
       mehr steht - sonst blieb unten ein leerer Streifen stehen. */
    padding-block: var(--space-2xs);
}
.site-nav.is-hidden { display: none; }
.site-nav.is-open {
    animation: papps-drawer var(--dur-slow) var(--ease-out);
}
@keyframes papps-drawer {
    from { opacity: 0; transform: translateY(-8px); }
    to   { opacity: 1; transform: translateY(0); }
}

.site-nav__list { list-style: none; margin: 0; padding: 0; }
.site-nav__item { margin: 0; border-bottom: var(--bw-hair) solid var(--color-line); }
/* Seit dem Wegfall des CTA-Buttons ist der letzte Menuepunkt auch das
   Ende des Drawers. Ohne diese Zeile stuende dort eine Trennlinie ohne
   etwas darunter. */
.site-nav__item:last-child { border-bottom: 0; }
.site-nav__link {
    display: flex;
    align-items: center;
    min-height: 3.25rem;         /* 52 px */
    padding-inline: var(--gutter);
    color: var(--color-ink);
    text-decoration: none;
    font-size: var(--fs-body);
    font-weight: var(--fw-semibold);
    line-height: var(--lh-ui);
    border-left: var(--bw-edge) solid transparent;
}
.site-nav__link:hover { background: var(--color-primary-soft); color: var(--color-ink); }
/* Aktiv: Farbe + Fettung + Balken — nie nur Farbe */
.site-nav__link.is-active {
    color: var(--color-primary);
    font-weight: var(--fw-bold);
    border-left-color: var(--color-primary);
    background: var(--color-primary-soft);
}
/* M7 — Waagerechte Navigation erst ab 1200 px, nicht ab 900 px.
   ------------------------------------------------------------------
   Gemessen bei 900 px Viewport: Der Header-Innenraum ist dort rund
   842 px breit (900 px minus 2 × 29 px Gutter). Nebeneinander müssten
   hineinpassen: Wortmarke (~145 px), Telefon-Button mit lesbarer
   Nummer (~190 px) und sechs Navigationspunkte samt Abständen
   (~550 px) — zusammen über 880 px. Es passt schlicht nicht.
   (Der CTA-Button „Anfrage senden" ist auf Kundenwunsch aus dem Menü
   entfernt; er brauchte hier zuvor weitere ~185 px.)
   Aufgelöst wird der Konflikt zugunsten der lesbaren Rufnummer
   (Designrichtung §6.4, Zielgruppe 50+): Sie erscheint ab 900 px,
   die Navigation bleibt bis 1199 px im Drawer hinter dem Burger —
   dort ist sie vollständig und mit 52 px hohen Einträgen sogar besser
   bedienbar als eine gequetschte Leiste.
   ACHTUNG: Dieser Wert muss mit `desktop` in assets/js/main.js und
   mit critical.css übereinstimmen. */
@media (min-width: 1200px) {
    .site-nav {
        position: static;
        display: flex !important;   /* Drawer-Zustand gilt nur mobil */
        align-items: center;
        gap: var(--space-md);
        background: none;
        border: 0;
        box-shadow: none;
        padding: 0;
        animation: none;
    }
    .site-nav.is-hidden { display: flex !important; }
    .site-nav__list { display: flex; align-items: center; gap: var(--space-md); }
    .site-nav__item { border: 0; }
    .site-nav__link {
        min-height: 3rem;
        padding-inline: 0;
        border-left: 0;
        border-bottom: 3px solid transparent;
        padding-bottom: 6px;
    }
    .site-nav__link:hover { background: none; color: var(--color-primary-hover); }
    .site-nav__link.is-active {
        background: none;
        border-bottom-color: var(--color-primary);
        border-left-color: transparent;
        font-weight: var(--fw-semibold);
    }
    /* Mittlere Rasterzelle, Menü darin zentriert. Erst hier — solange
       das <nav> Drawer ist, darf es KEINE Rasterposition bekommen:
       Ein absolut positioniertes Rasterkind mit fester Spalte wird an
       seiner Rasterzelle ausgerichtet statt am Kopf, der Drawer klappte
       dann nur über der mittleren Spalte auf statt über der vollen
       Breite. */
    .site-header__inner > .site-nav { grid-column: 2; justify-self: center; }
    .nav-toggle { display: none; }
}


/* ------------------------------------------------------------------
   8. Buttons
   ------------------------------------------------------------------ */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2xs);
    min-height: 3rem;
    padding: 0.75rem 1.5rem;
    font-family: var(--font-sans);
    font-size: var(--fs-btn);
    font-weight: var(--fw-semibold);
    line-height: var(--lh-ui);
    text-decoration: none;
    text-align: center;
    border-radius: var(--radius-md);
    border: var(--bw-input) solid transparent;
    cursor: pointer;
    transition: background-color var(--dur-fast) var(--ease-out),
                border-color var(--dur-fast) var(--ease-out),
                color var(--dur-fast) var(--ease-out),
                transform 100ms var(--ease-out);
}

.btn--primary {
    background: var(--color-primary);
    color: var(--color-on-primary);
    box-shadow: var(--shadow-sm);
}
.btn--primary:hover { background: var(--color-primary-hover); color: var(--color-on-primary); }
.btn--primary:active {
    background: var(--color-primary-active);
    transform: translateY(1px);
    box-shadow: none;
}
.btn--primary[disabled] {
    background: var(--color-disabled-bg);
    color: var(--color-ink-muted);
    cursor: not-allowed;
    box-shadow: none;
}

.btn--secondary {
    background: var(--color-surface);
    color: var(--color-primary);
    border-color: var(--color-primary);
}
.btn--secondary:hover {
    background: var(--color-primary-soft);
    color: var(--color-primary-hover);
    border-color: var(--color-primary-hover);
}
.btn--secondary:active {
    background: var(--color-primary-soft);
    color: var(--color-primary-active);
    border-color: var(--color-primary-active);
    transform: translateY(1px);
}
.btn--secondary[disabled] {
    background: transparent;
    color: var(--color-ink-muted);
    border-color: var(--color-border-input);
    cursor: not-allowed;
}
@media (prefers-color-scheme: dark) {
    .btn--secondary { background: transparent; }
}

.btn--quiet {
    background: none;
    border: 0;
    padding: 0.625rem 0;
    min-height: 3rem;
    color: var(--color-primary);
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 2px;
    justify-content: flex-start;
}
.btn--quiet:hover {
    color: var(--color-primary-hover);
    text-decoration-thickness: 3px;
}

/* Auf Mobil sind Primär und Sekundär volle Breite, gestapelt. */
@media (max-width: 679px) {
    .hero__actions .btn,
    .form__submit { width: 100%; }
}


/* ------------------------------------------------------------------
   9. Hero und Vertrauensband
   ------------------------------------------------------------------ */
.hero__grid { display: grid; gap: var(--space-xl); min-width: 0; }
.hero__text { min-width: 0; }
.hero__title { margin-bottom: var(--space-md); }

.lead {
    font-size: var(--fs-lead);
    line-height: 1.5;
    color: var(--color-ink-muted);
    max-width: 34ch;
    margin-bottom: var(--space-lg);
}

.hero__actions {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
    align-items: stretch;
}
@media (min-width: 680px) {
    .hero__actions { flex-direction: row; align-items: center; flex-wrap: wrap; }
}

.hero__media { aspect-ratio: 3 / 2; }

@media (min-width: 1440px) {
    .hero__grid {
        grid-template-columns: 55fr 45fr;
        align-items: center;
        gap: var(--space-2xl);
    }
}

.trustband {
    background: var(--color-primary);
    color: var(--color-on-primary);
    padding-block: var(--space-md);
}
.trustband__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-sm);
}
.trustband__item {
    margin: 0;
    font-size: var(--fs-small);
    line-height: 1.5;
    color: var(--color-on-primary);
    padding-inline: var(--space-md);
}
.trustband__item strong {
    display: block;
    font-size: var(--fs-body);
    font-weight: var(--fw-bold);
    color: var(--color-on-primary);
}
/* W1 — Die Schwelle lag bei 480 px und war damit zu frueh: Die drei
   Rastereintraege brauchen zusammen rund 492 px Mindestinhaltsbreite
   (gemessen 160 + 157,6 + 141,9 plus zweimal 16 px Abstand). Bei
   480 px Fensterbreite standen dafuer nur 425 px zur Verfuegung - die
   Seite bekam 39 px waagerechten Ueberstand, bei 500 px 20 px, bei
   520 px 2 px. min-width: 0 am Rasterkind haette zwar den Ueberstand
   der SEITE beseitigt, dafuer aber den Text aus der eigenen Spalte
   treten lassen (nachgemessen 26 px ueber die Trennlinie hinweg).
   Deshalb wird spaeter umgeschaltet statt enger gequetscht. */
@media (min-width: 600px) {
    .trustband__list { grid-template-columns: repeat(3, 1fr); }
    .trustband__item { padding-inline: 0 var(--space-md); }
    .trustband__item + .trustband__item {
        border-inline-start: var(--bw-hair) solid rgba(255, 255, 255, 0.35);
        padding-inline-start: var(--space-md);
    }
}
@media (prefers-color-scheme: dark) {
    .trustband__item + .trustband__item {
        border-inline-start-color: rgba(13, 19, 16, 0.35);
    }
}


/* ------------------------------------------------------------------
   10. Leistungs-Karten
   ------------------------------------------------------------------ */
.services__grid {
    display: grid;
    gap: var(--space-md);
    grid-template-columns: 1fr;
}
@media (min-width: 680px) {
    .services__grid { grid-template-columns: repeat(2, 1fr); }
    /* M8 — Karte 3 nimmt die volle Breite der zweiten Reihe ein und
       wird dort HORIZONTAL: Bild links 40 %, Text rechts 60 %
       (Designrichtung §7). Volle Breite mit Bild oben würde ein
       überdimensioniertes Foto und eine halbleere Zeile ergeben.
       Umgesetzt als eigenes Grid innerhalb der Karte, damit
       „height: 100%" und der Fuß-Link unten weiter funktionieren. */
    .services__grid > :nth-child(3) {
        grid-column: 1 / -1;
        display: grid;
        grid-template-columns: 40% 60%;
        column-gap: var(--space-md);
        align-content: start;
    }
    .services__grid > :nth-child(3) .service-card__media {
        grid-column: 1;
        grid-row: 1 / span 4;
        align-self: start;
        margin-bottom: 0;
    }
    .services__grid > :nth-child(3) .service-card__title,
    .services__grid > :nth-child(3) .service-card__text,
    .services__grid > :nth-child(3) .service-card__list,
    .services__grid > :nth-child(3) .service-card__foot {
        grid-column: 2;
    }
    .services__grid > :nth-child(3) .service-card__foot { margin-top: 0; }
}
@media (min-width: 900px) {
    .services__grid { gap: var(--space-lg); grid-template-columns: repeat(3, 1fr); }
    /* Ab 3 Spalten ist Karte 3 wieder eine normale, senkrechte Karte. */
    .services__grid > :nth-child(3) {
        grid-column: auto;
        display: flex;
        flex-direction: column;
    }
    .services__grid > :nth-child(3) .service-card__media {
        margin-bottom: var(--space-sm);
    }
    .services__grid > :nth-child(3) .service-card__foot { margin-top: auto; }
}

.service-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-width: 0;
    background: var(--color-surface);
    border: var(--bw-hair) solid var(--color-line);
    border-left: var(--bw-edge) solid var(--color-primary);
    border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
    padding: var(--space-md);
    box-shadow: var(--shadow-md);
    scroll-margin-top: 5.5rem;
    transition: box-shadow var(--dur-base) var(--ease-out),
                transform var(--dur-base) var(--ease-out),
                border-color var(--dur-base) var(--ease-out);
}
.service-card--accent { border-left-color: var(--color-accent); }
@media (min-width: 900px) {
    .service-card { padding: var(--space-lg); }
}
.service-card:hover {
    box-shadow: var(--shadow-lg);
    transform: translateY(-2px);
    border-color: var(--color-border-input);
}
.service-card--accent:hover { border-left-color: var(--color-accent); }
.service-card:hover { border-left-color: var(--color-primary); }
.service-card--accent:hover { border-left-color: var(--color-accent); }
.service-card:focus-within {
    outline: var(--bw-focus) solid var(--color-focus);
    outline-offset: 3px;
}

.service-card__media {
    aspect-ratio: 4 / 3;
    border-radius: var(--radius-md);
    margin-bottom: var(--space-sm);
}
.service-card__title { margin: 0 0 var(--space-2xs); }
.service-card__text { color: var(--color-ink); margin-bottom: var(--space-sm); }

.service-card__list {
    list-style: none;
    margin: 0 0 var(--space-md);
    padding: 0;
}
.service-card__list li {
    position: relative;
    padding-left: 1.25em;
    margin-bottom: var(--space-2xs);
}
.service-card__list li::before {
    content: "–";
    position: absolute;
    left: 0;
    color: var(--color-accent);
    font-weight: var(--fw-bold);
}

.service-card__foot { margin: auto 0 0; }


/* ------------------------------------------------------------------
   11. Warum Papps (mit Portrait)
   ------------------------------------------------------------------ */
.about__grid { display: grid; gap: var(--space-lg); min-width: 0; }
@media (min-width: 900px) {
    .about__grid { grid-template-columns: 320px 1fr; gap: var(--space-2xl); align-items: start; }
}
.about__portrait {
    aspect-ratio: 1 / 1;
    max-width: 320px;
    border-left: var(--bw-edge) solid var(--color-accent);
    border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
}

.reasons { display: grid; gap: var(--space-lg); min-width: 0; }
@media (min-width: 680px) {
    .reasons { grid-template-columns: repeat(2, 1fr); gap: var(--space-lg) var(--space-xl); }
}
.reason__title { margin: 0 0 var(--space-2xs); }
.reason p { color: var(--color-ink); margin: 0; }


/* ------------------------------------------------------------------
   12. Ablauf
   ------------------------------------------------------------------ */
.steps {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-lg);
    position: relative;
}
.step {
    margin: 0;
    min-width: 0;
    padding-left: var(--space-md);
    border-left: 3px solid var(--color-line);
}
.step__num {
    font-size: var(--fs-ordinal);
    line-height: 1;
    font-weight: var(--fw-bold);
    color: var(--color-accent);
    font-variant-numeric: tabular-nums;
    margin: 0 0 var(--space-2xs);
}
.step__title { margin: 0 0 var(--space-2xs); }
.step__text { margin: 0; color: var(--color-ink); }

@media (min-width: 680px) {
    .steps { grid-template-columns: repeat(3, 1fr); gap: var(--space-xl); }
    .step { padding-left: 0; border-left: 0; }
}


/* ------------------------------------------------------------------
   13. FAQ
   ------------------------------------------------------------------ */
.faq { border-top: var(--bw-hair) solid var(--color-line); }

.faq__item { border-bottom: var(--bw-hair) solid var(--color-line); }

.faq__q {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
    min-height: 3.25rem;
    padding-block: var(--space-sm);
    cursor: pointer;
    list-style: none;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q:hover { color: var(--color-primary-hover); }
.faq__q:focus-visible {
    outline: var(--bw-focus) solid var(--color-focus);
    outline-offset: 3px;
}
.faq__q-text {
    margin: 0;
    font-size: var(--fs-h4);
    line-height: var(--lh-snug);
    font-weight: var(--fw-semibold);
    color: inherit;
}
.faq__chevron {
    color: var(--color-primary);
    transition: transform var(--dur-slow) var(--ease-in-out);
}
.faq__item[open] .faq__chevron { transform: rotate(90deg); }

.faq__a { padding-bottom: var(--space-md); }
.faq__a p { margin: 0; max-width: 68ch; }


/* ------------------------------------------------------------------
   14. Kontakt und Formular
   ------------------------------------------------------------------ */
.contact__grid { display: grid; gap: var(--space-xl); min-width: 0; }
@media (min-width: 900px) {
    /* Feste 640 px für das Formular ließen der Nebenspalte bei genau
       900 px nur 123 px — Rufnummer, Öffnungszeiten und Karte standen
       dort zerquetscht. Mit einem Verhältnis wächst das Formular mit
       und erreicht ab 1200 px wieder rund 650 px. */
    .contact__grid { grid-template-columns: 1fr 1.6fr; gap: var(--space-2xl); align-items: start; }
}

.contact__aside { min-width: 0; }
.contact__label {
    font-size: var(--fs-small);
    font-weight: var(--fw-bold);
    text-transform: uppercase;
    letter-spacing: var(--ls-eyebrow);
    color: var(--color-accent);
    margin-bottom: var(--space-2xs);
}
.contact__phone { margin-bottom: var(--space-2xs); }
.contact__phone a {
    font-size: var(--fs-h1);
    line-height: 1.1;
    font-weight: var(--fw-bold);
    color: var(--color-primary);
    font-variant-numeric: tabular-nums;
    text-decoration: none;
    display: inline-block;
    padding-block: var(--space-3xs);
}
.contact__phone a:hover { color: var(--color-primary-hover); text-decoration: underline; }
.contact__mail { margin-top: var(--space-md); }
/* Einleitung zu den Ortsschildchen. Hieß früher .contact__maphint,
   weil darüber eine Einsatzgebietskarte stand; die ist entfallen.
   Der Abstand nach oben ist größer als vorher, weil die Zeile jetzt
   direkt an der E-Mail-Zeile hängt statt an einem Bild. */
.contact__gebiethint {
    margin-top: var(--space-lg);
    font-size: var(--fs-small);
    line-height: 1.5;
    color: var(--color-ink-muted);
    max-width: 420px;
}

.opening-hours {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-3xs) var(--space-sm);
    margin: 0 0 var(--space-sm);
    font-size: var(--fs-small);
}
.opening-hours dt { color: var(--color-ink-muted); }
.opening-hours dd {
    margin: 0;
    font-variant-numeric: tabular-nums;
    color: var(--color-ink);
}

.contact__formwrap {
    background: var(--color-surface);
    border: var(--bw-hair) solid var(--color-line);
    border-radius: var(--radius-lg);
    padding: var(--space-md);
    box-shadow: var(--shadow-md);
    min-width: 0;
}
@media (min-width: 680px) {
    .contact__formwrap { padding: var(--space-lg); }
}

.form__required-hint {
    font-size: var(--fs-small);
    color: var(--color-ink-muted);
    margin-bottom: var(--space-md);
}

.field {
    display: flex;
    flex-direction: column;
    gap: var(--space-3xs);
    margin-bottom: var(--space-md);
}
.field__label {
    font-weight: var(--fw-semibold);
    font-size: var(--fs-body);
    line-height: var(--lh-ui);
    color: var(--color-ink);
}
.field__req { color: var(--color-error); margin-left: 0.15em; }
.field__hint { font-size: var(--fs-small); line-height: 1.5; color: var(--color-ink-muted); margin: 0; }

.field__input {
    width: 100%;
    min-height: 3rem;
    padding: 0.6875rem 0.875rem;
    font-family: var(--font-sans);
    font-size: var(--fs-body);
    font-weight: var(--fw-regular);
    line-height: var(--lh-ui);
    color: var(--color-ink);
    background: var(--color-surface);
    border: var(--bw-input) solid var(--color-border-input);
    border-radius: var(--radius-md);
    transition: border-color var(--dur-fast) var(--ease-out);
}
.field__input::placeholder { color: var(--color-ink-muted); }
.field__input:hover { border-color: var(--color-ink-muted); }
.field__input:focus-visible {
    border-color: var(--color-primary);
    outline: var(--bw-focus) solid var(--color-focus);
    outline-offset: 2px;
}
.field__input[disabled] {
    border-color: var(--color-line);
    background: var(--color-disabled-bg);
    color: var(--color-ink-muted);
}
textarea.field__input {
    min-height: 8rem;
    resize: vertical;
    line-height: var(--lh-body);
}
/* K8 — Der Pfeil ist ein Data-URI; darin ist keine CSS-Variable
   moeglich. stroke='%234A524D' ist deshalb ein Literal und muss mit
   --color-ink-muted (Abschnitt 2) uebereinstimmen. Eine mask-Loesung
   waere variablenfaehig, kostet aber eine zweite Regel je Zustand
   ohne sichtbaren Gewinn - der Hinweis hier ist die guenstigere
   Absicherung. */
.field__select { appearance: none; padding-right: 2.5rem;
    background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%234A524D' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.75rem center;
}
/* stroke='%23B6BEB6' = --color-ink-muted im Dunkelmodus, siehe oben. */
@media (prefers-color-scheme: dark) {
    .field__select {
        background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23B6BEB6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    }
}

/* Fehlerzustand: Rahmen + Icon + Klartext — nie nur Farbe */
.field--error .field__input { border-width: var(--bw-error); border-color: var(--color-error); }
.field__error {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3xs);
    font-size: var(--fs-small);
    line-height: 1.45;
    font-weight: var(--fw-semibold);
    color: var(--color-error);
    margin: 0;
}

/* Checkbox */
.field--check { gap: var(--space-2xs); }
.check { display: flex; align-items: flex-start; gap: var(--space-xs); }
/* N8 — Tap-Target 48 × 48 px (Designrichtung §11), nicht 24 × 24.
   Ein natives <input type="checkbox"> lässt sich nicht per padding
   vergrößern (die UA-Darstellung ignoriert es) und `transform: scale`
   verkleinert auch die Trefferfläche mit. Deshalb sitzt das Kästchen
   in einem 48 × 48 px großen Wrapper: Optik bleibt bei 24 px, die
   klickbare Fläche misst 48 px. */
.check__boxwrap {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
}
.check__box {
    width: 1.5rem;
    height: 1.5rem;
    margin: 0;
    accent-color: var(--color-primary);
}
.check__label {
    font-size: var(--fs-small);
    line-height: 1.5;
    color: var(--color-ink);
    padding-block: var(--space-2xs);
}
.field--check.field--error .check__box { outline: var(--bw-error) solid var(--color-error); outline-offset: 2px; }

/* Honeypot: für Menschen unsichtbar, für Screenreader nicht vorgelesen */
.honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* Sammelmeldungen */
.formmsg {
    display: flex;
    align-items: flex-start;
    gap: var(--space-xs);
    padding: var(--space-md);
    margin-bottom: var(--space-md);
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
    font-size: var(--fs-body);
}
.formmsg--error {
    background: var(--color-surface);
    border: var(--bw-hair) solid var(--color-error);
    border-left: var(--bw-edge) solid var(--color-error);
    color: var(--color-ink);
}
/* M6 — `.formmsg--success` ist ersatzlos ENTFERNT.
   Die Regel war tot: Der Erfolgsfall wird nicht als Inline-Block über
   dem Formular ausgegeben, sondern per PRG-Redirect auf danke.php
   (siehe includes/contact-handler.php). Diese Seite bringt ihr eigenes
   `.pagemsg`-Layout mit. Zwei Erfolgsdarstellungen nebeneinander zu
   pflegen wäre eine Fehlerquelle; die Redirect-Variante bleibt, weil
   sie ein Neuladen (F5) unschädlich macht. */
.formmsg .icon { color: var(--color-error); margin-top: 0.15em; }
.formmsg p { margin: 0 0 var(--space-2xs); }
.formmsg p:last-child { margin-bottom: 0; }
.formmsg__list { margin: var(--space-2xs) 0 0; padding-left: 1.25em; font-size: var(--fs-small); }
.formmsg__list a { color: var(--color-error); text-decoration: underline; text-underline-offset: 3px; }
.formmsg:focus { outline: none; }
.formmsg:focus-visible { outline: var(--bw-focus) solid var(--color-focus); outline-offset: 3px; }


/* ------------------------------------------------------------------
   15. Footer
   ------------------------------------------------------------------ */
.site-footer {
    background: var(--color-bg-alt);
    border-top: var(--bw-edge) solid var(--color-primary);
    padding-block: var(--space-xl) var(--space-lg);
    color: var(--color-ink);
}
/* Der Fuss traegt nur noch Wortmarke und Claim; Kontakt, Leistungen
   und Einsatzgebiet sind auf Kundenwunsch entfallen (sie standen
   bereits im Kontaktabschnitt). Deshalb EINE Spalte, keine
   Umschaltpunkte mehr. Die Breite begrenzt der Claim selbst über
   seine Zeilenlänge, damit er auf breiten Schirmen nicht als eine
   endlose Zeile steht. */
.site-footer__grid { display: grid; gap: var(--space-lg); min-width: 0; }
.site-footer__col { min-width: 0; }
.site-footer__claim {
    color: var(--color-ink-muted);
    font-size: var(--fs-small);
    line-height: 1.6;
    max-width: 46ch;
    margin-bottom: 0;
}

/* N3 — 48 px Tap-Target sicher erreicht.
   Vorher: padding-block 10 px + Zeilenhöhe ergab je nach Schriftgröße
   nur rund 45 px. min-height garantiert die Höhe unabhängig von der
   Schrift, inline-flex zentriert den Text darin. */
.footer-link {
    display: inline-flex;
    align-items: center;
    min-height: 3rem;
    padding-block: 0.625rem;
    color: var(--color-primary);
    font-size: var(--fs-small);
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 2px;
}
.footer-link:hover { color: var(--color-primary-hover); text-decoration-thickness: 3px; }
.footer-link--phone {
    font-size: var(--fs-h4);
    font-weight: var(--fw-bold);
    font-variant-numeric: tabular-nums;
}

.chips { list-style: none; display: flex; flex-wrap: wrap; gap: var(--space-2xs); margin: var(--space-2xs) 0 0; padding: 0; }
.chip {
    margin: 0;
    padding: var(--space-3xs) var(--space-xs);
    border: var(--bw-hair) solid var(--color-line);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
    font-size: var(--fs-small);
    color: var(--color-ink);
}

.site-footer__legal {
    border-top: var(--bw-hair) solid var(--color-line);
    padding-top: var(--space-md);
    margin-top: var(--space-xl);
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2xs) var(--space-lg);
    align-items: center;
    justify-content: space-between;
}
.site-footer__copy { font-size: var(--fs-small); color: var(--color-ink-muted); margin: 0; }
.site-footer__legalnav ul {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-sm) var(--space-md);
    margin: 0;
    padding: 0;
}
.site-footer__legalnav li { margin: 0; }


/* ------------------------------------------------------------------
   16. Rechtsseiten, Danke-Seite, 404
   ------------------------------------------------------------------ */
.page-head { padding-block: var(--section-py) var(--space-lg); background: var(--color-bg); }
.page-head h1 { margin-bottom: 0; }

.breadcrumb { font-size: var(--fs-small); margin-bottom: var(--space-md); }
.breadcrumb ol { list-style: none; display: flex; flex-wrap: wrap; gap: var(--space-3xs) var(--space-2xs); margin: 0; padding: 0; }
.breadcrumb li { margin: 0; color: var(--color-ink-muted); }
.breadcrumb a { color: var(--color-primary); text-decoration: underline; text-underline-offset: 3px; }

.legal { padding-block: var(--space-lg) var(--section-py); background: var(--color-bg); }
.legal h2 { margin-top: var(--space-xl); }
.legal h3 { margin-top: var(--space-lg); }
.legal p, .legal li { max-width: var(--container-text); }
.legal dl { margin: 0 0 var(--space-sm); }
.legal dt { font-weight: var(--fw-semibold); margin-top: var(--space-2xs); }
.legal dd { margin: 0 0 var(--space-2xs); }

.pagemsg {
    padding-block: var(--section-py-lg);
    background: var(--color-primary-soft);
}
.pagemsg__box {
    max-width: 640px;
    background: var(--color-surface);
    border: var(--bw-hair) solid var(--color-line);
    border-left: var(--bw-edge) solid var(--color-success);
    border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
    padding: var(--space-lg);
    box-shadow: var(--shadow-md);
}
.pagemsg__box:focus { outline: none; }
.pagemsg__box:focus-visible { outline: var(--bw-focus) solid var(--color-focus); outline-offset: 3px; }
.pagemsg__icon { color: var(--color-success); margin-bottom: var(--space-sm); }
.pagemsg__actions { display: flex; flex-wrap: wrap; gap: var(--space-xs); margin-top: var(--space-lg); }

.error-page { padding-block: var(--section-py-lg); background: var(--color-bg); }
.error-page__code {
    font-size: var(--fs-ordinal);
    line-height: 1;
    font-weight: var(--fw-bold);
    color: var(--color-accent);
    font-variant-numeric: tabular-nums;
    margin-bottom: var(--space-sm);
}
.error-page__actions { display: flex; flex-wrap: wrap; gap: var(--space-xs); margin-top: var(--space-lg); }


/* ------------------------------------------------------------------
   17. Motion
   Reveal-Elemente sind OHNE JavaScript sichtbar: die Klasse
   .reveal wirkt erst, wenn das Skript <html> mit .js markiert hat.
   ------------------------------------------------------------------ */
.js .reveal {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity var(--dur-reveal) var(--ease-out),
                transform var(--dur-reveal) var(--ease-out);
}
.js .reveal.is-visible { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
    html { scroll-behavior: auto; }
    .reveal,
    .js .reveal { opacity: 1 !important; transform: none !important; }
    .service-card:hover { transform: none; }
}

@media (prefers-contrast: more) {
    :root {
        --bw-input: 3px;
        --color-line: #6E7671;
    }
    @media (prefers-color-scheme: dark) {
        :root { --color-line: #7C857C; }
    }
}

@media print {
    .site-header, .site-nav, .nav-toggle, .skip-link, .form, .phone-btn { display: none !important; }
    body { background: #fff; color: #000; }
}


/* ------------------------------------------------------------------
   18. Geschützte Kontaktdaten und Redaktionshinweise
   ------------------------------------------------------------------ */

/* Der <span class="mailto"> wird von main.js durch ein echtes <a>
   ersetzt. Ohne JavaScript bleibt nur der <noscript>-Inhalt stehen —
   er muss deshalb wie normaler Fließtext aussehen. */
.mailto { overflow-wrap: anywhere; }
.mailto__hint {
    display: block;
    font-size: var(--fs-small);
    line-height: 1.5;
    color: var(--color-ink-muted);
    margin-top: var(--space-3xs);
}

/* Redaktionshinweis im Impressum — sichtbar, aber klar als Hinweis
   erkennbar. Ocker statt Rot, damit es nicht wie ein Seitenfehler wirkt.
   --color-ink auf --color-accent-soft = 15,16 : 1 (AA erfüllt). */
.legal-warning {
    background: var(--color-accent-soft);
    border-left: var(--bw-edge) solid var(--color-accent);
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
    padding: var(--space-md);
    margin-block: var(--space-md);
    color: var(--color-ink);
    font-size: var(--fs-small);
    line-height: 1.6;
    max-width: var(--container-text);
}
.legal-warning code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.95em;
    background: var(--color-surface);
    border: var(--bw-hair) solid var(--color-line);
    border-radius: var(--radius-sm);
    padding: 0.1em 0.35em;
}

/* Liste der noch fehlenden Pflichtangaben im Redaktionshinweis. */
.legal-warning__list {
    max-width: var(--container-text);
    margin: 0 0 var(--space-md);
    padding-left: 2.5rem;
    font-size: var(--fs-small);
    line-height: 1.6;
    color: var(--color-ink);
}

/* Der <span class="wa"> wird von main.js durch ein echtes <a> ersetzt.
   Bis dahin — und falls das Skript ausfällt — steht dort die lesbare
   Rufnummer als normaler Fließtext. */
.wa { overflow-wrap: anywhere; }

/* Hinweis am Telefonbereich: WhatsApp als Zweitweg (Kundenwunsch). */
/* Zweite Ueberleitung im selben Block: Anders als die erste steht sie
   nicht oben, sie braucht deshalb Luft nach oben. */
.contact__label--wa { margin-top: var(--space-md); }

.contact__wahint {
    margin-bottom: var(--space-sm);
    font-size: var(--fs-small);
    line-height: 1.5;
    color: var(--color-ink-muted);   /* 6,87 : 1 auf --color-primary-soft */
    max-width: 46ch;
}
.contact__wa { margin-bottom: var(--space-md); }



/* ------------------------------------------------------------------
   19. Staging-Hinweisstreifen
   Nur sichtbar, solange 'staging' in includes/config.php true ist.
   Liegt VOR dem Sticky-Header und scrollt mit weg, damit der Header
   weiterhin sauber oben klebt.
   --color-ink auf --color-accent-soft = 15,16 : 1 (AA erfüllt).
   ------------------------------------------------------------------ */
.stagingbar {
    background: var(--color-accent-soft);
    border-bottom: var(--bw-hair) solid var(--color-accent);
    color: var(--color-ink);
    font-size: var(--fs-small);
    line-height: 1.5;
    padding-block: var(--space-2xs);
    text-align: center;
}
.stagingbar strong {
    font-weight: var(--fw-bold);
    color: var(--color-accent);      /* 5,29 : 1 auf --color-accent-soft */
}

/* ------------------------------------------------------------------
   Silbentrennung nur auf schmalen Viewports.
   Die Designrichtung fordert hyphens:auto, damit lange Komposita
   ("Grundstueckspflege") bei 320px nicht ueberlaufen. Ab 680px ist der
   Platz da und die Trennung schadet mehr als sie nuetzt - die H1 brach
   sonst als "Entruem-pelung" mitten im Wort um.
   Bewusst als min-width formuliert (Designrichtung: mobile-first).
   ------------------------------------------------------------------ */
@media (min-width: 680px) {
    body,
    h1, h2, h3, h4 {
        -webkit-hyphens: manual;
        hyphens: manual;
    }
}
