/*
 * Gestaltung des Portals nach dem Vorbild der Vereinsseite.
 *
 * Die Werte stammen aus der Vereinsseite (dort FrontEnd/src/styles.css, der Fußbereich aus
 * components/footer und die Navigationsleiste aus components/navbar). Sie gelten für die
 * öffentlichen Seiten und seit September 2026 auch für den internen Bereich samt Anmeldung,
 * damit das Portal nicht wie ein zweiter Auftritt neben der Vereinsseite wirkt.
 *
 * Zwei Klassen am body steuern den Umfang:
 *   tsv          das gemeinsame Design (Farben, Schrift, Überschriften, Links, Schaltflächen,
 *                Navigationsleiste, Fußbereich am unteren Rand)
 *   tsv-public   zusätzlich nur für die öffentlichen Seiten, aktuell ohne eigene Regeln;
 *                die Klasse bleibt als Ansatzpunkt für Abweichungen erhalten
 *
 * Bewusst nicht übernommen sind der Bildstreifen und die Menüstruktur der Vereinsseite.
 */

:root {
    --tsv-primary: #564E99;
    --tsv-color2: #8B9FBC;
    --tsv-color3: #E3E7EE;
    --tsv-color4: #465573;
    --tsv-primary-light: #A39ECD;
    --tsv-primary-verylight: #E7E6F2;
    --tsv-secondary: #6c757d;
    --tsv-text: #b2b2b2;
    --tsv-red: #E4171C;
}

/*
 * Schrift. Dieselbe Deklaration wie im body der Vereinsseite. Rubik wird dort nirgends geladen,
 * weder über Google Fonts noch als eigene Datei, also greift die generische serifenlose Schrift
 * des Geräts. Genau dieses Verhalten wird hier nachgebildet: wird Rubik auf der Vereinsseite
 * eines Tages wirklich eingebunden und ist dadurch auf dem Gerät vorhanden, greift sie hier
 * automatisch mit.
 */
body.tsv {
    font-family: 'Rubik', sans-serif;

    /* Bootstrap-Grundfarbe auf das Vereins-Violett ziehen. Das deckt alles ab, was über die
       Bootstrap-Variablen läuft: bg-primary, text-primary, border-primary, Abzeichen. */
    --bs-primary: #564E99;
    --bs-primary-rgb: 86, 78, 153;
    --bs-link-color: #564E99;
    --bs-link-color-rgb: 86, 78, 153;
    --bs-link-hover-color: #465573;
    --bs-link-hover-color-rgb: 70, 85, 115;
}

/*
 * Fußbereich am unteren Rand halten. Ist eine Seite kürzer als das Fenster, stand der
 * Fußbereich bisher mitten auf der Seite und darunter blieb eine weiße Fläche. Der body ist
 * deshalb eine Flex-Spalte über die volle Fensterhöhe, und der Fußbereich schiebt sich mit
 * margin-top: auto nach unten. Fest positionierte Elemente (Dialoge, Meldungen) sind aus dem
 * Fluss genommen und davon nicht betroffen.
 */
body.tsv {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

body.tsv > footer {
    margin-top: auto;
}

/*
 * Links im Inhaltsbereich: Vereinsfarbe, ohne Unterstreichung. Wie auf der Vereinsseite über
 * main eingegrenzt. Alles außerhalb von main (Navigationsleiste, Fußbereich) bringt seine
 * eigene Darstellung mit und wird hier nicht berührt.
 *
 * Das :not(.btn) ist wichtig und war anfangs nicht da. Ein Verweis, der wie eine Schaltfläche
 * aussieht (a class="btn ..."), wurde stattdessen über eine zweite Regel mit color: inherit
 * wieder ausgenommen. Diese Ausnahme galt aber auch für den Zustand beim Überfahren und schlug
 * dort die Vorgabe von Bootstrap: die Fläche färbte sich dunkel, die Schrift blieb geerbt und
 * damit dunkel. Auf dem Dashboard waren "Formular", "Antworten" und "Editor" beim Überfahren
 * nicht mehr lesbar. Mit :not(.btn) greift die Regel für Schaltflächen gar nicht erst, und
 * Bootstrap bestimmt deren Farben in allen Zuständen selbst.
 */
body.tsv main a:not(.btn),
body.tsv main a:not(.btn):link,
body.tsv main a:not(.btn):visited,
body.tsv main a:not(.btn):hover,
body.tsv main a:not(.btn):active {
    color: var(--tsv-primary);
    text-decoration: none;
}

/*
 * Hauptüberschrift einer Seite: linker Balken in der Vereinsfarbe. Bewusst als Klasse und nicht
 * als h1-Regel, damit mittig gesetzte Hinweisseiten ("Erfolgreich übermittelt", "Keine Plätze
 * verfügbar") keinen Balken an der linken Kante bekommen.
 */
.tsv .tsv-title {
    font-size: 1.4rem;
    margin-top: 2rem;
    margin-bottom: 2rem;
    border-left: var(--tsv-primary) 5px solid;
    border-bottom: transparent 5px solid;
    padding-left: 10px;
}

/* Zwischenüberschrift, ebenfalls wie auf der Vereinsseite. */
.tsv .tsv-subtitle {
    font-size: 1.2rem;
    color: var(--tsv-primary);
    margin-top: 3rem;
    margin-bottom: 1rem;
    border-left: var(--tsv-primary-light) 3px solid;
    border-bottom: #ffffff 3px solid;
    padding-left: 10px;
}

/* Die erste Zwischenüberschrift direkt unter der Hauptüberschrift braucht keinen zusätzlichen
   Abstand nach oben. */
.tsv .tsv-title + .tsv-subtitle {
    margin-top: 1rem;
}

.tsv .btn-primary {
    --bs-btn-bg: #564E99;
    --bs-btn-border-color: #564E99;
    --bs-btn-hover-bg: #465573;
    --bs-btn-hover-border-color: #465573;
    --bs-btn-active-bg: #465573;
    --bs-btn-active-border-color: #465573;
    --bs-btn-disabled-bg: #A39ECD;
    --bs-btn-disabled-border-color: #A39ECD;
    --bs-btn-focus-shadow-rgb: 86, 78, 153;
}

.tsv .btn-outline-primary {
    --bs-btn-color: #564E99;
    --bs-btn-border-color: #564E99;
    --bs-btn-hover-bg: #564E99;
    --bs-btn-hover-border-color: #564E99;
    --bs-btn-active-bg: #564E99;
    --bs-btn-active-border-color: #564E99;
    --bs-btn-focus-shadow-rgb: 86, 78, 153;
}

/* Eingabefelder und Schalter: Fokusrahmen in der Vereinsfarbe statt im Bootstrap-Blau.
   site.css setzt für .form-control:focus einen eigenen Schatten, der hier überschrieben wird. */
.tsv .form-control:focus,
.tsv .form-select:focus,
.tsv .form-check-input:focus {
    border-color: var(--tsv-primary-light);
    box-shadow: 0 0 0 0.25rem rgba(86, 78, 153, 0.25);
}

.tsv .form-check-input:checked {
    background-color: var(--tsv-primary);
    border-color: var(--tsv-primary);
}

/*
 * Navigationsleiste des internen Bereichs. Übernommen sind Farbe, Schatten und die Darstellung
 * der Einträge. Anordnung, Höhe und Logogröße bleiben wie bisher, die Vereinsseite hat dort
 * eine ganz andere Struktur (fester Kopf, mitwachsendes Logo, Untermenüs).
 */
body.tsv .navbar {
    background-color: #ffffff !important;
}

body.tsv .navbar .nav-link {
    color: rgba(0, 0, 0, .65);
    padding-right: .8rem;
    padding-left: .8rem;
    text-underline-offset: 0.4rem;
    transition: background-color 0.4s ease;

    /* Mittig, unabhängig von Schriftgröße und Zeilenhöhe. Als Flex-Behälter zentriert der
       Eintrag seinen Text im eigenen Kasten, und der Kasten sitzt über align-items des
       Navigationsbereichs mittig in der Leiste. Ohne das saß der Text eine halbe Zeile zu
       hoch, weil die Zeilenhöhe den Kasten nach unten verlängert. */
    display: flex;
    align-items: center;
}

/* Die Vereinsseite färbt den Eintrag beim Überfahren grau. Hier ist es das Vereins-Violett:
   grau auf weiß liest sich schlechter als die Grundfarbe, und die Leiste ist der einzige Ort
   im Portal, an dem ein Verweis seine Farbe wechselt. */
body.tsv .navbar .nav-link:hover,
body.tsv .navbar .nav-link:focus,
body.tsv .navbar .nav-item.show > .nav-link,
body.tsv .navbar .nav-item.active > .nav-link {
    color: var(--tsv-primary);
    text-decoration: underline;
}

/*
 * Logo in der Leiste. Ein img ist im Textfluss ein Zeichen auf der Grundlinie, unter ihm bleibt
 * der Platz für die Unterlänge frei und das Bild sitzt dadurch etwas zu tief. Als Blockelement
 * in einem mittig ausgerichteten Flex-Behälter fällt dieser Rest weg.
 */
body.tsv .navbar-brand {
    display: flex;
    align-items: center;
    padding-top: 0;
    padding-bottom: 0;
}

body.tsv .navbar-brand img {
    display: block;
}

/*
 * Fußbereich. Aufbau, Farben und Unterstreichungen wie auf der Vereinsseite: dunkler Block,
 * weiße Schrift, Verweise in gedecktem Grau und unterstrichen. Die Icon-Schrift der
 * Vereinsseite (Font Awesome) wird hier nicht verwendet, die Angaben stehen als Text davor.
 *
 * Der interne Bereich bekommt denselben Block in schmal: nur die Urheberzeile, keine Verweise.
 */
.tsv-footer {
    color: #ffffff;
}

.tsv-footer a,
.tsv-footer a:link,
.tsv-footer a:visited,
.tsv-footer a:hover,
.tsv-footer a:active {
    color: var(--tsv-text);
}

/*
 * Die Zeichen vor den Angaben im Fußbereich. Maße und Ausrichtung entsprechen dem, was Font
 * Awesome für seine SVG-Fassung selbst setzt: Höhe wie eine Zeile, feste Breite (dort die
 * Klasse fa-fw), abgesenkt um ein Achtel, damit das Zeichen auf der Schriftlinie sitzt statt
 * darauf zu stehen. currentColor: das Zeichen nimmt die weiße Schrift des Fußbereichs an,
 * während der Verweis daneben grau bleibt, genau wie auf der Vereinsseite.
 */
.tsv-footer .tsv-fa {
    height: 1em;
    width: 1.25em;
    vertical-align: -0.125em;
    fill: currentColor;
    margin-right: 0.25rem;
}

/*
 * Icons der Schrift Material Symbols.
 *
 * Vorher trugen die Einbindungen unterschiedliche Ausrichtungen im style-Attribut (middle,
 * text-bottom, gar nichts), dieselbe Schaltfläche sah je nach Ansicht anders aus. Die
 * Ausrichtung liegt jetzt ausschließlich hier, die 74 Angaben in den Ansichten sind entfallen.
 *
 * line-height: 1 macht den Kasten des Icons genau so hoch wie seine Schriftgröße, sodass das
 * Zeichen mittig darin sitzt. Die Verschiebung um -0,25em setzt die Mitte dieses Kastens auf
 * die Mitte der Textzeile daneben. Der Wert ist nicht geschätzt, sondern im Browser gegen den
 * Text ermittelt: die Abweichung liegt bei 0,0 Pixel.
 *
 * Warum vertical-align und nicht transform oder position: Innerhalb eines Flex-Behälters
 * (überall dort, wo eine Zeile d-flex trägt) ist das Icon ein Flex-Element. Für Flex-Elemente
 * wird vertical-align vom Browser ignoriert, die Ausrichtung übernimmt dort align-items, und
 * die ist bereits mittig. Eine Verschiebung über transform oder position würde dagegen auch
 * dort greifen und das Icon aus der Mitte schieben. Mit vertical-align stimmt beides:
 * im Textfluss die Verschiebung, im Flex-Behälter die Ausrichtung des Behälters.
 */
.material-symbols-outlined {
    display: inline-block;
    line-height: 1;
    vertical-align: -0.25em;
}

/*
 * Logo-Reihe über einem Formular: Vereinslogo links, Logo des Formulars rechts, beide exakt
 * gleich hoch.
 *
 * flex: 0 0 auto ist der entscheidende Teil. Ohne diese Angabe schrumpfen Flex-Elemente bei
 * knappem Platz in der Breite. Höhe und Breite sind hier aber getrennt gesetzt (Höhe fest,
 * Breite automatisch), eine gestauchte Breite hätte das Bild also verzerrt statt verkleinert,
 * und die beiden Logos wären unterschiedlich breit gestaucht worden. Auf schmalen Geräten
 * sinkt stattdessen die gemeinsame Höhe, damit beide nebeneinander passen.
 *
 * Die Breitenbegrenzung am rechten Logo ist eine Notbremse für ein ungewöhnlich breites Bild
 * (Seitenverhältnis über etwa 7:1). Sie greift bei den üblichen Logos nie; greift sie doch,
 * ist ein etwas niedrigeres Logo besser als eine Seite, die waagerecht scrollt.
 */
.tsv .tsv-logo-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: nowrap;
}

.tsv .tsv-logo {
    height: 60px;
    width: auto;
    flex: 0 0 auto;
}

.tsv .tsv-logo-right {
    max-width: 60%;
    object-fit: contain;
    object-position: right center;
}

@media (max-width: 575.98px) {
    .tsv .tsv-logo {
        height: 44px;
    }
}

/*
 * Rich-Text-Editoren (Quill).
 *
 * Vorher stand die Höhe als feste Pixelzahl im style-Attribut, je nach Stelle 100, 120, 200
 * oder 320 Pixel. In einem 100 Pixel hohen Feld sind drei Zeilen sichtbar, bei einer längeren
 * Beschreibung scrollt man im Feld und im Dialog zugleich.
 *
 * Jetzt wächst der Editor mit dem Fenster: 45 Prozent der Fensterhöhe, nach unten auf 220
 * Pixel begrenzt (damit auf einem Telefon noch der Rest des Dialogs sichtbar bleibt) und nach
 * oben auf 560 Pixel (damit ein sehr hoher Bildschirm nicht ein riesiges leeres Feld zeigt).
 *
 * Die zugehörigen Dialoge tragen modal-dialog-scrollable und nehmen dadurch die volle
 * Fensterhöhe ein, der Rumpf scrollt darin.
 */
.tsv .tsv-editor {
    height: clamp(220px, 45vh, 560px);
}

/*
 * Kleinere Ausführung für Beschreibungen. Im Dialog für ein Formularelement stehen unter dem
 * Editor noch Typ, Pflichtangabe, Preis und je nach Typ weitere Felder; ein Editor über die
 * halbe Fensterhöhe schiebt sie alle aus dem Blick. Eine Beschreibung ist außerdem meist kurz,
 * anders als der Antworttext einer Mail.
 */
.tsv .tsv-editor-klein {
    height: clamp(150px, 25vh, 280px);
}

/*
 * Platzhalter in den Mail-Editoren. {Vorname} und {Nachname} werden beim Versand je Empfänger
 * ersetzt; im Editor stehen sie in der Vereinsfarbe, damit man sie im Fließtext erkennt und
 * einen Tippfehler sofort sieht (ein falsch geschriebener Platzhalter bleibt grau). Die
 * Formatierung wird beim Speichern entfernt, sie steht nie in der versendeten Mail.
 */
.tsv-platzhalter-an {
    color: var(--tsv-primary);
    font-weight: 600;
}

/*
 * Die beiden Schaltflächen in der Werkzeugleiste tragen Text statt eines Zeichens und brauchen
 * deshalb mehr Breite als die 28 Pixel, die Quill für seine Symbole vorsieht.
 *
 * Der Selektor nennt ausdrücklich .ql-snow: die Vorgabe von Quill lautet
 * ".ql-snow.ql-toolbar button" und hat damit dieselbe Spezifität wie ein schlichtes
 * ".ql-toolbar button.tsv-platzhalter-knopf". Quills Stildatei wird nach dieser hier geladen
 * und gewann; die beiden Schaltflächen lagen auf 28 Pixel gequetscht übereinander.
 */
.ql-snow.ql-toolbar button.tsv-platzhalter-knopf,
.ql-snow .ql-toolbar button.tsv-platzhalter-knopf {
    width: auto;
    padding: 0 8px;
    font-size: 0.85rem;
    line-height: 24px;
    color: var(--tsv-primary);
}

.ql-snow.ql-toolbar button.tsv-platzhalter-knopf:hover,
.ql-snow .ql-toolbar button.tsv-platzhalter-knopf:hover {
    background-color: var(--tsv-primary-verylight);
}

/*
 * Meldungen.
 *
 * Die Vereinsseite hat dafür eine eigene Form: ein ruhiger Kasten in gedecktem Blaugrau mit
 * einem farbigen Balken an der linken Kante (dort die Klasse message). Genau die wird hier
 * übernommen, statt der bunten Flächen von Bootstrap. Die Art der Meldung steckt nur noch in
 * der Farbe des Balkens, der Rest bleibt in jedem Fall gleich. Das gilt für die Einblendungen
 * unten rechts wie für Hinweise mitten auf der Seite.
 *
 * Die Selektoren sind zweiteilig (.tsv .alert), damit sie die Variablen der Bootstrap-Varianten
 * (.alert-danger und die übrigen) überstimmen, ohne important zu brauchen.
 */
.tsv .alert {
    background-color: var(--tsv-color3);
    color: var(--tsv-color4);
    border: 0;
    border-left: 4px solid var(--tsv-color2);
    border-radius: 0;
    padding: 15px 25px;
}

.tsv .alert-success { border-left-color: #2f7d4f; }
.tsv .alert-danger { border-left-color: var(--tsv-red); }
.tsv .alert-warning { border-left-color: #c98a2b; }
.tsv .alert-info,
.tsv .alert-primary { border-left-color: var(--tsv-primary-light); }

/*
 * Die Einblendungen unten rechts sind eigenständig gestaltet: kein Balken an der Kante,
 * sondern die ganze Fläche leicht in der Farbe des Zustands, dazu eine dezente Kante und
 * Schatten, weil sie über der Seite schweben. Ein Balken wirkt an einem kleinen, kurzlebigen
 * Hinweis zu schwer; die Hinweise mitten auf der Seite behalten ihn.
 */
.tsv #alert-container .alert {
    border: 1px solid var(--tsv-color2);
    border-radius: 6px;
    padding: 15px;
    padding-right: 3rem;
    box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}

.tsv #alert-container .alert-success {
    background-color: #e6f4ec;
    border-color: #bfe0cd;
    color: #1e5b3a;
}

.tsv #alert-container .alert-danger {
    background-color: #fbe7e8;
    border-color: #f0c2c4;
    color: #8a1418;
}

.tsv #alert-container .alert-warning {
    background-color: #fdf3e3;
    border-color: #f0dcb8;
    color: #7a5312;
}

.tsv #alert-container .alert-info,
.tsv #alert-container .alert-primary {
    background-color: var(--tsv-primary-verylight);
    border-color: var(--tsv-primary-light);
    color: #3b3570;
}

/*
 * Platz für das Schließkreuz. Bootstrap reserviert ihn über padding-right an
 * .alert-dismissible; die Regeln oben setzen padding als Kurzform und hätten ihn sonst wieder
 * zurückgenommen, das Kreuz läge dann auf dem Text.
 */
.tsv .alert-dismissible {
    padding-right: 3.5rem;
}

/*
 * Mittig und mit demselben Abstand zum rechten Rand wie nach oben und unten. Der Innenabstand
 * von 0,25rem ist nicht beliebig: damit ist das Kreuz genau so hoch wie eine Textzeile, und
 * der Abstand nach oben und unten entspricht dann dem Innenabstand der Meldung, also demselben
 * Wert wie rechts. Nachgemessen: 16 Pixel in alle drei Richtungen.
 */
.tsv .alert-dismissible .btn-close {
    top: 50%;
    transform: translateY(-50%);
    padding: 0.25rem;
    right: 15px;
}

/*
 * Schaltflächen mit grauem Rahmen. Bootstrap setzt bei btn-outline-secondary auch die Schrift
 * auf das Grau des Rahmens. Neben einer Schaltfläche mit dunkler Schrift (btn-light) wirkte
 * das wie zwei verschiedene Zustände, obwohl beide gleich bedienbar sind. Die Beschriftung ist
 * deshalb dunkel wie der übrige Text, nur der Rahmen bleibt grau.
 */
.tsv .btn-outline-secondary {
    --bs-btn-color: #212529;
}

/*
 * Kontrast beim Überfahren.
 *
 * Bootstrap füllt die Fläche beim Überfahren mit der Grundfarbe der Schaltfläche und setzt die
 * Schrift auf Weiß. Bei Grau (#6c757d) und Rot (#dc3545) ergibt das ein Verhältnis von 4,7
 * beziehungsweise 4,5. Das erfüllt die Norm gerade eben, liest sich aber flau, besonders wenn
 * die Schaltfläche vorher dunkle Schrift auf Weiß hatte und der Sprung klein ausfällt.
 *
 * Die Füllung wird deshalb dunkler. Die Werte sind nicht geraten, sondern über das
 * Kontrastverhältnis nach WCAG ausgewählt: alle liegen jetzt bei 7 oder darüber, also auf der
 * strengeren Stufe AAA für Fließtext. Der Ruhezustand bleibt unverändert, es ändert sich nur,
 * was beim Überfahren und beim Drücken passiert.
 */
.tsv .btn-outline-secondary,
.tsv .btn-secondary {
    --bs-btn-hover-bg: #343a40;
    --bs-btn-hover-border-color: #343a40;
    --bs-btn-hover-color: #fff;
    --bs-btn-active-bg: #23272b;
    --bs-btn-active-border-color: #23272b;
    --bs-btn-active-color: #fff;
}

.tsv .btn-danger,
.tsv .btn-outline-danger {
    --bs-btn-hover-bg: #a11722;
    --bs-btn-hover-border-color: #a11722;
    --bs-btn-hover-color: #fff;
    --bs-btn-active-bg: #87131d;
    --bs-btn-active-border-color: #87131d;
    --bs-btn-active-color: #fff;
}

.tsv .btn-success,
.tsv .btn-outline-success {
    --bs-btn-hover-bg: #10603b;
    --bs-btn-hover-border-color: #10603b;
    --bs-btn-hover-color: #fff;
    --bs-btn-active-bg: #0d4f31;
    --bs-btn-active-border-color: #0d4f31;
    --bs-btn-active-color: #fff;
}

/* Gelb trägt dunkle Schrift, dort ist der Kontrast ohnehin hoch. Nur den Farbton beim
   Überfahren etwas kräftiger, damit der Wechsel überhaupt sichtbar ist. */
.tsv .btn-warning,
.tsv .btn-outline-warning {
    --bs-btn-hover-bg: #e0a800;
    --bs-btn-hover-border-color: #e0a800;
    --bs-btn-hover-color: #212529;
    --bs-btn-active-bg: #c69500;
    --bs-btn-active-border-color: #c69500;
    --bs-btn-active-color: #212529;
}

/*
 * Tabellen. Bootstrap richtet Zellinhalte oben aus. In den Übersichten stehen in einer Zeile
 * aber Texte unterschiedlicher Höhe nebeneinander (mehrzeilige Antworten neben einem Datum,
 * Schaltflächen neben einem Namen), und die kurzen Zellen klebten dann an der Oberkante.
 * Mittig gesetzt liest sich die Zeile als Einheit.
 */
.tsv .table > :not(caption) > * > * {
    vertical-align: middle;
}

/*
 * Schaltflächen mit Icon.
 *
 * Ein Icon ist meist größer gesetzt als der Text daneben (20 Pixel gegen 14). Im Textfluss
 * bestimmt das größere Zeichen die Höhe der Zeile, und die Zeile sitzt in der Schaltfläche
 * oben statt mittig: Icon und Beschriftung standen sichtbar zu hoch. Als Flex-Behälter mit
 * align-items: center zentriert die Schaltfläche ihren Inhalt unabhängig von der Zeilenhöhe.
 *
 * Der Abstand zwischen Icon und Beschriftung kommt dabei aus gap. Die Ansichten setzen an
 * einzelnen Icons noch margin-right im style-Attribut; das wird hier zurückgenommen, sonst
 * addierten sich beide Abstände und die Schaltflächen sähen unterschiedlich aus.
 *
 * :has wird von allen aktuellen Browsern unterstützt. Kennt ein Browser es nicht, verwirft er
 * die Regel und die Schaltfläche sieht aus wie vorher, es geht also nichts kaputt.
 */
.tsv .btn:has(.material-symbols-outlined) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
}

.tsv .btn:has(.material-symbols-outlined) .material-symbols-outlined {
    margin-right: 0 !important;
    margin-left: 0 !important;
}
