/*
    Globales CSS für Clocky, eingebunden in Components/App.razor.

    Warum global und nicht Blazor CSS Isolation:
    Scoped CSS hängt sein Scope-Attribut nur an Elemente, die in der eigenen .razor-Datei stehen.
    Alles, was eine MudBlazor-Komponente selbst rendert, bekommt es nicht — eine Regel auf
    Class="..." an einem MudIconButton greift also schlicht nicht. Dazu kommt: die beiden
    vorhandenen .razor.css-Dateien (MainLayout, NavMenu) stylen .page/.sidebar/.navbar-toggler,
    also Blazor-Template-Reste, die es in dieser Oberfläche nicht gibt. Es war hier nie verifiziert,
    dass Scoped CSS ankommt.

    wwwroot/app.css gab es einmal parallel dazu, war in App.razor aber nie verlinkt und damit
    wirkungslos — gelöscht in #99, statt die ~100 Zeilen Bootstrap-Reste scharfzuschalten.

    Farben kommen aus den Theme-Variablen, die MudThemeProvider setzt, damit hell und dunkel
    automatisch stimmen und eine Palettenänderung hier nichts nachzuziehen hat.
*/

/* ---------------------------------------------------------------------------
   Analyseblöcke (StatisticsPanel)

   Eine Ansicht für alle Breiten. Keine Breakpoints: die kompakte Fassung ist
   auch auf einem großen Bildschirm die bessere, und Clocky wird fast nur am
   Handy benutzt.
   --------------------------------------------------------------------------- */

.stats-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 12px;
}

/* Die Kopfzahlen: gearbeitet, Soll, Differenz. */
.stats-figures {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
}

.stats-figure {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    padding-left: 12px;
    border-left: 1px solid var(--mud-palette-lines-default);
}

.stats-figure:first-child {
    padding-left: 0;
    border-left: none;
}

.stats-label {
    font-size: 0.6875rem;
    line-height: 1.2;
    color: var(--mud-palette-text-secondary);
}

.stats-value {
    font-size: 1.125rem;
    font-weight: 600;
    line-height: 1.25;
    letter-spacing: -0.01em;
    white-space: nowrap;
    /* Gleich breite Ziffern, sonst tanzen die Zahlen beim Aktualisieren. */
    font-variant-numeric: tabular-nums;
}

.stats-value.is-positive {
    color: var(--mud-palette-success);
}

.stats-value.is-negative {
    color: var(--mud-palette-error);
}

.stats-caption {
    display: block;
    margin-top: 6px;
    font-size: 0.6875rem;
    line-height: 1.2;
    color: var(--mud-palette-text-secondary);
}

/* --- Prognose ----------------------------------------------------------------
   Durch eine Linie abgesetzt statt durch eine Fläche: die Prognose ist eine
   andere Art von Zahl als die darüber, aber kein anderer Block.
   --------------------------------------------------------------------------- */

.stats-forecast {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--mud-palette-lines-default);
}

.stats-forecast-label {
    display: block;
    margin-bottom: 8px;
    font-size: 0.6875rem;
    line-height: 1.2;
    color: var(--mud-palette-text-secondary);
}

/* Eine Figur seit #95 (vorher zwei konvergierende Prognosen) - kein Grid mehr nötig. */
.stats-forecast-figures {
    display: block;
}

/* ---------------------------------------------------------------------------
   Kalender (Monatsübersicht)
   --------------------------------------------------------------------------- */

.calendar-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 8px;
}

.calendar-header,
.calendar-week {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 3px;
}

.calendar-header {
    margin-bottom: 6px;
}

.calendar-week {
    margin-bottom: 3px;
}

.calendar-header-cell {
    text-align: center;
    font-size: 0.6875rem;
    font-weight: 600;
    color: var(--mud-palette-text-secondary);
}

.calendar-day-container {
    min-width: 0;
    /* Quadratisch: auf 390 px ergeben sieben Spalten rund 46 px und damit ein
       Ziel, das man mit dem Daumen trifft. */
    aspect-ratio: 1 / 1;
}

.calendar-day {
    /* Auch als <button>: keine Browser-Optik, die Fläche kommt aus DayPalette. */
    appearance: none;
    -webkit-appearance: none;
    margin: 0;
    font: inherit;
    width: 100%;
    height: 100%;
    padding: 4px;
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    overflow: hidden;
}

.calendar-day.is-clickable {
    cursor: pointer;
}

.calendar-day.is-clickable:active {
    filter: brightness(0.94);
}

.calendar-day-number {
    font-size: 0.8125rem;
    font-weight: 600;
    line-height: 1;
    text-align: left;
}

.calendar-day-note {
    font-size: 0.625rem;
    line-height: 1.1;
    text-align: right;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-variant-numeric: tabular-nums;
    opacity: 0.85;
    min-width: 0;
}

/* Abwesenheiten stehen als Symbol dort, wo bei erfassten Tagen die Zahl steht.
   "Feiertag" passte als Wort nicht in die knapp 38 px Textbreite einer Zelle.
   Zeit und Symbol bekommen je eine eigene Zeile (#148) — in einer gemeinsamen Zeile blieb von der
   Zeit nur die erste Ziffer übrig, weil Zeit, Halbtags-Markierung und Symbol sich eine Zeilenbreite
   von knapp 38 px teilen mussten. */
.calendar-day-mark {
    margin-top: auto;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 1px;
}

.calendar-day-icon-row {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 1px;
    line-height: 1;
}

.calendar-day-half {
    font-size: 0.625rem;
    line-height: 1;
}

/* MudIcon bringt seine eigene Größe mit, und selbst Size.Small ist in einer
   46-px-Zelle zu groß. Die Farbe erbt es aus der Zelle. */
.calendar-day-icon-row .mud-icon-root {
    width: 0.9375rem;
    height: 0.9375rem;
    font-size: 0.9375rem;
}

.calendar-day-empty {
    width: 100%;
    height: 100%;
}

/* Die Legende liegt jetzt hinter dem Info-Icon statt über dem Raster. */
.calendar-legend {
    padding: 8px 14px;
}

.calendar-legend-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 0;
    font-size: 0.8125rem;
    white-space: nowrap;
}

.calendar-legend-swatch {
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    border-radius: 4px;
    /* Trägt bei Abwesenheiten dasselbe Symbol wie die Zelle, damit man beides
       an einer Stelle nachschlagen kann. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.calendar-legend-swatch .mud-icon-root {
    width: 0.8125rem;
    height: 0.8125rem;
    font-size: 0.8125rem;
}

/* ---------------------------------------------------------------------------
   Wochenübersicht

   Eine Zeile je Tag statt einer Karte mit vier Feldern. Farben und Symbole
   kommen aus derselben Quelle wie im Kalender — dieselben Tage dürfen nicht
   unterschiedlich aussehen, nur weil man sie anders gruppiert.
   --------------------------------------------------------------------------- */

.week-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.week-day {
    /* Auch als <button>: keine Browser-Optik, die Fläche kommt aus DayPalette. */
    appearance: none;
    -webkit-appearance: none;
    margin: 0;
    font: inherit;
    width: 100%;
    padding: 10px 12px;
    border-radius: 10px;
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: baseline;
    gap: 2px 10px;
    text-align: left;
}

.week-day.is-clickable {
    cursor: pointer;
}

.week-day.is-clickable:active {
    filter: brightness(0.96);
}

.week-day.is-today {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: -1px;
}

.week-day-date {
    font-size: 0.875rem;
    font-weight: 600;
    display: flex;
    align-items: baseline;
    gap: 6px;
    min-width: 0;
}

.week-day-today {
    font-size: 0.625rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.75;
}

.week-day-main {
    justify-self: end;
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 1rem;
    font-weight: 600;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.week-day-main .mud-icon-root {
    width: 1rem;
    height: 1rem;
    font-size: 1rem;
}

.week-day-detail {
    grid-column: 1 / -1;
    font-size: 0.75rem;
    line-height: 1.3;
    opacity: 0.8;
}

/* ---------------------------------------------------------------------------
   Zeiterfassung

   Die laufende Zeit ist der Grund, warum man diese Seite öffnet. Sie bekommt
   den Platz, der Rest ist Beleg.
   --------------------------------------------------------------------------- */

.clock-hero {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    text-align: center;
    padding: 4px 0 16px;
}

.clock-state {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.8125rem;
    color: var(--mud-palette-text-secondary);
}

.clock-state .mud-icon-root {
    width: 1rem;
    height: 1rem;
    font-size: 1rem;
}

.clock-value {
    font-size: 2.75rem;
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: -0.02em;
    /* Ohne feste Ziffernbreite springt die Uhr bei jedem Sekundenwechsel. */
    font-variant-numeric: tabular-nums;
}

.clock-value.is-running {
    color: var(--mud-palette-success);
}

.clock-value.is-break {
    color: var(--mud-palette-warning);
}

.clock-meta {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
}

.clock-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* Pausen: eine Zeile je Pause statt einer Tabelle mit vier Spalten. */
.break-list {
    display: flex;
    flex-direction: column;
}

.break-row {
    display: grid;
    grid-template-columns: auto auto 1fr;
    align-items: baseline;
    gap: 10px;
    padding: 7px 0;
    border-bottom: 1px solid var(--mud-palette-lines-default);
    font-size: 0.875rem;
}

.break-row:last-child {
    border-bottom: none;
}

.break-span {
    font-variant-numeric: tabular-nums;
}

.break-duration {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.break-note {
    text-align: right;
    font-size: 0.6875rem;
    color: var(--mud-palette-text-secondary);
}

/* ---------------------------------------------------------------------------
   App-Bar

   Die Uhr in der Leiste. Vorher ein umrandeter Button mit dem Text
   "Arbeitszeit: 07:32:15" — in einer flachen Leiste aufgesetzt, und wegen der
   Sekunden änderte er jede Sekunde seine Breite.
   --------------------------------------------------------------------------- */

.mud-appbar {
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.appbar-clock {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    border-radius: 999px;
    cursor: pointer;
    font-size: 0.9375rem;
    font-weight: 600;
    line-height: 1;
    /* Feste Ziffernbreite, damit die Leiste beim Ticken nicht wandert. */
    font-variant-numeric: tabular-nums;
    background-color: var(--mud-palette-background-gray);
}

.appbar-clock .mud-icon-root {
    width: 1.125rem;
    height: 1.125rem;
    font-size: 1.125rem;
}

.appbar-clock.is-running {
    color: var(--mud-palette-success);
}

.appbar-clock.is-break {
    color: var(--mud-palette-warning);
}

/* Der Zustand im Menü — ein Block statt einer Reihe deaktivierter Menüeinträge. */
.appbar-clock-summary {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 10px 16px 12px;
    min-width: 190px;
}

.appbar-clock-summary-value {
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.appbar-clock-summary-value.is-running {
    color: var(--mud-palette-success);
}

.appbar-clock-summary-value.is-break {
    color: var(--mud-palette-warning);
}

/* Die Marke, sichtbar nur solange niemand angemeldet ist — siehe AppBar.razor. */
.appbar-brand {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.appbar-brand-text {
    font-weight: 600;
}


/* ---------------------------------------------------------------------------
   Überstunden — Saldo-Verlauf (nur wenn Überstunden nicht verfallen)
   --------------------------------------------------------------------------- */

.balance-chart-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 6px;
}

.balance-chart-head-label {
    font-size: 0.6875rem;
    color: var(--mud-palette-text-secondary);
}

.balance-chart-head-value {
    font-size: 1rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.balance-chart-head-value.is-positive {
    color: var(--mud-palette-success);
}

.balance-chart-head-value.is-negative {
    color: var(--mud-palette-error);
}

/* preserveAspectRatio="none" ist hier in Ordnung: es wird kein Text im SVG gezeichnet,
   und die Strichstärken hält vector-effect="non-scaling-stroke" konstant. */
.balance-chart-svg {
    width: 100%;
    height: 100px;
    display: block;
}

.balance-chart-zero {
    stroke: var(--mud-palette-lines-default);
    stroke-width: 1;
    stroke-dasharray: 2 3;
    vector-effect: non-scaling-stroke;
}

.balance-chart-line {
    fill: none;
    stroke: var(--mud-palette-primary);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.balance-chart-dot {
    fill: var(--mud-palette-primary);
}

.balance-chart-months {
    display: grid;
    gap: 2px;
    margin-top: 4px;
}

.balance-chart-months span {
    text-align: center;
    font-size: 0.625rem;
    line-height: 1;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   Überstunden — Monatswerte

   Bewusst kein SVG: <text> ist in Razor ein reserviertes Konstrukt, dessen Tag
   beim Rendern verschwindet — ein <tspan> ohne <text>-Eltern zeichnet nichts,
   und genau daran ist die Beschriftung zweimal unsichtbar geblieben. Als
   HTML-Raster sind die Schriftgrößen außerdem echte CSS-Größen und werden nicht
   durch eine viewBox skaliert.
   --------------------------------------------------------------------------- */

.monthly-bars-grid {
    display: grid;
    gap: 2px;
    align-items: end;
}

.monthly-bar-col {
    appearance: none;
    -webkit-appearance: none;
    background: none;
    border: none;
    margin: 0;
    padding: 4px 0 6px;
    font: inherit;
    color: inherit;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    border-radius: 6px;
    cursor: pointer;
}

.monthly-bar-col.is-selected {
    background: var(--mud-palette-action-default-hover);
}

/* Am eigenen Balken statt in einer Kopfzeile — die genaue Höhe kommt inline aus der
   Komponente, weil sie von der Balkenhöhe abhängt. */
.monthly-bar-value {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    font-size: 0.625rem;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.02em;
}

.monthly-bar-value.is-positive {
    color: var(--mud-palette-success);
}

.monthly-bar-value.is-negative {
    color: var(--mud-palette-error);
}

.monthly-bar-value.is-expired {
    color: var(--mud-palette-text-secondary);
}

/* Ein Monat ohne Abweichung ist eine echte Aussage und steht deshalb da — aber er soll die
   Monate mit Inhalt nicht überstimmen. */
.monthly-bar-value.is-zero {
    color: var(--mud-palette-text-secondary);
    font-weight: 400;
    opacity: 0.7;
}

/* Die Nulllinie liegt in der Mitte: darüber wächst ein Plus, darunter ein Minus.
   Höher als die Balken maximal werden, damit die Zahl über der Spitze noch Platz hat. */
.monthly-bar-plot {
    position: relative;
    width: 100%;
    height: 104px;
    display: block;
}

.monthly-bar-plot::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    border-top: 1px dashed var(--mud-palette-lines-default);
}

.monthly-bar-fill {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    width: 70%;
    max-width: 20px;
    /* Ein Monat mit Inhalt bleibt sichtbar, auch wenn er neben einem großen Ausschlag
       rechnerisch fast nichts ergibt. */
    min-height: 3px;
    border-radius: 3px;
}

.monthly-bar-fill.is-positive {
    bottom: 50%;
    background: var(--mud-palette-success);
}

.monthly-bar-fill.is-negative {
    top: 50%;
    background: var(--mud-palette-error);
}

/* Keine Füllung heißt: war da, ist es nicht mehr. Dieselbe Regel wie im Kalender,
   siehe docs/specs/2026-07-28-mobile-first-design.md. Durchgezogen statt gestrichelt:
   auf 20 px Breite zerfiel eine gestrichelte Kontur in einzelne Striche und sah aus
   wie ein Darstellungsfehler. */
.monthly-bar-fill.is-expired {
    bottom: 50%;
    background: none;
    border: 1.5px solid var(--mud-palette-success);
    opacity: 0.75;
}

/* Nur leicht abgesetzt: der laufende Monat ist noch nicht fertig, aber er ist auch die Zahl,
   wegen der man die Seite öffnet — ihn am blassesten zu zeichnen wäre verkehrt herum. */
.monthly-bar-fill.is-current {
    opacity: 0.8;
}

.monthly-bar-month {
    font-size: 0.625rem;
    line-height: 1;
    color: var(--mud-palette-text-secondary);
    white-space: nowrap;
}

.monthly-bar-col.is-selected .monthly-bar-month {
    color: var(--mud-palette-text-primary);
    font-weight: 600;
}

/* Immer eine Zahl im Blick, auch ohne Auswahl. */
.chart-readout {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 2px 8px;
    margin-bottom: 8px;
    min-height: 34px;
}

.chart-readout-month {
    font-size: 0.875rem;
    font-weight: 600;
}

.chart-readout-detail {
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
    font-variant-numeric: tabular-nums;
}

/* Welche Regel greift, direkt am Diagramm — nicht nur im Seitenkopf. */
.chart-rule {
    display: block;
    margin-top: 10px;
    font-size: 0.7rem;
    line-height: 1.35;
    color: var(--mud-palette-text-secondary);
}

/* ---------------------------------------------------------------------------
   Überstunden — Monatsliste

   Eine Zeile je Monat statt einer Tabelle mit sechs Spalten. MudTable stapelt
   die Spalten auf schmalen Schirmen untereinander — aus sechs Spalten wurden
   dort sechs Zeilen je Monat, also über siebzig Zeilen für ein Jahr.
   --------------------------------------------------------------------------- */

.balance-list {
    display: flex;
    flex-direction: column;
}

.balance-row {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: baseline;
    gap: 2px 10px;
    padding: 9px 4px;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.balance-row:last-child {
    border-bottom: none;
}

.balance-month {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-size: 0.875rem;
    font-weight: 600;
    min-width: 0;
}

.balance-tag {
    font-size: 0.625rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--mud-palette-text-secondary);
}

/* Verfallen ist keine Warnung — es ist die Regel, die der Nutzer selbst eingestellt hat.
   Deshalb dieselbe zurückhaltende Auszeichnung wie die anderen Tags, nur mit Umriss. */
.balance-tag.is-expired {
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 4px;
    padding: 0 4px;
}

.balance-main {
    justify-self: end;
    font-size: 1rem;
    font-weight: 600;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.balance-main.is-positive {
    color: var(--mud-palette-success);
}

.balance-main.is-negative {
    color: var(--mud-palette-error);
}

.balance-detail {
    grid-column: 1 / -1;
    font-size: 0.75rem;
    line-height: 1.3;
    color: var(--mud-palette-text-secondary);
    font-variant-numeric: tabular-nums;
}

/* Erklärtexte hinter einem Info-Icon — dasselbe Muster wie die Kalenderlegende. */
.info-popover {
    padding: 12px 16px;
    max-width: 300px;
}

/* ---------------------------------------------------------------------------
   Dashboard

   Schnellzugriffe: auf dem Handy liegt die Navigation hinter dem Menüknopf.
   --------------------------------------------------------------------------- */

.quick-links {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 6px;
}

.quick-link {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px;
    border-radius: 10px;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
    background-color: var(--mud-palette-background-gray);
}

.quick-link .mud-icon-root {
    width: 1.25rem;
    height: 1.25rem;
    font-size: 1.25rem;
    color: var(--mud-palette-primary);
}

/* Arbeitstage in den Einstellungen: zwei feste Spalten, damit die Liste als
   Woche lesbar bleibt und nicht nach Wortlänge umbricht. */
.settings-days {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0 8px;
}

/* Die Erklärung unter einem Erinnerungs-Schalter. Eingerückt auf die Höhe der
   Beschriftung, damit sie zum Schalter darüber gehört und nicht zum nächsten —
   ohne die Einrückung liest sich die Liste als fünf Paare in der falschen
   Zuordnung. */
.reminder-toggle-hint {
    display: block;
    margin: -6px 0 10px 48px;
    color: var(--mud-palette-text-secondary);
    line-height: 1.35;
}

.reminder-toggle-hint:last-child {
    margin-bottom: 0;
}

.reminder-time-picker {
    max-width: 160px;
    margin: 4px 0 4px 48px;
}

/* ---------------------------------------------------------------------------
   Jahreszahlen (Dashboard)

   Das Dashboard ist die Seite, auf der man landet — sie darf etwas hermachen.
   Der Akzent bleibt trotzdem sparsam: die Zahlen sind der Inhalt, nicht die
   Flächen um sie herum.
   --------------------------------------------------------------------------- */

.year-hero {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    text-align: center;
    padding: 22px 16px 24px;
    border-radius: 14px;
    color: var(--mud-palette-primary-text);
    background: linear-gradient(135deg,
        var(--mud-palette-primary) 0%,
        var(--mud-palette-primary-darken) 100%);
}

.year-hero-label {
    font-size: 0.75rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    opacity: 0.85;
}

.year-hero-value {
    font-size: 2.375rem;
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: -0.02em;
    font-variant-numeric: tabular-nums;
}

.year-hero-meta {
    font-size: 0.8125rem;
    opacity: 0.85;
}

.tile-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
}

.tile {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 14px;
    border-radius: 12px;
    background-color: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-lines-default);
    min-width: 0;
}

.tile-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.6875rem;
    line-height: 1.2;
    color: var(--mud-palette-text-secondary);
}

.tile-label .mud-icon-root {
    width: 0.875rem;
    height: 0.875rem;
    font-size: 0.875rem;
    color: var(--mud-palette-primary);
}

.tile-value {
    font-size: 1.375rem;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.01em;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.tile-meta {
    font-size: 0.6875rem;
    color: var(--mud-palette-text-secondary);
}

/* Rekorde: Bezeichnung links, Wert rechts, Datum darunter. */
.record-list {
    display: flex;
    flex-direction: column;
}

.record-row {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: baseline;
    gap: 2px 10px;
    padding: 8px 0;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.record-row:last-child {
    border-bottom: none;
}

.record-label {
    font-size: 0.875rem;
}

.record-value {
    justify-self: end;
    font-size: 1rem;
    font-weight: 600;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.record-meta {
    grid-column: 1 / -1;
    font-size: 0.6875rem;
    color: var(--mud-palette-text-secondary);
}

.record-meta:empty {
    display: none;
}

/* Umschalter Jahr / Gesamt — zwei Knöpfe in einer Spur, kein MudBlazor-Bauteil,
   damit die Optik zum Rest passt statt zum Framework. */
.summary-switch {
    display: flex;
    gap: 2px;
    padding: 3px;
    border-radius: 999px;
    background-color: var(--mud-palette-background-gray);
    /* Mit jedem Jahr wird die Spur länger — irgendwann passt sie nicht mehr auf
       ein Handy, also scrollt sie waagerecht statt umzubrechen. */
    overflow-x: auto;
    scrollbar-width: none;
}

.summary-switch::-webkit-scrollbar {
    display: none;
}

/* --- Das Perioden-Deck --------------------------------------------------------
   Alle geladenen Perioden nebeneinander, eine je Bildschirmbreite. Das Wischen
   macht der Browser über Scroll-Snap, mit der richtigen Physik — Touch-Events
   über den Circuit wären für eine Bewegung, die dem Finger folgt, zu langsam.

   Welche Periode eingerastet ist, meldet period-deck.js zurück; das kann CSS
   nicht, und der Umschalter soll zeigen, wo man ist (#187).
   ---------------------------------------------------------------------------- */

.summary-deck {
    display: flex;
    /* Abstand zwischen den Seiten: ohne ihn stoßen zwei Perioden aneinander und
       das Wischen liest sich, als rutschte eine Zahlenkolonne, statt dass ein
       Blatt weitergeht. Im Ruhezustand liegt der Abstand außerhalb des Bildes. */
    gap: 24px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    /* Keine Leiste: das Deck wird gewischt, nicht gezogen. Am Desktop bleibt der
       Umschalter die Bedienung. */
    scrollbar-width: none;
}

.summary-deck::-webkit-scrollbar {
    display: none;
}

.summary-deck-item {
    /* Genau eine Breite je Periode. Wo ein Abschnitt einrastet, rechnet das Modul
       aus seiner tatsächlichen Position statt aus index × Breite — sonst liefe
       der Abstand oben mit jedem Schritt weiter aus der Rechnung. */
    flex: 0 0 100%;
    min-width: 0;
    scroll-snap-align: start;
}

.summary-switch-option {
    appearance: none;
    -webkit-appearance: none;
    border: none;
    margin: 0;
    padding: 6px 16px;
    border-radius: 999px;
    font: inherit;
    font-size: 0.8125rem;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    color: var(--mud-palette-text-secondary);
    background-color: transparent;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    flex: 0 0 auto;
}

.summary-switch-option.is-active {
    color: var(--mud-palette-primary-text);
    background-color: var(--mud-palette-primary);
}

/* Ring plus Legende nebeneinander: der Ring zeigt das Verhältnis, die Legende
   die Zahlen. Einer allein kann beides nicht. */
.day-mix {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}

.day-mix-chart {
    flex: 0 0 auto;
}

.day-mix-legend {
    flex: 1 1 150px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.day-mix-row {
    display: grid;
    grid-template-columns: 10px 1fr auto;
    align-items: center;
    gap: 8px;
    font-size: 0.8125rem;
}

.day-mix-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
}

.day-mix-label {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.day-mix-value {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* --- Urlaubsbalken -----------------------------------------------------------
   Zwei Töpfe in einem Balken, der Übertrag links: die Füllung frisst ihn zuerst,
   und damit ist die Verbrauchsreihenfolge zu sehen statt behauptet (#151).

   Getrennt wird über Fläche und Ton, nicht über einen zweiten Farbton — das
   Theme hat genau einen Akzent, und ein zweiter wäre einer zu viel. Die 2-px-
   Lücke trägt die Trennung notfalls allein.

   Die Breiten kommen als flex-grow aus den Tagen selbst, es wird nirgends ein
   Prozentwert gerechnet.
   --------------------------------------------------------------------------- */

.vacation-bar {
    display: flex;
    gap: 2px;
    height: 8px;
}

.vacation-bar-zone {
    display: flex;
    flex-basis: 0;
    overflow: hidden;
    border-radius: 999px;
    background-color: var(--mud-palette-lines-default);
}

/* Jede Zone mindestens so breit, dass ihre Beschriftung darunter lesbar bleibt.
   Darunter stimmt der Balken nicht mehr genau proportional — das ist der bessere
   Fehler: ein abgeschnittenes „Übertr…" erklärt nichts, und 5 von 35 Tagen wären
   auf dem Handy sonst 50 px breit.

   Die Werte gelten für Zone und Beschriftung gleichermaßen, sonst liegt das Label
   nicht mehr unter seiner Zone. */
.vacation-bar-zone.is-carry-over,
.vacation-bar-legend > span.is-carry-over {
    min-width: 5rem;
}

.vacation-bar-zone.is-annual,
.vacation-bar-legend > span.is-annual {
    min-width: 6.75rem;
}

/* Der eigene Topf: ein Hauch des Akzents hinter der Zone, damit sie als etwas
   anderes zu lesen ist als der Jahresanspruch daneben. */
.vacation-bar-zone.is-carry-over {
    background-color: var(--mud-palette-primary-hover);
}

.vacation-bar-seg {
    flex-basis: 0;
}

.vacation-bar-seg.is-used {
    background-color: var(--mud-palette-primary);
}

.is-carry-over .vacation-bar-seg.is-used {
    background-color: var(--mud-palette-primary-lighten);
}

/* Über dem Kontingent: dieselbe Aussage wie vorher, nur am gefüllten Abschnitt
   statt am ganzen Balken. */
.vacation-bar-seg.is-over {
    background-color: var(--mud-palette-error);
}

/* Schraffur statt Fläche: verfallene Tage waren da und sind weg. Eine volle
   Fläche würde sie wie genutzte Tage aussehen lassen. */
.vacation-bar-seg.is-expired {
    background-image: repeating-linear-gradient(
        135deg,
        var(--mud-palette-text-disabled) 0 2px,
        transparent 2px 4px
    );
}

/* Die Beschriftung liegt unter ihrer Zone, weil sie dieselben Wachstumsfaktoren
   benutzt. */
.vacation-bar-legend {
    display: flex;
    gap: 2px;
    margin-top: 4px;
    font-size: 0.6875rem;
    line-height: 1.2;
    color: var(--mud-palette-text-secondary);
}

.vacation-bar-legend > span {
    flex-basis: 0;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Die Aufmerksamkeits-Kachel auf dem Dashboard: anders als WorkSummary löst sie beim Antippen
   etwas aus, deshalb die Button-Optik statt reiner Information. */
.attention-tile {
    display: flex;
    align-items: center;
    width: 100%;
}

.attention-tile-open {
    appearance: none;
    -webkit-appearance: none;
    margin: 0;
    font: inherit;
    text-align: left;
    border: none;
    border-radius: 8px;
    cursor: pointer;
    background-color: var(--mud-palette-warning-hover);
    padding: 1rem;
}

.attention-tile-open:active {
    filter: brightness(0.94);
}

.attention-tile-chevron {
    margin-left: auto;
}

.attention-tile-clear {
    background-color: var(--mud-palette-success-hover);
}

/* Der Abgemeldet-Landingscreen stand hier, solange das Dashboard anonym erreichbar war und
   "Anmelden" direkt zu Entra ging. Seit #268 verlangt "/" eine Anmeldung und SignIn.razor ist der
   gestaltbare Moment davor — mit eigenen Stilen, weil sie zu einem echten Formular gehören. */

/* ---------------------------------------------------------------------------
   ClockyLogo: Farbe und optionale Zeiger-Rotation

   Das SVG zeichnet mit currentColor, nicht mit var(--mud-palette-primary): auf einem gefüllten
   Primary-Knopf hätten Strich und Hintergrund sonst dieselbe Farbe und das Zeichen wäre
   unsichtbar. Die Standardfarbe steht deshalb hier, und wer die Farbe seines Kontexts braucht,
   hängt .clocky-logo-inherit an.
   --------------------------------------------------------------------------- */

.clocky-logo {
    color: var(--mud-palette-primary);
}

.clocky-logo-inherit {
    color: inherit;
}

@keyframes clocky-hand-spin {
    to {
        transform: rotate(360deg);
    }
}

.clocky-logo-hand-spin {
    /* Entspricht dem x1/y1-Drehpunkt des <line>-Elements im 100x100-viewBox von ClockyLogo. */
    transform-origin: 50px 50px;
    animation: clocky-hand-spin 1s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
    .clocky-logo-hand-spin {
        animation: none;
    }
}

/* ---------------------------------------------------------------------------
   ClockyLoader: das eine Wartezeichen (#130)

   Die Seitenvariante steht mittig und bekommt Luft nach oben — sie ersetzt Spinner, die vorher
   linksbündig an der Stelle klebten, an der der Inhalt beginnen würde.
   --------------------------------------------------------------------------- */

/* Der Loader erscheint erst nach einer Verzögerung, und zwar ohne Timer im C#: er steht sofort
   im DOM, ist aber 300 ms lang unsichtbar. Kommt die Antwort vorher — der Normalfall — wird er
   entfernt, bevor er je zu sehen war. Genau das ist der Unterschied zwischen "ruhig" und
   "blitzt bei jedem Klick".

   300 ms, weil darunter ein Ladeanzeiger die Wartezeit nicht erklärt, sondern nur Unruhe
   hinzufügt; ab etwa einer Sekunde braucht man ihn dagegen wirklich. */
.clocky-loader {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    padding: 2.5rem 1rem;
    opacity: 0;
    animation: clocky-loader-appear 200ms ease-out 300ms forwards;
}

@keyframes clocky-loader-appear {
    to {
        opacity: 1;
    }
}

/* Im Panel waagerecht und schmal: das Panel bringt sein eigenes Padding mit, und der Loader darf
   nicht höher werden als der Inhalt, den er ersetzt. */
.clocky-loader-panel {
    flex-direction: row;
    justify-content: flex-start;
    gap: 0.5rem;
    padding: 0;
}

.clocky-loader-label {
    font-size: 0.875rem;
    color: var(--mud-palette-text-secondary);
}

/* ---------------------------------------------------------------------------
   Nachladen: der alte Inhalt bleibt stehen

   Beim Jahreswechsel auf dem Dashboard wurden alle Kacheln erst entfernt und sofort wieder
   aufgebaut — das las sich als Zucken, nicht als Laden. Wer schon etwas anzuzeigen hat, zeigt es
   weiter und macht es blass, statt es abzureißen: die Seite behält ihre Höhe, nichts springt,
   und die alte Zahl bleibt lesbar, bis die neue sie ersetzt.
   --------------------------------------------------------------------------- */

.is-refreshing {
    opacity: 0.45;
    /* Dieselben 300 ms Verzögerung wie beim Loader, und aus demselben Grund: ohne sie ist das
       Dimmen selbst ein Blitzen — die Deckkraft fällt und ist sofort wieder oben. Eine schnelle
       Antwort soll die Zahlen austauschen und sonst nichts tun.

       Das Zurückspringen auf volle Deckkraft ist bewusst ohne Übergang: die Klasse verschwindet
       mit den neuen Daten, und die sollen sofort scharf sein. */
    transition: opacity 150ms ease-out 300ms;
    /* Während des Nachladens sind die Zahlen von gestern - nicht anklickbar machen. */
    pointer-events: none;
}

/* ---------------------------------------------------------------------------
   Reconnect-Overlay (#116)

   blazor.web.js schaltet components-reconnect-show/-failed/-rejected auf
   #components-reconnect-modal um. Ohne eine dieser Klassen ist die Verbindung intakt und das
   Overlay bleibt unsichtbar.
   --------------------------------------------------------------------------- */

#components-reconnect-modal {
    display: none;
    position: fixed;
    inset: 0;
    /* MudBlazors höchstes klassenbasiertes Element (.mud-scroll-to-top) liegt bei 100; einzelne
       JS-gesteuerte Overlays (Snackbar, Popover) setzen inline noch höhere Werte. 9999 gewinnt
       unabhängig davon, was gerade offen ist, wenn der Circuit abbricht. */
    z-index: 9999;
    align-items: center;
    justify-content: center;
    background-color: rgba(0, 0, 0, .55);
}

#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected {
    display: flex;
}

.reconnect-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    max-width: 320px;
    padding: 2rem 1.5rem;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: 14px;
    background-color: var(--mud-palette-surface);
}

.reconnect-attempting,
.reconnect-failed,
.reconnect-rejected {
    display: none;
    margin-top: 1.25rem;
}

#components-reconnect-modal.components-reconnect-show .reconnect-attempting,
#components-reconnect-modal.components-reconnect-failed .reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected .reconnect-rejected {
    display: block;
}

.reconnect-button {
    appearance: none;
    -webkit-appearance: none;
    margin-top: 0.75rem;
    padding: 8px 20px;
    border: none;
    border-radius: 999px;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
    color: var(--mud-palette-primary-text);
    background-color: var(--mud-palette-primary);
}

.reconnect-button:active {
    filter: brightness(0.94);
}

/* ---------------------------------------------------------------------------
   Settings: persistenter Speichern-Balken (#126)

   Der Button lebt außerhalb des scrollenden Formulars, fest am unteren Bildschirmrand —
   sonst verschwindet er beim Bearbeiten eines Feldes weiter oben aus dem sichtbaren Bereich.
   --------------------------------------------------------------------------- */

.settings-page {
    /* Reserviert Platz, damit der letzte Inhalt (der Info-Alert) nicht hinter der
       fixen Leiste verschwindet. Etwas großzügiger als deren Höhe (Button + Padding + Safe-Area). */
    padding-bottom: 128px;
}

/* --- Fehleranzeige -------------------------------------------------------------
   Mittig und ruhig: wer hier landet, hat schon genug Aufregung. Die technischen
   Angaben stecken in einem zugeklappten <details> — da, wenn man sie braucht,
   und sonst nicht im Weg.
   ------------------------------------------------------------------------------ */

.error-panel {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 48px 16px;
}

.error-panel-icon {
    width: 48px;
    height: 48px;
    margin-bottom: 16px;
    color: var(--mud-palette-text-disabled);
}

.error-panel-headline {
    margin-bottom: 6px;
}

.error-panel-detail {
    max-width: 34ch;
}

.error-panel-details {
    width: 100%;
    max-width: 30rem;
    margin-top: 40px;
    text-align: left;
}

.error-panel-details > summary {
    cursor: pointer;
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
    /* Der Standardmarker ist auf dem Handy winzig; die eigene Zeile ist leichter zu treffen. */
    padding: 8px 0;
}

/* Beschriftung und Wert untereinander statt nebeneinander: die Werte sind lang
   (Trace-Kennungen, Ausnahmemeldungen) und würden zweispaltig zerbrechen. */
.error-panel-facts {
    margin: 8px 0 0;
    font-size: 0.75rem;
}

.error-panel-facts dt {
    color: var(--mud-palette-text-secondary);
}

.error-panel-facts dd {
    margin: 0 0 10px;
    /* Kennungen brechen sonst aus dem Bild heraus. */
    overflow-wrap: anywhere;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

/* Die laufende Fassung, klein und am Ende der Seite. Sie steht dort für den einen
   Moment, in dem jemand wissen will, was gerade läuft — und sonst im Weg wäre. */
.settings-version {
    padding: 0 16px 8px;
    font-size: 0.6875rem;
    line-height: 1.2;
    color: var(--mud-palette-text-disabled);
    text-align: center;
}

.settings-save-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    /* Deutlich unter dem Reconnect-Overlay (9999, siehe dort) — ein Circuit-Abbruch auf dieser
       Seite muss weiterhin Vorrang haben. */
    z-index: 10;
    /* env(safe-area-inset-bottom) braucht viewport-fit=cover in App.razor, sonst 0 — hält den
       Button auf iPhones mit Home-Indicator von dessen Geste fern statt direkt daran zu kleben. */
    padding: 12px 16px calc(16px + env(safe-area-inset-bottom));
    background-color: var(--mud-palette-surface);
    border-top: 1px solid var(--mud-palette-lines-default);
}

/* ── Urlaubsseite (#118) ────────────────────────────────────────────────────────
   Die Jahresumschaltung sitzt in der Überschrift des Balkens, dort wo auf dem
   Dashboard „X von Y" steht. */
.year-switch {
    display: flex;
    align-items: center;
    gap: 2px;
}

.year-switch-value {
    min-width: 3.5ch;
    text-align: center;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-text-secondary);
}

/* Der Kopf klebt, die Liste läuft darunter durch.

   Das Offset ist die Höhe der App-Leiste. --mud-appbar-height ist dabei nur die
   *Grundhöhe* (64px); die tatsächliche Leiste rechnet MudBlazor daraus je
   Breakpoint neu aus — 64px ab 600px, 64-64/8 darunter, 64-64/4 im Querformat.
   Dieselben Formeln stehen deshalb unten, sonst klafft es genau um die Differenz.
   Das +1px ist die Randlinie, die .mud-appbar weiter oben bekommt.

   Dazu ein Streifen Flächenfarbe oberhalb per box-shadow: er liegt im Ruhezustand
   im oberen Innenabstand des Papiers und ist dort unsichtbar, deckt beim Kleben
   aber alles ab, was zwischen Leiste und Kopf sonst durchschiene. Kostet kein
   Layout und trägt auch dann, wenn die Rechnung oben eines Tages nicht mehr
   aufgeht. */
.vacation-head {
    position: sticky;
    top: calc(var(--mud-appbar-height, 64px) - var(--mud-appbar-height, 64px) / 8 + 1px);
    /* Über den Zeilen, aber weit unter dem Reconnect-Overlay (9999, siehe dort). */
    z-index: 2;
    margin-bottom: 4px;
    padding-bottom: 8px;
    background-color: var(--mud-palette-surface);
    box-shadow: 0 -20px 0 0 var(--mud-palette-surface);
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

@media (min-width: 600px) {
    .vacation-head {
        top: calc(var(--mud-appbar-height, 64px) + 1px);
    }
}

@media (max-width: 599px) and (orientation: landscape) {
    .vacation-head {
        top: calc(var(--mud-appbar-height, 64px) - var(--mud-appbar-height, 64px) / 4 + 1px);
    }
}

.vacation-head-actions {
    margin-top: 12px;
}

.absence-list {
    display: flex;
    flex-direction: column;
}

/* Feste Spaltenbreiten, keine inhaltsabhängigen: jede Zeile ist ihr eigenes Raster,
   also richten sich „auto"-Spalten zwischen den Zeilen gerade nicht aneinander aus —
   die Kategorie-Plakette begann dadurch je nach Länge von „10 Tage" oder „1 Tag" an
   einer anderen Stelle. */
.absence-row {
    display: grid;
    grid-template-columns: 8.5rem 5rem 6rem 1fr auto;
    grid-template-areas: "dates days cat note btn";
    align-items: center;
    gap: 8px;
    padding: 8px 0;
    border-bottom: 1px solid var(--mud-palette-lines-default);
}

.absence-row:last-child,
/* Vor dem „ab hier geplant"-Strich stünden sonst zwei Linien übereinander. */
.absence-row.is-last-before-divider {
    border-bottom: none;
}

.absence-dates {
    grid-area: dates;
    font-variant-numeric: tabular-nums;
}

.absence-days {
    grid-area: days;
    font-variant-numeric: tabular-nums;
    color: var(--mud-palette-text-secondary);
}

/* Dieselben Töne wie Kalender und Ring: ein Urlaubstag ist überall blau. Die Plakette
   füllt ihre Spalte, damit „Urlaub" und „Sonstige" gleich breit sind — verschieden
   breite Plaketten untereinander lesen sich als Unordnung, nicht als Information. */
.absence-category {
    grid-area: cat;
    display: block;
    width: 100%;
    text-align: center;
    font-size: 0.75rem;
    padding: 2px 8px;
    border-radius: 999px;
    white-space: nowrap;
}

.absence-category.is-vacation {
    background-color: var(--clocky-day-vacation-soft, rgba(33, 150, 243, 0.16));
    color: var(--mud-palette-text-primary);
}

.absence-category.is-other {
    background-color: var(--clocky-day-other-soft, rgba(158, 158, 158, 0.16));
    color: var(--mud-palette-text-primary);
}

.absence-note {
    grid-area: note;
    display: flex;
    flex-wrap: wrap;
    gap: 4px 10px;
    font-size: 0.8125rem;
    color: var(--mud-palette-text-secondary);
}

.absence-actions {
    grid-area: btn;
    display: flex;
    justify-content: flex-end;
}

.absence-carry-over {
    color: var(--mud-palette-warning-text);
}

/* Ein Strich mit Aufschrift: „ab hier geplant" trennt Vergangenes von Gebuchtem,
   und zwar genau einmal.

   Farbig und gesperrt gesetzt, weil er sonst zwischen den grauen Trennlinien der
   Zeilen untergeht — er ist die einzige Linie hier, die etwas bedeutet, und muss
   deshalb anders aussehen als die, die nur trennen. */
.absence-divider {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 16px 0 6px;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mud-palette-primary);
}

.absence-divider::before,
.absence-divider::after {
    content: "";
    flex: 1;
    height: 2px;
    border-radius: 1px;
    background-color: var(--mud-palette-primary);
    opacity: 0.4;
}

/* Auf dem Telefon bricht die Zeile in zwei: oben Datum, Menge, Kategorie und der
   Löschknopf, darunter die Notiz über die volle Breite. Über die Bereichsnamen, weil
   die Notiz im Markup vor dem Knopf steht — mit reiner Auto-Platzierung landete der
   Knopf sonst in einer dritten Zeile. */
@media (max-width: 599px) {
    .absence-row {
        grid-template-columns: 7.5rem 4.5rem 1fr auto;
        grid-template-areas:
            "dates days cat btn"
            "note note note note";
        row-gap: 2px;
    }

}
