/* ==========================================================================
   TSDS Booking — Token-Ebene, Basisregeln und geteilte Bausteine

   Reihenfolge in dieser Datei ist fuer die Kaskade massgeblich:
   1. Schriften  2. Token  3. Basisregeln  4. Typografie-Utilities
   5. Bausteine  6. Layout  7. Bewegung  8. Responsive  9. Rueckfaelle

   Die Rueckfaelle (forced-colors, prefers-reduced-motion) stehen zuletzt:
   eine Media Query erhoeht die Spezifitaet nicht, bei gleicher Spezifitaet
   entscheidet die Quellreihenfolge. Vor den Breakpoint-Regeln stehend wuerden
   sie von diesen still ueberschrieben.

   Seitenspezifische Stylesheets (booking.css, admin.css, admin-auth.css,
   landing.css, content.css) werden danach geladen und duerfen ueberschreiben.

   Grundlage: TSDS Design-Referenz. Wo die Referenz keine Vorlage hat
   (Tabellen, Dialoge, Toasts, Auswahlfelder, Radiogruppen, Datumsauswahl,
   Paginierung, Ladeanzeige, leere Zustaende, Fortschrittsanzeige, Button
   disabled/busy), sind die Regeln aus vorhandenen Token abgeleitet und mit
   "abgeleitet" gekennzeichnet.
   ========================================================================== */

/* ==========================================================================
   1. Schriften — lokal gehostet (kein CDN)
   ========================================================================== */

@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/inter-v18-latin-regular.woff2') format('woff2');
}

@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('../fonts/inter-v18-latin-500.woff2') format('woff2');
}

@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('../fonts/inter-v18-latin-600.woff2') format('woff2');
}

@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('../fonts/inter-v18-latin-700.woff2') format('woff2');
}

@font-face {
    font-family: 'JetBrains Mono';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('../fonts/jetbrains-mono-v18-latin-regular.woff2') format('woff2');
}

@font-face {
    font-family: 'JetBrains Mono';
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url('../fonts/jetbrains-mono-v18-latin-500.woff2') format('woff2');
}

/* Metrisch angepasster Systemschrift-Rueckfall: verhindert den Layoutsprung
   beim Font-Swap. Die Override-Werte gelten fuer genau dieses Schriftpaar. */
@font-face {
    font-family: 'Inter Fallback';
    src: local('Arial');
    size-adjust: 107.4%;
    ascent-override: 90.2%;
    descent-override: 22.48%;
    line-gap-override: 0%;
}

/* ==========================================================================
   2. Token
   ========================================================================== */

/* 2.1 Rohpalette — themeunabhaengig, in beiden Themes identisch */
:root {
    --tsds-orange-50: #fdece5;
    --tsds-orange-200: #f6a98a;
    --tsds-orange-300: #f47e4a;
    --tsds-orange-500: #ec5834;
    --tsds-orange-700: #d24d32;
    --tsds-orange-800: #a7341e;
    --tsds-orange-900: #7f271a;

    --tsds-ink-0: #ffffff;
    --tsds-ink-400: #82878c;
    --tsds-ink-500: #5a5e64;
    --tsds-ink-600: #3c4046;
    --tsds-ink-800: #20292f;
    --tsds-ink-900: #16191e;

    --tsds-success: #3c9a6a;
    --tsds-warning: #d89340;
    --tsds-info: #5a82e0;

    /* Schriftfamilien — Display und Body sind wertgleich, die Unterscheidung
       ist rein semantisch: Ueberschriften nutzen display, Fliesstext body. */
    --font-display: 'Inter', 'Inter Fallback', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Helvetica, Arial, sans-serif;
    --font-body: var(--font-display);
    --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;

    /* Groessenskala — statisch, ohne clamp(). Fluiditaet entsteht auf
       Komponentenebene ueber Breakpoints. */
    --fs-xs: 0.875rem;
    --fs-sm: 1rem;
    --fs-base: 1.125rem;
    --fs-md: 1.3125rem;
    --fs-lg: 1.5625rem;
    --fs-xl: 2rem;
    --fs-2xl: 2.625rem;
    --fs-3xl: 3.4375rem;
    --fs-4xl: 4.625rem;

    --fw-medium: 500;
    --fw-semibold: 600;
    --fw-bold: 700;

    --lh-tight: 1.1;
    --lh-snug: 1.25;
    --lh-normal: 1.5;
    --lh-relaxed: 1.65;

    --ls-tight: -0.025em;
    --ls-snug: -0.015em;
    --ls-wider: 0.08em;

    /* Abstaende — 4-px-Raster bis 16 px, danach 24 / 32 / 48 / 64.
       Projektentscheidung: Abstaende laufen durchgaengig ueber diese Token,
       rohe px-Werte fuer Abstaende kommen nicht vor. */
    --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;

    --container-max: 90rem;
    --container-prose: 48rem;
    --content-measure: 46rem;
    --gutter: clamp(1rem, 2.5vw, 2.5rem);

    --radius-sm: 4px;
    --radius-md: 6px;
    --radius-lg: 8px;
    --radius-full: 9999px;

    --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
    --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
    --duration-fast: 120ms;
    --duration-normal: 180ms;
}

/* 2.2 Semantische Token — Dark ist Standard und gilt auch ohne Attribut */
:root,
:root[data-theme="dark"] {
    color-scheme: dark;

    --bg: var(--tsds-ink-900);
    --bg-raised: var(--tsds-ink-800);
    --bg-sunken: #101318;

    --fg-1: #f4f5f7;
    --fg-2: #c6c9ce;
    --fg-3: var(--tsds-ink-400);
    --fg-4: var(--tsds-ink-500);

    /* Flaechen- und Akzentfarben. NICHT als Textfarbe verwenden. */
    --brand: var(--tsds-orange-700);
    --brand-hot: var(--tsds-orange-500);
    /* Kontrastgeprueft fuer Text auf --bg (Dark >= 5,5:1) */
    --brand-text: var(--tsds-orange-300);
    --brand-muted: rgba(236, 88, 52, 0.14);
    --brand-border: rgba(236, 88, 52, 0.36);
    --accent-line: 4px solid var(--brand-hot);

    --border-subtle: #262a31;
    --border-default: #363a41;
    --border-strong: #51555c;
    /* Rahmen von Bedienelementen. --border-default erreicht auf --bg-sunken nur
       1,63:1 und unterschreitet WCAG 1.4.11 (3:1); --border-strong mit 2,48:1
       ebenfalls. Wert aus der vorhandenen Rohpalette, erreicht 5,13:1. */
    --border-input: var(--tsds-ink-400);
    --focus-ring: 0 0 0 3px rgba(236, 88, 52, 0.4);

    --success: var(--tsds-success);
    --warning: var(--tsds-warning);
    --info: var(--tsds-info);
    /* Eigenstaendiges Rot statt Orange, damit Fehler nicht wie Branding wirken */
    --error: #c0392b;
    --error-text: #e57368;

    /* NEU gegenueber der Referenz: dort existiert nur --error-text.
       Statusplaketten brauchen fuer alle vier Zustaende eine kontrastgeprueft
       aufgehellte Textfarbe auf getoenter Flaeche. Werte aus dem
       Komponenten-Kanon 0.5; nachgerechnet mit tools/verify/contrast.mjs. */
    --success-text: #4cbb85;
    --warning-text: #e0a457;
    --info-text: #8aa8ea;

    --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.3);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.45), 0 2px 4px rgba(0, 0, 0, 0.25);
    --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.55);

    /* Abdunklung hinter Dialogen und der mobilen Navigation */
    --scrim: rgba(0, 0, 0, 0.45);
}

/* 2.3 Semantische Token — Light als Ueberschreibung.
   Nicht aufgefuehrte Token gelten aus dem Dark-Block auch hier: die
   Statusfarben --success, --warning, --info und --error sind in beiden
   Themes derselbe Wert, nur die zugehoerigen Textfarben unterscheiden sich. */
:root[data-theme="light"] {
    color-scheme: light;

    --bg: #fdfbfa;
    --bg-raised: #ffffff;
    --bg-sunken: #f5f2ee;

    --fg-1: var(--tsds-ink-900);
    --fg-2: var(--tsds-ink-600);
    --fg-3: var(--tsds-ink-500);
    --fg-4: var(--tsds-ink-400);

    /* --brand und --brand-hot sind in beiden Themes gleich */
    --brand-text: var(--tsds-orange-800);
    --brand-muted: var(--tsds-orange-50);
    --brand-border: var(--tsds-orange-200);

    --border-subtle: #e8e3dc;
    --border-default: #d4cec5;
    --border-strong: #a8a29a;
    --border-input: var(--tsds-ink-500);
    --focus-ring: 0 0 0 3px rgba(210, 77, 50, 0.35);

    --error-text: #a93226;

    /* Werte aus dem Komponenten-Kanon 0.5. Sie loesen drei Unterschreitungen
       ab, die die vorherige Ableitung auf getoenter --bg-sunken-Flaeche hatte
       (schwaechster Wert 4,23:1). Nachgerechnet mit tools/verify/contrast.mjs. */
    --success-text: #286848;
    --warning-text: #8a591c;
    --info-text: #2a5ac9;

    /* Eigenstaendig kalibriert, nicht bloss umgefaerbt: dunkle Tinte mit
       sehr niedriger Deckkraft statt Schwarz mit hoher. */
    --shadow-xs: 0 1px 2px rgba(22, 25, 30, 0.04);
    --shadow-md: 0 4px 12px rgba(22, 25, 30, 0.08), 0 2px 4px rgba(22, 25, 30, 0.04);
    --shadow-lg: 0 12px 32px rgba(22, 25, 30, 0.1);
}

/* ==========================================================================
   3. Basisregeln
   ========================================================================== */

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

* {
    margin: 0;
}

html {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body {
    background: var(--bg);
    color: var(--fg-1);
    font-family: var(--font-body);
    font-size: 18px;
    line-height: var(--lh-normal);
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    text-rendering: optimizeLegibility;
}

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

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

p,
h1,
h2,
h3,
h4,
h5,
h6 {
    overflow-wrap: break-word;
    text-wrap: pretty;
}

/* Einzige globale Link-Regel. Jeder Linktyp bringt seine eigene mit. */
a {
    color: inherit;
}

/* Sichtbarkeit laeuft ueber das hidden-Attribut, nicht ueber Inline-Styles.
   Ohne !important gewaenne jede Klasse mit eigener display-Angabe. */
[hidden] {
    display: none !important;
}

ul,
ol {
    padding: 0;
}

::selection {
    background: var(--brand-hot);
    color: var(--tsds-ink-0);
}

/* ==========================================================================
   4. Typografie-Utilities
   Die Komponentenklassen des Bestands sind denselben Regeln zugeordnet,
   damit kein Wert zweimal gepflegt wird.
   ========================================================================== */

.t-eyebrow {
    display: inline-flex;
    align-items: center;
}

/* Dasselbe Rezept, an sechs Stellen gebraucht. Die Werte stehen nur hier;
   die jeweiligen Komponentenregeln ergaenzen nur Abstand und Ausrichtung. */
.t-eyebrow,
.weekday,
.selected-date-display,
.detail-label,
.admin-nav-title,
.hero-note,
.pagination-info,
.admin-table th {
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    font-weight: var(--fw-medium);
    color: var(--fg-3);
    text-transform: uppercase;
    letter-spacing: var(--ls-wider);
}

.t-h1 {
    font-family: var(--font-display);
    font-size: var(--fs-4xl);
    font-weight: var(--fw-bold);
    line-height: var(--lh-tight);
    letter-spacing: var(--ls-tight);
    color: var(--fg-1);
}

.t-h2 {
    font-family: var(--font-display);
    font-size: var(--fs-3xl);
    font-weight: var(--fw-bold);
    line-height: var(--lh-snug);
    letter-spacing: var(--ls-tight);
    color: var(--fg-1);
}

.t-h3 {
    font-family: var(--font-display);
    font-size: var(--fs-2xl);
    font-weight: var(--fw-semibold);
    line-height: var(--lh-snug);
    letter-spacing: var(--ls-snug);
    color: var(--fg-1);
}

.t-h4 {
    font-family: var(--font-display);
    font-size: var(--fs-xl);
    font-weight: var(--fw-semibold);
    line-height: var(--lh-snug);
    letter-spacing: var(--ls-snug);
    color: var(--fg-1);
}

.t-h5 {
    font-family: var(--font-display);
    font-size: var(--fs-lg);
    font-weight: var(--fw-semibold);
    letter-spacing: var(--ls-snug);
    color: var(--fg-1);
}

.t-lead {
    font-family: var(--font-body);
    font-size: var(--fs-md);
    line-height: var(--lh-relaxed);
    color: var(--fg-2);
}

.t-body {
    font-family: var(--font-body);
    font-size: var(--fs-base);
    line-height: var(--lh-relaxed);
    color: var(--fg-2);
}

.t-small {
    font-family: var(--font-body);
    font-size: var(--fs-sm);
    line-height: var(--lh-normal);
    color: var(--fg-3);
}

.mono-small {
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    color: var(--fg-3);
}

/* Vom Bildschirm genommen, aber im Accessibility-Baum und fuer Bildschirmleser
   lesbar. Kein display:none und kein visibility:hidden — beides naehme das
   Element auch dem Bildschirmleser.
   Achtung: (0,1,0). Fuer Elemente mit einer konkurrierenden Elementregel
   (z. B. input[type="radio"], (0,1,1)) reicht die Klasse allein nicht aus. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Farbutilities — nur die im Markup tatsaechlich verwendeten */
.text-primary {
    color: var(--fg-1);
}

.text-secondary {
    color: var(--fg-2);
}

.text-muted {
    color: var(--fg-3);
}

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

/* 5.1 Buttons — eine Basisklasse, drei Varianten, zwei Groessenmodifier.
   Hoehe kommt aus min-height, nicht aus vertikalem Padding. */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    min-height: 56px;
    padding: 0 28px;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: 18px;
    font-weight: var(--fw-medium);
    line-height: 1;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    position: relative;
    background: transparent;
    transition:
        background var(--duration-normal) var(--ease-out),
        color var(--duration-normal) var(--ease-out),
        border-color var(--duration-normal) var(--ease-out),
        box-shadow var(--duration-normal) var(--ease-out),
        transform var(--duration-normal) var(--ease-out);
}

/* Solider Outline zusaetzlich zum weichen Ring — der halbtransparente Ring
   allein unterschreitet die 3:1-Anforderung aus WCAG 1.4.11. */
.btn:focus-visible {
    outline: 2px solid var(--brand-hot);
    outline-offset: 2px;
    box-shadow: var(--focus-ring);
    animation: tsds-focus-pulse 1.5s var(--ease-in-out) 0s 2;
}

/* Abgeleitet: die Referenz kennt weder einen deaktivierten noch einen
   beschaeftigten Button. Uebernommen ist das Rezept der deaktivierten
   Formularfelder (opacity 0.55, not-allowed). */
.btn:disabled,
.btn[aria-disabled="true"] {
    opacity: 0.55;
    cursor: not-allowed;
    transform: none;
    box-shadow: none;
}

.btn[aria-busy="true"] {
    opacity: 0.7;
    cursor: progress;
    pointer-events: none;
}

.btn-primary {
    background: var(--tsds-orange-800);
    color: var(--tsds-ink-0);
    border-color: var(--brand-hot);
}

.btn-primary::before {
    content: '\25B8';
    font-family: var(--font-mono);
    font-size: 13px;
    opacity: 0.85;
    transition: transform var(--duration-normal) var(--ease-out);
}

/* Fuellung bleibt beim Hover unveraendert — eine hellere Fuellung druecke
   den Textkontrast unter AA. Geaendert werden Erhebung und Glut. */
@media (hover: hover) {
    .btn-primary:hover:not(:disabled) {
        transform: translateY(-2px);
        box-shadow:
            0 0 0 1px var(--brand-hot),
            0 12px 32px -6px rgba(236, 88, 52, 0.45);
    }

    .btn-primary:hover:not(:disabled)::before {
        transform: translateX(4px);
    }
}

.btn-primary:active:not(:disabled) {
    background: var(--tsds-orange-900);
    transform: translateY(1px);
    box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.35);
    transition-duration: var(--duration-fast);
}

.btn-secondary {
    background: transparent;
    color: var(--brand-text);
    border-color: var(--brand-hot);
}

@media (hover: hover) {
    .btn-secondary:hover:not(:disabled) {
        background: var(--brand-muted);
    }
}

.btn-secondary:active:not(:disabled) {
    transform: translateY(1px);
    transition-duration: var(--duration-fast);
}

/* Abgeleitet: Umriss-Rezept in der Fehlerfamilie. Keine gefuellte Flaeche,
   damit eine destruktive Aktion nicht wie die Primaeraktion aussieht. */
.btn-danger {
    background: transparent;
    color: var(--error-text);
    border-color: var(--error);
}

@media (hover: hover) {
    .btn-danger:hover:not(:disabled) {
        background: color-mix(in srgb, var(--error) 14%, transparent);
    }
}

.btn-danger:active:not(:disabled) {
    transform: translateY(1px);
    transition-duration: var(--duration-fast);
}

/* Abgeleitet: Umriss-Rezept in der Erfolgsfamilie. */
.btn-success {
    background: transparent;
    color: var(--success-text);
    border-color: var(--success);
}

@media (hover: hover) {
    .btn-success:hover:not(:disabled) {
        background: color-mix(in srgb, var(--success) 14%, transparent);
    }
}

.btn-success:active:not(:disabled) {
    transform: translateY(1px);
    transition-duration: var(--duration-fast);
}

.btn-sm {
    min-height: 40px;
    padding: 0 16px;
    font-size: 16px;
}

.btn-sm.btn-primary::before {
    content: none;
}

/* Abgeleitet: eine Stufe ueber der Standardgroesse fuer den Haupteinstieg
   der Startseite. Schriftgroesse aus der Skala statt als neuer Rohwert. */
.btn-lg {
    min-height: 64px;
    padding: 0 36px;
    font-size: var(--fs-md);
}

.btn-block {
    width: 100%;
}

/* 5.2 Formular */
.form-group {
    margin-bottom: var(--space-5);
}

.form-label,
.form-checkbox .checkbox-label {
    display: block;
    font-size: 15px;
    font-weight: var(--fw-medium);
    color: var(--fg-1);
    margin-bottom: var(--space-2);
}

.form-input,
.form-textarea,
.form-select {
    width: 100%;
    font-family: var(--font-body);
    font-size: 16px;
    color: var(--fg-1);
    background: var(--bg-sunken);
    /* --border-input statt --border-default: dieser erreicht auf --bg-sunken
       nur 1,63:1 und unterschreitet WCAG 1.4.11 (3:1). Siehe Token-Ebene. */
    border: 1px solid var(--border-input);
    border-radius: var(--radius-md);
    padding: 9px 12px;
    transition:
        border-color var(--duration-fast) var(--ease-out),
        box-shadow var(--duration-fast) var(--ease-out);
}

.form-textarea {
    resize: vertical;
    min-height: 100px;
}

.form-input::placeholder,
.form-textarea::placeholder {
    color: var(--fg-4);
}

/* Einzige Stelle im Projekt mit outline: none. Der Ersatz ist ein
   Randfarbwechsel auf --brand-hot plus der weiche Fokusring. */
.form-input:focus,
.form-textarea:focus,
.form-select:focus {
    outline: none;
    border-color: var(--brand-hot);
    box-shadow: var(--focus-ring);
}

.form-input:disabled,
.form-textarea:disabled,
.form-select:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}

/* Abgeleitet: die Referenz kennt keinen Selektor auf [aria-invalid].
   Ein fehlerhaftes Feld bekommt die Randfarbe der Fehlerfamilie, damit der
   Fehler nicht ausschliesslich unter dem Feld steht.
   aria-invalid="true" am Feld ist der einzige Zustandstraeger. Die frueher
   danebenstehende Klassen-Schiene .form-group.error ist entfallen — sie wurde
   nirgends gesetzt und deckte .form-select ohnehin nicht mit ab.
   input-validation-error rendert ASP.NET Core selbst bei serverseitiger
   Validierung; ohne diese Zeile bliebe das Feld dort optisch unveraendert. */
.form-input[aria-invalid="true"],
.form-textarea[aria-invalid="true"],
.form-select[aria-invalid="true"],
.form-input.input-validation-error,
.form-textarea.input-validation-error,
.form-select.input-validation-error {
    border-color: var(--error);
}

/* Hoehere Spezifitaet als .form-input:focus, sonst gewaenne dort der
   markenfarbene Rahmen. Der Fokusring wechselt mit in die Fehlerfarbe: ein
   markenfarbener Ring auf rotem Rahmen liest sich als zwei Signale. */
.form-input[aria-invalid="true"]:focus,
.form-textarea[aria-invalid="true"]:focus,
.form-select[aria-invalid="true"]:focus,
.form-input.input-validation-error:focus,
.form-textarea.input-validation-error:focus,
.form-select.input-validation-error:focus {
    border-color: var(--error);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--error) 40%, transparent);
}

/* Abgeleitet: Auswahlfeld auf dem Feldrezept, Chevron aus Rahmenkanten
   statt als Grafik. */
.form-select {
    appearance: none;
    padding-right: 34px;
    background-image:
        linear-gradient(45deg, transparent 50%, currentColor 50%),
        linear-gradient(135deg, currentColor 50%, transparent 50%);
    background-position:
        calc(100% - 18px) calc(50% + 2px),
        calc(100% - 13px) calc(50% + 2px);
    background-size: 5px 5px, 5px 5px;
    background-repeat: no-repeat;
}

.form-error {
    display: block;
    margin-top: var(--space-1);
    color: var(--error-text);
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    line-height: var(--lh-normal);
}

/* Ohne diese Regel erzeugt jedes Formular einen leeren Abstandsblock unter
   jedem Feld, bevor ueberhaupt ein Fehler aufgetreten ist. */
.form-error:empty {
    display: none;
}

.form-hint,
.form-help {
    display: block;
    margin-top: var(--space-1);
    font-size: var(--fs-xs);
    color: var(--fg-3);
}

.text-danger {
    display: block;
    margin-top: var(--space-1);
    color: var(--error-text);
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
}

input[type="checkbox"],
input[type="radio"] {
    accent-color: var(--brand-hot);
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    cursor: pointer;
}

.form-checkbox,
.checkbox-inline {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-5);
}

.form-checkbox .checkbox-label,
.checkbox-inline .form-label {
    margin-bottom: 0;
    cursor: pointer;
    user-select: none;
}

/* Honeypot — vom Bildschirm genommen, nicht per display:none */
.form-honeypot {
    position: absolute;
    left: -10000px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* 5.3 Flaechen: Karte und hervorgehobener Kasten */
.admin-card,
.admin-stat-card,
.legal-section,
.feature-card,
.expect-item,
.step-content,
.booking-details-card,
.login-card,
.error-card {
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
    box-shadow: var(--shadow-xs);
    transition:
        border-color var(--duration-normal) var(--ease-out),
        transform var(--duration-normal) var(--ease-out),
        box-shadow var(--duration-normal) var(--ease-out);
}

@media (hover: hover) {
    .feature-card:hover,
    .admin-stat-card:hover {
        border-color: var(--border-default);
        transform: translateY(-2px);
        box-shadow: var(--shadow-md);
    }
}

/* Ohne diese Regel bekommt nur das Bedienelement in der Karte einen
   Fokusring, die Karte selbst bleibt unbeteiligt. */
.feature-card:focus-within,
.admin-stat-card:focus-within,
.expect-item:focus-within {
    border-color: var(--border-default);
    box-shadow: var(--shadow-md);
}

/* Wiederkehrendes Rezept fuer hervorgehobene Kaesten */
.booking-alert,
.warning-box,
.alert,
.admin-card-warning,
.admin-card-info {
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-left: var(--accent-line);
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
    font-size: 15px;
    line-height: 1.55;
    color: var(--fg-2);
    /* Text bleibt links, zentrierter Text braeche die Akzentkante */
    text-align: left;
}

.booking-alert.success,
.alert-success {
    background: color-mix(in srgb, var(--success) 14%, transparent);
    border-left-color: var(--success);
    color: var(--success-text);
}

.booking-alert.error,
.alert-error {
    background: color-mix(in srgb, var(--error) 14%, transparent);
    border-left-color: var(--error);
    color: var(--error-text);
}

.warning-box,
.admin-card-warning {
    background: color-mix(in srgb, var(--warning) 14%, transparent);
    border-left-color: var(--warning);
    color: var(--warning-text);
}

.admin-card-info {
    background: color-mix(in srgb, var(--info) 14%, transparent);
    border-left-color: var(--info);
    color: var(--info-text);
}

/* 5.4 Statusplaketten — abgeleitet aus dem Plaketten-Rezept der Referenz:
   Pillenform, Monospace, --fs-xs. Flaeche und Rahmen entstehen ueber
   color-mix aus der jeweiligen Statusfarbe, der Text aus dem zugehoerigen
   kontrastgeprueften Text-Token.
   Die Toenung liegt bei 14 %: bei 16 % faellt --error-text im Dark-Theme auf
   4,42:1 und --success-text im Light-Theme auf 4,23:1, beides unter AA.
   Der Rahmen bleibt bei 36 % — er ist dekorativ, den Status traegt der Text. */
.status-badge {
    display: inline-flex;
    align-items: center;
    width: fit-content;
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-full);
    border: 1px solid transparent;
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    line-height: 1.4;
    white-space: nowrap;
}

.status-pending {
    background: color-mix(in srgb, var(--warning) 14%, transparent);
    border-color: color-mix(in srgb, var(--warning) 36%, transparent);
    color: var(--warning-text);
}

.status-confirmed {
    background: color-mix(in srgb, var(--success) 14%, transparent);
    border-color: color-mix(in srgb, var(--success) 36%, transparent);
    color: var(--success-text);
}

.status-cancelled {
    background: color-mix(in srgb, var(--error) 14%, transparent);
    border-color: color-mix(in srgb, var(--error) 36%, transparent);
    color: var(--error-text);
}

.status-completed {
    background: color-mix(in srgb, var(--info) 14%, transparent);
    border-color: color-mix(in srgb, var(--info) 36%, transparent);
    color: var(--info-text);
}

/* Neutrale Variante. Sie traegt den Fallback fuer unbekannte Statuswerte und
   Zustaende, die kein Fehler sind (z. B. eine inaktive Verfuegbarkeitsregel).
   Ohne sie rendert ein unbekannter Status als transparente Plakette. */
.status-badge--neutral {
    background: var(--bg-sunken);
    border-color: var(--border-default);
    color: var(--fg-2);
}

/* 5.5 Tabellen — abgeleitet. Die Referenz hat keine Tabelle; uebernommen
   sind das Zeilenlisten-Rezept (Unterlinien, Hover ohne Guard) und der
   Eyebrow-Stil fuer die Kopfzeile. */
.admin-table-container {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* Der Behaelter ist per tabindex fokussierbar, damit ein waagerecht
   scrollender Bereich per Tastatur erreichbar ist (WCAG 2.1.1). Ein
   fokussierbares Element ohne sichtbaren Ring waere der naechste Fehler. */
.admin-table-container:focus-visible {
    outline: 2px solid var(--brand-hot);
    outline-offset: 2px;
}

.admin-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-sm);
}

.admin-table th {
    padding: var(--space-3) var(--space-4);
    text-align: left;
    border-bottom: 1px solid var(--border-default);
    white-space: nowrap;
}

.admin-table td {
    padding: var(--space-3) var(--space-4);
    color: var(--fg-2);
    border-bottom: 1px solid var(--border-subtle);
    vertical-align: top;
}

.admin-table tbody tr {
    transition: background var(--duration-fast) var(--ease-out);
}

.admin-table tbody tr:hover {
    background: var(--bg-sunken);
}

/* 5.6 Leerer Zustand — abgeleitet */
.empty-state {
    text-align: center;
    padding: var(--space-8) var(--space-4);
    color: var(--fg-3);
}

.empty-state-icon {
    color: var(--fg-4);
    margin-bottom: var(--space-4);
}

.empty-state-icon svg {
    margin: 0 auto;
    stroke: currentColor;
}

.empty-state-title {
    margin-bottom: var(--space-2);
}

/* Bis hierher kam die Optik allein aus der zusaetzlich gesetzten Utility
   .t-small; die Klasse war funktionslos. 40ch ist das Textmass des Kanons
   fuer diesen Baustein — der Block ist zentriert, deshalb margin-inline. */
.empty-state-text {
    max-width: 40ch;
    margin-inline: auto;
}

/* 5.7 Ladeanzeige — abgeleitet */
.loading-state {
    text-align: center;
    padding: var(--space-8) var(--space-4);
    color: var(--fg-3);
}

.spinner {
    width: 40px;
    height: 40px;
    margin: 0 auto var(--space-4);
    border: 3px solid var(--border-subtle);
    border-top-color: var(--brand-hot);
    border-radius: var(--radius-full);
    animation: tsds-spin 1s linear infinite;
}

@keyframes tsds-spin {
    to {
        transform: rotate(360deg);
    }
}

/* 5.8 Dialoge — natives <dialog> mit showModal(). Fokusfalle, Inertisierung
   des Hintergrunds, Scroll-Lock und Escape-Verhalten bringt das Element mit;
   die Fokusrueckgabe an den Ausloeser ebenfalls. Zustandstraeger ist das
   native open-Attribut, nicht hidden und keine Zustandsklasse.
   Abdunklung ueber ::backdrop mit --scrim, Flaeche aus dem Kartenrezept mit
   der staerksten Schattenstufe. */
.admin-dialog {
    width: 100%;
    max-width: min(92vw, 28rem);
    max-height: calc(100dvh - 2 * var(--space-6));
    /* Die Zentrierung im Top-Layer kommt normalerweise vom Browser
       (dialog:modal { margin: auto }). Die Basisregel * { margin: 0 } dieser
       Datei ist eine Autorenregel und schlaegt sie — ohne diese Zeile klebt
       der Dialog oben links. Gemessen, nicht gelesen. */
    margin: auto;
    padding: 0;
    border: none;
    background: transparent;
    overflow: visible;
    color: var(--fg-1);
}

.admin-dialog::backdrop {
    background: var(--scrim);
}

.modal,
.confirm-dialog {
    width: 100%;
    max-height: calc(100dvh - 2 * var(--space-6));
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--space-6);
}

.modal-header {
    margin-bottom: var(--space-4);
}

.modal-title,
.confirm-dialog-title {
    margin-bottom: var(--space-3);
}

.modal-body,
.confirm-dialog-message {
    color: var(--fg-2);
    font-size: var(--fs-sm);
    margin-bottom: var(--space-5);
}

.modal-footer,
.confirm-dialog-actions {
    display: flex;
    gap: var(--space-3);
    justify-content: flex-end;
    flex-wrap: wrap;
}

/* 5.9 Toast — abgeleitet aus dem Rezept fuer hervorgehobene Kaesten.
   Die Live-Region ist der Container, nicht der Toast: eine Region, die
   gleichzeitig mit ihrem Inhalt entsteht, lesen mehrere Bildschirmleser nicht
   vor. Der Bereich haelt zwei Container vor (hoeflich und assertiv), damit
   Erfolgs- und Fehlermeldungen sich stapeln statt sich zu ueberlagern. */
.admin-toast-region {
    position: fixed;
    top: var(--space-5);
    right: var(--space-5);
    z-index: 1200;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    width: min(24rem, calc(100vw - 2 * var(--space-5)));
    /* Der leere Bereich darf keine Klicks abfangen */
    pointer-events: none;
}

.admin-toast-container {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.admin-toast {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-left: var(--accent-line);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    color: var(--fg-1);
    font-size: 15px;
    line-height: 1.55;
    pointer-events: auto;
    animation: tsds-toast-in var(--duration-normal) var(--ease-out) both;
}

.admin-toast-icon {
    flex-shrink: 0;
    margin-top: 2px;
}

.admin-toast-message {
    flex: 1;
    margin: 0;
}

/* 44 px Trefferflaeche. Die negativen Aussenabstaende holen die Flaeche
   zurueck in die Polsterung des Toasts, damit er nicht hoeher wird. */
.admin-toast-close {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin: calc(var(--space-2) * -1) calc(var(--space-3) * -1) calc(var(--space-2) * -1) 0;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: var(--radius-sm);
    color: var(--fg-3);
    cursor: pointer;
    transition:
        background var(--duration-fast) var(--ease-out),
        color var(--duration-fast) var(--ease-out);
}

@media (hover: hover) {
    .admin-toast-close:hover {
        background: var(--bg-sunken);
        color: var(--fg-1);
    }
}

.admin-toast-close:focus-visible {
    outline: 2px solid var(--brand-hot);
    outline-offset: 2px;
}

/* Kante und Icon tragen die Variante. Der Text bleibt --fg-1: der Toast liegt
   ueber wechselndem Untergrund und muss in jeder Lage deckend sein. */
.admin-toast.success {
    border-left-color: var(--success);
}

.admin-toast.success .admin-toast-icon {
    color: var(--success-text);
}

.admin-toast.error {
    border-left-color: var(--error);
}

.admin-toast.error .admin-toast-icon {
    color: var(--error-text);
}

@keyframes tsds-toast-in {
    from {
        opacity: 0;
        transform: translateY(-8px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* 5.10 Paginierung — abgeleitet: Zaehler in Monospace, Schalter als btn-sm */
.admin-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-4);
    padding: var(--space-5) 0;
    flex-wrap: wrap;
}

/* Typografie kommt aus der gruppierten Eyebrow-Regel. Hier nur die
   Ziffernbreite, damit der Zaehler beim Blaettern nicht springt. */
.pagination-info {
    font-variant-numeric: tabular-nums;
}

/* 5.11 Theme-Umschalter */
.theme-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    padding: 0;
    background: transparent;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    color: var(--fg-2);
    cursor: pointer;
    transition:
        color var(--duration-fast) var(--ease-out),
        border-color var(--duration-fast) var(--ease-out),
        transform var(--duration-normal) var(--ease-out);
}

@media (hover: hover) {
    .theme-toggle:hover {
        color: var(--brand-hot);
        border-color: var(--brand-hot);
        transform: rotate(-12deg);
    }
}

.theme-toggle:focus-visible {
    outline: 2px solid var(--brand-hot);
    outline-offset: 2px;
    box-shadow: var(--focus-ring);
}

.theme-toggle:active {
    transform: scale(0.94);
}

/* Vor der Initialisierung bleibt die Box sichtbar reserviert, sonst poppt
   der Schalter unvermittelt auf. Kein visibility: hidden. */
.theme-toggle--pending {
    opacity: 0.35;
    pointer-events: none;
}

/* Es wird immer das Ziel-Symbol gezeigt, nicht der aktuelle Zustand */
.theme-toggle-icon--dark {
    display: none;
}

:root[data-theme="light"] .theme-toggle-icon--dark {
    display: block;
}

:root[data-theme="light"] .theme-toggle-icon--light {
    display: none;
}

/* 5.12 Cookie-Hinweis — abgeleitet. Die Referenz hat bewusst keinen Banner;
   uebernommen ist das Rezept fuer hervorgehobene Kaesten plus die
   Glasflaeche der Kopfzeile. */
.cookie-banner {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1000;
    padding: var(--space-3) var(--gutter);
    background: color-mix(in srgb, var(--bg-raised) 92%, transparent);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-top: 1px solid var(--border-subtle);
    box-shadow: var(--shadow-md);
}

.cookie-banner-content {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-5);
    max-width: var(--container-max);
    margin: 0 auto;
}

.cookie-banner-text {
    color: var(--fg-2);
    font-size: 15px;
    line-height: 1.55;
}

.cookie-banner-button {
    flex-shrink: 0;
    min-height: 44px;
    padding: 0 var(--space-4);
    background: transparent;
    color: var(--brand-text);
    border: 1px solid var(--brand-hot);
    border-radius: var(--radius-md);
    font-size: var(--fs-sm);
    font-weight: var(--fw-medium);
    white-space: nowrap;
    cursor: pointer;
    transition: background var(--duration-normal) var(--ease-out);
}

@media (hover: hover) {
    .cookie-banner-button:hover {
        background: var(--brand-muted);
    }
}

.cookie-banner-button:focus-visible {
    outline: 2px solid var(--brand-hot);
    outline-offset: 2px;
}

@media (max-width: 639px) {
    .cookie-banner-content {
        flex-direction: column;
        align-items: stretch;
        gap: var(--space-3);
    }
}

/* 5.13 Skip-Link */
.skip-link {
    position: absolute;
    left: -10000px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
    z-index: 9999;
}

.skip-link:focus,
.skip-link:focus-visible {
    position: fixed;
    left: 16px;
    top: 16px;
    width: auto;
    height: auto;
    overflow: visible;
    padding: 10px 16px;
    background: var(--bg-raised);
    color: var(--fg-1);
    border: 1px solid var(--brand-hot);
    border-radius: var(--radius-md);
    font-family: var(--font-body);
    font-size: 16px;
    font-weight: var(--fw-medium);
    text-decoration: none;
    box-shadow: var(--shadow-md);
}

/* ==========================================================================
   6. Layout
   ========================================================================== */

.container {
    width: 100%;
    max-width: min(92vw, var(--container-max));
    margin: 0 auto;
    padding-inline: var(--gutter);
}

.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
    background: color-mix(in srgb, var(--bg) 85%, transparent);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--border-subtle);
}

.nav-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-5);
    padding: 14px 32px;
    max-width: var(--container-max);
    margin: 0 auto;
}

.nav-actions {
    display: flex;
    align-items: center;
    gap: var(--space-4);
}

.site-logo {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    text-decoration: none;
    color: var(--fg-1);
}

.logo-text {
    font-size: 20px;
    font-weight: var(--fw-bold);
    letter-spacing: var(--ls-snug);
}

.logo-separator {
    color: var(--fg-4);
}

.logo-subtitle {
    font-family: var(--font-mono);
    font-size: 12px;
    letter-spacing: var(--ls-wider);
    color: var(--fg-3);
}

.nav-link,
.footer-link,
.login-link {
    font-size: 16px;
    font-weight: var(--fw-medium);
    color: var(--fg-2);
    text-decoration: none;
    transition: color var(--duration-fast) var(--ease-out);
}

@media (hover: hover) {
    .nav-link:hover,
    .footer-link:hover,
    .login-link:hover {
        color: var(--brand-text);
    }
}

.site-main {
    flex: 1;
    padding: var(--space-7) 0;
}

.site-footer {
    margin-top: var(--space-8);
    padding: var(--space-8) 0 var(--space-5);
    background: var(--bg-sunken);
    border-top: 1px solid var(--border-subtle);
}

.footer-container {
    max-width: var(--container-max);
    margin: 0 auto;
    padding-inline: var(--gutter);
    text-align: center;
}

.footer-text {
    font-family: var(--font-mono);
    font-size: var(--fs-xs);
    color: var(--fg-3);
    margin-bottom: var(--space-2);
}

.footer-links {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: var(--space-4);
    margin-top: var(--space-2);
}

.footer-separator {
    color: var(--fg-4);
}

/* Links im Fliesstext */
.legal-link,
.link-accent,
.about-link,
.cookie-banner-link {
    color: var(--brand-text);
    text-decoration: underline;
    text-underline-offset: 3px;
    word-break: break-word;
}

.about-link,
.link-accent {
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-weight: var(--fw-medium);
}

@media (hover: hover) {
    .about-link:hover,
    .link-accent:hover {
        text-decoration: underline;
        text-underline-offset: 3px;
    }
}

/* ==========================================================================
   7. Bewegung
   ========================================================================== */

@keyframes tsds-focus-pulse {
    0%,
    100% {
        box-shadow: var(--focus-ring);
    }

    50% {
        box-shadow: 0 0 0 5px rgba(236, 88, 52, 0.22);
    }
}

/* ==========================================================================
   8. Responsive Grundlagen
   ========================================================================== */

@media (max-width: 1023px) {
    .site-main {
        padding: var(--space-6) 0;
    }
}

@media (max-width: 767px) {
    .btn {
        min-height: 52px;
        padding: 0 22px;
        font-size: 17px;
    }

    .btn-sm {
        min-height: 44px;
        padding: 0 14px;
        font-size: 15px;
    }

    .btn-lg {
        min-height: 56px;
        padding: 0 24px;
        font-size: var(--fs-base);
    }

    /* Mindestens 16 px, sonst zoomt iOS beim Fokus ungefragt hinein */
    .form-input,
    .form-textarea,
    .form-select {
        min-height: 44px;
        padding: 10px 12px;
        font-size: 18px;
    }

    /* Die Kurzform padding daruber setzt padding-right zurueck. Eine Media
       Query erhoeht die Spezifitaet nicht, und diese Regel steht spaeter in
       der Datei — ohne diese Zeile laege der Chevron auf dem Text. */
    .form-select {
        padding-right: 34px;
    }

    .nav-container {
        padding: 10px 16px;
        gap: var(--space-2);
        flex-wrap: nowrap;
    }

    .site-main {
        padding: var(--space-5) 0;
    }

    .t-h1 {
        font-size: var(--fs-2xl);
    }

    .t-h2 {
        font-size: var(--fs-xl);
    }

    .t-h3 {
        font-size: var(--fs-lg);
    }

    .t-h4 {
        font-size: var(--fs-md);
    }

    .t-lead {
        font-size: var(--fs-base);
    }

    .admin-toast-region {
        left: var(--space-4);
        right: var(--space-4);
        width: auto;
    }

    .modal-footer,
    .confirm-dialog-actions {
        flex-direction: column;
    }

    .modal-footer .btn,
    .confirm-dialog-actions .btn {
        width: 100%;
    }
}

@media (max-width: 639px) {
    .container,
    .footer-container {
        padding-inline: 16px;
    }

    .footer-links {
        flex-wrap: wrap;
    }
}

@media (max-width: 400px) {
    /* Gestaffeltes Ausblenden der Wortmarke: Untertitel zuerst */
    .logo-subtitle,
    .logo-separator {
        display: none;
    }
}

@media (min-width: 1440px) {
    .site-main {
        padding: var(--space-8) 0;
    }
}

/* ==========================================================================
   9. Rueckfaelle

   Dieser Abschnitt steht bewusst als letzter in der Datei. Eine Media Query
   erhoeht die Spezifitaet nicht — bei gleicher Spezifitaet entscheidet die
   Quellreihenfolge. Standen die Rueckfaelle vor den Breakpoint-Regeln, setzte
   eine spaetere Kurzform (etwa "padding") die Rueckfallwerte still zurueck.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    :root {
        --duration-fast: 0.01ms;
        --duration-normal: 0.01ms;
    }

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

    /* Endzustaende ausdruecklich fixieren: eine auf 0,01 ms gekappte
       Einblendung liesse die Elemente sonst bei opacity 0 zurueck. */
    .admin-toast {
        opacity: 1 !important;
        transform: none !important;
    }

    /* Der Ladekreis bliebe als schiefer Ring stehen. Statt ihn zu kappen,
       wird er zu einem ruhenden Punkt. */
    .spinner {
        animation: none !important;
        border-color: var(--border-subtle);
        border-top-color: var(--brand-hot);
    }
}

@media (forced-colors: active) {
    /* Erzwungene Modi ersetzen background-color, aber keine Verlaeufe */
    .cta-content {
        background-image: none;
    }

    /* Der aus zwei Verlaeufen gebaute Chevron muss weg. Ohne appearance: auto
       stuende das Feld dann ganz ohne Aufklapp-Marke da — der Rueckfall
       beseitigte den einen Mangel und schuf den naechsten. */
    .form-select {
        appearance: auto;
        -webkit-appearance: auto;
        background-image: none;
        padding-right: var(--space-3);
    }

    /* Flaechen mit Bedeutung brauchen eine sichtbare Kante */
    .admin-card,
    .admin-stat-card,
    .legal-section,
    .feature-card,
    .expect-item,
    .step-content,
    .booking-details-card,
    .login-card,
    .error-card,
    .modal,
    .confirm-dialog,
    .admin-toast {
        border-color: CanvasText;
    }

    /* Die Abdunklung des Dialogs traegt --scrim, eine halbdurchsichtige Farbe.
       Erzwungene Farbmodi ersetzen sie nicht, weil ::backdrop kein gewoehnliches
       Element ist — der Seiteninhalt schiene weiterhin durch und der Dialog
       stuende ohne Trennung zum Hintergrund da. Kanon 2, Rueckfaelle:
       Abdunklung auf Canvas. Die Kante des Kastens deckt die Sammelregel
       oben ueber .modal und .confirm-dialog ab. */
    .admin-dialog::backdrop {
        background: Canvas;
    }

    /* Status wird ueber die Form kommuniziert, nicht ueber die Farbe */
    .status-badge {
        border: 1px solid CanvasText;
        border-radius: var(--radius-sm);
    }

    /* --- Toast: die Variante laeuft sonst allein ueber die Kantenfarbe, die
       der Kontrastmodus ersetzt. Das Symbol bleibt als Formunterschied. --- */
    .admin-toast-icon {
        forced-color-adjust: none;
    }

    /* --- Tabelle: Zeilentrennung und Hover verlieren ihre Flaechenfarbe --- */
    .admin-table tbody tr {
        border-bottom: 1px solid CanvasText;
    }

    .admin-table th {
        border-bottom: 2px solid CanvasText;
    }

    .admin-table tbody tr:hover,
    .admin-table tbody tr:focus-within {
        background: Highlight;
        color: HighlightText;
    }

    /* --- Meldungskaesten: die getoente Flaeche entfaellt ersatzlos, die
       Akzentkante traegt allein. --- */
    .booking-alert,
    .warning-box,
    .alert,
    .admin-card-warning,
    .admin-card-info {
        background: Canvas;
        border: 1px solid CanvasText;
        border-left: 4px solid CanvasText;
    }

    /* --- Feldfehler: die Farbe wird ersetzt, die Strichelung bleibt und ist
       damit das einzige verbleibende Merkmal des Fehlerzustands. --- */
    .form-input[aria-invalid="true"],
    .form-textarea[aria-invalid="true"],
    .form-select[aria-invalid="true"],
    .form-input.input-validation-error,
    .form-textarea.input-validation-error,
    .form-select.input-validation-error {
        border-width: 2px;
        border-style: dashed;
    }

    /* --- Leerzustand: Icon, Titel und Umgebung verschmelzen sonst auf
       dieselbe Systemfarbe. Die Kante grenzt den Block ab. --- */
    .empty-state {
        border: 1px dashed CanvasText;
        border-radius: var(--radius-md);
    }

    /* --- Cookie-Hinweis: backdrop-filter und die color-mix-Flaeche entfallen
       ersatzlos; ohne deckende Flaeche stuende der Text auf dem
       Seiteninhalt. --- */
    .cookie-banner {
        background: Canvas;
        border-top: 2px solid CanvasText;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }
}
