/* ═══════════════════════════════════════════════════════════════════
   NavalStrike – Admin-Backend

   Eigene Gestaltung, bewusst NICHT css/main.css: Das Spiel bringt dort
   66 KB Messing, Wasser und Schiffsanimationen mit, von denen ein
   Leitstand nichts braucht. Was er braucht, ist Ruhe und Dichte – viele
   Zahlen auf wenig Platz, ohne dass es eng wird.

   Die Farbwelt bleibt dieselbe (Marineblau, Messing als Leitfarbe), damit
   erkennbar ist, wozu die Seite gehoert. Die Variablen stehen hier noch
   einmal statt per Verweis auf main.css: Das Backend laeuft auf einer
   eigenen Subdomain, und eine Datei weniger zu laden ist an dieser Stelle
   das bessere Geschaeft als die gemeinsame Quelle.

   Ausnahme: demo/admin-dashboard.php bindet main.css zusaetzlich ein,
   weil die Entwurfsseite ihr eigenes Drumherum daraus faerbt.
   ═══════════════════════════════════════════════════════════════════ */

:root {
    --ocean-900: #070d17;
    --ocean-800: #0c1522;
    --ocean-700: #121f31;
    --ocean-600: #1b2c43;
    --ocean-500: #253a56;
    --ocean-400: #34506f;
    --ocean-300: #4d6d92;
    --ocean-200: #7593b8;

    --accent-brass: #d4a53f;
    --accent-gold: #f0c368;
    --accent-steel: #5b8fc7;
    --accent-red: #d96852;
    --accent-green: #5a9e6f;
    --accent-orange: #d2853a;

    --text-primary: #e8eef7;
    --text-secondary: #9fb3cc;
    --text-muted: #6b7f99;

    --border-subtle: rgba(140, 175, 215, 0.16);
    --surface-card: rgba(18, 31, 49, 0.88);

    --space-xs: 4px;
    --space-sm: 8px;
    --space-md: 16px;
    --space-lg: 24px;
    --space-xl: 32px;

    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 14px;

    /* Dieselben Schriften wie das Spiel, aus demselben Verzeichnis.
       Die Schreibmaschine traegt nur die Marke im Kopf – in Tabellen und
       Zahlen waere sie schlecht lesbar. */
    --font-main: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --font-display: 'Special Elite', 'Courier New', monospace;
    --font-mono: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;
}

/* Die Schriftdateien liegen im Webspace des Spiels. Auf der eigenen
   Subdomain sind sie darueber nicht erreichbar, deshalb holt der Build
   sie mit (siehe .gitlab-ci.yml, Deploy des Backends). */
@font-face {
    font-family: 'Outfit';
    src: url('assets/fonts/outfit-var.woff2') format('woff2');
    font-weight: 100 900;
    font-display: swap;
}
@font-face {
    font-family: 'Special Elite';
    src: url('assets/fonts/special-elite-400.woff2') format('woff2');
    font-weight: 400;
    font-display: swap;
}
@font-face {
    font-family: 'JetBrains Mono';
    src: url('assets/fonts/jetbrains-mono-var.woff2') format('woff2');
    font-weight: 100 800;
    font-display: swap;
}

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

body {
    font-family: var(--font-main);
    background: var(--ocean-900);
    color: var(--text-primary);
    line-height: 1.6;
    min-height: 100vh;
    -webkit-font-smoothing: antialiased;
}

/* Die Entwurfsseite bringt ihr eigenes Drumherum mit und soll nicht
   randlos sein. */
body.admin-demo { padding-bottom: var(--space-xl); }

.admin-shell {
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 var(--space-lg);
}

/* ─── Kopf ────────────────────────────────────────────────────────── */

.admin-head {
    display: flex;
    align-items: center;
    gap: var(--space-lg);
    padding: var(--space-md) 0;
    margin-bottom: var(--space-lg);
    border-bottom: 1px solid var(--border-subtle);
    flex-wrap: wrap;
}

.admin-head__brand { display: flex; flex-direction: column; line-height: 1.2; }

.admin-head__mark {
    font-family: var(--font-display);
    font-size: 1.05rem;
    color: var(--accent-gold);
    letter-spacing: 0.02em;
}

.admin-head__title {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--text-muted);
}

.admin-head__user {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.admin-head__name { font-size: 0.85rem; color: var(--text-secondary); }

/* ─── Reiter ──────────────────────────────────────────────────────── */

.admin-tabs { display: flex; gap: var(--space-xs); }

.admin-tab {
    font: inherit;
    font-size: 0.9rem;
    background: none;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    padding: var(--space-sm) var(--space-md);
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    transition: color 0.15s, background 0.15s, border-color 0.15s;
}

.admin-tab:hover { color: var(--text-primary); background: rgba(140, 175, 215, 0.06); }

.admin-tab.is-active {
    color: var(--accent-gold);
    border-color: rgba(212, 165, 63, 0.35);
    background: rgba(212, 165, 63, 0.08);
}

/* Die Zahl offener Meldungen. Rot waere Alarm; das ist es nicht, es ist
   Arbeit. Messing sagt "hier liegt etwas", ohne zu draengen. */
.admin-tab__badge {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    background: var(--accent-brass);
    color: var(--ocean-900);
    border-radius: 999px;
    padding: 1px 7px;
    font-weight: 600;
}

.admin-panel { display: none; }
.admin-panel.is-active { display: block; }

/* ─── Kennzahlen ──────────────────────────────────────────────────── */

.admin-kpis {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: var(--space-md);
    margin-bottom: var(--space-lg);
}

.admin-kpi {
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-md);
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.admin-kpi__label {
    font-size: 0.74rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
}

.admin-kpi__value {
    font-family: var(--font-mono);
    font-size: 1.9rem;
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.2;
}

.admin-kpi__trend { font-size: 0.78rem; color: var(--text-muted); }
.admin-kpi__trend.is-up { color: var(--accent-green); }
.admin-kpi__trend.is-down { color: var(--accent-steel); }
.admin-kpi__trend.is-warn { color: var(--accent-orange); }

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

/* Karten in einer Reihe werden gleich hoch, nicht jede so hoch wie ihr
   Inhalt – sonst steht eine Reihe aus drei Diagrammen auf drei
   verschiedenen Hoehen, je nachdem wie lang die Anmerkung darueber ist.
   Das Vorgabeverhalten von Grid (stretch) erledigt das; align-items: start
   stand hier vorher und verhinderte es. */
.admin-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: var(--space-md);
}

/* Die Anmerkungen auf eine gemeinsame Mindesthoehe bringen.
 *
 * Der naheliegende Weg waere, das Diagramm mit margin-top: auto nach unten
 * zu schieben – der ist aber falsch: Karten mit kurzer Anmerkung bekommen
 * dann eine Leerflaeche zwischen Text und Diagramm, die genau so gross
 * ist wie der laengste Nachbartext. Im Bild klaffte darueber die halbe
 * Karte.
 *
 * Stattdessen bekommt die Anmerkung selbst eine Mindesthoehe von zwei
 * Zeilen. Die Diagramme starten damit auf gleicher Linie, ohne dass
 * irgendwo Leere entsteht; eine dreizeilige Anmerkung waechst weiterhin
 * ueber das Mass hinaus und schiebt nur ihre eigene Karte. */
.admin-card__note { min-height: calc(2 * 1.55em); }

/* Karten ohne Anmerkung: Der Abstand, den die Anmerkung sonst nach unten
   traegt, muss trotzdem da sein. */
.admin-card__title + .admin-chart { margin-top: var(--space-md); }

.admin-card {
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-md) var(--space-md) var(--space-lg);
}

/* Ueber die volle Breite – fuer Zeitverlaeufe und die quadratischen
   Raster, die nebeneinander zu schmal wuerden. */
.admin-card--wide { grid-column: 1 / -1; }
.admin-card--flat { background: none; border-style: dashed; }

.admin-card__title {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: var(--space-xs);
}

.admin-card__note {
    font-size: 0.8rem;
    color: var(--text-muted);
    line-height: 1.55;
    margin-bottom: var(--space-md);
    max-width: 70ch;
}

.admin-card__note code,
.admin-card code {
    font-family: var(--font-mono);
    font-size: 0.88em;
    color: var(--accent-brass);
}

.admin-card__foot {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    margin-top: var(--space-md);
    padding-top: var(--space-md);
    border-top: 1px solid var(--border-subtle);
    flex-wrap: wrap;
}

/* ─── Diagramme ───────────────────────────────────────────────────── */

/* Feste Hoehe, weil Chart.js mit maintainAspectRatio: false zeichnet:
   Ohne sie faellt das Feld auf 0 Pixel zusammen und das Diagramm bleibt
   unsichtbar. */
.admin-chart { position: relative; height: 260px; }
.admin-chart--tall { height: 360px; }

/* Die beiden Spielfeldraster sind quadratisch (10x10) und sollen es
   bleiben.
 *
 * aspect-ratio allein genuegt nicht: Chart.js zeichnet mit
 * maintainAspectRatio: false in die gemessene Flaeche, und auf einer
 * Karte ueber die volle Breite geriet das Raster winzig und stand
 * verloren in der Mitte. Deshalb wird die KARTE schmaler gehalten, nicht
 * nur das Feld darin – ueber die Breite der Karte selbst.
 *
 * 520px sind zehn Zellen zu gut 50 Pixel; darunter werden die
 * Beschriftungen der Spalten eng. */
.admin-chart--square {
    height: auto;
    aspect-ratio: 1 / 1;
    width: 100%;
    max-width: 520px;
    margin: 0 auto;
}

/* Die Karte eines Rasters braucht nicht die volle Breite. Sie steht
   trotzdem in der eigenen Zeile (admin-card--wide), weil zwei Raster
   nebeneinander auf schmalen Schirmen unlesbar wuerden. */
.admin-card--grid { max-width: 600px; }

.admin-chart__missing {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    color: var(--text-muted);
    font-size: 0.85rem;
    border: 1px dashed var(--border-subtle);
    border-radius: var(--radius-md);
}

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

.admin-toolbar {
    display: flex;
    align-items: center;
    gap: var(--space-md);
    margin-bottom: var(--space-md);
    flex-wrap: wrap;
}

.admin-toolbar__right {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

.admin-filters { display: flex; gap: var(--space-sm); flex-wrap: wrap; align-items: flex-end; }

.admin-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-xs);
    font-size: 0.82rem;
    color: var(--text-secondary);
    background: rgba(140, 175, 215, 0.05);
    border: 1px solid var(--border-subtle);
    border-radius: 999px;
    padding: 5px var(--space-md) 5px var(--space-sm);
    cursor: pointer;
    user-select: none;
}

.admin-chip input { accent-color: var(--accent-brass); cursor: pointer; }
.admin-chip span { font-family: var(--font-mono); font-size: 0.76rem; color: var(--text-muted); }

.admin-chip.is-active {
    color: var(--text-primary);
    border-color: rgba(212, 165, 63, 0.4);
    background: rgba(212, 165, 63, 0.1);
}
.admin-chip.is-active span { color: var(--accent-gold); }

.admin-field { display: flex; flex-direction: column; gap: 3px; }
.admin-field > span {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
}

.admin-select,
.admin-search {
    font: inherit;
    font-size: 0.86rem;
    background: var(--ocean-800);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    padding: var(--space-sm) var(--space-md);
}

.admin-search { min-width: 230px; }
.admin-select:focus,
.admin-search:focus { outline: none; border-color: rgba(212, 165, 63, 0.5); }

/* ─── Knoepfe ─────────────────────────────────────────────────────── */

.admin-btn {
    font: inherit;
    font-size: 0.85rem;
    background: rgba(140, 175, 215, 0.08);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    padding: var(--space-sm) var(--space-md);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}

.admin-btn:hover { background: rgba(140, 175, 215, 0.14); }

.admin-btn--primary {
    background: rgba(212, 165, 63, 0.16);
    border-color: rgba(212, 165, 63, 0.45);
    color: var(--accent-gold);
}
.admin-btn--primary:hover { background: rgba(212, 165, 63, 0.24); }

.admin-btn--ghost { background: none; color: var(--text-secondary); }
.admin-btn--ghost:hover { background: rgba(140, 175, 215, 0.08); }

.admin-btn:disabled { opacity: 0.45; cursor: not-allowed; }

.admin-hint { font-size: 0.78rem; color: var(--text-muted); line-height: 1.5; }

.admin-hint--bar {
    padding: var(--space-sm) var(--space-md);
    background: rgba(140, 175, 215, 0.04);
    border-left: 2px solid var(--border-subtle);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    margin-bottom: var(--space-md);
    max-width: 90ch;
}

/* ─── Lagebericht ─────────────────────────────────────────────────── */

.admin-digest { font-size: 0.88rem; line-height: 1.7; max-width: 80ch; }
.admin-digest h3 {
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--accent-brass);
    margin: var(--space-md) 0 var(--space-xs);
}
.admin-digest h3:first-child { margin-top: 0; }
.admin-digest ol, .admin-digest ul { padding-left: 1.4em; }
.admin-digest li { margin-bottom: var(--space-xs); }
.admin-digest p { color: var(--text-secondary); }
.admin-digest strong { color: var(--text-primary); }
.admin-digest em { color: var(--accent-brass); font-style: normal; font-family: var(--font-mono); font-size: 0.9em; }

/* ─── Rueckmeldungen ──────────────────────────────────────────────── */

.admin-feedback { display: flex; flex-direction: column; gap: var(--space-sm); }

.admin-report {
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-md);
}

/* Offene Meldungen bekommen eine Messingkante an der Seite. Kein
   Farbwechsel der ganzen Karte: Die Liste soll ruhig bleiben, auch wenn
   die Haelfte offen ist. */
.admin-report.is-open { border-left: 2px solid rgba(212, 165, 63, 0.55); }

.admin-report__bar {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    flex-wrap: wrap;
    margin-bottom: var(--space-sm);
}

.admin-report__id {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    color: var(--text-muted);
}

.admin-report__meta {
    font-size: 0.78rem;
    color: var(--text-muted);
}

.admin-report__time {
    margin-left: auto;
    font-size: 0.78rem;
    color: var(--text-muted);
}

.admin-report__summary {
    font-size: 0.92rem;
    color: var(--text-primary);
    margin-bottom: var(--space-sm);
    max-width: 90ch;
}

/* Rohtext einer noch nicht eingeordneten Meldung: kursiv und blasser, um
   ihn von einer Zusammenfassung zu unterscheiden. */
.admin-report__summary--raw {
    font-style: italic;
    color: var(--text-secondary);
}

.admin-report__tags { display: flex; gap: var(--space-xs); flex-wrap: wrap; }

.admin-sev {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    padding: 2px var(--space-sm);
    border-radius: var(--radius-sm);
    font-weight: 600;
}

.admin-sev--blocking { background: rgba(217, 104, 82, 0.2); color: var(--accent-red); }
.admin-sev--annoying { background: rgba(210, 133, 58, 0.2); color: var(--accent-orange); }
.admin-sev--minor    { background: rgba(212, 165, 63, 0.16); color: var(--accent-brass); }
.admin-sev--praise   { background: rgba(90, 158, 111, 0.2); color: var(--accent-green); }

.admin-status {
    font-size: 0.72rem;
    padding: 2px var(--space-sm);
    border-radius: 999px;
    border: 1px solid var(--border-subtle);
    color: var(--text-muted);
}
.admin-status--new   { border-color: rgba(212, 165, 63, 0.45); color: var(--accent-gold); }
.admin-status--seen  { border-color: rgba(91, 143, 199, 0.4); color: var(--accent-steel); }
.admin-status--fixed { border-color: rgba(90, 158, 111, 0.4); color: var(--accent-green); }

.admin-tag {
    font-size: 0.74rem;
    font-family: var(--font-mono);
    padding: 1px var(--space-sm);
    border-radius: var(--radius-sm);
    background: rgba(140, 175, 215, 0.08);
    color: var(--text-secondary);
}

.admin-tag--bug { background: rgba(217, 104, 82, 0.14); color: #e59182; }
.admin-tag--praise { background: rgba(90, 158, 111, 0.16); color: #87c49a; }
.admin-tag--dup { background: rgba(155, 123, 184, 0.16); color: #bfa5d4; }
.admin-tag--unclear { background: rgba(107, 127, 153, 0.16); }
.admin-tag--note { background: rgba(212, 165, 63, 0.14); color: var(--accent-brass); }

/* Eine Einordnung, der das Modell selbst nicht traut, soll nicht wie
   eine sichere aussehen. */
.admin-tag--unsure {
    background: rgba(107, 127, 153, 0.12);
    color: var(--text-muted);
    border: 1px dashed var(--border-subtle);
}
.admin-tag--sure { background: rgba(90, 158, 111, 0.12); color: #87c49a; }

.admin-tag--pending {
    background: none;
    border: 1px dashed rgba(212, 165, 63, 0.4);
    color: var(--accent-brass);
}

/* ─── Eine Meldung im Detail ──────────────────────────────────────── */

.admin-report__detail { margin-top: var(--space-md); }

.admin-report__detail > summary {
    font-size: 0.82rem;
    color: var(--text-secondary);
    cursor: pointer;
    padding: var(--space-xs) 0;
    user-select: none;
}
.admin-report__detail > summary:hover { color: var(--accent-gold); }

.admin-report__body {
    padding-top: var(--space-md);
    margin-top: var(--space-sm);
    border-top: 1px solid var(--border-subtle);
}

.admin-report__body h4 {
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--accent-brass);
    margin: var(--space-md) 0 var(--space-xs);
}
.admin-report__body h4:first-child { margin-top: 0; }
.admin-report__body p { font-size: 0.88rem; color: var(--text-secondary); max-width: 85ch; }

.admin-kv { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
.admin-kv th {
    text-align: left;
    font-weight: 500;
    color: var(--text-muted);
    padding: 3px var(--space-md) 3px 0;
    white-space: nowrap;
    vertical-align: top;
    width: 1%;
}
.admin-kv td { padding: 3px 0; color: var(--text-secondary); font-family: var(--font-mono); font-size: 0.95em; }

.admin-console {
    font-family: var(--font-mono);
    font-size: 0.76rem;
    line-height: 1.65;
    background: var(--ocean-900);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: var(--space-sm) var(--space-md);
    color: #e59182;
    overflow-x: auto;
    white-space: pre;
}

.admin-shot {
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    overflow: hidden;
    max-width: 640px;
}
.admin-shot img { display: block; width: 100%; height: auto; }

/* Scheitert das Laden, tritt eine Textmeldung an die Stelle des Bildes
   (siehe admin.js). Ohne Innenabstand klebte sie am Rahmen – der war
   fuer ein randlos sitzendes Bild gemacht. */
.admin-shot .admin-empty { padding: var(--space-lg) var(--space-md); }

.admin-shot--placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 16 / 9;
    background: repeating-linear-gradient(
        45deg,
        rgba(140, 175, 215, 0.04),
        rgba(140, 175, 215, 0.04) 10px,
        transparent 10px,
        transparent 20px
    );
    color: var(--text-muted);
    font-size: 0.82rem;
    text-align: center;
}
.admin-shot--placeholder small { font-family: var(--font-mono); font-size: 0.9em; opacity: 0.7; }

.admin-note {
    font: inherit;
    font-size: 0.85rem;
    width: 100%;
    max-width: 640px;
    background: var(--ocean-800);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    padding: var(--space-sm) var(--space-md);
    resize: vertical;
}
.admin-note:focus { outline: none; border-color: rgba(212, 165, 63, 0.5); }

.admin-report__actions {
    display: flex;
    gap: var(--space-sm);
    margin-top: var(--space-md);
    flex-wrap: wrap;
}

/* ─── Grenzen der Daten ───────────────────────────────────────────── */

.admin-limits { list-style: none; display: grid; gap: var(--space-sm); }
.admin-limits li {
    font-size: 0.84rem;
    color: var(--text-muted);
    line-height: 1.6;
    padding-left: var(--space-md);
    border-left: 2px solid var(--border-subtle);
    max-width: 85ch;
}
.admin-limits strong { color: var(--text-secondary); }

/* ─── Anmeldung ───────────────────────────────────────────────────── */

/* [hidden] muss staerker sein als jede display-Regel.
 *
 * Das Attribut hidden setzt im Browser nur eine VORGABE (display: none aus
 * dem User-Agent-Stylesheet). Jede Regel aus dieser Datei ist staerker –
 * und .admin-login traegt display: flex. Das Ergebnis war, dass der
 * Anmeldekasten auch nach erfolgreicher Anmeldung sichtbar blieb und das
 * Dashboard darunter stand.
 *
 * Die Regel gilt bewusst fuer ALLE Elemente, nicht nur fuer die beiden
 * Bereiche: Auch die Fehlermeldung und die Zahl offener Meldungen werden
 * ueber hidden geschaltet, und dieselbe Falle wartet dort beim naechsten
 * display-Zusatz. */
[hidden] { display: none !important; }

.admin-login {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-lg);
}

.admin-login__box {
    background: var(--surface-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-xl);
    max-width: 420px;
    width: 100%;
    text-align: center;
}

.admin-login__mark {
    font-family: var(--font-display);
    font-size: 1.3rem;
    color: var(--accent-gold);
    display: block;
    margin-bottom: var(--space-xs);
}

.admin-login__title {
    font-size: 0.76rem;
    text-transform: uppercase;
    letter-spacing: 0.16em;
    color: var(--text-muted);
    margin-bottom: var(--space-lg);
}

.admin-login__text {
    font-size: 0.86rem;
    color: var(--text-secondary);
    margin-bottom: var(--space-lg);
    line-height: 1.6;
}

.admin-login .admin-btn { width: 100%; padding: var(--space-md); font-size: 0.92rem; }

.admin-login__error {
    font-size: 0.84rem;
    padding: var(--space-sm) var(--space-md);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-md);
    text-align: left;
    line-height: 1.55;
}
.admin-login__error.is-denied {
    background: rgba(210, 133, 58, 0.12);
    border: 1px solid rgba(210, 133, 58, 0.4);
    color: #e5a86f;
}
.admin-login__error.is-error {
    background: rgba(217, 104, 82, 0.12);
    border: 1px solid rgba(217, 104, 82, 0.4);
    color: #e59182;
}

/* ─── Zustaende ───────────────────────────────────────────────────── */

.admin-empty,
.admin-loading {
    padding: var(--space-xl);
    text-align: center;
    color: var(--text-muted);
    font-size: 0.88rem;
}

.admin-toast {
    position: fixed;
    bottom: var(--space-lg);
    left: 50%;
    transform: translateX(-50%);
    background: var(--ocean-700);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: var(--space-sm) var(--space-lg);
    font-size: 0.86rem;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
    z-index: 100;
}
.admin-toast.is-error { border-color: rgba(217, 104, 82, 0.5); color: #e59182; }

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

@media (max-width: 720px) {
    .admin-shell { padding: 0 var(--space-md); }

    .admin-head { gap: var(--space-sm); }
    .admin-head__user { width: 100%; order: 3; justify-content: space-between; }
    .admin-tabs { width: 100%; order: 2; overflow-x: auto; }

    .admin-toolbar__right { margin-left: 0; width: 100%; }
    .admin-search { flex: 1; min-width: 0; }

    .admin-report__time { margin-left: 0; width: 100%; }

    .admin-chart { height: 220px; }
    .admin-chart--tall { height: 300px; }
}
