/*
   Die Oberfläche orientiert sich an GitLab: linke Bereichsnavigation, eine Liste im Stil der
   Issue-Liste, eine Detailseite aus Titel, Beschreibung und rechter Metaspalte, und Formulare mit
   einzeiligem Titel über mehrzeiliger Beschreibung.

   Weiterhin ohne Framework und ohne JavaScript. Übernommen ist die Anordnung und die Rolle der
   Elemente, nicht das Designsystem von GitLab: GitLab UI ist ein eigenes Paket mit eigener Lizenz,
   und ein Nachbau seiner Klassennamen würde eine Herkunft behaupten, die nicht besteht. Deshalb
   tragen die Klassen hier deutsche Namen und die Farben sind eigene Werte in der Nähe der Vorlage.

   Die Oberfläche ist dunkel, und zwar als einziges Farbschema. Es gibt keine helle Fassung, keinen
   Umschalter und keine Abfrage von `prefers-color-scheme`: Wer die Anwendung öffnet, bekommt
   dieselbe Darstellung wie jeder andere. Eine Abfrage, deren heller Zweig nicht existiert, wäre
   eine Attrappe. Die Farben stehen deshalb ohne Alternative in `:root`, und jede Farbe im
   Stylesheet kommt von dort — ein fester Wert an einer Regel weiter unten wäre die eine Stelle,
   die beim nächsten Umstimmen übrig bliebe, und eine helle Fassung wäre später ein zusätzlicher
   Block und kein Umbau.

   Der Akzent stammt aus der Marke und nicht aus der Vorlage: Markenorange `#f8a66d` für jeden
   Verweis und für den Absendeknopf, dazu Creme `#fdfbf7` für die starke Schrift. Beide Werte
   stehen im Abschnitt „Branding" von `assets/README.md` des Repositories `Nalo`. Das Blau, das
   hier vorher stand, gehörte nie zur Marke und käme auf dunklem Grund ohnehin nicht über
   4,5 : 1. Das dunkle Markengrün `#697f70` scheidet aus demselben Grund aus — es erreicht nur
   3,98 : 1, während das Orange 8,72 : 1 erreicht.
*/

:root {
    /*
       `color-scheme` ist keine Farbe, sondern die Ansage an den Browser. Ohne sie zeichnet er
       Bildlaufleisten, die aufgeklappte Liste eines `select` und den Rahmen eines Eingabefelds
       weiter hell und setzt damit helle Flächen mitten in die dunkle Seite. Der gleichlautende
       `<meta name="color-scheme">` in `App.razor` sagt dasselbe früher — er wirkt schon, bevor
       dieses Stylesheet da ist, und verhindert das kurze weiße Aufblitzen beim ersten Aufruf.
    */
    color-scheme: dark;

    --grund: #1b1b1f;
    --grund-gedaempft: #232228;
    --grund-aktiv: #2f2e34;
    --schrift: #d5d3d0;
    --schrift-stark: #fdfbf7;
    --gedaempft: #a3a09a;
    --linie: #3b3a41;
    --linie-stark: #706f77;
    --akzent: #f8a66d;
    --akzent-flaeche: #f8a66d;
    --akzent-hell: #fbc39c;
    --auf-akzent: #1b1b1f;
    --fehler: #f09a9a;
    --fehler-linie: #e05a5a;
    --fehler-flaeche: #3d1712;
    --warnung: #f5ce62;
    --warnung-flaeche: #352d19;
    --zustand-offen: #7db4f5;
    --zustand-offen-flaeche: #1e2a3f;
    --zustand-bearbeitung: #f5b53c;
    --zustand-bearbeitung-flaeche: #33291a;
    --zustand-abgeschlossen: #6fd68f;
    --zustand-abgeschlossen-flaeche: #1b3025;
    --radius: 0.25rem;
    --seitenleiste: 15rem;
}

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    background: var(--grund);
    color: var(--schrift);
    font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
    font-size: 0.875rem;
    line-height: 1.5;
}

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

/* ------------------------------------------------------------------ Gerüst */

/*
   Zwei Spalten ab Tablet-Breite, darunter untereinander. Das Raster steht am äußeren Element und
   nicht an einer inneren Hülle, damit die Seitenleiste die volle Höhe behält, auch wenn der Inhalt
   kürzer ist als sie.
*/
.geruest {
    display: grid;
    grid-template-columns: 1fr;
    min-height: 100vh;
}

@media (min-width: 48rem) {
    .geruest {
        grid-template-columns: var(--seitenleiste) 1fr;
    }
}

.seitenleiste {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding: 0.75rem;
    background: var(--grund-gedaempft);
    border-bottom: 1px solid var(--linie);
}

@media (min-width: 48rem) {
    .seitenleiste {
        border-bottom: 0;
        border-right: 1px solid var(--linie);
    }
}

.marke {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.375rem;
    border-radius: var(--radius);
    text-decoration: none;
    color: var(--schrift-stark);
    font-weight: 600;
}

.marke:hover {
    background: var(--grund-aktiv);
}

/*
   Die Bildmarke an der Stelle, an der GitLab das Bild des Bereichs zeigt. Das Feld bleibt
   quadratisch, damit die Zeile ihre Höhe und die Navigation darunter ihre Flucht behält; die
   Marke ist hochkant (273 : 356) und steht darin zentriert. `object-fit: contain` hält ihr
   Seitenverhältnis, egal wie das Feld sich ändert.
*/
.marke-zeichen {
    width: 2rem;
    height: 2rem;
    object-fit: contain;
}

.marke-name {
    letter-spacing: 0.04em;
}

.bereichsnavigation {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

.bereichsnavigation-titel {
    margin: 0 0 0.25rem;
    padding: 0 0.375rem;
    color: var(--gedaempft);
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.navigation {
    padding: 0.375rem 0.625rem;
    border-radius: var(--radius);
    text-decoration: none;
    color: var(--schrift);
}

.navigation:hover {
    background: var(--grund-aktiv);
}

.navigation.active {
    background: var(--grund-aktiv);
    color: var(--schrift-stark);
    font-weight: 600;
}

.seitenleiste-benutzer {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    padding: 0 0.375rem;
}

.seitenleiste-symbol {
    flex-shrink: 0;
}

.benutzer-name {
    min-width: 0;
    overflow-wrap: anywhere;
}

.benutzer-wechsel {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    margin-left: auto;
    width: 2rem;
    height: 2rem;
    border-radius: var(--radius);
}

.benutzer-wechsel:hover {
    background: var(--grund-aktiv);
}

.benutzer-wechsel:focus-visible {
    outline: 2px solid var(--akzent);
    outline-offset: 2px;
}

.seitenleiste-fuss {
    margin-top: auto;
    padding: 0.75rem;
    border: 2px solid var(--warnung);
    border-radius: var(--radius);
    background: var(--warnung-flaeche);
    color: var(--schrift-stark);
    font-size: 0.75rem;
}

.seitenleiste-fuss p {
    margin: 0;
}

.seitenleiste-fuss .warnung-titel {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.5rem;
    color: var(--warnung);
}

.inhalt {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* Die Brotkrume sagt, wo man ist. Sie ist nicht die Überschrift der Seite. */
.brotkrume {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.375rem;
    padding: 0.625rem 1.5rem;
    border-bottom: 1px solid var(--linie);
    color: var(--gedaempft);
    font-size: 0.8125rem;
}

.brotkrume a {
    text-decoration: none;
}

.brotkrume a:hover {
    text-decoration: underline;
}

main {
    max-width: 70rem;
    padding: 1.5rem;
}

/* ----------------------------------------------------------- Überschriften */

.seitenkopf {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}

h1 {
    margin: 0;
    color: var(--schrift-stark);
    font-size: 1.25rem;
    line-height: 1.4;
}

h2 {
    margin: 0;
    color: var(--schrift-stark);
    font-size: 1rem;
}

/* ---------------------------------------------------------------- Vorgänge */

/*
   Die Liste im Stil der Issue-Liste: eine Zeile je Vorgang, Titel als Verweis, darunter eine
   gedämpfte Metazeile, rechts die Kennzahlen und die Aktionen. Keine Tabelle — die Metazeile
   umbricht, und eine Zelle mit umbrechendem Text neben ausgerichteten Spalten liest sich
   schlechter als eine Zeile, die von sich aus zweizeilig ist.
*/
.vorgangsliste {
    margin: 0;
    padding: 0;
    list-style: none;
    border: 1px solid var(--linie);
    border-radius: var(--radius);
}

.vorgang {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--linie);
}

.vorgang-klickbar {
    cursor: pointer;
}

.vorgang:last-child {
    border-bottom: 0;
}

.vorgang:hover {
    background: var(--grund-gedaempft);
}

.vorgang-haupt {
    flex: 1 1 24rem;
    min-width: 12rem;
}

.vorgang-titel {
    color: var(--schrift-stark);
    font-size: 0.9375rem;
    font-weight: 600;
    text-decoration: none;
}

.vorgang-titel:hover {
    color: var(--akzent);
    text-decoration: underline;
}

.vorgang-meta {
    margin: 0.125rem 0 0;
    color: var(--gedaempft);
    font-size: 0.8125rem;
}

.vorgang-neben {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.knopf.schlicht.vorgang-aktion {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 2rem;
    height: 2rem;
    padding: 0;
}

.vorgang-aktion:focus-visible {
    outline: 2px solid var(--akzent);
    outline-offset: 2px;
}

/* ------------------------------------------------------------------ Detail */

.vorgangskopf {
    padding-bottom: 1rem;
    margin-bottom: 1.5rem;
    border-bottom: 1px solid var(--linie);
}

.vorgangskopf h1 {
    font-size: 1.375rem;
}

.vorgangskopf .vorgang-meta {
    margin-top: 0.375rem;
}

/*
   Hauptspalte und Metaspalte wie in der Issue-Ansicht. Die Metaspalte steht im Markup nach dem
   Inhalt, damit sie auf schmalen Geräten und für einen Screenreader dort landet, wo sie hingehört
   — hinter dem, was sie beschreibt.
*/
.vorgangsinhalt {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1.5rem;
    align-items: start;
}

@media (min-width: 62rem) {
    .vorgangsinhalt {
        grid-template-columns: minmax(0, 1fr) 16rem;
    }
}

.vorgangsspalte {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    min-width: 0;
}

.karte {
    border: 1px solid var(--linie);
    border-radius: var(--radius);
}

.karte-kopf {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.625rem 1rem;
    border-bottom: 1px solid var(--linie);
    background: var(--grund-gedaempft);
    border-radius: var(--radius) var(--radius) 0 0;
}

.karte-rumpf {
    padding: 1rem;
}

/*
   Die Beschreibung ist reiner Text, keine Auszeichnungssprache. pre-wrap erhält Zeilenumbrüche
   und Leerzeilen des Verfassers und bricht lange Zeilen trotzdem um. overflow-wrap fängt das ab,
   was sonst die Spalte sprengt: eine URL ohne Leerzeichen.
*/
.beschreibung {
    margin: 0;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.leer {
    margin: 0;
    color: var(--gedaempft);
    font-style: italic;
}

.teile {
    margin: 0;
    padding: 0;
    list-style: none;
}

.teil {
    padding: 0.75rem 1rem;
    border-bottom: 1px solid var(--linie);
}

.teil:last-child {
    border-bottom: 0;
}

.teil-kopf {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.75rem;
}

.teil-titel {
    color: var(--schrift-stark);
    font-weight: 600;
}

/*
   Der Verweis auf die Bearbeitung eines Benutzers, rechts neben seinem Namen in der Liste. Die
   Liste selbst trägt keine eigene Gestaltung — sie ist dafür zu kurz —, also genügt hier der
   Abstand und ein kleinerer Grad, damit der Name die Zeile trägt und nicht der Verweis.
*/
.bearbeiten {
    margin-left: 0.75rem;
    font-size: 0.8125rem;
}

/*
   Der Bearbeiter einer Activity (WM11) und die Bedienung dazu. Die fehlende Zuweisung sieht aus
   wie eine fehlende Beschreibung, ist aber eine eigene Klasse: `leer` gehört dem fehlenden Text,
   und beides zu vermengen hieße, dass eine Änderung am einen still das andere trifft.
*/
.teil-bearbeiter {
    margin: 0.375rem 0 0;
    font-size: 0.8125rem;
}

.ohne-bearbeiter {
    color: var(--gedaempft);
    font-style: italic;
}

.teil-zuweisung {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

/*
   Sichtbar für Vorleseprogramme, unsichtbar auf dem Bildschirm. Die Auswahl steht neben dem
   Titel der Activity und ist für das Auge damit beschriftet; ohne `label` hätte sie für eine
   Sprachausgabe gar keinen Namen — und bei mehreren Activities auf einer Seite auch keinen
   unterscheidbaren.
*/
.versteckt {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.teil .beschreibung {
    margin-top: 0.375rem;
}

.teil .leer {
    margin-top: 0.375rem;
    font-size: 0.8125rem;
}

dl {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.375rem 1rem;
    margin: 0;
}

dt {
    color: var(--gedaempft);
}

dd {
    margin: 0;
    color: var(--schrift-stark);
}

/* --------------------------------------------------------------- Plaketten */

.plakette {
    display: inline-block;
    padding: 0.0625rem 0.5rem;
    border-radius: 0.625rem;
    background: var(--grund-aktiv);
    color: var(--schrift);
    font-size: 0.75rem;
    white-space: nowrap;
}

.plakette.zahl {
    font-variant-numeric: tabular-nums;
}

/*
   Der Arbeitszustand (WM6, WM12). Laufende Arbeit hebt sich ab, abgeschlossene tritt zurück;
   der Rahmen ist ein innerer Schatten, damit die Plakette nicht wächst und die Zeile nicht
   springt, wenn der Zustand wechselt.
*/
.plakette.zustand.in-bearbeitung {
    box-shadow: inset 0 0 0 1px var(--akzent);
    color: var(--schrift-stark);
}

.plakette.zustand.abgeschlossen {
    color: var(--gedaempft);
}

/*
   Die Plakette mit Symbol (Liste der Cases): Kontur, Symbol und Schrift tragen die Farbe des
   Zustands auf einem leicht getönten Grund. Die Farbe unterstützt nur — das Symbol (Kreis, Uhr,
   Haken) und die Bezeichnung unterscheiden die Zustände auch ohne sie.
*/
.plakette.zustand.mit-symbol {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.125rem 0.625rem 0.125rem 0.5rem;
    border-radius: 999px;
    font-weight: 500;
}

.plakette.zustand.mit-symbol svg {
    flex-shrink: 0;
}

.plakette.zustand.mit-symbol.offen {
    background: var(--zustand-offen-flaeche);
    box-shadow: inset 0 0 0 1px var(--zustand-offen);
    color: var(--zustand-offen);
}

.plakette.zustand.mit-symbol.in-bearbeitung {
    background: var(--zustand-bearbeitung-flaeche);
    box-shadow: inset 0 0 0 1px var(--zustand-bearbeitung);
    color: var(--zustand-bearbeitung);
}

.plakette.zustand.mit-symbol.abgeschlossen {
    background: var(--zustand-abgeschlossen-flaeche);
    box-shadow: inset 0 0 0 1px var(--zustand-abgeschlossen);
    color: var(--zustand-abgeschlossen);
}

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

.feld {
    margin-bottom: 1rem;
    max-width: 44rem;
}

.feld label {
    display: block;
    color: var(--schrift-stark);
    font-weight: 600;
    margin-bottom: 0.25rem;
}

.feld input,
.feld select,
.feld textarea {
    width: 100%;
    padding: 0.375rem 0.625rem;
    border: 1px solid var(--linie-stark);
    border-radius: var(--radius);
    background: var(--grund);
    color: var(--schrift);
    font: inherit;
}

/*
   Die Beschreibung ist ein textarea und deshalb von Hand höhenverstellbar. Ohne resize: vertical
   zieht der Nutzer sie auch in die Breite und schiebt damit das Formular aus dem Raster.
*/
.feld textarea {
    min-height: 8rem;
    resize: vertical;
    line-height: 1.5;
}

.feld input:focus,
.feld select:focus,
.feld textarea:focus {
    outline: 2px solid var(--akzent-flaeche);
    outline-offset: -1px;
}

fieldset {
    border: 1px solid var(--linie);
    border-radius: var(--radius);
    padding: 1rem 1rem 0;
    margin: 0 0 1rem;
    max-width: 44rem;
}

legend {
    color: var(--schrift-stark);
    font-weight: 600;
    padding: 0 0.375rem;
}

.formularfuss {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    padding-top: 0.5rem;
    max-width: 44rem;
}

/* ------------------------------------------------------------------ Knöpfe */

.knopf {
    display: inline-block;
    padding: 0.375rem 0.75rem;
    border: 1px solid var(--linie-stark);
    border-radius: var(--radius);
    background: var(--grund);
    color: var(--schrift);
    font: inherit;
    text-decoration: none;
    cursor: pointer;
}

.knopf:hover {
    background: var(--grund-gedaempft);
    border-color: var(--gedaempft);
}

.knopf.bestaetigen {
    background: var(--akzent-flaeche);
    border-color: var(--akzent-flaeche);
    color: var(--auf-akzent);
}

/*
   Auf hellem Grund wurde der Knopf beim Überfahren dunkler. Hier ist die Fläche selbst hell und
   der Grund dunkel, also geht der Hover in die andere Richtung: `--akzent-hell` ist die Aufhellung
   des Markenorange. Ein Abdunkeln würde ihn dem Grund annähern und wie ein Ausgrauen wirken.
*/
.knopf.bestaetigen:hover {
    background: var(--akzent-hell);
    border-color: var(--akzent-hell);
}

.knopf.gefaehrlich {
    border-color: var(--fehler-linie);
    color: var(--fehler);
}

.knopf.gefaehrlich:hover {
    background: var(--fehler-flaeche);
    border-color: var(--fehler-linie);
}

.knopf:disabled {
    opacity: 0.65;
    cursor: default;
}

/* Ein Verweis, der wie ein Verweis aussieht, aber in einer Knopfreihe steht. */
.knopf.schlicht {
    border-color: transparent;
    background: transparent;
    color: var(--akzent);
    padding-inline: 0.25rem;
}

.knopf.schlicht:hover {
    background: var(--grund-aktiv);
    border-color: transparent;
}

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

.hinweis {
    margin: 0.25rem 0 0;
    color: var(--gedaempft);
    font-size: 0.8125rem;
}

fieldset .hinweis:first-of-type {
    margin: 0 0 1rem;
}

.fehler,
.validation-message {
    color: var(--fehler);
}

.fehler {
    padding: 0.625rem 1rem;
    margin: 0 0 1rem;
    border: 1px solid var(--fehler-linie);
    border-radius: var(--radius);
    background: var(--fehler-flaeche);
}

.validation-message {
    display: block;
    margin-top: 0.25rem;
    font-size: 0.8125rem;
}

.bestaetigung {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    color: var(--fehler);
}

/*
   Die Leiste von Blazor kommt aus der Vorlage mit hellem Amber und einem Schlagschatten nach oben.
   Beides trägt hier nicht: Auf der dunklen Seite wäre die helle Fläche der einzige weiße Fleck, und
   ein schwarzer Schatten ist auf dunklem Grund nicht zu sehen.

   Sie übernimmt deshalb die Fehlerfarben statt eines eigenen Warntons. Das ist keine Sparsamkeit,
   sondern die Folge des Akzents: Seit der Verweis Markenorange trägt, wäre ein gelbes Amber
   daneben kein Warnsignal mehr, sondern eine zweite Spielart derselben Farbe. Ihr Text sagt „Ein
   unerwarteter Fehler ist aufgetreten"; Rot ist dafür ohnehin die richtige Aussage. Heraus sticht
   sie durch ihre Lage — über die volle Breite am unteren Rand — und als einzige rote Fläche auf
   dem Bildschirm.

   Die Schriftfarbe steht ausdrücklich hier: Die Leiste erbt sonst `--schrift` vom `body` und
   stünde damit in Textgrau auf Dunkelrot.
*/
#blazor-error-ui {
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 0.75rem 1.5rem;
    border-top: 1px solid var(--fehler-linie);
    background: var(--fehler-flaeche);
    color: var(--fehler);
    z-index: 1000;
}

/* Das Icon eines Projects (NALO-55): eigenes Icon und Standard-Icon gleich groß. */
.projekt-icon {
    width: 2rem;
    height: 2rem;
    object-fit: contain;
    flex: none;
}

.feld .projekt-icon {
    width: 6rem;
    height: 6rem;
}
