/* Preventra — Designsystem.
 *
 * Anmutung: Microsoft 365 / SharePoint (Fluent 2). Ruhige neutrale Flächen, blauer Akzent,
 * dünne Trennlinien statt Rahmen überall, weiche Schatten, 4-px-Radien, 14 px Grundschrift.
 * Leitgedanke ist Einfachheit: wenige Bausteine, klare Hierarchie, keine Effekte ohne Zweck.
 *
 * Hell ist die Vorgabe; dunkel wird über data-theme="dark" am <html>-Element gesetzt. Das
 * Attribut kommt serverseitig aus dem Cookie (siehe ThemePreference), damit beim Laden nichts
 * aufblitzt.
 *
 * Eine Datei, keine Framework-Abhängigkeit, keine externen Schriftarten: die CSP erlaubt keine
 * Fremd-Origins, und ein externer Font-Aufruf würde die IP des Nutzers an Dritte übertragen
 * (MANIFEST §2).
 *
 * Es gibt bewusst KEINE style="…"-Attribute im Markup: Nonces gelten nicht für Attribute, solche
 * Stile würde die CSP blockieren (MANIFEST §1.3). Alles läuft über Klassen aus dieser Datei.
 */

/* ── Schrift ────────────────────────────────────────────────────────────────────────────────────
 *
 * Ziel: Microsoft-Anmutung UND maximale Schärfe. Das sind zwei Ziele, die sich außerhalb von
 * Windows nicht vollständig zugleich erreichen lassen — die Reihenfolge hier ist das Ergebnis
 * einer Messung, nicht eines Geschmacksurteils.
 *
 *   Windows        → "Segoe UI Variable Text" / "Segoe UI".  Die echte Microsoft-Schrift, vom
 *                    Betriebssystem perfekt gehintet. Hier stimmt beides.
 *   macOS / iOS    → -apple-system (SF Pro). Humanistische Groteske wie Segoe UI, im Charakter
 *                    sehr nah, und vom System hervorragend gerendert.
 *   Linux/Sonstige → "Selawik" als metrisch identischer Segoe-UI-Ersatz.
 *
 * WARUM SELAWIK NICHT VORNE STEHT — messbar, nicht vermutet:
 * Selawik (von Microsoft unter SIL OFL veröffentlicht, metrisch identisch zu Segoe UI) enthält
 * laut Prüfung der Font-Tabellen **keine kern-Tabelle, keine GPOS-Kerning-Lookups und keine
 * Hinting-Programme** (fpgm/prep). Microsofts eigene README nennt genau das als offene Punkte.
 * Folge: lockere, ungleichmäßige Zeichenpaare (AV, To, Wa) und weiche Stämme in kleinen Graden.
 * Vor der Systemschrift eingesetzt, würde es die Oberfläche schlechter aussehen lassen, nicht
 * microsoftiger.
 *
 * Selawik bleibt als Rückfall für Systeme ohne gute UI-Schrift — dort ist es die beste Wahl, weil
 * es die Segoe-Metrik trägt und der Umbruch identisch bleibt.
 *
 * Wer die Microsoft-Schrift überall erzwingen will, verschiebt "Selawik" im Stapel unten einfach
 * vor -apple-system. Eine Zeile, eine bewusste Entscheidung.
 *
 * Segoe UI selbst darf NICHT gehostet werden — es ist proprietäre Software von Microsoft.
 * Selawik ist selbst gehostet (SIL OFL 1.1, Lizenztext unter wwwroot/fonts/), niemals per CDN:
 * die CSP erlaubt keine Fremd-Origins, und ein externer Font-Aufruf würde die IP-Adresse des
 * Nutzers an Dritte übertragen (MANIFEST §2).
 */

@font-face {
    font-family: "Selawik";
    src: url("../fonts/selawik-regular.woff2") format("woff2");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Selawik";
    src: url("../fonts/selawik-semibold.woff2") format("woff2");
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: "Selawik";
    src: url("../fonts/selawik-bold.woff2") format("woff2");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

/* ── Farb- und Maßtoken ─────────────────────────────────────────────────────────────────────── */

:root {
    color-scheme: light;

    /* Neutrale Flächen */
    --color-canvas: #faf9f8;
    --color-surface: #ffffff;
    --color-surface-hover: #f5f5f5;
    --color-surface-pressed: #ededed;

    /* Linien.
       'stroke' ist dekorativ (Trennlinien, Tabellenzeilen) und darf zart sein.
       'stroke-accessible' umreißt Bedienelemente und muss 3,0:1 erreichen (WCAG 1.4.11) —
       Fluent nennt dieses Token NeutralStrokeAccessible. */
    --color-stroke: #e1dfdd;
    --color-stroke-strong: #c8c6c4;
    --color-stroke-accessible: #616161;

    /* Schrift */
    --color-text: #242424;
    --color-text-secondary: #4d4d4d;
    --color-text-disabled: #767676;

    /* Akzent */
    --color-accent: #0f6cbd;
    --color-accent-hover: #115ea3;
    --color-accent-bg: #0f6cbd;
    --color-accent-bg-hover: #115ea3;
    --color-accent-bg-pressed: #0c3b5e;
    --color-on-accent: #ffffff;
    --color-accent-subtle: #ebf3fc;

    /* Statusfarben (Fluent MessageBar) */
    --color-danger: #a4262c;
    --color-danger-subtle: #fdf3f4;
    --color-warning: #7a4d05;
    --color-warning-subtle: #fff4ce;
    --color-success: #0e700e;
    --color-success-subtle: #f1faf1;
    --color-info: var(--color-accent);
    --color-info-subtle: #ebf3fc;

    /* Dateiarten in der Ablage. Die Farbe ist Wiedererkennung, kein Bedeutungstraeger: Neben
       jedem Symbol steht der Dateiname mit seiner Endung (WCAG 1.4.1). Alle Werte erreichen
       gegen Arbeitsflaeche, Karte und Hoverflaeche mindestens 3:1 (WCAG 1.4.11) —
       nachgerechnet in scripts/pruefe-kontrast.py, nicht geschaetzt. */
    --color-datei-pdf: #b8232f;
    --color-datei-word: #185abd;
    --color-datei-excel: #0e6e35;
    --color-datei-powerpoint: #b7472a;
    --color-datei-bild: #7160a8;

    /* Erhebung */
    --shadow-2: 0 1px 2px rgba(0, 0, 0, 0.14), 0 0 2px rgba(0, 0, 0, 0.12);
    --shadow-4: 0 2px 4px rgba(0, 0, 0, 0.14), 0 0 2px rgba(0, 0, 0, 0.12);
    --shadow-8: 0 4px 8px rgba(0, 0, 0, 0.14), 0 0 2px rgba(0, 0, 0, 0.12);

    /* Radien */
    --radius-sm: 4px;
    --radius-md: 6px;
    --radius-pill: 999px;

    /* Abstände */
    --space-xs: 4px;
    --space-s: 8px;
    --space-m: 12px;
    --space-l: 16px;
    --space-xl: 24px;
    --space-xxl: 32px;

    /* Maße */
    --topbar-height: 48px;
    --nav-width: 228px;
    --control-height: 32px;

    /* Reihenfolge und Begründung: siehe Abschnitt "Schrift" oben. */
    --font-family: "Segoe UI Variable Text", "Segoe UI", -apple-system, BlinkMacSystemFont,
        system-ui, "Selawik", "Helvetica Neue", Arial, sans-serif;
    --font-size-caption: 12px;
    --font-size-body: 14px;
    --font-size-subtitle: 16px;
    --font-size-title: 20px;
    --font-size-display: 28px;
}

:root[data-theme="dark"] {
    color-scheme: dark;

    --color-canvas: #141414;
    --color-surface: #1f1f1f;
    --color-surface-hover: #292929;
    --color-surface-pressed: #333333;

    --color-stroke: #333333;
    --color-stroke-strong: #494949;
    --color-stroke-accessible: #adadad;

    --color-text: #f5f5f5;
    --color-text-secondary: #c7c7c7;
    --color-text-disabled: #8f8f8f;

    /* Im Dunkelmodus muss der Akzent heller sein, damit der Kontrast auf dunkler Fläche
       ausreicht; Flächen mit Akzentfarbe bleiben dagegen dunkler als im Hellmodus. */
    --color-accent: #479ef5;
    --color-accent-hover: #62abf5;
    --color-accent-bg: #115ea3;
    --color-accent-bg-hover: #0f6cbd;
    --color-accent-bg-pressed: #0c3b5e;
    --color-on-accent: #ffffff;
    --color-accent-subtle: #082338;

    --color-danger: #ff9ea0;
    --color-danger-subtle: #3b1f21;
    --color-warning: #fdd8a5;
    --color-warning-subtle: #3a2c0f;
    --color-success: #9fd89f;
    --color-success-subtle: #10290f;
    --color-info: var(--color-accent);
    --color-info-subtle: #082338;

    /* Auf dunklem Grund muessen die Dateifarben heller werden — dieselbe Regel wie beim Akzent. */
    --color-datei-pdf: #f08a92;
    --color-datei-word: #7cb7f5;
    --color-datei-excel: #6ecf8e;
    --color-datei-powerpoint: #f39a7e;
    --color-datei-bild: #c3b0e8;

    /* Auf dunklem Grund brauchen Schatten mehr Deckkraft, um überhaupt sichtbar zu sein. */
    --shadow-2: 0 1px 2px rgba(0, 0, 0, 0.28), 0 0 2px rgba(0, 0, 0, 0.24);
    --shadow-4: 0 2px 4px rgba(0, 0, 0, 0.28), 0 0 2px rgba(0, 0, 0, 0.24);
    --shadow-8: 0 4px 8px rgba(0, 0, 0, 0.28), 0 0 2px rgba(0, 0, 0, 0.24);
}

/* ── Grundlagen ─────────────────────────────────────────────────────────────────────────────── */

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

html {
    /* Verhindert, dass die Seite beim Wechsel zu einer scrollenden Ansicht springt. */
    scrollbar-gutter: stable;
}

body {
    margin: 0;
    font-family: var(--font-family);
    font-size: var(--font-size-body);
    line-height: 20px;
    color: var(--color-text);
    background: var(--color-canvas);

    /* Graustufen-Glättung auf macOS: ergibt feinere, gleichmäßigere Stämme als die
       Subpixel-Glättung und entspricht dem, was Microsoft 365 im Browser zeigt. */
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;

    /* Kein künstlicher Fett- oder Kursivschnitt. Fehlt ein Schnitt, rechnet der Browser ihn
       sonst hoch — das Ergebnis ist unscharf und ungleichmäßig. Wir liefern 400, 600 und 700
       als echte Schnitte. */
    font-synthesis: none;

    /* Kerning und Standardligaturen ausdrücklich an — bei Schriften, die sie mitbringen. */
    font-kerning: normal;
    font-variant-ligatures: common-ligatures;

    /* Verhindert, dass iOS beim Drehen die Schrift eigenmächtig vergrößert. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

a {
    color: var(--color-accent);
    text-decoration: none;
}

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

/* Verweise innerhalb von Textblöcken tragen dauerhaft eine Unterstreichung: Farbe allein darf
   keine Bedeutung tragen (WCAG 1.4.1, Use of Color). In Navigation und Schaltflächen ist die Rolle
   durch Position und Form erkennbar, dort bleibt es ohne.

   Die Regel ist auf den Inhaltsbereich begrenzt, nicht bloß durch eine spätere Regel überschrieben:
   'li:not(.nav-item) > a:not(.button)' hat eine höhere Spezifität als '.sidebar a' und gewann
   deshalb auch dann, wenn danach 'text-decoration: none' stand — die Navigationspunkte waren
   unterstrichen. Eine strukturelle Eingrenzung ist verlässlicher als ein Wettlauf um Spezifität. */
/* Das ':not(.button)' gehört an JEDEN dieser Selektoren, nicht nur an den letzten. Eine
   Schaltfläche in einem Absatz — '<p><a class="button">…' — wurde sonst unterstrichen: Der
   Selektor '.content p a' ist spezifischer als '.button' und gewann. Dass danach irgendwo
   'text-decoration: none' steht, hilft nicht; Spezifität schlägt Reihenfolge. */
.content p a:not(.button),
.content .notice a:not(.button),
.content .lead a:not(.button),
.content li:not(.nav-item) > a:not(.button),
/* Vor der Anmeldung ist JEDER Verweis einer im Fliesstext — es gibt weder Navigation noch
   Werkzeugleiste, deren Form die Rolle schon zeigt. Die Regel war auf '.content' begrenzt, also
   auf die angemeldete Anwendung; '.schlicht-inhalt' war nie erfasst. Folge: Der Verweis
   "Zurueck zur Anmeldung" auf /passwort-vergessen war allein an seiner Farbe erkennbar — ein
   Verstoss gegen WCAG 1.4.1 an einer Stelle, an der ihn niemand suchte, weil es die Regel
   "im Fliesstext" ja gibt. ':not(.brand)' ist Vorsorge fuer den Fall, dass die Wortmarke je als
   Verweis hierher wandert. */
.schlicht-inhalt a:not(.button):not(.brand) {
    text-decoration: underline;
    text-underline-offset: 2px;
}

.sidebar a,
.brand,
.button {
    text-decoration: none;
}

:focus-visible {
    /* Zweifarbiger Ring wie in Fluent: innen dunkel/hell nach Textfarbe, außen die Fläche.
       Ein einfarbiger Ring wäre unsichtbar, sobald das Element selbst diese Farbe trägt —
       etwa ein Akzentring auf einer gefüllten Akzentschaltfläche (WCAG 2.4.11/2.4.13). */
    outline: 2px solid var(--color-text);
    outline-offset: 1px;
    box-shadow: 0 0 0 4px var(--color-canvas);
    border-radius: var(--radius-sm);
}

/* Sprungmarke, nur bei Tastaturfokus sichtbar. */
.skip-link {
    position: absolute;
    left: -9999px;
    z-index: 100;
}

.skip-link:focus {
    left: var(--space-s);
    top: var(--space-s);
    padding: var(--space-s) var(--space-m);
    background: var(--color-surface);
    color: var(--color-text);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-8);
}

/* Für Screenreader vorhanden, visuell entfernt. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ── Gerüst ─────────────────────────────────────────────────────────────────────────────────── */

.shell {
    display: grid;
    grid-template-columns: var(--nav-width) 1fr;
    grid-template-rows: var(--topbar-height) 1fr;
    grid-template-areas:
        "topbar topbar"
        "nav    main";
    min-height: 100vh;
}

/* ── Kopfzeile ──────────────────────────────────────────────────────────────────────────────── */

/*
 * Drei Spalten statt einer Reihe mit Abstandshaltern.
 *
 * Mit Abstandshaltern saß die Suche mittig *zwischen* Logo und rechter Seite — und weil rechts
 * Name, zwei Marken und drei Schaltflächen stehen, links aber nur das Logo, lag sie sichtbar
 * links von der Mitte. Zwei gleich große Abstandshalter teilen den *Rest* gleichmäßig auf, nicht
 * die Kopfzeile.
 *
 * 'minmax(0, 1fr)' statt '1fr': Damit dürfen die äußeren Spalten schmaler werden als ihr Inhalt.
 * Sonst wüchse die rechte Spalte über ihren Anteil hinaus, sobald der Name lang ist — und die
 * Mitte wäre wieder keine.
 */
.topbar {
    grid-area: topbar;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
    gap: var(--space-m);
    padding: 0 var(--space-l);
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-stroke);
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-s);
    color: var(--color-text);
    font-size: var(--font-size-subtitle);
    font-weight: 600;
}

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

.brand-mark {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: var(--radius-sm);
    background: var(--color-accent-bg);
    color: var(--color-on-accent);
    font-size: var(--font-size-body);
    font-weight: 700;
}

.topbar-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    justify-self: end;
    gap: var(--space-s);
    min-width: 0;
}

/* ── Konto-Menü ─────────────────────────────────────────────────────────────────────────────── */

/*
 * Als <details>/<summary>: Aufklappen kann der Browser selbst — ohne Skript, mit Tastatur und
 * mit Ansage durch Screenreader. Das Dreieck, das Browser vor <summary> setzen, ist hier falsch
 * (es ist kein Text, der sich ausklappt, sondern ein Menü) und wird entfernt.
 */
.user-menu-wrap {
    position: relative;
}

.user-menu > summary {
    display: flex;
    align-items: center;
    gap: var(--space-s);
    padding: var(--space-xs) var(--space-s) var(--space-xs) var(--space-xs);
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    cursor: pointer;
    list-style: none;
    color: var(--color-text-secondary);
}

.user-menu > summary::-webkit-details-marker {
    display: none;
}

.user-menu > summary:hover {
    background: var(--color-surface-hover);
    border-color: var(--color-stroke);
    color: var(--color-text);
}

.user-menu > summary:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

/* Initialen im Kreis — dieselbe Form wie die Wortmarke, damit es zusammengehörig wirkt. */
.user-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--color-accent);
    color: var(--color-on-accent);
    font-size: var(--font-size-caption);
    font-weight: 600;
}

/* Auf schmalen Bildschirmen bleibt nur der Kreis. */
@media (max-width: 1100px) {
    .user-menu-name {
        display: none;
    }
}

.user-menu-panel {
    position: absolute;
    inset-inline-end: 0;
    z-index: 20;
    min-width: 18rem;
    margin-top: var(--space-xs);
    padding: var(--space-m);
    background: var(--color-surface);
    border: 1px solid var(--color-stroke);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-2);
}

.user-menu-title {
    margin: 0 0 var(--space-xs);
    font-weight: 600;
}

.user-menu-badges {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
    margin: var(--space-s) 0;
}

.user-menu-switch {
    display: flex;
    gap: var(--space-xs);
    margin: var(--space-s) 0;
}

.user-menu-switch select {
    min-width: 0;
}

.user-menu-signout {
    width: 100%;
    margin-top: var(--space-s);
}

/* Bei wenig Platz zuerst den Namen weglassen, dann die Rolle. */
@media (max-width: 900px) {
    .topbar-user {
        display: none;
    }
}

/* ── Navigation ─────────────────────────────────────────────────────────────────────────────── */

.sidebar {
    grid-area: nav;
    display: flex;
    flex-direction: column;
    padding: var(--space-m) var(--space-s);
    background: var(--color-canvas);
    border-right: 1px solid var(--color-stroke);
}

.sidebar ul {
    list-style: none;
    margin: 0 0 var(--space-l);
    padding: 0;
}

/*
 * Hilfe sitzt am Fuß der Navigation, abgesetzt durch eine Linie und den freien Raum darüber.
 * 'margin-top: auto' schiebt sie ans untere Ende, solange die Navigation Platz hat — sie soll nicht
 * unmittelbar unter dem letzten Arbeitspunkt kleben und dadurch wie einer aussehen.
 */
.nav-footer {
    margin-top: auto;

    /* Kein Abstand nach unten: '.sidebar ul' gibt jeder Liste einen, und beim letzten Block
       stand er zwischen Eintrag und Fensterrand — sichtbar als Loch unter dem Trennstrich. */
    margin-bottom: 0;
    padding-top: var(--space-m);
    border-top: 1px solid var(--color-stroke);
}

.sidebar a {
    display: flex;
    align-items: center;
    min-height: 36px;
    padding: 0 var(--space-m);
    border-radius: var(--radius-sm);
    color: var(--color-text);
    font-size: var(--font-size-body);
}

.sidebar a:hover {
    background: var(--color-surface-hover);
    color: var(--color-text);
    text-decoration: none;
}

.sidebar a[aria-current="page"] {
    background: var(--color-accent-subtle);
    color: var(--color-accent);
    font-weight: 600;
}

.nav-heading {
    margin: 0 0 var(--space-xs);
    padding: 0 var(--space-m);
    color: var(--color-text-secondary);
    font-size: var(--font-size-caption);
    font-weight: 600;
}

/*
 * Die freigeschalteten Pakete — eine Aufzählung, keine Navigation.
 *
 * Bewusst ohne Verweis und ohne Zeigerhand: Die Pakete führen nirgendwohin, ihre Einträge stehen
 * schon in der Liste darüber. Wer hier klicken will und nichts passiert, hält es für kaputt.
 */
.nav-pakete {
    margin: 0 0 var(--space-m);
    padding: 0 var(--space-m);
    list-style: none;
}

.nav-pakete li {
    padding: var(--space-xs) 0;
    color: var(--color-text-secondary);
    font-size: var(--font-size-caption);
}

/* Ein Punkt davor, damit die Zeilen nicht wie anklickbare Eintraege aussehen. */
.nav-pakete li::before {
    content: "·";
    margin-right: var(--space-xs);
    color: var(--color-accent);
}

/* ── Inhalt ─────────────────────────────────────────────────────────────────────────────────── */

/* Volle Breite. Listen und Tabellen sind der Kern dieses Portals und sollen den Platz nutzen —
   eine Betriebsliste mit acht Spalten auf 1264 px zu beschränken verschenkt Bildschirm.
   Fließtext bekommt dagegen weiter unten eine Lesebreite: Zeilen über etwa 90 Zeichen sind
   messbar schlechter lesbar, und Lesbarkeit ist Teil der Barrierefreiheit (WCAG 1.4.8). */
.content {
    grid-area: main;
    padding: var(--space-xl);
    min-width: 0;
}

/* Lesebreite für zusammenhängenden Text — nicht für Listen, Tabellen und Kennzahlen. */
.lead,
.notice,
.empty-state p,
.content > p {
    max-width: 90ch;
}

/*
 * Formularkarten füllen die Inhaltsspalte — wie Tabellen und Listen auch.
 *
 * Vorher standen sie auf 1100px. Auf einem Notebook fiel das kaum auf, auf einem breiten Bildschirm
 * sehr wohl: Über der Karte laufen die Tabellen durch, die Karte darunter bricht mittendrin ab und
 * hängt links. Das liest sich nicht als bewusste Lesebreite, sondern als Fehler.
 *
 * Die Sorge hinter dem Deckel war richtig — ein Eingabefeld über die ganze Bildschirmbreite ist
 * schwer zu überblicken. Sie ist aber am falschen Ort gelöst: Dafür sind die Feldraster da
 * (.field-row), die mehrere Felder nebeneinander legen und die Breite so sinnvoll aufteilen.
 * Ein einzeln stehendes Feld gehört in ein solches Raster, nicht in eine schmalere Karte.
 */

h1 {
    margin: 0 0 var(--space-xs);
    font-size: var(--font-size-display);
    font-weight: 600;
    line-height: 36px;
}

h2 {
    margin: var(--space-xl) 0 var(--space-m);
    font-size: var(--font-size-subtitle);
    font-weight: 600;
    line-height: 22px;
}

h3 {
    margin: var(--space-l) 0 var(--space-s);
    font-size: var(--font-size-body);
    font-weight: 600;
}

.lead {
    margin: 0 0 var(--space-xl);
    color: var(--color-text-secondary);
}

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

.caption {
    font-size: var(--font-size-caption);
    color: var(--color-text-secondary);
}

/* Abstandshilfen — ersetzen die von der CSP blockierten style-Attribute. */
.stack-top {
    margin-top: var(--space-l);
}

.stack-top-lg {
    margin-top: var(--space-xxl);
}

.stack-bottom {
    margin-bottom: var(--space-l);
}

.align-end {
    align-self: end;
}

/*
 * Überschrift mit Schaltfläche rechts daneben. Die Schaltfläche gehört sichtbar zum Abschnitt,
 * deshalb in dieselbe Zeile — und nicht ans Ende der Liste, wo sie erst nach dem Scrollen auftaucht.
 */
.section-header {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-m);
}

.section-header h2 {
    margin-bottom: var(--space-s);
}

/*
 * Das Pluszeichen ist Schmuck, die Beschriftung trägt die Bedeutung — deshalb aria-hidden im
 * Markup. Ein Zeichen allein wäre für 30- bis 60-jährige Gelegenheitsnutzer eine Ratearbeit, und
 * für Screenreader gar nichts.
 */
.button-plus {
    margin-inline-end: var(--space-xs);
    font-size: var(--font-size-subtitle);
    line-height: 1;
}

/* Verweis auf die Suchseite, wenn es zu viele Mandanten für ein Auswahlfeld sind. */
/* ── Seiten vor der Anmeldung ───────────────────────────────────────────────────────────────── */

/*
 * Eine Aufgabe, ein Objekt. Es gibt hier keine Navigation, keine Werkzeugleiste und kein zweites
 * Ziel — vor der Anmeldung ist ein Dialoglayout die ehrliche Beschreibung des Zustands, und ein
 * Dialog ist genau das, was unsere Nutzer jeden Morgen in Outlook Web sehen.
 *
 * 'flex-direction: column' ist kein Geschmacksentscheid, sondern eine Reparatur: Das
 * Umgebungsbanner ist im Layout ein Geschwister von <main>. In der Vorgaberichtung 'row' wurde es
 * zum zweiten Flex-Element und stand als schmale Saeule NEBEN dem Formular, sobald
 * AppOptions.EnvironmentLabel gesetzt ist (Vorschau, Stage). Als Spalte liegt es wieder oben und
 * ueber die volle Breite.
 *
 * 'justify-content: center' faellt ersatzlos weg; die Zentrierung uebernimmt der automatische
 * Aussenabstand am Inhalt (Begruendung dort).
 */
.schlicht {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background: var(--color-canvas);
}

/*
 * Mittig — waagerecht UND senkrecht, aber ueber 'margin: auto' statt 'justify-content: center'.
 *
 * Automatische Raender nehmen in einer Flexbox nur POSITIVEN Restplatz auf. Ist der Inhalt hoeher
 * als das Fenster — 200 % Zoom, kleines Notebook, aufgeklappte Fehlermeldung, eingeblendete
 * Bildschirmtastatur —, loesen sie sich zu null auf und der Inhalt beginnt oben. Mit
 * 'justify-content: center' waere in genau diesem Fall die Oberkante aus dem Fenster geschoben
 * und mit keiner Bildlaufleiste erreichbar: der klassische Weg, WCAG 1.4.4 und 1.4.10 mit einer
 * Zeile Zentrierung zu verlieren. Diese Zeile bitte nicht "aufraeumen".
 *
 * Die 30 rem bleiben. Ein Anmeldeformular wird nicht besser, wenn es breiter ist.
 */
.schlicht-inhalt {
    width: min(30rem, 100%);
    margin: auto;
    padding: var(--space-xxl) var(--space-l);
}

/* Die Wortmarke sagt, wo man ist — mehr nicht. Sie bleibt im selben Zustand wie in der Kopfzeile
   der angemeldeten Anwendung (--font-size-subtitle, 28-px-Plaette). Auf einer sonst leeren Seite
   ist die Versuchung gross, sie zu vergroessern; genau dort wird aus einer Fachanwendung eine
   Marketingseite (MANIFEST §5.1). */
.schlicht-marke {
    margin-bottom: var(--space-xl);
    font-size: var(--font-size-subtitle);
}

/*
 * Der eigentliche Grund, warum diese Seiten "nur vorhanden" statt gestaltet wirkten.
 *
 * 'h1' traegt global 'margin: 0 0 var(--space-xs)' (app.css:577) — 4 px. In den Arbeitsansichten
 * stimmt das, dort folgt eine Werkzeugleiste, die selbst Abstand mitbringt. Hier klebt die
 * Ueberschrift an der Karte bzw. an der Fehlermeldung. 16 px trennen den Titel vom Objekt und
 * binden ihn zugleich staerker an dieses als an die Wortmarke darueber (24 px).
 *
 * Spezifitaet 0,1,1 gegen 0,0,1 — die Regel gewinnt unabhaengig von der Reihenfolge.
 */
.schlicht-inhalt h1 {
    margin-bottom: var(--space-l);
}

/*
 * Die Karte.
 *
 * ZWEI Dinge sind hier bewusst und beide sind nachgerechnet, nicht gefuehlt:
 *
 * 1. Der Selektor ist '.schlicht .card' (0,2,0) und NICHT eine eigene Klasse (0,1,0). '.card'
 *    steht in app.css:1028 mit 0,1,0 und WEITER UNTEN — eine gleich spezifische Regel hier oben
 *    verloere gegen sie, und zwar lautlos: Die Karte behielte 16 px Innenrand und --shadow-2,
 *    also exakt das heutige Bild. app.css warnt zwei Absaetze weiter oben (Zeile 250–253) woertlich
 *    vor diesem Fehler: Spezifitaet schlaegt Reihenfolge.
 *
 * 2. Der Selektor greift damit fuer ALLE drei Seiten vor der Anmeldung. Das ist kein Nebeneffekt,
 *    sondern Absicht: Anmelden, Passwort vergessen und Passwort setzen teilen sich dieses Layout.
 *    Eine erhobene Karte auf einer und zwei flache daneben waeren schlechter als der Zustand von
 *    heute. So ziehen alle drei ohne eine Zeile Markup-Aenderung mit.
 *
 * --shadow-8 statt --shadow-2, weil die Karte hier das einzige Objekt der Seite ist und nicht
 * eines von vielen in einer Liste; dort bleibt --shadow-2 richtig. 24 px statt 40 px Innenrand,
 * weil eine Erhebung nur glaubwuerdig ist, wenn sie etwas hebt: Zwei Felder in einer 30-rem-Karte
 * mit 40 px Rand heben vor allem Leere.
 *
 * Kontrast: Karte gegen Arbeitsflaeche sind 1,05:1 hell (#ffffff auf #faf9f8) und 1,12:1 dunkel.
 * Die Trennung leistet also nicht die Farbe, sondern die Erhebung. Das ist zulaessig: Die Karte
 * ist kein Bedienelement, WCAG 1.4.11 fordert fuer sie keine 3,0:1 — ohne die Kante geht keine
 * Information verloren, die Felder darin tragen ihre eigenen 6,19:1 (hell) bzw. 7,34:1 (dunkel).
 */
.schlicht .card {
    padding: var(--space-xl);
    box-shadow: var(--shadow-8);
}

/*
 * Im Dunkelmodus traegt der Schatten nicht: Schwarz auf fast schwarzem Grund ist unsichtbar, und
 * 1,12:1 zwischen Karte und Flaeche waere nur zu ahnen. Deshalb dort eine Haarlinie statt der
 * Erhebung — dekorativ, kein Bedienelement-Umriss (#494949 auf #1f1f1f = 1,83:1, gegen die
 * Arbeitsflaeche 2,05:1).
 *
 * Unter 'prefers-contrast: more' wird --color-stroke-strong ohnehin zu #c7c7c7 und die Linie mit
 * 9,75:1 gegen die Karte deutlich. Der Zweig verbessert also, er verschlechtert nichts.
 *
 * Damit gibt es voruebergehend zwei Kartensorten im Dunkelmodus. Sauber waere, '.card' global eine
 * Kante zu geben — das ist ein Eingriff in jede Liste, jedes Dashboard und jede Detailseite und
 * gehoert in einen eigenen Schritt mit eigenem Blick auf alle Seiten.
 */
:root[data-theme="dark"] .schlicht .card {
    border: 1px solid var(--color-stroke-strong);
}

/*
 * Der 60-ch-Deckel aus '.field > input' faellt hier weg.
 *
 * Er existiert, weil das Auge bei einem Feld ueber die halbe Bildschirmbreite auf dem Rueckweg vom
 * Ende der Eingabe die Zuordnung zur Beschriftung links verliert. In einer 30-rem-Spalte gibt es
 * dieses Problem nicht — dort teilt die Spalte die Breite bereits auf, genau wie '.field-row' es
 * in der Anwendung tut (siehe die Begruendung bei '.field-row .field > input').
 *
 * Und er kostet hier etwas: Endet das Feld vor der Kartenkante, steht die rechtsbuendige
 * Schaltflaeche darunter an keiner Fluchtlinie, sondern frei im Raum. Ob 60 ch bei der aktuellen
 * Schrift ueberhaupt greifen, haengt am Zeichensatz — eine Ausrichtung, die von der geladenen
 * Schrift abhaengt, ist keine.
 */
.schlicht .card .field > input,
.schlicht .card .field > select {
    max-width: none;
}

/* Absaetze, die unmittelbar in der Karte stehen, folgen ihrem 16-px-Raster und nicht der
   Browservorgabe von 1em oben und unten. Betrifft heute genau den Verweis-Absatz. */
.schlicht .card > p {
    margin: 0 0 var(--space-l);
}

/*
 * Genau eine Hauptaktion, unten rechts — wie in jedem Fluent-Dialog. Rechts ist hier keine
 * Konvention um ihrer selbst willen: Die Felder fuellen die Karte jetzt bis zur Kante, die
 * Schaltflaeche schliesst buendig an derselben Kante ab. Es ist eine echte Fluchtlinie.
 *
 * Gilt auch fuer /passwort-vergessen, wo zwei Schaltflaechen in der Zeile stehen: Sie ruecken als
 * Gruppe nach rechts, die Hauptaktion zuerst — die Windows-Reihenfolge, unveraendert aus dem
 * bestehenden Markup.
 */
.schlicht /* Damit ein Element in der Leiste nach rechts wandern kann (margin-inline-start: auto). */
.command-bar-actions {
    justify-content: flex-end;
}

/*
 * Ein Verweis, der ALLEIN in einer Zeile steht, ist ein eigenstaendiges Ziel. Die Inline-Ausnahme
 * aus WCAG 2.5.8 gilt nur fuer Verweise innerhalb eines Satzes, deren Groesse die Zeilenhoehe des
 * umgebenden Textes begrenzt — hier gibt es keinen umgebenden Text. 20 px Zeilenhoehe (body)
 * plus zweimal 4 px ergeben 28 px und damit mehr als die geforderten 24 px. MANIFEST §5.2
 * formuliert die 24 px ohne Ausnahme; auf die WCAG-Spacing-Ausnahme darf man sich hier also gar
 * nicht erst berufen.
 *
 * Eigener Klassenname statt 'p > a': Ein Verweis mitten in einem Satz darf nicht 'inline-block'
 * werden, sonst bricht er nicht mehr um.
 */
.standalone-link {
    display: inline-block;
    padding-block: var(--space-xs);
}

/*
 * Fussnote unter einer Trennlinie, IN der Karte.
 *
 * Sie beantwortet eine Frage, die nur wenige haben (Einladung erhalten, noch kein Passwort), und
 * darf deshalb nicht mit dem Formular konkurrieren — aber sie spart der Betreuung Anrufe. In der
 * Karte statt darunter, weil eine Erhebung nur glaubwuerdig ist, wenn sie etwas hebt: Die Fussnote
 * gibt der Karte eine untere Kante mit Inhalt statt einen dekorativen Rand. Eine Seite, ein Objekt.
 *
 * Groesse und Farbe kommen aus '.caption' (8,45:1 hell, 9,75:1 dunkel gegen die Karte — AAA),
 * hier steht nur die Abtrennung. Die Linie ist dekorativ (1,33:1 hell, 1,30:1 dunkel) und darf das
 * sein: Sie trennt, sie bedient nichts.
 *
 * Spezifitaet 0,3,0 — schlaegt '.schlicht .card > p' (0,2,1). Ohne den Kindkombinator dort waeren
 * die beiden Regeln in Konflikt geraten.
 */
.schlicht .card > .schlicht-fussnote {
    margin: var(--space-xl) 0 0;
    padding-top: var(--space-l);
    border-top: 1px solid var(--color-stroke);
}

.schlicht-fussnote > p {
    margin: 0;
}

.schlicht-fussnote > p + p {
    margin-top: var(--space-s);
}

/* ── Prüfhistorie ───────────────────────────────────────────────────────────────────────────── */

/*
 * Die Prüfvorgeschichte eines Betriebsmittels, aufklappbar in der Tabellenzelle.
 *
 * <details>/<summary> statt eines nachgebauten Aufklappens: Es funktioniert ohne eine Zeile
 * JavaScript, ist mit der Tastatur bedienbar und wird von Screenreadern als Ausklappbereich
 * angesagt. Ein Nachbau müsste all das erst herstellen — und tut es erfahrungsgemäß halb.
 */
.historie {
    margin-top: var(--space-s);
}

.historie summary {
    /* Trefferfläche: 14 px Schrift, 20 px Zeilenhöhe plus zweimal 4 px sind 28 px und damit mehr
       als die geforderten 24 px (WCAG 2.5.8). */
    padding: var(--space-xs) 0;
    color: var(--color-text-secondary);
    font-size: var(--font-size-caption);
    cursor: pointer;
}

.historie summary:hover,
.historie summary:focus-visible {
    color: var(--color-text);
}

.historie ul {
    margin: var(--space-xs) 0 0;
    padding-inline-start: var(--space-m);
    /* Bei sechzehn Prüfungen wächst die Tabellenzeile sonst über den Bildschirm hinaus. */
    max-height: 16rem;
    overflow-y: auto;
}

.historie li {
    padding: var(--space-xs) 0;
    font-size: var(--font-size-caption);
    border-bottom: 1px solid var(--color-stroke);
}

.historie li:last-child {
    border-bottom: none;
}

/* ── Brotkrumen ─────────────────────────────────────────────────────────────────────────────── */

/*
 * Sie stehen über der Überschrift und sind bewusst zurückhaltend: Sie beantworten die Frage
 * „wo bin ich", ohne sie zu stellen. Das Trennzeichen kommt aus CSS und nicht aus dem Markup —
 * ein Screenreader liest sonst bei jedem Eintrag ein sinnloses Zeichen mit.
 */
.breadcrumbs {
    margin-bottom: var(--space-m);
}

.breadcrumbs ol {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs);
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: var(--font-size-body);
}

.breadcrumbs li + li::before {
    content: "›";
    margin-inline-end: var(--space-xs);
    color: var(--color-text-secondary);
}

.breadcrumbs a {
    color: var(--color-text-secondary);
    text-decoration: none;
}

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

/* Die aktuelle Seite: sichtbar als Endpunkt, aber nicht als Ziel. */
.breadcrumbs [aria-current="page"] {
    color: var(--color-text);
    font-weight: 600;
}

/* ── Suche in der Kopfzeile ─────────────────────────────────────────────────────────────────── */

/*
 * Sie wächst mit dem verfügbaren Platz, bleibt aber lesbar begrenzt. Ohne 'min-width: 0' würde
 * das Eingabefeld in einem Flex-Kopf nicht unter seine Inhaltsbreite schrumpfen und die
 * Identitätsangabe rechts hinausdrücken.
 */
/*
 * Mittig durch zwei Abstandshalter links und rechts. Bewusst nicht 'flex: 1' — dann wüchse das
 * Feld über die halbe Kopfzeile und wäre kein Bedienelement mehr, sondern eine Fläche. Eine feste
 * Breite hält es dort, wo das Auge es sucht, auch wenn der Name daneben länger oder kürzer ist.
 */
.topbar-search {
    position: relative;
    width: min(46ch, 100%);
}

/*
 * Der Rahmen liegt hier, nicht an den Teilen darin.
 *
 * Vorher trugen Eingabefeld und Schaltfläche je einen eigenen Rahmen. Beim Überfahren wechselte
 * nur einer die Farbe, an der Naht traf hell auf dunkel, und es sah aus, als fiele der Rahmen
 * weg. Ein Bedienelement, ein Rahmen — dann kann auch nur eines reagieren.
 */
.search-field {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    padding-inline: var(--space-s);
    border: 1px solid var(--color-stroke-accessible);
    border-radius: var(--radius-pill);
    background: var(--color-surface);
}

.search-field:hover {
    border-color: var(--color-stroke-strong);
}

/* focus-within statt :focus am Feld: Der Rahmen gehört dem Behälter, der Fokus dem Feld darin. */
.search-field:focus-within {
    border-color: var(--color-accent);
    box-shadow: 0 0 0 1px var(--color-accent);
}

.search-icon {
    display: inline-flex;
    color: var(--color-text-secondary);
}

/* Das Eingabefeld selbst ist rahmenlos — es füllt nur den Behälter aus. */
.search-field input,
.search-field input:hover,
.search-field input:focus {
    flex: 1;
    min-width: 0;
    height: var(--control-height);
    min-height: 0;
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
    outline: none;
}

/* Die Suchlupe blendet in Chrome ein eigenes Kreuz ein — es doppelt sich mit dem Feldrahmen. */
.search-field input::-webkit-search-cancel-button {
    cursor: pointer;
}

.search-go {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: var(--control-height);
    height: var(--control-height);
    padding: 0;
    border: 0;
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--color-text-secondary);
    cursor: pointer;
    font-size: var(--font-size-body);
}

.search-go:hover {
    background: var(--color-surface-hover);
    color: var(--color-text);
}

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

/* ── Vorschläge unter dem Suchfeld ──────────────────────────────────────────────────────────── */

/*
 * Nur sichtbar, wenn etwas drinsteht: ':empty' erspart ein Skript, das ein leeres Feld ein- und
 * ausblendet — und damit eine Stelle, an der die Anzeige und der Inhalt auseinanderlaufen können.
 */
.search-panel {
    position: absolute;
    inset-inline: 0;
    z-index: 30;
    margin-top: var(--space-xs);
    background: var(--color-surface);
    border: 1px solid var(--color-stroke);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-8);
    overflow: hidden;
}

.search-panel:empty {
    display: none;
}

.search-suggestions {
    margin: 0;
    padding: var(--space-xs);
    list-style: none;
}

.search-suggestions a {
    display: block;
    padding: var(--space-xs) var(--space-s);
    border-radius: var(--radius-sm);
    color: var(--color-text);
    text-decoration: none;
}

.search-suggestions a:hover,
.search-suggestions a:focus-visible {
    background: var(--color-accent-subtle);
}

.search-suggestion-title {
    display: block;
}

.search-suggestion-meta {
    display: block;
    color: var(--color-text-secondary);
    font-size: var(--font-size-caption);
}

.search-hint {
    margin: 0;
    padding: var(--space-s) var(--space-m);
    color: var(--color-text-secondary);
    font-size: var(--font-size-caption);
}

.search-all {
    display: block;
    padding: var(--space-s) var(--space-m);
    border-top: 1px solid var(--color-stroke);
    color: var(--color-accent);
    font-size: var(--font-size-caption);
}

/*
 * Auf schmalen Bildschirmen verschwindet sie. Nicht aus Platznot allein: Eine Suche, die neben
 * Namen, Rolle und drei Schaltflächen auf 360 Pixel gequetscht wird, ist für niemanden bedienbar.
 * Erreichbar bleibt sie über die Seite /suche.
 */
@media (max-width: 900px) {
    .topbar-search {
        display: none;
    }
}

/* Trefferliste: Zeilen mit Abstand, damit Titel und Einordnung nicht verschmelzen. */
.search-hits > li {
    padding: var(--space-s) var(--space-m);
    border-bottom: 1px solid var(--color-stroke);
}

.search-hits > li:last-child {
    border-bottom: 0;
}

/* ── Nachrichten ────────────────────────────────────────────────────────────────────────────── */

.message-link {
    position: relative;
}

.message-link svg {
    width: 20px;
    height: 20px;
}

/*
 * Zähler ungelesener Vorgänge. Die Zahl selbst trägt die Bedeutung — Farbe allein dürfte es nicht
 * (WCAG 1.4.1), und für Screenreader steht der Text ausgeschrieben im visually-hidden-Bereich.
 */
.message-count {
    position: absolute;
    top: 0;
    inset-inline-end: 0;
    min-width: 16px;
    padding: 0 4px;
    border-radius: var(--radius-pill);
    background: var(--color-accent-bg);
    color: var(--color-on-accent);
    font-size: 11px;
    line-height: 16px;
    text-align: center;
    font-weight: 600;
}

/*
 * Gesprächsverlauf. Bewusst keine gegenüberliegenden Sprechblasen wie in einem Messenger: Der
 * Verlauf ist ein Nachweis und wird auch gelesen, gedruckt und exportiert. Eine linksbündige,
 * durchgehende Spalte bleibt dabei lesbar; die Herkunft steht als Text daneben, nicht nur als Seite.
 */
.thread {
    display: flex;
    flex-direction: column;
    gap: var(--space-m);
    margin-bottom: var(--space-l);
}

.message {
    padding: var(--space-m) var(--space-l);
    background: var(--color-surface);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-2);
    border-inline-start: 3px solid var(--color-stroke-strong);
}

/* Herkunft zusätzlich über eine Kante — als zweites Merkmal neben der Beschriftung. */
.message-staff {
    border-inline-start-color: var(--color-accent);
}

.message-client {
    border-inline-start-color: var(--color-success);
}

.message-meta {
    margin: 0 0 var(--space-xs);
    color: var(--color-text-secondary);
    font-size: var(--font-size-caption);
}

/*
 * Von wem stammt, was auf dieser Seite steht? Nur sichtbar, wenn jemand bei mehreren Anbietern
 * Kunde ist. Ruhig gehalten — es ist eine Ortsangabe, keine Warnung: dieselbe Zeilenhöhe wie die
 * Brotkrumen darüber, Sekundärtext, und der Name als einziges Fettes.
 *
 * Der Balken links trägt keine Bedeutung allein: Der Satz daneben sagt dasselbe in Worten
 * (MANIFEST §5).
 */
/*
 * Die Karte eines Anbieters auf der Auswahl.
 *
 * Als Spalte mit der Aktion am unteren Rand: Zwei Anbieter beschreiben sich unterschiedlich lang,
 * und ohne diesen Anschlag stuenden die Schaltflaechen auf verschiedenen Hoehen — die Reihe sieht
 * dann aus wie ein Fehler, nicht wie eine Wahl.
 */
.betreuungskarte {
    display: flex;
    flex-direction: column;
    gap: var(--space-s);
}

.betreuungskarte > h2 {
    margin: 0;
    font-size: var(--font-size-subtitle);
}

.betreuungskarte > p {
    margin: 0;
}

.betreuungskarte-aktion {
    margin-top: auto;
    padding-top: var(--space-s);
}

/*
 * Die Fläche für das Firmenzeichen — in jeder Karte gleich hoch, mit Logo oder ohne.
 *
 * Feste Höhe, Breite nach Bedarf: Logos kommen in jedem Seitenverhältnis, und eine feste Breite
 * verzerrte das eine oder ließe das andere winzig. 'object-fit: contain' hält das Bild
 * vollständig und unverzerrt, links bündig zum Namen darunter.
 */
.betreuungskarte-zeichen {
    display: flex;
    align-items: center;
    height: 48px;
}

.betreuungskarte-zeichen img {
    width: auto;
    max-width: 200px;
    height: 48px;
    object-fit: contain;
    object-position: left center;
}

/* Ohne hinterlegtes Logo: die Anfangsbuchstaben, wie beim Konto in der Kopfzeile. */
.betreuungskarte-kuerzel {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    border-radius: var(--radius-md);
    background: var(--color-accent-subtle);
    color: var(--color-accent);
    font-size: var(--font-size-subtitle);
    font-weight: 600;
}

/* Die Vorschau auf der Mandantenseite benutzt dieselbe Flaeche. */
.logovorschau {
    width: auto;
    max-width: 200px;
    height: 48px;
    object-fit: contain;
    object-position: left center;
}

.anbieterhinweis {
    margin: 0 0 var(--space-l);
    padding: var(--space-s) var(--space-m);
    border-left: 4px solid var(--color-accent);
    background: var(--color-accent-subtle);
    border-radius: 0 var(--radius-md) var(--radius-md) 0;
    color: var(--color-text-secondary);
    font-size: var(--font-size-caption);
}

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

/*
 * Was an einem Standort ansteht: drei bis fünf Zeilen aus Datum, Thema und Terminart. Bewusst
 * keine Tabelle — eine Tabelle mit fünf Zeilen und drei Spalten trägt mehr Rahmen als Inhalt,
 * und auf einem Telefon bricht sie in Spalten um, die niemand liest.
 */
.terminliste {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-m);
}

.terminliste li {
    display: grid;
    gap: var(--space-xs);
}

/* Das Datum führt die Zeile: Danach sucht das Auge, nicht nach dem Thema. */
.termin-zeit {
    font-weight: 600;
}

/*
 * Text, in dem die Zeilenumbrüche des Verfassers etwas bedeuten: eine Nachricht, eine
 * Tagesordnung. Sie bleiben erhalten, ohne dass HTML erlaubt wäre — der Text wird von Razor
 * escaped, 'pre-wrap' macht nur die Umbrüche sichtbar. 'overflow-wrap' verhindert, dass eine
 * lange Zeichenkette ohne Leerzeichen die Seite in die Breite zieht.
 */
.mehrzeilig {
    margin: 0;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

/*
 * Breitere Karten für die Übersicht: Ein Betrieb mit mehreren Standorten braucht mehr Platz als
 * eine Kennzahlenkachel, sonst bricht jede Zeile um.
 */
.card-grid-wide {
    grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
}

.card-title {
    margin-top: 0;
    margin-bottom: var(--space-xs);
    font-size: var(--font-size-subtitle);
}

/*
 * Auswahlfeld und Schaltfläche nebeneinander innerhalb einer Tabellenzelle.
 * Umbruch erlaubt (wrap), damit die Zelle auf schmalen Bildschirmen nicht die Tabelle sprengt.
 */
.field-row-tight {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
    align-items: center;
}

.field-row-tight select {
    width: auto;
    min-width: 12ch;
}

/*
 * Aufzählung ohne Punkte und Einzug — für kurze Listen innerhalb einer Tabellenzelle.
 * Bewusst eine Liste und kein <br>-getrennter Text: Screenreader kündigen die Anzahl der Einträge
 * an, was bei Mandantenzugehörigkeiten die eigentliche Information ist (WCAG 1.3.1).
 */
.plain-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

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

/* ── Dokumentenablage ───────────────────────────────────────────────────────────────────────── */

/*
 * Die Einrückung der Ordnerebenen.
 *
 * Über ein Datenattribut und feste Regeln statt über ein 'style'-Attribut: Die CSP verbietet
 * Inline-Stile, und eine berechnete Einrückung im Markup wäre genau das. Die Tiefe ist auf fünf
 * begrenzt — fünf Regeln genügen.
 *
 * Die Einrückung ist Gestaltung, nicht Bedeutung: Die Ebene steht zusätzlich als Text in der
 * Zelle. Wer die Seite vorgelesen bekommt, verliert die Struktur sonst.
 */
.ordner-name {
    display: inline-block;
}

.ordner-name[data-ebene="2"] { padding-left: var(--space-l); }
.ordner-name[data-ebene="3"] { padding-left: calc(var(--space-l) * 2); }
.ordner-name[data-ebene="4"] { padding-left: calc(var(--space-l) * 3); }
.ordner-name[data-ebene="5"] { padding-left: calc(var(--space-l) * 4); }

/* ── Bestätigung in zwei Schritten ──────────────────────────────────────────────────────────── */

/*
 * Der QR-Code steht auf eigener weißer Fläche.
 *
 * Kein Schmuck: Ein QR-Code braucht Kontrast zwischen Modulen und Grund. Im dunklen Modus
 * mitzuwandern machte ihn unlesbar — die Kamera sieht dann hell auf hell.
 */
.qr-flaeche {
    display: inline-block;
    padding: var(--space-m);
    background: #ffffff;
    border-radius: var(--radius-sm);
    border: 1px solid var(--color-stroke);
}

/* Wiederherstellungscodes: nebeneinander, damit die Liste nicht zehn Zeilen hoch wird. */
.code-liste {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-s) var(--space-l);
    margin: var(--space-m) 0 0;
    padding: 0;
    list-style: none;
}

/* ── Senkrechter Rhythmus zwischen Blöcken ──────────────────────────────────────────────────── */

/*
 * Was auf einen Block folgt, bekommt Abstand nach oben — an EINER Stelle für alle.
 *
 * Vorher trugen die Blöcke nur einen Abstand nach UNTEN, und 'card' und 'list-surface' gar
 * keinen. Ein Hinweis direkt hinter einer Tabelle klebte deshalb daran, und der nächste Block
 * hinter einer Karte ebenso. Der Fehler trat an vielen Stellen auf, weil er keine Stelle hatte:
 * Er entstand aus der Abwesenheit einer Regel.
 *
 * Der Nachbarschaftsselektor greift nur zwischen Geschwistern und nur NACH einem dieser Blöcke.
 * Überschriften bringen ihren eigenen, größeren Abstand mit; benachbarte Außenabstände fallen im
 * normalen Fluss zusammen, es addiert sich also nichts.
 *
 * Auf '.content' eingeengt, und das ist keine Vorsicht: Ohne die Einengung traf 'form + *' auch
 * das Suchfeld in der Navigation, und die Einträge darunter rutschten weg. Eine Regel für den
 * Lesefluss der Seite hat in der Navigationsspalte nichts zu suchen.
 */
.content .card + *,
.content .list-surface + *,
.content .notice + *,
.content .command-bar + *,
.content .empty-state + *,
.content .pager + *,
.content .ablagepfad + *,
.content .nebenaktionen + *,
.content form + * {
    margin-top: var(--space-xl);
}

/*
 * ... aber NICHT innerhalb eines Rasters oder einer Flex-Reihe.
 *
 * Dort macht 'gap' den Abstand. Ein zusätzlicher Außenabstand am Rasterkind verschiebt es nach
 * unten UND verkürzt es um denselben Betrag — die Karten einer Reihe stehen dann auf
 * verschiedenen Höhen. Sichtbar wurde das erst bei zwei Karten ungleicher Höhe (die
 * Anbieterauswahl); bei den gleich hohen Kennzahlkacheln fiel es jahrelang nicht auf.
 *
 * Die Regel oben gilt dem Lesefluss der Seite. Ein Raster ist keiner.
 */
.content .card-grid > *,
.content .nebenaktionen > *,
.content .command-bar-actions > * {
    margin-top: 0;
}

/* ── Karten ─────────────────────────────────────────────────────────────────────────────────── */

.card {
    padding: var(--space-l);
    background: var(--color-surface);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-2);
}

.card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--space-l);
}

.kpi {
    font-size: var(--font-size-display);
    font-weight: 600;
    line-height: 36px;
}

.kpi-label {
    margin-top: var(--space-xs);
    color: var(--color-text-secondary);
    font-size: var(--font-size-caption);
}

/* ── Werkzeugleiste ─────────────────────────────────────────────────────────────────────────── */

.command-bar {
    display: flex;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: var(--space-m);
    margin-bottom: var(--space-l);
    padding: var(--space-m) var(--space-l);
    background: var(--color-surface);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-2);
}

.command-bar .field {
    margin-bottom: 0;
    min-width: 240px;
    flex: 1 1 240px;
}

.command-bar-actions {
    display: flex;
    gap: var(--space-s);
}

/* ── Reiter (Fluent-2-Pivot) ────────────────────────────────────────────────────────────────── */

/*
 * Verweise, die wie Reiter aussehen — keine ARIA-Reiterrollen.
 *
 * Jeder Reiter hat eine eigene Adresse und laedt eine eigene Seite. 'role="tab"' verspraeche
 * einer Vorleseanwendung ein Umschalten ohne Seitenwechsel samt Pfeiltastenbedienung; hier ist
 * es eine Verweisliste, und als solche wird sie angesagt. Der aktive Reiter traegt
 * 'aria-current="page"' — dieselbe Auszeichnung wie in der Seitenleiste und in den Brotkrumen.
 *
 * Der Unterstrich traegt die Bedeutung NICHT allein: Der aktive Reiter ist zusaetzlich dunkler
 * und halbfett (MANIFEST §5.2 — Farbe traegt nie allein Bedeutung), und 'aria-current' sagt es
 * ohne jede Darstellung.
 */
.reiter {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
    margin-bottom: var(--space-l);
    border-bottom: 1px solid var(--color-stroke);
}

.reiter a {
    padding: var(--space-s) var(--space-m);
    color: var(--color-text-secondary);
    text-decoration: none;
    white-space: nowrap;

    /* Der Streifen ist immer da, nur meist unsichtbar: Ohne ihn spraenge die Zeile beim
       Wechseln um zwei Pixel. */
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
}

.reiter a:hover {
    color: var(--color-text);
    background: var(--color-surface-hover);
}

.reiter a[aria-current="page"] {
    color: var(--color-text);
    font-weight: 600;
    border-bottom-color: var(--color-accent);
}

/*
 * Auf schmalen Geraeten laeuft die Leiste seitlich statt umzubrechen: Sieben umgebrochene
 * Reiter fuellten sonst den halben Bildschirm, bevor der Inhalt anfaengt.
 */
@media (max-width: 640px) {
    .reiter {
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: thin;
    }
}

/* ── Listen (SharePoint-Anmutung) ───────────────────────────────────────────────────────────── */

.list-surface {
    background: var(--color-surface);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-2);

    /* Waagerecht scrollen statt abschneiden: Eine Ablageliste traegt Name, zwei Datumsangaben,
       Groesse und Sichtbarkeit — auf einem schmalen Fenster passt das nicht, und eine
       abgeschnittene Spalte ist schlechter als eine, die man erreicht. Die Seite selbst scrollt
       dabei nie waagerecht; nur dieser Kasten tut es. */
    overflow-x: auto;
    overflow-y: hidden;
}

table {
    width: 100%;
    border-collapse: collapse;
    background: var(--color-surface);
}

.list-surface table {
    box-shadow: none;
}

thead th {
    position: sticky;
    top: 0;
    padding: var(--space-s) var(--space-m);
    text-align: left;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-stroke);
    color: var(--color-text-secondary);
    font-size: var(--font-size-caption);
    font-weight: 600;
    white-space: nowrap;
}

tbody td {
    padding: var(--space-m);
    border-bottom: 1px solid var(--color-stroke);
    vertical-align: top;
}

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

tbody tr:hover {
    background: var(--color-surface-hover);
}

.numeric {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

/* Zeilen mit langem Text sollen umbrechen, Zahlenspalten nicht. */
td.numeric,
th.numeric {
    white-space: nowrap;
}

/* ── Abzeichen ──────────────────────────────────────────────────────────────────────────────── */

.badge {
    display: inline-flex;
    align-items: center;
    height: 20px;
    padding: 0 var(--space-s);
    border-radius: var(--radius-pill);
    background: var(--color-surface-hover);
    color: var(--color-text-secondary);
    font-size: var(--font-size-caption);
    font-weight: 600;
    white-space: nowrap;
}

.badge-accent {
    background: var(--color-accent-subtle);
    color: var(--color-accent);
}

.badge-success {
    background: var(--color-success-subtle);
    color: var(--color-success);
}

.badge-warning {
    background: var(--color-warning-subtle);
    color: var(--color-warning);
}

.badge-danger {
    background: var(--color-danger-subtle);
    color: var(--color-danger);
}

/* ── Schaltflächen ──────────────────────────────────────────────────────────────────────────── */

.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-s);
    min-height: var(--control-height);
    padding: 0 var(--space-m);
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: var(--color-accent-bg);
    color: var(--color-on-accent);
    font-family: inherit;
    font-size: var(--font-size-body);
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
}

.button:hover {
    background: var(--color-accent-bg-hover);
    color: var(--color-on-accent);
    text-decoration: none;
}

.button:active {
    background: var(--color-accent-bg-pressed);
}

/* Standardschaltfläche: Fläche mit Rahmen, wie in Fluent. */
.button-default {
    background: var(--color-surface);
    border-color: var(--color-stroke-accessible);
    color: var(--color-text);
}

.button-default:hover {
    background: var(--color-surface-hover);
    color: var(--color-text);
}

.button-default:active {
    background: var(--color-surface-pressed);
}

/* Dezente Schaltfläche: ohne Rahmen, für Aktionen in Listen und Kopfzeile. */
.button-subtle {
    background: transparent;
    border-color: transparent;
    color: var(--color-text);
    font-weight: 400;
}

.button-subtle:hover {
    background: var(--color-surface-hover);
    color: var(--color-text);
}

.button-icon {
    width: var(--control-height);
    padding: 0;
}

.button-icon svg {
    width: 20px;
    height: 20px;
    fill: currentColor;
}

/* ── Formulare ──────────────────────────────────────────────────────────────────────────────── */

/* Feldgruppen. fieldset/legend statt Überschriften, damit ein Screenreader die Zugehörigkeit
   ansagt („Anschrift, Postleitzahl, Eingabefeld") — eine <h2> davor leistet das nicht
   (WCAG 1.3.1). Der Browser-Standardrahmen wird entfernt; die Gliederung tragen Abstand und
   Beschriftung. */
.field-group {
    margin: 0 0 var(--space-xl);
    padding: 0;
    border: 0;
}

.field-group > legend {
    margin: 0 0 var(--space-m);
    padding: 0;
    font-size: var(--font-size-subtitle);
    font-weight: 600;
    line-height: 22px;
}

.field {
    margin-bottom: var(--space-l);
}

.field-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: var(--space-l);
}

/*
 * Ein Feld, das allein in einer Zeile steht, füllt die Karte nicht bis zum Rand.
 *
 * Der Grund ist nicht Geschmack: Bei einem Eingabefeld über die halbe Bildschirmbreite verliert
 * das Auge auf dem Rückweg vom Ende der Eingabe die Zuordnung zur Beschriftung links. Dieselbe
 * Regel gilt für Fließtext seit dem Buchdruck.
 *
 * Felder in einem Raster sind ausdrücklich ausgenommen — dort teilt das Raster die Breite bereits
 * auf, und ein zusätzlicher Deckel ließe die Spalten ausgefranst enden.
 */
.field > input,
.field > select {
    max-width: 60ch;
}

.field > textarea {
    max-width: 90ch;
}

/*
 * Die Ausnahme, und der Grund für die Reihenfolge: Im Raster teilt bereits die Spalte die Breite
 * auf. Ein zweiter Deckel darin ließe die Spalten unterschiedlich weit enden — die Felder stünden
 * nebeneinander, ihre rechten Kanten aber nicht.
 */
.field-row .field > input,
.field-row .field > select,
.field-row .field > textarea {
    max-width: none;
}

label {
    display: block;
    margin-bottom: var(--space-xs);
    font-size: var(--font-size-body);
    font-weight: 600;
}

/* Eingabefelder füllen ihre Zeile — Kästchen und Radioknöpfe ausdrücklich NICHT.
   Ohne diesen Ausschluss war jedes Kästchen ein bildschirmbreiter, 32 Pixel hoher Kasten mit
   Rahmen, in dessen Mitte das Häkchen schwebte, und die Beschriftung wurde in eine schmale
   Spalte daneben gequetscht. Das betraf jede Stelle mit einem Kästchen: Addons, zweiter Faktor,
   Import. Ein Fehler ohne eigenen Ort — er entstand aus einem zu weit gefassten Selektor.

   Der Ausschluss steht in ':where()', und das ist kein Schönheitsfehler: ':where()' zählt bei
   der Spezifität nicht mit. Mit einem nackten ':not()' stiege sie von (0,0,1) auf (0,2,1), und
   jede Komponentenregel, die dieses Grundmuster überschreibt — etwa das rahmenlose Suchfeld in
   der Kopfzeile —, verlöre plötzlich. Genau das ist beim ersten Anlauf passiert. */
input:where(:not([type="checkbox"], [type="radio"])),
select,
textarea {
    width: 100%;
    min-height: var(--control-height);
    padding: 0 var(--space-s);
    border: 1px solid var(--color-stroke-accessible);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-text);
    font-family: inherit;
    font-size: var(--font-size-body);
}

textarea {
    padding: var(--space-s);
    line-height: 20px;
    resize: vertical;
}

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

input:focus,
select:focus,
textarea:focus {
    border-color: var(--color-accent);
    outline: 1px solid var(--color-accent);
    outline-offset: -2px;
}

input::placeholder,
textarea::placeholder {
    color: var(--color-text-disabled);
}

.field-hint {
    display: block;
    margin-top: var(--space-xs);
    color: var(--color-text-secondary);
    font-size: var(--font-size-caption);
}

/*
 * Ein Kontrollkästchen mit Beschriftung daneben.
 *
 * Kästchen und Text sind GESCHWISTER, nicht ineinander verschachtelt: Ein Blockelement (der
 * Hinweistext) innerhalb einer Beschriftung bricht deren Ausrichtung, und der erste Versuch sah
 * genau so aus. Die Verknüpfung läuft über 'for' — das ist ohnehin die verlässlichere Zuordnung
 * für Bildschirmleseprogramme.
 *
 * Das Kästchen darf nicht schrumpfen: Bei langem Text bliebe sonst ein Strich übrig, und
 * WCAG 2.5.8 verlangt 24 × 24 px.
 */
.field-checkbox {
    display: flex;
    align-items: flex-start;
    gap: var(--space-s);
    margin-bottom: var(--space-m);
}

.field-checkbox input[type="checkbox"] {
    flex: 0 0 auto;
    /* Auf die Höhe der ersten Textzeile gesetzt, nicht an den oberen Rand des Kastens. */
    margin-top: 2px;
}

.field-checkbox-text {
    display: flex;
    flex-direction: column;
    gap: var(--space-xs);
}

.field-checkbox-text label {
    margin: 0;
    cursor: pointer;
}

.field-checkbox-text .field-hint {
    margin-top: 0;
}

.inline-form {
    display: inline;
    margin: 0;
}

/* Mindestgröße von Bedienelementen: 24 × 24 px (WCAG 2.2, 2.5.8). Die Steuerelemente hier sind
   mit 32 px größer; die Regel sichert ab, dass eine künftige Verkleinerung nicht darunter fällt. */
button,
[role="button"],
/* Kästchen und Radioknöpfe: eigene Größe, kein Rahmen der Anwendung — den zeichnet der
   Browser. 24 Pixel sind die Mindestgröße eines Bedienziels (WCAG 2.2, 2.5.8); 'accent-color'
   färbt den Haken in der Akzentfarbe, die gegen die Karte 5,4:1 erreicht (WCAG 1.4.11). */
input[type="checkbox"],
input[type="radio"] {
    width: auto;
    min-width: 24px;
    min-height: 24px;
    padding: 0;
    accent-color: var(--color-accent);
}

/* Formulare in Listenzellen: Steuerelemente nebeneinander, ohne Blockumbruch. */
.cell-form {
    display: flex;
    align-items: center;
    gap: var(--space-s);
    margin: 0;
}

.cell-form select {
    width: auto;
    min-width: 180px;
}

/* Mehrere Bedienelemente in einer Tabellenzelle: nebeneinander, mit Umbruch bei wenig Platz.
   Ohne diese Regel steht jedes Element auf einer eigenen Zeile, weil ein <select> als Blockelement
   die volle Breite nimmt — die Zelle wird dreimal so hoch wie die daneben, und die Zeile faellt
   auseinander. */
.cell-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-s);
}

/* Der einheitliche Blockabstand (`.content form + *`) gilt dem Seitenfluss: Was auf ein Formular
   folgt, steht darunter und braucht Luft. In einer Tabellenzelle steht es daneben — dort schob
   die Regel jede zweite Schaltfläche um 24 px nach unten, und die Zeile saß schief. Die Ausnahme
   steht hier und nicht als `!important` am Formular: Sie ist eine Aussage über den Ort, nicht
   über die Dringlichkeit. */
.content .cell-actions > * {
    margin-top: 0;
}

/* ── Ablage: Ordner und Dateien in einer Liste ──────────────────────────────────────────────
 *
 * Wie eine Dokumentbibliothek: Symbol, Name, darunter die Nebenangaben. Ordner stehen oben und
 * führen weiter, Dateien führen auf ihre Seite. Der wichtigste Unterschied in einer Ablage ist
 * der zwischen „hier geht es weiter" und „hier ist etwas" — deshalb ist das Ordnersymbol
 * gefüllt und das Dateisymbol umrissen.
 */
.ablage-symbol {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
}

.ablage-symbol svg {
    width: 24px;
    height: 24px;
}

.art-ordner { color: var(--color-accent); }
.art-pdf { color: var(--color-datei-pdf); }
.art-word { color: var(--color-datei-word); }
.art-excel { color: var(--color-datei-excel); }
.art-powerpoint { color: var(--color-datei-powerpoint); }
.art-bild { color: var(--color-datei-bild); }
.art-text,
.art-sonstige { color: var(--color-text-secondary); }

/* Symbol und Beschriftung als eine Einheit — das Symbol gehört zum Namen, nicht in eine
   eigene Spalte, die bei schmalen Fenstern als erstes zusammenfällt. */
.ablage-eintrag {
    display: flex;
    align-items: center;
    gap: var(--space-m);
    min-width: 0;
}

.ablage-eintrag-text {
    min-width: 0;
}

/* Der Name ist der Verweis, und er füllt die Zeile: Das Ziel ist damit so groß wie der Text und
   nicht so klein wie ein Symbol (WCAG 2.5.8). */
.ablage-eintrag a {
    font-weight: 600;
}

.ablage-eintrag .caption {
    display: block;
}

/* Das Vorschaubild an der Stelle des Symbols. Feste Kantenlänge, damit die Zeilen gleich hoch
   bleiben — eine Liste, in der jede Zeile eine andere Höhe hat, liest sich nicht. */
.ablage-vorschau {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    object-fit: cover;
    border: 1px solid var(--color-stroke);
    border-radius: var(--radius-sm);
    background: var(--color-surface-hover);
}

/* Die große Vorschau auf der Dateiseite. 'contain' statt 'cover': Ein Beweisfoto darf nicht
   beschnitten werden, nur weil es hochkant ist. */
.vorschau-flaeche {
    display: flex;
    align-items: center;
    justify-content: center;
    max-height: 60vh;
    padding: var(--space-l);
    background: var(--color-surface-hover);
    border: 1px solid var(--color-stroke);
    border-radius: var(--radius-md);
}

.vorschau-flaeche img {
    max-width: 100%;
    max-height: 56vh;
    object-fit: contain;
}

/* Ohne Vorschau: das Typsymbol groß, damit die Seite nicht leer wirkt. */
.vorschau-ersatz {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-m);
    color: var(--color-text-secondary);
}

.vorschau-ersatz .ablage-symbol {
    width: 64px;
    height: 64px;
}

.vorschau-ersatz .ablage-symbol svg {
    width: 56px;
    height: 56px;
}

/* Das Zahnradmenü am rechten Rand der Befehlsleiste. Selten gebrauchte Vorgänge liegen darin
   statt daneben: Eine Reihe gleich aussehender Knöpfe sagt „alles gleich wichtig", und dann
   sucht man den einen, den man täglich braucht, zwischen denen, die man einmal im
   Vertragsleben anfasst.

   <details>/<summary> und kein Skriptmenü: Es klappt ohne JavaScript auf, ist mit der Tastatur
   bedienbar und trägt seinen Zustand selbst. Das Skript schließt es nur, wenn man daneben
   klickt oder Escape drückt. */
.aktionsmenue {
    position: relative;
    margin-inline-start: auto;
}

.aktionsmenue > summary {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    height: var(--control-height);
    padding: 0 var(--space-m);
    border: 1px solid var(--color-stroke-accessible);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    color: var(--color-text);
    cursor: pointer;
    list-style: none;
}

.aktionsmenue > summary::-webkit-details-marker {
    display: none;
}

.aktionsmenue > summary:hover {
    background: var(--color-surface-hover);
}

.aktionsmenue > summary:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

.aktionsmenue svg {
    width: 16px;
    height: 16px;
}

.aktionsmenue-panel {
    position: absolute;
    inset-inline-end: 0;
    z-index: 20;
    min-width: 16rem;
    margin-top: var(--space-xs);
    padding: var(--space-s);
    background: var(--color-surface);
    border: 1px solid var(--color-stroke);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-8);
}

/* Jeder Eintrag füllt die Breite des Menüs — ein Ziel, das so groß ist wie seine Zeile. */
.aktionsmenue-panel a,
.aktionsmenue-panel button,
.aktionsmenue-panel .verweisknopf {
    display: block;
    width: 100%;
    padding: var(--space-s);
    border-radius: var(--radius-sm);
    color: var(--color-text);
    text-align: start;
    text-decoration: none;
}

.aktionsmenue-panel a:hover,
.aktionsmenue-panel button:hover {
    background: var(--color-surface-hover);
    color: var(--color-text);
}

.aktionsmenue-panel form {
    margin: 0;
}

/* Selten gebrauchte Vorgänge unter der Befehlsleiste: als Verweise, nicht als Schaltflächen.
   Eine Reihe gleich aussehender Knöpfe sagt „alles gleich wichtig" — und dann sucht man den
   einen, den man täglich braucht, zwischen denen, die man einmal im Vertragsleben anfasst. */
.nebenaktionen {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-l);
    margin-top: var(--space-m);
    font-size: var(--font-size-caption);
}

/* Ein Knopf, der wie ein Verweis aussieht — für Vorgänge, die ein Formular brauchen (POST mit
   Antiforgery-Token), aber nicht wie eine Hauptaktion wirken sollen. Er bleibt ein <button>:
   Ein Verweis, der etwas ändert, wäre für Vorlesegeräte und für den Browserverlauf falsch. */
.verweisknopf {
    padding: 0;
    background: none;
    border: none;
    color: var(--color-accent);
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

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

/* Ablagefläche zum Hineinziehen. Ohne JavaScript ein gewöhnliches Formular mit Auswahlfeld;
   der gestrichelte Rahmen und der Hinweis erscheinen erst, wenn das Skript sie eingerichtet
   hat (data-dropzone-bereit). Ein Hinweis „hierher ziehen" ohne Skript wäre ein Versprechen,
   das die Seite nicht hält. */
.ablage-dropzone {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-m);
    padding: var(--space-l);
    background: var(--color-surface);
    border: 1px solid var(--color-stroke);
    border-radius: var(--radius-md);
}

.ablage-dropzone[data-dropzone-bereit] {
    border-style: dashed;
    border-color: var(--color-stroke-accessible);
}

.ablage-dropzone .zieh-hinweis {
    display: none;
    margin: 0;
    color: var(--color-text-secondary);
}

.ablage-dropzone[data-dropzone-bereit] .zieh-hinweis {
    display: block;
}

/* Beim Überziehen: Rahmen und Fläche in der Akzentfarbe — die Rückmeldung, dass hier etwas
   ankommt. Der Rahmen trägt sie, nicht nur die Farbe der Fläche (WCAG 1.4.1). */
.ablage-dropzone.ist-ziel {
    border-color: var(--color-accent);
    border-width: 2px;
    background: var(--color-accent-subtle);
}

/* Der Ordnerpfad über der Liste. Dieselbe Form wie die Brotkrumen der Seite, aber ein eigener
   Bereich — er führt innerhalb der Ablage, nicht aus ihr heraus. */
.ablagepfad ol {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-xs);
    margin: 0;
    padding: 0;
    list-style: none;
}

.ablagepfad li:not(:first-child)::before {
    content: "›";
    margin-inline-end: var(--space-xs);
    color: var(--color-text-secondary);
}

.ablagepfad [aria-current="page"] {
    font-weight: 600;
}

/* Beschreibungsliste für Stammdaten: Bezeichnung und Wert in zwei Spalten. Semantisch dl/dt/dd
   statt einer Tabelle — es sind Name-Wert-Paare, keine tabellarischen Daten (WCAG 1.3.1). */
.detail-list {
    display: grid;
    grid-template-columns: minmax(180px, 240px) 1fr;
    gap: var(--space-s) var(--space-l);
    margin: 0;
}

.detail-list dt {
    color: var(--color-text-secondary);
    font-weight: 600;
}

.detail-list dd {
    margin: 0;
}

.detail-list dd .caption {
    display: block;
}

@media (max-width: 600px) {
    .detail-list {
        grid-template-columns: 1fr;
        gap: var(--space-xs);
    }

    .detail-list dd {
        margin-bottom: var(--space-s);
    }

    /* Kein neuer Haltepunkt: app.css hat vier (1100, 900, 800, 600), ein fuenfter waere eine
       fuenfte Wahrheit ueber "schmal". Bei 400 % Zoom auf 1280 px (= 320 px, WCAG 1.4.10) greift
       dieser Zweig ebenfalls: 320 - 2x12 - 2x16 = 256 px Inhaltsbreite in der Karte. */
    .schlicht-inhalt {
        padding: var(--space-xl) var(--space-m);
    }

    .schlicht .card {
        padding: var(--space-l);
    }
}

/* Kopfzeile einer Betriebskarte: Name links, Nutzerzahl rechts. */
.company-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-m);
    margin-bottom: var(--space-m);
}

.company-header h3 {
    margin: 0;
}

.company-header p {
    margin: var(--space-xs) 0 0;
}

/* Zuordnungsformular am Fuß einer Betriebskarte. */
.assign-form {
    display: flex;
    align-items: flex-end;
    gap: var(--space-m);
    margin-top: var(--space-l);
    padding-top: var(--space-l);
    border-top: 1px solid var(--color-stroke);
}

.assign-form .field {
    margin-bottom: 0;
    min-width: 280px;
    max-width: 420px;
}

/* Mehrere Aktionen in einer Tabellenzelle. */
.row-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
    margin-top: var(--space-xs);
}

/* ── Hinweise (Fluent MessageBar) ───────────────────────────────────────────────────────────── */

.notice {
    display: flow-root;
    margin-bottom: var(--space-l);
    padding: var(--space-m) var(--space-l);
    border-radius: var(--radius-sm);
    border-left: 3px solid var(--color-info);
    background: var(--color-info-subtle);
    color: var(--color-text);
}

.notice p {
    margin: 0 0 var(--space-s);
}

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

.notice-warning {
    border-left-color: var(--color-warning);
    background: var(--color-warning-subtle);
}

.notice-error {
    border-left-color: var(--color-danger);
    background: var(--color-danger-subtle);
}

.notice-success {
    border-left-color: var(--color-success);
    background: var(--color-success-subtle);
}

/* Leere Validierungszusammenfassung nicht als leeren Kasten zeigen. */
.notice:empty,
.validation-summary-valid {
    display: none;
}

.field-validation-error {
    display: block;
    margin-top: var(--space-xs);
    color: var(--color-danger);
    font-size: var(--font-size-caption);
}

/* Umgebungsbanner — verhindert, dass Preview für Produktion gehalten wird. */
.env-banner {
    padding: var(--space-xs) var(--space-l);
    text-align: center;
    background: var(--color-warning-subtle);
    color: var(--color-warning);
    font-size: var(--font-size-caption);
    font-weight: 600;
    border-bottom: 1px solid var(--color-stroke);
}

/* ── Leerer Zustand ─────────────────────────────────────────────────────────────────────────── */

.empty-state {
    padding: var(--space-xxl);
    text-align: center;
    background: var(--color-surface);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-2);
}

/*
 * 'margin-inline: auto' ist hier nicht kosmetisch: Der Absatz erbt weiter oben ein
 * 'max-width: 90ch'. Ohne automatischen Außenabstand steht der schmalere Block linksbündig in der
 * zentrierten Fläche — der Text darin ist zentriert, der Block aber nicht, und genau das sieht
 * schief aus.
 */
.empty-state p {
    margin: 0 auto var(--space-l);
    color: var(--color-text-secondary);
}

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

/* Hinweis mit Bezug zur Akzentfarbe — für Dinge, die warten, nicht für Fehler. */
.notice-info {
    border-inline-start: 3px solid var(--color-info);
    background: var(--color-info-subtle);
}

/* ── Seitenweise Navigation ─────────────────────────────────────────────────────────────────── */

.pager {
    display: flex;
    align-items: center;
    gap: var(--space-m);
    margin-top: var(--space-l);
}

.pager-status {
    color: var(--color-text-secondary);
    font-size: var(--font-size-caption);
}

/* ── Theme-Umschalter ───────────────────────────────────────────────────────────────────────── */

/* Ein Symbol für beide Zustände. Der Zustand steckt in aria-pressed — verlässlich für
   Screenreader — und wird visuell durch die Akzentfarbe des gedrückten Zustands gezeigt. */
.theme-toggle svg {
    width: 20px;
    height: 20px;
}

.theme-toggle[aria-pressed="true"] {
    background: var(--color-accent-subtle);
    color: var(--color-accent);
}

/* ── Schmale Fenster ────────────────────────────────────────────────────────────────────────── */

@media (max-width: 800px) {
    .shell {
        grid-template-columns: 1fr;
        grid-template-areas:
            "topbar"
            "nav"
            "main";
    }

    .sidebar {
        border-right: none;
        border-bottom: 1px solid var(--color-stroke);
        padding: var(--space-s);
    }

    .sidebar ul {
        display: flex;
        flex-wrap: wrap;
        gap: var(--space-xs);
        margin-bottom: var(--space-s);
    }

    .content {
        padding: var(--space-l);
    }
}

/* ── Druck (Nachweise, Protokolle) ──────────────────────────────────────────────────────────── */

@media print {
    .topbar,
    .sidebar,
    .skip-link,
    .command-bar-actions,
    .env-banner {
        display: none;
    }

    .shell {
        display: block;
    }

    .content {
        padding: 0;
        max-width: none;
    }

    /* '.schlicht .card' muss ausdruecklich dabeistehen: Es hat 0,2,0 und schluege '.card'
       (0,1,0) hier. Ohne diese Zeile wuerde die Anmeldekarte mit '--shadow-8' gedruckt — auf
       Papier ein grauer Schmier. Mit gleicher Spezifitaet und weiter unten in der Datei gewinnt
       die Druckregel wieder. */
    .card,
    .schlicht .card,
    .list-surface,
    .empty-state {
        box-shadow: none;
        border: 1px solid var(--color-stroke);
    }
}

/* ── Bewegungsreduzierung ───────────────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* ── Erzwungene Farben (Windows-Kontrastmodus) ──────────────────────────────────────────────────
 *
 * Im Kontrastmodus ersetzt das Betriebssystem alle Farben und entfernt Hintergründe und Schatten.
 * Karten, Listen und Statusmeldungen wären dann nicht mehr voneinander abgegrenzt. Deshalb hier
 * ausdrückliche Rahmen aus Systemfarben — und der Fokusring bekommt eine Systemfarbe, weil eigene
 * Farben ignoriert werden.
 */

@media (forced-colors: active) {
    /* Derselbe Spezifitaetsfall wie im Druck, und dieser ist der gefaehrlichere: Im
       Windows-Kontrastmodus entfernt das System Hintergruende und Schatten. Dieser Block gibt der
       Karte deshalb eine Kante aus CanvasText. '.schlicht .card' (0,2,0) haette die Schattenregel
       (0,1,0) ueberstimmt, und die einzige verlaessliche Abgrenzung der Anmeldekarte haette an
       einer Erhebung gehangen, die dort niemand sieht. */
    .card,
    .schlicht .card,
    .list-surface,
    .empty-state,
    .command-bar,
    .notice {
        border: 1px solid CanvasText;
        box-shadow: none;
    }

    .badge {
        border: 1px solid CanvasText;
    }

    .button {
        border: 1px solid ButtonText;
    }

    .sidebar a[aria-current="page"] {
        /* Die Hervorhebung über Hintergrundfarbe entfällt; Unterstreichung tritt an ihre Stelle. */
        text-decoration: underline;
        text-underline-offset: 3px;
    }

    :focus-visible {
        outline: 3px solid Highlight;
        box-shadow: none;
    }

    .theme-toggle svg {
        fill: ButtonText;
    }
}

/* ── Verstärkter Kontrast (Systemeinstellung) ───────────────────────────────────────────────────
 *
 * Wenn das System mehr Kontrast anfordert, werden Trennlinien und Umrisse kräftiger. Die
 * Textfarben erfüllen bereits AAA und bleiben unverändert.
 */

@media (prefers-contrast: more) {
    :root {
        --color-stroke: #767676;
        --color-stroke-strong: #4d4d4d;
        --color-stroke-accessible: #242424;
        --color-text-secondary: #242424;
    }

    :root[data-theme="dark"] {
        --color-stroke: #8f8f8f;
        --color-stroke-strong: #c7c7c7;
        --color-stroke-accessible: #f5f5f5;
        --color-text-secondary: #f5f5f5;
    }
}

/* ── Öffentliche Prüfabfrage (ADR 0017) ──────────────────────────────────────────────────────
 *
 * Eine einzige Seite unter der eigenen Domäne eines Mandanten, ohne Anmeldung und ohne
 * Navigation. Sie wird auf einem Telefon benutzt, in einer Werkhalle, oft bei schlechtem Licht
 * und mit Handschuhen — deshalb große Schrift, große Berührflächen und ein Ergebnis, das man
 * aus einem Meter Abstand erkennt.
 *
 * Alle Farben kommen aus Token. Haken und Kreuz tragen die Bedeutung nie allein: Daneben steht
 * der Klartext, und das Zeichen trägt sie in der Form (WCAG 1.4.1). Die verwendeten Paare
 * (Erfolgstext auf Erfolgsfläche, Fehlertext auf Fehlerfläche) sind in
 * scripts/pruefe-kontrast.py nachgerechnet. */

body.oeffentlich {
    background: var(--color-canvas);
    display: flex;
    justify-content: center;
}

.oeffentlich-blatt {
    width: 100%;
    max-width: 34rem;
    padding: var(--space-l) var(--space-m) var(--space-xl);
}

.oeffentlich-kopf {
    display: flex;
    justify-content: center;
    margin-bottom: var(--space-l);
}

.oeffentlich-logo {
    max-height: 3.5rem;
    max-width: 100%;
    object-fit: contain;
}

.oeffentlich-anbieter {
    font-size: var(--font-size-subtitle);
    font-weight: 600;
    color: var(--color-text);
    margin: 0;
}

.oeffentlich-blatt h1 {
    text-align: center;
}

.oeffentlich-blatt > .lead {
    text-align: center;
    margin-bottom: var(--space-l);
}

/* Das Eingabefeld ist der Zweck der Seite — entsprechend groß.
 *
 * 1,25rem Schriftgröße ist kein Geschmack: Unterhalb von 16px zoomt Safari auf dem iPhone beim
 * Hineintippen die ganze Seite heran, und der Nutzer landet in einer verschobenen Ansicht. */
.oeffentlich-blatt .field input {
    font-size: var(--font-size-subtitle);
    padding: var(--space-s) var(--space-m);
}

.oeffentlich-blatt .button {
    width: 100%;
    justify-content: center;
    min-height: 3rem;
    font-size: var(--font-size-body);
}

.oeffentlich-ergebnis {
    margin-top: var(--space-l);
}

.oeffentlich-geraet {
    font-size: var(--font-size-subtitle);
    font-weight: 600;
    color: var(--color-text);
    text-align: center;
    margin: 0 0 var(--space-m);
}

.oeffentlich-status {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-s);

    font-size: var(--font-size-display);
    font-weight: 600;

    padding: var(--space-l) var(--space-m);
    border-radius: var(--radius-md);

    /* Ohne Aussage: Für „mehrdeutig" und „nichts gefunden" gibt es kein Grün und kein Rot —
       beides wäre eine Antwort, die wir nicht geben. */
    background: var(--color-surface);
    color: var(--color-text);
    margin: 0 0 var(--space-m);
    text-align: center;
}

.oeffentlich-status.ist-geprueft {
    background: var(--color-success-subtle);
    color: var(--color-success);
}

.oeffentlich-status.nicht-geprueft {
    background: var(--color-danger-subtle);
    color: var(--color-danger);
}

.oeffentlich-zeichen {
    width: 2.5rem;
    height: 2.5rem;
    flex: none;
}

.oeffentlich-ergebnis .caption {
    text-align: center;
    display: block;
}

.oeffentlich-fuss {
    margin-top: var(--space-xl);
    padding-top: var(--space-m);
    border-top: 1px solid var(--color-stroke);
    text-align: center;
}

/* ── Wort-Bild-Marke ─────────────────────────────────────────────────────────────────────────
 *
 * Als Hintergrundgrafik und nicht als <img>: Nur so lässt sich die Fassung über das Farbschema
 * umschalten. Den Alternativtext trägt deshalb der umgebende Verweis bzw. Behälter (aria-label),
 * die Grafik selbst ist für Bildschirmleser unsichtbar.
 *
 * Eigene Dateien, eigener Ursprung — die CSP erlaubt keine fremden Quellen (MANIFEST §2). */

.brand-logo {
    display: block;
    width: 9.5rem;
    height: 2.25rem;
    background: url("../img/preventra-quer.png") no-repeat left center;
    background-size: contain;
}

.brand-schrift {
    display: none;
    align-items: center;
    gap: var(--space-s);
}

/* Im dunklen Schema wäre die dunkelblaue Schrift der Querfassung unlesbar. Bis eine weiße
 * Querfassung vorliegt, tritt dort der Schriftzug an ihre Stelle — kein Ersatz, ein Notnagel. */
:root[data-theme="dark"] .brand-logo {
    display: none;
}

:root[data-theme="dark"] .brand-schrift {
    display: inline-flex;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .brand-logo {
        display: none;
    }

    :root:not([data-theme="light"]) .brand-schrift {
        display: inline-flex;
    }
}

/* Die gestapelte Fassung auf den Seiten vor der Anmeldung — von ihr gibt es beide Farben. */
.marke-hoch {
    display: block;
    width: 7.5rem;
    height: 6.6rem;
    margin: 0 auto;
    background: url("../img/preventra-hoch.png") no-repeat center / contain;
}

:root[data-theme="dark"] .marke-hoch {
    background-image: url("../img/preventra-hoch-weiss.png");
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .marke-hoch {
        background-image: url("../img/preventra-hoch-weiss.png");
    }
}

/* Die Auswahlspalte in Zuordnungslisten: so schmal wie das Kästchen, damit die Spalte daneben
 * nicht verrutscht. */
.spalte-auswahl {
    width: 2.5rem;
    text-align: center;
}

/* ── QR-Code einlesen (öffentliche Prüfabfrage) ──────────────────────────────────────────────
 *
 * Das Symbol steht unter dem Eingabefeld und nicht darin: In einem Feld hätte es keine
 * Berührfläche von 44 px, die eine Hand mit Handschuh trifft (WCAG 2.5.5). */

.nummer-kamera {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    min-height: 2.75rem;
    margin-top: var(--space-xs);
}

.nummer-kamera svg {
    width: 1.25rem;
    height: 1.25rem;
    flex: none;
}

.qr-sucher {
    margin-top: var(--space-m);
    text-align: center;
}

.qr-sucher video {
    width: 100%;
    max-width: 100%;
    border-radius: var(--radius-md);
    background: var(--color-canvas);

    /* Ein hohes Bild fuellt sonst den Bildschirm, und die Schaltflaeche zum Abbrechen liegt
       unterhalb des sichtbaren Bereichs — ausgerechnet die, die man dann sucht. */
    max-height: 60vh;
    object-fit: cover;
}

/* Die rechtliche Fußzeile. Unaufdringlich, aber auf jeder Seite — § 5 DDG verlangt „ständig
 * verfügbar", nicht „auffällig". */
.rechtsfuss {
    margin-top: var(--space-xl);
    padding-top: var(--space-m);
    border-top: 1px solid var(--color-stroke);
    display: flex;
    gap: var(--space-s);
    justify-content: center;
    font-size: var(--font-size-caption);
    color: var(--color-text-secondary);
}

.rechtsfuss a {
    color: var(--color-text-secondary);
}
