/* ═══════════════════════════════════════════════════════════════════════════
   LokalWeb Hub — design system
   Brand: LokalWeb blue #004AAD (wordmark) · signal orange #FF3C00 (icon) · Inter
   ═══════════════════════════════════════════════════════════════════════════ */

@font-face { font-family: 'Inter'; src: url('../fonts/inter-400.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('../fonts/inter-500.woff2') format('woff2'); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('../fonts/inter-600.woff2') format('woff2'); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: 'Inter'; src: url('../fonts/inter-700.woff2') format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }

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

:root {
    /* Brand */
    --brand:        #004AAD;
    --brand-600:    #003C8C;
    --brand-700:    #002E6B;
    --brand-100:    #E3EDFA;
    --brand-50:     #F1F6FD;
    --signal:       #FF3C00;
    --signal-100:   #FFE8E0;

    /* Surfaces */
    --bg:           #F5F7FA;
    --surface:      #FFFFFF;
    --surface-2:    #F8FAFC;
    --surface-3:    #F1F5F9;
    --border:       #E2E8F0;
    --border-light: #EEF2F6;
    --border-strong:#CBD5E1;

    /* Text */
    --text:         #0F172A;
    --text-2:       #475569;
    --muted:        #64748B;
    --muted-2:      #94A3B8;
    --on-brand:     #FFFFFF;

    /* Semantic */
    --success:      #059669;
    --success-bg:   #D1FAE5;
    --success-fg:   #065F46;
    --warn:         #D97706;
    --warn-bg:      #FEF3C7;
    --warn-fg:      #92400E;
    --danger:       #DC2626;
    --danger-bg:    #FEE2E2;
    --danger-fg:    #991B1B;
    --info:         #0284C7;
    --info-bg:      #DBEAFE;
    --info-fg:      #1E40AF;

    /* Provider accents */
    --gmb:          #34A853;
    --gsc:          #F9AB00;
    --gads:         #4285F4;
    --ga4:          #E8710A;
    --mads:         #00A4EF;

    /* Chart series */
    --c1: #004AAD; --c2: #FF3C00; --c3: #059669; --c4: #7C3AED;
    --c5: #D97706; --c6: #0891B2; --c7: #DB2777; --c8: #65A30D;

    /* Elevation */
    --shadow-xs:  0 1px 2px rgba(15,23,42,.05);
    --shadow-sm:  0 1px 3px rgba(15,23,42,.07), 0 1px 2px rgba(15,23,42,.04);
    --shadow:     0 4px 14px rgba(15,23,42,.07), 0 2px 6px rgba(15,23,42,.04);
    --shadow-lg:  0 12px 36px rgba(15,23,42,.11), 0 4px 12px rgba(15,23,42,.06);

    /* Geometry */
    --r-sm: 8px; --r: 12px; --r-lg: 16px; --r-pill: 999px;
    --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px;
    --sp-5: 24px; --sp-6: 32px; --sp-7: 48px;

    --font: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

    --sidebar-w: 244px;
    --header-h: 60px;
}

:root[data-theme="dark"] {
    --brand:        #4D8FE8;
    --brand-600:    #6BA3EE;
    --brand-700:    #8FBBF3;
    --brand-100:    #16294A;
    --brand-50:     #111E33;
    --signal:       #FF6234;
    --signal-100:   #3B1A0E;

    --bg:           #0B1220;
    --surface:      #131C2E;
    --surface-2:    #18233A;
    --surface-3:    #1E2B45;
    --border:       #263449;
    --border-light: #1D2941;
    --border-strong:#33445E;

    --text:         #E8EEF7;
    --text-2:       #B4C2D6;
    --muted:        #8A9AB2;
    --muted-2:      #64748B;

    --success-bg:   #06301F; --success-fg: #6EE7B7;
    --warn-bg:      #37250A; --warn-fg:    #FCD34D;
    --danger-bg:    #3B1214; --danger-fg:  #FCA5A5;
    --info-bg:      #10243F; --info-fg:    #93C5FD;

    --shadow-xs: 0 1px 2px rgba(0,0,0,.3);
    --shadow-sm: 0 1px 3px rgba(0,0,0,.35);
    --shadow:    0 4px 14px rgba(0,0,0,.4);
    --shadow-lg: 0 12px 36px rgba(0,0,0,.5);
}

html { scroll-behavior: smooth; }
body {
    background: var(--bg); color: var(--text);
    font-family: var(--font); font-size: 14.5px; line-height: 1.6;
    -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}
a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }
h1,h2,h3,h4 { line-height: 1.25; letter-spacing: -.02em; font-weight: 700; }
h1 { font-size: 24px; } h2 { font-size: 18px; } h3 { font-size: 15px; }
small { font-size: 12px; }
code, pre, .mono { font-family: var(--mono); font-size: .92em; }
::selection { background: var(--brand-100); color: var(--brand-700); }

:focus-visible {
    outline: 2px solid var(--brand);
    outline-offset: 2px;
    border-radius: 4px;
}

.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
.skip-link {
    position: absolute; left: -9999px; top: 0; z-index: 200;
    background: var(--brand); color: #fff; padding: 10px 18px; border-radius: 0 0 var(--r) 0;
}
.skip-link:focus { left: 0; }

/* ── Shell ──────────────────────────────────────────────────────────────── */

.shell { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100vh; }

.sidebar {
    background: var(--surface); border-right: 1px solid var(--border);
    display: flex; flex-direction: column;
    position: sticky; top: 0; height: 100vh; overflow-y: auto;
    scrollbar-width: thin;
}
.sidebar-brand {
    display: flex; align-items: center; gap: 10px;
    padding: 16px 18px 14px; border-bottom: 1px solid var(--border-light);
}
.sidebar-brand img { height: 26px; width: auto; display: block; }
.sidebar-brand .env-tag {
    margin-left: auto; font-size: 9.5px; font-weight: 700; letter-spacing: .07em;
    text-transform: uppercase; padding: 2px 6px; border-radius: var(--r-pill);
    background: var(--signal-100); color: var(--signal);
}
.sidebar-scroll { flex: 1; padding: 12px 0 8px; }
.nav-section {
    font-size: 10px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
    color: var(--muted-2); padding: 14px 20px 6px;
}
.nav { list-style: none; padding: 0 10px; }
.nav a {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 11px; border-radius: 9px;
    font-size: 13.5px; font-weight: 500; color: var(--text-2);
    transition: background .14s, color .14s;
}
.nav a:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.nav a.active { background: var(--brand-100); color: var(--brand); font-weight: 650; }
.nav a.active .nav-icon { color: var(--brand); }
.nav-icon { width: 17px; height: 17px; flex-shrink: 0; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; color: var(--muted); }
.nav-count {
    margin-left: auto; font-size: 10.5px; font-weight: 700; min-width: 18px; text-align: center;
    padding: 1px 6px; border-radius: var(--r-pill); background: var(--danger); color: #fff;
}
.nav-count.quiet { background: var(--surface-3); color: var(--muted); }
.sidebar-foot { padding: 12px; border-top: 1px solid var(--border-light); }

/* dvh statt vh: auf dem Telefon rechnet vh mit dem Sichtfenster *ohne* eingeblendete
   Browserleisten, die Spalte waere also zu hoch und der Seitenfuss unerreichbar. */
.main { display: flex; flex-direction: column; min-height: 100dvh; min-width: 0; }

/* Overlay behind the off-canvas sidebar. Hidden by default at every width — it is
   only ever shown below the mobile breakpoint. Without this default rule it would be
   a visible element on desktop, and any layout that treats it as a sibling of the
   sidebar and the content column would place the content in the wrong cell. */
.sidebar-backdrop { display: none; }
.topbar {
    background: var(--surface); border-bottom: 1px solid var(--border);
    height: var(--header-h); padding: 0 24px;
    display: flex; align-items: center; gap: 14px;
    position: sticky; top: 0; z-index: 30;
}
.topbar h1 { font-size: 17px; font-weight: 700; }
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.content { padding: 24px; flex: 1; min-width: 0; }

/* Eine Seite, die den verbleibenden Platz füllen will (der Assistent), kann ihn nicht
   ausrechnen: über ihr steht eine Statusmeldung wechselnder Höhe, und CSS kann die Höhe
   eines vorherigen Geschwisters nicht lesen. Statt sie zu schätzen, wird die Spalte hier
   zur Flexbox — dann bleibt der Rest übrig, wie viel die Meldung auch einnimmt.
   `min-height: 0` ist dabei nicht optional: ohne das darf ein Flex-Kind nicht unter
   seine Inhaltshöhe schrumpfen und der innere Bildlauf entsteht nie.
   Die Regel greift nur, wenn wirklich eine solche Seite darin steht. */
.content:has(> .fills-height) {
    display: flex;
    flex-direction: column;
    min-height: 0;
    /* Die Flexbox allein *verteilt* nur — sie *begrenzt* nicht. `.main` trägt ein
       min-height, also ein Minimum: ohne Obergrenze wächst die Spalte mit dem Inhalt
       mit, der innere Bildlauf entsteht nie, und das Eingabefeld rutscht unter den
       Bildrand (gemessen: 1294 px daneben bei dreizehn Nachrichten auf 390×780).

       Die Grenze ist keine Schätzung: `.content` beginnt unter der Kopfleiste, deren
       Höhe als Token feststeht, und die Statusmeldung liegt *innerhalb* von `.content`
       — sie nimmt sich ihren Teil aus demselben Budget, statt die Spalte zu schieben.
       dvh statt vh, weil `.shell` mit 100vh aufzieht und vh auf dem Telefon die
       eingeblendeten Browserleisten nicht mitrechnet. */
    max-height: calc(100dvh - var(--header-h));
}
.content:has(> .fills-height) > .flashes { flex: none; }
.content:has(> .fills-height) > .fills-height { flex: 1; min-height: 0; }
.page-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 16px; flex-wrap: wrap; margin-bottom: 20px;
}
.page-head .sub { color: var(--muted); font-size: 13px; margin-top: 2px; }
.page-actions { display: flex; gap: 8px; flex-wrap: wrap; }

#menu-toggle { display: none; }

/* ── Cards & grids ──────────────────────────────────────────────────────── */

.card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r); padding: 20px; box-shadow: var(--shadow-xs);
}
.card.pad-0 { padding: 0; }
.card-head {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; margin-bottom: 16px; flex-wrap: wrap;
}
.card-head h2 { font-size: 15px; font-weight: 700; margin: 0; }
.card-head .sub { font-size: 12px; color: var(--muted); font-weight: 400; }
.card-foot {
    margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border-light);
    display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
}
.card--accent { border-left: 3px solid var(--accent-color, var(--brand)); }

.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
.grid-5 { grid-template-columns: repeat(5, minmax(0,1fr)); }
.grid-sidebar { grid-template-columns: minmax(0,2fr) minmax(0,1fr); }
.stack { display: flex; flex-direction: column; gap: 16px; }
.row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }
.row-between { display: flex; gap: 12px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.spacer { flex: 1; }

/* ── KPI tiles ──────────────────────────────────────────────────────────── */

.kpi {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r); padding: 16px 18px;
    display: flex; flex-direction: column; gap: 3px;
    box-shadow: var(--shadow-xs); transition: box-shadow .15s, transform .15s;
    color: inherit; text-decoration: none;
}
a.kpi:hover { box-shadow: var(--shadow); transform: translateY(-1px); text-decoration: none; }
.kpi-label {
    font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
    color: var(--muted);
}
.kpi-value { font-size: 1.85rem; font-weight: 700; letter-spacing: -.035em; line-height: 1.15; }
.kpi-value.sm { font-size: 1.4rem; }
.kpi-sub { font-size: 11.5px; color: var(--muted-2); }
.kpi-row { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.kpi--brand .kpi-value { color: var(--brand); }
.kpi--signal .kpi-value { color: var(--signal); }
.kpi--success .kpi-value { color: var(--success); }
.kpi--danger .kpi-value { color: var(--danger); }

.delta {
    display: inline-flex; align-items: center; gap: 2px;
    font-size: 11px; font-weight: 700; line-height: 1; white-space: nowrap;
}
.delta.up   { color: var(--success); }
.delta.down { color: var(--danger); }
.delta.flat { color: var(--muted); }
/* An increase is not always good — cost going up is bad. Callers add .invert. */
.delta.invert.up   { color: var(--danger); }
.delta.invert.down { color: var(--success); }

/* ── Buttons ────────────────────────────────────────────────────────────── */

.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    font-family: var(--font); font-size: 13.5px; font-weight: 650; line-height: 1;
    padding: 9px 16px; border-radius: 9px; border: 1px solid transparent;
    cursor: pointer; transition: background .14s, border-color .14s, transform .1s, box-shadow .14s;
    white-space: nowrap; text-decoration: none;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--brand); color: #fff; }
.btn-primary:hover { background: var(--brand-600); box-shadow: 0 4px 12px rgba(0,74,173,.28); }
.btn-signal { background: var(--signal); color: #fff; }
.btn-signal:hover { filter: brightness(1.07); box-shadow: 0 4px 12px rgba(255,60,0,.3); }
.btn-ghost { background: var(--surface); color: var(--text); border-color: var(--border); }
.btn-ghost:hover { background: var(--surface-2); border-color: var(--border-strong); }
.btn-quiet { background: transparent; color: var(--text-2); }
.btn-quiet:hover { background: var(--surface-2); color: var(--text); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-danger:hover { filter: brightness(1.07); }
.btn-danger-ghost { background: var(--surface); color: var(--danger); border-color: var(--border); }
.btn-danger-ghost:hover { background: var(--danger-bg); border-color: var(--danger); color: var(--danger-fg); }
.btn-sm { padding: 6px 11px; font-size: 12px; border-radius: 7px; }
.btn-lg { padding: 12px 22px; font-size: 15px; border-radius: 10px; }
.btn-block { width: 100%; }
.btn:disabled, .btn.is-disabled { opacity: .5; pointer-events: none; }
.btn svg { width: 15px; height: 15px; stroke-width: 2; flex-shrink: 0; }
.btn-group { display: inline-flex; gap: 0; }
.btn-group .btn { border-radius: 0; border-right-width: 0; }
.btn-group .btn:first-child { border-radius: 9px 0 0 9px; }
.btn-group .btn:last-child { border-radius: 0 9px 9px 0; border-right-width: 1px; }

/* ── Badges & pills ─────────────────────────────────────────────────────── */

.badge {
    display: inline-flex; align-items: center; gap: 4px;
    font-size: 10.5px; font-weight: 700; letter-spacing: .02em;
    padding: 3px 9px; border-radius: var(--r-pill); white-space: nowrap;
}
.badge--muted   { background: var(--surface-3); color: var(--muted); }
.badge--success { background: var(--success-bg); color: var(--success-fg); }
.badge--warn    { background: var(--warn-bg);    color: var(--warn-fg); }
.badge--danger  { background: var(--danger-bg);  color: var(--danger-fg); }
.badge--info    { background: var(--info-bg);    color: var(--info-fg); }
.badge--brand   { background: var(--brand-100);  color: var(--brand); }

.tag {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 11px; font-weight: 600; padding: 2px 9px;
    border-radius: var(--r-pill); background: var(--surface-3); color: var(--text-2);
}
.tag .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

.avatar {
    width: 32px; height: 32px; border-radius: 50%; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 11.5px; font-weight: 700; color: #fff; letter-spacing: .02em;
}
.avatar.sm { width: 24px; height: 24px; font-size: 9.5px; }
.avatar.lg { width: 44px; height: 44px; font-size: 15px; }
.avatar-1 { background: #004AAD; } .avatar-2 { background: #FF3C00; }
.avatar-3 { background: #059669; } .avatar-4 { background: #7C3AED; }
.avatar-5 { background: #D97706; } .avatar-6 { background: #0891B2; }
.avatar-7 { background: #DB2777; } .avatar-8 { background: #65A30D; }

/* ── Forms ──────────────────────────────────────────────────────────────── */

.form { display: flex; flex-direction: column; gap: 15px; }
.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.field > label, .label {
    font-size: 12.5px; font-weight: 650; color: var(--text-2);
    display: flex; align-items: center; gap: 5px;
}
.field .hint { font-size: 11.5px; color: var(--muted-2); }
.field .error { font-size: 11.5px; color: var(--danger); font-weight: 600; }
.req { color: var(--signal); }

input[type=text], input[type=email], input[type=password], input[type=number],
input[type=date], input[type=month], input[type=tel], input[type=url], input[type=search],
select, textarea, .input {
    width: 100%; font-family: var(--font); font-size: 14px; color: var(--text);
    background: var(--surface); border: 1px solid var(--border);
    border-radius: 9px; padding: 9px 12px;
    transition: border-color .14s, box-shadow .14s;
}
textarea { min-height: 90px; resize: vertical; line-height: 1.55; }
select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2364748B' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 10px center;
    padding-right: 32px;
}
input:focus, select:focus, textarea:focus, .input:focus {
    outline: none; border-color: var(--brand);
    box-shadow: 0 0 0 3px rgba(0,74,173,.12);
}
input[aria-invalid="true"], .input.is-error { border-color: var(--danger); }
input:disabled, select:disabled, textarea:disabled { background: var(--surface-3); color: var(--muted); cursor: not-allowed; }
input::placeholder, textarea::placeholder { color: var(--muted-2); }
.input-money { text-align: right; font-variant-numeric: tabular-nums; }

.check { display: flex; align-items: flex-start; gap: 9px; font-size: 13.5px; cursor: pointer; font-weight: 500; }
.check input[type=checkbox], .check input[type=radio] {
    width: 16px; height: 16px; margin-top: 2px; accent-color: var(--brand); flex-shrink: 0; cursor: pointer;
}
.field-row { display: grid; gap: 14px; grid-template-columns: repeat(2, minmax(0,1fr)); }
.field-row-3 { display: grid; gap: 14px; grid-template-columns: repeat(3, minmax(0,1fr)); }

.filters {
    display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r); padding: 14px 16px; margin-bottom: 16px;
}
.filters .field { min-width: 150px; }
.filters .field > label { font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }

.switch { position: relative; display: inline-block; width: 38px; height: 21px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .slider {
    position: absolute; inset: 0; cursor: pointer; background: var(--border-strong);
    border-radius: var(--r-pill); transition: background .18s;
}
.switch .slider::before {
    content: ''; position: absolute; height: 15px; width: 15px; left: 3px; bottom: 3px;
    background: #fff; border-radius: 50%; transition: transform .18s;
}
.switch input:checked + .slider { background: var(--brand); }
.switch input:checked + .slider::before { transform: translateX(17px); }
.switch input:focus-visible + .slider { outline: 2px solid var(--brand); outline-offset: 2px; }

/* ── Tables ─────────────────────────────────────────────────────────────── */

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table.data { width: 100%; border-collapse: collapse; font-size: 13px; }
table.data th {
    text-align: left; padding: 9px 12px; white-space: nowrap;
    color: var(--muted); font-size: 10.5px; font-weight: 700;
    text-transform: uppercase; letter-spacing: .05em;
    border-bottom: 2px solid var(--border); background: var(--surface);
    position: sticky; top: 0; z-index: 1;
}
table.data th a { color: inherit; }
table.data th.sortable { cursor: pointer; user-select: none; }
table.data th.sortable:hover { color: var(--text); }
table.data th .arrow { opacity: .35; margin-left: 3px; }
table.data th.sorted .arrow { opacity: 1; color: var(--brand); }
table.data td { padding: 10px 12px; border-bottom: 1px solid var(--border-light); vertical-align: middle; }
table.data tbody tr:last-child td { border-bottom: none; }
table.data tbody tr:hover td { background: var(--surface-2); }
table.data tr.clickable { cursor: pointer; }
table.data .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
table.data .actions { text-align: right; white-space: nowrap; }
table.data .strong { font-weight: 650; color: var(--text); }
table.data td.wrap { white-space: normal; min-width: 200px; }
table.data tfoot td { padding: 11px 12px; border-top: 2px solid var(--border); font-weight: 700; background: var(--surface-2); }

.empty {
    text-align: center; padding: 44px 20px; color: var(--muted);
}
.empty .icon { font-size: 30px; opacity: .35; margin-bottom: 8px; }
.empty h3 { font-size: 15px; color: var(--text); margin-bottom: 4px; }
.empty p { font-size: 13px; max-width: 380px; margin: 0 auto 14px; }

.pagination { display: flex; gap: 5px; align-items: center; justify-content: center; margin-top: 18px; flex-wrap: wrap; }
.pagination a, .pagination span {
    min-width: 32px; height: 32px; padding: 0 9px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: var(--r-sm); font-size: 13px; font-weight: 600;
    border: 1px solid var(--border); background: var(--surface); color: var(--text-2);
}
.pagination a:hover { background: var(--surface-2); text-decoration: none; }
.pagination .current { background: var(--brand); color: #fff; border-color: var(--brand); }
.pagination .gap { border: none; background: none; }

/* ── Flash & alerts ─────────────────────────────────────────────────────── */

.flashes { display: flex; flex-direction: column; gap: 8px; margin-bottom: 18px; }
.flash {
    display: flex; align-items: flex-start; gap: 10px;
    padding: 11px 15px; border-radius: var(--r-sm); font-size: 13.5px; font-weight: 500;
    border: 1px solid transparent;
}
.flash--success { background: var(--success-bg); color: var(--success-fg); border-color: rgba(5,150,105,.25); }
.flash--error   { background: var(--danger-bg);  color: var(--danger-fg);  border-color: rgba(220,38,38,.25); }
.flash--warning { background: var(--warn-bg);    color: var(--warn-fg);    border-color: rgba(217,119,6,.25); }
.flash--info    { background: var(--info-bg);    color: var(--info-fg);    border-color: rgba(2,132,199,.25); }

.alert-card {
    background: var(--surface); border: 1px solid var(--border);
    border-left: 4px solid var(--warn); border-radius: var(--r); padding: 14px 16px;
}
.alert-card.is-critical { border-left-color: var(--danger); }
.alert-card.is-info { border-left-color: var(--info); }
.alert-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.alert-title { font-size: 14px; font-weight: 700; margin: 0; }
.alert-meta { font-size: 11.5px; color: var(--muted); }
.alert-body { font-size: 13px; color: var(--text-2); margin-top: 6px; }
.alert-actions { display: flex; gap: 8px; margin-top: 11px; flex-wrap: wrap; }

/* ── Charts (hand-rolled SVG) ───────────────────────────────────────────── */

.chart { position: relative; }
.chart-plot { position: relative; height: 48px; }
.chart-plot.tall { height: 150px; }
.spark { display: block; width: 100%; height: 100%; overflow: visible; }
.spark-dot { position: absolute; width: 6px; height: 6px; border-radius: 50%; transform: translate(-50%,-50%); pointer-events: none; }
.spark-dot.last { width: 7px; height: 7px; box-shadow: 0 0 0 3px var(--surface); }
.spark-dot.peak { width: 5px; height: 5px; background: var(--surface); border: 1.5px solid; }
.spark-dot.hover { width: 9px; height: 9px; border: 2px solid var(--surface); display: none; box-shadow: 0 1px 3px rgba(0,0,0,.25); }
.spark-cursor { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--muted); opacity: .3; display: none; pointer-events: none; }
.chart-axis { display: flex; justify-content: space-between; margin-top: 5px; font-size: 10px; color: var(--muted-2); }
.chart-tip {
    position: absolute; top: 0; transform: translate(-50%, calc(-100% - 6px));
    background: var(--text); color: var(--surface); border-radius: 6px;
    padding: 4px 9px; font-size: 11px; line-height: 1.35; white-space: nowrap;
    pointer-events: none; display: none; z-index: 5; box-shadow: var(--shadow);
}
.chart-tip strong { display: block; font-size: 12.5px; font-weight: 700; }
.chart-legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 11.5px; color: var(--muted); margin-top: 10px; }
.chart-legend .item { display: inline-flex; align-items: center; gap: 5px; }
.chart-legend .swatch { width: 9px; height: 9px; border-radius: 2px; }

.bars { display: flex; flex-direction: column; gap: 8px; }
.bar-row { display: flex; align-items: center; gap: 10px; font-size: 12.5px; }
.bar-label { width: 132px; flex-shrink: 0; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-track { flex: 1; background: var(--surface-3); border-radius: 4px; height: 8px; overflow: hidden; min-width: 40px; }
.bar-fill { height: 100%; border-radius: 4px; background: var(--brand); transition: width .5s ease; }
.bar-val { width: 62px; flex-shrink: 0; text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }

.histogram { display: flex; gap: 3px; align-items: flex-end; height: 68px; }
.histogram .col { flex: 1; min-width: 4px; border-radius: 3px 3px 0 0; background: var(--brand); transition: opacity .15s; }
.histogram .col:hover { opacity: .7; }

/* ── Provider sections ──────────────────────────────────────────────────── */

.provider-card { border-left: 4px solid var(--provider, var(--border)); }
.provider-card.gmb  { --provider: var(--gmb); }
.provider-card.gsc  { --provider: var(--gsc); }
.provider-card.gads { --provider: var(--gads); }
.provider-card.ga4  { --provider: var(--ga4); }
.provider-card.mads { --provider: var(--mads); }
.provider-title { display: flex; align-items: center; gap: 8px; font-size: 16px; font-weight: 700; }
.provider-title::before {
    content: ''; width: 9px; height: 9px; border-radius: 50%;
    background: var(--provider, var(--brand)); flex-shrink: 0;
}

/* ── Range picker ───────────────────────────────────────────────────────── */

.range-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 16px; }
.range-pills {
    display: flex; flex-wrap: wrap; gap: 3px;
    background: var(--surface-2); border: 1px solid var(--border);
    border-radius: 10px; padding: 3px;
}
.range-pills a, .range-pills button {
    background: none; border: none; border-radius: 7px;
    padding: 6px 13px; font-size: 12.5px; font-weight: 650; color: var(--muted);
    font-family: var(--font); cursor: pointer; white-space: nowrap;
    transition: background .14s, color .14s;
}
.range-pills a:hover, .range-pills button:hover { color: var(--text); text-decoration: none; }
.range-pills .active { background: var(--brand); color: #fff; }
.range-custom { display: flex; gap: 6px; align-items: center; }
.range-custom input[type=date] { width: auto; padding: 7px 10px; font-size: 13px; }

/* ── Timeline ───────────────────────────────────────────────────────────── */

.timeline { position: relative; padding-left: 22px; }
.timeline::before { content: ''; position: absolute; left: 6px; top: 5px; bottom: 5px; width: 2px; background: var(--border); }
.tl-item { position: relative; padding-bottom: 18px; }
.tl-item:last-child { padding-bottom: 0; }
.tl-item::before {
    content: ''; position: absolute; left: -20px; top: 5px; width: 9px; height: 9px;
    border-radius: 50%; background: var(--brand); border: 2px solid var(--surface); box-shadow: 0 0 0 2px var(--border);
}
.tl-item.is-done::before { background: var(--success); }
.tl-item.is-warn::before { background: var(--warn); }
.tl-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.tl-title { font-size: 13.5px; font-weight: 650; }
.tl-time { font-size: 11.5px; color: var(--muted-2); }
.tl-body { font-size: 13px; color: var(--text-2); margin-top: 2px; white-space: pre-wrap; }

/* ── Tabs ───────────────────────────────────────────────────────────────── */

.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); margin-bottom: 18px; overflow-x: auto; }
.tabs a {
    padding: 9px 14px; font-size: 13.5px; font-weight: 600; color: var(--muted);
    border-bottom: 2px solid transparent; white-space: nowrap;
}
.tabs a:hover { color: var(--text); text-decoration: none; }
.tabs a.active { color: var(--brand); border-bottom-color: var(--brand); }

/* ── Modal ──────────────────────────────────────────────────────────────── */

dialog.modal {
    border: none; border-radius: var(--r-lg); padding: 0; max-width: 620px; width: calc(100% - 32px);
    background: var(--surface); color: var(--text); box-shadow: var(--shadow-lg);
    /* Der globale Reset (`* { margin: 0 }`) schlaegt die UA-Regel `dialog { margin: auto }`,
       weil Autorenregeln immer vor dem Browser-Stylesheet greifen. Ohne das folgende
       margin klebt jeder Dialog in der linken oberen Ecke statt mittig zu stehen. */
    margin: auto;
    /* Lange Formulare (Regel anlegen) sind hoeher als der Viewport. */
    max-height: calc(100vh - 48px);
    overflow-y: auto;
}
dialog.modal::backdrop { background: rgba(15,23,42,.5); backdrop-filter: blur(2px); }
dialog.modal .modal-head { padding: 18px 22px 0; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
dialog.modal .modal-body { padding: 16px 22px; }
dialog.modal .modal-foot { padding: 14px 22px 18px; display: flex; gap: 8px; justify-content: flex-end; border-top: 1px solid var(--border-light); margin-top: 6px; }
dialog.modal.wide { max-width: 860px; }

/* ── Toast ──────────────────────────────────────────────────────────────── */

.toast-host { position: fixed; bottom: 22px; right: 22px; z-index: 100; display: flex; flex-direction: column; gap: 8px; }
.toast {
    padding: 11px 18px; border-radius: 10px; font-size: 13.5px; font-weight: 600;
    color: #fff; box-shadow: var(--shadow-lg); background: var(--text);
    animation: toast-in .2s ease;
}
.toast.success { background: var(--success); }
.toast.error   { background: var(--danger); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* ── Misc ───────────────────────────────────────────────────────────────── */

.muted { color: var(--muted); }
.muted-2 { color: var(--muted-2); }
.text-sm { font-size: 12.5px; }
.text-xs { font-size: 11.5px; }
.strong { font-weight: 650; }
.nowrap { white-space: nowrap; }
.tabular { font-variant-numeric: tabular-nums; }
.text-right { text-align: right; }
.text-center { text-align: center; }
.pos { color: var(--success); } .neg { color: var(--danger); }
.mt-0 { margin-top: 0; } .mt-2 { margin-top: 8px; } .mt-3 { margin-top: 12px; }
.mt-4 { margin-top: 16px; } .mt-5 { margin-top: 24px; }
.mb-2 { margin-bottom: 8px; } .mb-3 { margin-bottom: 12px; } .mb-4 { margin-bottom: 16px; }
.hidden { display: none !important; }
hr.sep { border: none; border-top: 1px solid var(--border-light); margin: 18px 0; }

.def-list { display: grid; grid-template-columns: max-content 1fr; gap: 7px 16px; font-size: 13.5px; align-items: baseline; }
.def-list dt { color: var(--muted); font-size: 12.5px; }
.def-list dd { color: var(--text); font-weight: 500; word-break: break-word; }

.progress { height: 7px; background: var(--surface-3); border-radius: var(--r-pill); overflow: hidden; }
.progress .fill { height: 100%; background: var(--brand); border-radius: var(--r-pill); transition: width .4s; }
.progress .fill.over { background: var(--danger); }
.progress .fill.warn { background: var(--warn); }

.checklist { list-style: none; display: flex; flex-direction: column; gap: 7px; }
.checklist li { display: flex; align-items: center; gap: 9px; font-size: 13.5px; }
.checklist .mark {
    width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--border-strong);
    flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
    font-size: 10px; color: transparent;
}
.checklist li.done .mark { background: var(--success); border-color: var(--success); color: #fff; }
.checklist li.done span { color: var(--muted); text-decoration: line-through; }

.skeleton {
    background: linear-gradient(90deg, var(--surface-3) 25%, var(--border) 50%, var(--surface-3) 75%);
    background-size: 200% 100%; animation: shimmer 1.4s infinite; border-radius: 6px;
}
@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }

.stars { color: var(--warn); letter-spacing: 1px; font-size: 13px; }
.stars .off { color: var(--border-strong); }

.copyable { display: inline-flex; align-items: center; gap: 6px; }
.copyable code { background: var(--surface-3); padding: 2px 7px; border-radius: 5px; }

/* ── Print (invoices/reports rendered from the browser) ─────────────────── */

@media print {
    .sidebar, .topbar, .page-actions, .btn, .filters, .toast-host, .flashes { display: none !important; }
    .shell { grid-template-columns: 1fr; }
    .content { padding: 0; }
    .card { border: none; box-shadow: none; padding: 0; }
    body { background: #fff; font-size: 11pt; }
}

/* ── Responsive ─────────────────────────────────────────────────────────── */

@media (max-width: 1200px) {
    .grid-5 { grid-template-columns: repeat(3, minmax(0,1fr)); }
}
@media (max-width: 1024px) {
    .grid-4 { grid-template-columns: repeat(2, minmax(0,1fr)); }
    .grid-sidebar { grid-template-columns: 1fr; }
}
@media (max-width: 860px) {
    .shell { grid-template-columns: 1fr; }
    .sidebar {
        position: fixed; left: -280px; top: 0; width: 268px; z-index: 60;
        transition: left .24s ease; box-shadow: var(--shadow-lg);
    }
    .sidebar.open { left: 0; }
    #menu-toggle { display: inline-flex; }
    .sidebar-backdrop {
        position: fixed; inset: 0; background: rgba(15,23,42,.45); z-index: 55; display: none;
    }
    .sidebar-backdrop.show { display: block; }
    .grid-3, .grid-5 { grid-template-columns: repeat(2, minmax(0,1fr)); }
    .content { padding: 16px; }
    .topbar { padding: 0 16px; }
}
@media (max-width: 560px) {
    .grid-2, .grid-3, .grid-4, .grid-5 { grid-template-columns: 1fr; }
    .field-row, .field-row-3 { grid-template-columns: 1fr; }
    .kpi-value { font-size: 1.5rem; }
    /* 16px prevents iOS from zooming the viewport on focus. */
    input, select, textarea { font-size: 16px !important; }
    .btn { min-height: 40px; }
    table.data { font-size: 12.5px; }
}

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
    html { scroll-behavior: auto; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Tagesbericht (Dashboard)
   Eigener Abschnitt am Dateiende. Der Tagesbericht ist die einzige Fläche der
   Anwendung, die Fließtext trägt — Feststellung, Begründung, nächster Schritt —
   und braucht dafür eigene Typografie. Alles hier verwendet ausschließlich die
   Design-Tokens von oben, damit der dunkle Modus ohne eine einzige Zusatzregel
   mitläuft. Keine bestehende Regel wird überschrieben.
   ═══════════════════════════════════════════════════════════════════════════ */

.report-headline {
    font-size: 15.5px; font-weight: 600; line-height: 1.5;
    color: var(--text); margin-bottom: 18px; max-width: 78ch;
}

/* Zusammenfassung: dichte Faktenkacheln, bewusst flacher als .kpi — die großen
   Zahlen stehen schon in der KPI-Reihe darüber. */
.report-summary {
    display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 1px;
    background: var(--border-light); border: 1px solid var(--border-light);
    border-radius: var(--r); overflow: hidden; margin-bottom: 22px;
}
.report-fact {
    display: flex; flex-direction: column; gap: 3px; padding: 12px 14px;
    background: var(--surface); color: inherit; text-decoration: none;
    transition: background .14s;
}
.report-fact:hover { background: var(--surface-2); text-decoration: none; }
.report-fact-label {
    font-size: 10.5px; font-weight: 700; letter-spacing: .06em;
    text-transform: uppercase; color: var(--muted);
}
.report-fact-value {
    display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap;
    font-size: 1.15rem; font-weight: 700; letter-spacing: -.02em; color: var(--text);
}
.report-fact-note { font-size: 11.5px; line-height: 1.45; color: var(--muted-2); }

.report-section + .report-section { margin-top: 24px; }
.report-h {
    display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap;
    font-size: 12.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
    color: var(--text-2); margin: 0 0 12px; padding-bottom: 8px;
    border-bottom: 1px solid var(--border-light);
}
.report-h .sub {
    font-size: 11.5px; font-weight: 400; letter-spacing: 0;
    text-transform: none; color: var(--muted);
}

.report-list {
    list-style: none; display: grid;
    grid-template-columns: repeat(2, minmax(0,1fr)); gap: 12px;
}
.report-item {
    display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
    background: var(--surface-2); border-top: 1px solid var(--border-light);
    border-left: 3px solid var(--muted-2); border-radius: 0;
    padding: 13px 15px;
}
.report-item.is-critical { border-left-color: var(--danger); }
.report-item.is-warn     { border-left-color: var(--warn); }
.report-item.is-info     { border-left-color: var(--info); }
.report-item-head {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 10px; width: 100%;
}
.report-item-title { font-size: 13.5px; font-weight: 700; line-height: 1.35; color: var(--text); }
.report-item-amount { font-size: 12.5px; font-weight: 700; color: var(--text-2); white-space: nowrap; }
.report-item-why  { font-size: 12.5px; line-height: 1.5; color: var(--text-2); }
.report-item-next { font-size: 12.5px; line-height: 1.5; color: var(--text); }
.report-item-step {
    margin-right: 6px; font-size: 10px; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; color: var(--muted);
}
.report-item .btn { margin-top: 2px; }

.report-empty { font-size: 12.5px; line-height: 1.55; color: var(--muted); max-width: 78ch; }
.report-foot {
    margin-top: 20px; padding-top: 12px; border-top: 1px solid var(--border-light);
    font-size: 11px; line-height: 1.5; color: var(--muted-2);
}

@media (max-width: 1024px) { .report-summary { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 860px)  { .report-list { grid-template-columns: 1fr; } }
@media (max-width: 560px)  { .report-summary { grid-template-columns: 1fr; } }

/* ── Upsell: Lead-Weiterleitungen (Kundendetail) ─────────────────────────── */

.upsell { margin-top: 16px; }
.upsell-body { align-items: start; margin-top: 4px; }
.upsell-subhead {
    font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
    color: var(--muted); margin-bottom: 10px;
}
/* Hinweis statt Alarm: getönte Fläche ohne Rahmenstreifen, damit die Sektion
   nicht lauter wirkt als der Rest der Kundenseite. */
.upsell-note {
    background: var(--surface-3); color: var(--text-2);
    font-size: 12.5px; line-height: 1.55;
    padding: 10px 13px; border-radius: var(--r-sm); margin-bottom: 10px;
}
.upsell-note.is-warn { background: var(--warn-bg); color: var(--warn-fg); }
.upsell-meta { font-size: 12px; color: var(--muted); margin-top: 3px; }
.upsell-meta.is-error { color: var(--danger); font-weight: 600; }
.upsell-meta .mono { font-size: 11.5px; }
/* Der Punkt der Zeitleiste trägt den Ausgang der Weiterleitung. */
.tl-item.upsell-sent::before   { background: var(--success); }
.tl-item.upsell-queued::before { background: var(--warn); }
.tl-item.upsell-failed::before { background: var(--danger); }

/* ═══════════════════════════════════════════════════════════════════════════
   Automatisierung (Dashboard)
   Die Agenten-Fläche. Zweite Ebene desselben Abschnitts wie der Tagesbericht,
   deshalb wieder ausschließlich Tokens und keine eigene Elevation: die Agenten
   sitzen in einer Karte, also tragen sie selbst keinen Schatten. Sie sind
   abgerundet und ohne Farbstreifen — die Berichtszeilen darüber sind eckig und
   mit Streifen. Zwei Dinge, zwei Behandlungen, keine Vermischung.
   ═══════════════════════════════════════════════════════════════════════════ */

.agent-supervisor {
    font-size: 12.5px; line-height: 1.55; color: var(--text-2);
    background: var(--surface-2); border-left: 3px solid var(--brand);
    padding: 11px 14px; margin-bottom: 18px; max-width: 92ch;
}
.agent-supervisor-label {
    display: inline-block; margin-right: 8px;
    font-size: 10px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
    color: var(--brand);
}

.agent-grid {
    display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 12px;
    margin-bottom: 24px;
}
.agent {
    display: flex; flex-direction: column; gap: 9px;
    background: var(--surface-2); border: 1px solid var(--border-light);
    border-radius: var(--r); padding: 14px 15px;
}

.agent-head { display: flex; align-items: flex-start; gap: 10px; }
.agent-icon {
    flex-shrink: 0; width: 30px; height: 30px; border-radius: 8px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--surface-3); color: var(--text-2);
}
.agent-icon svg { width: 17px; height: 17px; }
.agent-id { flex: 1; min-width: 0; display: block; }
.agent-name { font-size: 13.5px; font-weight: 700; line-height: 1.3; margin: 0; color: var(--text); }
.agent-source {
    display: block; font-family: var(--mono); font-size: 10px; color: var(--muted-2);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.agent-state {
    display: inline-flex; align-items: center; gap: 5px; flex-shrink: 0;
    font-size: 10.5px; font-weight: 700; color: var(--muted); white-space: nowrap;
}
.agent-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--muted-2); }

.agent.is-ok .agent-dot      { background: var(--success); }
.agent.is-ok .agent-state    { color: var(--success); }
.agent.is-waiting .agent-dot { background: var(--info); }
.agent.is-waiting .agent-state { color: var(--info); }
.agent.is-overdue .agent-dot { background: var(--warn); }
.agent.is-overdue .agent-state { color: var(--warn); }
.agent.is-error .agent-dot   { background: var(--danger); }
.agent.is-error .agent-state { color: var(--danger); }
.agent.is-error .agent-icon  { background: var(--danger-bg); color: var(--danger-fg); }
.agent.is-never .agent-state { color: var(--muted-2); }

/* Der Puls läuft ausschließlich, solange wirklich ein Job läuft. Reine Tokens,
   damit der Ring im dunklen Modus dieselbe Markenfarbe trägt wie der Punkt. */
.agent.is-running .agent-dot   { background: var(--brand); position: relative; }
.agent.is-running .agent-dot::after {
    content: ''; position: absolute; inset: -4px; border-radius: 50%;
    border: 1px solid var(--brand); animation: agent-pulse 1.8s ease-out infinite;
}
.agent.is-running .agent-state { color: var(--brand); }
.agent.is-running .agent-icon  { background: var(--brand-100); color: var(--brand); }
@keyframes agent-pulse {
    0%   { opacity: .65; transform: scale(.55); }
    100% { opacity: 0;   transform: scale(1.2); }
}

.agent-purpose { font-size: 12px; line-height: 1.5; color: var(--muted); }

.agent-work { display: flex; flex-direction: column; gap: 4px; }
.agent-work > div { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.agent-work dt { font-size: 11.5px; color: var(--muted); }
.agent-work dd { font-size: 13px; font-weight: 700; color: var(--text); white-space: nowrap; }

.agent-message {
    font-size: 11.5px; line-height: 1.45; color: var(--text-2);
    border-top: 1px solid var(--border-light); padding-top: 8px;
}
.agent-empty { font-size: 11.5px; line-height: 1.5; color: var(--muted); }
.agent-empty-next { display: block; margin-top: 4px; color: var(--text-2); }

.agent-clock {
    display: flex; flex-wrap: wrap; gap: 4px 16px;
    font-size: 11px; color: var(--text-2);
    border-top: 1px solid var(--border-light); padding-top: 8px;
}
.agent-clock-label {
    display: inline-block; margin-right: 4px;
    font-size: 9.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
    color: var(--muted-2);
}
.agent-queue { font-size: 11.5px; color: var(--text-2); }

.agent-foot { margin-top: auto; padding-top: 4px; }
.agent-escalation, .agent-link { font-size: 11.5px; font-weight: 650; }
.agent-escalation { color: var(--signal); }
.agent-escalation-more {
    display: inline-block; margin-left: 4px; padding: 0 5px;
    border-radius: var(--r-pill); background: var(--signal-100); color: var(--signal);
    font-size: 10px; font-weight: 700;
}

/* Arbeitsprotokoll — bewusst eine Protokollzeile, keine Karte. */
.agent-log { margin-top: 4px; }
.worklog { list-style: none; display: flex; flex-direction: column; }
.worklog-item {
    display: grid; grid-template-columns: 92px 116px minmax(140px, 1fr) minmax(0, 2fr);
    gap: 12px; align-items: baseline;
    padding: 7px 0 7px 11px; border-top: 1px solid var(--border-light);
    border-left: 2px solid var(--border-strong);
    font-size: 12px;
}
.worklog-item:first-child { border-top: none; }
.worklog-item.is-ok,
.worklog-item.is-done    { border-left-color: var(--success); }
.worklog-item.is-partial { border-left-color: var(--warn); }
.worklog-item.is-running { border-left-color: var(--brand); }
.worklog-item.is-failed,
.worklog-item.is-error   { border-left-color: var(--danger); }
.worklog-time { color: var(--muted-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.worklog-kind { color: var(--muted-2); font-size: 11px; white-space: nowrap; }
.worklog-title { font-weight: 650; color: var(--text); }
.worklog-count {
    display: inline-block; margin-left: 4px; padding: 0 5px;
    border-radius: var(--r-pill); background: var(--surface-3); color: var(--muted);
    font-size: 10px; font-weight: 700;
}
.worklog-detail { color: var(--text-2); overflow: hidden; text-overflow: ellipsis; }

@media (max-width: 1200px) { .agent-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } }
@media (max-width: 1024px) {
    .worklog-item { grid-template-columns: 92px minmax(140px, 1fr) minmax(0, 2fr); }
    .worklog-kind { display: none; }
}
@media (max-width: 700px) {
    .agent-grid { grid-template-columns: 1fr; }
    .worklog-item { grid-template-columns: 1fr; gap: 2px; }
}

/* ── Website-Scanner ────────────────────────────────────────────────────────
   Nur für views/scans/*. Angehängt am Dateiende, damit keine bestehende Regel
   berührt wird; alle Farben kommen aus den vorhandenen Token, damit hell und
   dunkel ohne Sonderfall funktionieren. */

/* Ein Befund. Die farbige Kante links ersetzt ein Icon: der Status ist schon
   beim Überfliegen sichtbar, ohne dass jede Zeile ein Badge braucht. */
.scan-finding {
    padding: 13px 0 13px 14px;
    border-bottom: 1px solid var(--border-light);
    border-left: 3px solid var(--border);
    min-width: 0;
}
.scan-finding:last-child { border-bottom: none; }
.scan-finding.is-fail    { border-left-color: var(--danger); }
.scan-finding.is-warn    { border-left-color: var(--warn); }
.scan-finding.is-pass    { border-left-color: var(--success); }
.scan-finding.is-info    { border-left-color: var(--info); }
.scan-finding.is-unknown { border-left-color: var(--border-strong); }

/* Beleg: standardmäßig eingeklappt, damit der Bericht lesbar bleibt, aber immer
   einen Klick entfernt — ein Befund ohne einsehbaren Beleg ist wertlos. */
.scan-evidence > summary {
    cursor: pointer; font-size: 11.5px; font-weight: 650; color: var(--muted);
    list-style: none; display: inline-flex; align-items: center; gap: 5px;
}
.scan-evidence > summary::-webkit-details-marker { display: none; }
.scan-evidence > summary::before { content: '▸'; font-size: 10px; }
.scan-evidence[open] > summary::before { content: '▾'; }
.scan-evidence > summary:hover { color: var(--text); }

.scan-code {
    margin-top: 8px; padding: 9px 11px;
    background: var(--surface-2); border: 1px solid var(--border-light);
    border-radius: var(--r-sm);
    font-family: var(--mono); font-size: 11.5px; line-height: 1.5;
    color: var(--text-2);
    white-space: pre-wrap; word-break: break-word; overflow-x: auto;
}

/* Die Reihung „was zuerst zu tun ist". */
.scan-priority { display: flex; gap: 12px; align-items: flex-start; }
.scan-priority-rank {
    flex-shrink: 0; width: 22px; height: 22px; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--brand-100); color: var(--brand);
    font-size: 11.5px; font-weight: 700;
}

/* ── Ticketsystem: Fehlermeldungen ───────────────────────────────────────── */

/* Der Zugang „Fehler melden" steht im Fuß der Seitenleiste direkt über
   „Abmelden". Ohne Abstand kleben die beiden Schaltflächen aneinander und lesen
   sich als eine Gruppe — der Abstand trennt die beiläufige Meldung von der
   Abmeldung, die niemand versehentlich treffen soll. */
.sidebar-foot > .btn-block { margin-bottom: 6px; }

/* Die Ticketliste zeigt Pfade in der Spalte „Betroffene Seite". Ein Pfad ist
   Technik, kein Fließtext: er wird in der Schmalschrift gesetzt und darf die
   Spalte nicht sprengen. */
.ticket-path { font-size: 12px; word-break: break-all; }

/* Der Verlauf steht in derselben Zeitleiste wie die Kundenaktivitäten; nur der
   Punkt trägt den Ausgang des Statuswechsels. */
.tl-item.ticket-resolved::before  { background: var(--success); }
.tl-item.ticket-dismissed::before { background: var(--muted-2); }

/* ── Tafeln: Karten ziehen ─────────────────────────────────────────────────
   Gilt für beide Tafeln, /pipeline und /projekte. Das Ziehen selbst steckt in
   app.js; hier steht nur, was man dabei sieht.

   Die Karte wird beim Ziehen blasser statt kleiner oder gedreht: Sie soll
   erkennbar bleiben, während man sie über die Spalten führt. Die Zielspalte
   bekommt einen Rahmen in der Markenfarbe — und ausdrücklich keinen Schatten,
   weil sonst jede Spalte beim Überfahren zu schweben beginnt.

   `.is-moving` deckt die Zeit zwischen Loslassen und Neuladen ab. Ohne diesen
   Zustand wirkt die Karte in der neuen Spalte für einen Moment so, als wäre
   schon alles gespeichert. */
.deal[draggable="true"], .pcard[draggable="true"] { cursor: grab; }
.deal.is-dragging, .pcard.is-dragging { opacity: .45; cursor: grabbing; }
.board-col.is-drop-target, .pboard-col.is-drop-target {
    border-color: var(--brand);
    background: var(--brand-50);
}
.deal.is-moving, .pcard.is-moving { opacity: .6; pointer-events: none; }

/* Ziehen ist ein Zusatz, kein Ersatz: Am Touchgerät gibt es HTML5-Ziehen nicht,
   dort bleibt das Auswahlfeld der einzige Weg. Es wird deshalb nie versteckt. */

/* ── Projekt-Pipeline ──────────────────────────────────────────────────────
   Dieselbe Bauart wie die Deal-Pipeline unter /pipeline: Stufenspalten,
   verschoben wird über ein Select. Ein Unterschied zwingt zu eigenem CSS statt
   zur Wiederverwendung von `.board`: dort stehen sechs Spalten fest im
   Quelltext, hier sind es beliebig viele aus den Einstellungen. Deshalb ein
   Flex-Streifen, der waagrecht rollt, statt eines Rasters mit fester
   Spaltenzahl. */
.pboard { display: flex; gap: 12px; align-items: flex-start; overflow-x: auto; padding-bottom: 6px; }
.pboard-col {
    flex: 1 0 240px; min-width: 240px;
    background: var(--surface-2); border: 1px solid var(--border);
    border-radius: var(--r); padding: 10px;
}
.pboard-col > header {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 8px; margin-bottom: 10px; padding: 0 2px;
}
.pboard-col h2 { font-size: 12px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.pboard-col .col-sum { font-size: 11.5px; font-weight: 700; color: var(--text-2); font-variant-numeric: tabular-nums; }
.pboard-col.is-closed { border-color: rgba(5,150,105,.4); }
/* Die Sammelspalte fällt bewusst auf: sie ist ein Hinweis, keine Stufe. */
.pboard-col.is-orphan { border-color: var(--warn); border-style: dashed; }
.pboard-col .col-note { font-size: 11.5px; color: var(--muted); margin-bottom: 9px; line-height: 1.45; }
.pcard {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r-sm); padding: 11px 12px; margin-bottom: 9px;
    box-shadow: var(--shadow-xs);
}
.pcard:last-child { margin-bottom: 0; }
.pcard h3 { font-size: 13.5px; margin-bottom: 3px; word-break: break-word; }
.pcard h3 a { color: inherit; }
.pcard .pcard-cust { font-size: 11.5px; }
.pcard .pcard-figs { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-top: 7px; font-variant-numeric: tabular-nums; }
.pcard .pcard-move { display: flex; gap: 5px; margin-top: 9px; }
.pcard .pcard-move select { padding: 5px 26px 5px 8px; font-size: 12px; border-radius: 7px; background-position: right 6px center; }
.pcard-empty { font-size: 12px; color: var(--muted-2); text-align: center; padding: 14px 4px; }

/* Stufenverwaltung in den Einstellungen. Sortiert wird über Zahlenfelder statt
   per Ziehen — das ist die Variante, die ohne JavaScript und mit Tastatur
   funktioniert. */
.pstage-row {
    display: grid; gap: 10px; align-items: end;
    grid-template-columns: 70px minmax(0,1fr) auto auto;
    padding: 12px 0; border-bottom: 1px solid var(--border-light);
}
.pstage-row:last-of-type { border-bottom: none; }
.pstage-row .pstage-flags { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }
.pstage-row .pstage-count { font-size: 11.5px; color: var(--muted-2); }
.pstage-move { grid-column: 1 / -1; }
.pstage-key { font-size: 11px; color: var(--muted-2); font-family: var(--mono, ui-monospace, monospace); }

@media (max-width: 700px) {
    .pboard { flex-direction: column; overflow-x: visible; }
    .pboard-col { flex: 1 1 auto; width: 100%; min-width: 0; }
    .pstage-row { grid-template-columns: 1fr; align-items: stretch; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Master-KI-Assistent (Seite + Schublade)
   Eigener Abschnitt am Dateiende. Keine bestehende Regel wird überschrieben,
   und es steht kein einziger roher Farbwert darin — der dunkle Modus läuft
   ausschließlich über die Tokens von oben mit.

   Drei Dinge entscheiden hier über Brauchbarkeit am Telefon:

   1. `100dvh` statt `100vh`. `vh` rechnet auf iOS mit dem Sichtfenster *ohne*
      Browserleisten; das Eingabefeld läge dann dauerhaft unter dem Bildrand.
   2. Keine Regel hier fixiert das Eingabefeld. Ein fixiertes Feld liegt auf iOS
      unter der Tastatur, weil Safari das Layout-Viewport beim Öffnen der
      Tastatur nicht verkleinert; ein Feld am Ende einer Spalte im normalen Fluss
      wird von Safari dagegen darüber geschoben. Die Seite ist deshalb reiner
      Fluss. Die Schublade kann das nicht sein: ein `dialog` im Top-Layer wird
      vom Browser fixiert positioniert, ganz ohne Zutun dieser Datei — und erbt
      damit genau dieses Problem. Für sie gibt es `--assistant-keyboard`, das
      JavaScript aus `visualViewport` setzen kann.
   3. Nichts hängt an `:hover`. Auf einem Telefon gibt es keinen Hover; jede
      Beschriftung und jeder Rahmen ist ohne Zeigegerät sichtbar.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Tippziele ──────────────────────────────────────────────────────────────
   44 px ist die Untergrenze, unterhalb derer ein Daumen danebentrifft. Gilt
   auch am Desktop: die Knöpfe hier lösen Schreibvorgänge in echten Kundendaten
   aus, ein Fehlklick ist teurer als ein paar Pixel Bauhöhe. */
.assistant-tap { min-height: 44px; }

/* ── Seite ─────────────────────────────────────────────────────────────────
   Eine Spalte über die volle Höhe: Kopf, Verlauf (scrollt), Eingabe (bleibt).
   Vom Sichtfenster gehen die Kopfleiste und der Innenabstand von `.content` ab. */
.assistant-page {
    display: flex;
    flex-direction: column;
    min-height: 0;
    gap: var(--sp-3);
}
/* Die Obergrenze der Spalte steht im Layout an `.content:has(> .fills-height)` —
   ohne sie verteilt die Flexbox nur und begrenzt nichts. Sie ist die Bedingung
   dafür, dass der Verlauf unten überhaupt einen eigenen Bildlauf bekommt. */
/* Der frühere Zuschlag für die Statusmeldung ist entfallen: die Spalte ist jetzt eine
   Flexbox (siehe `.content:has(> .fills-height)`), der Rest ergibt sich von selbst. */
.assistant-page-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: var(--sp-3); flex-wrap: wrap; flex-shrink: 0;
}
.assistant-page-title h1 { margin: 0; }
.assistant-page-title .sub { color: var(--muted); font-size: 13px; margin-top: 2px; }
.assistant-page-actions { display: flex; gap: var(--sp-2); flex-wrap: wrap; align-items: center; }

/* Tagesbudget: eine Zeile Text. Kein Balken — der Deckel ist keine Kennzahl,
   die man beobachtet, sondern eine Grenze, an die man erinnert werden will. */
.assistant-budget { font-size: 11.5px; color: var(--muted); flex-shrink: 0; }
.assistant-budget.is-tight { color: var(--warn-fg); font-weight: 650; }

/* ── Frühere Gespräche ─────────────────────────────────────────────────────
   `details` statt eines zweiten Seitenstreifens: braucht keinen dauerhaften
   Platz, ist mit der Tastatur bedienbar und funktioniert ohne JavaScript. */
.assistant-history { flex-shrink: 0; }
.assistant-history > summary {
    display: flex; align-items: center; gap: var(--sp-2);
    font-size: 12.5px; font-weight: 650; color: var(--text-2);
    cursor: pointer; list-style: none; padding: var(--sp-2) 0;
}
.assistant-history > summary::-webkit-details-marker { display: none; }
.assistant-history > summary::before { content: '▸'; font-size: 10px; color: var(--muted); }
.assistant-history[open] > summary::before { content: '▾'; }
.assistant-history-list {
    list-style: none; display: grid; gap: var(--sp-2);
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    margin-bottom: var(--sp-2);
}
.assistant-history-item {
    display: flex; flex-direction: column; justify-content: center; gap: 2px;
    padding: var(--sp-2) var(--sp-3);
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r-sm); color: var(--text); text-decoration: none;
}
.assistant-history-item:hover { text-decoration: none; border-color: var(--border-strong); }
.assistant-history-item.is-current { border-color: var(--brand); background: var(--brand-50); }
.assistant-history-title {
    font-size: 13px; font-weight: 650; line-height: 1.35;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.assistant-history-meta { font-size: 11.5px; color: var(--muted); }

/* ── Verlauf ───────────────────────────────────────────────────────────────
   Der einzige Bereich, der scrollt. `min-height: 0` ist keine Kosmetik: ohne
   sie weigert sich ein Flex-Kind zu schrumpfen und der Container wächst über
   das Sichtfenster hinaus, womit das Eingabefeld wieder unten hinausfiele.
   `overscroll-behavior: contain` verhindert, dass die Wischbewegung am Ende
   des Verlaufs die Seite dahinter mitzieht. */
.assistant-thread {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--r);
    padding: var(--sp-4);
}
.assistant-messages { list-style: none; display: flex; flex-direction: column; gap: var(--sp-4); }
/* Sprungziel für `#ende`. Der Browser scrollt dafür auch verschachtelte
   Scrollbereiche — ohne JavaScript der einzige Weg ans Ende des Verlaufs. */
.assistant-end { height: 1px; scroll-margin-bottom: var(--sp-4); }

/* ── Blasen ────────────────────────────────────────────────────────────────
   Die Antwort des Assistenten steht links auf einer eigenen Fläche, die eigene
   Nachricht rechts in Markenfarbe. Beide Farbpaare sind Token-Paare, die in
   hell wie dunkel tragen — eine weiße Schrift auf `--brand` täte das nicht,
   weil `--brand` im dunklen Modus aufgehellt wird. */
.assistant-msg { display: flex; flex-direction: column; gap: var(--sp-1); max-width: 100%; }
.assistant-msg.is-user { align-items: flex-end; }
.assistant-msg-head { display: flex; align-items: baseline; gap: var(--sp-2); font-size: 11.5px; }
.assistant-msg-role { font-weight: 700; color: var(--text-2); letter-spacing: .01em; }
.assistant-msg-time { color: var(--muted-2); }

.assistant-bubble {
    max-width: min(68ch, 100%);
    padding: var(--sp-3) var(--sp-4);
    border-radius: var(--r);
    background: var(--surface);
    border: 1px solid var(--border);
    color: var(--text);
    font-size: 14.5px; line-height: 1.6;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}
.assistant-msg.is-user .assistant-bubble {
    background: var(--brand-100);
    border-color: var(--brand-100);
    color: var(--brand-700);
}
.assistant-bubble.is-empty { color: var(--muted); font-style: italic; }

/* Wartezustand — ehrlicher Text, kein erfundener Fortschritt. Der Lauf dauert
   Sekunden bis Minuten, und niemand kann sagen, wie weit er ist. */
.assistant-bubble.is-working { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.assistant-working { display: inline-flex; gap: 4px; align-items: center; }
.assistant-working span {
    width: 6px; height: 6px; border-radius: 50%; background: var(--brand);
    animation: assistant-pulse 1.2s ease-in-out infinite;
}
.assistant-working span:nth-child(2) { animation-delay: .2s; }
.assistant-working span:nth-child(3) { animation-delay: .4s; }
@keyframes assistant-pulse { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }
.assistant-working-text { font-weight: 650; }
/* Fester Hinweistext, kein Modelltext: er darf das pre-wrap der Blase nicht erben,
   sonst schlagen Einrueckungen aus dem Quelltext auf die Darstellung durch. */
.assistant-working-note { flex-basis: 100%; font-size: 12.5px; line-height: 1.5; color: var(--muted); white-space: normal; }

/* Auf schmalen Geraeten nur das Symbol: mit Beschriftung quetscht der Auslöser das
   Suchfeld in der Kopfzeile auf null Breite. */
.assistant-launch-label { margin-left: 6px; }
@media (max-width: 720px) {
    .assistant-launch-label { display: none; }
}

.assistant-bubble.is-failed { background: var(--danger-bg); border-color: var(--danger); color: var(--danger-fg); }
.assistant-failed-title { font-weight: 700; font-size: 13.5px; }
.assistant-failed-reason { font-size: 13px; margin-top: var(--sp-1); overflow-wrap: anywhere; }
.assistant-failed-next { font-size: 12.5px; margin-top: var(--sp-2); color: var(--text-2); }

/* Protokollzeilen (Werkzeug/System) sind keine Unterhaltung. */
.assistant-note {
    align-self: center; font-size: 11.5px; color: var(--muted);
    display: flex; gap: var(--sp-2); align-items: baseline; flex-wrap: wrap;
}
.assistant-note-role { font-weight: 700; text-transform: uppercase; letter-spacing: .07em; font-size: 10px; }

/* ── Rückfrage ─────────────────────────────────────────────────────────────
   Nachfragen ist der Normalfall, nicht der Fehlerfall: lieber einmal fragen
   als einen Datensatz anlegen, den niemand mehr zuordnet. Deshalb der ruhige
   Informationston und nicht Warn- oder Fehlerfarbe. */
.assistant-question {
    max-width: min(68ch, 100%);
    background: var(--info-bg);
    border: 1px solid var(--info);
    border-radius: var(--r);
    padding: var(--sp-3) var(--sp-4);
    display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-2);
}
.assistant-question-label {
    font-size: 10px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
    color: var(--info-fg);
}
.assistant-question-text { font-size: 14.5px; line-height: 1.55; color: var(--text); }

/* ── Aktionskarte ──────────────────────────────────────────────────────────
   Die Sicherheitsstelle der ganzen Funktion. Der Satz, was passieren würde,
   steht groß und ungekürzt; jeder Wert steht einzeln darunter im Klartext und
   nicht in einer Codebox. Wer einen falsch verstandenen Firmenwortlaut
   übersehen soll, übersieht ihn genau dann, wenn er klein und im Monospace
   steht. Ein Vorschlag, der auf eine Entscheidung wartet, ist zusätzlich
   angehoben — Erhebung heißt hier „das wartet auf Sie". */
.assistant-actions { display: flex; flex-direction: column; gap: var(--sp-3); max-width: min(68ch, 100%); }
.assistant-action {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r);
    padding: var(--sp-4);
    display: flex; flex-direction: column; gap: var(--sp-3);
    align-items: flex-start;
}
.assistant-action.is-proposed { border-color: var(--brand); box-shadow: var(--shadow); }
.assistant-action.is-failed   { border-color: var(--danger); }
.assistant-action.is-rejected,
.assistant-action.is-expired  { background: var(--surface-2); }

.assistant-action-head { display: flex; align-items: center; gap: var(--sp-2); width: 100%; flex-wrap: wrap; }
.assistant-action-icon {
    width: 26px; height: 26px; flex-shrink: 0; border-radius: var(--r-sm);
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--surface-3); color: var(--muted);
}
.assistant-action.is-proposed .assistant-action-icon { background: var(--brand-100); color: var(--brand); }
.assistant-action.is-executed .assistant-action-icon { background: var(--success-bg); color: var(--success-fg); }
.assistant-action.is-failed   .assistant-action-icon { background: var(--danger-bg);  color: var(--danger-fg); }
.assistant-action-icon svg { width: 15px; height: 15px; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.assistant-action-title { font-size: 13.5px; font-weight: 700; margin: 0; flex: 1; min-width: 0; }

.assistant-action-summary {
    font-size: 15px; font-weight: 650; line-height: 1.5; color: var(--text);
    overflow-wrap: anywhere;
}

.assistant-action-args {
    display: grid; grid-template-columns: max-content minmax(0, 1fr);
    gap: var(--sp-2) var(--sp-4); width: 100%; font-size: 13.5px; align-items: baseline;
}
.assistant-action-args dt { font-size: 12.5px; color: var(--muted); }
.assistant-action-args dd {
    color: var(--text); font-weight: 600; overflow-wrap: anywhere;
    /* `describeArgument()` trennt Positionen mit \n — eine Zeile je Eintrag.
       `pre-line` zeigt genau diese Umbrüche und schluckt die Einrückung. */
    white-space: pre-line;
}

.assistant-action-foot {
    display: flex; gap: var(--sp-4); justify-content: space-between;
    width: 100%; flex-wrap: wrap; padding-top: var(--sp-1);
}
/* „Ausführen" ist der folgenreiche Knopf und steht deshalb am anderen Ende der
   Zeile als „Verwerfen" — nicht direkt daneben, wo der Daumen ihn streift.
   Die Reihenfolge im Quelltext ist dieselbe wie die sichtbare, damit die
   Tabulatorreihenfolge nicht gegen das Auge läuft. */
.assistant-action-foot .btn-primary { min-width: 130px; }

.assistant-action-values { width: 100%; margin-top: calc(var(--sp-2) * -1); }
.assistant-action-values > summary {
    display: inline-flex; align-items: center; gap: var(--sp-2);
    min-height: 44px; cursor: pointer; list-style: none;
    font-size: 12.5px; font-weight: 650; color: var(--text-2);
}
.assistant-action-values > summary::-webkit-details-marker { display: none; }
.assistant-action-values > summary::before { content: '▸'; font-size: 10px; color: var(--muted); }
.assistant-action-values[open] > summary::before { content: '▾'; }

.assistant-action-result { font-size: 13.5px; line-height: 1.5; color: var(--text); overflow-wrap: anywhere; }
.assistant-action-error  { font-size: 13.5px; line-height: 1.5; color: var(--danger); font-weight: 600; overflow-wrap: anywhere; }
.assistant-action-hint   { font-size: 12.5px; line-height: 1.5; color: var(--muted); }

/* ── Lesevorgänge ──────────────────────────────────────────────────────────
   Der Beleg dafür, dass der Assistent nachgesehen und nicht geraten hat.
   Eingeklappt, weil er beim Lesen stört und beim Prüfen unverzichtbar ist. */
.assistant-lookups { max-width: min(68ch, 100%); }
.assistant-lookups > summary {
    display: inline-flex; align-items: center; gap: var(--sp-2);
    min-height: 44px; cursor: pointer; list-style: none;
    font-size: 12.5px; font-weight: 650; color: var(--text-2);
}
.assistant-lookups > summary::-webkit-details-marker { display: none; }
.assistant-lookups > summary::before { content: '▸'; font-size: 10px; color: var(--muted); }
.assistant-lookups[open] > summary::before { content: '▾'; }
.assistant-lookup-list {
    list-style: none; display: flex; flex-direction: column; gap: var(--sp-2);
    padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-2);
    background: var(--surface-2); border: 1px solid var(--border-light); border-radius: var(--r-sm);
}
.assistant-lookup { display: flex; flex-direction: column; gap: 1px; font-size: 12.5px; }
.assistant-lookup-text { color: var(--text-2); line-height: 1.45; overflow-wrap: anywhere; }
.assistant-lookup.is-failed .assistant-lookup-text { color: var(--danger); }
.assistant-lookup-why { color: var(--muted); font-size: 11.5px; line-height: 1.45; overflow-wrap: anywhere; }
.assistant-lookup-error { color: var(--danger); font-size: 11.5px; overflow-wrap: anywhere; }
.assistant-lookup-name { font-size: 11px; color: var(--muted-2); overflow-wrap: anywhere; }

/* ── Leerer Zustand ────────────────────────────────────────────────────────
   Grund und nächster Schritt, dann sofort absendbare Beispiele. Jedes Beispiel
   ist ein eigener Absende-Knopf — die einzige Bauform, die ohne JavaScript
   funktioniert. */
.assistant-intro { display: flex; flex-direction: column; gap: var(--sp-3); max-width: 62ch; }
.assistant-intro-title { font-size: 15px; font-weight: 700; color: var(--text); }
.assistant-intro-text { font-size: 13.5px; line-height: 1.6; color: var(--text-2); }
.assistant-suggestions { display: flex; flex-direction: column; gap: var(--sp-2); }
.assistant-suggestions-label {
    font-size: 10px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--muted-2);
}
.assistant-suggestion-list { display: flex; flex-direction: column; gap: var(--sp-2); align-items: flex-start; }
.assistant-suggestion {
    min-height: 44px; text-align: left; white-space: normal;
    padding: var(--sp-2) var(--sp-4);
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-pill);
    color: var(--text); font-family: var(--font); font-size: 13.5px; font-weight: 500;
    line-height: 1.45; cursor: pointer; max-width: 100%;
}
.assistant-suggestion:hover { border-color: var(--brand); color: var(--brand); }

/* ── Eingabe ───────────────────────────────────────────────────────────────
   Letztes Kind der Spalte, im normalen Fluss, nicht fixiert (siehe Kopf des
   Abschnitts). 16 px Schriftgröße, weil iOS bei allem darunter beim Fokus in
   das Feld hineinzoomt — unabhängig von der Bildschirmbreite. */
.assistant-composer {
    flex-shrink: 0;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r);
    padding: var(--sp-3) var(--sp-4);
    display: flex; flex-direction: column; gap: var(--sp-2);
}
.assistant-composer-row { display: flex; gap: var(--sp-2); align-items: flex-end; }
.assistant-composer textarea {
    flex: 1; min-width: 0;
    min-height: 44px; max-height: 38dvh;
    font-size: 16px; line-height: 1.5;
    padding: 10px 12px;
    /* Ohne das mitwachsende JavaScript bleibt der Anfasser die Rückfallebene:
       ein langer Auftrag lässt sich dann von Hand aufziehen. */
    resize: vertical;
}
.assistant-send { flex-shrink: 0; min-width: 44px; }
.assistant-send svg { width: 16px; height: 16px; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.assistant-composer-hint { font-size: 11.5px; line-height: 1.5; color: var(--muted); }
.assistant-blocked {
    font-size: 12.5px; line-height: 1.5; color: var(--text-2);
    background: var(--surface-3); border-radius: var(--r-sm); padding: var(--sp-2) var(--sp-3);
}

/* ── Schublade ─────────────────────────────────────────────────────────────
   Am Desktop rechts angedockt, unter 720 px bildschirmfüllend. Als `dialog`
   geöffnet, damit Fokusfalle, Esc und Hintergrund vom Browser kommen und kein
   eigenes JavaScript dafür nötig ist. Ohne JavaScript bleibt sie zu — deshalb
   führt der Auslöser im Layout als gewöhnlicher Link auf `/assistent`.

   `--assistant-keyboard` ist der Haken für die iOS-Tastatur: ein fixiertes
   Element wird dort nicht verkleinert, wenn die Tastatur aufgeht. Wer den Wert
   aus `visualViewport` setzt, schiebt das Eingabefeld darüber. */
.assistant-drawer {
    --assistant-keyboard: 0px;
    border: none; padding: 0;
    background: var(--surface); color: var(--text);
    box-shadow: var(--shadow-lg);
    width: min(460px, 100%);
    max-width: none;
    height: 100dvh; max-height: 100dvh;
    /* Der globale Reset schlägt `dialog { margin: auto }`; ohne diese Zeile
       klebte die Schublade oben links statt am rechten Rand. */
    margin: 0 0 0 auto;
    border-radius: var(--r-lg) 0 0 var(--r-lg);
    overflow: hidden;
}
/* Gleicher Wert wie bei `dialog.modal::backdrop` — die Schublade soll denselben
   Hintergrund abdunkeln wie jeder andere Dialog der Anwendung. */
.assistant-drawer::backdrop { background: rgba(15,23,42,.5); }
.assistant-drawer-inner {
    display: flex; flex-direction: column;
    height: 100%; min-height: 0;
    padding: var(--sp-4);
    padding-bottom: calc(var(--sp-4) + var(--assistant-keyboard));
    gap: var(--sp-3);
}
.assistant-drawer-head { display: flex; align-items: flex-start; gap: var(--sp-2); flex-shrink: 0; }
.assistant-drawer-title { flex: 1; min-width: 0; }
.assistant-drawer-title h2 { font-size: 16px; margin: 0; }
.assistant-drawer-sub {
    font-size: 12px; color: var(--muted); margin-top: 2px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.assistant-drawer-head .btn svg { width: 16px; height: 16px; stroke-width: 2; stroke-linecap: round; }

/* Setzt `app.js`, solange die Schublade offen ist. `showModal()` sperrt das
   Durchscrollen zwar in der Spezifikation, auf iOS Safari scrollt der Hintergrund
   trotzdem mit. Dies ist die einzige Regel des Abschnitts, die nicht auf einer
   eigenen Klasse sitzt — sie überschreibt nichts, sie kommt hinzu. */
body.panel-open { overflow: hidden; }

/* ── Schmale Bildschirme ───────────────────────────────────────────────────
   Unter 720 px füllt die Schublade den Bildschirm, und die Seite gibt ihren
   Rand an den Verlauf ab. Die Höhe steht hier nicht mehr: die Spalte bekommt
   den verbleibenden Platz vom Layout und muss ihn auf keiner Breite ausrechnen. */
@media (max-width: 720px) {
    .assistant-drawer {
        width: 100%; height: 100dvh; max-height: 100dvh;
        margin: 0; border-radius: 0;
    }
    .assistant-drawer-inner { padding: var(--sp-3); padding-bottom: calc(var(--sp-3) + var(--assistant-keyboard)); }
    .assistant-thread { padding: var(--sp-3); }
    .assistant-bubble { max-width: 100%; }
    .assistant-action-args { grid-template-columns: 1fr; gap: 0; }
    .assistant-action-args dt { margin-top: var(--sp-2); }
    /* Nicht gestapelt: nebeneinander an den beiden Kartenrändern liegen die
       Knöpfe so weit auseinander wie die Karte breit ist. Übereinander wäre der
       untere — der bequem erreichbare — ausgerechnet einer von beiden, und wer
       „Ausführen" nach unten legt, lädt den Fehlgriff ein. */
    .assistant-action-foot .btn { min-width: 120px; padding-left: var(--sp-3); padding-right: var(--sp-3); }
    .assistant-history-list { grid-template-columns: 1fr; }
    /* Auf einem kleinen Telefon konkurriert jede Zeile unter dem Eingabefeld
       direkt mit dem Verlauf. Die wiederholte Rückfrage bleibt als Erinnerung
       stehen, aber gedeckelt — vollständig steht sie ohnehin darüber. */
    .assistant-composer-hint {
        display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
        overflow: hidden;
    }
    .assistant-page-title h1 { font-size: 20px; }
}
/* Ganz schmal: der Absende-Knopf gibt seine Beschriftung ab, damit das Textfeld
   breit genug für eine ganze Zeile Platzhalter bleibt. Den Namen trägt er
   weiterhin im `aria-label`. */
@media (max-width: 480px) {
    .assistant-send span { display: none; }
    .assistant-send { padding-left: var(--sp-3); padding-right: var(--sp-3); }
}
