/* MyTime – Oberfläche. Bewusst ohne Framework, damit die App ohne Build-Schritt
   auf jedem Webhosting läuft. */

:root {
    --bg: #f5f6f8;
    --surface: #ffffff;
    --surface-2: #fafbfc;
    --border: #e2e5ea;
    --border-strong: #cbd1da;
    --text: #1c2430;
    --text-muted: #6b7684;
    --accent: #2f6fd0;
    --accent-hover: #2559ac;
    --accent-soft: #e8f0fc;
    --running: #14875a;
    --running-soft: #e3f5ec;
    --danger: #c0392b;
    --danger-soft: #fdecea;
    --warning: #b8860b;
    /* Variantenfarben: Solo in gebranntem Ocker, Team im Blau der Anwendung.
       Blau gegen Orange bleibt bei den häufigsten Farbfehlsichtigkeiten
       unterscheidbar – Rot gegen Grün wäre die schlechteste Wahl. */
    --solo: #b25a0c;
    --solo-hover: #8f4709;
    --solo-soft: #fbeee2;
    --team: #2f6fd0;
    --team-hover: #2559ac;
    --team-soft: #e6eefb;

    /*
     * Eine Höhe für alles, was man anfassen kann.
     *
     * Ohne sie rechnet jedes Element seine Höhe aus Schrift und Innenabstand
     * selbst – und ein Auswahlfeld kommt dabei anders heraus als ein
     * Eingabefeld (37 statt 41 Pixel). In einer Zeile aus Auswahl, Eingabe und
     * Schaltfläche stand dann alles um ein paar Pixel versetzt, und mit
     * `align-items: end` rutschten auch die Beschriftungen auseinander.
     */
    --control: 40px;
    --control-sm: 32px;

    /*
     * Wie breit die Seite wird.
     *
     * Alle Seiten teilen die Breite der Berichte. Früher waren es 1180 Punkte
     * und nur breite Tafeln hoben sie an (`#app.ist-weit`) – beim Wechsel
     * zwischen den Bereichen sprang dann die Kopfzeile hin und her. Damit
     * Formulare und Fliesstext trotzdem lesbar bleiben, deckeln untereinander
     * stehende Felder und Absätze ihre Breite selbst (siehe „Lesebreite").
     */
    --seitenbreite: 1600px;
    --seitenbreite-weit: 1600px;

    --radius: 8px;
    --shadow: 0 1px 2px rgba(20, 30, 45, .06), 0 4px 12px rgba(20, 30, 45, .05);
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #14181f;
        --surface: #1b212b;
        --surface-2: #202733;
        --border: #2c3542;
        --border-strong: #3a4553;
        --text: #e6eaf0;
        --text-muted: #98a3b3;
        --accent: #5b9bf0;
        --accent-hover: #7db0f5;
        --solo: #e8944a;
        --solo-hover: #f3a862;
        --solo-soft: #33241a;
        --team: #6ba5f2;
        --team-hover: #7db0f5;
        --team-soft: #1a2536;
        --accent-soft: #1f2c40;
        --running: #34c98a;
        --running-soft: #16302a;
        --danger: #e5776b;
        --danger-soft: #34211f;
        --warning: #d9a441;
        --shadow: 0 1px 2px rgba(0, 0, 0, .3), 0 4px 12px rgba(0, 0, 0, .25);
    }
}

* { box-sizing: border-box; }

/*
 * Das hidden-Attribut muss wirken, auch wenn ein Element eine eigene
 * display-Regel trägt: display: flex würde die Voreinstellung sonst
 * überschreiben und das Element bliebe sichtbar.
 */
[hidden] { display: none !important; }

html {
    /* Kein Verzögern der Tap-Reaktion durch Doppeltipp-Zoom. Zoom selbst
       bleibt möglich – die Seite schränkt ihn nirgends ein. */
    touch-action: manipulation;
    -webkit-tap-highlight-color: rgba(47, 111, 208, .18);
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
}

.app-loading { padding: 60px; text-align: center; color: var(--text-muted); }

a { color: var(--accent); }

/* Sprungmarke: nur sichtbar, wenn sie den Fokus hat. */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 200;
    padding: 10px 16px;
    background: var(--surface);
    border: 1px solid var(--accent);
    border-radius: 0 0 var(--radius) 0;
    font-weight: 600;
    text-decoration: none;
}

.skip-link:focus-visible { left: 0; }

/* Ankersprünge sollen nicht unter der Kopfzeile landen. */
[id] { scroll-margin-top: 70px; }

/* ---------- Kopfzeile ---------- */

.topbar {
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 20;
}

.topbar-inner {
    max-width: var(--seitenbreite);
    margin: 0 auto;
    padding: 0 max(20px, env(safe-area-inset-right)) 0 max(20px, env(safe-area-inset-left));
    display: flex;
    align-items: center;
    gap: 20px;
    min-height: 58px;
    /* Nicht umbrechen: Die Navigation schrumpft und scrollt bei Bedarf, statt
       die Kopfzeile zweizeilig werden zu lassen. Auf schmalen Geräten wird der
       Umbruch weiter unten wieder erlaubt. */
    flex-wrap: nowrap;
}

.brand {
    font-weight: 650;
    letter-spacing: -.01em;
    display: flex;
    align-items: center;
    gap: 8px;
    margin-right: 4px;
}

.brand span { font-size: 18px; }

.nav {
    display: flex;
    gap: 2px;
    flex: 1 1 auto;
    min-width: 0;
    align-items: center;
    /* Nicht scrollen: Was nicht hineinpasst, wandert ins Menü. Ein Balken,
       der seitlich wegläuft, versteckt Bereiche, ohne es zu sagen. */
    overflow: hidden;
}

.nav-icon { display: none; }

/* "Mehr" öffnet die selteneren Bereiche – auf großen Geräten als Klappmenü
   unter der Schaltfläche, auf kleinen als Fläche über der unteren Leiste. */
.nav-more-wrap { position: relative; }

.nav-more-toggle {
    border: none;
    background: none;
    padding: 7px 12px;
    border-radius: var(--radius);
    color: var(--text-muted);
    font-weight: 500;
}

.nav-more-toggle:hover { background: var(--surface-2); color: var(--text); }
.nav-more-toggle.active { background: var(--accent-soft); color: var(--accent); }

/*
 * Fest positioniert, nicht absolut: Das Menü steckt in der Leiste, und die
 * schneidet mit `overflow: hidden` ab, was nicht hineinpasst. Ein absolut
 * positioniertes Klappmenü wurde davon mit abgeschnitten – vom Menü blieb ein
 * Streifen in Höhe der Leiste übrig. Feste Position hängt am Fenster und
 * entkommt dem Beschnitt; wohin, sagt die Leiste beim Öffnen.
 */
.nav-more {
    position: fixed;
    top: 0;
    left: auto;
    right: 0;
    min-width: 200px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    z-index: 40;
}

.nav-more a { display: block; }

/*
 * Ein Eintrag im Menü, der keinen Bereich öffnet, sondern einen Dialog: der
 * eigene Zugang. Eine Schaltfläche und kein Verweis – sie führt nirgendwohin.
 */
.nav-more .menue-eintrag {
    display: block;
    width: 100%;
    height: auto;
    min-height: 0;
    padding: 7px 12px;
    border: none;
    border-radius: var(--radius);
    background: none;
    color: var(--text-muted);
    font-size: 14px;
    text-align: left;
}

.nav-more .menue-eintrag:hover { background: var(--surface-2); color: var(--text); }

/*
 * "Admin" – ein Bereich, der aufklappt.
 *
 * Sieht in der Leiste aus wie ein Verweis, ist aber eine Schaltfläche; der
 * kleine Winkel dahinter sagt, dass noch etwas kommt. Sein Feld ist dasselbe
 * wie das von "Mehr", nur linksbündig unter der Schaltfläche.
 */
.nav-gruppe-wrap { position: relative; }

.nav-gruppe-toggle {
    border: none;
    background: none;
    padding: 7px 12px;
    border-radius: var(--radius);
    color: var(--text-muted);
    font-weight: 500;
    white-space: nowrap;
}

.nav-gruppe-toggle::after {
    content: "";
    display: inline-block;
    width: 5px;
    height: 5px;
    margin-left: 7px;
    vertical-align: 1px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg);
}

.nav-gruppe-toggle:hover { background: var(--surface-2); color: var(--text); }
.nav-gruppe-toggle.active { background: var(--accent-soft); color: var(--accent); }

.nav-gruppe-feld {
    position: fixed;
    top: 0;
    left: auto;
    right: 0;
    min-width: 180px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    z-index: 40;
}

.nav-gruppe-feld a { display: block; }

/*
 * Dieselbe Gruppe, nachdem sie ins Menü "Mehr" gerutscht ist: keine zweite
 * Klappe, sondern eine Überschrift mit den Einträgen darunter. Ein Feld im
 * Feld wäre mit dem Daumen nicht zu treffen.
 */
.menue-gruppe { display: flex; flex-direction: column; gap: 2px; }

.menue-gruppe-titel {
    padding: 10px 12px 4px;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-muted);
    border-top: 1px solid var(--border);
    margin-top: 4px;
}

.nav-more .menue-gruppe:first-child .menue-gruppe-titel { border-top: none; margin-top: 0; }

.nav a {
    padding: 7px 12px;
    border-radius: var(--radius);
    text-decoration: none;
    color: var(--text-muted);
    font-weight: 500;
    white-space: nowrap;
}

.nav a:hover { background: var(--surface-2); color: var(--text); }
.nav a.active { background: var(--accent-soft); color: var(--accent); }

.topbar-right { display: flex; align-items: center; gap: 12px; flex: 0 1 auto; min-width: 0; }

/*
 * Der eigene Name in der Kopfzeile ist eine Schaltfläche: Dahinter steht der
 * eigene Zugang. Sie sieht aber nicht danach aus – ein Knopf neben dem Knopf
 * "Abmelden" liesse offen, welcher der beiden gemeint ist.
 */
.user-chip {
    color: var(--text-muted);
    font-size: 14px;
    background: none;
    border: none;
    height: auto;
    min-height: 0;
    padding: 4px 6px;
    border-radius: 6px;
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.user-chip:hover { background: var(--surface-2); color: var(--text); }

/* Mit dem Finger bedient braucht auch sie eine Fläche. */
@media (pointer: coarse) {
    .user-chip { min-height: 44px; }
}

/* Laufende Stoppuhr in der Kopfzeile */
.tracker-pill {
    display: flex;
    align-items: center;
    gap: 10px;
    background: var(--running-soft);
    color: var(--running);
    border: 1px solid transparent;
    border-radius: 999px;
    padding: 5px 6px 5px 14px;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    max-width: 380px;
    min-width: 0;
}

.tracker-pill .tracker-label {
    font-weight: 500;
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 200px;
}

.tracker-dot {
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--running);
    animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

/*
 * Wer Bewegung abbestellt hat, bekommt keine – auch keine kurze.
 *
 * Vorher stand hier nur der pulsierende Punkt der Stoppuhr. Die Übergänge an
 * Balken und Fortschritt liefen weiter; für wen Bewegung ein Problem ist, ist
 * eine kurze so wenig hilfreich wie eine lange.
 */
@media (prefers-reduced-motion: reduce) {
    .tracker-dot { animation: none; }

    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
        scroll-behavior: auto !important;
    }
}

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

/*
 * Die Seite als Spalte: Kopf, Inhalt, Fusszeile.
 *
 * Damit steht die Fusszeile mit den Rechtstexten auch auf einer kurzen Seite
 * unten am Fensterrand und nicht mitten im Bild.
 */
#app { display: flex; flex-direction: column; min-height: 100vh; }

/*
 * Die breite Seite -- fuer die Tafeln, die quer stehen.
 *
 * Die Berichte und die Auswertungen bestehen aus Kreuztabellen, deren Spalten
 * die Zeit sind. Dort ist die Breite kein Luxus, sondern der Unterschied
 * zwischen „man sieht den Monat" und „man rollt ihn ab". Jede andere Seite
 * behaelt die Lesebreite: Eine Einstellungsmaske ueber sechzehnhundert Punkte
 * zu ziehen machte aus einem Formular eine Landschaft, in der die
 * Beschriftung links und das Feld rechts steht.
 *
 * Die Klasse setzt die Ansicht selbst (`App.breiteSeite`), weil nur sie
 * weiss, was sie zeigt. Beim naechsten Zeichnen faellt sie von allein weg --
 * die Wurzel wird dabei geleert.
 */
#app.ist-weit { --seitenbreite: var(--seitenbreite-weit); }

/*
 * Lesebreite.
 *
 * Die Seite ist so breit wie die Berichte. Ein Formular, dessen Felder
 * untereinander stehen, und ein Absatz Erklärung würden auf 1600 Punkte
 * gezogen unlesbar – sie behalten ihr altes Mass. Felder nebeneinander in
 * einer Reihe (`.row`, `.filters`) sind davon nicht betroffen.
 */
main .card-body > .field,
main .card-body > form > .field { max-width: 760px; }
main .card-body > p,
main .card-body > .small,
main .card > p { max-width: 110ch; }

main {
    flex: 1 0 auto;
    width: 100%;
    max-width: var(--seitenbreite);
    margin: 0 auto;
    /* Auf Geräten mit Aussparungen bleibt der Inhalt frei davon. */
    padding: 24px max(20px, env(safe-area-inset-right)) calc(80px + env(safe-area-inset-bottom)) max(20px, env(safe-area-inset-left));
}

/*
 * Impressum und Datenschutz, unter jeder Ansicht.
 *
 * Zurueckhaltend: Sie gehoeren dorthin, wo man sie sucht, und nicht dorthin,
 * wo man sie sieht. Auf dem Telefon haelt sie Abstand zur Leiste am unteren
 * Rand -- sonst laege sie darunter.
 */
.app-fuss {
    padding: 14px max(20px, env(safe-area-inset-right)) 18px max(20px, env(safe-area-inset-left));
    border-top: 1px solid var(--border);
    font-size: 13px;
}

.app-fuss nav {
    /* Bündig mit dem Inhalt: main zieht seinen Innenabstand von der Breite ab. */
    max-width: calc(var(--seitenbreite) - 40px);
    margin: 0 auto;
    display: flex;
    flex-wrap: wrap;
    gap: 6px 18px;
}

.app-fuss a { color: var(--muted); text-decoration: none; }
.app-fuss a:hover { color: var(--text); text-decoration: underline; }

@media (max-width: 640px) {
    .app-fuss { padding-bottom: calc(80px + env(safe-area-inset-bottom)); }
}

.page-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 18px;
    flex-wrap: wrap;
}

h1 { font-size: 22px; margin: 0; letter-spacing: -.01em; text-wrap: balance; }
h2 { font-size: 17px; margin: 0 0 12px; text-wrap: balance; }

.muted { color: var(--text-muted); }
.small { font-size: 13px; }

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    margin-bottom: 18px;
}

.card-body { padding: 16px; }
/* Die Überschrift bringt ihren Abstand nach unten mit; im Kopf einer Karte
   steht sie allein und der Abstand wäre eine tote Zone. */
.card-head h2 { margin-bottom: 0; }

.card-head {
    padding: 12px 16px;
    border-bottom: 1px solid var(--border);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

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

label { display: block; font-size: 13px; font-weight: 500; color: var(--text-muted); margin-bottom: 4px; }

input, select, textarea, button {
    font: inherit;
    color: inherit;
}

input[type=text], input[type=email], input[type=password], input[type=date], input[type=number], select, textarea {
    width: 100%;
    min-width: 0;
    padding: 8px 10px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: 6px;
}

/*
 * Alles einzeilig Bedienbare auf dasselbe Mass – als feste Höhe, nicht als
 * Mindesthöhe: Ein Eingabefeld kommt von sich aus auf 41 Pixel, ein
 * Auswahlfeld auf 37. Eine Untergrenze hätte nur das kleinere angehoben und
 * den Unterschied auf ein Pixel verkleinert, statt ihn zu beenden.
 *
 * Das mehrzeilige Textfeld bleibt aussen vor: Es soll wachsen dürfen.
 */
input[type=text], input[type=email], input[type=password], input[type=date],
input[type=number], select, button, .btn {
    height: var(--control);
}

/* ---------- Uhrzeit als zwei Felder ---------- */

/*
 * Stunde und Minute stehen getrennt, sehen zusammen aber wie ein einzelnes
 * Feld aus. Der Rahmen sitzt an der Gruppe, die beiden Felder darin sind
 * rahmenlos – sonst zerfiele die Uhrzeit optisch in zwei Eingaben.
 */
.timeinput {
    display: inline-flex;
    align-items: center;
    /* Das Mass trägt die Gruppe; die Felder darin sind nur ihr Inhalt. */
    height: var(--control);
    gap: 1px;
    padding: 0 8px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: 6px;
}

.timeinput input.time-part {
    width: 2.2em;
    min-height: 0;
    padding: 8px 0;
    border: 0;
    background: none;
    border-radius: 0;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.timeinput input.time-part:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
    border-radius: 4px;
}

/* Der Rahmen gehört zur Gruppe, also leuchtet auch die Gruppe auf. */
.timeinput:focus-within {
    border-color: var(--accent);
}

.time-colon {
    color: var(--muted);
    padding-bottom: 1px;
}

/* ---------- Zeitzeilen der Anwesenheit ---------- */

.zeit-zeilen { display: flex; flex-direction: column; gap: 8px; }

/*
 * Eine Zeile der Zeiterfassung braucht zwei Zeilen Platz: oben die Zeiten,
 * darunter die Zuordnung. Nebeneinander wäre bei sechs Feldern jedes zu
 * schmal, um es zu lesen.
 */
.zeit-zeile {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-2);
}

/*
 * Die Zuordnung untereinander, nicht nebeneinander.
 *
 * Nebeneinander blieb fuer jedes der drei Felder ein Drittel der Dialogbreite
 * -- zu wenig, um "999 - Allgemein" zu lesen, und die Kuerzel davor (KST, KTR,
 * PRJ) musste man kennen. Untereinander hat jede Ebene ihre ausgeschriebene
 * Beschriftung und die volle Breite fuer den Namen dahinter.
 */
/*
 * Die Frage an der Naht zweier Zeilen.
 *
 * Sie steht in der Zeile, in der geaendert wurde, und nicht als Dialog ueber
 * dem Dialog: Gefragt wird nach einer Kleinigkeit, und wer sie uebergeht, hat
 * damit schon geantwortet. Zurueckhaltend gefaerbt -- es ist ein Angebot und
 * keine Beanstandung.
 */
.zeit-anschluss {
    flex: 1 0 100%;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 6px;
    padding: 7px 10px;
    border-radius: var(--radius);
    background: var(--accent-soft);
    font-size: 13px;
}

/* Schmale Grundbreite, damit „Ja“ und „Nein“ neben dem Text stehen bleiben:
   mit `auto` waere der Satz die Grundbreite, und die Knoepfe fielen darunter. */
.zeit-anschluss > span { flex: 1 1 12em; min-width: 0; }

/* Keine Frage mehr, sondern eine Zusage: ruhiger als die Frage daneben. */
.zeit-anschluss.ist-gemerkt {
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text-muted);
}

.zeit-kosten {
    flex: 1 0 100%;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    gap: 6px 10px;
}

.zeit-kosten select,
.zeit-kosten .combo,
.zeit-kosten input[type=text] { min-width: 0; width: 100%; }

.zeit-kosten-label {
    font-size: 12px;
    font-weight: 500;
    color: var(--text-muted);
    white-space: nowrap;
    text-align: right;
}

.zeit-zeile .zeit-art {
    width: auto;
    /* Breit genug fuer "Arbeit", aber nicht breiter als die Uhrzeiten: die
       Zeiten sind die Eingabe, die Art nur ihre Einordnung. */
    flex: 1 1 auto;
    min-width: 6.5em;
    max-width: 11em;
}

.zeit-zeile .zeit-weg { flex: 0 0 auto; margin-left: auto; }

.zeit-bis-strich { color: var(--muted); }

.zeit-summe {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--border);
    font-variant-numeric: tabular-nums;
}

tr.zeile-pause td { color: var(--text-muted); }

/* ---------- Variante des Kontos ---------- */

/*
 * Die Variante färbt die gesamte Oberfläche. Sie steht am Wurzelelement,
 * damit einzelne Ansichten sie nicht mitführen müssen.
 */
/*
 * Auch die Farbe beim Überfahren gehört der Variante.
 *
 * Bisher wurde nur `--accent` umgestellt, `--accent-hover` blieb auf dem
 * blauen Grundwert stehen. In Solo schlug damit jede aktive Schaltfläche
 * unter dem Mauszeiger von Braun nach Blau um – am deutlichsten am
 * Umschalter, dessen gewählte Stellung man ja gerade angeklickt hat und
 * deshalb noch überfährt.
 */
:root[data-variante="solo"] {
    --accent: var(--solo);
    --accent-hover: var(--solo-hover);
    --accent-soft: var(--solo-soft);
}

:root[data-variante="team"] {
    --accent: var(--team);
    --accent-hover: var(--team-hover);
    --accent-soft: var(--team-soft);
}

:root[data-variante="solo"] .marke-zeichen { color: var(--solo); }
:root[data-variante="team"] .marke-zeichen { color: var(--team); }

.marke-zeichen { width: 22px; height: 22px; flex: 0 0 auto; }

/* ---------- Logo für Anmeldung und Registrierung ---------- */

.logo {
    display: flex;
    align-items: center;
    gap: 13px;
    margin-bottom: 18px;
}

.logo .marke-zeichen { width: 46px; height: 46px; }

/*
 * Der Schriftzug ist Text, kein Bild: So bleibt er in jeder Größe scharf,
 * folgt der Systemschrift und lässt sich vorlesen.
 */
.logo-wort {
    font-size: 30px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -.025em;
    white-space: nowrap;
    color: var(--text);
}

.logo-akzent { color: var(--accent); }

.logo-variante {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: .24em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-top: 6px;
}

/* Ohne gewählte Variante trägt die Marke den Grundakzent der Anwendung. */
.logo-neutral .marke-zeichen { color: var(--accent); }
.logo-solo .marke-zeichen, .logo-solo .logo-akzent { color: var(--solo); }
.logo-team .marke-zeichen, .logo-team .logo-akzent { color: var(--team); }

/* Die Auswahlkarten der Variante zeigen ihre eigene Marke. */
.mode-kopf { display: flex; align-items: center; gap: 9px; }
.mode-kopf .marke-zeichen { width: 26px; height: 26px; }
.mode-option[data-mode="solo"] .marke-zeichen { color: var(--solo); }
.mode-option[data-mode="team"] .marke-zeichen { color: var(--team); }

/* Der Titel der gewählten Karte trägt die Farbe ihrer Variante, nicht den
   Grundakzent – sonst stünde eine ockerfarbene Marke neben blauer Schrift. */
.mode-option[data-mode="solo"].is-active .mode-title { color: var(--solo); }
.mode-option[data-mode="team"].is-active .mode-title { color: var(--team); }

.brand-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.marke-schild {
    font-size: 10.5px;
    letter-spacing: .09em;
    text-transform: uppercase;
    font-weight: 600;
    padding: 2px 7px;
    border-radius: 3px;
    background: var(--accent-soft);
    color: var(--accent);
    flex: 0 0 auto;
}

/* ---------- Übersicht ---------- */

.uebersicht { display: flex; flex-direction: column; gap: 16px; }

/*
 * Der offene Betrag ist die Aussage der Seite und darf sich deshalb als
 * einziges Element vom übrigen Raster abheben.
 */
.card.offen { border-left: 3px solid var(--accent); }
.card.offen h2 { margin-bottom: 12px; }

.offen-zahlen {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 8px 20px;
    margin-bottom: 14px;
}

.offen-betrag {
    font-size: 34px;
    font-weight: 650;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
    color: var(--accent);
}

.offen-neben { color: var(--text-muted); }

/* Nichts offen ist eine gute Nachricht, keine Warnung. */
.card.offen-leer { border-left-color: var(--running); }
.card.offen-leer h2 { color: var(--running); }

.kennzahlen {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 36px;
    padding: 16px;
}

.kennzahl { display: flex; flex-direction: column; gap: 2px; }
.kennzahl-label { font-size: 12px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; }
.kennzahl-wert { font-size: 24px; font-weight: 650; font-variant-numeric: tabular-nums; }
.kennzahl-zusatz { font-size: 12px; color: var(--text-muted); }

.liste > * + * { border-top: 1px solid var(--border); }

.budget-zeile {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 140px auto;
    align-items: center;
    gap: 16px;
    padding: 12px 16px;
}

.budget-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.budget-wert { font-variant-numeric: tabular-nums; white-space: nowrap; font-size: 14px; }
.budget-anteil { color: var(--text-muted); }

.budget-zeile.ist-knapp .budget-anteil { color: var(--warning); font-weight: 600; }
.budget-zeile.ist-ueber .budget-anteil { color: var(--danger); font-weight: 600; }
.budget-zeile.ist-knapp .bar > div { background: var(--warning); }

.letzte-zeile {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    align-items: baseline;
    gap: 16px;
    padding: 11px 16px;
}

.letzte-text { min-width: 0; }
.letzte-dauer { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.letzte-datum { white-space: nowrap; }

@media (max-width: 640px) {
    .offen-betrag { font-size: 28px; }

    /* Balken und Wert rücken auf eine zweite Zeile, damit der Projektname
       nicht auf wenige Zeichen zusammenschrumpft. */
    .budget-zeile { grid-template-columns: minmax(0, 1fr) auto; }
    .budget-zeile .budget-balken { grid-column: 1 / -1; order: 3; }

    .letzte-zeile { grid-template-columns: minmax(0, 1fr) auto; }
    .letzte-datum { grid-column: 1; font-size: 12px; }
}

/* Monat und Download stehen nebeneinander wie ein Feld. */
/* Monat und zwei Ausgaben – schmal reicht eine Zeile dafür nicht. */
.export-zeile { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.export-zeile select { width: auto; min-width: 150px; }
.export-zeile .btn { white-space: nowrap; }

/* ---------- Übersicht: wer heute da ist ---------- */

.personen {
    display: grid;
    /* auto-fit statt auto-fill: Bei wenigen Personen ziehen sich die
       vorhandenen Spalten auf, statt leere Spuren als graue Lücke zu zeigen. */
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 1px;
    background: var(--border);
    border-top: 1px solid var(--border);
}

.person {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 16px;
    background: var(--surface);
}

.person-name { font-weight: 500; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.person-zustand { font-size: 12.5px; color: var(--text-muted); white-space: nowrap; }

/* Der Zustand steht auch links als Streifen – Farbe allein trüge ihn nicht. */
.person { border-left: 3px solid transparent; }
.person.ist-dienst { border-left-color: var(--running); }
.person.ist-dienst .person-zustand { color: var(--running); }
.person.ist-abwesend { border-left-color: var(--accent); }
.person.ist-abwesend .person-zustand { color: var(--accent); }

.person-laeuft { font-weight: 600; }

.kommt-zeile {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 11px 16px;
    flex-wrap: wrap;
}

.kommt-text { min-width: 0; }
.kommt-datum { white-space: nowrap; }

/* ---------- Urlaub: Anträge ---------- */

.antrag {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    padding: 13px 16px;
    flex-wrap: wrap;
}

.antrag-text { min-width: 0; flex: 1 1 260px; }

.antrag-kopf {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
    margin-bottom: 2px;
}

.antrag-aktionen { display: flex; gap: 8px; flex: 0 0 auto; }

/* Ein offener Antrag verlangt eine Handlung und wird deshalb hervorgehoben. */
.antrag-requested { border-left: 3px solid var(--warning); }
.antrag-rejected .antrag-text { opacity: .72; }

/* ---------- Urlaubskonto ---------- */

.konto-zeile {
    display: grid;
    grid-template-columns: minmax(120px, 200px) minmax(0, 1fr) auto;
    align-items: center;
    gap: 12px 20px;
    padding: 13px 16px;
}

.konto-name { font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

.konto-werte {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 28px;
}

.konto-wert { display: flex; flex-direction: column; gap: 1px; min-width: 74px; }
.konto-label { font-size: 11px; letter-spacing: .05em; text-transform: uppercase; color: var(--text-muted); }
.konto-zahl { font-variant-numeric: tabular-nums; }
.konto-rest .konto-zahl { font-weight: 650; }
.konto-aktion { flex: 0 0 auto; }

/* Ein negativer Rest ist eine Überziehung, keine Nebensache. */
.ist-negativ .konto-zahl, .ist-negativ { color: var(--danger); }

/* ---------- Umschalter zwischen zwei Sichten ---------- */

/*
 * Zwei Schaltflächen, die aussehen wie ein Schalter mit zwei Stellungen. Kein
 * ARIA-Reiter: Der verspräche eine Bedienung mit den Pfeiltasten. Welche
 * Stellung gilt, sagt `aria-pressed` – und sichtbar der Kontrast.
 */
.schalter {
    display: inline-flex;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    overflow: hidden;
}

.schalter-knopf {
    height: var(--control-sm);
    padding: 0 14px;
    border: none;
    border-radius: 0;
    background: var(--surface);
    color: var(--text-muted);
    font-size: 13px;
}

.schalter-knopf + .schalter-knopf { border-left: 1px solid var(--border); }
.schalter-knopf:hover { background: var(--surface-2); color: var(--text); }

.schalter-knopf.ist-aktiv {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
    font-weight: 600;
}

.schalter-knopf.ist-aktiv:hover { background: var(--accent-hover); color: #fff; }

/*
 * Als Reiter einer Seite statt als kleiner Umschalter in einem Kartenkopf.
 *
 * Dort gehört er zu den Werkzeugen daneben und ist entsprechend klein; hier
 * gliedert er die ganze Seite und muss dieselbe Höhe und Schrift haben wie
 * jede andere Schaltfläche – sonst wirkt der wichtigste Griff der Seite wie
 * eine Nebensache.
 */
.schalter-reiter { margin-bottom: 18px; }

.schalter-reiter .schalter-knopf {
    height: var(--control);
    padding: 0 16px;
    font-size: 15px;
}

/*
 * Schmal löst sich die Reihe auf.
 *
 * Aneinandergesetzt braucht sie die volle Breite; drei Reiter mit Wörtern wie
 * „Betriebsfreie Tage" passen auf 320 Punkte nicht in eine Zeile. Getrennte
 * Schaltflächen mit Abstand brechen um, ohne dass eine Beschriftung abreisst.
 */
@media (max-width: 560px) {
    .schalter {
        display: flex;
        flex-wrap: wrap;
        gap: 6px;
        max-width: 100%;
        border: none;
        overflow: visible;
    }

    .schalter-knopf,
    .schalter-knopf + .schalter-knopf {
        border: 1px solid var(--border-strong);
        border-radius: var(--radius);
    }
}

/* Was rechts im Kartenkopf steht, gehört zusammen. */
.card-head-rechts { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

/* ---------- Urlaubstage ---------- */

/*
 * Ein Block ist ein zusammenhängender Urlaub, aufgeklappt stehen seine Tage
 * darunter. Die Zeile bleibt einzeilig, solange sie es kann: Datum, Anzahl,
 * Stand, und rechts, was sich damit tun lässt.
 */
.urlaub-abschnitt {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 16px 16px 4px;
    border-top: 1px solid var(--border);
}

.urlaub-abschnitt:first-of-type { border-top: none; }
.urlaub-abschnitt h3 { margin: 0; font-size: 13px; letter-spacing: .04em; text-transform: uppercase; color: var(--text-muted); }

.urlaub-block { padding: 4px 16px 10px; }

.urlaub-block-kopf {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.urlaub-block-titel { display: flex; align-items: baseline; gap: 10px; min-width: 0; flex: 1 1 auto; }
.urlaub-block-tage { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Die einzelnen Tage rücken ein und gehören sichtbar zur Zeile darüber. */
.urlaub-tage {
    margin: 6px 0 0 14px;
    padding-left: 12px;
    border-left: 2px solid var(--border);
}

.urlaub-tag {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px;
    padding: 5px 0;
}

/*
 * Ein vergangener Tag lässt sich berichtigen wie ein kommender – und seine
 * Schaltflächen sehen auch so aus. Sie blasser zu zeichnen war der erste
 * Gedanke, ist aber genau der Auftritt einer abgeschalteten Schaltfläche
 * (`button[disabled]`, 50 %): Der Tag sähe wieder gesperrt aus, obwohl er es
 * nicht ist. Dass es um eine Korrektur geht, sagen stattdessen die
 * Beschriftung und die Rückfrage.
 */

.urlaub-tag-datum { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.urlaub-tag-mass { font-variant-numeric: tabular-nums; white-space: nowrap; font-size: 13px; color: var(--text-muted); }
.urlaub-tag-notiz { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }

@media (max-width: 700px) {
    /*
     * Schmal steht die Notiz unter dem Tag, statt ihn zusammenzuquetschen.
     * Die Schaltflächen bleiben dabei in der ersten Zeile – ohne die feste
     * Zuweisung rutschten sie hinter die Notiz auf eine dritte.
     */
    .urlaub-tag { grid-template-columns: minmax(0, 1fr) auto auto; }
    .urlaub-tag .actions { grid-column: 3; grid-row: 1; }
    .urlaub-tag-notiz { grid-column: 1 / -1; grid-row: 2; white-space: normal; }
}

@media (max-width: 700px) {
    /* Name über die volle Breite, die Werte darunter – so bleibt der Rest
       sichtbar, statt aus dem Bild zu scrollen. */
    .konto-zeile { grid-template-columns: minmax(0, 1fr) auto; }

    /* Vier Werte zu zweit – wie die Kennzahlen an anderer Stelle. */
    .konto-werte {
        grid-column: 1 / -1;
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 12px 16px;
    }
}

@media (max-width: 640px) {
    .antrag-aktionen { width: 100%; }
    .antrag-aktionen .btn-sm { flex: 1 1 0; }
}

/* ---------- Wahl der Variante ---------- */

.gate {
    display: flex;
    justify-content: center;
    padding: 24px 0 48px;
}

.gate-card { max-width: 620px; width: 100%; }
.gate-card h1 { font-size: 22px; margin-bottom: 8px; }
.gate-aktion { margin-top: 18px; }

input:focus-visible, select:focus-visible, textarea:focus-visible, button:focus-visible, a:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

textarea { min-height: 70px; resize: vertical; }

.field { margin-bottom: 12px; }
.field-error { color: var(--danger); font-size: 12px; margin-top: 4px; }

/*
 * Hinweise stehen nicht mehr als Satz unter dem Feld, sondern hinter einem
 * Fragezeichen neben der Beschriftung. Sie sind da, wenn man sie sucht, und
 * weg, wenn man sie nicht braucht -- ein Formular soll aus Feldern bestehen
 * und nicht aus Erklaerungen.
 */
/* Der Bezugspunkt der Blase: Sie richtet sich am Feld aus und nicht am
   Fragezeichen -- so kann sie nie breiter werden als das Feld und nie ueber
   den rechten Rand der Seite hinausragen. `App.hinweis` gehoert deshalb
   immer in eine `.field-kopf`. */
.field-kopf { position: relative; display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }

/* Ein Feld, das nur wenige Zeichen aufnimmt, soll nicht so breit sein
   wie eines fuer einen ganzen Namen. */
.feld-kurz input { max-width: 160px; }
.field-kopf > label { margin-bottom: 0; }

.hinweis { display: inline-flex; }

/*
 * Die Schaltflaeche ist die Trefferflaeche, der Kreis darin das Zeichen. Am
 * Finger braucht die Flaeche ihre 44 Punkte; der Kreis bleibt klein, damit die
 * Zeile nicht auseinandergeht -- den Zuwachs holt der negative Rand zurueck.
 */
.hinweis-knopf {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    margin: -2px 0;
    padding: 0;
    border: none;
    background: none;
    color: var(--text-muted);
    cursor: pointer;
}

.hinweis-knopf > span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border: 1px solid var(--border-strong);
    border-radius: 50%;
    font-size: 12px;
    font-weight: 600;
    line-height: 1;
}

.hinweis-knopf:hover > span,
.hinweis-knopf:focus-visible > span {
    color: var(--accent);
    border-color: var(--accent);
}

/*
 * Verborgen ueber die Deckkraft und nicht ueber `display`: Was nicht angezeigt
 * wird, liest auch kein Vorleseprogramm vor -- und der Hinweis haengt per
 * `aria-describedby` am Feld.
 */
.hinweis-text {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 40;
    margin-top: 4px;
    width: max-content;
    max-width: min(280px, 100%);
    padding: 8px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    box-shadow: var(--shadow);
    color: var(--text);
    font-size: 13px;
    font-weight: 400;
    line-height: 1.45;
    white-space: normal;
    opacity: 0;
    pointer-events: none;
    transition: opacity .12s ease;
}

.hinweis:hover .hinweis-text,
.hinweis:focus-within .hinweis-text,
.hinweis.offen .hinweis-text { opacity: 1; pointer-events: auto; }

@media (pointer: coarse) {
    .hinweis-knopf { height: 44px; margin: -10px 0; }
}

/*
 * Ein erklaerender Satz unter einem Feld.
 *
 * Der Hinweis am `?` ist fuer das Beilaeufige da -- man klappt ihn auf, wenn
 * man stutzt. Was jeder lesen muss, bevor er klickt, darf nicht dahinter
 * liegen; das steht hier und ist zu sehen.
 */
.form-hint { margin-top: 6px; color: var(--muted); font-size: 12px; line-height: 1.5; }

/*
 * Die Schaltflaeche, hinter der es kein Zurueck gibt.
 *
 * Sie traegt die Warnfarbe nur im Rand und in der Schrift, nicht in der
 * Flaeche: Eine rote Flaeche zieht den Blick an und laedt zum Klicken ein --
 * das Gegenteil dessen, was sie soll.
 */
.btn-gefahr { color: var(--danger); border-color: var(--danger); }
.btn-gefahr:hover { background: var(--danger-soft); }

/*
 * Der Kasten, der sagt, dass es kein Zurueck gibt.
 *
 * Sieht aus wie `.form-errors` und ist doch etwas anderes: Der raeumt sich
 * weg, sobald der Server etwas beanstandet -- diesen soll auch der zweite
 * Versuch noch lesen.
 */
.warnkasten {
    margin-bottom: 14px;
    padding: 10px 12px;
    border: 1px solid var(--danger);
    border-radius: 6px;
    color: var(--danger);
    font-size: 13px;
    line-height: 1.5;
}

/* Der eigene Datenauszug und das Loeschen, unten im Zugang. */
.meine-daten > .btn { display: inline-flex; }
.meine-daten-loeschen:not(:empty) { margin-top: 14px; }

/* Beanstandungen, die zu keinem einzelnen Feld gehoeren. */
.form-errors {
    margin-bottom: 14px;
    padding: 10px 12px;
    border: 1px solid var(--danger);
    border-radius: 6px;
    color: var(--danger);
    font-size: 13px;
}

.form-errors:focus-visible { outline: 2px solid var(--danger); outline-offset: 2px; }

/* Ein beanstandeter Bereich wird als Ganzes hervorgehoben. */
.field.invalid > .zeit-zeilen { box-shadow: 0 0 0 1px var(--danger); border-radius: 6px; }
input.invalid, select.invalid { border-color: var(--danger); }

.row { display: flex; gap: 12px; flex-wrap: wrap; }
.row > * { flex: 1; min-width: 140px; }

/* Feldpaare, die auch schmal nebeneinander bleiben: zwei- und dreistellige
   Eingaben, bei denen die volle Breite nur Leere wäre. */
.row-eng > * { min-width: 0; }

/* Button-Gruppen sollen ihre natürliche Breite behalten. */
.btn-group, .actions {
    display: flex;
    gap: 4px;
    flex-wrap: nowrap;
    align-items: center;
}

/*
 * Im Seitenkopf stehen Aktionen mit ausgeschriebenen Beschriftungen. Sie
 * müssen umbrechen dürfen – "nowrap" ist für die kompakte Datumsnavigation
 * gedacht, nicht für eine Reihe wie "Nachtragen · Abwesenheit · Nachweis als
 * CSV", die sonst über den Bildschirmrand hinausläuft.
 */
.page-head .btn-group { flex-wrap: wrap; gap: 8px; }

.actions { justify-content: flex-end; }

/*
 * In einer Zeilenleiste steht auf einer Schaltflaeche fast immer nur ein
 * Zeichen. Sie soll dann quadratisch sein und nicht breit: Fuenf breite
 * Rechtecke nebeneinander nehmen ein Viertel der Tabelle, und was rechts
 * steht, ist nicht die Hauptsache.
 */
.actions .btn-sm { padding: 5px 6px; min-width: var(--control-sm); }
.btn-group > *, .actions > * { flex: 0 0 auto; min-width: 0; }

/* Auswahlfelder in Schaltflächenleisten behalten ihre Inhaltsbreite,
   statt die 100-Prozent-Regel der Formularfelder zu erben. */
/* Im Kopf einer Karte steht ein Auswahlfeld neben der Überschrift, nicht
   über die ganze Breite darunter. */
.btn-group select, .actions select, .card-head select { width: auto; }

.checkbox { display: flex; align-items: center; gap: 8px; }
.checkbox input { width: auto; }
.checkbox label { margin: 0; color: var(--text); }

button, .btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px 14px;
    border-radius: 6px;
    border: 1px solid var(--border-strong);
    background: var(--surface);
    cursor: pointer;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
}

button:hover, .btn:hover { background: var(--surface-2); }

/*
 * Auf Zeigergeräten dürfen Schaltflächen kompakt sein. Wo mit dem Finger
 * bedient wird, brauchen sie eine Fläche von mindestens 44 Punkten – sonst
 * trifft man sie nicht zuverlässig.
 */
@media (pointer: coarse) {
    button, .btn, select, .nav a,
    input[type=text], input[type=email], input[type=password],
    input[type=date], input[type=number], .timeinput {
        min-height: 44px;
    }

    .btn-sm, .btn-icon, .actions select { min-height: 44px; }


    .btn-sm, .btn-icon {
        min-width: 44px;
        padding-left: 12px;
        padding-right: 12px;
    }

    /*
     * Auch in einer Zeilenleiste.
     *
     * Dort steht die Regel, die aus einer Schaltflaeche ein Quadrat von 32
     * Pixeln macht -- und sie ist genauer als die Zeile darueber, also gaelte
     * sie auch am Finger. Zweiunddreissig Pixel trifft ein Daumen nicht
     * zuverlaessig; hier gewinnt die Hand.
     */
    .actions .btn-sm {
        min-width: 44px;
        padding-left: 12px;
        padding-right: 12px;
    }

    .actions { gap: 6px; }

    /* Kontrollkästchen samt Beschriftung als ein Ziel */
    .checkbox { min-height: 44px; }
    .checkbox input { width: 24px; height: 24px; flex: 0 0 auto; }
    .checkbox label { padding: 10px 0; }
}

.btn-primary {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

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

.btn-running { background: var(--running); border-color: var(--running); color: #fff; }
.btn-running:hover { filter: brightness(1.07); background: var(--running); }

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

.btn-icon { height: var(--control-sm); padding: 6px 8px; line-height: 1; }
.btn-sm { height: var(--control-sm); padding: 5px 10px; font-size: 13px; }

/*
 * Ein Knopf, in dem nur ein Zeichen steht, ist ein Bild und keine Schrift.
 *
 * Die 13 Pixel der kleinen Schaltflaeche sind fuer ein Wort gedacht. Am
 * Finger wird die Schaltflaeche auf 44 Pixel gedehnt -- das Zeichen darin
 * blieb bei 13 und stand als Punkt in einem Kasten, den man dreimal so gross
 * sieht. Wer das Schloss vom Papierkorb unterscheiden will, muss naeher
 * herangehen, als ein Knopf verlangen darf.
 *
 * Getroffen wird nur der Knopf, in dem nichts als das Zeichen steht: Wo eine
 * Beschriftung danebensteht ("⇄ Umhaengen"), gehoert das Zeichen zur Schrift
 * und richtet sich nach ihr.
 */
.btn-sm > span[aria-hidden="true"]:only-child,
.btn-icon > span[aria-hidden="true"]:only-child {
    font-size: 18px;
    line-height: 1;
}

/*
 * Am Finger ist die Schaltflaeche 44 Pixel hoch -- dann darf das Zeichen
 * darin auch groesser sein. Die Regel steht hier und nicht oben bei den
 * uebrigen Fingergroessen: Dort stuende sie vor der Zeile darueber und wuerde
 * von ihr wieder aufgehoben.
 */
@media (pointer: coarse) {
    .btn-sm > span[aria-hidden="true"]:only-child,
    .btn-icon > span[aria-hidden="true"]:only-child { font-size: 21px; }
}

/* Ein Auswahlfeld in einer Schaltflächenleiste ist eine Schaltfläche mehr –
   es soll so hoch sein wie seine Nachbarn, nicht wie ein Formularfeld. */
.actions select, .btn-group .btn-sm ~ select { height: var(--control-sm); }
.btn-link { border: none; background: none; color: var(--accent); padding: 4px; }
.btn-link:hover { background: none; text-decoration: underline; }

button[disabled] { opacity: .5; cursor: not-allowed; }

/*
 * Ein Verweis, der noch nicht zeigt, wohin.
 *
 * Eine Schaltflaeche kann `disabled` sein, ein `a` nicht -- und eines ohne
 * `href` sieht aus wie ein Knopf, der nichts tut, statt wie einer, der noch
 * nicht kann. Sobald die Daten da sind und mit ihnen der Zeitraum, bekommt er
 * seine Adresse und die Klasse faellt weg.
 */
.btn.ist-aus {
    opacity: .5;
    cursor: not-allowed;
    pointer-events: none;
}

/* ---------- Tabellen ---------- */

table { width: 100%; border-collapse: collapse; }

/*
 * Spaltenüberschriften. Ausdrücklich nur diese: Ein th mit scope="row" ist
 * ein Name oder ein Datum in der Zeile selbst und soll aussehen wie Inhalt,
 * nicht wie eine Überschrift. Die frühere Regel galt für jedes th und hat
 * zweimal Mitarbeiternamen in Großbuchstaben gesetzt.
 */
th {
    text-align: left;
    padding: 10px 12px;
    border-bottom: 1px solid var(--border);
    color: var(--text);
    font-weight: 600;
    white-space: nowrap;
}

/* Die Auszeichnung der Spaltenüberschrift gehört an den Kopf, nicht an jedes th. */
thead th {
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-muted);
}

td { padding: 10px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--surface-2); }

.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.duration { font-variant-numeric: tabular-nums; font-weight: 600; }

.table-wrap { overflow-x: auto; }

/* Bei langen Listen zeichnet der Browser nur, was im Blickfeld liegt. */
.table-wrap tbody tr { content-visibility: auto; contain-intrinsic-size: auto 44px; }

tr.is-running td { background: var(--running-soft); }
tr.is-locked .duration::after { content: " 🔒"; font-size: 11px; }

/* ---------- Kleinteile ---------- */

.tag {
    display: inline-block;
    padding: 1px 7px;
    border-radius: 999px;
    font-size: 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text-muted);
}

/* Der Status eines Antrags. Muss nach .tag stehen, sonst gewinnt dessen
   Hintergrund – gleiche Spezifität, spätere Regel. */
.tag-requested { background: var(--warning); border-color: var(--warning); color: #fff; }
.tag-approved { background: var(--running-soft); border-color: var(--running-soft); color: var(--running); }
.tag-rejected { background: var(--danger-soft); border-color: var(--danger-soft); color: var(--danger); }

.tag-archived { background: var(--danger-soft); color: var(--danger); border-color: transparent; }
.tag-nonbillable { background: var(--surface-2); }

.entry-note { color: var(--text); }
.entry-meta { color: var(--text-muted); font-size: 13px; }

.day-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 12px 16px;
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    font-weight: 600;
}

.empty { padding: 40px 20px; text-align: center; color: var(--text-muted); }

/*
 * Als Raster, nicht als Reihe: Bei sieben Filtern in sechs Spalten rutscht
 * der letzte in eine zweite Zeile. Im Raster steht er dort unter dem ersten
 * und sieht gewollt aus statt vergessen.
 */
.filters {
    display: grid;
    /* auto-fill, nicht auto-fit: Zwei Auswahlfelder sollen zwei Spalten breit
       sein und nicht die ganze Zeile unter sich aufteilen. */
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 10px 12px;
    align-items: end;
}

.filters > div { min-width: 0; }

/*
 * Der zusammenklappbare Filterblock. Breit ist er immer offen und die
 * Zusammenfassung verschwindet – dort gibt es nichts zu klappen.
 */
.filterblock > summary {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 10px 2px;
    cursor: pointer;
    font-weight: 600;
    list-style: none;
}

.filterblock > summary::-webkit-details-marker { display: none; }

/* Ein Pfeil, der sich mitdreht – ohne ihn sähe die Zeile aus wie eine
   Überschrift und nicht wie etwas zum Antippen. */
.filterblock > summary::before {
    content: "⌄";
    display: inline-block;
    width: 14px;
    color: var(--text-muted);
    transition: transform .15s ease;
}

.filterblock[open] > summary::before { transform: rotate(180deg); }

.filterblock-stand { color: var(--text-muted); font-size: 13px; font-weight: 400; }

@media (min-width: 641px) {
    .filterblock > summary { display: none; }
}

.summary {
    display: flex;
    gap: 28px;
    flex-wrap: wrap;
    padding: 14px 16px;
    background: var(--surface-2);
    border-top: 1px solid var(--border);
}

.summary div span { display: block; }
.summary .summary-label { font-size: 12px; color: var(--text-muted); text-transform: uppercase; letter-spacing: .04em; }
.summary .summary-value { font-size: 20px; font-weight: 650; font-variant-numeric: tabular-nums; }

.bar {
    height: 6px;
    background: var(--border);
    border-radius: 3px;
    overflow: hidden;
    min-width: 60px;
}

.bar > div { height: 100%; background: var(--accent); }
.bar.over > div { background: var(--danger); }

/* ---------- Dialog ---------- */

.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(15, 20, 28, .45);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 40px 16px;
    z-index: 50;
    overflow-y: auto;
    /* Am Ende des Dialogs nicht die Seite darunter mitscrollen. */
    overscroll-behavior: contain;
}

.modal {
    background: var(--surface);
    border-radius: 10px;
    overscroll-behavior: contain;
    box-shadow: 0 12px 40px rgba(0, 0, 0, .25);
    width: 100%;
    max-width: 540px;
}

.modal header {
    padding: 16px;
    border-bottom: 1px solid var(--border);
    font-weight: 600;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.modal .modal-body { padding: 16px; }

.modal footer {
    padding: 12px 16px;
    border-top: 1px solid var(--border);
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

/* ---------- Meldungen ---------- */

.toast-area {
    position: fixed;
    bottom: calc(20px + env(safe-area-inset-bottom));
    left: 50%;
    transform: translateX(-50%);
    z-index: 100;
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-width: calc(100vw - 32px);
}

.toast {
    background: var(--text);
    color: var(--bg);
    padding: 10px 16px;
    border-radius: 6px;
    box-shadow: var(--shadow);
    font-size: 14px;
}

.toast.error { background: var(--danger); color: #fff; }

/* ---------- Anmeldung ---------- */

/*
 * Kein `min-height: 100vh` mehr: Die Anmeldemaske ist ein Teil der Spalte und
 * nicht das ganze Fenster. Sonst schoebe sie die Fusszeile unter den Rand --
 * und die Datenschutzerklaerung gehoert vor die Anmeldung, nicht darunter.
 */
.login-wrap { flex: 1 0 auto; display: flex; align-items: center; justify-content: center; padding: 20px; }
.login-card { width: 100%; max-width: 380px; }
.login-card.is-wide { max-width: 560px; }
.login-card h1 { margin-bottom: 4px; }

/* ---------- Schnellerfassung ---------- */

.quick-form { display: grid; grid-template-columns: 2fr 1.4fr 3fr 110px auto; gap: 12px; align-items: end; }
.quick-form > * { min-width: 0; }

/* Zwei Schaltflächen nebeneinander, nicht aneinandergeklebt. */
.quick-actions { display: flex; gap: 8px; }

@media (max-width: 900px) {
    .quick-form { grid-template-columns: 1fr 1fr; }
    .quick-form .quick-note { grid-column: 1 / -1; }
    .quick-form .quick-actions { grid-column: 1 / -1; display: flex; gap: 8px; }
    .quick-form .quick-actions button { flex: 1; }
}

@media (max-width: 640px) {
    .topbar-inner { padding: 8px 14px; gap: 8px; min-height: 46px; flex-wrap: nowrap; }
    .brand { flex: 1; min-width: 0; }
    .brand span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

    /*
     * Auf dem Smartphone steht die Navigation unten: dort ist sie mit dem
     * Daumen erreichbar, während der Inhalt oben Platz behält.
     */
    .nav {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 30;
        background: var(--surface);
        border-top: 1px solid var(--border);
        gap: 0;
        justify-content: space-around;
        padding: 4px max(4px, env(safe-area-inset-right)) calc(4px + env(safe-area-inset-bottom)) max(4px, env(safe-area-inset-left));
        box-shadow: 0 -1px 3px rgba(20, 30, 45, .06);
    }

    .nav a, .nav-more-toggle, .nav-gruppe-toggle {
        flex: 1;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 2px;
        padding: 6px 2px;
        font-size: 11px;
        line-height: 1.2;
        text-align: center;
        min-height: 52px;
    }

    .nav-icon { display: block; width: 22px; height: 22px; flex: none; }
    .nav-gruppe-toggle::after { display: none; }
    .nav-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
    .nav a.active { background: none; color: var(--accent); }

    .nav-more-wrap { flex: 1; display: flex; }
    .nav-gruppe-wrap { flex: 1; display: flex; }

    /* Das Menü legt sich über die Leiste, nicht darunter. */
    .nav-more {
        position: fixed;
        left: 8px;
        right: 8px;
        bottom: calc(64px + env(safe-area-inset-bottom));
        top: auto;
        min-width: 0;
        max-height: 60vh;
        overflow-y: auto;
        overscroll-behavior: contain;
    }

    /* Im Menü stehen die Einträge untereinander und linksbündig – die
       Ausrichtung der Tab-Leiste passt dort nicht. */
    .nav-more a, .nav-gruppe-feld a {
        flex-direction: row;
        align-items: center;
        justify-content: flex-start;
        gap: 12px;
        text-align: left;
        min-height: 48px;
        padding: 12px 14px;
        font-size: 15px;
    }

    .nav-more a .nav-label { max-width: none; }

    /* Das Feld der Gruppe legt sich wie das Menü über die Leiste. */
    .nav-gruppe-feld {
        position: fixed;
        left: 8px;
        right: 8px;
        bottom: calc(64px + env(safe-area-inset-bottom));
        top: auto;
        min-width: 0;
        max-height: 60vh;
        overflow-y: auto;
        overscroll-behavior: contain;
    }

    /* Der Eintrag trägt kein Symbol – sein Text beginnt trotzdem dort, wo die
       Beschriftungen der anderen beginnen. */
    .nav-more .menue-eintrag { min-height: 48px; padding: 12px 14px 12px 48px; font-size: 15px; }

    /*
     * Platz fuer die untere Leiste.
     *
     * In einer Regel, nicht in zweien: Die zweite setzte den Innenabstand als
     * Kurzschreibweise neu und nahm den Platz unten wieder weg -- die letzte
     * Zeile einer Tabelle lag danach hinter der Leiste.
     */
    /*
     * Der Abstand zur Leiste am unteren Rand steht jetzt an der Fusszeile:
     * Sie ist das Letzte auf der Seite, nicht mehr der Inhalt. Zwei Polster
     * uebereinander waeren eine leere Bildschirmhoehe zum Scrollen.
     */
    main { padding: 16px 14px 16px; }
    .toast-area { bottom: calc(76px + env(safe-area-inset-bottom)); }
    th, td { padding: 8px 6px; }
    .hide-sm { display: none; }

    /*
     * Zeiteinträge auf dem Telefon.
     *
     * Als Tabelle blieb für die Notiz eine Spalte von gut der halben Breite –
     * vier Schaltflächen und die Dauer nehmen den Rest. Ein Satz wie
     * "Email senden funktioniert nicht. Teamviewer Session ..." stand dann in
     * acht Zeilen zu zwei Wörtern.
     *
     * Deshalb wird die Zeile hier zu einem Block: oben die Zeit und die
     * Schaltflächen, darunter die Notiz über die ganze Breite.
     */
    .zeit-liste tr {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 6px 12px;
        padding: 12px;
        border-bottom: 1px solid var(--border);
    }

    .zeit-liste tbody tr:last-child { border-bottom: none; }

    .zeit-liste td:not(.hide-sm) {
        display: block;
        padding: 0;
        border: none;
    }

    /* Die Dauer zuerst – sie ist die Zahl, nach der man sucht. */
    .zeit-liste td.duration { order: 1; flex: 0 0 auto; font-size: 16px; }

    /* Die Schaltflächen daneben, rechtsbündig. */
    .zeit-liste td.num:last-child { order: 2; flex: 1 1 auto; }
    .zeit-liste td.num:last-child .actions { justify-content: flex-end; }

    /* Und darunter die Notiz, über die volle Breite. */
    .zeit-liste td:first-child { order: 3; flex: 1 1 100%; }

    .zeit-liste .entry-note { line-height: 1.4; }
    .zeit-liste .entry-meta { margin-top: 2px; }

    /* Filter untereinander, jeder über die volle Breite – unterschiedlich
       breite Auswahlfelder wirken sonst unruhig. */
    .filters { grid-template-columns: 1fr; gap: 12px; }
    .filters .field { margin-bottom: 0; }

    /*
     * Kennzahlen zu zweit nebeneinander. Als Reihe mit Umbruch blieb bei vier
     * Werten der letzte allein in einer zweiten Zeile stehen – das sah nach
     * Versehen aus, nicht nach Aufteilung.
     */
    .summary, .kennzahlen {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 14px 16px;
    }

    /* Ein einzelner Wert nimmt beide Spalten – halbe Breite zwänge seine
       Beschriftung in einen Umbruch, obwohl daneben nichts steht. */
    .summary > :only-child, .kennzahlen > :only-child { grid-column: 1 / -1; }

    /* Datum unter den Text, immer – sonst steht es mal rechts daneben und
       mal darunter, je nachdem wie lang der Text gerade ist. */
    .kommt-zeile { flex-direction: column; align-items: flex-start; gap: 2px; }

    /*
     * Feldpaare untereinander. Nebeneinander blieben bei 390 Pixeln knapp
     * 160 pro Feld – für "Aktuelles Passwort" oder einen Hinweissatz
     * darunter zu wenig.
     */
    .row > * { min-width: 100%; }
    .row-eng > * { min-width: 0; }

    /* Untereinander gibt es keine Beschriftung mehr, neben der auszurichten wäre. */
    .ohne-label { padding-top: 0; }

    /*
     * Schaltflächen dürfen schmal umbrechen. Nebeneinander behalten sie ihre
     * Beschriftung und schieben die Seite über den Rand – und eine Seite, die
     * breiter ist als das Gerät, sieht aus, als wäre sie hineingezoomt.
     */
    .btn-group { flex-wrap: wrap; }

    /*
     * Eingabefelder mindestens 16 Pixel: Darunter zoomt iOS beim Antippen
     * hinein und danach nicht wieder heraus. Die App bliebe vergrößert
     * zurück, ohne dass jemand sie vergrößert hätte.
     */
    input, select, textarea { font-size: 16px; }

    /*
     * Eine Stammdatenliste ist am Telefon keine Tabelle mehr.
     *
     * Vier Spalten und eine Knopfleiste brauchen mehr als dreihundertsechzig
     * Pixel -- die Tabelle lief ueber, und die Knoepfe standen rechts
     * ausserhalb des Bildes. Man kam an sie heran, indem man die Tabelle
     * seitwaerts schob: Das findet niemand, der es nicht weiss.
     *
     * Statt zu schrumpfen, bricht die Zeile um. Oben der Name, darunter die
     * Werte mit ihrer Beschriftung -- die Spaltenueberschrift kommt an jede
     * Zelle, weil es ueber ihnen keine Zeile mehr gibt --, unten rechts die
     * Knoepfe. Nichts faellt weg, nichts steht draussen.
     *
     * Nur fuer Listen, ausdruecklich: Eine Kreuztabelle mit dreissig Tagen
     * laesst sich nicht umbrechen, die rollt weiter.
     */
    table.liste,
    table.liste tbody,
    table.liste tr,
    table.liste td { display: block; }

    table.liste thead { display: none; }

    /*
     * Die Zeile ist ein Block mit drei Reihen: der Name ueber die ganze
     * Breite, darunter die Werte -- und die Knoepfe rechts daneben, nicht
     * darunter. Deshalb Flex und nicht einfach untereinander: Sonst bleibt
     * neben den Werten eine Zeile leer.
     */
    table.liste tbody > tr:not(.detail-zeile) {
        display: flex;
        flex-wrap: wrap;
        align-items: flex-end;
        padding: 10px 12px;
        border-bottom: 1px solid var(--border);
    }

    table.liste tbody > tr:not(.detail-zeile):last-child { border-bottom: none; }

    table.liste td {
        padding: 0;
        border: none;
        text-align: left;
    }

    /* Der Name traegt die Zeile und steht allein in der ersten Reihe. */
    table.liste td:first-child { flex: 1 0 100%; font-size: 15px; }

    /* Die Werte nebeneinander, jeder mit seiner Beschriftung darueber -- die
       Spaltenueberschrift kommt an die Zelle, weil es ueber ihr keine Zeile
       mehr gibt. */
    table.liste td[data-spalte] { flex: 0 0 auto; margin: 8px 18px 0 0; }

    table.liste td[data-spalte]::before {
        content: attr(data-spalte);
        display: block;
        margin-bottom: 1px;
        font-size: 11px;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .04em;
        color: var(--text-muted);
    }

    /* Was auf dem Schreibtisch schon wegblieb, bleibt auch hier weg -- die
       Regel dafuer ist weniger genau als die Zeile darueber und verloere. */
    table.liste td.hide-sm { display: none; }

    /* Die Knoepfe an den rechten Rand, auf der Hoehe der Werte. */
    table.liste td:last-child { margin: 8px 0 0 auto; }
    table.liste td:last-child:empty { display: none; }

    /* Die aufgeklappte Zeile haengt am Block darueber und bringt ihren
       eigenen Rahmen mit. */
    table.liste tr.detail-zeile > td { padding: 0; }

    /* Auf dem Smartphone zählen Notiz und Dauer – Aktionen rücken zusammen. */
    .actions { gap: 2px; }
    .actions .btn-sm { padding: 5px 6px; }
    .day-head { padding: 10px 12px; }
    .page-head { align-items: stretch; }

    /*
     * Im Kopf einer Seite stehen nicht nur Schaltflächen, sondern auch
     * Auswahlfelder. Schmal bekommt jede Gruppe ihre eigene Zeile – sonst
     * behält sie ihre Inhaltsbreite und schiebt die Seite über den Rand.
     */
    .page-head .kopf-felder > * { flex: 1 1 100%; }

    /*
     * Drei Schaltflaechen im Seitenkopf als Raster statt als Reihe.
     *
     * Umgebrochen behaelt jede ihre Inhaltsbreite: Zwei stehen nebeneinander,
     * die dritte halb so breit darunter, und die Zeile sieht aus, als waere
     * etwas verrutscht. Im Raster sind sie gleich breit -- und eine ungerade
     * letzte nimmt die ganze Zeile.
     *
     * Ausdruecklich angefordert und nicht fuer jeden Kopf: Wo neben den
     * Schaltflaechen ein Auswahlfeld steht, ist die Reihe die bessere Form.
     */
    .btn-raster {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
        /* Eine eigene Zeile, wie jede Gruppe im Seitenkopf -- `width: 100%`
           waere die Breite des ganzen Kopfes und ragte neben der Ueberschrift
           hinaus. */
        flex: 1 1 100%;
        min-width: 0;
    }

    .btn-raster > * { min-width: 0; }
    .btn-raster > :last-child:nth-child(odd) { grid-column: 1 / -1; }
    .export-zeile select { flex: 1 1 140px; min-width: 0; }
    .export-zeile .btn { flex: 1 1 auto; justify-content: center; }
    .tracker-pill .tracker-label { display: none; }
    .tracker-pill { padding-left: 10px; }
    /* Schmal ist in der Kopfzeile kein Platz für den Namen – abgeschnitten
       verdrängte er den Firmennamen. Zum eigenen Zugang führt dort der
       Eintrag „Mein Zugang" im Menü. */
    .user-chip { display: none; }
    /*
     * Schmal steht jedes Feld für sich. Zu zweit blieben knapp 160 Pixel je
     * Auswahlfeld – "Muster GmbH – Website" bricht darin mitten im Namen ab,
     * und gerade das Projekt muss man lesen können, bevor man erfasst.
     */
    .quick-form { grid-template-columns: 1fr; gap: 8px; }
}

/* ---------- Anwesenheit ---------- */

.punch {
    display: flex;
    align-items: flex-end;
    gap: 20px;
    flex-wrap: wrap;
}

.punch-state { flex: 1; min-width: 180px; }
.punch-kosten { min-width: 220px; flex: 1; }
.punch-kosten .field { margin: 0; }

.punch-clock {
    font-size: 34px;
    font-weight: 650;
    font-variant-numeric: tabular-nums;
    letter-spacing: -.02em;
    line-height: 1.1;
    color: var(--running);
}

.punch-clock.is-break { color: var(--warning); }
.punch-clock.muted { color: var(--text-muted); }

.btn-punch { padding: 11px 20px; font-size: 15px; }

/* Beanstandungen nach Arbeitszeitgesetz */
.findings { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }

.findings li {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 8px 10px;
    border-radius: 6px;
    font-size: 14px;
    line-height: 1.45;
}

.finding-label {
    flex: 0 0 auto;
    font-weight: 650;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .04em;
    padding-top: 2px;
}

.finding-violation { background: var(--danger-soft); color: var(--danger); }
.finding-warning   { background: color-mix(in srgb, var(--warning) 14%, transparent); color: var(--warning); }
.finding-notice    { background: var(--surface-2); color: var(--text-muted); }

.card.has-violation { border-left: 3px solid var(--danger); }
.card.has-notice    { border-left: 3px solid var(--warning); }

.text-violation { color: var(--danger); }

.break-row input { flex: 1; min-width: 90px; }

@media (max-width: 640px) {
    .punch { gap: 14px; }
    .punch-clock { font-size: 28px; }
    .btn-punch { flex: 1; }
}

.tag-attendance {
    background: var(--accent-soft);
    color: var(--accent);
    border-color: transparent;
}

/* ---------- Abwesenheitstage ---------- */

.tag.absence-vacation { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.tag.absence-sick     { background: var(--danger-soft); color: var(--danger); border-color: transparent; }
.tag.absence-timeoff  { background: color-mix(in srgb, var(--warning) 14%, transparent); color: var(--warning); border-color: transparent; }

/* ---------- Anwesenheit: Kacheln und Tagesliste ---------- */

/*
 * Die Seite folgt dem Aufbau eines Dashboards: oben die Kennzahlen des
 * Zeitraums, darunter ein Tag je Zeile. Die Einzelbuchungen stehen
 * eingeklappt darunter – sie werden selten gebraucht, machten die Liste aber
 * als Karten je Tag unübersichtlich.
 */

.tagfilter { margin-bottom: 16px; }

.kacheln {
    display: grid;
    /* 160 statt 190: Sonst steht auf dem Telefon jede Kachel allein in ihrer
       Zeile, und vier fast leere Kästen füllen den halben Bildschirm. */
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 14px;
    margin-bottom: 18px;
}

.kachel {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

/* Die wichtigste Kachel bekommt zwei Spalten, solange das Raster sie hergibt. */
.kachel-weit { grid-column: span 2; }

.kachel-label {
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.kachel-wert {
    font-size: 28px;
    font-weight: 650;
    line-height: 1.15;
    font-variant-numeric: tabular-nums;
}

.kachel-von { font-size: 17px; font-weight: 500; color: var(--text-muted); }
.kachel-zusatz { font-size: 12px; color: var(--text-muted); }
.kachel-warnung .kachel-wert { color: var(--danger); }
.kachel .bar { margin: 4px 0 2px; }

.tagliste { padding: 0; overflow: hidden; }

.tagliste-kopf,
.tagzeile {
    display: grid;
    /* Tag, Von-bis, Erfasst, Saldo, Status, Schalter. */
    grid-template-columns:
        minmax(140px, 1.6fr) 108px minmax(140px, 1.1fr) 88px minmax(104px, 1fr) 78px;
    gap: 12px;
    align-items: center;
    padding: 10px 16px;
}

.tagliste-kopf {
    background: var(--surface-2);
    border-bottom: 1px solid var(--border);
    font-size: 12px;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: .04em;
}

.tagblock { border-bottom: 1px solid var(--border); border-left: 3px solid transparent; }
.tagblock:last-child { border-bottom: 0; }

.tagblock.is-weekend .tagzeile { background: var(--surface-2); }
.tagblock.is-weekend .tz-tag { color: var(--text-muted); }
.tagblock.is-today { border-left-color: var(--accent); }
.tagblock.is-today .tz-tag { font-weight: 650; }
.tagblock.has-violation { border-left-color: var(--danger); }
.tagblock.has-notice { border-left-color: var(--warning); }

.tz-datum { display: flex; flex-direction: column; gap: 1px; min-width: 0; align-items: flex-start; }
.tz-tag { font-weight: 600; }

/*
 * Der Tag in der Liste fuehrt zu diesem Tag.
 *
 * Er sieht aus wie die Beschriftung daneben und nicht wie eine Schaltflaeche:
 * In einer Liste aus dreissig Zeilen waeren dreissig Knoepfe ein Zaun. Dass er
 * einer ist, zeigt sich beim Darauffahren -- und der Tastatur sagt es das
 * Element selbst.
 */
.tz-tagknopf {
    height: auto;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    text-align: left;
    justify-content: flex-start;
    border-radius: 4px;
}

.tz-tagknopf:hover { background: none; color: var(--accent); text-decoration: underline; }
.tz-person { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tz-spanne { font-variant-numeric: tabular-nums; font-size: 14px; }
.tz-ist { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.tz-wert { white-space: nowrap; }
.tz-saldo { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Die Zahl steht rechts in ihrer Spalte -- die Ueberschrift darueber auch. */
.tagliste-kopf > span:nth-child(4) { text-align: right; }
.tz-status { display: flex; flex-wrap: wrap; gap: 4px; }
.tz-mehr { display: flex; justify-content: flex-end; gap: 4px; }

/* Der Pfeil dreht sich mit dem Zustand – ohne Umbau des Knopfes. */
.tagdetail-schalter span { display: inline-block; transition: transform .15s ease; }
.tagdetail-schalter[aria-expanded="true"] span { transform: rotate(180deg); }

/* Der eingerueckte Rand zeigt, dass die Buchungen zum Tag darueber gehoeren. */
.tagdetail {
    background: var(--surface-2);
    border-top: 1px solid var(--border);
    padding-left: 14px;
}
.tagdetail table { font-size: 14px; }
.tagdetail .findings { margin: 0; }

.tag-laeuft { background: var(--running-soft); color: var(--running); border-color: transparent; }
.tag-erfasst { background: var(--running-soft); color: var(--running); border-color: transparent; }
.tag-verstoss { background: var(--danger-soft); color: var(--danger); border-color: transparent; }
.tag-hinweis { background: color-mix(in srgb, var(--warning) 14%, transparent); color: var(--warning); border-color: transparent; }

/*
 * In MyTime Solo trägt ein erfasster Tag die Variantenfarbe – wie im
 * Kalender. Dort ist Grün die einzige fremde Farbe in einer ockerfarbenen
 * Oberfläche.
 */
:root[data-variante="solo"] .tag-erfasst {
    background: var(--accent-soft);
    color: var(--accent);
}

@media (max-width: 720px) {
    .kachel-weit { grid-column: span 1; }
    .kachel-wert { font-size: 24px; }
}

/*
 * Sechs Spalten brauchen Platz.
 *
 * Die Grenze liegt hoeher als bei den Kacheln: Mit dem Saldo steht in der
 * Zeile eine Spalte mehr, und darunter draengten sich Datum, Spanne, zwei
 * Zahlen, der Status und zwei Schaltflaechen auf eine Zeile.
 */
@media (max-width: 820px) {
    .tagliste-kopf { display: none; }

    /* Schmal wird aus der Zeile ein kleiner Block – die Von-bis-Zeit bleibt,
       sie ist der Nachweis. */
    .tagzeile {
        grid-template-columns: 1fr auto;
        grid-template-areas:
            "datum  mehr"
            "spanne status"
            "ist    saldo";
        gap: 4px 12px;
        padding: 12px 14px;
    }

    .tz-datum { grid-area: datum; }
    .tz-spanne { grid-area: spanne; }
    .tz-ist { grid-area: ist; }
    .tz-saldo { grid-area: saldo; align-self: end; }
    .tz-status { grid-area: status; justify-content: flex-end; align-items: center; }
    .tz-mehr { grid-area: mehr; align-items: flex-start; }
}

/* ---------- Postausgang einrichten ---------- */

/*
 * Das Formular im Betriebsbereich. Die vier allgemeinen Felder stehen als
 * Raster nebeneinander, der SMTP-Teil darunter -- er faellt weg, wenn gar
 * nicht ueber einen Mailserver verschickt wird.
 */
.postfach-form .filters { margin-bottom: 6px; }

.postfach-smtp {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 10px 12px;
    align-items: end;
    padding-top: 10px;
    margin-top: 4px;
    border-top: 1px solid var(--border);
}

.postfach-smtp[hidden] { display: none; }
.postfach-smtp .checkbox { grid-column: 1 / -1; }

.postfach-schluessel { margin-top: 14px; }

/* Die Zeile zum Abschreiben: Sie soll sich in einem Stueck markieren lassen. */
.schluessel-zeile {
    display: block;
    margin-top: 6px;
    padding: 8px 10px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: 6px;
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 13px;
    word-break: break-all;
    user-select: all;
}

/* ---------- Berichte auf einen Blick ---------- */

/*
 * Zwei Kreuztabellen statt eines Baumes.
 *
 * Zeilen sind die Sache, Spalten die Zeit. Beide Tafeln koennen breiter
 * werden als das Fenster -- zwoelf Monate, acht Kostentraeger --, deshalb
 * rollen sie in sich und nicht die ganze Seite.
 */
/* Der Reiter der Seite steht dichter an den Tafeln als sonst -- dazwischen
   liegt noch der Zeitraumschalter. */
.berichts-reiter { margin-bottom: 12px; }

.tafel-schalter {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 10px;
    margin-bottom: 16px;
}

.tafel-zeitraum { min-width: 10em; }

/*
 * Kein Abstand nach unten in der Reihe.
 *
 * Als Reiter einer Seite traegt `.schalter-reiter` 18 Pixel unter sich. Hier
 * steht er aber neben dem Blaetterfeld, und in einer Reihe, die ihre Teile
 * mittig ausrichtet, hebt dieser Abstand ihn um neun Pixel an: Er stand
 * sichtbar hoeher als seine Nachbarn.
 */
.tafel-schalter > .schalter { margin-bottom: 0; }

/*
 * Schmal bekommt der Umschalter seine eigene Zeile.
 *
 * Sonst steht "Monat | Jahr" mit dem Blaetterfeld zusammen in der ersten und
 * der Knopf zum laufenden Zeitraum allein in der zweiten -- eine halbe Zeile,
 * die aussieht wie vergessen.
 */
@media (max-width: 560px) {
    .tafel-schalter > .schalter { flex: 1 0 100%; }
}

.tafel-karte { margin-bottom: 18px; }
.tafel-karte .card-head { padding-bottom: 6px; }

.tafel-rollen { overflow-x: auto; }

.tafel {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}

.tafel th,
.tafel td { padding: 7px 10px; border-bottom: 1px solid var(--border); text-align: left; }
.tafel thead th { position: sticky; top: 0; background: var(--surface); font-size: 12px; color: var(--text-muted); }
.tafel .num { text-align: right; white-space: nowrap; }
.tafel tbody tr:hover td,
.tafel tbody tr:hover th { background: var(--surface-2); }
.tafel tfoot th,
.tafel tfoot td { border-bottom: 0; border-top: 2px solid var(--border-strong); font-weight: 600; }
.tafel .ist-summe { font-weight: 600; }

/* Die Nummer traegt die Zeile, die Bezeichnung steht klein darunter. */
.tafel-nummer { display: block; font-weight: 600; }
.tafel-name { display: block; }
.tafel-link { display: block; color: inherit; text-decoration: none; border-radius: 4px; }
.tafel-link:hover { color: var(--accent); text-decoration: underline; }
.tafel-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Ueber der Traegernummer steht ihre Kostenstelle -- sonst waeren zwei
   Spalten "420" nicht auseinanderzuhalten. */
.tafel-oben { display: block; font-size: 11px; font-weight: 400; }

/* Ein Wochenende und ein Tag ohne Buchung treten zurueck -- sie sind die
   Luecke, die man sehen soll, aber nicht das, worauf man schaut. Seit die
   Traeger in den Zeilen stehen, sind das Spalten: Die Kennzeichnung sitzt an
   jeder Zelle und nicht mehr an der Zeile. */
.tafel-anteile th.ist-wochenende,
.tafel-anteile td.ist-wochenende { background: var(--surface-2); }
.tafel-anteile th.ist-leer,
.tafel-anteile td.ist-leer,
.tafel-anteile tr.ist-leer > th { color: var(--text-muted); }

/*
 * Die erste Spalte bleibt stehen.
 *
 * Eine Kreuztabelle laesst sich nicht umbrechen: Ein Monat sind
 * einunddreissig Spalten, und die passen auf kein Telefon. Sie rollt also
 * seitwaerts -- und wer nach rechts rollt, haette die Nummer sonst nach drei
 * Tagen aus dem Bild verloren und laese Zahlen, ohne zu wissen, wozu sie
 * gehoeren.
 *
 * Fuer jede Tafel, nicht nur fuer die eine: Tage je Projekt, Anteil je
 * Kostentraeger, Vollstaendigkeit. Zellen, die sich ueber die ganze Breite
 * ziehen, bleiben aussen vor -- sie haben keine Spalte, in der sie stehen
 * bleiben koennten.
 */
.tafel-rollen .tafel > thead > tr > *:first-child:not([colspan]),
.tafel-rollen .tafel > tbody > tr > *:first-child:not([colspan]),
.tafel-rollen .tafel > tfoot > tr > *:first-child:not([colspan]) {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--surface);
    /* Eine Kante, damit die stehende Spalte als solche zu lesen ist und die
       Zahlen nicht unter ihr hervorzukommen scheinen. */
    box-shadow: 1px 0 0 var(--border);
}

/* Die Ecke oben links steht in beide Richtungen und muss ueber allem liegen. */
.tafel-rollen .tafel > thead > tr > *:first-child { z-index: 3; }

.tafel-rollen .tafel > tbody > tr:hover > *:first-child { background: var(--surface-2); }

/*
 * Breit genug fuer eine Nummer -- mehr steht dort nicht.
 *
 * Die Bezeichnung stand einmal klein darunter und machte aus dieser Spalte die
 * breiteste der Tafel: „Auftrag Meier Instandhaltung Werkhalle Nord" sind
 * dreihundert Punkte. Sie steht jetzt im Mouseover, und die Spalte braucht
 * noch die Breite von „ohne".
 */
.tafel-anteile .tafel-ecke { min-width: 4rem; }

/*
 * Die Summenspalte haelt Abstand zum Rand.
 *
 * Sie ist die letzte, rechtsbuendig, und die Polsterung der Tafel ist schmal
 * geworden -- die Zahl klebte damit an der Kante der Karte. Vier Punkte sind
 * zu wenig, um als Rand zu gelten; zehn sehen aus wie Absicht.
 */
.tafel-anteile .tafel-gesamt { padding-right: 10px; }

/*
 * Die Tagesspalten so eng wie lesbar.
 *
 * Eine Zelle traegt vier Zeichen („100,0"), ihr Kopf zwei und eine Zahl. Mit
 * der Polsterung der uebrigen Tafeln -- zehn Punkte links wie rechts -- kostete
 * jede Spalte zwanzig Punkte Luft, und einunddreissig Spalten machen daraus
 * sechshundert: der Unterschied zwischen „der Monat steht da" und „der Monat
 * rollt seitwaerts weg".
 *
 * Deshalb hier und nur hier enger. Die erste Spalte behaelt ihre Polsterung:
 * Sie traegt Text und keine Zahl, und eng gesetzter Text liest sich schlecht.
 */
.tafel-anteile th,
.tafel-anteile td { padding: 6px 4px; font-size: 13px; }

.tafel-anteile .tafel-ecke { padding: 6px 10px; font-size: 14px; }

/* Der Wochentag klein ueber der Zahl -- sonst waere jede Spalte doppelt so
   breit wie noetig. */
.tafel-zeit { text-align: center !important; }
.tafel-tagname { display: block; font-weight: 400; font-size: 11px; }
.tafel-tagzahl { display: block; font-weight: 600; }

/*
 * Die Vollstaendigkeit: wer hat den Monat erfasst.
 *
 * Die Zahl, um die es geht, ist die der fehlenden Tage -- sie traegt die
 * Farbe, nicht die ganze Zeile. Eine rot hinterlegte Zeile liest sich wie ein
 * Vorwurf; ein Mensch, der zwei Tage nachzutragen hat, ist kein Fehler.
 */
.tafel-voll th[scope="row"] { min-width: 12rem; }

/*
 * Die Tafel der auffaelligen Buchungen.
 *
 * Die Nummer traegt die Aussage und bekommt Platz; was jemand noch nie
 * gebucht hat, hebt sich ab. Kraeftig genug, um beim Ueberfliegen
 * aufzufallen, und zurueckhaltend genug, um keine Anschuldigung zu sein --
 * hier steht ein Hinweis, kein Befund.
 */
.tafel-auffall th[scope="row"] { min-width: 11rem; }

.tag-erstmals {
    background: var(--surface);
    color: var(--warning);
    border-color: var(--warning);
}

.tafel-auffall tr.ist-erstmals > * { background: var(--surface-2); }

.luecken-zahl {
    display: inline-block;
    min-width: 1.6em;
    padding: 1px 6px;
    border-radius: 6px;
    font-weight: 600;
}

.luecken-zahl.ist-offen { background: var(--danger-soft); color: var(--danger); }
.tafel-voll .ist-vollstaendig .luecken-zahl { color: var(--running); }

/* Der Name als Schaltflaeche: Sie klappt die fehlenden Tage auf. Wo nichts
   fehlt, gibt es nichts aufzuklappen -- der Pfeil bleibt dann weg. */
.tafel-voll .gruppe-knopf { gap: 6px; text-align: left; }
.tafel-voll .gruppe-knopf[disabled] { cursor: default; }
.tafel-voll .gruppe-knopf[disabled] .gruppe-pfeil { visibility: hidden; }

/*
 * Die fehlenden Tage: quer statt untereinander.
 *
 * Einundzwanzig Tage untereinander sind ein halber Bildschirm, und die Zahlen
 * der Zeile schweben dann in seiner Mitte. Nebeneinander mit Umbruch sind es
 * zwei Zeilen.
 */
.luecken-liste {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px 8px;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 13px;
}

.luecke {
    padding: 1px 7px;
    border-radius: 6px;
    background: var(--surface-2);
}

.luecke-tag { font-variant-numeric: tabular-nums; }

.tafel-voll .voll-luecken > td { padding-top: 0; }

@media (max-width: 720px) {
    .tafel th, .tafel td { padding: 6px 7px; }
    .tafel { font-size: 13px; }

    .tafel-voll th[scope="row"] { min-width: 9rem; }

    /*
     * Ein langer Name bricht um, statt die Tabelle breiter zu machen.
     *
     * `th` steht von Haus aus auf `nowrap` -- in einer Kopfzeile richtig, in
     * einer Zeile falsch: Dort steht keine Ueberschrift, sondern ein Name.
     * „Auftrag Meier Instandhaltung Werkhalle Nord" machte die erste Spalte
     * der Projekttafel zweihundertachtundneunzig Punkte breit, von
     * dreihundertsechzig -- die Zahlen daneben waren aus dem Bild geschoben,
     * und zu sehen war ein Streifen Tabelle.
     *
     * Breit bleibt es, wie es war: Dort ist Platz, und eine Zeile, die nicht
     * umbricht, liest sich ruhiger.
     */
    .tafel > tbody > tr > th[scope="row"],
    .tafel > tfoot > tr > th[scope="row"] {
        white-space: normal;
        overflow-wrap: anywhere;
    }
}

/*
 * Nur am Bildschirm: Papier hat keinen schmalen Schirm.
 *
 * Alles hierunter ist Abhilfe fuer ein Fenster, das zu schmal ist -- winzige
 * Schrift, feste Spaltenanteile, Ueberschriften ohne Versalien. Im Druck gilt
 * das Gegenteil: Der Bogen ist so breit wie das Blatt, und wie die Tafel
 * darauf steht, sagt der Druckabschnitt weiter unten. Ohne das `screen` kam
 * die Breite des Druckfensters (gut siebenhundert Punkte) hier durch, und auf
 * dem Blatt stand eine Tabelle in Neun-Punkt-Schrift neben einer in
 * Sieben-Punkt-Schrift.
 */
@media screen and (max-width: 720px) {
    /*
     * Die Woche am Telefon: neun Spalten, fest verteilt.
     *
     * Eine Tabelle waechst sonst nach ihrem Inhalt, und die Breite, die der
     * laengste Eintrag verlangt, bekommt die Spalte fuer alle Zeilen. Auf
     * dreihundertsechzig Punkten reicht ein einziger Name dafuer, die sieben
     * Tage aus dem Bild zu schieben -- der ganze Sinn der Wochensicht war,
     * dass genau das nicht mehr noetig ist.
     *
     * Fest verteilt kann sie nicht ueber den Rand hinauswachsen: ein knappes
     * Sechstel fuer die Nummer, ein Siebtel fuer die Summe, der Rest zu
     * gleichen Teilen auf die sieben Tage. Was nicht passt, bricht um, statt
     * die Tabelle breiter zu machen.
     *
     * Nur fuer die Woche. Einunddreissig Tagesspalten auf dieselbe Weise
     * verteilt waeren zehn Punkte je Spalte -- lesbar ist daran nichts, und
     * der Monat rollt am Telefon zu Recht.
     */
    .tafel-anteile.tafel-woche {
        table-layout: fixed;
        width: 100%;
    }

    /*
     * Zwei Punkte Polsterung, nicht zehn: Bei neun Spalten ist jeder Punkt,
     * den die Luft nimmt, bald eine Ziffer weniger.
     *
     * Die Groesse steht an den Zellen und nicht nur an der Tafel: Die Zellen
     * setzen ihre eigene (`.tafel-anteile th`), und die ueberschriebe, was sie
     * sonst von oben erben wuerden.
     */
    .tafel-anteile.tafel-woche th,
    .tafel-anteile.tafel-woche td {
        padding: 6px 2px;
        font-size: 12px;
    }

    /*
     * Die erste Spalte: so breit wie eine Nummer, nicht wie ein Name.
     *
     * Darin steht „420" oder „ohne", der Name liegt im Mouseover. Umbrechen
     * darf sie trotzdem -- eine Nummer wie „10.123.4711" gibt es, und sie soll
     * die Tafel nicht sprengen, sondern zweizeilig werden.
     */
    .tafel-anteile.tafel-woche > thead > tr > *:first-child,
    .tafel-anteile.tafel-woche > tbody > tr > *:first-child,
    .tafel-anteile.tafel-woche > tfoot > tr > *:first-child {
        width: 15%;
        min-width: 0;
        white-space: normal;
        overflow-wrap: anywhere;
        padding-left: 6px;
        padding-right: 2px;
    }

    /* Die Summe rechts haelt ihren Abstand zum Rand der Karte. */
    .tafel-anteile.tafel-woche > thead > tr > *:last-child,
    .tafel-anteile.tafel-woche > tbody > tr > *:last-child,
    .tafel-anteile.tafel-woche > tfoot > tr > *:last-child {
        width: 14%;
        padding-right: 8px;
    }
}

/* ---------- Kostenstellen ---------- */

.kosten-spalten {
    display: grid;
    /* min(320px, 100%): Auf einem schmalen Gerät ist die Spalte so breit wie
       der Bildschirm, nicht 320 Pixel. */
    grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
    gap: 18px;
    align-items: start;
}

.kosten-zeile {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 16px;
}

.kosten-nr { min-width: 42px; }

/*
 * Mehrere Nummern auf einmal.
 *
 * Der Haken steht vor dem Aufklapppfeil und nicht dahinter: Er gehoert zur
 * Zeile als Ganzes, der Pfeil nur zu dem, was unter ihr haengt.
 */
.kosten-haken { flex: 0 0 auto; width: 16px; height: 16px; margin: 0; accent-color: var(--accent); }

.kosten-auswahl {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
    padding: 10px 16px;
    background: var(--accent-soft);
    border-bottom: 1px solid var(--border);
}

.kosten-auswahl-zahl { font-weight: 500; }

/*
 * Der Nummernbaum.
 *
 * Die Tiefe zeigt die Einrückung, nicht der Rahmen: Drei ineinander
 * verschachtelte Kästen würden bei achtzig Trägern mehr Linien als Inhalt
 * ergeben. Eine dünne Leitlinie links genügt, um zu sehen, was zusammengehört.
 */
.nummer-baum { padding-bottom: 6px; }

/*
 * Zwei Gruppen in einer Karte: Kostenstellen und Kostentraeger.
 *
 * Sie sind zwei Ordnungen und keine zwei Ebenen -- deshalb eine Trennlinie
 * dazwischen und eine Ueberschrift ueber jeder, statt einer Einrueckung.
 */
.nummer-gruppe + .nummer-gruppe {
    border-top: 1px solid var(--border);
    margin-top: 6px;
}

.nummer-gruppe-titel {
    margin: 0;
    padding: 14px 16px 4px;
    font-size: 14px;
    font-weight: 600;
    color: var(--text-muted);
    letter-spacing: .02em;
}

.nummer-kinder {
    border-left: 2px solid var(--border);
    margin-left: 18px;
    background: var(--surface-2);
}

.nummer-ast > .kosten-zeile { gap: 8px; }

/*
 * Der Pfeil zum Aufklappen -- und der Platz, den er auch dort einnimmt, wo es
 * nichts aufzuklappen gibt: Sonst stünden die Nummern einer Ebene nicht
 * untereinander. Breit genug, dass ein Daumen ihn trifft.
 */
.nummer-ast > .kosten-zeile > .gruppe-knopf {
    min-width: 26px;
    justify-content: center;
    flex: none;
}

.gruppe-pfeil-leer { display: inline-block; width: 26px; flex: none; }

.nummer-anlegen { padding: 6px 16px 10px; }

.nummer-plus {
    color: var(--accent);
    border-style: dashed;
}

.nummer-formular {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
    margin-top: 8px;
}

.nummer-formular input[type=text] { flex: 1 1 140px; min-width: 0; height: var(--control-sm); }
.nummer-formular input[name=code],
.nummer-neu input[name^="code_"] { flex: 0 0 110px; }

@media (max-width: 560px) {
    .nummer-formular input[name=code],
    .nummer-neu input[name^="code_"] { flex: 1 1 100%; }
    .nummer-kinder { margin-left: 10px; }
}

/*
 * Der Dialog „Nummer anlegen": drei Stufen untereinander, jede mit dem, was es
 * dort schon gibt, und darunter -- wenn „neu" gewaehlt ist -- den zwei
 * Feldern. Eingerueckt, damit der Weg von oben nach unten zu sehen ist.
 */
.anlegen-stufe { margin-bottom: 14px; }
.anlegen-stufe .nummer-neu { margin-top: 6px; padding-left: 14px; border-left: 2px solid var(--accent-soft); }
.anlegen-pfad { margin: 0; padding-top: 10px; border-top: 1px solid var(--border); }

/*
 * Einen Tag vor, einen Tag zurueck.
 *
 * Die drei gehoeren zusammen und sitzen deshalb in einem gemeinsamen Rahmen,
 * wie Stunde und Minute bei der Uhrzeit. Vorher lagen sie lose in der
 * Filterspalte, und weil das Datum dazwischen den freien Platz aufbrauchte,
 * standen die Pfeile an den beiden Enden -- weit auseinander und weit weg von
 * dem, was sie verstellen.
 */
/* Umbrechen darf er: Auf einem schmalen Schirm rutscht „Heute" unter die
   Pfeile, statt die Zeile ueber den Rand zu schieben. */
.tag-schalter { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }

.tag-gruppe {
    display: inline-flex;
    align-items: center;
    /*
     * Nicht mitwachsen und nicht nachgeben: Der Schalter behaelt seine Breite,
     * egal wie viel Platz die Spalte hergibt. Wandern die Pfeile, klickt der
     * zweite Klick daneben.
     */
    flex: 0 0 auto;
    /* Das Mass traegt die Gruppe; die Knoepfe darin sind nur ihr Inhalt. */
    height: var(--control);
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: 6px;
}

.tag-schalter > button, .tag-gruppe > button { flex: 0 0 auto; }

.tag-pfeil {
    width: 36px;
    min-width: 36px;
    height: 100%;
    padding: 0;
    border: 0;
    border-radius: 5px;
    background: none;
    box-shadow: none;
    font-size: 20px;
    line-height: 1;
    color: var(--text-muted);
}

.tag-pfeil:hover { background: var(--surface-2); color: var(--text); }
.tag-pfeil:focus-visible { outline-offset: -2px; }

/*
 * Der Sprung auf ein Datum.
 *
 * Selbst gezeichnet und nicht der Kalender des Browsers. Der schien der
 * bescheidenere Weg -- er kennt die Sprache und auf dem Telefon seine eigene
 * Bedienung --, ist aber in jedem Browser anders gross, in manchen so klein,
 * dass man die Tage sucht, und er weiss nichts von den Farben dieser
 * Anwendung und nichts von ihrem dunklen Aussehen.
 */
.tag-kalenderhalter { position: relative; display: inline-flex; flex: 0 0 auto; }

/*
 * Verankert wird das Blatt am Feld und nicht nur am Knopf.
 *
 * Der Knopf steht rechts in der Zeile; auf einem Telefon stuende ein Blatt
 * von 304 Pixeln daneben zur Haelfte ausserhalb des Bildschirms. Am Feld
 * beginnt es links -- dort, wo die Karte anfaengt.
 */
.tag-feld { position: relative; }

.tag-kalender { width: var(--control); min-width: var(--control); padding: 0; }
.tag-kalender-icon { width: 20px; height: 20px; display: block; }

.tag-kalenderblatt {
    position: absolute;
    z-index: 30;
    top: calc(100% + 6px);
    left: 0;
    /* Auf einem schmalen Schirm so breit, wie Platz ist -- ein Blatt, das
       ueber den Rand steht, laesst sich in der letzten Spalte nicht treffen. */
    width: min(304px, calc(100vw - 32px));
    padding: 10px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: 10px;
    box-shadow: var(--shadow);
}

/* Zugeklappt ist zu: Ohne dies gewaenne `display: grid` gegen `hidden`. */
.tag-kalenderblatt[hidden] { display: none; }

.kalblatt-kopf { display: flex; align-items: center; gap: 6px; margin-bottom: 8px; }
.kalblatt-monat { flex: 1 1 auto; text-align: center; font-weight: 600; }

.kalblatt-pfeil {
    flex: 0 0 auto;
    width: 32px;
    min-width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    background: none;
    font-size: 18px;
    line-height: 1;
    color: var(--text-muted);
}

.kalblatt-pfeil:hover { background: var(--surface-2); color: var(--text); }

.kalblatt-wochentage,
.kalblatt-gitter { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }

.kalblatt-wochentage span {
    padding-bottom: 4px;
    text-align: center;
    font-size: 11px;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.kalblatt-tag {
    height: 38px;
    min-width: 0;
    padding: 0;
    border: 0;
    background: none;
    border-radius: 8px;
    font-variant-numeric: tabular-nums;
}

.kalblatt-tag:hover { background: var(--surface-2); }

/* Die Tage der Nachbarmonate stehen mit, damit die Woche vollstaendig ist --
   gemeint ist aber der Monat in der Mitte. */
.kalblatt-tag.ist-fremd { color: var(--text-muted); opacity: .5; }
.kalblatt-tag.ist-wochenende { color: var(--text-muted); }
.kalblatt-tag.ist-heute { box-shadow: inset 0 0 0 1px var(--border-strong); font-weight: 650; }

.kalblatt-tag.ist-gewaehlt,
.kalblatt-tag.ist-gewaehlt.ist-wochenende {
    background: var(--accent);
    color: #fff;
    font-weight: 600;
}

.kalblatt-tag.ist-gewaehlt:hover { background: var(--accent-hover); }

.kalblatt-fuss { margin-top: 8px; }

.tag-schalter-datum {
    /*
     * Feste Breite, gleich breite Ziffern: Sonst ruecken die Pfeile bei jedem
     * Sprung ein Stueck, weil der 9. schmaler ist als der 10.
     */
    flex: 0 0 auto;
    min-width: 8em;
    padding: 0 2px;
    text-align: center;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    font-weight: 500;
}

/* Mit dem Finger bedient braucht auch der Pfeil seine 44 Punkte. */
@media (pointer: coarse) {
    .tag-gruppe { min-height: 44px; }
    .tag-pfeil { width: 44px; min-width: 44px; }
}

@media (max-width: 720px) {
    .tag-kalenderhalter { position: static; }

    .tag-kalenderblatt {
        left: 0;
        right: auto;
        width: min(304px, calc(100vw - 40px));
    }
}

/* Der Tagesschalter braucht mehr als eine Spalte der Filterzeile. */
@media (min-width: 560px) {
    .filters > .tag-feld { grid-column: span 2; }
}

/* Die Schaltflaeche am Ende der Zeiten eines Tages. */
.tagzeilen-fuss { padding: 10px 16px 4px; }

/* Was in einem zugeklappten Ast steckt, steht rechts in der Zeile. */
.kosten-drin { flex: 0 0 auto; white-space: nowrap; }

/* Ueberschrift plus Fragezeichen im Kartenkopf: Der Block waechst mit, damit
   die Hinweisblase darunter die Breite der Karte nutzen kann. */
.card-head > .field-kopf { flex: 1 1 auto; margin-bottom: 0; }

/*
 * Schmal steht die Beschriftung ueber dem Feld: Eine Spalte fuer
 * "Projektnummer" und eine fuer das Feld liessen dem Feld zu wenig uebrig.
 */
@media (max-width: 460px) {
    .zeit-kosten { grid-template-columns: minmax(0, 1fr); gap: 2px; }
    .zeit-kosten-label { text-align: left; margin-top: 4px; }
}

/*
 * Die Nummernliste als Aufklappfeld.
 *
 * Die Zusammenfassung sieht aus wie eine Zeile der Liste darunter, nicht wie
 * eine Schaltfläche: Sie gehört zur Liste und ist ihr Deckel, kein eigenes
 * Bedienelement neben ihr.
 */
.kosten-klappe > summary {
    padding: 10px 16px;
    cursor: pointer;
    color: var(--text-muted);
    font-size: 13px;
    border-bottom: 1px solid var(--border);
    list-style-position: inside;
}

.kosten-klappe > summary:hover { background: var(--surface-2); color: var(--text); }
.kosten-klappe[open] > summary { border-bottom: 1px solid var(--border); }
.kosten-anzahl { font-weight: 600; }

/* Das Suchfeld sitzt im Kartenkopf und darf ihn nicht sprengen. */
.kosten-suche {
    max-width: 220px;
    height: var(--control-sm);
    font-size: 13px;
}

@media (max-width: 560px) {
    .kosten-suche { max-width: 100%; width: 100%; }
}

/* Oben ausgerichtet: Das Feld mit dem Hinweis darunter ist höher, und unten
   ausgerichtet stünden die beiden Eingaben auf verschiedener Höhe. */
.kosten-spalten .filters { align-items: start; }
.kosten-text { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; }

/*
 * Berichte in Team – die gebuchte Zeit nach Nummer, Mitarbeiter oder Monat.
 *
 * Eine Tabelle, keine Kacheln: Sechs Spalten, die untereinander vergleichbar
 * bleiben müssen. Zwei davon verschwinden auf dem Telefon – der Balken, weil
 * die Prozentzahl daneben dasselbe sagt, und die Dezimalstunden, weil die
 * Dauer daneben dasselbe sagt.
 */
.gruppen-titel {
    font-size: 13px;
    color: var(--text-muted);
    margin-bottom: 6px;
}

/*
 * Die Gruppierungsleiste ist kein Raster.
 *
 * Ein Raster gibt jeder Zelle dieselbe Breite; eine Reihe aus vier
 * Schaltflächen ist aber so breit, wie ihre Wörter es verlangen. Im Raster
 * ragte sie über ihre Zelle hinaus und legte sich über die Reihe daneben –
 * sichtbar erst daran, dass deren Schaltflächen die Klicks abfingen.
 * Nebeneinander mit Umbruch nimmt jede den Platz, den sie braucht.
 */
.filters-gruppen {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 28px;
    align-items: end;
}

.bericht-tafel td:nth-child(2) { width: 140px; }

/*
 * Auch im Baum bleibt die Bezeichnung stehen.
 *
 * Auf dem Telefon passen die sechs Spalten nicht nebeneinander; die Tabelle
 * rollt. Ohne stehende erste Spalte stuenden dann Tage und Zeit ohne den
 * Namen da, zu dem sie gehoeren -- und die Einrueckung, die im Baum die
 * Tiefe zeigt, waere gleich mit aus dem Bild.
 */
.konto-tafel > thead > tr > *:first-child,
.konto-tafel > tbody > tr > *:first-child,
.bericht-tafel > thead > tr > *:first-child,
.bericht-tafel > tbody > tr > *:first-child,
.bericht-tafel > tfoot > tr > *:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--surface);
    box-shadow: 1px 0 0 var(--border);
}

.konto-tafel > thead > tr > *:first-child,
.bericht-tafel > thead > tr > *:first-child { z-index: 3; }

.konto-tafel > tbody > tr:hover > *:first-child,
.bericht-tafel > tbody > tr:hover > *:first-child { background: var(--surface-2); }

/*
 * Der Baum steht in einer einzigen Tabelle.
 *
 * Eine eigene Tabelle je Ebene liesse die Spalten auseinanderlaufen, und genau
 * das Vergleichen der Zahlen untereinander ist der Zweck. Die Tiefe zeigt
 * deshalb die Einrückung, nicht der Rahmen.
 */
.baum-zeile[data-tiefe="1"] > td { font-size: 14px; }
.baum-zeile[data-tiefe="2"] > td,
.baum-zeile[data-tiefe="3"] > td { font-size: 13px; color: var(--text-muted); }
.baum-zeile[data-tiefe="3"] > td.duration { color: var(--text); }

/*
 * Die Aufschlüsselung rückt ein und gehört sichtbar zur Zeile darüber.
 * Der Hintergrund steht an der Zelle, nicht an der Zeile: Sonst gewänne
 * beim Überfahren der Hintergrund von `tbody tr:hover`.
 */
.bericht-tafel tr.kind-zeile > td {
    background: var(--surface-2);
    font-size: 14px;
}

.bericht-tafel tr.kind-zeile .kind-name {
    padding-left: 34px;
    color: var(--text-muted);
}

.bericht-tafel tfoot td {
    border-top: 2px solid var(--border);
    font-weight: 600;
}

/* Eine Zeile ohne Aufschlüsselung klappt nicht auf – dann auch kein Pfeil,
   der es verspräche. */
.bericht-tafel .gruppe-knopf[disabled] { cursor: default; }
.bericht-tafel .gruppe-knopf[disabled] .gruppe-pfeil { visibility: hidden; }

.card-fuss {
    padding: 10px 16px;
    border-top: 1px solid var(--border);
}

/*
 * Der Bericht des Sammel-Imports.
 *
 * Was angelegt wurde, steht ruhig da; was liegen blieb, sticht heraus und
 * nennt die Zeile mit ihrem Wortlaut – sonst müsste jemand achtzig Zeilen
 * durchsehen, um die eine zu finden, die nicht durchkam.
 */
.import-bericht:empty { display: none; }
.import-bericht { margin-top: 12px; }

.import-summe {
    padding: 8px 12px;
    border-radius: var(--radius);
    background: var(--surface-2);
    font-weight: 600;
}

.import-fehler {
    margin-top: 8px;
    padding: 8px 12px;
    border-radius: var(--radius);
    background: var(--danger-soft);
    color: var(--danger);
    font-size: 13px;
}

/* Die Probe vor dem Schreiben: ruhig, aber lesbar. */
.import-probe {
    margin-top: 8px;
    padding: 8px 12px;
    border-radius: var(--radius);
    background: var(--surface-2);
    font-size: 13px;
}

.import-probe ul { margin: 6px 0 0; padding-left: 18px; }
.import-probe li { margin-bottom: 3px; }

.import-fehler ul { margin: 6px 0 0; padding-left: 18px; }
.import-fehler li { margin-bottom: 3px; }
.import-fehler code { font-size: 12px; word-break: break-word; }

/*
 * Auswahlfeld zum Tippen.
 *
 * Die Liste liegt über dem, was darunter steht, statt es beiseite zu schieben:
 * In einer Zeile des Tagesdialogs würde ein aufklappender Kasten die Zeilen
 * darunter jedesmal verrutschen lassen, und der Finger träfe daneben.
 *
 * Getragen wird sie von `.combo` -- deshalb steht die Hülle relativ. Ein
 * Vorfahre mit `overflow: hidden` würde sie abschneiden; im Dialog scrollt der
 * Hintergrund, nicht der Kasten, und die Stempelkarte schneidet nichts ab.
 */
.combo { position: relative; }
.combo-eingabe { width: 100%; }

.combo-liste {
    position: absolute;
    z-index: 30;
    top: calc(100% + 2px);
    left: 0;
    right: 0;
    margin: 0;
    padding: 4px;
    list-style: none;
    max-height: 280px;
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
}

.combo-option {
    padding: 9px 10px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 14px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/*
 * Markiert wird die Zeile, auf der die Tastatur steht -- nicht die, unter der
 * der Zeiger liegt. Beides gleichzeitig hervorzuheben zeigte zwei Antworten
 * auf die Frage, welche Zeile die Eingabetaste nimmt.
 */
.combo-option.ist-markiert { background: var(--accent); color: #fff; }
.combo-option[aria-selected="true"] { font-weight: 600; }

.combo-leer { padding: 9px 10px; color: var(--text-muted); font-size: 14px; }

/* Auf dem Telefon muss die Zeile mit dem Daumen zu treffen sein. */
@media (pointer: coarse) {
    .combo-option { padding: 12px 10px; }
}

/* ---------- Betriebsfreie Tage ---------- */

.frei-zeile {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 11px 16px;
}

/* ---------- Zeitkonto ---------- */

.balance-plus  { color: var(--running); }
.balance-minus { color: var(--danger); }

/* ---------- Der Kalender als Karte ---------- */

/*
 * Der Kalender hatte eine eigene Seite und ist heute eine Karte auf der
 * Uebersicht. Er besteht dort aus mehreren Karten -- Kopf mit Summen, Gitter,
 * Legende --, die untereinander denselben Abstand halten wie die Karten der
 * Uebersicht.
 */
.kalender-block { display: flex; flex-direction: column; gap: 16px; }

/*
 * Die Summenzeile steht direkt unter dem Kartenkopf. Ihr eigener Strich nach
 * oben laege dort auf dem des Kopfes -- zwei Linien statt einer.
 */
.kalender-block .card-head + .summary { border-top: none; }

/* Die Legende schliesst die Karte ab und traegt deshalb den Strich darueber. */
.kalender-fuss:not(:empty) { padding: 12px 16px; border-top: 1px solid var(--border); }

/* Die Woche ist eine Liste von Tageskarten und haelt deren Abstand. */
.kalender-woche:not(:empty) { display: flex; flex-direction: column; gap: 16px; }

.kalender-schalter { gap: 10px; }

/*
 * Schmal bricht die Kopfzeile um. Die Schalter stehen dann in einer eigenen
 * Reihe und fuellen sie, statt zusammengedraengt am rechten Rand zu kleben.
 */
@media (max-width: 560px) {
    .kalender-kopf > .kalender-schalter { flex: 1 0 100%; }
    .kalender-schalter > select { flex: 1 1 auto; }
}

/* ---------- Teamkalender ---------- */

table.calendar { font-size: 13px; }
table.calendar th, table.calendar td { padding: 4px 0; text-align: center; border-bottom: 1px solid var(--border); }

.cal-name {
    text-align: left !important;
    padding: 4px 10px !important;
    white-space: nowrap;
    position: sticky;
    left: 0;
    background: var(--surface);
    z-index: 1;
}

th.cal-name { font-size: 13px; font-weight: 500; }

.cal-day, .cal-cell { min-width: 24px; width: 24px; font-variant-numeric: tabular-nums; }
.cal-weekend { background: var(--surface-2); color: var(--text-muted); }
.cal-today { box-shadow: inset 0 -2px 0 var(--accent); }

.cal-cell { font-weight: 650; color: transparent; }

.cal-vacation { background: var(--accent); color: #fff; }
.cal-sick     { background: var(--danger); color: #fff; }
.cal-timeoff  { background: var(--warning); color: #fff; }

/* Halbe Tage werden gestreift dargestellt. */
.cal-half {
    background-image: linear-gradient(135deg, transparent 45%, rgba(255, 255, 255, .55) 45%, rgba(255, 255, 255, .55) 55%, transparent 55%);
}

.cal-legend { display: flex; gap: 18px; flex-wrap: wrap; align-items: center; font-size: 14px; }

.cal-swatch {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 4px;
    margin-right: 6px;
    font-size: 12px;
    font-weight: 650;
    color: #fff;
    vertical-align: middle;
}

/* ---------- Wahl der Erfassungsart ---------- */

.mode-choice { display: grid; gap: 10px; margin: 14px 0 18px; }

.mode-option {
    display: block;
    text-align: left;
    /* Die globale Regel für Schaltflächen verbietet den Umbruch; diese Karten
       tragen aber einen Erklärtext, der umbrechen muss. */
    white-space: normal;
    min-width: 0;
    padding: 12px 14px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    background: var(--surface);
    cursor: pointer;
}

.mode-option:hover { background: var(--surface-2); }

.mode-option.is-active {
    border-color: var(--accent);
    background: var(--accent-soft);
    box-shadow: inset 0 0 0 1px var(--accent);
}

.mode-title { display: block; font-weight: 650; margin-bottom: 3px; }
.mode-text { display: block; font-size: 13px; line-height: 1.45; color: var(--text-muted); font-weight: 400; overflow-wrap: break-word; }
.mode-option.is-active .mode-title { color: var(--accent); }

/* ---------- Hinweis zur Erfassungsart ---------- */

.mode-banner { border-left: 3px solid var(--accent); }
.mode-banner h2 { margin-bottom: 4px; }
.mode-banner .mode-choice { grid-template-columns: 1fr 1fr; }
.mode-banner .btn-link { padding-left: 0; }

@media (max-width: 640px) {
    /* Auf schmalen Schirmen zaehlt jeder Punkt, damit "Arbeit" neben den
       beiden Uhrzeiten noch vollstaendig in die Zeile passt. */
    .zeit-zeile { gap: 6px; }
    .zeit-zeile .timeinput { padding: 0 4px; }
    .zeit-zeile .timeinput input.time-part { width: 1.9em; }
    .zeit-zeile .zeit-art { min-width: 5.6em; padding-left: 6px; padding-right: 2px; }
    .zeit-zeile .zeit-weg { padding-left: 8px; padding-right: 8px; }

    .mode-banner .mode-choice { grid-template-columns: 1fr; margin: 12px 0 12px; }

    /* Auf dem kleinen Schirm tragen die beiden Karten die Erklärung selbst –
       der einleitende Absatz kostet dort mehr Platz, als er erklärt. */
    .mode-banner .card-body > p { display: none; }
    .mode-banner .mode-text { font-size: 12px; }
    .mode-banner h2 { font-size: 16px; }
}

/* Feiertage im Kalender */
.cal-holiday { background: var(--accent-soft); color: var(--accent); }
.cal-holiday-swatch { background: var(--accent-soft); border: 1px solid var(--accent); }

/*
 * Betriebsfrei ist kein Feiertag: Es steht nicht im Gesetz, sondern ist eine
 * Entscheidung des Betriebs. Deshalb eine eigene, ruhigere Kennzeichnung –
 * gestrichelt statt flächig, damit ein Feiertag daneben der stärkere bleibt.
 */
/* Als Verlauf statt als Schatten: Der Schatten ist an "heute" vergeben. */
.cal-company {
    background-color: color-mix(in srgb, var(--border-strong) 42%, transparent);
    background-image: linear-gradient(to top, var(--border-strong) 0 2px, transparent 2px);
}
.cal-company-swatch { background: color-mix(in srgb, var(--border-strong) 42%, transparent); border: 1px solid var(--border-strong); }

/* ---------- Eigener Kalender ---------- */

/*
 * Das Wochenende ist der Untergrund, kein Zustand: Es steht vor den Farben der
 * Tageszustände, damit ein Feiertag, ein Urlaubstag oder ein Tag mit erfasster
 * Zeit auch am Samstag und Sonntag zu sehen ist. Stand es danach, gewann bei
 * gleicher Spezifität das Grau – wer sonntags gearbeitet hatte, sah davon im
 * Kalender nichts.
 */
.kal-wochenende { background: var(--surface-2); color: var(--text-muted); }

/*
 * Sonntag rot wie im gedruckten Kalender – neben dem Samstag ist er sonst
 * nicht zu unterscheiden, und im Arbeitszeitgesetz ist er es sehr wohl.
 *
 * Nur dort, wo der Tag sonst nichts zu sagen hat: Auf einem Urlaubs-,
 * Krankheits- oder Feiertag stünde die rote Zahl auf farbigem Grund und wäre
 * schlechter zu lesen als die weisse. Die Aufzählung macht die Regel zugleich
 * spezifisch genug, um das `color: inherit` der Tagesschaltflächen zu
 * überstimmen.
 */
.kal-mini.kal-sonntag:not(.kal-urlaub):not(.kal-krank):not(.kal-ausgleich):not(.kal-feiertag),
.kal-monat-tag.kal-sonntag:not(.kal-urlaub):not(.kal-krank):not(.kal-ausgleich):not(.kal-feiertag) {
    color: var(--danger);
}

/* Farben der Tageszustände, gemeinsam für alle drei Auflösungen */
.kal-urlaub    { background: var(--accent); color: #fff; }
.kal-krank     { background: var(--danger); color: #fff; }
.kal-ausgleich { background: var(--warning); color: #fff; }
.kal-feiertag  { background: var(--accent-soft); color: var(--accent); }
.kal-betriebsfrei {
    background-color: color-mix(in srgb, var(--border-strong) 42%, transparent);
    background-image: linear-gradient(to top, var(--border-strong) 0 3px, transparent 3px);
}
/*
 * Ein Tag mit erfasster Zeit.
 *
 * In MyTime Solo trägt er die Variantenfarbe: Dort gibt es weder Urlaub noch
 * Feiertage, mit denen er verwechselbar wäre, und Grün stünde als einzige
 * fremde Farbe in einer sonst ockerfarbenen Oberfläche.
 *
 * In MyTime Team bleibt es beim Grün. Der Akzent ist dort schon zweimal
 * vergeben – Urlaub trägt ihn voll, ein Feiertag abgeschwächt – und ein
 * erfasster Tag sähe aus wie ein Feiertag.
 */
.kal-gearbeitet { background: var(--running-soft); }

:root[data-variante="solo"] .kal-gearbeitet { background: var(--accent-soft); }
.kal-heute { box-shadow: inset 0 0 0 2px var(--accent); }

.kal-halb {
    background-image: linear-gradient(135deg, transparent 45%, rgba(255, 255, 255, .55) 45%, rgba(255, 255, 255, .55) 55%, transparent 55%);
}

.cal-swatch.kal-feiertag-probe { background: var(--accent-soft); border: 1px solid var(--accent); }
.cal-swatch.kal-betriebsfrei-probe { background: color-mix(in srgb, var(--border-strong) 42%, transparent); border: 1px solid var(--border-strong); }
/* Das Wochenende ist nur eine hellere Fläche – als Probe braucht es eine
   Kante, sonst wäre das Feld in der Legende gar nicht zu sehen. */
.cal-swatch.kal-wochenende { border: 1px solid var(--border-strong); }
.cal-swatch.kal-sonntag { border: 1px solid var(--border-strong); color: var(--danger); font-weight: 700; }
.cal-swatch.kal-gearbeitet-probe { background: var(--running-soft); border: 1px solid var(--running); }

:root[data-variante="solo"] .cal-swatch.kal-gearbeitet-probe {
    background: var(--accent-soft);
    border-color: var(--accent);
}

/* Jahr: zwölf kleine Monate.
   minmax(0, 1fr) statt 1fr – sonst hält die Mindestbreite der Tageszellen die
   Spalten auf, das Raster wird breiter als der Bildschirm und läuft über. */
.kal-jahr { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 18px; }

.kal-mini-kopf { font-weight: 650; margin-bottom: 6px; font-size: 14px; }
/* minmax(0, 1fr) wie beim Raster darüber: Sonst halten die Tageszellen
   ihre Inhaltsbreite und der Monat wird breiter als der Bildschirm. */
.kal-mini-gitter { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }

.kal-mini-wt { font-size: 10px; color: var(--text-muted); text-align: center; padding-bottom: 2px; }

.kal-mini {
    aspect-ratio: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    border-radius: 3px;
    cursor: pointer;
    font-variant-numeric: tabular-nums;
}

.kal-mini:hover { outline: 1px solid var(--accent); }

/* Monat: klassisches Raster */
.kal-monat { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }

.kal-monat-wt {
    text-align: center;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: .04em;
    padding-bottom: 4px;
}

.kal-monat-tag {
    min-height: 74px;
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 5px 6px;
    display: flex;
    flex-direction: column;
    gap: 1px;
    cursor: pointer;
    font-size: 12px;
}

.kal-monat-tag:hover { border-color: var(--accent); }
.kal-monat-nr { font-weight: 650; font-variant-numeric: tabular-nums; }
.kal-monat-text { font-size: 11px; line-height: 1.3; }
.kal-monat-zeit { margin-top: auto; font-weight: 650; font-variant-numeric: tabular-nums; }
.kal-monat-saldo { font-size: 11px; font-variant-numeric: tabular-nums; }

.kal-heute-karte { border-left: 3px solid var(--accent); }

@media (max-width: 900px) {
    .kal-jahr { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 700px) {
    .kal-jahr { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
    /* Ein Monat je Zeile: So bleiben die Tage groß genug, um sie zu lesen und
       zu treffen – zwei Spalten drückten sie auf die Hälfte. */
    .kal-jahr { grid-template-columns: minmax(0, 1fr); gap: 20px; }
    .kal-mini { font-size: 13px; }
    .kal-mini-kopf { font-size: 15px; }
    .kal-mini-wt { font-size: 11px; }

    .kal-monat { gap: 2px; }
    .kal-monat-tag { min-height: 56px; padding: 3px 4px; font-size: 11px; }
    .kal-monat-text, .kal-monat-saldo { display: none; }
}



/* Die Tage im Kalender sind Schaltflächen – sie sollen aber wie Zellen
   aussehen, nicht wie Knöpfe. */
button.kal-mini,
button.kal-monat-tag {
    font: inherit;
    color: inherit;
    text-align: left;
    -webkit-appearance: none;
    appearance: none;
}

button.kal-mini { border: none; }
button.kal-mini:hover, button.kal-monat-tag:hover { background-color: var(--surface-2); }
button.kal-mini.kal-urlaub:hover, button.kal-monat-tag.kal-urlaub:hover { background-color: var(--accent-hover); }

/* ---------- Aus mite übernehmen ---------- */

/* Ein Dateifeld bringt seine eigene Breite mit: die Schaltfläche des Browsers
   plus Platz für den Dateinamen. Auf einem schmalen Gerät sprengt das die
   Seite, weil die Schaltfläche nicht umbricht. */
input[type="file"] { max-width: 100%; box-sizing: border-box; }

/* Ein Feld ohne eigene Beschriftung neben einem mit: ohne diesen Vorschub
   klebte es an der Oberkante der Zeile, statt neben der Eingabe zu stehen. */
.ohne-label { padding-top: 24px; }

input[type="file"]::file-selector-button {
    margin-right: 10px;
    padding: 6px 10px;
    border: 1px solid var(--border-strong);
    border-radius: 6px;
    background: var(--surface);
    color: var(--text);
    font: inherit;
    cursor: pointer;
}

/* ---------- Bericht der mite-Übernahme ---------- */

.import-bericht:empty { display: none; }

.import-bericht {
    margin-top: 16px;
    padding: 14px 16px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-2);
}

.import-kopf { font-weight: 600; margin-bottom: 10px; }

.import-bericht table { margin-bottom: 10px; }

.import-bericht th,
.import-bericht td { padding: 3px 0; border-bottom: 1px solid var(--border); }

.import-bericht th { font-weight: 500; color: var(--text-muted); font-size: 13px; }

.import-summe { margin-bottom: 6px; }

.import-liste { margin-top: 8px; font-size: 13px; }

.import-liste summary { cursor: pointer; color: var(--text-muted); }

.import-liste ul { margin: 6px 0 0; padding-left: 20px; }

.import-liste li { margin-bottom: 2px; }

/* ---------- Konten des Betreibers ---------- */

/* Ein gesperrtes Konto bleibt lesbar, tritt aber zurück: Es ist da, es
   arbeitet nur niemand mehr darin. */
tr.ist-gesperrt > td { opacity: .6; }

/* Das Variantenschild steht sonst nur in der Kopfzeile, wo es die eigene
   Variante nennt. Hier steht es je Zeile und trägt deren Farbe. */
/*
 * Der Betriebsbereich unter /admin.
 *
 * Er sieht aus wie die Anwendung, traegt aber ein eigenes Schild: Wer beide
 * Fenster offen hat, soll auf einen Blick wissen, in welchem er gerade ist.
 */
.marke-schild[data-variante="betrieb"] {
    background: var(--text);
    color: var(--surface);
}

.stand-zeile {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    padding: 6px 0;
    border-bottom: 1px solid var(--border);
}

.stand-zeile:last-child { border-bottom: none; }
.stand-zeile > span:last-child { font-variant-numeric: tabular-nums; text-align: right; }

td .marke-schild[data-variante="solo"] { background: var(--solo-soft); color: var(--solo); }
td .marke-schild[data-variante="team"] { background: var(--team-soft); color: var(--team); }

/* ---------- Bericht: eine Gruppe aufklappen ---------- */

/*
 * Die Beschriftung einer Gruppe ist eine Schaltfläche, sieht aber aus wie
 * Text: Ein Rahmen um jede Zeile machte die Tabelle unruhig. Erkennbar ist
 * sie am Pfeil und daran, dass sie beim Überfahren die Akzentfarbe annimmt.
 */
.gruppe-knopf {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: auto;
    min-height: 0;
    padding: 2px 0;
    border: none;
    background: none;
    color: inherit;
    font-weight: inherit;
    text-align: left;
    white-space: normal;
}

.gruppe-knopf-haupt { font-weight: 600; }

/*
 * Mit dem Finger bedient braucht auch sie eine Fläche. Die Regel steht hier
 * und nicht oben bei den anderen: Sie muss nach `min-height: 0` kommen, sonst
 * gewinnt bei gleicher Spezifität die spätere.
 */
@media (pointer: coarse) {
    .gruppe-knopf { min-height: 44px; }
}
.gruppe-knopf:hover { background: none; color: var(--accent); }

.gruppe-pfeil {
    display: inline-block;
    color: var(--text-muted);
    transition: transform .15s ease;
}

.gruppe-knopf[aria-expanded="true"] .gruppe-pfeil { transform: rotate(90deg); }

.detail-zeile > td { padding: 0; background: var(--surface-2); }

/* Der aufgeklappte Block gehört zur Zeile darüber – die Kante sagt das. */
.zeit-detail {
    padding: 12px 16px 14px;
    border-left: 3px solid var(--accent);
}

.zeit-detail-kopf {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 8px;
    color: var(--text-muted);
    font-size: 13px;
}

.zeit-detail-zeile {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 0;
    border-top: 1px solid var(--border);
}

.zeit-detail-text { flex: 1; min-width: 0; }
.zeit-detail-geld { flex: 0 0 auto; }

/*
 * Anhaken, um mehrere auf einmal abzurechnen.
 *
 * Das Kaestchen steht vor der Zeile und nicht in der Leiste am Ende: Wer eine
 * Liste durchgeht, wandert an der linken Kante entlang, und die Knoepfe rechts
 * meinen jeweils genau diese eine Zeile -- ein Kaestchen dazwischen hiesse,
 * zwei verschiedene Dinge saehen gleich aus.
 *
 * Das Label traegt eine Fingerflaeche um das Kaestchen herum; der Name steht
 * darin fuer die Vorlesesoftware und ist fuer das Auge fort.
 */
.zeit-haken {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    margin: -6px 0;
    cursor: pointer;
}

.zeit-haken input { width: 17px; height: 17px; cursor: pointer; accent-color: var(--accent); }

@media (pointer: coarse) {
    .zeit-haken { width: 44px; height: 44px; margin-left: -6px; }
    .zeit-haken input { width: 21px; height: 21px; }
}

/*
 * Was mit der Auswahl geschehen soll.
 *
 * Die Leiste erscheint erst, wenn etwas angehakt ist, und sitzt zwischen Kopf
 * und Liste -- dort, wo die Auswahl entstanden ist, und nicht am Ende einer
 * Liste, die man erst wieder hochscrollen muesste.
 */
.zeit-auswahl {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 8px 12px;
    margin-bottom: 4px;
    padding: 8px 10px;
    border-radius: 6px;
    background: var(--surface-2);
    font-size: 13px;
    font-weight: 600;
}

.zeit-auswahl .actions { flex-wrap: wrap; gap: 6px; }

/*
 * Eine Ebene tiefer: die Projekte eines Kunden, und darunter deren Zeiten.
 * Der innere Block rückt ein und bekommt eine ruhigere Kante – zwei gleich
 * kräftige Striche nebeneinander sagten nicht mehr, was zu was gehört.
 */
.projekt-block + .projekt-block { border-top: 1px solid var(--border); }

.projekt-kopf {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 6px 0;
}

.projekt-block .zeit-detail {
    margin: 0 0 8px 12px;
    padding: 4px 0 4px 12px;
    border-left-color: var(--border);
}

@media (max-width: 640px) {
    /* Schmal steht das Geld nicht mehr daneben – die Notiz braucht den Platz. */
    .zeit-detail-geld { display: none; }
    .zeit-detail { padding: 10px 12px 12px; }
}

/*
 * Ganz schmal bricht die Zeile um.
 *
 * Kaestchen, Notiz, Dauer und drei fingergrosse Schaltflaechen nebeneinander
 * brauchen rund 330 Punkte. Auf einem Geraet mit 320 passte das nie: Der
 * aufgeklappte Block zog die Berichtstabelle ueber ihren Rand hinaus, und man
 * musste seitwaerts rollen, um an die Schaltflaechen zu kommen -- die man dort
 * am wenigsten sucht.
 *
 * Also zwei Zeilen: oben das Kaestchen und der Text, darunter Dauer und
 * Schaltflaechen, rechtsbuendig. Nichts faellt weg, nichts wird kleiner.
 */
@media (max-width: 400px) {
    .zeit-detail-zeile { flex-wrap: wrap; row-gap: 6px; }
    .zeit-detail-text { flex: 1 1 100%; }
    .zeit-detail-zeile > .duration { margin-left: auto; }
}

/* ---------- Tickets ---------- */

/* Zwei Spalten am Schreibtisch, eine auf dem Telefon: Der Verlauf ist das
   Lange, die Angaben daneben sind das Kurze. */
.ticket-detail { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
.ticket-spalte { flex: 1 1 380px; min-width: 0; }
.ticket-spalte-schmal { flex: 0 1 320px; }

@media (max-width: 720px) {
    .ticket-spalte, .ticket-spalte-schmal { flex: 1 1 100%; }
}

.ticket-liste td { vertical-align: top; }

/* Der Knopf am Ende der Zeile: erledigen oder schliessen, ohne Umweg über das
   einzelne Ticket. Er steht rechts und nimmt nur die Breite, die er braucht. */
.ticket-liste td.actions { white-space: nowrap; width: 1%; }

/* Der Ausweg im Buchungsdialog: „Ohne Buchung erledigen" gehört nicht neben
   den Hauptknopf, sondern unter die Felder -- er beantwortet deren Frage. */
.dialog-ausweg {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}
.ticket-kopfzeile { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 2px; }
.ticket-kennung { font-variant-numeric: tabular-nums; color: var(--text-muted); text-decoration: none; }
.ticket-betreff { font-weight: 600; color: var(--text); text-decoration: none; }
.ticket-betreff:hover { text-decoration: underline; }
.ticket-marken { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 4px; }

/* Die Marken: Zustand und Prioritaet auf einen Blick. Der Zustand traegt die
   Farbe der Anwendung, die Prioritaet nur dann eine, wenn sie ueber dem
   Ueblichen liegt -- sonst leuchtete jede Zeile. */
.ticket-marke {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 999px;
    border: 1px solid var(--border-strong);
    font-size: 12px;
    line-height: 1.7;
    white-space: nowrap;
}

.ticket-status-neu { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.ticket-status-offen { background: var(--accent-soft); color: var(--accent); }
.ticket-status-wartet { background: var(--surface-2); color: var(--text-muted); }
.ticket-status-erledigt { background: var(--running-soft); border-color: var(--running); color: var(--running); }
.ticket-status-geschlossen { background: var(--surface-2); color: var(--text-muted); }

.ticket-prio-hoch { border-color: var(--warning); color: var(--warning); }
.ticket-prio-dringend { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); }
.ticket-prio-niedrig { color: var(--text-muted); }

.ticket-ueberfaellig { color: var(--danger); }

.ticket-beschreibung, .ticket-nachricht-text { white-space: pre-wrap; margin-top: 4px; }

/* Der Verlauf liest sich von oben nach unten wie ein Gespraech. Die interne
   Notiz steht dabei ausdruecklich anders da als die Antwort: Was der Kunde nie
   sehen darf, soll sich nicht wie das lesen, was an ihn hinausgeht. */
.ticket-verlauf { display: flex; flex-direction: column; gap: 10px; margin: 8px 0 16px; }

.ticket-nachricht {
    border: 1px solid var(--border);
    border-left: 3px solid var(--border-strong);
    border-radius: var(--radius);
    padding: 8px 12px;
    background: var(--surface-2);
}

.ticket-nachricht-kopf { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 13px; }
.ticket-nachricht-antwort { border-left-color: var(--accent); }
.ticket-nachricht-notiz { border-left-color: var(--warning); }
.ticket-nachricht-system { border-left-color: var(--border); color: var(--text-muted); font-size: 13px; }
.ticket-marke.ticket-antwort { border-color: var(--accent); color: var(--accent); }
.ticket-marke.ticket-notiz { border-color: var(--warning); color: var(--warning); }

.ticket-neu { border-top: 1px solid var(--border); padding-top: 12px; }

.ticket-angabe {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 5px 0;
    border-bottom: 1px solid var(--border);
}

.ticket-angabe:last-of-type { border-bottom: none; }
.ticket-angabe > span:last-child { text-align: right; }

.ticket-summe { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; }

.ticket-zeit-zeile {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 0;
    border-top: 1px solid var(--border);
}

.ticket-zeit-zeile > div:first-child { flex: 1; min-width: 0; }
.ticket-zeit-zeile .duration { white-space: nowrap; }

/* Die Filterzeile bricht auf schmalen Geraeten um, statt zu schrumpfen. */
.filter-zeile { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; }
.filter-zeile > * { flex: 1 1 160px; min-width: 0; margin-bottom: 0; }

/* Ein Suchfeld steht nicht in der allgemeinen Liste der Eingaben -- es kaeme
   sonst mit der Eigenbreite des Browsers daher und liefe aus seiner Spalte
   heraus. Hier bekommt es dasselbe Mass wie seine Nachbarn. */
.filter-zeile input[type=search] {
    width: 100%;
    min-width: 0;
    height: var(--control);
    padding: 8px 10px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: 6px;
}

/* Das Kaestchen traegt keine Beschriftung ueber sich und waechst deshalb
   nicht mit: Es steht so breit da, wie sein Text lang ist. */
.filter-zeile .checkbox { flex: 0 0 auto; height: var(--control); }

/* Kontaktpersonen im Dialog: eine Liste und darunter das Formular. */
.ticket-kontakte { margin: 12px 0; }

.ticket-kontakt {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 0;
    border-bottom: 1px solid var(--border);
}

.ticket-kontakt:last-child { border-bottom: none; }

.ticket-kontakt-formular {
    border-top: 1px solid var(--border);
    padding-top: 12px;
    margin-top: 12px;
}

.ticket-marke.ticket-portal { border-color: var(--running); color: var(--running); }

/* Die Dateien eines Tickets. */
.ticket-datei {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 10px;
    padding: 5px 0;
    border-bottom: 1px solid var(--border);
}

.ticket-datei:last-of-type { border-bottom: none; }
.ticket-datei a { word-break: break-word; }

.ticket-nachricht-dateien { margin-top: 8px; display: flex; flex-direction: column; gap: 2px; font-size: 13px; }

/* Die Adressen des Portals stehen in den Einstellungen zum Herauskopieren. */
.portal-block {
    border-top: 1px solid var(--border);
    margin-top: 16px;
    padding-top: 12px;
}

/* Was die Prüfung des Mailwegs sagt. */
.mail-fehler { color: var(--danger); }

/*
 * Woran die Einrichtung des Ticketsystems noch hängt.
 *
 * Kein Häkchen-Bild, sondern ein Zeichen und ein Satz: Was fehlt, soll man
 * lesen können, nicht deuten müssen. Die Farbe trägt nichts allein – daneben
 * steht immer der Text, und für ein Vorleseprogramm der Zustand in Worten.
 */
.pruefliste {
    list-style: none;
    margin: 0;
    padding: 0;
}

.pruefliste li {
    display: flex;
    gap: 8px;
    align-items: baseline;
    padding: 4px 0;
}

.pruef-zeichen {
    flex: 0 0 auto;
    width: 14px;
    text-align: center;
    font-weight: 700;
}

.pruefliste .ist-gut .pruef-zeichen { color: var(--running); }
.pruefliste .ist-offen .pruef-zeichen { color: var(--text-muted); }

/* Nur für Vorleseprogramme: sichtbar nirgends, hörbar überall. */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Die Ziffer in der Navigation: wie viele Tickets noch Arbeit sind. */
.nav-zahl {
    display: inline-block;
    min-width: 18px;
    padding: 0 5px;
    margin-left: 6px;
    border-radius: 999px;
    background: var(--accent);
    color: #fff;
    font-size: 11px;
    line-height: 18px;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

/* ---------- Druckansicht des Berichts ---------- */

/*
 * Ein PDF entsteht über den Druckdialog des Browsers. Gedruckt wird aber nicht
 * der Bildschirm: Filterkästen, Balken und Schaltflächen gehören nicht auf
 * einen Nachweis. Der Bogen wird beim Klick gebaut, steht als einziger im
 * Druck sichtbar da und verschwindet danach wieder.
 */
.druckbogen { display: none; }

@media print {
    body.druckt #app > :not(main),
    body.druckt main > :not(.druckbogen),
    body.druckt .toast-area,
    body.druckt .skip-link { display: none !important; }

    body.druckt { background: #fff; }
    body.druckt .druckbogen { display: block; color: #000; }

    /*
     * Auf Papier traegt nichts mehr die Polsterung des Bildschirms.
     *
     * `main` hielt oben 24 und unten 80 Punkte frei -- Platz fuer die
     * Fussleiste, die es im Druck nicht gibt. Der Bogen passte damit zwar auf
     * ein Blatt, das Dokument war aber hundert Punkte hoeher als er, und
     * genau daran entstand die zweite, fast leere Seite.
     */
    body.druckt main {
        max-width: none;
        margin: 0;
        padding: 0;
    }

    .druck-kopf { margin-bottom: 12px; }
    .druck-kopf h1 { margin: 0 0 2px; font-size: 16pt; }
    .druck-kopf p { margin: 0; font-size: 9pt; }
    .druck-kopf ul { margin: 5px 0 0; padding-left: 15px; font-size: 8.5pt; }
    .druck-datum { margin-top: 4px !important; color: #555; }

    /*
     * Auf dem Querbogen steht der Kopf einzeilig.
     *
     * Zeitraum, Mitarbeiter und Personentag untereinander kosten drei Zeilen
     * Hoehe -- genau die, an denen die zweite Tabelle scheiterte. Nebeneinander
     * ist dieselbe Auskunft eine Zeile.
     */
    .druckbogen-quer .druck-kopf ul {
        display: flex;
        flex-wrap: wrap;
        gap: 2px 18px;
        margin-left: 0;
        padding-left: 0;
        list-style: none;
    }

    .druckbogen h2 {
        margin: 20px 0 8px;
        font-size: 11pt;
        text-transform: uppercase;
        letter-spacing: .04em;
    }

    .druck-tabelle { width: 100%; border-collapse: collapse; font-size: 9.5pt; }
    .druck-tabelle th {
        text-align: left;
        font-size: 8pt;
        text-transform: uppercase;
        letter-spacing: .03em;
        border-bottom: 1px solid #999;
        padding: 0 6px 4px 0;
    }
    .druck-tabelle td { padding: 4px 6px 4px 0; border-bottom: 1px solid #ddd; vertical-align: top; }
    .druck-tabelle .num { text-align: right; padding-right: 0; font-variant-numeric: tabular-nums; }
    .druck-tabelle tfoot td { border-top: 1.5px solid #999; border-bottom: none; font-weight: 700; }
    .druck-tabelle tr.druck-gruppe td { font-weight: 600; }

    /* Die Aufschlüsselung einer Gruppe: eingerückt, ohne eigene Trennlinie –
       sie gehört zur Zeile darüber und soll den Block nicht zerschneiden. */
    .druck-tabelle tr.druck-kind td { border-bottom: none; color: #444; }
    .druck-tabelle tr.druck-kind + tr.druck-gruppe td { border-top: 1px solid #ddd; }
    .druck-tabelle .nowrap { white-space: nowrap; }

    /* Die Kopfzeile wiederholt sich auf jeder Seite, Zeilen brechen nicht um. */
    .druck-tabelle thead { display: table-header-group; }
    .druck-tabelle tr { break-inside: avoid; }
    .druck-zeiten { font-size: 8.5pt; }

    /*
     * Der Bogen mit den Kreuztabellen liegt quer.
     *
     * Einunddreissig Tagesspalten passen hochkant auf kein Blatt. Eine
     * benannte Seite laesst genau diesen Bogen drehen und die uebrigen --
     * Nachweis, Baum -- stehen, wo sie stehen.
     */
    /*
     * Quer liegt das Blatt, nicht ein Abschnitt darin.
     *
     * Vorher tat das eine benannte Seite (`page: quer`). Sie drehte zwar, warf
     * aber einen Seitenumbruch davor -- aus einem Bogen wurden zwei, der erste
     * leer. Gedruckt wird ohnehin immer nur ein Bogen; welches Format er
     * braucht, setzt deshalb `App.druckformat()` beim Drucken als eigene
     * Regel ein und nimmt sie danach wieder weg.
     */

    /* Auf Papier gibt es kein Scrollen: Was der Kasten sonst abschneidet,
       muss hier sichtbar sein. */
    .druckbogen .tafel-rollen { overflow: visible; }

    /*
     * Die Tafel bekommt genau die Breite des Blattes.
     *
     * Ohne `table-layout: fixed` nimmt sie sich, was ihr Inhalt verlangt --
     * bei einunddreissig Tagesspalten rund vierzehnhundert Punkte. Das ist
     * breiter als ein Querformat, und Chromium bricht dann *seitlich* um:
     * Aus einem Bogen wurden drei Seiten, von denen zwei fast leer waren.
     * Fest verteilt teilen sich die Spalten den vorhandenen Platz.
     */
    .druckbogen .tafel { width: 100%; font-size: 7pt; }
    .druckbogen .tafel th,
    .druckbogen .tafel td { padding: 2px 3px; }

    /*
     * Nur die breite Tafel wird fest verteilt.
     *
     * Ohne `table-layout: fixed` nimmt sie sich, was ihr Inhalt verlangt --
     * bei einunddreissig Tagesspalten rund vierzehnhundert Punkte, breiter als
     * ein Querformat. Die schmale Projekttafel braucht das nicht und saehe
     * damit schlechter aus: Zwei Spalten, fest verteilt, reissen in der Mitte
     * ein Loch auf.
     */
    /*
     * Auf dem Zeitnachweis stehen zwei Tabellen, und sie sollen wie eine
     * Drucksache aussehen.
     *
     * Der Baum bringt die Groesse seines eigenen Bogens mit (9,5 Punkt) -- dort
     * steht er allein auf einem Blatt und darf das. Hier steht unter ihm eine
     * Tafel in sechs Punkt, und der Groessenunterschied las sich wie zwei
     * Blaetter, die jemand uebereinandergelegt hat. Enger gesetzt bleibt
     * ausserdem Platz: Bei einem Dutzend Nummern entschied das darueber, ob der
     * Nachweis auf ein Blatt passt.
     */
    .druckbogen-nachweis .druck-tabelle { font-size: 7.5pt; }

    .druckbogen-nachweis .druck-tabelle th,
    .druckbogen-nachweis .druck-tabelle td { padding: 2px 4px; }

    .druckbogen .tafel-anteile {
        table-layout: fixed;
        font-size: 6pt;
    }

    /*
     * Drei Punkte zwischen den Spalten, nicht einer.
     *
     * Die Zahlen stehen rechtsbuendig: Der Strich einer leeren Spalte sass
     * damit unmittelbar vor der Zahl der naechsten und las sich als „-33,3".
     * Seit die erste Spalte nur noch eine Nummer traegt, ist der Platz dafuer
     * da.
     */
    .druckbogen .tafel-anteile th,
    .druckbogen .tafel-anteile td { padding: 2px 3px; }

    /*
     * Die erste Spalte traegt eine Nummer, die letzte die Summe.
     *
     * Sechzehn Prozent waren es, solange die Bezeichnung darin stand -- jetzt
     * steht dort „420" oder „ohne", und was uebrig bleibt, verteilt sich auf
     * die Tage. Die letzte braucht mehr als ein Tag: In ihr steht in der
     * Fusszeile die Gesamtzeit („24:10"), und sie hat ihren Rand zum
     * Blattende, sonst sitzt die Zahl auf der Schnittkante.
     */
    .druckbogen .tafel-anteile > thead > tr > *:first-child,
    .druckbogen .tafel-anteile > tbody > tr > *:first-child,
    .druckbogen .tafel-anteile > tfoot > tr > *:first-child { width: 8%; }

    .druckbogen .tafel-anteile > thead > tr > *:last-child,
    .druckbogen .tafel-anteile > tbody > tr > *:last-child,
    .druckbogen .tafel-anteile > tfoot > tr > *:last-child {
        width: 8%;
        padding-right: 4px;
    }

    .druckbogen .tafel-anteile th[scope="col"] { font-size: 5.5pt; line-height: 1.15; }

    /*
     * Keine Farbflaechen auf dem Nachweis.
     *
     * Am Bildschirm trennen sie Wochenende von Werktag und heben die groessten
     * Anteile hervor. Auf Papier druckt sie nicht jeder Drucker, und wo doch,
     * sind sie grau und stoeren die Zahlen darin.
     */
    .druckbogen .tafel td,
    .druckbogen .tafel th { background: none !important; }

    /*
     * Nichts klebt auf Papier.
     *
     * Am Bildschirm bleibt die erste Spalte jeder Tafel stehen, waehrend man
     * seitwaerts rollt. Auf dem Blatt gibt es kein Rollen -- eine klebende
     * Spalte loest sich dort von ihren Zeilen und landet als eigener Block
     * neben der Tabelle. Die Regel gilt fuer alle Tafeln, nicht nur fuer die
     * eine: Sonst faellt beim naechsten Zusatz wieder eine durch.
     */
    .druckbogen .tafel > thead > tr > *,
    .druckbogen .tafel > tbody > tr > *,
    .druckbogen .tafel > tfoot > tr > *,
    .druckbogen .bericht-tafel > thead > tr > *,
    .druckbogen .bericht-tafel > tbody > tr > *,
    .druckbogen .bericht-tafel > tfoot > tr > * {
        position: static !important;
        box-shadow: none !important;
    }

    /*
     * Der Bogen traegt keine Karten.
     *
     * Am Bildschirm fasst eine Karte zusammen, was zusammengehoert -- auf
     * Papier tut das der Weissraum, und Rahmen, Schatten und Fuellung kosten
     * nur die Hoehe, die am Ende fuer die zweite Tabelle fehlt.
     */
    .druckbogen .card,
    .druckbogen .tafel-karte {
        margin: 0;
        padding: 0;
        border: none;
        border-radius: 0;
        background: none;
        box-shadow: none;
    }

    .druckbogen .card-head { padding: 0; border: none; }

    /*
     * Die Ueberschrift steht einmal.
     *
     * Der Bogen setzte eine eigene ueber jede Karte, und die Karte brachte
     * ihre eigene mit -- auf dem Blatt stand „Anteil je Kostentraeger"
     * zweimal untereinander. Die der Karte bleibt: An ihr haengt der Satz,
     * der sagt, was die Zahlen bedeuten.
     */
    .druckbogen > h2 { display: none; }

    .druckbogen .card-head h2 {
        margin: 0 0 2px;
        font-size: 10pt;
        text-transform: uppercase;
        letter-spacing: .04em;
    }

    .druckbogen .card-head .muted { font-size: 7.5pt; color: #555; }

    /* Eine Tabelle wird nicht zerschnitten, solange sie als Ganzes passt. */
    .druckbogen .tafel-karte { break-inside: avoid; margin-bottom: 10px; }

    @page { margin: 14mm 12mm; }
}

/*
 * Die Auswertung „Zeit je Kunde und Ticket".
 *
 * Zwei Ebenen in einer Tabelle: der Kunde als Zeile mit seiner Summe, darunter
 * seine Tickets. Die Einrückung macht die Ebene sichtbar, ohne eine zweite
 * Tabelle zu brauchen.
 */
.auswertung-liste .auswertung-kunde td {
    font-weight: 600;
    background: var(--surface-2);
    border-top: 1px solid var(--border);
}

.auswertung-liste tbody td:first-child { padding-left: 24px; }
.auswertung-liste .auswertung-kunde td:first-child { padding-left: 12px; }
.auswertung-liste tfoot td { font-weight: 600; border-top: 2px solid var(--border-strong); }

/* ---------- Urlaub: Kacheln ---------- */

/*
 * Der eigene Stand auf einen Blick. Der Rest ist die Zahl, um die es geht –
 * er steht vorn, ist breiter und farbig hinterlegt.
 */
.kacheln {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 14px;
    margin-bottom: 18px;
}

.kacheln-konto { grid-template-columns: minmax(220px, 1.6fr) repeat(4, minmax(130px, 1fr)); }

.kachel {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
    padding: 16px 18px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

.kachel-label { font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted); font-weight: 600; }
.kachel-zahl { font-size: 32px; line-height: 1.1; font-weight: 700; font-variant-numeric: tabular-nums; }
.kachel-zahl small { font-size: 15px; font-weight: 500; color: var(--text-muted); }
.kachel-unter { font-size: 13px; color: var(--text-muted); }

.kachel-haupt { background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 35%, transparent); }
.kachel-haupt .kachel-zahl { font-size: 42px; color: var(--accent); }
.kachel-haupt.ist-negativ .kachel-zahl { color: var(--danger); }
.kachel-offen .kachel-zahl { color: var(--warning); }

.kachel-balken {
    height: 6px;
    margin: 6px 0 2px;
    border-radius: 3px;
    background: color-mix(in srgb, var(--accent) 18%, transparent);
    overflow: hidden;
}

.kachel-balken > div { height: 100%; background: var(--accent); border-radius: 3px; }

@media (max-width: 900px) {
    .kacheln-konto { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .kacheln-konto .kachel-haupt { grid-column: 1 / -1; }
}

@media (max-width: 560px) {
    .kacheln { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
    .kachel { padding: 12px 14px; }
    .kachel-zahl { font-size: 26px; }
    .kachel-haupt { grid-column: 1 / -1; }
}

/* ---------- Urlaub: Planung ---------- */

.vorschlag {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr) auto;
    align-items: center;
    gap: 16px;
    padding: 13px 16px;
}

.vorschlag-faktor {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 56px;
    border-radius: var(--radius);
    background: var(--running-soft);
    color: var(--running);
}

.vorschlag-faktor-zahl { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; }
.vorschlag-faktor-text { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; }
.vorschlag-titel { font-size: 15px; margin-bottom: 2px; }
.vorschlag-anlass { color: var(--accent); margin-top: 2px; }
.vorschlag.ist-zu-viel .vorschlag-faktor { background: var(--surface-2); color: var(--text-muted); }

.planung-raster {
    display: grid;
    grid-template-columns: minmax(240px, 1fr) minmax(0, 2.4fr);
    gap: 18px;
    align-items: start;
}

.feiertage { display: flex; flex-direction: column; gap: 2px; }

.feiertag {
    display: grid;
    grid-template-columns: 92px minmax(0, 1fr);
    gap: 0 10px;
    padding: 7px 0;
    border-bottom: 1px solid var(--border);
}

.feiertag:last-child { border-bottom: none; }
.feiertag-datum { font-variant-numeric: tabular-nums; font-weight: 600; }
.feiertag-hinweis { grid-column: 2; font-size: 12px; color: var(--running); }
.feiertag.ist-wochenende .feiertag-hinweis { color: var(--text-muted); }
.feiertag.ist-vergangen { opacity: .55; }

.kal-vorschlag:not(.kal-urlaub) {
    background: var(--running-soft);
    color: var(--running);
    box-shadow: inset 0 0 0 1px var(--running);
    font-weight: 600;
}

.cal-swatch.kal-vorschlag-probe { background: var(--running-soft); border: 1px solid var(--running); }

@media (max-width: 900px) {
    .planung-raster { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 560px) {
    .vorschlag { grid-template-columns: 52px minmax(0, 1fr); }
    .vorschlag > button { grid-column: 1 / -1; }
}

/* Übersicht: der eigene Stand vorn, farbig; die Zahlen des Tages daneben. */
.kacheln-uebersicht .kachel-haupt .kachel-zahl { font-size: 34px; }
.kachel-dienst .kachel-zahl { color: var(--running); }
.kachel-hinweis .kachel-zahl { color: var(--warning); }

@media (max-width: 560px) {
    .kacheln-uebersicht .kachel-haupt { grid-column: auto; }
    .kacheln-uebersicht .kachel-haupt .kachel-zahl { font-size: 26px; }
}
.uebersicht > .kacheln, .uebersicht > .card { margin-bottom: 0; }

/* ---------- Aufgaben ---------- */

/* Links die Listen, rechts die Aufgaben. Auf dem Telefon fällt die Spalte weg
   und eine Auswahl über den Aufgaben tritt an ihre Stelle. */
.todo-layout { display: flex; gap: 16px; align-items: flex-start; }
.todo-listen {
    flex: 0 0 230px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.todo-haupt { flex: 1 1 auto; min-width: 0; }
.todo-listenwahl { display: none; }

.todo-listeneintrag { display: flex; align-items: center; gap: 2px; border-radius: var(--radius); }
.todo-listeneintrag:hover { background: var(--surface-2); }
.todo-listeneintrag.ist-aktiv { background: var(--accent-soft); }
.todo-listenlink {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 8px;
    color: var(--text);
    text-decoration: none;
}
.todo-listeneintrag.ist-aktiv .todo-listenlink { color: var(--accent); font-weight: 600; }
.todo-listenname { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.todo-listenzahl {
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}

/* Das Menü einer Liste: am Schreibtisch erst beim Zeigen oder Tasten sichtbar,
   mit dem Finger immer -- dort gibt es kein Zeigen. */
.todo-listenmenue { opacity: 0; border: none; background: transparent; color: var(--text-muted); }
.todo-listeneintrag:hover .todo-listenmenue,
.todo-listenmenue:focus-visible { opacity: 1; }
@media (pointer: coarse) { .todo-listenmenue { opacity: 1; } }

.todo-neue-liste {
    margin-top: 6px;
    border: 1px dashed var(--border-strong);
    background: transparent;
    color: var(--text-muted);
    text-align: left;
}
.todo-neue-liste:hover { color: var(--accent); border-color: var(--accent); }

.todo-archiv { margin-top: 8px; font-size: 13px; color: var(--text-muted); }
.todo-archiv summary { cursor: pointer; padding: 4px 8px; }

.todo-punkt {
    flex: 0 0 auto;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--text-muted);
}
.todo-punkt.ohne-farbe { background: transparent; border: 2px solid var(--border-strong); }

/* Schnelleingabe */
/*
 * Der Kopf der Liste: Schnelleingabe, eine Werkzeugzeile, Filter auf Abruf.
 *
 * Vorher standen hier bis zu sechs Reihen Bedienung über der ersten Aufgabe.
 * Jetzt sind es zwei: das Feld für die neue Aufgabe und eine Zeile aus Suche
 * und „Filter“. Was gefiltert ist, steht als kleine Marke darunter.
 */

/* Die Schnelleingabe als ein Feld: Plus, Text, Zielliste, Knopf. */
.todo-schnell {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 10px;
    padding: 4px 4px 4px 12px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    transition: border-color .15s ease, box-shadow .15s ease;
}
.todo-schnell:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.todo-schnell-plus { flex: none; color: var(--text-muted); font-size: 20px; line-height: 1; }
.todo-schnell input.todo-schnell-titel {
    flex: 1 1 0;
    width: auto;
    min-width: 0;
    height: 38px;
    min-height: 38px;
    padding: 0 4px;
    border: none;
    background: transparent;
    box-shadow: none;
    outline: none;
}
.todo-schnell-zielwahl {
    display: flex;
    align-items: center;
    gap: 4px;
    flex: 0 1 auto;
    min-width: 0;
    margin: 0;
    font-size: 13px;
    font-weight: 400;
    color: var(--text-muted);
}
.todo-schnell select.todo-schnell-ziel {
    width: auto;
    max-width: 150px;
    min-width: 0;
    height: 30px;
    min-height: 30px;
    padding: 0 6px;
    border: 1px solid transparent;
    border-radius: 6px;
    background-color: var(--surface-2);
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
}
.todo-schnell .todo-schnell-knopf { flex: none; height: 38px; min-height: 38px; padding: 0 14px; }

/* Die Werkzeugzeile: Suche und der Knopf für die Filter. */
.todo-werkzeug { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; }
.todo-werkzeug input[type=search] {
    flex: 1 1 auto;
    min-width: 0;
    height: var(--control);
    padding: 8px 10px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: 6px;
}
.todo-filterknopf {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0 12px;
    font-weight: 500;
}
.todo-filterknopf[aria-expanded=true] { background: var(--surface-2); border-color: var(--text-muted); }
.todo-filterknopf.hat-filter { border-color: var(--accent); color: var(--accent); }
/* Drei Striche, kürzer werdend – das übliche Zeichen für „eingrenzen“. */
.todo-filtersymbol {
    width: 14px;
    height: 10px;
    background:
        linear-gradient(currentColor, currentColor) 0 0 / 14px 2px no-repeat,
        linear-gradient(currentColor, currentColor) 2px 4px / 10px 2px no-repeat,
        linear-gradient(currentColor, currentColor) 5px 8px / 4px 2px no-repeat;
}
.todo-filterzahl {
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 9px;
    background: var(--accent);
    color: var(--surface);
    font-size: 11px;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
}

/* Das Feld mit den Filtern, aufgeklappt unter der Werkzeugzeile. */
.todo-filterpanel {
    display: grid;
    gap: 10px;
    margin: -2px 0 12px;
    padding: 12px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
}
.todo-filterpanel[hidden] { display: none; }
.todo-filtergruppe { display: grid; grid-template-columns: 80px minmax(0, 1fr); align-items: center; gap: 8px; }
.todo-filtername { font-size: 13px; font-weight: 500; color: var(--text-muted); }
.todo-chips { max-width: 100%; }
.todo-chips .schalter-knopf { white-space: nowrap; }
.todo-sortierung { display: flex; align-items: center; gap: 6px; max-width: 100%; min-width: 0; }
.todo-sortierung select { width: auto; min-width: 0; max-width: 100%; flex: 1 1 auto; }
.todo-richtung { min-width: 40px; font-size: 1.05em; line-height: 1; }

/* Was gerade filtert: kleine Marken, ein Tipp löst sie. */
.todo-aktivfilterleiste { display: flex; flex-wrap: wrap; gap: 6px; margin: -2px 0 12px; }
.todo-aktivfilter {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 28px;
    min-height: 28px;
    padding: 0 6px 0 10px;
    border: 1px solid var(--accent);
    border-radius: 14px;
    background: var(--accent-soft);
    color: var(--text);
    font-size: 13px;
}
.todo-aktivfilter-x { color: var(--text-muted); font-size: 15px; line-height: 1; }
.todo-aktivfilter:hover .todo-aktivfilter-x { color: var(--text); }

/* Die kleinen Knöpfe neben der Listenwahl. */
.todo-symbolknopf { flex: none; width: var(--control); font-size: 18px; line-height: 1; }

/* Die Zeilen */
.todo-liste { list-style: none; margin: 0; padding: 0; }
.todo-zeile {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 10px 14px;
    border-bottom: 1px solid var(--border);
}
.todo-zeile:last-child { border-bottom: none; }
.todo-zeile:hover { background: var(--surface-2); }

/* Das Kästchen ist die Hauptsache der Zeile: gross genug für den Daumen, und
   die Fläche darum herum gehört dazu. */
/*
 * Selbst gezeichnet: Safari auf dem iPhone malt ein eigenes Kästchen, im
 * dunklen Modus als schwarze Fläche – man sah nicht, dass es ein Kästchen ist.
 * Ein Ring, der sich beim Abhaken grün füllt und einen Haken zeigt.
 */
.todo-haken {
    -webkit-appearance: none;
    appearance: none;
    flex: 0 0 auto;
    display: inline-grid;
    place-content: center;
    width: 22px;
    height: 22px;
    min-height: 0;
    margin: 1px 0 0;
    padding: 0;
    border: 2px solid var(--border-strong);
    border-radius: 50%;
    background: var(--surface);
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease;
}
.todo-haken::after {
    content: "";
    width: 10px;
    height: 6px;
    margin-top: -2px;
    border: solid var(--surface);
    border-width: 0 0 2px 2px;
    transform: rotate(-45deg) scale(0);
    transition: transform .15s ease;
}
.todo-haken:hover { border-color: var(--running); }
.todo-haken:checked { background: var(--running); border-color: var(--running); }
.todo-haken:checked::after { transform: rotate(-45deg) scale(1); }
.todo-haken:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (pointer: coarse) { .todo-haken { width: 26px; height: 26px; min-height: 0; } .todo-haken::after { width: 12px; height: 7px; } }
@media (prefers-reduced-motion: reduce) { .todo-haken, .todo-haken::after { transition: none; } }

.todo-inhalt {
    flex: 1 1 auto;
    min-width: 0;
    display: block;
    height: auto;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--text);
    text-align: left;
    white-space: normal;
    font: inherit;
    cursor: pointer;
}
.todo-kopf { display: flex; gap: 8px; align-items: baseline; }
.todo-titel { min-width: 0; }
.todo-nr { flex: 0 0 auto; font-variant-numeric: tabular-nums; color: var(--text-muted); font-size: 13px; }
.todo-titel { font-weight: 600; overflow-wrap: anywhere; }
/* Unter dem Titel: vorn die wenigen Marken, die drängen, dahinter alles
   Übrige als eine leise graue Zeile mit Punkten dazwischen. */
.todo-unterzeile { display: flex; gap: 4px 10px; flex-wrap: wrap; align-items: center; margin-top: 3px; }
.todo-marken { display: inline-flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.todo-meta { display: inline-flex; flex-wrap: wrap; align-items: center; font-size: 12px; color: var(--text-muted); min-width: 0; }
.todo-meta > * + *::before { content: "·"; margin: 0 6px; color: var(--border-strong); }

.todo-zeile.ist-erledigt .todo-titel { text-decoration: line-through; color: var(--text-muted); font-weight: 400; }
.todo-zeile.ist-erledigt .todo-unterzeile { opacity: .65; }

.todo-marke {
    display: inline-block;
    padding: 0 8px;
    border-radius: 999px;
    border: 1px solid var(--border-strong);
    font-size: 12px;
    line-height: 1.7;
    white-space: nowrap;
    color: var(--text-muted);
}
.todo-prio-hoch { background: var(--danger-soft); border-color: var(--danger); color: var(--danger); }
.todo-ueberfaellig { border-color: var(--danger); color: var(--danger); font-weight: 600; }
.todo-heute-faellig { border-color: var(--warning); color: var(--warning); font-weight: 600; }
.todo-erinnerung-jetzt { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); font-weight: 600; }
/* In der grauen Zeile hebt sich nur Claude ab: seine Aufgaben will man finden. */
.todo-meta .todo-wer-claude { color: var(--accent); font-weight: 600; }
.todo-wiederhol-hinweis { margin: 6px 2px 0; }
.todo-wiederhol-hinweis[hidden] { display: none; }
.todo-heute-punkt { background: var(--accent); }
.todo-heute + .todo-listeneintrag { margin-top: 2px; }

/* Übersicht: eine schmale Zeile, kein Kasten. */
.aufgaben-heute {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--accent-soft);
    color: var(--accent);
    text-decoration: none;
    font-weight: 600;
}
.aufgaben-heute:hover { border-color: var(--accent); }
.aufgaben-heute-zahl { font-variant-numeric: tabular-nums; }

.todo-listenmarke { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-muted); }

/* Farbwahl im Listendialog */
.todo-farben { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 6px; }
.todo-farbe {
    width: 28px;
    height: 28px;
    min-width: 0;
    padding: 0;
    border-radius: 50%;
    border: 2px solid transparent;
    outline-offset: 2px;
}
.todo-farbe.ohne-farbe { background: transparent; border-color: var(--border-strong); }
.todo-farbe.ist-aktiv { border-color: var(--text); box-shadow: 0 0 0 2px var(--surface) inset; }

/* Schlüssel für Claude */
.todo-zwischentitel { font-size: 14px; margin: 18px 0 8px; }
.todo-schluessel-zeile {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    padding: 8px 0;
    border-bottom: 1px solid var(--border);
}
.todo-schluessel-zeile:last-child { border-bottom: none; }
.todo-kopierzeile { display: flex; gap: 8px; align-items: flex-end; }
.todo-kopierzeile input { flex: 1 1 auto; min-width: 0; }
.todo-neuer-schluessel {
    margin-top: 14px;
    padding: 12px;
    border: 1px solid var(--running);
    border-radius: var(--radius);
    background: var(--running-soft);
}
.todo-anleitung { margin-top: 10px; }
.todo-befehl {
    display: block;
    margin-top: 4px;
    padding: 8px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    font-size: 12px;
    overflow-wrap: anywhere;
    user-select: all;
}

@media (max-width: 720px) {
    .todo-layout { flex-direction: column; align-items: stretch; gap: 12px; }
    .todo-listen { display: none; }
    .todo-listenwahl { display: flex; gap: 8px; margin-bottom: 12px; }
    .todo-listenwahl select { flex: 1 1 auto; min-width: 0; }
    /* Auf dem Telefon trägt der Knopf nur das Plus – der Platz gehört dem Text. */
    .todo-schnell .todo-schnell-knopftext { font-size: 0; }
    .todo-schnell .todo-schnell-knopftext::before { content: "+"; font-size: 22px; line-height: 1; }
    .todo-schnell .todo-schnell-knopf { width: 44px; padding: 0; }
    .todo-schnell-plus { display: none; }
    .todo-schnell { padding-left: 8px; }
    /* Die Zielliste erst beim Schreiben, dann als eigene Zeile im Feld. */
    .todo-schnell { flex-wrap: wrap; }
    .todo-schnell-zielwahl { display: none; order: 3; flex: 1 1 100%; padding: 0 0 4px 4px; }
    .todo-schnell:focus-within .todo-schnell-zielwahl,
    .todo-schnell.hat-text .todo-schnell-zielwahl { display: flex; }
    .todo-schnell select.todo-schnell-ziel { max-width: none; flex: 1 1 auto; }
    .todo-filtergruppe { grid-template-columns: 1fr; gap: 6px; }
    .todo-chips { display: flex; flex-wrap: wrap; gap: 6px; border: none; overflow: visible; }
    .todo-chips .schalter-knopf, .todo-chips .schalter-knopf + .schalter-knopf {
        border: 1px solid var(--border-strong);
        border-radius: var(--radius);
    }
    .todo-kopierzeile { flex-wrap: wrap; }
}
/* Verlauf einer Aufgabe (Mini-Blog im Bearbeiten-Dialog) */
.todo-verlaufmarke { font-variant-numeric: tabular-nums; }

/* ---------- Die Aufgabenkarte (Bearbeiten-Dialog) ---------- */

/*
 * Die Karte ist ein Eigenschaftsblatt, kein Formular.
 *
 * Vorher stand jedes Feld als eigener Block untereinander – Beschriftung,
 * Feld, Abstand, sieben Mal, auf dem Telefon über drei Bildschirme. Jetzt
 * steht oben der Titel, darunter ein ruhiger Kasten, in dem jede Eigenschaft
 * eine Zeile ist: Beschriftung links, Wert rechts. Die Werte sind Felder ohne
 * eigenen Rahmen; erst wer darauf zeigt oder sie anwählt, sieht, dass man sie
 * ändern kann. Darunter der Verlauf als Zeitleiste.
 */
.modal.todo-dialog { max-width: 600px; margin-bottom: 24px; }

/*
 * Die Fussleiste klebt am unteren Rand des Bildlaufs. Der Hintergrund hat
 * dort aber 40 Punkte Innenabstand, und um diese stünde sie zu hoch – darunter
 * schaute ein Streifen Inhalt hervor. Der Abstand wandert deshalb an den
 * Dialog selbst.
 */
.modal-backdrop:has(> .todo-dialog) { padding-bottom: 0; }
.todo-dialog .modal-body { padding: 4px 20px 20px; }

/* Speichern bleibt in Reichweite, auch am Ende eines langen Verlaufs. */
.todo-dialog footer {
    position: sticky;
    bottom: 0;
    background: var(--surface);
    border-radius: 0 0 10px 10px;
    z-index: 1;
}

/* Der Titel: gross, umbrechend, ohne Kasten – bis man hineinklickt. */
.todo-dialog-kopf { margin: 0 0 14px; }
.todo-dialog .todo-dialog-titel {
    display: block;
    width: 100%;
    min-height: 0;
    margin: 0 -8px;
    width: calc(100% + 16px);
    padding: 10px 8px;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    font-size: 19px;
    font-weight: 650;
    line-height: 1.3;
    letter-spacing: -0.01em;
    resize: none;
    overflow: hidden;
    overflow-wrap: anywhere;
}
.todo-dialog .todo-dialog-titel:hover { background: var(--surface-2); }
.todo-dialog .todo-dialog-titel:focus { background: var(--surface); border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--accent-soft); }

/* Das Blatt */
.todo-blatt {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface-2);
    overflow: hidden;
}
.todo-blatt .todo-eig {
    display: grid;
    grid-template-columns: 96px minmax(0, 1fr);
    align-items: center;
    gap: 0 8px;
    margin: 0;
    padding: 2px 6px 2px 14px;
    min-height: 46px;
}
.todo-blatt .todo-eig + .todo-eig { border-top: 1px solid var(--border); }
.todo-blatt .todo-eig > label {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    font-size: 13px;
    font-weight: 500;
    color: var(--text-muted);
}
.todo-eig-wert { position: relative; display: flex; align-items: center; min-width: 0; }

/* Die Werte: Felder ohne eigenen Rahmen, die sich erst bei Berührung zeigen. */
.todo-blatt select,
.todo-blatt input[type=date] {
    width: 100%;
    min-width: 0;
    height: 38px;
    min-height: 38px;
    padding: 0 8px;
    border: 1px solid transparent;
    border-radius: 6px;
    background-color: transparent;
    font-weight: 500;
    color: var(--text);
    cursor: pointer;
}
.todo-blatt select:hover,
.todo-blatt input[type=date]:hover { background-color: var(--surface); border-color: var(--border); }
.todo-blatt select:focus-visible,
.todo-blatt input[type=date]:focus-visible { background-color: var(--surface); border-color: var(--accent); outline: none; box-shadow: 0 0 0 3px var(--accent-soft); }

/*
 * Das Datumsfeld auf dem iPhone.
 *
 * Safari gibt `input[type=date]` eine eigene Mindestbreite und setzt den Wert
 * in die Mitte – im Dialog lief das Feld deshalb über den rechten Rand. Ohne
 * die eigene Darstellung des Systems hält es sich an die Breite der Zeile.
 */
.todo-dialog input[type=date] {
    -webkit-appearance: none;
    appearance: none;
    display: block;
    max-width: 100%;
    text-align: left;
}
.todo-dialog input[type=date]::-webkit-date-and-time-value { text-align: left; margin: 0; }

/* Der Punkt vor der Priorität – dieselben Farben wie an der Zeile. */
.todo-prio-punkt {
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--text-muted);
}
.todo-prio-punkt[data-prio=hoch] { background: var(--danger); }
.todo-prio-punkt[data-prio=mittel] { background: var(--warning); }
.todo-prio-punkt[data-prio=niedrig] { background: var(--border-strong); }

/* ---------- Der Verlauf als Zeitleiste ---------- */

.todo-verlauf { margin-top: 26px; }
.todo-abschnittstitel {
    margin: 0 0 10px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* Der neue Eintrag: erst eine Zeile, beim Schreiben das Übrige. */
.todo-eintragform { min-width: 0; }
.todo-eintragform .field { margin-bottom: 10px; }
.todo-eintragform-neu {
    padding: 4px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    transition: border-color .15s ease, box-shadow .15s ease;
}
.todo-eintragform-neu.ist-offen { padding: 10px; border-color: var(--border-strong); box-shadow: var(--shadow); }
.todo-eintragform-neu > .field:first-child { margin: 0; }
.todo-eintragform-neu > .field:first-child input { border-color: transparent; background: transparent; }
.todo-eintragform-neu.ist-offen > .field:first-child { margin-bottom: 10px; }
.todo-eintragform-neu.ist-offen > .field:first-child input { border-color: var(--border-strong); background: var(--surface); }
.todo-eintragform-mehr { display: none; }
.todo-eintragform-neu.ist-offen .todo-eintragform-mehr { display: block; }
.todo-eintragform textarea { min-height: 76px; resize: vertical; }

.todo-eintragform-fuss {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 8px 12px;
    flex-wrap: wrap;
}
.todo-eintragform-fuss .field { margin: 0; }
.todo-eintragform-datum { flex: 0 1 170px; min-width: 0; }
.todo-eintragform-knoepfe { display: flex; align-items: center; gap: 4px; margin-left: auto; }

/* Die Einträge an einer senkrechten Linie, das Neueste oben. */
.todo-eintraege {
    position: relative;
    margin-top: 16px;
    padding-left: 20px;
}
.todo-eintraege::before {
    content: "";
    position: absolute;
    left: 4px;
    top: 8px;
    bottom: 8px;
    width: 2px;
    border-radius: 1px;
    background: var(--border);
}
.todo-eintrag { position: relative; padding: 0 0 18px; min-width: 0; }
.todo-eintrag:last-child { padding-bottom: 2px; }
.todo-eintrag::before {
    content: "";
    position: absolute;
    left: -20px;
    top: 5px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--surface);
    border: 2px solid var(--border-strong);
    box-sizing: border-box;
}
.todo-eintrag:first-child::before { border-color: var(--accent); background: var(--accent); }
.todo-eintrag.todo-eintragform::before { border-color: var(--accent); }
.todo-eintrag.todo-eintragform {
    padding: 10px;
    margin-bottom: 14px;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius);
    background: var(--surface);
}
.todo-eintrag.todo-eintragform::before { left: -21px; top: 15px; }

.todo-eintrag-kopf { display: flex; align-items: center; gap: 8px; min-height: 20px; }
.todo-eintrag-datum {
    font-size: 12px;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
}
.todo-eintrag-titel {
    margin: 2px 0 0;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.35;
    overflow-wrap: anywhere;
}
.todo-eintrag-text {
    margin-top: 4px;
    color: var(--text);
    line-height: 1.5;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}
.todo-eintrag-knoepfe { display: flex; gap: 2px; margin: 4px 0 0 -6px; }
.todo-eintrag-knoepfe .btn-link {
    height: auto;
    min-height: 0;
    padding: 4px 6px;
    font-size: 13px;
    color: var(--text-muted);
}
.todo-eintrag-knoepfe .btn-link:hover { color: var(--text); }
.todo-link-gefahr.btn-link,
.todo-eintrag-knoepfe .todo-link-gefahr:hover { color: var(--danger); }
.todo-verlauf-leer { margin: 12px 0 0; color: var(--text-muted); font-size: 14px; }

/* Ganz unten, leise: die Aufgabe löschen. */
.todo-dialog-ausweg { margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--border); }
.todo-dialog-ausweg .btn-link { height: auto; padding: 4px 0; font-size: 14px; }

@media (pointer: coarse) {
    .todo-eintrag-knoepfe .btn-link { min-height: 36px; padding: 8px 10px; }
    .todo-blatt select, .todo-blatt input[type=date] { min-height: 42px; height: 42px; }
}

@media (max-width: 480px) {
    .todo-dialog .modal-body { padding: 4px 16px 16px; }
    .todo-blatt .todo-eig { grid-template-columns: 84px minmax(0, 1fr); padding-left: 12px; }
    .todo-dialog .todo-dialog-titel { font-size: 18px; }
}

@media (prefers-reduced-motion: reduce) {
    .todo-eintragform-neu { transition: none; }
}
.todo-inhalt:hover, .todo-inhalt:focus { background: transparent; }
.todo-farbe:hover { background-color: var(--surface-2); }
.todo-farbe:not(.ohne-farbe):hover { opacity: .85; }
.todo-listenmenue:hover { background: var(--surface); }
