/* ============================================================
   Theme-Tokens in EINEM :root, zwei Abschnitte:
   1) --fbd-* = statische Design-Token-Palette (Single Source der
      kanonischen Marken-/Strukturfarben + Basis-Typografie).
   2) --office-* = dynamische Branding-Schicht (Laufzeit-Override +
      Auto-Kontrast via OfficeThemeStyle); ihre Defaults referenzieren
      die --fbd-*-Konstanten.
   Regel: Neutrale/semantische Farben → --fbd-*; Brand-/Rollenfarben → --office-*.
   ============================================================ */

/* ============================================================
   Lexend — Schriftfamilie für die Theme-Option "Lexend, sans-serif"

   Herkunft: @fontsource-variable/lexend@5.3.0 via LibMan (libman.json → wwwroot/lib/lexend/),
   SIL Open Font License 1.1; alle Dateien same-origin, kein externer Aufruf.

   Familienname bewusst 'Lexend' statt des Fontsource-Namens 'Lexend Variable': Der im
   Alt-Portal gespeicherte Theme-Wert lautet 'Lexend, sans-serif' und landet unverändert in
   --office-font-family; das mitgelieferte wght.css griffe deshalb ins Leere. Aus demselben
   Grund format('woff2') statt dessen veraltetem format('woff2-variations') — Engines, die es
   nicht kennen, verwerfen die ganze src-Angabe. Pfad relativ, weil url() gegen diese Datei
   auflöst: bleibt auch unter einem virtuellen Verzeichnis richtig.

   Hier statt in eigener Datei und ohne rel="preload": Lexend ist die Option einzelner Ämter.
   Ein eigenes Stylesheet wäre ein Extra-Request auf jeder Seite jedes Amtes, ein Preload die
   88 KB für alle; so lädt @font-face erst bei Verwendung. Variable Font, weil das Portal
   Gewicht 500 nutzt (dafür gibt es keine statische Datei); drei Zeichenbereiche, damit ein
   vietnamesischer Name nicht auf die Ersatzschrift fällt. unicode-range unverändert aus 5.3.0.
   ============================================================ */

@font-face {
    font-family: 'Lexend';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('lib/lexend/files/lexend-latin-wght-normal.woff2') format('woff2');
    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;
}

@font-face {
    font-family: 'Lexend';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('lib/lexend/files/lexend-latin-ext-wght-normal.woff2') format('woff2');
    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: 'Lexend';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('lib/lexend/files/lexend-vietnamese-wght-normal.woff2') format('woff2');
    unicode-range: U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB;
}

:root {
    /* === FBD Design-Tokens (statische Palette) === */
    /* Blau */
    --fbd-blue-vois: #004987;
    --fbd-blue-science: #006CD2;
    --fbd-blue-prussian: #003765;
    --fbd-blue-patterns: #D7EAF8;
    --fbd-blue-alice: #F3F7FF;

    /* Monochrom */
    --fbd-mono-nero: #222222;
    --fbd-mono-charcoal: #414141;
    --fbd-mono-industrial: #737373;
    --fbd-mono-mice: #919191;
    --fbd-mono-silverish: #CCCCCC;
    --fbd-mono-porcelain: #F0F0F0;
    --fbd-mono-gallery: #F5F5F5;
    --fbd-mono-alabaster: #FAFAFA;
    --fbd-mono-white: #FFFFFF;

    /* Grün */
    --fbd-green-moss: #0E6D00;
    --fbd-green-laurel: #008900;
    --fbd-green-mint: #F5FAE8;

    /* Rot */
    --fbd-red-burgundy: #7A000F;
    --fbd-red-carmine: #A80212;
    --fbd-red-venetian: #D50006;
    --fbd-red-palepink: #FFF0F0;

    /* Gelb */
    --fbd-yellow-selective: #FFBB00;
    --fbd-yellow-cassonade: #E09C24;
    --fbd-yellow-ivorish: #FFFFF5;

    /* Orange */
    --fbd-orange-blaze: #F15B00;

    /* Typografie (Basis) */
    --fbd-font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    --fbd-font-size-base: 1rem;

    /* === Office-Branding (dynamisch) ===
       Defaults stützen sich auf die --fbd-*-Palette oben und entsprechen exakt dem
       Standard-Erscheinungsbild. Zur Laufzeit überschreibt <OfficeThemeStyle> pro
       Verwaltung nur einzelne --office-*-Werte (validiert in ThemeTokenSanitizer).
       Nur Farb-/Schrift-Properties – Layout/Abstände sind nicht beeinflussbar. */

    /* Primär (Buttons, Header, Office-Name) */
    --office-primary: var(--fbd-blue-vois); /* blueVois */
    --office-primary-hover: var(--fbd-blue-science); /* blueScience */
    --office-primary-fontcolor: var(--fbd-mono-white);

    /* Sekundär (sekundäre Buttons) */
    --office-secondary: #5a6268;
    --office-secondary-hover: #4e555b;
    --office-secondary-fontcolor: var(--fbd-mono-white);

    /* Grundlayout */
    --office-font-family: var(--fbd-font-family);
    --office-font-size: var(--fbd-font-size-base);
    --office-line-height: 1.5;

    /* Links */
    --office-link: var(--fbd-blue-vois);
    --office-link-hover: var(--fbd-blue-prussian);

    /* Formulare */
    --office-placeholder: #6C787F;

    /* === App-Flächen/Text (semantische Schicht für den Kontrastmodus) ===
       Die Defaults sind wörtlich die bisherigen Werte → im Normalmodus ändert sich nichts.
       Der Block html.a11y-contrast (weiter unten) flippt ausschließlich diese Tokens (+ die
       --office-*-Brandtokens) auf Hochkontrast; einzelne Regeln müssen dafür nicht
       angefasst werden. */
    --app-page-bg: var(--fbd-mono-white); /* Seitenhintergrund */
    --app-page-text: #212529; /* Fließtext auf der Seite */
    --app-surface: var(--fbd-mono-gallery); /* erhabene Flächen: Card (Wizard-Sidebar: Slice 02) */
    --app-surface-input: var(--fbd-mono-alabaster); /* Eingabefelder, bg-light */
    --app-surface-input-focus: var(--fbd-mono-white); /* Eingabefeld bei Fokus */
    --app-surface-input-text: var(--fbd-mono-nero); /* Text/Label in Formularen */
    --app-border: var(--fbd-mono-mice); /* Standard-Rahmen/Trennlinien */
    --app-border-strong: #dee2e6; /* kräftigere Rahmen (Card-Header) */
    --app-muted-text: #595959; /* sekundärer/Hilfetext */

    /* Hamburger-Button der Wizard-Sidebar (FundanzeigeNavMenu.razor.css). Als Tokens, weil die
       Blazor-CSS-Isolation dort keinen Vorfahren-Selektor kennt (kein :global()) und ein
       Override aus dieser Datei per Spezifität gegen die scoped Regel verliert:
       html.a11y-contrast .navbar-toggler (0,1,1) < .navbar-toggler[b-xyz] (0,2,0).
       Alle drei Werte hier und nicht als var()-Fallback in der Insel: Der data-URI muss ohnehin
       in eine Deklaration, und die beiden Farbwerte gehen mit, damit die Insel eine Schicht
       liest statt zwei Mustern. Werte = der bisherige Bestand, Normalmodus unverändert. */
    --app-toggler-border: rgba(0, 0, 0, 0.2);
    --app-toggler-bg: rgba(0, 0, 0, 0.05);
    --app-toggler-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");

    /* Bootstrap-Grundwerte. Seitenhintergrund/-Textfarbe laufen über die --app-*-Tokens
       (im Normalmodus hell, im Kontrastmodus dunkel). */
    --bs-body-bg: var(--app-page-bg);
    --bs-body-color: var(--app-page-text);
    --bs-body-font-size: var(--office-font-size);
    --bs-body-line-height: var(--office-line-height);
    --bs-link-color: var(--office-link);
    --bs-link-hover-color: var(--office-link-hover);
}

body {
    padding: 1rem;
}

html, body {
    font-family: var(--office-font-family, 'Helvetica Neue', Helvetica, Arial, sans-serif);
}

h1:focus {
    outline: none;
}

/* Honeypot-Feld gegen Bots: aus dem Layout entfernt und vom Screenreader (aria-hidden
   im Markup) sowie der Tab-Reihenfolge (tabindex=-1) ausgenommen. display:none wird
   bewusst gemieden, damit naive Bots das Feld dennoch finden und (fälschlich) ausfüllen. */
.hp-field {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.form-control::placeholder {
    color: var(--office-placeholder, var(--bs-secondary-color));
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--office-placeholder, var(--bs-secondary-color));
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}

/* Submission Steps Styling */
.submission-container {
    max-width: 1200px;
    margin: 0 auto;
}

.step-content {
    border-radius: 10px;
    min-height: 400px;
}

/* Navigation Buttons */
.step-navigation {
    display: flex;
    justify-content: space-between;
    margin-top: 30px;
    padding-top: 20px;
    border-top: 1px solid #e0e0e0;
}

/* Navigation Menu Button Styling */
.nav-link {
    background: none;
    border: none;
    width: 100%;
    text-align: left;
    padding: 0.5rem 1rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    transition: all 0.2s ease;
}

.nav-link:hover {
    background-color: rgba(255, 255, 255, 0.1);
}

.nav-link.active {
    background-color: var(--office-primary, var(--fbd-blue-vois));
    color: var(--office-primary-fontcolor, var(--fbd-mono-white));
}

.step-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 33px;
    height: 33px;
    border: 1px solid var(--office-primary-readable, var(--fbd-blue-vois));
    border-radius: 50%;
    color: var(--office-primary-readable, var(--fbd-blue-vois));
    font-weight: bold;
    font-size: 14px;
    background-color: transparent;
    margin-right: 0.1rem;
    transition: all 0.3s ease;
}

.step-badge.completed {
/*    background-color: #26b050;
    border-color: #26b050;
    color: white;*/
}

.nav-link.active .step-badge {
    background-color: var(--office-primary, var(--fbd-blue-vois));
    border-color: var(--office-primary, var(--fbd-blue-vois));
    color: var(--office-primary-fontcolor, var(--fbd-mono-white));
}

/* Mobile Responsiveness */
@media (max-width: 768px) {
    .step-badge {
        width: 28px;
        height: 28px;
        font-size: 12px;
    }
    
    .step-content {
        padding: 10px 0;
    }
}

/* Form Step Styling */
.form-step {
    margin-bottom: 2rem;
}

.form-step.active {
    display: block;
}

.card {
    border: 1px solid var(--app-border, var(--fbd-mono-mice)); /* monochromeMice - Rahmenfarbe */
    border-radius: 10px;
    margin-bottom: 1rem;
    background-color: var(--app-surface, var(--fbd-mono-gallery));
}

.card-header {
    padding: 0.75rem 1.25rem;
    margin-bottom: 0;
    color: var(--office-primary-fontcolor, var(--fbd-mono-white)); /* monochromeWhite */
    background-color: var(--office-primary, var(--fbd-blue-vois)); /* blueVois - Header */
    border-bottom: 1px solid var(--app-border-strong, #dee2e6);
    border-top-left-radius: calc(0.375rem - 1px);
    border-top-right-radius: calc(0.375rem - 1px);
}

    .card-header h1,
    .card-header h2,
    .card-header h3,
    .card-header h4,
    .card-header h5,
    .card-header h6 {
        margin: 0;
        color: var(--office-primary-fontcolor, var(--fbd-mono-white)); /* Auto-Schriftfarbe auf gefüllter Primärfläche */
        line-height: 1.2;
    }

    .card-header h1 {
        font-weight: 700;
        font-size: 20px;
        line-height: 24px;
    }

    .card-header h2 {
        font-weight: 600;
        font-size: 18px;
        line-height: 20px;
    }

    .card-header h3 {
        font-weight: 500;
        font-size: 16px;
        line-height: 19px;
    }

    .card-header h4 {
        font-weight: 400;
        font-size: 14px;
        line-height: 17px;
    }

    .card-header h5 {
        font-weight: 500;
        font-size: 14px;
        line-height: 17px;
    }

    .card-header h6 {
        font-weight: 400;
        font-size: 12px;
        line-height: 15px;
    }

.card-body {
    padding: 1.25rem;
}

/* ============================
   Form Controls (Input, Select, Textarea)
   ============================ */
.form-control {
    background-color: var(--app-surface-input, var(--fbd-mono-alabaster)); /* monochromeAlabaster - Hintergrundfarbe Textbox */
    border: 1px solid var(--app-border, var(--fbd-mono-mice)); /* monochromeMice - Rahmenfarbe Textbox */
    color: var(--app-surface-input-text, var(--fbd-mono-nero)); /* monochromeNero */
    padding: 0.5rem 0.75rem;
    border-radius: 0.25rem;
}

    .form-control:focus {
        background-color: var(--app-surface-input-focus, var(--fbd-mono-white));
        border-color: var(--office-primary, var(--fbd-blue-vois)); /* blueVois */
        outline: 0;
        box-shadow: 0 0 0 0.2rem var(--office-primary-focus-ring-subtle, rgba(0, 73, 135, 0.25));
    }

    .form-control:disabled,
    .form-control[readonly] {
        background-color: var(--fbd-mono-porcelain); /* monochromePorcelain */
        border-color: var(--fbd-mono-silverish); /* monochromeSilverish */
        color: var(--fbd-mono-industrial); /* monochromeIndustrial */
    }

/* ============================
   Form Labels
   ============================ */
.form-label,
label {
    color: var(--app-surface-input-text, var(--fbd-mono-nero)); /* monochromeNero */
    font-weight: 500;
    margin-bottom: 0.5rem;
}

.required-field::after {
    content: " *";
    color: var(--fbd-red-venetian); /* Pflichtfeld */
    font-weight: bold;
}

/* ============================
   Validation States
   ============================ */
.is-invalid {
    border-color: var(--fbd-red-venetian); /* redVenetian - Fehler */
    box-shadow: 0 0 0 0.2rem rgba(213, 0, 6, 0.25);
    background-color: var(--fbd-red-palepink); /* redPalepink */
}

.is-valid {
    border-color: var(--fbd-green-moss); /* greenMoss - Success */
    box-shadow: 0 0 0 0.2rem rgba(14, 109, 0, 0.25);
    background-color: var(--fbd-green-mint); /* greenMintflavour */
}

.invalid-feedback {
    display: block;
    color: var(--fbd-red-burgundy); /* redBurgundy - Fehler */
    font-size: 0.875rem;
    margin-top: 0.25rem;
}

.valid-feedback {
    display: block;
    color: var(--fbd-green-moss); /* greenMoss - Success */
    font-size: 0.875rem;
    margin-top: 0.25rem;
}

/* ============================
   Alert / Message Boxes
   ============================ */
.alert {
    padding: 1rem;
    margin-bottom: 1rem;
    border: 1px solid transparent;
    border-radius: 0.25rem;
}

.alert-success {
    background-color: var(--fbd-green-mint); /* greenMintflavour */
    border-color: var(--fbd-green-moss); /* greenMoss - Rahmen Success-Box */
    color: var(--fbd-green-moss);
}

.alert-danger,
.alert-error {
    background-color: var(--fbd-red-palepink); /* redPalepink */
    border-color: var(--fbd-red-burgundy); /* redBurgundy - Rahmen Error-Box */
    color: var(--fbd-red-burgundy);
}

.alert-warning {
    background-color: var(--fbd-yellow-ivorish); /* yellowIvorish */
    border-color: var(--fbd-yellow-selective); /* yellowSelective - Rahmen Warning-Box */
    color: var(--fbd-mono-nero); /* monochromeNero */
}

.alert-info {
    background-color: var(--fbd-blue-alice); /* blueAlice */
    border-color: var(--fbd-blue-vois); /* blueVois */
    color: var(--fbd-blue-vois);
}

/* ============================
   Buttons
   ============================ */
.btn {
    padding: 0.5rem 1.5rem;
    border-radius: 0.25rem;
    font-weight: 500;
    transition: all 0.2s ease-in-out;
}

/* Bootstrap-eigene --bs-btn-*-Variablen der themed Varianten auf die Office-Tokens setzen.
   Bootstrap liest in ALLEN Zuständen (normal/hover/active/focus, inkl. der höher spezifischen
   :active- und :active:focus-visible-Regeln) aus diesen Variablen → kein Spezifitätskampf, kein
   Bootstrap-Blau. Semantik-Buttons (success/danger/warning) bleiben unangetastet. */
.btn-primary, .btn-info {
    --bs-btn-bg: var(--office-primary, var(--fbd-blue-vois));
    --bs-btn-border-color: var(--office-primary, var(--fbd-blue-vois));
    --bs-btn-color: var(--office-primary-fontcolor, var(--fbd-mono-white));
    --bs-btn-hover-bg: var(--office-primary-hover, var(--fbd-blue-science));
    --bs-btn-hover-border-color: var(--office-primary-hover, var(--fbd-blue-science));
    --bs-btn-hover-color: var(--office-primary-fontcolor, var(--fbd-mono-white));
    --bs-btn-active-bg: var(--office-primary-active, var(--fbd-blue-science));
    --bs-btn-active-border-color: var(--office-primary-active, var(--fbd-blue-science));
    --bs-btn-active-color: var(--office-primary-fontcolor, var(--fbd-mono-white));
    --bs-btn-focus-box-shadow: 0 0 0 0.2rem var(--office-primary-focus-ring, rgba(0, 73, 135, 0.5));
    --bs-btn-disabled-bg: var(--fbd-mono-mice); /* monochromeMice */
    --bs-btn-disabled-border-color: var(--fbd-mono-mice);
    --bs-btn-disabled-color: var(--fbd-mono-white);
}

.btn-secondary {
    --bs-btn-bg: var(--office-secondary, #5a6268);
    --bs-btn-border-color: var(--office-secondary, #5a6268);
    --bs-btn-color: var(--office-secondary-fontcolor, var(--fbd-mono-white));
    --bs-btn-hover-bg: var(--office-secondary-hover, #4e555b);
    --bs-btn-hover-border-color: var(--office-secondary-hover, #4e555b);
    --bs-btn-hover-color: var(--office-secondary-fontcolor, var(--fbd-mono-white));
    --bs-btn-active-bg: var(--office-secondary-active, #4e555b);
    --bs-btn-active-border-color: var(--office-secondary-active, #4e555b);
    --bs-btn-active-color: var(--office-secondary-fontcolor, var(--fbd-mono-white));
    --bs-btn-focus-box-shadow: 0 0 0 0.2rem var(--office-secondary-focus-ring, rgba(90, 98, 104, 0.5));
}

.btn-outline-primary {
    --bs-btn-color: var(--office-primary-readable, var(--fbd-blue-vois));
    --bs-btn-border-color: var(--office-primary-readable, var(--fbd-blue-vois));
    --bs-btn-hover-bg: var(--office-primary, var(--fbd-blue-vois));
    --bs-btn-hover-border-color: var(--office-primary, var(--fbd-blue-vois));
    --bs-btn-hover-color: var(--office-primary-fontcolor, var(--fbd-mono-white));
    --bs-btn-active-bg: var(--office-primary-active, var(--fbd-blue-science));
    --bs-btn-active-border-color: var(--office-primary-active, var(--fbd-blue-science));
    --bs-btn-active-color: var(--office-primary-fontcolor, var(--fbd-mono-white));
    --bs-btn-focus-box-shadow: 0 0 0 0.2rem var(--office-primary-focus-ring, rgba(0, 73, 135, 0.5));
}

/* Fokus-Ring auch im gedrückten (Maus-)Zustand: Bootstrap setzt bei :active ohne :focus-visible
   keinen Ring. Spezifität (0,2,0) genügt — Bootstraps :active-Regel setzt nur Farbe, keinen box-shadow;
   der Tastatur-Pfad (:active:focus-visible) liefert weiterhin --bs-btn-focus-box-shadow. */
.btn-primary:active, .btn-info:active, .btn-outline-primary:active {
    box-shadow: 0 0 0 0.2rem var(--office-primary-focus-ring, rgba(0, 73, 135, 0.5));
}

.btn-secondary:active {
    box-shadow: 0 0 0 0.2rem var(--office-secondary-focus-ring, rgba(90, 98, 104, 0.5));
}

.btn-success {
    background-color: var(--fbd-green-moss); /* greenMoss - Success */
    border-color: var(--fbd-green-moss);
    color: var(--fbd-mono-white);
}

    .btn-success:hover {
        background-color: var(--fbd-green-laurel); /* greenJapaneseLaurel */
        border-color: var(--fbd-green-laurel);
        color: var(--fbd-mono-white);
    }

    .btn-success:focus,
    .btn-success:active {
        background-color: var(--fbd-green-laurel);
        border-color: var(--fbd-green-laurel);
        color: var(--fbd-mono-white);
        box-shadow: 0 0 0 0.2rem rgba(14, 109, 0, 0.5);
    }

.btn-danger {
    background-color: var(--fbd-red-burgundy); /* redBurgundy - Fehler */
    border-color: var(--fbd-red-burgundy);
    color: var(--fbd-mono-white);
}

    .btn-danger:hover {
        background-color: var(--fbd-red-carmine); /* redCarmine */
        border-color: var(--fbd-red-carmine);
        color: var(--fbd-mono-white);
    }

    .btn-danger:focus,
    .btn-danger:active {
        background-color: var(--fbd-red-carmine);
        border-color: var(--fbd-red-carmine);
        color: var(--fbd-mono-white);
        box-shadow: 0 0 0 0.2rem rgba(122, 0, 15, 0.5);
    }

.btn-warning {
    background-color: var(--fbd-yellow-selective); /* yellowSelective - Warnung */
    border-color: var(--fbd-yellow-selective);
    color: var(--fbd-mono-nero); /* monochromeNero */
}

    .btn-warning:hover {
        background-color: var(--fbd-yellow-cassonade); /* yellowCassonade */
        border-color: var(--fbd-yellow-cassonade);
        color: var(--fbd-mono-nero);
    }

    .btn-warning:focus,
    .btn-warning:active {
        background-color: var(--fbd-yellow-cassonade);
        border-color: var(--fbd-yellow-cassonade);
        color: var(--fbd-mono-nero);
        box-shadow: 0 0 0 0.2rem rgba(255, 187, 0, 0.5);
    }

/* ============================
   Checkboxes & Radio Buttons
   ============================ */
.form-check-input {
    border: 1px solid var(--app-border, var(--fbd-mono-mice)); /* monochromeMice */
}

    .form-check-input:checked {
        background-color: var(--office-primary, var(--fbd-blue-vois)); /* blueVois */
        border-color: var(--office-primary, var(--fbd-blue-vois));
    }

    .form-check-input:focus {
        border-color: var(--office-primary, var(--fbd-blue-vois));
        box-shadow: 0 0 0 0.2rem var(--office-primary-focus-ring-subtle, rgba(0, 73, 135, 0.25));
    }

.form-check-label {
    color: var(--app-surface-input-text, var(--fbd-mono-nero)); /* monochromeNero */
}

/* ============================
   Select Dropdown
   ============================ */
select.form-control,
.form-select {
    background-color: var(--app-surface-input, var(--fbd-mono-alabaster)); /* monochromeAlabaster */
    border: 1px solid var(--app-border, var(--fbd-mono-mice)); /* monochromeMice */
    color: var(--app-surface-input-text, var(--fbd-mono-nero));
}

    select.form-control:focus,
    .form-select:focus {
        border-color: var(--office-primary, var(--fbd-blue-vois)); /* blueVois */
        box-shadow: 0 0 0 0.2rem var(--office-primary-focus-ring-subtle, rgba(0, 73, 135, 0.25));
    }

/* ============================
   Dividers / Separators
   ============================ */
hr,
.divider {
    border-top: 1px solid var(--app-border, var(--fbd-mono-mice)); /* monochromeMice - Trennlinie */
    margin: 1.5rem 0;
}

/* ============================
   Background Colors
   ============================ */
.bg-light {
    background-color: var(--app-surface-input, var(--fbd-mono-alabaster)); /* monochromeAlabaster */
}

/* ============================
   Text Colors
   ============================ */
.text-primary {
    color: var(--office-primary-readable, var(--fbd-blue-vois)) !important; /* blueVois */
}

.text-success {
    color: var(--fbd-green-moss) !important; /* greenMoss */
}

.text-danger,
.text-error {
    color: var(--fbd-red-burgundy) !important; /* redBurgundy */
}

.text-warning {
    color: var(--fbd-yellow-selective) !important; /* yellowSelective */
}

.text-muted {
    color: var(--app-muted-text, #595959) !important;
}

/* ============================
   Tooltips & Popovers
   ============================ */
.tooltip-inner {
    background-color: var(--fbd-mono-nero); /* monochromeNero */
    color: var(--fbd-mono-white);
}

.popover {
    border-color: var(--app-border, var(--fbd-mono-mice)); /* monochromeMice */
}

/* ============================
   Loading / Disabled States
   ============================ */
.disabled,
[disabled] {
    opacity: 0.65;
    cursor: not-allowed;
}

/* ============================
   Responsive Utilities
   ============================ */
@media (max-width: 768px) {
    .card-body {
        padding: 1rem;
    }

    h1 {
        font-size: 18px;
        line-height: 22px;
    }

    h2 {
        font-size: 16px;
        line-height: 19px;
    }

    h3 {
        font-size: 14px;
        line-height: 17px;
    }

    /* Summary: icon sizing aligned to heading */
    .summary-section h3 .bi {
        font-size: 1em;
        vertical-align: -0.125em;
    }
}

/* Modal Improvements */
.modal-header .modal-title {
    font-weight: 600;
}

.modal-body h6 {
    font-weight: 600;
    margin-top: 1.5rem;
    margin-bottom: 0.5rem;
    color: #495057;
}

.modal-body h6:first-child {
    margin-top: 0;
}

/* Datenschutz-Trigger: ein <button class="btn btn-link"> im Fließtext.
   - font-weight zurück auf den Fließtext-Wert: Die .btn-Regel oben setzt 500 als direkte
     Deklaration und schlägt damit Bootstraps --bs-btn-font-weight: 400 des .btn-link. */
.btn-modal-trigger {
    font-weight: 400;
}

/* Fokusring bewusst als deckender outline statt über --bs-btn-focus-box-shadow: Bootstraps
   Ring ist halbtransparent (~3:1 über Weiß, exakt am Minimum von WCAG 1.4.11) und liegt wegen
   p-0 ohne Abstand am Glyphen. Das `outline: 0` aus .btn wird hier überschrieben, box-shadow
   abgeschaltet, damit nicht zwei Ringe entstehen. Gleicher Indikator wie beim früheren <a>. */
.btn-modal-trigger:focus-visible {
    outline: 2px solid var(--office-primary-readable, var(--fbd-blue-vois));
    outline-offset: 2px;
    box-shadow: none;
}

/* Gethemter Fokusring für Links im Fließtext und im Modal-Body statt UA-Blau */
a:focus-visible {
    outline: 2px solid var(--office-primary-readable, var(--fbd-blue-vois));
    outline-offset: 2px;
}

/* Links im Modal-Body (z.B. Datenschutz-/AGB-HTML aus der DB) themen */
.modal-body a {
    color: var(--office-link, var(--fbd-blue-vois));
}

.modal-body a:hover {
    color: var(--office-link-hover, var(--fbd-blue-prussian));
}

/* Form improvements */
.form-text {
    font-size: 0.875em;
    color: var(--app-muted-text, #595959);
    margin-top: 0.25rem;
}

.col-md-6 .mb-3:last-child {
    margin-bottom: 1rem !important;
}

/* Fieldset and Legend Styling */
fieldset {
/*    border: 1px solid #dee2e6;
    border-radius: 0.375rem;
    padding: 1rem;*/
    margin: 1rem 0;
}

legend {
    float: left;
    width: auto;
    /*padding: 0 0.5rem;*/
    margin-bottom: 0.5rem;
    font-size: 1rem !important;
    line-height: inherit;
}

/* Info Icon Styling */
.bi-info-circle {
    cursor: help;
    font-size: 0.875rem;
}

.bi-info-circle:hover {
    color: var(--office-primary-readable, #0d6efd) !important;
}

/* Required Field Indicator */
.text-danger {
    color: #dc3545 !important;
}

/* Responsive adjustments */
@media (max-width: 767.98px) {
    .btn.me-2 {
        margin-bottom: 0.5rem;
    }
    
    .btn-info {
        width: 100%;
        margin-bottom: 0.5rem;
    }
    
    .btn-info:last-child {
        margin-bottom: 0;
    }
    
    legend {
        font-size: 0.9rem !important;
    }
}

/* Category Search Improvements */
.form-control[list]:focus {
    border-color: var(--office-primary, var(--fbd-blue-vois));
    box-shadow: 0 0 0 0.2rem var(--office-primary-focus-ring-subtle, rgba(0, 73, 135, 0.25));
}

/* Datalist Styling */
datalist {
    display: none;
}

/* Category Selection Styling */
.form-select:focus {
    border-color: var(--office-primary, var(--fbd-blue-vois));
    box-shadow: 0 0 0 0.2rem var(--office-primary-focus-ring-subtle, rgba(0, 73, 135, 0.25));
}

/* Loading Spinner */
.spinner-border {
    width: 3rem;
    height: 3rem;
}

.visually-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
} 

/* Input Group for Currency */
.input-group-text {
    background-color: #e9ecef;
    border-color: #ced4da;
}

/* Section headers with icons */
.card-body h5 {
    color: #495057;
    margin-bottom: 1rem;
    font-weight: 600;
}

/*Validation*/
.valid.modified:not([type=radio]):not([type=checkbox]):not(select) {
    border-color: var(--fbd-green-moss);
    box-shadow: 0 0 0 0.2rem rgba(14, 109, 0, 0.25);
    background-color: var(--fbd-green-mint);
    outline: none;
    padding-right: calc(1.5em + 0.75rem);
    background-image: url('/images/icon-valid.svg');
    background-repeat: no-repeat;
    background-position: right calc(0.375em + 0.1875rem) center;
    background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
}

.invalid:not([type=radio]):not([type=checkbox]):not(select) {
    border-color: var(--fbd-red-venetian);
    box-shadow: 0 0 0 0.2rem rgba(213, 0, 6, 0.25);
    background-color: var(--fbd-red-palepink);
    outline: none;
    padding-right: calc(1.5em + 0.75rem);
    background-image: url('/images/icon-invalid.svg');
    background-repeat: no-repeat;
    background-position: right calc(0.375em + 0.1875rem) center;
    background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
}

.validation-message {
    display: block;
    color: var(--fbd-red-venetian);
    font-size: 0.875rem;
    margin-top: 0.25rem;
}

/* ============================
   Validation - Select: Icon links neben Dropdown-Pfeil
   ============================ */
select.valid.modified,
.form-select.valid.modified {
    border-color: var(--fbd-green-moss);
    box-shadow: 0 0 0 0.2rem rgba(14, 109, 0, 0.25);
    background-color: var(--fbd-green-mint);
    padding-right: 4.125rem;
    background-image: url('/images/icon-dropdown.svg'), url('/images/icon-valid.svg');
    background-repeat: no-repeat, no-repeat;
    background-position: right 0.75rem center, center right 2.25rem;
    background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
}

select.invalid,
.form-select.invalid {
    border-color: var(--fbd-red-venetian);
    box-shadow: 0 0 0 0.2rem rgba(213, 0, 6, 0.25);
    background-color: var(--fbd-red-palepink);
    padding-right: 4.125rem;
    background-image: url('/images/icon-dropdown.svg'), url('/images/icon-invalid.svg');
    background-repeat: no-repeat, no-repeat;
    background-position: right 0.75rem center, center right 2.25rem;
    background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
}

/* ============================================================
   Optionaler Kontrastmodus (BFSG/WCAG 2.2)
   ============================================================
   Aktiv über die Klasse a11y-contrast am <html>-Element. Bei gesetztem Session-Cookie rendert
   der Server sie mit (App.razor); sonst setzt AccessibilityPreferencesService sie per
   JS-Interop (Startwert: prefers-contrast: more). Die Auflagen zum Cookie stehen in
   .claude/rules/barrierefreiheit-und-theming.md.

   Der Block flippt ausschließlich Variablen: die --app-*-Ebene (Flächen/Text) und die
   --office-*-Brandtokens. Einzelne Regeln müssen dafür nicht angefasst werden; nachgezogen
   wird unten nur, was feste Semantik-Hexwerte trägt oder ein Bootstrap-!important hat.

   Spezifität: html.a11y-contrast (0,1,1) schlägt :root (0,1,0) reihenfolgeunabhängig — damit
   überstimmt der Modus auch die per <OfficeThemeStyle> injizierten :root-Overrides
   (OfficeThemeStyle.razor, ohne !important) und die Theme-Vorschau.

   Branding wird bewusst neutralisiert: Markenfarben sind pro Verwaltung frei wählbar und
   könnten den Kontrast sonst wieder brechen.

   forced-colors (Windows-Kontrastdesigns) ist ein EIGENER Mechanismus: Dort ersetzt der BROWSER
   die Autorenfarben, bevor dieser Block etwas ausrichten könnte.

   Gemessen am 2026-09-04 mit aktivem Windows-Kontrastdesign: forced-colors: active = true UND
   prefers-contrast: more = true (custom = false — ein früherer Kommentar behauptete hier das
   Gegenteil). Die beiden Mechanismen treffen also dieselben Nutzer, und für die ist dieser Block
   wirkungslos. Konsequenz an drei Stellen: der Schalter ist dort ausgeblendet
   (AccessibilityToggle.razor.css), der automatische Start entfällt
   (AccessibilityPreferencesService.InitializeAsync), und die Icon-Regeln weiter unten nehmen
   ihre Bilder im Block "Erzwungene Farben" zurück (die Tokens --app-icon-*). Zurückgenommen
   statt vorab weggeschaltet: Eine Weiche, die `forced-colors` nennt, ist in einem Browser ohne
   Unterstützung immer falsch — die Begründung steht an den Icon-Regeln selbst.
   Was der Browser NICHT leistet — Rahmen für verschmelzende Flächen, Fokusring als
   outline statt box-shadow — steht im Block "Erzwungene Farben" am Ende dieser Datei.
   ============================================================ */
html.a11y-contrast {
    /* Flächen/Text: weiß auf schwarz (21:1), Abgrenzung über kräftige Rahmen. */
    --app-page-bg: #000000;
    --app-page-text: #ffffff;
    --app-surface: #000000;
    --app-surface-input: #000000;
    --app-surface-input-focus: #000000;
    --app-surface-input-text: #ffffff;
    --app-border: #ffffff;
    --app-border-strong: #ffffff;
    --app-muted-text: #e6e6e6;

    /* Hamburger-Button der Wizard-Sidebar: heller Rahmen, kein Füllton, helles Icon. Den
       aufgeklappten Zustand markiert hier ein Ring statt des Fülltons (der wäre schwarz auf
       schwarz); sein Token hat bewusst KEINEN :root-Default — im Normalmodus greift dort der
       Fallback transparent und die Darstellung bleibt unverändert. */
    --app-toggler-border: #ffffff;
    --app-toggler-bg: transparent;
    --app-toggler-ring-checked: #ffff00;
    --app-toggler-icon: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23ffffff' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");

    /* Aufliegende Flächen (die Vorschlagslisten von PLZ-/Ort-Autocomplete und Kategoriesuche).
       Diese fünf Tokens sind — anders als die --app-*-Ebene oben — BEWUSST nur hier definiert
       und haben keinen :root-Default: Beide Listen liegen in scoped CSS, das
       html.a11y-contrast nicht als Vorfahren adressieren kann. Sie schreiben deshalb
       var(--app-surface-raised, <ihr heutiger Wert>) — im Normalmodus greift der Fallback und
       die Insel behält ihren Wert (sie sind nicht wertgleich: weiß hier, #fff dort, und die
       Hervorhebung ist zweimal verschieden gerechnet). Ein :root-Default müsste einen der
       beiden Werte zum gemeinsamen machen und würde den Normalmodus verschieben.
       Die Rahmen der Listen bleiben, wie sie sind: #dee2e6 = 14:1 und #919191 = 6,5:1 auf
       Schwarz, beide über den 3:1 aus WCAG 1.4.11. */
    --app-surface-raised: #000000;
    --app-surface-raised-active: #001a26;
    --app-surface-raised-active-ring: #ffff00;
    --app-surface-raised-muted: #e6e6e6;
    --app-surface-raised-danger: #ff9a9a;

    /* Fundsuche (Slice 03). Dieselbe Bauart wie die fünf Tokens darüber: nur hier definiert,
       die Insel schreibt ihren heutigen Wert als var()-Fallback — der Normalmodus bleibt damit
       unberührt.

       --app-row-hover ersetzt in FundsucheResults.razor.css die aus --office-primary gemischte
       Hover-Fläche. Die ist im Modus WEISS beigemischt zu Weiß, der Zeilentext dagegen weiß:
       ~1:1. Gleiche Blaustufe wie --app-surface-raised-active, damit „hier stehe ich" in Liste
       und Vorschlagsliste gleich aussieht.

       --app-badge-* dreht das Badge der Gegenstandsnummer um. Es ist dunkel gefüllt (#222) und
       verschwände auf schwarzem Grund als FLÄCHE — der Text darin wäre lesbar, die
       Hervorhebung aber keine mehr. Invertiert folgt es derselben Regel, die der Block schon
       auf --office-primary anwendet: gefüllte Flächen weiß mit schwarzem Text. */
    --app-row-hover: #001a26;
    --app-badge-bg: #ffffff;
    --app-badge-text: #000000;

    /* Versteigerungen (Slice 04). Wieder die Bauart „Token ohne :root-Default": Der
       Galerie-Dialog (OfflineItemGalleryDialog.razor.css) ist randlos gebaut und soll das im
       Normalmodus bleiben — dort greift der Fallback `transparent`. Im Modus ist der Rahmen
       die EINZIGE Kante des Dialogs: Er ist schwarz auf schwarzer Seite, und ::backdrop mit
       rgba(0, 0, 0, .5) darüber bleibt ebenfalls schwarz. --app-border wäre hier falsch, weil
       sein :root-Default (#919191) im Normalmodus einen sichtbaren Rahmen einführen würde.

       ABGRENZUNG: Das Token trägt die im Normalmodus RANDLOSEN Dialoge — den Galerie-Dialog und
       (seit Slice 05) den Reconnect-Dialog (ReconnectModal.razor.css). Der Fundsuche-Dialog
       (FundItemDetailDialog.razor.css) hat im Normalmodus einen Rahmen und zeichnet ihn weiter
       über --app-border — wer „den Dialograhmen im Kontrastmodus" ändern will, muss beide
       Stellen ansehen. */
    --app-dialog-border: #ffffff;

    /* Logofläche der Wizard-Sidebar (FundanzeigeNavMenu.razor.css). Wieder „Token ohne
       :root-Default": Die Fläche bleibt im Modus BEWUSST weiß, weil hinterlegte Office-Logos für
       weißen Grund gemacht sind — das Token färbt nur den Text darauf. Sichtbar wird er, wenn das
       Logo ausfällt (Pfad gesetzt, Datei fehlt) und der Browser den alt-Text zeigt; der erbte
       sonst das globale Weiß dieses Blocks. Schwarz auf Weiß ist dieselbe Regel, die der Block
       schon auf --office-primary anwendet: gefüllte weiße Fläche, schwarzer Text. */
    --app-logo-surface-text: #000000;

    /* Die drei Icons des Modus — Dropdown-Pfeil und die beiden Validierungszustände. Wieder die
       Bauart „Token ohne :root-Default": Die nutzenden Regeln weiter unten hängen selbst an
       html.a11y-contrast, der Wert löst dort also immer auf; im Normalmodus greift keine der
       Regeln und der Default fehlt niemandem.

       Sie sind Tokens und keine festen url(), damit der Block „Erzwungene Farben" am Ende dieser
       Datei sie an EINER Stelle auf die hellen Varianten zurücknehmen kann — die dortige
       Begründung erklärt, warum das die Umkehrung des früheren Guards ist. */
    --app-icon-dropdown: url('/images/icon-dropdown-contrast.svg');
    --app-icon-valid: url('/images/icon-valid-contrast.svg');
    --app-icon-invalid: url('/images/icon-invalid-contrast.svg');

    /* Der Vorbelegungs-Hinweis (PrefillItemBanner) baut auf Bootstraps Info-Subtle-Palette.
       Die hier zu flippen ist billiger als ein eigenes Token und trifft die Insel über die
       Vererbung — dieselben Werte wie die .alert-info-Regel weiter unten. */
    --bs-info-bg-subtle: #001a26;
    --bs-info-border-subtle: #66ccff;
    --bs-info-text-emphasis: #cfeeff;

    /* Branding neutralisieren: gefüllte Flächen (Kopfleiste, Buttons) weiß mit schwarzem
       Text; Vordergrund-Tint (Links, Outline-Buttons) hellblau; Fokusring gelb. */
    --office-primary: #ffffff;
    --office-primary-hover: #d6d6d6;
    --office-primary-active: #d6d6d6;
    --office-primary-fontcolor: #000000;
    --office-primary-readable: #66ccff;
    --office-primary-focus-ring: #ffff00;
    --office-primary-focus-ring-subtle: #ffff00;
    --office-secondary: #ffffff;
    --office-secondary-hover: #d6d6d6;
    --office-secondary-active: #d6d6d6;
    --office-secondary-fontcolor: #000000;
    --office-secondary-focus-ring: #ffff00;
    --office-secondary-focus-ring-subtle: #ffff00;
    --office-link: #66ccff;
    --office-link-hover: #ffffff;
    --office-placeholder: #cccccc;

    /* Bootstrap 5.3 färbt <a> über --bs-link-color-RGB, nicht über --bs-link-color. Das in
       :root gesetzte --bs-link-color greift für Fließtext-Links daher nicht; sie sind heute
       Bootstrap-Blau (#0d6efd). Das bleibt im Normalmodus so (eine Änderung dort wäre eine
       sichtbare Verschiebung und gehört nicht in diesen Slice) — im Kontrastmodus MUSS der
       Link aber mitflippen, sonst stünde #0d6efd auf Schwarz bei ~3,3:1, also unter AA. */
    --bs-link-color-rgb: 102, 204, 255;
    --bs-link-hover-color-rgb: 255, 255, 255;

    /* Direkt am Element, nicht nur über --bs-body-*: Das <html>-Element selbst trägt sonst
       weiterhin die Standardfarben und blitzt an den Rändern des <body> durch. */
    background-color: #000000;
    color: #ffffff;
}

/* Hinweis-/Statusboxen tragen feste Semantik-Hexwerte (--fbd-green-*, --fbd-red-* …), die auf
   Schwarz zu dunkel wären. Deshalb hier eigene Werte: dunkel getönter Grund, heller farbiger
   Rahmen, heller Text — die Farbe bleibt als Bedeutungsträger erkennbar. */
html.a11y-contrast .alert-info {
    background-color: #001a26;
    border-color: #66ccff;
    color: #cfeeff;
}

html.a11y-contrast .alert-success {
    background-color: #04210a;
    border-color: #8fe98f;
    color: #d4f5d4;
}

html.a11y-contrast .alert-warning {
    background-color: #261d00;
    border-color: #ffd24d;
    color: #ffe9a8;
}

html.a11y-contrast .alert-danger,
html.a11y-contrast .alert-error {
    background-color: #260606;
    border-color: #ff9a9a;
    color: #ffd0d0;
}

/* Bootstraps .bg-light-Utility trägt !important und bliebe sonst hell, während der Text auf
   weiß flippt (weiß auf fast weiß). Hier mit !important nachziehen. */
html.a11y-contrast .bg-light {
    background-color: #000000 !important;
    color: #ffffff;
}

/* Modal-Grundfläche: Bootstrap zieht sie aus eigenen --bs-modal-*-Variablen, die die
   --app-*-Ebene nicht kennen. Sonst bliebe der Dialog eine helle Insel mit hellem Text. */
html.a11y-contrast .modal {
    --bs-modal-bg: #000000;
    --bs-modal-color: #ffffff;
    --bs-modal-border-color: #ffffff;
    --bs-modal-header-border-color: #ffffff;
    --bs-modal-footer-border-color: #ffffff;
}

html.a11y-contrast .modal-body h6 {
    color: #ffffff; /* fester Grauwert #495057 wäre auf Schwarz unlesbar */
}

/* Das Schließen-Kreuz ist ein dunkles Hintergrund-SVG und verschwände auf schwarzem Grund. */
html.a11y-contrast .btn-close {
    filter: invert(1) grayscale(100%) brightness(200%);
}

/* ------------------------------------------------------------
   Fokusindikatoren im Kontrastmodus: doppelter Ring
   ------------------------------------------------------------
   Der Modus neutralisiert das Branding auf WEISS (--office-primary: #ffffff), während der
   Seitengrund schwarz ist. Ein einfarbiger Ring kann nicht gegen beide Flächen die 3:1 aus
   WCAG 1.4.11 halten: Gelb (#ffff00) erreicht auf Weiß nur 1,07:1, das hellblaue
   --office-primary-readable (#66ccff) nur 1,80:1 — gemessen am Zurück-Link in der Kopfleiste.

   Lösung ohne Palettenänderung: zwei Ringe, schwarz innen und gelb außen. Auf weißer Fläche
   trägt der schwarze (21:1), auf schwarzer der gelbe (19,6:1), und zueinander stehen sie bei
   19,6:1 — es ist also immer ein Ring sichtbar. Das ist dasselbe Prinzip, das der
   Kontrast-Toggle mit currentColor verfolgt (AccessibilityToggle.razor.css), hier nur
   flächenunabhängig statt vererbt.
   ------------------------------------------------------------ */
html.a11y-contrast a:focus-visible,
html.a11y-contrast .btn-modal-trigger:focus-visible {
    outline: 2px solid #ffff00;
    outline-offset: 2px;
    box-shadow: 0 0 0 2px #000000;
}

/* Bootstraps Button-Ring kommt aus --bs-btn-focus-box-shadow. Die Variable ist in .btn-primary
   (0,1,0) AM ELEMENT deklariert und lässt sich von html.a11y-contrast (0,1,1) am <html> nicht
   überschreiben — der Override braucht deshalb den Nachfahren-Selektor (0,2,1). */
html.a11y-contrast .btn-primary,
html.a11y-contrast .btn-info,
html.a11y-contrast .btn-outline-primary {
    --bs-btn-focus-box-shadow: 0 0 0 2px #000000, 0 0 0 5px #ffff00;
}

html.a11y-contrast .btn-secondary {
    --bs-btn-focus-box-shadow: 0 0 0 2px #000000, 0 0 0 5px #ffff00;
}

/* Dieselben zwei Ringe im gedrückten (Maus-)Zustand, den die :active-Regeln oben direkt als
   box-shadow setzen — sonst fiele dort auf Weiß wieder ein einzelner gelber Ring an. */
html.a11y-contrast .btn-primary:active,
html.a11y-contrast .btn-info:active,
html.a11y-contrast .btn-outline-primary:active,
html.a11y-contrast .btn-secondary:active {
    box-shadow: 0 0 0 2px #000000, 0 0 0 5px #ffff00;
}

/* Abschnittsüberschriften in Cards tragen den festen Grauwert #495057 (siehe .card-body h5) und
   stehen auf der hier schwarzen Card bei 2,57:1 — Zwilling zur .modal-body h6-Regel oben. */
html.a11y-contrast .card-body h5 {
    color: #ffffff;
}

/* ------------------------------------------------------------
   Formularflächen (Slice 02)
   ------------------------------------------------------------
   Stellen, die die Token-Ebene nicht erreicht, weil sie eine feste Semantik-Farbe tragen oder
   ihre Fläche aus einem Brandtoken beziehen, der hier auf WEISS gedreht wird. Gemessen am
   2026-09-04 im Kontrastmodus (Chromium), Werte im jeweiligen Kommentar.
   ------------------------------------------------------------ */

/* Das Pflichtfeld-Sternchen trägt --fbd-red-venetian (#D50006): 3,83:1 auf Schwarz, unter der
   Textschwelle. Gleiche helle Rotstufe wie .validation-message weiter unten. */
html.a11y-contrast .required-field::after {
    color: #ff9a9a;
}

/* Der angehakte Zustand bezieht seine Fläche aus --office-primary, hier also WEISS — und
   Bootstraps Häkchen-SVG ist stroke='%23fff': weiß auf weiß, der Zustand war unsichtbar (1:1).
   Umgekehrt gelöst statt mit einem zweiten Icon: schwarze Fläche, weißer Rahmen, das
   vorhandene weiße Häkchen steht darauf bei 21:1. Gilt genauso für den Radio-Punkt. */
html.a11y-contrast .form-check-input:checked {
    background-color: #000000;
    border-color: #ffffff;
}

/* Das Symbolfeld einer Eingabegruppe (€ am Wertfeld) behielt #e9ecef und erbte die weiße
   Schrift: 1,19:1 gemessen. */
html.a11y-contrast .input-group-text {
    background-color: #000000;
    border-color: #ffffff;
    color: #ffffff;
}

/* Gesperrte Felder blieben hell und wirkten auf der schwarzen Card AUFFÄLLIGER als ein
   bedienbares Feld — die Ausgrauung kehrte sich um. Betrifft BEIDE Feldarten, und aus
   verschiedenen Gründen: .form-control:disabled kam auf #F0F0F0, .form-select:disabled dagegen
   auf Bootstraps #e9ecef aus --bs-secondary-bg — ein Token, das der Kontrastblock bewusst nicht
   flippt (es hängt an zu vielen Stellen), weshalb hier die Regel selbst greifen muss. Dort war
   es weiß auf #e9ecef, 1,19:1. [readonly] gibt es nur an <input>, nicht an <select>.

   Grauer statt weißer Rahmen hält den Unterschied zu „aktiv" aufrecht. Gemessen im
   Kontrastmodus, für beide Feldarten gleich: Text 10,02:1, Rahmen 6,66:1 — letzterer über den
   3:1 für grafische Elemente (WCAG 1.4.11); WCAG 1.4.3/1.4.11 nehmen inaktive Bedienelemente
   ohnehin von der Schwelle aus.

   Die opacity aus .disabled,[disabled] weiter oben wirkt hier NICHT, obwohl beide Selektoren
   passen: Bootstrap setzt .form-control:disabled{opacity:1} (0,2,0) und select:disabled{opacity:1}
   (0,1,1), beide schlagen [disabled] (0,1,0). Die Werte oben sind also die vollen Farben, nicht
   abgeblendete. Nachgemessen am 2026-09-07, weil hier vorher „~4,2:1" stand — eine Zahl, die
   eine wirksame Abblendung unterstellte, die es nie gab. Beide Feldarten sind in
   AccessibilityContrastTests eigene Messpunkte, und die Messung rechnet eine opacity mit, wo
   eine gilt (deckkraftVon dort). */
html.a11y-contrast .form-control:disabled,
html.a11y-contrast .form-control[readonly],
html.a11y-contrast .form-select:disabled {
    background-color: #000000;
    border-color: #919191;
    color: #b3b3b3;
}

/* Das Erfolgs-Icon der Absende-Bestätigung (SubmitSuccessCard) trägt --fbd-green-moss und
   verschwindet auf Schwarz (1,98:1). Es ist aria-hidden, also formal ausgenommen — aber ein
   4rem-Symbol, das praktisch nicht da ist. Gleiche Grünstufe wie der .alert-success-Rahmen.
   !important, weil die Ursprungsregel es ebenfalls trägt (Bootstrap-Utility-Konvention). */
html.a11y-contrast .text-success {
    color: #8fe98f !important;
}

/* Browsereigene Feldfarben, die Feldhintergründe unabhängig von den Tokens überschreiben.
   Beide Regeln setzen Grund UND Schrift, sind also in sich vollständig — deshalb können sie
   nicht halb greifen. Welche ein Browser tatsächlich respektiert, ist verschieden (Chromium und
   Firefox vererben die Select-Farben auf Windows ans Popup, andere Kombinationen nicht); wo
   eine ignoriert wird, bleibt es beim Verhalten ohne sie. */
html.a11y-contrast option {
    background-color: #000000;
    color: #ffffff;
}

html.a11y-contrast ::selection {
    background-color: #ffff00;
    color: #000000;
}

/* ------------------------------------------------------------
   Autofill: hier steht bewusst KEINE Regel
   ------------------------------------------------------------
   Automatisch ausgefüllte Felder behalten im Kontrastmodus die helle Hervorhebung ihres
   Browsers. Das ist ein optischer Bruch, aber lesbar — und der Versuch, es zu ändern, war
   messbar schlechter.

   Die UA-Styles sind ein PAAR: heller Grund und dunkle Schrift, beide !important. Man kann es
   vollständig ersetzen oder muss es vollständig in Ruhe lassen. In Chromium geht das Ersetzen
   (box-shadow … inset für den Grund, -webkit-text-fill-color für die Schrift). In Firefox ist
   der Grund NICHT erreichbar: Die Hervorhebung läuft über ein internes Pseudo-Element
   (Bugzilla 1355438), und Bugzilla 740979 ("implement :-moz-autofill") steht seit 14 Jahren auf
   NEW. Ein solcher Block trifft dort also nur die Schrift und bricht das Paar — am 2026-09-04 in
   Firefox gemessen: weiß auf hellgelb, 1,07:1, also schlechter als ohne die Regel.

   ACHTUNG, das war die Falle: Firefox aliast -webkit-Präfixe. ":-webkit-autofill" wird dort als
   ":autofill" geparst und angewendet, "-webkit-text-fill-color" ist unterstützt. Ein
   -webkit-Selektor trifft also NICHT nur Blink/WebKit.

   Eine Weiche nur für Chromium ist verworfen: Es gibt keine Feature-Query für "der box-shadow
   schlägt den Autofill-Grund", übrig bleiben Engine-Sniffs — und die sind gerade wegen des
   Aliasings unzuverlässig. Ein Sniff, der still veraltet, hinterlässt hier ein unlesbares Feld.
   Ebenfalls verworfen: autocomplete="off" an den Feldern (beseitigt die Hervorhebung, indem es
   Autofill abschafft — gegen WCAG 1.3.5 und gegen genau die Zielgruppe dieses Modus).

   Geprüft: Am 2026-09-09 hat der Entwickler Firefox, Edge und Chrome im Kontrastmodus angesehen —
   Autofill ist in allen drei lesbar, auch das Blau auf hellerem Blau in Edge, das den Zweifel
   ausgelöst hatte; Firefox am 2026-09-11 noch einmal nachgesehen, unauffällig. Damit bleibt es
   beim Verzicht auf eine Regel; er ist nicht länger nur die vorsichtige Wahl, sondern geprüft.

   Ändert ein Browser künftig seine Autofill-Farben, steht unter
   docs/features/contrast-mode/messrunde-autofill.md ein Protokoll mit Messpunkten, Snippet und
   Entscheidungsraster. Playwright kann Autofill nicht auslösen (hängt am Browserprofil), der
   Nachweis bleibt in jedem Fall Handarbeit.
   ------------------------------------------------------------ */

/* Der Fehlertext trägt --fbd-red-venetian (#D50006) und erreicht auf Schwarz nur 3,83:1, also
   unter der Textschwelle 4,5:1. Gleiche helle Rotstufe wie der Rahmen der .alert-danger-Box —
   Rot bleibt damit Bedeutungsträger. */
html.a11y-contrast .validation-message {
    color: #ff9a9a;
}

/* ------------------------------------------------------------
   Validierungszustände im Kontrastmodus
   ------------------------------------------------------------
   Die Selektoren oben setzen helle Pastellflächen (--fbd-red-palepink #FFF0F0,
   --fbd-green-mint #F5FAE8), während dieser Modus den Feldtext über
   --app-surface-input-text auf Weiß stellt: weiß auf fast weiß, gemessen 1,06–1,11:1. Deshalb
   hier dieselbe Bauart wie bei den Hinweisboxen — dunkel getönter Grund, heller farbiger
   Rahmen, heller Text. Die Zustandsfarbe (rot/grün) bleibt erkennbar, ist aber wie im
   Normalmodus nicht der einzige Träger: Rahmen, Icon und Fehlertext kommen dazu.

   Die Status-Icons werden gegen helle Varianten getauscht statt gefiltert: filter auf dem
   <input> würde Text und Rahmen mitfärben. Die übrigen Bild-Eigenschaften (Position, Größe,
   padding-right) bleiben unberührt und werden hier bewusst nicht wiederholt.
   ------------------------------------------------------------ */
html.a11y-contrast .invalid:not([type=radio]):not([type=checkbox]):not(select),
html.a11y-contrast select.invalid,
html.a11y-contrast .form-select.invalid {
    background-color: #260606;
    border-color: #ff9a9a;
    box-shadow: 0 0 0 0.2rem rgba(255, 154, 154, 0.35);
}

html.a11y-contrast .valid.modified:not([type=radio]):not([type=checkbox]):not(select),
html.a11y-contrast select.valid.modified,
html.a11y-contrast .form-select.valid.modified {
    background-color: #04210a;
    border-color: #8fe98f;
    box-shadow: 0 0 0 0.2rem rgba(143, 233, 143, 0.35);
}

/* Die Icon-Regeln — die EINZIGEN Regeln des Kontrastmodus, die nicht bloß Farben setzen, und
   deshalb die einzigen, die unter erzwungenen Farben etwas zurücknehmen müssen. Betroffen sind
   die Validierungs-Icons und (seit Slice 02) der Dropdown-Pfeil.

   forced-colors erzwingt Farbeigenschaften, lässt background-image aber unangetastet. Die
   Icon-Varianten hier sind für schwarzen Grund gezeichnet; auf einem HELLEN Kontrastdesign
   (Windows-Variante "Weiß") wären sie unsichtbar. Der Modus würde die Barrierefreiheit dort also
   verschlechtern — die dunklen Icons müssen dort wieder gewinnen.

   DESHALB DIE UMKEHRUNG und kein Guard davor: Eine Media Query, die das Feature `forced-colors`
   überhaupt nennt, ist in einem Browser, der es nicht kennt, als GANZES ungültig — der
   unbekannte Feature-Name wertet zu `unknown`, und die Query ist damit immer falsch. Auch eine
   verneinte Weiche (`@media not (...)`) hilft nicht, sie ist dort genauso falsch. Bis 2026-09-08
   standen die Regeln hier in einer solchen Weiche und waren in genau diesen Browsern
   stillgelegt: Wer den Kontrastmodus dort einschaltete, bekam dunkle Icons auf schwarzem Feld
   (~1,5:1). Dieselbe Falle beschreibt app.js für die JS-Abfrage und vermeidet sie dort mit zwei
   getrennten Funktionen.

   Robust ist nur: hier UNBEDINGT setzen und im Block "Erzwungene Farben" am Ende der Datei
   zurücknehmen. Dieser Block greift bei Nichtunterstützung einfach nie, und dann bleibt genau
   das richtige Ergebnis übrig — dasselbe Muster wie bei .btn-close. Ein Wächter hält das fest:
   FBD.Portal.Tests/Architecture/ForcedColorsGuardTests.

   AUSDRÜCKLICH NICHT stattdessen background-image: none. Unter erzwungenen Farben fällt die
   farbliche Anzeige von gültig/ungültig weg; das Icon ist dort der letzte verbleibende Hinweis
   und muss bleiben, nur in der dunklen Variante.

   Erreichbar ist der erzwungene Fall ohnehin nur, wenn jemand das Kontrastdesign MITTEN in der
   Sitzung einschaltet, nachdem er den Schalter geklickt hat — danach ist der Schalter weg
   (AccessibilityToggle.razor.css) und der automatische Start aus. */

/* Der Dropdown-Pfeil ist bei Bootstrap stroke='%23343a40', im eigenen icon-dropdown.svg
   #222222 — auf dem hier schwarzen Feld ~1,5:1, das Feld war nicht mehr als Auswahl
   erkennbar. Betrifft ALLE Selects, nicht nur validierte, daher die eigene Grundregel.
   Nur .form-select und nicht auch select.form-control: Letzteres kommt im Markup nicht vor
   (geprüft) und trägt heute gar kein Hintergrundbild — ein background-image ohne die
   zugehörigen background-repeat/-position/-size würde dort kacheln. Die übrigen
   Bild-Eigenschaften bleiben unberührt und werden bewusst nicht wiederholt. */
html.a11y-contrast .form-select {
    background-image: var(--app-icon-dropdown);
}

html.a11y-contrast .invalid:not([type=radio]):not([type=checkbox]):not(select) {
    background-image: var(--app-icon-invalid);
}

html.a11y-contrast select.invalid,
html.a11y-contrast .form-select.invalid {
    background-image: var(--app-icon-dropdown), var(--app-icon-invalid);
}

html.a11y-contrast .valid.modified:not([type=radio]):not([type=checkbox]):not(select) {
    background-image: var(--app-icon-valid);
}

html.a11y-contrast select.valid.modified,
html.a11y-contrast .form-select.valid.modified {
    background-image: var(--app-icon-dropdown), var(--app-icon-valid);
}

/* Der Kontrast-Toggle selbst braucht hier bewusst KEINE Regel: Er zeichnet Rahmen, Text und
   Fokusring durchgehend in currentColor (siehe AccessibilityToggle.razor.css) und erbt seine
   Farbe damit automatisch von der Fläche, auf der er sitzt — Kopfleiste oder Seitengrund, im
   Normal- wie im Kontrastmodus. Ein globaler Override wäre nötig, wenn er gefüllte Zustände
   hätte (die scoped CSS-Isolation kennt kein :global() für Vorfahren wie html.a11y-contrast) —
   genau deshalb hat er keine. */

/* ------------------------------------------------------------
   Fundsuche und Startseite (Slice 03)
   ------------------------------------------------------------
   Drei Stellen, die die --app-*-Ebene nicht erreicht, weil ihre Farben aus
   BOOTSTRAP-KOMPONENTENVARIABLEN kommen. Die sind am Element deklariert (.table, .pagination,
   .btn-outline-secondary = 0,1,0) und lassen sich von html.a11y-contrast (0,1,1) am <html>
   nicht überschreiben; der Override braucht deshalb den Nachfahren-Selektor (0,2,0) — gleiche
   Begründung wie bei .modal und .btn-primary weiter oben.

   Bewusst NICHT über --bs-emphasis-color bzw. --bs-secondary-bg gelöst, obwohl das kürzer
   wäre: Beide hängen an zu vielen Stellen, um sie global zu drehen (für --bs-secondary-bg ist
   das oben bei .form-select:disabled schon einmal entschieden worden).
   ------------------------------------------------------------ */

/* Die Trefferliste der Fundsuche war SCHWARZ AUF SCHWARZ. Bootstrap setzt
   --bs-table-color: var(--bs-emphasis-color), und das ist im Light-Theme #000; der Zellentext
   stand damit auf dem hier schwarzen --bs-table-bg (das über --bs-body-bg korrekt mitflippt).
   Der bestehende axe-Fall lief nur im Normalmodus und konnte es nicht sehen. */
html.a11y-contrast .table {
    --bs-table-color: #ffffff;
}

/* Blätterleiste: drei der --bs-pagination-*-Flächen sind feste helle Werte oder hängen an
   Tokens, die dieser Block nicht dreht — sie blieben helle Inseln auf schwarzem Grund.
   Gemessen im Bestand: aktive Seite #fff auf #0d6efd = 3,68:1 (unter der Textschwelle),
   deaktivierter Pfeil auf --bs-secondary-bg #e9ecef und Hover auf --bs-tertiary-bg #f8f9fa.

   Die aktive Seite wird zur weißen Fläche mit schwarzer Schrift (21:1) — dieselbe Umkehrung,
   die der Block für --office-primary vornimmt. Der deaktivierte Pfeil bekommt einen dunkleren
   Grauton als „bedienbar", damit „nicht bedienbar" nicht auffälliger wirkt.

   Der Textwert ist #e6e6e6 und NICHT das #b3b3b3 der gesperrten Felder: Auf .disabled greift
   die opacity: .65 aus dieser Datei, und zwar hier WIRKLICH — bei den Feldern setzt Bootstrap
   spezifischer opacity: 1 dagegen, an der Blätterleiste gibt es das nicht. #b3b3b3 kommt damit
   wirksam als rgb(116, 116, 116) heraus und wurde mit 4,49:1 gemessen, also knapp unter der
   Textschwelle. #e6e6e6 ergibt wirksam rgb(150, 150, 150) und 7,08:1 — Abstand statt
   Punktlandung, und gegenüber dem weißen Seitentext bleibt der Pfeil sichtbar abgesetzt.
   (WCAG 1.4.3 nimmt inaktive Bedienelemente formal aus; hier wird trotzdem gemessen, weil ein
   Blätter-Pfeil je nach Seite aktiv oder inaktiv ist und beides lesbar sein soll.)

   --bs-pagination-color und -bg brauchen keinen Eintrag: die erste hängt über :root an
   --office-link (#66ccff, 8,4:1), die zweite an --bs-body-bg. */
html.a11y-contrast .pagination {
    --bs-pagination-border-color: #ffffff;
    --bs-pagination-hover-bg: #000000;
    --bs-pagination-hover-color: #ffffff;
    --bs-pagination-focus-bg: #000000;
    --bs-pagination-focus-color: #ffffff;
    --bs-pagination-active-bg: #ffffff;
    --bs-pagination-active-color: #000000;
    --bs-pagination-active-border-color: #ffffff;
    --bs-pagination-disabled-bg: #000000;
    --bs-pagination-disabled-color: #e6e6e6;
    --bs-pagination-disabled-border-color: #919191;
    /* Doppelter Ring wie bei den Buttons: der Ring muss gegen den schwarzen Seitengrund UND
       gegen die weiße Fläche der aktiven Seite tragen. Bootstraps Standardring
       rgba(13, 110, 253, .25) verschwindet auf Schwarz. */
    --bs-pagination-focus-box-shadow: 0 0 0 2px #000000, 0 0 0 5px #ffff00;
}

/* .btn-outline-secondary war nirgends gethemt und behielt Bootstraps #6c757d: auf Schwarz
   3,94:1, unter der Textschwelle. Betrifft die Vor/Zurück-Buttons des Fundsuche-Dialogs, den
   „Zusatzangaben ausblenden"-Button im Verlust-Wizard (eine offene Stelle aus Slice 02) und den
   Drucken-Button in VersteigerungenVorOrtDetail.razor. Aufbau wie .btn-outline-primary oben, nur
   mit den festen Werten dieses Blocks statt der Office-Tokens (das Branding ist hier
   neutralisiert).

   Die Grenze dieser Regel: #66ccff ist gegen den schwarzen Seitengrund gerechnet (11,65:1). Auf
   einer im Modus WEISSEN Fläche wären es 1,80:1 — dort trägt der Wert nicht. Alle drei Stellen
   stehen auf Schwarz; eine vierte auf heller Fläche bräuchte einen eigenen Block.

   --bs-btn-disabled-color ist wie bei der Blätterleiste #e6e6e6 und nicht das #b3b3b3 der
   gesperrten Felder: Bootstrap blendet gesperrte Buttons über
   --bs-btn-disabled-opacity: .65 ab, #b3b3b3 käme also wirksam bei 4,49:1 heraus. */
html.a11y-contrast .btn-outline-secondary {
    --bs-btn-color: #66ccff;
    --bs-btn-border-color: #66ccff;
    --bs-btn-hover-bg: #ffffff;
    --bs-btn-hover-border-color: #ffffff;
    --bs-btn-hover-color: #000000;
    --bs-btn-active-bg: #d6d6d6;
    --bs-btn-active-border-color: #d6d6d6;
    --bs-btn-active-color: #000000;
    --bs-btn-disabled-color: #e6e6e6;
    --bs-btn-disabled-border-color: #919191;
    --bs-btn-focus-box-shadow: 0 0 0 2px #000000, 0 0 0 5px #ffff00;
}

/* Der Body-Text der Startseite (Portal.razor) ist HTML aus der Datenbank, das jede Verwaltung
   selbst pflegt. Der Sanitizer läuft mit den Ganss-Standardlisten (Program.cs) — dort ist nur
   die Schema-Liste eingeschränkt (http/https/mailto), nicht die Liste erlaubter
   CSS-Eigenschaften. Das style-Attribut kommt also samt color, background-color UND
   background-image durch, und ein Inline-Style schlägt jede normale Regel. Ohne !important
   könnte der Modus auf dieser Seite nicht halten, was der Schalter verspricht.

   Deshalb wird der Hintergrund vollständig neutralisiert, Farbe und Bild: background-color
   allein würde bei einem hinterlegten <div style="background-image:url(/uploads/hell.png)">
   nur den Farbanteil wegräumen und das helle Bild unter dem auf #ffffff gezwungenen Text
   stehen lassen (same-origin und damit von img-src 'self' data: gedeckt). Kein Anspruch auf
   Vollständigkeit über diese beiden Eigenschaften hinaus — sie sind die, die unter Text
   liegen.

   Der Preis ist benannt: bewusste Farbakzente im Verwaltungstext sind im Kontrastmodus weg.
   Das ist die Absicht des Modus (er neutralisiert auch das Branding). Die Ursache — die
   erlaubten CSS-Eigenschaften im Sanitizer — bleibt unangetastet, weil eine Änderung dort den
   NORMALmodus für alle Offices verschieben würde und nicht in einen CSS-Slice gehört. */
html.a11y-contrast .portal-home-text,
html.a11y-contrast .portal-home-text * {
    color: var(--app-page-text) !important;
    background-color: transparent !important;
    background-image: none !important;
}

/* ------------------------------------------------------------
   Druck im Kontrastmodus (Slice 04)
   ------------------------------------------------------------
   Die Vor-Ort-Detailseite (VersteigerungenVorOrtDetail.razor) trägt den einzigen
   Drucken-Button der Anwendung. Ohne diesen Block druckt sie im Kontrastmodus WEISSE SCHRIFT:
   Die Farben oben gelten auch im Druck, und Hintergründe lässt der Druckdialog
   standardmäßig weg (Chrome/Edge: „Hintergrundgrafiken" ist aus). Bootstrap 5 hat dagegen
   nichts — sein einziger @media-print-Block enthält nur die .d-print-*-Klassen; die
   Farbrücknahme aus Bootstrap 4 (`* { color: #000 !important }`) ist dort entfallen.

   Auf Papier ist der Modus gegenstandslos — es gibt keine hinterleuchtete Fläche, deren
   Kontrast er erhöhen könnte. Deshalb wird er im Druck vollständig zurückgedreht statt
   nachgebaut.

   Warum grob über den Nachfahren-Selektor und nicht token-fein: Ein Zurücksetzen der
   --app-*- und --office-*-Tokens auf die :root-Werte ist von hier aus nicht möglich. Eine
   Deklaration auf html.a11y-contrast VERDECKT die aus :root, und `initial` macht die
   Custom Property ungültig — die Inseln würden dann in ihre var()-Fallbacks laufen und nicht
   in die Normalwerte. Die Tokens noch einmal wörtlich aufzulisten wäre eine zweite Kopie der
   Palette, die beim nächsten Farbwechsel auseinanderläuft.

   Der Block greift ausschließlich unter html.a11y-contrast — der Druck im Normalmodus bleibt
   unberührt. Benannter Preis: Im Kontrastmodus-Druck fallen auch die Office-Farben weg
   (Logo-Flächen, farbige Hinweisboxen). Nicht per E2E prüfbar (Playwright kann die
   Druckvorschau nicht messen) — Handprüfung.
   ------------------------------------------------------------ */
@media print {
    html.a11y-contrast,
    html.a11y-contrast body,
    html.a11y-contrast * {
        background-color: #ffffff !important;
        color: #000000 !important;
        border-color: #000000 !important;
    }
}

/* ------------------------------------------------------------
   Erzwungene Farben (forced-colors, Slice 05)
   ------------------------------------------------------------
   Ein aktives Windows-Kontrastdesign ersetzt die Autorenfarben; der App-Kontrastmodus ist dort
   wirkungslos und deshalb abgeschaltet (siehe die Weiche im Kopfkommentar oben). Was der Browser
   NICHT ersetzt, ist Struktur — und genau die geht an drei Stellen verloren. Dieser Block setzt
   deshalb ausschließlich Kanten und Fokus-Technik und KEINE einzige Farbe: Jedes eigene `color`
   oder `background-color` wäre hier wirkungslos oder schädlich. Die zwei Systemfarb-Schlüsselwörter
   (Highlight, CanvasText) sind keine Ausnahme davon — sie sind die vom erzwungenen Schema
   gelieferten Werte, kein eigener Ton.

   GEMESSEN am 2026-09-08 unter Chromium mit ForcedColors.Active (Protokoll im Slice-Dokument),
   nicht aus der Spezifikation abgeleitet. Drei Ergebnisse tragen die Regeln unten:

   1. `box-shadow` wird verworfen — an JEDEM gemessenen Element, auch im :focus-visible-Zustand.
      Bootstraps Fokusring hängt vollständig daran (--bs-btn-focus-box-shadow, .form-control:focus)
      und ist damit weg; `.btn:focus-visible` meldete `outline: 3px NONE`, also gar keinen
      Indikator (Bootstrap setzt dort `outline: 0`). Das ist ein Verstoß gegen WCAG 2.4.11 und der
      Hauptbefund dieses Slices.
   2. Verschmelzende Flächen sind die AUSNAHME, nicht die Regel: Bootstrap deklariert an .btn,
      .card, .alert, .page-link, .form-control und .modal-content einen 1px-Rahmen (oft
      `transparent`), und der erzwungene Modus färbt auch einen transparenten RAHMEN sichtbar ein
      — transparente HINTERGRÜNDE bleiben dagegen transparent. Für all diese Flächen ist hier
      also nichts zu tun; die Liste der Spec ist an dieser Stelle überholt. Übrig bleiben die
      Stellen mit Rahmenbreite NULL: die Fehlerleiste hier, der Reconnect-Dialog SAMT SEINEM
      KNOPF „Erneut versuchen" (ReconnectModal.razor.css — der Dialog trägt die Kante gegen den
      Seitengrund, der Knopf eine eigene: seine Füllung wird zu ButtonFace und fällt dort mit
      Canvas zusammen) und die farbige Kopfleiste (PortalHeader.razor.css). Dieselbe Lücke hat
      die 429-Seite, die kein Stylesheet lädt — sie führt ihren eigenen forced-colors-Block mit
      (RateLimitResponse.cs).
   3. Der Zustand „hier stehe ich" wird nur durch Füllung markiert (.nav-link.active im
      Wizard-Schrittmenü, die aktive Seite der Blätterleiste) und verschwindet mit ihr. Beide
      tragen `aria-current` — für Screenreader bleibt der Zustand also erhalten, sichtbar wird er
      hier über ein outline wieder hergestellt.
   ------------------------------------------------------------ */
@media (forced-colors: active) {
    /* Fokusring als outline, weil box-shadow verworfen wird (Befund 1). `Highlight` ist die
       Auswahlfarbe des erzwungenen Schemas — der einzige Weg, einen Ring zu zeichnen, der sich
       vom Text- und Rahmenton unterscheidet. Die Breite steht auf 3px, weil Chromium im
       erzwungenen Modus ohnehin auf 3px hochgeht (gemessen an .btn-modal-trigger, das 2px
       deklariert) — dann steht hier lieber der Wert, der wirkt.

       a und .btn-modal-trigger brauchen keinen Eintrag: Sie zeichnen ihren Ring schon im
       Normalbetrieb als outline (weiter oben in dieser Datei) und behalten ihn deshalb. */
    .btn:focus-visible,
    .form-control:focus-visible,
    .form-select:focus-visible,
    .form-check-input:focus-visible,
    .page-link:focus-visible {
        outline: 3px solid Highlight;
        outline-offset: 2px;
    }

    /* Der aktive Zustand ohne Füllung (Befund 3). Angesetzt an aria-current und nicht an
       .active/.page-item.active: Das Attribut ist die Zusicherung, die im Markup ohnehin steht
       (FundanzeigeNavMenu.razor: "step", FundPaginationComponent.razor: "page") — damit können
       sichtbarer und vorgelesener Zustand nicht auseinanderlaufen. Negativer outline-offset, damit
       der Ring INNEN liegt und die Zeile nicht verrückt. */
    .nav-link[aria-current],
    .page-link[aria-current] {
        outline: 2px solid CanvasText;
        outline-offset: -2px;
    }

    /* Die Fehlerleiste (alle drei Layouts) hat Rahmenbreite null und trennt sich sonst nur über
       lightyellow und einen box-shadow vom Seiteninhalt — beides ist hier weg. Sie ist die letzte
       Meldung, die ein Nutzer bei sterbendem Circuit sieht; ohne Kante steht sie unvermittelt im
       Text. Die scoped Regeln der Layouts deklarieren keinen border-top, es gibt also keinen
       Spezifitätskampf. */
    #blazor-error-ui {
        border-top: 2px solid CanvasText;
    }

    /* Das invert(1) aus Slice 03 wird zurückgenommen: Im erzwungenen Modus bestimmt das System
       die Farben, ein invertiertes Icon sieht dort unvorhersehbar aus. Der Selektor wiederholt
       html.a11y-contrast, weil er die Regel von dort überstimmen muss (0,2,0) — erreichbar ist
       der Fall nur, wenn jemand das Kontrastdesign mitten in der Sitzung einschaltet. */
    html.a11y-contrast .btn-close {
        filter: none;
    }

    /* Die Icon-Regeln des Modus werden hier zurückgenommen — die Gegenseite der Umkehrung, die
       weiter oben ("Die Icon-Regeln") begründet ist. Die Tokens tragen im Modus die für
       schwarzen Grund gezeichneten Varianten; auf einem HELLEN Kontrastdesign wären die
       unsichtbar, weil forced-colors Farben erzwingt, background-image aber nicht anfasst.
       Zurückgesetzt wird auf die hellen Icons, also genau die, die auch der Normalmodus zeigt.

       An den Tokens und nicht an den fünf Regeln: eine Stelle statt fünf, und der Selektor ist
       derselbe wie oben (html.a11y-contrast, 0,1,1) — dieser Block steht später in der Datei
       und gewinnt damit bei gleicher Spezifität.

       Kennt ein Browser das Feature nicht, greift dieser Block nie: Dann bleiben die dunklen
       Icons aus den unbedingten Regeln stehen, was dort das richtige Ergebnis ist. Genau das war
       mit der früheren Weiche nicht zu erreichen. */
    html.a11y-contrast {
        --app-icon-dropdown: url('/images/icon-dropdown.svg');
        --app-icon-valid: url('/images/icon-valid.svg');
        --app-icon-invalid: url('/images/icon-invalid.svg');
    }
}
