/* ==========================================================================
   S3.DocCenter – Theme & Base Styles
   Based on S3.NorthDataAutoExporter design system
   ========================================================================== */

/* ---------- CSS Custom Properties ---------- */

:root {
    --font-size: 16px;
    --background: #fafafa;
    --foreground: #1f1f1f;
    --card: #ffffff;
    --card-foreground: #1f1f1f;
    --popover: #ffffff;
    --popover-foreground: #1f1f1f;
    --primary: #0C5DA6;
    --primary-foreground: #ffffff;
    --secondary: #f5f5f5;
    --secondary-foreground: #1f1f1f;
    --muted: #f0f0f0;
    --muted-foreground: #6b6b6b;
    --accent: #e6f7ff;
    --accent-foreground: #0C5DA6;
    --destructive: #ff4444;
    --destructive-foreground: #ffffff;
    --border: #e8e8e8;
    --input: transparent;
    --input-background: #ffffff;
    --font-weight-medium: 500;
    --font-weight-normal: 400;
    --ring: #0C5DA6;
    --radius: 0;
    --sidebar: #333333;
    --sidebar-foreground: #e8e8e8;
    --sidebar-primary: #0C5DA6;
    --sidebar-primary-foreground: #ffffff;
    --sidebar-accent: #3a3a3a;
    --sidebar-accent-foreground: #ffffff;
    --sidebar-border: #444444;
    --sidebar-ring: #0C5DA6;
    --sidebar-submenu: #2b2b2b;
}

/* ---------- Base styles ---------- */

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

html, body {
    height: 100vh;
}

/* PDF.js erstellt versteckte Off-Screen-Canvases als Body-Children.
   Diese Canvases haben height:0 aber position im Dokument, was scrollHeight erhöht. */
body > canvas {
    position: fixed;
    top: 0;
    left: 0;
    pointer-events: none;
}

html {
    font-size: var(--font-size);
}

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    font-size: 1rem;
    font-weight: var(--font-weight-normal);
    line-height: 1.5;
    color: var(--foreground);
    background-color: var(--background);
}

h1 {
    font-size: 1.5rem;
    font-weight: var(--font-weight-medium);
    line-height: 1.5;
    border: none;
    outline: none;
}

h2 {
    font-size: 1.25rem;
    font-weight: var(--font-weight-medium);
    line-height: 1.5;
}

h3 {
    font-size: 1.125rem;
    font-weight: var(--font-weight-medium);
    line-height: 1.5;
}

h4 {
    font-size: 1rem;
    font-weight: var(--font-weight-medium);
    line-height: 1.5;
}

label {
    font-size: 1rem;
    font-weight: var(--font-weight-medium);
    line-height: 1.5;
}

button {
    font-size: 1rem;
    font-weight: var(--font-weight-medium);
    line-height: 1.5;
    cursor: pointer;
}

input {
    font-size: 1rem;
    font-weight: var(--font-weight-normal);
    line-height: 1.5;
}

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

a:hover {
    text-decoration: underline;
}

/* ---------- Shadow utilities ---------- */

.shadow-header {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.shadow-sidebar {
    box-shadow: 2px 0 8px rgba(0, 0, 0, 0.12);
}

.shadow-actionbar {
    box-shadow: 0 -1px 4px rgba(0, 0, 0, 0.06);
}

.shadow-card {
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.10);
}

.shadow-button {
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}

.shadow-dropdown {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}

/* ---------- Layout ---------- */

.layout {
    display: flex;
    flex: 1;
    overflow: hidden;
}

.sidebar {
    background-color: var(--sidebar);
    color: var(--sidebar-foreground);
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
}

.sidebar-animating {
    transition: width 0.2s ease;
}

.sidebar-collapsed {
    width: 64px;
}

.header {
    height: 68px;
    background-color: var(--card);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    padding: 0 1.5rem;
    gap: 1rem;
}

.action-bar {
    background-color: var(--card);
    padding: 0.5rem 2rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    flex-shrink: 0;
    min-height: 48px;
    margin-top: 1rem;
    box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.10), 0 2px 10px rgba(0, 0, 0, 0.10);
    position: relative;
}

.action-bar-loader {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 3px;
    background-color: color-mix(in srgb, var(--primary) 15%, transparent);
    overflow: hidden;
    opacity: 0;
    transition: opacity 0.3s ease;
}

.action-bar-loader.active {
    opacity: 1;
}

.action-bar-loader::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 40%;
    background-color: var(--primary);
    animation: actionbar-loading 1.2s ease-in-out infinite;
}

@keyframes actionbar-loading {
    0%   { left: -40%; }
    100% { left: 100%; }
}

.content-area {
    flex: 1;
    padding: 2rem;
    overflow-y: auto;
    width: 100%;
}

/* ---------- Content-Container (max-width + zentriert) ---------- */

/* Container-Varianten — die jeweilige Page wraps ihren Top-Level-Inhalt
   mit einer dieser Klassen. Breite steht statisch im Markup, kein
   Runtime-State, kein Page-Wechsel-Flicker. */
.container-narrow,
.container-standard,
.container-wide,
.container-full {
    width: 100%;
    margin: 0 auto;
}

/* Seiten stapeln ihre Karten mit einheitlichem Abstand (STANDARDS: Standard-Gap
   0.75rem). Ohne das kleben aufeinanderfolgende Karten aneinander - `.card` bringt
   bewusst keinen eigenen Aussenabstand mit. Muster aus S3.FinCenter.vNext, wo jede
   Seite denselben Stapel selbst definiert; hier einmal zentral. */
.container-narrow,
.container-standard,
.container-wide,
.container-full {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    align-content: start;
}

.container-narrow   { max-width: 720px;  }
.container-standard { max-width: 1040px; }
.container-wide     { max-width: 1584px; }
.container-full     { max-width: none;   }

/* ---------- Status badges ---------- */

.badge {
    display: inline-flex;
    align-items: center;
    padding: 0.125rem 0.5rem;
    font-size: 0.75rem;
    font-weight: var(--font-weight-medium);
    border-radius: 9999px;
    white-space: nowrap;
}

.badge-success {
    background-color: #dcfce7;
    color: #166534;
}

.badge-warning {
    background-color: #fef9c3;
    color: #854d0e;
}

.badge-error {
    background-color: #fee2e2;
    color: #991b1b;
}

.badge-primary {
    background-color: color-mix(in srgb, var(--primary) 12%, transparent);
    color: var(--primary);
}

.badge-muted {
    background-color: var(--muted);
    color: var(--muted-foreground);
}

/* ---------- Tables ---------- */

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.875rem;
}

.data-table th {
    text-align: left;
    padding: 0.625rem 0.75rem;
    font-weight: var(--font-weight-medium);
    color: var(--muted-foreground);
    border-bottom: 2px solid var(--border);
    white-space: nowrap;
    /* Label oben verankern, damit Spalten ohne Filter dasselbe Label-Y
       haben wie Spalten mit Filter (sonst zentriert die default
       vertical-align: middle das Label in der Zelle). */
    vertical-align: top;
}

.data-table td {
    padding: 0.625rem 0.75rem;
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
}

.data-table tbody tr:nth-child(odd) {
    background-color: var(--background);
}

.data-table tbody tr:nth-child(even) {
    background-color: var(--card);
}

.data-table tbody tr:hover {
    background-color: var(--muted);
}

/* Klickbare Zeile — Cursor-Pointer als visuelle Affordance fuer
   Row-Click-Navigation. Action-Buttons in der Zelle haben
   `@onclick:stopPropagation`, damit sie nicht doppelt navigieren. */
.data-table tbody tr.clickable {
    cursor: pointer;
}

/* Fixed Layout — Spaltenbreiten werden aus <col>-Elementen übernommen,
   erlaubt sticky Header ohne Spalten-Verschiebung, schneidet lange
   Inhalte per `text-overflow: ellipsis` in Zellen mit `overflow: hidden`. */
.data-table.data-table-fixed {
    table-layout: fixed;
}

/* Header-Zelle: 2-zeilig — oben Label+Sort, unten Filter-Input/Select */
.data-table .th-label {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.125rem 0;
    user-select: none;
}

.data-table .th-label.sortable {
    cursor: pointer;
}

.data-table .th-label.sortable:hover {
    color: var(--foreground);
}

.data-table .sort-icon {
    opacity: 0.45;
    flex-shrink: 0;
}

.data-table .sort-icon.sort-active {
    opacity: 1;
    color: var(--primary);
}

/* Robustes Safety-Net: greift auch dann, wenn ein Projekt das Sort-Icon ohne
   `sort-icon`-Klasse rendert (nur `icon-sm`) — passierte unabhängig in VDZ +
   HYTORC. Stylt direkt das svg im sortierbaren Header: inaktiv dezenter Grauton,
   aktiv hervorgehoben (egal ob `sort-active` am DIV oder am Icon hängt). */
.data-table .th-label.sortable svg {
    color: var(--muted-foreground);
    opacity: 0.4;
}

.data-table .th-label.sortable.sort-active svg,
.data-table .th-label.sortable svg.sort-active {
    color: var(--primary);
    opacity: 1;
}

.data-table .th-filter-input,
.data-table .th-filter-select {
    width: 100%;
    margin-top: 0.375rem;
    padding: 0.375rem 0.5rem;
    height: 34px;
    box-sizing: border-box;
    font-size: 0.8125rem;
    font-weight: var(--font-weight-normal);
    border: 1px solid var(--border);
    background-color: var(--card);
    color: var(--foreground);
    border-radius: var(--radius);
    outline: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.data-table .th-filter-input:focus,
.data-table .th-filter-select:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 15%, transparent);
}

.data-table .th-filter-input.is-active,
.data-table .th-filter-select.is-active {
    border-color: var(--primary);
    background-color: color-mix(in srgb, var(--primary) 4%, var(--card));
}

.data-table .th-filter-select {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
    background-repeat: no-repeat;
    background-position: right 0.375rem center;
    background-size: 14px;
    padding-right: 1.5rem;
}

/* Select wirkt wie Placeholder solange "Alle" gewählt ist (kein .is-active).
   Optionen im Dropdown bleiben in der normalen Schriftfarbe. */
.data-table .th-filter-select:not(.is-active) {
    color: var(--muted-foreground);
}

.data-table .th-filter-select option {
    color: var(--foreground);
}

/* ----- Filter-Input mit ×-Clear-Button -----
   Wrap übernimmt margin-top vom Input, damit der absolut positionierte
   Clear-Button vertikal mittig im Input sitzt (sonst rutscht er um halben
   Margin nach unten). */
.th-filter-wrap {
    position: relative;
    display: flex;
    align-items: center;
    margin-top: 0.375rem;
}

.th-filter-wrap .th-filter-input {
    flex: 1;
    margin-top: 0;
    padding-right: 1.75rem;
}

.th-filter-clear {
    position: absolute;
    right: 0.375rem;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    background: var(--muted);
    border: none;
    border-radius: 50%;
    color: var(--muted-foreground);
    cursor: pointer;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1;
    padding: 0;
    transition: background-color 0.15s, color 0.15s;
}

.th-filter-clear:hover {
    background: var(--destructive);
    color: #fff;
}

/* ===== Datum-Filter (Popover am Spalten-Header) =====
   Trigger ist ein <div> in der th-Zelle, Popover öffnet via JS-Interop
   (popover-position.js) als position:fixed. Pflicht: font-weight: 400 am
   Trigger, sonst erbt er die 500 von ".data-table th" und der "Zeitraum …"-
   Placeholder wirkt fetter als die Text-Filter-Placeholder daneben. */
.th-date-col {
    position: relative;
    overflow: visible;
}

.th-date-trigger {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.25rem;
    width: 100%;
    margin-top: 0.375rem;
    padding: 0.375rem 0.5rem;
    height: 34px;
    box-sizing: border-box;
    font-size: 0.8125rem;
    font-weight: 400;
    border: 1px solid var(--border);
    background-color: var(--card);
    border-radius: var(--radius);
    color: var(--muted-foreground);
    cursor: pointer;
    transition: border-color 0.15s ease;
}

.th-date-trigger:hover {
    border-color: var(--primary);
}

.th-date-trigger.has-value {
    color: var(--foreground);
}

.th-date-trigger.is-active {
    border-color: var(--primary);
    background-color: color-mix(in srgb, var(--primary) 4%, var(--card));
}

.th-date-display {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.date-chevron {
    margin-left: auto;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    color: #999;
}

.date-popover-overlay {
    position: fixed;
    inset: 0;
    z-index: 49;
}

.date-popover-container {
    display: grid;
    grid-template-columns: auto auto;
    background: var(--card);
    border: 1px solid var(--border);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.14);
}

.date-popover-presets {
    padding: 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 170px;
    border-right: 1px solid var(--border);
    flex-shrink: 0;
}

.date-presets-title {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--muted-foreground);
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 0.25rem 0.5rem 0.375rem;
}

.date-preset-btn {
    font-size: 0.8125rem;
    padding: 0.4rem 0.625rem;
    background: none;
    border: none;
    text-align: left;
    cursor: pointer;
    color: var(--foreground);
    white-space: nowrap;
}

.date-preset-btn:hover {
    background: var(--muted);
}

.date-preset-btn.active {
    background: color-mix(in srgb, var(--primary) 10%, transparent);
    color: var(--primary);
    font-weight: 500;
}

.date-popover {
    padding: 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-width: 220px;
}

.date-popover-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.date-popover-row label {
    font-size: 0.75rem;
    color: var(--muted-foreground);
    width: 28px;
    flex-shrink: 0;
}

.date-popover-row .date-input {
    flex: 1;
    min-width: 0;
    margin-top: 0;
}

.date-popover-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.25rem;
    border-top: 1px solid var(--border);
    padding-top: 0.5rem;
}

.date-popover-apply {
    flex: 1;
    font-size: 0.75rem;
    padding: 0.4rem 0.75rem;
    background: var(--primary);
    color: var(--primary-foreground);
    border: 1px solid var(--primary);
    border-radius: var(--radius);
    cursor: pointer;
    text-align: center;
}

.date-popover-apply:hover {
    opacity: 0.9;
}

.date-popover-clear {
    font-size: 0.75rem;
    color: var(--muted-foreground);
    background: none;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    cursor: pointer;
    padding: 0.4rem 0.75rem;
}

.date-popover-clear:hover {
    color: var(--foreground);
    border-color: var(--foreground);
}

/* Optionale Selected-Row-Markierung — 3px Primary-Border links + leichter
   Primary-Tint. Wird auf `<tr class="selected">` angewendet. */
.data-table tbody tr.selected {
    background-color: color-mix(in srgb, var(--primary) 8%, var(--card)) !important;
    box-shadow: inset 3px 0 0 var(--primary);
}

/* Empty-State-Zeile innerhalb der Tabelle */
.data-table .empty-state-row td {
    padding: 2.5rem 0.75rem;
}

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    /* STANDARDS §3.10 gibt 2.5rem 0.75rem vor. In der Showcase-app.css fehlt das
       Padding - dort klebt der Empty-State an den Kartenkanten. Der geschriebene
       Standard nennt einen konkreten Wert und gewinnt daher. */
    padding: 2.5rem 0.75rem;
    color: var(--muted-foreground);
    text-align: center;
}

/* Innerhalb einer Card bringt der Body bereits 1.25rem mit - dort reicht
   entsprechend weniger, sonst wirkt der Platzhalter aufgeblaeht. */
.fc-card-body > .empty-state {
    padding: 1.25rem 0.75rem;
}

/* Zelle mit Ellipsis — funktioniert nur in data-table-fixed (table-layout: fixed). */
.data-table .cell-ellipsis {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Action-Spalte (icon-only Buttons rechts in der Zeile). Header-Label und
   Body-Buttons rechtsbündig. Gap entsteht durch margin-left an Buttons,
   damit der `<td>` als table-cell-Layout intakt bleibt. */
/* Zeilen der Hauptlisten sind echte Links: ein leerer, ueber die ganze Zeile
   gestreckter <a> liegt in der ersten Zelle. Damit funktionieren Mittelklick,
   Strg+Klick, Kontextmenue und die Adressanzeige beim Ueberfahren so, wie man es von
   Links erwartet - ein reiner @onclick kann das alles nicht.
   Der Beschriftungstext kommt ueber aria-label, weil der Link selbst leer bleiben muss:
   traege er den Titel, wuerde dessen overflow:hidden die eigene Streckung abschneiden. */
.data-table tr.clickable {
    position: relative;
}

.zeilen-link {
    position: absolute;
    inset: 0;
    z-index: 0;
}

/* Die Aktionsspalte muss ueber dem gestreckten Link liegen, sonst faengt er ihre
   Schaltflaechen ab. */
.data-table .cell-actions {
    position: relative;
    z-index: 1;
}

.data-table .cell-actions {
    text-align: right;
    white-space: nowrap;
}

.data-table td.cell-actions .action-btn + .action-btn {
    margin-left: 0.25rem;
}

/* ---------- Cards ---------- */

.card {
    background-color: var(--card);
    color: var(--card-foreground);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.10);
    width: 100%;
}

/* ---------- Buttons ---------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.5rem 1rem;
    font-size: 0.875rem;
    font-weight: var(--font-weight-medium);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--card);
    color: var(--foreground);
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
    text-decoration: none;
}

.btn:hover {
    background-color: var(--muted);
}

.btn:disabled,
.btn[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

.btn-primary {
    background-color: var(--primary);
    color: var(--primary-foreground);
    border-color: var(--primary);
}

.btn-primary:hover {
    background-color: color-mix(in srgb, var(--primary) 85%, #000);
    border-color: color-mix(in srgb, var(--primary) 85%, #000);
}

.btn-secondary {
    background-color: var(--card);
    color: var(--foreground);
    border-color: var(--border);
}

.btn-secondary:hover {
    background-color: var(--muted);
}

.btn-danger {
    background-color: var(--destructive);
    color: var(--destructive-foreground);
    border-color: var(--destructive);
}

.btn-danger:hover {
    background-color: #e03030;
    border-color: #e03030;
}

.btn-sm {
    padding: 0.25rem 0.5rem;
    font-size: 0.8125rem;
}

.action-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: transparent;
    color: var(--foreground);
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.action-btn:hover {
    background-color: var(--muted);
}

.action-btn-danger:hover {
    background-color: #fee2e2;
    color: var(--destructive);
}

.action-bar-title {
    font-size: 1.125rem;
    font-weight: var(--font-weight-medium);
    line-height: 1.5;
    white-space: nowrap;
    border: none;
    outline: none;
    margin: 0;
    padding: 0;
}

.action-bar-title-with-back {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

/* ---------- Forms ---------- */

.form-input {
    width: 100%;
    height: 2.5rem;
    padding: 0.5rem 0.75rem;
    font-size: 0.875rem;
    font-family: inherit;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--input-background);
    color: var(--foreground);
    outline: none;
    transition: border-color 0.15s ease;
}

.form-input:focus {
    border-color: var(--ring);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--ring) 15%, transparent);
}

.form-input[readonly],
.form-input:read-only {
    background-color: var(--background);
    color: var(--muted-foreground);
    cursor: default;
    border-color: var(--border);
}

.form-input[readonly]:focus,
.form-input:read-only:focus {
    border-color: var(--border);
    box-shadow: none;
}

.form-select {
    width: 100%;
    height: 2.5rem;
    padding: 0.5rem 0.75rem;
    font-size: 0.875rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--input-background);
    color: var(--foreground);
    outline: none;
    cursor: pointer;
}

.form-select:focus {
    border-color: var(--ring);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--ring) 15%, transparent);
}

/* Input-Labels bewusst klein und dezent (0.75rem, gedaempft) - Projektkonvention
   fuer DEVEX, die vom S3-Standard (0.875rem, Medium, Vordergrund) abweicht. Gleiche
   Anmutung wie die Feldbeschriftungen des Prototyps (text-xs text-muted-foreground)
   und wie .detail-feld-label. Siehe ADR-018. */
.form-label {
    display: block;
    margin-bottom: 0.25rem;
    font-size: 0.75rem;
    font-weight: var(--font-weight-normal);
    color: var(--muted-foreground);
}

.checkbox-label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    font-size: 0.875rem;
    color: var(--foreground);
}

.form-actions {
    display: flex;
    gap: 0.5rem;
    justify-content: flex-end;
    margin-top: 0.5rem;
}

.alert-success {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.625rem 1rem;
    background-color: #dcfce7;
    color: #166534;
    font-size: 0.875rem;
    border-radius: var(--radius);
}

/* ---------- Modals (STANDARDS §3.5) ---------- */

.modal-backdrop {
    position: fixed;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 100;
}

.modal {
    background-color: var(--card);
    width: 600px;
    max-width: calc(100vw - 32px);
    max-height: 85vh;
    overflow-y: auto;
    padding: 1.5rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.25);
}

.modal-wide {
    width: 1200px;
}

.modal-titel {
    margin: 0 0 1rem;
    font-size: 1.125rem;
    font-weight: var(--font-weight-medium);
}

.modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border);
}

/* Zwischenueberschrift im Formular - gliedert lange Eingabemasken. */
.detail-abschnitt {
    margin: 0.5rem 0 0;
    font-size: 0.875rem;
    font-weight: var(--font-weight-medium);
    color: var(--muted-foreground);
}

.detail-abschnitt:first-child {
    margin-top: 0;
}

/* Mehrfachauswahl im Formular - scrollbare Kaestchenliste statt Multi-Select,
   das sich in Blazor nicht sauber binden laesst. */
.auswahl-liste {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    max-height: 9rem;
    overflow-y: auto;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
}

/* ---------- Speichern-Feedback (STANDARDS §3.19) ---------- */

.btn--saved,
.btn-primary.btn--saved,
.btn-primary.btn--saved:hover {
    background-color: #0a7d2c;
    border-color: #0a7d2c;
    color: #ffffff;
}

/* ---------- Formulare ---------- */

/* Zweispaltiges Feldraster in Formularen und Modals. */
.form-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem 1rem;
}

.form-grid-voll {
    grid-column: 1 / -1;
}

/* Angebot „Konditionen & Vertrieb": feineres 12-Spalten-Raster fuer ungleiche
   Feldbreiten. Waehrung bewusst deutlich schmaler als Zahlungsbedingungen. */
.kond-grid {
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    gap: 0.75rem 1rem;
    align-items: start;
}

.kond-grid > .kond-3 { grid-column: span 3; }
.kond-grid > .kond-6 { grid-column: span 6; }
.kond-grid > .kond-9 { grid-column: span 9; }
.kond-grid > .kond-voll { grid-column: 1 / -1; }

/* Angebot „Dokumente": Dateizeilen mit Icon + Name links, Aktion rechts (Prototyp
   OfferDetail: Word-.docx und PDF, je „Öffnen" oder „Nicht vorhanden"). */
.dokument-liste {
    display: flex;
    flex-direction: column;
}

.dokument-zeile {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--border);
}

.dokument-info {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    min-width: 0;
}

.dokument-name {
    font-size: 0.875rem;
    font-weight: 500;
}

/* Angebot „Dokument-Erstellung": Vorlagenauswahl als Liste statt Select (Prototyp
   OfferDetail). Gewählte Vorlage in getönter Box, darunter die auswählbaren Karten. */
.vorlage-gewaehlt {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.75rem;
    background: var(--accent);
    border: 1px solid var(--border);
}

.vorlage-gewaehlt-text {
    min-width: 0;
}

.vorlage-name {
    font-size: 0.875rem;
    font-weight: 500;
}

.vorlage-liste {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.vorlage-option {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.75rem;
    background: var(--card);
    border: 1px solid var(--border);
    cursor: pointer;
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

.vorlage-option:hover {
    border-color: var(--primary);
}

.vorlage-option-aktiv {
    border-color: var(--primary);
    background: var(--accent);
}

.vorlage-leer {
    padding: 0.75rem;
    border: 1px dashed var(--border);
    font-size: 0.75rem;
    color: var(--muted-foreground);
}

.form-input.is-invalid,
.form-select.is-invalid,
.form-textarea.is-invalid {
    border-color: var(--destructive);
}

.form-fehler {
    margin-top: 0.25rem;
    font-size: 0.75rem;
    color: var(--destructive);
}

.form-textarea {
    width: 100%;
    padding: 0.5rem 0.75rem;
    font-family: inherit;
    font-size: 1rem;
    color: var(--foreground);
    background-color: var(--card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    resize: vertical;
}

.form-textarea:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent);
}

/* Hinweisbanner in derselben Bauform wie .alert-success (STANDARDS §3.4), aber im
   Warnton der Badge-Palette (§3.9). Der Standard kennt bisher nur die Erfolgs-
   Variante; hier gebraucht fuer den Hinweis auf die offene ERP-Spezifikation. */
.alert-info {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.625rem 1rem;
    background-color: #fef9c3;
    color: #854d0e;
    font-size: 0.875rem;
    border-radius: var(--radius);
}

.alert-info-titel {
    font-weight: var(--font-weight-medium);
}

.alert-info-text {
    margin-top: 0.25rem;
    font-size: 0.75rem;
}

.filter-label {
    font-size: 0.875rem;
    font-weight: var(--font-weight-medium);
    color: var(--muted-foreground);
    white-space: nowrap;
}

/* ---------- Pagination ---------- */

.pagination {
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.pagination-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    height: 2rem;
    padding: 0 0.5rem;
    font-size: 0.875rem;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--card);
    color: var(--foreground);
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.pagination-btn:hover {
    background-color: var(--muted);
}

.pagination-btn-active {
    background-color: var(--primary);
    color: var(--primary-foreground);
    border-color: var(--primary);
}

.pagination-btn-active:hover {
    background-color: color-mix(in srgb, var(--primary) 85%, #000);
}

.pagination-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1rem;
    gap: 1rem;
    flex-wrap: wrap;
}

.pagination-info {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    font-size: 0.875rem;
    color: var(--muted-foreground);
}

.pagination-left,
.pagination-right {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.875rem;
    color: var(--muted-foreground);
}

.pagination-range {
    font-variant-numeric: tabular-nums;
}

.pagination-ellipsis {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2rem;
    height: 2rem;
    color: var(--muted-foreground);
    user-select: none;
}

/* Page-Size-Select in der Pagination-Card — eigenständig (nicht von
   .th-filter-select abgeleitet, sonst sind Höhe/Padding/Width vermischt). */
.page-size-select {
    height: 34px;
    box-sizing: border-box;
    padding: 0 1.75rem 0 0.625rem;
    font-size: 0.875rem;
    line-height: 1;
    border: 1px solid var(--border);
    background-color: var(--card);
    color: var(--foreground);
    border-radius: var(--radius);
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
    background-repeat: no-repeat;
    background-position: right 0.5rem center;
    background-size: 14px;
    cursor: pointer;
    outline: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.page-size-select:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 15%, transparent);
}

/* Vertikaler Abstand zwischen Tabellen-Card und Pagination-Card. */
/* Der Stapelabstand kommt vom Seiten-Container; die Klasse bleibt als Haken für
   listenspezifische Regeln. */
.list-page {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/* ---------- Detail-Page ---------- */

.detail-card {
    padding: 1.5rem 2rem;
}

.detail-grid {
    display: grid;
    grid-template-columns: max-content 1fr;
    column-gap: 2rem;
    row-gap: 0.625rem;
    margin: 0;
    font-size: 0.875rem;
}

.detail-grid dt {
    color: var(--muted-foreground);
    font-weight: var(--font-weight-medium);
    margin: 0;
}

.detail-grid dd {
    margin: 0;
    color: var(--foreground);
}

/* Rechtsbuendige Zahlenspalte (Gesamtumsatz, offene Angebote) - der Prototyp
   stellt beide rechtsbuendig mit Tabellenziffern dar. */
.data-table .cell-zahl,
.data-table th.cell-zahl .th-label {
    text-align: right;
    justify-content: flex-end;
}

/* ---------- Bereiche der Kundendetailseite ---------- */

/* Icon-Kachel vor Karten- und Eintragsköpfen (Prototyp: quadratisch, Primary-Ton). */
.icon-kachel {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 2.5rem;
    height: 2.5rem;
    background: color-mix(in srgb, var(--primary) 10%, transparent);
    color: var(--primary);
}

.icon-kachel-gross {
    width: 3rem;
    height: 3rem;
}

.icon-kachel-klein {
    width: 2rem;
    height: 2rem;
}

/* Ansprechpartner: zweispaltiges Kartenraster. */
.kontakt-karten {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem;
    align-items: start;
}

/* Kurze Hervorhebung nach einem Sprung aus der globalen Suche oder der Kontaktliste
   (?highlight={id}): der Rahmen zeigt zwei Sekunden lang, welche Karte gemeint war,
   und verschwindet dann von selbst - eine dauerhafte Markierung müsste man wegklicken. */
.kontakt-karte-hervorgehoben {
    animation: kontakt-hervorheben 2.4s ease forwards;
}

@keyframes kontakt-hervorheben {
    0%, 70% {
        box-shadow: 0 0 0 3px rgba(12, 93, 166, 0.45);
    }
    100% {
        box-shadow: 0 0 0 3px rgba(12, 93, 166, 0);
    }
}

/* Ohne Bewegung bleibt der Rahmen einfach stehen - ein Aufblitzen wäre hier genau das,
   was die Einstellung vermeiden soll. */
@media (prefers-reduced-motion: reduce) {
    .kontakt-karte-hervorgehoben {
        animation: none;
        box-shadow: 0 0 0 3px rgba(12, 93, 166, 0.45);
    }
}

/* Gleiche Polsterung wie .fc-card-header der Card-Komponente - die Koepfe sollen
   ueber alle Karten hinweg auf derselben Hoehe sitzen. */
.kontakt-kopf {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.75rem 1.25rem;
    border-bottom: 1px solid var(--border);
}

.kontakt-kopf-links {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    min-width: 0;
}

.kontakt-name {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    font-weight: var(--font-weight-medium);
}

.kontakt-zeile {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    font-size: 0.875rem;
}

.kontakt-daten {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1.25rem;
}

.kontakt-notiz {
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
}

/* Journal: Zeitstrahl aus Karten, dazwischen schmale Zeilen für Statuswechsel. */
.journal-strang {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.journal-statuswechsel {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.625rem 1rem;
    background: var(--card);
    border: 1px solid var(--border);
    font-size: 0.875rem;
}

.journal-karte {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    padding: 1.25rem;
}

.journal-kopf {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.5rem;
}

.journal-meta {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-top: 0.25rem;
    font-size: 0.75rem;
    color: var(--muted-foreground);
}

.journal-meta span {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

.journal-fuss {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 0.75rem;
    font-size: 0.75rem;
}

.journal-fuss-gruppe {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    flex-wrap: wrap;
    color: var(--muted-foreground);
}

/* Wiedervorlage am Fuß eines Journaleintrags. */
.wiedervorlage {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--border);
}

/* Angebote: Kennzahlen-Kacheln über der Liste. */
.kennzahlen {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.75rem;
}

.kennzahl {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    padding: 1.25rem;
}

.kennzahl-wert {
    font-size: 1.25rem;
    font-weight: var(--font-weight-medium);
    line-height: 1.2;
}

.kennzahl-label {
    margin-top: 0.25rem;
    font-size: 0.875rem;
    color: var(--muted-foreground);
}

.kennzahl-zusatz {
    font-size: 0.75rem;
    color: var(--muted-foreground);
}

.kennzahl-gruen { background: #dcfce7; color: #166534; }
.kennzahl-gelb { background: #fef9c3; color: #854d0e; }

/* Angebotskarte im Angebote-Bereich. */
.angebot-karte {
    padding: 1.25rem;
}

.angebot-kopf {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}

.angebot-nummern {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.75rem;
    color: var(--muted-foreground);
    font-family: monospace;
}

.angebot-rechts {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 0.5rem;
    flex-shrink: 0;
}

.angebot-summe {
    font-size: 1.125rem;
    font-weight: var(--font-weight-medium);
}

.angebot-fuss {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
    font-size: 0.75rem;
}

.angebot-fuss-gruppe {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    color: var(--muted-foreground);
}

.angebot-fuss-gruppe span {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
}

/* Aufklappbarer Status-Verlauf auf der Angebotsdetailseite. */
.status-verlauf > summary {
    font-size: 0.75rem;
    color: var(--muted-foreground);
    cursor: pointer;
    user-select: none;
}

.status-verlauf > summary:hover {
    color: var(--foreground);
}

.status-verlauf-liste {
    margin-top: 0.75rem;
}

.status-verlauf-eintrag {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--border);
}

.status-verlauf-eintrag:last-child {
    border-bottom: none;
}

/* Hervorgehobene Summenzeile am Fuß der Kalkulation. */
.angebot-summe-zeile {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
    font-size: 0.875rem;
}

/* Kompakte Zeilenliste in Übersicht und Dashboard - Icon, Text, optional ein
   Betrag rechts. */
/* Die Liste greift seitlich in die Polsterung der Karte hinein; die Zeilen holen den
   Ueberhang als eigene Polsterung zurueck. Dadurch reicht die Hervorhebung beim
   Ueberfahren ueber das Symbol hinaus, statt direkt an dessen Kante abzuschneiden -
   der Inhalt bleibt trotzdem an derselben Fluchtlinie. */
.uebersicht-liste {
    display: flex;
    flex-direction: column;
    margin: 0 -0.5rem;
}

.uebersicht-zeile {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 0.625rem 0.5rem;
    border-bottom: 1px solid var(--border);
    font-size: 0.875rem;
}

.uebersicht-zeile:last-child {
    border-bottom: none;
}

.uebersicht-zeile.karte-klickbar:hover {
    background: var(--muted);
}

/* Klickbare Karte - gleiche Rückmeldung wie eine Tabellenzeile. */
.karte-klickbar {
    cursor: pointer;
    transition: border-color 0.15s ease;
}

.karte-klickbar:hover {
    border-color: color-mix(in srgb, var(--primary) 50%, transparent);
}

/* Auftragswahrscheinlichkeit als schmaler Balken - Muster aus Offers.tsx.
   Die Farbe steigt mit der Wahrscheinlichkeit. */
.wahrscheinlichkeit {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.25rem;
}

.wahrscheinlichkeit-balken {
    width: 4rem;
    height: 0.375rem;
    background: var(--muted);
    overflow: hidden;
    flex-shrink: 0;
}

.wahrscheinlichkeit-fuellung {
    height: 100%;
}

.wahrscheinlichkeit-wert {
    font-size: 0.75rem;
    color: var(--muted-foreground);
}

/* Termin, der in weniger als 14 Tagen faellig ist - der Prototyp hebt ihn hervor. */
.termin-bald {
    color: #c2410c;
    font-weight: var(--font-weight-medium);
}

/* Fliesstext in einer Datenkarte (Kurzbeschreibung, Notizen). */
.detail-fliesstext {
    font-size: 0.875rem;
    line-height: 1.6;
    white-space: pre-wrap;
}

.detail-leer {
    font-size: 0.875rem;
    color: var(--muted-foreground);
}

/* ---------- Navigation ---------- */

.nav-link {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0 1rem;
    height: 40px;
    font-size: 0.875rem;
    color: var(--sidebar-foreground);
    text-decoration: none;
    border-radius: var(--radius);
    transition: background-color 0.15s ease;
}

.nav-link:hover {
    background-color: var(--sidebar-accent);
    color: var(--sidebar-accent-foreground);
    text-decoration: none;
}

.nav-link-active,
.nav-link.active {
    background-color: var(--sidebar-accent);
    color: var(--sidebar-accent-foreground);
    box-shadow: inset 4px 0 0 var(--sidebar-primary);
}

.nav-link-active:hover,
.nav-link.active:hover {
    background-color: var(--sidebar-accent);
    color: var(--sidebar-accent-foreground);
}

/* ---------- Tree / Nav-Row ---------- */
/* Flat + Tree-Items teilen sich die gleiche nav-link-Struktur.
   Active-Indicator (4px box-shadow) sitzt am Sidebar-Rand.
   Folder-Expand-Chevron ist rechts, damit das Icon direkt
   neben dem Indicator steht. */

.tree-link-folder {
    cursor: pointer;
}

.tree-chevron-right {
    margin-left: auto;
    opacity: 0.6;
    transition: transform 0.15s ease;
}

.tree-chevron-open {
    transform: rotate(90deg);
}

.tree-children {
    position: relative;
    margin-left: 16px;
}

.tree-children::before {
    content: '';
    position: absolute;
    left: 8px;
    top: 2px;
    bottom: 2px;
    width: 1px;
    background-color: var(--sidebar-border);
}

/* Collapsed Sidebar: Baumkinder werden komplett ausgeblendet — nur
   Level-0-Folder bleiben als Icons sichtbar. Dadurch fluchtet jedes
   sichtbare Icon mit den flachen NavLinks. */
.tree-children.sidebar-collapsed {
    display: none;
}

/* Collapsed Sidebar: Chevron am Folder-Header raus, sonst wuerde
   `margin-left: auto` das Folder-Icon aus der zentrierten Spur druecken. */
.nav-collapsed .tree-chevron-right {
    display: none;
}

/* ---------- Icon sizes ---------- */

.icon-sm {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.icon-md {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}

/* ---------- Blazor ReconnectModal ---------- */

.components-reconnect-first-attempt-visible,
.components-reconnect-repeated-attempt-visible,
.components-reconnect-failed-visible,
.components-pause-visible,
.components-resume-failed-visible,
.components-rejoining-animation {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible,
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation,
#components-reconnect-modal.components-reconnect-paused .components-pause-visible,
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible,
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible,
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation,
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible {
    display: block;
}

#components-reconnect-modal:not([open]) {
    display: none;
}

#components-reconnect-modal {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
    color: var(--foreground);
    font-size: 0.875rem;
}

#components-reconnect-modal::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
}

.components-reconnect-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button {
    border: 0;
    background-color: var(--primary);
    color: var(--primary-foreground);
    padding: 0.5rem 1.5rem;
    cursor: pointer;
    font-size: 0.875rem;
    font-weight: var(--font-weight-medium);
}

#components-reconnect-modal button:hover {
    background-color: color-mix(in srgb, var(--primary) 85%, #000);
}

.components-rejoining-animation {
    position: relative;
    width: 60px;
    height: 60px;
}

.components-rejoining-animation div {
    position: absolute;
    border: 3px solid var(--primary);
    opacity: 1;
    border-radius: 50%;
    animation: components-rejoining-animation 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
}

.components-rejoining-animation div:nth-child(2) {
    animation-delay: -0.5s;
}

@keyframes components-rejoining-animation {
    0%, 4.9% {
        top: 30px; left: 30px; width: 0; height: 0; opacity: 0;
    }
    5% {
        top: 30px; left: 30px; width: 0; height: 0; opacity: 1;
    }
    100% {
        top: 0; left: 0; width: 60px; height: 60px; opacity: 0;
    }
}

/* ---------- Formular-spezifisch (kompakte Inputs/Labels) ---------- */

.formular .form-input {
    font-size: 0.8125rem;
    padding: 0.25rem 0.5rem;
    height: 1.75rem;
    min-height: 1.75rem;
    max-height: 1.75rem;
    box-sizing: border-box;
    line-height: 1.2;
}

.formular input[type="date"].form-input {
    padding: 0 0.5rem;
    line-height: 1.75rem;
    font-family: inherit;
    -webkit-appearance: none;
    appearance: none;
}

.formular input[type="date"].form-input::-webkit-datetime-edit {
    padding: 0;
    line-height: 1.75rem;
}

.formular input[type="date"].form-input::-webkit-calendar-picker-indicator {
    padding: 0;
    margin: 0;
}

/* ---------- Text Picker (PDF → Input) ---------- */
/* Cursor im PDF bleibt unverändert (Text-Selektion bleibt natürlich) */

/* ---------- Animations ---------- */

/* Lade-Spinner: neutraler rotierender Ring. Ersetzt im Ladezustand ein Icon —
   Icons selbst drehen NIE (STANDARDS.md § Icons). Erbt die Farbe via currentColor. */
.spinner {
    display: inline-block;
    flex: none;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-top-color: transparent;
    animation: spin 0.7s linear infinite;
    vertical-align: middle;
}

.spinner-sm { width: 16px; height: 16px; }
.spinner-md { width: 20px; height: 20px; }

@keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

/* ---------- Login page ---------- */

.login-page {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    background-color: var(--sidebar);
    padding: 1.5rem;
}

.login-card {
    width: 100%;
    max-width: 400px;
    padding: 2rem;
}

.login-logo {
    display: flex;
    justify-content: center;
    margin-bottom: 1.5rem;
}

.login-logo-img {
    height: 88px;
    width: auto;
}

.login-title {
    text-align: center;
    margin-bottom: 1.5rem;
    color: var(--foreground);
}

.login-field {
    margin-bottom: 1rem;
}

.login-btn {
    width: 100%;
    margin-top: 0.5rem;
}

.login-error {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.625rem 1rem;
    margin-bottom: 1rem;
    background-color: #fee2e2;
    color: #991b1b;
    font-size: 0.875rem;
    border-radius: var(--radius);
}

.login-footer {
    margin-top: 1.5rem;
    text-align: center;
    font-size: 0.6875rem;
    color: var(--sidebar-foreground);
    opacity: 0.5;
    line-height: 1.6;
}

.login-version {
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.01em;
}

.login-fieldset {
    border: 0;
    padding: 0;
    margin: 0;
    min-width: 0;
}

/* ---------- Blazor-specific ---------- */

#blazor-error-ui {
    background: lightyellow;
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

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

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

.valid.modified:not([type=checkbox]) {
    outline: 1px solid #26b050;
}

.invalid {
    outline: 1px solid var(--destructive);
}

/* ==========================================================================
   Projektspezifische Ergaenzungen (DEVEX CRM)

   Diese Klassen fehlen in der S3-Showcase, werden von STANDARDS.md aber
   vorausgesetzt bzw. von den dortigen Vorlagen selbst verwendet. Sie sind hier
   nach der Textspezifikation ergaenzt und sollten bei Gelegenheit in den
   Standard zurueckfliessen (siehe CONTRIBUTING.md des Standards).
   ========================================================================== */

/* Rotation fuer Ladezustaende. Die Showcase nutzt "spin" in ListDemo und
   Administration, definiert die Klasse selbst aber nirgends - nur .spinner. */
.spin {
    animation: spin 0.8s linear infinite;
}

/* Zweite, gedaempfte Zeile in einer Tabellenzelle, z.B. die Kundennummer
   unter dem Firmennamen. */
.cell-subtext {
    font-size: 0.75rem;
    color: var(--muted-foreground);
    margin-top: 0.125rem;
}

/* Erste Zelle der Hauptlisten: Symbolkachel vor dem zweizeiligen Text, wie im
   Prototyp. Kein S3-Standard, sondern eine bewusste Uebernahme - die Kachel macht
   die Zeilen auf einen Blick unterscheidbar (ADR-015).
   `min-width: 0` am Textblock, weil er sonst nicht kuerzt: ein Flex-Element gibt
   von sich aus nicht unter seine Inhaltsbreite nach. */
.zeile-mit-symbol {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.zeile-mit-symbol-text {
    min-width: 0;
}

.zeile-mit-symbol-text > div {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Ziffern gleicher Breite fuer Zahlenspalten - damit Werte untereinander
   ausgerichtet bleiben. Die Showcase setzt die Eigenschaft bisher nur direkt
   in .pagination-range. */
.tabular-nums {
    font-variant-numeric: tabular-nums;
}

/* SSR-Form-Spinner (Muster aus HYTORC.LizenzService und VDZ.PruefCenter).
   Die Anmeldeseite ist statisch gerendert und schickt ein klassisches
   Formular - ein Blazor-Ladezustand ist dort nicht moeglich. Stattdessen
   schaltet form-submit-spinner.js den Button beim Absenden auf .is-loading. */
.login-btn-spinner {
    display: none;
}

.login-btn.is-loading {
    pointer-events: none;
    opacity: 0.85;
}

.login-btn.is-loading .login-btn-spinner {
    display: inline-flex;
}

/* ===== Detailseite mit Unternavigation =====

   Uebernommen aus HG.HGVerwaltung, das es seinerseits von VDZ.PruefCenter hat -
   das etablierte Hausmuster fuer Detailseiten. Die S3-Showcase kennt dafuer
   kein Pendant: ihre Detailvorlage ist einseitig, die Tab-Klassen aus
   STANDARDS §3.11 sind dort nicht implementiert. */

.detail-layout {
    display: grid;
    grid-template-columns: 300px 1fr;
    gap: 0.75rem;
    align-items: stretch;
}

.detail-sidebar {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.detail-submenu {
    padding: 1rem;
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
}

.detail-submenu-head {
    padding: 1.25rem;
    border-bottom: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    gap: 0;
}

.detail-submenu-head-nr {
    font-size: 0.75rem;
    color: var(--muted-foreground);
    font-variant-numeric: tabular-nums;
}

.detail-submenu-item {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.5rem 0.75rem;
    font-size: 0.875rem;
    color: var(--foreground);
    text-decoration: none;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.detail-submenu-item:hover {
    background: var(--muted);
}

.detail-submenu-item.active {
    background: var(--primary);
    color: var(--primary-foreground);
}

.detail-content {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    min-width: 0;
}

.detail-content > .card {
    margin-top: 0;
}

/* Kopf des Untermenues. Traegt wie im Prototyp die Identifikation des
   Datensatzes: Firmenname, Nummer, Branche, Ort und die Kurzbeschreibung.
   Bewusst KEINE voll breite Kopfkarte ueber Menue und Inhalt - der Prototyp
   fuehrt diese Angaben ausschliesslich hier im Menuekopf. */
.detail-submenu-name {
    font-size: 1rem;
    font-weight: var(--font-weight-medium);
    color: var(--foreground);
    line-height: 1.3;
}

.detail-submenu-head-branche {
    margin-top: 0.25rem;
    font-size: 0.875rem;
    color: var(--muted-foreground);
}

.detail-submenu-head-ort {
    font-size: 0.75rem;
    color: var(--muted-foreground);
}

.detail-submenu-beschreibung {
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
    font-size: 0.75rem;
    line-height: 1.6;
    color: var(--muted-foreground);
}

/* Datensatz-Navigation in der ActionBar (vorheriger/naechster Datensatz). */
.record-nav {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    margin-left: 1rem;
}

.record-nav-count {
    font-size: 0.875rem;
    color: var(--muted-foreground);
    min-width: 3.25rem;
    text-align: center;
}

/* Datenkarten nebeneinander im Inhaltsbereich. Der Prototyp stellt die
   Stammdaten dreispaltig dar, Kurzbeschreibung und Notizen zweispaltig.
   Kein `align-items: start` - die Karten einer Reihe sollen wie im Prototyp
   auf gleiche Hoehe ziehen (Grid-Standard `stretch`). */
.detail-spalten {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem;
}

/* Dashboard: zwei Spalten, in denen jede Karte ihre natuerliche Hoehe behaelt und die
   naechste direkt darunter anschliesst. Bewusst nicht .detail-spalten - das ist ein
   Raster, das die Karten einer Zeile aneinander koppelt. Auf den Detailseiten ist genau
   das gewollt (gleich hohe Boxen), auf dem Dashboard nicht: dort sind die Listen
   unterschiedlich lang, und eine gestreckte Karte hinterlaesst eine leere Flaeche. */
.dashboard-spalten {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem;
    align-items: start;
}

.dashboard-spalte {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.detail-spalten-3 {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.75rem;
}

/* Feldliste innerhalb einer Datenkarte: Label ueber dem Wert (Prototyp-Muster).
   Bewusst NICHT das zweispaltige .detail-grid - der Prototyp stapelt. */
.detail-felder {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.detail-feld-label {
    font-size: 0.75rem;
    color: var(--muted-foreground);
    margin-bottom: 0.25rem;
}

.detail-feld-wert {
    font-size: 0.875rem;
    color: var(--foreground);
}

/* Anzeigewert mit vorangestelltem Symbol - ohne Flex sitzt das SVG auf der Grundlinie
   und schiebt die Zeile auseinander. */
.detail-feld-wert-icon {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    color: var(--muted-foreground);
}

/* Herkunftsangabe im Kopf der Kurzbeschreibung-Karte. */
.detail-karte-meta {
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--muted-foreground);
}

/* Angebotssumme im Formular: Eingabefeld statt reiner Anzeige, weil die Summe laut
   Konzept F.04 manuell uebersteuerbar ist. Solange sie berechnet wird, ist das Feld
   getoent - so ist auf einen Blick erkennbar, ob ein Wert fest vorgegeben wurde. */
.angebot-summe-eingabe {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.angebot-summe-eingabe .form-input {
    width: 11rem;
    text-align: right;
}

.form-input.ist-berechnet {
    background-color: var(--muted);
}

.btn-link {
    background: none;
    border: none;
    padding: 0;
    font-family: inherit;
    font-size: 0.75rem;
    color: var(--primary);
    cursor: pointer;
}

.btn-link:hover {
    text-decoration: underline;
}

/* Uebersichtszeilen sind echte Links (Mittelklick, Strg+Klick, Kontextmenue). Als <a>
   erben sie sonst Linkfarbe und Unterstreichung - beides ist hier unerwuenscht, die
   Zeile soll aussehen wie zuvor. */
a.uebersicht-zeile {
    color: inherit;
    text-decoration: none;
}

a.uebersicht-zeile:hover {
    text-decoration: none;
}

/* Untergeordnete Leiste unter der ActionBar (Dashboard-Umschalter). Bewusst ohne
   margin-top und ohne eigenen Schatten: die ActionBar soll ein schwebender Streifen
   bleiben, diese Leiste haengt sichtbar daran. Seitliche Polsterung wie die ActionBar. */
.action-bar-sub {
    background-color: var(--card);
    padding: 0.5rem 2rem;
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    flex-shrink: 0;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.10);
}

/* Segmentierter Umschalter - zwei Knoepfe in einer getoenten Schiene, der aktive
   hebt sich als heller Block ab (Muster aus Dashboard.tsx). */
.segment-schiene {
    display: inline-flex;
    align-items: center;
    gap: 0.125rem;
    background-color: var(--muted);
    padding: 0.125rem;
}

.segment-knopf {
    padding: 0.375rem 0.75rem;
    font-family: inherit;
    font-size: 0.75rem;
    font-weight: var(--font-weight-normal);
    color: var(--muted-foreground);
    background: none;
    border: none;
    border-radius: var(--radius);
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}

.segment-knopf:hover {
    color: var(--foreground);
}

.segment-knopf.aktiv {
    background-color: var(--card);
    color: var(--foreground);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}

.action-bar-sub-label {
    font-size: 0.75rem;
    color: var(--muted-foreground);
}

.action-bar-sub .form-select {
    width: auto;
    height: auto;
    padding: 0.25rem 0.5rem;
    font-size: 0.75rem;
}

/* Kalkulation (OfferDetail.tsx): Zwischensumme "Summe Kalkulation" mit Trennlinie
   darüber, die Endsumme mit kräftigerer Linie abgesetzt. */
.kalk-zwischensumme {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
    font-size: 0.875rem;
    color: var(--muted-foreground);
}

.angebot-summe-final {
    padding-top: 0.75rem;
    border-top: 2px solid var(--foreground);
}

/* Korrekturhinweis im Status-Bereich (OfferDetail.tsx: gelber Kasten). Macht den beim
   Anfordern erfassten Kommentar sichtbar. */
.korrektur-hinweis {
    margin-top: 0.5rem;
    padding: 0.75rem;
    background-color: #fef9c3;
    border: 1px solid #fde68a;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.korrektur-eintrag {
    padding: 0.5rem;
    background-color: var(--card);
    border: 1px solid #fde68a;
}

/* Kalkulation als Rechenblatt (OfferDetail.tsx): Label links, schmales rechtsbündiges
   Zahlenfeld rechts, alle Werte auf einer rechten Spalte. */
.kalk-blatt {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.kalk-zeile {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

/* Wie .form-label klein und dezent (ADR-018); nur die Position weicht ab (links
   statt darüber), weil die Kalkulation ein Rechenblatt ist. */
.kalk-zeile > label {
    font-size: 0.75rem;
    font-weight: var(--font-weight-normal);
    color: var(--muted-foreground);
}

.form-input.kalk-feld {
    width: 11rem;
    flex-shrink: 0;
    text-align: right;
}

.kalk-feld-wert {
    width: 11rem;
    text-align: right;
}

/* Aufschlagsfelder rechtsbündig gruppiert, Beschriftung darüber. */
.kalk-aufschlag {
    display: flex;
    justify-content: flex-end;
    gap: 1rem;
}

.kalk-aufschlag > div {
    display: flex;
    flex-direction: column;
}

.kalk-aufschlag label {
    font-size: 0.75rem;
    font-weight: var(--font-weight-normal);
    color: var(--muted-foreground);
    text-align: right;
    margin-bottom: 0.25rem;
}

/* Endsumme: Beschriftung in derselben Größe wie die Zwischensumme "Summe Kalkulation"
   (0.875rem), Zahl zusätzlich fett im Feld. */
.angebot-summe-final > span {
    font-size: 0.875rem;
    color: var(--muted-foreground);
}

.angebot-summe-final .form-input {
    font-weight: var(--font-weight-medium);
}

/* Kundenauswahl im Angebot (FirmaAutocomplete). Gewählter Kunde als Kästchen mit
   Ändern-Knopf; beim Suchen eine Trefferliste wie bei der globalen Suche. */
.firma-auswahl {
    position: relative;
}

/* Gewählt: Namensfeld (wie ein Eingabefeld) mit "×" zum Leeren, daneben der
   Sprung-zum-Kunden-Knopf (CustomerAutocomplete). */
.firma-auswahl-zeile {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.firma-auswahl-gewaehlt {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 1;
    min-width: 0;
    height: 2.5rem;
    padding: 0.375rem 0.75rem;
    border: 1px solid var(--border);
    background-color: var(--card);
    /* Gleiche Schriftgröße und Höhe wie ein Eingabefeld, damit der gewählte Kunde
       nicht größer wirkt als andere Inputs. */
    font-size: 0.875rem;
}

.firma-auswahl-gewaehlt .firma-auswahl-name {
    flex: 1;
}

.firma-auswahl-x {
    flex-shrink: 0;
    border: none;
    background: none;
    padding: 0;
    font-size: 1.125rem;
    line-height: 1;
    color: var(--muted-foreground);
    cursor: pointer;
}

.firma-auswahl-x:hover {
    color: var(--foreground);
}

.firma-auswahl-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.firma-auswahl-liste {
    position: absolute;
    top: 100%;
    left: 0;
    /* Mindestens so breit wie das Eingabefeld, darf aber fuer lange Firmennamen
       breiter werden (bis zu einer Obergrenze), statt umzubrechen. */
    min-width: 100%;
    width: max-content;
    max-width: 32rem;
    margin-top: 0.25rem;
    max-height: 15rem;
    overflow-y: auto;
    background-color: var(--popover);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    z-index: 50;
}

/* Trefferzeile: "Name (Nummer)" einzeilig, ohne Symbol. */
.firma-auswahl-treffer {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    font-size: 0.875rem;
    cursor: pointer;
}

.firma-auswahl-treffer .firma-auswahl-name {
    font-weight: var(--font-weight-medium);
}

.firma-auswahl-nummer {
    color: var(--muted-foreground);
}

/* Tastatur-Hervorhebung (Primary-Tönung) und die aktuell gewählte Firma (Akzent). */
.firma-auswahl-treffer.ist-hervorgehoben {
    background-color: color-mix(in srgb, var(--primary) 10%, transparent);
}

.firma-auswahl-treffer.ist-gewaehlt {
    background-color: var(--accent);
}

.firma-auswahl-leer {
    padding: 0.75rem;
    font-size: 0.875rem;
    color: var(--muted-foreground);
}

/* Grunddaten-Raster (OfferDetail.tsx): erste Zeile dreispaltig, dann Zweierpaare. */
.grunddaten-block {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.grunddaten-3 {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
}

.grunddaten-2 {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
}

/* Vollflächiger Klickfänger hinter aufgeklappten Dropdowns. Global, weil ihn mehrere
   Komponenten nutzen (globale Suche, Kopfmenü, Kundenauswahl im Angebot) - in scoped
   Component-CSS wirkt die Regel wegen der CSS-Isolation nur in der jeweiligen Komponente,
   nicht in FirmaAutocomplete. Die aufgeklappte Liste liegt mit z-index 50 darüber. */
.dropdown-overlay {
    position: fixed;
    inset: 0;
    z-index: 49;
}
