/*
 * KDG-Server – Design-System
 * ==========================
 *
 * Eigenes CSS, kein Framework und kein Kauftemplate. Aufbau:
 *   1. Design-Tokens (Farben, Abstaende, Typografie) als Custom Properties
 *   2. Grundlagen und Reset
 *   3. Layout und Raster
 *   4. Kopfbereich und Navigation
 *   5. Bausteine (Buttons, Karten, Tabellen, Badges, Hinweise)
 *   6. Abschnitte (Hero, Merkmale, Produkte, Konfigurator, Domainsuche, Referenzen)
 *   7. Fussbereich
 *  7a. Warenkorb, Kasse und Bestellbestaetigung
 *  7b. Verwaltung (Admin-Oberflaeche)
 *   8. Bewegung und Barrierefreiheit
 *
 * Grundsaetze:
 *   - Alle Farben kommen aus Tokens; Dark- und Light-Mode sind gleichwertig.
 *   - Kontraste erfuellen WCAG 2.2 AA (Text mindestens 4,5:1).
 *   - Jede Animation respektiert prefers-reduced-motion.
 *   - Layout ohne feste Breiten: Grid mit auto-fit statt Breakpoint-Kaskaden.
 */

/* ========================================================================
   1. Design-Tokens
   ======================================================================== */

/*
 * Die Hausschrift: Plus Jakarta Sans (SIL Open Font License, Lizenz neben den Dateien).
 * Lokal ausgeliefert - eine Schrift von einem fremden Dienst waere bei jedem Seitenaufruf
 * ein Datenabfluss, und die CSP erlaubt ohnehin nur `font-src 'self'`. Eine variable Datei
 * je Zeichenumfang traegt alle Staerken von 200 bis 800; `latin` deckt Umlaute, ß, „“ und €,
 * `latin-ext` den Rest europaeischer Namen (ein Kunde heisst auch mal Łukasz).
 * `swap`: der Text steht sofort in der Systemschrift und wechselt, sobald die Datei da ist.
 *
 * **Wer eine Schriftdatei ersetzt, gibt ihr einen neuen Namen.** Unter `/assets/` liefert
 * der Webserver alles ein Jahr lang als `immutable` aus; CSS und Skripte entkommen dem ueber
 * `?v=`, eine Schrift mit gleichem Namen bliebe bei jedem Besucher die alte. Der Name steht
 * an drei Stellen: hier, im `preload` in `templates/layout.php` und im Test
 * `MarkeUndSchriftTest`.
 */
@font-face {
    font-family: "Plus Jakarta Sans";
    font-style: normal;
    font-weight: 200 800;
    font-display: swap;
    src: url("../fonts/plus-jakarta-sans-latin-ext-wght-normal.woff2") format("woff2-variations");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
        U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113,
        U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Plus Jakarta Sans";
    font-style: normal;
    font-weight: 200 800;
    font-display: swap;
    src: url("../fonts/plus-jakarta-sans-latin-wght-normal.woff2") format("woff2-variations");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304,
        U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/*
 * Farbwelt „Tiefblau“ (Gestaltung vom 28.09.2026).
 *
 *  - **Tinte** (`--ink*`) ist die Marke: Leiste oben, Kopf der Startseite, Seitenkoepfe,
 *    Fussbereich, der zweite Produktweg. Sie folgt der Darstellung - hell ein kuehles
 *    Blaugrau, dunkel die tiefe Tinte. Fest dunkel bleibt nur das Zeichen selbst (`--marke`:
 *    Markenzeichen, Knopf in den Kundenbereich, Favicon).
 *  - **Akzent** (`--accent`) ist allein fuer Handlungen: Knoepfe, Verweise, Fokus. Wer ihn
 *    fuer Schmuck verwendet, nimmt ihm die Bedeutung „hier kann ich etwas tun“.
 *  - **Bernstein** (`--highlight`) ist die Waerme daneben - sparsam: eine Auszeichnung, ein
 *    Preistipp, ein Lichtpunkt. Nie Text auf weissem Grund (dort fehlt der Kontrast).
 *
 * Jede Text-/Flaechenpaarung ist nachgerechnet (WCAG 2.2 AA, Text >= 4,5:1, Raender von
 * Bedienelementen >= 3:1); die schwaechste Textpaarung liegt bei 4,96:1
 * (`--on-ink-accent` auf `--ink-accent-soft` ueber `--ink`, nachgerechnet 29.09.2026).
 */
:root {
    color-scheme: light dark;

    /* Flaechen und Text – helle Darstellung */
    --bg: #f6f7f9;
    --bg-alt: #edf0f5;
    --surface: #ffffff;
    --surface-2: #f8f9fb;
    --border: #e1e6ed;
    --border-strong: #c5cdd8;
    --text: #0e1726;
    --text-muted: #4a5566;
    /* Rand von Eingabefeldern: 3:1 gegen Feld und Seite (WCAG 1.4.11). */
    --input-border: #7a8596;
    /* Schatten am Rand einer seitlich verschiebbaren Tabelle */
    --scroll-shadow: rgba(14, 23, 38, 0.2);

    /* Akzent: Handlung */
    --accent: #1f4fd8;
    --accent-hover: #1a3fb0;
    --accent-contrast: #ffffff;
    --accent-soft: rgba(31, 79, 216, 0.08);
    --accent-line: rgba(31, 79, 216, 0.24);

    /* Marke: Tinte. Die Markenflaechen (Leiste oben, Hero, Seitenkoepfe, Fuss, der zweite
       Weg) folgen der Darstellung: hell ein kuehles Blaugrau, dunkel die tiefe Tinte
       (Betreiber, 28.09.2026 - vorher blieben sie in beiden dunkel, und die Website hatte
       keinen wirklich hellen Modus). Nachgerechnet gegen --ink, --ink-2 und --ink-3: Text
       >= 5,19:1, Feldrand >= 3,58:1, Bernstein als Schrift (--ink-highlight) >= 5,56:1. */
    --ink: #e9eff9;
    --ink-2: #f5f8fd;
    --ink-3: #dce5f4;
    --ink-end: #f3f6fc;
    --ink-line: rgba(31, 79, 216, 0.12);
    --on-ink: #0e1726;
    --on-ink-muted: #3f4b5e;
    --on-ink-accent: #1f4fd8;
    --ink-scheme: light;
    --ink-border: rgba(14, 23, 38, 0.12);
    --ink-border-strong: rgba(14, 23, 38, 0.22);
    --ink-input-border: #6b778a;
    --ink-accent: #1f4fd8;
    --ink-accent-hover: #1a3fb0;
    --ink-accent-contrast: #ffffff;
    --ink-accent-soft: rgba(31, 79, 216, 0.1);
    --ink-accent-line: rgba(31, 79, 216, 0.28);
    --ink-ok: #0f6b3c;
    --ink-warn: #8a4b00;
    --ink-fail: #a3161c;
    --ink-highlight: #7c4f00;
    /* Grosse Zahlen: Verlauf von Text nach Akzent, beide Enden >= 5,2:1 */
    --ink-number-from: #0e1726;
    --ink-number-to: #1f4fd8;
    /* Lichtschein, Raster, Glas und Schatten auf der Markenflaeche */
    --ink-glow: 0.45;
    --ink-grid: rgba(31, 79, 216, 0.07);
    --ink-veil: rgba(255, 255, 255, 0.55);
    --ink-hover: rgba(14, 23, 38, 0.06);
    --ink-shadow-sm: 0 1px 2px rgba(14, 23, 38, 0.05), 0 1px 3px rgba(14, 23, 38, 0.07);
    --ink-shadow-md: 0 2px 4px -1px rgba(14, 23, 38, 0.05), 0 10px 24px -6px rgba(14, 23, 38, 0.12);
    --ink-shadow-lg: 0 4px 8px -2px rgba(14, 23, 38, 0.05), 0 24px 48px -12px rgba(14, 23, 38, 0.18);

    /* Das Markenzeichen und der Knopf in den Kundenbereich bleiben dunkel - ein Zeichen
       wechselt nicht die Farbe, eine Flaeche schon. */
    --marke: #0b1628;
    --marke-3: #1c2e4b;
    --on-marke: #eef3fb;

    /* Waerme: Bernstein */
    --highlight: #f5b53d;
    --highlight-contrast: #1f1400;
    --highlight-soft: rgba(245, 181, 61, 0.14);

    /* Signalfarben */
    --ok: #0f6b3c;
    --warn: #8a4b00;
    --fail: #a3161c;
    --ok-soft: rgba(15, 107, 60, 0.09);
    --warn-soft: rgba(138, 75, 0, 0.09);
    --fail-soft: rgba(163, 22, 28, 0.08);

    /* Tiefe: geschichtete, kuehle Schatten statt eines grauen Flecks */
    --shadow-sm: 0 1px 2px rgba(14, 23, 38, 0.05), 0 1px 3px rgba(14, 23, 38, 0.07);
    --shadow-md: 0 2px 4px -1px rgba(14, 23, 38, 0.05), 0 10px 24px -6px rgba(14, 23, 38, 0.12);
    --shadow-lg: 0 4px 8px -2px rgba(14, 23, 38, 0.05), 0 24px 48px -12px rgba(14, 23, 38, 0.18);
    --glow: none;

    /* Typografie */
    --font-sans: "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", monospace;

    --step--1: clamp(0.84rem, 0.82rem + 0.1vw, 0.9rem);
    --step-0: clamp(1rem, 0.97rem + 0.15vw, 1.08rem);
    --step-1: clamp(1.18rem, 1.1rem + 0.35vw, 1.38rem);
    --step-2: clamp(1.42rem, 1.28rem + 0.7vw, 1.85rem);
    --step-3: clamp(1.75rem, 1.5rem + 1.25vw, 2.5rem);
    --step-4: clamp(2.15rem, 1.7rem + 2.2vw, 3.4rem);
    --step-5: clamp(2.6rem, 1.85rem + 3.6vw, 4.6rem);

    /* Abstaende */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;
    --space-7: 3rem;
    --space-8: 4rem;
    --space-9: 6rem;
    --space-10: 8rem;

    --radius-sm: 0.5rem;
    --radius: 0.75rem;
    --radius-lg: 1.25rem;
    --radius-xl: 1.75rem;
    --radius-full: 999px;

    --container: 76rem;
    --container-narrow: 46rem;
    --gutter: 1rem;

    /* Hoehe des klebenden Kopfbereichs: fuer Sprungziele und klebende Spalten. */
    --header-h: 4rem;

    --transition: 180ms cubic-bezier(0.4, 0, 0.2, 1);
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

@media (min-width: 78.0625rem) {
    :root {
        --header-h: 4.5rem;
    }
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --bg: #070c16;
        --bg-alt: #0b1322;
        --surface: #111b2d;
        --surface-2: #16223a;
        --border: #22314a;
        --border-strong: #30425f;
        --text: #e8eef8;
        --text-muted: #a3b0c4;
        --input-border: #66768f;
        --scroll-shadow: rgba(0, 0, 0, 0.75);

        --accent: #86a8ff;
        --accent-hover: #a9c1ff;
        --accent-contrast: #06102a;
        --accent-soft: rgba(134, 168, 255, 0.12);
        --accent-line: rgba(134, 168, 255, 0.3);

        --ink: #0a1426;
        --ink-2: #111f38;
        --ink-3: #1a2c4a;
        --ink-end: #0d1a30;
        --ink-line: rgba(169, 183, 204, 0.18);
        --on-ink: #eef3fb;
        --on-ink-muted: #a9b7cc;
        --on-ink-accent: #8fb0ff;
        --ink-scheme: dark;
        --ink-border: rgba(169, 183, 204, 0.16);
        --ink-border-strong: rgba(169, 183, 204, 0.32);
        --ink-input-border: #6f82a0;
        --ink-accent: #8fb0ff;
        --ink-accent-hover: #b3caff;
        --ink-accent-contrast: #06102a;
        --ink-accent-soft: rgba(143, 176, 255, 0.14);
        --ink-accent-line: rgba(143, 176, 255, 0.32);
        --ink-ok: #5fd39b;
        --ink-warn: #efbe68;
        --ink-fail: #f59a9a;
        --ink-highlight: #f5b53d;
        --ink-number-from: #ffffff;
        --ink-number-to: #a9c1ff;
        --ink-glow: 1;
        --ink-grid: rgba(169, 183, 204, 0.07);
        --ink-veil: rgba(255, 255, 255, 0.04);
        --ink-hover: rgba(255, 255, 255, 0.06);
        --ink-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
        --ink-shadow-md: 0 10px 24px -6px rgba(0, 0, 0, 0.5);
        --ink-shadow-lg: 0 24px 48px -12px rgba(0, 0, 0, 0.6);

        --ok: #5fd39b;
        --warn: #efbe68;
        --fail: #f59a9a;
        --ok-soft: rgba(95, 211, 155, 0.13);
        --warn-soft: rgba(239, 190, 104, 0.13);
        --fail-soft: rgba(245, 154, 154, 0.13);

        --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.45);
        --shadow-md: 0 10px 24px -6px rgba(0, 0, 0, 0.55);
        --shadow-lg: 0 24px 48px -12px rgba(0, 0, 0, 0.65);
        --glow: 0 0 0 1px rgba(134, 168, 255, 0.06), 0 20px 60px -20px rgba(79, 124, 255, 0.25);
    }
}

/* Eine gewaehlte Darstellung gilt auch fuer Bedienelemente des Browsers (Auswahllisten,
   Kalender, Scrollleisten) - sonst blieben sie bei dunkler Wahl und hellem System hell. */
:root[data-theme="light"] {
    color-scheme: light;
}

:root[data-theme="dark"] {
    color-scheme: dark;
    --bg: #070c16;
    --bg-alt: #0b1322;
    --surface: #111b2d;
    --surface-2: #16223a;
    --border: #22314a;
    --border-strong: #30425f;
    --text: #e8eef8;
    --text-muted: #a3b0c4;
    --input-border: #66768f;
    --scroll-shadow: rgba(0, 0, 0, 0.75);

    --accent: #86a8ff;
    --accent-hover: #a9c1ff;
    --accent-contrast: #06102a;
    --accent-soft: rgba(134, 168, 255, 0.12);
    --accent-line: rgba(134, 168, 255, 0.3);

    --ink: #0a1426;
    --ink-2: #111f38;
    --ink-3: #1a2c4a;
    --ink-end: #0d1a30;
    --ink-line: rgba(169, 183, 204, 0.18);
    --on-ink: #eef3fb;
    --on-ink-muted: #a9b7cc;
    --on-ink-accent: #8fb0ff;
    --ink-scheme: dark;
    --ink-border: rgba(169, 183, 204, 0.16);
    --ink-border-strong: rgba(169, 183, 204, 0.32);
    --ink-input-border: #6f82a0;
    --ink-accent: #8fb0ff;
    --ink-accent-hover: #b3caff;
    --ink-accent-contrast: #06102a;
    --ink-accent-soft: rgba(143, 176, 255, 0.14);
    --ink-accent-line: rgba(143, 176, 255, 0.32);
    --ink-ok: #5fd39b;
    --ink-warn: #efbe68;
    --ink-fail: #f59a9a;
    --ink-highlight: #f5b53d;
    --ink-number-from: #ffffff;
    --ink-number-to: #a9c1ff;
    --ink-glow: 1;
    --ink-grid: rgba(169, 183, 204, 0.07);
    --ink-veil: rgba(255, 255, 255, 0.04);
    --ink-hover: rgba(255, 255, 255, 0.06);
    --ink-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
    --ink-shadow-md: 0 10px 24px -6px rgba(0, 0, 0, 0.5);
    --ink-shadow-lg: 0 24px 48px -12px rgba(0, 0, 0, 0.6);

    --ok: #5fd39b;
    --warn: #efbe68;
    --fail: #f59a9a;
    --ok-soft: rgba(95, 211, 155, 0.13);
    --warn-soft: rgba(239, 190, 104, 0.13);
    --fail-soft: rgba(245, 154, 154, 0.13);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.45);
    --shadow-md: 0 10px 24px -6px rgba(0, 0, 0, 0.55);
    --shadow-lg: 0 24px 48px -12px rgba(0, 0, 0, 0.65);
    --glow: 0 0 0 1px rgba(134, 168, 255, 0.06), 0 20px 60px -20px rgba(79, 124, 255, 0.25);
}

/* ========================================================================
   2. Grundlagen
   ======================================================================== */

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

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--header-h) + var(--space-4));
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: var(--font-sans);
    font-size: var(--step-0);
    line-height: 1.65;
    text-wrap: pretty;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-optical-sizing: auto;
}

h1,
h2,
h3,
h4 {
    margin: 0 0 var(--space-3);
    line-height: 1.12;
    font-weight: 750;
    letter-spacing: -0.016em;
    text-wrap: balance;
    /* Lange deutsche Woerter ("Geschaeftsbedingungen") laufen auf 390 px sonst ueber den Rand. */
    overflow-wrap: break-word;
    hyphens: auto;
}

/* Eine E-Mail-Adresse bricht nicht am Bindestrich um („a2-⏎anna@example.net“ las sich wie zwei
   Adressen, Durchsicht 29.09.2026); nur eine sehr lange darf ueberall umbrechen. */
.mailadresse {
    white-space: nowrap;
}

@media (max-width: 30rem) {
    .mailadresse {
        white-space: normal;
        overflow-wrap: anywhere;
    }
}

h1 { font-size: var(--step-5); letter-spacing: -0.024em; }
h2 { font-size: var(--step-3); letter-spacing: -0.02em; }
h3 { font-size: var(--step-1); font-weight: 700; letter-spacing: -0.012em; }
h4 { font-size: var(--step-0); font-weight: 700; letter-spacing: -0.01em; }

p {
    margin: 0 0 var(--space-4);
    max-width: 68ch;
}

a {
    color: var(--accent);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.2em;
}

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

img,
svg {
    max-width: 100%;
    height: auto;
    vertical-align: middle;
}

ul,
ol {
    margin: 0 0 var(--space-4);
    padding-left: 1.25rem;
}

li + li {
    margin-top: var(--space-1);
}

code {
    font-family: var(--font-mono);
    font-size: 0.9em;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 0.1em 0.35em;
}

hr {
    border: 0;
    border-top: 1px solid var(--border);
    margin: var(--space-7) 0;
}

strong {
    font-weight: 700;
}

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

/* Grundform aller Eingabefelder. :where() hat keine Spezifitaet: jede Regel eines
   Bausteins (.form-field, .domain-search ...) geht vor. */
:where(input:not([type]), input[type="text"], input[type="email"], input[type="password"],
    input[type="number"], input[type="search"], input[type="tel"], input[type="url"],
    input[type="date"], input[type="datetime-local"], input[type="file"], select, textarea) {
    max-width: 100%;
    min-height: 2.75rem;
    padding: 0.6rem 0.85rem;
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--input-border);
    border-radius: var(--radius-sm);
    font: inherit;
    transition: border-color var(--transition), box-shadow var(--transition);
}

:where(input, select, textarea):where(:hover):not(:disabled) {
    border-color: var(--text-muted);
}

/* Ein Feld, in dem man gerade schreibt, sagt es mit einem weichen Ring - zusaetzlich zum
   Fokusrahmen, nicht an seiner Stelle. */
:where(input, select, textarea):focus-visible {
    border-color: var(--accent);
    box-shadow: 0 0 0 4px var(--accent-soft);
}

:where(textarea) {
    min-height: 6rem;
}

/* Ein Suchfeld sagt im Platzhalter, wonach es sucht („Nummer, Betreff, Kunde, E-Mail“) -
   abgeschnitten half der Satz niemandem. */
:where(input[type="search"]) {
    min-width: min(100%, 22rem);
}

:where(input[type="checkbox"], input[type="radio"]) {
    accent-color: var(--accent);
}

::placeholder {
    color: var(--text-muted);
    opacity: 1;
}

::selection {
    background: var(--accent);
    color: var(--accent-contrast);
}

/* Das Attribut hidden gilt immer - auch gegen display-Regeln der Bausteine
   (sonst stuenden z. B. Menue- und Darstellungsknopf ohne JavaScript funktionslos da). */
[hidden] {
    display: none !important;
}

/* Nur fuer Screenreader sichtbar */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

.skip-link {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 100;
    transform: translateY(-120%);
    padding: var(--space-3) var(--space-4);
    background: var(--accent);
    color: var(--accent-contrast);
    font-weight: 600;
    text-decoration: none;
    border-radius: 0 0 var(--radius) 0;
    transition: transform var(--transition);
}

.skip-link:focus {
    transform: translateY(0);
    color: var(--accent-contrast);
}

/* ========================================================================
   3. Layout
   ======================================================================== */

.container {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: var(--gutter);
}

.container-narrow {
    max-width: var(--container-narrow);
}

.section {
    padding-block: var(--space-8);
}

/* Grosszuegiger Rhythmus auf breiten Bildschirmen: ein Abschnitt ist eine Aussage, und
   zwischen zwei Aussagen darf Luft sein. */
@media (min-width: 62rem) {
    .section {
        padding-block: var(--space-9);
    }
}

.section-alt {
    background: var(--bg-alt);
    border-block: 1px solid var(--border);
}

/* Die Lesebreite gehoert an den Text, nicht an den ganzen Kopf: `52ch` am Kopf bemass sich
   an der Grundschrift, die h2 ist aber viermal so gross - "In jedem / Webspace / enthalten"
   brach in drei Zeilen, obwohl 1200 px frei waren (Durchsicht 29.09.2026). `ch` an der h2
   selbst misst in ihrer eigenen Schrift. */
.section-head {
    margin-bottom: var(--space-7);
}

.section-head h2 {
    max-width: 30ch;
    font-size: var(--step-4);
    font-weight: 800;
    letter-spacing: -0.026em;
}

.section-head > p {
    max-width: 60ch;
}

/* Die Dachzeile: ein kurzer Strich in Bernstein davor - das wiederkehrende Zeichen der
   Marke zwischen den Abschnitten. */
.section-head .eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: var(--space-3);
    color: var(--accent);
    font-size: 0.8125rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.section-head .eyebrow::before {
    content: "";
    width: 1.5rem;
    height: 2px;
    border-radius: 2px;
    background: var(--highlight);
}

.section-head p {
    color: var(--text-muted);
    font-size: 1.0625rem;
    margin-bottom: 0;
}

/* Seitenkopf mit h1: die Ueberschrift darf die volle Breite nutzen, nur der
   Einleitungstext bleibt auf eine gut lesbare Zeilenlaenge begrenzt. */
.section-head:has(> h1) {
    max-width: none;
}

.section-head:has(> h1) > p {
    max-width: 52ch;
}

.grid {
    display: grid;
    gap: var(--space-5);
}

.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); }

/* grid-2 heisst zwei Spalten: auf breiten Bildschirmen nicht zu dritt (3 + 1). Dasselbe
   gilt fuer grid-3 - bei 76 rem Inhaltsbreite passten vier hinein, und aus sechs
   Leistungen wurde 4 + 2, aus fuenf Referenzen 4 + 1, jeweils mit Luecke. */
@media (min-width: 64rem) {
    .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Vier Stufen nebeneinander (Managed vServer): die Karte ist dort gut 17 rem schmal, und
   Name und Preis in der Groesse der zweispaltigen Karten brachen um („Managed / vServer
   S“). Eine Stufe kleiner, wenn wirklich vier nebeneinander stehen. */
@media (min-width: 64rem) {
    .grid-4 .plan {
        padding: var(--space-5);
    }

    .grid-4 .plan__name {
        font-size: var(--step-1);
    }

    .grid-4 .plan__amount {
        font-size: var(--step-3);
    }

    .grid-4 .plan__badge {
        left: var(--space-5);
    }
}

.stack > * + * {
    margin-top: var(--space-4);
}

.cluster {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    align-items: center;
}

.text-muted { color: var(--text-muted); }
.text-center { text-align: center; }
.mb-0 { margin-bottom: 0; }
.mt-6 { margin-top: var(--space-6); }

/* ========================================================================
   4. Kopfbereich und Navigation
   ======================================================================== */

/* Aufbau (Gestaltung vom 28.09.2026): eine **schmale Leiste in Tinte** mit den Seiten
   ueber das Haus (Leistungen, Infrastruktur, Referenzen, Wissen, Kontakt), darunter
   **eine** Hauptzeile: Marke, die Produkte, die Werkzeuge. Vorher standen neun
   gleichrangige Verweise in einer zweiten Zeile - die Produkte, um die es geht, hatten
   dasselbe Gewicht wie das Impressum des Hauses. Jetzt entscheidet die Gliederung, was
   wichtiger ist (E-100), und keine Zeile bricht um.

   Unter 78rem verschwindet die Leiste; ihre Verweise stehen dann im aufklappbaren Menue
   (`.site-nav__neben`). Das Menue klappt nur auf Knopfdruck, wenn das Skript laeuft (es
   setzt data-collapsible) - ohne JavaScript steht es vollstaendig unter der Marke, und
   der Kopf klebt dann nicht, damit er auf dem Telefon nicht den halben Schirm verdeckt.

   Warum 78rem und nicht die 62rem des uebrigen Layouts: ab 78rem hat der Container seine
   volle Breite (76rem plus Rand), und der Kopf mit voller Navigation braucht angemeldet
   nachgemessen 1161 von 1184 px (Marke 222, Navigation 478, Werkzeuge 430 mit Warenkorb,
   Name, Abmelden und Darstellung, dazu zwei Abstaende). Darunter brach er in zwei Zeilen
   um. Wer hier etwas dazunimmt, misst nach - die Reserve sind 23 px. */

.topbar {
    background: var(--ink);
    color: var(--on-ink-muted);
    font-size: 0.8125rem;
}

.topbar__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    min-height: 2.25rem;
}

.topbar__claim {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0;
    max-width: none;
}

/* Der Lichtpunkt: ein kleiner Kreis in Bernstein, reine Zierde (die Aussage steht daneben). */
.topbar__claim::before {
    content: "";
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 50%;
    background: var(--highlight);
    box-shadow: 0 0 0 3px rgba(245, 181, 61, 0.18);
}

.topbar__nav ul {
    display: flex;
    gap: var(--space-1);
    margin: 0;
    padding: 0;
    list-style: none;
}

.topbar__nav li + li {
    margin-top: 0;
}

.topbar__nav a {
    display: block;
    padding: 0.4rem 0.6rem;
    border-radius: var(--radius-sm);
    color: var(--on-ink-muted);
    font-weight: 500;
    text-decoration: none;
}

.topbar__nav a:hover {
    color: var(--on-ink);
    background: var(--ink-hover);
}

/* Der Strich der aktuellen Seite in der Farbe, die auf Tinte traegt: `--highlight` lag im
   hellen Modus bei 1,57:1 auf `--ink`, `--ink-highlight` bei 5,56:1 (WCAG 1.4.11, Durchsicht
   29.09.2026). Im dunklen Modus sind beide Bernstein. */
.topbar__nav a[aria-current="page"] {
    color: var(--on-ink);
    text-decoration: underline;
    text-decoration-color: var(--ink-highlight);
    text-decoration-thickness: 2px;
    text-underline-offset: 0.45em;
}

.topbar :focus-visible {
    outline-color: var(--on-ink-accent);
}

@media (max-width: 78rem) {
    .topbar {
        display: none;
    }
}

.site-header {
    position: sticky;
    top: 0;
    z-index: 50;
    background: color-mix(in srgb, var(--surface) 88%, transparent);
    backdrop-filter: saturate(160%) blur(14px);
    border-bottom: 1px solid var(--border);
}

.site-header__inner {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    /* 16 px statt 24: angemeldet, mit Darstellung und Warenkorb, blieben sonst 23 px von
       1184 (nachgemessen, KDG-Server (Testlauf) als Name) - bei 24 px brach er um. */
    column-gap: var(--space-4);
    min-height: var(--header-h);
}

.site-header__inner > .brand {
    padding-block: var(--space-3);
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    font-size: 1.0625rem;
    font-weight: 800;
    letter-spacing: -0.03em;
    color: var(--text);
    text-decoration: none;
    white-space: nowrap;
}

.brand:hover {
    color: var(--text);
}

/* Das Zeichen: fest dunkel (`--marke`) mit einem Lichtschein aus der Ecke - dieselbe Farbwelt wie der Kopf
   der Startseite und die Seitenleiste der Arbeitsoberflaeche. */
.brand__mark {
    display: grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 0.65rem;
    background:
        radial-gradient(120% 120% at 100% 0%, rgba(79, 124, 255, 0.85) 0%, rgba(79, 124, 255, 0) 60%),
        var(--marke);
    color: #ffffff;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12), 0 4px 12px -4px rgba(11, 22, 40, 0.5);
}

/* Das Zeichen selbst: dasselbe „k“ wie im Favicon, der Betriebspunkt in Bernstein. */
.brand__mark svg {
    width: 100%;
    height: 100%;
}

.brand__punkt {
    fill: var(--highlight);
}

.site-header__tools {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-left: auto;
}

.site-header__tools .button {
    min-height: 2.5rem;
}

.nav-cart {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 2.5rem;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: var(--step--1);
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}

.nav-cart:hover {
    background: var(--bg-alt);
    color: var(--text);
}

.nav-cart[aria-current="page"] {
    color: var(--accent);
    background: var(--accent-soft);
}

/* Angemeldet steht der Warenkorb nur als Symbol da (mit Zaehler und Tooltip): Name und
   Abmelden brauchen den Platz, sonst bricht der Kopf um. Die Beschriftung bleibt fuer
   Screenreader. */
.site-header__tools:has(.site-header__account--angemeldet) .nav-cart__label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.nav-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: 2.5rem;
    padding: var(--space-2) var(--space-3);
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    font: inherit;
    font-size: var(--step--1);
    font-weight: 600;
    cursor: pointer;
}

.nav-toggle[aria-expanded="true"] {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
}

/*
 * Die Wahl der Darstellung (partials/darstellung): drei Knoepfe in einem Rahmen. Die
 * gueltige Wahl traegt Flaeche, Akzentfarbe **und** einen Rand in Akzentfarbe (gegen die
 * Flaeche >= 3:1, WCAG 1.4.11) - nicht nur eine Farbe. Kompakt im Kopf (nur Symbole, 34 px
 * je Knopf, ueber den 24 px aus WCAG 2.5.8), mit Text im Menue und in der Seitenleiste.
 */
.darstellung {
    display: inline-flex;
    gap: 2px;
    padding: 2px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
}

.darstellung__knopf {
    display: inline-flex;
    flex: 1 1 0;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    min-height: 2.125rem;
    padding: 0 0.65rem;
    background: transparent;
    color: var(--text-muted);
    border: 1px solid transparent;
    border-radius: calc(var(--radius-sm) - 2px);
    font: inherit;
    font-size: var(--step--1);
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: color var(--transition), border-color var(--transition), background var(--transition);
}

.darstellung__knopf:hover {
    color: var(--text);
    background: var(--bg-alt);
}

.darstellung__knopf[aria-pressed="true"] {
    color: var(--accent);
    background: var(--accent-soft);
    border-color: var(--accent);
}

.darstellung__knopf svg {
    flex: 0 0 auto;
}

/* Im Kopf 30 px je Knopf (ueber den 24 px aus WCAG 2.5.8): der Kopf der Website hat
   angemeldet kaum Luft (nachgemessen), und jeder Knopf mehr bricht ihn sonst um. */
.darstellung--kompakt .darstellung__knopf {
    width: 1.875rem;
    min-height: 1.875rem;
    padding: 0;
}

/* Mit Text: eine Liste untereinander, volle Breite - im Menue und in der Seitenleiste. */
.darstellung-wahl__titel {
    margin: 0 0 var(--space-2);
    color: var(--text-muted);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.darstellung-wahl .darstellung {
    display: flex;
    flex-direction: column;
    width: 100%;
}

.darstellung-wahl .darstellung__knopf {
    justify-content: flex-start;
    gap: var(--space-3);
    min-height: 2.5rem;
    padding: 0 var(--space-3);
}

/* Im aufklappbaren Menue der Website: nur dort, wo der Kopf keinen Platz fuer die Symbole
   hat (siehe unten, 78rem). */
.site-nav__darstellung {
    display: none;
}

.site-nav ul {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0 var(--space-1);
    margin: 0;
    padding: 0;
    list-style: none;
}

.site-nav li + li {
    margin-top: 0;
}

.site-nav a {
    position: relative;
    display: block;
    padding: var(--space-2) 0.65rem;
    border-radius: var(--radius-sm);
    color: var(--text);
    font-size: 0.9375rem;
    font-weight: 600;
    letter-spacing: -0.005em;
    text-decoration: none;
    transition: color var(--transition), background var(--transition);
}

.site-nav a:hover {
    background: var(--bg-alt);
    color: var(--text);
}

/* Aktive Seite: Farbe und eine Linie - Farbe allein genuegt nicht (WCAG 1.4.1). */
.site-nav a[aria-current="page"] {
    color: var(--accent);
}

.site-nav a[aria-current="page"]::after {
    content: "";
    position: absolute;
    left: 0.8rem;
    right: 0.8rem;
    bottom: -0.2rem;
    height: 2px;
    border-radius: 2px;
    background: currentColor;
}

/* Die Seiten ueber das Haus stehen auf breiten Bildschirmen in der Leiste oben, der
   Kundenbereich als Schaltflaeche - im aufklappbaren Menue kommen beide dazu. */
.site-nav__neben,
.site-nav__account {
    display: none;
}

/* Mit Skript ist das Menue eine Schublade - dann bleibt der Kopf eine Zeile, auch mit
   langem Namen: der Name wird gekuerzt, die Werkzeuge rutschen nicht darunter. Ohne
   Skript steht das Menue als eigene Zeile darunter und braucht den Umbruch. */
@media (max-width: 78rem) {
    .site-header__inner:has(.site-nav[data-collapsible="true"]) {
        flex-wrap: nowrap;
    }

    .site-header__inner > .brand {
        min-width: 0;
    }

    .brand > span:last-child {
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .site-header__tools {
        flex-shrink: 0;
    }
}

@media (max-width: 40rem) {
    .site-header__inner {
        column-gap: var(--space-3);
    }

    .site-header__tools .site-header__account {
        display: none;
    }

    .site-nav__account {
        display: list-item;
    }

    /* Warenkorb nur als Symbol; die Beschriftung bleibt fuer Screenreader. */
    .nav-cart__label {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
}

@media (max-width: 78rem) {
    .site-nav {
        order: 3;
        flex: 1 0 100%;
    }

    .site-nav__neben {
        display: list-item;
    }

    /* Die Darstellung wandert mit Text ins Menue; oben bleibt Platz fuer Marke und Werkzeuge. */
    .site-header__tools .darstellung--kopf {
        display: none;
    }

    .site-nav__darstellung {
        display: list-item;
        margin-top: var(--space-3);
        padding-top: var(--space-3);
        border-top: 1px solid var(--border);
    }

    /* Ohne JavaScript ist die Gruppe verborgen - dann keine leere Zeile mit Linie. */
    .site-nav__darstellung:has(> [hidden]) {
        display: none;
    }

    /* Der erste Verweis ueber das Haus bekommt eine Trennlinie zu den Produkten. */
    .site-nav__neben--erster {
        margin-top: var(--space-2);
        padding-top: var(--space-2);
        border-top: 1px solid var(--border);
    }

    /* Ohne JavaScript: Navigation offen, Kopf nicht klebend. */
    .site-header:has(.site-nav:not([data-collapsible="true"])) {
        position: relative;
    }

    .site-nav:not([data-collapsible="true"]) ul {
        padding-bottom: var(--space-3);
    }

    .site-nav[data-collapsible="true"] {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        max-height: calc(100dvh - var(--header-h));
        overflow-y: auto;
        padding: var(--space-3) var(--gutter) var(--space-5);
        background: var(--surface);
        border-bottom: 1px solid var(--border);
        box-shadow: var(--shadow-lg);
    }

    .site-nav[data-collapsible="true"][data-open="true"] {
        display: block;
    }

    .site-nav[data-collapsible="true"] ul {
        flex-direction: column;
        align-items: stretch;
    }

    .site-nav[data-collapsible="true"] a {
        padding: var(--space-3);
        font-size: var(--step-0);
    }

    .site-nav a[aria-current="page"]::after {
        display: none;
    }

    .site-nav a[aria-current="page"] {
        background: var(--accent-soft);
        text-decoration: underline;
        text-decoration-thickness: 2px;
        text-underline-offset: 0.35em;
    }
}

@media (min-width: 78.0625rem) {
    .nav-toggle {
        display: none;
    }
}

/* ========================================================================
   5. Bausteine
   ======================================================================== */

.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: 2.75rem;
    padding: 0.7rem 1.25rem;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    font: inherit;
    font-size: 0.9375rem;
    font-weight: 700;
    letter-spacing: -0.005em;
    line-height: 1.2;
    text-decoration: none;
    cursor: pointer;
    transition:
        background var(--transition),
        border-color var(--transition),
        box-shadow var(--transition),
        color var(--transition),
        transform var(--transition);
}

/* Der Hauptknopf hat Koerper: ein leichter Verlauf von oben und ein Schatten in seiner
   eigenen Farbe. Er ist das Einzige auf einer Seite, das so aussieht - daran erkennt man
   den naechsten Schritt. */
.button--primary {
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0)) var(--accent);
    color: var(--accent-contrast);
    box-shadow: 0 1px 2px rgba(14, 23, 38, 0.12), 0 6px 16px -6px color-mix(in srgb, var(--accent) 70%, transparent);
}

.button--primary:hover {
    background-color: var(--accent-hover);
    color: var(--accent-contrast);
    box-shadow: 0 1px 2px rgba(14, 23, 38, 0.12), 0 10px 22px -8px color-mix(in srgb, var(--accent) 80%, transparent);
}

.button--secondary {
    background: var(--surface);
    color: var(--text);
    border-color: var(--border-strong);
    box-shadow: var(--shadow-sm);
}

.button--secondary:hover {
    background: var(--surface-2);
    border-color: var(--text-muted);
    color: var(--text);
}

/* Marke statt Handlung: der Weg in den Kundenbereich. Er traegt das Zeichen (`--marke`)
   und bleibt in beiden Darstellungen dunkel; im dunklen Auftritt traegt ein heller Rand
   die Kante. */
.button--ink {
    background: var(--marke);
    color: var(--on-marke);
    border-color: var(--marke);
}

.button--ink:hover {
    background: var(--marke-3);
    border-color: var(--marke-3);
    color: var(--on-marke);
}

.button--ghost {
    background: transparent;
    color: var(--accent);
    border-color: var(--accent-line);
}

.button--ghost:hover {
    background: var(--accent-soft);
    border-color: var(--accent);
}

/* Eine Handlung mit Folgen, die sich nicht zuruecknehmen lassen (Neustart eines Servers).
   Nachgerechnet: hell Weiss auf #a3161c 7,81:1, dunkel #06102a auf #f59a9a 8,94:1. */
.button--gefahr {
    background: var(--fail);
    color: var(--accent-contrast);
    border-color: var(--fail);
}

.button--gefahr:hover {
    filter: brightness(0.92);
}

.button--gross {
    min-height: 3.25rem;
    padding: 0.9rem 1.6rem;
    font-size: 1rem;
    border-radius: var(--radius);
}

.button--block {
    width: 100%;
}

.button:active {
    transform: translateY(1px);
}

/* Ein Pfeil hinter dem Text, der beim Zeigen einen Schritt nach vorn macht. */
.button__pfeil {
    transition: transform var(--transition);
}

.button:hover .button__pfeil {
    transform: translateX(3px);
}

/* Abgeschaltete Knoepfe sollen auch so aussehen – sonst wirkt z. B. "Zahlungspflichtig
   bestellen" ohne eingerichtete Zahlungsart wie ein aktiver Primaerknopf. */
.button:disabled,
.button[aria-disabled="true"],
.button:disabled:hover,
.button[aria-disabled="true"]:hover {
    opacity: 0.55;
    cursor: not-allowed;
    box-shadow: none;
    transform: none;
}

.button--primary:disabled:hover,
.button--primary[aria-disabled="true"]:hover {
    background-color: var(--accent);
}

.badge {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.65rem;
    border-radius: var(--radius-full);
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 0.8125rem;
    font-weight: 700;
    letter-spacing: 0.01em;
    line-height: 1.5;
    white-space: nowrap;
}

.badge--ok { background: var(--ok-soft); color: var(--ok); }
.badge--warn { background: var(--warn-soft); color: var(--warn); }
.badge--fail { background: var(--fail-soft); color: var(--fail); }

.card {
    display: flex;
    flex-direction: column;
    padding: var(--space-6);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

.card h3 {
    margin-bottom: var(--space-2);
}

/* Ueberschriften in Karten sind Kastentitel, keine Abschnittsueberschriften. */
.card > h2 {
    font-size: var(--step-1);
    margin: 0 0 var(--space-3);
}

.app-body .card h2 {
    font-size: var(--step-1);
}

.card p:last-child {
    margin-bottom: 0;
}

.card__icon {
    display: grid;
    place-items: center;
    width: 2.75rem;
    height: 2.75rem;
    margin-bottom: var(--space-4);
    border-radius: var(--radius);
    background: var(--accent-soft);
    color: var(--accent);
    box-shadow: inset 0 0 0 1px var(--accent-line);
}

/*
 * Der leere Zustand (`.leer`, Gestaltung vom 28.09.2026).
 *
 * „Noch keine Angebote.“ stand bisher als loser grauer Satz unter einer Filterleiste -
 * man suchte den Rest der Seite. Dass nichts da ist, ist eine Antwort und bekommt die Form
 * einer Flaeche: gestrichelter Rand (die Stelle, an der eine Liste stuende), ein ruhiges
 * Zeichen davor. In einer Karte oder einem Hinweis ist dieselbe Aussage nur ein Satz -
 * dort waere ein Kasten im Kasten zu laut.
 */
/* Block, nicht Flex: als Flex-Container zerlegte die Flaeche einen Satz mit Verweis in
   einzelne Stuecke mit Luecken dazwischen („… Ihr Vorhaben“ und der Punkt dahinter). Das
   Zeichen steht deshalb absolut, der Text bleibt Fliesstext. */
.leer {
    position: relative;
    max-width: none;
    margin: var(--space-5) 0 0;
    padding: var(--space-6) var(--space-6) var(--space-6) calc(var(--space-6) + 2.25rem + var(--space-4));
    border: 1px dashed var(--border-strong);
    border-radius: var(--radius-lg);
    background: color-mix(in srgb, var(--surface) 55%, transparent);
    color: var(--text-muted);
}

.leer::before {
    content: "";
    position: absolute;
    left: var(--space-6);
    top: 50%;
    transform: translateY(-50%);
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    background:
        radial-gradient(circle, var(--accent) 0 0.2rem, transparent 0.22rem),
        var(--accent-soft);
    box-shadow: inset 0 0 0 1px var(--accent-line);
}

:is(.card, .note, .app-karte, td, .definition-list) .leer {
    display: block;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
}

:is(.card, .note, .app-karte, td, .definition-list) .leer::before {
    content: none;
}

.note {
    padding: var(--space-4) var(--space-5);
    border: 1px solid var(--border);
    border-left: 4px solid var(--accent);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text-muted);
}

/* Im dunklen Auftritt laege Tinte auf fast gleich dunklem Grund: eine Stufe heller und
   eine sichtbare Kante (Rand von Bedienelementen: 3:1, WCAG 1.4.11). */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .button--ink {
        background: var(--marke-3);
        border-color: #56698a;
    }
}

:root[data-theme="dark"] .button--ink {
    background: var(--marke-3);
    border-color: #56698a;
}

/* Zustaende: Randfarbe, leichte Toenung und Text in voller Staerke. Die Art steht
   ausserdem als Wort in der Meldung (partials/meldungen), nicht nur als Farbe. */
.note--warn,
.note--ok,
.note--fail {
    color: var(--text);
}

.note--warn { border-left-color: var(--warn); background: color-mix(in srgb, var(--warn) 7%, var(--surface)); }
.note--ok { border-left-color: var(--ok); background: color-mix(in srgb, var(--ok) 7%, var(--surface)); }
.note--fail { border-left-color: var(--fail); background: color-mix(in srgb, var(--fail) 7%, var(--surface)); }

.note__label {
    font-weight: 700;
}

/* Meldungen nach einer Aktion stehen untereinander, nicht aneinander. */
.note--meldung {
    margin-bottom: var(--space-4);
}

/* Die Wartezeit auf den Server ist kein Fehler und keine Warnung, sondern ein Zustand:
   deshalb der gewoehnliche Akzentrand - aber Text in voller Staerke, weil hier steht,
   was der Kunde gerade wissen muss. */
.note--warten {
    color: var(--text);
}

.note p:last-child { margin-bottom: 0; }

.note strong { color: var(--text); }

/* Tabellen
   ---------
   Jede Tabelle steht in einem .table-wrap. Ist sie breiter als der Bildschirm, laesst
   sie sich darin seitlich verschieben (die Seite selbst wird nie breiter); Schatten an
   den Raendern zeigen, dass rechts oder links noch etwas steht. app.js macht einen
   Behaelter, der tatsaechlich ueberlaeuft, per Tastatur erreichbar (tabindex="0",
   role="region" und eine Beschriftung aus der <caption>) - wer das Markup selbst
   schreibt, nimmt:

     <div class="table-wrap" role="region" aria-labelledby="…" tabindex="0">

   Fuer Listen mit wenigen, kurzen Spalten (Dienste, Rechnungen, Bestellungen) gibt es
   die gestapelte Darstellung: <table class="table-stack"> und an jeder Zelle
   data-label="Spaltenname". Unter 40rem wird dann jede Zeile zur Karte mit
   "Spalte: Wert" untereinander. Zellen ohne data-label (z. B. Knoepfe) stehen ohne
   Beschriftung in voller Breite. */
.table-wrap {
    /* Haelt auch absolut gesetzte Elemente (versteckte Beschriftungen) im Rollbereich. */
    position: relative;
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background:
        linear-gradient(to right, var(--surface) 30%, transparent) left center / 2.5rem 100% no-repeat local,
        linear-gradient(to left, var(--surface) 30%, transparent) right center / 2.5rem 100% no-repeat local,
        radial-gradient(farthest-side at 0 50%, var(--scroll-shadow), transparent) left center / 0.85rem 100% no-repeat scroll,
        radial-gradient(farthest-side at 100% 50%, var(--scroll-shadow), transparent) right center / 0.85rem 100% no-repeat scroll,
        var(--surface);
}

.table-wrap:focus-visible {
    outline-offset: 3px;
}

table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--step--1);
}

caption {
    padding: var(--space-4) var(--space-4) 0;
    text-align: left;
    font-weight: 650;
    color: var(--text);
}

th,
td {
    padding: var(--space-3) var(--space-4);
    text-align: left;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
}

thead th {
    padding-block: 0.65rem;
    background: var(--surface-2);
    font-size: 0.75rem;
    font-weight: 800;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.07em;
    white-space: nowrap;
}

tbody tr:last-child td {
    border-bottom: 0;
}

tbody tr {
    transition: background var(--transition);
}

tbody tr:hover {
    background: var(--accent-soft);
}

/* Kennungen brechen nicht am Bindestrich: „DI-00005“ stand als „DI-“ ueber „00005“, weil
   der Bindestrich eine erlaubte Umbruchstelle ist. `nowrap` verbietet aber **jeden**
   Umbruch - an einem langen Titel (Inhalte, Produkte) waere das falsch. Die Regel haengt
   deshalb am Ziel des Verweises: in der ersten Spalte fuehren genau diese Listen auf eine
   Detailseite, deren Verweistext eine Nummer ist (DI-, K-, BE-, RE-, AN-, Auftrag Nr.). */
td:first-child > a:is(
    [href^="/admin/dienste/"],
    [href^="/admin/kunden/"],
    [href^="/admin/bestellungen/"],
    [href^="/admin/rechnungen/"],
    [href^="/admin/auftraege/"],
    [href^="/admin/angebote/"],
    [href^="/management/dienste/"],
    [href^="/management/rechnungen/"],
    [href^="/management/bestellungen/"]
) {
    white-space: nowrap;
}

/* Eine Kennung als Text in ihrer Zelle („DI-00005“ in „Meine Pakete“) - ohne Verweis
   greift die Regel darueber nicht, die Klasse steht deshalb im Markup. */
td.kennung {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* Eine Zahl mit ihrer Einheit („30 Tage“, „12 Monate“) bricht nicht zwischen beidem. Die
   Klasse steht im Markup - an der Form der Zelle laesst sich das nicht erkennen, lange
   Befundtexte in der letzten Spalte sehen genauso aus. */
td.num {
    white-space: nowrap;
}

/* Aktionen einer Tabellenzeile zum Aufklappen (Produkte): die Spalte bleibt schmal. */
.aktionen-klappe summary {
    cursor: pointer;
    color: var(--accent);
    font-weight: 600;
    white-space: nowrap;
}

.aktionen-klappe[open] .admin-actions {
    margin-top: var(--space-2);
}

/* Mehrere Tabellen untereinander mit gleichen Spalten (Mailtexte je Gruppe): feste
   Breiten, damit die Spalten nicht von Karte zu Karte springen. */
.tabelle--fest {
    table-layout: fixed;
    width: 100%;
}

.tabelle--fest .spalte-schmal {
    width: 7rem;
}

.tabelle--fest .spalte-mittel {
    width: 10rem;
}

/* Gestapelte Tabelle auf schmalen Bildschirmen (Aufbau siehe .table-wrap). */
@media (max-width: 40rem) {
    .table-stack thead {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    .table-stack,
    .table-stack tbody,
    .table-stack tr {
        display: block;
        width: 100%;
    }

    .table-stack tr {
        padding: var(--space-3) var(--space-4);
        border-bottom: 1px solid var(--border);
    }

    .table-stack tbody tr:last-child {
        border-bottom: 0;
    }

    .table-stack td,
    .table-stack tbody th {
        display: block;
        padding: var(--space-1) 0;
        border: 0;
        text-align: left;
        white-space: normal;
    }

    .table-stack td[data-label],
    .table-stack tbody th[data-label] {
        display: grid;
        grid-template-columns: minmax(6.5rem, 38%) minmax(0, 1fr);
        gap: var(--space-3);
        justify-items: start;
    }

    .table-stack td[data-label]::before,
    .table-stack tbody th[data-label]::before {
        content: attr(data-label);
        color: var(--text-muted);
        font-size: var(--step--1);
        font-weight: 700;
    }

    .table-stack td:not([data-label]) {
        padding-top: var(--space-2);
    }

    .table-stack tfoot {
        display: block;
    }

    .table-stack tfoot tr {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
        gap: var(--space-2);
    }

    .table-stack tfoot td,
    .table-stack tfoot th {
        padding: 0;
        border: 0;
    }
}

.definition-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr));
    gap: var(--space-4);
    margin: 0;
}

.definition-list dt {
    font-size: var(--step--1);
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.definition-list dd {
    margin: var(--space-1) 0 0;
    /* Lange Adressen und Kennungen (API-Aufruf, E-Mail) umbrechen statt ueberzulaufen. */
    overflow-wrap: anywhere;
}

/* Untereinander statt in Spalten - wo jede Angabe einen Satz traegt (Erreichbarkeit), brechen
   zwei Spalten in einer halben Karte in schmale Streifen um. */
.definition-list--gestapelt {
    grid-template-columns: 1fr;
}

/* Messuhren (Auslastung eines Managed Servers): ein Halbkreis je Wert. Die Zeichnung ist
   aria-hidden - Zahl, Titel und Stufe stehen daneben als Text, und die Stufe hat ein Wort,
   nicht nur eine Farbe (WCAG 1.4.1). Der Fuellstand kommt als SVG-Attribut, nie als style. */
.messuhren {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
    gap: var(--space-5);
}

/* Dienstzustand unter den Messuhren: je Dienst Marke und Name, nebeneinander solange Platz ist. */
.dienstzustand h3 {
    margin: 0 0 var(--space-3);
    font-size: var(--step-0);
}

.dienstzustand__liste {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3) var(--space-6);
    margin: 0 0 var(--space-3);
    padding: 0;
    list-style: none;
}

/* Ueberschrift einer Karte mit einem Schalter daneben (Auslastung: Aktualisierung anhalten). */
.karte__kopf {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
}

.karte__kopf h2 {
    margin: 0;
}

/* Der Schalter der Auslastung: sein Name bleibt, der Zustand ist ein Punkt davor - gruen,
   solange aktualisiert wird, hohl, wenn angehalten (dazu aria-pressed fuer Screenreader). */
.auslastung-schalter::before {
    content: "";
    display: inline-block;
    width: 0.55rem;
    height: 0.55rem;
    margin-right: var(--space-2);
    border: 2px solid var(--text-muted);
    border-radius: 50%;
}

.auslastung-schalter[aria-pressed="true"]::before {
    border-color: var(--ok);
    background: var(--ok);
}

/* Der Bogen folgt dem neuen Stand weich - nur fuer den, der Bewegung nicht abbestellt hat. */
@media (prefers-reduced-motion: no-preference) {
    .messuhr__stand {
        transition: stroke-dasharray 600ms ease;
    }
}

.messuhr {
    text-align: center;
}

.messuhr__bild {
    display: block;
    width: min(100%, 11rem);
    margin-inline: auto;
}

.messuhr__bahn,
.messuhr__stand {
    fill: none;
    stroke-width: 10;
    stroke-linecap: round;
}

.messuhr__bahn {
    stroke: var(--border);
}

.messuhr__stand {
    stroke: var(--ok);
}

/* Ohne Wert kein Bogen: die runde Kappe zeichnete bei "0 100" sonst einen Punkt. */
.messuhr__stand[stroke-dasharray^="0 "] {
    stroke-opacity: 0;
}

.messuhr--knapp .messuhr__stand {
    stroke: var(--warn);
}

.messuhr--kritisch .messuhr__stand {
    stroke: var(--fail);
}

.messuhr__zahl {
    margin: calc(-1 * var(--space-5)) 0 0;
    font-size: var(--step-3);
    font-weight: 800;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

.messuhr__titel {
    margin: var(--space-1) 0 0;
    font-size: var(--step-0);
}

.messuhr__stufe {
    margin: var(--space-1) 0 0;
    font-size: var(--step--1);
    font-weight: 700;
    color: var(--ok);
}

.messuhr--knapp .messuhr__stufe {
    color: var(--warn);
}

.messuhr--kritisch .messuhr__stufe {
    color: var(--fail);
}

.messuhr--leer .messuhr__stufe {
    color: var(--text-muted);
}

/* ========================================================================
   6. Abschnitte
   ======================================================================== */

/*
 * Die Markenflaeche (`.flaeche-tinte`).
 *
 * Kopf der Startseite, Seitenkoepfe, Fussbereich, der zweite Produktweg, die Anmeldung:
 * im hellen Modus ein kuehles Blaugrau, im dunklen die tiefe Tinte - die Werte stehen als
 * `--ink*` je Darstellung in Abschnitt 1. Statt jeden Baustein darin
 * einzeln umzufaerben, stellt die Klasse den **ganzen Tokensatz** um - Knoepfe, Felder,
 * Hinweise, die Domainsuche samt Treffern passen sich von selbst an, und ein Baustein,
 * der spaeter dazukommt, auch. Alle Paarungen sind nachgerechnet (AA; hell schwaechste
 * 5,19:1 fuer Text und 3,58:1 fuer Feldraender, dunkel 6,7:1 und 4,1:1).
 */
.flaeche-tinte {
    color-scheme: var(--ink-scheme);

    --bg: var(--ink);
    --bg-alt: var(--ink-2);
    --surface: var(--ink-2);
    --surface-2: var(--ink-3);
    --border: var(--ink-border);
    --border-strong: var(--ink-border-strong);
    --text: var(--on-ink);
    --text-muted: var(--on-ink-muted);
    --input-border: var(--ink-input-border);
    --scroll-shadow: rgba(0, 0, 0, 0.6);

    --accent: var(--ink-accent);
    --accent-hover: var(--ink-accent-hover);
    --accent-contrast: var(--ink-accent-contrast);
    --accent-soft: var(--ink-accent-soft);
    --accent-line: var(--ink-accent-line);

    --ok: var(--ink-ok);
    --warn: var(--ink-warn);
    --fail: var(--ink-fail);
    --ok-soft: color-mix(in srgb, var(--ink-ok) 14%, transparent);
    --warn-soft: color-mix(in srgb, var(--ink-warn) 14%, transparent);
    --fail-soft: color-mix(in srgb, var(--ink-fail) 14%, transparent);

    --shadow-sm: var(--ink-shadow-sm);
    --shadow-md: var(--ink-shadow-md);
    --shadow-lg: var(--ink-shadow-lg);

    background-color: var(--ink);
    color: var(--text);
}

.flaeche-tinte :focus-visible {
    outline-color: var(--accent);
}

/*
 * Der Kopf der Startseite.
 *
 * Tinte mit zwei Lichtquellen - kuehles Blau von rechts oben, ein Hauch Bernstein von
 * links unten - und einem feinen Raster, das zur Mitte hin verblasst: Technik, aber ruhig.
 * Nichts davon traegt Information; es ist die Buehne fuer den einen Satz, um den es geht.
 */
.hero {
    position: relative;
    isolation: isolate;
    padding-block: var(--space-9) var(--space-9);
    overflow: hidden;
    background: var(--bg);
}

.hero.flaeche-tinte {
    background:
        radial-gradient(60rem 36rem at 88% -10%, rgb(79 124 255 / calc(0.34 * var(--ink-glow))), transparent 60%),
        radial-gradient(40rem 28rem at -5% 110%, rgba(245, 181, 61, 0.1), transparent 60%),
        linear-gradient(180deg, var(--ink) 0%, var(--ink-end) 100%);
}

.hero::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image:
        linear-gradient(to right, var(--ink-grid) 1px, transparent 1px),
        linear-gradient(to bottom, var(--ink-grid) 1px, transparent 1px);
    background-size: 4.5rem 4.5rem;
    mask-image: radial-gradient(ellipse 70% 70% at 70% 30%, #000 20%, transparent 75%);
    pointer-events: none;
}

/* Eine Horizontlinie an der Unterkante: das Band endet mit einem Lichtstreif, nicht mit
   einer harten Kante. */
.hero::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(143, 176, 255, 0.55) 30%, rgba(245, 181, 61, 0.45) 70%, transparent);
    pointer-events: none;
}

.hero__inner {
    position: relative;
    display: grid;
    gap: var(--space-8);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
    align-items: center;
}

@media (min-width: 62rem) {
    .hero__inner {
        grid-template-columns: 1.2fr 0.8fr;
    }
}

.hero__marke {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0 0 var(--space-5);
    padding: 0.35rem 0.85rem 0.35rem 0.5rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    background: var(--ink-veil);
    color: var(--text-muted);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: 0.01em;
}

.hero__marke-punkt {
    display: inline-grid;
    place-items: center;
    width: 1.35rem;
    height: 1.35rem;
    border-radius: 50%;
    background: var(--highlight-soft);
    color: var(--ink-highlight);
}

.hero__titel {
    margin-bottom: var(--space-5);
    font-size: var(--step-5);
    font-weight: 800;
    line-height: 1.04;
    letter-spacing: -0.028em;
    max-width: 17ch;
}

/* Der zweite Satz ist die Pointe - leiser gesetzt, damit der erste traegt. */
.hero__titel-zwei {
    display: block;
    color: var(--text-muted);
    font-weight: 700;
}

.hero__lead {
    font-size: var(--step-1);
    line-height: 1.55;
    color: var(--text-muted);
    max-width: 40ch;
}

.hero .cluster {
    margin-top: var(--space-6);
    gap: var(--space-3);
}

.hero__trust {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
    gap: var(--space-3) var(--space-5);
    max-width: 34rem;
    margin: var(--space-7) 0 0;
    padding: var(--space-5) 0 0;
    border-top: 1px solid var(--border);
    list-style: none;
    font-size: 0.9375rem;
    color: var(--text-muted);
}

.hero__trust li {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: 0;
}

.hero__trust svg {
    flex: 0 0 auto;
    color: var(--ink-highlight);
}

/* Die Domainsuche im Kopf: Glas auf der Markenflaeche. */
.hero .domainbox {
    position: relative;
    padding: var(--space-6);
    background: linear-gradient(180deg, var(--ink-veil), transparent);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-xl);
    box-shadow: var(--ink-shadow-lg), inset 0 1px 0 rgba(255, 255, 255, 0.08);
    backdrop-filter: blur(10px);
}

.hero .domainbox__titel {
    font-size: var(--step-2);
}

/* Unterseiten: derselbe Kopf, kleiner - Tinte, Titel, ein Satz. */
.seitenkopf {
    position: relative;
    isolation: isolate;
    padding-block: var(--space-8) var(--space-7);
    overflow: hidden;
    background:
        radial-gradient(50rem 26rem at 95% -20%, rgb(79 124 255 / calc(0.3 * var(--ink-glow))), transparent 60%),
        linear-gradient(180deg, var(--ink) 0%, var(--ink-end) 100%);
}

.seitenkopf::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image:
        linear-gradient(to right, var(--ink-grid) 1px, transparent 1px),
        linear-gradient(to bottom, var(--ink-grid) 1px, transparent 1px);
    background-size: 4.5rem 4.5rem;
    mask-image: radial-gradient(ellipse 60% 90% at 85% 0%, #000 10%, transparent 70%);
    pointer-events: none;
}

.seitenkopf .section-head {
    margin-bottom: 0;
}

.seitenkopf h1 {
    font-size: var(--step-5);
    font-weight: 800;
    letter-spacing: -0.026em;
    max-width: 22ch;
}

.seitenkopf .section-head p {
    font-size: var(--step-1);
    line-height: 1.55;
}

/* Auf dem Telefon brach „Serveradministration“ in der groessten Stufe mitten im Wort.
   Eine Stufe kleiner passt ein langes deutsches Wort in die Zeile; wo nicht, trennt das
   Telefon selbst (`hyphens: auto` steht an allen Ueberschriften). */
@media (max-width: 30rem) {
    .seitenkopf h1 {
        font-size: var(--step-4);
    }
}

/* Wo auf den Kopf direkt ein Arbeitsbereich folgt (Konfigurator), ragt er ins Band. */
.seitenkopf + .section--angedockt {
    padding-top: 0;
}

.seitenkopf + .section--angedockt > .container {
    margin-top: -5rem;
    position: relative;
}

/* Der Kopf gibt dem hineinragenden Bereich den Platz, den er ihm nimmt - sonst sitzt der
   Einleitungstext direkt auf den Karten. */
.seitenkopf:has(+ .section--angedockt) {
    padding-bottom: calc(5rem + var(--space-7));
}

/* Statuskacheln */
.stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 11rem), 1fr));
    gap: var(--space-4);
}

.stat {
    padding: var(--space-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.stat__value {
    display: block;
    font-size: var(--step-2);
    font-weight: 700;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

.stat__label {
    display: block;
    margin-top: var(--space-1);
    font-size: var(--step--1);
    color: var(--text-muted);
}

/* Produktkarten */
.plan {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: var(--space-6);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-sm);
    transition: border-color var(--transition), box-shadow 300ms var(--ease-out), transform 300ms var(--ease-out);
}

.plan:hover {
    border-color: var(--accent-line);
    box-shadow: var(--shadow-lg), var(--glow);
    transform: translateY(-3px);
}

/* Die empfohlene Stufe: ein Rahmen in Akzentfarbe und ein Schein aus der Ecke. */
.plan--featured {
    background:
        radial-gradient(28rem 14rem at 100% 0%, var(--accent-soft), transparent 70%),
        var(--surface);
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent), var(--shadow-md), var(--glow);
}

/* Die Auszeichnung („Preistipp“) sitzt als Bernstein-Plakette auf der Oberkante - ganz
   auf dem Rand, nicht halb darin; halb darin sah sie aus wie abgeschnitten. */
.plan__badge {
    position: absolute;
    top: 0;
    left: var(--space-6);
    transform: translateY(-50%);
    background: var(--highlight);
    color: var(--highlight-contrast);
    box-shadow: 0 4px 10px -4px rgba(138, 75, 0, 0.5);
}

.plan__name {
    font-size: var(--step-2);
    font-weight: 800;
    letter-spacing: -0.02em;
    margin-bottom: var(--space-1);
}

.plan__tagline {
    margin: 0 0 var(--space-5);
    font-size: 0.9375rem;
    color: var(--text-muted);
}

.plan__price {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2);
    margin-bottom: var(--space-1);
}

.plan__amount {
    font-size: var(--step-4);
    font-weight: 800;
    letter-spacing: -0.035em;
    line-height: 1.05;
    font-variant-numeric: tabular-nums;
}

.plan__period {
    white-space: nowrap;
    font-size: 0.9375rem;
    color: var(--text-muted);
}

.plan__setup {
    margin: 0 0 var(--space-5);
    font-size: var(--step--1);
    color: var(--text-muted);
}

/* Die Eckdaten als eigene Flaeche - dort schaut ein Profi zuerst hin. */
.plan__specs {
    margin: 0 0 var(--space-5);
    padding: var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-2);
    display: grid;
    gap: var(--space-2);
}

.plan__spec {
    display: flex;
    gap: var(--space-3);
    font-size: 0.9375rem;
}

.plan__spec dt {
    flex: 0 0 4.5rem;
    color: var(--text-muted);
}

.plan__spec dd {
    margin: 0;
    font-weight: 700;
}

/* Auf der Startseite genuegen auf dem Telefon Name, Ausstattung und Preis; die Liste der
   Merkmale steht auf der Produktseite (Durchsicht 29.09.2026). */
@media (max-width: 40rem) {
    .plan__features--kompakt {
        display: none;
    }
}

.plan__features {
    margin: 0 0 var(--space-6);
    padding: 0;
    list-style: none;
    font-size: 0.9375rem;
    display: grid;
    gap: var(--space-2);
}

.plan__features li {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    margin-top: 0;
    color: var(--text-muted);
}

.plan__features svg {
    flex: 0 0 auto;
    margin-top: 0.25em;
    color: var(--ok);
}

.plan__action {
    margin-top: auto;
}

.plan__action .button {
    min-height: 3rem;
}

/* Standortwahl beim Managed vServer (Phase 17) */
.plan__location {
    margin-bottom: var(--space-3);
}

/* Umschaltung der Laufzeit */
.term-switch {
    display: inline-flex;
    padding: 0.2rem;
    margin-bottom: var(--space-6);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
}

.term-switch a {
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-full);
    font-size: var(--step--1);
    font-weight: 650;
    color: var(--text-muted);
    text-decoration: none;
}

.term-switch a[aria-current="true"] {
    background: var(--accent);
    color: var(--accent-contrast);
}

/* Konfigurator */
.configurator {
    display: grid;
    gap: var(--space-6);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
    align-items: start;
}

.configurator__controls {
    display: grid;
    gap: var(--space-6);
    padding: var(--space-5);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
}

.field label {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-3);
    margin-bottom: var(--space-2);
    font-weight: 650;
}

.field output {
    font-size: var(--step-0);
    font-weight: 700;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
}

.field__hint {
    display: block;
    margin-top: var(--space-1);
    font-size: var(--step--1);
    color: var(--text-muted);
}

/* Skala unter einem Schieberegler: Minimum, Bezeichnung, Maximum nebeneinander. */
.field__hint--scale {
    display: flex;
    justify-content: space-between;
    gap: var(--space-2);
}

/* Schieberegler im Stil der Marke: Spur mit Fuellung bis zum Griff (`--regler-anteil`,
   gesetzt von configurator.js ueber CSSOM - die CSP erlaubt das, ein style-Attribut nicht).
   Ohne Skript bleibt die Spur ungefuellt, der Griff zeigt den Wert. Vorher waren es
   unformatierte Browser-Regler, im Dunkeln braeunlich-grau (Durchsicht 29.09.2026). */
input[type="range"] {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 1.75rem;
    margin: 0;
    background: transparent;
    accent-color: var(--accent);
    cursor: pointer;
}

input[type="range"]::-webkit-slider-runnable-track {
    height: 0.375rem;
    border-radius: var(--radius-full);
    background: linear-gradient(to right, var(--accent) var(--regler-anteil, 0%), var(--border-strong) var(--regler-anteil, 0%));
}

input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 1.375rem;
    height: 1.375rem;
    margin-top: -0.5rem;
    border: 3px solid var(--surface);
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 0 1px var(--accent), var(--shadow-sm, 0 1px 2px rgb(0 0 0 / 0.2));
}

input[type="range"]::-moz-range-track {
    height: 0.375rem;
    border-radius: var(--radius-full);
    background: var(--border-strong);
}

input[type="range"]::-moz-range-progress {
    height: 0.375rem;
    border-radius: var(--radius-full);
    background: var(--accent);
}

input[type="range"]::-moz-range-thumb {
    width: 1rem;
    height: 1rem;
    border: 3px solid var(--surface);
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
}

/* Genau einstellen auf dem Telefon: ein Zahlenfeld neben dem Regler (von configurator.js
   angelegt; ohne Skript gibt es "Preis berechnen"). */
.regler-zahl {
    width: 5.5rem;
    padding: var(--space-1) var(--space-2);
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.beispiele {
    padding-top: var(--space-4);
    border-top: 1px solid var(--border);
}

.beispiele ul {
    list-style: none;
    margin: var(--space-2) 0 0;
    padding: 0;
    display: grid;
    gap: var(--space-2);
}

.beispiele li {
    display: flex;
    flex-wrap: wrap;
    gap: 0 var(--space-2);
    font-size: var(--step--1);
}

.radio-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
}

.radio-row label {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    font-size: var(--step--1);
    font-weight: 600;
    cursor: pointer;
}

.radio-row input:checked + span {
    color: var(--accent);
}

.radio-row label:has(input:checked) {
    border-color: var(--accent);
    background: var(--accent-soft);
}

/* Bankdaten mit GiroCode daneben; auf schmalen Flaechen darunter. */
.zahlungsdaten {
    display: grid;
    gap: var(--space-5);
    align-items: start;
}

@media (min-width: 40rem) {
    .zahlungsdaten:has(.girocode) {
        grid-template-columns: minmax(0, 1fr) 11rem;
    }
}

.girocode {
    margin: 0;
    max-width: 11rem;
    font-size: var(--step--1);
    color: var(--text-muted);
}

.girocode figcaption {
    margin-top: var(--space-2);
}

.einrichtungscode {
    margin: 0 0 var(--space-4);
    max-width: 13rem;
}

/* Ein QR-Code steht in beiden Darstellungen dunkel auf hell - invertiert lesen ihn viele
   Banking-Apps nicht. Deshalb hier feste Werte statt Tokens der Darstellung. */
.qr {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--radius-sm);
}

.qr__hell {
    fill: #fff;
}

.qr__dunkel {
    fill: #000;
}

/* Kontakt: Formular links, Wege rechts - vorher stand das Formular mittig, die rechte
   Haelfte blieb leer (Durchsicht 29.09.2026). */
.kontakt-raster {
    display: grid;
    gap: var(--space-7);
    align-items: start;
}

@media (min-width: 60rem) {
    .kontakt-raster {
        grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
    }
}

.kontaktwege {
    display: grid;
    gap: var(--space-4);
}

.kontaktwege h2 {
    font-size: var(--step-1);
    margin: 0;
}

.kontaktwege__liste {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-2);
}

.kontaktwege .card h3 {
    font-size: var(--step-0);
    margin: 0 0 var(--space-2);
}

/* Haeufige Fragen: aufklappbare Karten, zwei Spalten ab mittlerer Breite. */
.faq {
    display: grid;
    gap: var(--space-3);
    max-width: 60rem;
}

.faq__eintrag {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.faq__eintrag summary {
    padding: var(--space-4) var(--space-5);
    font-weight: 650;
    cursor: pointer;
    list-style-position: inside;
}

.faq__eintrag summary:hover {
    color: var(--accent);
}

.faq__eintrag[open] summary {
    border-bottom: 1px solid var(--border);
}

.faq__eintrag p {
    margin: 0;
    padding: var(--space-4) var(--space-5);
    color: var(--text-muted);
}

/* Vertrauenssignale an der Kasse: ruhig, mit Haken, ohne Werbeton. */
.vertrauen {
    list-style: none;
    margin: var(--space-5) 0 0;
    padding: var(--space-4) 0 0;
    border-top: 1px solid var(--border);
    display: grid;
    gap: var(--space-2);
    font-size: var(--step--1);
    color: var(--text-muted);
}

.vertrauen li {
    position: relative;
    padding-left: 1.4em;
}

.vertrauen li::before {
    content: "✓";
    position: absolute;
    left: 0;
    color: var(--accent);
    font-weight: 700;
}

/* Laufzeit und Preisansicht nebeneinander, auf dem Telefon untereinander. */
.preiswahl {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-5);
}

.preiswahl > .term-switch {
    margin: 0;
}

.laufzeitvorteil {
    margin: calc(-1 * var(--space-3)) 0 var(--space-5);
    max-width: 60ch;
}

/* Gleich breite Wahl (Kasse: Privat- oder Geschäftskunde) - auf dem Telefon standen sie
   untereinander in verschieden breiten Kästen. */
.radio-row--gleich > label {
    flex: 1 1 12rem;
}

/* Firma und USt-IdNr. nur, wenn ein Geschäftskunde bestellt. Ohne `:has()` bleiben die
   Felder sichtbar - die Kasse verwirft sie für Privatkunden ohnehin (`Checkout::place()`). */
.checkout:has(#kundenart-privat:checked) .nur-geschaeft {
    display: none;
}

/* Summen innerhalb einer Karte (Bestellung im Kundenbereich): keine zweite gerahmte Karte in
   der Karte mit leerem Innenabstand (Durchsicht 29.09.2026). */
.summary.summary--eingebettet {
    position: static;
    padding: var(--space-4) 0 0;
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    box-shadow: none;
    background: none;
}

.summary {
    position: sticky;
    top: calc(var(--header-h) + var(--space-4));
    padding: var(--space-5);
    background: var(--surface);
    border: 1px solid var(--accent-line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md), var(--glow);
}

.summary__total {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-1) var(--space-2);
    margin-bottom: var(--space-4);
}

/* Der Zusatz neben dem Gesamtbetrag ist ein Satz („Gesamtbetrag, jetzt zu zahlen (inkl.
   19 % USt)“), keine kurze Einheit wie „pro Monat“ - mit deren `nowrap` lief er in der
   Kasse ueber den Kartenrand hinaus. */
.summary__total .plan__period {
    white-space: normal;
}

.summary__amount {
    font-size: var(--step-4);
    font-weight: 700;
    letter-spacing: -0.03em;
    font-variant-numeric: tabular-nums;
}

.summary__rows {
    margin: 0 0 var(--space-4);
    padding: var(--space-4) 0;
    border-block: 1px solid var(--border);
    display: grid;
    gap: var(--space-3);
    font-size: var(--step--1);
}

.summary__row {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--space-2);
}

.summary__row dt {
    color: var(--text-muted);
}

.summary__row dd {
    margin: 0;
    font-weight: 650;
    font-variant-numeric: tabular-nums;
}

.summary__row small {
    display: block;
    color: var(--text-muted);
    font-weight: 400;
}

/* Domainsuche */
.domain-search {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    padding: var(--space-3);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
}

.domain-search input[type="search"],
.domain-search input[type="text"] {
    flex: 1 1 14rem;
    min-width: 0;
    padding: 0.75rem 1rem;
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--input-border);
    border-radius: var(--radius-sm);
    font: inherit;
}

.domain-search input::placeholder {
    color: var(--text-muted);
}

.domain-results {
    margin-top: var(--space-5);
    display: grid;
    gap: var(--space-3);
}

/* "Weitere Endungen" klebte ohne Abstand am Treffer darueber (Durchsicht 29.09.2026). */
.domain-results > h2 {
    margin: var(--space-4) 0 0;
    font-size: 1.25rem;
}

.domain-result {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.domain-result__name {
    font-weight: 650;
    font-size: var(--step-0);
    margin-right: auto;
    word-break: break-all;
}

.domain-result__price {
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
    font-size: var(--step--1);
}

.domain-result form {
    margin: 0;
}

.domain-result__note {
    flex-basis: 100%;
    font-size: var(--step--1);
}

/* Endungen mit Preis unter dem Suchfeld der Startseite - Auskunft, kein Knopf. */
.endungspreise {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-5);
    margin: var(--space-5) 0 0;
    font-size: var(--step--1);
    color: var(--text-muted);
}

.endungspreise strong {
    font-family: var(--font-mono);
    color: var(--text);
}

.tld-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.3rem 0.7rem;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    font-size: var(--step--1);
    font-family: var(--font-mono);
    color: var(--text-muted);
}

/* Referenzen */
.reference {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    text-decoration: none;
    color: var(--text);
    transition: border-color var(--transition), transform var(--transition);
}

.reference:hover {
    border-color: var(--accent-line);
    color: var(--text);
    transform: translateY(-2px);
}

.reference__name {
    font-weight: 650;
    word-break: break-all;
}

.reference__meta {
    font-size: var(--step--1);
    color: var(--text-muted);
}

/* Aufruf zum Handeln */
.cta {
    display: grid;
    gap: var(--space-5);
    padding: var(--space-7) var(--space-5);
    background: var(--surface);
    border: 1px solid var(--accent-line);
    border-radius: var(--radius-lg);
    text-align: center;
    justify-items: center;
    box-shadow: var(--glow);
}

.cta h2 {
    margin-bottom: 0;
}

.cta p {
    margin-bottom: 0;
    color: var(--text-muted);
}

/* Formulare */
.form-grid {
    display: grid;
    gap: var(--space-5);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
}

.form-field label {
    display: block;
    margin-bottom: var(--space-2);
    font-weight: 650;
}

.form-field input,
.form-field select,
.form-field textarea {
    width: 100%;
    padding: 0.7rem 0.9rem;
    background: var(--surface);
    color: var(--text);
    border: 1px solid var(--input-border);
    border-radius: var(--radius-sm);
    font: inherit;
}

.form-field textarea {
    min-height: 10rem;
    resize: vertical;
}

.form-field--full {
    grid-column: 1 / -1;
}

.form-field__error {
    display: block;
    margin-top: var(--space-2);
    color: var(--fail);
    font-size: var(--step--1);
    font-weight: 600;
}

.form-field input[aria-invalid="true"],
.form-field textarea[aria-invalid="true"] {
    border-color: var(--fail);
}

.checkbox-field {
    display: flex;
    gap: var(--space-3);
    align-items: flex-start;
}

.checkbox-field input {
    margin-top: 0.3em;
    width: 1.1rem;
    height: 1.1rem;
    accent-color: var(--accent);
}

/* Die Anmeldung: Formular und Tintenflaeche nebeneinander, gleich hoch. */
.anmeldung {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-6);
    max-width: 68rem;
}

@media (min-width: 56rem) {
    .anmeldung {
        grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
        align-items: stretch;
    }
}

.anmeldung__formular {
    padding: var(--space-7) var(--space-7) var(--space-6);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-md);
}

.anmeldung__formular .section-head {
    margin-bottom: var(--space-6);
}

.anmeldung__formular h1 {
    font-size: var(--step-4);
}

.anmeldung__formular form > .button--primary {
    width: 100%;
    min-height: 3.25rem;
    font-size: 1rem;
}

.anmeldung__seite {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    padding: var(--space-7);
    border-radius: var(--radius-xl);
    background:
        radial-gradient(30rem 20rem at 100% 0%, rgb(79 124 255 / calc(0.38 * var(--ink-glow))), transparent 65%),
        radial-gradient(22rem 14rem at 0% 110%, rgba(245, 181, 61, 0.12), transparent 65%),
        var(--ink);
    box-shadow: var(--shadow-lg);
}

.anmeldung__seite::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image:
        linear-gradient(to right, var(--ink-grid) 1px, transparent 1px),
        linear-gradient(to bottom, var(--ink-grid) 1px, transparent 1px);
    background-size: 3.5rem 3.5rem;
    mask-image: radial-gradient(ellipse 80% 70% at 100% 0%, #000 10%, transparent 70%);
}

.anmeldung__dach {
    margin: 0 0 var(--space-3);
    color: var(--ink-highlight);
    font-size: 0.8125rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.anmeldung__seite h2 {
    font-size: var(--step-3);
    font-weight: 800;
    margin-bottom: var(--space-6);
}

.anmeldung__liste {
    display: grid;
    gap: var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
    color: var(--text-muted);
}

.anmeldung__liste li {
    position: relative;
    margin: 0;
    padding-left: var(--space-6);
}

/* Der Betriebspunkt aus dem Markenzeichen als Aufzaehlungszeichen. */
.anmeldung__liste li::before {
    content: "";
    position: absolute;
    left: 0.35rem;
    top: 0.55em;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: var(--highlight);
    box-shadow: 0 0 0 4px rgba(245, 181, 61, 0.16);
}

.anmeldung__liste strong {
    color: var(--text);
}

@media (max-width: 40rem) {
    .anmeldung__formular,
    .anmeldung__seite {
        padding: var(--space-6) var(--space-5);
    }
}

/* Inhaltsseiten mit Fliesstext.

   Die Seitenueberschrift eines Rechtstexts ist ein langes deutsches Wort
   („Geschäftsbedingungen“, „Datenschutzerklärung“) in einer schmalen Spalte. In der
   groessten Stufe brach es mitten im Wort und ohne Trennstrich - Chrome unter Windows
   hat fuer Deutsch keine Silbentrennung, `overflow-wrap` bricht dann hart. Eine Stufe
   kleiner passt jedes dieser Woerter auf einem Arbeitsplatz in eine Zeile. Eine weiche
   Trennstelle im Text waere der andere Weg, ist aber versperrt: aus denselben Vorlagen
   entstehen die unveraenderlichen Vertragsunterlagen, und jede Textaenderung dort waere
   eine neue Fassung. */
.prose > h1,
.container-narrow > .section-head > h1 {
    font-size: var(--step-4);
}

@media (max-width: 30rem) {
    .prose > h1,
    .container-narrow > .section-head > h1 {
        font-size: var(--step-3);
    }
}

/* Ein Hinweiskasten im Fliesstext steht frei - vorher klebte das Inhaltsverzeichnis an ihm. */
.prose > .note {
    margin-block: var(--space-5);
}

/* Dasselbe fuer eine Tabelle: der Absatz darunter klebte am Rahmen (Service Level). */
.prose > .table-wrap {
    margin-block: var(--space-5);
}

.prose h2 {
    margin-top: var(--space-7);
    font-size: var(--step-2);
}

.prose h3 {
    margin-top: var(--space-6);
}

.prose ul {
    max-width: 68ch;
}

/* Nur der Einleitungssatz direkt unter der Seitenueberschrift (bzw. der erste Absatz
   eines Beitragstextes) ist ein Lead – nie der erste Absatz nach einem Hinweiskasten. */
.prose > h1 + p,
.prose > p:first-child {
    font-size: var(--step-1);
    color: var(--text-muted);
}

.toc {
    padding: var(--space-4) var(--space-5);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.toc ul {
    margin-bottom: 0;
}

/* Die Rubriken der Wissensdatenbank: eine Sprungleiste statt einer Aufzaehlung im Kasten -
   fuenf kurze Woerter lesen sich nebeneinander, nicht untereinander. */
.toc--leiste {
    padding: 0;
    background: none;
    border: 0;
}

.toc--leiste ul {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    padding: 0;
    list-style: none;
}

.toc--leiste li + li {
    margin-top: 0;
}

.toc--leiste a {
    display: inline-flex;
    align-items: center;
    min-height: 2.5rem;
    padding: 0.4rem 1rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
    color: var(--text);
    font-size: 0.9375rem;
    font-weight: 600;
    text-decoration: none;
    transition: border-color var(--transition), color var(--transition);
}

.toc--leiste a:hover {
    border-color: var(--accent);
    color: var(--accent);
}

/* Die Wege auf der Fehlerseite: vier Karten, jede ganz ein Verweis. */
.wegweiser__titel {
    font-size: var(--step-2);
    margin-bottom: var(--space-5);
}

.wegweiser {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr));
    gap: var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
}

.wegweiser li + li {
    margin-top: 0;
}

.wegweiser a {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    height: 100%;
    padding: var(--space-5);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
    color: var(--text-muted);
    text-decoration: none;
    transition: border-color var(--transition), box-shadow 300ms var(--ease-out), transform 300ms var(--ease-out);
}

.wegweiser a:hover {
    border-color: var(--accent);
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.wegweiser strong {
    color: var(--accent);
    font-size: 1.0625rem;
}

/* ========================================================================
   7. Fussbereich
   ======================================================================== */

/* Der Fuss schliesst die Marke ab: Tinte (`.flaeche-tinte` am Element), oben ein Satz, wer
   wir sind, und der Weg zum Gespraech - darunter die Verweise in vier Gruppen. */
.site-footer {
    position: relative;
    margin-top: 0;
    padding-block: var(--space-8) var(--space-5);
    font-size: var(--step--1);
    background:
        radial-gradient(50rem 24rem at 100% 0%, rgb(79 124 255 / calc(0.16 * var(--ink-glow))), transparent 65%),
        var(--ink);
}

.site-footer::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(143, 176, 255, 0.5) 30%, rgba(245, 181, 61, 0.4) 70%, transparent);
}

.site-footer__kopf {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-5) var(--space-7);
    margin-bottom: var(--space-7);
    padding-bottom: var(--space-7);
    border-bottom: 1px solid var(--border);
}

.site-footer__kopf .brand {
    color: var(--text);
    font-size: 1.25rem;
}

.site-footer__satz {
    margin: var(--space-4) 0 0;
    max-width: 44ch;
    color: var(--text-muted);
    font-size: var(--step-0);
    line-height: 1.6;
}

.site-footer h2 {
    margin-bottom: var(--space-4);
    color: var(--text);
    font-size: 0.8125rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

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

/* Der Abstand zwischen zwei Links ist hier nicht Geschmack, sondern Bedingung: die Links
   sind nur 17 bis 19 px hoch und damit kleiner als die 24 x 24 px aus WCAG 2.5.8
   (Zielgroesse, Stufe AA). Sie bestehen dort ueber die Ausnahme "genug Abstand" - ein
   Kreis von 24 px Durchmesser um den Mittelpunkt darf kein Nachbarziel schneiden.
   Nachgerechnet: Mittelpunkt zu Mittelpunkt 30,8 px bei 1400 px Fensterbreite und 29,3 px
   bei 320 px (17 px Zielhoehe + 8 px Abstand + 4,3 px Rest der Zeilenhoehe), verlangt sind
   24 - also 5,3 px Spielraum im schlechtesten Fall. Wer diesen Abstand verkleinert oder
   die Schrift kleiner macht, nimmt den Spielraum weg; dann brauchen die Links stattdessen
   Innenabstand. */
.site-footer li + li {
    margin-top: var(--space-2);
}

.site-footer a {
    color: var(--text-muted);
    text-decoration: none;
}

.site-footer a:hover {
    color: var(--text);
    text-decoration: underline;
    text-decoration-color: var(--highlight);
    text-underline-offset: 0.3em;
}

/* Ein Knopf im Fuss ist kein Fussverweis: die Regel darueber ist spezifischer als die
   Knopfregel und faerbte seinen Text in die Knopffarbe (am Bild gefunden, 28.09.). */
.site-footer a.button--primary,
.site-footer a.button--primary:hover {
    color: var(--accent-contrast);
    text-decoration: none;
}

/* Kuendigen und widerrufen (E-178): eine eigene Zeile mit Knoepfen, damit sich beide von
   den Fussverweisen abgrenzen - § 356a BGB verlangt "hervorgehoben platziert". Der Rand
   traegt die Farbe des gedaempften Textes: die ist in jeder Flaeche und Darstellung als
   Text nachgerechnet (mindestens 4,5:1) und liegt damit sicher ueber den 3:1 fuer Raender. */
.vertragsende {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    margin-top: var(--space-7);
}

.vertragsende__titel {
    margin: 0 var(--space-2) 0 0;
    color: var(--text);
    font-weight: 700;
}

.vertragsende a.button--secondary,
.vertragsende a.button--secondary:hover {
    color: var(--text);
    border-color: var(--text-muted);
    text-decoration: none;
}

.vertragsende a.button--secondary:hover {
    border-color: var(--text);
}

.app__fuss .vertragsende {
    margin: 0 0 var(--space-4);
}

/* Auf dem Telefon steht die Zeile sonst halb neben dem ersten Knopf, halb darueber. */
@media (max-width: 40rem) {
    .vertragsende__titel {
        flex-basis: 100%;
    }
}

/* Auf einer kurzen Seite steht der Fuss am unteren Rand, nicht mitten im Fenster mit
   heller Flaeche darunter. Nur fuer die oeffentliche Schale - die Arbeitsoberflaeche hat
   ihren eigenen Aufbau. */
body:has(> .site-footer) {
    display: flex;
    flex-direction: column;
    min-height: 100dvh;
}

body:has(> .site-footer) > main {
    flex: 1 0 auto;
}

.site-footer__bottom {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3) var(--space-5);
    align-items: center;
    margin-top: var(--space-7);
    padding-top: var(--space-5);
    border-top: 1px solid var(--border);
    color: var(--text-muted);
}

.site-footer__bottom p {
    margin: 0;
}

/* Die grossen Zahlen der Startseite: Tinte, grosse Ziffern, eine Lichtlinie darueber. */
.band-zahlen {
    background:
        radial-gradient(44rem 22rem at 50% -10%, rgb(79 124 255 / calc(0.26 * var(--ink-glow))), transparent 65%),
        var(--ink);
}

.band-zahlen .stats {
    gap: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    background: rgba(255, 255, 255, 0.02);
    overflow: hidden;
}

.band-zahlen .stat {
    padding: var(--space-6) var(--space-5);
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
}

.band-zahlen .stat + .stat {
    border-left: 1px solid var(--border);
}

@media (max-width: 48rem) {
    .band-zahlen .stat + .stat {
        border-left: 0;
        border-top: 1px solid var(--border);
    }
}

.band-zahlen .stat__value {
    font-size: var(--step-4);
    font-weight: 800;
    letter-spacing: -0.03em;
    background: linear-gradient(180deg, var(--ink-number-from) 30%, var(--ink-number-to));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

/* Ein Verweis darin bleibt ein Verweis: in Akzentfarbe, ohne Verlauf. */
.band-zahlen .stat__value a {
    color: var(--accent);
    -webkit-text-fill-color: var(--accent);
}

.band-zahlen .stat__label {
    margin-top: var(--space-2);
    font-size: 0.9375rem;
}

/* „bis“ steht als kleine Vorzeile ueber der Zahl - in derselben Groesse brach es allein
   in eine Zeile, und die Zahl, um die es geht, rutschte darunter. */
.stat__vor {
    display: block;
    margin-bottom: var(--space-1);
    font-size: 0.8125rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    -webkit-text-fill-color: var(--text-muted);
    color: var(--text-muted);
}

.band-zahlen .stat__value {
    white-space: nowrap;
}

/* Die vierte Kachel ist ein Verweis, keine Zahl: kleiner, damit „Live-Status“ nicht am
   Bindestrich bricht, und mit derselben Vorzeilenhoehe wie die Zahlen daneben. */
.band-zahlen .stat--verweis .stat__value {
    padding-top: 1.35rem;
    font-size: var(--step-2);
}

.band-zahlen__aktion {
    text-align: center;
    max-width: none;
}

/* ========================================================================
   7a. Warenkorb, Kasse und Bestellbestaetigung
   ======================================================================== */

.nav-cart__count {
    display: inline-grid;
    place-items: center;
    min-width: 1.4rem;
    height: 1.4rem;
    padding: 0 0.35rem;
    border-radius: var(--radius-full);
    background: var(--accent);
    color: var(--accent-contrast);
    font-size: var(--step--1);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.plan__alt {
    margin: var(--space-2) 0 0;
    text-align: center;
    font-size: var(--step--1);
    color: var(--text-muted);
}

/* Warenkorb: Positionen links, Summe rechts. Unter 60rem stapelt es. */
.cart {
    display: grid;
    gap: var(--space-6);
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
}

@media (min-width: 60rem) {
    .cart {
        grid-template-columns: minmax(0, 1fr) 22rem;
    }

    .cart__summary {
        position: sticky;
        /* unter dem klebenden Kopfbereich, nicht dahinter */
        top: calc(var(--header-h) + var(--space-4));
    }
}

.cart__items {
    display: grid;
    gap: var(--space-4);
}

.cart-item {
    display: grid;
    gap: var(--space-4);
    padding: var(--space-5);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
}

@media (min-width: 48rem) {
    .cart-item {
        grid-template-columns: minmax(0, 1fr) auto auto;
        align-items: start;
    }
}

.cart-item__name {
    margin: 0 0 var(--space-1);
    font-size: var(--step-1);
}

.cart-item__facts {
    margin: var(--space-2) 0 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: var(--space-1);
    font-size: var(--step--1);
    color: var(--text-muted);
}

.cart-item__quantity {
    display: grid;
    gap: var(--space-2);
    justify-items: start;
}

.cart-item__quantity label {
    font-size: var(--step--1);
    color: var(--text-muted);
}

.cart-item__quantity input[type="number"] {
    width: 5rem;
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--input-border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--text);
    font: inherit;
    font-variant-numeric: tabular-nums;
}

.cart-item__remove {
    color: var(--fail);
}

.cart-item__price {
    margin: 0;
    display: grid;
    gap: var(--space-1);
    text-align: right;
    justify-items: end;
}

.cart-item__amount {
    font-size: var(--step-1);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* Kasse: Formular links, Bestelluebersicht rechts (und vor der Schaltflaeche). */
.checkout {
    display: grid;
    gap: var(--space-6);
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
}

@media (min-width: 62rem) {
    .checkout {
        grid-template-columns: minmax(0, 1fr) 24rem;
    }

    .checkout__summary {
        position: sticky;
        /* unter dem klebenden Kopfbereich, nicht dahinter */
        top: calc(var(--header-h) + var(--space-4));
    }
}

.checkout__main {
    display: grid;
    gap: var(--space-5);
}

.checkout__block {
    margin: 0;
    padding: var(--space-5);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
}

/* Die drei Schritte der Kasse sind gleichrangig und gleich gross: „3 Ihre Bestellung“ stand
   als freie Ueberschrift doppelt so gross wie „1 Wer bestellt?“. */
.checkout__block legend,
.summary > h2 {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: 0 var(--space-2);
    font-size: var(--step-1);
    font-weight: 750;
}

.summary > h2 {
    margin-bottom: var(--space-4);
    padding: 0;
}

.checkout__step {
    display: inline-grid;
    place-items: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: var(--radius-full);
    background: var(--accent-soft);
    color: var(--accent);
    font-size: var(--step--1);
    font-weight: 700;
}

.payment-options {
    display: grid;
    gap: var(--space-3);
}

.payment-option {
    display: flex;
    gap: var(--space-3);
    align-items: flex-start;
    padding: var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-2);
    cursor: pointer;
}

.payment-option:has(input:checked) {
    border-color: var(--accent);
    background: var(--accent-soft);
}

.payment-option span {
    display: grid;
    gap: var(--space-1);
}

.payment-option small {
    color: var(--text-muted);
}

/* ========================================================================
   7b. Arbeitsoberflaeche (Verwaltung und Kundenbereich)
   ======================================================================== */

/*
 * Eine Schale fuer beide angemeldeten Bereiche: Navigation links in Gruppen, Inhalt
 * rechts ueber die ganze verbleibende Breite.
 *
 * Vorher lag die Navigation waagerecht oben - in der Verwaltung 28 Punkte, die auf jedem
 * Bildschirm in zwei bis drei Zeilen umbrachen, im Kundenbereich eine zweite Zeile unter
 * der Verkaufsnavigation der Website. Beides wirkte unfertig und wurde mit jedem neuen
 * Punkt schlechter. Senkrecht bricht nichts um, die Gruppe sagt, wonach man sucht, und
 * der Inhalt bekommt die Breite, die eine Tabelle mit zehn Spalten braucht.
 *
 * Unter 62rem wird die Leiste zur Schublade - ueber denselben Knopf, den auch die
 * Website benutzt. Ohne JavaScript bleibt sie einfach stehen und ruecht ueber den
 * Inhalt: sichtbar bleibt sie immer.
 */
.app {
    display: grid;
    grid-template-columns: 17rem minmax(0, 1fr);
    min-height: 100vh;
    background: var(--bg);
}

/* Die Seitenleiste folgt der gewaehlten Darstellung: hell im hellen, dunkel im dunklen
   Modus. Bis zum 29.09.2026 war sie in beiden Tinte - dem Betreiber fiel auf, dass der
   helle Modus damit hinter der Anmeldung nur halb hell war. Die Marke traegt das Zeichen
   mit dem Betriebspunkt und der Lichtschein aus dem Akzent. */
.app__seitenleiste {
    position: sticky;
    top: 0;
    align-self: start;
    height: 100vh;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--space-4) var(--space-3) var(--space-6);
    background:
        radial-gradient(22rem 16rem at 0% 0%, var(--accent-soft), transparent 70%),
        var(--surface);
    border-right: 1px solid var(--border);
    scrollbar-color: var(--border-strong) transparent;
}

.app__marke {
    padding: var(--space-2) var(--space-3) var(--space-6);
}


.app__marke .brand {
    color: var(--text);
}

.app-nav__gruppe + .app-nav__gruppe {
    margin-top: var(--space-5);
}

.app-nav__titel {
    margin: 0 0 var(--space-2);
    padding-inline: var(--space-3);
    font-size: 0.6875rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.app-nav ul {
    list-style: none;
    margin: 0;
    padding: 0;
}

.app-nav li {
    margin: 0;
}

.app-nav li + li {
    margin-top: 2px;
}

.app-nav a {
    display: block;
    padding: 0.5rem var(--space-3);
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 600;
    transition: background var(--transition), color var(--transition);
}

.app-nav a:hover,
.app-nav a:focus-visible {
    background: var(--bg-alt);
    color: var(--text);
}

/* Die aktuelle Seite: eine getoente Flaeche und ein Strich in Bernstein - der Strich
   verschiebt nichts, wenn er erscheint, und Farbe allein genuegt nicht (WCAG 1.4.1). */
.app-nav a[aria-current="page"] {
    background: var(--accent-soft);
    color: var(--text);
    font-weight: 700;
    box-shadow: inset 3px 0 0 var(--highlight);
}

.app__spalte {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.app__kopf {
    position: sticky;
    top: 0;
    z-index: 20;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-height: 4rem;
    padding: var(--space-3) var(--space-6);
    background: color-mix(in srgb, var(--surface) 88%, transparent);
    backdrop-filter: saturate(160%) blur(14px);
    border-bottom: 1px solid var(--border);
}

.app__kopfmarke {
    display: none;
    font-weight: 800;
    color: var(--text);
    text-decoration: none;
}

.app__konto {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-left: auto;
    font-size: var(--step--1);
    color: var(--text-muted);
}

.app__kopflink {
    color: var(--text-muted);
    font-weight: 600;
    text-decoration: none;
}

.app__kopflink:hover,
.app__kopflink:focus-visible {
    color: var(--accent);
    text-decoration: underline;
}

.app__person {
    display: flex;
    flex-direction: column;
    line-height: 1.25;
    text-align: right;
    color: var(--text);
    font-weight: 700;
}

.app__person small {
    font-weight: 500;
}

.app__inhalt {
    flex: 1;
    padding-block: var(--space-7) var(--space-8);
}

/*
 * Die Arbeitsbreite. Nicht unbegrenzt - jenseits von etwa 110rem wird selbst eine
 * Tabelle unleserlich, weil das Auge die Zeile nicht mehr haelt -, aber deutlich mehr
 * als die Breite der Website: hinter der Anmeldung stehen Listen, keine Fliesstexte.
 */
.app__breite {
    width: min(100% - 2 * var(--space-6), 110rem);
    margin-inline: auto;
}

/* Seiten, auf denen wirklich gelesen oder ausgefuellt wird (Stammdaten, Sicherheit,
   eine Supportanfrage), behalten ihre Lesebreite. */
.app__seite--schmal {
    max-width: 58rem;
}

.app__titel {
    margin: 0 0 var(--space-6);
    font-size: var(--step-3);
    font-weight: 800;
    letter-spacing: -0.024em;
}

/* Der Empfang im Kundenbereich: eine Flaeche mit Lichtschein in der Farbe der gewaehlten
   Darstellung, links der Gruss, rechts die drei haeufigsten Wege. */
.willkommen {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-5) var(--space-7);
    margin-bottom: var(--space-6);
    padding: var(--space-7) var(--space-7) var(--space-6);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    background:
        radial-gradient(36rem 20rem at 100% 0%, var(--accent-line), transparent 65%),
        radial-gradient(24rem 14rem at 0% 120%, var(--highlight-soft), transparent 65%),
        var(--surface);
    box-shadow: var(--shadow-md);
}

.willkommen::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image:
        linear-gradient(to right, var(--border) 1px, transparent 1px),
        linear-gradient(to bottom, var(--border) 1px, transparent 1px);
    background-size: 3.5rem 3.5rem;
    mask-image: radial-gradient(ellipse 60% 100% at 100% 0%, #000 10%, transparent 70%);
}

.app-body .willkommen h1 {
    margin: 0;
    font-size: var(--step-4);
    font-weight: 800;
    letter-spacing: -0.026em;
}

.willkommen__nummer {
    margin: var(--space-2) 0 0;
    color: var(--text-muted);
}

.willkommen__wege {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
}

@media (max-width: 40rem) {
    .willkommen {
        padding: var(--space-6) var(--space-5);
    }
}

.app__fuss {
    border-top: 1px solid var(--border);
    padding-block: var(--space-5);
    color: var(--text-muted);
    font-size: var(--step--1);
}

/* Die Pflichtlinks stehen als eine Zeile mit Mittelpunkten als Trenner. Bricht sie um -
   auf einem Telefon ab etwa 340 px Breite -, liegen der letzte Link der ersten und der
   erste Link der zweiten Zeile senkrecht so dicht beieinander, dass die Ausnahme "genug
   Abstand" von WCAG 2.5.8 (Zielgroesse, Stufe AA) nicht mehr greift: gemessen 22,1 px
   von Mittelpunkt zu Mittelpunkt, verlangt sind 24. Die Links selbst sind nur 17 px hoch.

   Deshalb eine Zeilenhoehe in absoluter Groesse: 1.625rem sind 26 px, gleichgueltig wie
   gross die fluide Schrift gerade ausfaellt - eine Zeilenhoehe als Faktor waere bei
   kleiner Schrift wieder zu knapp. In einer Zeile wird der Streifen davon 3 px hoeher,
   sonst aendert sich nichts. */
.app__fuss p {
    margin: 0;
    line-height: 1.625rem;
}

.app__menue {
    display: none;
}

.app__inhalt .note + * {
    margin-top: var(--space-4);
}

@media (max-width: 62rem) {
    .app {
        grid-template-columns: minmax(0, 1fr);
    }

    .app__menue {
        display: inline-flex;
    }

    .app__kopfmarke {
        display: block;
    }

    /* Mit JavaScript: Schublade von links.

       **Geschlossen ist sie nicht da, nicht nur verschoben.** Waere sie bloss aus dem
       Bild geschoben, blieben ihre Verweise anklickbar und vor allem mit Tab erreichbar:
       wer sich die Seite mit der Tastatur erschliesst, landete in einem Dutzend
       unsichtbarer Links und wuesste nicht, wo er ist (WCAG 2.2, 2.4.3 Fokus-Reihenfolge
       und 2.4.11 Fokus nicht verdeckt). `visibility: hidden` nimmt sie aus der
       Tab-Reihenfolge und aus dem Baum fuer die Sprachausgabe.

       Der Uebergang bleibt trotzdem sichtbar, aber **nicht ueber eine Blende auf
       `visibility`**: die war 160 ms lang unentschieden, und genau in dieser Zeit lief
       das `focus()` aus `app.js` ins Leere - der Fokus blieb am Knopf, und weil die
       Seitenleiste im Quelltext vor ihm steht, fuehrte der naechste Tabulator in den
       Inhalt statt ins Menue (im Browser nachgemessen). Stattdessen schaltet
       `visibility` ohne Dauer: beim Aufklappen sofort (`0s`), beim Zuklappen erst nach
       dem Hinausschieben (`0s linear 160ms`). Sichtbar ist dasselbe, aber die Schublade
       ist im selben Augenblick fokussierbar, in dem sie aufgeht. */
    .app__seitenleiste[data-collapsible="true"] {
        position: fixed;
        inset: 0 auto 0 0;
        z-index: 40;
        width: min(18rem, 85vw);
        box-shadow: var(--shadow-lg);
        transform: translateX(-100%);
        visibility: hidden;
        transition: transform 160ms ease, visibility 0s linear 160ms;
    }

    .app__seitenleiste[data-collapsible="true"][data-open="true"] {
        transform: translateX(0);
        visibility: visible;
        transition: transform 160ms ease, visibility 0s;
    }

    /* Ohne JavaScript: einfach ueber dem Inhalt, nie verborgen. */
    .app__seitenleiste:not([data-collapsible="true"]) {
        position: static;
        height: auto;
        border-right: 0;
        border-bottom: 1px solid var(--border);
    }

    .app__breite {
        width: min(100% - 2 * var(--gutter), 110rem);
    }

    .app__kopf {
        padding-inline: var(--gutter);
    }
}

/* Auf dem Telefon lief der Kopf ueber: „Zur Website“ brach in zwei Zeilen, der Name wurde
   abgeschnitten, und **„Abmelden“ lag ausserhalb des Schirms**. Weg faellt, was ohnehin
   woanders steht - „Zur Website“ im Fuss, der Name auf der Seite. Abmelden und die
   Darstellung bleiben: sie steht nur hier (Betreiber, 29.09.2026 - einmal oben reicht). */
@media (max-width: 40rem) {
    .app__konto .app__kopflink,
    .app__konto .app__person {
        display: none;
    }
}

/* Ganz schmal (Telefon hochkant) reicht der Platz fuer Menue, Darstellung und Abmelden -
   aber nicht auch noch fuer den Schriftzug; er steht in der Schublade und als Dachzeile. */
@media (max-width: 30rem) {
    .app__kopf .app__kopfmarke {
        display: none;
    }
}

@media (max-width: 40rem) {

    .app__kopf {
        gap: var(--space-2);
    }
}

@media (prefers-reduced-motion: reduce) {
    .app__seitenleiste[data-collapsible="true"] {
        transition: none;
    }
}
.admin-filter {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

/* Filterformulare: Feld darf wachsen, Knoepfe stehen auf Hoehe des Eingabefelds. */
form.admin-filter {
    align-items: flex-end;
    margin-bottom: var(--space-4);
}

form.admin-filter .form-field {
    flex: 1 1 14rem;
    max-width: 28rem;
}

/* Die Spalte mit dem Suchfeld ist so breit wie sein Platzhalter - sonst schnitt die Spalte
   ab, was das Feld selbst schon zeigen wollte (Rechnungen). */
form.admin-filter .form-field:has(> input[type="search"]) {
    flex-basis: 22rem;
}

/* Zustandsfilter sehen aus wie Filter, nicht wie Code (die TLD-Chips sind monospace).

   Eine Form fuer alle Filterleisten der Arbeitsoberflaeche (Gestaltung vom 28.09.2026):
   vorher standen fuer dieselbe Sache eckige Knoepfe ohne sichtbaren Zustand (Angebote,
   Empfehlungen) neben kleinen Pillen. Jetzt 2,25 rem hoch - eine Zielflaeche, die man
   trifft -, und der aktive Filter traegt neben der Farbe einen Punkt, damit er nicht nur
   an der Farbe zu erkennen ist (WCAG 1.4.1). Im Markup steht dazu `aria-current`. */
.admin-filter {
    align-items: center;
}

.admin-filter .tld-chip {
    gap: 0.4rem;
    min-height: 2.25rem;
    padding: 0.35rem 0.9rem;
    background: var(--surface);
    border-color: var(--border);
    font-family: inherit;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--text-muted);
    text-decoration: none;
    box-shadow: var(--shadow-sm);
    transition: color var(--transition), border-color var(--transition), background var(--transition);
}

.admin-filter .tld-chip:hover {
    color: var(--text);
    border-color: var(--border-strong);
}

.admin-filter .tld-chip--active,
.admin-filter .tld-chip--active:hover {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
    font-weight: 700;
}

.admin-filter .tld-chip--active::before {
    content: "";
    width: 0.4rem;
    height: 0.4rem;
    border-radius: 50%;
    background: currentColor;
}

.tld-chip--active {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--accent);
}

.admin-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.admin-actions .button {
    padding: 0.3rem 0.6rem;
    font-size: var(--step--1);
}

/* Ueberschrift mit Schaltflaeche daneben; auf schmalen Bildschirmen untereinander. */
.admin-heading-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2) var(--space-4);
    margin-bottom: var(--space-3);
}

.admin-heading-row > h2 {
    margin: 0;
}

.admin-inline-check {
    display: block;
    font-size: var(--step--1);
    color: var(--text-muted);
}

.admin-form {
    display: grid;
    gap: var(--space-4);
}

.admin-split {
    display: grid;
    gap: var(--space-6);
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
}

@media (min-width: 64rem) {
    .admin-split {
        grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    }
}

/* Tabellen hinter der Anmeldung tragen mehr Spalten: kleinere Schrift, engere Zellen. */
.app-body .table-wrap table {
    font-size: var(--step--1);
}

.app-body .table-wrap td,
.app-body .table-wrap th {
    padding: var(--space-2) var(--space-3);
}

.app-body .table-wrap input[type="text"],
.app-body .table-wrap input[type="number"] {
    padding: 0.35rem 0.5rem;
    border: 1px solid var(--input-border);
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    color: var(--text);
    font: inherit;
    font-size: var(--step--1);
}

/* Roh-Anfrage und Roh-Antwort eines API-Aufrufs. Umbruch statt waagerechtem
   Scrollen: JSON-Zeilen sind lang, und im Fehlerfall will man alles sehen. */
/* `.code-block` steht weiter unten - hier stand dieselbe Klasse ein zweites Mal, und
   die spaetere gewann: `margin`, `line-height` und `overflow-wrap` von hier wirkten nie.
   Zusammengelegt, damit niemand die tote Haelfte pflegt. */

/* ========================================================================
   8. Bewegung und Barrierefreiheit
   ======================================================================== */

/* Einblenden beim Scrollen. Versteckt wird nur, was app.js ausdruecklich als
   "pending" markiert - und das nur auf dem Bildschirm und nur ohne Wunsch nach
   reduzierter Bewegung. Ohne JavaScript, beim Drucken und fuer Suchmaschinen ist
   alles sichtbar; was beim Laden schon im Bild ist, blendet das Skript gar nicht erst aus. */
@media screen and (prefers-reduced-motion: no-preference) {
    .js-reveal[data-reveal="pending"] {
        opacity: 0;
        transform: translateY(12px);
    }

    .js-reveal[data-reveal="shown"] {
        opacity: 1;
        transform: none;
        transition: opacity 400ms ease, transform 400ms ease;
    }
}

@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;
    }

    .plan:hover,
    .reference:hover,
    .button:active {
        transform: none;
    }
}

/* Windows-Kontrastmodus: Flaechen verschwinden, Raender und Fokus bleiben sichtbar. */
@media (forced-colors: active) {
    .button,
    .nav-toggle,
    .darstellung__knopf,
    .badge {
        border: 1px solid ButtonText;
    }

    .site-nav a[aria-current="page"],
    .app-nav a[aria-current="page"] {
        border: 1px solid Highlight;
    }
}

/* Druck: immer hell, ohne Navigation und Bedienelemente, Tabellen in voller Breite. */
@media print {
    :root,
    :root[data-theme="dark"],
    :root:not([data-theme="light"]) {
        color-scheme: light;
        --bg: #fff;
        --bg-alt: #fff;
        --surface: #fff;
        --surface-2: #fff;
        --border: #bbb;
        --border-strong: #888;
        --text: #000;
        --text-muted: #333;
        --accent: #1f4fd8;
        --accent-hover: #1f4fd8;
        --accent-contrast: #fff;
        --accent-soft: transparent;
        --accent-line: #888;
        --ok: #0f6b3c;
        --warn: #7a4a00;
        --fail: #97161b;
        --ok-soft: transparent;
        --warn-soft: transparent;
        --fail-soft: transparent;
        --shadow-sm: none;
        --shadow-md: none;
        --shadow-lg: none;
        --glow: none;
        --scroll-shadow: transparent;
    }

    .skip-link,
    .site-header,
    .site-footer,
    .nav-toggle,
    .darstellung,
    .darstellung-wahl,
    .app__seitenleiste,
    .app__kopf,
    .app__fuss,
    .impersonation form,
    .cta {
        display: none !important;
    }

    body {
        background: #fff;
        color: #000;
        font-size: 11pt;
    }

    .hero::before,
    .hero::after {
        display: none;
    }

    .hero,
    .section {
        padding-block: var(--space-5);
    }

    .js-reveal {
        opacity: 1 !important;
        transform: none !important;
    }

    .summary,
    .cart__summary,
    .checkout__summary {
        position: static;
    }

    .table-wrap {
        overflow: visible;
    }

    tr,
    .card,
    .plan,
    .note {
        break-inside: avoid;
    }

    h1,
    h2,
    h3 {
        break-after: avoid;
    }

    /* Verweisziele im Fliesstext mitdrucken - auf Papier kann man nicht klicken. */
    .prose a[href^="http"]::after {
        content: " (" attr(href) ")";
        font-size: 0.85em;
        word-break: break-all;
    }
}

/* ========================================================================
   9. Kundenbereich (Phase 5)
   ======================================================================== */

/* ========================================================================
   10. Administration und Inhalte (Phase 6)
   ======================================================================== */

/* Ansicht als Kunde: bewusst auffaellig und ganz oben. Farbe allein genuegt nicht
   (WCAG 1.4.1), deshalb steht der Zustand auch als Text darin. */
.impersonation {
    background: var(--warn-soft);
    color: var(--warn);
    border-bottom: 2px solid var(--warn);
}

.impersonation__inner {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    align-items: center;
    justify-content: space-between;
    padding-block: var(--space-3);
}

.impersonation p {
    margin: 0;
    max-width: 70ch;
}

.impersonation form {
    margin: 0;
}

/* Zwei gleichwertige Karten nebeneinander - Kundenakte, Auftragsdetail.
   Gleichrangiges steht nebeneinander - und endet auch nebeneinander. Mit
   `align-items: start` behielt jede Karte ihre natuerliche Hoehe, und unter der
   kuerzeren blieb der Seitenhintergrund stehen: gemessen 527 px in der Kundenakte,
   325 px im Postausgang, 61 bis 204 px auf den uebrigen vier Seiten. Wie bei
   `.kartenraster` fuellt die Karte jetzt ihre Zeile aus. */
.admin-grid {
    display: grid;
    gap: var(--space-5);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
    align-items: stretch;
}

.button-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: center;
    margin-top: var(--space-4);
}

.button-row form {
    margin: 0;
}

/* Aufklappbarer Bereich (Stammdaten aendern). Funktioniert ohne JavaScript. */
.admin-details {
    padding: var(--space-4) var(--space-5);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.admin-details summary {
    cursor: pointer;
    font-weight: 600;
}

.admin-details[open] summary {
    margin-bottom: var(--space-4);
}

.form-legend {
    display: block;
    margin-bottom: var(--space-2);
    font-weight: 600;
}

/* Notizen der Kundenakte: Liste ohne Aufzaehlungszeichen, neueste zuerst. */
.note-list {
    list-style: none;
    padding: 0;
}

.note-list > li {
    padding: var(--space-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius);
}

.note-list > li + li {
    margin-top: var(--space-3);
}

.note-list__meta {
    margin-bottom: var(--space-2);
    color: var(--text-muted);
    font-size: var(--step--1);
}

.note-list p:last-child {
    margin-bottom: 0;
}

/* Verlauf einer Supportanfrage (Phase 10). Wer schreibt, erkennt man an der Seite der
   Linie und an der Beschriftung - nicht allein an der Farbe (WCAG 1.4.1). Interne
   Notizen sind zusaetzlich gestrichelt umrandet und tragen ein Etikett. */
.ticket-thread {
    list-style: none;
    padding: 0;
    margin: 0;
}

.ticket-message {
    padding: var(--space-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius);
}

.ticket-message + .ticket-message {
    margin-top: var(--space-3);
}

.ticket-message--customer {
    border-left-color: var(--text-muted);
}

.ticket-message--internal {
    border-style: dashed;
    border-left-style: solid;
    border-left-color: var(--warn);
    background: var(--surface-2);
}

.ticket-message--system {
    padding-block: var(--space-2);
    border-left-color: var(--border);
    background: transparent;
    color: var(--text-muted);
    font-size: var(--step--1);
}

.ticket-message__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: center;
    margin-bottom: var(--space-2);
    color: var(--text-muted);
    font-size: var(--step--1);
}

.ticket-message__meta strong {
    color: var(--text);
}

.ticket-message__body p {
    margin-bottom: 0;
    overflow-wrap: anywhere;
}

.ticket-message--system .ticket-message__meta {
    margin-bottom: 0;
}

.ticket-message__files {
    margin: var(--space-3) 0 0;
    padding-left: var(--space-5);
    font-size: var(--step--1);
}

/* Vorformatierter Text: Auftragsdaten, Fehlermeldungen. Umbruch erlaubt, damit eine
   lange Zeile die Seite nicht breiter macht als den Bildschirm. */
/* Ein Block, kein Zeichen im Fliesstext: `overflow-x` wirkt an einem Inline-Element
   gar nicht, und genau daran stand die otpauth-Adresse auf der Sicherheitsseite ueber
   die Karte hinaus. */
.code-block {
    display: block;
    margin: 0;
    padding: var(--space-4);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text);
    font-family: var(--font-mono);
    font-size: var(--step--1);
    line-height: 1.5;
    white-space: pre-wrap;
    word-break: break-word;
    overflow-wrap: anywhere;
    overflow-x: auto;
}

.permission-table th[scope="row"] {
    text-align: left;
    font-weight: 500;
}

/* Medienverwaltung */
.media-grid {
    display: grid;
    gap: var(--space-4);
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
    list-style: none;
    padding: 0;
}

.media-grid > li + li {
    margin-top: 0;
}

.media-grid img {
    width: 100%;
    height: auto;
    max-height: 12rem;
    object-fit: contain;
    background: var(--surface-2);
    border-radius: var(--radius-sm);
}

.media-grid__meta {
    margin-block: var(--space-3);
    color: var(--text-muted);
    font-size: var(--step--1);
    word-break: break-word;
}

/* Blog und Wissensdatenbank */
/*
 * Die Liste der Beitraege und Artikel - zwei Spalten, wo Platz ist.
 *
 * Ein Absatz hoert bei 68 Zeichen auf (Lesebreite), die Karte lief aber ueber die
 * ganze Breite: neben jedem Anriss stand ein leeres Drittel, und dreizehn Artikel
 * untereinander sind eine lange Rutschpartie. Zwei Spalten bringen doppelt so viel
 * ins Bild, ohne dass der Text schmaler wird als er ohnehin ist.
 *
 * **Kein `grid-auto-flow: dense`**: das loeste die Reihenfolge auf dem Bildschirm von
 * der im Quelltext (WCAG 1.3.2 und 2.4.3). Die Karten sind gleich hoch, damit eine
 * Zeile nicht ausfranst (wie `.kartenraster`).
 */
.article-list {
    list-style: none;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr));
    gap: var(--space-4);
    align-items: stretch;
}

.article-card {
    display: grid;
    gap: var(--space-4);
    grid-template-columns: minmax(0, 1fr);
    padding: var(--space-5);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

@media (min-width: 48rem) {
    .article-card:has(img) {
        grid-template-columns: 14rem minmax(0, 1fr);
        align-items: start;
    }
}

.article-card img {
    width: 100%;
    height: auto;
    border-radius: var(--radius-sm);
}

.article-card h2,
.article-card h3 {
    margin-bottom: var(--space-2);
    font-size: var(--step-1);
}

/* Zwei Karten nebeneinander: ein Titel in zwei Zeilen neben einem in einer liess die
   Anrisstexte ungleich hoch beginnen (Durchsicht 29.09.2026). */
@media (min-width: 56rem) {
    .article-list .article-card h3 {
        min-height: 2.6em;
    }
}

/* Querverweise unter einem Artikel: kleiner als dessen Abschnittsueberschriften, sonst
   wirkt "Mehr zu …" wichtiger als der Artikel selbst. */
.artikel-weiter {
    font-size: var(--step-1);
}

.wissen-suche {
    margin-bottom: var(--space-6);
}

.wissen-suche label {
    display: block;
    margin-bottom: var(--space-2);
    font-weight: 650;
}

.wissen-suche input[type="search"] {
    flex: 1 1 18rem;
    max-width: 32rem;
}

.article-card p:last-child {
    margin-bottom: 0;
}

.article-card__meta {
    margin-bottom: var(--space-2);
    color: var(--text-muted);
    font-size: var(--step--1);
}

.article-image {
    width: 100%;
    height: auto;
    margin-bottom: var(--space-6);
    border-radius: var(--radius);
}

/* Fliesstext eines Beitrags: Ergaenzungen zu .prose fuer die Auszeichnungen, die
   `Markup` erzeugen kann. */
.prose pre {
    padding: var(--space-4);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow-x: auto;
}

.prose pre code {
    padding: 0;
    background: none;
    border: 0;
}

.prose blockquote {
    margin: var(--space-5) 0;
    padding: var(--space-4) var(--space-5);
    background: var(--surface-2);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius-sm);
}

.prose blockquote p:last-child {
    margin-bottom: 0;
}

.prose ol {
    max-width: 68ch;
}

/* Abstandshilfen, die in Phase 6 dazugekommen sind. */
.mt-3 { margin-top: var(--space-3); }
.mt-4 { margin-top: var(--space-4); }
.mt-5 { margin-top: var(--space-5); }
.mt-7 { margin-top: var(--space-7); }
.mb-5 { margin-bottom: var(--space-5); }

/* Zustand ohne Wertung (verworfener Auftrag): sichtbar, aber nicht alarmierend. */
.badge--neutral {
    background: var(--surface-2);
    color: var(--text-muted);
}

/*
 * Phase 8: Ersatz fuer Stilattribute in Templates. Die Content-Security-Policy erlaubt
 * Stile nur aus Dateien und Bloecken mit Nonce - ein style="..." am Element wird vom
 * Browser verworfen, und die Seite sieht anders aus als gedacht.
 */
.error-code {
    font-size: var(--step-4);
    font-weight: 700;
}

.fieldset-plain {
    border: 0;
    padding: 0;
    margin: 0;
    min-width: 0;
}

/* Zwei Gruppen eines Formulars untereinander: die Ueberschrift der zweiten klebte sonst am
   letzten Feld der ersten („Vertrag erfassen", Durchsicht 29.09.2026). */
.fieldset-plain + .fieldset-plain {
    margin-top: var(--space-7);
    padding-top: var(--space-5);
    border-top: 1px solid var(--border);
}

.fieldset-box {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: var(--space-4);
}

.fieldset-box > legend {
    max-width: 100%;
    font-weight: 650;
    padding-inline: var(--space-2);
    overflow-wrap: anywhere;
}

/* Wartungsseite: eigenstaendig, ohne Navigation (die Datenbank kann gerade fehlen). */
.maintenance {
    min-height: 100vh;
    display: grid;
    place-items: center;
    padding: var(--space-5);
}

.maintenance__box {
    /* Etwas breiter als reine Lesebreite: die Ueberschrift nennt den Firmennamen, und
       der soll nicht mitten im Wort umbrechen ("KDG-" / "Server"). */
    max-width: 46rem;
}

.maintenance__box h1 {
    font-size: var(--step-4);
}

/* Auswertungen (Phase 13): Zahlenspalten, Balkendiagramm als Lesehilfe, Exportliste. */
.num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.form-field--end {
    align-self: flex-end;
}

.admin-actions .button[aria-current="true"] {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--accent);
}

.report-chart {
    display: block;
    width: 100%;
    max-width: 48rem;
    height: auto;
    margin-block: var(--space-4);
}

.report-chart__bar {
    fill: var(--accent);
}

.report-chart__label {
    fill: var(--text-muted);
    font-size: 11px;
    text-anchor: middle;
}

.report-exports {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    gap: var(--space-3);
}

.report-exports li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
}

/* Angemeldete Geraete (Phase 14) */
.session-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    gap: var(--space-3);
}

.session-list__item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding-block: var(--space-3);
    border-bottom: 1px solid var(--border);
}

/* Postausgang (Phase 15): die Textfassung einer Mail, umbrechend statt breit. */
.mail-text {
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    max-width: 72ch;
    padding: var(--space-4);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-size: var(--step--1);
}

/* Gutscheincode im Warenkorb (Phase 17) */
.voucher-form {
    margin-top: var(--space-4);
}

.voucher-form .cluster input {
    flex: 1 1 10rem;
    min-width: 0;
}

/* E-Mail-Adressen eines Webspace (Phase 21): Liste statt Tabelle, damit Adresse und
   Formulare auch auf dem Telefon Platz haben. */
.mail-list {
    display: grid;
    gap: var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
}

.mail-item {
    padding: var(--space-4) var(--space-5);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.mail-item__head {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    align-items: baseline;
    justify-content: space-between;
}

.mail-item__address {
    font-weight: 700;
    overflow-wrap: anywhere;
}

.mail-item details {
    margin-top: var(--space-3);
}

.mail-item summary {
    cursor: pointer;
    font-weight: 600;
}

.mail-item details[open] summary {
    margin-bottom: var(--space-4);
}

.mail-item details form + form {
    margin-top: var(--space-5);
    padding-top: var(--space-5);
    border-top: 1px solid var(--border);
}

.mail-item__row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3) var(--space-4);
    align-items: flex-end;
}

.mail-item__row .form-field {
    flex: 1 1 16rem;
}

/* Mailtexte (Phase 24): Platzhalter sind klein geschrieben gemeint und werden so gezeigt. */
.definition-list dt code {
    text-transform: none;
    letter-spacing: normal;
}

.form-field textarea.mail-text-editor {
    font-family: var(--font-mono);
    font-size: var(--step--1);
}

/* DNS-Eintraege (Phase 23): Art als Kuerzel, Inhalt in Festbreite und umbrechend. */
.dns-type {
    display: inline-block;
    min-width: 3.5em;
    margin-right: var(--space-2);
    font-family: var(--font-mono);
    font-size: var(--step--1);
    color: var(--text-muted);
}

.dns-value {
    font-family: var(--font-mono);
    font-size: var(--step--1);
    overflow-wrap: anywhere;
}

.dns-list {
    display: grid;
    gap: var(--space-2);
    margin: var(--space-3) 0 0;
    padding: 0;
    list-style: none;
    overflow-wrap: anywhere;
}

/* Neuer DNS-Eintrag: erst die Aufgabe ("Webseite liegt woanders"), dann das Formular.
   Jede Karte ist ein Verweis - ohne JavaScript bedienbar, die Art steht klein darunter. */
.aufgabenwahl {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr));
    gap: var(--space-3);
    margin: var(--space-3) 0 0;
    padding: 0;
    list-style: none;
}

.aufgabenwahl__option {
    display: grid;
    gap: var(--space-1);
    height: 100%;
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    color: var(--text);
    text-decoration: none;
}

.aufgabenwahl__option:hover {
    border-color: var(--accent);
    background: var(--accent-soft);
}

.aufgabenwahl__option:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.aufgabenwahl__titel {
    font-weight: 600;
}

.aufgabenwahl__text {
    font-size: 0.9rem;
    color: var(--text-muted);
}

.aufgabenwahl__art {
    font-family: var(--font-mono);
    font-size: var(--step--1);
    color: var(--text-muted);
}

/* Wenige Felder untereinander statt im Raster (DNS: Name und Ziel) - begrenzt auf eine
   Breite, in der man eine Adresse noch mit einem Blick liest. */
.feldgruppe-schmal {
    max-width: 40rem;
}

/* Eine Frage mit mehreren Antworten (Assistenten): Fieldset ohne Rahmen, die Frage als
   Ueberschrift, die Antworten untereinander. */
.auswahlgruppe {
    display: grid;
    gap: var(--space-2);
    margin-inline: 0;
    padding: 0;
    border: 0;
}

.auswahlgruppe legend {
    padding: 0;
    margin-bottom: var(--space-2);
    font-weight: 600;
}

/* Eingabe mit festem Domainteil dahinter: "info" + "@beispiel.de". */
.address-field {
    display: flex;
    align-items: stretch;
    max-width: 40rem;
}

/* Im Formularraster eine eigene Zeile: seit Domains frei verknuepft werden (E-142), ist der
   Domainteil oft laenger als eine Spalte, und abgeschnitten ("@beispiel-mit-langem-na…")
   weiss niemand, unter welcher Domain die Adresse entsteht. */
.form-grid > .form-field:has(> .address-field) {
    grid-column: 1 / -1;
}

.address-field input {
    flex: 1 1 5rem;
    width: auto;
    min-width: 0;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

.address-field__domain {
    display: flex;
    align-items: center;
    flex: 0 1 auto;
    max-width: 70%;
    padding: 0 0.75rem;
    overflow: hidden;
    background: var(--surface-2);
    color: var(--text-muted);
    border: 1px solid var(--input-border);
    border-left: 0;
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* --------------------------------------------- Dateimanager (Phase 39, E-88) */

/*
 * Der Hinweis auf das Ziehen und Ablegen ist ohne JavaScript unsichtbar: er
 * verspraeche sonst etwas, was dann nicht geht. `dateien.js` setzt das Merkmal.
 */
[data-dateien-hinweis] {
    display: none;
}

[data-dateien-hinweis][data-aktiv="true"] {
    display: block;
}

[data-dateien-ablage] {
    border: 2px dashed transparent;
    transition: border-color 120ms ease, background-color 120ms ease;
}

[data-dateien-ablage][data-ueber="true"] {
    border-color: var(--accent);
    background: var(--surface-raised, var(--surface));
}

@media (prefers-reduced-motion: reduce) {
    [data-dateien-ablage] {
        transition: none;
    }
}

[data-dateien-fortschritt] {
    display: block;
    width: 100%;
    height: 0.75rem;
}

.breadcrumb {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: center;
}

.breadcrumb span {
    color: var(--text-muted);
}

/* ------------------------------- Angemeldeter Zugang im Kopf (Rueckmeldung 2026-09-24) */

/*
 * Name und Abmelden standen unter der Unternavigation und stoerten dort. Jetzt liegen sie
 * oben, wo auch sonst der Zugang liegt - an der Stelle des Knopfs "Kundenbereich".
 */
.site-header__account--angemeldet {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.site-header__account--angemeldet > a {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: 0.4rem 0.7rem;
    border-radius: var(--radius);
    text-decoration: none;
    color: var(--text);
    font-weight: 600;
    white-space: nowrap;
}

.site-header__account--angemeldet > a:hover,
.site-header__account--angemeldet > a[aria-current="page"] {
    background: var(--accent-soft);
    color: var(--accent);
}

.site-header__name {
    max-width: 12ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.button--klein {
    padding: 0.35rem 0.7rem;
    font-size: 0.85rem;
}

@media (max-width: 40rem) {
    /* Auf schmalen Geraeten genuegt das Abmelden - der Name steht auf der Seite selbst. */
    .site-header__name {
        display: none;
    }
}

/* ------------------------------------ Zustand im Kundenbereich (Rueckmeldung 2026-09-24) */

/*
 * Vier Kacheln, die die Frage beantworten, mit der ein Kunde die Seite oeffnet:
 * laeuft alles? Die Zahl traegt, das Wort erklaert, der Hinweis ordnet ein. Der Ton
 * faerbt nur den Rand und die Zahl - eine vollflaechig rote Kachel waere ein Alarm, und
 * ein offener Betrag ist kein Alarm.
 */
.zustand {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr));
    gap: var(--space-4);
}

.zustand__kachel {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: var(--space-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 4px solid var(--border);
    border-radius: var(--radius);
    text-decoration: none;
    color: inherit;
    transition: border-color 120ms ease, transform 120ms ease;
}

.zustand__kachel:hover,
.zustand__kachel:focus-visible {
    border-color: var(--accent);
    transform: translateY(-2px);
}

.zustand__kachel--ok {
    border-left-color: var(--ok, #2e7d4f);
}

.zustand__kachel--warn {
    border-left-color: var(--warn, #b8860b);
}

.zustand__kachel--ruhig {
    border-left-color: var(--accent);
}

.zustand__wert {
    font-size: var(--step-3, 1.8rem);
    font-weight: 800;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

.zustand__kachel--warn .zustand__wert {
    color: var(--warn, #b8860b);
}

.zustand__label {
    font-weight: 600;
}

.zustand__hinweis {
    color: var(--text-muted);
    font-size: 0.9rem;
}

@media (prefers-reduced-motion: reduce) {
    .zustand__kachel {
        transition: none;
    }

    .zustand__kachel:hover,
    .zustand__kachel:focus-visible {
        transform: none;
    }
}

/* ----------------------------- Bereiche eines Vertrags (Rueckmeldung 2026-09-25) */

/*
 * Reiter ueber dem Inhalt, nicht eine zweite Spalte daneben.
 *
 * Bis zum 25.09. stand die Vertragsnavigation links - neben der Navigation der Schale,
 * die seitdem ebenfalls links steht. Zwei Leisten nebeneinander nehmen die halbe Breite
 * und verwirren: die eine fuehrt durch den Kundenbereich, die andere durch **einen**
 * Vertrag. Als Reiterzeile ueber dem Inhalt ist der Unterschied sofort klar, und die
 * Breite bleibt dem Inhalt.
 *
 * Die Reiterzeile bricht nicht um, sie schiebt sich - eine umbrechende Navigation wirkt
 * unfertig, eine schiebbare ist von jedem Browser bekannt.
 */
.dienst-layout {
    display: block;
}

.dienst-nav {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4) 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius) var(--radius) 0 0;
    border-bottom: 0;
}

.dienst-nav__zurueck {
    order: 1;
    flex: 1 0 100%;
    margin: 0;
    font-size: var(--step--1);
}

.dienst-nav__zurueck a {
    color: var(--text-muted);
    text-decoration: none;
}

.dienst-nav__zurueck a:hover,
.dienst-nav__zurueck a:focus-visible {
    color: var(--accent);
    text-decoration: underline;
}

.dienst-nav__kopf {
    order: 2;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    align-items: center;
    margin: 0 auto 0 0;
}

/* Seit der Kopf entfallen ist, schiebt der Rueckweg die Auswahl nach rechts. */
.dienst-nav__zurueck {
    margin-right: auto;
    flex: 0 1 auto;
}

.dienst-nav__name {
    font-weight: 700;
    font-size: var(--step-1);
    letter-spacing: -0.01em;
    overflow-wrap: anywhere;
}

/* Die beiden Auswahlfelder (Vertrag, Webseite) stehen rechts in derselben Zeile. */
.dienst-nav__wahl {
    order: 3;
    display: flex;
    flex-wrap: nowrap;
    gap: var(--space-2);
    align-items: center;
    margin: 0;
}

.dienst-nav__wahl label {
    flex: 0 0 auto;
    font-weight: 600;
    font-size: var(--step--1);
    color: var(--text-muted);
}

.dienst-nav__wahl select {
    flex: 0 1 12rem;
    min-width: 0;
}

/* Auf dem Telefon ragte die Vertragsauswahl aus der Karte, „Wechseln“ lag ausserhalb des
   Schirms: die Auswahl durfte schrumpfen, das Formular um sie herum nicht - sein
   Mindestmass ist die natuerliche Breite der laengsten Adresse. Jetzt darf es schrumpfen
   und umbrechen, die Auswahl nimmt die ganze Zeile. */
@media (max-width: 40rem) {
    .dienst-nav__wahl {
        flex: 1 1 100%;
        flex-wrap: wrap;
        min-width: 0;
    }

    .dienst-nav__wahl select {
        flex: 1 1 100%;
    }
}

.dienst-nav ul {
    order: 4;
    flex: 1 0 100%;
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    gap: var(--space-1);
    margin: 0;
    padding: 0;
    list-style: none;
    overflow-x: auto;
    scrollbar-width: thin;
    /* Derselbe Schatten wie an den Reitern der Einstellungen: er zeigt, dass es seitlich
       weitergeht - nur, wenn es weitergeht. */
    background:
        linear-gradient(to right, var(--surface) 30%, transparent) left center / 2.5rem 100% no-repeat local,
        linear-gradient(to left, var(--surface) 30%, transparent) right center / 2.5rem 100% no-repeat local,
        radial-gradient(farthest-side at 0 50%, var(--scroll-shadow), transparent) left center / 0.85rem 100% no-repeat scroll,
        radial-gradient(farthest-side at 100% 50%, var(--scroll-shadow), transparent) right center / 0.85rem 100% no-repeat scroll;
}

.dienst-nav li {
    margin: 0;
    flex: 0 0 auto;
}

/* Auf dem Telefon brechen die Reiter eines Vertrags um, statt seitlich zu laufen: der Reiter
   „Kündigung“ lag sonst rechts ausserhalb, und genau er muss ohne Suchen zu finden sein
   (§ 312k BGB, Durchsicht 29.09.2026). Die Seitenleiste bleibt einzeilig; das hier sind
   Reiter ueber dem Inhalt. */
@media (max-width: 40rem) {
    .dienst-nav ul {
        flex-wrap: wrap;
        overflow-x: visible;
        background: none;
    }
}

.dienst-nav a {
    display: block;
    padding: var(--space-3) var(--space-3);
    border-bottom: 2px solid transparent;
    text-decoration: none;
    color: var(--text-muted);
    font-size: var(--step--1);
    font-weight: 600;
    white-space: nowrap;
}

.dienst-nav a:hover,
.dienst-nav a:focus-visible {
    color: var(--text);
}

/* Der aktive Reiter traegt die Linie - Farbe allein genuegt fuer WCAG 1.4.1 nicht. */
.dienst-nav a[aria-current="page"],
.dienst-nav__gruppen a[aria-current="true"] {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

/* Gruppierte Reiter (mehr als sechs): oben die Gruppen, darunter ihre Reiter als Flaechen -
   so sieht die zweite Zeile nicht wie die Fortsetzung der ersten aus. */
.dienst-nav .dienst-nav__reiter {
    order: 5;
    padding-block: var(--space-2) var(--space-3);
}

.dienst-nav__reiter a {
    padding: var(--space-2) var(--space-3);
    border: 1px solid transparent;
    border-radius: var(--radius-full);
}

.dienst-nav__reiter a[aria-current="page"] {
    border-color: var(--accent);
    background: var(--accent-soft);
}

/* Der Inhalt schliesst buendig an die Reiter an: eine Flaeche, kein zweiter Kasten. */
.dienst-inhalt {
    padding-top: var(--space-5);
    border-top: 1px solid var(--border);
}

@media (max-width: 48rem) {
    .dienst-nav__wahl {
        flex: 1 0 100%;
    }

    .dienst-nav__wahl select {
        flex: 1 1 auto;
    }
}
/* --------------------------------------------------------------------------
   Auswahl der Domainart (Rueckmeldung 2026-09-24)
   --------------------------------------------------------------------------
   Drei Moeglichkeiten mit je einem erklaerenden Satz. Als Karten statt als
   Auswahlliste, weil die Erklaerung mitgelesen werden muss: in einem <select>
   waere sie nicht unterzubringen, und ohne sie waehlt niemand richtig.
   Der Rahmen der gewaehlten Karte wird farbig, damit die Wahl auch dann zu
   sehen ist, wenn der Radioknopf selbst klein gerendert wird.                */

.artwahl {
    /* Nur seitlich zuruecksetzen (Vorgabe des Fieldsets): der Abstand nach oben kommt aus
       `.stack`, und ein `margin: 0` hier stuende spaeter in der Datei und nahm ihn weg. */
    margin-inline: 0;
    padding: 0;
    border: 0;
    display: grid;
    gap: var(--space-3);
}

.artwahl legend {
    padding: 0;
    margin-bottom: var(--space-2);
    font-weight: 600;
}

.artwahl__option {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-3);
    align-items: start;
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
}

.artwahl__option:has(input:checked) {
    border-color: var(--accent);
    background: var(--accent-soft);
}

.artwahl__option:has(input:focus-visible) {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.artwahl__option input {
    margin-top: 0.25rem;
}

.artwahl__option label {
    display: grid;
    gap: 0.15rem;
    cursor: pointer;
    margin: 0;
}

.artwahl__titel {
    font-weight: 600;
    color: var(--text);
}

.artwahl__text {
    font-size: 0.9rem;
    color: var(--text-muted);
}

/* ------------------------------ Arbeitsliste der Verwaltung (Rueckmeldung 2026-09-24) */

/*
 * Die erste Frage in der Verwaltung ist nicht "wie laeuft das Geschaeft?", sondern
 * "wartet jemand auf mich?". Oben steht deshalb kein Diagramm, sondern eine Reihe von
 * Stapeln: eine Zahl, ein Wort, ein Satz, ein Ziel.
 *
 * Gefaerbt wird - wie beim Zustand im Kundenbereich - nur der linke Rand und die Zahl.
 * Eine vollflaechig rote Kachel liest sich als Alarm, und eine ueberfaellige Rechnung ist
 * keiner. Der leere Zustand ist kein Weglassen: dass nichts wartet, ist die wichtigste
 * Auskunft dieser Seite und wird ausgesprochen.
 */
.arbeit {
    margin-bottom: var(--space-6);
}

.arbeit__kopf {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2) var(--space-4);
    margin-bottom: var(--space-4);
}

.arbeit__kopf h2 {
    margin: 0;
}

.arbeit__zusatz {
    margin: 0;
    color: var(--text-muted);
    font-size: var(--step--1);
}

.arbeit__liste {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
    gap: var(--space-4);
    list-style: none;
    margin: 0;
    padding: 0;
}

.arbeit__liste > li {
    margin: 0;
    display: flex;
}

.arbeit__kachel {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 0.15rem;
    padding: var(--space-5);
    background: var(--surface);
    border: 1px solid var(--border);
    border-left: 4px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    text-decoration: none;
    color: inherit;
    transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;
}

.arbeit__kachel:hover,
.arbeit__kachel:focus-visible {
    border-color: var(--accent);
    transform: translateY(-2px);
    box-shadow: var(--shadow-sm);
}

.arbeit__kachel--fail { border-left-color: var(--fail); }
.arbeit__kachel--warn { border-left-color: var(--warn); }

.arbeit__wert {
    font-size: var(--step-4);
    font-weight: 800;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

.arbeit__kachel--fail .arbeit__wert { color: var(--fail); }
.arbeit__kachel--warn .arbeit__wert { color: var(--warn); }

.arbeit__label {
    font-weight: 600;
}

.arbeit__hinweis {
    color: var(--text-muted);
    font-size: var(--step--1);
}

/* Alles erledigt: ruhig, aber nicht unscheinbar - es ist eine Auskunft, kein Nichts. */
.arbeit__fertig {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    margin: 0;
    padding: var(--space-4) var(--space-5);
    background: var(--ok-soft);
    border: 1px solid color-mix(in srgb, var(--ok) 35%, transparent);
    border-radius: var(--radius);
}

.arbeit__haken {
    flex: 0 0 auto;
    color: var(--ok);
}

@media (prefers-reduced-motion: reduce) {
    .arbeit__kachel {
        transition: none;
    }

    .arbeit__kachel:hover,
    .arbeit__kachel:focus-visible {
        transform: none;
    }
}

/* ------------------------------- Kartenraster (Rueckmeldung 2026-09-25) */

/*
 * Eine Sammlung gleichrangiger Bereiche steht nebeneinander, nicht untereinander.
 *
 * Auf der Seite eines Vertrags lagen bis zu elf Karten in einer Spalte - Postfaecher,
 * Zugaenge, DNS, Paket, Kuendigung. Untereinander wird daraus eine Seite, an deren Ende
 * niemand ankommt, obwohl der Platz daneben leer bleibt. Nebeneinander sieht man in einem
 * Blick, was es zu diesem Vertrag gibt.
 *
 * Die Karten einer Zeile teilen sich die Hoehe (`stretch`). Vorher stand hier
 * `align-items: start` mit der Begruendung, die hoechste Karte zoege sonst alle anderen
 * mit in die Laenge - das stimmt, ist aber das kleinere Uebel. Mit `start` endete jede
 * Karte an ihrem Inhalt, und darunter lag bis zur naechsten Zeile der Seitenhintergrund
 * frei: nachgemessen 429 px auf der Uebersicht der Verwaltung, 147 px in der Suche,
 * 182 px auf einer Vertragsseite (1500 px Fenster; bei 1920 px eher das Doppelte, weil
 * drei Spalten mehr Gelegenheit zu ungleichen Hoehen geben). Das las sich als Loch, nicht
 * als Absicht. Mit `stretch` wird aus einer Zeile ein Band, und der Platz liegt sichtbar
 * *in* der Karte statt daneben - dorthin, wo `.card__fuss` ihn braucht.
 *
 * Bewusst *nicht* gemacht: `grid-auto-flow: dense`. Es wuerde eine spaetere schmale Karte
 * in eine fruehere Luecke ziehen und damit die Reihenfolge auf dem Bildschirm von der im
 * Quelltext loesen - wer mit Tastatur oder Sprachausgabe arbeitet, bekaeme eine andere
 * Reihenfolge als wer sieht (WCAG 1.3.2 und 2.4.3). Ein huebscheres Bild ist das nicht
 * wert. Aus demselben Grund werden Karten nicht im Markup zu Spalten gebuendelt.
 */
.kartenraster {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 27rem), 1fr));
    gap: var(--space-5);
    align-items: stretch;
}

/* Was eine Tabelle oder ein Formular traegt, braucht die ganze Zeile. */
.kartenraster__breit {
    grid-column: 1 / -1;
}

/*
 * Karten, die nur eine Zahl und einen Fuellstand tragen, duerfen enger stehen.
 *
 * Mit den regulaeren 27 rem passen bei der Arbeitsbreite genau zwei nebeneinander - drei
 * Fuellstaende brechen dann 2+1 um, und neben dem dritten bleibt eine leere Spalte.
 * Ein Nutzungsbalken braucht aber keine Lesebreite (`.nutzung` kommt mit 9 rem aus), und
 * drei nebeneinander beantworten die Frage "wie voll ist mein Paket?" in einem Blick.
 * Nur dafuer gedacht: was Fliesstext traegt, bleibt im regulaeren Raster.
 */
.kartenraster--schmal {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 19rem), 1fr));
}

/*
 * Der Fuss einer Karte: der Verweis oder der Knopf, mit dem es weitergeht.
 *
 * Weil die Karten einer Zeile gleich hoch sind, muss der gewonnene Platz irgendwo hin.
 * Er gehoert zwischen Text und Aktion, nicht zwischen Ueberschrift und Text: ein
 * pauschales `margin-top: auto` auf das letzte Kind haben wir ausprobiert und wieder
 * verworfen - es riss die Ueberschrift vom Absatz darunter los. Deshalb wird der Fuss
 * ausgezeichnet, nicht geraten. Nebenbei stehen die Aktionen benachbarter Karten dann
 * auf einer Linie.
 *
 * Nur im Kartenraster, damit Karten auf der Website davon unberuehrt bleiben.
 */
.kartenraster .card__fuss {
    margin-top: auto;
    padding-top: var(--space-4);
}

/* Ein Absatz als Fuss bringt seinen eigenen Abstand schon mit. */
.kartenraster p.card__fuss {
    margin-bottom: 0;
}

/* ------------------------------------- Reiter (Rueckmeldung 2026-09-25) */

/*
 * Eine Seite, die aus Bereichen besteht, zeigt sie als Reiter - nicht alle Bereiche
 * untereinander.
 *
 * Bei den Einstellungen waren das dreizehn Bereiche mit ueber hundert Feldern auf einer
 * Seite: wer die Alarmadresse aendern wollte, scrollte an Firmendaten, Steuer, Mahnwesen
 * und Webspace vorbei. Jeder Reiter ist eine eigene Adresse (`?bereich=`), damit er sich
 * verlinken und mit dem Zurueck-Knopf verlassen laesst - und damit er ohne JavaScript
 * funktioniert.
 *
 * Die Zeile bricht nicht um, sie schiebt sich: eine umbrechende Leiste wirkt unfertig.
 */
.reiter {
    border-bottom: 1px solid var(--border);
}

/* Passen die Reiter nicht in die Breite (Einstellungen: zwoelf Bereiche), laesst sich die
   Leiste seitlich schieben. Vorher endete sie rechts mitten in einem Wort („Bu…“), ohne
   dass man sah, dass es weitergeht. Jetzt derselbe Schatten wie an breiten Tabellen - er
   erscheint nur an der Seite, an der wirklich noch etwas steht (`local` gegen `scroll`). */
.reiter ul {
    display: flex;
    flex-wrap: nowrap;
    gap: var(--space-1);
    margin: 0;
    padding: 0;
    list-style: none;
    overflow-x: auto;
    scrollbar-width: thin;
    background:
        linear-gradient(to right, var(--bg) 30%, transparent) left center / 2.5rem 100% no-repeat local,
        linear-gradient(to left, var(--bg) 30%, transparent) right center / 2.5rem 100% no-repeat local,
        radial-gradient(farthest-side at 0 50%, var(--scroll-shadow), transparent) left center / 0.85rem 100% no-repeat scroll,
        radial-gradient(farthest-side at 100% 50%, var(--scroll-shadow), transparent) right center / 0.85rem 100% no-repeat scroll;
}

.reiter li {
    margin: 0;
    flex: 0 0 auto;
}

.reiter a {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3);
    margin-bottom: -1px;
    border-bottom: 2px solid transparent;
    color: var(--text-muted);
    text-decoration: none;
    font-size: var(--step--1);
    font-weight: 600;
    white-space: nowrap;
}

.reiter a:hover,
.reiter a:focus-visible {
    color: var(--text);
}

/* Der aktive Reiter traegt die Linie - Farbe allein genuegt fuer WCAG 1.4.1 nicht. */
.reiter a[aria-current="page"],
.reiter a[aria-current="true"] {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

/* Die zweite Ebene (Einstellungen: Bereiche einer Gruppe) - kleiner und als Fläche, damit
   sie nicht wie eine zweite Zeile derselben Navigation aussieht. */
.reiter--zweite {
    border-bottom: 0;
}

.reiter--zweite a {
    padding: var(--space-2) var(--space-3);
    border: 1px solid transparent;
    border-radius: var(--radius-full);
    margin-bottom: 0;
}

.reiter--zweite a[aria-current="page"] {
    border-color: var(--accent);
    background: var(--accent-soft);
}

.reiter-inhalt {
    margin-top: var(--space-5);
}

/* Zahl am Reiter (Kundenakte): wie viele Vorgänge dahinterstehen. */
.reiter__zahl {
    display: inline-grid;
    place-items: center;
    min-width: 1.5rem;
    padding: 0 0.35rem;
    border-radius: var(--radius-full);
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text-muted);
    font-size: 0.75rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.reiter a[aria-current="page"] .reiter__zahl {
    background: var(--accent-soft);
    border-color: var(--accent-line);
    color: var(--accent);
}

/* ------------------------- Die zwei Wege auf der Startseite (Rueckmeldung 2026-09-25) */

/*
 * Zwei grosse Angebote statt drei gleich aussehender Kaertchen.
 *
 * Vorher standen Webspace, Managed vServer und Managed Server in derselben Groesse
 * nebeneinander - der Besucher musste erst einen Unterschied suchen, und der Schwerpunkt
 * des Hauses war nicht zu erkennen. Jetzt tragen die beiden Schwerpunktprodukte einen
 * Preis, drei bis vier Punkte und einen Knopf; der Managed vServer steht weiter unten als
 * Hinweis.
 *
 * Gefaerbt wird nur der obere Rand und - beim Einstiegsprodukt - ein weicher Verlauf.
 * Eine vollflaechig eingefaerbte Karte waere in der dunklen Darstellung entweder blass
 * oder zu laut, und feste Farben gibt es hier nicht.
 */
.angebote {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr));
    gap: var(--space-6);
    align-items: stretch;
}

/*
 * Zwei Wege mit zwei Gesichtern (Gestaltung vom 28.09.2026): der **Webspace** hell, mit
 * einem Lichtschein in Akzentfarbe - der Einstieg; der **Managed Server** in Tinte
 * (`.flaeche-tinte` am Element) - die eigene Maschine. Vorher unterschieden sich beide
 * Karten nur im Text; jetzt sieht man den Unterschied, bevor man ihn liest.
 */
.angebot {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: var(--space-7) var(--space-6) var(--space-6);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-md);
    transition: transform 300ms var(--ease-out), box-shadow 300ms var(--ease-out);
}

.angebot:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-lg);
}

.angebot--betont {
    background:
        radial-gradient(32rem 18rem at 100% 0%, var(--accent-soft), transparent 70%),
        var(--surface);
    border-color: var(--accent-line);
}

.angebot.flaeche-tinte {
    background:
        radial-gradient(34rem 20rem at 100% 0%, rgb(79 124 255 / calc(0.32 * var(--ink-glow))), transparent 70%),
        radial-gradient(26rem 16rem at 0% 100%, rgba(245, 181, 61, 0.08), transparent 70%),
        var(--ink);
    border-color: var(--ink-3);
    box-shadow: var(--shadow-lg);
}

.angebot__art {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    align-self: flex-start;
    margin: 0 0 var(--space-4);
    padding: 0.25rem 0.7rem;
    border-radius: var(--radius-full);
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 0.75rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.angebot__name {
    margin: 0 0 var(--space-5);
    font-size: var(--step-2);
    font-weight: 800;
    letter-spacing: -0.022em;
}

/* Der Preis ist die Antwort auf die zweite Frage jedes Besuchers - er steht gross. */
.angebot__preis {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2);
    margin: 0 0 var(--space-4);
    padding-bottom: var(--space-5);
    border-bottom: 1px solid var(--border);
}

.angebot__ab,
.angebot__takt {
    color: var(--text-muted);
    font-size: 0.9375rem;
}

.angebot__betrag {
    font-size: var(--step-5);
    font-weight: 800;
    letter-spacing: -0.035em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.angebot__fuer {
    margin: 0 0 var(--space-5);
    color: var(--text-muted);
    font-size: 1.0625rem;
}

.angebot__liste {
    list-style: none;
    margin: 0 0 var(--space-6);
    padding: 0;
    display: grid;
    gap: var(--space-3);
}

.angebot__liste li {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-3);
    align-items: start;
    margin: 0;
}

/* Der Haken in einem kleinen Kreis: ruhiger als ein nackter Strich. */
.angebot__liste svg {
    box-sizing: content-box;
    margin-top: 0.1rem;
    padding: 0.2rem;
    border-radius: 50%;
    background: var(--accent-soft);
    color: var(--accent);
}

/* Der Knopf steht bei beiden Karten auf derselben Hoehe, auch wenn die Listen
   unterschiedlich lang sind - sonst sieht es aus wie ein Fehler. */
.angebot__aktion {
    margin-top: auto;
}

.angebot__aktion .button {
    min-height: 3.25rem;
    font-size: 1rem;
}

.angebot__hinweis {
    margin: var(--space-3) 0 0;
    color: var(--text-muted);
    font-size: var(--step--1);
    text-align: center;
}

/* Entscheidungshilfe: der Besucher erkennt sich in einer Zeile wieder. */
.wahlhilfe {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 22rem), 1fr));
    gap: var(--space-5);
}

.wahlhilfe__spalte {
    padding: var(--space-5);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.wahlhilfe__spalte h3 {
    margin: 0 0 var(--space-4);
    font-size: var(--step-1);
}

.wahlhilfe__spalte ul {
    list-style: none;
    margin: 0 0 var(--space-4);
    padding: 0;
    display: grid;
    gap: var(--space-3);
}

.wahlhilfe__spalte li {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--space-3);
    align-items: start;
    margin: 0;
}

.wahlhilfe__spalte svg {
    margin-top: 0.25rem;
    color: var(--accent);
}

.wahlhilfe__spalte p {
    margin: 0;
}

/* Der Managed vServer: im Angebot, aber nicht im Schwerpunkt. */
.nebenangebot {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4) var(--space-6);
    align-items: center;
    justify-content: space-between;
    padding: var(--space-5) var(--space-6);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.nebenangebot h2 {
    margin: 0 0 var(--space-2);
    font-size: var(--step-1);
}

.nebenangebot p {
    margin: 0;
    max-width: 52ch;
    color: var(--text-muted);
}

.nebenangebot__aktion {
    flex: 0 0 auto;
}

/* ------------------- Auftritt nachgeschaerft (Rueckmeldung 2026-09-25, am Bild) */

/*
 * Am gerenderten Bild gefunden: jeder Abschnittskopf stand links in halber Breite, der
 * Inhalt darunter ueber die ganze - bei jedem Abschnitt blieb die rechte Haelfte leer,
 * und die Seite sah aus, als fehle dort etwas. Ueber einem Raster gehoert der Kopf in die
 * Mitte.
 *
 * Nur auf den oeffentlichen Seiten: hinter der Anmeldung ist ein linksbuendiger Kopf
 * richtig, weil dort gearbeitet und nicht geworben wird.
 */
.section-head--mitte {
    margin-inline: auto;
    text-align: center;
}

.section-head--mitte > h2,
.section-head--mitte > p {
    margin-inline: auto;
}

.section-head--mitte > p {
    max-width: 58ch;
}

/* Groesse, Abstaende und Spalten des Kopfs der Startseite stehen seit der Gestaltung vom
   28.09.2026 an einer Stelle (Abschnitt 6, `.hero`) - hier ueberschrieben sie ihn. */

/*
 * Die Domainsuche war ein loses Feld in einer sonst leeren Haelfte. Als Block mit
 * Ueberschrift ist sie der zweite Einstieg neben den beiden Angeboten.
 */
.domainbox {
    padding: var(--space-5);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md);
}

.domainbox__titel {
    margin: 0 0 var(--space-2);
    font-size: var(--step-1);
}

.domainbox__text {
    margin: 0 0 var(--space-4);
    color: var(--text-muted);
    font-size: var(--step--1);
}

.domainbox__hinweis {
    margin: var(--space-4) 0 0;
    padding-top: var(--space-4);
    border-top: 1px solid var(--border);
    color: var(--text-muted);
    font-size: var(--step--1);
}

/* Die Endungen unter dem Suchfeld stehen enger am Feld, nicht eine Zeile tiefer. */
.domainbox .cluster.mt-6 {
    margin-top: var(--space-4);
}

/* ------------------- Hierarchie hinter der Anmeldung (am Bild gefunden, 2026-09-25) */

/*
 * Die Seitenüberschrift und eine Abschnittsüberschrift waren gleich groß: "Kunde K-00002"
 * und "Fremdsysteme" standen in derselben Stufe, ebenso "Übersicht" und "Was jetzt zu tun
 * ist". Wenn alles gleich laut ist, führt nichts - deshalb ist ein freistehendes h2 hier
 * eine Stufe kleiner als die Seitenüberschrift.
 */
.app-body h2 {
    font-size: var(--step-2);
}

/* Die Regel darueber gilt fuer freistehende Ueberschriften - in einer Karte bleibt die
   Ueberschrift klein, sonst waere jede Karte so laut wie ein Abschnitt. */
.app-body .card h2 {
    font-size: var(--step-1);
}

/*
 * Die Seitenueberschrift ist in beiden Bereichen gleich gross. Im Kundenbereich kam sie
 * aus dem Website-Layout mit der groessten Stufe (knapp 4rem) - auf einer Arbeitsseite
 * wirkt das wie ein Plakat.
 */
.app-body h1,
.app-body .app__titel {
    font-size: var(--step-3);
}

/* Der Erklärsatz gehört zu den Kacheln darüber, nicht als loser Absatz daneben. */
.stats__fussnote {
    max-width: none;
    margin-top: var(--space-3);
    color: var(--text-muted);
    font-size: var(--step--1);
}

/* --------------------------- Zeichnung und Referenzen (Rueckmeldung 2026-09-25) */

/*
 * Der Auftritt hatte kein einziges Bild. Statt eines Stockfotos, das jeder zweite Hoster
 * auch hat, steht hier eine Zeichnung, die etwas erklaert: was in einem Paket steckt.
 *
 * Sie traegt keine Information allein - daneben steht dieselbe Aussage als Liste. Farben
 * kommen aus Klassen und damit aus den Tokens: feste Farben im SVG muessten fuer die
 * dunkle Darstellung zweimal gepflegt werden, und Stilattribute verbietet die CSP.
 */
.schema {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 26rem), 1fr));
    gap: var(--space-6);
    align-items: center;
}

/* Auf dem Telefon ist die Schrift in der Zeichnung rund 9 px gross - unlesbar. Der Text
   daneben traegt denselben Inhalt (die Zeichnung ist `aria-hidden`), also faellt sie dort
   weg (Durchsicht 29.09.2026). */
@media (max-width: 40rem) {
    .schema__bild {
        display: none;
    }
}

.schema__bild {
    width: 100%;
    height: auto;
}

.schema__paket {
    fill: var(--surface);
    stroke: var(--accent-line);
    stroke-width: 1.5;
}

.schema__kachel {
    fill: var(--surface-2);
    stroke: var(--border);
    stroke-width: 1;
}

.schema__kachel--akzent {
    fill: var(--accent-soft);
    stroke: var(--accent-line);
}

.schema__pfeil {
    stroke: var(--accent);
    stroke-width: 1.8;
    fill: none;
}

.schema__spitze {
    fill: var(--accent);
}

.schema__marke {
    fill: var(--accent);
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.schema__text {
    fill: var(--text);
    font-size: 15px;
    font-weight: 650;
    text-anchor: middle;
}

.schema__text--links {
    text-anchor: start;
}

.schema__klein {
    fill: var(--text-muted);
    font-size: 12.5px;
}

.schema__erklaerung h3 {
    margin-bottom: var(--space-4);
    font-size: var(--step-1);
}

.schema__liste {
    list-style: none;
    margin: 0 0 var(--space-4);
    padding: 0;
    display: grid;
    gap: var(--space-3);
}

.schema__liste li {
    margin: 0;
    padding-left: var(--space-4);
    border-left: 2px solid var(--accent-line);
    color: var(--text-muted);
}

.schema__liste strong {
    color: var(--text);
}

.schema__hinweis {
    margin: 0;
    color: var(--text-muted);
    font-size: var(--step--1);
}

/*
 * Referenzen: ein Monogramm statt eines Logos. Erfunden wird keines - aber eine Kachel
 * aus zwei Textzeilen ist als Vertrauensanker zu wenig.
 */
.reference {
    flex-direction: row;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-4) var(--space-5);
}

.reference__zeichen {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: var(--radius);
    background: var(--accent-soft);
    color: var(--accent);
    font-size: var(--step-1);
    font-weight: 700;
}

.reference__inhalt {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.reference__name {
    word-break: normal;
    overflow-wrap: anywhere;
}

.reference__produkt {
    align-self: flex-start;
    margin-top: var(--space-2);
    padding: 0.1rem 0.5rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    color: var(--text-muted);
    font-size: 0.75rem;
}

.reference:hover,
.reference:focus-visible {
    border-color: var(--accent);
}

/* Eine Referenz, zu der keine brauchbare Adresse hinterlegt ist, bleibt stehen - Name
   und Beschreibung sind echter Inhalt -, gibt sich aber nicht als Verweis aus. Ohne das
   hier hoebe sich eine Kachel unter dem Zeiger, die nirgendwohin fuehrt. */
.reference--ohne-link:hover {
    border-color: var(--border);
    transform: none;
}

/* ------------------ Durchgang am Bild (2026-09-25): Tabellen und schmale Schirme */

/*
 * Drei Aktionen in einer Tabellenzelle brachen untereinander um und machten jede Zeile
 * dreimal so hoch wie noetig - bei sechzehn Produkten wurde daraus eine Seite ohne Ende.
 * Die Zelle bekommt deshalb so viel Breite, dass die drei nebeneinander stehen.
 */
.app-body .table-wrap .admin-actions {
    min-width: 19rem;
}

.admin-actions .button {
    white-space: nowrap;
}

/*
 * Betragsfelder in Tabellen waren so breit wie ein Satz, obwohl "12,99" darin steht.
 * Bei den Domainendungen schob das die Spalte "Anzeige" aus dem Bild - genau die, in der
 * entschieden wird, ob eine Endung im Shop erscheint.
 */
/* Ein Preisfeld in einer Tabelle ist so breit wie sein laengster Inhalt, „auf Anfrage“ -
   mit `size="8"` allein stand dort „auf Anfrag“. */
.app-body .table-wrap input[inputmode="decimal"] {
    width: 7.5rem;
    max-width: 7.5rem;
}

/* Ein Datumsfeld braucht keine halbe Bildschirmbreite. */
.app-body input[type="date"] {
    max-width: 14rem;
}

/* Eine Artikelnummer bricht nicht mitten im Wort um. */
.app-body .table-wrap td code,
.app-body .table-wrap th code {
    white-space: nowrap;
}

/* Freitext in einer Tabelle (Notizen im Lebenslauf, Meldungen fremder Systeme) bricht auch
   an langen Woertern um - sonst schob eine Fehlermeldung ohne Leerzeichen die Spalte „Wer"
   aus dem sichtbaren Bereich (Durchsicht 29.09.2026). */
.app-body .table-wrap td.umbruch {
    min-width: 14rem;
    overflow-wrap: anywhere;
}

/* Der Vertragsname im Auswahlfeld war nach zwanzig Zeichen abgeschnitten. */
.dienst-nav__wahl select {
    flex: 0 1 20rem;
}

/*
 * Ohne JavaScript stand auf schmalen Schirmen die vollstaendige Navigation **vor** dem
 * Inhalt - in der Verwaltung 28 Punkte, an denen man erst vorbeiscrollen musste. Sie
 * steht jetzt darunter: erreichbar bleibt sie, aber der Inhalt kommt zuerst.
 */
@media (max-width: 62rem) {
    .app__spalte {
        order: 1;
    }

    .app__seitenleiste:not([data-collapsible="true"]) {
        order: 2;
        border-bottom: 0;
        border-top: 1px solid var(--border);
    }
}

/* --------------------------- Übergreifende Suche (2026-09-25) */

/*
 * Das Suchfeld steht in der Kopfleiste, nicht in der Navigation: es gehoert zu keinem
 * Bereich, sondern zu allen. Auf schmalen Schirmen faellt es weg - dort ist der Platz
 * fuer den Menueknopf, und die Suche steht eine Ebene tiefer auf ihrer eigenen Seite.
 */
.app__suche {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0 auto 0 var(--space-5);
    padding: 0 var(--space-3);
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    color: var(--text-muted);
}

.app__suche:focus-within {
    border-color: var(--accent);
    color: var(--accent);
}

.app__suche input {
    width: min(26rem, 26vw);
    padding: 0.45rem 0;
    border: 0;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: var(--step--1);
}

/*
 * Der Fokusring gehoert um das ganze Suchfeld, nicht um das Eingabefeld darin: das hat
 * keinen eigenen Rahmen, ein Ring um es allein saesse schief im Rund. Der innere Ring
 * wird deshalb nur dort abgeschaltet, wo der aeussere sicher erscheint - ein
 * `outline: none` ohne Ersatz waere ein Verstoss gegen WCAG 2.4.7 (sichtbarer Fokus),
 * und die Randfarbe allein ist zu leise, um als Ring zu gelten.
 *
 * `:has()` und nicht `:focus-within`, weil im Feld auch der Lupenknopf steht: der bringt
 * seinen eigenen Ring mit, und zwei Ringe uebereinander sagen nicht mehr als einer.
 */
@supports selector(:has(*)) {
    .app__suche:has(input:focus-visible) {
        outline: 3px solid var(--accent);
        outline-offset: 2px;
    }

    .app__suche input:focus {
        outline: none;
    }
}

@media (max-width: 62rem) {
    .app__suche {
        display: none;
    }
}

/* Trefferliste: Titel, Beiwerk und Zustand in einer Zeile. */
.trefferliste {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-1);
}

.trefferliste li {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin: 0;
    padding: var(--space-2) 0;
    border-bottom: 1px solid var(--border);
}

.trefferliste li:last-child {
    border-bottom: 0;
}

.trefferliste a {
    display: grid;
    gap: 0.1rem;
    min-width: 0;
    text-decoration: none;
    color: inherit;
}

.trefferliste a:hover .trefferliste__titel,
.trefferliste a:focus-visible .trefferliste__titel {
    color: var(--accent);
    text-decoration: underline;
}

.trefferliste__titel {
    font-weight: 600;
    overflow-wrap: anywhere;
}

.trefferliste__meta {
    color: var(--text-muted);
    font-size: var(--step--1);
    overflow-wrap: anywhere;
}

/* ------------------------------ Nutzungsbalken (2026-09-25) */

/*
 * "Wie voll ist es?" - dieselbe Frage bei der Auslastung eines Servers und beim
 * Kontingent eines Pakets. Eine Prozentzahl muss man lesen und einordnen; ein Balken
 * sagt es im Vorbeigehen.
 *
 * Die Breite kommt aus einer Klasse in Fuenferschritten, nicht aus einem Stilattribut:
 * die CSP erlaubt keine, und fuer eine Fuellanzeige ist die Genauigkeit von fuenf
 * Prozentpunkten mehr als genug.
 */
.nutzung {
    display: grid;
    gap: var(--space-2);
    min-width: 9rem;
}

.nutzung__zahl {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2);
    margin: 0;
    font-variant-numeric: tabular-nums;
}

.nutzung__zahl strong {
    font-size: var(--step-1);
    letter-spacing: -0.02em;
}

.nutzung__von {
    color: var(--text-muted);
    font-size: var(--step--1);
}

.nutzung__prozent {
    margin-left: auto;
    font-size: var(--step--1);
    font-weight: 700;
}

.nutzung__balken {
    position: relative;
    height: 0.5rem;
    border-radius: var(--radius-full);
    background: var(--surface-2);
    border: 1px solid var(--border);
    overflow: hidden;
}

.nutzung__fuellung {
    display: block;
    height: 100%;
    border-radius: inherit;
    background: var(--accent);
}

.nutzung--eng .nutzung__fuellung { background: var(--warn); }
.nutzung--eng .nutzung__prozent { color: var(--warn); }
.nutzung--voll .nutzung__fuellung { background: var(--fail); }
.nutzung--voll .nutzung__prozent { color: var(--fail); }

.nutzung__hinweis {
    margin: 0;
    color: var(--text-muted);
    font-size: var(--step--1);
}

.nutzung__balken--0 .nutzung__fuellung { width: 0%; }
.nutzung__balken--5 .nutzung__fuellung { width: 5%; }
.nutzung__balken--10 .nutzung__fuellung { width: 10%; }
.nutzung__balken--15 .nutzung__fuellung { width: 15%; }
.nutzung__balken--20 .nutzung__fuellung { width: 20%; }
.nutzung__balken--25 .nutzung__fuellung { width: 25%; }
.nutzung__balken--30 .nutzung__fuellung { width: 30%; }
.nutzung__balken--35 .nutzung__fuellung { width: 35%; }
.nutzung__balken--40 .nutzung__fuellung { width: 40%; }
.nutzung__balken--45 .nutzung__fuellung { width: 45%; }
.nutzung__balken--50 .nutzung__fuellung { width: 50%; }
.nutzung__balken--55 .nutzung__fuellung { width: 55%; }
.nutzung__balken--60 .nutzung__fuellung { width: 60%; }
.nutzung__balken--65 .nutzung__fuellung { width: 65%; }
.nutzung__balken--70 .nutzung__fuellung { width: 70%; }
.nutzung__balken--75 .nutzung__fuellung { width: 75%; }
.nutzung__balken--80 .nutzung__fuellung { width: 80%; }
.nutzung__balken--85 .nutzung__fuellung { width: 85%; }
.nutzung__balken--90 .nutzung__fuellung { width: 90%; }
.nutzung__balken--95 .nutzung__fuellung { width: 95%; }
.nutzung__balken--100 .nutzung__fuellung { width: 100%; }

/* ------------------------------ Tiefe (2026-09-25) */

/*
 * Eine feine Lichtkante oben auf jeder Flaeche.
 *
 * In der dunklen Darstellung lag alles in derselben Ebene - Karten wirkten wie
 * aufgemalte Rechtecke. Ein Prozent Weiss an der Oberkante genuegt, damit eine Flaeche
 * als Koerper gelesen wird; in der hellen Darstellung ist es praktisch unsichtbar und
 * stoert dort nicht.
 *
 * Bewusst ueber `box-shadow` und nicht ueber einen zweiten Rahmen: ein Rahmen wuerde die
 * Groesse aendern und in Rastern zu Spruengen fuehren.
 */
.card,
.angebot,
.app__seitenleiste,
.wahlhilfe__spalte,
.nebenangebot,
.domainbox,
.plan,
.stat,
.arbeit__kachel,
.zustand__kachel {
    box-shadow:
        inset 0 1px 0 rgb(255 255 255 / 4%),
        var(--shadow-sm);
}

/* Der Fuellstand bekommt seinen Glanz von innen - sonst wirkt er wie ein Aufkleber. */
.nutzung__fuellung {
    box-shadow: inset 0 1px 0 rgb(255 255 255 / 18%);
}

/* ------------------------------ Blätterleiste (E-107, 2026-09-25) */

/*
 * Sie erscheint erst, wenn es mehr als eine Seite gibt. Links steht, was man gerade
 * sieht ("1001 bis 2000 von 2431") - die Zahl beantwortet die Frage, wie viel da ist;
 * rechts die Wege. Anfang und Ende sind leiser als Zurueck und Weiter: sie werden
 * seltener gebraucht.
 */
.blaettern {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3) var(--space-4);
    margin-top: var(--space-4);
    padding: var(--space-3) var(--space-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

.blaettern__stand {
    margin: 0;
    color: var(--text-muted);
    font-size: var(--step--1);
    font-variant-numeric: tabular-nums;
}

.blaettern__wege {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin: 0;
}

/* ------------------------- Feldbreiten in der Arbeitsoberflaeche (2026-09-25)

   Ein Eingabefeld ist so breit wie das, was hineingehoert - nicht so breit wie die
   Karte. In einer 110rem breiten Oberflaeche lief ein `width: 100%` sonst ueber mehr
   als tausend Pixel: das Auge findet den Anfang des Wertes nicht mehr wieder, und eine
   Domain in einem Feld dieser Laenge sieht aus wie ein Versehen.

   Die Grenze gilt nur fuer einzeln stehende Felder in der Oberflaeche. Felder in einer
   Tabelle oder in einer Filterleiste behalten ihre Spaltenbreite, und ein `textarea`
   darf breiter sein, weil dort mehrere Zeilen stehen. */
.app-body .form-field > input,
.app-body .form-field > select {
    max-width: 34rem;
}

.app-body .form-field > textarea {
    max-width: 60rem;
}

/* In einer Tabelle zaehlt die Spalte, nicht die Wortbreite. */
.app-body table .form-field > input,
.app-body table .form-field > select,
.app-body .admin-filter .form-field > input,
.app-body .admin-filter .form-field > select {
    max-width: none;
}

/* Der Kopierknopf steht direkt unter seinem Feld - er gehoert dazu, nicht zum Text. */
.feld-kopieren {
    margin-top: var(--space-2);
}

/* Ein einmalig gezeigtes Kennwort: gut lesbar, Zeichen fuer Zeichen unterscheidbar. */
.feld-geheimnis {
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: var(--step-1);
    letter-spacing: 0.05em;
}

/* Ersatzcodes: einmal gezeigt, zum Abschreiben - in zwei Spalten, gut lesbar. */
.ersatzcodes {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
    gap: var(--space-2) var(--space-5);
    margin-top: var(--space-4);
    padding: 0;
    /* Die Ziffern stehen im Kasten, nicht davor - im Raster haengen sie sonst ueber den Rand. */
    list-style-position: inside;
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: var(--step-1);
    letter-spacing: 0.05em;
}

/* Die Lupe im Kopf ist ein Knopf (WCAG 3.2.2) - sie soll aber aussehen wie zuvor:
   kein Rahmen, keine Flaeche, nur das Zeichen. Sichtbar wird sie erst beim Fokus.

   **Mindestens 24 x 24 Pixel** (WCAG 2.2, 2.5.8 Zielgroesse, Stufe AA): das Zeichen
   selbst ist 16 x 16, und ohne Innenabstand war der Knopf genau so gross - am Telefon
   oder mit zittriger Hand nicht zu treffen. Die Ausnahme "genug Abstand" greift nicht,
   weil das Suchfeld unmittelbar daneben im selben Rund liegt und selbst ein Ziel ist.
   Optisch aendert der Innenabstand nichts, weil der Knopf ohnehin rahmenlos ist. */
.app__suche-knopf {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.5rem;
    min-height: 1.5rem;
    padding: 0.25rem;
    border: 0;
    background: none;
    color: inherit;
    cursor: pointer;
}

.app__suche-knopf:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: var(--radius-sm, 4px);
}
