/* ============================================================================
   components.css — globale Komponenten- & Control-Styles
   ----------------------------------------------------------------------------
   Enthält: FluentUI-Control-Overrides (::part()), Header-/Tool-Container,
   YearMonth-Feld (.ym-*), NumberSpinner (.ns-*), Tabellen/DataGrid, Dialoge,
   Preview-/Diagnostics-Layout, Error-Modals, Farbswatches (.w4l-swatch*),
   Szenario-Pills (.w4l-pill* — NB: Szenario-Auswahl, nicht die Toggle-Pills
   aus utilities.css).

   W4L-Design-Tokens leben in tokens.css. Grund-Layout/Chrome in base.css.
   Geteilte Bausteine + Layout-Utilities in utilities.css.
   ============================================================================ */

/* ==========================================================================
   Reconnect Modal Fokus-Styling entfernen
   ========================================================================== */
#components-reconnect-modal:focus-visible {
    outline: none;
}


/* ==========================================================================
    Header Styles
   ========================================================================== */
/* Desktop - Standard */

/* FluentBodyContent: verhindert Overflow im Flex-Container */
#body-content,
fluent-body-content {
    min-width: 0;
    flex: 1 1 auto;
    overflow: hidden;
}

/* FluentCard: FAST setzt im Shadow-Stylesheet `:host { content-visibility: auto }`
   (+ `contain: content`) als Render-Optimierung. In iPadOS/macOS Safari 18 ist
   content-visibility:auto in verschachtelten Scroll-Containern (unsere Scroll-
   Roots .marketing-layout-wrapper / .content-height, nicht das Dokument) kaputt:
   Cards, die aus dem Viewport scrollen, werden «skipped» und verlieren ihre
   Höhe, der Inhalt darunter springt hoch, die Cards rücken dadurch wieder in
   den Relevanz-Bereich und expandieren — eine Layout-Oszillation, die Safari als
   flackernde, doppelt gezeichnete Stale-Tiles rendert (About-Seite: CTA «Curious
   to find out?» + Footer zweimal übereinander, 2026-08-20, iPad Air). Chrome
   zeigt nichts davon, weil es die «last remembered size» korrekt einsetzt.
   Der Perf-Gewinn ist bei unseren Card-Mengen null — Feature global aus. */
fluent-card {
    content-visibility: visible;
}

.content-area {
    /*padding: 1.5rem 1.5rem 1.5rem 0;*/
    width: 100%;
    min-width: 0; /* wichtig: verhindert Overflow im Flex-Container */
    flex: 1 1 auto;
}

.logo-container {
    width: 260px;
}

.tool-container {
    display: flex;
    align-items:center;
    justify-content: flex-end;
    gap: 8px;
    width: 260px;
    padding: 3px 0;
    margin-right: 0;
}

.tool-container .hide-on-mobile {
    display: flex;
    align-items: center;
    gap: 8px;
}

.language-select-no-arrow::part(indicator) {
    display: none !important;
}

/* Gleicher Footprint wie die Icon-Buttons daneben (fluent-button.header: 32×32) —
   die Selects sollen in der Tool-Leiste nicht breiter wiegen als Help/Chat/Bot.
   FAST-Selects defaulten auf min-width:250px; ohne expliziten Reset bliebe der
   Host breiter als die 32px. */
.language-select-no-arrow {
    width: 32px;
    min-width: 32px;
}

.language-select-no-arrow::part(control) {
    padding-right: 0 !important;
    padding-left: 0 !important;
}

.language-select-no-arrow::part(selected-value) {
    text-align: center !important;
    justify-content: center !important;
    margin: 0 !important;
}

/* Das aufgeklappte Menü darf NICHT auf die 32px des Hosts schrumpfen — es
   nimmt seine natürliche Inhaltsbreite und richtet sich weiter am Host aus. */
.language-select-no-arrow::part(listbox) {
    min-width: max-content;
}

.language-select-no-arrow.theme-select::part(control) {
    font-size: 20px;
}

.language-select-no-arrow.theme-select::part(selected-value) {
    font-size: 20px;
}

.language-select-no-arrow.theme-select fluent-option {
    font-size: 18px;
}


.transparent-field::part(root) {
    background-color: transparent !important;
    border-color: transparent !important;
}

.transparent-field::part(control) {
    background-color: transparent !important;
}



/*fluent-text-field.fluent-large {
    !* skaliert die gesamte Control-Höhe (Default ≈ 8) *!
    --base-height-multiplier: 10;

    !* Schriftgröße korrekt über Fluent-Typografie *!
    --type-ramp-base-font-size: 16px;
}*/

/* Größerer Text + höheres Feld (Host + Shadow Parts) */
fluent-text-field.fluent-large,
fluent-number-field.fluent-large {
    height: 44px;              /* gewünschte Gesamthöhe */
    min-height: 44px;
}

/* Der eigentliche Container im Shadow-DOM */
fluent-text-field.fluent-large::part(root),
fluent-number-field.fluent-large::part(root) {
    height: 100%;
    min-height: 100%;
    align-items: center;       /* vertikal zentrieren */
}

/* Das <input> im Shadow-DOM */
fluent-text-field.fluent-large::part(control),
fluent-number-field.fluent-large::part(control) {
    height: 100%;
    font-size: 20px;           /* gewünschte Schriftgrösse */
    font-weight: 500;
    line-height: 1.2;
    padding-block: 0;          /* verhindert "Unterlinie zu tief"-Effekt durch Extra-Padding */
}

/* Falls du ein Start-Icon hast: sorgt dafür, dass es nicht die Höhe "sprengt" */
fluent-text-field.fluent-large::part(start),
fluent-number-field.fluent-large::part(start) {
    display: flex;
    align-items: center;
}

/* Spinner-Controls für number-field kompakt halten */
fluent-number-field.fluent-large::part(controls) {
    height: 100%;
}

/* Chrome/Edge Autofill: verhindert, dass der Browser die Schriftgrösse "zurücksetzt" */
fluent-text-field.fluent-large::part(control):-webkit-autofill,
fluent-text-field.fluent-large::part(control):-webkit-autofill:hover,
fluent-text-field.fluent-large::part(control):-webkit-autofill:focus {
    font-size: 20px !important;
    font-weight: 500;
    line-height: 1.2 !important;
}

/* Kleinerer Text + niedrigeres Feld (Host + Shadow Parts) */
fluent-text-field.fluent-small,
fluent-number-field.fluent-small {
    height: 28px;              /* gewünschte Gesamthöhe */
    min-height: 28px;
}

/* Der eigentliche Container im Shadow-DOM */
fluent-text-field.fluent-small::part(root),
fluent-number-field.fluent-small::part(root) {
    height: 100%;
    min-height: 100%;
    align-items: center;       /* vertikal zentrieren */
}

/* Das <input> im Shadow-DOM */
fluent-text-field.fluent-small::part(control),
fluent-number-field.fluent-small::part(control) {
    height: 100%;
    font-size: 12px;           /* gewünschte Schriftgrösse */
    font-weight: 400;
    line-height: 1.2;
    padding-block: 0;          /* verhindert "Unterlinie zu tief"-Effekt durch Extra-Padding */
}

/* Falls du ein Start-Icon hast: sorgt dafür, dass es nicht die Höhe "sprengt" */
fluent-text-field.fluent-small::part(start),
fluent-number-field.fluent-small::part(start) {
    display: flex;
    align-items: center;
}

/* Spinner-Controls für number-field kompakt halten */
fluent-number-field.fluent-small::part(controls) {
    height: 100%;
}

/* Chrome/Edge Autofill: verhindert, dass der Browser die Schriftgrösse "zurücksetzt" */
fluent-text-field.fluent-small::part(control):-webkit-autofill,
fluent-text-field.fluent-small::part(control):-webkit-autofill:hover,
fluent-text-field.fluent-small::part(control):-webkit-autofill:focus {
    font-size: 12px !important;
    font-weight: 400;
    line-height: 1.2 !important;
}

/* ---------------------------------------------------------------------------
   Globale Autofill-Korrektur für ALLE FluentTextField-Inputs.

   Chromium/Edge übermalen autofillte Inputs mit einem eigenen Hintergrund
   (hellblau im Light-Mode, weiss im Dark-Mode) und ignorieren dabei
   `background-color`. Das fällt z.B. im Login-Form auf, sobald der Browser
   ein gespeichertes Passwort einsetzt. Der einzige zuverlässige Workaround
   ist ein riesiger inset box-shadow, der den Autofill-Layer überdeckt, plus
   `-webkit-text-fill-color` für die Textfarbe. Funktioniert auch über
   ::part(control) hinweg ins Shadow-DOM des Web Components.
   --------------------------------------------------------------------------- */
fluent-text-field::part(control):-webkit-autofill,
fluent-text-field::part(control):-webkit-autofill:hover,
fluent-text-field::part(control):-webkit-autofill:focus,
fluent-text-field::part(control):-webkit-autofill:active {
    -webkit-box-shadow: 0 0 0 1000px var(--neutral-fill-input-rest) inset !important;
    -webkit-text-fill-color: var(--neutral-foreground-rest) !important;
    caret-color: var(--neutral-foreground-rest);
    /* Riesige Transition verhindert das kurze Aufblitzen der Browser-Farbe. */
    transition: background-color 5000s ease-in-out 0s;
}


/* Wiederverwendbare Klasse für FluentSelect ohne min-width */
.fluent-select-responsive {
    min-width: 0 !important;
    max-width: 100%;
}

.fluent-card-switched {
    align-self: flex-start;
    transition: opacity 0.2s ease;
    opacity: 0.7;

    &.enabled {
        opacity: 1;
    }
}

/* ---------------------------------------------------------------------------
   FluentMessageBar — theme-aware Intent-Flächen.

   Die Library hartcodet für jedes Intent eine helle Fläche (`intent-error`
   → #FDF3F4) und kennt nur eine `.dark`-Variante, die an einer eigenen
   Luminanz-Erkennung hängt und bei uns nicht greift. Der Text kommt aber aus
   `--neutral-foreground-rest` (theme-aware) — im Dark-Mode stand also heller
   Text auf fast weisser Fläche (z.B. „Email is required." im Login-Dialog).

   Wir mischen die Fläche stattdessen aus der Status-Farbe und der theme-aware
   Layer-Farbe des MessageBars, das funktioniert in beiden Themes ohne Klasse.

   Spezifität: die Library-Regeln sind scoped (`[b-…]`) und laden nach uns
   (W4L.Web.styles.css). `body …[class]` hebt uns knapp über die Light-Regel,
   lässt aber deren spezifischere `.dark`-Variante gewinnen, falls sie in einer
   künftigen Version doch greift — deren Dark-Farben sind ebenfalls lesbar.
   --------------------------------------------------------------------------- */
body .fluent-messagebar[class].intent-error {
    background-color: color-mix(in srgb, var(--w4l-negative) 12%, var(--neutral-layer-floating));
    border: 1px solid color-mix(in srgb, var(--w4l-negative) 45%, var(--neutral-layer-floating));
}

body .fluent-messagebar[class].intent-warning {
    background-color: color-mix(in srgb, var(--w4l-warning) 12%, var(--neutral-layer-floating));
    border: 1px solid color-mix(in srgb, var(--w4l-warning) 45%, var(--neutral-layer-floating));
}

body .fluent-messagebar[class].intent-success {
    background-color: color-mix(in srgb, var(--w4l-positive) 12%, var(--neutral-layer-floating));
    border: 1px solid color-mix(in srgb, var(--w4l-positive) 45%, var(--neutral-layer-floating));
}

body .fluent-messagebar[class].intent-info {
    background-color: color-mix(in srgb, var(--w4l-info) 8%, var(--neutral-layer-floating));
    border: 1px solid var(--neutral-stroke-rest);
}

/****************************************************************************************/
/* ==========================================================================
   YearMonth fields — fluent-number-field look, leak-free (native inputs only).
   Shared chrome for YearMonthField / YearMonthDurationField. CSS ported from
   the FAST fluent-number-field shadow DOM (Microsoft.FluentUI 4.14.1).
   ========================================================================== */

/* :host equivalent — the outer wrapper */
.ym-field {
    display: inline-block;
    box-sizing: border-box;
    max-width: 100%;
    position: relative;
    color: var(--neutral-foreground-rest);
    fill: currentcolor;
    user-select: none;
    font-family: var(--body-font);
    font-size: var(--type-ramp-base-font-size, 14px);
    line-height: var(--type-ramp-base-line-height, 20px);
}

.ym-label {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 8px;
    cursor: pointer;
    color: var(--neutral-foreground-rest);
    font-size: var(--type-ramp-base-font-size, 14px);
    line-height: var(--type-ramp-base-line-height, 20px);
    margin-bottom: 4px;
}

/* In a YearMonthField the label text is wrapped in its own span; let it shrink and
   ellipsis in narrow grid columns so the age chips never wrap under or overflow it.
   Other .ym-label users render their text directly (no child span), so they are
   unaffected by this selector. */
.ym-label > span:first-child {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Right-aligned container for one or more age chips (see YearMonthField Ages). */
.ym-ages {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
}

/* Subtle age chip, right-aligned in the label (see YearMonthField BirthDate/Ages).
   The transparent border is the resting state; colour-coded chips override
   border-color + color inline (AgeChipStyle) for per-person identity. */
.ym-age {
    flex: 0 0 auto;
    font-size: 11px;
    line-height: 15px;
    color: var(--neutral-foreground-hint);
    background: var(--neutral-fill-secondary-rest);
    border: calc(var(--stroke-width, 1) * 1px) solid transparent;
    border-radius: calc(var(--control-corner-radius, 4) * 1px);
    padding: 0 5px;
    font-variant-numeric: tabular-nums;
}

/* .root equivalent — the bordered control row.
   Reproduces FAST's outline-appearance border exactly: a transparent border
   plus a padding-box/border-box background pair. --neutral-stroke-input-rest
   carries the fine bottom-emphasised underline of a resting text-field. */
.ym-row {
    box-sizing: border-box;
    width: 100%;
    position: relative;
    display: flex;
    flex-direction: row;
    align-items: center;
    color: inherit;
    border: calc(var(--stroke-width, 1) * 1px) solid transparent;
    border-radius: calc(var(--control-corner-radius, 4) * 1px);
    background:
        padding-box linear-gradient(var(--neutral-fill-input-rest), var(--neutral-fill-input-rest)),
        border-box var(--neutral-stroke-input-rest);
    height: calc((var(--base-height-multiplier, 8) + var(--density, 0)) * var(--design-unit, 4) * 1px);
}

.ym-row:hover {
    background:
        padding-box linear-gradient(var(--neutral-fill-input-hover), var(--neutral-fill-input-hover)),
        border-box var(--neutral-stroke-input-hover);
}

.ym-field:focus-within .ym-row {
    background:
        padding-box linear-gradient(var(--neutral-fill-input-focus), var(--neutral-fill-input-focus)),
        border-box var(--neutral-stroke-input-rest);
}

.ym-row.ym-disabled {
    opacity: var(--disabled-opacity, 0.3);
    cursor: not-allowed;
    background:
        padding-box linear-gradient(var(--neutral-fill-input-rest), var(--neutral-fill-input-rest)),
        border-box var(--neutral-stroke-rest);
}

.ym-row.ym-disabled * {
    pointer-events: none;
}

/* EditContext invalid state (TextField / FluentInputBase fields) */
.ym-row.invalid {
    background:
        padding-box linear-gradient(var(--neutral-fill-input-rest), var(--neutral-fill-input-rest)),
        border-box var(--error, #d13438);
}

/* focus underline — full-width accent stroke, scales in on focus.
   Spans the whole field (not a partial segment). */
.ym-row::after {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: calc(var(--focus-stroke-width, 2) * 1px);
    border-bottom: calc(var(--focus-stroke-width, 2) * 1px) solid var(--accent-fill-rest);
    border-bottom-left-radius: calc(var(--control-corner-radius, 4) * 1px);
    border-bottom-right-radius: calc(var(--control-corner-radius, 4) * 1px);
    transform: scaleX(0);
    transition: transform 300ms cubic-bezier(0.1, 0.9, 0.2, 1);
    z-index: 2;
}

.ym-field:focus-within .ym-row::after {
    transform: scaleX(1);
}

.ym-row.ym-disabled::after {
    content: none;
}

/* layout — deterministic widths; the spacer absorbs all stretch */
.ym-icon {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    margin-inline-start: 11px;
    fill: currentcolor;
}

.ym-sep {
    flex: 0 0 auto;
    padding: 0 1px;
    color: var(--neutral-foreground-hint, var(--neutral-foreground-rest));
}

/* prefix / suffix affixes (units like "%", "CHF") */
.ym-affix {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    white-space: nowrap;
    color: var(--neutral-foreground-hint, var(--neutral-foreground-rest));
}

.ym-affix-prefix {
    margin-inline-start: 11px;
}

.ym-affix-suffix {
    margin-inline-end: 11px;
}

/* native text input filling the row (TextField) */
.ym-text-input {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    padding: 0 10px;
    border: 0;
    outline: none;
    background: transparent;
    color: inherit;
    font-family: inherit;
    font-size: inherit;
    line-height: inherit;
}

.ym-text-input:disabled {
    cursor: not-allowed;
}

/* header-size variant (TextField Large="true") — taller row, larger bolder text */
.ym-row.ym-large {
    height: 44px;
}

.ym-row.ym-large .ym-text-input {
    font-size: 20px;
    font-weight: 500;
    line-height: 1.2;
}

/* compact variant — dense grids (e.g. per-year IK income editor) */
.ym-row.ym-compact {
    height: 26px;
}

.ym-row.ym-compact .ns-input,
.ym-row.ym-compact .ym-text-input,
.ym-row.ym-compact .ym-affix {
    font-size: 13px;
}

.ym-row.ym-compact .ym-affix-suffix {
    margin-inline-end: 8px;
}

/* reset button — revealed on hover / focus */
.ym-reset {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 8px 0 0;
    padding: 2px;
    border: 0;
    background: transparent;
    color: var(--neutral-foreground-rest);
    fill: currentcolor;
    cursor: pointer;
    border-radius: calc(var(--control-corner-radius, 4) * 1px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.1s ease-in-out;
}

.ym-row:hover .ym-reset,
.ym-field:focus-within .ym-reset {
    opacity: 1;
    pointer-events: auto;
}

/* persistently visible once the value differs from its default (discoverable revert) */
.ym-reset.ym-reset-changed {
    opacity: 0.65;
    pointer-events: auto;
}

.ym-row:hover .ym-reset.ym-reset-changed,
.ym-field:focus-within .ym-reset.ym-reset-changed {
    opacity: 1;
}

.ym-reset:hover {
    background: var(--neutral-fill-secondary-hover, rgba(0, 0, 0, 0.06));
}

/* reveal the NumberSpinner chevrons when the whole field is hovered/focused */
.ym-row:hover .ns-controls,
.ym-field:focus-within .ns-controls {
    opacity: 1;
    pointer-events: auto;
}

/* YearMonthRangeField — two fields side by side, one column on small screens */
.ym-range {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
}

@media (max-width: 639px) {
    .ym-range {
        grid-template-columns: 1fr;
    }
}

/* At-max constraint hint below the range fields (shown only while To sits at MaxTo) */
.ymr-max-hint {
    margin-top: 4px;
    font-size: 12px;
    color: var(--neutral-foreground-hint);
}

/****************************************************************************************/


.navmenu-item-container {
    display: flex;
    padding: 8px;
    background-color: var(--neutral-fill-stealth-rest);
    border-radius: calc(var(--control-corner-radius) * 1px);
    margin: calc(var(--design-unit) * 1px) 0;
}
/* Tablet (900px - 1279px) */
@media (min-width: 900px) and (max-width: 1279px) {
    .hide-on-tablet {
        display: none !important;
    }

    .logo-container {
        width: 260px;
    }

    .tool-container {
        width: 260px;
    }
}

/* Mobile-Shell (≤899px = md): Header-Tools weg, Burger übernimmt */
@media (max-width: 899px) {
    .hide-on-mobile {
        display: none !important;
    }

    .show-on-mobile {
        display: block !important;
    }

    .logo-container {
        width: 160px;
    }

    .tool-container {
        width: auto;
        margin-right: 30px;
    }
}

/* ==========================================================================
   Logo
   ========================================================================== */

.w4l-logo {

    /* Smoother edges when the detailed mark is scaled down (e.g. 32px header) */
    shape-rendering: geometricPrecision;
    text-rendering: geometricPrecision;

    /* Farben */

    .logo-mark path {
        fill: var(--accent-fill-rest);
    }

    .wealth-text path {
        fill: var(--neutral-foreground-rest);
    }

    .life-text path {
        fill: var(--accent-fill-rest);
    }

    &.header {
        margin: 2px 0;
        height: 32px;
    }
}

/* Tenant-uploaded raster logo (BrandLogo.razor) — replaces the inline SVG mark.
   Same footprint as .w4l-logo.header; width follows the image's aspect ratio. */
img.brand-logo-img {
    display: block;
    max-width: 100%;
    object-fit: contain;

    &.header {
        margin: 2px 0;
        height: 32px;
        width: auto;
    }
}

/* ==========================================================================
   Header Button
   ========================================================================== */

fluent-button.header {
    width: 32px;
    height: 32px;

    &::part(control) {
        background: transparent !important;
        border: none !important;
        box-shadow: none !important;
        transition: background 0.15s ease;
    }

    &:hover {
        &::part(control) {
            background: var(--neutral-fill-input-hover) !important;
        }
    }

    &:active {
        /* setzt die Vordergrundfarbe (Text/Icon) auf Accent */
        --foreground-rest: var(--accent-fill-rest);
        --foreground-active: var(--accent-fill-rest);

        &::part(control) {
            background: var(--accent-fill-active, var(--accent-fill-rest)) !important;
        }
    }
}

fluent-select.header {
    height: 32px;

    &::part(control) {
        background: transparent !important;
        border: none !important;
        box-shadow: none !important;
        transition: background 0.15s ease;
    }

    &:hover {
        &::part(control) {
            background: var(--neutral-fill-input-hover) !important;
        }
    }

    &:active {
        &::part(control) {
            background: var(--accent-fill-active, var(--accent-fill-rest)) !important;
        }
    }
}

/* ==========================================================================
   Table Action Button Styles
   - Stil für Aktionsschaltflächen in Tabellenzellen
   - Fokus-Styling im Fluent-Stil
   - Icon immer klar sichtbar
   ========================================================================== */

.table-action-button {
    background-color: transparent !important;
    border: none !important;
    padding: 4px;
    border-radius: 4px;
    transition: background-color 0.15s ease, box-shadow 0.15s ease;

    &:hover {
        background-color: rgba(0, 0, 0, 0.06);
        cursor: pointer;
    }

    &:active {
        background-color: rgba(0, 0, 0, 0.10);
        box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.15);
    }

    /* Fokus-Styling im Fluent-Stil */

    &:focus-visible {
        outline: 2px solid var(--accent-fill-rest);
        outline-offset: 2px;
    }

    /* Icon immer klar sichtbar */

    fluent-icon {
        opacity: 1 !important;
    }
}

/* Native <select>-Helfer (.w4l-select*, .w4l-neb-table*, .w4l-select-label)
   → utilities.css. */

/* DataGrid selected-row: die Basis-Regel (+ Zell-/::part-Varianten) lebt in
   base.css; hier nur der Hover-State. */
.selected-row:hover {
    background-color: var(--accent-fill-hover) !important;
}

/* ==========================================================================
   Marriage Inventory entry cards (Anfangsvermögen-Form)
   Card-like wrapper with subtle accent rail to separate Items visually.
   ========================================================================== */
.w4l-inventory-entry {
    border: 1px solid var(--neutral-stroke-rest, #d1d1d1);
    border-left: 3px solid var(--accent-fill-rest, #0078d4);
    border-radius: 4px;
    padding: 12px 14px;
    margin-top: 10px;
    background-color: var(--neutral-layer-1, transparent);
}


/* Blazor Error UI - Modal ohne Backdrop */
#blazor-error-ui {
    position: fixed;
    width: 28rem;
    max-width: 90vw;
    top: 20vh;
    left: 50%;
    transform: translateX(-50%);

    background-color: var(--neutral-layer-1, white);
    padding: 2rem;
    border: 0;
    border-radius: calc(var(--control-corner-radius, 4) * 1px);
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    color: var(--neutral-foreground-rest);

    z-index: 10000;

    animation: error-modal-slideUp 1.5s cubic-bezier(.05, .89, .25, 1.02),
    error-modal-fadeIn 0.5s ease-in-out;
    animation-fill-mode: forwards;
}

/* Error Page - Modal mit Backdrop */
.error-page-backdrop {
    position: fixed;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.4);
    z-index: 9999;
    animation: error-modal-fadeIn 0.5s ease-in-out;
}

.error-page-modal {
    position: fixed;
    width: 28rem;
    max-width: 90vw;
    top: 20vh;
    left: 50%;
    transform: translateX(-50%);

    background-color: var(--neutral-layer-1, white);
    padding: 2rem;
    border: 0;
    border-radius: calc(var(--control-corner-radius, 4) * 1px);
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    color: var(--neutral-foreground-rest);

    animation: error-modal-slideUp 1.5s cubic-bezier(.05, .89, .25, 1.02),
    error-modal-fadeIn 0.5s ease-in-out;
    animation-fill-mode: forwards;
}

/* Shared Content Container - Flexbox für vertikale Verteilung */
.error-modal-content {
    display: flex;
    flex-direction: column;
    min-height: 12rem;
}

/* Shared Typography */
#blazor-error-ui h2,
.error-page-modal h2 {
    margin-top: 0;
    margin-bottom: 0;
    color: var(--neutral-foreground-rest);
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

#blazor-error-ui h2 svg,
.error-page-modal h2 svg {
    flex-shrink: 0;
}

#blazor-error-ui h3,
.error-page-modal h3 {
    margin-top: 1.5rem;
    color: var(--neutral-foreground-rest);
}

#blazor-error-ui p,
.error-page-modal p {
    margin: 0;
    line-height: 1.5;
    color: var(--neutral-foreground-rest);
    flex: 1;
    display: flex;
    align-items: center;
}

#blazor-error-ui code,
.error-page-modal code {
    padding: 0.2rem 0.4rem;
    background-color: var(--neutral-layer-2, #f3f4f6);
    border-radius: calc(var(--control-corner-radius, 4) * 1px);
    font-family: monospace;
    color: var(--neutral-foreground-rest);
}

/* Shared Actions Container */
.error-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: auto;
}

/* Shared Reload Button - FluentUI Button Style */
.error-reload {
    display: inline-flex;
    align-items: center;
    justify-content: center;

    /* FluentUI Button Sizing */
    height: calc((var(--base-height-multiplier) + var(--density)) * var(--design-unit) * 1px);
    min-width: calc(var(--base-height-multiplier) * var(--design-unit) * 1px);
    padding: 0 calc(var(--design-unit) * 2.5px);

    /* FluentUI Accent Button Colors */
    background-color: var(--accent-fill-rest);
    color: var(--foreground-on-accent-rest);

    /* FluentUI Border & Radius */
    border: calc(var(--stroke-width) * 1px) solid transparent;
    border-radius: calc(var(--control-corner-radius) * 1px);

    /* Remove default link styling */
    text-decoration: none;
    cursor: pointer;
    white-space: nowrap;

    /* FluentUI Transitions */
    transition: background-color 0.1s ease, border-color 0.1s ease;
}

.error-reload:hover {
    background-color: var(--accent-fill-hover);
    color: var(--foreground-on-accent-rest);
    text-decoration: none;
}

.error-reload:active {
    background-color: var(--accent-fill-active);
    color: var(--foreground-on-accent-rest);
}

.error-reload:focus-visible {
    outline: calc(var(--focus-stroke-width) * 1px) solid var(--focus-stroke-outer);
    outline-offset: 2px;
}


/* Shared Animations */
@keyframes error-modal-slideUp {
    0% {
        transform: translateX(-50%) translateY(30px) scale(0.95);
    }
    100% {
        transform: translateX(-50%) translateY(0) scale(1);
    }
}

@keyframes error-modal-fadeIn {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}


/* ==========================================================================
   Layout Container 
   ========================================================================== */

.nav-content {
    width: 100%;
    max-width: 100%;
    padding: 1.5rem 1rem;
    max-height: calc(100dvh - var(--w4l-header-height));
    overflow-y: auto;
    scrollbar-gutter: stable;
}

/* Container-Setup */
.preview-columns {
    width: 100%;
    height: calc(100dvh - var(--w4l-header-height));
    display: grid;
    /* Arbeitsbereich : Preview. Historie: 3fr:2fr (60/40, min 500px) → 5fr:3fr (62.5/37.5,
       min 450px) → 7fr:3fr (70/30) bei 400px Untergrenze. Die Formulare sind der
       Arbeitsplatz, die Preview begleitet nur — die Charts bleiben bei 380px lesbar.

       Die Minima sind 2026-07-14 von 640/400 auf 600/380 gesenkt worden, weil die Summe
       sonst nicht aufgeht: die Zwei-Spalten-Ansicht gilt bis hinunter zu 1280px Viewport
       (lg), dort bleiben nach der 288px-Navigation aber nur ~990px für dieses Grid übrig —
       gegen 1040px Bedarf. Die Differenz wurde von `#body-content { overflow: hidden }`
       still weggeschnitten (kein Fehlerbild, nur ~50px, die fehlen). 600+380 = 980 passt.
       Dieselbe Rechnung trägt die Push-Schwelle des Side-Docks (≥1760px, base.css):
       1760 − 480 Dock = 1280 — darüber geht sich die 2-Spalten-Ansicht auch neben dem
       Dock noch aus, darunter bleibt das Dock Overlay. */
    grid-template-columns: minmax(600px, 7fr) minmax(380px, 3fr);
    position: relative;
}

/* Breite Monitore: der Arbeitsbereich hat bei ~1140px seine sinnvolle Maximalbreite
   erreicht (mehr Breite macht Formulare nicht besser — 1140 = 70% der Grid-Breite am
   früheren Shell-Cap 1910px, der Umschlag bei 1912px ist deshalb sprungfrei). Alles,
   was der Viewport darüber hinaus hergibt, fliesst VOLLSTÄNDIG in die Preview:
   minmax(380px, 1fr) absorbiert den Überschuss, bis der Shell-Cap
   (--w4l-content-max-width: 2250px, tokens.css) sie bei ~822px deckelt. Unterhalb
   von 1912px bleibt die proportionale 7fr:3fr-Regel — dort ist die Preview bereits
   heute das nachgiebige Element (380 → 487px). */
@media (min-width: 1912px) {
    .preview-columns {
        grid-template-columns: minmax(600px, 1140px) minmax(380px, 1fr);
    }
}

/* Maximierter Modus: nur eine Spalte, volle Breite */
.preview-columns.maximized {
    grid-template-columns: 1fr;
}

/* Eingeklapptes Preview: Inhalt nutzt die volle Breite, das Pane bleibt
   gemountet (FAST-Leak-Regel) aber unsichtbar — visibility statt display,
   damit Chart.js beim Wiedereinblenden korrekt resized (keine 0×0-Messung
   durch display:none). Zuklappen über den Toggle an der Globe-Position im
   Preview-Header; Wieder-Einblenden über den Reopen-Knopf am rechten Ende der
   sticky IconTitle-Action-Leiste (.w4l-icontitle-reopen, via Cascading). */
.preview-columns.preview-collapsed {
    grid-template-columns: minmax(0, 1fr) 0;
}

.preview-content {
    grid-column: 1;
    grid-row: 1;
    /* KEIN eigenes Scroll & KEIN Padding: der IconTitle-Header liegt ausserhalb
       des Scrollens und spannt so über die ECHTE volle Breite (die Scrollbar läuft
       nicht mehr hinter/neben ihm → kein transparenter Streifen rechts). Gescrollt
       wird der Inhalt in .w4l-page-body; das seitliche/untere Padding sitzt dort.
       Flex-Spalte, die die Höhe an .card → Shell → .w4l-page-body durchreicht. */
    padding: 0;
    justify-self: stretch;
    height: 100%;
    min-height: 0;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* Content-Card füllt die volle Höhe und reicht sie als Flex-Spalte weiter. */
.preview-content > .card {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}

/* Seiten-Shell (der äussere FluentStack einer Seite): füllt die Card, damit der
   darunterliegende Body-Container scrollen kann. Kein Gap zwischen Header & Body.
   align-items:stretch überstimmt das Inline-`align-items:start` des FluentStack
   (Default HorizontalAlignment=Left) — sonst schrumpfen Header & .w4l-page-body
   auf Inhaltsbreite statt die volle Arbeitsbreite zu füllen. */
.w4l-page-shell {
    flex: 1;
    min-height: 0;
    gap: 0 !important;
    align-items: stretch !important;
}

/* Scrollender, gepolsterter Inhaltscontainer UNTER dem Header. Trägt das Padding
   (Header ist voll-bleed) und reproduziert als Flex-Spalte das vertikale Spacing
   des früheren äusseren FluentStack. Padding-top 26px ersetzt den früheren
   führenden VerticalSpacer der Pages (1rem + 10px Flex-Gap) — dadurch ist der
   Abstand Header→erste Card auf allen Pages konstant, egal ob Overflow. */
.w4l-page-body {
    flex: 1 1 0;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-gutter: stable;
    padding: 1.625rem 1rem 1.5rem 1rem;
    /* ≥900px bekommt der Inhalt mehr Abstand zu den senkrechten Regionslinien
       (Nav/Preview) — bei einer Struktur, die nur über Linien trägt, wirkt 1rem
       eingeklemmt. Die Kopfzeile (.icon-title--sticky) zieht mit, damit der
       Seitentitel mit dem Inhalt fluchtet (Regel weiter unten). */
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

@media (min-width: 900px) {
    .w4l-page-body {
        padding-left: 1.5rem;
        padding-right: 1.5rem;
    }
}

/* Beim Overflow dürfen die Kinder NICHT komprimiert werden: Flex-Items schrumpfen
   per Default (flex-shrink:1) bevor der Container scrollt — leere Spacer
   (VerticalSpacer, min-content 0) kollabieren dabei vollständig und die Abstände
   ändern sich, sobald ein selektiertes Objekt den Inhalt über die Sichthöhe
   drückt. Kinder behalten ihre natürliche Höhe; gescrollt wird stattdessen. */
.w4l-page-body > * {
    flex-shrink: 0;
}

/* FluentUI-Karten defaulten auf height:var(--card-height, 100%) — als Flex-Item im
   .w4l-page-body (definierte Höhe) wird das zur flex-basis von 100% der Bodyhöhe:
   die Karten strecken sich dann weit über ihren Inhalt hinaus (Children Education
   Overview, Relationship-Cards, Overviews …). Karten im scrollenden Body sollen
   immer nur so hoch sein wie ihr Inhalt.
   WICHTIG: nicht via `height:`-Override lösbar — die Paket-Regel
   `.fluent-card-minimal-style[b-…]` hat gleiche Spezifität und W4L.Web.styles.css
   lädt NACH components.css (Cascade-Verlierer). Stattdessen wird die von der
   Paket-Regel selbst konsumierte Custom-Property --card-height gesetzt; sie erbt
   auch in verschachtelte Karten und ins fluent-card-Shadow-DOM. Explizite
   Height-Parameter (Inline-Style) gewinnen weiterhin. */
.w4l-page-body {
    --card-height: fit-content;
}

.w4l-page-body > fluent-card,
.w4l-page-body > .fluent-card-minimal-style {
    flex: none;
}

/* Ausblenden im maximierten Modus */
.preview-columns.maximized .preview-content {
    display: none;
}

.preview-pane {
    grid-column: 2; /* explizit — siehe Kommentar bei .preview-content */
    grid-row: 1;
    height: 100%;
    /* KEIN Padding — die Preview-Spalte spiegelt jetzt den Arbeitsbereich (.preview-content):
       die Kopfzeile liegt voll-bleed ganz oben (eigenes Padding + Divider, siehe
       .preview-header), der Body darunter trägt die Innenabstände selbst. Nur so beginnen
       beide Kopfzeilen auf DERSELBEN Höhe, und nur so kann das scrollende FindingsPanel
       bis an die rechte Shell-Kante reichen (sonst schneidet ein overflow:hidden-Vorfahr
       es an seiner Padding-Kante ab — genau daran ist die Scrollbar verschwunden). */
    padding: 0;
    min-width: 0;
    overflow: hidden;
    box-sizing: border-box;
    /* Dezente Fläche der Flanken — dasselbe Layer wie nav.sitenav (siehe base.css).
       Der Arbeitsbereich dazwischen bleibt die helle Leinwand; die Preview begleitet
       nur und tritt zurück. Der Preview-Header darin wird transparent (s.u.), sonst
       läge ein --fill-color-Streifen als Fremdkörper auf der getönten Spalte. */
    background: var(--neutral-layer-2);
    /* Regionsgrenze Arbeitsbereich → Preview (nur im 2-Spalten-Layout; gestapelt
       wird sie weiter unten zur Oberkante). box-sizing:border-box → die Linie
       frisst keine Spaltenbreite. Eingeklappt ist das Pane visibility:hidden,
       die Kante verschwindet also mit. */
    border-left: 1px solid var(--w4l-shell-line, var(--neutral-stroke-rest));
}

.preview-columns.preview-collapsed .preview-pane {
    visibility: hidden;
    padding: 0;
}

/* Eingeklappte Preview: rechte Begrenzung des Arbeitsbereichs. Geöffnet schliessen
   die getönte Preview-Spalte (+ optional die Regionslinie) den Arbeitsbereich rechts
   ab — eingeklappt verschwindet beides mit dem Pane und die Region liefe ohne Kante
   aus. Die Linie ist deshalb HART auf --neutral-stroke-rest, NICHT am
   «Show shell lines»-Schalter (--w4l-shell-line): wie die Unterkante der
   Sticky-Kopfzeile (.icon-title--sticky) gehört sie zur Grundgeometrie der Region,
   nicht zum optionalen Linienraster — der Schalter steht per Default auf AUS.
   ≥900px wie die übrigen Regionslinien (der Mobile-Drawer entfernt auch die
   Nav-Kante, siehe base.css). */
@media (min-width: 900px) {
    .preview-columns.preview-collapsed .preview-content {
        border-right: 1px solid var(--neutral-stroke-rest);
    }
}

/* Card innerhalb preview-pane: verhindert Überlauf. Bewusst OHNE Padding — die Kopfzeile
   soll voll-bleed sein (wie im Arbeitsbereich), die Innenabstände trägt der Body darunter. */
.preview-pane .card {
    min-width: 0;
    overflow: hidden;
    height: 100%;
    display: flex;
    flex-direction: column;
}

/* ==========================================================================
   Seiten-Header (IconTitle/IconTitleEdit mit Sticky="true")
   Liegt als fixes Flex-Element (flex:0 0 auto) OBERHALB des scrollenden
   .w4l-page-body — dadurch spannt er über die echte volle Breite (die Scrollbar
   sitzt im Body darunter, nicht hinter dem Header). Volle Breite kommt aus dem
   Flex-Parent (align-items:stretch); eigenes horizontales Padding rückt den Titel
   ein, während der Hintergrund Kante-zu-Kante deckt. (Der Klassenname bleibt aus
   Kompatibilität „--sticky", die Positionierung ist aber nicht mehr position:sticky.) */
/* Gemeinsame Kopfzeilen-Geometrie der beiden Regionen: Arbeitsbereich (.icon-title--sticky)
   und Preview (.preview-header). Beide liegen voll-bleed ganz oben in ihrer Spalte, tragen
   dasselbe Padding, denselben Divider und dieselbe min-height — dadurch fluchten die zwei
   Titelbereiche und ihre Trennlinien exakt auf derselben Höhe.

   Beide sind auf eine FESTE Höhe von 64px geeicht (inkl. Divider, box-sizing: border-box) —
   nicht min-height. Ein Boden hätte nur den kleineren der beiden angehoben und den grösseren
   auf seiner natürlichen Höhe gelassen; die Divider blieben dann versetzt, solange der Boden
   nicht exakt getroffen ist. Eine feste Höhe eicht beide unabhängig vom Inhalt.

   Der Inhalt (Arbeitsbereich: H2-Titel + 36px-Icon; Preview: H4 + Icon-Button) wird von den
   FluentStacks vertikal zentriert und ist knapp niedriger bzw. gleich hoch — kein Clipping. */
.icon-title--sticky,
.preview-header {
    flex: 0 0 auto;
    background: var(--fill-color);
    padding: 0.85rem 1rem 0.65rem 1rem;
    height: 64px;
    box-sizing: border-box;
    /* --neutral-stroke-rest statt --neutral-stroke-divider-rest: Divider-rest ist im
       Light-Mode praktisch unsichtbar. Da die Struktur hier ausschliesslich über Linien
       trägt (keine Flächen/Karten), müssen sie auch tatsächlich lesbar sein. */
    border-bottom: 1px solid var(--w4l-shell-line, var(--neutral-stroke-rest));
}

/* Unterkante der Arbeitsbereichs-Kopfzeile: bewusst NICHT über --w4l-shell-line, sondern
   fest. Sie trennt den fixen Kopf vom scrollenden Body — ohne sie schiebt sich der Inhalt
   beim Scrollen ansatzlos unter den Titel. Der «Show shell lines»-Schalter darf die
   Regionsgrenzen ausblenden, diese eine Linie aber nicht. Die Preview-Kopfzeile bleibt an
   der Config (Regel darüber); die 1px-Geometrie ist auf beiden Seiten identisch, die
   Titel fluchten also weiterhin. */
.icon-title--sticky {
    border-bottom-color: var(--neutral-stroke-rest);
}

/* ≥900px zieht die Arbeitsbereichs-Kopfzeile horizontal mit dem .w4l-page-body mit
   (dort 1.5rem statt 1rem), damit Seitentitel und Inhalt weiter fluchten. Der
   .preview-header bleibt bei 1rem — die Preview-Spalte ist schmaler und in sich
   konsistent (ihr Inhalt padded ebenfalls 1rem). */
@media (min-width: 900px) {
    .icon-title--sticky {
        padding-left: 1.5rem;
        padding-right: 1.5rem;
    }
}

/* Der Preview-Header sitzt auf der getönten Preview-Spalte (neutral-layer-2) und darf
   deshalb NICHT den --fill-color der gemeinsamen Regel darüber tragen — er würde sonst
   als hellerer Streifen aus der Fläche herausstechen. Er liegt ausserhalb des Scrollens
   (flex:0 0 auto), überlagert also nichts und braucht keine eigene Deckung. Der
   Arbeitsbereichs-Header (.icon-title--sticky) behält --fill-color: dort IST die
   Leinwand hell. */
.preview-pane .preview-header {
    background: transparent;
}

/* Sektionsanfang im Arbeitsbereich — IconTitle mit Spaced="true".
   Die Trennung trägt AUSSCHLIESSLICH der Weissraum: keine Linie, kein Rahmen, kein
   Typografie-Wechsel. Waagrechte 2px-Linien bleiben den Edit-Panel-Begrenzern vorbehalten
   (Ebene (c) der Liniensprache) — eine zweite Linien-Sorte über Section-Titeln hätte zwei
   ähnliche Vokabulare auf derselben Seite bedeutet.

   Die Vorgeschichte, damit der Weg nicht rückwärts gegangen wird: eine Linie über
   Section-Titeln (.icon-title--divider), ein kurzer Anstrich (--divider-short) und eine
   Overline-Typografie (--overline) waren gebaut und wurden im Sichttest /Cash/0 (2026-07-14)
   allesamt gegen den reinen Weissraum verworfen. Ursache des ursprünglich «gedrängten»
   Eindrucks war nicht die fehlende Linie, sondern der verkehrte Rhythmus (nur 8px zwischen
   den Sektionen); mit 2rem vor dem Sektionsanfang trägt der Weissraum allein. Keine dieser
   Varianten nachrüsten — Begründung in Docs/DesignBacklog.md §3.

   Den nachfolgenden Abstand (Titel → Inhalt) trägt ein VerticalSpacer S; ein VORANGEHENDER
   Spacer gehört weg, sonst addiert er sich auf diese 2rem (siehe Docs/Css.md). */
.icon-title--spaced {
    margin-top: 2rem;
}

/* Reopen-Preview-Knopf: sitzt als letztes Element der IconTitle-Action-Leiste
   (nur auf der sticky Kopfzeile, via display umgeschaltet — siehe IconTitle.razor).
   Natives <button> im Stealth-Icon-Look, passt sich den übrigen Action-Icons an. */
.w4l-icontitle-reopen,
.w4l-icontitle-action {
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--neutral-foreground-rest);
    cursor: pointer;
    flex-shrink: 0;
    transition: background-color 120ms ease;
}

/* Generische Action-Variante derselben Optik, aber immer sichtbar (der Reopen-Knopf
   schaltet sein display per Inline-Style um). Genutzt vom Close-X der Rechner. */
.w4l-icontitle-action {
    display: inline-flex;
}

.w4l-icontitle-reopen:hover,
.w4l-icontitle-action:hover {
    background: var(--neutral-fill-stealth-hover);
}

.w4l-icontitle-reopen:focus-visible,
.w4l-icontitle-action:focus-visible {
    outline: 2px solid var(--accent-fill-rest);
    outline-offset: -2px;
}

/* Volle Breite im maximierten Modus */
.preview-columns.maximized .preview-pane {
    width: 100%;
    max-width: 100%;
    grid-column: 1 / -1;
    /* Der Arbeitsbereich ist ausgeblendet — es gibt keine Region mehr, gegen die
       abgegrenzt würde; die Linie klebte sonst am linken Fensterrand. */
    border-left: none;
    /* Aus demselben Grund fällt die Flanken-Tönung weg: maximiert ist die Preview
       keine begleitende Spalte mehr, sondern der ganze Arbeitsbereich — und der ist
       die helle Leinwand. Sonst läge layer-2 über den vollen Viewport. */
    background: var(--fill-color);
}

/* TABLET-/MOBILE-STRATEGIE (Konvention `lg`, siehe Docs/Css.md) */
/* Wenn das Fenster schmaler als 1280px wird (Content + Pane + Gap passen nicht
   mehr nebeneinander), wird die Preview NICHT gestapelt (unter dem Formular war
   sie unbrauchbar: weit weg vom Arbeitskontext, und die 100%-Höhen-Ketten der
   Charts kollabieren im Fixed-Height-Grid zu 0). Stattdessen weicht sie seitlich
   aus: geöffnet liegt sie als von rechts angedocktes Overlay ÜBER dem Formular
   (schwebende Ebene → Schatten, wie das Side-Dock im Overlay-Modus); Default ist
   eingeklappt (PreviewLayout setzt den State beim ersten Render per matchMedia).
   Gilt durchgängig bis zum kleinsten Viewport — ohne untere Grenze, sonst
   fällt <768px auf die 2-Spalten-Basisregel (min. 1140px) zurück.
   Eingeklappt greift die Basisregel (visibility:hidden) — das fixe Pane belegt
   keinen Layoutplatz, Kante und Schatten verschwinden mit. */
@media (max-width: 1279px) {
    .preview-columns,
    .preview-columns.preview-collapsed {
        grid-template-columns: 1fr;
    }

    .preview-pane {
        position: fixed;
        top: var(--w4l-header-height);
        right: 0;
        bottom: 0;
        width: min(520px, 100vw);
        height: auto; /* top/bottom definieren die Höhe (Basisregel: height:100%) */
        min-width: unset;
        z-index: 100; /* über dem Seiteninhalt, unter Header-Drawer (1050) und Dialogen */
        /* Als Overlay muss die Spalte deckend sein — dasselbe Layer wie in der
           2-Spalten-Ansicht, damit die Preview überall gleich aussieht. */
        background: var(--neutral-layer-2);
        border-left: 1px solid var(--w4l-shell-line, var(--neutral-stroke-rest));
        box-shadow: -6px 0 18px rgba(0, 0, 0, 0.18);
    }

    /* Maximiert ist die Preview der ganze Arbeitsbereich: volle Breite, helle
       Leinwand, keine Ebenen-Trennung mehr (Kante/Schatten weg). */
    .preview-columns.maximized .preview-pane {
        width: 100vw;
        background: var(--fill-color);
        border-left: none;
        box-shadow: none;
    }
}

/* Offenes Side-Dock: KEINE eigene Preview-Regel mehr nötig. Der Content-Push des Docks
   greift erst ab 1760px (base.css) — dort geht sich die 2-Spalten-Ansicht auf der um die
   Dockbreite verkleinerten Shell noch exakt aus (1760 − 480 = 1280 = lg-Grenze). Unterhalb
   bleibt das Dock ein Overlay und überlappt die Preview-Spalte, statt sie in den
   Arbeitsbereich zu schieben. Die frühere «Stapel-Schwelle um die Dockbreite verschoben»
   (1380–1759) ist damit ersatzlos entfallen. */

/* MOBILE (Konvention `md`, siehe Docs/Css.md): das Overlay aus der ≤1279px-Regel
   nimmt die volle Breite — auf dem Phone gibt es kein «daneben» mehr, in das
   das Formular noch sinnvoll durchscheinen könnte. */
@media (max-width: 899px) {
    .preview-pane {
        width: 100vw;
    }
}

/* 1-Spalten-Layout: gleiche Breitenlogik wie deine linke Spalte */
.layout-columns {
    width: 100%;
    display: grid;
    grid-template-columns: minmax(640px, 3fr); /* wie dein Content links */
}

/* Content: nur Y-Scroll, X ist komplett unterbunden */
.layout-content {
    padding: 1.5rem 1rem;
    justify-self: stretch;

    height: calc(100dvh - var(--w4l-header-height));
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-gutter: stable;

    /* wichtig bei Grid/Flex, verhindert "Aufblasen" durch Kinder */
    min-width: 0;
    max-width: 100%;
    box-sizing: border-box;

    /* lange Strings umbrechen statt X-Overflow */
    overflow-wrap: break-word;
    word-break: break-word;
}

/* Kinder dürfen den Container nicht breiter machen */
.layout-content > * {
    min-width: 0;
    max-width: 100%;
}

/* Medien (img/svg/video/canvas) niemals breiter als Container */
.layout-content img,
.layout-content svg,
.layout-content video,
.layout-content canvas {
    max-width: 100%;
    height: auto;
    display: block;
}

/* Tabellen: zwingen, in der Breite zu bleiben (kein X-Scroll) */
.layout-content table {
    width: 100%;
    max-width: 100%;
    table-layout: fixed;
}

.layout-content th,
.layout-content td {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Codeblöcke: hier entscheiden — komplett kappen statt X-Scroll */
.layout-content pre,
.layout-content code {
    white-space: pre-wrap;
    overflow-x: hidden;
    max-width: 100%;
}

/* Responsive: unter 1280px eine Spalte (bleibt eh 1 Spalte, aber min Breite weg) */
@media (max-width: 1279px) {
    .layout-columns {
        grid-template-columns: 1fr;
    }
}

/* ==========================================================================
   Diagnostic Page Layout
   - Header (Titel + Select) oben fixiert
   - Tabellen-Bereich scrollbar (X + Y) unterhalb
   ========================================================================== */

.diagnostic-page-container {
    display: flex;
    flex-direction: column;
    height: calc(100dvh - var(--w4l-header-height));
    width: 100%;
    padding: 1.5rem 1rem;
    box-sizing: border-box;
    overflow: hidden;
    min-width: 0; /* wichtig für Flex-Kinder */
}

/* Header-Bereich: fixiert oben, kein Scroll */
.diagnostic-page-header {
    flex-shrink: 0;
    margin-bottom: 1rem;
}

/* Content-Bereich: nimmt restliche Höhe, scrollt X+Y */
.diagnostic-page-content {
    flex: 1 1 auto;
    min-height: 0; /* wichtig für Flex-Scroll */
    min-width: 0;  /* wichtig für Flex-Breite */
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* Der Scroll-Container für die Tabelle innerhalb DiagnosticReport */
.diagnostic-scroll-container {
    flex: 1 1 auto;
    min-height: 0;
    min-width: 0;
    overflow: auto; /* X + Y Scroll */
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 4px;
}

/* Tabelle innerhalb Scroll-Container: auto-width für Horizontal-Scroll */
.diagnostic-scroll-container table {
    width: auto;
    min-width: 100%;
    table-layout: auto;
}

/* Summary-Bereich über der Tabelle */
.diagnostic-summary-fixed {
    flex-shrink: 0;
    margin-bottom: 0.5rem;
    padding: 0.5rem;
    background: var(--neutral-layer-2);
    border-radius: 4px;
}

/* ==========================================================================
   Diagnostic Table Styles
   ========================================================================== */
.diagnostic-data-table {
    border-collapse: separate;
    border-spacing: 0;
    font-size: 0.75rem;
    width: auto;
    min-width: 100%;
}

.diagnostic-data-table th,
.diagnostic-data-table td {
    border-right: 1px solid var(--neutral-stroke-rest);
    border-bottom: 1px solid var(--neutral-stroke-rest);
    padding: 0.2rem;
}

.diagnostic-data-table th:first-child,
.diagnostic-data-table td:first-child {
    border-left: 1px solid var(--neutral-stroke-rest);
}

.diagnostic-data-table thead tr:first-child th {
    border-top: 1px solid var(--neutral-stroke-rest);
}

.diagnostic-data-table thead th {
    position: sticky;
    top: 0;
    background: var(--neutral-layer-3);
    z-index: 10;
    text-align: center;
    white-space: nowrap;
}

.diagnostic-data-table tbody td {
    text-align: right;
    white-space: nowrap;
}

.diagnostic-data-table tbody td:first-child {
    position: sticky;
    left: 0;
    background: var(--neutral-layer-1);
    font-weight: 600;
    z-index: 5;
    text-align: center;
    width: 80px;
}

/* Row hover - the table is 60-80 rows of numbers; tracking one year across it needs a guide. */
.diagnostic-data-table tbody tr:hover td {
    background: var(--neutral-fill-secondary-hover);
}

/* The sticky first-column rule above outranks the hover rule (higher specificity), so without
   this the year cell - the one cell the hover guide is meant to anchor - stays unhighlighted. */
.diagnostic-data-table tbody tr:hover td:first-child {
    background: var(--neutral-fill-secondary-hover);
}

.diagnostic-data-table thead th:first-child {
    position: sticky;
    left: 0;
    top: 0;
    z-index: 15;
    background: var(--neutral-layer-3);
}

.error-text {
    color: var(--error, #d13438);
}

/* Generisches 2-Spalten-Seiten-Layout (.two-col-grid, .form-row-2col, .hint-box,
   .two-col-context) → utilities.css. */

/* Timeline lock toggle (AssetForm / StrategyForm) — native checkbox, FAST-leak-free */
.timeline-lock-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 6px;
    font-size: 0.8125rem;
    color: var(--neutral-foreground-hint);
    cursor: pointer;
    user-select: none;
}

.timeline-lock-toggle input {
    cursor: pointer;
}

/* ── Inheritance (received) — list/detail page + event form ── */
.inh-body.inh-disclaimed {
    opacity: 0.5;
    filter: grayscale(1);
}

.inh-preview {
    padding: 8px 12px;
    background: var(--neutral-fill-secondary-rest);
    border-radius: 6px;
}

.inh-badge {
    display: inline-block;
    margin-left: 6px;
    padding: 0 6px;
    border-radius: 8px;
    font-size: 0.7rem;
    line-height: 1.4;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    background: var(--neutral-fill-secondary-rest);
    color: var(--neutral-foreground-hint);
    vertical-align: middle;
}

.inh-chip {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    margin-bottom: 6px;
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 8px;
    background: var(--neutral-fill-secondary-rest);
}

.inh-chip-debt {
    border-left: 3px solid var(--error, #d13438);
}

.inh-chip-cash {
    border-left: 3px solid var(--accent-fill-rest, #0ea5e9);
}

/* Result-cards — same visual language as the Funds/Strategy .stat-card:
   centered, small uppercase label, large bold value, layer-1 fill. */
.inh-rescards {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-content: flex-start;
}

.inh-rescard {
    flex: 1 1 0;
    min-width: 100px;
    padding: 8px 10px;
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 6px;
    background: var(--neutral-layer-1);
    text-align: center;
}

.inh-rescard-label {
    font-size: 11px;
    color: var(--neutral-foreground-hint);
    text-transform: uppercase;
    letter-spacing: 0.4px;
}

.inh-rescard-value {
    font-size: 22px;
    font-weight: 700;
    margin-top: 2px;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

.inh-rescard-neg .inh-rescard-value {
    color: var(--error, #d13438);
}

/* Prominent accept/disclaim decision box at the end of the event editor. */
.inh-decision {
    padding: 12px 14px;
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 8px;
    background: var(--neutral-layer-1);
}

.inh-decision-title {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--neutral-foreground-hint);
    margin-bottom: 8px;
}

.inh-chip-name {
    font-weight: 600;
}

.inh-chip-value {
    color: var(--neutral-foreground-hint);
}

.inh-chip-link {
    margin-left: auto;
    font-size: 0.85rem;
    white-space: nowrap;
}

.inh-chip-remove {
    border: none;
    background: transparent;
    cursor: pointer;
    color: var(--neutral-foreground-hint);
    font-size: 0.9rem;
    line-height: 1;
    padding: 2px 4px;
}

.inh-chip-remove:hover {
    color: var(--error, #d13438);
}

.inh-add-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 4px;
}

.inh-add-pills {
    margin: 2px 0 10px;
}

.inh-mini-form {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 8px;
    margin-top: 4px;
    padding: 8px;
    border: 1px dashed var(--neutral-stroke-rest);
    border-radius: 8px;
}

.inh-mini-field {
    display: flex;
    flex-direction: column;
}

.inh-mini-form .w4l-input {
    height: 32px;
    padding: 0 8px;
    border: 1px solid var(--neutral-stroke-rest);
    border-radius: 4px;
    background: var(--neutral-fill-input-rest, var(--neutral-fill-rest));
    color: var(--neutral-foreground-rest);
    font: inherit;
    min-width: 180px;
}
