/*
 * Uptime - die Designschicht ueber Tabler.
 *
 * Tabler (tabler.min.css) bringt Bootstrap 5.3 samt allen Bausteinen mit. Hier
 * steht nur, was darueber hinausgeht: die Marke, die Zustaende eines Checks und
 * ein paar Feinheiten. Farben kommen durchgehend aus Tablers Variablen, damit
 * der dunkle Modus ohne eigene Regeln mitkommt.
 *
 * Wer eine Regel hinzufuegt, prueft vorher, ob Tabler sie schon hat - die
 * vorige Oberflaeche ist genau daran gescheitert, dass zwei Frameworks
 * uebereinander lagen.
 */

:root {
    /* Zustaende eines Checks. Rot und Gruen allein reichen nicht - jeder
       Zustand steht in der Oberflaeche immer auch als Wort da. */
    --up-state-up: var(--tblr-green);
    --up-state-down: var(--tblr-red);
    --up-state-warn: var(--tblr-orange);
    --up-state-paused: var(--tblr-gray-400);
}

/* --- Grundlagen --------------------------------------------------------- */

/* Zahlen in gleicher Breite: Spalten mit Latenzen und Prozenten stehen sonst
   nicht buendig, und ein sich aktualisierender Wert springt. */
.tabular,
.kpi-value,
.table .num {
    font-variant-numeric: tabular-nums;
}

.table .num {
    text-align: end;
    white-space: nowrap;
}

/* Unsichtbare Beschriftungen fuer Screenreader (visually-hidden) sind absolut
   positioniert. Ohne eigenen Bezugsrahmen richten sie sich an der Karte aus,
   nicht am scrollenden Tabellencontainer - und entkommen so dessen
   Beschnitt: auf dem Telefon wurde die ganze Seite seitlich verschiebbar. */
.table-responsive {
    position: relative;
}

/* Sprungmarke fuer Tastatur und Screenreader - sichtbar erst beim Fokus. */
.skip-link {
    position: absolute;
    top: -4rem;
    left: 1rem;
    z-index: 2000;
    padding: .5rem 1rem;
    border-radius: var(--tblr-border-radius);
    background: var(--tblr-primary);
    color: var(--tblr-primary-fg, #fff);
    font-weight: 600;
    transition: top .15s ease-out;
}

.skip-link:focus {
    top: 1rem;
    color: var(--tblr-primary-fg, #fff);
    text-decoration: none;
}

/* Tabler setzt Icons in Knoepfen mit Abstand nach rechts. In reinen
   Symbolknoepfen soll keiner sein. */
.btn-icon > .icon {
    margin: 0;
}

/* --- Marke ---------------------------------------------------------------- */

.brand {
    display: inline-flex;
    align-items: center;
    gap: .625rem;
    color: var(--tblr-body-color);
    font-size: 1.0625rem;
    font-weight: 700;
    letter-spacing: -.01em;
    text-decoration: none;
}

.brand:hover,
.brand:focus {
    color: var(--tblr-body-color);
    text-decoration: none;
}

.brand-mark {
    width: 2rem;
    height: 2rem;
    flex: none;
}

.brand-lg .brand-mark {
    width: 2.75rem;
    height: 2.75rem;
}

.brand-lg {
    font-size: 1.5rem;
}

/* --- Seitenleiste ----------------------------------------------------------- */

/* Tabler verteilt Inhalt der Marke in der vertikalen Leiste auf die ganze
   Breite (space-between) - Logo links, Name ganz rechts. Zusammen gehoert es. */
.navbar-vertical .navbar-brand.brand {
    justify-content: flex-start;
}

.navbar-vertical .nav-section {
    padding: 1.25rem 1rem .375rem;
    color: var(--tblr-secondary);
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
}

/* Die Zahl in einem Menuepunkt (Alarme heute) steht in der Zeile, mittig und
   mit etwas Abstand zum Rand. Tabler setzt sie sonst als Benachrichtigungspunkt
   absolut oben rechts auf den Link - in der Seitenleiste ragte sie damit ueber
   die Zeile hinaus und stiess rechts an den Rand. */
.navbar-vertical .navbar-nav .nav-link .badge {
    position: static;
    transform: none;
    align-self: center;
    margin-inline-start: auto;
    margin-inline-end: .375rem;
}

/* Das Konto unten in der Seitenleiste: wem gehoert, was man hier sieht. Genau
   das war bisher nirgends zu erkennen - siehe die Frage nach dem Mandanten. */
.account-card {
    margin: 1rem;
    padding: .75rem .875rem;
    border: 1px solid var(--tblr-border-color);
    border-radius: var(--tblr-border-radius-lg, .5rem);
    background: var(--tblr-bg-surface-secondary);
    font-size: .8125rem;
}

.account-card .account-name {
    overflow: hidden;
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Das Symbol der Darstellung zeigt, was gerade gilt. */
[data-bs-theme=dark] .theme-icon-light,
:root:not([data-bs-theme=dark]) .theme-icon-dark {
    display: none;
}

/* Die gewaehlte Darstellung im Menue markieren (setzt uptime.js). */
.dropdown-item[aria-pressed=true] {
    color: var(--tblr-primary);
    font-weight: 600;
}

/* --- Kennzahlen ----------------------------------------------------------- */

/* Kompakt: die Karten stehen ueber der Liste der Checks, und jede Zeile hier
   ist eine Zeile weniger von ihr. Das Icon sitzt deshalb oben rechts neben
   Beschriftung und Wert, statt als eigene Zeile die Karte zu strecken. */
.kpis .card-body {
    padding: 1rem 1.25rem;
}

.kpis .kpi-icon {
    position: absolute;
    top: 1rem;
    right: 1rem;
    width: 2rem;
    height: 2rem;
}

.kpis .kpi-icon .icon {
    width: 1.125rem;
    height: 1.125rem;
}

.kpis .kpi-label {
    /* Platz fuer das Icon, damit lange Beschriftungen darunter umbrechen. */
    padding-right: 2.5rem;
}

.kpis .kpi-foot {
    margin-top: .25rem;
}

/* Auf dem Telefon stehen zwei Karten nebeneinander. Das Icon ist dort nur
   Schmuck und zwingt die Beschriftung in eine zweite Zeile. */
@media (max-width: 575.98px) {
    .kpis .kpi-icon {
        display: none;
    }

    .kpis .kpi-label {
        padding-right: 0;
    }
}

.kpi-label {
    color: var(--tblr-secondary);
    font-size: .8125rem;
    font-weight: 500;
}

.kpi-value {
    margin-top: .25rem;
    font-size: 1.75rem;
    font-weight: 600;
    letter-spacing: -.02em;
    line-height: 1.15;
}

.kpi-unit {
    margin-inline-start: .125rem;
    color: var(--tblr-secondary);
    font-size: .9375rem;
    font-weight: 500;
    letter-spacing: 0;
}

.kpi-foot {
    margin-top: .375rem;
    color: var(--tblr-secondary);
    font-size: .8125rem;
}

.kpi-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: var(--tblr-border-radius-lg, .5rem);
}

.kpi-icon .icon {
    width: 1.375rem;
    height: 1.375rem;
}

/* --- Zustand eines Checks --------------------------------------------------- */

/* Tablers .status mit Punkt und Wort. Hier nur die Breite, damit die Spalte
   ruhig steht, und ein Zaehler fuer Fehlschlaege in Folge. */
.state {
    min-width: 7.5rem;
    justify-content: flex-start;
}

.state-count {
    margin-inline-start: .25rem;
    padding: 0 .375rem;
    border-radius: 1rem;
    background: rgba(var(--tblr-red-rgb), .12);
    font-size: .6875rem;
    font-weight: 700;
    line-height: 1.25rem;
}

/* Wer Bewegung abbestellt hat, bekommt den pulsierenden Punkt ruhig. */
@media (prefers-reduced-motion: reduce) {
    .status-dot-animated::before {
        animation: none;
    }
}

/* Die Uebersichtsbanderole ueber der Liste der Checks. */
.overall {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.overall-icon {
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    border-radius: 50%;
}

.overall-icon .icon {
    width: 1.5rem;
    height: 1.5rem;
}

/* --- Liste der Checks ------------------------------------------------------- */

.check-name {
    color: var(--tblr-body-color);
    font-weight: 600;
}

.check-url {
    display: block;
    max-width: 42ch;
    overflow: hidden;
    color: var(--tblr-secondary);
    font-size: .8125rem;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Die ganze Zeile ist anklickbar (stretched-link), die Verweise darin bleiben
   es trotzdem. */
.table-checks tbody tr {
    position: relative;
}

.table-checks tbody tr:hover {
    background: var(--tblr-bg-surface-secondary);
}

.table-checks .above-link {
    position: relative;
    z-index: 2;
}

.table-checks tr[hidden] {
    display: none;
}

/* Der Filter oberhalb der Liste. */
.filter-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .75rem;
}

.filter-bar .input-icon {
    flex: 1 1 16rem;
    max-width: 24rem;
}

/* Filter nach Zustand: einzelne Chips, die umbrechen duerfen - als
   Knopfgruppe liefen sie auf dem Telefon ueber den Rand. */
.filter-chips {
    display: flex;
    flex-wrap: wrap;
    gap: .375rem;
}

.filter-chip {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    padding: .25rem .625rem .25rem .75rem;
    border: 1px solid var(--tblr-border-color);
    border-radius: 999px;
    background: var(--tblr-bg-surface);
    color: var(--tblr-body-color);
    font-size: .8125rem;
    font-weight: 500;
    line-height: 1.25rem;
    transition: border-color .15s, background-color .15s, color .15s;
}

.filter-chip:hover {
    border-color: var(--tblr-border-color-dark, var(--tblr-secondary));
}

.filter-chip.active {
    border-color: var(--tblr-primary);
    background: rgba(var(--tblr-primary-rgb), .08);
    color: var(--tblr-primary);
}

.filter-chip .badge {
    margin: 0 !important;
}

/* Kennzeichnung der Live-Aktualisierung. */
.live {
    display: inline-flex;
    align-items: center;
    gap: .375rem;
    color: var(--tblr-secondary);
    font-size: .8125rem;
}

/* --- Verfuegbarkeit als Balken (Statusseite, Bericht) ------------------------ */

/* Tablers .tracking liefert die Balken; die Stufen hier entsprechen den
   level-Werten aus CheckService.getUptimeHeatmap und PublicStatusService. */
.tracking-block.perfect { background: var(--tblr-green); }
.tracking-block.good { background: rgba(var(--tblr-green-rgb), .55); }
.tracking-block.warn { background: var(--tblr-yellow); }
.tracking-block.bad { background: var(--tblr-orange); }
.tracking-block.critical { background: var(--tblr-red); }
.tracking-block.none { background: var(--tblr-border-color); }
/* Fuellt im Jahreskalender den Wochentag vor dem ersten Tag auf. */
.tracking-block.placeholder { background: transparent; }

.tracking {
    --tblr-tracking-height: 2rem;
}

/* Auf dem Telefon passen 90 Tage nicht nebeneinander - jeder Block hat eine
   Mindestbreite, und die Leiste lief ueber den Rand. Dort zeigt sie die
   letzten 30 Tage; die Beschriftung darunter wechselt mit (.days-*). */
@media (max-width: 575.98px) {
    .tracking-recent > .tracking-block:nth-last-child(n+31) {
        display: none;
    }
}

/* Die Kalenderansicht eines Jahres: sieben Zeilen, eine Spalte je Woche. */
.heatmap {
    display: grid;
    grid-auto-columns: minmax(0, 1fr);
    grid-auto-flow: column;
    grid-template-rows: repeat(7, auto);
    gap: 3px;
}

.heatmap .tracking-block {
    aspect-ratio: 1;
    height: auto;
    border-radius: 2px;
}

.heatmap-legend {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: .25rem;
    margin-top: .75rem;
    color: var(--tblr-secondary);
    font-size: .75rem;
}

.heatmap-legend .tracking-block {
    /* Tabler gibt den Bloecken flex: 1 - in der Legende wurden daraus Balken. */
    flex: none;
    width: .75rem;
    height: .75rem;
    border-radius: 2px;
}

/* --- Formulare --------------------------------------------------------------- */

/* Die Art der Pruefung als Karten zum Anklicken statt als Radioknoepfe. Als
   Grid: Tablers selectgroup ist ein umbrechender Flex-Container und vertraegt
   sich nicht mit Bootstraps Spalten - die Karten brachen ungleich um. */
.type-options {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(8.5rem, 1fr));
    gap: .5rem;
    width: 100%;
}

.type-options .form-selectgroup-item {
    margin: 0;
}

.type-options .form-selectgroup-label {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .125rem;
    height: 100%;
    padding: .75rem;
    text-align: start;
    white-space: normal;
}

.type-options .form-selectgroup-label .icon {
    margin-bottom: .25rem;
    color: var(--tblr-primary);
}

.type-options .type-hint {
    color: var(--tblr-secondary);
    font-size: .75rem;
    font-weight: 400;
}

/* Ein Knopf im Eingabefeld (Passwort einblenden): ohne das erbt er die
   Mindesthoehe eines Knopfes, und das Feld wird 60 statt 40 Pixel hoch. */
.input-group-text > .btn-link {
    min-height: 0;
    border: 0;
    line-height: 1;
}

/* Geheimnisse und Adressen, die man kopieren soll. */
.copy-field {
    font-family: var(--tblr-font-monospace);
    font-size: .8125rem;
}

/* --- Anmeldeseiten ------------------------------------------------------------ */

.auth-bg {
    background:
        radial-gradient(60rem 30rem at 50% -8rem, rgba(var(--tblr-primary-rgb), .14), transparent 70%),
        var(--tblr-body-bg);
}

.auth-card {
    border: 0;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .04), 0 12px 32px -12px rgba(15, 23, 42, .18);
}

[data-bs-theme=dark] .auth-card {
    box-shadow: 0 0 0 1px var(--tblr-border-color), 0 12px 32px -12px rgba(0, 0, 0, .6);
}

/* Die Sicherheitspruefung (ALTCHA) in den Farben und Formen von Tabler. Das
   Widget setzt seine Werte auf :root und laedt sein CSS erst zur Laufzeit -
   also nach dieser Datei. Am Element selbst gesetzt gewinnen diese hier trotzdem,
   weil CSS-Variablen vom naechsten Vorfahren erben. Hell und dunkel folgen
   damit von allein dem Theme. */
altcha-widget {
    display: block;
    /* Reserviert die Hoehe, bevor das Skript geladen ist - sonst springt der
       Knopf darunter beim Laden um eine Zeile nach unten. */
    min-height: 3.25rem;
    --altcha-max-width: 100%;
    /* Ein Wert, keine zwei: das Widget rechnet damit in calc(). */
    --altcha-padding: .75rem;
    --altcha-border-radius: var(--tblr-border-radius);
    --altcha-border-color: var(--tblr-border-color);
    --altcha-color-base: var(--tblr-bg-forms);
    --altcha-color-base-content: var(--tblr-body-color);
    --altcha-color-neutral: var(--tblr-border-color);
    --altcha-color-neutral-content: var(--tblr-secondary);
    --altcha-color-primary: var(--tblr-primary);
    --altcha-color-primary-content: var(--tblr-primary-fg);
    --altcha-color-success: var(--tblr-success);
    --altcha-color-error: var(--tblr-danger);
    --altcha-checkbox-border-color: var(--tblr-border-color);
    --altcha-checkbox-outline-color: rgba(var(--tblr-primary-rgb), .35);
    --altcha-checkbox-size: 1.25rem;
}

/* --- Oeffentliche Seiten (Statusseite, Rechtstexte) --------------------------- */

.doc-content h1,
.doc-content h2,
.doc-content h3 {
    margin-top: 1.75rem;
    margin-bottom: .5rem;
    font-size: 1rem;
    font-weight: 600;
}

.doc-content > :first-child {
    margin-top: 0;
}

.doc-content p,
.doc-content li {
    line-height: 1.65;
}

/* Diagnosedaten: lange Header und Seiteninhalte ohne Umbruch des Layouts.
   Textfarbe ausdruecklich: Tabler macht aus jedem <pre> einen dunklen
   Codeblock mit heller Schrift. Mit dem hellen Hintergrund hier stand im
   hellen Modus sonst Weiss auf Weiss. */
.diagnostics {
    --tblr-scrollbar-color: var(--tblr-secondary);
    max-height: 18rem;
    overflow: auto;
    padding: .75rem;
    border: 1px solid var(--tblr-border-color);
    border-radius: var(--tblr-border-radius);
    color: var(--tblr-body-color);
    background: var(--tblr-bg-surface-secondary);
    font-family: var(--tblr-font-monospace);
    font-size: .75rem;
    white-space: pre-wrap;
    word-break: break-word;
}

/* Im Druck zaehlt der Inhalt, nicht die Navigation. */
@media print {
    .navbar-vertical,
    .page-header .btn-list,
    .footer {
        display: none !important;
    }
}
