/* mitarbeiter.com Brain — Oberfläche.
 *
 * Aufteilung der Farben: die Umgebung (Navigation, Leseansicht) ist hell, die Karte selbst
 * ist der dunkelblaue Kasten. Dadurch liegt das Blau der Knoten auf dem einzigen dunklen
 * Feld der Seite und ist das Erste, was man sieht.
 *
 * League Spartan für Überschriften, Poppins für Text — beide selbst ausgeliefert, damit die
 * Seite nicht bei einem fremden Anbieter nachlädt. */

@font-face {
    font-family: 'League Spartan';
    src: url('/assets/fonts/LeagueSpartan-Bold.ttf') format('truetype');
    font-weight: 700;
    font-display: swap;
}
@font-face {
    font-family: 'League Spartan';
    src: url('/assets/fonts/LeagueSpartan-Black.ttf') format('truetype');
    font-weight: 900;
    font-display: swap;
}
@font-face {
    font-family: 'Poppins';
    src: url('/assets/fonts/Poppins-Regular.ttf') format('truetype');
    font-weight: 400;
    font-display: swap;
}
@font-face {
    font-family: 'Poppins';
    src: url('/assets/fonts/Poppins-Medium.ttf') format('truetype');
    font-weight: 500;
    font-display: swap;
}
@font-face {
    font-family: 'Poppins';
    src: url('/assets/fonts/Poppins-Bold.ttf') format('truetype');
    font-weight: 700;
    font-display: swap;
}

:root {
    --blue: #3aa5f5;
    --blue-bright: #4db5ff;
    --blue-soft: #7cc4fa;
    --cyan: #25b9dc;
    --green: #39c26d;
    --lime: #aac933;
    --amber: #f5b83d;
    --ink: #0d2a47;
    --ink-soft: #4a6076;
    --ink-faint: #8298ad;
    --paper: #ffffff;
    --paper-tint: #eef4fa;
    --line: #dde8f2;
    --deep: #0a2540;
    /* Der Grund, auf dem die Karten schweben — neutraler und einen Hauch dunkler als das
     * Weiss der Karten, damit deren Ränder ohne harte Linien lesbar sind. */
    --shell: #eef1f5;
    --radius: 20px;
    --radius-sm: 12px;
    --shadow: 0 18px 50px rgba(7, 24, 41, 0.14);
    --shadow-sm: 0 4px 16px rgba(7, 24, 41, 0.08);
    --side-w: 296px;
    --panel-w: 470px;
    --head: 'League Spartan', system-ui, -apple-system, sans-serif;
    --copy: 'Poppins', system-ui, -apple-system, sans-serif;
}

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

html,
body {
    margin: 0;
    height: 100%;
}

body {
    font-family: var(--copy);
    color: var(--ink);
    background: var(--paper-tint);
    -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3,
h4 {
    font-family: var(--head);
    font-weight: 700;
    letter-spacing: -0.01em;
    margin: 0;
}

a {
    color: #1c7fd0;
    text-decoration: none;
}
a:hover {
    text-decoration: underline;
}

button {
    font-family: var(--copy);
    cursor: pointer;
}

/* ===================================================================== Anmeldung */

/* Navy, damit die Anmeldung dieselbe Sprache spricht wie der Kartenkasten dahinter. Die
 * Verläufe geben Tiefe, ohne ein Bild zu laden; die Bewegung kommt aus `login.js`. */
.page-login {
    min-height: 100%;
    background:
        radial-gradient(70rem 45rem at 50% -8rem, #17456a 0%, rgba(23, 69, 106, 0) 62%),
        radial-gradient(50rem 40rem at 85% 110%, #0e3352 0%, rgba(14, 51, 82, 0) 60%),
        var(--deep);
    color: #e8f1f9;
}

.bg-canvas {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    /* Die Fläche liegt über dem Hintergrund, aber unter der Karte, und fängt keine Klicks. */
    z-index: 0;
    pointer-events: none;
}

/* Feste Zentrierung: `min-height: 100dvh` statt `100%`, damit die Karte auch dann in der
 * Mitte steht, wenn der Inhalt kürzer ist als das Fenster — und `place-items` auf dem
 * Container, nicht auf dem Body, sonst hängt die Zentrierung an der Body-Höhe. */
.login {
    position: relative;
    z-index: 1;
    display: grid;
    place-items: center;
    min-height: 100vh;
    min-height: 100dvh;
    padding: 2rem 1rem;
}

/* Weiss auf Navy: die Karte ist die helle Fläche in einem dunklen Raum und damit das
 * Erste, was man ansieht. Der tiefe Schatten hebt sie von der Konstellation ab, statt
 * sie darauf aufzukleben. */
.login-card {
    width: min(30rem, 100%);
    background: var(--paper);
    border: 1px solid rgba(255, 255, 255, 0.5);
    border-radius: var(--radius);
    box-shadow:
        0 34px 90px rgba(2, 12, 24, 0.6),
        0 4px 14px rgba(2, 12, 24, 0.3);
    padding: 2.25rem 2.5rem 2rem;
    text-align: center;
    color: var(--ink);
}
.login-card-wide {
    width: min(38rem, 100%);
    text-align: left;
}
/* Die breite Karte ist ein Dokument, keine Anmeldemaske: dann gehört auch der Kopf
 * linksbündig, sonst steht ein zentriertes Icon über linksbündigem Text. */
.login-card-wide .login-mark {
    text-align: left;
}

/* „Interner Zugang" — die erste Zeile der Karte, damit niemand rätselt, wofür das hier ist. */
.intern {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0 0 1.35rem;
    padding: 0.3rem 0.8rem 0.3rem 0.65rem;
    border: 1px solid rgba(58, 165, 245, 0.28);
    background: #eaf5fe;
    border-radius: 999px;
    color: #1c6fb0;
    font-size: 0.72rem;
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
}
.intern svg {
    width: 13px;
    height: 13px;
    flex: none;
}

.login-mark {
    margin-bottom: 1.25rem;
}
/* Die Marke kommt als <img> aus /assets/brain-icon (echte Datei, sonst nachgezeichnet).
 * Breite und Höhe stehen im Attribut — hier nur dafür sorgen, dass ein nicht ganz
 * quadratisches Original nicht verzerrt wird. */
.brainmark {
    display: inline-block;
    vertical-align: middle;
    object-fit: contain;
}

/* Keine Fassung um die Marke nötig: `brain-icon.png` hat einen deckend weissen Hintergrund
 * (geprüft — die Ecke ist 255,255,255,255), und auf der weissen Karte geht der einfach
 * darin auf. Auf dunklem Grund hätte er als weisser Kasten gestanden — das war der Grund,
 * die Karte weiss zu halten, statt das Icon nachzubearbeiten. */
.login-card h1 {
    font-size: 1.6rem;
    margin-bottom: 0.6rem;
    color: var(--ink);
}
.login-sub {
    color: var(--ink-soft);
    line-height: 1.6;
    font-size: 0.95rem;
    margin: 0 0 1.5rem;
}
.login-error {
    background: #fdf0ef;
    border: 1px solid #f6d4d0;
    color: #a3312a;
    border-radius: var(--radius-sm);
    padding: 0.75rem 1rem;
    font-size: 0.9rem;
    line-height: 1.5;
    text-align: left;
    margin: 0 0 1.25rem;
}

/* Dunkle Fläche auf der weissen Karte: die eindeutig wichtigste Handlung der Seite. */
.btn-google {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.65rem;
    width: 100%;
    padding: 0.85rem 1.25rem;
    background: var(--ink);
    color: #fff;
    font-weight: 500;
    font-size: 0.95rem;
    border-radius: 999px;
    transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.btn-google:hover {
    background: #123a5f;
    text-decoration: none;
    transform: translateY(-1px);
    box-shadow: 0 10px 24px rgba(13, 42, 71, 0.32);
}
/* Das Google-Zeichen ist farbig und liegt auf Dunkelblau — eine weisse Scheibe darunter
 * hält es lesbar, so wie es auch in Googles eigenen Vorgaben steht. */
.btn-google svg {
    background: #fff;
    border-radius: 50%;
    padding: 3px;
    box-sizing: content-box;
}

.login-note {
    color: var(--ink-faint);
    font-size: 0.8rem;
    line-height: 1.6;
    margin: 1.25rem 0 0;
}
.login-note strong {
    color: var(--ink-soft);
    font-weight: 500;
}
.login-connector {
    border-top: 1px solid var(--line);
    padding-top: 1rem;
}
.steps {
    color: var(--ink-soft);
    line-height: 1.7;
    font-size: 0.95rem;
    padding-left: 1.25rem;
}
.steps strong {
    color: var(--ink);
    font-weight: 500;
}
code {
    font-family: ui-monospace, 'SF Mono', Menlo, monospace;
    font-size: 0.85em;
    background: var(--paper-tint);
    padding: 0.15em 0.4em;
    border-radius: 5px;
}

/* ===================================================================== Gerüst */

.page-app {
    overflow: hidden;
    background: var(--shell);
}

/*
 * Vier Karten links, die Bühne rechts — als Geschwister in EINEM Raster, nicht die Karten
 * in einem Rahmen. Nur so kann die Bühne auf dem Handy zwischen Suche und Ordner rutschen
 * (siehe die schmale Ansicht unten); in einem gemeinsamen Rahmen wäre sie immer davor oder
 * dahinter.
 *
 * Die Ordner-Karte bekommt die freie Höhe (`minmax(0, 1fr)`) und scrollt in sich. `minmax`
 * mit 0 als Minimum ist Absicht: `1fr` allein würde vom Inhalt nach unten gedrückt und die
 * Karte statt ihres Inhalts scrollen lassen.
 */
.app {
    display: grid;
    gap: 0.8rem;
    padding: 0.8rem;
    height: 100vh;
    height: 100dvh;
    grid-template-columns: var(--side-w) minmax(0, 1fr);
    grid-template-rows: auto auto auto minmax(0, 1fr) auto;
    grid-template-areas:
        'brand   stage'
        'search  stage'
        'drop    stage'
        'folders stage'
        'stats   stage';
}

/* Bei aktiver Suche verschwinden die Ordner und die Trefferliste nimmt ihren Platz —
 * währenddessen interessiert nichts darunter. Der Bereich bleibt rechteckig, sonst wäre
 * die Zuweisung ungültig. */
/* Bei aktiver Suche fallen Einwerfen und Ordner weg — die Trefferliste nimmt ihren Platz. */
.app.sucht {
    grid-template-areas:
        'brand   stage'
        'search  stage'
        'search  stage'
        'search  stage'
        'stats   stage';
}
.app.sucht .drop-card {
    display: none;
}
.app.sucht .folders-card {
    display: none;
}

.card {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    box-shadow: 0 1px 2px rgba(13, 42, 71, 0.04), 0 8px 24px rgba(13, 42, 71, 0.05);
    min-width: 0;
}
.brand-card {
    grid-area: brand;
    padding: 0.8rem;
}
.search-card {
    grid-area: search;
    padding: 0.8rem;
    display: flex;
    flex-direction: column;
    min-height: 0;
    gap: 0.6rem;
}
.drop-card {
    grid-area: drop;
    padding: 0.8rem;
}
.folders-card {
    grid-area: folders;
    display: flex;
    flex-direction: column;
    min-height: 0;
    padding: 0.8rem 0.55rem 0.55rem;
}
.stats-card {
    grid-area: stats;
    padding: 0.8rem;
}
.stage {
    grid-area: stage;
}

/* ===================================================================== Marke */

/* Das Logo sitzt direkt in der weissen Karte — keine Box in der Box. Dass der weisse
 * Hintergrund von `brain-icon.png` hier keine Fassung braucht, ist genau der Vorteil: auf
 * Weiss geht er auf, und die Marke steht frei. */
.brand {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    color: var(--ink);
}
.brand:hover {
    text-decoration: none;
}
.brand .brainmark {
    flex: none;
}
.brand-text {
    font-size: 0.95rem;
    color: var(--ink-soft);
    /* Eine Zeile: die Schriftgrössen sind so gewählt, dass „mitarbeiter.com Brain" neben dem
     * 56-px-Logo in die Kartenbreite passt. */
    white-space: nowrap;
    min-width: 0;
}
.brand-text strong {
    font-family: var(--head);
    font-weight: 900;
    font-size: 1.2rem;
    letter-spacing: -0.02em;
    color: var(--ink);
    vertical-align: -1px;
}

/* ===================================================================== Suche */

.search {
    position: relative;
    display: flex;
    align-items: center;
    flex: none;
}
.search-icon {
    position: absolute;
    left: 0.7rem;
    width: 15px;
    height: 15px;
    color: var(--ink-faint);
    pointer-events: none;
}
#q {
    width: 100%;
    font-family: var(--copy);
    font-size: 0.875rem;
    color: var(--ink);
    padding: 0.6rem 1.9rem 0.6rem 2.1rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--paper-tint);
    outline: none;
    transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
#q::-webkit-search-cancel-button {
    display: none;
}
#q:focus {
    background: var(--paper);
    border-color: var(--blue);
    box-shadow: 0 0 0 3px rgba(58, 165, 245, 0.16);
}
#q-clear {
    position: absolute;
    right: 0.45rem;
    border: 0;
    background: transparent;
    color: var(--ink-faint);
    font-size: 1.2rem;
    line-height: 1;
    padding: 0.1rem 0.35rem;
    border-radius: 50%;
}
#q-clear:hover {
    color: var(--ink);
}

/* Die Trefferliste füllt die Karte und scrollt darin — nicht mehr ein Streifen von
 * wenigen Pixeln, in dem man nicht scrollen kann. */
.results {
    overflow-y: auto;
    overscroll-behavior: contain;
    min-height: 0;
    flex: 1 1 auto;
    margin: 0 -0.35rem;
    padding: 0 0.35rem;
}
.results[hidden] {
    display: none;
}
.results-head {
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ink-faint);
    font-weight: 500;
    margin: 0.5rem 0 0.35rem;
}
.results-head:first-child {
    margin-top: 0;
}

/* Ein Eintrag — in der Trefferliste wie im geöffneten Ordner dieselbe Gestalt. */
.hit {
    display: block;
    width: 100%;
    text-align: left;
    border: 0;
    background: transparent;
    border-radius: 9px;
    padding: 0.4rem 0.55rem;
    color: var(--ink);
    font-size: 0.83rem;
    line-height: 1.35;
}
.hit:hover,
.hit:focus-visible {
    background: #eef7fe;
    outline: none;
}
.hit[aria-current='true'] {
    background: #e2f1fd;
}
.hit-title {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-weight: 500;
}
.hit-title .dot {
    flex: none;
}
.hit-title span:last-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.hit-meta {
    color: var(--ink-faint);
    font-size: 0.72rem;
    margin-top: 0.1rem;
    padding-left: 1rem;
}
.hit-snippet {
    color: var(--ink-soft);
    font-size: 0.75rem;
    line-height: 1.45;
    margin-top: 0.15rem;
    padding-left: 1rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.results-empty {
    color: var(--ink-faint);
    font-size: 0.82rem;
    padding: 0.5rem 0.55rem;
}

.dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    display: inline-block;
    background: var(--blue);
}

/* ===================================================================== Einwerfen */

/* Umschalter extern/intern. Zwei Knöpfe in einer Schiene statt eines Kästchens: es ist eine
 * Wahl zwischen zwei Dingen, nicht ein An und Aus — und welches gilt, muss man sehen können,
 * ohne es zu erschliessen. */
.seg {
    display: inline-flex;
    gap: 2px;
    background: var(--paper-tint);
    border: 1px solid var(--line);
    border-radius: 999px;
    padding: 2px;
}
.seg button {
    border: 0;
    background: transparent;
    color: var(--ink-faint);
    font-size: 0.68rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    /* Genug Polster, dass die beiden Wörter nicht als eines gelesen werden — „externintern"
     * war bei engerem Satz genau das Ergebnis. */
    padding: 0.24rem 0.7rem;
    border-radius: 999px;
    line-height: 1.4;
}
.seg button.seg-on {
    background: var(--paper);
    color: #0f5e9e;
    font-weight: 500;
    box-shadow: 0 1px 2px rgba(13, 42, 71, 0.12);
}
/* Intern ist die Ablage, bei der niemand von aussen im Raum war — sie bekommt einen eigenen
 * Ton, damit ein versehentliches „intern" auffällt. */
#seg-intern.seg-on {
    color: #9a6100;
    background: #fff8e8;
}

.drop {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.8rem 0.75rem;
    border: 1.5px dashed var(--line);
    border-radius: var(--radius-sm);
    background: #fafcfe;
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}
.drop:hover {
    border-color: var(--blue-soft);
    background: #f4fbff;
}
/* Während etwas über der Fläche hängt: deutlich, damit man das Loslassen traut. */
.drop.drueber {
    border-color: var(--blue);
    border-style: solid;
    background: #eaf5fe;
}
.drop svg {
    width: 22px;
    height: 22px;
    flex: none;
    color: var(--blue);
}
.drop-text {
    display: flex;
    flex-direction: column;
    line-height: 1.25;
    min-width: 0;
}
.drop-text strong {
    font-size: 0.83rem;
    font-weight: 500;
}
.drop-text small {
    font-size: 0.72rem;
    color: var(--ink-faint);
}
.drop.aus {
    cursor: not-allowed;
    opacity: 0.6;
}

/* Eine Zeile je Datei: Name, Zustand, und bei Bedarf der Hinweis, dass die Endung von der
 * Pipeline nicht gelesen wird. */
.drop-liste {
    margin-top: 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 2px;
    max-height: 11rem;
    overflow-y: auto;
}
/* Raster statt Flexreihe: der Dateiname bekommt die erste Spalte, der Zustand die zweite,
 * ein Hinweis die ganze Breite darunter. Als Flexreihe drückten Zustand und Hinweis den
 * Namen auf „Sales …" zusammen — und der Name ist das, was man lesen will. */
.drop-zeile {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    gap: 0.1rem 0.4rem;
    font-size: 0.76rem;
    padding: 0.2rem 0.15rem;
    line-height: 1.35;
}
.drop-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--ink);
}
.drop-stand {
    font-size: 0.7rem;
    color: var(--ink-faint);
    white-space: nowrap;
}
.drop-zeile.ok .drop-stand {
    color: #1c7f4f;
}
.drop-zeile.fehler .drop-stand {
    color: #b4372e;
}
.drop-warnung {
    grid-column: 1 / -1;
    font-size: 0.7rem;
    color: #9a6100;
}
.drop-zeile.fehler .drop-warnung {
    color: #b4372e;
}

/* ===================================================================== Ordner */

.card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ink-faint);
    font-weight: 500;
    margin: 0 0.25rem 0.5rem;
    flex: none;
}
.card-head button {
    border: 0;
    background: transparent;
    color: #1c7fd0;
    font-size: 0.7rem;
    text-transform: none;
    letter-spacing: 0;
    padding: 0;
}

.types {
    overflow-y: auto;
    overscroll-behavior: contain;
    min-height: 0;
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

/* Ein Ordner. Zugeklappt eine Zeile, aufgeklappt Zeile plus Einträge. */
.type {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    border: 0;
    background: transparent;
    border-radius: 9px;
    padding: 0.42rem 0.5rem;
    font-size: 0.85rem;
    color: var(--ink);
    text-align: left;
}
.type:hover {
    background: var(--paper-tint);
}
.type-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.type-count {
    margin-left: auto;
    font-size: 0.72rem;
    color: var(--ink-faint);
    font-variant-numeric: tabular-nums;
}
.type-caret {
    flex: none;
    width: 9px;
    height: 9px;
    color: var(--ink-faint);
    transition: transform 0.18s ease;
}
.type[aria-expanded='true'] {
    background: #e2f1fd;
    color: #0f5e9e;
    font-weight: 500;
}
.type[aria-expanded='true'] .type-caret {
    transform: rotate(90deg);
    color: #1275be;
}
.type[aria-expanded='true'] .type-count {
    color: #3b87c4;
}

/* Die Einträge des geöffneten Ordners, leicht eingezogen und mit einer Führungslinie —
 * damit man sieht, dass sie zu der Zeile darüber gehören. */
.type-list {
    margin: 0.15rem 0 0.4rem 0.75rem;
    padding-left: 0.5rem;
    border-left: 2px solid #dceafa;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

/* ===================================================================== Zahlen */

/* Zwei Zeilen statt fünf: die Höhe gehört der Ordnerkarte darüber. Die Trennpunkte kommen
 * aus dem CSS, damit im Markup nur die Werte stehen. */
.stats {
    display: flex;
    flex-wrap: wrap;
    gap: 0.15rem 0.5rem;
    margin: 0 0 0.65rem;
    font-size: 0.76rem;
    color: var(--ink-faint);
    line-height: 1.5;
}
.stats span {
    font-variant-numeric: tabular-nums;
}
.stats span:not(:last-child)::after {
    content: '·';
    color: var(--line);
    margin-left: 0.5rem;
}
.stats strong {
    color: var(--ink);
    font-weight: 500;
}
.stats-sha {
    width: 100%;
}
.stats-sha::after {
    content: none;
}
.user {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.78rem;
    color: var(--ink-soft);
    border-top: 1px solid var(--line);
    padding-top: 0.65rem;
}
.user span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.user a {
    flex: none;
    color: var(--ink-faint);
}

/* ===================================================================== Bühne */

.stage {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    /* Ausdrücklich eine Zeile, die die Höhe füllt. Ohne das wäre die Zeilenhöhe `auto`,
     * also inhaltsabhängig — und der Inhalt ist ein Canvas mit `height:100%`. Diese
     * Zirkelabhängigkeit löst der Browser mit 0 auf: der Kasten bliebe leer. */
    grid-template-rows: minmax(0, 1fr);
    /* Abstand und Polster liegen jetzt auf `.app` — hier bleibt nur der Spalt zur Leseansicht. */
    gap: 0.8rem;
    min-height: 0;
    min-width: 0;
    transition: grid-template-columns 0.32s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.stage.with-panel {
    grid-template-columns: minmax(0, 1fr) var(--panel-w);
}

/* Der Kasten: dunkelblau, abgerundet, mit leichter Tiefe zur Mitte. */
.graph-box {
    position: relative;
    min-width: 0;
    min-height: 0;
    border-radius: var(--radius);
    overflow: hidden;
    background:
        radial-gradient(120% 100% at 50% 0%, #14405f 0%, rgba(20, 64, 95, 0) 55%),
        radial-gradient(90% 90% at 50% 100%, #0d3050 0%, rgba(13, 48, 80, 0) 60%),
        var(--deep);
    box-shadow: var(--shadow), inset 0 0 0 1px rgba(255, 255, 255, 0.06);
}

/* Absolut im Kasten, nicht im Fluss: damit kann die eigene Grösse des Canvas die Höhe des
 * Kastens nie beeinflussen — die Richtung ist immer Kasten → Canvas. */
#graph {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    cursor: grab;
    touch-action: none;
}
#graph.dragging {
    cursor: grabbing;
}
#graph.on-node {
    cursor: pointer;
}

.graph-hud {
    position: absolute;
    inset: auto 0 0 0;
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.9rem 1.05rem;
    pointer-events: none;
}
.hud-label {
    color: rgba(255, 255, 255, 0.9);
    font-size: 0.8rem;
    line-height: 1.5;
    max-width: 60%;
    text-shadow: 0 1px 8px rgba(4, 20, 36, 0.8);
}
.hud-label strong {
    font-family: var(--head);
    font-weight: 700;
    font-size: 0.95rem;
    display: block;
}
.hud-label em {
    color: rgba(255, 255, 255, 0.6);
    font-style: normal;
}
.hud-tools {
    display: flex;
    gap: 0.35rem;
    pointer-events: auto;
}
.hud-tools button {
    border: 1px solid rgba(255, 255, 255, 0.16);
    background: rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.92);
    font-size: 0.78rem;
    font-weight: 500;
    padding: 0.35rem 0.7rem;
    border-radius: 999px;
    backdrop-filter: blur(8px);
    transition: background 0.15s ease, border-color 0.15s ease;
}
.hud-tools button:hover {
    background: rgba(255, 255, 255, 0.18);
    border-color: rgba(255, 255, 255, 0.3);
}

.loading {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    color: rgba(255, 255, 255, 0.6);
    font-size: 0.85rem;
    letter-spacing: 0.02em;
    background: var(--deep);
    transition: opacity 0.4s ease;
}
.loading[hidden] {
    display: grid;
    opacity: 0;
    pointer-events: none;
}

/* ===================================================================== Leseansicht */

.panel {
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    overflow-y: auto;
    overscroll-behavior: contain;
    min-width: 0;
}
.panel[hidden] {
    display: none;
}

.panel-head {
    position: sticky;
    top: 0;
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--line);
    padding: 1.15rem 1.5rem 0.9rem;
    z-index: 2;
}
.panel-kicker {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ink-faint);
    font-weight: 500;
}
.panel-close {
    margin-left: auto;
    border: 0;
    background: transparent;
    color: var(--ink-faint);
    font-size: 1.35rem;
    line-height: 1;
    padding: 0 0.2rem;
    border-radius: 6px;
}
.panel-close:hover {
    color: var(--ink);
    background: var(--paper-tint);
}
.panel-head h2 {
    font-size: 1.3rem;
    line-height: 1.25;
    margin: 0.45rem 0 0;
}
.panel-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 0.9rem;
    margin-top: 0.55rem;
    font-size: 0.74rem;
    color: var(--ink-faint);
}
.tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-top: 0.6rem;
}
.tag {
    font-size: 0.7rem;
    color: #1c6fb0;
    background: #eaf5fe;
    border-radius: 999px;
    padding: 0.15rem 0.55rem;
}

.panel-body {
    padding: 1.35rem 1.5rem 2rem;
    font-size: 0.875rem;
    line-height: 1.68;
    color: #24425e;
}
.panel-body > *:first-child {
    margin-top: 0;
}
/* Die H1 der Seite steht schon im Kopf des Panels. */
.panel-body h1 {
    display: none;
}
.panel-body h2 {
    font-size: 1.05rem;
    margin: 1.9rem 0 0.6rem;
    padding-bottom: 0.35rem;
    border-bottom: 1px solid var(--line);
    color: var(--ink);
}
.panel-body h3 {
    font-size: 0.95rem;
    margin: 1.4rem 0 0.45rem;
    color: var(--ink);
}
.panel-body h4 {
    font-size: 0.85rem;
    margin: 1.1rem 0 0.35rem;
    color: var(--ink-soft);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.panel-body p {
    margin: 0 0 0.85rem;
}
.panel-body ul,
.panel-body ol {
    margin: 0 0 0.9rem;
    padding-left: 1.15rem;
}
.panel-body li {
    margin-bottom: 0.3rem;
}
.panel-body li > ul,
.panel-body li > ol {
    margin: 0.3rem 0 0.2rem;
}
.panel-body strong {
    font-weight: 500;
    color: var(--ink);
}
.panel-body hr {
    border: 0;
    border-top: 1px solid var(--line);
    margin: 1.5rem 0;
}
.panel-body blockquote {
    margin: 0 0 0.9rem;
    padding: 0.6rem 0.95rem;
    border-left: 3px solid var(--blue-soft);
    background: #f6fbff;
    border-radius: 0 8px 8px 0;
    color: var(--ink-soft);
}
.panel-body pre {
    background: #f4f8fc;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    padding: 0.85rem 1rem;
    overflow-x: auto;
    font-size: 0.78rem;
    line-height: 1.55;
}
.panel-body pre code {
    background: none;
    padding: 0;
}

.table-scroll {
    overflow-x: auto;
    margin: 0 0 1.1rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
}
.panel-body table {
    border-collapse: collapse;
    width: 100%;
    font-size: 0.78rem;
}
.panel-body th,
.panel-body td {
    text-align: left;
    padding: 0.5rem 0.7rem;
    border-bottom: 1px solid var(--line);
    vertical-align: top;
}
.panel-body th {
    background: var(--paper-tint);
    font-weight: 500;
    color: var(--ink);
    white-space: nowrap;
}
.panel-body tr:last-child td {
    border-bottom: 0;
}

/* Wikilinks: als Verweis erkennbar, ohne den Text zu zerreissen. */
.wl {
    color: #1c7fd0;
    border-bottom: 1px solid rgba(28, 127, 208, 0.28);
    cursor: pointer;
}
.wl:hover {
    text-decoration: none;
    border-bottom-color: #1c7fd0;
    background: #eaf5fe;
}
.wl-dead {
    color: var(--ink-faint);
    border-bottom: 1px dashed var(--line);
    cursor: help;
}

.panel-links {
    border-top: 1px solid var(--line);
    padding: 1.15rem 1.5rem 1.75rem;
    background: #fafcfe;
}
.panel-links h3 {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ink-faint);
    font-weight: 500;
    margin: 0 0 0.55rem;
}
.panel-links h3:not(:first-child) {
    margin-top: 1.35rem;
}
.link-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}
.link-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    border: 1px solid var(--line);
    background: var(--paper);
    border-radius: 999px;
    padding: 0.25rem 0.7rem 0.25rem 0.55rem;
    font-size: 0.76rem;
    color: var(--ink);
    max-width: 100%;
}
.link-chip span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.link-chip:hover {
    border-color: var(--blue);
    background: #f4fbff;
}

.panel-empty {
    padding: 2rem 1.5rem;
    color: var(--ink-faint);
    font-size: 0.85rem;
}

/* ===================================================================== Schmal */

@media (max-width: 1180px) {
    :root {
        --panel-w: 380px;
        --side-w: 264px;
    }
}

/*
 * Handy und schmale Fenster.
 *
 * Vorher stand hier nur „eine Spalte" — und damit war die Karte unbenutzbar: die
 * Navigationsspalte nahm ihre Inhaltshöhe (Marke, Suche, zehn Ordner, Zahlen), und für die
 * Bühne blieb ein Streifen übrig. Zwei Dinge lösen das:
 *
 *  1. **Die Bühne rückt nach oben**, zwischen Suche und Ordner. Deshalb sind die Karten
 *     Geschwister der Bühne und nicht in einem Rahmen — anders wäre diese Reihenfolge nicht
 *     möglich.
 *  2. **Sie bekommt eine feste Höhe** statt eines Anteils an einer Seite, die selbst scrollt.
 *     `62dvh` ist genug, um die Karte zu lesen, und lässt darunter erkennen, dass es
 *     weitergeht. `dvh` statt `vh`, weil die Adressleiste auf dem Handy sonst mitzählt.
 */
@media (max-width: 900px) {
    .page-app {
        overflow: auto;
    }
    .app {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: auto auto auto auto auto auto;
        grid-template-areas:
            'brand'
            'search'
            'stage'
            'drop'
            'folders'
            'stats';
        height: auto;
        min-height: 100dvh;
    }
    /* Bei aktiver Suche fallen Einwerfen und Ordner weg; die Zeilen sind hier alle
     * inhaltsabhängig, dadurch schliesst sich die Lücke von selbst. */
    .app.sucht {
        grid-template-areas:
            'brand'
            'search'
            'stage'
            'drop'
            'folders'
            'stats';
    }
    .stage {
        height: 62dvh;
    }
    /* Die Trefferliste darf hier nicht die halbe Seite werden — gescrollt wird die Seite. */
    .results {
        max-height: 45dvh;
    }
    .types {
        max-height: none;
        overflow: visible;
    }
    .folders-card {
        min-height: 0;
    }

    /* Die Leseansicht wird zur ganzen Fläche statt einer zweiten Spalte: auf 390 px wären
     * zwei Spalten beides zu schmal. Fest im Fensterrahmen, mit eigenem Scrollen — sonst
     * scrollt die Seite darunter weg, während man liest. */
    .stage.with-panel {
        grid-template-columns: minmax(0, 1fr);
    }
    .panel {
        position: fixed;
        inset: 0;
        z-index: 50;
        border-radius: 0;
        border: 0;
        max-height: 100dvh;
    }
    .panel-head {
        padding-top: 1rem;
    }
}

@media (max-width: 480px) {
    .login-card,
    .login-card-wide {
        padding: 1.75rem 1.35rem 1.5rem;
    }
    /* „Mit dem Firmenkonto anmelden" ist bei 375 px vier Zeichen zu lang für eine Zeile.
     * Lieber etwas kleiner setzen als die Beschriftung kürzen — der Satz sagt, worum es
     * geht: ein Firmenkonto, kein privates. */
    .btn-google {
        font-size: 0.88rem;
        padding: 0.8rem 0.9rem;
        gap: 0.5rem;
    }
    .app {
        gap: 0.6rem;
        padding: 0.6rem;
    }
    .brand-text strong {
        font-size: 1.35rem;
    }
    /* Auf dem Handy zählt jede Zeile: die Werkzeuge unten in der Karte werden kompakter,
     * damit sie nicht über die halbe Breite laufen. */
    .hud-tools button {
        font-size: 0.72rem;
        padding: 0.3rem 0.55rem;
    }
    .hud-label {
        max-width: 100%;
        font-size: 0.75rem;
    }
    .graph-hud {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.5rem;
        padding: 0.7rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .stage,
    .btn-google,
    .loading {
        transition: none;
    }
}
