/* Zeiterfassung - Dark Theme (BUILD.md §9) */

:root {
    /* Flaechen: tiefes Schwarz als Basis, Karten leicht angehoben.
       Dunkles Thema ist das einzige Thema (siehe BUILD.md §9). */
    --bg: #0b0d11;
    --bg-alt: #12151b;
    --card: #171b22;
    --card-hoch: #1e232b;
    --line: #272d38;
    --line-stark: #3a4250;

    /* Text: Koerpertext >= 4.5:1, Sekundaertext >= 3:1 gegen --bg. */
    --text: #e8eaee;
    --muted: #a2a9b4;

    /* Statusfarben - jeweils mit Symbol oder Text kombiniert, nie allein. */
    /* Akzent: helles Blau. Kontrast gegen --bg rund 9:1, damit es auch als
       reine Textfarbe (Saldo, Verweise) lesbar bleibt. */
    --accent: #38bdf8;
    --accent-ink: #04121b;
    --danger: #f4695f;
    --warn: #f5b544;
    /* Hinweise standen bisher in einem Blau, das dem neuen Akzent zu nahe kam:
       Erfolg und Hinweis waren kaum auseinanderzuhalten. Violett liegt im
       Farbkreis weit genug entfernt. */
    --info: #a78bfa;

    --radius: 14px;
    --radius-klein: 10px;

    /* Abstandsraster (4er-Schritte), dicht genug für Datenansichten. */
    --raum-1: 0.25rem;
    --raum-2: 0.5rem;
    --raum-3: 0.75rem;
    --raum-4: 1rem;
    --raum-6: 1.5rem;
    --raum-8: 2rem;
    --gap: var(--raum-4);

    /* Bewegungsdauern: kurz und einheitlich. */
    --dauer-schnell: 120ms;
    --dauer-normal: 200ms;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font: 16px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

h1, h2 { line-height: 1.25; margin: 0 0 0.75rem; font-weight: 600; letter-spacing: -0.01em; }
h1 { font-size: 1.4rem; }
h2 { font-size: 1.1rem; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ------------------------------------------------------------ Kopfzeile */

.topbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem 1.25rem;
    padding: 0.9rem 1.25rem;
    background: var(--bg-alt);
    border-bottom: 1px solid var(--line);
}

.topbar .brand { font-weight: 700; color: var(--text); letter-spacing: -0.02em; }
.topbar nav { display: flex; flex-wrap: wrap; gap: 0.4rem 1.4rem; margin-right: auto; }
.topbar nav a { color: var(--muted); }
.topbar nav a:hover { color: var(--text); text-decoration: none; }
.topbar nav a.is-active { color: var(--accent); }
.topbar .logout { margin: 0; }

/* Drei Gruppen statt acht gleich aussehender Verweise: Zeit, Abrechnung,
   Einstellungen. Der Strich dazwischen macht die Gliederung sichtbar, ohne
   dass ein Klappmenü und damit JavaScript nötig würde. */
.topbar .navgroup { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 1rem; }
.topbar .navgroup + .navgroup { padding-left: 1.4rem; border-left: 1px solid var(--line); }

/* --------------------------------------------------------------- Layout */

.wrap { max-width: 62rem; margin: 0 auto; padding: var(--gap); display: grid; gap: var(--gap); }
.foot { color: var(--muted); font-size: 0.8rem; padding-top: 0; }
.foot p { margin: 0; }

.card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 1.25rem;
}

.card-narrow { max-width: 34rem; width: 100%; margin: 0 auto; }
.day-today { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); }

.grid { display: grid; gap: var(--gap); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }

.row { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; }
.row-between { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; justify-content: space-between; }

/* Ueberschriften in einer solchen Zeile bringen sonst ihren unteren
   Außenabstand mit und sitzen dadurch nicht auf einer Linie mit dem Knopf. */
.row-between > h1,
.row-between > h2 { margin: 0; }

/* Der weggefallene Abstand der Ueberschrift wird der Zeile selbst gegeben,
   damit der folgende Inhalt nicht anstößt. */
.card > .row-between { margin-bottom: var(--raum-3); }
.nav-week { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.stack { display: grid; gap: 0.6rem; }

/* -------------------------------------------------------------- Formular */

label { color: var(--muted); font-size: 0.85rem; }

input[type="text"], input[type="email"], input[type="password"],
input[type="date"], input[type="time"], input[type="number"],
input[type="tel"], input[type="url"], select {
    width: 100%;
    padding: 0.65rem 0.75rem;
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--line);
    border-radius: 10px;
    font: inherit;
    color-scheme: dark;
}

/*
 * Datum und Uhrzeit auf allen Geräten gleich darstellen.
 *
 * iOS Safari zeichnet diese Felder als eigenes Bedienelement: der Wert steht
 * mittig, ein Symbol zum Öffnen gibt es nicht - die Maske sah dort deutlich
 * anders aus als auf dem Rechner. Mit abgeschalteter nativer Darstellung
 * verhalten sie sich wie gewöhnliche Textfelder; das Symbol kommt als
 * Hintergrundbild dazu und ist damit überall vorhanden.
 */
input[type="date"], input[type="time"] {
    -webkit-appearance: none;
    appearance: none;
    text-align: left;
    /* iOS bemisst die Höhe sonst nach dem Inhalt und damit uneinheitlich. */
    min-height: 2.9rem;
    padding-right: 2.5rem;
    background-repeat: no-repeat;
    background-position: right 0.75rem center;
    background-size: 1.15rem 1.15rem;
}

input[type="date"] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23a2a9b4'%3E%3Cpath d='M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19a2 2 0 0 0 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11z'/%3E%3C/svg%3E");
}

input[type="time"] {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23a2a9b4'%3E%3Cpath d='M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67z'/%3E%3C/svg%3E");
}

/*
 * Chrome bringt ein eigenes Symbol mit, das sonst doppelt erschiene. Es wird
 * unsichtbar gemacht, bleibt aber die Schaltfläche, die den Auswähler öffnet -
 * es liegt genau über dem eingeblendeten Symbol.
 */
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator {
    opacity: 0;
    cursor: pointer;
}

input:focus, select:focus { border-color: var(--accent); outline: none; }

/*
 * Auswahlfelder.
 *
 * Sie hatten bisher gar keine Regel und kamen deshalb in der Darstellung des
 * Betriebssystems - hell, mit eigener Schrift und eigener Hoehe. Neben den
 * dunklen Textfeldern sah das aus wie ein Fremdkoerper. Die native
 * Darstellung wird darum abgeschaltet und der Pfeil als Hintergrundbild
 * gesetzt, genau wie bei den Datums- und Uhrzeitfeldern.
 *
 * Die Klappliste selbst zeichnet weiterhin das Betriebssystem; color-scheme
 * und die Regel fuer option sorgen dafuer, dass sie ebenfalls dunkel bleibt.
 */
select {
    -webkit-appearance: none;
    appearance: none;
    min-height: 2.9rem;
    padding-right: 2.5rem;
    cursor: pointer;
    background-repeat: no-repeat;
    background-position: right 0.75rem center;
    background-size: 1.15rem 1.15rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23a2a9b4'%3E%3Cpath d='M7.41 8.59 12 13.17l4.59-4.58L18 10l-6 6-6-6z'/%3E%3C/svg%3E");
}

select option { background: var(--bg-alt); color: var(--text); }

/* ------------------------------------------------------- Grosse Formulare
   Ausstellerprofil und Auftraggeber tragen ueber zwanzig Felder. Als eine
   lange Spalte ist das auf dem Rechner eine Wueste; deshalb sitzen die
   Felder in beschrifteten Gruppen, und die Gruppen stehen ab Desktop
   nebeneinander. Auf dem Handy bleibt genau eine Spalte - die Reihenfolge
   der Gruppen ist dann die Lesereihenfolge.

   Ein System fuer beide Formulare: was hier steht, benutzen views/
   settings_billing.php und views/customer_form.php gemeinsam. */

.form { display: grid; gap: var(--gap); align-items: start; }

.form-group {
    display: grid;
    gap: 0.6rem;
    align-content: start;
    margin: 0;
    padding: var(--raum-4);
    border: 1px solid var(--line);
    border-radius: var(--radius-klein);
    background: var(--bg-alt);
    /* fieldset bringt eigene Mindestbreiten mit und sprengte sonst das
       Raster, sobald ein Feld breiter wird als seine Spalte. */
    min-width: 0;
}

.form-group > legend {
    padding: 0 0.4rem;
    color: var(--text);
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

/* Ein Feld: Beschriftung, Eingabe, darunter ggf. Hinweis und Fehler. */
.field { display: grid; gap: 0.25rem; min-width: 0; }

/* Ankreuzfeld: Kaestchen und Beschriftung in einer Zeile. Die Beschriftung
   traegt hier den ganzen Satz und darf deshalb nicht kleiner sein als der
   Fliesstext - anders als die kurzen Beschriftungen ueber den Eingaben. */
.checkbox {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    color: var(--text);
    font-size: 0.9rem;
    cursor: pointer;
}

.checkbox input[type="checkbox"] {
    flex: 0 0 auto;
    width: 1.1rem;
    height: 1.1rem;
    margin: 0.1rem 0 0;
    accent-color: var(--accent);
}

.field-error {
    margin: 0;
    font-size: 0.8rem;
    color: var(--danger);
}

/* Ein bemaengeltes Feld muss auch ohne die Meldung auffindbar sein. */
[aria-invalid="true"] { border-color: var(--danger); }

/* Zwei schmale Felder nebeneinander INNERHALB einer Gruppe, etwa PLZ und
   Ort. Die Mindestbreite ist deutlich kleiner als bei .grid-2: eine Gruppe
   ist auf dem Rechner nur eine halbe Spalte breit und auf einem 390 Pixel
   breiten Schirm innen keine 19rem - mit 15rem je Feld stuende das Paar
   ueberall untereinander und die Regel waere wirkungslos. */
.field-pair {
    display: grid;
    gap: var(--raum-3);
    grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
}

.form-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.75rem;
}

@media (min-width: 52rem) {
    /* Ab hier zwei Spalten. Der Wert liegt bewusst ueber dem Umbruchpunkt
       der Navigation (45rem): erst wenn die Kopfzeile wieder oben sitzt,
       ist der Bildschirm auch fuer zwei Spalten Formular breit genug. */
    .form-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* Gruppen, die ueber beide Spalten laufen, und die Knopfzeile. */
    .form-grid > .form-group-wide,
    .form-grid > .form-actions { grid-column: 1 / -1; }
}

.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.85rem; }

/* --------------------------------------------------------------- Buttons */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.65rem 1.1rem;
    border: 1px solid transparent;
    border-radius: 10px;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    background: var(--line);
    color: var(--text);
}

.btn:hover { filter: brightness(1.12); text-decoration: none; }
.btn[disabled] { opacity: 0.6; cursor: progress; }

.btn-accent { background: var(--accent); color: var(--accent-ink); }
.btn-danger { background: var(--danger); color: #fff; }
.btn-ghost { background: transparent; border-color: var(--line); color: var(--text); }
.btn-small { padding: 0.35rem 0.7rem; font-size: 0.85rem; }
.btn-icon { padding: 0.5rem; }
.btn .icon { width: 1.15rem; height: 1.15rem; }

/* Wochennavigation: Pfeile außen, Zeitraum mittig. */
.weeknav { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.weeknav h1 { margin: 0; text-align: center; font-size: 1.15rem; }
.weeknav-range { display: block; font-size: 0.85rem; font-weight: 400; color: var(--muted); }

/* --------------------------------------------------------------- Inhalte */

.status { display: flex; align-items: center; gap: 0.5rem; font-size: 1.05rem; margin: 0; }

.dot { width: 10px; height: 10px; border-radius: 50%; background: var(--muted); display: inline-block; }
.dot-live { background: var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 25%, transparent); }

.live-timer { color: var(--muted); font-variant-numeric: tabular-nums; }

.kv { display: grid; grid-template-columns: auto 1fr; gap: 0.35rem 1rem; margin: 0; }
.kv dt { color: var(--muted); font-size: 0.85rem; }
.kv dd { margin: 0; font-variant-numeric: tabular-nums; }
.kv-inline { margin-top: 1rem; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); }
.kv-inline dt { grid-row: 1; }
.kv-inline dd { grid-row: 2; }

.big { font-size: 1.35rem; font-weight: 600; }
.pos { color: var(--accent); }
.neg { color: var(--warn); }
.muted { color: var(--muted); }
.hint { color: var(--muted); font-size: 0.78rem; }
.summary { margin: 0; color: var(--muted); }
.summary strong { color: var(--text); }

.table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.table th, .table td { text-align: left; padding: 0.55rem 0.6rem; border-bottom: 1px solid var(--line); }
.table th { color: var(--muted); font-size: 0.78rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; }
.table tr:last-child td { border-bottom: none; }
.table .actions { display: flex; gap: 0.4rem; justify-content: flex-end; }
.table .actions form { margin: 0; }

.tag {
    display: inline-block; padding: 0.1rem 0.45rem; border-radius: 999px;
    background: var(--bg); border: 1px solid var(--line); color: var(--muted); font-size: 0.75rem;
}

.warnings { list-style: none; padding: 0; margin: 1rem 0 0; display: grid; gap: 0.4rem; }

.badge {
    padding: 0.45rem 0.7rem;
    border-radius: 10px;
    font-size: 0.88rem;
    border: 1px solid;
}

.badge-warn   { color: var(--warn);   border-color: color-mix(in srgb, var(--warn) 45%, transparent);   background: color-mix(in srgb, var(--warn) 12%, transparent); }
.badge-danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 45%, transparent); background: color-mix(in srgb, var(--danger) 12%, transparent); }
.badge-info   { color: var(--info);   border-color: color-mix(in srgb, var(--info) 45%, transparent);   background: color-mix(in srgb, var(--info) 12%, transparent); }

/* --------------------------------------------------------- Meldungsecke
   Meldungen standen frueher als Block am Seitenanfang und schoben den
   Inhalt nach unten. Jetzt schweben sie oben rechts ueber der Seite - auf
   dem Handy oben ueber die volle Breite, weil unten Symbolleiste und
   Start/Stopp-Leiste sitzen.

   Sichtbarkeit liegt ausschliesslich hier: ohne JavaScript bleibt jede
   Meldung stehen. toast.js nimmt sie nur weg. */

.toasts {
    position: fixed;
    top: calc(env(safe-area-inset-top, 0px) + 0.75rem);
    right: 0.75rem;
    /* Ueber Kopfzeile (50), unterer Leiste (60) und Start/Stopp-Leiste (50),
       aber unter dem Bestaetigungsdialog (200): der verlangt eine Antwort. */
    z-index: 150;
    display: grid;
    gap: 0.5rem;
    width: min(26rem, calc(100vw - 1.5rem));
    /* Die Ecke selbst faengt keine Klicks ab, nur die Meldungen darin. */
    pointer-events: none;
}

.toasts:empty { display: none; }

.toast {
    pointer-events: auto;
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.7rem 0.6rem 0.7rem 0.9rem;
    border: 1px solid var(--line-stark);
    border-left-width: 4px;
    border-radius: var(--radius-klein);
    background: color-mix(in srgb, var(--card-hoch) 97%, #000);
    color: var(--text);
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
}

.toast-text { margin: 0; flex: 1 1 auto; font-size: 0.9rem; overflow-wrap: anywhere; }

.toast-close {
    flex: 0 0 auto;
    width: 1.9rem;
    height: 1.9rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: 1px solid transparent;
    border-radius: 8px;
    background: transparent;
    color: var(--muted);
    font: inherit;
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
}

.toast-close:hover { color: var(--text); border-color: var(--line); }

.toast-success { border-left-color: var(--accent); }
.toast-success .toast-text { color: var(--accent); }
.toast-danger  { border-left-color: var(--danger); }
.toast-danger .toast-text { color: var(--danger); }
.toast-warn    { border-left-color: var(--warn); }
.toast-warn .toast-text { color: var(--warn); }
.toast-info    { border-left-color: var(--info); }
.toast-info .toast-text { color: var(--info); }

/* Ausklang beim Schliessen. Nur ueber eine Klasse, die toast.js setzt -
   nie beim Einblenden, sonst waere die Meldung ohne JavaScript unsichtbar. */
.toast.is-weg { opacity: 0; transform: translateX(0.75rem); transition: opacity var(--dauer-normal), transform var(--dauer-normal); }

@media (max-width: 45rem) {
    .toasts { left: 0.75rem; right: 0.75rem; width: auto; }
}

/* ------------------------------------------------- Start/Stopp-Leiste
   Feste Leiste am unteren Rand, mobile first: runder Start-Knopf links,
   Beschriftung mittig, Stopp-Knopf rechts. Liegt in der Daumenzone. */

.timerbar {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    /* Auf kleinen Bildschirmen sitzt darunter die Symbolnavigation. */
    bottom: calc(0.9rem + env(safe-area-inset-bottom) + var(--nav-height, 0px));
    z-index: 50;
    width: min(32rem, calc(100% - 1.6rem));
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding: 0.6rem 0.7rem;
    border-radius: 999px;
    background: color-mix(in srgb, var(--card) 92%, #000);
    border: 1px solid var(--line);
    box-shadow: 0 18px 45px -20px #000, 0 2px 10px -4px #000;
    backdrop-filter: blur(12px);
}

.timerbar-form { margin: 0; display: flex; }

.timerbar-btn {
    width: 3.25rem;
    height: 3.25rem;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    transition: transform 0.12s ease, opacity 0.12s ease;
}

.timerbar-btn svg { width: 1.6rem; height: 1.6rem; fill: currentColor; }
.timerbar-btn:active { transform: scale(0.94); }

.timerbar-start { background: var(--accent); color: var(--accent-ink); }
.timerbar-stop  { background: var(--line);   color: var(--text); }

/* Laufende Erfassung: der Stopp-Knopf wird zum aktiven Element. */
.timerbar-start[disabled] { background: var(--line); color: var(--muted); cursor: default; }
.timerbar-stop:not([disabled]) { background: var(--danger); color: #fff; }
.timerbar-stop[disabled] { color: var(--muted); cursor: default; }

.timerbar-label {
    flex: 1 1 auto;
    margin: 0;
    text-align: center;
    font-size: 1.02rem;
    font-weight: 600;
    color: var(--accent);
    line-height: 1.25;
}

.timerbar-running { color: var(--text); }
.timerbar-pausiert { color: var(--warn); }

/* Der linke Knopf zeigt je nach Zustand Start oder Pause. */
.timerbar-btn .symbol-start,
.timerbar-btn .symbol-pause { display: flex; }
.timerbar-btn [hidden] { display: none; }
.timerbar-timer { color: var(--muted); font-weight: 400; font-variant-numeric: tabular-nums; }

/* Hinweis auf offline gepufferte Klicks - sitzt über der Leiste. */
.timerbar-pending {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    bottom: calc(100% + 0.5rem);
    margin: 0;
    white-space: nowrap;
    padding: 0.35rem 0.75rem;
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 500;
    color: var(--warn);
    border: 1px solid color-mix(in srgb, var(--warn) 45%, transparent);
    background: color-mix(in srgb, var(--warn) 16%, var(--bg));
}

.timerbar-pending[hidden] { display: none; }

/* Rückmeldung, wenn eine Aktion nichts bewirkt hat. */
.timerbar-pending.is-hinweis {
    color: var(--danger);
    border-color: color-mix(in srgb, var(--danger) 45%, transparent);
    background: color-mix(in srgb, var(--danger) 16%, var(--bg));
    white-space: normal;
    max-width: min(22rem, 90vw);
    text-align: center;
}

/* Platz schaffen, damit die schwebenden Leisten nichts verdecken.
   Der Wert wird zur Laufzeit aus den tatsächlichen Hoehen von Start/Stopp-
   Leiste und Symbolnavigation gesetzt (siehe app.js); die Angabe hier ist
   nur der Ausgangswert, falls kein JavaScript läuft. */
.wrap-with-bar { padding-bottom: var(--leisten-hoehe, 7rem); }
.foot.wrap-with-bar { padding-bottom: calc(var(--leisten-hoehe, 7rem) + 1rem); }

.hint-bar { margin: 0.75rem 0 0; font-size: 0.85rem; }

/* ----------------------------------------------------------- Zeitleiste
   Tagesbearbeitung: Blöcke ziehen, Kanten fassen, Pausen freischneiden. */

.tageditor-kopf { display: grid; gap: 0.6rem; margin-bottom: 1rem; }

.modus { display: inline-flex; gap: 0.25rem; padding: 0.25rem; background: var(--bg); border: 1px solid var(--line); border-radius: 999px; width: fit-content; }

.modus-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.45rem 0.9rem;
    border: none;
    border-radius: 999px;
    background: none;
    font: inherit;
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--muted);
    cursor: pointer;
}

.modus-btn .icon { width: 1.1rem; height: 1.1rem; }
.modus-btn.is-active { background: var(--accent); color: var(--accent-ink); }

/* Feste Höhe je Stunde statt Stauchung auf einen Bildschirm: sonst sind
   kurze Einträge nicht greifbar. Der Bereich scrollt. */
.zeitleiste {
    --stunden-hoehe: 4.5rem;
    display: grid;
    grid-template-columns: 3.4rem 1fr;
    gap: 0.5rem;
    max-height: min(60vh, 34rem);
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
}

.zeitleiste-skala,
.zeitleiste-flaeche { height: calc(var(--stunden-hoehe) * 24); }

/* Freiraum am unteren Ende, damit sich auch die letzten Stunden über die
   schwebende Start/Stopp-Leiste hinausschieben lassen. */
.zeitleiste::after {
    content: '';
    grid-column: 1 / -1;
    height: var(--leisten-hoehe, 7rem);
}

.zeitleiste-skala { position: relative; }

.zeitleiste-marke {
    position: absolute;
    right: 0;
    transform: translateY(-50%);
    font-size: 0.72rem;
    color: var(--muted);
    font-variant-numeric: tabular-nums;
}

.zeitleiste-flaeche {
    position: relative;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 12px;
    overflow: hidden;
    touch-action: none;          /* Ziehen darf die Seite nicht scrollen */
    cursor: crosshair;
}

.zeitleiste-raster { position: absolute; inset: 0; pointer-events: none; }

.zeitleiste-linie {
    position: absolute;
    left: 0;
    right: 0;
    height: 1px;
    background: var(--line);
    opacity: 0.5;
}

.zeitleiste-linie.is-stark { opacity: 1; }

.zeitleiste-bloecke { position: absolute; inset: 0; }

.block {
    position: absolute;
    left: 0.35rem;
    right: 0.35rem;
    border-radius: 10px;
    padding: 0.25rem 0.5rem;
    font-size: 0.78rem;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 0.1rem;
}

/* Auch ein Arbeitseintrag von wenigen Sekunden muss bedienbar bleiben:
   Zeitangabe und Loeschknopf brauchen Platz. Pausen sind davon
   ausgenommen - sie zeigen die tatsaechliche Dauer und werden nicht
   einzeln gelöscht. */
.block-arbeit { min-height: 2.4rem; }

/* Zu kurz für zwei Zeilen: Zeit und Knopf nebeneinander. */
.block-arbeit[data-kurz="1"] {
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
    padding-block: 0.15rem;
}

/* Flache Pausen: nur die Zeitangabe, einzeilig und ohne Zwang zur Höhe. */
.block-pause[data-kurz="1"] {
    flex-direction: row;
    align-items: center;
    gap: 0.4rem;
    padding-block: 0;
    padding-inline: 0.45rem;
    font-size: 0.72rem;
}

.block[data-kurz="1"] .block-text { display: none; }

.block[data-kurz="1"] .block-weg {
    position: static;
    margin-left: auto;
    flex: 0 0 auto;
    opacity: 1;
}

/* Kurze Blöcke können sich beruehren - der angefasste kommt nach vorn. */
.block-arbeit:hover,
.block-arbeit:focus-within,
.block-pause.is-fix:hover { z-index: 3; }

.block-zeit { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.block-text { color: inherit; opacity: 0.75; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.block-arbeit {
    background: color-mix(in srgb, var(--accent) 24%, var(--card));
    border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
    color: var(--text);
    cursor: grab;
    touch-action: none;
}

.block-arbeit:active { cursor: grabbing; }
.block-arbeit.is-laufend { border-style: dashed; }

.block-pause {
    background: color-mix(in srgb, var(--warn) 16%, var(--card));
    border: 1px dashed color-mix(in srgb, var(--warn) 50%, transparent);
    color: var(--warn);
    pointer-events: none;
}

.block-pause.is-kurz { opacity: 0.55; }

/* Bewusst eingetragene Pause: gesperrter Bereich, deutlich abgesetzt. */
.block-pause.is-fix {
    background: repeating-linear-gradient(
        135deg,
        color-mix(in srgb, var(--warn) 20%, var(--card)),
        color-mix(in srgb, var(--warn) 20%, var(--card)) 8px,
        color-mix(in srgb, var(--warn) 12%, var(--card)) 8px,
        color-mix(in srgb, var(--warn) 12%, var(--card)) 16px
    );
    border-style: solid;
    border-color: color-mix(in srgb, var(--warn) 65%, transparent);
    pointer-events: auto;
}

.block-pause.is-fix .block-weg { opacity: 0; }
.block-pause.is-fix:hover .block-weg { opacity: 1; }

.block-vorschau {
    background: color-mix(in srgb, var(--accent) 30%, transparent);
    border: 1px dashed var(--accent);
    pointer-events: none;
}

.block-vorschau.block-pause { background: color-mix(in srgb, var(--warn) 25%, transparent); border-color: var(--warn); }

/* Greifkanten zum Ändern der Dauer.
   Sichtbar schmal, Trefferflaeche aber groß genug für den Finger. */
.griff {
    position: absolute;
    left: 0;
    right: 0;
    height: 16px;
    cursor: ns-resize;
    touch-action: none;
}

/* Unsichtbar vergrößerte Trefferflaeche (Mindestmaß für Berührung). */
.griff::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    height: 44px;
}

.griff-oben { top: -3px; }
.griff-unten { bottom: -3px; }

/* Bei sehr kurzen Blöcken dürfen sich die Flaechen nicht überlagern. */
.block-arbeit[data-kurz="1"] .griff::before { height: 24px; }

.griff::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 2rem;
    height: 3px;
    border-radius: 2px;
    background: color-mix(in srgb, var(--accent) 70%, transparent);
}

.block-weg {
    position: absolute;
    top: 2px;
    right: 4px;
    width: 1.4rem;
    height: 1.4rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 50%;
    background: color-mix(in srgb, var(--danger) 20%, transparent);
    color: var(--danger);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.12s ease;
}

.block-arbeit:hover .block-weg,
.block-arbeit:focus-within .block-weg { opacity: 1; }

/* Während des Ziehens tritt die schwebende Leiste zurück, damit sie die
   Zeitleiste nicht verdeckt. */
body.zieht .timerbar { opacity: 0.12; pointer-events: none; }
.timerbar { transition: opacity var(--dauer-normal) ease; }

/* Sichtbarer Fokus auf Blöcken für die Tastaturbedienung. */
.block-arbeit:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    z-index: 2;
}

/* Leerer Tag: erklaeren statt kommentarlos leere Fläche zeigen. */
.zeitleiste-leer {
    display: flex;
    align-items: center;
    gap: var(--raum-3);
    margin-bottom: var(--raum-3);
    padding: var(--raum-3) var(--raum-4);
    border: 1px dashed var(--line-stark);
    border-radius: var(--radius-klein);
    background: var(--bg);
    color: var(--muted);
    text-align: left;
}

.zeitleiste-leer .icon { width: 1.5rem; height: 1.5rem; flex: 0 0 auto; opacity: 0.6; }
.zeitleiste-leer strong { color: var(--text); font-weight: 600; display: block; }
.zeitleiste-leer span { font-size: 0.86rem; }
.zeitleiste-leer > div { display: grid; gap: 0.15rem; }

.tageditor-status { min-height: 1.4rem; margin: 0.75rem 0 0; font-size: 0.88rem; color: var(--muted); }

/* Rueckgaengig-Angebot nach dem Löschen. */
.tageditor-status .undo {
    margin-left: 0.6rem;
    padding: 0.2rem 0.6rem;
    border: 1px solid var(--line-stark);
    border-radius: 999px;
    background: var(--card-hoch);
    color: var(--text);
    font: inherit;
    font-size: 0.82rem;
    cursor: pointer;
}

.tageditor-status .undo:hover { border-color: var(--accent); color: var(--accent); }
.tageditor-status.is-ok { color: var(--accent); }
.tageditor-status.is-fehler { color: var(--danger); }
.tageditor-status.is-hinweis { color: var(--info); }

/* Textvarianten je Bildschirmbreite. */
.nur-schmal { display: none; }

@media (max-width: 45rem) {
    .nur-breit { display: none; }
    .nur-schmal { display: inline; }
    .tageditor-kopf { gap: var(--raum-2); margin-bottom: var(--raum-3); }
    .tageditor-kopf .hint { font-size: 0.8rem; }
    .zeitleiste { max-height: 58vh; }
}

@media (max-width: 32rem) {
    .zeitleiste { grid-template-columns: 2.9rem 1fr; --stunden-hoehe: 4rem; }
    .block { font-size: 0.72rem; }
    .block-weg { opacity: 1; }
    .modus-btn { padding: 0.45rem 0.75rem; font-size: 0.85rem; }
}

/* ------------------------------------------------ Bestätigungsdialog
   Löschen verlangt eine bewusste Geste: der Regler muss durchgezogen
   werden. Ein Fehltipper löscht damit nichts. */

.dialog-overlay {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--raum-4);
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(3px);
    opacity: 0;
    transition: opacity var(--dauer-normal) ease;
}

.dialog-overlay.is-offen { opacity: 1; }

.dialog {
    --fortschritt: 0%;
    --text-deckkraft: 1;
    --griff: 3.1rem;
    width: min(25rem, 100%);
    display: grid;
    gap: var(--raum-4);
    padding: var(--raum-6);
    border: 1px solid var(--line-stark);
    border-radius: 20px;
    background: linear-gradient(180deg, var(--card-hoch), var(--card));
    box-shadow: 0 30px 70px -24px #000, 0 0 0 1px rgba(255, 255, 255, 0.03) inset;
    transform: translateY(10px) scale(0.97);
    transition: transform var(--dauer-normal) cubic-bezier(0.2, 0.9, 0.3, 1);
}

.dialog-overlay.is-offen .dialog { transform: none; }

.dialog-kopf { display: flex; align-items: center; gap: var(--raum-3); }
.dialog h2 { margin: 0; font-size: 1.15rem; }

/* Sinnbild der Aktion - macht sofort klar, worum es geht. */
.dialog-zeichen {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 50%;
    color: var(--danger);
    background: color-mix(in srgb, var(--danger) 16%, transparent);
}

.dialog-zeichen svg { width: 1.4rem; height: 1.4rem; }

.dialog-text {
    margin: 0;
    color: var(--muted);
    font-size: 0.92rem;
    font-variant-numeric: tabular-nums;
}

.dialog-abbruch {
    justify-self: center;
    padding: 0.5rem 1rem;
    border: none;
    border-radius: 999px;
    background: none;
    font: inherit;
    font-size: 0.9rem;
    color: var(--muted);
    cursor: pointer;
}

.dialog-abbruch:hover { color: var(--text); }

/* ---- Schieberegler --------------------------------------------------- */

.schieber {
    position: relative;
    height: 3.6rem;
    padding: 0.25rem;
    border-radius: 999px;
    background: var(--bg);
    border: 1px solid var(--line);
    box-shadow: 0 2px 8px -4px #000 inset;
    overflow: hidden;
    touch-action: none;
}

/* Wächst mit dem Fortschritt mit; die Breite setzt confirm.js in Pixeln. */
.schieber-fuellung {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 0;
    background: linear-gradient(90deg,
        color-mix(in srgb, var(--danger) 30%, transparent),
        color-mix(in srgb, var(--danger) 75%, transparent));
    transition: width 60ms linear;
}

.schieber-text {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding-left: var(--griff);
    font-size: 0.92rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    color: var(--text);
    opacity: var(--text-deckkraft);
    transition: opacity 80ms linear;
    pointer-events: none;
}

/* Der sichtbare Griff folgt dem Fortschritt; die Position setzt confirm.js. */
.schieber-griff {
    position: absolute;
    top: 50%;
    left: 4px;
    width: var(--griff);
    height: calc(100% - 0.5rem);
    transform: translateY(-50%);
    display: grid;
    place-items: center;
    border-radius: 999px;
    background: var(--danger);
    color: #fff;
    box-shadow: 0 6px 16px -6px #000;
    transition: left 60ms linear, background var(--dauer-normal) ease;
    pointer-events: none;
}

.schieber-griff svg { width: 1.5rem; height: 1.5rem; }

.dialog.is-bestaetigt .schieber-fuellung { width: 100% !important; }
.dialog.is-bestaetigt .schieber-griff { background: var(--accent); color: var(--accent-ink); }

/*
 * Der Regler liegt unsichtbar darüber und trägt den Wert für Tastatur und
 * Hilfsmittel. Zeiger und Finger erreichen ihn bewusst nicht: ein Bereichsfeld
 * springt beim Antippen auf die getippte Stelle, was am rechten Ende sofort
 * ein Löschen ausgelöst hätte. Das Ziehen übernimmt confirm.js.
 */
.schieber-regler {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    background: none;
    appearance: none;
    -webkit-appearance: none;
    pointer-events: none;
}

.schieber { cursor: grab; }
.schieber:active { cursor: grabbing; }

.schieber-regler::-webkit-slider-thumb {
    appearance: none;
    -webkit-appearance: none;
    width: var(--griff);
    height: 100%;
    background: transparent;
    cursor: grab;
}

.schieber-regler::-moz-range-thumb {
    width: var(--griff);
    height: 100%;
    border: none;
    background: transparent;
    cursor: grab;
}

.schieber-regler:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 999px; }

/* -------------------------------------------------- Symbole & Navigation */

.icon { width: 1.5rem; height: 1.5rem; fill: currentColor; display: block; }

/* Untere Symbolnavigation - nur auf kleinen Bildschirmen sichtbar. */
.bottomnav {
    display: none;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    justify-content: space-around;
    align-items: stretch;
    gap: 0.25rem;
    padding: 0.4rem 0.5rem calc(0.4rem + env(safe-area-inset-bottom));
    background: color-mix(in srgb, var(--bg-alt) 96%, #000);
    border-top: 1px solid var(--line);
}

.bottomnav-logout { margin: 0; display: flex; flex: 1 1 0; }

.bottomnav-item {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.2rem;
    padding: 0.35rem 0.25rem;
    border: none;
    border-radius: 12px;
    background: none;
    font: inherit;
    font-size: 0.7rem;
    color: var(--muted);
    text-decoration: none;
    cursor: pointer;
    width: 100%;
    -webkit-tap-highlight-color: transparent;
}

.bottomnav-item:hover { color: var(--text); text-decoration: none; }
.bottomnav-item.is-active { color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.bottomnav-item .icon { width: 1.45rem; height: 1.45rem; }

/* ------------------------------------------------------ Kleine Bildschirme */

@media (max-width: 45rem) {
    /* Mobil übernimmt die Symbolleiste unten die Navigation. */
    :root { --nav-height: 4.4rem; }
    .bottomnav { display: flex; }
    .topbar nav { display: none; }
    .topbar .logout { display: none; }
    .topbar { justify-content: center; padding: 0.8rem 1rem; }
    .topbar .brand { margin: 0; }

    /* Ausgangswert ohne JavaScript: Navigation plus Start/Stopp-Leiste. */
    .wrap-with-bar { padding-bottom: var(--leisten-hoehe, 12rem); }
    .foot.wrap-with-bar { padding-bottom: calc(var(--leisten-hoehe, 12rem) + 1rem); }

    /* Bezeichnung neben den Wert, und umbrechen lassen.
       Auf breiten Schirmen stehen die Bezeichnungen in Zeile 1 und die Werte
       darunter in Zeile 2. Das erzwingt aber je Eintrag eine eigene Spalte:
       bei sechs Eintraegen entstehen mehr Spalten, als auto-fit vorsieht, und
       die zusaetzlichen haben keine Mindestbreite - die Zusammenfassung lief
       damit seitlich aus dem Bild. Die Spaltenzahl bleibt gerade, sonst
       geriete ein Wert unter die Bezeichnung eines anderen Eintrags. */
    .kv-inline { grid-template-columns: repeat(4, 1fr); gap: 0.2rem 1rem; }
    .kv-inline dt, .kv-inline dd { grid-row: auto; }
}

@media (max-width: 32rem) {
    /* Kurzform vermeiden: sie würde den unten reservierten Platz für die
       schwebenden Leisten wieder überschreiben. */
    .wrap { padding-top: 1rem; padding-left: 1rem; padding-right: 1rem; gap: 1rem; }
    .card { padding: 1rem; }

    /* Bezeichnung über den Wert stellen, sonst brechen Zahlen mehrzeilig um. */
    .kv { grid-template-columns: 1fr; gap: 0; }
    .kv dt { margin-top: 0.7rem; }
    .kv dt:first-child { margin-top: 0; }
    .kv dd { margin-bottom: 0.1rem; }
    /* Noch schmaler: nur noch ein Paar je Zeile. */
    .kv-inline { grid-template-columns: repeat(2, 1fr); }

    /* Kopfzeile: Marke und Abmelden in einer Zeile, Navigation darunter. */
    .topbar { padding: 0.75rem 1rem; gap: 0.5rem 1rem; }
    .topbar .brand { margin-right: auto; }
    .topbar .logout { order: 2; }
    .topbar nav {
        order: 3;
        width: 100%;
        gap: 1rem;
        overflow-x: auto;
        flex-wrap: nowrap;
        scrollbar-width: none;
    }
    .topbar nav::-webkit-scrollbar { display: none; }
    .topbar nav a { white-space: nowrap; }

    /* Mittige Ausrichtung auch auf schmalen Schirmen beibehalten: sonst sitzt
       der Knopf oben statt auf einer Linie mit der Ueberschrift. Umbricht die
       Zeile, sorgt der Abstand für Luft. */
    .row-between { align-items: center; row-gap: 0.5rem; }
    .timerbar-label { font-size: 0.95rem; }
    .timerbar { gap: 0.6rem; }
}

/* Tabellen werden auf kleinen Bildschirmen zu Kärtchen - sonst müsste
   die Seite seitlich scrollen.

   Aufbau eines Kärtchens:
     08:00                    12:15     <- Beginn links, Ende rechts, groß
                 4 h 15 m               <- Dauer mittig, ohne Beschriftung
     NOTIZ            Projekt Alpha
     ------------------------------
     [manual]              Stift  Müll <- Quelle als Pille in der Fußzeile
*/
@media (max-width: 45rem) {
    .table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
    .table, .table tbody { display: block; width: 100%; }

    .table tr {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        border: 1px solid var(--line);
        border-radius: 12px;
        padding: 0.6rem 0.8rem;
        margin-bottom: 0.6rem;
        background: var(--bg);
    }

    .table td {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: 1rem;
        width: 100%;
        border: none;
        padding: 0.2rem 0;
    }

    .table td::before {
        content: attr(data-label);
        color: var(--muted);
        font-size: 0.78rem;
        text-transform: uppercase;
        letter-spacing: 0.04em;
    }

    /* Beginn und Ende: ohne Beschriftung, groß, außen ausgerichtet. */
    .table td[data-label="Von"],
    .table td[data-label="Bis"] {
        width: auto;
        font-size: 1.35rem;
        font-weight: 600;
        padding-top: 0;
    }

    .table td[data-label="Von"]::before,
    .table td[data-label="Bis"]::before,
    .table td[data-label="Dauer"]::before,
    .table td[data-label="Quelle"]::before { content: none; }

    .table td[data-label="Bis"] { margin-left: auto; justify-content: flex-end; }

    /* Dauer: mittig unter den beiden Zeiten. */
    .table td[data-label="Dauer"] {
        justify-content: center;
        color: var(--muted);
        font-size: 0.95rem;
        padding-bottom: 0.35rem;
    }

    /* Die eigene Quelle-Zeile entfällt - die Pille sitzt in der Fußzeile. */
    .table td[data-label="Quelle"] { display: none; }

    .table td:empty { display: none; }

    .table .actions {
        justify-content: flex-end;
        gap: 0.5rem;
        padding-top: 0.55rem;
        margin-top: 0.35rem;
        border-top: 1px solid var(--line);
    }

    .table .actions::before { content: none; }
    .table .actions .tag-fuss { display: inline-block; margin-right: auto; }

    /* In der Schmalansicht reichen Symbole. */
    .table .actions .btn-text { display: none; }
    .table .actions .btn { padding: 0.45rem 0.6rem; }
}

/* Auf breiten Schirmen bleibt die Quelle in ihrer eigenen Spalte. */
.tag-fuss { display: none; }

/* Zahlenwerte nie umbrechen lassen. */
.kv dd.big, .timerbar-label, .summary strong { white-space: nowrap; }

@media (prefers-reduced-motion: reduce) {
    * { transition: none !important; animation: none !important; }
}
