/* =============================================================================
   Phishin Design System — "Clean Professional SaaS"
   (m3-adminui-design-system)

   Ein leichtgewichtiges, framework-freies Design-System: Tokens + Basis-Element-
   Styles + Komponenten-Klassen (.ph-*). Bewusst KEIN Bootstrap/Tailwind — nur
   CSS-Variablen + Klassen, damit Tenant-Branding spaeter nur Tokens ueberschreibt.

   Konventionen:
   - Tokens:        --ph-*           (Single Source of Truth)
   - Komponenten:   .ph-*            (z.B. .ph-btn, .ph-card, .ph-table)
   - Kompatibilitaet: alte --phishin-* / .phishin-* Namen sind Aliase auf die Tokens.
   ========================================================================== */

/* ---------- Tokens ---------- */
:root {
    /* Farb-Primitive */
    --ph-bg:              #f7f8fa;
    --ph-surface:         #ffffff;
    --ph-surface-2:       #f1f3f6;
    --ph-surface-3:       #e9edf2;
    --ph-border:          #e4e7ec;
    --ph-border-strong:   #d0d5dd;

    --ph-fg:              #101828;
    /* a11y (#131): muted/subtle auf >= 4.5:1 (WCAG AA) gegen alle Surfaces angehoben.
       muted #667085→#565e70 (war 4.23:1 auf surface-3); subtle #98a2b3→#5d6675 (war 2.58:1 auf weiss). */
    --ph-fg-muted:        #565e70;
    --ph-fg-subtle:       #5d6675;
    --ph-fg-on-accent:    #ffffff;

    --ph-accent:          #4f46e5;
    --ph-accent-hover:    #4338ca;
    --ph-accent-active:   #3730a3;
    --ph-accent-subtle:   #eef2ff;
    --ph-accent-ring:     rgba(79, 70, 229, 0.35);

    --ph-success:         #067647;
    --ph-success-subtle:  #ecfdf3;
    --ph-warning:         #b54708;
    --ph-warning-subtle:  #fffaeb;
    --ph-danger:          #d92d20;
    --ph-danger-hover:    #b42318;
    --ph-danger-subtle:   #fef3f2;
    --ph-info:            #175cd3;
    --ph-info-subtle:     #eff8ff;

    /* Semantische Alert-/Status-Akzente (Border + Text je Ton) — Single Source of Truth,
       damit Komponenten-CSS keine hartcodierten Alert-Farben mehr traegt. */
    --ph-info-border:     #b2ddff;
    --ph-info-fg:         #0b4a8f;
    --ph-success-border:  #abefc6;
    --ph-success-fg:      #085d3a;
    --ph-warning-border:  #fedf89;
    --ph-warning-fg:      #93370d;
    --ph-danger-border:   #fecdca;
    --ph-danger-fg:       #912018;
    /* Brand-Akzent-Verlauf (2. Stop) */
    --ph-accent-2:        #7c73ff;

    /* Typografie */
    --ph-font-sans: "Inter", ui-sans-serif, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --ph-font-mono: ui-monospace, "SFMono-Regular", "Cascadia Code", "Consolas", monospace;

    --ph-text-xs:   0.75rem;    /* 12 */
    --ph-text-sm:   0.8125rem;  /* 13 */
    --ph-text-base: 0.875rem;   /* 14 — SaaS-Default */
    --ph-text-md:   0.9375rem;  /* 15 */
    --ph-text-lg:   1.125rem;   /* 18 */
    --ph-text-xl:   1.375rem;   /* 22 */
    --ph-text-2xl:  1.75rem;    /* 28 */

    --ph-fw-regular:  400;
    --ph-fw-medium:   500;
    --ph-fw-semibold: 600;
    --ph-fw-bold:     700;

    /* Spacing (4px-Basis) */
    --ph-space-1: 0.25rem;
    --ph-space-2: 0.5rem;
    --ph-space-3: 0.75rem;
    --ph-space-4: 1rem;
    --ph-space-5: 1.5rem;
    --ph-space-6: 2rem;
    --ph-space-7: 3rem;

    /* Radii */
    --ph-radius-sm:   6px;
    --ph-radius-md:   8px;
    --ph-radius-lg:   12px;
    --ph-radius-full: 999px;

    /* Schatten (weich) */
    --ph-shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.06), 0 1px 3px rgba(16, 24, 40, 0.05);
    --ph-shadow-md: 0 2px 4px rgba(16, 24, 40, 0.06), 0 4px 12px rgba(16, 24, 40, 0.08);
    --ph-shadow-lg: 0 8px 24px rgba(16, 24, 40, 0.12);

    /* Layout */
    --ph-sidebar-width: 252px;
    --ph-topbar-height: 56px;
    --ph-content-max:   1180px;
}

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

html, body {
    margin: 0;
    font-family: var(--ph-font-sans);
    font-size: var(--ph-text-base);
    line-height: 1.5;
    color: var(--ph-fg);
    background: var(--ph-bg);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 { margin: 0 0 var(--ph-space-3); font-weight: var(--ph-fw-semibold); color: var(--ph-fg); line-height: 1.3; }
h1 { font-size: var(--ph-text-2xl); letter-spacing: -0.01em; }
h2 { font-size: var(--ph-text-xl); letter-spacing: -0.01em; }
h3 { font-size: var(--ph-text-lg); }
h4 { font-size: var(--ph-text-md); }
p  { margin: 0 0 var(--ph-space-4); }

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

code, kbd, samp, .ph-mono {
    font-family: var(--ph-font-mono);
    font-size: 0.92em;
}
:not(pre) > code {
    background: var(--ph-surface-2);
    border: 1px solid var(--ph-border);
    border-radius: var(--ph-radius-sm);
    padding: 0.1em 0.4em;
    color: var(--ph-fg);
}

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

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

/* ---------- Buttons ---------- */
.ph-btn,
button:not(.ph-unstyled) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--ph-space-2);
    font-family: inherit;
    font-size: var(--ph-text-base);
    font-weight: var(--ph-fw-medium);
    line-height: 1.2;
    padding: 0.5rem 0.9rem;
    border-radius: var(--ph-radius-md);
    border: 1px solid transparent;
    cursor: pointer;
    transition: background-color .12s ease, border-color .12s ease, box-shadow .12s ease, color .12s ease;
    white-space: nowrap;
    user-select: none;
    text-decoration: none;
}
/* Anchor-Buttons (<a class="ph-btn">) duerfen nie vom globalen a:hover-Unterstrich erfasst werden. */
.ph-btn:hover { text-decoration: none; }

/* Default-Button (primary) */
.ph-btn,
.ph-btn--primary,
button:not(.ph-unstyled):not(.ph-btn--secondary):not(.ph-btn--ghost):not(.ph-btn--danger) {
    background: var(--ph-accent);
    color: var(--ph-fg-on-accent);
    box-shadow: var(--ph-shadow-sm);
}
.ph-btn:hover,
.ph-btn--primary:hover,
button:not(.ph-unstyled):not(.ph-btn--secondary):not(.ph-btn--ghost):not(.ph-btn--danger):hover {
    background: var(--ph-accent-hover);
}

.ph-btn--secondary {
    background: var(--ph-surface);
    color: var(--ph-fg);
    border-color: var(--ph-border-strong);
    box-shadow: var(--ph-shadow-sm);
}
.ph-btn--secondary:hover { background: var(--ph-surface-2); }

.ph-btn--ghost {
    background: transparent;
    color: var(--ph-fg-muted);
    box-shadow: none;
}
.ph-btn--ghost:hover { background: var(--ph-surface-2); color: var(--ph-fg); }

.ph-btn--danger {
    background: var(--ph-danger);
    color: var(--ph-fg-on-accent);
    box-shadow: var(--ph-shadow-sm);
}
.ph-btn--danger:hover { background: var(--ph-danger-hover); }

.ph-btn--sm { padding: 0.35rem 0.65rem; font-size: var(--ph-text-sm); }
.ph-btn--block { width: 100%; }

button:disabled,
.ph-btn:disabled,
.ph-btn.is-disabled {
    background: var(--ph-surface-3);
    color: var(--ph-fg-subtle);
    border-color: transparent;
    box-shadow: none;
    cursor: not-allowed;
}

/* ---------- Forms ---------- */
label { display: block; font-size: var(--ph-text-sm); font-weight: var(--ph-fw-medium); color: var(--ph-fg); }

input:not([type=checkbox]):not([type=radio]):not([type=color]):not(.ph-unstyled),
select:not(.ph-unstyled),
textarea:not(.ph-unstyled),
.ph-input {
    display: block;
    width: 100%;
    font-family: inherit;
    font-size: var(--ph-text-base);
    color: var(--ph-fg);
    background: var(--ph-surface);
    border: 1px solid var(--ph-border-strong);
    border-radius: var(--ph-radius-md);
    padding: 0.5rem 0.7rem;
    transition: border-color .12s ease, box-shadow .12s ease;
}
input:not([type=checkbox]):not([type=radio]):not(.ph-unstyled):focus,
select:not(.ph-unstyled):focus,
textarea:not(.ph-unstyled):focus,
.ph-input:focus {
    outline: none;
    border-color: var(--ph-accent);
    box-shadow: 0 0 0 3px var(--ph-accent-ring);
}
input::placeholder, textarea::placeholder { color: var(--ph-fg-subtle); }

.ph-field { margin-bottom: var(--ph-space-4); }
.ph-field > label { margin-bottom: var(--ph-space-2); }
.ph-field__hint { margin-top: var(--ph-space-1); font-size: var(--ph-text-xs); color: var(--ph-fg-muted); }
.ph-field__error { margin-top: var(--ph-space-1); font-size: var(--ph-text-xs); color: var(--ph-danger); font-weight: var(--ph-fw-medium); }
.ph-field__required { color: var(--ph-danger); margin-left: 0.15rem; }

/* Aktions-Zeile: Buttons, die einem Eingabe-Control folgen (Speichern unter einer Checkbox,
   Aktivieren unter einem Textfeld), gruppiert + sichtbar abgesetzt — nicht am Control klebend.
   Opt-in (nicht global auf <button>, sonst verschoebe es Toolbar-/Tabellen-/Dialog-Buttons). */
.ph-form-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ph-space-2);
    margin-top: var(--ph-space-4);
}
/* Ein Select/Input, das mit seinem Aktions-Button in einer Reihe steht, behaelt natuerliche
   Breite statt width:100% (sonst draengt es die Buttons weg). Steht nach den Basis-Form-Regeln
   → gewinnt bei gleicher Spezifitaet. */
.ph-form-actions > select,
.ph-form-actions > input:not([type=checkbox]):not([type=radio]) { width: auto; }

/* Aktions-Reihe in einer Tabellen-/Listen-Aktionsspalte (#347): mehrere zeilenbezogene Aktions-
   Elemente als gruppierte Button-Reihe mit sichtbarem Abstand, umbruchsicher. Inline-flex, damit
   die Zelle nur so breit wie noetig wird. */
.ph-row-actions {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ph-space-2);
}

/* Schluessel/Wert-Detailliste (z. B. Kampagnen-Konfiguration, #349): zweispaltiges Grid,
   Label links (gedaempft), Wert rechts. Auf schmalem Viewport einspaltig gestapelt. */
.ph-detail-list {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--ph-space-2) var(--ph-space-5);
    margin: 0;
}
.ph-detail-list dt { font-weight: var(--ph-fw-semibold); color: var(--ph-fg-muted); }
.ph-detail-list dd { margin: 0; }
@media (max-width: 600px) {
    .ph-detail-list { grid-template-columns: 1fr; gap: 0.15rem var(--ph-space-5); }
    .ph-detail-list dd { margin-bottom: var(--ph-space-2); }
}

/* ---------- Cards ---------- */
.ph-card {
    background: var(--ph-surface);
    border: 1px solid var(--ph-border);
    border-radius: var(--ph-radius-lg);
    box-shadow: var(--ph-shadow-sm);
}
.ph-card__header {
    padding: var(--ph-space-4) var(--ph-space-5);
    border-bottom: 1px solid var(--ph-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ph-space-3);
}
.ph-card__title { font-size: var(--ph-text-md); font-weight: var(--ph-fw-semibold); margin: 0; }
.ph-card__body { padding: var(--ph-space-5); }
.ph-card__footer {
    padding: var(--ph-space-4) var(--ph-space-5);
    border-top: 1px solid var(--ph-border);
    background: var(--ph-surface-2);
    border-radius: 0 0 var(--ph-radius-lg) var(--ph-radius-lg);
}
/* Gestapelte Karten im Seiteninhalt (z.B. Feedback-Triage: Filter/Tabelle/Detail) brauchen
   vertikalen Abstand — .ph-card hat selbst keinen margin. Der Adjacent-Sibling-Kombinator
   ueberspringt Blazor-Kommentar-Marker (nur Element-Geschwister zaehlen). */
.ph-content .ph-card + .ph-card { margin-top: var(--ph-space-5); }
/* ...aber NICHT fuer Karten in einem Grid: dort setzt der Container den Abstand ueber gap.
   Ein Stapel-margin wuerde bei align-items:stretch die kombinatorlos getroffene erste Karte
   auf volle Reihenhoehe belassen und die uebrigen verkuerzen -> erste Karte scheinbar groesser
   (GH-482). Gleiche Spezifitaet (0,3,0), spaeter -> gewinnt ohne !important. */
.ph-content .ph-grid .ph-card { margin-top: 0; }

/* ---------- Dialog-Primitiv (ph-dialog) ---------- */
/* Natives <dialog> via showModal(): rendert im Top-Layer (zentriert via UA margin:auto + inset:0),
   unabhaengig von position/overflow/transform der Vorfahren (#326). Die innere .ph-card traegt
   Flaeche/Rahmen/Schatten; der Dialog selbst ist nur Huelle + ::backdrop. */
.ph-dialog {
    margin: auto;
    width: min(32rem, calc(100vw - 2 * var(--ph-space-5)));
    /* dvh statt vh: auf Mobil ist 100vh die Layout-Hoehe INKL. dem Bereich hinter der URL-Bar →
       der Dialog wuerde hoeher als der sichtbare Viewport und ragte unten raus. dvh folgt der
       sichtbaren Hoehe. vh-Deklaration zuerst als Fallback fuer Browser ohne dvh. */
    max-height: calc(100vh - 2 * var(--ph-space-5));
    max-height: calc(100dvh - 2 * var(--ph-space-5));
    padding: 0;
    border: none;
    background: transparent;
    color: inherit;
    overflow: visible;
}
.ph-dialog::backdrop {
    background: rgba(15, 23, 42, 0.55);
}
.ph-dialog > .ph-card {
    margin: 0;
    padding: var(--ph-space-5);
    max-height: calc(100vh - 2 * var(--ph-space-5));
    max-height: calc(100dvh - 2 * var(--ph-space-5));
    overflow-y: auto;
}
/* Breite Variante fuer inhaltsreiche Editoren (Mail-Vorlage/Landing-Page, #352): deutlich mehr
   Breite auf grossen Viewports. Die mobilen Regeln (@media 600px: dvh + fast Vollbreite) greifen
   unveraendert, da .ph-dialog--wide stets zusammen mit .ph-dialog gesetzt wird und die mobile
   .ph-dialog-Regel spaeter in der Quelle steht (gewinnt bei gleicher Spezifitaet). */
.ph-dialog--wide {
    /* GH-506: mitwachsend (min(90rem, 92vw)) statt festem 60rem-Deckel — nutzt breite Desktop-
       Viewports (Editor + Vorschau nebeneinander, Transfer-Listen); die mobile .ph-dialog-Regel
       (spaeter in der Quelle) uebertrumpft weiterhin auf schmalen Viewports. */
    width: min(90rem, 92vw);
}

/* Waehrend eines In-App-Screenshots (getDisplayMedia) den Dialog + Backdrop unsichtbar
   schalten, OHNE das native Modal zu schliessen (GH-380): der erfasste Tab-Frame zeigt dann
   die dahinterliegende Ansicht statt des Dialogs. Formular-/Top-Layer-Zustand bleibt. */
.ph-dialog--capturing {
    visibility: hidden;
}
.ph-dialog--capturing::backdrop {
    background: transparent;
}

/* ---------- Stat-Cards (Dashboard) ---------- */
.ph-stat {
    background: var(--ph-surface);
    border: 1px solid var(--ph-border);
    border-radius: var(--ph-radius-lg);
    box-shadow: var(--ph-shadow-sm);
    padding: var(--ph-space-5);
}
.ph-stat__label { font-size: var(--ph-text-sm); color: var(--ph-fg-muted); font-weight: var(--ph-fw-medium); margin: 0 0 var(--ph-space-2); }
.ph-stat__value { font-size: var(--ph-text-2xl); font-weight: var(--ph-fw-bold); letter-spacing: -0.02em; line-height: 1.1; }
.ph-stat__meta  { margin-top: var(--ph-space-2); font-size: var(--ph-text-xs); color: var(--ph-fg-subtle); }

/* ---------- Reporting / Auswertung (reporting-web-dashboard) ---------- */
/* KPI-Akzente: Klick = Risiko (rot), Melden = positiv (gruen) — konsistent mit dem PDF-Report. */
.rpt-stat--risk .ph-stat__value     { color: var(--ph-danger); }
.rpt-stat--positive .ph-stat__value { color: var(--ph-success); }

.rpt-panel { margin-top: var(--ph-space-6); }
.rpt-panel__title { font-size: var(--ph-text-lg); margin-bottom: var(--ph-space-2); }
.rpt-panel--secondary {
    margin-top: var(--ph-space-7);
    padding-top: var(--ph-space-5);
    border-top: 1px solid var(--ph-border);
}
.rpt-delivery-note { margin-top: var(--ph-space-3); }

/* Awareness-Funnel: Label | Balken | Wert. */
.rpt-funnel { display: flex; flex-direction: column; gap: var(--ph-space-3); margin-top: var(--ph-space-4); }
.rpt-funnel__row {
    display: grid;
    grid-template-columns: 7rem 1fr 8rem;
    align-items: center;
    gap: var(--ph-space-3);
}
.rpt-funnel__label { font-size: var(--ph-text-sm); font-weight: var(--ph-fw-medium); color: var(--ph-fg); }
.rpt-funnel__track {
    display: block;
    min-width: 0;                       /* in der Grid-Zelle schrumpfen statt ueberlaufen (GH-331) */
    height: 1.25rem;
    background: var(--ph-surface-3);
    border-radius: var(--ph-radius-full);
    overflow: hidden;
}
.rpt-funnel__bar {
    display: block;
    height: 100%;
    min-width: 3px;
    border-radius: var(--ph-radius-full);
    transition: width 0.3s ease;
}
.rpt-funnel__value { font-size: var(--ph-text-sm); font-weight: var(--ph-fw-semibold); text-align: right; }

/* Funnel-Stufenfarben — nur Tokens (Design-System-Gate: kein Hex ausserhalb :root). */
.rpt-bar--delivered { background: var(--ph-info); }
.rpt-bar--opened    { background: var(--ph-warning); }
.rpt-bar--clicked   { background: var(--ph-danger); }
.rpt-bar--landing   { background: var(--ph-accent-2); }
.rpt-bar--ack       { background: var(--ph-accent); }

/* Dashboard-Startseite: "Aktive Kampagnen"-KPI-Karten. */
.rpt-camp-card {
    display: flex;
    flex-direction: column;
    gap: var(--ph-space-3);
    padding: var(--ph-space-5);
}
.rpt-camp-card:hover { text-decoration: none; border-color: var(--ph-accent); box-shadow: var(--ph-shadow-md); transform: translateY(-1px); }
.rpt-camp-card__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--ph-space-3); }
.rpt-camp-card__name { font-weight: var(--ph-fw-semibold); color: var(--ph-fg); }
.rpt-camp-card__rates { display: flex; gap: var(--ph-space-5); }
.rpt-camp-card__rate-label { font-size: var(--ph-text-xs); color: var(--ph-fg-muted); }
.rpt-camp-card__rate-value { font-size: var(--ph-text-lg); font-weight: var(--ph-fw-bold); }
.rpt-camp-card__rate--risk .rpt-camp-card__rate-value     { color: var(--ph-danger); }
.rpt-camp-card__rate--positive .rpt-camp-card__rate-value { color: var(--ph-success); }

/* ---------- Tables ---------- */
.ph-table { width: 100%; border-collapse: collapse; font-size: var(--ph-text-base); }
.ph-table thead th {
    text-align: left;
    font-size: var(--ph-text-xs);
    font-weight: var(--ph-fw-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--ph-fg-muted);
    padding: var(--ph-space-3) var(--ph-space-4);
    border-bottom: 1px solid var(--ph-border);
    background: var(--ph-surface-2);
    white-space: nowrap;
}
.ph-table tbody td {
    padding: var(--ph-space-3) var(--ph-space-4);
    border-bottom: 1px solid var(--ph-border);
    vertical-align: middle;
}
.ph-table tbody tr:last-child td { border-bottom: none; }
.ph-table tbody tr:hover { background: var(--ph-surface-2); }
/* Warn-Hervorhebung einer Tabellenzeile (z. B. Bot-verdaechtige Tracking-Events) — token-basiert, ueberschreibt den Hover. */
.ph-table tbody tr.ph-table__row--flagged td { background: var(--ph-warning-subtle); }
.ph-table--card { background: var(--ph-surface); border: 1px solid var(--ph-border); border-radius: var(--ph-radius-lg); overflow: hidden; box-shadow: var(--ph-shadow-sm); }

/* ---------- Badges / Status ---------- */
.ph-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.35em;
    font-size: var(--ph-text-xs);
    font-weight: var(--ph-fw-medium);
    line-height: 1;
    padding: 0.3em 0.6em;
    border-radius: var(--ph-radius-full);
    background: var(--ph-surface-3);
    color: var(--ph-fg-muted);
    white-space: nowrap;
}
.ph-badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.ph-badge--success { background: var(--ph-success-subtle); color: var(--ph-success); }
.ph-badge--warning { background: var(--ph-warning-subtle); color: var(--ph-warning); }
.ph-badge--danger  { background: var(--ph-danger-subtle);  color: var(--ph-danger); }
.ph-badge--info    { background: var(--ph-info-subtle);    color: var(--ph-info); }
.ph-badge--accent  { background: var(--ph-accent-subtle);  color: var(--ph-accent); }
.ph-badge--neutral { background: var(--ph-surface-3);      color: var(--ph-fg-muted); }
.ph-badge--plain::before { display: none; }

/* ---------- Alerts ---------- */
.ph-alert {
    display: flex;
    gap: var(--ph-space-3);
    padding: var(--ph-space-3) var(--ph-space-4);
    border-radius: var(--ph-radius-md);
    border: 1px solid var(--ph-border);
    background: var(--ph-surface-2);
    font-size: var(--ph-text-base);
    margin-bottom: var(--ph-space-4);
}
.ph-alert--info    { background: var(--ph-info-subtle);    border-color: var(--ph-info-border);    color: var(--ph-info-fg); }
.ph-alert--success { background: var(--ph-success-subtle); border-color: var(--ph-success-border); color: var(--ph-success-fg); }
.ph-alert--warning { background: var(--ph-warning-subtle); border-color: var(--ph-warning-border); color: var(--ph-warning-fg); }
.ph-alert--danger  { background: var(--ph-danger-subtle);  border-color: var(--ph-danger-border);  color: var(--ph-danger-fg); }

/* ---------- Page-Header ---------- */
.ph-page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--ph-space-4);
    margin-bottom: var(--ph-space-5);
    flex-wrap: wrap;
}
.ph-page-header__titles { min-width: 0; }
.ph-page-header h1 { margin: 0; }
.ph-page-header__heading { display: flex; align-items: center; gap: var(--ph-space-2); min-width: 0; }
.ph-page-header__heading h1 { margin: 0; }
.ph-page-header__subtitle { color: var(--ph-fg-muted); font-size: var(--ph-text-md); margin: var(--ph-space-1) 0 0; }
.ph-page-header__actions { display: flex; gap: var(--ph-space-2); flex-shrink: 0; }

/* ---------- Toolbar (adminui-design-system): .ph-toolbar ---------- */
.ph-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ph-space-2);
    margin-bottom: var(--ph-space-5);
}

/* ---------- Lade-Zustand (adminui-design-system) ---------- */
.ph-loading {
    display: flex;
    align-items: center;
    gap: var(--ph-space-3);
    padding: var(--ph-space-5);
    color: var(--ph-fg-muted);
    font-size: var(--ph-text-md);
}
.ph-loading__spinner {
    width: 1.1rem;
    height: 1.1rem;
    border: 2px solid var(--ph-border-strong);
    border-top-color: var(--ph-accent);
    border-radius: var(--ph-radius-full);
    animation: ph-spin .7s linear infinite;
    flex-shrink: 0;
}
@keyframes ph-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .ph-loading__spinner { animation: none; } }

/* ---------- Utilities ---------- */
.ph-stack    { display: flex; flex-direction: column; gap: var(--ph-space-4); }
.ph-row      { display: flex; gap: var(--ph-space-3); align-items: center; }
.ph-row--wrap{ flex-wrap: wrap; }
.ph-grid     { display: grid; gap: var(--ph-space-4); }
.ph-grid--cards { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.ph-spacer   { flex: 1 1 auto; }
.ph-muted    { color: var(--ph-fg-muted); }
.ph-subtle   { color: var(--ph-fg-subtle); }
.ph-text-sm  { font-size: var(--ph-text-sm); }
.ph-text-xs  { font-size: var(--ph-text-xs); }
.ph-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ph-error { color: var(--ph-danger); font-weight: var(--ph-fw-semibold); }
.ph-success { color: var(--ph-success); font-weight: var(--ph-fw-semibold); }

/* Inline-Hilfe (#74): dezenter „?"-Trigger + Popover. */
.ph-help { position: relative; display: inline-flex; vertical-align: middle; }
/* Trigger ist ein <summary> (native disclosure, funktioniert ohne Blazor-Circuit → SSR-tauglich, #350).
   Den Default-Disclosure-Marker (Dreieck) entfernen, damit nur das runde „?"-Icon erscheint. */
.ph-help__trigger {
    width: 1.15rem; height: 1.15rem; padding: 0; margin-left: 0.25rem;
    border: 1px solid var(--ph-border-strong); border-radius: var(--ph-radius-full);
    background: var(--ph-surface); color: var(--ph-fg-muted);
    font-size: var(--ph-text-xs); line-height: 1; cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
    list-style: none;
}
.ph-help__trigger::-webkit-details-marker { display: none; }
.ph-help__trigger:hover,
details.ph-help[open] > .ph-help__trigger { color: var(--ph-accent); border-color: var(--ph-accent); }
.ph-help__popover {
    position: absolute; top: 1.6rem; left: 0; z-index: 30;
    width: max-content; max-width: 22rem;
    background: var(--ph-surface); color: var(--ph-fg);
    border: 1px solid var(--ph-border); border-radius: var(--ph-radius-md);
    box-shadow: var(--ph-shadow-lg);
    padding: 0.6rem 0.75rem; font-size: var(--ph-text-sm); font-weight: 400;
    text-align: left; white-space: normal;
}

.ph-help__more { display: inline-block; margin-top: 0.5rem; color: var(--ph-accent); font-weight: var(--ph-fw-semibold); }

/* Kontext-Hilfe-Einstieg in der Topbar (#81). */
.ph-topbar__help {
    width: 1.6rem; height: 1.6rem; border-radius: var(--ph-radius-full);
    border: 1px solid var(--ph-border); background: var(--ph-surface); color: var(--ph-fg-muted);
    display: inline-flex; align-items: center; justify-content: center;
    font-size: var(--ph-text-sm); text-decoration: none;
}
.ph-topbar__help:hover { color: var(--ph-accent); border-color: var(--ph-accent); }

/* Hilfe-Center (#74): Sidebar (Suche + Themenliste) + Inhaltsbereich. */
.help-center { display: grid; grid-template-columns: 16rem 1fr; gap: 1.25rem; align-items: start; }
.help-center__search {
    width: 100%; box-sizing: border-box; padding: 0.5rem 0.7rem; margin-bottom: 0.75rem;
    border: 1px solid var(--ph-border); border-radius: var(--ph-radius-md);
    background: var(--ph-surface); color: var(--ph-fg); font-size: var(--ph-text-sm);
}
.help-center__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.15rem; }
.help-center__item {
    width: 100%; text-align: left; padding: 0.4rem 0.6rem; cursor: pointer;
    border: 0; background: transparent; color: var(--ph-fg);
    border-radius: var(--ph-radius-sm); font-size: var(--ph-text-sm);
}
.help-center__item:hover { background: var(--ph-surface-2); }
.help-center__item.active { background: var(--ph-accent-subtle); color: var(--ph-accent); font-weight: var(--ph-fw-semibold); }
.help-center__content {
    background: var(--ph-surface); border: 1px solid var(--ph-border);
    border-radius: var(--ph-radius-md); padding: 1rem 1.25rem; max-width: 48rem;
}
.help-center__content h1 { font-size: var(--ph-text-xl); margin-top: 0; }
.help-center__content h2 { font-size: var(--ph-text-lg); margin-top: 1.25rem; }
.help-center__content code { background: var(--ph-surface-2); padding: 0.05rem 0.3rem; border-radius: var(--ph-radius-sm); }
.help-center__langs { display: flex; gap: 0.25rem; margin-bottom: 0.5rem; }
.help-center__lang {
    flex: 1; padding: 0.3rem 0.4rem; cursor: pointer; font-size: var(--ph-text-xs);
    border: 1px solid var(--ph-border); background: var(--ph-surface);
    color: var(--ph-fg-muted); border-radius: var(--ph-radius-sm);
}
.help-center__lang.active { background: var(--ph-accent-subtle); color: var(--ph-accent); border-color: var(--ph-accent); font-weight: var(--ph-fw-semibold); }

/* ---------- App-Shell ---------- */
.ph-shell {
    display: grid;
    grid-template-columns: var(--ph-sidebar-width) 1fr;
    grid-template-rows: var(--ph-topbar-height) 1fr;
    grid-template-areas: "sidebar topbar" "sidebar main";
    min-height: 100vh;
}

.ph-topbar {
    grid-area: topbar;
    display: flex;
    align-items: center;
    gap: var(--ph-space-3);
    padding: 0 var(--ph-space-5);
    background: var(--ph-surface);
    border-bottom: 1px solid var(--ph-border);
    position: sticky;
    top: 0;
    z-index: 20;
}
.ph-topbar__title { font-size: var(--ph-text-md); font-weight: var(--ph-fw-semibold); color: var(--ph-fg); }

.ph-sidebar {
    grid-area: sidebar;
    background: var(--ph-surface);
    border-right: 1px solid var(--ph-border);
    display: flex;
    flex-direction: column;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
}
.ph-brand {
    display: flex;
    align-items: center;
    gap: var(--ph-space-2);
    height: var(--ph-topbar-height);
    padding: 0 var(--ph-space-5);
    border-bottom: 1px solid var(--ph-border);
    flex-shrink: 0;
}
.ph-brand__mark {
    width: 28px; height: 28px;
    flex-shrink: 0;
}
.ph-brand__text { display: flex; flex-direction: column; justify-content: center; line-height: 1.15; min-width: 0; }
.ph-brand__name { font-weight: var(--ph-fw-semibold); font-size: var(--ph-text-md); letter-spacing: -0.01em; }
.ph-brand__name span { color: var(--ph-fg-subtle); font-weight: var(--ph-fw-regular); }
.ph-brand__version { font-size: var(--ph-text-xs); color: var(--ph-fg-subtle); font-weight: var(--ph-fw-regular); }


.ph-nav { padding: var(--ph-space-4) var(--ph-space-3); flex: 1; }
.ph-nav__group + .ph-nav__group { margin-top: var(--ph-space-5); }
.ph-nav__group-label {
    font-size: var(--ph-text-xs);
    font-weight: var(--ph-fw-semibold);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--ph-fg-subtle);
    padding: 0 var(--ph-space-3);
    margin-bottom: var(--ph-space-2);
}
.ph-nav__link {
    display: flex;
    align-items: center;
    gap: var(--ph-space-3);
    padding: 0.5rem var(--ph-space-3);
    border-radius: var(--ph-radius-md);
    color: var(--ph-fg-muted);
    font-weight: var(--ph-fw-medium);
    font-size: var(--ph-text-base);
    text-decoration: none;
    transition: background-color .1s ease, color .1s ease;
}
.ph-nav__link:hover { background: var(--ph-surface-2); color: var(--ph-fg); text-decoration: none; }
.ph-nav__link.active { background: var(--ph-accent-subtle); color: var(--ph-accent); font-weight: var(--ph-fw-semibold); }
.ph-nav__icon { width: 18px; height: 18px; flex-shrink: 0; opacity: 0.9; }

.ph-content { grid-area: main; padding: var(--ph-space-6); width: 100%; }
.ph-content__inner { max-width: var(--ph-content-max); margin: 0 auto; }

/* ---------- Mobile-Navigation (Off-Canvas-Drawer) ----------
   Steuerung CSS-first via versteckter Checkbox (#ph-nav-toggle) + <label>-Bedienelemente
   (Hamburger in der Topbar, Scrim als Backdrop) — CSP-konform, ohne JavaScript funktionsfaehig.
   Auf Desktop (> 1024px, s. Responsive-Sektion) sind Hamburger/Scrim ausgeblendet und der
   Toggle wirkungslos; die Sidebar bleibt persistent im Grid. */
.ph-nav-toggle {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0; border: 0;
    clip: rect(0 0 0 0); clip-path: inset(50%);
    overflow: hidden; white-space: nowrap;
}
.ph-hamburger {
    display: none; /* nur im Kompakt-Modus sichtbar (s. Responsive-Sektion) */
    align-items: center; justify-content: center;
    width: 2.25rem; height: 2.25rem;
    border-radius: var(--ph-radius-md);
    border: 1px solid var(--ph-border);
    background: var(--ph-surface);
    color: var(--ph-fg-muted);
    cursor: pointer;
    flex-shrink: 0;
    -webkit-tap-highlight-color: transparent;
}
.ph-hamburger:hover { color: var(--ph-fg); border-color: var(--ph-border-strong); }
.ph-hamburger svg { width: 1.25rem; height: 1.25rem; }
/* Tastatur-Fokus landet auf der sr-only Checkbox → Fokus-Ring am sichtbaren Hamburger zeigen.
   `:has()` (Descendant) statt General-Sibling (`~`): robust gegenueber der DOM-Reihenfolge, die
   Blazor Server durch Komponenten-Marker zwischen den Shell-Kindern veraendern kann. */
.ph-shell:has(.ph-nav-toggle:focus-visible) .ph-hamburger {
    outline: 2px solid var(--ph-accent);
    outline-offset: 2px;
    border-color: var(--ph-accent);
}
.ph-scrim {
    display: none; /* nur im Kompakt-Modus + geoeffnet sichtbar */
    position: fixed; inset: 0;
    background: rgba(16, 24, 40, 0.45);
    z-index: 50;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s ease;
}
/* Utility: Element auf sehr schmalen Viewports ausblenden. */
.ph-hide-narrow { display: inline; }

/* User-Menu / Topbar-Chip */
.ph-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--ph-space-2);
    padding: 0.3rem 0.6rem;
    border-radius: var(--ph-radius-full);
    background: var(--ph-surface-2);
    border: 1px solid var(--ph-border);
    font-size: var(--ph-text-sm);
    color: var(--ph-fg);
}
.ph-avatar {
    width: 26px; height: 26px; border-radius: 50%;
    background: var(--ph-accent-subtle); color: var(--ph-accent);
    display: inline-flex; align-items: center; justify-content: center;
    font-weight: var(--ph-fw-semibold); font-size: var(--ph-text-xs);
    flex-shrink: 0;
}

/* Profil-Menü (natives <details>, buendelt die Konto-Aktionen) */
.ph-profile { position: relative; }
.ph-profile__trigger {
    display: inline-flex; align-items: center; gap: var(--ph-space-2);
    padding: 0.25rem 0.5rem; border-radius: var(--ph-radius-full);
    cursor: pointer; list-style: none; user-select: none;
    border: 1px solid transparent; color: var(--ph-fg);
}
.ph-profile__trigger::-webkit-details-marker { display: none; }
.ph-profile__trigger:hover,
.ph-profile[open] .ph-profile__trigger { background: var(--ph-surface-2); border-color: var(--ph-border); }
.ph-profile__caret { color: var(--ph-fg-subtle); transition: transform 0.15s ease; flex-shrink: 0; }
.ph-profile[open] .ph-profile__caret { transform: rotate(180deg); }
.ph-profile__menu {
    position: absolute; top: calc(100% + var(--ph-space-1)); right: 0; z-index: 30;
    min-width: 200px; display: flex; flex-direction: column; gap: 2px; padding: var(--ph-space-1);
    background: var(--ph-surface); border: 1px solid var(--ph-border);
    border-radius: var(--ph-radius-md); box-shadow: var(--ph-shadow-md);
}
.ph-profile__item {
    display: flex; align-items: center; gap: var(--ph-space-2);
    padding: var(--ph-space-2) var(--ph-space-3); border-radius: var(--ph-radius-sm);
    color: var(--ph-fg); font-size: var(--ph-text-sm); text-decoration: none;
    background: none; border: none; width: 100%; text-align: left; cursor: pointer; font: inherit;
}
.ph-profile__item:hover { background: var(--ph-surface-2); text-decoration: none; }
.ph-profile__item--danger { color: var(--ph-danger); }
.ph-profile__item--danger:hover { background: var(--ph-danger-subtle); }

/* ---------- Demo-Banner (rendert oben im Content) ---------- */
.ph-demo-banner {
    display: flex;
    gap: var(--ph-space-2);
    background: var(--ph-warning-subtle);
    color: var(--ph-warning-fg);
    border: 1px solid var(--ph-warning-border);
    border-radius: var(--ph-radius-md);
    padding: var(--ph-space-3) var(--ph-space-4);
    font-size: var(--ph-text-sm);
    margin-bottom: var(--ph-space-5);
}

/* ---------- Login (EmptyLayout) ---------- */
.empty-layout {
    /* dvh statt vh (#346): auf Mobil ist 100vh die Layout-Hoehe INKL. dem Bereich hinter der
       URL-Bar → die Flex-Zentrierung liegt unterhalb der Mitte des sichtbaren Viewports und die
       Karte wirkt nach unten verschoben. dvh folgt der sichtbaren Hoehe; vh zuerst als Fallback. */
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--ph-space-5);
    background:
        radial-gradient(1200px 600px at 50% -10%, var(--ph-accent-subtle), transparent 60%),
        var(--ph-bg);
}
.login-card { width: 100%; max-width: 400px; box-shadow: var(--ph-shadow-lg); }
.login-card__body { padding: var(--ph-space-6); }
.login-brand { display: flex; align-items: center; gap: var(--ph-space-2); margin-bottom: var(--ph-space-5); }
.login-title { margin: 0 0 var(--ph-space-1); font-size: var(--ph-text-xl); }
.login-subtitle { margin: 0 0 var(--ph-space-5); font-size: var(--ph-text-sm); }
.login-divider { display: flex; align-items: center; gap: var(--ph-space-3); margin: var(--ph-space-5) 0; color: var(--ph-fg-subtle); font-size: var(--ph-text-xs); }
.login-divider::before, .login-divider::after { content: ""; flex: 1; height: 1px; background: var(--ph-border); }
.sso-buttons { display: flex; flex-direction: column; gap: var(--ph-space-2); }
.sso-buttons form { margin: 0; }

/* ---------- Message-Pages (Zugriff verweigert / Nicht gefunden / Fehler) ---------- */
.ph-message-page {
    max-width: 32rem;
    margin: var(--ph-space-7) auto;
    padding: var(--ph-space-6);
    text-align: center;
    background: var(--ph-surface);
    border: 1px solid var(--ph-border);
    border-radius: var(--ph-radius-lg);
    box-shadow: var(--ph-shadow-sm);
}
.ph-message-page__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    margin-bottom: var(--ph-space-4);
    border-radius: var(--ph-radius-full);
    background: var(--ph-accent-subtle);
    color: var(--ph-accent);
}
.ph-message-page__icon svg { width: 1.6rem; height: 1.6rem; }
.ph-message-page--error .ph-message-page__icon { background: var(--ph-warning-subtle); color: #93370d; }
.ph-message-page h1 { font-size: var(--ph-text-xl); margin: 0 0 var(--ph-space-2); }
.ph-message-page p { color: var(--ph-fg-muted); margin: 0 0 var(--ph-space-5); }
.ph-message-page__meta { font-size: var(--ph-text-sm); }
.ph-message-page__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ph-space-2);
    justify-content: center;
}

/* ---------- Empty-State / Onboarding-Hero ----------
   Fokussierter, zentrierter Einstieg fuer Leerzustaende (z.B. SystemAdmin ohne
   Mandant, #279). Token-basiert → Tenant-Branding ueberschreibt nur Variablen. */
.ph-empty {
    max-width: 34rem;
    margin: var(--ph-space-7) auto;
    padding: var(--ph-space-7) var(--ph-space-6);
    text-align: center;
    background: var(--ph-surface);
    border: 1px solid var(--ph-border);
    border-radius: var(--ph-radius-lg);
    box-shadow: var(--ph-shadow-sm);
}
.ph-empty__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3.5rem;
    height: 3.5rem;
    margin-bottom: var(--ph-space-5);
    border-radius: var(--ph-radius-full);
    background: var(--ph-accent-subtle);
    color: var(--ph-accent);
}
.ph-empty__icon svg { width: 1.75rem; height: 1.75rem; }
.ph-empty__title { font-size: var(--ph-text-2xl); margin: 0 0 var(--ph-space-3); }
.ph-empty__text {
    color: var(--ph-fg-muted);
    font-size: var(--ph-text-md);
    margin: 0 auto var(--ph-space-6);
    max-width: 28rem;
}
.ph-empty__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ph-space-3);
    justify-content: center;
    align-items: center;
}

/* ---------- Dashboard ---------- */
.dash-section-title { font-size: var(--ph-text-md); font-weight: var(--ph-fw-semibold); margin: var(--ph-space-6) 0 var(--ph-space-3); }
.dash-section-title:first-of-type { margin-top: var(--ph-space-2); }

.dash-action {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ph-space-3);
    padding: var(--ph-space-5);
    text-decoration: none;
    color: inherit;
    transition: border-color .12s ease, box-shadow .12s ease, transform .12s ease;
}
.dash-action:hover { text-decoration: none; border-color: var(--ph-accent); box-shadow: var(--ph-shadow-md); transform: translateY(-1px); }
.dash-action__title { font-weight: var(--ph-fw-semibold); color: var(--ph-fg); margin-bottom: var(--ph-space-1); }
.dash-action__desc { font-size: var(--ph-text-sm); }
.dash-action__arrow { color: var(--ph-accent); font-size: var(--ph-text-lg); flex-shrink: 0; }

.dash-area {
    display: flex;
    flex-direction: column;
    gap: var(--ph-space-1);
    padding: var(--ph-space-4) var(--ph-space-5);
    text-decoration: none;
    color: inherit;
    transition: border-color .12s ease, box-shadow .12s ease;
}
.dash-area:hover { text-decoration: none; border-color: var(--ph-border-strong); box-shadow: var(--ph-shadow-md); }
.dash-area__title { font-weight: var(--ph-fw-semibold); color: var(--ph-fg); }

/* ---------- Wizard-Schritt-Muster (ph-wizard / ph-steps / ph-form-grid) ----------
   Generalisiert aus dem Onboarding-Wizard (campaign-create-wizard, ADR 5): token-only,
   von OnboardingWizard UND dem Kampagnen-Anlege-Wizard genutzt. Die `.onb-*`-Selektoren
   bleiben als Alias auf denselben Regeln erhalten, damit der Onboarding-Wizard (Markup +
   Test-Ids) unveraendert weiterlaeuft. */
.ph-steps ol, .onb-steps ol { display: flex; flex-wrap: wrap; gap: var(--ph-space-2); list-style: none; padding: 0; margin: 0 0 var(--ph-space-5); }
.ph-steps li, .onb-steps li { flex: 1 1 8rem; }
.ph-step-btn, .onb-step-btn {
    display: flex; align-items: center; gap: var(--ph-space-2); width: 100%;
    padding: var(--ph-space-2) var(--ph-space-3);
    border: 1px solid var(--ph-border); border-radius: var(--ph-radius-md);
    background: var(--ph-surface); color: var(--ph-fg-muted); cursor: pointer; text-align: left;
}
.ph-step-btn:disabled { cursor: default; opacity: 0.55; }
.ph-steps li.active .ph-step-btn, .onb-steps li.active .onb-step-btn { border-color: var(--ph-accent); color: var(--ph-fg); box-shadow: var(--ph-shadow-sm); }
.ph-steps li.done .ph-step-btn, .onb-steps li.done .onb-step-btn { color: var(--ph-fg); }
.ph-step-num, .onb-step-num {
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.5rem; height: 1.5rem; border-radius: var(--ph-radius-full); flex-shrink: 0;
    background: var(--ph-surface-2); color: var(--ph-fg-muted); font-size: var(--ph-text-sm); font-weight: var(--ph-fw-semibold);
}
.ph-steps li.active .ph-step-num, .onb-steps li.active .onb-step-num { background: var(--ph-accent); color: var(--ph-fg-on-accent); }
.ph-steps li.done .ph-step-num, .onb-steps li.done .onb-step-num { background: var(--ph-success, #12b76a); color: #fff; }
.ph-step-label, .onb-step-label { font-size: var(--ph-text-sm); font-weight: var(--ph-fw-medium); }
/* GH-504: rein anzeigender Stepper (z. B. CSV-Import) — die Schritte sind kein Bedien-Element. */
.ph-steps--static .ph-step-btn { cursor: default; }

/* Vertikaler Wizard-Rahmen (Schritt-Navigation + Panel + Aktionen). */
.ph-wizard { display: flex; flex-direction: column; gap: var(--ph-space-4); }

/* Mehrspaltiges Feld-Grid: 1 Spalte mobil, 2 Spalten ab breiten Viewports. Jedes Feld
   (`.ph-field` aus <FormField>) ist eine Grid-Zelle; `.ph-wide` spannt beide Spalten. */
.ph-form-grid { display: grid; grid-template-columns: 1fr; gap: 0 var(--ph-space-4); }
.ph-form-grid .ph-wide { grid-column: 1 / -1; }
@media (min-width: 48rem) {
    .ph-form-grid { grid-template-columns: 1fr 1fr; }
}
.onb-panel { padding: var(--ph-space-5); margin-bottom: var(--ph-space-4); }
.onb-section h2 { margin-top: 0; font-size: var(--ph-text-lg); }
.onb-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); gap: var(--ph-space-3); margin: var(--ph-space-4) 0; }
.onb-grid label { display: flex; flex-direction: column; gap: var(--ph-space-1); font-size: var(--ph-text-sm); font-weight: var(--ph-fw-medium); }
.onb-grid .onb-wide { grid-column: 1 / -1; }
.onb-check { display: flex; flex-direction: row !important; align-items: center; gap: var(--ph-space-2); }
.onb-actions { display: flex; flex-wrap: wrap; gap: var(--ph-space-2); margin-top: var(--ph-space-2); }
.onb-nav { display: flex; justify-content: space-between; gap: var(--ph-space-2); }
.onb-sep { border: none; border-top: 1px solid var(--ph-border); margin: var(--ph-space-5) 0; }
.onb-status { font-size: var(--ph-text-sm); font-weight: var(--ph-fw-medium); padding: 0.2rem 0.6rem; border-radius: var(--ph-radius-md); }
.onb-status--open { background: var(--ph-warning-subtle); color: #93370d; }
.onb-status--done { background: var(--ph-accent-subtle); color: var(--ph-accent); }
.onb-feedback { margin: var(--ph-space-3) 0 0; padding: var(--ph-space-2) var(--ph-space-3); border-radius: var(--ph-radius-md); font-size: var(--ph-text-sm); }
.onb-feedback--ok { background: var(--ph-accent-subtle); color: var(--ph-accent); }
.onb-feedback--error { background: var(--ph-danger-subtle, #fee4e2); color: var(--ph-danger, #b42318); }
.onb-feedback--info { background: var(--ph-surface-2); color: var(--ph-fg-muted); }

/* ---------- 2FA-QR-Code (Enrollment) ---------- */
.tfa-qr {
    display: inline-block;
    margin: var(--ph-space-3) 0;
    padding: var(--ph-space-3);
    background: #ffffff;
    border: 1px solid var(--ph-border);
    border-radius: var(--ph-radius-md);
    line-height: 0;
}
.tfa-qr svg { display: block; width: 200px; height: 200px; }

/* ---------- Auswahl-Liste + Content-Editor (Vorlagen/Landing-Pages) ---------- */
.ph-select-list { list-style: none; padding: 0; margin: 0 0 var(--ph-space-4); display: flex; flex-direction: column; gap: var(--ph-space-1); }
.ph-select-list__item {
    display: flex; align-items: center; justify-content: space-between; gap: var(--ph-space-3);
    width: 100%; text-align: left; cursor: pointer;
    padding: var(--ph-space-3) var(--ph-space-4);
    background: var(--ph-surface); border: 1px solid var(--ph-border); border-radius: var(--ph-radius-md);
}
.ph-select-list__item:hover { border-color: var(--ph-border-strong); background: var(--ph-surface-2); }
.ph-select-list li.is-selected .ph-select-list__item { border-color: var(--ph-accent); box-shadow: 0 0 0 1px var(--ph-accent); }

.content-editor { padding: var(--ph-space-5); margin-bottom: var(--ph-space-5); }
.content-editor .locale-section {
    border: 1px solid var(--ph-border); border-radius: var(--ph-radius-md);
    padding: var(--ph-space-4); margin: var(--ph-space-3) 0;
    display: flex; flex-direction: column; gap: var(--ph-space-2);
}
.content-editor .locale-section legend { font-weight: var(--ph-fw-semibold); padding: 0 var(--ph-space-2); }
.content-editor .locale-section label { display: flex; flex-direction: column; gap: var(--ph-space-1); font-size: var(--ph-text-sm); font-weight: var(--ph-fw-medium); }
/* GH-506: vertikales Resize eingehegt — horizontales Ziehen (sprengte das min-width:0-Grid) entfaellt;
   im Fill-Dialog scrollt die Karte bei Vergroesserung, statt das Layout zu ueberlaufen. */
.content-editor .locale-section textarea { font-family: var(--ph-font-mono); resize: vertical; }
.content-editor__actions { margin-top: var(--ph-space-3); }

/* Sprach-Tab + Live-Vorschau side-by-side (mailtemplate-preview-side-by-side).
   Flex-Wrap statt Geschwister-Kombinator (Lektion 330/331: Blazor schiebt
   Kommentar-Knoten zwischen Elemente); min-width:0 gegen horizontalen Overflow. */
.content-editor .locale-tabs { display: flex; flex-wrap: wrap; gap: var(--ph-space-2); margin: var(--ph-space-3) 0; }
.content-editor .locale-editor__grid { display: flex; flex-wrap: wrap; gap: var(--ph-space-4); }
.content-editor .locale-fields { flex: 1 1 320px; min-width: 0; margin: 0; }
.content-editor .locale-preview { flex: 1 1 340px; min-width: 0; display: flex; flex-direction: column; gap: var(--ph-space-2); }
.content-editor .locale-preview h3 { margin: 0; }

/* GH-506: Vorschau-iframe — Standardhoehe (Nicht-Fill/mobil) als Klasse statt inline, damit die
   Fill-Variante die Hoehe ueberschreiben kann (inline style gewaenne sonst ueber externes CSS). */
.locale-preview__frame {
    width: 100%;
    height: clamp(460px, 60vh, 640px);
    border: 1px solid var(--ph-border);
    border-radius: var(--ph-radius-sm);
}

/* GH-506: Fill-Hoehenmodell — inhaltsreiche Dialoge (Editoren + Zielgruppen-Transfer) nehmen eine
   feste hohe Ziel-Hoehe ein und verteilen sie ueber eine durchgaengige min-height:0-Kette an ihre
   Kinder, sodass Vorschau/Listen/Eingabe die Hoehe FUELLEN statt auf festen Deckeln (iframe 640px,
   textarea-rows, transfer-list 20rem) stehenzubleiben. Gesetzt via expliziter --fill-Variante (nicht
   --wide), damit kurze Wide-Dialoge (Kampagnen-Wizard/SMTP/Feedback) unberuehrt shrink-to-fit bleiben.
   Muss VOR der mobilen @media 600px-Regel stehen, die die feste Hoehe zuruecksetzt (gleiche Spezifitaet,
   spaetere Quelle gewinnt). */
.ph-dialog--fill > .ph-card {
    height: min(85dvh, calc(100dvh - 2 * var(--ph-space-5)));
    display: flex;
    flex-direction: column;
}
.ph-dialog--fill .content-editor {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    margin-bottom: 0;
}
.ph-dialog--fill .locale-editor__grid { flex: 1 1 auto; min-height: 0; }
.ph-dialog--fill .locale-fields,
.ph-dialog--fill .locale-preview { min-height: 0; }
/* Eingabe-Textareas fuellen anteilig (Body-HTML 3 : Body-Text 1); feste rows bleiben Mindesthoehe. */
.ph-dialog--fill .locale-field--grow { flex: 3 1 0; min-height: 0; }
.ph-dialog--fill .locale-field--grow-sm { flex: 1 1 0; min-height: 0; }
.ph-dialog--fill .locale-field--grow textarea,
.ph-dialog--fill .locale-field--grow-sm textarea { flex: 1 1 auto; min-height: 0; }
/* Eingabespalte auf lesbare Breite deckeln, Ueberschuss fliesst in die Vorschau. */
.ph-dialog--fill .locale-fields { flex: 1 1 320px; max-width: 60ch; }
.ph-dialog--fill .locale-preview { flex: 2 1 340px; }
/* Vorschau fuellt die Spaltenhoehe (Pixeldeckel entfaellt). */
.ph-dialog--fill .locale-preview__frame { flex: 1 1 auto; height: auto; min-height: 18rem; }
/* Zielgruppen-Transfer-List fuellt die Dialoghoehe (gleicher Fill-Mechanismus). */
.ph-dialog--fill .ph-stack {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
}
.ph-dialog--fill .ph-transfer { flex: 1 1 auto; min-height: 0; }
.ph-dialog--fill .ph-transfer__list { max-height: none; flex: 1 1 auto; }

/* =============================================================================
   Legacy-Kompatibilitaet — die 35 Bestandsseiten nutzen .phishin-*-Klassen, die
   im alten Theme ungestylt waren. Wir mappen sie auf das neue Design-System,
   damit alle Seiten ohne Markup-Aenderung modernisiert werden.
   ========================================================================== */

/* Legacy-`.phishin-*`-Kompatibilitaets-CSS entfernt (adminui-legacy-css-cleanup):
   das gesamte AdminUi ist auf das Design-System migriert (legacy-Ratchet 0), keine Seite
   nutzt diese Klassen mehr. Aktive Bausteine: .ph-btn/.ph-card/.ph-table/.ph-badge/.ph-alert/
   .ph-toolbar/.ph-field/.ph-muted/.ph-table__row--flagged (siehe oben). */

/* ---------- Responsive ----------
   Gestuftes Breakpoint-System (framework-frei; die Werte stehen fest, da @media kein var()
   aufloesen kann — Konvention hier zentral dokumentiert):
     - Desktop  > 1024px : persistente Sidebar links (Grid-Basis oben, unveraendert).
     - Kompakt  <= 1024px: Sidebar als Off-Canvas-Drawer, Hamburger sichtbar, Shell einspaltig.
     - Handy    <=  600px: Topbar-/Content-Feinschliff, nachrangige Topbar-Elemente ausgeblendet. */
@media (max-width: 1024px) {
    .ph-shell {
        grid-template-columns: 1fr;
        grid-template-rows: var(--ph-topbar-height) 1fr;
        grid-template-areas: "topbar" "main";
    }
    /* Sidebar wird zum Off-Canvas-Drawer (von links eingeschoben). Die gruppierte Navigation
       inkl. Bereichs-Labels bleibt erhalten (Orientierung), anders als die alte Wrap-Leiste. */
    .ph-sidebar {
        position: fixed;
        top: 0; left: 0; bottom: 0;
        width: min(86vw, 320px);
        /* dvh statt vh (#345): 100vh schliesst auf Mobil den Bereich hinter der URL-Bar ein → der
           Drawer wird hoeher als der sichtbare Viewport, die untersten Nav-Items ragen dahinter.
           dvh folgt der sichtbaren Hoehe (overflow-y:auto der Basis macht den Rest scrollbar). */
        height: 100vh;
        height: 100dvh;
        z-index: 60;
        transform: translateX(-100%);
        transition: transform 0.24s ease;
        border-right: 1px solid var(--ph-border);
        box-shadow: var(--ph-shadow-lg);
    }
    .ph-scrim { display: block; }
    /* Geoeffneter Drawer: `:has()`-Descendant (nicht Sibling `~`) — s. Kommentar oben. */
    .ph-shell:has(.ph-nav-toggle:checked) .ph-sidebar { transform: translateX(0); }
    .ph-shell:has(.ph-nav-toggle:checked) .ph-scrim { opacity: 1; pointer-events: auto; }
    .ph-hamburger { display: inline-flex; }

    /* Content-Ebene: breite Daten-Tabellen (ph-table, members, oidc-providers,
       isms-assessments, rohe <table>) horizontal scrollbar machen statt die Seite zu sprengen.
       `display: block` macht die Tabelle selbst zum Scroll-Container; die `white-space: nowrap`
       Header halten die natuerliche Breite (→ scrollt statt zu quetschen). Ein Selektor deckt
       alle ~22 Listen-Seiten ab, unabhaengig von der Tabellen-Klasse.
       PFLICHT dazu: `.ph-content` ist das Grid-Item `grid-area: main` und hat damit den Default
       `min-width: auto` → es kann NICHT unter seine Inhaltsbreite schrumpfen, die Tabelle wuerde
       den Container (und die Seite) sprengen statt zu scrollen. `min-width: 0` hebt das auf. */
    .ph-content { min-width: 0; }
    .ph-content table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
    /* Fest zweispaltiges Hilfe-Layout (16rem-Themenliste + Inhalt) einspaltig stapeln. */
    .help-center { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
    /* Die Topbar traegt viele Aktionen (Hamburger, Tenant-Chip, Feedback, Hilfe/2FA/Passwort,
       Avatar, Abmelden), die auf Handy-Breite nicht in EINE Zeile passen. Statt horizontalem
       Overflow darf sie umbrechen: Spacer weg → Elemente fliessen linksbuendig und brechen bei
       Bedarf in eine zweite Zeile um; die Topbar-Grid-Zeile waechst dafuer auf `auto`. */
    .ph-shell { grid-template-rows: auto 1fr; }
    .ph-topbar {
        flex-wrap: wrap;
        height: auto;
        min-height: var(--ph-topbar-height);
        padding: var(--ph-space-2) var(--ph-space-3);
        gap: var(--ph-space-2);
        row-gap: var(--ph-space-2);
    }
    .ph-topbar .ph-spacer { display: none; }
    .ph-content { padding: var(--ph-space-4); }
    .ph-hide-narrow { display: none; }

    /* Overlay-Dialoge auf Handy fast Vollbild: mehr Breite (der Vorlagen-/Inhalts-Editor quetscht
       sonst) + kleinerer Rand/Padding fuer mehr sichtbaren Inhalt. Hoehe via dvh (URL-Bar-sicher),
       die innere Karte scrollt. */
    .ph-dialog {
        width: calc(100vw - 2 * var(--ph-space-3));
        max-height: calc(100dvh - 2 * var(--ph-space-3));
    }
    .ph-dialog > .ph-card {
        max-height: calc(100dvh - 2 * var(--ph-space-3));
        padding: var(--ph-space-4);
    }
    /* GH-506: Fill-Dialoge auf schmalen Viewports zurueck auf shrink-to-fit (dvh-Hoehe wie bisher,
       feste ~85dvh-Zielhoehe gilt nur auf breiteren Viewports). */
    .ph-dialog--fill > .ph-card {
        height: auto;
    }
}

/* Transfer-List (assignment-transfer-list): zwei gefilterte Listen (Kandidaten | Zugeordnet) mit
   Aktionsspalte dazwischen. Nur Design-Tokens, kein rohes Farb-Literal (Design-System-Gate). */
.ph-transfer {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    gap: var(--ph-space-3);
    align-items: stretch;
}
.ph-transfer__pane {
    display: flex;
    flex-direction: column;
    min-width: 0;
    border: 1px solid var(--ph-border);
    border-radius: var(--ph-radius-md);
    background: var(--ph-surface);
    overflow: hidden;
}
.ph-transfer__head {
    display: flex;
    flex-direction: column;
    gap: var(--ph-space-2);
    padding: var(--ph-space-3);
    border-bottom: 1px solid var(--ph-border);
    background: var(--ph-surface-2);
}
.ph-transfer__title {
    font-weight: var(--ph-fw-semibold);
    font-size: var(--ph-text-sm);
    color: var(--ph-fg);
}
.ph-transfer__count {
    color: var(--ph-fg-muted);
    font-weight: var(--ph-fw-regular);
}
.ph-transfer__filter {
    width: 100%;
}
.ph-transfer__list {
    list-style: none;
    margin: 0;
    padding: var(--ph-space-1);
    overflow-y: auto;
    max-height: 20rem;
    min-height: 8rem;
}
.ph-transfer__item {
    margin: 0;
}
.ph-transfer__row {
    display: flex;
    align-items: center;
    gap: var(--ph-space-2);
    padding: var(--ph-space-2);
    border-radius: var(--ph-radius-sm);
    cursor: pointer;
}
.ph-transfer__row:hover {
    background: var(--ph-surface-2);
}
.ph-transfer__text {
    flex: 1 1 auto;
    min-width: 0;
    /* GH-506: lange E-Mail-Adressen umbrechen statt clippen/horizontal scrollen. */
    overflow-wrap: anywhere;
    font-size: var(--ph-text-base);
    color: var(--ph-fg);
}
.ph-transfer__badge {
    flex: 0 0 auto;
}
.ph-transfer__actions {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: var(--ph-space-2);
}
@media (max-width: 720px) {
    .ph-transfer {
        grid-template-columns: 1fr;
    }
    .ph-transfer__actions {
        flex-direction: row;
        justify-content: center;
    }
}
