/* ── Breakpoints (#186) ───────────────────────────────────
   3 canonical breakpoints used throughout this file. CSS custom
   properties cannot be referenced inside an @media condition, so
   these are documented here and used as literal pixel values —
   the paired "-1" value below each is the max-width complement
   used to avoid a 1px overlap with the next tier's min-width query.
     --bp-sm: 640px  (max-width pair: 639px)
     --bp-md: 768px  (max-width pair: 767px)
     --bp-lg: 1024px (max-width pair: 1023px)
   Do not introduce new breakpoint values outside this set. */

/* ── Design Tokens ────────────────────────────────────── */
:root {
    /* Bootstrap-Overrides */
    --bs-body-bg: #070d1a;
    --bs-body-color: #f8fafc;
    --bs-primary: #34d399;
    --bs-primary-rgb: 52, 211, 153;
    --bs-secondary-bg: #1e293b;
    --bs-border-color: #334155;
    --bs-link-color: #34d399;
    --bs-link-hover-color: #6ee7b7;
    --bs-danger: #ef4444;
    --bs-danger-rgb: 239, 68, 68;
    --bs-warning: #f59e0b;
    --bs-warning-rgb: 245, 158, 11;

    /* Surfaces */
    --tp-bg-deep:       #070d1a;
    --tp-bg-base:       #0f172a;
    --tp-surface:       #1e293b;
    --tp-surface-hover: #293548;
    /* #1463: Kopfband der Kacheln (tp-panel-header) - im Light Mode deutlich dunkler als die Fläche. */
    --tp-panel-header-bg: #293548;
    --tp-panel-header-border: #1a2540;
    --tp-border:        #334155;
    --tp-border-subtle: #1a2540;
    --tp-border-hover:  #475569;

    /* Semantic colours */
    --tp-success: #34d399;
    --tp-info:    #3b82f6;
    --tp-accent:  #a78bfa;
    --tp-warning: #f59e0b;
    --tp-danger:  #ef4444;

    /* #479: RGB triples of the semantic colours above, for rgba(var(--tp-*-rgb), alpha) tints
       (a CSS custom property can't be interpolated into a hex literal, only supplied whole). */
    --tp-success-rgb: 52, 211, 153;
    --tp-info-rgb:    59, 130, 246;
    --tp-accent-rgb:  167, 139, 250;
    --tp-warning-rgb: 245, 158, 11;
    --tp-danger-rgb:  239, 68, 68;

    /* #723: Textfarben der semantischen Töne - im Dark Mode identisch, im Light Mode dunkler (AA 4,5:1). */
    --tp-success-text: var(--tp-success);
    --tp-info-text:    var(--tp-info);
    --tp-accent-text:  var(--tp-accent);
    --tp-warning-text: var(--tp-warning);
    --tp-danger-text:  var(--tp-danger);

    /* #480: calendar/material-availability category colours. Training/match/task/external alias
       an existing semantic token (single source of truth, themed automatically); appointment and
       birthday are hues that exist only in calendar contexts, so they get their own literal +
       -rgb pair for tints, with WCAG-AA-safe light-theme overrides below (the dark values are too
       light to read on a white background). */
    --tp-cat-appointment:     #60a5fa;
    --tp-cat-appointment-rgb: 96, 165, 250;
    --tp-cat-task:            var(--tp-accent);
    --tp-cat-birthday:        #fbbf24;
    --tp-cat-birthday-rgb:    251, 191, 36;
    --tp-cat-external:        var(--tp-text-muted);
    --tp-cat-training:        var(--tp-success);
    --tp-cat-match:           var(--tp-warning);

    /* #480: the pitch in the match lineup editor represents a real-world green playing field, not
       a brand/status colour - deliberately literal, not aliased to any semantic token. The shirt-
       number badge is likewise a fixed jersey-badge colour, not team/status semantics; --tp-info
       was considered but its lighter blue drops white-text contrast on a 12px badge below AA. */
    --tp-pitch: #2e7d32;
    --tp-pitch-player: #1565c0;
    /* #618: Hallenboden (Handball, Basketball, Volleyball) und neutrales Feld - ebenso bewusst wörtlich. */
    --tp-court: #a0612f;
    --tp-court-neutral: #546e7a;
    --tp-pitch-line: rgba(255, 255, 255, 0.75);
    --tp-pitch-line-strong: rgba(255, 255, 255, 0.95);
    /* #1182: Rasenstreifen, Trikotrand und Schatten auf dem Feld - das Feld bleibt in beiden Themes grün. */
    --tp-pitch-stripe: rgba(0, 0, 0, 0.04);
    --tp-pitch-ring: rgba(255, 255, 255, 0.85);
    --tp-pitch-text-faint: rgba(255, 255, 255, 0.5);
    --tp-pitch-shadow: rgba(0, 0, 0, 0.6);
    --tp-pitch-shadow-strong: rgba(0, 0, 0, 0.9);

    /* Text */
    --tp-text-primary:   #f8fafc;
    --tp-text-secondary: #cbd5e1;
    /* #469: #64748b on --tp-surface only reached 3.07:1 (WCAG AA needs 4.5:1 for body text) -
       #94a3b8 clears it comfortably (~5.7:1 on --tp-surface, ~7:1 on --tp-bg-base). */
    --tp-text-muted:     #94a3b8;
    --tp-text-muted-rgb: 148, 163, 184;
    /* #432: a third, lighter-than-muted tier for secondary-button labels/form-labels/muted badges -
       distinct from --tp-text-muted (used where a legible-on-white value is needed for light theme;
       the placeholder rule below keeps its own separate, intentionally theme-invariant #94a3b8). */
    --tp-text-tertiary:  #94a3b8;

    /* #479: contrast text against an arbitrary, non-token background (SVG bars, calendar blocks) -
       always white regardless of theme, since it reads against the block's own colour, not the page. */
    --tp-on-color-text: #fff;

    /* #1067: feste Töne zu den Grundfarben, die in beiden Themes gleich bleiben (Danger, Accent, Warning, Success
       ändern sich im Light-Block nicht) - als Token statt als Literal in einzelnen Regeln. */
    --tp-danger-hover:    #dc2626;
    --tp-on-accent-text:  #1e1b4b;
    --tp-on-warning-text: #1e1300;
    --tp-success-deep:    #059669;
    --tp-logo-preview-bg: #fff;

    /* Alert/table text — readable against each alert's own ~10%-opacity tinted background, which
       stays a near-transparent tint over whatever page background is behind it in either theme. */
    --tp-alert-danger-text:  #fca5a5;
    --tp-alert-warning-text: #fde68a;
    --tp-alert-success-text: #6ee7b7;
    --tp-alert-info-text:    #93c5fd;

    /* #479: subtle "today" highlight for calendar cells, same hue as the existing --tp-success-based
       today accents in CalendarAgendaView/CalendarGridView (border/text use --tp-success directly). */
    --tp-today-bg: rgba(var(--tp-success-rgb), 0.06);

    /* Legacy aliases (keep for backward compat) */
    --tp-border-color: #334155;
    --tp-accent-color: #34d399;
    /* Note: --tp-accent was #34d399 (green) in v1. It is now #a78bfa (purple/violet).
       Use --tp-success (#34d399) for green, --tp-accent for violet. */
    --tp-amber:   #f59e0b;
    --tp-text:    #f8fafc;
    --tp-muted:   #64748b;

    /* Spacing */
    /* #876: Abstands-Skala im 0,25-rem-Raster (4 px) - padding/margin/gap nehmen diese Tokens statt rem-Literalen. */
    --sp-0: 0;
    --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px;
    --sp-4: 16px; --sp-5: 20px; --sp-6: 24px; --sp-7: 28px; --sp-8: 32px;

    /* Border radius */
    --radius-sm:   4px;
    --radius-md:   8px;
    --radius-lg:   12px;
    --radius-xl:   16px;
    --radius-full: 9999px;

    /* #482: type scale. html's font-size:87.5% below scales all rem values with the user's browser
       zoom/font-size setting - px font-sizes do not, which was the original bug. */
    --fs-2xs: .7rem;   /* chips, tiny counter badges */
    --fs-xs:  .75rem;  /* secondary labels, form hints */
    --fs-sm:  .875rem; /* small body text, table cells */
    --fs-md:  1rem;    /* default body text */
    --fs-lg:  1.25rem; /* section headings, emphasized numbers */
    --fs-xl:  1.75rem; /* page-level headings */
    --fs-2xl: 2rem;    /* hero/stat numbers */
    /* Issue 912: Rahmen für Fremdlogos (Sponsoren) - bewusst in beiden Themes hell, Logos sind für Weiß gemacht. */
    --tp-logo-bg:   #ffffff;
    --tp-logo-text: #475569;

    /* Brand color (overridable per club) */
    --tp-brand-primary: #34d399;
    --tp-brand-on-primary: #0f172a;
    --tp-brand-primary-hover: #6ee7b7;
}

/* Theme toggle: show only the icon matching <html data-theme-preference="…"> */
.tp-theme-icon { display: none; }
[data-theme-preference="System"] .tp-theme-icon[data-theme-show="System"],
[data-theme-preference="Light"]  .tp-theme-icon[data-theme-show="Light"],
[data-theme-preference="Dark"]   .tp-theme-icon[data-theme-show="Dark"]  { display: inline; }

/* ── Light theme overrides ────────────────────────────── */
[data-theme="light"] {
    --bs-body-bg: #ffffff;
    --bs-body-color: #0f172a;
    --bs-secondary-bg: #f1f5f9;
    --bs-border-color: #e2e8f0;

    --tp-bg-deep:       #f8fafc;
    --tp-bg-base:       #ffffff;
    --tp-surface:       #ffffff;
    --tp-surface-hover: #f1f5f9;
    --tp-panel-header-bg: #e2e8f0;
    --tp-panel-header-border: #cbd5e1;
    --tp-border:        #e2e8f0;
    --tp-border-subtle: #f1f5f9;
    --tp-border-hover:  #cbd5e1;

    --tp-text-primary:   #0f172a;
    --tp-text-secondary: #334155;
    --tp-text-muted:     #64748b;
    --tp-text-muted-rgb: 100, 116, 139;
    --tp-text-tertiary:  #64748b;

    --tp-alert-danger-text:  #b91c1c;
    --tp-alert-warning-text: #92400e;
    --tp-alert-success-text: #047857;
    --tp-alert-info-text:    #1e40af;

    /* #723: auf Weiß erreichten die Grundtöne als Text nur 1,9:1 (Success) bis 3,8:1 (Danger). */
    --tp-success-text: #047857;
    --tp-info-text:    #1e40af;
    --tp-accent-text:  #6d28d9;
    --tp-warning-text: #92400e;
    --tp-danger-text:  #b91c1c;

    /* #480: dark values (#60a5fa ~2.3:1, #fbbf24 ~1.6:1) fail AA on white; reuse the already-
       vetted alert-text darks above for a known-good contrast instead of picking new ones. */
    --tp-cat-appointment:     #1e40af;
    --tp-cat-appointment-rgb: 30, 64, 175;
    --tp-cat-birthday:        #92400e;
    --tp-cat-birthday-rgb:    146, 64, 14;

    --tp-text:    #0f172a;
    --tp-muted:   #64748b;
    --tp-border-color: #e2e8f0;
}

[data-theme="light"] body { background-color: var(--tp-bg-deep); color: var(--tp-text-primary); }
/* #469: #94a3b8 on white only reached 2.56:1 (WCAG AA needs 4.5:1) - #64748b clears it (4.76:1). */
[data-theme="light"] .form-control::placeholder { color: var(--tp-text-muted); }
[data-theme="light"] .table thead th { color: var(--tp-text-secondary); }
[data-theme="light"] .text-success { color: var(--tp-success-text) !important; }
[data-theme="light"] .text-warning { color: var(--tp-warning-text) !important; }
[data-theme="light"] .text-danger  { color: var(--tp-danger-text) !important; }
[data-theme="light"] .text-info    { color: var(--tp-info-text) !important; }
[data-theme="light"] .badge.bg-primary { background-color: rgba(var(--tp-success-rgb),0.15) !important; color: var(--tp-alert-success-text) !important; }

/* ── Base ─────────────────────────────────────────────── */
html, body {
    font-family: 'Inter', 'Helvetica Neue', Helvetica, Arial, sans-serif;
    background-color: var(--tp-bg-deep);
    color: var(--tp-text-primary);
    min-height: 100vh;
    font-size: 87.5%;
}

h1:focus { outline: none; }
/* #717: Seitentitel laufen über PageHeader (--fs-lg); ein rohes h1 (z. B. aus Markdown) bekommt nie
   Bootstraps 2,5rem. */
h1 { font-size: var(--fs-xl); }

/* ── Blazor-Bootstrapping (Lade-Spinner) ─────────────────
   #478: vormals in wwwroot/css/app.css (Blazor-Vorlage) mit Bootstrap-Blau
   statt Marken-Tokens. #blazor-error-ui/.blazor-error-boundary sind bereits
   weiter unten ("Blazor error UI"/"Blazor validation") markengerecht gestylt. */
.loading-progress {
    position: absolute;
    display: block;
    width: 8rem;
    height: 8rem;
    inset: 20vh 0 auto 0;
    margin: 0 auto 0 auto;
}

    .loading-progress circle {
        fill: none;
        stroke: var(--tp-border);
        stroke-width: 0.6rem;
        transform-origin: 50% 50%;
        transform: rotate(-90deg);
    }

        .loading-progress circle:last-child {
            stroke: var(--tp-brand-primary);
            stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
            transition: stroke-dasharray 0.05s ease-in-out;
        }

.loading-progress-text {
    position: absolute;
    text-align: center;
    font-weight: bold;
    inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

    .loading-progress-text:after {
        content: var(--blazor-load-percentage-text, "Lädt");
    }

/* ── Links ────────────────────────────────────────────── */
a, .btn-link { color: var(--tp-brand-primary); }
a:hover, .btn-link:hover { color: var(--tp-brand-primary-hover); }

/* ── Buttons ──────────────────────────────────────────── */
.btn-primary {
    background-color: var(--tp-brand-primary);
    border-color: var(--tp-brand-primary);
    color: var(--tp-brand-on-primary);
    font-weight: 600;
}
.btn-primary:hover, .btn-primary:focus {
    filter: brightness(1.08);
    color: var(--tp-brand-on-primary);
}
.btn-secondary, .btn-outline-secondary {
    background-color: transparent;
    border-color: var(--tp-border);
    color: var(--tp-text-tertiary);
}
.btn-secondary:hover, .btn-outline-secondary:hover {
    background-color: var(--tp-surface-hover);
    border-color: var(--tp-border-hover);
    color: var(--tp-text-primary);
}
.btn-danger {
    background-color: var(--tp-danger);
    border-color: var(--tp-danger);
    color: var(--tp-on-color-text);
}
.btn-danger:hover {
    background-color: var(--tp-danger-hover);
    border-color: var(--tp-danger-hover);
    color: var(--tp-on-color-text);
}
.btn-outline-danger {
    background-color: transparent;
    border-color: var(--tp-danger);
    color: var(--tp-danger-text);
}
.btn-outline-danger:hover {
    background-color: rgba(var(--tp-danger-rgb),0.1);
    border-color: var(--tp-danger);
    color: var(--tp-danger-text);
}
.btn-outline-warning {
    background-color: transparent;
    border-color: var(--tp-warning);
    color: var(--tp-warning-text);
}
.btn-outline-warning:hover {
    background-color: rgba(var(--tp-warning-rgb),0.1);
    color: var(--tp-warning-text);
    border-color: var(--tp-warning);
}

/* Focus ring — keyboard-visible focus (U2: :focus-visible) */
.btn:focus, .btn:active:focus, .form-check-input:focus {
    box-shadow: 0 0 0 3px rgba(var(--tp-success-rgb), 0.15);
}
:focus-visible {
    outline: 2px solid var(--tp-success);
    outline-offset: 2px;
}
a:focus-visible, .btn:focus-visible, [tabindex]:focus-visible:not(h1) {
    outline: 2px solid var(--tp-success);
    outline-offset: 2px;
    box-shadow: 0 0 0 4px rgba(var(--tp-success-rgb), 0.15);
}
h1:focus-visible { outline: none; box-shadow: none; }
/* `outline`/`box-shadow` on <tr> is not reliably painted by browsers (table-row isn't a normal
   box for outline purposes) — the [tabindex]:focus-visible rule above is invisible on rows added
   for #177's keyboard-accessible tables/lists, so those get a background highlight instead. */
tr[tabindex]:focus-visible {
    outline: none;
    box-shadow: none;
    background-color: rgba(var(--tp-success-rgb), 0.18);
}

/* ── Forms ────────────────────────────────────────────── */
.form-control, .form-select {
    background-color: var(--tp-bg-base);
    border-color: var(--tp-border);
    color: var(--tp-text-primary);
    border-radius: var(--radius-md);
}
.form-check-input {
    background-color: var(--tp-bg-base);
    border-color: var(--tp-border);
    color: var(--tp-text-primary);
}
.form-control:focus, .form-select:focus {
    background-color: var(--tp-bg-base);
    border-color: var(--tp-success);
    color: var(--tp-text-primary);
    box-shadow: 0 0 0 3px rgba(var(--tp-success-rgb), 0.15);
}
.form-control::placeholder { color: var(--tp-text-muted); }
.form-label { color: var(--tp-text-tertiary); font-size: var(--fs-sm); }
.tp-required-marker { color: var(--tp-danger-text); margin-left: 0.15rem; }

.valid.modified:not([type=checkbox]) { outline: 1px solid var(--tp-success); }
.invalid { outline: 1px solid var(--tp-danger); }
.validation-message {
    color: var(--tp-alert-danger-text);
    font-size: var(--fs-sm);
}
.validation-message::before { content: "⚠ "; }

/* ── Not-found view ───────────────────────────────────── */
.tp-not-found {
    text-align: center;
    padding: 3rem var(--sp-4);
}
.tp-not-found-icon {
    font-size: 2.5rem;
    color: var(--tp-text-secondary);
    margin-bottom: var(--sp-3);
}

/* ── Tables ───────────────────────────────────────────── */
.table {
    color: var(--tp-text-secondary);
    border-color: var(--tp-border);
}
.table > :not(caption) > * > * {
    background-color: transparent;
    border-bottom-color: var(--tp-border-subtle);
    color: inherit;
}
.table thead th {
    color: var(--tp-text-muted);
    font-size: var(--fs-2xs);
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    border-bottom: 1px solid var(--tp-border);
}
.table-hover > tbody > tr:hover > * { background-color: var(--tp-surface-hover); }
.table-group-row > * { background-color: var(--tp-surface-hover) !important; color: var(--tp-text-primary) !important; }
/* #670: feste Spaltenbreiten (z. B. Rechte im Profil - Rollenspalte über mehrere Tabellen bündig). */
.tp-table-fixed { table-layout: fixed; }

/* tp-table: token-native table wrapper */

/* ── DataTable (#186) ─────────────────────────────── */
.tp-sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.tp-sortable:hover { color: var(--tp-text-primary); }
/* #468: sortable header content is a real <button> for keyboard focus/activation, reset to look
   like the plain <th> text it replaces. #513: `font: inherit` does not carry text-transform or
   letter-spacing (they aren't part of the font shorthand), so those need repeating explicitly or
   the button text renders in normal case while plain <th> headers render uppercase/letter-spaced. */
.tp-sort-btn {
    display: block;
    width: 100%;
    height: 100%;
    text-align: inherit;
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    font: inherit;
    color: inherit;
    text-transform: inherit;
    letter-spacing: inherit;
    cursor: pointer;
    user-select: none;
    white-space: nowrap;
}
.tp-sort-btn:hover { color: var(--tp-text-primary); }
.tp-sort-icon-inactive { opacity: 0.25; }
.tp-datatable-narrow { max-width: 120px; }
/* #511: non-real (system/seed) accounts shown alongside real ones stay visually secondary. */
/* #1078: Opacity nur auf die Zellen - auf der Zeile machte sie auch das aufgeklappte Aktionsmenü durchsichtig und
   sperrte es in den Stapelkontext der Zeile (die Zeilen darüber lagen scheinbar davor). */
.tp-row-muted > td { opacity: 0.55; }
.tp-row-muted > td:has(.tp-row-menu) { opacity: 1; }
.tp-row-muted .tp-row-menu-trigger { opacity: 0.55; }

/* ── Responsive stacked tables (U4) ────────────────── */
/* Wrap a table-responsive div with tp-stacked-table;
   add data-label="Spaltenname" to each <td> for mobile labels. */
@media (max-width: 639px) {
    .tp-stacked-table table,
    .tp-stacked-table thead,
    .tp-stacked-table tbody,
    .tp-stacked-table th,
    .tp-stacked-table td,
    .tp-stacked-table tr { display: block; }

    .tp-stacked-table thead { display: none; }

    .tp-stacked-table tbody tr {
        border: 1px solid var(--tp-border);
        border-radius: var(--radius-md);
        margin-bottom: var(--sp-3);
        overflow: hidden;
    }

    .tp-stacked-table td {
        display: flex;
        align-items: baseline;
        gap: var(--sp-2);
        padding: 0.45rem var(--sp-3);
        border: none;
        border-bottom: 1px solid var(--tp-border-subtle);
        text-align: left;
    }

    .tp-stacked-table td:last-child { border-bottom: none; }

    .tp-stacked-table td::before {
        content: attr(data-label);
        min-width: 110px;
        flex-shrink: 0;
        font-weight: 600;
        font-size: var(--fs-2xs);
        color: var(--tp-text-muted);
        text-transform: uppercase;
        letter-spacing: 0.05em;
        padding-top: 2px;
    }

    .tp-stacked-table td[data-label=""]::before,
    .tp-stacked-table td:not([data-label])::before { display: none; }

    .tp-stacked-table tbody tr.tp-table-group-row {
        border: none;
        border-radius: var(--radius-md);
        margin-bottom: var(--sp-1);
    }
    .tp-stacked-table tbody tr.tp-table-group-row td { padding-left: var(--sp-3); padding-right: var(--sp-3); }
}

/* #878: Matrizen und Raster (Tabellen, Heatmap, Doodle, Kennzahlen) bleiben echte Tabellen - auf dem Handy
   horizontal scrollbar statt gestapelt, Zahlen spaltengenau. Listen nutzen stattdessen DataTable. */
.tp-matrix-table {
    font-variant-numeric: tabular-nums;
}

.tp-matrix-table th,
.tp-matrix-table td {
    white-space: nowrap;
}

/* ── Compact single-line row list (#110) ─────────────────
   Alternative to tp-stacked-table for lists where the stacked-card layout
   (repeated column labels, ~270px/row) leaves too few rows on screen -
   one line per entry (name + summary), details shown on tap instead. */

/* ── Alerts ───────────────────────────────────────────── */
.alert-danger {
    background-color: rgba(var(--tp-danger-rgb), 0.1);
    border-color: rgba(var(--tp-danger-rgb), 0.3);
    color: var(--tp-alert-danger-text);
    border-radius: var(--radius-md);
}

.table-warning, .table-danger{
    color: var(--tp-text-primary);
}
.alert-warning {
    background-color: rgba(var(--tp-warning-rgb), 0.1);
    border-color: rgba(var(--tp-warning-rgb), 0.3);
    color: var(--tp-alert-warning-text);
    border-radius: var(--radius-md);
}
.alert-success {
    background-color: rgba(var(--tp-success-rgb), 0.1);
    border-color: rgba(var(--tp-success-rgb), 0.3);
    color: var(--tp-alert-success-text);
    border-radius: var(--radius-md);
}

/* ── Badges (semantic pill system) ───────────────────── */
.tp-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.2em;
    font-size: var(--fs-2xs);
    font-weight: 600;
    padding: 2px var(--sp-2);
    border-radius: var(--radius-full);
    white-space: nowrap;
}
.tp-badge-success {
    background: rgba(var(--tp-success-rgb),0.12);
    color: var(--tp-success-text);
    border: 1px solid rgba(var(--tp-success-rgb),0.25);
}
.tp-badge-info {
    background: rgba(var(--tp-info-rgb),0.12);
    color: var(--tp-info-text);
    border: 1px solid rgba(var(--tp-info-rgb),0.25);
}
.tp-badge-accent {
    background: rgba(var(--tp-accent-rgb),0.12);
    color: var(--tp-accent-text);
    border: 1px solid rgba(var(--tp-accent-rgb),0.25);
}
.tp-badge-warning {
    background: rgba(var(--tp-warning-rgb),0.12);
    color: var(--tp-warning-text);
    border: 1px solid rgba(var(--tp-warning-rgb),0.25);
}
.tp-badge-danger {
    background: rgba(var(--tp-danger-rgb),0.12);
    color: var(--tp-danger-text);
    border: 1px solid rgba(var(--tp-danger-rgb),0.25);
}
.tp-badge-muted {
    background: rgba(var(--tp-text-muted-rgb),0.12);
    color: var(--tp-text-muted);
    border: 1px solid rgba(var(--tp-text-muted-rgb),0.25);
}
.tp-badge-secondary {
    background: rgba(var(--tp-success-rgb),0.12);
    color: var(--tp-success-text);
    border: 1px solid rgba(var(--tp-success-rgb),0.25);
}
/* Keep Bootstrap badge compat */
.badge.bg-primary  { background-color: rgba(var(--tp-success-rgb),0.15)  !important; color: var(--tp-success-text) !important; font-weight: 600; }
.badge.bg-info     { background-color: rgba(var(--tp-info-rgb),0.15)  !important; color: var(--tp-info-text) !important; font-weight: 600; }
.badge.bg-warning  { background-color: rgba(var(--tp-warning-rgb),0.15)  !important; color: var(--tp-warning-text) !important; font-weight: 600; }
.badge.bg-danger   { background-color: rgba(var(--tp-danger-rgb),0.15)   !important; color: var(--tp-danger-text) !important; font-weight: 600; }
.badge.bg-secondary{ background-color: rgba(var(--tp-text-muted-rgb),0.15) !important; color: var(--tp-text-tertiary) !important; }

/* ── Event list toolbar (search/filter/sort) ─────────── */
.tp-list-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-3);
    margin-bottom: var(--sp-3);
}
.tp-list-search { max-width: 300px; }
.tp-list-team-filter { max-width: 220px; }
.tp-list-past-toggle {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: var(--fs-sm);
    color: var(--tp-text-muted);
    cursor: pointer;
    margin: 0;
    white-space: nowrap;
}

/* ── Category group header row (grouped table lists, e.g. team pickers) ── */
.tp-table-group-row td {
    padding: 0.4rem var(--sp-4);
    font-size: var(--fs-2xs);
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--tp-text-muted);
    background: var(--tp-surface-hover);
    cursor: pointer;
    border-bottom: none;
}
.table-hover > tbody > tr.tp-table-group-row:hover > * { background-color: var(--tp-surface-hover); }

/* Issue #289 (refined by #297): rows belonging to a group are indented under their group header so
   the grouping reads visually, not just through the header row's own styling. Works for both the
   DataTable component's group rows (tp-table-group-row) and the hand-rolled ones that predate it
   (table-group-row, e.g. Material) - a following-sibling selector needs no markup change on the
   data rows themselves. The indent must clearly exceed the header row's own text start (its cell
   padding plus the chevron icon and its margin) or the two visually line up despite the different
   padding-left values - #297 was exactly that: 1.75rem coincidentally landed almost exactly on the
   header's icon-shifted text, so rows looked flush with the header instead of nested under it. */
tr.tp-table-group-row ~ tr:not(.tp-table-group-row) > td:first-child,
tr.table-group-row ~ tr:not(.table-group-row) > td:first-child {
    padding-left: 3rem;
}

/* Collapsible group headers (Issue #289): the chevron icon direction is toggled in markup
   (bi-chevron-down / bi-chevron-right); this just gives it consistent alignment. */
.tp-table-group-row .bi-chevron-down,
.tp-table-group-row .bi-chevron-right,
.table-group-row .bi-chevron-down,
.table-group-row .bi-chevron-right {
    font-size: var(--fs-2xs);
    vertical-align: 1px;
}

.tp-row-menu { position: relative; display: inline-flex; align-items: center; gap: 0.4rem; }
/* #757: auf dem Handy mindestens 40 px Touch-Ziel für Zeilenaktionen, nebeneinanderliegende Buttons mit Abstand. */
@media (max-width: 767px) {
    .tp-row-menu-trigger, td .btn-sm, .tp-row-menu .btn-sm {
        min-height: 40px;
        min-width: 40px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
    td .btn-sm + .btn-sm { margin-left: var(--sp-2); }
}
/* #1069: auf Touch-Geräten auch außerhalb von Tabellen (Karten, Kopfzeilen, Profil) mindestens 40 px hohe kleine
   Buttons; reine Symbol-Buttons zusätzlich 40 px breit. */
@media (pointer: coarse) {
    .btn-sm {
        min-height: 40px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--sp-1);
    }
    .btn-sm:has(> .bi:only-child) { min-width: 40px; }
}
.tp-row-menu-backdrop { position: fixed; inset: 0; z-index: 150; background: transparent; }
.tp-row-menu-list {
    position: fixed;
    min-width: 160px;
    background: var(--tp-bg-base);
    border: 1px solid var(--tp-border-subtle);
    border-radius: var(--radius-md);
    box-shadow: 0 8px 24px rgba(0,0,0,0.3);
    z-index: 151;
    padding: 0.35rem 0;
    display: flex;
    flex-direction: column;
}
.tp-row-menu-item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 0.9rem;
    color: var(--tp-text-secondary, var(--tp-text-muted));
    text-decoration: none;
    font-size: var(--fs-sm);
    background: none;
    border: none;
    width: 100%;
    text-align: left;
    cursor: pointer;
}
.tp-row-menu-item:hover { color: var(--tp-text-primary); background: rgba(41,53,72,0.5); }
.tp-row-menu-item-danger { color: var(--tp-danger-text); }
.tp-row-menu-item-danger:hover { color: var(--tp-danger-text); background: rgba(var(--tp-danger-rgb),0.12); }
.tp-row-menu-item i { width: 18px; text-align: center; flex-shrink: 0; }

/* ── Searchable select combobox (TeamSelect/MemberSelect, Issue #354) ── */
.tp-select {
    position: relative;
}

.tp-select input {
    padding-right: 1.9rem;
}

.tp-select-clear {
    position: absolute;
    top: 50%;
    right: 0.5rem;
    transform: translateY(-50%);
    border: 0;
    background: transparent;
    color: var(--tp-text-muted);
    font-size: var(--fs-md);
    line-height: 1;
    padding: 0 0.15rem;
    cursor: pointer;
}

.tp-select-clear:hover {
    color: var(--tp-text-primary);
}

.tp-select-list {
    position: absolute;
    top: calc(100% + 2px);
    left: 0;
    right: 0;
    z-index: 1060;
    margin: 0;
    padding: var(--sp-1) 0;
    list-style: none;
    max-height: 18rem;
    overflow-y: auto;
    background: var(--tp-bg-base);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-md);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}

.tp-select-item {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0.3rem var(--sp-3);
    cursor: pointer;
    color: var(--tp-text);
}

.tp-select-item:hover,
.tp-select-item.active {
    background: var(--tp-surface-hover);
}

.tp-select-suffix {
    font-size: var(--fs-xs);
    color: var(--tp-text-secondary);
}

.tp-select-hint {
    flex-basis: 100%;
    font-size: var(--fs-xs);
    color: var(--tp-text-muted);
}

.tp-select-empty {
    padding: 0.4rem var(--sp-3);
    font-size: var(--fs-sm);
    color: var(--tp-text-muted);
}

.tp-select-group {
    padding: 0.35rem var(--sp-3) 0.15rem;
    font-size: var(--fs-2xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--tp-text-muted);
}

/* #876: Avatar mit überlagertem Status - Größe kommt inline (je Aufruf), das Gerüst von hier. */
.tp-avatar-stack {
    position: relative;
    flex-shrink: 0;
}

/* ── Empty states ─────────────────────────────────── */
.tp-empty {
    padding: var(--sp-6);
    font-size: var(--fs-xs);
    color: var(--tp-text-muted);
    text-align: center;
}

.tp-empty-hint {
    margin-bottom: 0;
    font-size: var(--fs-sm);
    color: var(--tp-text-muted);
}

.tp-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--sp-3);
    padding: var(--sp-8) var(--sp-6);
    text-align: center;
}

.tp-empty-state-icon {
    font-size: var(--fs-2xl);
    color: var(--tp-text-muted);
    opacity: 0.5;
}

.tp-empty-state-text {
    margin: 0;
    font-size: var(--fs-sm);
    color: var(--tp-text-muted);
}

.tp-empty-state-action {
    margin-top: var(--sp-1);
}

/* ── Cards ────────────────────────────────────────────── */
/* Bootstrap-.card im App-Theme */
.card {
    background-color: var(--tp-surface);
    border-color: var(--tp-border);
    border-radius: var(--radius-lg);
    color: var(--tp-text-primary);
}
.card-header, .card-footer {
    background-color: rgba(255,255,255,0.04);
    border-color: var(--tp-border);
}

/* ── Auth card (Login/Join/ResetPassword/ConfirmEmail/AccountDeleted) ──── */
/* #485: shared across five pages via AuthCardHeader - was previously scoped
   to Login.razor.css only, so every other auth page rendered an unstyled card. */
.tp-auth-card {
    background-color: var(--tp-surface);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-md);
    padding: var(--sp-8);
    width: 100%;
    max-width: 400px;
}
.tp-auth-logo {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    color: var(--tp-accent-color);
    font-size: var(--fs-lg);
    font-weight: 700;
    text-align: center;
    margin-bottom: var(--sp-2);
}
.tp-auth-logo img {
    border-radius: var(--radius-sm);
}
.tp-auth-title {
    color: var(--tp-text-primary);
    font-size: var(--fs-lg);
    font-weight: 600;
    text-align: center;
    margin-bottom: var(--sp-6);
}

/* ── Surface helper ───────────────────────────────────── */
.tp-surface {
    background-color: var(--tp-surface);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-md);
    padding: var(--sp-6);
    color: var(--tp-text-primary);
}

/* ── Page layout ──────────────────────────────────────── */
/* #761: einheitlicher Rückweg über dem Seitentitel (PageHeader BackHref). */
.tp-back-link {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    margin-bottom: var(--sp-1);
    font-size: var(--fs-sm);
    color: var(--tp-text-muted);
    text-decoration: none;
}
.tp-back-link:hover { color: var(--tp-text-primary); }

/* #1299: Bankabgleich in drei Spalten - Umsätze, gewählter Umsatz, offene Forderungen */
.tp-bank-columns {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr) minmax(0, 1.1fr);
    gap: var(--sp-3);
    align-items: start;
}
.tp-bank-column { min-width: 0; padding-left: var(--sp-3); border-left: 1px solid var(--tp-border-subtle); }
.tp-bank-lines { display: flex; flex-direction: column; gap: var(--sp-1); max-height: 60vh; overflow-y: auto; }
.tp-bank-line {
    display: block;
    width: 100%;
    text-align: left;
    padding: var(--sp-1) var(--sp-2);
    border: 1px solid var(--tp-border-subtle);
    border-left: 3px solid var(--tp-border);
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--tp-text-primary);
}
.tp-bank-line:hover { background: var(--tp-surface-hover); }
.tp-bank-line.active { background: var(--tp-surface-hover); border-color: var(--tp-accent); }
.tp-bank-line-done { border-left-color: var(--tp-success); }
.tp-bank-line-partial, .tp-bank-line-proposal { border-left-color: var(--tp-warning); }
.tp-bank-person { padding: var(--sp-1) 0; border-bottom: 1px solid var(--tp-border-subtle); }

/* #1300: Feedback-Dialog über einem bereits offenen Dialog */
.modal-backdrop.tp-modal-above { z-index: 1065; }
.modal.tp-modal-above { z-index: 1070; }

/* #1258: NavStrip - Bereichsleiste unter 768 px, eine Zeile, horizontal scrollbar */
.tp-nav-strip {
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    border-bottom: 1px solid var(--tp-border);
    margin-bottom: var(--sp-3);
}
.tp-nav-strip::-webkit-scrollbar { display: none; }
.tp-nav-strip ul {
    display: flex;
    flex-wrap: nowrap;
    gap: var(--sp-1);
    margin: 0;
    padding: 0;
    list-style: none;
}
.tp-nav-strip li { flex: 0 0 auto; scroll-snap-align: start; }
.tp-nav-strip li.tp-nav-strip-group { margin-left: var(--sp-2); padding-left: var(--sp-2); border-left: 1px solid var(--tp-border-subtle); }
.tp-nav-strip a {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-1);
    padding: var(--sp-2) var(--sp-2);
    white-space: nowrap;
    font-size: var(--fs-sm);
    color: var(--tp-text-muted);
    text-decoration: none;
    border-bottom: 2px solid transparent;
}
.tp-nav-strip a:hover { color: var(--tp-text-primary); }
.tp-nav-strip a.active { color: var(--tp-text-primary); font-weight: 600; border-bottom-color: var(--tp-accent); }
.tp-nav-strip a:focus-visible { outline: 2px solid var(--tp-accent); outline-offset: -2px; }

.page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: var(--sp-5);
}
.page-header h1, .page-header h2, .page-header h3 { margin: 0; font-size: var(--fs-lg); font-weight: 600; }
.page-header-title-row { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2); }
.page-header-actions { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: var(--sp-2); }

/* ── Stat tiles ───────────────────────────────────────── */
.stat-tile {
    background-color: var(--tp-surface);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-md);
    padding: var(--sp-4) var(--sp-5);
}
.stat-tile .stat-label {
    font-size: var(--fs-2xs);
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--tp-text-muted);
    margin-bottom: 0.4rem;
}
.stat-tile .stat-value {
    font-size: var(--fs-xl);
    font-weight: 700;
    line-height: 1;
}
.stat-tile .stat-value.accent { color: var(--tp-success-text); }
.stat-tile .stat-value.amber  { color: var(--tp-warning-text); }
.stat-tile .stat-value.plain  { color: var(--tp-text-primary); }

/* ── Dashboard grid (Club/Team home) ───────────────────── */
/* Shared across multiple components (Club/Index.razor, Team/Home.razor) -
   must live in the global stylesheet, not a component-scoped .razor.css,
   or Blazor's CSS isolation strips it from every component but the first. */

.tp-stat-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--sp-4);
    margin-bottom: var(--sp-6);
}
@media (max-width: 767px) {
    .tp-stat-grid { grid-template-columns: repeat(2, 1fr); }
}

/* #302/#1314: Startseiten von Verein und Abteilung zeigen 6 statt 4 Kacheln - eigener Modifier, da die
   Mannschaftsseite weiterhin 4 Kacheln über .tp-stat-grid zeigt. #1354: feste Stufen nach der Breite des Inhalts
   (.tp-home ist Container) - 6, sonst 3 + 3, schmal 2 je Reihe; auto-fit ergab auf dem iPad 5 + 1. */
.tp-home { container-type: inline-size; }
.tp-stat-grid--6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
@container (max-width: 1099px) {
    .tp-stat-grid--6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@container (max-width: 559px) {
    .tp-stat-grid--6 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.tp-stat-card {
    background: var(--tp-surface);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-lg);
    padding: var(--sp-6);
    position: relative;
    overflow: hidden;
    display: block;
    color: inherit;
    text-decoration: none;
}
.tp-stat-card::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 3px;
}
.tp-stat-card.success::before { background: var(--tp-success); }
.tp-stat-card.info::before    { background: var(--tp-info); }
.tp-stat-card.warning::before { background: var(--tp-warning); }
.tp-stat-card.accent::before  { background: var(--tp-accent); }
.tp-stat-card.danger::before  { background: var(--tp-danger); }
.tp-stat-value {
    font-size: var(--fs-2xl);
    font-weight: 700;
    color: var(--tp-text-primary);
    line-height: 1;
    margin-bottom: var(--sp-1);
}
.tp-stat-label {
    font-size: var(--fs-2xs);
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--tp-text-muted);
}

.tp-dashboard-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--sp-4);
}
@media (max-width: 1023px) {
    .tp-dashboard-grid { grid-template-columns: 1fr; }
}

/* #302/#1314/#1315: Startseiten von Verein und Abteilung - Termine, Aufgaben, Geburtstage in drei Spalten (#1523: ohne
   Ansprechpartner). #1354: in mittleren Breiten zwei Spalten, damit Kopfzeilen nicht umbrechen. */
.tp-dashboard-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@container (max-width: 1099px) {
    .tp-dashboard-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@container (max-width: 599px) {
    .tp-dashboard-grid--3 { grid-template-columns: 1fr; }
}

.tp-panel {
    background: var(--tp-surface);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
}
/* #1293: Kopfband mit Farbkante je Bereich (tp-panel--warning/success/accent/info wie die Kennzahl-Kacheln),
   rechts einheitlich ein kleiner Button "Zu … →". */
.tp-panel-header {
    padding: var(--sp-3) var(--sp-6);
    background: var(--tp-panel-header-bg);
    border-bottom: 1px solid var(--tp-panel-header-border);
    border-left: 3px solid var(--tp-panel-tone, var(--tp-border-hover));
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-2);
}
.tp-panel-title {
    font-size: var(--fs-md);
    font-weight: 700;
    color: var(--tp-text-primary);
}
.tp-panel-header > .btn { white-space: nowrap; flex-shrink: 0; }
.tp-panel-title .bi { margin-right: var(--sp-2); color: var(--tp-panel-tone, var(--tp-text-muted)); }
.tp-panel--warning { --tp-panel-tone: var(--tp-warning); }
.tp-panel--success { --tp-panel-tone: var(--tp-success); }
.tp-panel--accent  { --tp-panel-tone: var(--tp-accent); }
.tp-panel--info    { --tp-panel-tone: var(--tp-info); }
.tp-event-item {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-6);
    border-bottom: 1px solid var(--tp-border-subtle);
    color: inherit;
    text-decoration: none;
}
.tp-event-item:last-child { border-bottom: none; }
.tp-event-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}
.tp-event-dot.match    { background: var(--tp-info); }
.tp-event-dot.training { background: var(--tp-success); }
.tp-event-dot.appointment { background: var(--tp-accent); }
.tp-event-dot.tournament { background: var(--tp-warning); }
.tp-event-name { font-size: var(--fs-xs); color: var(--tp-text-secondary); flex: 1; }
.tp-event-date { font-size: var(--fs-xs); color: var(--tp-text-muted); white-space: nowrap; }

.tp-task-item {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-6);
    border-bottom: 1px solid var(--tp-border-subtle);
}
.tp-task-item:last-child { border-bottom: none; }

.tp-task-name { font-size: var(--fs-xs); color: var(--tp-text-secondary); flex: 1; }
.tp-task-date { font-size: var(--fs-xs); color: var(--tp-text-muted); white-space: nowrap; }

.tp-task-group-header {
    padding: var(--sp-2) var(--sp-6);
    background: var(--tp-surface-hover);
    border-bottom: 1px solid var(--tp-border-subtle);
}
.tp-task-group-link {
    font-size: var(--fs-2xs);
    font-weight: 600;
    color: var(--tp-text-muted);
    text-decoration: none;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.tp-task-group-link:hover { color: var(--tp-success-text); }

/* ── Blazor error UI ──────────────────────────────────── */
#blazor-error-ui {
    background: rgba(var(--tp-danger-rgb), 0.15);
    border-top: 1px solid var(--tp-danger);
    color: var(--tp-alert-danger-text);
    bottom: 0;
    box-shadow: 0 -1px 2px rgba(0,0,0,0.4);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: 0.6rem var(--sp-5) 0.7rem var(--sp-5);
    position: fixed;
    width: 100%;
    z-index: 1060;
}
#blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

/* ── Blazor validation ────────────────────────────────── */
.blazor-error-boundary {
    background-color: rgba(var(--tp-danger-rgb),0.1);
    border: 1px solid rgba(var(--tp-danger-rgb),0.3);
    color: var(--tp-alert-danger-text);
    padding: var(--sp-4) var(--sp-4) var(--sp-4) var(--sp-5);
    border-radius: var(--radius-md);
}
.blazor-error-boundary::after { content: "Ein unerwarteter Fehler ist aufgetreten."; }

/* ── Quill Editor dark theme ──────────────────────────── */
.ql-toolbar.ql-snow {
    background-color: var(--tp-surface);
    border-color: var(--tp-border);
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    font-family: inherit;
}
.ql-container.ql-snow {
    background-color: var(--tp-surface);
    border-color: var(--tp-border);
    border-top: none;
    border-radius: 0 0 var(--radius-md) var(--radius-md);
    color: var(--tp-text-primary);
    font-family: inherit;
    font-size: var(--fs-sm);
}
.ql-editor {
    color: var(--tp-text-primary);
}
.ql-editor.ql-blank::before {
    color: var(--tp-text-muted);
    font-style: normal;
}
.ql-snow .ql-stroke {
    stroke: var(--tp-text-primary);
}
.ql-snow .ql-fill,
.ql-snow .ql-stroke.ql-fill {
    fill: var(--tp-text-primary);
}
.ql-snow.ql-toolbar button:hover,
.ql-snow .ql-toolbar button:hover {
    color: var(--tp-success-text);
}
.ql-snow.ql-toolbar button:hover .ql-stroke,
.ql-snow .ql-toolbar button:hover .ql-stroke,
.ql-snow.ql-toolbar button.ql-active .ql-stroke,
.ql-snow .ql-toolbar button.ql-active .ql-stroke {
    stroke: var(--tp-success);
}
.ql-snow.ql-toolbar button:hover .ql-fill,
.ql-snow .ql-toolbar button:hover .ql-fill,
.ql-snow.ql-toolbar button.ql-active .ql-fill,
.ql-snow .ql-toolbar button.ql-active .ql-fill {
    fill: var(--tp-success);
}
.ql-snow .ql-picker {
    color: var(--tp-text-secondary);
}
.ql-snow .ql-picker-options {
    background-color: var(--tp-surface);
    border-color: var(--tp-border);
}

/* ── Modal backdrop ───────────────────────────────────────── */
.modal-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1040;
    background-color: rgba(0, 0, 0, 0.5);
}

/* ── Misc ─────────────────────────────────────────────── */
.text-muted { color: var(--tp-text-muted) !important; }
.border { border-color: var(--tp-border) !important; }
.darker-border-checkbox.form-check-input { border-color: var(--tp-border-hover); }

/* ── Kabinen-Zeitstrahl ── */
.tp-timeline-block:hover .tp-remove-btn { opacity: 1 !important; }

/* ── Event confirmation status ─────────────────────────────────────────── */
.tp-week-block-pending  { border: 2px dashed var(--tp-warning) !important; opacity: 0.85; }
.tp-week-block-rejected { text-decoration: line-through !important; opacity: 0.65; background-color: rgba(var(--bs-danger-rgb), 0.25) !important; }

/* ── App Shell ────────────────────────────────────────────── */
/* #481: the mobile/tablet overrides for this section live further down (after ".conversation-list"),
   not here - every selector below targets a base rule that is itself defined later in this file, and
   an unconditional rule of equal specificity always wins over an earlier @media rule regardless of
   which one currently matches the viewport. Defining them here left them dead code (e.g. the tablet
   compact sidebar never actually applied at any width) until this fix moved them past their bases. */

.tp-app-shell {
    display: flex;
    flex-direction: column;
    height: 100dvh;
}

.tp-topbar {
    background-color: var(--tp-bg-base);
    border-bottom: 1px solid var(--tp-border-subtle);
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-shrink: 0;
    z-index: 100;
    position: sticky;
    top: 0;
}

.tp-topbar-brand {
    width: 52px;
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--fs-lg);
    text-decoration: none;
    border-right: 1px solid var(--tp-border-subtle);
    flex-shrink: 0;
    color: var(--tp-text-primary);
}
.tp-topbar-brand img {
    width: 28px;
    height: 28px;
    border-radius: var(--radius-md);
    transition: opacity 0.15s ease;
}
.tp-topbar-brand:hover img { opacity: 0.85; }

.tp-topbar-feedback-btn {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    background: var(--tp-warning);
    /* #479: fixed dark text tuned for --tp-warning's amber (theme-invariant) -
       --tp-brand-on-primary is tuned for the green brand colour, not this one. */
    color: var(--tp-on-warning-text);
    font-size: var(--fs-xs);
    font-weight: 600;
    line-height: 1;
    border: none;
    border-radius: var(--radius-full);
    padding: 0.4rem var(--sp-3);
    text-decoration: none;
    transition: opacity 0.15s ease;
    flex-shrink: 0;
}
.tp-topbar-feedback-btn:hover { opacity: 0.85; color: var(--tp-on-warning-text); }

.tp-topbar-left {
    min-width: 0;
    flex: 1 1 auto;
    overflow: hidden;
}

.tp-breadcrumb {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    padding: 0 var(--sp-4);
    font-size: var(--fs-md);
    color: var(--tp-text-muted);
    min-width: 0;
    flex: 1 1 auto;
    overflow: hidden;
}
.tp-breadcrumb a {
    color: var(--tp-text-muted);
    text-decoration: none;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.tp-breadcrumb a:hover { color: var(--tp-text-primary); }
.tp-breadcrumb .tp-breadcrumb-active {
    color: var(--tp-text-primary);
    font-weight: 700;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.tp-breadcrumb-sep { color: var(--tp-border); flex-shrink: 0; }

.tp-breadcrumb-skeleton {
    display: inline-block;
    width: 9rem;
    height: 1rem;
    border-radius: var(--radius-sm);
    background: linear-gradient(90deg, var(--tp-border) 25%, var(--tp-surface-alt, var(--tp-border)) 37%, var(--tp-border) 63%);
    background-size: 400% 100%;
    animation: tp-skeleton-pulse 1.4s ease infinite;
}
@keyframes tp-skeleton-pulse {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

.tp-skeleton {
    display: flex;
    flex-direction: column;
    gap: var(--sp-2);
}
.tp-skeleton-line {
    display: block;
    border-radius: var(--radius-sm);
    background: linear-gradient(90deg, var(--tp-border) 25%, var(--tp-surface-alt, var(--tp-border)) 37%, var(--tp-border) 63%);
    background-size: 400% 100%;
    animation: tp-skeleton-pulse 1.4s ease infinite;
}

.tp-topbar-right {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding-right: var(--sp-4);
}

/* ── Sidebar ───────────────────────────────────────────── */
.tp-body {
    display: flex;
    flex: 1;
    min-height: 0;
    overflow: hidden;
}

.tp-sidebar {
    width: 180px;
    flex-shrink: 0;
    background-color: var(--tp-bg-base);
    border-right: 1px solid var(--tp-border-subtle);
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    gap: 0;
    padding: 0;
    transition: width 0.15s ease;
}

.tp-sidebar-collapsed { width: 52px; }
.tp-sidebar-collapsed .tp-sidebar-label { display: none; }
.tp-sidebar-collapsed .tp-sidebar-group-label { display: none; }
.tp-sidebar-collapsed .nav-link { justify-content: center; padding-left: 0; }
.tp-sidebar-collapsed .tp-badge { display: none; }

.tp-sidebar-collapse-toggle {
    margin-top: auto;
    background: none;
    border: none;
    border-top: 1px solid var(--tp-border-subtle);
    width: 100%;
    cursor: pointer;
}

.tp-sidebar-group-label {
    font-size: var(--fs-2xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--tp-border);
    padding: 0.6rem 0 0.2rem 17px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tp-sidebar .nav-link,
.tp-mobile-menu .tp-mobile-menu-link {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    padding: 0.55rem 0;
    padding-left: var(--sp-4);
    padding-right: var(--sp-3);
    color: var(--tp-text-muted);
    text-decoration: none;
    font-size: var(--fs-xs);
    font-weight: 500;
    border-left: 3px solid transparent;
    white-space: nowrap;
    overflow: hidden;
    transition: color 0.12s, background 0.12s;
}
.tp-sidebar .nav-link:hover,
.tp-mobile-menu .tp-mobile-menu-link:hover {
    color: var(--tp-text-secondary);
    background: rgba(41,53,72,0.5);
}
.tp-sidebar .nav-link.active,
.tp-mobile-menu .tp-mobile-menu-link.active {
    color: var(--tp-success-text);
    background: rgba(var(--tp-success-rgb),0.08);
    border-left-color: var(--tp-success);
}
.tp-mobile-menu {
    display: flex;
    flex-direction: column;
    padding: var(--sp-2) 0;
}
/* NavLink renders <a>, LogoutMenuItem renders <button> - buttons need the browser's default
   border/background/font reset that <a> never had, or Logout shows a grey box (review finding 2). */
.tp-mobile-menu button.tp-mobile-menu-link {
    background: none;
    border: 0;
    border-left: 3px solid transparent;
    width: 100%;
    text-align: left;
    cursor: pointer;
    font: inherit;
}
.tp-mobile-menu-section {
    border-bottom: 1px solid var(--tp-border-subtle);
}
.tp-mobile-menu-section-title {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--sp-3) var(--sp-4);
    font-weight: 600;
    cursor: pointer;
    list-style: none;
}
.tp-mobile-menu-section-title::-webkit-details-marker {
    display: none;
}
/* Native disclosure triangle is hidden above (list-style/::-webkit-details-marker) - without a
   replacement a collapsed section reads as a dead heading (review finding 3). */
.tp-mobile-menu-section-title::after {
    content: "\25B8";
    transition: transform 0.15s;
}
.tp-mobile-menu-section[open] > .tp-mobile-menu-section-title::after {
    transform: rotate(90deg);
}
.tp-sidebar-skeleton {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
    padding: var(--sp-3) var(--sp-4);
}
.tp-sidebar-skeleton .tp-breadcrumb-skeleton {
    width: 100%;
    height: 0.9rem;
}
.tp-sidebar-icon {
    font-size: var(--fs-md);
    width: 22px;
    text-align: center;
    flex-shrink: 0;
}
.tp-sidebar-label {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
    flex: 1;
}

.sidebar-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--tp-success);
    color: var(--tp-bg-base);
    font-size: var(--fs-2xs);
    font-weight: 700;
    border-radius: var(--radius-full);
    padding: 0.1rem 0.35rem;
    min-width: 16px;
    line-height: 1.4;
    margin-left: auto;
    margin-right: var(--sp-1);
}

.sidebar-badge-danger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--tp-danger);
    color: var(--tp-bg-base);
    font-size: var(--fs-2xs);
    font-weight: 700;
    border-radius: var(--radius-full);
    padding: 0.1rem 0.35rem;
    min-width: 16px;
    line-height: 1.4;
    margin-left: auto;
    margin-right: var(--sp-1);
}

.tp-sidebar-divider {
    height: 1px;
    background: var(--tp-border-subtle);
    margin: 0.4rem 0.65rem;
}

.club-logo-xs {
    height:30px;
    width:30px;
    object-fit:contain;
    border-radius:var(--radius-md);
    flex-shrink:0
}

.club-logo-xs.tp-breadcrumb-avatar {
    object-fit:cover;
    border-radius:50%
}

.club-logo-s {
    height:48px;
    width:48px;
    object-fit:contain;
    border-radius:var(--radius-md);
    flex-shrink:0
}

/* ── Main content ──────────────────────────────────────── */
.tp-main {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    background: var(--tp-bg-deep);
}

/* ── Avatar ────────────────────────────────────────────── */
.tp-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--tp-success), var(--tp-success-deep));
    color: var(--tp-bg-base);
    font-size: var(--fs-xs);
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.tp-avatar-img {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    object-fit: cover;
}

/* ═══════════════════════════════════════════════════════════
   MESSAGING
   ═══════════════════════════════════════════════════════════ */

/* ── Page layout ─────────────────────────────────────────── */
/* Present only when NavContext has a previous page to offer (Issue #262) - shrinks .messages-layout's
   effective height by its own, so the chat area still fills the rest of the page. */
.messages-back-row {
    display: flex;
    justify-content: flex-end;
    padding-bottom: var(--sp-3);
    flex-shrink: 0;
}
.messages-layout {
    display: flex;
    height: 100%;
    overflow: hidden;
    background: var(--tp-bg-base);
}

.messages-placeholder {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--tp-text-muted);
    font-size: var(--fs-md);
}

.tp-mobile-back {
    background: none;
    border: none;
    border-bottom: 1px solid var(--tp-border-subtle);
    color: var(--tp-text-muted);
    font-size: var(--fs-sm);
    padding: var(--sp-3) var(--sp-4);
    cursor: pointer;
    text-align: left;
    flex-shrink: 0;
    width: 100%;
}
.tp-mobile-back:hover { color: var(--tp-text-primary); }

/* ── Conversation list ───────────────────────────────────── */
.conversation-list {
    width: 300px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    border-right: 1px solid var(--tp-border);
    background: var(--tp-bg-base);
    overflow: hidden;
}

/* #481: relocated from directly under the "App Shell"/"Page layout" headings above, where every one
   of these overrides came before the unconditional base rule it targets and was therefore dead
   (equal-specificity cascade always resolved to the later, unconditional rule - see the note there). */
@media (max-width: 767px) {
    .tp-body > .tp-sidebar { display: none; }
    .tp-main               { padding-bottom: 64px; }
    .messages-layout       { flex-direction: column; }
    .conversation-list     { width: 100%; border-right: none; border-bottom: 1px solid var(--tp-border); }
    .conversation-list-wrapper { width: 100%; }
}

@media (min-width: 768px) and (max-width: 1023px) {
    .tp-sidebar { width: 52px; }
    .tp-sidebar-label { display: none; }
    .tp-sidebar-group-label { display: none; }
    .tp-sidebar .nav-link { justify-content: center; padding-left: 0; }
    
    .tp-main { padding: 0 var(--sp-2); }
    .conversation-list { width: 220px; }
    
}

.conversation-list-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: var(--sp-2);
    padding: 0.875rem var(--sp-4);
    border-bottom: 1px solid var(--tp-border);
    font-weight: 600;
    font-size: var(--fs-md);
    color: var(--tp-text-primary);
    flex-shrink: 0;
}

.conversation-list-filters {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    padding: var(--sp-2) var(--sp-4);
    border-bottom: 1px solid var(--tp-border);
    flex-shrink: 0;
}
.conversation-list-filters input[type="search"] { flex: 1; min-width: 0; }

/* ── Conversation list item ──────────────────────────────── */
.conversation-item {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    cursor: pointer;
    border-bottom: 1px solid var(--tp-border-subtle);
    transition: background 0.1s;
}
.conversation-item:hover  { background: var(--tp-surface-hover); }
.conversation-item.active { background: var(--tp-surface); }

.conversation-avatar {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--tp-surface);
    border: 1px solid var(--tp-border);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--fs-sm);
    font-weight: 700;
    color: var(--tp-text-secondary);
}

/* #1501: 1:1-Chats zeigen das Profilbild (Initialen als Rückfall), ohne den Rahmen des Platzhalters. */
.conversation-avatar-user,
.chat-header-avatar-user { background: none; border: none; }
.chat-header-avatar-user { width: 32px; height: 32px; }

.dm-icon    { color: var(--tp-accent-text); }
.group-icon { color: var(--tp-accent-text); }

.conversation-info {
    flex: 1;
    min-width: 0;
}

.conversation-name {
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--tp-text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.conversation-preview {
    font-size: var(--fs-xs);
    color: var(--tp-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 0.1rem;
}

.conversation-meta {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--sp-1);
    flex-shrink: 0;
}

.conversation-time {
    font-size: var(--fs-2xs);
    color: var(--tp-text-muted);
}

.unread-badge {
    background: var(--tp-accent);
    color: var(--tp-on-accent-text); /* fixed dark text: --tp-accent is a light violet in both themes, unlike --tp-bg-base it doesn't invert */
    font-size: var(--fs-2xs);
    font-weight: 700;
    border-radius: var(--radius-full);
    padding: 0.1rem 0.4rem;
    min-width: 18px;
    text-align: center;
}

/* ── Chat window ─────────────────────────────────────────── */
.chat-window {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--tp-bg-deep);
}

/* ── Chat header ─────────────────────────────────────────── */
.chat-header {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    border-bottom: 1px solid var(--tp-border);
    background: var(--tp-bg-base);
    flex-shrink: 0;
}

.chat-header-clickable { cursor: pointer; transition: background 0.1s; }
.chat-header-clickable:hover { background: var(--tp-surface-hover); }

.chat-header-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--tp-surface);
    border: 1px solid var(--tp-border);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: var(--fs-sm);
    color: var(--tp-accent-text);
    flex-shrink: 0;
}

.chat-header-name {
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--tp-text-primary);
}

.chat-header-sub {
    font-size: var(--fs-xs);
    color: var(--tp-text-muted);
}

/* ── Message list ────────────────────────────────────────── */
.message-list {
    flex: 1;
    overflow-y: auto;
    padding: var(--sp-4);
    display: flex;
    flex-direction: column;
}

.load-more {
    align-self: center;
    background: transparent;
    border: 1px solid var(--tp-border);
    color: var(--tp-text-muted);
    font-size: var(--fs-xs);
    border-radius: var(--radius-md);
    padding: var(--sp-1) var(--sp-3);
    cursor: pointer;
    margin-bottom: var(--sp-2);
}
.load-more:hover { background: var(--tp-surface-hover); }

/* ── Message bubble ──────────────────────────────────────── */
.message-bubble {
    display: flex;
    flex-direction: column;
    max-width: 70%;
    position: relative;
    margin-top: var(--sp-3); /* default gap between different senders / grouping runs */
}
.message-bubble:first-child { margin-top: 0; }
.message-bubble.grouped { margin-top: 0.15rem; } /* consecutive message from the same sender */
.message-bubble.own   { align-self: flex-end; align-items: flex-end; }
.message-bubble.other { align-self: flex-start; align-items: flex-start; }

.bubble-sender {
    font-size: var(--fs-2xs);
    font-weight: 600;
    color: var(--tp-accent-text);
    margin-bottom: 0.15rem;
    padding-left: var(--sp-1);
}

.bubble-body {
    border-radius: var(--radius-xl); /* #1500: kein radius-full - mehrzeilige Blasen (Zitat) würden sonst oval */
    padding: var(--sp-2) 0.875rem;
    word-break: break-word;
    position: relative;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}
.message-bubble.own   .bubble-body { background: var(--tp-accent); color: var(--tp-on-accent-text); border-bottom-right-radius: 0.25rem; }
.message-bubble.other .bubble-body { background: var(--tp-surface); color: var(--tp-text-primary); border-bottom-left-radius: 0.25rem; }
.message-bubble.grouped.own   .bubble-body { border-top-right-radius: 0.25rem; }
.message-bubble.grouped.other .bubble-body { border-top-left-radius: 0.25rem; }

.bubble-text {
    margin: 0;
    font-size: var(--fs-sm);
    line-height: 1.45;
}

.bubble-footer {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    margin-top: 0.2rem;
}

.bubble-time {
    font-size: var(--fs-2xs);
    opacity: 0.7;
}

.read-receipt {
    font-size: var(--fs-2xs);
    opacity: 0.8;
}

/* Hover (desktop) / long-press (touch) action overlay: quick reactions + reply,
   replacing the previously always-visible action buttons to declutter the bubble. */
.bubble-hover-actions {
    display: flex;
    align-items: center;
    gap: 0.15rem;
    position: absolute;
    bottom: -1.35rem;
    background: var(--tp-surface);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-full);
    padding: 0.2rem 0.3rem;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.12s;
    z-index: 2;
}
.message-bubble.own   .bubble-hover-actions { right: 0; }
.message-bubble.other .bubble-hover-actions { left: 0; }
.message-bubble:hover .bubble-hover-actions,
.message-bubble.actions-visible .bubble-hover-actions {
    opacity: 1;
    pointer-events: auto;
}
.bubble-hover-actions button {
    background: transparent;
    border: none;
    font-size: var(--fs-md);
    line-height: 1;
    cursor: pointer;
    border-radius: var(--radius-full);
    padding: 0.2rem 0.35rem;
}
.bubble-hover-actions button:hover { background: var(--tp-surface-hover); }
.bubble-hover-actions .reply-action {
    font-size: var(--fs-sm);
    color: var(--tp-text-secondary);
    border-left: 1px solid var(--tp-border);
    margin-left: 0.1rem;
    padding-left: 0.4rem;
}

/* ── Quoted message (inside bubble) ─────────────────────── */
.quoted-message {
    border-left: 3px solid var(--tp-accent);
    padding: var(--sp-1) var(--sp-2);
    border-radius: 0 0.25rem 0.25rem 0;
    margin-bottom: 0.35rem;
    background: var(--tp-surface-hover);
    font-size: var(--fs-xs);
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
    max-width: 100%;
}
.quoted-sender  { font-weight: 600; color: var(--tp-accent-text); }
.quoted-content { color: var(--tp-text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* #1500: in der eigenen (violetten) Blase bleibt das Zitat hell und nimmt die Textfarbe der Blase an. */
.message-bubble.own .quoted-message { background: rgba(255, 255, 255, 0.45); border-left-color: var(--tp-on-accent-text); }
.message-bubble.own .quoted-sender,
.message-bubble.own .quoted-content { color: var(--tp-on-accent-text); }
.message-bubble.own .quoted-content { opacity: 0.8; }

/* ── Quote preview (composer) ────────────────────────────── */
.quote-preview {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    padding: 0.375rem var(--sp-3);
    background: var(--tp-surface);
    border-top: 1px solid var(--tp-border);
    border-left: 3px solid var(--tp-accent);
}
.quote-preview-content { flex: 1; min-width: 0; display: flex; gap: var(--sp-2); align-items: baseline; }
.quote-author  { font-size: var(--fs-xs); font-weight: 600; color: var(--tp-accent-text); flex-shrink: 0; }
.quote-text    { font-size: var(--fs-xs); color: var(--tp-text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.quote-dismiss {
    background: transparent;
    border: none;
    color: var(--tp-text-muted);
    cursor: pointer;
    font-size: var(--fs-xs);
    flex-shrink: 0;
    padding: 0;
}
.quote-dismiss:hover { color: var(--tp-text-primary); }

/* ── Reaction bar ────────────────────────────────────────── */
.reaction-bar {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-1);
    margin-top: var(--sp-1);
}
.reaction {
    background: var(--tp-surface);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-full);
    padding: 0.1rem var(--sp-2);
    font-size: var(--fs-xs);
    cursor: pointer;
    transition: background 0.1s;
}
.reaction:hover  { background: var(--tp-surface-hover); }
.reaction.reacted { border-color: var(--tp-accent); background: rgba(var(--tp-accent-rgb),0.15); }

/* ── Message attachment ──────────────────────────────────── */
.message-attachment {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    background: rgba(0,0,0,0.2);
    border-radius: var(--radius-md);
    padding: 0.3rem 0.6rem;
    margin-top: var(--sp-1);
    text-decoration: none;
    color: inherit;
    font-size: var(--fs-xs);
    border: 1px solid rgba(255,255,255,0.1);
    max-width: 240px;
}
.message-attachment:hover { background: rgba(0,0,0,0.35); }
.attachment-icon { flex-shrink: 0; opacity: 0.7; }
.attachment-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attachment-size { flex-shrink: 0; opacity: 0.6; font-size: var(--fs-2xs); }

/* ── Attachment picker ───────────────────────────────────── */
.attachment-picker {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.375rem;
    padding: 0 var(--sp-1);
}
.attachment-picker input[type="file"] {
    width: 0.1px;
    height: 0.1px;
    opacity: 0;
    position: absolute;
}
.attachment-chip {
    display: flex;
    align-items: center;
    gap: var(--sp-1);
    background: var(--tp-surface);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-full);
    padding: 0.1rem var(--sp-2);
    font-size: var(--fs-xs);
    color: var(--tp-text-secondary);
}
.attachment-chip button {
    background: transparent;
    border: none;
    color: var(--tp-text-muted);
    cursor: pointer;
    font-size: var(--fs-2xs);
    padding: 0;
    line-height: 1;
}

/* ── Message composer ────────────────────────────────────── */
.message-composer {
    border-top: 1px solid var(--tp-border);
    background: var(--tp-bg-base);
    flex-shrink: 0;
}

.composer-body {
    display: flex;
    align-items: flex-end;
    gap: var(--sp-2);
    padding: 0.625rem 0.875rem;
}

.composer-input {
    flex: 1;
    background: var(--tp-surface);
    border: 1px solid var(--tp-border);
    /* feste Rundung - radius-full würde ein mehrzeiliges Feld zur Ellipse machen */
    border-radius: var(--radius-xl);
    color: var(--tp-text-primary);
    font-size: var(--fs-sm);
    padding: var(--sp-2) 0.875rem;
    resize: none;
    /* #1490: wächst mit dem Text (bis 120 px, dann Rollbalken) statt mehrzeiligen Text in einer Zeile abzuschneiden. */
    field-sizing: content;
    min-height: calc(1.45em + 2 * var(--sp-2) + 2px);
    max-height: 120px;
    outline: none;
    line-height: 1.45;
    font-family: inherit;
}
.composer-input:focus { border-color: var(--tp-border-hover); }
.composer-input:focus-visible { border-color: var(--tp-success); box-shadow: 0 0 0 3px rgba(var(--tp-success-rgb), 0.15); }
.composer-input::placeholder { color: var(--tp-text-muted); }

.composer-send {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--tp-accent);
    color: var(--tp-on-accent-text); /* fixed dark text: --tp-accent is a light violet in both themes, unlike --tp-bg-base it doesn't invert */
    border: none;
    font-size: var(--fs-md);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: opacity 0.15s;
}
.composer-send:hover    { opacity: 0.85; }
.composer-send:disabled { opacity: 0.35; cursor: default; }

/* ── New conversation modal extras ──────────────────────── */
.modal-tabs {
    display: flex;
    gap: var(--sp-2);
    margin-bottom: var(--sp-1);
}
.modal-tabs button {
    flex: 1;
    background: var(--tp-surface);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-md);
    color: var(--tp-text-secondary);
    padding: 0.375rem;
    cursor: pointer;
    font-size: var(--fs-sm);
    transition: background 0.1s;
}
.modal-tabs button.active,
.modal-tabs button:hover {
    background: var(--tp-surface-hover);
    color: var(--tp-text-primary);
    border-color: var(--tp-border-hover);
}

.member-list {
    max-height: 220px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: var(--sp-1);
    margin-bottom: var(--sp-1);
}

.member-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--sp-2) var(--sp-3);
    border-radius: var(--radius-md);
    cursor: pointer;
    font-size: var(--fs-sm);
    color: var(--tp-text-primary);
    background: var(--tp-surface);
    border: 1px solid transparent;
    transition: background 0.1s;
}
.member-item:hover    { background: var(--tp-surface-hover); }

.modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: var(--sp-2);
    margin-top: var(--sp-1);
}
.modal-footer button {
    background: var(--tp-surface);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-md);
    color: var(--tp-text-primary);
    padding: 0.4rem var(--sp-4);
    cursor: pointer;
    font-size: var(--fs-sm);
}
.modal-footer button:hover { background: var(--tp-surface-hover); }
.modal-footer .btn-primary {
    background: var(--tp-accent);
    border-color: var(--tp-accent);
    color: var(--tp-on-accent-text); /* fixed dark text: --tp-accent is a light violet in both themes, unlike --tp-bg-base it doesn't invert */
    font-weight: 600;
}
.modal-footer .btn-primary:hover   { opacity: 0.85; }

/* ═══════════════════════════════════
   Chat Drawer
   ═══════════════════════════════════ */

.chat-drawer-backdrop {
    position: fixed;
    inset: 0;
    z-index: 1040;
    background: rgba(0, 0, 0, 0.25);
}

.chat-drawer {
    position: fixed;
    right: 0;
    top: 0;
    bottom: 0;
    /* #1490: Standard 400 px, per Ziehen am linken Rand 320 px bis halbe Fensterbreite (chat-drawer.js). */
    width: var(--chat-drawer-width, 400px);
    max-width: 100vw;
    z-index: 1050;
    background: var(--bs-body-bg);
    box-shadow: -4px 0 16px rgba(0, 0, 0, 0.15);
    display: flex;
    flex-direction: column;
    animation: chat-drawer-slide-in 0.25s ease forwards;
}

@keyframes chat-drawer-slide-in {
    from { transform: translateX(100%); }
    to   { transform: translateX(0); }
}

@media (max-width: 639px) {
    .chat-drawer { width: 100vw; }
    .chat-drawer-resize { display: none; }
}

.chat-drawer-resize {
    position: absolute;
    left: -4px;
    top: 0;
    bottom: 0;
    width: 8px;
    cursor: ew-resize;
    z-index: 1;
}
.chat-drawer-resize:hover,
body.chat-drawer-resizing .chat-drawer-resize { background: rgba(var(--tp-info-rgb), 0.25); }
body.chat-drawer-resizing { cursor: ew-resize; user-select: none; }

/* In der Leiste steht die Chatliste allein über die volle Breite (auf der Seite daneben der Chat). */
.chat-drawer .conversation-list { width: 100%; flex: 1; border-right: none; }

.chat-drawer-actions { display: inline-flex; gap: var(--sp-3); align-items: center; }
.chat-drawer-header .chat-drawer-back {
    font-size: var(--fs-sm);
    font-weight: 600;
    color: var(--tp-link, var(--tp-info-text));
    display: inline-flex;
    gap: var(--sp-1);
    align-items: center;
}

.chat-drawer-header {
    background: var(--tp-surface);
    color: var(--tp-text-primary);
    padding: var(--sp-3) var(--sp-4);
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-shrink: 0;
    font-weight: 600;
    font-size: var(--fs-sm);
}

.chat-drawer-header button {
    background: none;
    border: none;
    color: var(--tp-text-primary);
    cursor: pointer;
    font-size: var(--fs-md);
    line-height: 1;
    padding: 0;
}

.chat-drawer-subject-hint {
    background: rgba(var(--tp-info-rgb), 0.1);
    border-bottom: 1px solid rgba(var(--tp-info-rgb), 0.3);
    padding: var(--sp-2) 0.875rem;
    font-size: var(--fs-xs);
    color: var(--tp-info-text);
    flex-shrink: 0;
}

.chat-drawer-body {
    flex: 1;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

/* ═══════════════════════════════════
   Topbar dropdown (avatar / admin / verwaltung menus)
   ═══════════════════════════════════ */

.tp-topbar-dropdown { position: relative; display: flex; }

.tp-topbar-dropdown-trigger {
    background: none;
    border: none;
    cursor: pointer;
    color: var(--tp-text-muted);
    font-size: var(--fs-md);
    padding: var(--sp-1) 0.375rem;
    display: flex;
    align-items: center;
    line-height: 1;
    border-radius: var(--radius-sm);
    transition: color 0.15s;
}
.tp-topbar-dropdown-trigger:hover,
.tp-topbar-dropdown-trigger.active { color: var(--tp-text-primary); }

.tp-topbar-dropdown-backdrop {
    position: fixed;
    inset: 0;
    z-index: 150;
    background: transparent;
}

.tp-topbar-dropdown-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 230px;
    background: var(--tp-bg-base);
    border: 1px solid var(--tp-border-subtle);
    border-radius: var(--radius-md);
    box-shadow: 0 8px 24px rgba(0,0,0,0.3);
    z-index: 151;
    padding: 0.35rem 0;
    display: flex;
    flex-direction: column;
}

.tp-topbar-dropdown-header {
    font-size: var(--fs-2xs);
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--tp-border);
    padding: 0.35rem 0.9rem var(--sp-1);
}

.tp-topbar-dropdown-divider {
    height: 1px;
    background: var(--tp-border-subtle);
    margin: 0.3rem 0;
}

.tp-topbar-dropdown-item {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 0.9rem;
    color: var(--tp-text-secondary, var(--tp-text-muted));
    text-decoration: none;
    font-size: var(--fs-sm);
    background: none;
    border: none;
    width: 100%;
    text-align: left;
    cursor: pointer;
}
.tp-topbar-dropdown-item:hover {
    color: var(--tp-text-primary);
    background: rgba(41,53,72,0.5);
}
.tp-topbar-dropdown-item i { width: 18px; text-align: center; flex-shrink: 0; }

/* ═══════════════════════════════════
   Topbar chat button + badge
   ═══════════════════════════════════ */

.tp-topbar-chat-btn {
    position: relative;
    cursor: pointer;
    background: none;
    border: none;
    color: var(--tp-text-muted);
    font-size: var(--fs-md);
    padding: var(--sp-1) 0.375rem;
    display: flex;
    align-items: center;
    line-height: 1;
    border-radius: var(--radius-sm);
    transition: color 0.15s;
    text-decoration: none;
}

.tp-topbar-chat-btn:hover {
    color: var(--tp-text);
}

.tp-topbar-chat-badge {
    position: absolute;
    top: -2px;
    right: -2px;
    background: var(--tp-danger);
    color: var(--tp-on-color-text);
    border-radius: 50%;
    min-width: 16px;
    height: 16px;
    font-size: var(--fs-2xs);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 3px;
    font-weight: 600;
    pointer-events: none;
}
.modal-footer .btn-primary:disabled { opacity: 0.4; cursor: default; }

/* ═══════════════════════════════════
   Bottom Navigation Bar
   ═══════════════════════════════════ */

.tp-bottom-nav {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    height: 56px;
    background: var(--tp-bg-base);
    border-top: 1px solid var(--tp-border-subtle);
    display: flex;
    align-items: stretch;
    z-index: 200;
}

@media (min-width: 768px) {
    .tp-bottom-nav { display: none; }
}

.tp-bottom-tab {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    color: var(--tp-text-muted);
    text-decoration: none;
    font-size: var(--fs-2xs);
    font-weight: 500;
    border: none;
    background: none;
    cursor: pointer;
    transition: color 0.12s;
    padding: 0;
}

.tp-bottom-tab:hover,
.tp-bottom-tab.active {
    color: var(--tp-success-text);
}

.tp-bottom-icon {
    font-size: var(--fs-lg);
    position: relative;
    line-height: 1;
}

.tp-bottom-label {
    font-size: var(--fs-2xs);
    white-space: nowrap;
}

.tp-bottom-badge {
    position: absolute;
    top: -4px;
    right: -6px;
    background: var(--tp-danger);
    color: var(--tp-on-color-text);
    border-radius: 50%;
    min-width: 14px;
    height: 14px;
    font-size: var(--fs-2xs);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 2px;
    font-weight: 700;
    pointer-events: none;
}

.tp-bottom-more { color: var(--tp-text-muted); }

/* ═══════════════════════════════════
   Floating Action Button (mobile list pages, #236)
   ═══════════════════════════════════ */

.tp-fab {
    position: fixed;
    right: 16px;
    bottom: calc(56px + 16px); /* above the 56px-tall BottomNav */
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--tp-success);
    color: var(--tp-on-color-text);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--fs-lg);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
    z-index: 210;
    text-decoration: none;
}

.tp-fab:hover,
.tp-fab:focus-visible {
    color: var(--tp-on-color-text);
    filter: brightness(1.08);
}

@media (min-width: 768px) {
    .tp-fab { display: none; }
}
.tp-bottom-more:hover { color: var(--tp-text-primary); }

/* ═══════════════════════════════════
   Mobile Drawer
   ═══════════════════════════════════ */

.tp-mobile-drawer-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 1040;
    background: rgba(0, 0, 0, 0.5);
}
.tp-mobile-drawer-backdrop.active {
    display: block;
}

.tp-mobile-drawer {
    position: fixed;
    left: 0;
    top: 0;
    bottom: 0;
    width: 280px;
    z-index: 1050;
    background: var(--tp-bg-base);
    border-right: 1px solid var(--tp-border);
    display: flex;
    flex-direction: column;
    transform: translateX(-100%);
    transition: transform 0.25s ease;
    overflow-y: auto;
}

.tp-mobile-drawer--open {
    transform: translateX(0);
}

@media (max-width: 639px) {
    .tp-mobile-drawer { width: 100vw; }
}

@media (min-width: 768px) {
    .tp-mobile-drawer          { display: none; }
    .tp-mobile-drawer-backdrop { display: none; }
}

.tp-mobile-drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 var(--sp-4);
    height: 52px;
    border-bottom: 1px solid var(--tp-border-subtle);
    flex-shrink: 0;
    font-weight: 600;
    font-size: var(--fs-sm);
    color: var(--tp-text-primary);
}

.tp-mobile-drawer-header button {
    background: none;
    border: none;
    color: var(--tp-text-muted);
    cursor: pointer;
    font-size: var(--fs-md);
    padding: var(--sp-1);
    line-height: 1;
}
.tp-mobile-drawer-header button:hover { color: var(--tp-text-primary); }

/* ── Toast notifications ─────────────────────────────── */
/* #1491: unten rechts statt oben rechts - oben verdeckten die Meldungen Feedback, Suche und Glocke der Kopfzeile.
   Neueste Meldung unten (column), auf dem Handy über der unteren Leiste und dem Plus-Knopf (56 + 16 + 56 + 16 px). */
.tp-toast-container {
    position: fixed;
    bottom: calc(56px + 16px + 56px + 16px + env(safe-area-inset-bottom, 0px));
    right: 1rem;
    left: 1rem;
    z-index: 1100;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: var(--sp-2);
    pointer-events: none;
}
@media (min-width: 768px) {
    .tp-toast-container { bottom: 1.5rem; left: auto; max-width: 360px; }
}

.tp-toast {
    pointer-events: auto;
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-3) var(--sp-4);
    border-radius: var(--radius-md);
    box-shadow: 0 4px 12px rgba(0,0,0,.15);
    /* Die Tönung (tp-toast-*) liegt über deckender Fläche - sonst scheint der Seiteninhalt durch. */
    background-color: var(--tp-surface);
    max-width: 360px;
    animation: tp-toast-in 0.2s ease forwards;
}

@keyframes tp-toast-in {
    from { opacity: 0; transform: translateY(0.5rem); }
    to   { opacity: 1; transform: translateY(0); }
}

/* #479: was the raw Bootstrap light-alert palette, unthemed - appeared as bright islands on
   the dark theme. Now the same token-tint + token-text pattern as .tp-badge and .alert above. */
.tp-toast-success { background-image: linear-gradient(rgba(var(--tp-success-rgb), 0.12), rgba(var(--tp-success-rgb), 0.12)); color: var(--tp-alert-success-text); border-left: 4px solid var(--tp-success); }
.tp-toast-error   { background-image: linear-gradient(rgba(var(--tp-danger-rgb), 0.12), rgba(var(--tp-danger-rgb), 0.12)); color: var(--tp-alert-danger-text); border-left: 4px solid var(--tp-danger); }
.tp-toast-warning { background-image: linear-gradient(rgba(var(--tp-warning-rgb), 0.12), rgba(var(--tp-warning-rgb), 0.12)); color: var(--tp-alert-warning-text); border-left: 4px solid var(--tp-warning); }
.tp-toast-info    { background-image: linear-gradient(rgba(var(--tp-info-rgb), 0.12), rgba(var(--tp-info-rgb), 0.12)); color: var(--tp-alert-info-text); border-left: 4px solid var(--tp-info); }

.tp-toast-message { flex: 1; font-size: var(--fs-sm); }

.tp-toast-close {
    background: none;
    border: none;
    padding: 0;
    opacity: 0.5;
    cursor: pointer;
    line-height: 1;
    font-size: var(--fs-md);
}
.tp-toast-close:hover { opacity: 1; }

/* ── Statistics / Heatmap ────────────────────────────────────────────────── */

.tp-chart-wrapper canvas {
    width: 100% !important;
}

.tp-heatmap-wrapper {
    overflow-x: auto;
}

.tp-heatmap {
    border-collapse: separate;
    border-spacing: 2px;
    min-width: max-content;
    font-size: var(--fs-xs);
}

.tp-heatmap th,
.tp-heatmap td {
    padding: 0;
    border: none;
}

.tp-heatmap-player-col {
    padding: var(--sp-1) var(--sp-3) var(--sp-1) 0 !important;
    white-space: nowrap;
    color: var(--tp-text-secondary);
    font-weight: 500;
    min-width: 120px;
}

.tp-heatmap-date {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    white-space: nowrap;
    padding: var(--sp-2) var(--sp-1) !important;
    color: var(--tp-text-muted);
    font-weight: 400;
    font-size: var(--fs-xs);
    min-width: 24px;
    text-align: center;
}

.tp-heatmap-cell {
    width: 22px;
    height: 22px;
    border-radius: var(--radius-sm);
    cursor: default;
}

.tp-heatmap-present    { background-color: var(--tp-success);  opacity: 0.85; }
.tp-heatmap-absent     { background-color: var(--tp-danger);   opacity: 0.7;  }
.tp-heatmap-unknown    { background-color: var(--tp-warning);  opacity: 0.6;  }

/* ═══════════════════════════════════════════════════════════
   TASKS (Aufgaben / Buckets)
   ═══════════════════════════════════════════════════════════ */

/* ── Stacked progress bar (bucket list "Fortschritt" column) ── */
.tp-stacked-progress {
    display: flex;
    height: 6px;
    width: 100%;
    min-width: 80px;
    border-radius: var(--radius-full);
    overflow: hidden;
    background: var(--tp-border-subtle);
}
.tp-stacked-progress-segment.status-open        { background: var(--tp-text-muted); }
.tp-stacked-progress-segment.status-in-progress { background: var(--tp-info); }
.tp-stacked-progress-segment.status-done        { background: var(--tp-success); }
.tp-stacked-progress-caption {
    font-size: var(--fs-2xs);
    color: var(--tp-text-muted);
    margin-top: 0.3rem;
}

/* ── Task tree (bucket detail page) ───────────────────────── */
.tp-task-tree {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}
.tp-task-card {
    background: var(--tp-surface);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
}
.tp-task-card-main {
    display: flex;
    align-items: center;
    padding: 0.65rem 0.9rem;
    cursor: grab;
}
.tp-task-dragging {
    opacity: 0.4;
}
.tp-task-drop-target {
    outline: 2px dashed var(--tp-accent);
    outline-offset: -2px;
    background: var(--tp-surface-hover);
}
.tp-task-card-subprogress-label {
    font-size: var(--fs-2xs);
    color: var(--tp-text-muted);
    white-space: nowrap;
}
.tp-task-subtask-list {
    border-top: 1px solid var(--tp-border-subtle);
}
.tp-task-subtask-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: var(--sp-2) 0.9rem;
    position: relative;
    cursor: grab;
}
.tp-task-subtask-row + .tp-task-subtask-row {
    border-top: 1px solid var(--tp-border-subtle);
}
/* Left offset must clear the fixed 1.4rem checkbox column (+0.6rem grid gap) before
   scaling by depth, otherwise the connector is drawn under/through the checkbox instead
   of the gap before the (padding-indented) title -- see .tp-task-col-title below. */
.tp-task-subtask-row::before {
    content: "";
    position: absolute;
    left: calc(1.5rem * var(--tp-task-depth, 1) + 1.2rem);
    top: 0;
    bottom: 0;
    width: 1px;
    background: var(--tp-border);
}
.tp-task-subtask-row::after {
    content: "";
    position: absolute;
    left: calc(1.5rem * var(--tp-task-depth, 1) + 1.2rem);
    top: 50%;
    width: 0.8rem;
    height: 1px;
    background: var(--tp-border);
}

/* Row grid shared by top-level card rows and nested subtask rows.
   Every column except the title has a fixed width (badges included -- an "auto" badges
   column would resize per-row depending on whether "Ueberfaellig" is present, which eats
   into the title's leftover 1fr space and pushes every column after it left/right) so that
   counter/dates/assigned/badges line up vertically across all rows regardless of depth or
   badge count; only the title text itself (not the checkbox) is pushed in via its own
   padding-left. */
.tp-task-row-grid {
    display: grid;
    grid-template-columns: 1.4rem minmax(0, 1fr) 128px 148px 220px 140px;
    align-items: center;
    column-gap: 0.6rem;
    width: 100%;
}
.tp-task-col-title {
    min-width: 0;
    padding-left: calc(var(--sp-6) * var(--tp-task-depth, 0));
}
.tp-task-col-title-text {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.tp-task-col-description {
    font-size: var(--fs-xs);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.tp-task-col-counter {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.tp-task-col-counter .tp-stacked-progress { max-width: 100%; }
.tp-task-col-counter-label {
    font-size: var(--fs-2xs);
    color: var(--tp-text-muted);
    white-space: nowrap;
}
.tp-task-col-dates,
.tp-task-col-assigned {
    font-size: var(--fs-sm);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.tp-task-col-badges {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    justify-self: end;
}
@media (max-width: 767px) {
    .tp-task-row-grid {
        grid-template-columns: 1.4rem minmax(0, 1fr) 92px 140px;
    }
}
.tp-heatmap-noresponse { background-color: var(--tp-border);   opacity: 0.9;  }

/* ── Global search (TopBar, #226 / #254 collapsed behind icon) ──────────────── */
.tp-global-search {
    position: relative;
    display: flex;
    align-items: center;
}
.tp-global-search-icon {
    position: absolute;
    left: 0.6rem;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.4rem;
    height: 1.4rem;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--tp-text-muted);
    font-size: var(--fs-sm);
    cursor: pointer;
}
.tp-global-search-input {
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--tp-text);
    font-size: var(--fs-sm);
    opacity: 0;
    transition: width 0.15s, opacity 0.15s, padding 0.15s, background-color 0.15s, border-color 0.15s;
}
.tp-global-search-input:focus,
.tp-global-search--open .tp-global-search-input {
    outline: none;
    width: 220px;
    padding: 0 0.6rem 0 1.9rem;
    background: var(--tp-bg-elevated, var(--tp-bg-base));
    border-color: var(--tp-border-subtle);
    opacity: 1;
}
.tp-global-search-input:focus {
    width: 280px;
    border-color: var(--tp-accent);
}
.tp-global-search-backdrop {
    position: fixed;
    inset: 0;
    z-index: 150;
}
.tp-global-search-results {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    width: 360px;
    max-height: 70vh;
    overflow-y: auto;
    background: var(--tp-bg-base);
    border: 1px solid var(--tp-border-subtle);
    border-radius: var(--radius-md);
    box-shadow: 0 8px 24px rgba(0,0,0,0.3);
    z-index: 151;
    padding: 0.35rem 0;
}
.tp-global-search-group {
    padding: 0.35rem 0.85rem 0.15rem;
    font-size: var(--fs-2xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--tp-text-muted);
}
.tp-global-search-item {
    display: flex;
    flex-direction: column;
    padding: 0.35rem 0.85rem;
    text-decoration: none;
    color: var(--tp-text);
}
.tp-global-search-item:hover,
.tp-global-search-item.active {
    background: var(--tp-bg-hover, rgba(255,255,255,0.06));
    color: var(--tp-text);
}
.tp-global-search-title { font-size: var(--fs-sm); }
.tp-global-search-subtitle { font-size: var(--fs-xs); color: var(--tp-text-muted); }
.tp-global-search-hint { padding: 0.6rem 0.85rem; font-size: var(--fs-sm); color: var(--tp-text-muted); }

/* #509: the fixed 220/280/360px widths above overflow a 360-390px-wide phone viewport - the
   results list is pinned edge-to-edge (offset by the same gutter DataTable etc. use) and the
   input grows to fill the remaining TopBar width instead of a fixed px value. */
@media (max-width: 639px) {
    .tp-global-search-input:focus,
    .tp-global-search--open .tp-global-search-input {
        width: calc(100vw - 6rem);
    }
    .tp-global-search-results {
        position: fixed;
        left: var(--sp-3);
        right: var(--sp-3);
        top: 52px;
        width: auto;
    }
}

/* ── DataTable toolbar / pagination (#227) ─────────────────────────────────
   Search and filters sit as a plain row above the table card (same look as
   .tp-list-toolbar), not as a highlighted band inside it. */
.tp-datatable-toolbar {
    display: flex;
    align-items: center;
    gap: var(--sp-3);
    flex-wrap: wrap;
    margin-bottom: var(--sp-3);
}
.tp-datatable-search { max-width: 300px; }

/* ── Icon search input (search + dropdown filters in a list toolbar) ── */
.tp-search-input-wrap { position: relative; display: flex; align-items: center; flex: 1 1 260px; max-width: 300px; }
.tp-search-input-wrap .tp-search-icon {
    position: absolute;
    left: 10px;
    width: 15px;
    height: 15px;
    color: var(--tp-text-muted);
    pointer-events: none;
}
.tp-search-input-wrap .form-control { padding-left: var(--sp-8); }
.tp-search-toolbar-reset {
    background: none;
    border: none;
    color: var(--tp-text-muted);
    font-size: var(--fs-xs);
    cursor: pointer;
    padding: 0.3rem 0.2rem;
}
.tp-search-toolbar-reset:hover { color: var(--tp-text-primary); text-decoration: underline; }
.tp-pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sp-3);
    flex-wrap: wrap;
    padding: var(--sp-2) var(--sp-4);
    border-top: 1px solid var(--tp-border-subtle);
}
.tp-pagination-controls { display: flex; align-items: center; gap: 0.35rem; }
.tp-pagination-size { width: auto; }
.tp-datatable-detail td { background: var(--tp-bg-elevated, rgba(0,0,0,0.04)); }
.tp-datatable-select-col { width: 2.25rem; text-align: center; }
.tp-row-link { cursor: pointer; }
.tp-row-link a { display: block; }

/* Issue 912: öffentliche Vereinsseite - Abteilungen mit ihren Mannschaften als Kacheln. */
.tp-public-department { padding: var(--sp-4) var(--sp-6); }
.tp-public-department + .tp-public-department { border-top: 1px solid var(--tp-border-subtle); }
.tp-public-department-title { font-size: var(--fs-md); font-weight: 600; margin: 0 0 var(--sp-2); }
.tp-public-department-title a { color: inherit; text-decoration: none; }
.tp-public-department-title a:hover { text-decoration: underline; }
.tp-public-department-title .bi { font-size: var(--fs-xs); color: var(--tp-text-muted); }
.tp-public-team-grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: var(--sp-2);
}
.tp-public-team {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    height: 100%;
    padding: var(--sp-2) var(--sp-3);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-sm);
    background: var(--tp-surface);
    color: inherit;
    text-decoration: none;
}
.tp-public-team .bi { color: var(--tp-text-muted); }
.tp-public-team:hover { border-color: var(--tp-border-hover); background: var(--tp-surface-hover); }

/* Issue 912: Sponsorenlogos in gleich großen Rahmen, eingepasst statt abgeschnitten. */
.tp-sponsor-grid {
    list-style: none;
    margin: 0;
    padding: var(--sp-4) var(--sp-6);
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: var(--sp-3);
}
.tp-sponsor-tile {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 5.5rem;
    padding: var(--sp-2) var(--sp-3);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-sm);
    background: var(--tp-logo-bg);
    text-align: center;
}
.tp-sponsor-tile img { max-width: 100%; max-height: 100%; object-fit: contain; }
.tp-sponsor-tile span { color: var(--tp-logo-text); font-size: var(--fs-sm); }

/* ── Utility classes generated for #230 (replacing single-property inline styles) ───── */
.tp-pointer { cursor: pointer; }

/* #876: Hilfsklassen statt wiederkehrender Inline-Styles. */
.tp-tracking-wide { letter-spacing: .05em; }
.tp-text-muted { color: var(--tp-text-muted); }
.tp-toggle-header { cursor: pointer; user-select: none; }
.tp-leading-relaxed { line-height: 1.6; }
.tp-scroll-160 { max-height: 160px; overflow-y: auto; }
.tp-color-swatch { width: 14px; height: 14px; border-radius: var(--radius-sm); }
.tp-pre-wrap { white-space: pre-wrap; }
.tp-logo-preview { max-height: 80px; padding: var(--sp-1); border-radius: var(--radius-sm); background: var(--tp-logo-preview-bg); }

.tp-mail-preview {
    width: 100%;
    height: 520px;
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-md);
    background: var(--tp-bg-base);
}
.tp-logo-preview--dark { background: var(--tp-bg-base); }
.tp-club-card { transition: border-color .15s; }
.tp-club-card:hover { border-color: var(--tp-success); }
.tp-flex-00-12 { flex:0 0 12rem; }
.tp-flex-00-5 { flex:0 0 5rem; }
.tp-flex-11-10 { flex:1 1 10rem; }
.tp-flex-11-12 { flex:1 1 12rem; }
.tp-flex-11-8 { flex:1 1 8rem; }
.tp-text-2xs { font-size: var(--fs-2xs); }
.tp-text-sm { font-size: var(--fs-sm); }
.tp-h-8 { height:8px; }
.tp-mh-200 { max-height:200px; }
.tp-mh-400 { max-height:400px; }
.tp-minw-110 { min-width:110px; }
.tp-contents { display: contents; }
.tp-minw-120 { min-width:120px; }
.tp-minw-220 { min-width:220px; }
.tp-minw-360 { min-width:360px; }
.tp-mw-120 { max-width:120px; }
/* #865: Schriftgrößen im Markup nur über die --fs-Skala */
.tp-fs-2xs { font-size: var(--fs-2xs); }
.tp-fs-xs { font-size: var(--fs-xs); }
.tp-fs-sm { font-size: var(--fs-sm); }
.tp-fs-lg { font-size: var(--fs-lg); }
.tp-fs-inherit { font-size: inherit; }
.tp-fs-hero { font-size: 2.5rem; }
/* #914: Profilbild auf der öffentlichen Ausweisprüfung */
.tp-member-card-photo { display: block; width: 96px; height: 96px; margin: 0 auto; border-radius: 50%; object-fit: cover; }
.tp-check-card { max-width: 360px; margin: var(--sp-8) auto; }
/* #1068: Inhaltsbereich des App- und des öffentlichen Rahmens (vorher inline in MainLayout). */
.tp-content { padding: var(--sp-6); }
/* #1068: feste Namensspalte der Aufgaben-Zeitachse; Höhe und Einrückung je Zeile bleiben inline (berechnet). */
.tp-timeline-labels { position: sticky; left: 0; z-index: 1; background: var(--bs-body-bg); flex-shrink: 0; width: 210px; }
.tp-timeline-label { cursor: pointer; display: flex; align-items: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Profilbild zuschneiden: runder Ausschnitt, das Bild darin verschiebt und skaliert avatar-cropper.js. */
.tp-avatar-crop { position: relative; width: 280px; height: 280px; max-width: 100%; margin: 0 auto; border-radius: 50%; overflow: hidden; touch-action: none; cursor: grab; background: var(--tp-border); }
.tp-avatar-crop img { position: absolute; max-width: none; user-select: none; pointer-events: none; }
.tp-member-card-initials { display: flex; align-items: center; justify-content: center; background: var(--tp-accent); color: var(--tp-on-color-text); font-size: var(--fs-xl); font-weight: 600; }
.tp-mw-140 { max-width:140px; }
.tp-mw-160 { max-width:160px; }
.tp-mw-200 { max-width:200px; }
.tp-mw-220 { max-width:220px; }
.tp-mw-240 { max-width:240px; }
.tp-mw-300 { max-width:300px; }
.tp-mw-400 { max-width:400px; }
.tp-mw-480 { max-width:480px; }
.tp-mw-520 { max-width:520px; }
.tp-mw-600 { max-width:600px; }
.tp-mw-640 { max-width:640px; }
.tp-mw-700 { max-width:700px; }
.tp-mw-960 { max-width:960px; }
.tp-w-110 { width:110px; }
.tp-w-140 { width:140px; }
.tp-w-160 { width:160px; }
.tp-w-180 { width:180px; }
.tp-w-200 { width:200px; }
.tp-w-240 { width:240px; }

.tp-w-60 { width:60px; }
.tp-w-70 { width:70px; }
.tp-w-75 { width:75px; }
.tp-w-80 { width:80px; }

/* ── "Heute"-Bereich / TodayPanel (#232) ──────────────────────────────────── */
.tp-today-panel { margin-bottom: var(--sp-4); border-color: var(--tp-accent); }
.tp-today-item { gap: var(--sp-3); }
.tp-today-actions { display: flex; gap: 0.35rem; flex-shrink: 0; }
.tp-today-item-link { color: inherit; text-decoration: none; }

/* ── Skip-Link (#505) ──────────────────────────────────── */
.tp-skip-link {
    position: absolute;
    top: -40px;
    left: 0;
    z-index: 2000;
    padding: var(--sp-2) var(--sp-3);
    background: var(--tp-accent);
    color: var(--tp-on-accent-text); /* fixed dark text: --tp-accent is a light violet in both themes, unlike --tp-bg-base it doesn't invert */
    text-decoration: none;
    border-radius: 0 0 0.25rem 0;
    transition: top 0.1s ease-in-out;
}

.tp-skip-link:focus {
    top: 0;
}

/* ── Reduced motion (#177) ──────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* #618: Aufstellungsfeld je Sportart - Seitenverhältnis und Untergrund; die Linien zeichnet PitchMarkings (SVG). */
.tp-pitch { position: relative; background-color: var(--tp-pitch); }
.tp-pitch--football { aspect-ratio: 68 / 105; }
.tp-pitch--hockey { aspect-ratio: 55 / 91.4; }
.tp-pitch--handball { aspect-ratio: 1 / 2; background-color: var(--tp-court); }
.tp-pitch--basketball { aspect-ratio: 15 / 28; background-color: var(--tp-court); }
.tp-pitch--volleyball { aspect-ratio: 1 / 2; background-color: var(--tp-court); }
.tp-pitch--neutral { aspect-ratio: 2 / 3; background-color: var(--tp-court-neutral); }

.tp-pitch-lines {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.tp-pitch-line { fill: none; stroke: var(--tp-pitch-line); stroke-width: 1px; }
.tp-pitch-line--strong { stroke: var(--tp-pitch-line-strong); stroke-width: 3px; }
.tp-pitch-line--dashed { stroke-dasharray: 6 4; }
.tp-pitch-line--filled { fill: var(--tp-pitch-line); }


/* #1040: Markdown-Inhalte (MarkdownView) - kein Abstand nach dem letzten Absatz, Bilder und Tabellen bleiben in der Spalte. */
.tp-markdown > :last-child { margin-bottom: 0; }
.tp-markdown img { max-width: 100%; height: auto; }
.tp-markdown table { display: block; max-width: 100%; overflow-x: auto; }

/* #632: laufende Version unten in der Seitenleiste - ein Eintrag wie die übrigen, nur kleiner und ohne Trennlinie. */
.tp-sidebar .nav-link.tp-sidebar-version {
    padding-top: var(--sp-1);
    padding-bottom: var(--sp-2);
    font-size: var(--fs-xs);
    font-weight: 400;
    white-space: normal;
}
.tp-sidebar .nav-link.tp-sidebar-version .tp-sidebar-icon { font-size: var(--fs-sm); }
.tp-sidebar .nav-link.tp-sidebar-version .tp-sidebar-label { white-space: normal; }

/* #635: Neuigkeiten - Version, Vorschau-Kennzeichen und Datum in einer Zeile, Abschnitte und Einträge kompakt. */
.tp-release { padding: var(--sp-4); margin-bottom: var(--sp-3); }
.tp-release-title {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--sp-2);
    font-size: var(--fs-lg);
    font-weight: 600;
    margin-bottom: var(--sp-2);
}
.tp-release-title .tp-badge { align-self: center; }
.tp-release-date { margin-left: auto; font-size: var(--fs-sm); font-weight: 400; color: var(--tp-text-muted); }
.tp-release-section {
    font-size: var(--fs-sm);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--tp-text-secondary);
    margin: var(--sp-3) 0 var(--sp-1);
}
.tp-release-entries { padding-left: var(--sp-5); margin-bottom: 0; }
.tp-release-entries li + li { margin-top: var(--sp-1); }
.tp-release > summary { cursor: pointer; color: var(--tp-text-secondary); }

/* #1186: Teilflächen eingerückt unter ihrer Fläche */
.tp-tree-indent-1 { padding-left: var(--sp-5); }
.tp-tree-indent-2 { padding-left: var(--sp-8); }

/* Fehlerdiagnose (admin/errors): Aufrufketten scrollen statt die Tabelle zu sprengen. */
.tp-error-sample + .tp-error-sample { border-top: 1px solid var(--tp-border-subtle); padding-top: var(--sp-3); }
.tp-stack {
    max-height: 320px;
    overflow: auto;
    white-space: pre;
    background: var(--tp-bg-deep);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-md);
    padding: var(--sp-2) var(--sp-3);
}


/* #1301: Zuordnungen im Bankabgleich - nach Person gruppiert, schmale Betragsfelder, dezentes Entfernen. */
.tp-bank-alloc { font-size: var(--fs-sm); }
.tp-bank-alloc-group { padding: var(--sp-2) 0; border-top: 1px solid var(--tp-border-subtle); }
.tp-bank-alloc-head { display: flex; justify-content: space-between; gap: var(--sp-2); font-weight: 600; }
.tp-bank-alloc-row { display: flex; align-items: center; gap: var(--sp-2); padding: 2px 0; min-width: 0; }
.tp-bank-alloc .form-control.tp-bank-amount { width: 6rem; flex: 0 0 6rem; text-align: right; }
.tp-bank-remove { color: var(--tp-text-muted); padding: 0 var(--sp-1); }
.tp-bank-remove:hover { color: var(--tp-danger); }
.tp-bank-alloc-sum { display: flex; justify-content: space-between; padding-top: var(--sp-2); border-top: 1px solid var(--tp-border-subtle); font-weight: 600; }
.tp-bank-prepay { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); margin-top: var(--sp-2); padding: var(--sp-2); border: 1px dashed var(--tp-border); border-radius: var(--radius-sm); font-size: var(--fs-sm); }
.tp-bank-prepay .form-select { width: auto; max-width: 12rem; }
.tp-bank-prepay .form-control.tp-bank-periods { width: 4.5rem; flex: 0 0 4.5rem; text-align: right; }

/* ── #1489: Kachelraster für Einstellungsseiten (Profil) ──────────────────
   Thematische Gruppen (tp-tile-group) mit je einem Raster: ab 1024 px zwei Spalten, darunter eine;
   tp-tile--wide (Listen wie Anmeldungen, Geräte) über die volle Breite. Leere Raster nehmen keinen Platz ein. */
.tp-tile-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sp-4);
    align-items: start;
    margin-bottom: var(--sp-5);
}
.tp-tile-grid:empty { display: none; }
@media (min-width: 1024px) {
    .tp-tile-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.tp-tile-grid > .tp-tile--wide { grid-column: 1 / -1; }
.tp-tile {
    background: var(--tp-surface);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-md);
    padding: var(--sp-4);
    min-width: 0;
}
.tp-tile > h5:first-child { margin-top: 0; }
.tp-tile-group {
    font-size: var(--fs-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--tp-text-muted);
    margin: 0 0 var(--sp-2);
}

/* ── #1492: Erwähnungen in Kommentaren ─────────────────────────────── */
.tp-mention-text { white-space: pre-wrap; }
.tp-mention {
    background: rgba(var(--tp-info-rgb), 0.15);
    color: var(--tp-info-text);
    border-radius: var(--radius-sm);
    padding: 0 var(--sp-1);
    font-weight: 600;
}
.tp-mention--me { background: rgba(var(--tp-warning-rgb), 0.22); color: var(--tp-alert-warning-text); }
.tp-mention-input { position: relative; flex: 1; min-width: 0; }
.tp-mention-popup {
    position: absolute;
    left: 0;
    top: 100%;
    z-index: 1060;
    margin: var(--sp-1) 0 0;
    padding: var(--sp-1) 0;
    list-style: none;
    min-width: 260px;
    max-width: 100%;
    background: var(--tp-surface);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-md);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
}
.tp-mention-popup li[role=option] {
    display: flex;
    align-items: center;
    gap: var(--sp-2);
    padding: var(--sp-1) var(--sp-3);
    cursor: pointer;
}
.tp-mention-popup li.active, .tp-mention-popup li[role=option]:hover { background: var(--tp-surface-hover); }
.tp-mention-avatar {
    width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--tp-border); font-size: var(--fs-xs); font-weight: 700;
}
.tp-mention-hint { font-size: var(--fs-xs); color: var(--tp-text-muted); padding: var(--sp-1) var(--sp-3) 0; border-top: 1px solid var(--tp-border); }
/* Sprung aus einer Mitteilung (?comment=) - kurz hervorgehoben. */
.tp-comment-highlight { animation: tp-comment-highlight 2.4s ease-out; border-radius: var(--radius-md); }
@keyframes tp-comment-highlight {
    from { box-shadow: 0 0 0 3px rgba(var(--tp-warning-rgb), 0.7); background: rgba(var(--tp-warning-rgb), 0.12); }
    to   { box-shadow: 0 0 0 3px transparent; background: transparent; }
}

/* ── #1197: Belegungsanzeige (Bildschirm im Vereinsheim) ─────────────────── */
.tp-display-shell {
    min-height: 100vh;
    background: var(--tp-bg-base);
    color: var(--tp-text-primary);
    padding: var(--sp-4);
}
.tp-display-message { font-size: var(--fs-xl); color: var(--tp-text-secondary); text-align: center; padding-top: 30vh; }
.tp-display-header { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--sp-3); margin-bottom: var(--sp-4); }
.tp-display-title { font-size: var(--fs-2xl); font-weight: 700; margin: 0; }
.tp-display-sub { font-size: var(--fs-lg); color: var(--tp-text-secondary); }
.tp-display-clock { font-size: var(--fs-2xl); font-weight: 700; font-variant-numeric: tabular-nums; }
.tp-display-stale { color: var(--tp-danger-text); font-size: var(--fs-md); margin-bottom: var(--sp-3); }
.tp-display-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: var(--sp-3); }
.tp-display-field,
.tp-display-matches {
    background: var(--tp-surface);
    border: 1px solid var(--tp-border);
    border-radius: var(--radius-lg);
    padding: var(--sp-3);
}
.tp-display-matches { margin-top: var(--sp-4); }
.tp-display-cabin { border-style: dashed; }
.tp-display-field-name { font-size: var(--fs-lg); font-weight: 700; margin: 0 0 var(--sp-2); }
.tp-display-free { color: var(--tp-text-secondary); font-size: var(--fs-md); }
.tp-display-entry {
    display: grid;
    grid-template-columns: auto 1fr auto;
    gap: var(--sp-2);
    align-items: baseline;
    padding: var(--sp-1) var(--sp-2);
    border-left: 4px solid var(--tp-border);
    border-radius: var(--radius-sm);
    font-size: var(--fs-md);
}
.tp-display-kind-training { border-left-color: var(--tp-success); }
.tp-display-kind-spiel,
.tp-display-kind-turnier { border-left-color: var(--tp-accent); }
.tp-display-kind-sperre { border-left-color: var(--tp-danger); }
.tp-display-now { background: var(--tp-surface-hover); font-weight: 600; }
.tp-display-past { opacity: 0.45; }
.tp-display-time { font-variant-numeric: tabular-nums; color: var(--tp-text-secondary); }
.tp-display-detail { color: var(--tp-text-secondary); font-size: var(--fs-sm); }
.tp-display-score { font-weight: 700; font-variant-numeric: tabular-nums; }

/* Vereins- und Gegner-Logos (fussball.de): klein in Spiellisten, groß und anklickbar im Kopf der Spielseite (#1512, #1513). */
.tp-team-cell { display: inline-flex; align-items: center; gap: var(--sp-1); }
.tp-team-logo {
    height: 20px;
    width: 20px;
    flex-shrink: 0;
    object-fit: contain;
}
.tp-team-logo-lg { height: 48px; width: 48px; }
.tp-team-logo-button {
    display: inline-flex;
    padding: 0;
    border: 0;
    background: none;
    border-radius: var(--radius-sm);
    cursor: zoom-in;
}
.tp-team-logo-button:focus-visible { outline: 2px solid var(--tp-accent); outline-offset: 2px; }
.tp-match-headline { display: inline-flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.tp-team-logo-zoom { width: min(256px, 100%); height: auto; object-fit: contain; }
